//+++keyword+++ "@(#)%v %n, %f, %w"
// "@(#)14 SSAFE.S, 21-Nov-95,22:08:56, LDH"

macro_file SSAFE;
/******************************************************************************
														 Multi-Edit Macro File
															 15-Aug-93  02:08

	This macro is the specific interface code for the VCS pakcage SourceSafe by
	One Tree Software

	SSafeExt     -
	SSafeLFile   -
	SSafeChkLib  -
	SSafeCmds    - The SourceSafe command interface.
	SSafeFile    - Creates a file dialog box for the SourceSafe VCS package.
	SSafeLogin   - Check if a SourceSafe user is logged in, and prompts if not.

								 Copyright (C) 1994 by Small Systems Support.
********************************************************************( ldh )***/

#include WINDOWS.SH
#include DIALOG.SH
#include WINEXEC.SH
#include IDEXE.SH
#include FPROMPT.SH
#include MEWLIST2.SH
#include EXIT.SH
#include METOOLS.SH
#include DBTOOLS.SH
#include DB.SH
#include MEWLIB.SH
#include VCS.SH

#ifdef   _DEBUG_
	#include MSGLOG.SH
#endif

#ifdef  _BETA_
  #define _SSAFE_VER   "7.01(0.10b)á"
#else
  #define _SSAFE_VER   "7.01(0.10b)"
#endif

prototype SSafe {
	int  SSafeExec( str CmdLine, int Show_Win, int Chg_Dir );
	str  SSafeXlate( str Path, str FName, str Project );
	str  SSafeExt( str FName );
	int  SSafeChkLib( str Project, str FName, int Pm );
	str  SSafeGetFName( str LibFile );
	int  SSafeChkLock( );
	int  SSafeLogin( int Chg_Usr );
	str  SSafeLookup( str FName, str Field1, str Field2 );
	str  SSafeCfgFile( str FName, str Param );
	int  SSafeCmds( str Cmd, str FName, str Project );
	int  SSafeGetPrj( str &Project, int Change );
	int  SSafeGetLib( str FName );
	void SSafeParseErr( );
	str  SSafeGetUser( );
	int  SSafeGetDirFile( int NewScan, int ChkOnly );
	int  SSafeUpdDirFile( str FName, str FStr );
	// Dialog macros in SSAFE.SWI
	int  SSafeFileSelPrj( str &Project, int Change );
	int  SSafeFileSetLst( str &Project, int hDlg, int FWOnly, int NewScan );
	void SSafeFileBtnProc( );
	void SSafeFileCmds( );
	int  SSafeFileMsgProc( int &RetVal, int Window, int Message, int WParam,
					int LParam, str Parms );
	void SSafeFileDlg( str Title, str Project );
}

global {
	str g_SSafeDirFile	"~ssafeDirFile";
	str g_SSafeUser			"~ssafeUser";			// Contains the current user name
	str g_SSafeUsr1			"~ssafeUsr1";			// Contains the original user name
	str g_SSafeIni			"~ssafeIni";			// Contains the SRCSAFE.INI file path
	str g_SSafePrj			"~ssafePrj";			// Contains the current project
	str g_SSafePwd			"~ssafePwd";			// Contains the temporary user password
	str g_SSafeCfg			"!ssafeCfg";			// Contains the command/setup options
	str g_SSafeLUT			"!ssafeLUT";			// Contains the LOOKUP data record
	str g_SSafeFUsr			"!ssafeFUsr";
	str g_SSafeLogCmd		"!ssafeLogCmd";		// The LOGIN command exe
	str g_SSafeCmdLn		"!ssafeCmdLn";		// The Command line exe

	int g_SSafeRDir			"!ssafeRDir";
}

#include SSAFE.SWI                      // Include Windows dialog macros


macro SSafe Trans {
/******************************************************************************
															 Multi-Edit Macro
															 15-Sep-94  21:25

	Name    : SSafe

	Function: Checks that the GET executable is found and initilizes SourceSafe
						support.

	Syntax  : Rm( "SSafe /I" );

	Entry   : /I              - Initialize the system if checks pass.

	Exit    : Return_Int
							False         - SrcSafe support not installed and checks failed.
							True          - SrcSafe support installed and checks passed.

						gstr !vcsVerStr - "SSAFE " + macro version number.
						gstr !vcsRevStr - macro revision number.

	Globals : int !vcsNoMenu  - True disables most of the menu commands.
						int !vcsNoAct   - True disables the interactive menu command.
						int !vcsNoCUId  - True disables the change use Id menu command.
						str !vcsVerStr  - Returns the string "SSAFE " + macro version no.
						str !vcsRevStr  - Returns the macro revision number.

	Macros  : int VcsChkVer
						mac PathSearch

								 Copyright (C) 1994 by Small Systems Support.
********************************************************************( ldh )***/

//+++keyword+++ "@(#)%v %n, %f, %w"
	str Rev_Id = "@(#)14 SSAFE.S, 21-Nov-95,22:08:56, LDH";
	str Cmd = Copy( _GET_CMDL, 1, XPos( " ", _GET_CMDL, 1 ) - 1 );
  str BDir = _BDIR_CMDL;

	// Check for get command EXE file
  if ( Svl( BDir ) ) {
    BDir += ";";
  }
	if ( Truncate_Extension( Cmd ) == "SS" ) {
		g_SSafeLogCmd = "SSLOGIN.EXE";
		g_SSafeCmdLn = "SS.EXE";
	}
	else {
		g_SSafeLogCmd = "SSWLOGIN.EXE";
		g_SSafeCmdLn = "SSWCL.EXE";
	}
  Return_Str = ExecSearchPath( Cmd, BDir + "<%PATH>" );
	Return_Int = ( Return_Str != "" );
	if ( Return_Int ) {
		if ( VcsChkVer( _SSAFE_VER ) ) {
			if ( XPos( "/I", MParm_Str, 1 )) {  // Initialize?
				vcsDoLogin = True;              // Enable change user ID menu item
				if ( g_SSafeUser == "" ) {
					if ( !( Return_Int = SSafeLogin( False ) ) ) {
						Error_Level = 9012;         // Set login error
					}
				}
			}
		}
		else {
			Error_Level = 9011;               // Set version error
		}
	}
	else {
		Error_Level = 9010;                 // Set no EXE found error
	}
	vcsVerStr = "SSAFE " + _SSAFE_VER;
	vcsRevStr = Rev_Id;

}  // SSafe

macro SSafeView Trans2 {
/******************************************************************************
															 Multi-Edit Macro
															 18-Aug-93  22:49

	Name    : SSafeView

	Function: The SourceSafe specific view macro to view the changes to the
						current work file compared to the latest revision in the archive.

	Syntax  : Rm( "SSafeView" );

	Entry   : gstr !vcsFName  - Filename of file to compare
						gint !vcsLibFnd - Set True if archive found.

	Exit    : Return_Int
							True          - No Error
							False         - ( Error_Level == 0 ) Cancelled
															( Error_Level != 0 ) Error

	Globals : str !vcsFName   - The work file name.
						int !vcsLibFnd  - The archive found status (True = found).
						str !vcsDlgMsg  - The dialog message when calling VcsGetLib.
						str !vcsMsg     - The status line message when exec is run.
						str !ssafeCfg   - The SSAFE specific command/setup options.
						str !vcsName    - The vcs temp file name.


	Macros  : int  SSafeGetLib
						int  SSafeExec
						mac  CDiff
						void VcsViewWinDlg

								Copyright (C) 1990-94 by Small Systems Support.
********************************************************************( ldh )***/

	str FName = Truncate_Path( vcsFName );
	str TFName = TempFileName( FName );

	int Frn = False;

	if ( !vcsLibFnd ) {
		vcsDlgMsg = "(SSAFE) VIEW Project.";
		if ( !vcsLibFnd = SSafeGetLib( vcsFName )) {
			vcsMsg = "SSAFE archive for \"" + FName + "\" not found.";
			Error_Level = 3002;
			Return_Int = False;
		}
	}
	if ( vcsLibFnd ) {
		Working;
    if ( Switch_File( vcsFName ) ) {
			if ( File_Changed ) {
				Rm( "SaveFile /NP=1" );
			}
		}
    if ( File_Exists( TFName ) ) {
      Set_File_Attr( _VCS3_TMP, 0 );
      Del_File( _VCS3_TMP );
      Rename_File( TFName, _VCS3_TMP );
      Frn = True;
    }
		vcsMsg = "Viewing changes made to \"" + FName + "\"...";
		vcsDlgMsg = "(SSAFE) VIEW Command Line.";
    if ( Return_Int = SSafeExec( _VIEW_CMDL, _DISP_WIN, _DO_CD ) ) {
      if ( Global_Int( "!UseCDiff" ) ) {
        Rm( "CDiff /F=" + TFName + "/D=" + Str( !_CDIF ) );
      }
      else {
        Rm( "Fc /F=" + TFName + "/S=" + Str( _CDIF * 6 ) );
      }
      if ( Return_Int == 1 ) {
        vcsMsg = "Files the same.";
      }
      else {
        vcsMsg = "CDIFF complete.";
      }
      Set_File_Attr( TFName, 0 );
//      Del_File( TFName );
      Return_Int = True;
    }
		if ( Frn ) {
			Rename_File( _VCS3_TMP, TFName );
		}
	}
}  // SSafeView

