2 /*----------------------------
3 /* SOURCE FILE NAME: rtfile.c
4 /*----------------------------
10 #include "restpars.h" /*;AN000;4*/
13 #include "dos.h" /*;AN000;2*/
14 #include "comsub.h" /* common subroutine def'n */
19 extern BYTE control_flag;
20 extern BYTE control_flag2;
21 extern BYTE filename[12];
22 extern BYTE far *buf_pointer;
23 extern char far *control_buf_pointer;
24 extern unsigned int done_searching; /* !wrw */
25 extern unsigned int numentry;
27 unsigned dest_file_handle;
28 extern unsigned src_file_handle;
29 extern unsigned control_file_handle; /* !wrw */
30 BYTE dest_file_spec[MAXFSPEC+3];
31 extern struct FileFindBuf filefindbuf;
32 extern BYTE src_fname[MAXFNAME];
33 extern struct subst_list sublist; /*;AN000;6 Message substitution list */
35 /***************** START OF SPECIFICATION *********************************/
37 /* SUBROUTINE NAME : restore_a_file */
39 /* DESCRIPTIVE NAME : restore a file found onto the destination disk. */
41 /* FUNCTION: This subroutine call open_dest_file to open the destination */
42 /* file under the proper path. If the path is not found, build */
44 /* It then enter a loop to do reading the source disk and */
45 /* writing the destination disk until end of file. If the file */
46 /* is so large that it is backed up on more than one disk, */
47 /* the user is prompt to insert next diskette. In this */
48 /* situation, the disk is checked for correct sequence number, */
49 /* and then searched for the file to be continue restoring. */
50 /* after the file is completely restored, the time, date, and */
51 /* attributes of the restored file is set to be the same as */
52 /* its original value. */
54 /********************** END OF SPECIFICATIONS *******************************/
56 void restore_a_file(finfo,dinfo,bufsize,control_bufsize, /* wrw! */
57 fheadnew,dheadold,dheadnew,
58 srcd,destd,inpath,infname,infspec,dnumwant,dirhandle)
60 struct file_info *finfo;
61 struct disk_info *dinfo;
62 unsigned long bufsize;
63 unsigned int *control_bufsize;
64 struct file_header_new far *fheadnew;
65 struct disk_header_old *dheadold;
66 struct disk_header_new far *dheadnew;
69 unsigned char *inpath;
70 unsigned char *infname;
71 unsigned char *infspec;
72 unsigned int *dnumwant;
73 unsigned int *dirhandle;
78 BYTE temp_fname[MAXFSPEC];
82 /*declaration for dosfindfirst */
85 unsigned attribute = NOTV; /* */
86 unsigned search_cnt = 1; /* # of entries to find */
87 unsigned buf_len = sizeof(struct FileFindBuf);
88 BYTE search_string[MAXPATHF+2];
89 /*end decleration for ffirst and fnext*/
91 BYTE outstring[MAXPATHF+2];
99 WORD file_seq_num = 1; /*when this routine is called, the first
100 part of the file already get check against the
101 file sequence number */
102 BYTE file_tobe_opened[MAXFSPEC+2];
108 WORD next_file_pointer;
112 BYTE my_own_dirpath[MAXPATH];
114 union REGS qregs; /*;AN000;8*/
116 /*build a string of destination file specification*/
117 dest_file_spec[0] = destd;
118 dest_file_spec[1] = ':';
119 dest_file_spec[2] = NULLC;
120 strcat(dest_file_spec,finfo->fname);
122 /*********************************************************************/
123 /* Open destination file, and chdir the the path where the dest file */
124 /* going to reside. If the path is not there, then create the path. */
125 /* If file sharing error, exit this routine */
126 /*********************************************************************/
128 retcode=open_dest_file(finfo,destd);
130 /*if file sharring error, exit this subroutine*/
131 if (retcode == FALSE)
132 display_it(FILE_CREATION_ERROR,STND_ERR_DEV,0,NO_RESPTYPE,(BYTE)UTIL_MSG); /*;AN000;6*/
136 set_reset_test_flag(&control_flag,PARTIAL,SET);
138 /*********************************************************************/
139 /* This loop will be processed once for each part of the source file */
140 /*********************************************************************/
144 /*********************************************************************/
145 /* compare source file size and buf size to determine the */
146 /* iteration of reading and writing */
147 /*********************************************************************/
148 part_size = finfo->partsize;
150 if (set_reset_test_flag(&control_flag,OLDNEW,TEST)==TRUE)
151 part_size = part_size - HEADLEN;
153 iterate_num = part_size / bufsize;
154 /*if remain of of filesize/bufsize != 0, add 1 to iterate_num*/
155 remainder = part_size % bufsize;
159 /*********************************************************************/
160 /*loop through each of the iteration */
161 /*********************************************************************/
162 for (i = 1; i <= iterate_num; ++i)
164 /***************************************************************/
165 /* if old format, read from the beginning of the source file */
166 /***************************************************************/
167 /*read source file (new and old have different pointer)*/
168 if (set_reset_test_flag(&control_flag,OLDNEW,TEST) == TRUE)
170 retcode = DOSREAD( src_file_handle,
171 (char far *)&buf_pointer[0],
173 (unsigned far *)&numread);
183 /***************************************************************/
184 /* if new format, search backup.xxx for the file to be restored*/
186 /***************************************************************/
187 temp_offset = finfo->offset + bufsize * (i - 1);
193 (DWORD far *) &newptr
196 if (i == iterate_num)
198 part_size = part_size - bufsize * (iterate_num -1);
202 (char far *)&buf_pointer[0],
204 (unsigned far *)&numread
212 (char far *)&buf_pointer[0],
214 (unsigned far *)&numread
217 } /*end of i == iterate_num */
218 } /*end of new format */
220 /*************************************************************/
221 /* write to dest file */
222 /*************************************************************/
226 (char far *)&buf_pointer[0],
228 (unsigned far *) &numwrite
231 /*************************************************************/
232 /*if the num of bytes read != num of bytes write */
233 /* call dos_write_error to find out why */
234 /*************************************************************/
235 if (numread != numwrite)
236 dos_write_error(bufsize,destd);
238 /*end iteration loop*/
240 /*****************************************************************/
241 /*if the file is system file, turn RTSYSTEM on */
242 /*****************************************************************/
243 if (strcmp(finfo->fname,"IBMBIO.COM")==0 ||
244 strcmp(finfo->fname,"IBMDOS.COM")==0 ||
245 strcmp(finfo->fname,"COMMAND.COM")==0 )
246 set_reset_test_flag(&control_flag2,RTSYSTEM,SET);
249 /*****************************************************************/
250 /*if the source file header indicate that this is the last disk, */
251 /* that is,it is completely copied, then exit the for loop */
252 /*****************************************************************/
253 if (set_reset_test_flag(&finfo->fflag,LAST_PART,TEST) == TRUE)
254 break; /* exit the loop */
256 /*****************************************************************/
257 /*The logic flow come here when the file expanded into next disk.*/
258 /* if old format, close the file handle and find handle */
259 /* if new format, close src file */
260 /*****************************************************************/
261 if (set_reset_test_flag(&control_flag,OLDNEW,TEST) == TRUE)
262 { /*close source file*/
263 DOSCLOSE(src_file_handle);
265 if (first_time == TRUE)
266 { temp_dirhandle = *dirhandle;
268 retcode = DOSFINDCLOSE(temp_dirhandle);
273 DOSCLOSE(src_file_handle);
274 DOSCLOSE(control_file_handle); /* !wrw */
275 control_file_handle = 0xffff; /* !wrw */
278 /*****************************************************************/
279 /* output message for user to insert another diskette */
280 /* "strike any key when ready" */
281 /* with response type 4 (wait for a key to be hit) */
282 /*****************************************************************/
284 if (control_file_handle != 0xffff) /* !wrw */
286 DOSCLOSE(control_file_handle); /* !wrw */
287 control_file_handle = 0xffff; /* !wrw */
291 temp_array1[0] = (char) (*dnumwant / 10) + '0';
292 temp_array1[1] = (char) (*dnumwant % 10) + '0';
293 temp_array1[2] = NULLC;
294 temp_array2[0] = srcd;
295 temp_array2[1] = NULLC;
297 sublist.value1 = (char far *)temp_array1; /*;AN000;6 */
298 sublist.flags1 = LEFT_ALIGN + CHAR_FIELD_ASCIIZ; /*;AN000;6 */
299 sublist.max_width1 = (BYTE)strlen(temp_array1); /*;AN000;6 */
300 sublist.min_width1 = sublist.max_width1; /*;AN000;6 */
302 sublist.value2 = (char far *)temp_array2; /*;AN000;6 */
303 sublist.flags2 = LEFT_ALIGN + CHAR_FIELD_ASCIIZ; /*;AN000;6 */
304 sublist.max_width2 = (BYTE)strlen(temp_array2); /*;AN000;6 */
305 sublist.min_width2 = sublist.max_width2; /*;AN000;6 */
307 display_it(INSERT_SOURCE_DISK,STND_ERR_DEV,2,NO_RESPTYPE,(BYTE)UTIL_MSG); /*;AN000;6*/
308 display_it(PRESS_ANY_KEY,STND_ERR_DEV,0,ANY_KEY_RESPTYPE,(BYTE)UTIL_MSG); /*;AN000;6*/
310 /* If single drive system, eliminates double prompting */
311 /* for user to "Insert diskette for drive %1" */
312 qregs.x.ax = SETLOGICALDRIVE; /*;AN000;8*/
313 qregs.h.bl = srcd; /*;AN000;8*/
314 intdos(&qregs,&qregs); /*;AN000;8*/
316 /**************************************************/
317 /**************************************************/
318 if (set_reset_test_flag(&control_flag,OLDNEW,TEST) == TRUE)
319 check_bkdisk_old(dheadold,dinfo,srcd,dnumwant);
321 check_bkdisk_new(dheadnew,dinfo,srcd,dnumwant,control_bufsize);
323 /*at this point a real backup diskette which is in correct sequence
324 number has been found. In the case of new format, the file
325 CONTROL.xxx is opened.*/
327 /*****************************************************************/
328 /*increament file sequence number */
329 /*****************************************************************/
330 file_seq_num = file_seq_num + 1;
332 /*****************************************************************/
333 /* search the new disk for next part of the file */
334 /*****************************************************************/
335 if (set_reset_test_flag(&control_flag,OLDNEW,TEST) == TRUE)
336 { /**************************************************************/
338 /*DosFindFirst:find the first file on the diskette (non-vol id*/
340 /**************************************************************/
341 search_string[0] = srcd;
342 search_string[1] = ':';
343 search_string[2] = NULLC;
344 strcat(search_string, src_fname);
346 next_dirhandle = 0xffff; /* directory handle */
348 retcode = /* Find the 1st filename that */
349 DOSFINDFIRST( /* matches specified file spec*/
350 (char far * ) search_string, /* File path name */
351 (unsigned far * ) &next_dirhandle, /* Directory search */
352 attribute, /* Search attribute */
353 (struct FileFindBuf far *) &filefindbuf,
354 buf_len, /* Result buffer length */
355 (unsigned far * ) &search_cnt, /* Number of entries to find*/
361 display_it(NOT_ABLE_TO_RESTORE_FILE,STND_ERR_DEV,0,NO_RESPTYPE,(BYTE)UTIL_MSG); /*;AN000;6*/
366 /*if the directory found is a subdirectory, find next one*/
367 while((retcode = filefindbuf.attributes & SUBDIR) == SUBDIR)
370 retcode = DOSFINDNEXT(next_dirhandle,
371 (struct FileFindBuf far *)&filefindbuf,
373 (unsigned far *)&search_cnt);
377 display_it(NOT_ABLE_TO_RESTORE_FILE,STND_ERR_DEV,0,NO_RESPTYPE,(BYTE)UTIL_MSG); /*;AN000;6*/
383 retcode = DOSFINDCLOSE(next_dirhandle);
385 /*****************************************************************/
386 /* check_flheader_old: open and read file header, check dnum */
387 /* of the file, and fill fheadold and finfo with correct info*/
388 /*****************************************************************/
389 strcpy(temp_fname,filefindbuf.file_name);
393 filefindbuf.write_date, filefindbuf.write_time,
394 filefindbuf.attributes, filefindbuf.file_size,
395 file_seq_num, srcd, destd, infspec, inpath, dnumwant
400 display_it(NOT_ABLE_TO_RESTORE_FILE,STND_ERR_DEV,0,NO_RESPTYPE,(BYTE)UTIL_MSG); /*;AN000;6*/
404 /*****************************************************************/
405 /* check file sequence number. */
406 /*****************************************************************/
407 if (finfo->dnum != file_seq_num)
408 { display_it(FILE_SEQUENCE_ERROR,STND_ERR_DEV,0,NO_RESPTYPE,(BYTE)UTIL_MSG); /*;AN000;6*/
409 unexperror(FILESEQERROR);
415 /**********************************************/
416 /* Find the file on the CONTROL.xxx first */
417 /**********************************************/
419 /* findfirst_new on the new diskette using the filename.??? */
422 ( finfo, &found, &done_searching,
423 finfo->path, finfo->fname, (WORD far **) &dirptr, /* wrw! */
424 (WORD far **) &flptr, &numentry, my_own_dirpath
427 while (retcode != 0 )
429 display_it(NOT_ABLE_TO_RESTORE_FILE,STND_ERR_DEV,0,NO_RESPTYPE,(BYTE)UTIL_MSG); /*;AN000;6*/
430 unexperror(CREATIONERROR);
433 if (finfo->dnum != file_seq_num)
434 { display_it(FILE_SEQUENCE_ERROR,STND_ERR_DEV,0,NO_RESPTYPE,(BYTE)UTIL_MSG); /*;AN000;6*/
435 unexperror(FILESEQERROR);
438 /**************************************************************/
439 /* open file backup.xxx */
440 /**************************************************************/
441 /*the current disk is one less than the disk num wanted*/
443 /*make the file name to be opened*/
444 file_tobe_opened[0] = srcd;
445 file_tobe_opened[1] = ':';
446 file_tobe_opened[2] = NULLC;
447 strcat(file_tobe_opened,"BACKUP.");
448 file_tobe_opened[9] = (char)((dnum / 100) + '0');
450 file_tobe_opened[10] = (char)((dnum / 10) + '0');
452 file_tobe_opened[11] = (char)(dnum + '0');
453 file_tobe_opened[12] = NULLC;
457 ( (char far *)&file_tobe_opened[0],
458 (unsigned far *)&src_file_handle,
459 (unsigned far *)&action,
460 (DWORD)0, /*file size*/
461 0, /*file attribute*/
462 0x01, /*if file exist, open it*/
463 /*if file not exist, fail it*/
464 0x00c0, /*deny write, read only*/
469 { display_it(NOT_ABLE_TO_RESTORE_FILE,STND_ERR_DEV,0,NO_RESPTYPE,(BYTE)UTIL_MSG); /*;AN000;6*/
474 /*end of if new format*/
476 /*assume the file to be continue definatly will be found on the
477 second diskette because the dnum of the file already gets checked
478 in check_bkdisk_old or check_bkdisk_new*/
480 /*set flag to be SPLITFILE*/
481 set_reset_test_flag(&control_flag,SPLITFILE,SET);
483 /*******************************************/
484 /* Display name of file is to be restored */
485 /*******************************************/
486 /*outstring = inpath\infspec*/
487 strcpy(outstring,finfo->path);
488 if (strlen(finfo->path) != 1 )
489 strcat(outstring,"\\");
491 strcat(outstring,finfo->fname);
492 x = strlen(outstring);
493 outstring[x] = CR; /*;AN000;6*/
494 outstring[x+1] = LF; /*;AN000;6*/
495 outstring[x+2] = NUL; /*;AN000;6*/
496 qregs.x.ax = 0x4000; /*;AN000;6*/
497 qregs.x.bx = 0x0001; /*;AN000;6*/
498 qregs.x.cx = (WORD)strlen(outstring); /*;AN000;6*/
499 qregs.x.dx = (unsigned int)&outstring[0]; /*;AN000;6*/
500 intdos(&qregs,&qregs); /*;AN000;6*/
502 /*loop back to do the read source and write dest until finfo->fflag
503 indicate that this is the last part of file*/
504 } /*end of for loop*/
506 /************************************************************************/
507 /*set_attributes_and_close: set the attributes and last write date/time */
508 /*of the file just restore to be like those of the backup file */
509 /************************************************************************/
510 set_attributes_and_close(finfo,destd);
512 /************************************************************************/
513 /* If old format and the file split, then find next matching file */
514 /************************************************************************/
515 if (set_reset_test_flag(&control_flag,SPLITFILE,TEST)==TRUE &&
516 set_reset_test_flag(&control_flag,OLDNEW,TEST) == TRUE)
518 /*search string used for DisFindFirst = srcd:infname.**/
519 /*DosFindFirst:find the first file on the diskette (non-vol id entry)
520 using the search string*/
521 search_string[0] = srcd;
522 search_string[1] = ':';
523 search_string[2] = NULLC;
524 strcat(search_string, infname);
525 strcat(search_string, ".*");
527 temp_dirhandle = 0xffff;
528 retcode = /* Find the 1st filename that */
529 DOSFINDFIRST( /* matches specified file spec*/
530 ( char far * ) search_string, /* File path name */
531 ( unsigned far * ) &temp_dirhandle, /* Directory search handle*/
532 (unsigned) NOTV, /* Search attribute */
533 (struct FileFindBuf far *) &filefindbuf,
534 buf_len, /* Result buffer length */
535 ( unsigned far * ) &search_cnt, /* Number of entries to find */
539 /*if not found return*/
541 temp_dirhandle = 0xffff;
545 /*if the directory found is a subdirectory, find next one*/
546 while((retcode = filefindbuf.attributes & SUBDIR) == SUBDIR)
549 retcode = DOSFINDNEXT(temp_dirhandle,
550 (struct FileFindBuf far *)&filefindbuf,
552 (unsigned far *)&search_cnt);
554 temp_dirhandle = 0xffff;
557 if(strcmp(filefindbuf.file_name,BACKUPID)==0 ||
558 strcmp(filefindbuf.file_name,src_fname)==0 )
560 retcode =DOSFINDNEXT(temp_dirhandle,
561 (struct FileFindBuf far *)&filefindbuf,
563 (unsigned far *)&search_cnt);
566 temp_dirhandle = 0xffff;
570 if(strcmp(filefindbuf.file_name,BACKUPID)==0 ||
571 strcmp(filefindbuf.file_name,src_fname)==0 )
573 retcode =DOSFINDNEXT(temp_dirhandle,
574 (struct FileFindBuf far *)&filefindbuf,
576 (unsigned far *)&search_cnt);
579 temp_dirhandle = 0xffff;
582 } /*end of the rc is 0 */
583 } /*end of if strcomp is sucessful*/
586 *dirhandle = temp_dirhandle;
588 } /*end of if the file was splitted */
591 /****************************************************************/
592 /*set FOUNDFILE flag */
593 /****************************************************************/
594 set_reset_test_flag(&control_flag,FOUND,SET);
595 } /* end of if open destination file get file sharing error */
597 } /*end of restore_a_file subroutine*/