Source code of Windows XP (NT5)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

235 lines
6.6 KiB

  1. /*
  2. ** args.c - Command-line argument manipulation functions.
  3. **
  4. ** Author: DavidDi
  5. **
  6. ** N.b., setargv.obj must be linked with this module for the command-line
  7. ** parsing to function properly.
  8. */
  9. // Headers
  10. ///////////
  11. #include <ctype.h>
  12. #include <stdio.h>
  13. #include <string.h>
  14. #include "lz_common.h"
  15. #include "args.h"
  16. #include "main.h"
  17. #include "messages.h"
  18. extern BOOL PathType(LPSTR lpszFileString); /* WIN32 MOD*/
  19. // Globals
  20. ///////////
  21. // All the globals defined in this module are set by ParseArguments().
  22. BOOL bDoRename, // flag for performing compressed file renaming
  23. bDisplayHelp, // flag for displaying help information
  24. bTargetIsDir; // flag telling whether or not files are being
  25. // compressed to a directory
  26. INT nNumFileSpecs, // number of non-switch, non-directory command-line
  27. // arguments, assumed to be file specifications
  28. iTarget; // argv[] index of target directory argument, or FAIL if
  29. // none present
  30. BOOL bDoListFiles; // flag for displaying list of files from a CAB
  31. // (instead of actually expanding them)
  32. CHAR ARG_PTR *pszSelectiveFilesSpec; // name of file(s) to expand from a CAB
  33. /*
  34. ** BOOL ParseArguments(int argc, char ARG_PTR *argv[]);
  35. **
  36. ** Parse command-line arguments.
  37. **
  38. ** Arguments: like arguments to main()
  39. **
  40. ** Returns: TRUE if command-line arguments parsed successfully. FALSE if
  41. ** not.
  42. **
  43. ** Globals: All globals defined in this module are set in this function,
  44. ** as described above.
  45. */
  46. BOOL ParseArguments(INT argc, CHAR ARG_PTR *argv[])
  47. {
  48. INT i;
  49. CHAR chSwitch;
  50. // Set up default values for globals.
  51. bDoRename = FALSE;
  52. bDisplayHelp = FALSE;
  53. bTargetIsDir = FALSE;
  54. nNumFileSpecs = 0;
  55. iTarget = FAIL;
  56. bDoListFiles = FALSE;
  57. pszSelectiveFilesSpec = NULL;
  58. // Look at each command-line argument.
  59. for (i = 1; i < argc; i++)
  60. if (ISSWITCH(*(argv[i])))
  61. {
  62. // Get switch character.
  63. chSwitch = *(argv[i] + 1);
  64. //for bad DBCS argument
  65. if( IsDBCSLeadByte(chSwitch) )
  66. {
  67. CHAR work[3];
  68. lstrcpyn(work, argv[i] + 1, 3);
  69. LoadString(NULL, SID_BAD_SWITCH2, ErrorMsg, 1024);
  70. printf(ErrorMsg, work);
  71. return(FALSE);
  72. }
  73. // Classify switch.
  74. if (toupper(chSwitch) == toupper(chRENAME_SWITCH))
  75. bDoRename = TRUE;
  76. else if (toupper(chSwitch) == toupper(chHELP_SWITCH))
  77. bDisplayHelp = TRUE;
  78. else if (toupper(chSwitch) == toupper(chLIST_SWITCH))
  79. bDoListFiles = bDoRename = TRUE;
  80. else if ((toupper(chSwitch) == toupper(chSELECTIVE_SWITCH)) &&
  81. (argv[i][2] == ':') &&
  82. (argv[i][3] != '\0') &&
  83. (pszSelectiveFilesSpec == NULL))
  84. pszSelectiveFilesSpec = &argv[i][3];
  85. else
  86. {
  87. // Unrecognized switch.
  88. LoadString(NULL, SID_BAD_SWITCH, ErrorMsg, 1024);
  89. // WARNING: Cannot call CharToOemW with src=dest
  90. CharToOem(ErrorMsg, ErrorMsg);
  91. printf(ErrorMsg, chSwitch);
  92. return(FALSE);
  93. }
  94. }
  95. else
  96. {
  97. // Keep track of last non-switch command-line argument as
  98. // destination argument.
  99. iTarget = i;
  100. if (IsDir((LPSTR)argv[i]) == FALSE)
  101. // Non-switch arguments are assumed to be file specifications.
  102. nNumFileSpecs++;
  103. }
  104. // Set bTargetIsDir.
  105. if (iTarget != FAIL)
  106. bTargetIsDir = IsDir((LPSTR)argv[iTarget]);
  107. // Command-line arguments parsed successsfully.
  108. return(TRUE);
  109. }
  110. /*
  111. ** BOOL CheckArguments(void);
  112. **
  113. ** Check command-line arguments for error conditions.
  114. **
  115. ** Arguments: void
  116. **
  117. ** Returns: BOOL - TRUE if no problems found. FALSE if problem found.
  118. **
  119. ** Globals: none
  120. */
  121. BOOL CheckArguments(VOID)
  122. {
  123. if (nNumFileSpecs < 1)
  124. {
  125. // No file specifications given.
  126. LoadString(NULL, SID_NO_FILE_SPECS, ErrorMsg, 1024);
  127. // WARNING: Cannot call CharToOemW with src=dest
  128. CharToOem(ErrorMsg, ErrorMsg);
  129. printf(ErrorMsg);
  130. return(FALSE);
  131. }
  132. else if (nNumFileSpecs == 1 && bDoRename == FALSE && bTargetIsDir == FALSE && bDoListFiles == FALSE)
  133. {
  134. // We don't want to process a source file on to itself.
  135. LoadString(NULL, SID_NO_OVERWRITE, ErrorMsg, 1024);
  136. // WARNING: Cannot call CharToOemW with src=dest
  137. CharToOem(ErrorMsg, ErrorMsg);
  138. printf(ErrorMsg, pszTargetName);
  139. return(FALSE);
  140. }
  141. else if (nNumFileSpecs > 2 && bDoRename == FALSE && bTargetIsDir == FALSE && bDoListFiles == FALSE)
  142. {
  143. // There are multiple files to process, and the destination
  144. // specification argument is not a directory. But we weren't told to
  145. // rename the output files. Bail out since we don't want to wipe out
  146. // the input files.
  147. LoadString(NULL, SID_NOT_A_DIR, ErrorMsg, 1024);
  148. // WARNING: Cannot call CharToOemW with src=dest
  149. CharToOem(ErrorMsg, ErrorMsg);
  150. printf(ErrorMsg, pszTargetName);
  151. return(FALSE);
  152. }
  153. else if (bDoListFiles && bTargetIsDir == TRUE)
  154. {
  155. // Requested only a listing of the files from the source CAB, but then
  156. // supplied a destination directory. There is no destination when we're
  157. // only displaying names. Bail out because he must be confused.
  158. LoadString(NULL, SID_UNEXP_TARGET, ErrorMsg, 1024);
  159. // WARNING: Cannot call CharToOemW with src=dest
  160. CharToOem(ErrorMsg, ErrorMsg);
  161. printf(ErrorMsg, pszTargetName);
  162. return(FALSE);
  163. }
  164. else
  165. // No problems encountered.
  166. return(TRUE);
  167. }
  168. /*
  169. ** int GetNextFileArg(char ARG_PTR *argv[]);
  170. **
  171. ** Find the next file name argument on the command-line.
  172. **
  173. ** Arguments: like argument to main()
  174. **
  175. ** Returns: int - Index in argv[] of next file name argument. FAIL if
  176. ** none found.
  177. **
  178. ** Globals: none
  179. */
  180. INT GetNextFileArg(CHAR ARG_PTR *argv[])
  181. {
  182. INT i;
  183. static INT iLastArg = 0;
  184. for (i = iLastArg + 1; i <= iTarget; i++)
  185. if (! ISSWITCH(*(argv[i])) &&
  186. (i < iTarget || bTargetIsDir == FALSE)
  187. && (! IsDir((LPSTR)argv[i])))
  188. return(iLastArg = i);
  189. return(FAIL);
  190. }
  191. /* WIN32 MODS */
  192. /* returns 0 if not directory, 1 if so */
  193. INT IsDir(LPSTR lpszTestString)
  194. {
  195. BOOL bRetVal;
  196. bRetVal = PathType(lpszTestString);
  197. if(bRetVal == 0){ /*assert*/
  198. bRetVal++; /* this is because if lpszTestString file doesnt exist*/
  199. /* API returns 0, so I increment to 1, cause is NOT directory*/
  200. }
  201. return(--bRetVal); /* because returns 2 if dir, 1 if not*/
  202. }