2 /*------------------------------
3 /* SOURCE FILE NAME: rtfile1.c
4 /*------------------------------
10 #include "restpars.h" /*;AN000;4*/
13 #include "dos.h" /*;AN000;2*/
14 #include "comsub.h" /* common subroutine def'n */
18 char ext_attrib_buff[4086]; /*;AN000;3*/
21 extern BYTE control_flag;
22 extern BYTE control_flag2;
23 extern unsigned dest_file_handle;
24 extern unsigned src_file_handle;
25 extern BYTE far *buf_pointer;
26 extern BYTE dest_file_spec[MAXFSPEC+3];
27 extern struct FileFindBuf filefindbuf;
29 extern struct file_header_new far *fheadnew; /*;AN000;3 */
31 /*
\f*************** START OF SPECIFICATION ********************************
33 /* SUBROUTINE NAME : open_dest_file
35 /* DESCRIPTIVE NAME : open the destination file and build a path to it
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.
47 /********************** END OF SPECIFICATIONS ******************************/
48 WORD open_dest_file(finfo,destd)
49 struct file_info *finfo;
52 BYTE fname[MAXFSPEC+2];
53 BYTE path_to_be_chdir[MAXPATH+2];
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*/
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
73 /**************************************************************************/
75 if (strcmp(finfo->path,finfo->curdir)!=0)
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)
85 build_path_create_file(finfo->path,destd,finfo->fflag,finfo->ea_offset); /*;AC000;3*/
86 if (dest_file_handle != NULLC)
91 /* Current directory is the one where files are to be restored to*/
93 retcode = create_the_file(finfo->fflag,finfo->ea_offset); /*;AN000;3*/
95 if (retcode == NOERROR)
98 /*----------------------------------------*/
99 /*- There was an error creating target -*/
100 /*- file. Reset attribute and try again -*/
101 /*----------------------------------------*/
105 (char far *)&dest_file_spec[0],
110 retcode = create_the_file(finfo->fflag,finfo->ea_offset); /*;AN000;3*/
112 if (retcode == NOERROR)
115 return(FALSE); /*;AC000;p1102*/
118 } /*end of subroutine*/
119 /*
\f*************** START OF SPECIFICATION ********************************
121 /* SUBROUTINE NAME : build_path_create_file
123 /* DESCRIPTIVE NAME : Build path for the destination file, and create
124 /* the file in the current direactory.
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
131 /********************* END OF SPECIFICATIONS ********************************/
132 void build_path_create_file(in_path,destd,fflag,ea_offset)
135 BYTE fflag; /*;AN000;3*/
136 DWORD ea_offset; /*;AN000;3*/
140 BYTE path[MAXPATH+2];
142 BYTE cant_make = FFALSE; /*;AN000;10*/
147 strcat(path,in_path);
151 /* Create the path for destination file */
152 /*Loop until mkdir(path) is successful*/
154 while (mkdir(path) && !cant_make) /*;AC000;10*/
156 /*scan path backward until find a \ */
157 for (; path[i] != '\\'; i--)
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*/
165 /*obtain the last subdir from the path */
168 /*save the location of the last \ in an array of \ locations */
172 /*loop through the array of \ locations*/
176 if (i >= 0 && !cant_make) /*;AC000;10*/
178 path[array[i]] = '\\';
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*/
191 chdir(path); /*;AN000;3*/
192 retcode = create_the_file(fflag,ea_offset); /*;AN000;3*/
198 /********************************************************/
200 /* SUBROUTINE NAME: create_the_file
202 /* DESCRIPTIVE NAME : Create the target file.
203 /* Use DOS 4.00 Extended Create Function 6C00h
204 /* Remember to handle Extended Attributes!
206 /********************************************************/
207 #define EXTENDEDOPEN 0x6c00 /*;AN000;3*/
208 WORD create_the_file(fflag,ea_offset) /*;AN000;3*/
209 BYTE fflag; /*;AN000;3*/
210 DWORD ea_offset; /*;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*/
217 if ((fflag & EXT_ATTR_FLAG) == EXT_ATTR_FLAG) /*;AN000;3*/
218 read_the_extended_attributes(ea_offset); /*;AN000;3*/
220 ea_parmlist.ext_attr_addr = (DWORD)(char far *)&ext_attrib_buff[0];/*;AN000;3*/
221 ea_parmlist.num_additional = 0; /*;AN000;3*/
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*/
230 reg.x.si = (WORD)&dest_file_spec[0]; /* Filename */ /*;AN000;3*/
232 if ((fflag & EXT_ATTR_FLAG) == EXT_ATTR_FLAG) /*;AN000;3*/
233 reg.x.di = (WORD)&ea_parmlist; /* Parmlist */ /*;AN000;3*/
235 reg.x.di = 0xffff; /* No parmlist */ /*;AN000;3*/
237 intdos(®,®); /*;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*/
241 dest_file_handle = reg.x.ax; /*;AN000;3*/
243 return(retcode); /*;AN000;3*/
245 /********************************************************/
247 /* SUBROUTINE NAME: read_the_extended_attributes
249 /* DESCRIPTIVE NAME : reads in the extended attributes
251 /********************************************************/
252 void read_the_extended_attributes(ea_offset) /*;AN000;3*/
253 DWORD ea_offset; /*;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*/
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*/
270 /*************************************/
271 /* Read in Extended Attribute length */
272 retcode = /*;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*/
281 /***********************************/
282 /* Read in the Extended Attributes */
283 retcode = /*;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*/
295 /*
\f*************** START OF SPECIFICATION ********************************
297 /* SUBROUTINE NAME : set_attributes_and_close
299 /* DESCRIPTIVE NAME : Set the file attributes and close the file
301 /* FUNCTION: Set the attributes and last write date/time of the file just
302 /* restored to be like those of the backup file.
304 /********************* END OF SPECIFICATIONS ********************************/
305 int set_attributes_and_close(finfo,destd)
306 struct file_info *finfo;
309 struct FileStatus fileinfo_buf;
311 WORD buflen = sizeof(struct FileStatus);
315 destdnum = destd - 'A' + 1;
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 */
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*/
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 */
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*/
349 /******************************************************************/
351 /******************************************************************/
352 DOSCLOSE(dest_file_handle);
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;
362 (char far *)dest_file_spec,
363 (unsigned) finfo->attrib, (DWORD) 0
367 /******************************************************************/
368 /*reset flag PARTIAL */
369 /******************************************************************/
370 set_reset_test_flag(&control_flag,PARTIAL,RESET);
372 return(0); /* wrw! */
374 } /*end of subroutine*/
376 /*
\f*************** START OF SPECIFICATION ********************************
378 /* SUBROUTINE NAME : dos_write_error
380 /* DESCRIPTIVE NAME : Determine the cause of the error during
381 /* DOS write, and output message according to it.
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.
390 /********************** END OF SPECIFICATIONS *******************************/
391 int dos_write_error(buf_size,destd)
397 struct fsinfo *fsinfo_buf;
401 /******************************************************************/
402 /*DosQFsinfo: get free space in the hard disk */
403 /******************************************************************/
404 drive_num = destd - 'A' + 1;
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 */
413 free_space = fsinfo_buf->sectors_per_alloc_unit *
414 fsinfo_buf->available_alloc_unit *
415 fsinfo_buf->bytes_per_sector;
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*/
427 DOSCLOSE(dest_file_handle);
429 if ((retcode = DOSDELETE((char far *)&dest_file_spec[0],
432 /*set file mode to 0*/
436 (char far *)&dest_file_spec[0],
441 /* delete the partially completed destination file*/
442 retcode = DOSDELETE((char far *) dest_file_spec,(DWORD)0);
445 display_it(LAST_FILE_NOT_RESTORED,STND_ERR_DEV,0,NO_RESPTYPE,(BYTE)UTIL_MSG); /*;AN000;6*/
446 usererror(TARGETFULL);
449 { display_it(FILE_CREATION_ERROR,STND_ERR_DEV,0,NO_RESPTYPE,(BYTE)UTIL_MSG); /*;AN000;6*/
450 usererror(CREATIONERROR);
454 return(0); /* wrw! */
456 }/*end of subroutine*/