2 /*-------------------------------
3 /* SOURCE FILE NAME: RTOLD1.C
4 /*-------------------------------
10 #include "restpars.h" /*;AN000;4*/
12 #include "dos.h" /*;AN000;2*/
13 #include "comsub.h" /* common subroutine def'n */
19 extern BYTE control_flag;
20 extern BYTE control_flag2;
21 extern char far *buf_pointer;
22 extern unsigned src_file_handle;
23 extern struct FileFindBuf filefindbuf;
24 extern struct FileFindBuf dfilefindbuf;
25 BYTE src_fname[MAXFNAME];
26 extern struct subst_list sublist; /*;AN000;6 Message substitution list */
27 extern char response_buff[5]; /*;AN000;6*/
28 struct file_header_old fheadold; /*;AN000;*/
30 /***************** START OF SPECIFICATION ********************************
32 /* SUBROUTINE NAME : pathmatch
34 /* DESCRIPTIVE NAME : Compare two paths and return TRUE or FALSE
35 /* according to whether they match or not.
37 /* NOTES: Global characters * and ? are meaningless in the file path name
38 /* Assume both path pattern and path subject are not end with \
40 /* INPUT: (PARAMETERS)
41 /* subject - the file path to be compared.
42 /* pattern - the file path to be compared against.
44 /********************** END OF SPECIFICATIONS *******************************/
45 WORD pathmatch(patterns,subjects)
47 BYTE *patterns; /* the string to be matched with */
48 BYTE *subjects; /* the string to be matched */
50 BYTE *pattern; /* the working pointer to point to the pattern */
51 BYTE *subject; /* the working pointer to point to the subject */
54 /*save the pointers to both strings*/
58 /* loop until matched or unmatched is determined */
61 if (*pattern == *subject)
63 if (*pattern != NULLC) /* not finish scanning yet*/
65 pattern+=1; /* advance the pointer by 1 */
66 subject+=1; /* advance the pointer by 1 */
67 continue; /* continue on comparing again */
73 { /* if subject is longer than pattern and SUB flag in rtswitches is on */
74 if (set_reset_test_flag(&rtswitch, SUB, TEST)==TRUE)
76 if ((*pattern == NULLC && *subject == '\\') ||
77 (patterns[0] == '\\' && patterns[1] == NULLC))
86 return(TRUE); /*;AN000;*/
89 /***************** START OF SPECIFICATION ********************************
91 /* SUBROUTINE NAME : fspecmatch
93 /* DESCRIPTIVE NAME : Compare two file spec. and return TRUE or FALSE
94 /* according to whether they match or not.
96 /* FUNCTION: This subroutine compare the file names and file extensions
97 /* to determine whether they are match or not.
98 /* TRUE is returned if they are match, otherwise, FALSE
101 /* NOTES: * and ? are acceptable in the file name and file extension.
103 /********************** END OF SPECIFICATIONS *******************************/
104 fspecmatch(patterns, subjects)
119 /*advance pointer in pattern until find '.' or nullc*/
120 for (;*pattern != '.' && *pattern != NULLC; ++pattern);
121 if (*pattern == NULLC)
124 /* pattern has no extension, so make sure subject doesn't either */
125 /* find end or '.' in subject */
127 for (;*subject != '.' && *subject != NULLC; ++subject);
129 if (*subject == NULLC || *(subject+1) == '.')
131 else /* subject has extension, so return FALSE */
136 if ( *(pattern+1) == '*')
140 /*advance pointer in subject until find '.' or nullc*/
141 for (;*subject != '.' && *subject != NULLC; ++subject);
142 if (*subject == NULLC )
144 if (*(pattern+1) != NULLC)
154 } /*end of if *subject is not NULL*/
155 } /*end of if *(pattern+1) is not '*' */
156 } /*end of if *pattern == NULLC */
160 if (*pattern == *subject || *pattern == '?')
162 if (*pattern != NULLC)
172 if (*pattern == '.' && *(pattern+1) == '*' && *subject == NULLC)
178 } /*end of for loop*/
180 } /*end of subroutine */
182 /***************** START OF SPECIFICATION ********************************
184 /* SUBROUTINE NAME : switchmatch
186 /* DESCRIPTIVE NAME : Check the file attributes, and/or file modes
187 /* against the switches set in the input command
190 /* FUNCTION: this subroutine search the hard disk for the dest
191 /* file first. If dest file is found, the attributs of the
192 /* destination file will be used for checking.
194 /* Check the switches set in the input command line one by
195 /* one, whenever a switch not match is found, FALSE is returne
196 /* In the case a switch is match, TRUE is not returned until al
197 /* switches is checked.
200 /********************** END OF SPECIFICATIONS *******************************/
201 WORD switchmatch(finfo, srcd, destd, td)
202 struct file_info *finfo;
214 unsigned file_pointer;
218 /*declaration for dosqfileinfo*/
219 struct FileStatus fileinfo_buf;
221 WORD buflen = sizeof(struct FileStatus);
224 /*declaration for dosfindfirst */
225 unsigned ddirhandle = 0xffff;
226 unsigned attribute = NOTV;
227 unsigned search_cnt = 1;
228 unsigned buf_len = sizeof(struct FileFindBuf);
229 BYTE search_string[MAXPATHF+2];
230 /*end decleration for ffirst and fnext*/
232 /***********************************************************************/
233 /* Search hard file for the path and name of file about to be restored */
234 /* and get the file information of the file on the hard disk */
235 /***********************************************************************/
236 search_string[0] = destd;
237 search_string[1] = ':';
238 search_string[2] = NULLC;
239 strcat(search_string, finfo->path);
240 if (strlen(finfo->path) != 1)
241 strcat(search_string, "\\");
242 strcat(search_string, finfo->fname);
244 retcode = DOSOPEN( (char far *)&search_string[0],
245 (unsigned far *)&file_pointer,
246 (unsigned far *)&action,
247 (DWORD)0, /*file size*/
248 0, /*file attribute*/
249 0x01, /*if file exist, open*/
250 /*if file not exist, fail*/
251 0x00c0, /*deny write, read write access*/
252 (DWORD)0 ); /*reserved*/
253 /***********************************************************************/
254 /*if open fail (means the file does not exist on the hard disk), then */
256 /***********************************************************************/
257 if (retcode != NOERROR) {
259 set_reset_test_flag(&control_flag,CREATIT,SET);
263 /*********************************************************************/
264 /* call DosQFileInfo: Request date and time of the dest file */
265 /*********************************************************************/
266 retcode = DOSQFILEINFO (
267 (unsigned)file_pointer, /* File handle */
268 (unsigned)1, /* File info data required */
269 (char far *)&fileinfo_buf, /* File info buffer */
270 (unsigned)buflen); /* File info buffer size */
273 if (retcode != NOERROR) {
278 if ((retcode = DOSQFILEMODE((char far *)&search_string[0],
279 (unsigned far *) &attributes,
286 DOSCLOSE(file_pointer);
287 /***********************************************************************/
288 /*if NOTEXIST flag is on */
289 /***********************************************************************/
290 if (set_reset_test_flag(&rtswitch,NOTEXIST,TEST) == TRUE) {
294 /***********************************************************************/
295 /*if BEFORE or AFTER is on, convert date into integer form */
296 /***********************************************************************/
297 if (set_reset_test_flag(&rtswitch,BEFORE,TEST) == TRUE ||
298 set_reset_test_flag(&rtswitch,AFTER,TEST) == TRUE ) {
299 /*convert the input date into correct numbers.*/
300 /*Both new and old format have date in the form of date returned from*/
302 /*the input date is in the form of: yyyyyyymmmmddddd*/
303 yy = (fileinfo_buf.write_date >> YRSHIFT & YRMASK) + LOYR;
304 mm = fileinfo_buf.write_date >> MOSHIFT & MOMASK;
305 dd = fileinfo_buf.write_date & DYMASK;
309 /***********************************************************************/
310 /*if BEFORE flag is on */
311 /***********************************************************************/
312 if (set_reset_test_flag(&rtswitch,BEFORE,TEST) == TRUE) {
313 if ( yy > td->before_year ) {
317 if (yy == td->before_year && mm > td->before_month) {
321 if (yy == td->before_year && mm == td->before_month &&
322 dd > td->before_day) {
328 /***********************************************************************/
329 /*if AFTER flag is on */
330 /***********************************************************************/
331 if (set_reset_test_flag(&rtswitch,AFTER,TEST) == TRUE) {
332 if (yy < td->after_year ) {
336 if (yy == td->after_year && mm < td->after_month) {
340 if (yy == td->after_year && mm == td->after_month && dd < td->after_day) {
346 /***********************************************************************/
347 /*if EARLIER or LATER is on, convert date time into integer form */
348 /***********************************************************************/
349 if (set_reset_test_flag(&rtswitch,EARLIER,TEST) == TRUE ||
350 set_reset_test_flag(&rtswitch,LATER,TEST) == TRUE) {
351 /* convert the input time into correct numbers. */
352 /* Both new and old format have time in the form of date returned */
354 /* the input time is in the form of: hhhhhmmmmmmsssss */
355 hh = fileinfo_buf.write_time >> HRSHIFT & HRMASK;
356 mn = fileinfo_buf.write_time >> MNSHIFT & MNMASK;
357 ss = fileinfo_buf.write_time & SCMASK;
361 /***********************************************************************/
362 /*if EARLIER flag is on */
363 /***********************************************************************/
364 if (set_reset_test_flag(&rtswitch,EARLIER,TEST) == TRUE) {
365 if (hh > td->earlier_hour) {
369 if (hh == td->earlier_hour && mn > td->earlier_minute) {
373 if (hh == td->earlier_hour && mn == td->earlier_minute &&
374 ss > td->earlier_second) {
380 /***********************************************************************/
381 /*if LATER flag is on */
382 /***********************************************************************/
383 if (set_reset_test_flag(&rtswitch,LATER,TEST) == TRUE) {
384 if (hh < td->later_hour) {
388 if (hh == td->later_hour && mn < td->later_minute) {
392 if (hh == td->later_hour && mn == td->later_minute &&
393 ss < td->later_second) {
399 /*************************************************************************/
400 /* if Revised flag is on and fileinfo->attrib indicate file has not */
401 /* been Revised, return FALSE */
402 /*************************************************************************/
403 if (set_reset_test_flag(&rtswitch,Revised,TEST) == TRUE) {
404 if((retcode = attributes & 0x0020) != 0x0020) {
410 /***********************************************************************/
411 /* if PROMPT and fileinfo->file_attrib indicate READONLY, or CHANGED*/
412 /***********************************************************************/
413 if ((set_reset_test_flag(&rtswitch,PROMPT,TEST) == TRUE) &&
414 (((retcode = attributes & 0x0001) == 0x0001) ||
415 ((retcode = attributes & 0x0020) == 0x0020) ))
417 /*call subroutine to ask whether the user really wants to restore */
418 retcode = readonly_or_changed(attributes,destd,finfo->fname,finfo->path);
419 if (retcode == FALSE) {
426 /***********************************************************************/
427 /* if pass all the switch testing, return TRUE */
428 /***********************************************************************/
431 } /*end of subroutine switch_match */
433 /***************** START OF SPECIFICATION ********************************
435 /* SUBROUTINE NAME : check_flheader_old
437 /* DESCRIPTIVE NAME : Check the information in the file header of
438 /* the file to be restored.
440 /* FUNCTION: For old format only, Open the file to be restored, get
444 /********************** END OF SPECIFICATIONS *******************************/
445 int check_flheader_old
446 ( finfo,f_name,f_date,f_time,f_attrib,f_len,
447 file_seq_num,srcd,destd,infspec,inpath,dnumwant
450 struct file_info *finfo;
451 unsigned char *f_name; /* name string */
452 unsigned f_date; /* file's date */
453 unsigned f_time; /* file's time */
454 unsigned f_attrib; /* file's attribute */
455 unsigned long f_len; /* file length */
456 unsigned int file_seq_num;
461 unsigned int *dnumwant;
466 BYTE file_to_be_opened[15];
467 BYTE string_to_be_separate[79];
472 WORD i; /*loop counter*/
476 temp_dnumwant = *dnumwant; /*to fix a bug that dosread change the
480 /***********************************************************************/
481 /*open the file to be restored as deny write and read access */
482 /***********************************************************************/
483 strcpy(src_fname,f_name);
484 file_to_be_opened[0] = srcd;
485 file_to_be_opened[1] = ':';
486 file_to_be_opened[2] = NULLC;
487 strcat(file_to_be_opened,f_name);
488 retcode = DOSOPEN( (char far *)&file_to_be_opened[0],
489 (unsigned far *)&src_file_handle,
490 (unsigned far *)&action,
491 (DWORD)0, /*file size*/
492 0, /*file attribute*/
493 0x01, /*if file exist, open it*/
494 /*if file not exist, fail it*/
495 0x00c0, /*deny write, read only*/
496 (DWORD)0 ); /*reserved*/
500 /****not able to restore the file****/
501 display_it(NOT_ABLE_TO_RESTORE_FILE,STND_ERR_DEV,0,NO_RESPTYPE,(BYTE)UTIL_MSG); /*;AN000;6*/
506 /***********************************************************************/
507 /*read 128 bytes header information from the file into fheadold */
508 /***********************************************************************/
509 retcode = DOSREAD( src_file_handle,
510 (char far *)&fheadold,
512 (unsigned far *)&numread);
516 display_it(NOT_ABLE_TO_RESTORE_FILE,STND_ERR_DEV,0,NO_RESPTYPE,(BYTE)UTIL_MSG); /*;AN000;6*/
519 /*end of if read fail */
521 /*if the number of read is less than HEADLEN, return FALSE */
522 if (numread != HEADLEN)
525 /* save disk number */
526 finfo->dnum = fheadold.disknum[1]* 10 + fheadold.disknum[0];
528 if (fheadold.wherefrom[0] != '\\')
530 strcpy(string_to_be_separate,fheadold.wherefrom);
531 separate(string_to_be_separate,path,name,ext,spec);
533 /***********************************************************************/
534 /* match the path and file spec. */
535 /***********************************************************************/
537 ( pathmatch(inpath,path) == FALSE ||
538 fspecmatch(infspec,spec) == FALSE
541 *dnumwant = temp_dnumwant;
545 /***********************************************************************/
546 /*Store some information from filefindbuf into finfo */
547 /***********************************************************************/
548 finfo->ftime = f_time;
549 finfo->fdate = f_date;
550 finfo->attrib = f_attrib;
551 finfo->partsize = f_len;
553 /***********************************************************************/
554 /*Store filename and path information from fheadold into finfo */
555 /***********************************************************************/
556 strcpy(finfo->fname,spec);
557 strcpy(finfo->path,path);
559 /***********************************************************************/
560 /* store some other information from fheadold to finfo */
561 /***********************************************************************/
562 if (fheadold.headflg == 0xff)
563 finfo->fflag= LAST_PART;
567 *dnumwant = temp_dnumwant;
572 } /*end of subroutine*/
575 /***************** START OF SPECIFICATION ********************************
577 /* SUBROUTINE NAME : readonly_or_changed
579 /* DESCRIPTIVE NAME : handle the situration that a read only file
580 /* or is found, or the file has been Revised.
582 /* FUNCTION: In the case that a readonly file is found, or the file
583 /* on the destination disk has been Revised since last backup,
584 /* this subroutine output a warning message to the user, and
585 /* prompt for user to enter yes or no depending on whether
586 /* the user wants to proceed restoring the file.
589 /********************* END OF SPECIFICATIONS ********************************/
590 #define CHECK_YES_NO 0x6523 /*;AN000;6*/
591 #define YES_NO_RESPTYPE 0xc1 /*;AN000;6*/
592 #define YES 1 /*;AN000;6*/
594 int readonly_or_changed(attrib,destd,fspec,fpath)
598 unsigned char *fspec;
599 unsigned char *fpath;
602 union REGS inregs, outregs; /*;AN000;6 Register set */
605 char file_to_be_chmode[MAXPATHF+2];
609 sublist.value1 = (char far *)fspec; /*;AN000;6 */
610 sublist.flags1 = LEFT_ALIGN + CHAR_FIELD_ASCIIZ; /*;AN000;6 */
611 sublist.max_width1 = (BYTE)strlen(fspec); /*;AN000;6 */
612 sublist.min_width1 = sublist.max_width1; /*;AN000;6 */
614 /***********************************************************************/
615 /* if readonly, output msg and wait for user's prompt */
616 /***********************************************************************/
619 if((retcode = attrib & 0x0001) == 0x0001)
620 display_it(FILE_IS_READONLY,STND_ERR_DEV,1,YES_NO_RESPTYPE,(BYTE)UTIL_MSG); /*;AN000;6*/
622 display_it(FILE_WAS_CHANGED,STND_ERR_DEV,1,YES_NO_RESPTYPE,(BYTE)UTIL_MSG); /*;AN000;6*/
625 inregs.x.ax = (unsigned)CHECK_YES_NO; /*;AN000;6*/
626 inregs.h.dl = response_buff[0]; /*;AN000;6*/
627 int86(0x21,&inregs,&outregs); /*;AN000;6*/
628 display_it(CRLF,STND_ERR_DEV,0,NO_RESPTYPE,(BYTE)UTIL_MSG); /*;AN000;6*/
630 while (outregs.h.al > 1); /*;AN000;6*/
632 /***********************************************************************/
633 /* if user's input is 'Y', return TRUE, else return FALSE */
634 /***********************************************************************/
635 if (outregs.x.ax == YES) /*;AN000;6*/
636 { file_to_be_chmode[0] = destd;
637 file_to_be_chmode[1] = ':';
638 file_to_be_chmode[2] = NULLC;
639 strcat(file_to_be_chmode,fpath);
640 if (strlen(fpath) != 1) {
641 strcat(file_to_be_chmode,"\\");
643 strcat(file_to_be_chmode,fspec);
644 /* change the file attribute to be 0, that is, reset it */
645 if ((retcode = DOSSETFILEMODE((char far *)file_to_be_chmode,(unsigned) 0x00, dw)) != 0)
656 } /* end of subroutine readonly_or_changed */