macro SSafeList Trans2 {
/******************************************************************************
															 Multi-Edit Macro
															 18-Aug-93  22:49

	Name    : SSafeList

	Function:

	Syntax  :

	Entry   :

	Exit    : Return_Int
							True          - No Error
							False         - ( Error_Level == 0 ) Cancelled
															( Error_Level != 0 ) Error

	Globals :

	Macros  :

								Copyright (C) 1990-94 by Small Systems Support.
********************************************************************( ldh )***/

	str FName = Truncate_Path( vcsFName );

	if ( !vcsLibFnd ) {
		vcsDlgMsg = "(SSAFE) LIST Project.";
		if ( !vcsLibFnd = SSafeGetLib( vcsFName )) {
			vcsMsg = "SSAFE archive for \"" + FName + "\" not found.";
			Error_Level = 3002;
			Return_Int = False;
		}
	}
	if ( vcsLibFnd ) {
		vcsMsg = "Listing versions of \"" + Truncate_Path( vcsFName ) + "\"...";
		vcsDlgMsg = "(SSAFE) LIST Command Line.";
		if ( Return_Int = SSafeExec( _LIST_CMDL, _DISP_WIN, False ) ) {  // No vcs errors
			if ( Switch_File( vcsName ) ) {
				Return_Int = False;
				Error_Level = 0;
				if ( vcsNameLoaded == False ) {
					Load_File( vcsName );
				}
				if ( !Error_Level ) {
					Right_Margin = 70;
					while ( Find_Text( "Comment: ", 0, 0 ) ) {
						Word_Wrap_Line( True, False );
					}
					if ( File_Changed == True ) {

						int TSave = Save_Resets_Changed;

						Save_Resets_Changed = True;
						Save_File;
						Save_Resets_Changed = TSave;
					}
					Tof;
					VcsViewWinDlg( "(SSAFE) Versions of " + Truncate_Path( vcsFName ),
							100, 18, "BT_VCS_109", hc_vcs_List );
					vcsMsg = "SSAFE LIST command complete.";
					Return_Int = True;
				}
			}
		}
	}
}  // SSafeList

macro SSafeLock Trans2 {
/******************************************************************************
															 Multi-Edit Macro
															 18-Aug-93  22:49

	Name    : SSafeLock

	Function:

	Syntax  :

	Entry   :

	Exit    : Return_Int
							True          - No Error
							False         - ( Error_Level == 0 ) Cancelled
															( Error_Level != 0 ) Error

	Globals :

	Macros  :

								Copyright (C) 1990-94 by Small Systems Support.
********************************************************************( ldh )***/

	str FName = Truncate_Path( vcsFName );

	int Frn = False;

	if ( !vcsLibFnd ) {
		vcsDlgMsg = "(SSAFE) LOCK Project.";
		if ( !vcsLibFnd = VcsGetLib( vcsFName ) ) {
			vcsMsg = "SSAFE archive for \"" + FName + "\" not found.";
			Error_Level = 3002;
			Return_Int = False;
		}
	}
	if ( vcsLibFnd ) {
		if ( Return_Int = !SSafeChkLock( ) ) {
			if ( File_Exists( vcsFName ) ) {
				Set_File_Attr( _VCS3_TMP, 0 );
				Del_File( _VCS3_TMP );
				Rename_File( vcsFName, _VCS3_TMP );
				Frn = True;
			}
			vcsMsg = "Locking \"" + vcsFName + "\"...";
			vcsDlgMsg = "(SSAFE) LOCK Command Line.";
			Return_Int = SSafeExec( _LOCK_CMDL, _DISP_WIN, _DO_CD );
			if ( Return_Int ) {
				vcsDlgMsg = "\x7F" + "F=" + FName + "\x7F" + "U=" + g_SSafeUser +
						"\x7F" + "D=" + Date + " ";
				Return_Str = Time;
				Return_Str = Copy( Return_Str, 1, Length( Return_Str ) - 5 ) +
						Lower( Copy( Return_Str, Length( Return_Str ) - 1, 1 ) );
				vcsDlgMsg += Return_Str + "\x7F" + "WD=" + Get_Path( vcsFName );
				SSafeUpdDirFile( vcsAFile, vcsDlgMsg );
			}
			if ( Frn ) {
				if ( Return_Int ) {
					Rename_File( _VCS3_TMP, vcsFName );
				}
				else {
					int Sel = Error_Level;

					Set_File_Attr( _VCS3_TMP, 0 );
					Del_File( _VCS3_TMP );
					Error_Level = Sel;
				}
			}
		}
	}
}  // SSafeLock

macro SSafeGet Trans2 {
/******************************************************************************
															 Multi-Edit Macro
															 18-Aug-93  22:49

	Name    : SSafeGet

	Function:

	Syntax  :

	Entry   :

	Exit    : Return_Int
							True          - No Error
							False         - ( Error_Level == 0 ) Cancelled
															( Error_Level != 0 ) Error

	Globals :

	Macros  :

								Copyright (C) 1990-94 by Small Systems Support.
********************************************************************( ldh )***/

	str Vcs_Cmd[ 128 ];
	str FName = Truncate_Path( vcsFName );
	str Cmd[ 20 ] = Parse_Str( "/C=", MParm_Str );

	int Fw = 0;
	int Frn = False;
	int Sel;

	if ( !vcsLibFnd ) {
		vcsDlgMsg = "(SSAFE) " + Cmd + " Project.";
		if ( !vcsLibFnd = SSafeGetLib( vcsFName ) ) {
			vcsMsg = "SSAFE archive for \"" + FName + "\" not found.";
			Error_Level = 3002;
			Return_Int = False;
		}
	}
	if ( vcsLibFnd ) {
		Return_Int = True;
		if ( Cmd == "GET" ) {
			Return_Int = !SSafeChkLock( );
			Vcs_Cmd = _GET_CMDL;
		}
		else {
			Vcs_Cmd = _BROWSE_CMDL;
		}
		if ( Return_Int ) {
			if ( Caps( File_Name ) == Caps( vcsFName ) ) {
				Frn = True;
			}
			else if ( Switch_File( vcsFName ) ) {
				Frn = True;
			}
			if ( Frn ) {
				if ( !Read_Only || vcsDF || ( Truncate_Path( File_Name ) != FName ) ) {
					Rm( "Verify /H=" + hc_vcs_Verify + "/T=" + vcsFName +
							" Already loaded, OVERWRITE? /BL= ARE YOU SURE? " );
				}
				if ( Return_Int ) {
					Fw = Window_Id;
					VcsPushPos( );
					Erase_Window;
				}
			}
			else if ( File_Exists( vcsFName ) ) {
				Rm( "Verify /H=" + hc_vcs_Verify + "/T=" + vcsFName +
						" Already exists, OVERWRITE? /BL= ARE YOU SURE? " );
			}
		}
		if ( Return_Int ) {
			Frn = False;
			if ( File_Exists( vcsFName ) ) {
				Set_File_Attr( _VCS3_TMP, 0 );
				Del_File( _VCS3_TMP );
				Rename_File( vcsFName, _VCS3_TMP );
				Frn = True;
			}
			vcsMsg = "Retrieving \"" + vcsFName + "\"...";
			vcsDlgMsg = "(SSAFE) " + Cmd + " Command Line.";
			if ( Return_Int = SSafeExec( Vcs_Cmd, _DISP_WIN, _DO_CD ) ) {
				if ( Frn ) {
					Sel = Error_Level;
					Set_File_Attr( _VCS3_TMP, 0 );
					Del_File( _VCS3_TMP );
					Error_Level = Sel;
				}
				if ( Cmd == "GET" ) {
					vcsDlgMsg = "\x7F" + "F=" + FName + "\x7F" + "U=" + g_SSafeUser +
							"\x7F" + "D=" + Date + " ";
					Return_Str = Time;
					Return_Str = Copy( Return_Str, 1, Length( Return_Str ) - 5 ) +
							Lower( Copy( Return_Str, Length( Return_Str ) - 1, 1 ) );
					vcsDlgMsg += Return_Str + "\x7F" + "WD=" + Get_Path( vcsFName );
					SSafeUpdDirFile( vcsAFile, vcsDlgMsg );
				}
			}
			else {                            // error, restore file
				if ( Frn ) {
					Rename_File( _VCS3_TMP, vcsFName );
				}
				if ( Switch_Win_Id( Fw ) ) {
					Sel = Error_Level;
					Error_Level = 0;
					Load_File( vcsFName );
					if ( !Error_Level ) {
						Rm( "ExtSetup" );
					}
					VcsPopPos( True );
					Error_Level = Sel;
					Return_Int = False;
				}
			}
		}
	}
}  // SSafeGet

