236 lines
6.6 KiB
C
236 lines
6.6 KiB
C
/*
|
|
** args.c - Command-line argument manipulation functions.
|
|
**
|
|
** Author: DavidDi
|
|
**
|
|
** N.b., setargv.obj must be linked with this module for the command-line
|
|
** parsing to function properly.
|
|
*/
|
|
|
|
|
|
// Headers
|
|
///////////
|
|
|
|
#include <ctype.h>
|
|
#include <stdio.h>
|
|
#include <string.h>
|
|
|
|
#include "lz_common.h"
|
|
|
|
#include "args.h"
|
|
#include "main.h"
|
|
#include "messages.h"
|
|
|
|
extern BOOL PathType(LPSTR lpszFileString); /* WIN32 MOD*/
|
|
|
|
// Globals
|
|
///////////
|
|
|
|
// All the globals defined in this module are set by ParseArguments().
|
|
|
|
BOOL bDoRename, // flag for performing compressed file renaming
|
|
bDisplayHelp, // flag for displaying help information
|
|
bTargetIsDir; // flag telling whether or not files are being
|
|
// compressed to a directory
|
|
|
|
INT nNumFileSpecs, // number of non-switch, non-directory command-line
|
|
// arguments, assumed to be file specifications
|
|
iTarget; // argv[] index of target directory argument, or FAIL if
|
|
// none present
|
|
|
|
BOOL bDoListFiles; // flag for displaying list of files from a CAB
|
|
// (instead of actually expanding them)
|
|
CHAR ARG_PTR *pszSelectiveFilesSpec; // name of file(s) to expand from a CAB
|
|
|
|
|
|
/*
|
|
** BOOL ParseArguments(int argc, char ARG_PTR *argv[]);
|
|
**
|
|
** Parse command-line arguments.
|
|
**
|
|
** Arguments: like arguments to main()
|
|
**
|
|
** Returns: TRUE if command-line arguments parsed successfully. FALSE if
|
|
** not.
|
|
**
|
|
** Globals: All globals defined in this module are set in this function,
|
|
** as described above.
|
|
*/
|
|
|
|
BOOL ParseArguments(INT argc, CHAR ARG_PTR *argv[])
|
|
{
|
|
INT i;
|
|
CHAR chSwitch;
|
|
|
|
// Set up default values for globals.
|
|
bDoRename = FALSE;
|
|
bDisplayHelp = FALSE;
|
|
bTargetIsDir = FALSE;
|
|
nNumFileSpecs = 0;
|
|
iTarget = FAIL;
|
|
bDoListFiles = FALSE;
|
|
pszSelectiveFilesSpec = NULL;
|
|
|
|
// Look at each command-line argument.
|
|
for (i = 1; i < argc; i++)
|
|
if (ISSWITCH(*(argv[i])))
|
|
{
|
|
// Get switch character.
|
|
chSwitch = *(argv[i] + 1);
|
|
|
|
//for bad DBCS argument
|
|
if( IsDBCSLeadByte(chSwitch) )
|
|
{
|
|
CHAR work[3];
|
|
lstrcpyn(work, argv[i] + 1, 3);
|
|
LoadString(NULL, SID_BAD_SWITCH2, ErrorMsg, 1024);
|
|
printf(ErrorMsg, work);
|
|
return(FALSE);
|
|
}
|
|
|
|
// Classify switch.
|
|
if (toupper(chSwitch) == toupper(chRENAME_SWITCH))
|
|
bDoRename = TRUE;
|
|
else if (toupper(chSwitch) == toupper(chHELP_SWITCH))
|
|
bDisplayHelp = TRUE;
|
|
else if (toupper(chSwitch) == toupper(chLIST_SWITCH))
|
|
bDoListFiles = bDoRename = TRUE;
|
|
else if ((toupper(chSwitch) == toupper(chSELECTIVE_SWITCH)) &&
|
|
(argv[i][2] == ':') &&
|
|
(argv[i][3] != '\0') &&
|
|
(pszSelectiveFilesSpec == NULL))
|
|
pszSelectiveFilesSpec = &argv[i][3];
|
|
else
|
|
{
|
|
// Unrecognized switch.
|
|
LoadString(NULL, SID_BAD_SWITCH, ErrorMsg, 1024);
|
|
// WARNING: Cannot call CharToOemW with src=dest
|
|
CharToOem(ErrorMsg, ErrorMsg);
|
|
printf(ErrorMsg, chSwitch);
|
|
return(FALSE);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
// Keep track of last non-switch command-line argument as
|
|
// destination argument.
|
|
iTarget = i;
|
|
|
|
if (IsDir((LPSTR)argv[i]) == FALSE)
|
|
// Non-switch arguments are assumed to be file specifications.
|
|
nNumFileSpecs++;
|
|
}
|
|
|
|
// Set bTargetIsDir.
|
|
if (iTarget != FAIL)
|
|
bTargetIsDir = IsDir((LPSTR)argv[iTarget]);
|
|
|
|
// Command-line arguments parsed successsfully.
|
|
return(TRUE);
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
** BOOL CheckArguments(void);
|
|
**
|
|
** Check command-line arguments for error conditions.
|
|
**
|
|
** Arguments: void
|
|
**
|
|
** Returns: BOOL - TRUE if no problems found. FALSE if problem found.
|
|
**
|
|
** Globals: none
|
|
*/
|
|
BOOL CheckArguments(VOID)
|
|
{
|
|
if (nNumFileSpecs < 1)
|
|
{
|
|
// No file specifications given.
|
|
LoadString(NULL, SID_NO_FILE_SPECS, ErrorMsg, 1024);
|
|
// WARNING: Cannot call CharToOemW with src=dest
|
|
CharToOem(ErrorMsg, ErrorMsg);
|
|
printf(ErrorMsg);
|
|
return(FALSE);
|
|
}
|
|
else if (nNumFileSpecs == 1 && bDoRename == FALSE && bTargetIsDir == FALSE && bDoListFiles == FALSE)
|
|
{
|
|
// We don't want to process a source file on to itself.
|
|
LoadString(NULL, SID_NO_OVERWRITE, ErrorMsg, 1024);
|
|
// WARNING: Cannot call CharToOemW with src=dest
|
|
CharToOem(ErrorMsg, ErrorMsg);
|
|
printf(ErrorMsg, pszTargetName);
|
|
return(FALSE);
|
|
}
|
|
else if (nNumFileSpecs > 2 && bDoRename == FALSE && bTargetIsDir == FALSE && bDoListFiles == FALSE)
|
|
{
|
|
// There are multiple files to process, and the destination
|
|
// specification argument is not a directory. But we weren't told to
|
|
// rename the output files. Bail out since we don't want to wipe out
|
|
// the input files.
|
|
LoadString(NULL, SID_NOT_A_DIR, ErrorMsg, 1024);
|
|
// WARNING: Cannot call CharToOemW with src=dest
|
|
CharToOem(ErrorMsg, ErrorMsg);
|
|
printf(ErrorMsg, pszTargetName);
|
|
return(FALSE);
|
|
}
|
|
else if (bDoListFiles && bTargetIsDir == TRUE)
|
|
{
|
|
// Requested only a listing of the files from the source CAB, but then
|
|
// supplied a destination directory. There is no destination when we're
|
|
// only displaying names. Bail out because he must be confused.
|
|
LoadString(NULL, SID_UNEXP_TARGET, ErrorMsg, 1024);
|
|
// WARNING: Cannot call CharToOemW with src=dest
|
|
CharToOem(ErrorMsg, ErrorMsg);
|
|
printf(ErrorMsg, pszTargetName);
|
|
return(FALSE);
|
|
}
|
|
else
|
|
// No problems encountered.
|
|
return(TRUE);
|
|
}
|
|
|
|
|
|
/*
|
|
** int GetNextFileArg(char ARG_PTR *argv[]);
|
|
**
|
|
** Find the next file name argument on the command-line.
|
|
**
|
|
** Arguments: like argument to main()
|
|
**
|
|
** Returns: int - Index in argv[] of next file name argument. FAIL if
|
|
** none found.
|
|
**
|
|
** Globals: none
|
|
*/
|
|
INT GetNextFileArg(CHAR ARG_PTR *argv[])
|
|
{
|
|
INT i;
|
|
static INT iLastArg = 0;
|
|
|
|
for (i = iLastArg + 1; i <= iTarget; i++)
|
|
if (! ISSWITCH(*(argv[i])) &&
|
|
(i < iTarget || bTargetIsDir == FALSE)
|
|
&& (! IsDir((LPSTR)argv[i])))
|
|
return(iLastArg = i);
|
|
|
|
return(FAIL);
|
|
}
|
|
|
|
/* WIN32 MODS */
|
|
|
|
/* returns 0 if not directory, 1 if so */
|
|
INT IsDir(LPSTR lpszTestString)
|
|
{
|
|
|
|
BOOL bRetVal;
|
|
|
|
bRetVal = PathType(lpszTestString);
|
|
if(bRetVal == 0){ /*assert*/
|
|
bRetVal++; /* this is because if lpszTestString file doesnt exist*/
|
|
/* API returns 0, so I increment to 1, cause is NOT directory*/
|
|
}
|
|
return(--bRetVal); /* because returns 2 if dir, 1 if not*/
|
|
|
|
}
|