summaryrefslogtreecommitdiff
path: root/v4.0/src/CMD/RESTORE/RTFILE1.C
diff options
context:
space:
mode:
Diffstat (limited to 'v4.0/src/CMD/RESTORE/RTFILE1.C')
-rw-r--r--v4.0/src/CMD/RESTORE/RTFILE1.C456
1 files changed, 456 insertions, 0 deletions
diff --git a/v4.0/src/CMD/RESTORE/RTFILE1.C b/v4.0/src/CMD/RESTORE/RTFILE1.C
new file mode 100644
index 0000000..722cd6c
--- /dev/null
+++ b/v4.0/src/CMD/RESTORE/RTFILE1.C
@@ -0,0 +1,456 @@
1
2/*------------------------------
3/* SOURCE FILE NAME: rtfile1.c
4/*------------------------------
5/*  0 */
6
7#include "rt.h"
8#include "rt1.h"
9#include "rt2.h"
10#include "restpars.h" /*;AN000;4*/
11#include "direct.h"
12#include "string.h"
13#include "dos.h" /*;AN000;2*/
14#include "comsub.h" /* common subroutine def'n */
15#include "doscalls.h"
16#include "error.h"
17
18char ext_attrib_buff[4086]; /*;AN000;3*/
19
20extern BYTE rtswitch;
21extern BYTE control_flag;
22extern BYTE control_flag2;
23extern unsigned dest_file_handle;
24extern unsigned src_file_handle;
25extern BYTE far *buf_pointer;
26extern BYTE dest_file_spec[MAXFSPEC+3];
27extern struct FileFindBuf filefindbuf;
28
29extern struct file_header_new far *fheadnew; /*;AN000;3 */
30
31/* *************** START OF SPECIFICATION ********************************
32/*
33/* SUBROUTINE NAME : open_dest_file
34/*
35/* DESCRIPTIVE NAME : open the destination file and build a path to it
36/* if necessary.
37/*
38/* FUNCTION: Try to change the current directory of the destination disk
39/* to be the one the file is to be restored. If not able to
40/* do it because the directory does not exist, call
41/* build_path_create_file subroutine to build path,
42/* create the destination file and return a handle on it.
43/* If file can not be created, find out whether it is caused
44/* by file sharing error, or caused by disk full.
45/*
46/*
47/********************** END OF SPECIFICATIONS ******************************/
48WORD open_dest_file(finfo,destd)
49struct file_info *finfo;
50BYTE destd;
51{
52 BYTE fname[MAXFSPEC+2];
53 BYTE path_to_be_chdir[MAXPATH+2];
54 WORD rc;
55
56 WORD retcode;
57
58 /*declaration for dosfindfirst */
59 unsigned dirhandle = 0xffff;
60 unsigned attribute = NOTV;
61 unsigned search_cnt = 1;
62 unsigned buf_len = sizeof(struct FileFindBuf);
63 BYTE search_string[MAXPATHF+2];
64 /*end decleration for ffirst and fnext*/
65
66 /*************************************************************************
67 /*if current directory is not where the file wants to be restored and
68 /* (the file is not to be restored in root or the current directory is
69 /* not root). This is to avoid building path if the the current
70 /* directory already got updated to be the right directory (in dorestore),
71 /* or both current directory and the requested directory are root
72 /* directory
73 /**************************************************************************/
74
75 if (strcmp(finfo->path,finfo->curdir)!=0)
76 {
77 /* Change to finfo->path. If error, create the directory */
78 strcpy(finfo->curdir,finfo->path);
79 path_to_be_chdir[0] = destd;
80 path_to_be_chdir[1] = ':';
81 path_to_be_chdir[2] = NULLC;
82 strcat(path_to_be_chdir,finfo->curdir);
83 if(chdir(path_to_be_chdir)!=0)
84 {
85 build_path_create_file(finfo->path,destd,finfo->fflag,finfo->ea_offset); /*;AC000;3*/
86 if (dest_file_handle != NULLC)
87 return(TRUE);
88 }
89 }
90
91 /* Current directory is the one where files are to be restored to*/
92
93 retcode = create_the_file(finfo->fflag,finfo->ea_offset); /*;AN000;3*/
94
95 if (retcode == NOERROR)
96 return(TRUE);
97
98 /*----------------------------------------*/
99 /*- There was an error creating target -*/
100 /*- file. Reset attribute and try again -*/
101 /*----------------------------------------*/
102 retcode =
103 DOSSETFILEMODE
104 (
105 (char far *)&dest_file_spec[0],
106 (unsigned) 0x00,
107 (DWORD) 0
108 );
109
110 retcode = create_the_file(finfo->fflag,finfo->ea_offset); /*;AN000;3*/
111
112 if (retcode == NOERROR)
113 return(TRUE);
114 else
115 return(FALSE); /*;AC000;p1102*/
116
117
118} /*end of subroutine*/
119/* *************** START OF SPECIFICATION ********************************
120/*
121/* SUBROUTINE NAME : build_path_create_file
122/*
123/* DESCRIPTIVE NAME : Build path for the destination file, and create
124/* the file in the current direactory.
125/*
126/* FUNCTION: Rebuild the path of the file about to be restored by
127/* recreating all subdirectories needed to complete the path.
128/* Then chdir to the one which is to reside and create the
129/* file.
130/*
131/********************* END OF SPECIFICATIONS ********************************/
132void build_path_create_file(in_path,destd,fflag,ea_offset)
133BYTE *in_path;
134BYTE destd;
135BYTE fflag; /*;AN000;3*/
136DWORD ea_offset; /*;AN000;3*/
137{
138 WORD array[20];
139 int i,j;
140 BYTE path[MAXPATH+2];
141 WORD retcode;
142 BYTE cant_make = FFALSE; /*;AN000;10*/
143
144 path[0] = destd;
145 path[1] = ':';
146 path[2] = NULLC;
147 strcat(path,in_path);
148 i = strlen(path);
149 j = -1;
150
151 /* Create the path for destination file */
152 /*Loop until mkdir(path) is successful*/
153
154 while (mkdir(path) && !cant_make) /*;AC000;10*/
155 {
156 /*scan path backward until find a \ */
157 for (; path[i] != '\\'; i--)
158 if (i < 0)
159 { display_it(FILE_CREATION_ERROR,STND_ERR_DEV,0,NO_RESPTYPE,(BYTE)UTIL_MSG);/*;AN000;6*/
160 display_it(PRESS_ANY_KEY,STND_ERR_DEV,0,ANY_KEY_RESPTYPE,(BYTE)UTIL_MSG); /*;AN000;9*/
161 cant_make = TTRUE; /*;AN000;10*/
162 break; /*;AN000;10*/
163 }
164
165 /*obtain the last subdir from the path */
166 path[i] = NULLC;
167 j++;
168 /*save the location of the last \ in an array of \ locations */
169 array[j] = i;
170 }
171
172 /*loop through the array of \ locations*/
173 i = j;
174 for (;;)
175 {
176 if (i >= 0 && !cant_make) /*;AC000;10*/
177 {
178 path[array[i]] = '\\';
179 if (mkdir(path))
180 { display_it(FILE_CREATION_ERROR,STND_ERR_DEV,0,NO_RESPTYPE,(BYTE)UTIL_MSG);/*;AN000;6*/
181 display_it(PRESS_ANY_KEY,STND_ERR_DEV,0,ANY_KEY_RESPTYPE,(BYTE)UTIL_MSG); /*;AN000;9*/
182 cant_make = TTRUE; /*;AN000;10*/
183 break; /*;AN000;10*/
184 }
185 --i;
186 }
187 else
188 break;
189 } /*end for loop */
190
191 chdir(path); /*;AN000;3*/
192 retcode = create_the_file(fflag,ea_offset); /*;AN000;3*/
193
194 return; /* wrw! */
195
196}
197
198/********************************************************/
199/*
200/* SUBROUTINE NAME: create_the_file
201/*
202/* DESCRIPTIVE NAME : Create the target file.
203/* Use DOS 4.00 Extended Create Function 6C00h
204/* Remember to handle Extended Attributes!
205/*
206/********************************************************/
207#define EXTENDEDOPEN 0x6c00 /*;AN000;3*/
208WORD create_the_file(fflag,ea_offset) /*;AN000;3*/
209BYTE fflag; /*;AN000;3*/
210DWORD ea_offset; /*;AN000;3*/
211{ /*;AN000;3*/
212 WORD action; /*;AN000;3*/
213 WORD retcode; /*;AN000;3*/
214 union REGS reg; /*;AN000;3*/
215 struct parm_list ea_parmlist; /*;AN000;3 Parameter list for extended open*/
216
217 if ((fflag & EXT_ATTR_FLAG) == EXT_ATTR_FLAG) /*;AN000;3*/
218 read_the_extended_attributes(ea_offset); /*;AN000;3*/
219
220 ea_parmlist.ext_attr_addr = (DWORD)(char far *)&ext_attrib_buff[0];/*;AN000;3*/
221 ea_parmlist.num_additional = 0; /*;AN000;3*/
222
223 retcode = NOERROR; /*;AN000;3*/
224 reg.x.ax = EXTENDEDOPEN; /* Function */ /*;AN000;3*/
225 reg.x.bx = 0x2011; /* Mode */ /*;AN000;3*/
226 reg.x.bx = 0x0081; /* Mode */ /*;AN000;3*/
227 reg.x.cx = 0; /* Attribute */ /*;AN000;3*/
228 reg.x.dx = 0x112; /* Flag */ /*;AN000;3*/
229
230 reg.x.si = (WORD)&dest_file_spec[0]; /* Filename */ /*;AN000;3*/
231
232 if ((fflag & EXT_ATTR_FLAG) == EXT_ATTR_FLAG) /*;AN000;3*/
233 reg.x.di = (WORD)&ea_parmlist; /* Parmlist */ /*;AN000;3*/
234 else
235 reg.x.di = 0xffff; /* No parmlist */ /*;AN000;3*/
236
237 intdos(&reg,&reg); /*;AN000;3*/
238 if (reg.x.cflag & CARRY) /* If there was an error /*;AN000;3*/
239 retcode = reg.x.ax; /* then set return code /*;AN000;3*/
240
241 dest_file_handle = reg.x.ax; /*;AN000;3*/
242
243 return(retcode); /*;AN000;3*/
244} /*;AN000;3*/
245/********************************************************/
246/*
247/* SUBROUTINE NAME: read_the_extended_attributes
248/*
249/* DESCRIPTIVE NAME : reads in the extended attributes
250/*
251/********************************************************/
252void read_the_extended_attributes(ea_offset) /*;AN000;3*/
253DWORD ea_offset; /*;AN000;3*/
254{ /*;AN000;3*/
255 WORD ea_len; /*;AN000;3*/
256 DWORD file_position; /*;AN000;3*/
257 WORD read_count; /*;AN000;3*/
258 WORD retcode; /*;AN000;3*/
259 /*******************************/
260 /* Seek to Extended Attributes */
261 retcode = /*;AN000;3*/
262 DOSCHGFILEPTR /*;AN000;3*/
263 ( /*;AN000;3*/
264 src_file_handle, /* Handle */ /*;AN000;3*/
265 ea_offset, /* New location */ /*;AN000;3*/
266 (BYTE)0, /* MOVE METHOD */ /*;AN000;3*/
267 (DWORD far *)&file_position /*;AN000;3*/
268 ); /*;AN000;3*/
269
270 /*************************************/
271 /* Read in Extended Attribute length */
272 retcode = /*;AN000;3*/
273 DOSREAD /*;AN000;3*/
274 ( /*;AN000;3*/
275 src_file_handle, /*;AN000;3*/
276 (char far *)&ea_len, /*;AN000;3*/
277 (unsigned short)2, /*;AN000;3*/
278 (unsigned far *)&read_count /*;AN000;3*/
279 ); /*;AN000;3*/
280
281 /***********************************/
282 /* Read in the Extended Attributes */
283 retcode = /*;AN000;3*/
284 DOSREAD /*;AN000;3*/
285 ( /*;AN000;3*/
286 src_file_handle, /*;AN000;3*/
287 (char far *)&ext_attrib_buff[0], /*;AN000;3*/
288 (unsigned short)ea_len, /*;AN000;3*/
289 (unsigned far *)&read_count /*;AN000;3*/
290 ); /*;AN000;3*/
291
292 return; /*;AN000;3*/
293} /*;AN000;3*/
294
295/* *************** START OF SPECIFICATION ********************************
296/*
297/* SUBROUTINE NAME : set_attributes_and_close
298/*
299/* DESCRIPTIVE NAME : Set the file attributes and close the file
300/*
301/* FUNCTION: Set the attributes and last write date/time of the file just
302/* restored to be like those of the backup file.
303/*
304/********************* END OF SPECIFICATIONS ********************************/
305int set_attributes_and_close(finfo,destd)
306struct file_info *finfo;
307BYTE destd;
308{
309 struct FileStatus fileinfo_buf;
310 WORD destdnum;
311 WORD buflen = sizeof(struct FileStatus);
312
313 WORD retcode;
314
315 destdnum = destd - 'A' + 1;
316
317 /************************************************************************/
318 /* call DosQFileInfo: Request date and time of the dest file */
319 /************************************************************************/
320 retcode = DOSQFILEINFO (
321 (unsigned)dest_file_handle, /* File handle */
322 (unsigned)1, /* File info data required */
323 (char far *)&fileinfo_buf, /* File info buffer */
324 (unsigned)buflen); /* File info buffer size */
325
326 /*if fail, unexperror "file creation error"*/
327 if (retcode != NOERROR)
328 { display_it(FILE_CREATION_ERROR,STND_ERR_DEV,0,NO_RESPTYPE,(BYTE)UTIL_MSG); /*;AN000;6*/
329 usererror(retcode);
330 }
331 /************************************************************************/
332 /* call DosSetFileInfo: Set date and time in dest file as the same date */
333 /* and time in finfo */
334 /************************************************************************/
335 fileinfo_buf.write_date = finfo->fdate;
336 fileinfo_buf.write_time = finfo->ftime;
337 retcode = DOSSETFILEINFO (
338 (unsigned)dest_file_handle, /* File handle */
339 (unsigned)1, /* File info data required */
340 (char far *)&fileinfo_buf, /* File info buffer */
341 (unsigned)buflen); /* File info buffer size */
342
343 /*if fail, unexperror "file creation error"*/
344 if (retcode != NOERROR)
345 { display_it(FILE_CREATION_ERROR,STND_ERR_DEV,0,NO_RESPTYPE,(BYTE)UTIL_MSG); /*;AN000;6*/
346 usererror(retcode);
347 }
348
349 /******************************************************************/
350 /*close dest file */
351 /******************************************************************/
352 DOSCLOSE(dest_file_handle);
353
354 /******************************************************************/
355 /*DosSetFileMode to set file attrib of d:infspec(from input line) */
356 /*to be the attrib in finfo structure */
357 /******************************************************************/
358 finfo->attrib = finfo->attrib & 0xffdf;
359 retcode =
360 DOSSETFILEMODE
361 (
362 (char far *)dest_file_spec,
363 (unsigned) finfo->attrib, (DWORD) 0
364 );
365
366
367 /******************************************************************/
368 /*reset flag PARTIAL */
369 /******************************************************************/
370 set_reset_test_flag(&control_flag,PARTIAL,RESET);
371
372return(0); /* wrw! */
373
374} /*end of subroutine*/
375
376/* *************** START OF SPECIFICATION ********************************
377/*
378/* SUBROUTINE NAME : dos_write_error
379/*
380/* DESCRIPTIVE NAME : Determine the cause of the error during
381/* DOS write, and output message according to it.
382/*
383/* FUNCTION: If error returned from get free space of the disk
384/* is caused by disk full, a message "target disk is
385/* full" is output to the user.
386/* Otherwise, the error is caused by other reason, and
387/* a message "file creation error" is output to the user.
388/*
389/*
390/********************** END OF SPECIFICATIONS *******************************/
391int dos_write_error(buf_size,destd)
392DWORD buf_size;
393BYTE destd;
394{
395 DWORD free_space;
396 WORD drive_num;
397 struct fsinfo *fsinfo_buf;
398
399 WORD retcode;
400
401 /******************************************************************/
402 /*DosQFsinfo: get free space in the hard disk */
403 /******************************************************************/
404 drive_num = destd - 'A' + 1;
405 retcode = DOSQFSINFO
406 ((unsigned)drive_num, /* Drive number - 0=default, 1=A, etc */
407 (unsigned)1, /* File system info required */
408 (char far *)fsinfo_buf, /* File system info buffer */
409 (unsigned)FSINFO_BYTES /* File system info buffer size */
410 );
411
412
413 free_space = fsinfo_buf->sectors_per_alloc_unit *
414 fsinfo_buf->available_alloc_unit *
415 fsinfo_buf->bytes_per_sector;
416
417
418 /******************************************************************/
419 /*if the free space left is less than buffer size for file read */
420 /* and write, output msg "target is full", and "file creation */
421 /* error", otherwise, output "file creation error". */
422 /******************************************************************/
423 if ( free_space < buf_size)
424 { display_it(TARGET_IS_FULL,STND_ERR_DEV,0,NO_RESPTYPE,(BYTE)UTIL_MSG); /*;AN000;6*/
425
426 /*close dest file*/
427 DOSCLOSE(dest_file_handle);
428
429 if ((retcode = DOSDELETE((char far *)&dest_file_spec[0],
430 (DWORD)0)) != 0)
431 {
432 /*set file mode to 0*/
433 retcode =
434 DOSSETFILEMODE
435 (
436 (char far *)&dest_file_spec[0],
437 (unsigned) 0x00,
438 (DWORD)0
439 );
440
441 /* delete the partially completed destination file*/
442 retcode = DOSDELETE((char far *) dest_file_spec,(DWORD)0);
443 }
444
445 display_it(LAST_FILE_NOT_RESTORED,STND_ERR_DEV,0,NO_RESPTYPE,(BYTE)UTIL_MSG); /*;AN000;6*/
446 usererror(TARGETFULL);
447 }
448 else
449 { display_it(FILE_CREATION_ERROR,STND_ERR_DEV,0,NO_RESPTYPE,(BYTE)UTIL_MSG); /*;AN000;6*/
450 usererror(CREATIONERROR);
451 }
452 /*endif*/
453
454 return(0); /* wrw! */
455
456}/*end of subroutine*/