2 /*-------------------------------
3 /* SOURCE FILE NAME: restpars.c
4 /*-------------------------------
9 #include "restpars.h" /*;AN000;4*/
13 #include "dos.h" /*;AN000;2*/
14 #include "comsub.h" /* common subroutine def'n */
18 /*=============================*/
19 extern BYTE srcd; /*;AN000;4*/
20 extern BYTE destd; /*;AN000;4*/
21 extern BYTE inpath [MAXPATH]; /*;AN000;*/
22 extern BYTE infname [MAXFNAME]; /*;AN000;*/
23 extern BYTE infext [MAXFEXT]; /*;AN000;*/
24 extern BYTE infspec [MAXFSPEC]; /*;AN000;*/
25 /*=============================*/
27 extern BYTE destddir[MAXPATH+3];
28 extern BYTE srcddir[MAXPATH+3];
30 extern BYTE control_flag;
31 extern BYTE control_flag2;
32 extern BYTE filename[12];
33 extern unsigned control_file_handle; /* !wrw */
34 extern struct subst_list sublist; /*;AN000;6Message substitution list */
36 struct p_parms parms; /*;AN000;4 Parser data structure */
37 struct p_parmsx parmsx; /*;AN000;4 Parser data structure */
38 struct p_pos_blk pos1; /*;AN000;4 Parser data structure */
39 struct p_pos_blk pos2; /*;AN000;4 Parser data structure */
40 struct p_sw_blk sw1; /*;AN000;4 /S /P /M /N data structure */
41 struct p_sw_blk sw2; /*;AN000;4 /E: /L: parser data structure */
42 struct p_sw_blk sw3; /*;AN000;4 /B: /A: parser data structure */
43 struct p_result_blk pos_buff; /*;AN000;4 Parser data structure */
44 struct switchbuff sw_buff; /*;AN000;4 Parser data structure */
45 struct timebuff time_buff; /*;AN000;4 Parser data structure */
46 struct datebuff date_buff; /*;AN000;4 Parser data structure */
47 DWORD noval; /*;AN000;4 Value list for PARSER */
48 int parse_count = 1; /*;AN000;4*//*;AC002;*/
49 char curr_parm[128]; /*;AN004; Current parameter being parsed*/
50 extern struct timedate td;
52 /*
\f************************************************/
54 /* SUBROUTINE NAME: parse_command_line
58 /* Parse the RESTORE command line
60 /**************************************************/
61 void parse_command_line(argc,argv) /*;AN000;4 */
62 int argc; /*;AN000;4 */
63 char *argv[]; /*;AN000;4 */
65 #define EOL -1 /*;AN000;4 */
66 union REGS inregs, outregs; /*;AN000;4 */
67 char cmd_line[128]; /*;AN000;4 */
68 char not_finished = TTRUE; /*;AN000;4 */
72 /* Copy command line parameters to local area */
73 cmd_line[0] = NUL; /*;AN000;4*/
74 for (x=1; x<=argc; x++) /*;AN000;4*/
76 strcat(cmd_line,argv[x]); /*;AN000;4*/
77 if (x!=argc) strcat(cmd_line," "); /*;AN000;4*/
80 strcat(cmd_line,"\r"); /* Add CR, LF */ /*;AN004;*/
82 if (argc-1 < 1) /*;AN000;4*/
84 display_it(NO_SOURCE,STND_ERR_DEV,0,NO_RESPTYPE,(BYTE)UTIL_MSG);/*;AN000;6*/
85 usererror(INVALIDPARM); /*;AC000;4*/
88 if (argc-1 < 2) /*;AN000;4*/
90 display_it(NO_TARGET,STND_ERR_DEV,0,NO_RESPTYPE,(BYTE)UTIL_MSG);/*;AN000;6*/
91 usererror(INVALIDPARM); /*;AC000;4*/
94 /* Check for same source and target drive */
95 if (com_toupper(*argv[1]) == com_toupper(*argv[2]) /*;AN000;4*/
96 && (BYTE)*(argv[1]+1) == ':' /*;AN000;4*/
97 && (BYTE)*(argv[1]+2) == NUL /*;AN000;4*/
98 && (BYTE)*(argv[2]+1) == ':' /*;AN000;4*/
101 display_it(SOURCE_TARGET_SAME,STND_ERR_DEV,0,NO_RESPTYPE,(BYTE)UTIL_MSG);/*;AN000;6*/
102 usererror(INVALIDPARM); /*;AC000;4*/
105 /* Initialize parser data structures */
106 parse_init(); /*;AN000;4*/
108 inregs.x.si = (WORD)&cmd_line[0]; /*DS:SI*/ /*;AN000;4 make DS:SI point to source */
109 inregs.x.cx = 0; /*;AN000;4*/
111 /*********************/
112 /* PARSE LOOP !!!!!! */
113 /*********************/
114 while (not_finished) /*;AN000;4 For all strings in command line */
116 inregs.x.dx = 0; /*;AN000;4 RESERVED */
117 inregs.x.di = (WORD)&parms; /*ES:DI*/ /*;AN000;4 address of parm list */
118 parse(&inregs,&outregs); /*;AN000;4 Call DOS PARSE service routines*/
120 x=0; /* Save the parsed parameter */ /*;AN004;*/
121 for (inregs.x.si; inregs.x.si<outregs.x.si; inregs.x.si++) /*;AN004;*/
123 curr_parm[x] = *(char *)inregs.x.si; /*;AN004;*/
127 curr_parm[x] = NUL; /*;AN004;*/
129 inregs = outregs; /* Reset registers */ /*;AN000;4 Reset registers*/
131 /* Check for PARSE ERROR*/
132 if (outregs.x.ax != (WORD)NOERROR) /*;AN000;4*/
134 if (outregs.x.ax==(WORD)EOL) /* Was it End of line? */ /*;AN000;4*/
135 not_finished = FFALSE; /*;AN000;4*/
137 { /* It was an error */ /*;AN000;4*/
138 not_finished = FFALSE; /*;AN000;4*/
139 parse_error(outregs.x.ax,(BYTE)PARSEERR); /*;AN000;4*//*;AC002;*/
143 if (not_finished) /* Parse was successful !*/ /*;AN000;4*/
145 if ( outregs.x.dx == (WORD)&time_buff || /*;AN000;4*/
146 outregs.x.dx == (WORD)&date_buff || /*;AN000;4*/
147 outregs.x.dx == (WORD)&sw_buff /*;AN000;4*/
149 process_switch(outregs.x.dx,argv[parse_count]); /*;AN000;4*//*;AC002;*/
152 parse_count++; /*;AN000;4*//*;AC002;*/
153 } /* End WHILE Parse loop */ /*;AN000;4*/
155 /* Check source and target filespec */
156 if (strlen(argv[2]) >= 5) /*;AN000;p2591*/
157 check_for_device_names(argv); /*;AN000;p2591*/
159 check_source_drive(argc,argv); /*;AN000;4*/
160 check_target_filespec(argc,argv); /*;AN000;4*/
163 } /* end parser */ /*;AN000;4*/
165 /**
\f***********************************************/
167 /* SUBROUTINE NAME: parse_error
171 /* There was a parse error. Display message and die
173 /**************************************************/
174 void parse_error(msg_num,class) /*;AN000;4*//*;AC002;*/
175 WORD msg_num; /*;AN000;4*/
176 BYTE class; /*;AN000;4*/
178 sublist.value1 = &curr_parm[0]; /*;AN002;*/
179 sublist.flags1 = LEFT_ALIGN + CHAR_FIELD_ASCIIZ; /*;AN002;*/
180 sublist.one = 0; /*;AN002;*/
181 sublist.max_width1 = (BYTE)strlen(curr_parm); /*;AN002;*/
182 sublist.min_width1 = sublist.max_width1; /*;AN002;*/
185 if (msg_num == NO_SOURCE || msg_num == NO_TARGET) /*;AN000;6*/
186 display_it(msg_num,STND_ERR_DEV,0,NO_RESPTYPE,class); /*;AN000;6*/
188 display_it(msg_num,STND_ERR_DEV,1,NO_RESPTYPE,class); /*;AN000;6*/
191 usererror(INVALIDPARM); /*;AN000;4*//*;AC002;*/
195 /**
\f***********************************************/
197 /* SUBROUTINE NAME: check_date
201 /* A date parameter was entered. Validate it
203 /**************************************************/
204 void check_date(year,month,day) /*;AN000;4*//*;AC002;*/
205 WORD year; /*;AN000;4*/
206 BYTE month; /*;AN000;4*/
207 BYTE day; /*;AN000;4*/
209 if (year > 2099 || year < 1980) /*;AC000;4*/
210 parse_error(INV_DATE,(BYTE)UTILMSG); /*;AC000;4*//*;AC002;*/
212 if (month > 12 || month < 1) /*;AC000;4*/
213 parse_error(INV_DATE,(BYTE)UTILMSG); /*;AC000;4*//*;AC002;*/
215 if (day > 31 || month < 1) /*;AC000;4*/
216 parse_error(INV_DATE,(BYTE)UTILMSG); /*;AC000;4*//*;AC002;*/
218 /* Verify day not greater then 30 if Apr,Jun,Sep,Nov */
219 if ((day>30) && (month==4 || month==6 || month==9 || month==11)) /*;AC000;4*/
220 parse_error(INV_DATE,(BYTE)UTILMSG); /*;AC000;4*//*;AC002;*/
222 if (month == 2) /* Deal with February */ /*;AC000;4*/
224 if (day > 29) /* if Feb 30 or above */ /*;AC000;4*/
225 parse_error(INV_DATE,(BYTE)UTILMSG); /*;AC000;4*//*;AC002;*/
227 if ((year % 4) != 0) /* If not a leap year */ /*;AC000;4*/
228 if (day > 28) /* if Feb 29 or above */ /*;AC000;4*/
229 parse_error(INV_DATE,(BYTE)UTILMSG); /*;AC000;4*//*;AC002;*/
234 /**
\f***********************************************/
236 /* SUBROUTINE NAME: check_time
240 /* A time parameter was entered. Validate it
242 /**************************************************/
243 void check_time(hours,minutes,seconds,hundreds) /*;AN000;4*//*;AC002;*/
244 BYTE hours; /*;AN000;4*/
245 BYTE minutes; /*;AN000;4*/
246 BYTE seconds; /*;AN000;4*/
247 BYTE hundreds; /*;AN000;4*/
250 if (hours > 23 || hours < 0) /*;AC000;4*/
251 parse_error(INV_TIME,(BYTE)UTILMSG); /*;AC000;4*//*;AC002;*/
253 if (minutes >= 60 || minutes < 0) /*;AC000;4*/
254 parse_error(INV_TIME,(BYTE)UTILMSG); /*;AC000;4*//*;AC002;*/
256 if (seconds >= 60 || seconds < 0) /*;AC000;4*/
257 parse_error(INV_TIME,(BYTE)UTILMSG); /*;AC000;4*//*;AC002;*/
262 /**
\f***********************************************/
264 /* SUBROUTINE NAME: parse_init
268 /* Initialize the parser data structures
270 /**************************************************/
271 #define SSTRING 0x2000 /*;AN000;4*/
272 #define FILESPEC 0x0200 /*;AN000;4 */
273 #define CAP_FILETABLE 0x0001 /*;AN000;4 */
274 #define DRIVELETTER 0x100; /*;AN000;4 */
275 #define DATESTRING 0x1000 /*;AN000;4 */
276 #define TIMESTRING 0x0800 /*;AN000;4 */
278 void parse_init() /*;AN000;4 */
280 { /* Initialize PARMS data structure */ /*;AN000;4 */
281 parms.parmsx_ptr = (WORD)&parmsx; /*;AN000;4 */
282 parms.p_num_extra = 1; /*;AN000;4 */
283 parms.p_len_extra_delim = 1; /*;AN000;4 */
284 parms.p_extra_delim[0] = ';'; /*;AN000;4 */
285 parms.p_extra_delim[1] = NUL; /*;AN000;4 */
287 /* Initialize PARMSX data structure */
288 parmsx.p_minpos= 2; /*;AN000;4 */
289 parmsx.p_maxpos= 2; /*;AN000;4 */
290 parmsx.pos1_ptr= (WORD)&pos1; /*;AN000;4 */
291 parmsx.pos2_ptr= (WORD)&pos2; /*;AN000;4 */
292 parmsx.num_sw = 3; /*;AN000;4 */
293 parmsx.sw1_ptr = (WORD)&sw1; /*;AN000;4 */
294 parmsx.sw2_ptr = (WORD)&sw2; /*;AN000;4 */
295 parmsx.sw3_ptr = (WORD)&sw3; /*;AN000;4 */
296 parmsx.num_keywords = 0; /*;AN000;4 */
298 /* Initialize POS1 (Source Drive) data structure */
299 pos1.match_flag = FILESPEC; /*;AN000;4 */
300 pos1.function_flag = 0; /*;AN000;4 */
301 pos1.result_buf = (WORD)&pos_buff; /*;AN000;4 */
302 pos1.value_list = (WORD)&noval; /*;AN000;4 */
303 pos1.nid = 0; /*;AN000;4 */
305 /* Initialize POS2 (Target FILESPEC) data structure */
306 pos2.match_flag = SSTRING; /*;AN000;4 */
307 pos2.function_flag = 0; /*;AN000;4 */
308 pos2.result_buf = (WORD)&pos_buff; /*;AN000;4 */
309 pos2.value_list = (WORD)&noval; /*;AN000;4 */
310 pos2.nid = 0; /*;AN000;4 */
312 /* Initialize SW1 data structure */
313 sw1.p_match_flag = DATESTRING; /*;AN000;4 */
314 sw1.p_function_flag = 0; /*;AN000;4 */
315 sw1.p_result_buf = (WORD)&date_buff; /*;AN000;4 */
316 sw1.p_value_list = (WORD)&noval; /*;AN000;4 */
317 sw1.p_nid = 2; /*;AN000;4 */
318 strcpy(sw1.switch1,"/B"); /*;AN000;4 */
319 strcpy(sw1.switch2,"/A"); /*;AN000;4 */
321 /* Initialize SW2 data structure */
322 sw2.p_match_flag = TIMESTRING; /*;AN000;4 */
323 sw2.p_function_flag = 0; /*;AN000;4 */
324 sw2.p_result_buf = (WORD)&time_buff; /*;AN000;4 */
325 sw2.p_value_list = (WORD)&noval; /*;AN000;4 */
326 sw2.p_nid = 2; /*;AN000;4 */
327 strcpy(sw2.switch1,"/E"); /*;AN000;4 */
328 strcpy(sw2.switch2,"/L"); /*;AN000;4 */
331 /* Initialize SW3 data structure */
332 sw3.p_match_flag = 0; /*;AN000;4 */
333 sw3.p_function_flag = 0; /*;AN000;4 */
334 sw3.p_result_buf = (WORD)&sw_buff; /*;AN000;4 */
335 sw3.p_value_list = (WORD)&noval; /*;AN000;4 */
336 sw3.p_nid = 4; /*;AN000;4 */
337 strcpy(sw3.switch1,"/S"); /*;AN000;4 */
338 strcpy(sw3.switch2,"/P"); /*;AN000;4 */
339 strcpy(sw3.switch3,"/M"); /*;AN000;4 */
340 strcpy(sw3.switch4,"/N"); /*;AN000;4 */
342 /*********************************************/
343 /* Also initialize all time and date values */
344 /*********************************************/
346 td.earlier_minute = 0;
347 td.earlier_second = 0;
358 /**************************************************/
359 /* Also initialize the message substitution list */
360 /**************************************************/
361 sublist.sl_size1= SUBLIST_SIZE; /*;AN000;6*/
362 sublist.sl_size2= SUBLIST_SIZE; /*;AN000;6*/
363 sublist.one = 1; /*;AN000;6*/
364 sublist.two = 2; /*;AN000;6*/
365 sublist.zero1 = 0; /*;AN000;6*/
366 sublist.zero2 = 0; /*;AN000;6*/
367 sublist.pad_char1 = ' '; /*;AN000;6*/
368 sublist.pad_char2 = ' '; /*;AN000;6*/
370 return; /*;AN000;4 */
374 /**
\f***********************************************/
376 /* SUBROUTINE NAME: check_for_device_names
380 /* Make sure user not trying to restore a reserved device name
382 /**************************************************/
383 void check_for_device_names(argv) /*;AN000;p2591*/
384 char *argv[]; /*;AN000;p2591*/
386 union REGS qregs; /*;AN000;p2591*/
387 char target[128]; /*;AN000;p2591*/
388 char *t; /*;AN000;p2591*/
390 #define CAPITALIZE_STRING 0x6521 /*;AN000;p2591*/
392 qregs.x.ax = CAPITALIZE_STRING; /*;AN000;p2591*/
393 qregs.x.dx = (WORD)argv[2]; /*;AN000;p2591*/
394 strcpy(target,argv[2]); /*;AN000;p2591*/
395 qregs.x.cx = strlen(target); /*;AN000;p2591*/
396 intdos(&qregs,&qregs); /*;AN000;p2591*/
397 strcpy(target,argv[2]); /*;AN000;p2591*/
399 for (t=&target[0]; *t!=NUL; t++)
401 ( strcmp(t,"LPT1")==0 || /*;AN000;p2591*/
402 strcmp(t,"LPT2")==0 || /*;AN000;p2591*/
403 strcmp(t,"PRN")==0 || /*;AN000;p2591*/
404 strcmp(t,"CON")==0 || /*;AN000;p2591*/
405 strcmp(t,"NUL")==0 || /*;AN000;p2591*/
406 strcmp(t,"AUX")==0 || /*;AN000;p2591*/
407 strcmp(t,"LPT1:")==0 || /*;AN000;p2591*/
408 strcmp(t,"LPT2:")==0 || /*;AN000;p2591*/
409 strcmp(t,"PRN:")==0 || /*;AN000;p2591*/
410 strcmp(t,"CON:")==0 || /*;AN000;p2591*/
411 strcmp(t,"NUL:")==0 || /*;AN000;p2591*/
412 strcmp(t,"AUX:")==0 /*;AN000;p2591*/
415 sublist.value1 = (char far *)t; /*;AN000;p2591*/
416 sublist.flags1 = LEFT_ALIGN + CHAR_FIELD_ASCIIZ; /*;AN000;p2591*/
417 sublist.one = 0; /*;AN000;p2591*/
418 sublist.max_width1 = (BYTE)strlen(t); /*;AN000;p2591*/
419 sublist.min_width1 = sublist.max_width1; /*;AN000;p2591*/
421 display_it(INVPARM,STND_ERR_DEV,1,NO_RESPTYPE,(BYTE)PARSEERROR);/*;AN000;p2591*/
422 usererror(INVALIDPARM); /*;AN000;p2591*/
426 return; /*;AN000;p2591*/
429 /**
\f***********************************************/
431 /* SUBROUTINE NAME: check_source_drive
435 /* Verify drive letter and start building srcddir
437 /**************************************************/
438 void check_source_drive(argc,argv) /*;AN000;4*/
439 int argc; /*;AN000;4*/
440 char *argv[]; /*;AN000;4*/
442 WORD retcode; /*;AC000;*/
450 union REGS qregs; /*;AN000;8*/
452 *argv[1]=(BYTE)com_toupper(*argv[1]); /*;AN000;4*/
455 *argv[1] < 'A' || /*;AN000;4*/
456 *argv[1] > 'Z' || /*;AN000;4*/
457 *(argv[1]+1)!=':' || /*;AN000;4*/
458 *(argv[1]+2)!=NUL /*;AN000;4*/
461 display_it(INVALID_DRIVE,STND_ERR_DEV,0,NO_RESPTYPE,(BYTE)UTIL_MSG);/*;AN000;6*/
462 usererror(INVALIDDRIVE); /*;AN000;4*/
465 srcd = (BYTE)*argv[1]; /*;AN000;4*/
466 srcddir[0] = srcd; /*;AN000;4*/
467 srcddir[1] = ':'; /*;AN000;4*/
468 srcddir[2] = NUL; /*;AN000;4*/
470 /***********************************************************************/
471 /* dosopen to find out whether the src drive exist */
472 /* and dosdevioctl to find out whether it is a removable drive */
473 /***********************************************************************/
474 retcode = /*;AC000;4*/
476 ( (char far *)&srcddir[0], /*;AC000;4*/
477 (unsigned far *)&device_handle, /*;AC000;4*/
478 (unsigned far *)&action, /*;AC000;4*/
479 (DWORD)0, /*file size*/ /*;AC000;4*/
480 0, /*file attribute*/ /*;AC000;4*/
481 0x01, /*if file exist, open it*/ /*;AC000;4*/
482 /*if file not exist, fail it*//*;AC000;4*/
483 0x80c2, /*deny write, read only*/ /*;AC000;4*/
484 (DWORD)0 /*reserved*/ /*;AC000;4*/
487 if (retcode != NOERROR) /*;AC000;4*/
489 display_it(INVALID_DRIVE,STND_ERR_DEV,0,NO_RESPTYPE,(BYTE)UTIL_MSG);/*;AN000;6*/
490 usererror(INVALIDDRIVE); /*;AC000;4*/
493 /************************************/ /*;AC000;4*/
494 /* See if source drive is removable */ /*;AC000;4*/
495 /************************************/ /*;AC000;4*/
496 retcode = /*;AC000;4*/
497 DOSDEVIOCTL /*;AC000;4*/
498 ( (char far *)&media_type, /*;AC000;4*/
499 (char far *)&parm, /*;AC000;4*/
502 device_handle /*;AC000;4*/
505 if (retcode != NOERROR) /*;AC000;4*/
506 { display_it(INVALID_DRIVE,STND_ERR_DEV,0,NO_RESPTYPE,(BYTE)UTIL_MSG);/*;AN000;6*/
507 usererror(INVALIDDRIVE); /*;AC000;4*/
510 #define REMOVABLE 0 /*;AC000;4*/
511 if (media_type != REMOVABLE) /*;AC000;4*/
512 set_reset_test_flag(&control_flag2,SRC_HDISK,SET); /*;AC000;4*/
514 else /* Source disk is removable */ /*;AC000;4*/
516 temp_array1[0] = (BYTE)((dnumwant / 10) + '0'); /*;AC000;4*/
517 temp_array1[1] = (BYTE)((dnumwant % 10) + '0'); /*;AC000;4*/
518 temp_array1[2] = NUL; /*;AC000;4*/
519 temp_array2[0] = srcd; /*;AC000;4*/
520 temp_array2[1] = NUL; /*;AC000;4*/
522 sublist.value1 = (char far *)temp_array1; /*;AN000;6*/
523 sublist.flags1 = LEFT_ALIGN + CHAR_FIELD_ASCIIZ; /*;AN000;6*/
524 sublist.max_width1 = (BYTE)strlen(temp_array1); /*;AN000;6*/
525 sublist.min_width1 = sublist.max_width1; /*;AN000;6*/
527 sublist.value2 = (char far *)temp_array2; /*;AN000;6*/
528 sublist.flags2 = LEFT_ALIGN + CHAR_FIELD_ASCIIZ; /*;AN000;6*/
529 sublist.max_width2 = (BYTE)strlen(temp_array2); /*;AN000;6*/
530 sublist.min_width2 = sublist.max_width2; /*;AN000;6*/
532 display_it(INSERT_SOURCE_DISK,STND_ERR_DEV,2,NO_RESPTYPE,(BYTE)UTIL_MSG); /*;AN000;6*/
533 display_it(PRESS_ANY_KEY,STND_ERR_DEV,0,ANY_KEY_RESPTYPE,(BYTE)UTIL_MSG); /*;AN000;6*/
535 /* If single drive system, eliminates double prompting */
536 /* for user to "Insert diskette for drive %1" */
537 qregs.x.ax = SETLOGICALDRIVE; /*;AN000;8*/
538 qregs.h.bl = srcddir[0] - 'A' + 1; /*;AN000;8*/
539 intdos(&qregs,&qregs); /*;AN000;8*/
545 /**
\f***********************************************/
547 /* SUBROUTINE NAME: check_target_filespec
551 /* Verify the target filespec.
552 /* 1. Validate destination drive, or use default if none specified
553 /* 2. Validate path, or use current dir if not specified
554 /* 3. Validate the file name
556 /**************************************************/
557 void check_target_filespec(argc,argv) /*;AN000;4*/
558 int argc; /*;AN000;4*/
559 char *argv[]; /*;AN000;4*/
561 WORD retcode; /*;AC000;*/
567 BYTE temp_destddir[MAXPATH+2];
570 WORD default_drive_num;
572 WORD dirlen = MAXPATH;
573 BYTE tdestddir[MAXPATH+3];
574 BYTE ttdestddir[MAXPATH+3];
576 BYTE argv2_has_switch;
577 BYTE search_string[MAXPATHF+2];
583 union REGS qregs; /*;AN000;8*/
586 /**************************/
587 /* Uppercase the string */
588 /**************************/
589 #define CAPITALIZE_STRING 0x6521 /*;AN000;p????*/
591 qregs.x.ax = CAPITALIZE_STRING; /*;AN000;p????*/
592 qregs.x.dx = (WORD)argv[2]; /*;AN000;p????*/
593 strcpy(tempp,argv[2]); /*;AN000;p????*/
594 qregs.x.cx = strlen(tempp); /*;AN000;p????*/
595 intdos(&qregs,&qregs); /*;AN000;p????*/
598 /***************************************************/
599 /* If no drive letter specified, use current drive */
600 /***************************************************/
602 *(argv[2]+1)!=':' || /*;AC000;4*/
603 *argv[2] < 'A' || /*;AC000;4*/
604 *argv[2] > 'Z' /*;AC000;4*/
607 DOSQCURDISK /*;AC000;4*/
608 ( (unsigned far *)&default_drive_num, /*;AC000;4*/
609 (DWORD far *) &drive_map /*;AC000;4*/
611 destd = (BYTE)(default_drive_num + 'A' - 1); /*;AC000;4*/
614 { /* User specified the destination drive*/ /*;AC000;4*/
615 destd = (BYTE)*argv[2]; /*;AC000;4*/
616 argv[2] = argv[2] + 2; /*;AC000;4*/
619 destddir[0] = destd; /*;AC000;4*/
620 destddir[1] = ':'; /*;AC000;4*/
621 destddir[2] = NUL; /*;AC000;4*/
623 /***********************************************************************/
624 /* if source drive and destination drive are the same, output error msg*/
625 /***********************************************************************/
626 if (srcd == destd) /*;AC000;4*/
628 display_it(SOURCE_TARGET_SAME,STND_ERR_DEV,0,NO_RESPTYPE,(BYTE)UTIL_MSG);/*;AN000;6*/
629 usererror(INVALIDPARM); /*;AC000;4*/
632 /***********************************************************************/
633 /* dosopen to find out whether the destination drive is exist */
634 /* and dosdevioctl to find out whether it is a removable drive */
635 /***********************************************************************/
637 retcode = /*;AC000;4*/
639 ( (char far *)&destddir[0], /*;AC000;4*/
640 (unsigned far *)&device_handle, /*;AC000;4*/
641 (unsigned far *)&action, /*;AC000;4*/
642 (DWORD)0, /*file size*/ /*;AC000;4*/
643 0, /*file attribute*/ /*;AC000;4*/
644 0x01, /*if file exist, open it*/ /*;AC000;4*/
645 /*if file not exist, fail it*/ /*;AC000;4*/
646 0x80c2, /*deny write, read only*/ /*;AC000;4*/
647 (DWORD)0 /*reserved*/ /*;AC000;4*/
650 if (retcode != NOERROR)/*if open fail*/ /*;AC000;4*/
652 display_it(INVALID_DRIVE,STND_ERR_DEV,0,NO_RESPTYPE,(BYTE)UTIL_MSG);/*;AN000;6*/
653 usererror(INVALIDDRIVE); /*;AC000;4*/
656 /************************************/ /*;AC000;4*/
657 /* See if target drive is removable */ /*;AC000;4*/
658 /************************************/ /*;AC000;4*/
659 retcode = /*;AC000;4*/
660 DOSDEVIOCTL /*;AC000;4*/
661 ( (char far *)&media_type, /*;AC000;4*/
662 (char far *)&parm, /*;AC000;4*/
665 device_handle /*;AC000;4*/
668 if (retcode != NOERROR) /*;AC000;4*/
669 { display_it(INVALID_DRIVE,STND_ERR_DEV,0,NO_RESPTYPE,(BYTE)UTIL_MSG);/*;AN000;6*/
670 usererror(INVALIDDRIVE); /*;AC000;4*/
673 if (media_type == REMOVABLE) /*;AC000;4*/
674 { temp_array1[0] = destd; /*;AC000;4*/
675 temp_array1[1] = NUL; /*;AC000;4*/
676 sublist.value1 = (char far *)temp_array1; /*;AN000;6*/
677 sublist.flags1 = LEFT_ALIGN + CHAR_FIELD_ASCIIZ; /*;AN000;6*/
678 sublist.max_width1 = (BYTE)strlen(temp_array1); /*;AN000;6*/
679 sublist.min_width1 = sublist.max_width1; /*;AN000;6*/
681 display_it(INSERT_TARGET_DISK,STND_ERR_DEV,1,NO_RESPTYPE,(BYTE)UTIL_MSG); /*;AN000;6*/
682 display_it(PRESS_ANY_KEY,STND_ERR_DEV,0,ANY_KEY_RESPTYPE,(BYTE)UTIL_MSG); /*;AN000;6*/
685 /* If single drive system, eliminates double prompting */
686 /* for user to "Insert diskette for drive %1" */
687 qregs.x.ax = SETLOGICALDRIVE; /*;AN000;8*/
688 qregs.h.bl = destddir[0] - 'A' + 1; /*;AN000;8*/
689 intdos(&qregs,&qregs); /*;AN000;8*/
691 /**********************************************************************/
692 /* save current directory of destination disk to be reset back later */
693 /**********************************************************************/
695 destd_num = (WORD) (destd - 'A' +1); /*;AC000;4*/
697 /* get current directory of destd_num (DosQCurDir) */
698 if ((retcode = /*;AC000;4*/
699 DOSQCURDIR /*;AC000;4*/
700 ( destd_num, /*;AC000;4*/
701 (char far *) tdestddir, /*;AC000;4*/
702 (unsigned far *) &dirlen) /*;AC000;4*/
705 display_it(INVALID_DRIVE,STND_ERR_DEV,0,NO_RESPTYPE,(BYTE)UTIL_MSG);/*;AN000;6*/
706 usererror(INVALIDDRIVE); /*;AC000;4*/
709 #define BACKSLASH 0x5c
711 if (strlen(tdestddir) != 1) /*;AC000;4*/
712 { strcpy(temp_destddir,"\\"); /*;AC000;4*/
713 strcat(temp_destddir,tdestddir); /*;AC000;4*/
714 strcpy(tdestddir,temp_destddir); /*;AC000;4*/
718 /**********************************************************************/
719 /* The next parameter has to be a file name with or without path, */
720 /* or a switch. In the case of there is no path, the current path */
721 /* is used. In the case of there is no file name, the global file */
722 /* name *.* is used */
723 /**********************************************************************/
724 /* argv[2] is a drive spec*/ /*;AC000;4*/
725 if (*(argv[2]+1)==':' && *argv[2] >= 'A' && *argv[2] <= 'Z' && argc!=2) /*;AC000;4*/
727 display_it(INVPARM,STND_ERR_DEV,0,NO_RESPTYPE,(BYTE)PARSEERROR);/*;AN000;6*/
728 usererror(INVALIDPARM); /*;AC000;4*/
731 { /*if argv[2] is not a drive spec */ /*;AC000;4*/
732 /*if argv[2] started with '/' (is a switch) or there is no argv[i]*/ /*;AC000;4*/
733 if (*argv[2] == '/' || *argv[2] == NUL || argc ==2) /*;AC000;4*/
734 { strcpy(srcf,tdestddir); /*;AC000;4*/
735 strcat(srcf,"\\*.*"); /*;AC000;4*/
738 { /*argv[2] does not started with / */ /*;AC000;4*/
739 /* find out whether part of argv[2] is switch specification */ /*;AC000;4*/
740 for (k = 0; argv[2][k] != '/' && argv[2][k] != NUL; ++k);/*;AC000;4*/
741 if (argv[2][k] == '/') /*;AC000;4*/
743 argv[2][k] = NUL; /*;AC000;4*/
744 argv2_has_switch = TRUE; /*;AC000;4*/
747 /*if argv[2] is \\, invalid parm */ /*;AC000;4*/
748 if (argv[2][0] == '\\' && argv[2][1] == '\\' || argv[2][0] == ':') /*;AC000;;4*/
750 display_it(INVPARM,STND_ERR_DEV,0,NO_RESPTYPE,(BYTE)PARSEERROR);/*;AN000;6*/
751 usererror(INVALIDPARM); /*;AC000;4*/
754 /*if argv[2] starts with '\' (it is a complete path)*/ /*;AC000;4*/
755 if (*argv[2] == '\\') /*;AC000;4*/
756 strcpy(srcf,argv[2]); /*;AC000;4*/
758 /* it is not a complete path, have to put current path in */ /*;AC000;;4*/
759 /* front of the string to build a complete path */ /*;AC000;4*/
760 { strcpy(srcf,tdestddir); /*;AC000;4*/
761 if (strlen(tdestddir) != 1) /*;AC000;4*/
762 strcat(srcf,"\\"); /*;AC000;4*/
763 strcat(srcf,argv[2]); /*;AC000;4*/
764 } /*endif*/ /*;AC000;4*/
765 } /*end of argv[2] does not start with '/' */ /*;AC000;4*/
767 j = strlen(srcf); /*;AC000;4*/
770 { for (;srcf[z] != '.' && srcf[z] != NUL; ++z); /*;AC000;4*/
771 if (srcf[z] == '.' && srcf[z+1] == '.' && /*;AC000;4*/
772 (srcf[z+2] == '\\' || srcf[z+2] == NUL)) /*;AC000;4*/
773 { backdir = TRUE; /*;AC000;4*/
776 z = z+1; /*;AC000;4*/
778 while (z < j); /*;AC000;4*/
780 /*validate the path*/ /*;AC000;4*/
781 for (z = j; srcf[z] != '\\'; --z); /*;AC000;4*/
782 strcpy(tempp,srcf); /*;AC000;4*/
783 tempp[z] = NUL; /*;AC000;4*/
785 for (z = 0; tempp[z] != '*' && tempp[z] != NUL; ++z); /*;AC000;4*/
786 if (tempp[z] == '*' ) /*;AC000;4*/
787 { display_it(PATH_NOT_FOUND,STND_ERR_DEV,1,NO_RESPTYPE,(BYTE)UTIL_MSG); /*;AN000;6*/
788 usererror(INVALIDPARM); /*;AC000;4*/
791 if (backdir == TRUE) /*;AC000;4*/
792 { search_string[0] = destd; /*;AC000;4*/
793 search_string[1] = ':'; /*;AC000;4*/
794 search_string[2] = NUL; /*;AC000;4*/
795 if (srcf[0] == NUL) /*;AC000;4*/
796 strcat(search_string,"\\"); /*;AC000;4*/
798 strcat(search_string, tempp); /*;AC000;4*/
800 if(chdir(search_string)!=0) /*;AC000;4*/
801 { sublist.value1 = (char far *)argv[2]; /*;AN000;6*/
802 sublist.flags1 = LEFT_ALIGN + CHAR_FIELD_ASCIIZ; /*;AN000;6*/
803 sublist.max_width1 = (BYTE)strlen(argv[2]); /*;AN000;6*/
804 sublist.min_width1 = sublist.max_width1; /*;AN000;6*/
805 display_it(PATH_NOT_FOUND,STND_ERR_DEV,1,NO_RESPTYPE,(BYTE)UTIL_MSG); /*;AN000;6*/
806 usererror(INVALIDPARM); /*;AC000;4*/
809 dirlen = MAXPATH; /*;AC000;4*/
810 if ((retcode = DOSQCURDIR(destd_num, /*;AC000;4*/
811 (char far *) ttdestddir, /*;AC000;4*/
812 (unsigned far *) &dirlen)) != NOERROR) /*;AC000;4*/
814 com_msg(retcode); /*;AC000;4*/
815 usererror(retcode); /*;AC000;4*/
817 /* endif */ /*;AC000;4*/
819 temp_destddir[0] = destd; /*;AC000;4*/
820 temp_destddir[1] = ':'; /*;AC000;4*/
821 temp_destddir[2] = NUL; /*;AC000;4*/
822 strcat(temp_destddir,tdestddir); /*;AC000;4*/
823 chdir(temp_destddir); /*;AC000;4*/
825 if (strlen(ttdestddir) != 1) /*;AC000;4*/
826 { strcpy(temp_destddir,"\\"); /*;AC000;4*/
827 strcat(temp_destddir,ttdestddir); /*;AC000;4*/
828 strcpy(ttdestddir,temp_destddir); /*;AC000;4*/
831 strcat(ttdestddir,"\\"); /*;AC000;4*/
832 strcat(ttdestddir,srcf+z+1); /*;AC000;4*/
833 strcpy(srcf,ttdestddir); /*;AC000;4*/
834 } /*end of if backdir is true */ /*;AC000;4*/
836 /* The documentation says if path is specified, file name has to */
837 /* be specified also. This logic actually allows user to specify*/
838 /* path without specify filename, as long as the path end with */
840 /*If *srcf ends with '\', add "*.*" to the end*/ /*;AC000;4*/
841 j = strlen(srcf); /*;AC000;4*/
842 if (srcf[j-1] == '\\') /*;AC000;4*/
843 strcat(srcf,"*.*"); /*;AC000;4*/
844 if (argv2_has_switch == TRUE) /*;AC000;4*/
845 { *(argv[2]+k) = '/'; /*;AC000;4*/
846 argv[2] = argv[2] + k; /*;AC000;4*/
847 } /* end of if argv[2] started with '/' */ /*;AC000;4*/
848 } /* end of checking for argv[2] */ /*;AC000;4*/
850 /**********************************************************************/
851 /* add '\' at the beginning of the current destination directory */
852 /**********************************************************************/
853 temp_destddir[0] = destd; /*;AC000;4*/
854 temp_destddir[1] = ':'; /*;AC000;4*/
855 temp_destddir[2] = NUL; /*;AC000;4*/
856 strcat(temp_destddir,tdestddir); /*;AC000;4*/
857 strcpy(destddir,temp_destddir); /*;AC000;4*/
859 /************************************************************************/
860 /* separate the filename for search into prefix(inpath), */
861 /* filename(infname), and file extension (infext) */
862 /* Also take care of the situation that user enter '.' only */
864 /************************************************************************/
865 separate(srcf,inpath,infname,infext,infspec); /*;AC000;4*/
866 if (strlen(infname) > MAXFNAME-1 || /*;AC000;4*/
867 strlen(infext) > MAXFEXT-1 || /*;AC000;4*/
868 strlen(inpath) > MAXPATH-1 || /*;AC000;4*/
869 strcmp(infspec,"LPT1")==0 || /*;AC000;4*/
870 strcmp(infspec,"LPT2")==0 || /*;AC000;4*/
871 strcmp(infspec,"PRN")==0 || /*;AC000;4*/
872 strcmp(infspec,"CON")==0 || /*;AC000;4*/
873 strcmp(infspec,"NUL")==0 || /*;AC000;4*/
874 strcmp(infspec,"AUX")==0 || /*;AC000;4*/
875 strcmp(infspec,"LPT1:")==0 || /*;AC000;4*/
876 strcmp(infspec,"LPT2:")==0 || /*;AC000;4*/
877 strcmp(infspec,"PRN:")==0 || /*;AC000;4*/
878 strcmp(infspec,"CON:")==0 || /*;AC000;4*/
879 strcmp(infspec,"NUL:")==0 || /*;AC000;4*/
880 strcmp(infspec,"AUX:")==0 ) /*;AC000;4*/
882 sublist.value1 = (char far *)&infspec[0]; /*;AN000;6*/
883 sublist.flags1 = LEFT_ALIGN + CHAR_FIELD_ASCIIZ; /*;AN000;6*/
884 sublist.one = 0; /* Yes, this is right */ /*;AN000;6*/
885 sublist.max_width1 = (BYTE)strlen(infspec); /*;AN000;6*/
886 sublist.min_width1 = sublist.max_width1; /*;AN000;6*/
888 display_it(INVPARM,STND_ERR_DEV,1,NO_RESPTYPE,(BYTE)PARSEERROR);/*;AN000;6*/
889 usererror(INVALIDPARM); /* invalid parm */ /*;AC000;4*/
892 /************************************************************************/
893 /* set wildcard flag according to whether there is '*' or/and '?' in */
894 /* file specification */
895 /************************************************************************/
896 c = infspec; /*;AC000;4*/
897 while (*c) /*;AC000;4*/
899 if (*c == '*' || *c == '?') /*;AC000;4*/
900 { set_reset_test_flag(&control_flag,WILDCARD,SET); /*;AC000;4*/
904 c = c+1; /*;AC000;4*/
911 /**
\f***********************************************/
913 /* SUBROUTINE NAME: process_switch
917 /* Identify the switch (/S,/P,/M,/N,/B:,/A:,/E:,/L:)
918 /* entered and handle it
920 /**************************************************/
921 void process_switch(buff_addr,ptr) /*;AN000;4*//*;AC002;*/
922 unsigned buff_addr; /*;AN000;4*/
923 char *ptr; /*;AN002;*/
926 if (buff_addr == (unsigned)&sw_buff) /*;AN000;4*/
928 if (sw_buff.sw_synonym_ptr == (WORD)&sw3.switch1[0]) /*;AN000;4 /S */
929 {set_reset_test_flag(&rtswitch, SUB, SET); /*;AN000;4*/
932 if (sw_buff.sw_synonym_ptr == (WORD)&sw3.switch2[0]) /*;AN000;4 /P */
934 set_reset_test_flag(&rtswitch, PROMPT, SET); /*;AN000;4*/
935 set_reset_test_flag(&control_flag, SWITCHES, SET); /*;AN000;4*/
938 if (sw_buff.sw_synonym_ptr == (WORD)&sw3.switch3[0]) /*;AN000;4 /M */
940 set_reset_test_flag(&rtswitch, Revised, SET); /*;AN000;4*/
941 set_reset_test_flag(&control_flag, SWITCHES, SET); /*;AN000;4*/
944 if (sw_buff.sw_synonym_ptr == (WORD)&sw3.switch4[0]) /*;AN000;4 /N */
946 set_reset_test_flag(&rtswitch, NOTEXIST, SET); /*;AN000;4*/
947 set_reset_test_flag(&control_flag, SWITCHES, SET); /*;AN000;4*/
952 if (buff_addr == (unsigned)&time_buff) /*;AN000;4*/
954 check_time(time_buff.hours,time_buff.minutes,time_buff.seconds,time_buff.hundreds); /*;AN000;4*//*;AC002;*/
956 if (time_buff.tb_synonym_ptr == (WORD)&sw2.switch1[0]) /*;AN000;4 /E */
958 td.earlier_hour = time_buff.hours; /*;AN000;4*/
959 td.earlier_minute = time_buff.minutes; /*;AN000;4*/
960 td.earlier_second = time_buff.seconds; /*;AN000;4*/
961 set_reset_test_flag(&rtswitch, EARLIER, SET); /*;AN000;4*/
962 set_reset_test_flag(&control_flag, SWITCHES, SET); /*;AN000;4*/
965 if (time_buff.tb_synonym_ptr == (WORD)&sw2.switch2[0]) /*;AN000;4 /L */
967 td.later_hour = time_buff.hours; /*;AN000;4*/
968 td.later_minute = time_buff.minutes; /*;AN000;4*/
969 td.later_second = time_buff.seconds; /*;AN000;4*/
970 set_reset_test_flag(&rtswitch, LATER, SET); /*;AN000;4*/
971 set_reset_test_flag(&control_flag, SWITCHES, SET); /*;AN000;4*/
977 if (buff_addr == (unsigned)&date_buff) /*;AN000;4*/
979 check_date(date_buff.year,date_buff.month,date_buff.day); /*;AN000;4*//*;AC002;*/
981 if (date_buff.db_synonym_ptr == (WORD)&sw1.switch1[0]) /*;AN000;4 /B */
983 td.before_year = date_buff.year; /*;AN000;4*/
984 td.before_month = date_buff.month; /*;AN000;4*/
985 td.before_day = date_buff.day; /*;AN000;4*/
986 set_reset_test_flag(&rtswitch, BEFORE, SET); /*;AN000;4*/
987 set_reset_test_flag(&control_flag, SWITCHES, SET); /*;AN000;4*/
990 if (date_buff.db_synonym_ptr == (WORD)&sw1.switch2[0]) /*;AN000;4 /A */
992 td.after_year = date_buff.year; /*;AN000;4*/
993 td.after_month = date_buff.month; /*;AN000;4*/
994 td.after_day = date_buff.day; /*;AN000;4*/
995 set_reset_test_flag(&rtswitch, AFTER, SET); /*;AN000;4*/
996 set_reset_test_flag(&control_flag, SWITCHES, SET); /*;AN000;4*/
1001 return; /*;AN000;4*/