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.

387 lines
10 KiB

  1. /*
  2. * UPDRN: UPD with rename
  3. *
  4. * HISTORY:
  5. * manis : 22-May-87 : first written and released
  6. * 29-May-87 danl Added explicit test for only two args
  7. * Removed rootpath tests
  8. * Added string.h
  9. * Don't remove trailing '\' from args to /g
  10. * 12-Jun-87 brianwi Get around FAPI one-open dir limitation
  11. */
  12. #include <malloc.h>
  13. #include <math.h>
  14. #include <ctype.h>
  15. #include <fcntl.h>
  16. #include <string.h>
  17. #include <sys\types.h>
  18. #include <sys\stat.h>
  19. #include <io.h>
  20. #include <stdio.h>
  21. #include <process.h>
  22. #include <ctype.h>
  23. #include <math.h>
  24. #include <stdlib.h>
  25. #include <windows.h>
  26. #include <tools.h>
  27. // Forward Function Declarations..
  28. void docopy( char *, struct findType * );
  29. int setup( char *, int, void (*)() );
  30. void __cdecl usage( char *, ... );
  31. void getfile( int, char ** );
  32. char const rgstrUsage[] = {
  33. "Usage: UPDRN [/fnvape] srcfile destfile\n"
  34. " UPDRN /g file {arg}*\n"
  35. "\n"
  36. " /f Files differ, then copy\n"
  37. " /n No saving of replaced file to deleted directory\n"
  38. " /v Verbose\n"
  39. " /a Archive bit on source should NOT be reset\n"
  40. " /p Print actions, but do nothing\n"
  41. " /e Exit codes 1-error or no src else 0\n"
  42. " Default is 1-copy done 0-no copy done\n"
  43. " /g Get params from file\n"
  44. };
  45. #define BUFLEN MAX_PATH
  46. #define MAXARGV 20
  47. unsigned _stack = 4096;
  48. flagType fInGetfile = FALSE;
  49. flagType fAll = FALSE;
  50. flagType fDel = TRUE;
  51. flagType fVerbose = FALSE;
  52. flagType fArchiveReset = TRUE;
  53. flagType fPrintOnly = FALSE;
  54. flagType fErrorExit = FALSE; /* TRUE => exit (1) errors or no src else 0 */
  55. flagType fNoSrc = FALSE; /* TRUE => "No src msg emitted" */
  56. int cCopied = 0;
  57. int fAnyUpd = 0;
  58. struct findType buf;
  59. char source[BUFLEN], dest[BUFLEN] ;
  60. /* for use by getfile */
  61. char *argv[MAXARGV];
  62. char bufIn[BUFLEN];
  63. char strLine[BUFLEN];
  64. char ekoLine[BUFLEN]; /* undestroyed copy of line for echo */
  65. void copyfile(src, srctype, dst)
  66. char *src, *dst;
  67. struct findType *srctype;
  68. {
  69. char *result;
  70. flagType fNewfile = FALSE;
  71. /* if the file already exists, fdelete will return 0; then don't */
  72. /* notify the user that a file transfer has taken place.Otherwise*/
  73. /* a new file has been created so tell the user about it. */
  74. printf(" %s => %s", src, dst);
  75. fAnyUpd = 1;
  76. if (!fPrintOnly) {
  77. if( fDel ) {
  78. fNewfile = (flagType)( (fdelete(dst)) ? TRUE : FALSE );
  79. }
  80. if (!(result = fcopy(src, dst))) {
  81. if (fArchiveReset)
  82. SetFileAttributes( src, srctype->fbuf.dwFileAttributes & ~FILE_ATTRIBUTE_ARCHIVE );
  83. if (fVerbose || fNewfile) printf(" [OK]");
  84. }
  85. else
  86. printf(" %s - %s", result, error());
  87. }
  88. else
  89. printf (" [no copy]");
  90. printf("\n");
  91. fflush(stdout);
  92. }
  93. void docopy (p, b)
  94. /* copy source file to destination file based on time stamps */
  95. /* and different switches. */
  96. char *p;
  97. struct findType *b;
  98. {
  99. int fNotFound;
  100. char *pPat;
  101. char *pT = p;
  102. struct findType *bT = b;
  103. pPat = malloc (BUFLEN);
  104. if (pPat) {
  105. strcpy(pPat, dest);
  106. cCopied++;
  107. if( ( fNotFound = ffirst(pPat, ~(FILE_ATTRIBUTE_DIRECTORY), &buf)) ||
  108. ( CompareFileTime( &buf.fbuf.ftLastWriteTime, &bT->fbuf.ftLastWriteTime ) < 0 ) ||
  109. ( fAll &&
  110. CompareFileTime( &buf.fbuf.ftLastWriteTime, &bT->fbuf.ftLastWriteTime ) > 0
  111. )
  112. ) {
  113. copyfile(pT, bT, pPat);
  114. }
  115. else if( !fNotFound &&
  116. CompareFileTime( &buf.fbuf.ftLastWriteTime, &bT->fbuf.ftLastWriteTime ) == 0 &&
  117. buf.fbuf.nFileSizeLow != bT->fbuf.nFileSizeLow
  118. ) {
  119. printf("\n\007UPDRN: warning - %s not copied\n", pT);
  120. printf("\007UPDRN: warning - same time, different length in src & dest\n", pT);
  121. }
  122. findclose( &buf );
  123. free (pPat);
  124. }
  125. }
  126. setup(pat, attr, rtn)
  127. /* set up buffer for find first call. if the source file is valid */
  128. /* and ffirst call is successful, call the routine "rtn". */
  129. char *pat;
  130. int attr;
  131. void (*rtn)();
  132. {
  133. struct findType *fbuf;
  134. char *buf;
  135. if ((fbuf=(struct findType *)malloc(sizeof (*fbuf) + MAX_PATH ))==NULL)
  136. return FALSE;
  137. if (ffirst (pat, attr, fbuf)) {
  138. free ((char *) fbuf);
  139. return FALSE;
  140. }
  141. if ((buf = (char *)malloc(MAX_PATH)) == NULL) {
  142. free ((char *) fbuf);
  143. return FALSE;
  144. }
  145. drive (pat, buf);
  146. path (pat, strend (buf));
  147. pat = strend (buf);
  148. strcpy (pat, fbuf->fbuf.cFileName);
  149. _strlwr (pat);
  150. findclose (fbuf);
  151. (*rtn) (buf, fbuf);
  152. free (buf);
  153. free ((char *) fbuf);
  154. return TRUE;
  155. }
  156. void __cdecl usage( char *p, ... )
  157. /* prints error messages */
  158. {
  159. char **rgstr;
  160. rgstr = &p;
  161. if (*rgstr) {
  162. fprintf (stderr, "UPDRN: ");
  163. while (*rgstr)
  164. fprintf (stderr, "%s", *rgstr++);
  165. fprintf (stderr, "\n");
  166. }
  167. fputs (rgstrUsage, stderr);
  168. exit ((fErrorExit ? 1 : 0));
  169. }
  170. int
  171. __cdecl
  172. main (c, v)
  173. int c;
  174. char *v[];
  175. {
  176. char *p, namebuf[ BUFLEN ];
  177. fAll = FALSE;
  178. fDel = TRUE;
  179. fArchiveReset = TRUE;
  180. fPrintOnly = FALSE;
  181. cCopied = 0;
  182. if (!fInGetfile)
  183. ConvertAppToOem( c, v );
  184. SHIFT(c, v); /* Flush the command name */
  185. while( c && fSwitChr( *v[0] ) ) {
  186. p = v[ 0 ];
  187. SHIFT(c, v);
  188. while (*++p)
  189. switch (tolower(*p)) {
  190. case 'a':
  191. fArchiveReset = FALSE;
  192. break;
  193. case 'g':
  194. if (fInGetfile)
  195. usage("/g allowed only on command line", 0);
  196. getfile(c, v);
  197. break;
  198. case 'e':
  199. fErrorExit = TRUE;
  200. break;
  201. case 'v':
  202. fVerbose = TRUE;
  203. break;
  204. case 'f':
  205. fAll = TRUE;
  206. break;
  207. case 'n':
  208. fDel = FALSE;
  209. break;
  210. case 'p':
  211. fPrintOnly = TRUE;
  212. break;
  213. default:
  214. usage("Invalid switch - ", p, 0);
  215. }
  216. }
  217. /* Must be at one source file and dest file. */
  218. if (c != 2)
  219. usage(0);
  220. /* Make sure source and destination dirs are valid */
  221. /* Wildcards not allowed */
  222. rootpath( v[1], dest );
  223. rootpath( v[0], source);
  224. if (!filename(source, namebuf))
  225. usage("Source file name not specified - ", source, 0);
  226. if (fileext(source, namebuf))
  227. if (strpbrk(namebuf,"*")!=NULL)
  228. usage("Wild cards not allowed - ", source, 0);
  229. if (fileext(dest, namebuf)){
  230. if (strpbrk(namebuf,"*")!=NULL)
  231. usage("Wild cards not allowed - ", dest, 0);
  232. }
  233. else
  234. usage("Destination file not specified - ", dest, 0);
  235. /* now compcopy the source file to dest file. source
  236. file has subset of the attributes specified */
  237. if (fVerbose) {
  238. printf("Comparing and copying srcfile: %s\n", source);
  239. printf(" To destination file: %s\n", dest);
  240. }
  241. cCopied = 0;
  242. setup(source, FILE_ATTRIBUTE_HIDDEN | FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_READONLY | FILE_ATTRIBUTE_ARCHIVE, (void ( *)())docopy);
  243. if (!cCopied) {
  244. printf("UPDRN: no src file matching %s\n", source);
  245. fNoSrc = 1;
  246. }
  247. if (!fInGetfile)
  248. return( (int)fErrorExit ? (int)fNoSrc : fAnyUpd );
  249. return 0;
  250. }
  251. /* call if UPDRN /g getfile, reads lines from getfile and for each line
  252. calls main */
  253. void getfile(c, v)
  254. int c;
  255. char *v[];
  256. {
  257. int cargv = 0;
  258. FILE *fp;
  259. int i, j;
  260. char *p, *p2;
  261. char lbuf[BUFLEN];
  262. /*
  263. * 13-SEPT-90 w-barry
  264. *
  265. * Change open() to fopen() and replace assembly routines getl() and
  266. * getlinit() with fgets.
  267. */
  268. if (c == 0)
  269. usage("no getfile specified", 0);
  270. fInGetfile = TRUE;
  271. if( ( fp = fopen( *v, "r" ) ) == NULL ) {
  272. usage("error opening ", *v, 0);
  273. }
  274. SHIFT(c, v);
  275. /* getlinit((char far *)bufIn, BUFLEN, fh);
  276. * while (getl(strLine, BUFLEN) != NULL) {
  277. */
  278. while( fgets( strLine, BUFLEN, fp ) != NULL ) {
  279. if (*strLine == '#')
  280. continue;
  281. if (*strLine == ';') {
  282. printf("%s\n", strLine);
  283. continue;
  284. }
  285. /* fgets doesn't remove \n */
  286. *strbscan(strLine, "\n") = '\0';
  287. cargv = 0;
  288. /* convert strLine into argv */
  289. p = strbskip(strLine, " ");
  290. strcpy (ekoLine, p + 5);
  291. while (*p) {
  292. argv[cargv++] = p;
  293. p = strbscan(p, " ");
  294. if (*p)
  295. *p++ = '\0';
  296. p = strbskip(p, " ");
  297. }
  298. if (!_stricmp (argv[0], "rem")) continue;
  299. if (!_stricmp (argv[0], "echo"))
  300. {
  301. if (!_stricmp (argv[1], "on"))
  302. {
  303. fVerbose = TRUE;
  304. printf ("Verbose On\n");
  305. }
  306. else if (!_stricmp (argv[1], "off"))
  307. {
  308. fVerbose = FALSE;
  309. printf ("Verbose Off\n");
  310. }
  311. else printf ("%s\n", ekoLine);
  312. continue;
  313. }
  314. /* replace the arguments in the file : %0, %1 etc */
  315. /* with the arguments from the command line */
  316. /* lbuf : holds the strings formed by replacing %0 etc*/
  317. p2 = lbuf;
  318. for (i = 0; i < cargv; i++) {
  319. if (*(p = argv[i]) == '%') {
  320. if ((j = atoi(++p)) < c) {
  321. strcpy(p2, v[j]);
  322. argv[i] = strcat(p2,++p);
  323. p2 += strlen(argv[i])+1;
  324. }
  325. else
  326. usage("bad arg ", argv[i], 0);
  327. }
  328. }
  329. if (cargv)
  330. main(cargv, argv);
  331. }
  332. fclose( fp );
  333. exit( (int)fErrorExit ? (int)fNoSrc : fAnyUpd );
  334. }