macro SSafePut Trans2 {
/******************************************************************************
															 Multi-Edit Macro
															 18-Aug-93  22:49

	Name    : SSafePut

	Function: The SourceSafe specific CREATE/PUT/UNLOCK commands.

	Syntax  :

	Entry   :

	Exit    : Return_Int
							True          - No Error
							False         - ( Error_Level == 0 ) Cancelled
															( Error_Level != 0 ) Error
	Globals :

	Macros  :

								Copyright (C) 1990-94 by Small Systems Support.
********************************************************************( ldh )***/

	str Vcs_Cmd[ 128 ];
	str Cmd[ 20 ] = Parse_Str( "/C=", MParm_Str );
	str FName[ 12 ] = Truncate_Path( vcsFName );
	str SavPrj;

	int Sel;
	int Sri;
	int Fw = 0;
	int Ow = 0;
	int Get_Cmt = False;
	int Chg_Prj = False;

	Return_Int = True;
	if ( vcsChkMod != "V" ) {
		Return_Int = !SSafeChkLock( );
	}
	if ( Return_Int ) {
		if ( Caps( File_Name ) == Caps( vcsFName ) ) {
			Fw = Window_Id;
		}
		else if ( Switch_File( vcsFName ) ) {
			Fw = Window_Id;
		}
		if ( Fw ) {
			VcsPushPos( );
		}
		if ( vcsChkMod == "V" ) {
			if ( Window_Id == Fw ) {
				Erase_Window;
			}
			if ( File_Exists( vcsFName ) ) {
				Set_File_Attr( vcsFName, 0 );
				Del_File( vcsFName );
			}
		}
		else {
			if ( !vcsLibFnd ) {
				vcsDlgMsg = "(SSAFE) " + Cmd + " Project.";
				vcsLibFnd = SSafeGetLib( vcsFName );
				Return_Int = !Error_Level;
				Error_Level = 0;
			}
			if ( Return_Int ) {
				if ( Cmd == "PUT" ) {
					Get_Cmt = True;
					if ( !vcsLibFnd ) {
						Cmd = "CREATE";
					}
					if ( !Fw ) {
						Ow = Window_Id;
						Switch_Window( Window_Count );
						Create_Window;
						Load_File( vcsFName );
						Fw = Window_Id;
					}
				}
				Return_Int = True;
				switch ( Cmd ) {
					case "CREATE":
						if ( vcsAFile != g_SSafePrj ) {
							SavPrj = g_SSafePrj;
							vcsMsg = "Changing to SSAFE project " + vcsAFile + "...";
							if ( Return_Int = SSafeCmds( "CP", "", vcsAFile ) ) {
								Chg_Prj = True;
							}
						}
						Vcs_Cmd = _CREATE_CMDL;
						vcsMsg = "Creating \"" + Get_Path( vcsAFile ) + FName + "\" ...";
						vcsDlgMsg = "(SSAFE) Describe \"" + FName + "\".";
						break;

					case "PUT":
						Vcs_Cmd = _PUT_CMDL;
						vcsMsg = "Storing \"" + FName + "\" in \"" + Get_Path( vcsAFile ) +
								FName + "\"...";
						vcsDlgMsg = "(SSAFE) Describe changes to \"" + FName + "\".";
						break;

					case "UNLOCK":
						Vcs_Cmd = _UNLOCK_CMDL;
						vcsMsg = "Unlocking \"" + Get_Path( vcsAFile ) + FName + "\"...";
						break;
				}
				if ( Return_Int  ) {
					if ( Get_Cmt ) {
						Return_Int = VcsGetCmt( True, False );
					}
				}
				if ( Return_Int ) {
					if ( Fw ) {
						Erase_Window;
					}
					vcsDlgMsg = "(SSAFE) " + Cmd + " Command Line.";
					if ( Return_Int = SSafeExec( Vcs_Cmd, _DISP_WIN, _DO_CD ) ) {
						if ( File_Exists( vcsFName ) ) {
							if ( _DEL_SRC ) {
								Sel = Error_Level;
								Set_File_Attr( vcsFName, 0 );
								Del_File( vcsFName );
								Error_Level = Sel;
							}
							else if ( Cmd == "UNLOCK" ) {
								Set_File_Attr( vcsFName, 0x01 );  // force file readonly
							}
						}
						if ( Ow ) {
							Delete_Window;
							Switch_Win_Id( Ow );
						}
						vcsDlgMsg = "\x7F" + "F=" + FName;
						SSafeUpdDirFile( vcsAFile, vcsDlgMsg );
					}
					else {                        // error, reload file
						if ( Switch_Win_Id( Fw ) ) {
							Sel = Error_Level;
							Error_Level = 0;
							Load_File( vcsFName );
							if ( Error_Level == 0 ) {
								if ( Get_Cmt && vcsChgFlg ) {
									VcsPutCmt( False );
								}
								Rm( "ExtSetup" );
							}
							Get_Cmt = True;
							if ( Ow ) {
								Delete_Window;
								Switch_Win_Id( Ow );
								Get_Cmt = False;
							}
							VcsPopPos( Get_Cmt );
							Error_Level = Sel;
							Return_Int = False;
						}
					}
				}
				if ( Chg_Prj ) {
					Sel = Error_Level;
					Sri = Return_Int;
					vcsMsg = "Changing to SSAFE project " + SavPrj + "...";
					SSafeCmds( "CP", "", SavPrj );
					Return_Int = Sri;
					Error_Level = Sel;
				}
			}
		}
	}
}  // SSafePut

