1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
|
/*----------------------------
/* SOURCE FILE NAME: rtfile.c
/*----------------------------
/* 0 */
#include "rt.h"
#include "rt1.h"
#include "rt2.h"
#include "restpars.h" /*;AN000;4*/
#include "string.h"
#include "stdio.h"
#include "dos.h" /*;AN000;2*/
#include "comsub.h" /* common subroutine def'n */
#include "doscalls.h"
#include "error.h"
extern BYTE rtswitch;
extern BYTE control_flag;
extern BYTE control_flag2;
extern BYTE filename[12];
extern BYTE far *buf_pointer;
extern char far *control_buf_pointer;
extern unsigned int done_searching; /* !wrw */
extern unsigned int numentry;
unsigned dest_file_handle;
extern unsigned src_file_handle;
extern unsigned control_file_handle; /* !wrw */
BYTE dest_file_spec[MAXFSPEC+3];
extern struct FileFindBuf filefindbuf;
extern BYTE src_fname[MAXFNAME];
extern struct subst_list sublist; /*;AN000;6 Message substitution list */
/***************** START OF SPECIFICATION *********************************/
/* */
/* SUBROUTINE NAME : restore_a_file */
/* */
/* DESCRIPTIVE NAME : restore a file found onto the destination disk. */
/* */
/* FUNCTION: This subroutine call open_dest_file to open the destination */
/* file under the proper path. If the path is not found, build */
/* the path. */
/* It then enter a loop to do reading the source disk and */
/* writing the destination disk until end of file. If the file */
/* is so large that it is backed up on more than one disk, */
/* the user is prompt to insert next diskette. In this */
/* situation, the disk is checked for correct sequence number, */
/* and then searched for the file to be continue restoring. */
/* after the file is completely restored, the time, date, and */
/* attributes of the restored file is set to be the same as */
/* its original value. */
/* */
/********************** END OF SPECIFICATIONS *******************************/
void restore_a_file(finfo,dinfo,bufsize,control_bufsize, /* wrw! */
fheadnew,dheadold,dheadnew,
srcd,destd,inpath,infname,infspec,dnumwant,dirhandle)
struct file_info *finfo;
struct disk_info *dinfo;
unsigned long bufsize;
unsigned int *control_bufsize;
struct file_header_new far *fheadnew;
struct disk_header_old *dheadold;
struct disk_header_new far *dheadnew;
BYTE srcd;
BYTE destd;
unsigned char *inpath;
unsigned char *infname;
unsigned char *infspec;
unsigned int *dnumwant;
unsigned int *dirhandle;
{
BYTE c;
BYTE temp_array1[4];
BYTE temp_array2[4];
BYTE temp_fname[MAXFSPEC];
WORD action;
WORD first_time=TRUE;
/*declaration for dosfindfirst */
WORD temp_dirhandle;
WORD next_dirhandle;
unsigned attribute = NOTV; /* */
unsigned search_cnt = 1; /* # of entries to find */
unsigned buf_len = sizeof(struct FileFindBuf);
BYTE search_string[MAXPATHF+2];
/*end decleration for ffirst and fnext*/
BYTE outstring[MAXPATHF+2];
WORD retcode;
DWORD iterate_num;
DWORD i; /* wrw! */
WORD numread;
WORD numwrite;
DWORD int remainder;
DWORD part_size;
WORD file_seq_num = 1; /*when this routine is called, the first
part of the file already get check against the
file sequence number */
BYTE file_tobe_opened[MAXFSPEC+2];
WORD found = FALSE;
WORD *dirptr;
WORD *flptr;
WORD read_count;
DWORD newptr;
WORD next_file_pointer;
unsigned int dnum;
DWORD temp_offset;
BYTE my_own_dirpath[MAXPATH];
int x; /*;AN000;8*/
union REGS qregs; /*;AN000;8*/
/*build a string of destination file specification*/
dest_file_spec[0] = destd;
dest_file_spec[1] = ':';
dest_file_spec[2] = NULLC;
strcat(dest_file_spec,finfo->fname);
/*********************************************************************/
/* Open destination file, and chdir the the path where the dest file */
/* going to reside. If the path is not there, then create the path. */
/* If file sharing error, exit this routine */
/*********************************************************************/
/*open_dest_file*/
retcode=open_dest_file(finfo,destd);
/*if file sharring error, exit this subroutine*/
if (retcode == FALSE)
display_it(FILE_CREATION_ERROR,STND_ERR_DEV,0,NO_RESPTYPE,(BYTE)UTIL_MSG); /*;AN000;6*/
else
{
/*setflag PARTIAL*/
set_reset_test_flag(&control_flag,PARTIAL,SET);
/*********************************************************************/
/* This loop will be processed once for each part of the source file */
/*********************************************************************/
for ( ; ; )
{
/*********************************************************************/
/* compare source file size and buf size to determine the */
/* iteration of reading and writing */
/*********************************************************************/
part_size = finfo->partsize;
/*if old*/
if (set_reset_test_flag(&control_flag,OLDNEW,TEST)==TRUE)
part_size = part_size - HEADLEN;
iterate_num = part_size / bufsize;
/*if remain of of filesize/bufsize != 0, add 1 to iterate_num*/
remainder = part_size % bufsize;
if (remainder > 0)
++iterate_num;
/*********************************************************************/
/*loop through each of the iteration */
/*********************************************************************/
for (i = 1; i <= iterate_num; ++i)
{
/***************************************************************/
/* if old format, read from the beginning of the source file */
/***************************************************************/
/*read source file (new and old have different pointer)*/
if (set_reset_test_flag(&control_flag,OLDNEW,TEST) == TRUE)
{
retcode = DOSREAD( src_file_handle,
(char far *)&buf_pointer[0],
(unsigned)bufsize,
(unsigned far *)&numread);
if (retcode != 0)
{
com_msg(retcode);
unexperror(retcode);
}
}
else
{ /*new format*/
/***************************************************************/
/* if new format, search backup.xxx for the file to be restored*/
/* and read it. */
/***************************************************************/
temp_offset = finfo->offset + bufsize * (i - 1);
retcode =
DOSCHGFILEPTR
(src_file_handle,
(DWORD) temp_offset,
(unsigned) 0,
(DWORD far *) &newptr
);
if (i == iterate_num)
{
part_size = part_size - bufsize * (iterate_num -1);
retcode =
DOSREAD
( src_file_handle,
(char far *)&buf_pointer[0],
(unsigned)part_size,
(unsigned far *)&numread
);
}
else
{
retcode =
DOSREAD
(src_file_handle,
(char far *)&buf_pointer[0],
(unsigned)bufsize,
(unsigned far *)&numread
);
} /*end of i == iterate_num */
} /*end of new format */
/*************************************************************/
/* write to dest file */
/*************************************************************/
retcode =
DOSWRITE
(dest_file_handle,
(char far *)&buf_pointer[0],
(unsigned) numread,
(unsigned far *) &numwrite
);
/*************************************************************/
/*if the num of bytes read != num of bytes write */
/* call dos_write_error to find out why */
/*************************************************************/
if (numread != numwrite)
dos_write_error(bufsize,destd);
}
/*end iteration loop*/
/*****************************************************************/
/*if the file is system file, turn RTSYSTEM on */
/*****************************************************************/
if (strcmp(finfo->fname,"IBMBIO.COM")==0 ||
strcmp(finfo->fname,"IBMDOS.COM")==0 ||
strcmp(finfo->fname,"COMMAND.COM")==0 )
set_reset_test_flag(&control_flag2,RTSYSTEM,SET);
/*****************************************************************/
/*if the source file header indicate that this is the last disk, */
/* that is,it is completely copied, then exit the for loop */
/*****************************************************************/
if (set_reset_test_flag(&finfo->fflag,LAST_PART,TEST) == TRUE)
break; /* exit the loop */
/*****************************************************************/
/*The logic flow come here when the file expanded into next disk.*/
/* if old format, close the file handle and find handle */
/* if new format, close src file */
/*****************************************************************/
if (set_reset_test_flag(&control_flag,OLDNEW,TEST) == TRUE)
{ /*close source file*/
DOSCLOSE(src_file_handle);
if (first_time == TRUE)
{ temp_dirhandle = *dirhandle;
first_time = FALSE;
retcode = DOSFINDCLOSE(temp_dirhandle);
}
}
else
{
DOSCLOSE(src_file_handle);
DOSCLOSE(control_file_handle); /* !wrw */
control_file_handle = 0xffff; /* !wrw */
}
/*****************************************************************/
/* output message for user to insert another diskette */
/* "strike any key when ready" */
/* with response type 4 (wait for a key to be hit) */
/*****************************************************************/
if (control_file_handle != 0xffff) /* !wrw */
{ /* !wrw */
DOSCLOSE(control_file_handle); /* !wrw */
control_file_handle = 0xffff; /* !wrw */
} /* !wrw */
printf("\n");
temp_array1[0] = (char) (*dnumwant / 10) + '0';
temp_array1[1] = (char) (*dnumwant % 10) + '0';
temp_array1[2] = NULLC;
temp_array2[0] = srcd;
temp_array2[1] = NULLC;
sublist.value1 = (char far *)temp_array1; /*;AN000;6 */
sublist.flags1 = LEFT_ALIGN + CHAR_FIELD_ASCIIZ; /*;AN000;6 */
sublist.max_width1 = (BYTE)strlen(temp_array1); /*;AN000;6 */
sublist.min_width1 = sublist.max_width1; /*;AN000;6 */
sublist.value2 = (char far *)temp_array2; /*;AN000;6 */
sublist.flags2 = LEFT_ALIGN + CHAR_FIELD_ASCIIZ; /*;AN000;6 */
sublist.max_width2 = (BYTE)strlen(temp_array2); /*;AN000;6 */
sublist.min_width2 = sublist.max_width2; /*;AN000;6 */
display_it(INSERT_SOURCE_DISK,STND_ERR_DEV,2,NO_RESPTYPE,(BYTE)UTIL_MSG); /*;AN000;6*/
display_it(PRESS_ANY_KEY,STND_ERR_DEV,0,ANY_KEY_RESPTYPE,(BYTE)UTIL_MSG); /*;AN000;6*/
/* If single drive system, eliminates double prompting */
/* for user to "Insert diskette for drive %1" */
qregs.x.ax = SETLOGICALDRIVE; /*;AN000;8*/
qregs.h.bl = srcd; /*;AN000;8*/
intdos(&qregs,&qregs); /*;AN000;8*/
/**************************************************/
/**************************************************/
if (set_reset_test_flag(&control_flag,OLDNEW,TEST) == TRUE)
check_bkdisk_old(dheadold,dinfo,srcd,dnumwant);
else
check_bkdisk_new(dheadnew,dinfo,srcd,dnumwant,control_bufsize);
/*at this point a real backup diskette which is in correct sequence
number has been found. In the case of new format, the file
CONTROL.xxx is opened.*/
/*****************************************************************/
/*increament file sequence number */
/*****************************************************************/
file_seq_num = file_seq_num + 1;
/*****************************************************************/
/* search the new disk for next part of the file */
/*****************************************************************/
if (set_reset_test_flag(&control_flag,OLDNEW,TEST) == TRUE)
{ /**************************************************************/
/* if old format, */
/*DosFindFirst:find the first file on the diskette (non-vol id*/
/*entry) */
/**************************************************************/
search_string[0] = srcd;
search_string[1] = ':';
search_string[2] = NULLC;
strcat(search_string, src_fname);
next_dirhandle = 0xffff; /* directory handle */
retcode = /* Find the 1st filename that */
DOSFINDFIRST( /* matches specified file spec*/
(char far * ) search_string, /* File path name */
(unsigned far * ) &next_dirhandle, /* Directory search */
attribute, /* Search attribute */
(struct FileFindBuf far *) &filefindbuf,
buf_len, /* Result buffer length */
(unsigned far * ) &search_cnt, /* Number of entries to find*/
(DWORD) 0
);
if (retcode != 0)
{
display_it(NOT_ABLE_TO_RESTORE_FILE,STND_ERR_DEV,0,NO_RESPTYPE,(BYTE)UTIL_MSG); /*;AN000;6*/
unexperror(retcode);
}
/*if the directory found is a subdirectory, find next one*/
while((retcode = filefindbuf.attributes & SUBDIR) == SUBDIR)
{
search_cnt = 1;
retcode = DOSFINDNEXT(next_dirhandle,
(struct FileFindBuf far *)&filefindbuf,
buf_len,
(unsigned far *)&search_cnt);
if (retcode != 0)
{
display_it(NOT_ABLE_TO_RESTORE_FILE,STND_ERR_DEV,0,NO_RESPTYPE,(BYTE)UTIL_MSG); /*;AN000;6*/
unexperror(retcode);
}
} /*end while */
retcode = DOSFINDCLOSE(next_dirhandle);
/*****************************************************************/
/* check_flheader_old: open and read file header, check dnum */
/* of the file, and fill fheadold and finfo with correct info*/
/*****************************************************************/
strcpy(temp_fname,filefindbuf.file_name);
retcode =
check_flheader_old
( finfo, temp_fname,
filefindbuf.write_date, filefindbuf.write_time,
filefindbuf.attributes, filefindbuf.file_size,
file_seq_num, srcd, destd, infspec, inpath, dnumwant
);
if (retcode != 0)
{
display_it(NOT_ABLE_TO_RESTORE_FILE,STND_ERR_DEV,0,NO_RESPTYPE,(BYTE)UTIL_MSG); /*;AN000;6*/
unexperror(retcode);
}
/*****************************************************************/
/* check file sequence number. */
/*****************************************************************/
if (finfo->dnum != file_seq_num)
{ display_it(FILE_SEQUENCE_ERROR,STND_ERR_DEV,0,NO_RESPTYPE,(BYTE)UTIL_MSG); /*;AN000;6*/
unexperror(FILESEQERROR);
}
}
else
{ /*new format*/
/**********************************************/
/* Find the file on the CONTROL.xxx first */
/**********************************************/
/* findfirst_new on the new diskette using the filename.??? */
retcode =
findfirst_new
( finfo, &found, &done_searching,
finfo->path, finfo->fname, (WORD far **) &dirptr, /* wrw! */
(WORD far **) &flptr, &numentry, my_own_dirpath
); /* wrw! */
while (retcode != 0 )
{
display_it(NOT_ABLE_TO_RESTORE_FILE,STND_ERR_DEV,0,NO_RESPTYPE,(BYTE)UTIL_MSG); /*;AN000;6*/
unexperror(CREATIONERROR);
}
if (finfo->dnum != file_seq_num)
{ display_it(FILE_SEQUENCE_ERROR,STND_ERR_DEV,0,NO_RESPTYPE,(BYTE)UTIL_MSG); /*;AN000;6*/
unexperror(FILESEQERROR);
}
/**************************************************************/
/* open file backup.xxx */
/**************************************************************/
/*the current disk is one less than the disk num wanted*/
dnum = *dnumwant -1;
/*make the file name to be opened*/
file_tobe_opened[0] = srcd;
file_tobe_opened[1] = ':';
file_tobe_opened[2] = NULLC;
strcat(file_tobe_opened,"BACKUP.");
file_tobe_opened[9] = (char)((dnum / 100) + '0');
dnum = dnum % 100;
file_tobe_opened[10] = (char)((dnum / 10) + '0');
dnum = dnum % 10;
file_tobe_opened[11] = (char)(dnum + '0');
file_tobe_opened[12] = NULLC;
retcode =
DOSOPEN
( (char far *)&file_tobe_opened[0],
(unsigned far *)&src_file_handle,
(unsigned far *)&action,
(DWORD)0, /*file size*/
0, /*file attribute*/
0x01, /*if file exist, open it*/
/*if file not exist, fail it*/
0x00c0, /*deny write, read only*/
(DWORD)0
); /*reserved*/
if (retcode != 0)
{ display_it(NOT_ABLE_TO_RESTORE_FILE,STND_ERR_DEV,0,NO_RESPTYPE,(BYTE)UTIL_MSG); /*;AN000;6*/
unexperror(retcode);
}
}
/*end of if new format*/
/*assume the file to be continue definatly will be found on the
second diskette because the dnum of the file already gets checked
in check_bkdisk_old or check_bkdisk_new*/
/*set flag to be SPLITFILE*/
set_reset_test_flag(&control_flag,SPLITFILE,SET);
/*******************************************/
/* Display name of file is to be restored */
/*******************************************/
/*outstring = inpath\infspec*/
strcpy(outstring,finfo->path);
if (strlen(finfo->path) != 1 )
strcat(outstring,"\\");
strcat(outstring,finfo->fname);
x = strlen(outstring);
outstring[x] = CR; /*;AN000;6*/
outstring[x+1] = LF; /*;AN000;6*/
outstring[x+2] = NUL; /*;AN000;6*/
qregs.x.ax = 0x4000; /*;AN000;6*/
qregs.x.bx = 0x0001; /*;AN000;6*/
qregs.x.cx = (WORD)strlen(outstring); /*;AN000;6*/
qregs.x.dx = (unsigned int)&outstring[0]; /*;AN000;6*/
intdos(&qregs,&qregs); /*;AN000;6*/
/*loop back to do the read source and write dest until finfo->fflag
indicate that this is the last part of file*/
} /*end of for loop*/
/************************************************************************/
/*set_attributes_and_close: set the attributes and last write date/time */
/*of the file just restore to be like those of the backup file */
/************************************************************************/
set_attributes_and_close(finfo,destd);
/************************************************************************/
/* If old format and the file split, then find next matching file */
/************************************************************************/
if (set_reset_test_flag(&control_flag,SPLITFILE,TEST)==TRUE &&
set_reset_test_flag(&control_flag,OLDNEW,TEST) == TRUE)
{
/*search string used for DisFindFirst = srcd:infname.**/
/*DosFindFirst:find the first file on the diskette (non-vol id entry)
using the search string*/
search_string[0] = srcd;
search_string[1] = ':';
search_string[2] = NULLC;
strcat(search_string, infname);
strcat(search_string, ".*");
temp_dirhandle = 0xffff;
retcode = /* Find the 1st filename that */
DOSFINDFIRST( /* matches specified file spec*/
( char far * ) search_string, /* File path name */
( unsigned far * ) &temp_dirhandle, /* Directory search handle*/
(unsigned) NOTV, /* Search attribute */
(struct FileFindBuf far *) &filefindbuf,
buf_len, /* Result buffer length */
( unsigned far * ) &search_cnt, /* Number of entries to find */
( DWORD) 0
);
/*if not found return*/
if (retcode != 0)
temp_dirhandle = 0xffff;
else
{
/*if the directory found is a subdirectory, find next one*/
while((retcode = filefindbuf.attributes & SUBDIR) == SUBDIR)
{
search_cnt = 1;
retcode = DOSFINDNEXT(temp_dirhandle,
(struct FileFindBuf far *)&filefindbuf,
buf_len,
(unsigned far *)&search_cnt);
if (retcode != 0)
temp_dirhandle = 0xffff;
} /*end while */
if(strcmp(filefindbuf.file_name,BACKUPID)==0 ||
strcmp(filefindbuf.file_name,src_fname)==0 )
{
retcode =DOSFINDNEXT(temp_dirhandle,
(struct FileFindBuf far *)&filefindbuf,
buf_len,
(unsigned far *)&search_cnt);
if (retcode != 0)
temp_dirhandle = 0xffff;
else
{
if(strcmp(filefindbuf.file_name,BACKUPID)==0 ||
strcmp(filefindbuf.file_name,src_fname)==0 )
{
retcode =DOSFINDNEXT(temp_dirhandle,
(struct FileFindBuf far *)&filefindbuf,
buf_len,
(unsigned far *)&search_cnt);
if (retcode != 0)
temp_dirhandle = 0xffff;
}
} /*end of the rc is 0 */
} /*end of if strcomp is sucessful*/
}
*dirhandle = temp_dirhandle;
} /*end of if the file was splitted */
/****************************************************************/
/*set FOUNDFILE flag */
/****************************************************************/
set_reset_test_flag(&control_flag,FOUND,SET);
} /* end of if open destination file get file sharing error */
} /*end of restore_a_file subroutine*/
|