]> wirehaze git hosting - MS-DOS.git/blob - v4.0/src/CMD/RESTORE/RTT.C

wirehaze git hosting

MZ is back!
[MS-DOS.git] / v4.0 / src / CMD / RESTORE / RTT.C
1 static char *SCCSID = "@(#)rtt.c 8.1 86/09/20";
2
3 /* \ f \e0 */
4
5 #include <stdio.h>
6 #include "rt.h"
7 #include "rt1.h"
8 #include "rt2.h"
9 #include <comsub.h> /* common subroutine def'n */
10 #include <doscalls.h>
11 #include <basemid.h>
12 #include <wrwdefs.h> /* wrw! */
13
14 unsigned char destddir[MAXPATH+3] = {'\0'};
15 unsigned char srcddir[MAXPATH+3] = {'\0'};
16 unsigned char rtswitch=0;
17 unsigned char control_flag=0;
18 unsigned char control_flag2=0;
19 unsigned char filename[MAXFSPEC] = {"OSO001.MSG"};
20 unsigned char *buf_pointer;
21
22 /****************************************************************************/
23 /* The following comments are necessary to be here to make msgprof.exe */
24 /* correctly. */
25 /****************************************************************************/
26 /* #define INSERT_SOURCE_DISK MSG_INS_BACKUP_DISK */
27 /* #define SOURCE_TARGET_SAME MSG_REST_SOUR_TARG_SAME */
28 /* #define INVALID_NUM_PARM MSG_REST_NUM_INVAL_PARA */
29 /* #define INVALID_DRIVE MSG_REST_INVAL_SPEC */
30 /* #define NO_FILE_TO_RESTORE MSG_REST_NO_FILE_FOUND */
31 /* #define INVALID_PARM MSG_REST_INVAL_PARA */
32 /* #define LAST_FILE_NOT_RESTORED MSG_REST_LAST_FILE_NOT */
33 /* #define SOURCE_NO_BACKUP_FILE MSG_REST_SOURCE_NO_BACK */
34 /* #define INSUFFICIENT_MEMORY MSG_REST_INSUF_MEM */
35 /* #define FILE_SEQUENCE_ERROR MSG_REST_FILE_SEQ_ERROR */
36 /* #define FILE_CREATION_ERROR MSG_REST_FILE_CREAT_ERROR */
37 /* #define TARGET_IS_FULL MSG_REST_TARG_FULL */
38 /* #define NOT_ABLE_TO_RESTORE_FILE MSG_REST_CANNOT_REST_FILE */
39 /* #define INVALID_DOS_VER MSG_REST_INVAL_VERS */
40 /* #define FILE_SHARING_ERROR MSG_REST_FILE_SHAR */
41 /* #define FILE_WAS_CHANGED MSG_REST_CHNG_REPL */
42 /* #define DISK_OUT_OF_SEQUENCE MSG_REST_DISK_OUT_SEQ */
43 /* #define FILE_IS_READONLY MSG_REST_FILE_READ */
44 /* #define SYSTEM_FILE_RESTORED MSG_REST_SYS */
45 /* #define FILES_WERE_BACKUP_ON MSG_REST_FILE_BACKUP */
46 /* #define RESTORE_FILE_FROM_DRIVE MSG_REST_FILE_FROM */
47 /* #define INSERT_TARGET_DISK MSG_REST_TARG_DISK */
48 /* #define FILE_TO_BE_RESTORED MSG_REST_FILENAME */
49 /* #define DISKETTE_NUM MSG_REST_DISKETTE */
50 /* #define PATH_NOT_FOUND MSG_BACK_INVAL_PATH */
51
52 /***************** START OF SPECIFICATION *********************************/
53 /* */
54 /* MODULE NAME : RESTORE utility */
55 /* */
56 /* DESCRIPTIVE NAME : Restore one or more backed-up files from a */
57 /* disk to another disk */
58 /* */
59 /* FUNCTION: Restore files saved by BACKUP utility to their */
60 /* destination disk. This utility will be able to identify */
61 /* which of the two backup formats was used and to do the */
62 /* restore accordingly. */
63 /* */
64 /* NOTES: This RESTORE utility recognize two data formats: */
65 /* 1. The data format used by BACKUP utility of 3.2 and before. */
66 /* 2. The data format used by BACKUP utility of 3.3 and above, */
67 /* and also used by CP/DOS 1.0 and above. */
68 /* */
69 /* DEPENDENCY: */
70 /* This utility has a dependency on the BACKUP utility to */
71 /* perform file backup correctly using the data structure */
72 /* agreed on. */
73 /* */
74 /* RESTRICTION: */
75 /* This utility is able to restore the files which are previously */
76 /* backup by IBM BACKUP utility only. */
77 /* */
78 /* ENTRY POINT: Main */
79 /* */
80 /* INPUT: (PARAMETERS) */
81 /* */
82 /* COMMAND SYNTAX: */
83 /* [d:][path]Restore d: [d:][path][filename][.ext] */
84 /* [/S] [/P] [/B:date] [/A:date] [/E:time][/L:time][/M] [/N] */
85 /* */
86 /* Parameters: */
87 /* The first parameter you specify is the drive designator of */
88 /* the disk containing the backed up files. The second */
89 /* parameter is the a filespec indicating which files you want */
90 /* to restore. */
91 /* Switches: */
92 /* /S - Restore subdirectories too. */
93 /* /P - If any hidden or read-only files match the filespec, */
94 /* prompt the user for permission to restore them. */
95 /* /B - Only restore those files which were last Revised on or */
96 /* before the given date. */
97 /* /A - Only restore those files which were last Revised on or */
98 /* after the given date. */
99 /* /E - Only restore those files which were last Revised at or */
100 /* earlier then the given time. */
101 /* /L - Only restore those files which were last Revised at or */
102 /* later then the given time. */
103 /* /M - Only restore those files which have been Revised since */
104 /* the last backup. */
105 /* /N - Only restore those files which no longer exist on the */
106 /* destination disk. */
107 /* */
108 /* EXIT-NORMAL: */
109 /* */
110 /* The following messages will be displayed when the program */
111 /* exit normally. */
112 /* */
113 /* *** Files were backed up xx/xx/xxxx *** */
114 /* (xx/xx/xxxx will be different in differnt country codes) */
115 /* */
116 /* *** Restoring files from drive d: *** */
117 /* Diskette: xx */
118 /* path\filename.ext */
119 /* path\filename.ext */
120 /* path\filename.ext */
121 /* path\filename.ext */
122 /* ..... */
123 /* */
124 /* EXIT-ERROR: */
125 /* The restore program sets the ERRORLEVEL in the following manner: */
126 /* */
127 /* 0 Normal completion */
128 /* 1 No files were found to backup */
129 /* 2 Some files not restored due to sharing conflict */
130 /* 3 Terminated by user */
131 /* 4 Terminated due to error */
132 /* */
133 /* EFFECTS: None */
134 /* */
135 /* OTHER USER INTERFACES: */
136 /* RESTORE prompts for the user to insert source diskette if */
137 /* the source disk specified is removable: */
138 /* */
139 /* Insert backup diskette 01 in drive d: */
140 /* (d: is the source diskette) */
141 /* Strike any key when ready */
142 /* */
143 /* If the destination disk is a removable drive, the following */
144 /* message is also displayed: */
145 /* */
146 /* Insert restore target in drive d: */
147 /* (d: is the destination disk) */
148 /* Strike any key when ready */
149 /* */
150 /* No matter whether the destination disk is a removable drive */
151 /* or a non_removable drive, when the destination disk is full, */
152 /* RESTORE output a message "Target is full" and exit. RESTORE */
153 /* does not prompt for user to change destination disk when it */
154 /* is full. */
155 /* */
156 /* When there is any system file restored, the following message */
157 /* is displayed: */
158 /* System file restored */
159 /* Target disk may not be bootable */
160 /* */
161 /* INTERNAL REFERENCES: */
162 /* ROUTINES: */
163 /* Major routines are shown as follows: */
164 /* main */
165 /* parse_input_drive_and_file */
166 /* set_input_switches */
167 /* verify_input_switches */
168 /* dorestore */
169 /* check_bkdisk_old */
170 /* printinfo */
171 /* check_bkdisk_new */
172 /* search_src_disk_old */
173 /* check_flheader_old */
174 /* pathmatch */
175 /* fspecmatch */
176 /* switchmatch */
177 /* restore_a_file */
178 /* search_src_disk_new */
179 /* findfirst_new */
180 /* findfile_new */
181 /* findnext_new */
182 /* check_flheader_new */
183 /* readonly_or_changed */
184 /* open_dest_file */
185 /* build_path_create_file */
186 /* dos_write_error */
187 /* set_attributes_and_close */
188 /* */
189 /* Minor routines are shown as follows: */
190 /* signal_handler_routine */
191 /* usererror */
192 /* unexperror */
193 /* exit_routine */
194 /* putmsg */
195 /* com_msg */
196 /* beep */
197 /* checkdosver */
198 /* separate */
199 /* initbuf */
200 /* init_control_buf */
201 /* set_reset_test_flag */
202 /* valid_input_date */
203 /* valid_input_time */
204 /* */
205 /***************** END OF SPECIFICATION *********************************/
206 /***************** START OF SPECIFICATION *********************************/
207 /* */
208 /* SUBROUTINE NAME : Main */
209 /* */
210 /* DESCRIPTIVE NAME : Main routine for RESTORE utility */
211 /* */
212 /* FUNCTION: Main routine does the following: */
213 /* 1. Verifies the DOS version */
214 /* 2. Validate the input command line */
215 /* 3. Calls dorestore to do the file restore. */
216 /* */
217 /* NOTES: */
218 /* */
219 /* ENTRY POINT: Main */
220 /* Linkage: main((argc,argv) */
221 /* */
222 /* INPUT: (PARAMETERS) */
223 /* argc - number of arguments */
224 /* argv - array of pointers to arguments */
225 /* */
226 /* */
227 /* EXIT-NORMAL: */
228 /* */
229 /* EXIT-ERROR: */
230 /* */
231 /* EFFECTS: rtswitch is changed to reflect the switches passed. */
232 /* */
233 /* INTERNAL REFERENCES: */
234 /* ROUTINES: */
235 /* dorestore */
236 /* checkdosver */
237 /* set_input_switches */
238 /* parse_input_drive_and_file */
239 /* separate */
240 /* beep */
241 /* putmsg */
242 /* usererror */
243 /* exit_routine */
244 /* set_reset_test_flag */
245 /* set_input_switches */
246 /* exit_routine */
247 /* */
248 /* EXTERNAL REFERENCES: */
249 /* ROUTINES: */
250 /* com_strupr */
251 /* DSOSETSIGHANDLER */
252 /* */
253 /********************** END OF SPECIFICATIONS *******************************/
254 void main(argc,argv) /* wrw! */
255 int argc;
256 char *argv[];
257 {
258 /*variables for putmsg */
259 unsigned char *ivtable[2];/*point to the table of bairables to insert*/
260 unsigned char respdata; /*response data area*/
261 unsigned int msg_id;
262 unsigned int retcode;
263
264 unsigned int destdnum; /*the destination disk in the integer form*/
265 unsigned int i; /*loop counter */
266 unsigned int j; /*arrary subcript */
267 unsigned char *c;
268 unsigned long drive_map;
269 unsigned long prev_address;
270 unsigned int prev_action;
271 unsigned char srcd;
272 unsigned char destd;
273 unsigned char srcf[MAXPATHF];
274 unsigned char inpath[MAXPATH];
275 unsigned char infname[MAXFNAME];
276 unsigned char infext[MAXFEXT];
277 unsigned char infspec[MAXFSPEC];
278 unsigned int next_arg;
279 struct timedate td;
280 void far pascal signal_handler_routine();
281 /************************************************************************/
282 /* set signal handler */
283 /************************************************************************/
284
285 retcode = DOSSETSIGHANDLER(
286 (void (far *)() )signal_handler_routine, /* Signal handler address */
287 (unsigned long far *)&prev_address, /* Address of previous handler */
288 (unsigned far *)&prev_action, /* Address of previous action */
289 (unsigned)INSTALL_SIGNAL, /* Indicate request type */
290 (unsigned)CTRL_C); /* Signal number */
291
292 if (retcode != 0)
293 com_msg(retcode);
294
295 retcode = DOSSETSIGHANDLER(
296 (void (far *)() )signal_handler_routine, /* Signal handler address */
297 (unsigned long far *)&prev_address, /* Address of previous handler */
298 (unsigned far *)&prev_action, /* Address of previous action */
299 (unsigned)INSTALL_SIGNAL, /* Indicate request type */
300 (unsigned)CTRL_BREAK); /* Signal number */
301
302 if (retcode != 0)
303 com_msg(retcode);
304
305 /************************************************************************/
306 /* check dos version */
307 /************************************************************************/
308 retcode = checkdosver();
309 if (retcode != TRUE) {
310
311 msg_id = INVALID_DOS_VER;
312 putmsg (ivtable,0,msg_id,NO_RESPTYPE,&respdata,RESPDATA_SIZE);
313
314 usererror(ERROR_INVALID_DOSVER);
315 }
316
317 /************************************************************************/
318 /*convert the input arguments into upper case */
319 /************************************************************************/
320 for (i=1; i <=argc-1; ++i) {
321 com_strupr(argv[i]);
322 }
323
324 /************************************************************************/
325 /* verify the number of parameters */
326 /************************************************************************/
327 if (argc-1 < MINARGS || argc-1 > MAXARGS) {
328 msg_id = INVALID_NUM_PARM; /*invalid number of parameters*/
329 putmsg (ivtable,0,msg_id,NO_RESPTYPE,&respdata,RESPDATA_SIZE);
330 usererror(INVALIDPARM);
331 }
332 /* endif*/
333
334 /************************************************************************/
335 /* call subroutine to parse the drive and file name entered */
336 /************************************************************************/
337 parse_input_drive_and_file( argc, argv, &destd, &srcd,
338 srcf, &next_arg) ;
339
340 /************************************************************************/
341 /* separate the filename for search into prefix(inpath), */
342 /* filename(infname), and file extension (infext) */
343 /* Also take care of the situation that user enter '.' only */
344 /* for file spec. */
345 /************************************************************************/
346 separate(srcf,inpath,infname,infext,infspec);
347 if (strlen(infname) > MAXFNAME-1 ||
348 strlen(infext) > MAXFEXT-1 ||
349 strlen(inpath) > MAXPATH-1 ||
350 strcmp(infspec,"LPT1")==0 ||
351 strcmp(infspec,"LPT2")==0 ||
352 strcmp(infspec,"PRN")==0 ||
353 strcmp(infspec,"CON")==0 ||
354 strcmp(infspec,"NUL")==0 ||
355 strcmp(infspec,"AUX")==0 ||
356 strcmp(infspec,"LPT1:")==0 ||
357 strcmp(infspec,"LPT2:")==0 ||
358 strcmp(infspec,"PRN:")==0 ||
359 strcmp(infspec,"CON:")==0 ||
360 strcmp(infspec,"NUL:")==0 ||
361 strcmp(infspec,"AUX:")==0 )
362 {
363 msg_id = INVALID_PARM;
364 ivtable[0] = infspec;
365 putmsg (ivtable,1,msg_id,NO_RESPTYPE,&respdata,RESPDATA_SIZE);
366 usererror(INVALIDPARM); /* invalid parm */
367 }
368
369 /************************************************************************/
370 /* set wildcard flag according to whether there is '*' or/and '?' in */
371 /* file specification */
372 /************************************************************************/
373 c = infspec;
374 while (*c) {
375 if (*c == '*' || *c == '?') {
376 set_reset_test_flag(&control_flag,WILDCARD,SET);
377 break;
378 }
379 else
380 c = c+1;
381 } /*end while*/
382
383 /************************************************************************/
384 /* if there is any more parameters to be parsed, call set_input_switches*/
385 /* to parse them started from argv[next_arg] */
386 /************************************************************************/
387 if (next_arg != 0 && argc > next_arg) {
388 set_input_switches( argc, argv, &next_arg, &td);
389 } /* started from argv[next_arg] should be switches */
390
391 /************************************************************************/
392 /* call dorestore to actually do the restoring */
393 /************************************************************************/
394 dorestore(srcd,destd,inpath,infname,infext,infspec,&td);
395
396 /************************************************************************/
397 /* output a msg in the following situations: */
398 /* if flag indicates no file found */
399 /************************************************************************/
400 if (set_reset_test_flag(&control_flag,FOUND,TEST)==FALSE) {
401 beep();
402 msg_id = NO_FILE_TO_RESTORE; /*warning! No files were found to restore*/
403 putmsg (ivtable,0,msg_id,NO_RESPTYPE,&respdata,RESPDATA_SIZE);
404 exit_routine(NOFILES);
405 }
406
407 exit_routine(NORMAL);
408
409 } /* end of main*/