int SSafeExec( str CmdLine, int Show_Win, int Chg_Dir ) Trans2 {
/******************************************************************************
															 Multi-Edit Macro
															 15-Sep-94  21:42

	Name    : SSafeExec

	Function: Execute the SSAFE command in cmdline.

	Syntax  : pass = SSafeExec( CmdLine, Show_Win, Chg_Dir );

	Entry   : str CmdLine
						int Show_Win
						int Chg_Dir
						gstr !vcsFName
						gstr !vcsAFile
						gint !vcsSNCL

	Exit    : int
							True            - No Error.
							False           - ( Error_Level == 0 ) Cancelled
																( Error_Level = Error number ) Error
								gstr !vcsMsg  - Error message  ( Only when Error_Level != 0 )

						gstr !vcsDlgMsg   - Cleared.

	Globals : str !vcsFName   - Contains the work file name.
						str !vcsAFile   - Contains the archive file name.
						int !vcsSNCL    - Flag to not show cmdline dialog ( True ).
						str !vcsCfg     - Contains the main vcs config options.
						str !vcsMsg     - Contains the status line message.
						str !vcsName    - Contains the vcs temp file name.
						str !vcsDlgMsg  - Contains the show cmdline dialog message.

	Macros  : str SSafeXlate
						int VcsEditStrDlg
						int ExecProg

								Copyright (C) 1990-94 by Small Systems Support.
********************************************************************( ldh )***/

	int Result = True;
	int Ow = Window_Id;
	int Srf = Refresh;
	int Flags = _ep_flags_NoBypass | _ep_flags_NoSavFile;

  str Cmd = Get_Path( Copy( CmdLine, 1, XPos( " ", CmdLine, 1 ) - 1 ) );
  str BDir = _BDIR_CMDL;

	Refresh = False;
  if ( Svl( Cmd ) == 0 ) {
    if ( Svl( BDir ) ) {
      CmdLine = AddTrailingSlash( BDir ) + CmdLine;
    }
  }
  CmdLine = SSafeXlate( CmdLine, vcsFName, vcsAFile );
	Error_Level = 0;
	if ( vcsSNCL ) {
		if ( Check_Key && ( ( Key1 == 27 ) && ( Key2 == 1 ) ) ) {
			Result = False;
		}
	}
	else if ( _SHOW_CMD ) {
		Result = VcsEditStrDlg( vcsDlgMsg, CmdLine, False );
	}
	if ( Result ) {
		Set_File_Attr( vcsName, 0 );
		Del_File( vcsName );                // Erase tmp capture file
		Result = False;
		Working;
		Make_Message( vcsMsg );
		vcsMsg = "";
    if ( XPos( "SSWCL.EXE", CmdLine, 1 ) || Xpos( "SS.EXE", CmdLine, 1 ) ) {
      if ( g_SSafeUser != g_SSafeUsr1 ) {
        CmdLine += " -Y" + g_SSafeUser + SIf( g_SSafePwd != "", "," +
						g_SSafePwd, "" );
      }
    }
// DBWin( "SSafeExec Before ExecProg Ow=%d Cw=%d", Ow, Window_Id );
		Error_Level = ExecProg( CmdLine, vcsPrjDir, vcsName, vcsName, Flags );
//				_EP_Flags_Minimized | _EP_FLAGS_NOBYPASS );
//     if ( Window_Id != Ow ) {            // DBug
//       Beep;
//       DBug( "SSafeExec Error! Ow=%d Cw=%d", Ow, Window_Id );  // DBug
//     }                                   // DBug
// DBWin( "SSafeExec After ExecProg Ow=%d Cw=%d", Ow, Window_Id );
		switch ( Error_Level ) {

			case _Exec_Abort :
				Error_Level = 0;
				break;

			case _Exec_Error :
				Error_Level = ExecErrorCode;
				break;

			case _Exec_Success :
				Error_Level = 0;
				switch ( ExecId ) {

					case _Exe_Id_Windows :
						SSafeParseErr( );

					case _Exe_Id_Dos :
					case _Exe_Id_Os2 :
					case _Exe_Id_Nt :
						Error_Level = ExecReturnCode;
						if ( Error_Level == 0 ) {
							Result = True;
							break;
						}

					default :
						Error_Level += 9000;
				}
		}
	}
	vcsDlgMsg = "";
	Switch_Win_Id( Ow );
	Refresh = Srf;
	return ( Result );

}  // SSafeExec

str SSafeXlate(
			str CmdLine	= Return_Str,
			str FName 	= Parse_Str( "/F=", MParm_Str ),
			str Project = Parse_Str( "/P=", MParm_Str )
) trans2
/******************************************************************************
															 Multi-Edit Macro
															 12-Aug-94  23:34

	Name    : SSafeXlate

	Function: Place holder for adding code to implement any SourceSafe specific
						tranlation metacommands. Call VcsXlate to finish the translations.

	Syntax  : Path = SSafeXlate( Path, FName, Project );

	Entry   : str CmdLine         - The string to be translated.
						str FName           - The work file name.
						str Project         - The SourceSafe project.

	Exit    : str ( Return_Str )  - The expanded command line.

	Globals : none

	Macros  : str VcsXlate

								Copyright (C) 1990-94 by Small Systems Support.
********************************************************************( ldh )***/
{
	if ( XPos( "<LPATH", CmdLine, 1 ) ) {

		int Jx;
		int Jy;

		str Alias;
    str TStr[ MAX_LINE_LENGTH ];

		if ( Project == "" ) {
			Project = FName;
		}
    Jx = 1;
    while ( Jx = XPos( "<", Cmdline, Jx ) ) {
      if ( ( Jy = XPos( ">", Cmdline, Jx ) ) == 0 ) {
        break;
      }
      Jy = Jy - Jx - 1;
      Alias = Copy( CmdLine, Jx + 1, Jy );
      switch ( Caps( Alias ) ) {
				case "LPATH" :
					TStr = Get_Path( Project );
					break;

				case "LPATHX" :
					TStr = AddTrailingSlash( Get_Path( Project ) );
					break;

        default:
          Jx += Jy + 2;
          Jy = 0;
      }
      if ( Jy ) {
        Cmdline = Str_Del( Cmdline, Jx, Jy + 2 );
        if ( Svl( TStr ) ) {
          Cmdline = Str_Ins( TStr, Cmdline, Jx );
        }
      }
		}
	}
	return ( VcsXlate( CmdLine, FName, Project ) );

}  // SSafeXlate

str SSafeExt( str FName = Parse_Str( "/F=", MParm_Str ) ) Trans2 {
/******************************************************************************
															 Multi-Edit Macro
															 15-Aug-94  23:05

	Name    : SSafeExt

	Function: Takes a filename extension and converts it to the equivalent
						SourceSafe LIBEXT extension.

	Syntax  : RcsExt( str FName );

	Entry   : str FName     - Filename for which the extension is translated.

	Exit    : str           - The vcs file extension based upon LIBEXT.

	Globals : none.

	Macros  : none.

								Copyright (C) 1990-94 by Small Systems Support.
********************************************************************( ldh )***/

	return ( Get_Extension( FName ) );

}  // SSafeExt

int SSafeChkLib(
				str Project = Parse_Str( "/P=", MParm_Str ),
				str FName = Parse_Str( "/F=", MParm_Str ),
				int Pm = Parse_Int( "/M=", MParm_Str )
		) Trans2 {
/******************************************************************************
															 Multi-Edit Macro
															 12-Aug-94  23:31

	Name    : SSafeChkLib

	Function: Search "Project" for the SourceSafe archive for "FName" based upon
						"Pm".

	Syntax  : LibFnd = SSafeChkLib( Project, FName, Pm );

	Entry   : gstr !vcsID   - The name of the currently selected vcs package.
						str  Project  - Contains the search path.
						str  FName    - The filename for which to find archive.
						int  Pm       - Path Mode.
							-2          - Check for and return archive file only.
							-1          - Check for and return archive file,
														iff no file return 1st lib path.
							 0          - Return full archive path.
							+#          - Return # directory from archive path.

	Exit    : int ( gint !vcsRInt )
							#                 - File was found in # path.
								gstr !vcsAFile  - The found archive filename or path.
							0                 - File NOT found.
								gstr !vcsAFile  - The archive path based upon pm.
																	( Not set if Pm == -2 ).

	Globals : str !vcsID    - The name of the currently selected vcs package.
						int !vcsRInt  - The return integer.
						str !vcsAFile - The found archive filename or path.

	Macros  : int SSafeXlate
						int SSafeCmds

								Copyright (C) 1993-94 by Small Systems Support.
********************************************************************( ldh )***/

	str FPath[ 128 ] = "";
	str LPath[ 128 ];
	str TFName = Truncate_Path( FName );

	int Jx;
	int Jy = 0;
	int Cnt = 0;

	vcsRInt = False;
	g_SSafeFUsr = "";
	if ( ( Project == _LIB_PATH ) && ( _DO_CD == 2 ) ) {
		Project = "<LOOKUP>";
	}
	if ( ( Project = SSafeXlate( Project, FName, "" ) ) != "" ) {
		if ( Pm ) {
			while ( True ) {
				if ( Jy > Svl( Project ) ) {
					if ( Pm != -2 ) {
						vcsAFile = LPath;
					}
					break;
				}
				Jx = XPos( ";", Project, Jy + 1 );
				if ( Jx == 0 ) {
					Jx = Svl( Project ) + 1;
				}
				FPath = Copy( Project, Jy + 1, Jx - Jy - 1 );
				if ( ( Svl( Project ) > 0 ) &&
						( Copy( FPath, Svl( FPath ), 1 ) != "\\" ) ) {
					FPath += "\\";
				}
				Jy = Jx;
				if ( Pm == ++Cnt ) {
					vcsAFile = FPath;
					vcsRInt = Cnt;
					break;
				}
				if ( Pm < 0 ) {
					vcsMsg = "Checking for \"" + TFName + "\" in \"" +
							FPath + "\"...";
					vcsRInt = SSafeCmds( "DIR", FName, FPath );
					Set_File_Attr( vcsName, 0 );
					Del_File( vcsName );
					Error_Level = 0;
					if ( vcsRInt ) {
						vcsAFile = FPath + TFName;
						vcsRInt = Cnt;
						break;
					}
				}
				if ( Cnt == 1 ) {
					LPath = FPath;
				}
			}
		}
		else {
			vcsAFile = Project;
		}
	}
	return ( vcsRInt );

}  // SSafeChkLib

str SSafeGetFName( str LibFile = Parse_Str( "/P=", MParm_Str ) ) Trans2 {
/******************************************************************************
															 Multi-Edit Macro
															 18-Aug-93  22:49

	Name    : SSafeGetFName

	Function: Returns the work file name extracted from the archive "LibFile" or
						"" when archive doesn't exist.

	Syntax  : FName = SSafeGetFName( LibFile );

	Entry   : str LibFile           - archive file name

	Exit    : str ( gstr !vcsRStr ) - The workfile_name or "".

	Globals : str !vcsRStr          - The return string.

	Macros  : none

								Copyright (C) 1993-94 by Small Systems Support.
********************************************************************( ldh )***/

	vcsRStr = LibFile;
	return ( vcsRStr );

}  // SSafeGetFName

int SSafeChkLock( ) Trans2 {
/******************************************************************************
															 Multi-Edit Macro
															 30-Mar-94  01:39

	Name    : SSafeChkLock

	Function: Check to see if a SourceSafe archive file is locked.

	Syntax  : Locked = SSafeChkLock( );

	Entry   : gint !vcsAFile  - The project filename.

	Exit    : int
							True      - Archive file locked.
							False     - Archive file not locked.

	Globals : str !vcsAFile - The project name
						str !ssafeFUsr   - The username who has the file checked out.
						str ~ssafeUser   - The current username.

	Macros  : mac MessageBox

								Copyright (C) 1993-94 by Small Systems Support.
**********************************************************************(ldh)***/

	int Result = False;

	str User = g_SSafeFUsr;

	g_SSafeFUsr = "";
	if ( ( User != "" ) && ( Caps( User ) != Caps( g_SSafeUser ) ) ) {
		Rm( "MessageBox /B=1/T=SSAFE Error/M=" + vcsAFile + " is locked by \"" +
				User + "\"" );
		Result = True;
	}
	return ( Result );

}  // SSafeChkLock

macro SSafeDir Trans2 {
/******************************************************************************
															 Multi-Edit Macro
															 20-Sep-94  16:29

	Name    : SSafeDir

	Function: Displays directory listing of SourseSafe project files.  Allows
						user to select a file to be retrieved for modification, viewing
						only, or listing the version history.

	Syntax  : Rm( "SSafeDir"  );

	Entry   : None.

	Exit    : None.

	Globals : None.

	Macros  : void SSafeFileDlg;

								Copyright (C) 1993-94 by Small Systems Support.
********************************************************************( ldh )***/

	SSafeFileDlg( "(SSAFE) Archive Files", g_SSafePrj );

}  // SSafeDir

macro SSafeIActive Trans {
/******************************************************************************
															 Multi-Edit Macro
															 15-Aug-94  23:05

	Name    : SSafeIActive

	Function: Runs the "menu command line" that is contained in "!ssafeCfg" global
						variable.

	Syntax  : Rm( "SSafeIActive" );

	Entry   : none.

	Exit    : none.

	Globals : str !ssafeCfg - Contains the commands/setup options for SourceSafe.

	Macros  : int WinExecAndWait

								Copyright (C) 1993-94 by Small Systems Support.
********************************************************************( ldh )***/

	str CmdLine = _MENU_CMDL;
  str Cmd = Get_Path( Copy( CmdLine, 1, XPos( " ", CmdLine, 1 ) - 1 ) );
  str BDir = _BDIR_CMDL;

  if ( Svl( Cmd ) == 0 ) {
    if ( Svl( BDir ) ) {
      if ( Copy( BDir, Svl( BDir ), 1 ) != "\\" ) {
        BDir += "\\";
      }
      CmdLine = BDir + CmdLine;
    }
  }
	if ( _SHOW_CMD ) {
		vcsDlgMsg = "(SSAFE) Run Interactive Command Line";
		Return_Int = VcsEditStrDlg( vcsDlgMsg, CmdLine, False );
	}
	if ( Return_Int ) {
//		WinExecAndWait( CmdLine, "", _EP_Flags_DontWait, "", "" );
		ExecProg( CmdLine, "", "", "", _EP_Flags_DontWait | _EP_Flags_SkipExec );
	}
}  // SSafeIActive

int SSafeLogin( int Chg_Usr = XPos( "/CU", MParm_Str, 1 ) ) Trans {
/******************************************************************************
															 Multi-Edit Macro
															 26-Mar-94  15:49

	Name    : SSafeLogin

	Function: Check if a SourceSafe user is logged in, and prompts if not.

	Syntax  : Logged = SSafeLogin( Chg_Usr );

	Entry   : int Chg_Usr   - Force a prompt for a new user.

	Exit    : int
							True        - User logged in.
							False       - Error checking user logged in.
						gstr ~ssafeUser  - Set to SourceSafe user name.

	Globals : str ~ssafePrj
						str ~ssafeINI
						str ~ssafeUser

	Macros  : mac MessageBox
						int SSafeCmds
						mac Data_In
						mac Verify

								Copyright (C) 1992-94 by Small Systems Support.
********************************************************************( ldh )***/

	int Ow = Window_Id;
	int Srf = Refresh;
	int Jx;
	int Result;
	int Pass2 = False;

	str User;
	str Pwd;

	Result = !Chg_Usr;                // Change User
	Refresh = False;
	if ( Result ) {
		Make_Message( "Checking SourceSafe Login Status..." );
		g_SSafeUser = "";
		Result = SSafeCmds( "LOGIN", "", "" );
	}
	if ( Result == False ) {
		Pass2 = True;
		while ( True ) {
			if ( ( User = g_SSafeUser ) == "" ) {
				User = SSafeGetUser( );
			}
			Result = VcsLoginDlg( "SourceSafe Login", User, Pwd );
			if ( Result ) {
				g_SSafeUser = User;
				g_SSafePwd =  Pwd;
				Make_Message( "Logging into SourceSafe..." );
				Result = SSafeCmds( "LOGIN", "", "" );
				if ( Result ) {
					if ( Caps( User ) == Caps( g_SSafeUsr1 ) ) {
						g_SSafePwd = "";
					}
					vcsDoLogin = True;          // Enable change user ID menu item
					break;
				}
				Rm( "Verify /T=Invalid User or Password./BL=Try Again? /H=" +
						hc_vcs_Verify );
				Result = Return_Int;
				if ( Result == False ) {
					Rm( "MessageBox /T=SourceSafe Login Error/M=\"SSINIT\" not found," +
							" SSAFE Support not Loaded" );
					vcsId = "";
					vcsDoLogin = False;             // Disable change user ID menu item
					break;
				}
			}
			else {
				break;
			}
		}
	}
	if ( Result == True ) {
		Switch_Window( Window_Count );
		Create_Window;
		Error_Level = 0;
		Load_File( vcsName );
		if ( !Error_Level ) {
			if ( Find_Text( "User: ", 0, 0 ) ) {
				g_SSafeUser = Shorten_Str( Parse_Str( "User: ", Get_Line( ) ) );
				if ( ( Pass2 == False ) && ( g_SSafeUsr1 == '' ) ) {
					g_SSafeUsr1 = g_SSafeUser;
				}
			}
			if ( Find_Text( "Project: ", 0, 0 ) ) {
				g_SSafePrj = Caps( Shorten_Str( Parse_Str( "Project: ", Get_Line( ) ) ) );
				Jx = 1;
				while ( Jx = XPos( "/", g_SSafePrj, Jx ) ) {
					g_SSafePrj = Str_Del( g_SSafePrj, Jx, 1 );
					g_SSafePrj = Str_Ins( "\\", g_SSafePrj, Jx );
				}
				if ( Length( g_SSafePrj ) != 2 ) {
					g_SSafePrj += "\\";
				}
			}
			if ( Find_Text( "Ini file: ", 0, 0 ) ) {
				g_SSafeIni = Shorten_Str( Copy( Get_Line, Length( Found_Str ) + 1, 255 ) );
			}
		}
		Delete_Window;
	}

Exit:
	Error_Level = 0;
//   Set_File_Attr( vcsName, 0 );
//   Del_File( vcsName );
	Switch_Win_Id( Ow );
	Refresh = Srf;
	return ( Result );

}  // SSafeLogin

macro SSafeAdminPrj Trans {
/******************************************************************************
															 Multi-Edit Macro
															 15-Aug-94  23:05

	Name    : SSafeAdminPrj

	Function: Create, edit and delete entries in the user's administer project
						database for SourceSafe.

	Syntax  : Rm( "SSafeAdminPrj" );

	Entry   : none.

	Exit    : none.

	Globals : str !ssafeLUT - The contents of the current db record.

	Macros  : mac SSafeChkAdmin

								 Copyright (C) 1994 by Small Systems Support.
********************************************************************( ldh )***/

	g_SSafeLUT = "";                         // clear global lookup variable
	Db( _VCS_DB, "SSAFE.VAD", "MEWHDRS.DB", "VCSVAD.HDR",
			"(SSAFE) Associate Directories",
			"(SSAFE) Associate Directories Setup",
			"!VAD", 0,
			"/BMP=BT_VCS_102/NDF=1/PRE=!VAD/H=" + hc_vcs_Admin +
					"/DIRB=1/CP=New File Directory:/MOVE=1/MACRO=SSafeChkAdmin" );

}  // SSafeAdminPrj

str SSafeLookup(
				str FName = Parse_str( "/F=", MParm_Str ),
				str Field1 = Parse_Str( "/F1=", MParm_Str ),
				str Field2 = Parse_Str( "/F2=", MParm_Str )
		) Trans2 {
/******************************************************************************
															 Multi-Edit Macro
															 15-Aug-94  23:05

	Name    : SSafeLookup

	Function: Returns the string in "Field2" of the SSAFE administer project
						database when the directory of "FName" matches a string in
						"Field1".

	Syntax  : Str_Val = SSafeLookup( FName, Field1, Field2 );

	Entry   : str FName  - The filename to extract the directory name from.
						str Field1 - The field name of the field to match the directory to.
						str Field2 - The field name fo the field to return the string from.

	Exit    : str ( gstr !vcsRStr )
							""          - Empty string if no match or Field2 empty.
							[Field2]    - Contents of Field2 when match found.

						gstr !ssafeLUT  - Contains the found record.

	Globals : str !vcsRStr  - The return string.
						str !ssafeLUT   - The contents of the matched db record.

	Macros  : int DbGetRecord

								 Copyright (C) 1994 by Small Systems Support.
********************************************************************( ldh )***/

	int Result = True;

	vcsRStr = "";
	FName = Caps( Get_Path( FName ) );
	if ( FName != Parse_Str( "\x7F" + Field1 + "=", g_SSafeLUT ) ) {

		int Cnt = 0;
		int OrgWin = Window_Id;
		int TRefresh = Refresh;
		int Flags = _dbf_NoDelWin | _dbf_NoSwitchWin;

		str ADField = "\x7F" + "AD=";
		str DbName = _VCS_DB;
		str TStr;
		str SFName = FName;

		Result = False;
		Refresh = False;
		g_SSafeLUT = "";
		while ( DbGetRecord( DbName, "SSAFE.VAD", Field1, FName, Cnt, Flags, "" ) ==
				_NoError ) {
			if ( g_SSafeLUT != "" ) {
				TStr =  Parse_Str( ADField, g_SSafeLUT ) + ";" +
						Parse_Str( ADField, FName );
				Return_Str = ADField;
				Rm( "ChngParm /G=!ssafeLUT/P=" + TStr );
			}
			else {
				g_SSafeLUT = FName;
				if ( Field1 == "AD" ) {
					break;
				}
			}
			Flags =  _dbf_NoDelWin | _dbf_NoSwitchWin | _sf_Position;
			FName = SFName;
			DbName = "";
			Result = True;
		}
		Switch_Win_Id( OrgWin );
		Refresh = TRefresh;
	}
	if ( Result ) {
		vcsRStr = Parse_Str( "\x7F" + Field2 + "=", g_SSafeLUT );
		if ( Field1 == "AD" ) {
			g_SSafeLUT = "";
		}
	}
	return ( vcsRStr );

}  // SSafeLookup

str SSafeCfgFile(
				str FName = Parse_Str( "/F=", MParm_Str ),
				str Param = Parse_Str( "/P=", MParm_Str )
		) Trans2 {
/******************************************************************************
															 Multi-Edit Macro
															 20-Dec-94  00:50

	Name    : SSafeCfgFile

	Function: Parse and return the value for Param.
						(Note: SourceSafe uses the <LOOKUP> method for this function)

	Syntax  : Str_Val = SSafeCfgFile( FName, Param );

	Entry   : str FName   - The filename to extract the directory name from
						str Param   - The parameter to parse for the return string

	Exit    : str ( gstr !vcsRStr )
							""          - Empty string if no match
							[Param]     - Contents of Param from config file when match found

	Globals : str !vcsRStr  - The return string
						str !ssafeCfg
						str ~ssafeUser

	Macros  : str SSafeLookUp

								 Copyright (C) 1994 by Small Systems Support.
********************************************************************( ldh )***/

	vcsRStr = "";
	switch ( Param ) {
		case "ARCDIR" :
			vcsRStr = SSafeLookup( FName, "FD", "AD" );
			break;

		case "ARCEXT" :
			vcsRStr = _LIB_EXT;
			break;

		case "USER" :
			vcsRStr = g_SSafeUser;
			break;

		case "WORKDIR" :
			vcsRStr = SSafeLookup( FName, "FD", "WD" );
			break;
	}
	return ( vcsRStr );

}  // SSafeCfgFile

macro SSafeChkAdmin Trans {
/******************************************************************************
															 Multi-Edit Macro
															 15-Aug-94  23:05

	Name    : SSafeChkAdmin

	Function: Called by the AdminPrj dialog to capitialize, check and update all
						directories to end with a \ when saving the data in the dialog.

	Syntax  : Called only by the DB macro when in the AdminPrj dialog.

	Entry   : Values passed by the DB macro.

	Exit    : updated data.

	Globals : none.

	Macros  : none.

								 Copyright (C) 1994 by Small Systems Support.
********************************************************************( ldh )***/

	if ( Parse_Int( "/P=", MParm_Str ) != 0 ) {

		str GStr = Parse_Str( "/GLO=", MParm_Str );
		str TStr = Translate( Caps( Global_Str( GStr ) ), "\\", "/" );

		int Len = Svl( TStr );
		int Jx = 1;

		while ( Jx < Len ) {
			if ( ( Jx = XPos( "\x7F", TStr, ++Jx ) ) == 0 ) {
				Jx = Len + 1;
			}
			if ( Pos( Copy( TStr, Jx - 2, 1 ), "=" ) == 0 ) {
				if ( Pos( Copy( TStr, Jx - 1, 1 ), ";>\\" ) == 0 ) {
					TStr = Str_Ins( "\\", TStr, Jx );
					Len = Svl( TStr );
				}
			}
		}
		Jx = 1;
		while ( Jx = XPos( ";", TStr, Jx ) ) {
			if ( Copy( TStr, Jx - 1, 1 ) != "\\" ) {
				TStr = Str_Ins( "\\", TStr, Jx );
			}
			++Jx;
		}
		Set_Global_Str( GStr, TStr );
	}
}  // SSafeChkAdmin

int SSafeCmds( str Cmd, str FName, str Project ) Trans2 {
/******************************************************************************
															 Multi-Edit Macro
															 26-Mar-94  16:08

	Name    : SSafeCmds
	Function: The SourceSafe command interface.
	Syntax  : Rm( "SSafeCmds /C=str/F=str" );
	Entry   : /F=str      The filename
												CP
						/C=str      DIR
												LOGIN
						Return_Str  Contains the project name.
	Exit    : Return_Int
							False - File not Found.
							True  - File Found.
						Return_Str  The found project\file name or User.

								Copyright (C) 1992-94 by Small Systems Support.
********************************************************************( ldh )***/

	int Result;
	int SavSNCL = vcsSNCL;

	vcsSNCL = True;
//   vcsSNCL = False;
	switch ( Cmd ) {

		case "LOGIN" :
//			Result = SSafeExec( "SSWLOGIN.EXE -E -O@" + vcsName + " " + g_SSafeUser +
			Result = SSafeExec( g_SSafeLogCmd + " -E -O@" + vcsName + " " +
					g_SSafeUser + " " + g_SSafePwd, 0, False);
			break;

		case "DIR" :
			if ( SSafeGetDirFile( False, True ) ) {
				vcsAFile = Project;
				vcsFName = FName;
				Result = SSafeUpdDirFile( vcsAFile + Truncate_Path( FName ), "" );
				if ( Result == False ) {
					FName = "";
				}
				vcsAFile = Project + Truncate_Path( FName );
				break;
			}

		case "SDIR" :
			if ( g_SSafeRDir == True ) {
				Project = "$\\";
			}
			vcsAFile = Project;
			vcsFName = FName;
			if ( !( Result = SSafeExec(
//					"SSWCL.EXE DIR -EXITCODE -I- -E -O&@" + vcsName +
					g_SSafeCmdLn + " DIR -EXITCODE -I- -E -O&@" + vcsName +
					SIf( g_SSafeRDir, " -R", "" ) + " \"<LPATH><NAME>.<EXT>\"", 0, False ) ) ) {
				FName = "";
			}
			vcsAFile = Project + Truncate_Path( FName );
			break;

		case "CP" :
			Result = False;
			if ( Project != "" ) {
				if ( ( Result = SSafeGetPrj( Project, True ) ) == True ) {
					g_SSafePrj = Project;
				}
				else {
					vcsAFile = Project;
//					Result = SSafeExec( "SSWCL.EXE CP -EXITCODE -I- -O&@" + vcsName +
					Result = SSafeExec( g_SSafeCmdLn + " CP -EXITCODE -I- -O&@" +
							vcsName + " \"<LPATHX>\" ", 0, False );
					if ( Result == True ) {
						if ( SSafeGetPrj( Project, False ) == True ) {
							g_SSafePrj = Project;
						}
					}
				}
			}
			break;
	}
	vcsSNCL = SavSNCL;
	return ( Result );

}  // SSafeCmds

int SSafeGetPrj( str &Project, int Change ) {
/******************************************************************************
															 Multi-Edit Macro
															 26-Mar-94  16:02

	Name    : SSafeGetPrj

	Function: Reads the user's SS.INI file for the current project.

	Syntax  : SSafeGetPrj( );

	Entry   : gstr ~ssafeINI - contains the path\file name of the user's SS.INI file.

	Exit    : The current users current SourceSafe project is store in the
						gstr ~ssafePrj

	Globals : str ~ssafeINI  - user's SS.INI path\file name.
						str ~ssafePrj  - user's current project.

	Macros  : none.

								Copyright (C) 1993-94 by Small Systems Support.
********************************************************************( ldh )***/

	int Ow = Window_Id;
	int Srf = Refresh;
	int Jx;
	int Result = False;

	str TStr;

	Refresh = False;
	Switch_Window( Window_Count );
	Create_Window;
	Error_Level = 0;
	Load_File( g_SSafeIni );
	if ( !Error_Level ) {
		TStr = "Project = ";
		if ( Find_Text( TStr, 0, 0 ) ) {
			if ( Change == True ) {
				Jx = 1;
				while ( Jx = XPos( "\\", Project, Jx ) ) {
					Project = Str_Del( Project, Jx, 1 );
					Project = Str_Ins( "/", Project, Jx );
				}
				Jx = Svl( Project );
				if ( ( Jx > 2 ) && ( Copy( Project, Jx, 1 ) == "/" ) ) {
					Project = Copy( Project, 1, Jx - 1 );
				}
				Project = TStr + Caps( Project );
				Put_Line( Project );
				Save_File;
			}
			Project = Caps( Parse_Str( TStr, Get_Line( ) ) );
			Jx = Svl( Project );
			if ( ( Jx > 2 ) && ( Copy( Project, Jx, 1 ) != "/" ) ) {
				Project += "\\";
			}
			Jx = 1;
			while ( Jx = XPos( "/", Project, Jx ) ) {
				Project = Str_Del( Project, Jx, 1 );
				Project = Str_Ins( "\\", Project, Jx );
			}
			Result = True;
		}
	}
	Error_Level = 0;
	Delete_Window;
	Switch_Win_Id( Ow );
	Refresh = Srf;
	return ( Result );

}  // SSafeGetPrj

int SSafeGetLib( str FName ) Trans2 {
/******************************************************************************
															 Multi-Edit Macro
															 29-Mar-94  23:40

	Name    : SSafeGetLib

	Function: Get the archive project and filename for the file "FName".  If it
						doesn't exist in the checkout list and the "No Prompts" options is
						not enabled then a dialog prompting for archive project is given
						and then checked to see if the archive exists.

	Syntax  : LibFnd = SSafeGetLib( FName );

	Entry   : str   FName       - the filename to archive information for.
						gint  !vcsSNP     - global_int used to disable prompts when set.
						gstr  !vcsDlgMsg  - global_str with prompt dialog title.

	Exit    : 0 - Archive does not exists or <ESC> at dialog prompt.

								error_level = 0 except when <ESC> hit then error_level = 9000.
								gstr !vcsAFile set to selected project if prompt accepted.

						1 - Archive exists.

								error_level = 0.
								gstr !vcsChkMod set to checkout mode if found else cleared.
								gstr !vcsAFile set to archive project\filename.

						gstr !vcsDlgMsg cleared.

	Globals : gint !vcsSNP    - show No Prompts option.  True no prompt.
						gstr !vcsDlgMsg - prompt for archive path message.

						gstr vcsAFile  - the archive path and filename.
						gstr vcsChkMod - archive file checkout mode.

	Macros  : int VcsFileOut
						str SSafeXlate
						mac Data_In
						int SSafeChkLib

								Copyright (C) 1993-94 by Small Systems Support.
********************************************************************( ldh )***/

	int Result;
	int Jx;

	str Path;

	Error_Level = 0;
	if ( !( Result = VcsFileOut( FName, 0 ) ) && !vcsSNP ) {
		Path = SSafeXlate( _LIB_PATH, FName, "" );
		if ( Jx = XPos( ";", Path, 1 ) ) {
			Path = Copy( Path, 1, Jx - 1 );
			if ( ( Svl( Path ) > 0 ) && ( Copy( Path, Svl( Path ), 1 ) != "\\" ) ) {
				Path += "\\";
			}
		}
		Result = VcsEditStrDlg( vcsDlgMsg, Path, False );
		if ( Result ) {
			if ( ( Svl( Path ) > 0 ) && ( Copy( Path, Svl( Path ), 1 ) != "\\" ) ) {
				Path += "\\";
			}
			if ( Result = SSafeChkLib( Path, FName, -2 ) ) {
				vcsChkMod = "";
			}
			Error_Level = 0;
		}
		else {
			Error_Level = 9000;
		}
	}
	vcsDlgMsg = "";
	return ( Result );

}  // SSafeGetLib

void SSafeParseErr( ) Trans2 {
/******************************************************************************
															 Multi-Edit Macro
															 15-Sep-94  21:42

	Name    : SSafeParseErr

	Function: Parse the exit code out of the captured SSWCL.EXE command output.

	Syntax  : SSafeParseErr( );

	Entry   : None.

	Exit    : gint ExecReturnCode - The exit code from the captured file.
							 0                  No Error
							 1                  Minor Error
							100                 Major Error

	Globals : int ExecReturnCode  - The return code of the executed program.
						int !vcsNameLoaded  - Set when the vcsName file has loaded.

	Macros  : None.

									Copyright (C) 1994 by Small Systems Support
********************************************************************( ldh )***/

	int Result;
	int SwF = False;

	if ( !Switch_File( vcsName ) ) {
		SwF = True;
		Switch_Window( Window_Count );
		Create_Window;
	}
	ExecReturnCode = 100;                 // Assume major failure
	Error_Level = 0;
	Load_File( vcsName );
	if ( Error_Level == 0 ) {
		vcsNameLoaded = True;
		if ( Find_Text( "Exit code: ", 0, 0 ) ) {
			Val( Result, Parse_Str( "Exit code: ", Get_Line ) );
			ExecReturnCode = Result;
		}
		else {
			Tof;
			if ( Find_Text( "User: ", 0, 0 ) ) {
				ExecReturnCode = 0;             // Found user with SSWLOGIN.EXE
			}
		}
		Tof;
	}
	if ( SwF == True ) {
		Delete_Window;
		vcsNameLoaded = False;
	}

}  // SSafeParseErr

str SSafeGetUser( ) {
/******************************************************************************
															 Multi-Edit Macro
															 04-Jan-95  12:32

	Name    :
	Function:
	Syntax  :
	Entry   :
	Exit    :
	Globals :
	Macros  :

							 Copyright (C) 1995 by American Cybernectics, Inc.
********************************************************************( ldh )***/

	str Result = Get_Environment( "SSUSER" );

	if ( Result == "" ) {
		Result = _VCS_USERID;
	}
	return ( Result );

}  // SSafeGetUser

int SSafeGetDirFile( int NewScan, int ChkOnly ) {
/******************************************************************************
															 Multi-Edit Macro
															 22-Sep-94  14:08

	Name    :
	Function:
	Syntax  :
	Entry   :
	Exit    :
	Globals :
	Macros  :

									Copyright (C) 1994 by Small Systems Support
********************************************************************( ldh )***/

	int Result = False;
	int Srf = Refresh;
	int Ow = Window_Id;
	int LLen;
	int Jx;
	int Jy;
	int Cnt;
	str TLine;
	str TStr;


	if ( g_SSafeDirFile == "" ) {
		g_SSafeDirFile = TempFileName( "SSAFEDIR.TMP" );
	}
	Refresh = False;
	if ( !( Result = Switch_File( g_SSafeDirFile ) ) ) {
		Switch_Window( Window_Count );
		Create_Window;
		Window_Attr = 0x81;
		NewScan = True;
	}
	if ( ChkOnly ) {
		NewScan = False;
	}
	if ( NewScan ) {
		vcsMsg = "Scanning projects...";
		g_SSafeRDir = True;
    Result = SSafeCmds( "SDIR", "", "" );
		Make_Message( "" );
		g_SSafeRDir = False;
		if ( Result ) {
			Error_Level = 0;
			Load_File( vcsName );
			File_Name = g_SSafeDirFile;
			if ( Error_Level ) {
				Error_Level = 0;
				Result = False;
			}
		}
//    Set_File_Attr( vcsName, 0 );
//    Del_File( vcsName );
		if ( Result == True ) {
			if ( Find_Text( "item(s)", 0, 0 ) ) {
				Block_Begin;
				Eof;
				Delete_Block;
			}
			Tof;
			Put_Line( "\x7F" + "L=0" + "\x7F" + "P=$\\" );
			Down;
			while ( !At_Eof ) {
				TLine = Remove_Space( Get_Line );
				LLen = Svl( TLine );
				if ( Copy( TLine, LLen, 1 ) == ":" ) {
					Cnt = 0;
					TLine = Copy( TLine, 1, LLen - 1 );
					Jx = 0;
					TStr = "";
					while ( Jy = XPos( "/", TLine, ++Jx ) ) {
						++Cnt;
						TStr += Copy( TLine, Jx, Jy - Jx ) + "\\";
						Jx = Jy;
					}
					TLine = "\x7F" + "L=" + Str( Cnt ) + "\x7F" + "P1=" + TStr +
							"\x7F" + "P=" + Copy( TLine, Jx, Jx - LLen - 1);
					Put_Line( TLine );
				}
				else if ( XPos( "$", TLine, 1 ) ) {
					Del_Line;
					Up;
				}
				else if ( TLine != "" ) {
					TStr = "\x7F" + "F=" + TLine;
					if ( Jx = XPos( " ", TStr, 1 ) ) {
						TStr = Str_Ins( "\x7F" + "U=", Str_Del( TStr, Jx, 1 ), Jx );
						Jx = XPos( " ", TStr, Jx );
						TStr = Str_Ins( "\x7F" + "D=", Str_Del( TStr, Jx, 1 ), Jx );
						Jx = XPos( " ", TStr, Jx );
						Jx = XPos( " ", TStr, ++Jx );
						TStr = Str_Ins( "\x7F" + "WD=", Str_Del( TStr, Jx, 1 ), Jx );
					}
					Put_Line( TStr );
				}
				Down;
			}
			if ( File_Changed ) {
				Save_File;
			}
		}
	}
	if ( Result == False ) {
		Delete_Window;
	}
	Switch_Win_Id( Ow );
	Refresh = Srf;
	return ( Result );

}  // SSafeGetDirFile

int SSafeUpdDirFile( str FName, str FStr ) {
/******************************************************************************
															 Multi-Edit Macro
															 22-Sep-94  23:51

	Name    :
	Function:
	Syntax  :
	Entry   :
	Exit    :
	Globals :
	Macros  :

									Copyright (C) 1994 by Small Systems Support
********************************************************************( ldh )***/

	int Result = False;
	int Ow = Window_Id;
	int Srf = Refresh;
	int Jx;
	int Jy;
	int Cnt;
	str TStr;
	str TLine;

	Refresh = False;
	FName = Caps( FName );
	if ( Switch_File( g_SSafeDirFile ) ) {
		TStr = "\x7F" + "P1=" + Get_Path( FName );
		TStr = Copy( TStr, 1, Svl( TStr ) - 1 );
		Cnt = 0;
		Jx = 0;
		while ( Jy = XPos( "\\", TStr, ++Jx ) ) {
			++Cnt;
			Jx = Jy;
		}
		TStr = "\x7F" + "L=" + Str( Cnt ) + Str_Ins( "\x7F" + "P=", TStr, Jx );
		Tof;
		while ( Find_Text( TStr, 0, 0 ) ) {
			if ( Caps( Found_Str ) == Caps( Get_Line( ) ) ) {
				Down;
				Jx = C_Line;
				TStr = "\x7F" + "F=" + Truncate_Path( FName );
				while ( ( TLine = Caps( Get_Line( ) ) ) != "" ) {
					if ( XPos( TStr, TLine, 1 ) ) {
						if ( Truncate_Path( FName ) == Parse_Str( "\x7F" + "F=", TLine ) ) {
							if ( FStr != "" ) {
								Put_Line( FStr );
							}
							else {
								g_SSafeFUsr = Parse_Str( "\x7F" + "U=", TLine );
							}
							Result = True;
							break;
						}
					}
					Down;
				}
				if ( ( FStr != "" ) && ( Result == False ) ) {
					Cr;
					Up;
					Put_Line( FStr );
					QSort_Lines( Jx, C_Line, True, 3, 12, True );
				}
				break;
			}
		}
	}
	Switch_Win_Id( Ow );
	Refresh = Srf;
	return ( Result );

}  // SSafeUpdDirFile
