diff options
| author | 2024-04-25 21:24:10 +0100 | |
|---|---|---|
| committer | 2024-04-25 22:32:27 +0000 | |
| commit | 2d04cacc5322951f187bb17e017c12920ac8ebe2 (patch) | |
| tree | 80ee017efa878dfd5344b44249e6a241f2a7f6e2 /v4.0/src/CMD/RESTORE | |
| parent | Merge pull request #430 from jpbaltazar/typoptbr (diff) | |
| download | ms-dos-main.tar.gz ms-dos-main.tar.xz ms-dos-main.zip | |
Diffstat (limited to 'v4.0/src/CMD/RESTORE')
26 files changed, 7913 insertions, 0 deletions
diff --git a/v4.0/src/CMD/RESTORE/DIRECT.H b/v4.0/src/CMD/RESTORE/DIRECT.H new file mode 100644 index 0000000..aba9076 --- /dev/null +++ b/v4.0/src/CMD/RESTORE/DIRECT.H | |||
| @@ -0,0 +1,26 @@ | |||
| 1 | /* | ||
| 2 | * direct.h | ||
| 3 | * | ||
| 4 | * This include file contains the function declarations for the library | ||
| 5 | * functions related to directory handling and creation. | ||
| 6 | * | ||
| 7 | * Copyright (C) 1988 Microsoft Corporation | ||
| 8 | * | ||
| 9 | */ | ||
| 10 | |||
| 11 | /* function declarations for those who want strong type checking | ||
| 12 | * on arguments to library function calls | ||
| 13 | */ | ||
| 14 | |||
| 15 | #ifdef LINT_ARGS /* arg. checking enabled */ | ||
| 16 | |||
| 17 | int chdir(char *); | ||
| 18 | char *getcwd(char *, int); | ||
| 19 | int mkdir(char *); | ||
| 20 | int rmdir(char *); | ||
| 21 | |||
| 22 | #else | ||
| 23 | |||
| 24 | extern char *getcwd(); | ||
| 25 | |||
| 26 | #endif /* LINT_ARGS */ | ||
diff --git a/v4.0/src/CMD/RESTORE/MAKEFILE b/v4.0/src/CMD/RESTORE/MAKEFILE new file mode 100644 index 0000000..ba67431 --- /dev/null +++ b/v4.0/src/CMD/RESTORE/MAKEFILE | |||
| @@ -0,0 +1,108 @@ | |||
| 1 | #************************** makefile for cmd\... *************************** | ||
| 2 | |||
| 3 | msg =..\..\messages | ||
| 4 | dos =..\..\dos | ||
| 5 | inc =..\..\inc | ||
| 6 | hinc =..\..\h | ||
| 7 | |||
| 8 | # | ||
| 9 | ####################### dependencies begin here. ######################### | ||
| 10 | # | ||
| 11 | |||
| 12 | map =..\..\mapper | ||
| 13 | here =..\cmd\restore | ||
| 14 | |||
| 15 | all: not_file restore.com | ||
| 16 | |||
| 17 | #-------BUILD MAPPER ---------------- | ||
| 18 | not_file : makefile #Always perform these steps! | ||
| 19 | cd $(map) | ||
| 20 | nmake | ||
| 21 | cd $(here) | ||
| 22 | |||
| 23 | |||
| 24 | _parse.obj : _parse.asm \ | ||
| 25 | makefile \ | ||
| 26 | $(inc)\parse.asm \ | ||
| 27 | $(inc)\psdata.inc | ||
| 28 | |||
| 29 | restore.ctl : restore.skl \ | ||
| 30 | makefile \ | ||
| 31 | $(msg)\$(COUNTRY).msg | ||
| 32 | |||
| 33 | |||
| 34 | _msgret.obj: _msgret.asm \ | ||
| 35 | makefile \ | ||
| 36 | restore.ctl \ | ||
| 37 | restore.cl1 \ | ||
| 38 | $(inc)\msgserv.asm \ | ||
| 39 | $(inc)\sysmsg.inc | ||
| 40 | |||
| 41 | |||
| 42 | restore.obj : restore.c rt.h rt1.h rt2.h restpars.h makefile \ | ||
| 43 | $(hinc)\comsub.h $(hinc)\doscalls.h \ | ||
| 44 | $(hinc)\error.h | ||
| 45 | |||
| 46 | rtt1.obj : rtt1.c rt.h rt1.h rt2.h restpars.h makefile \ | ||
| 47 | $(hinc)\comsub.h $(hinc)\doscalls.h \ | ||
| 48 | $(hinc)\error.h | ||
| 49 | |||
| 50 | rtt3.obj : rtt3.c rt.h rt1.h rt2.h restpars.h makefile \ | ||
| 51 | $(hinc)\comsub.h $(hinc)\doscalls.h \ | ||
| 52 | $(hinc)\error.h | ||
| 53 | |||
| 54 | rtdo.obj : rtdo.c rt.h rt1.h rt2.h restpars.h makefile \ | ||
| 55 | $(hinc)\comsub.h $(hinc)\doscalls.h \ | ||
| 56 | $(hinc)\error.h | ||
| 57 | |||
| 58 | rtdo1.obj : rtdo1.c rt.h rt1.h rt2.h restpars.h makefile \ | ||
| 59 | $(hinc)\comsub.h $(hinc)\doscalls.h \ | ||
| 60 | $(hinc)\error.h | ||
| 61 | |||
| 62 | rtnew.obj : rtnew.c rt.h rt1.h rt2.h restpars.h makefile \ | ||
| 63 | $(hinc)\comsub.h $(hinc)\doscalls.h \ | ||
| 64 | $(hinc)\error.h | ||
| 65 | |||
| 66 | rtnew1.obj : rtnew1.c rt.h rt1.h rt2.h restpars.h makefile \ | ||
| 67 | $(hinc)\comsub.h $(hinc)\doscalls.h \ | ||
| 68 | $(hinc)\error.h | ||
| 69 | |||
| 70 | rtold.obj : rtold.c rt.h rt1.h rt2.h restpars.h makefile \ | ||
| 71 | $(hinc)\comsub.h $(hinc)\doscalls.h \ | ||
| 72 | $(hinc)\error.h | ||
| 73 | |||
| 74 | rtold1.obj : rtold1.c rt.h rt1.h rt2.h restpars.h makefile \ | ||
| 75 | $(hinc)\comsub.h $(hinc)\doscalls.h \ | ||
| 76 | $(hinc)\error.h | ||
| 77 | |||
| 78 | rtfile.obj : rtfile.c rt.h rt1.h rt2.h restpars.h makefile \ | ||
| 79 | $(hinc)\comsub.h $(hinc)\doscalls.h \ | ||
| 80 | $(hinc)\error.h | ||
| 81 | |||
| 82 | rtfile1.obj : rtfile1.c rt.h rt1.h rt2.h restpars.h makefile \ | ||
| 83 | $(hinc)\comsub.h $(hinc)\doscalls.h \ | ||
| 84 | $(hinc)\error.h | ||
| 85 | |||
| 86 | restpars.obj : restpars.c rt.h rt1.h rt2.h restpars.h makefile \ | ||
| 87 | $(hinc)\comsub.h $(hinc)\doscalls.h \ | ||
| 88 | $(hinc)\error.h | ||
| 89 | |||
| 90 | restore.com: restore.obj \ | ||
| 91 | restpars.obj \ | ||
| 92 | rtdo.obj \ | ||
| 93 | rtdo1.obj \ | ||
| 94 | rtfile.obj \ | ||
| 95 | rtfile1.obj \ | ||
| 96 | rtnew.obj \ | ||
| 97 | rtnew1.obj \ | ||
| 98 | rtold.obj \ | ||
| 99 | rtold1.obj \ | ||
| 100 | rtt1.obj \ | ||
| 101 | rtt3.obj \ | ||
| 102 | restore.lnk \ | ||
| 103 | _msgret.obj \ | ||
| 104 | _parse.obj \ | ||
| 105 | $(map)\mapper.lib | ||
| 106 | link @restore.lnk | ||
| 107 | convert restore.exe restore.com | ||
| 108 | erase restore.exe | ||
diff --git a/v4.0/src/CMD/RESTORE/MESSAGES.INC b/v4.0/src/CMD/RESTORE/MESSAGES.INC new file mode 100644 index 0000000..fbc11bc --- /dev/null +++ b/v4.0/src/CMD/RESTORE/MESSAGES.INC | |||
| @@ -0,0 +1 @@ | |||
| include restmsg.inc \ No newline at end of file | |||
diff --git a/v4.0/src/CMD/RESTORE/RESTORE.C b/v4.0/src/CMD/RESTORE/RESTORE.C new file mode 100644 index 0000000..e60288f --- /dev/null +++ b/v4.0/src/CMD/RESTORE/RESTORE.C | |||
| @@ -0,0 +1,240 @@ | |||
| 1 | |||
| 2 | /* 0 */ | ||
| 3 | |||
| 4 | /**************************************************************************/ | ||
| 5 | /* | ||
| 6 | /* MODULE NAME : RESTORE utility | ||
| 7 | /* | ||
| 8 | /* SOURCE FILE NAME: RESTORE.C | ||
| 9 | /* | ||
| 10 | /* DESCRIPTIVE NAME : Restore one or more backed-up files from a | ||
| 11 | /* disk to another disk | ||
| 12 | /* | ||
| 13 | /* FUNCTION: Restore files saved by BACKUP utility to their | ||
| 14 | /* destination disk. This utility will be able to identify | ||
| 15 | /* which of the two backup formats was used and to do the | ||
| 16 | /* restore accordingly. | ||
| 17 | /* | ||
| 18 | /* NOTES: This RESTORE utility recognize two data formats: | ||
| 19 | /* 1. The data format used by BACKUP utility of 3.2 and before. | ||
| 20 | /* 2. The data format used by BACKUP utility of 3.3 and above, | ||
| 21 | /* and also used by CP/DOS 1.0 and above. | ||
| 22 | /* | ||
| 23 | /* DEPENDENCY: | ||
| 24 | /* This utility has a dependency on the BACKUP utility to | ||
| 25 | /* perform file backup correctly using the data structure | ||
| 26 | /* agreed on. | ||
| 27 | /* | ||
| 28 | /* RESTRICTION: | ||
| 29 | /* This utility is able to restore the files which are previously | ||
| 30 | /* backup by the BACKUP utility only. | ||
| 31 | /* | ||
| 32 | /* ENTRY POINT: Main | ||
| 33 | /* | ||
| 34 | /* INPUT: (PARAMETERS) | ||
| 35 | /* | ||
| 36 | /* COMMAND SYNTAX: | ||
| 37 | /* [d:][path]Restore d: [d:][path][filename][.ext] | ||
| 38 | /* [/S] [/P] [/B:date] [/A:date] [/E:time][/L:time][/M] [/N] | ||
| 39 | /* | ||
| 40 | /* Parameters: | ||
| 41 | /* The first parameter you specify is the drive designator of | ||
| 42 | /* the disk containing the backed up files. The second | ||
| 43 | /* parameter is the a filespec indicating which files you want | ||
| 44 | /* to restore. | ||
| 45 | /* Switches: | ||
| 46 | /* /S - Restore subdirectories too. | ||
| 47 | /* /P - If any hidden or read-only files match the filespec, | ||
| 48 | /* prompt the user for permission to restore them. | ||
| 49 | /* /B - Only restore those files which were last Revised on or | ||
| 50 | /* before the given date. | ||
| 51 | /* /A - Only restore those files which were last Revised on or | ||
| 52 | /* after the given date. | ||
| 53 | /* /E - Only restore those files which were last Revised at or | ||
| 54 | /* earlier then the given time. | ||
| 55 | /* /L - Only restore those files which were last Revised at or | ||
| 56 | /* later then the given time. | ||
| 57 | /* /M - Only restore those files which have been Revised since | ||
| 58 | /* the last backup. | ||
| 59 | /* /N - Only restore those files which no longer exist on the | ||
| 60 | /* destination disk. | ||
| 61 | /* | ||
| 62 | /* EXIT-ERROR: | ||
| 63 | /* The restore program sets the ERRORLEVEL in the following manner: | ||
| 64 | /* | ||
| 65 | /* 0 Normal completion | ||
| 66 | /* 1 No files were found to backup | ||
| 67 | /* 2 Some files not restored due to sharing conflict | ||
| 68 | /* 3 Terminated by user | ||
| 69 | /* 4 Terminated due to error | ||
| 70 | /* | ||
| 71 | /* | ||
| 72 | /* SOURCE HISTORY: | ||
| 73 | /* | ||
| 74 | /* Modification History: | ||
| 75 | /* | ||
| 76 | /* Code added in DOS 3.3 to allow control file > 64k commented as: | ||
| 77 | /* /* !wrw */ | ||
| 78 | /* | ||
| 79 | /* ;AN000; Code added in DOS 4.0 | ||
| 80 | /* ;AN000;2 Support for APPEND /X deactivation | ||
| 81 | /* ;AN000;3 Support for Extended Attributes | ||
| 82 | /* ;AN000;4 Support for PARSE service routines | ||
| 83 | /* ;AN000;5 Support for code page file tags | ||
| 84 | /* ;AN000;6 Support for MESSAGE retriever | ||
| 85 | /* ;AN000;8 Eliminate double prompting on single drive systems | ||
| 86 | /* ;AN000;9 Fix for termination on "Unable to MKDIR" | ||
| 87 | /* ;AN000;10 Fix for p1620 | ||
| 88 | /* ;AN001; Add CR, LF to end of command line | ||
| 89 | /* ;AN002; Make parser errors display the offending parameter | ||
| 90 | /* ;AN003; Only disallow restore of system files in ROOT !! | ||
| 91 | /* ;AN004; Fix parser | ||
| 92 | /* ;AN005; Replace COM_STRRCHR dbcs routine, fixes p5029 | ||
| 93 | /***************** END OF SPECIFICATION *********************************/ | ||
| 94 | |||
| 95 | #include "rt.h" | ||
| 96 | #include "rt1.h" | ||
| 97 | #include "rt2.h" | ||
| 98 | #include "restpars.h" /*;AN000;4*/ | ||
| 99 | #include "dos.h" /*;AN000;2*/ | ||
| 100 | #include "comsub.h" /* common subroutine def'n */ | ||
| 101 | #include "doscalls.h" | ||
| 102 | #include "error.h" | ||
| 103 | |||
| 104 | |||
| 105 | BYTE destddir[MAXPATH+3] = {'\0'}; | ||
| 106 | BYTE srcddir[MAXPATH+3] = {'\0'}; | ||
| 107 | BYTE rtswitch=0; | ||
| 108 | BYTE control_flag=0; | ||
| 109 | BYTE control_flag2=0; | ||
| 110 | BYTE *buf_pointer; | ||
| 111 | |||
| 112 | /*=============================*/ | ||
| 113 | BYTE srcd; /*;AN000;4*/ | ||
| 114 | BYTE destd; /*;AN000;4*/ | ||
| 115 | BYTE inpath [MAXPATH]; /*;AN000;*/ | ||
| 116 | BYTE infname [MAXFNAME]; /*;AN000;*/ | ||
| 117 | BYTE infext [MAXFEXT]; /*;AN000;*/ | ||
| 118 | BYTE infspec [MAXFSPEC]; /*;AN000;*/ | ||
| 119 | /*=============================*/ | ||
| 120 | /*---------------------------------------*/ | ||
| 121 | /*- */ | ||
| 122 | /*- Data structures for the PARSER */ | ||
| 123 | /*- */ | ||
| 124 | /*---------------------------------------*/ | ||
| 125 | |||
| 126 | struct subst_list sublist; /*;AN000;6 Message substitution list */ | ||
| 127 | char response_buff[5]; /*;AN000;6 User response buffer *//*;AN000;6*/ | ||
| 128 | |||
| 129 | BYTE append_indicator = 0xff; /*;AN000;2 Indicates the support for APPEND /X is active */ | ||
| 130 | WORD original_append_func; /*;AN000;2 APPEND functions on program entry*/ | ||
| 131 | struct timedate td; | ||
| 132 | |||
| 133 | /***************** START OF SPECIFICATION *********************************/ | ||
| 134 | /* | ||
| 135 | /* SUBROUTINE NAME : Main | ||
| 136 | /* | ||
| 137 | /* DESCRIPTIVE NAME : Main routine for RESTORE utility | ||
| 138 | /* | ||
| 139 | /* FUNCTION: Main routine does the following: | ||
| 140 | /* 1. Verifies the DOS version | ||
| 141 | /* 2. Validate the input command line | ||
| 142 | /* 3. Calls dorestore to do the file restore. | ||
| 143 | /* | ||
| 144 | /* NOTES: | ||
| 145 | /* | ||
| 146 | /* ENTRY POINT: Main | ||
| 147 | /* Linkage: main((argc,argv) | ||
| 148 | /* | ||
| 149 | /* INPUT: (PARAMETERS) | ||
| 150 | /* argc - number of arguments | ||
| 151 | /* argv - array of pointers to arguments | ||
| 152 | /* | ||
| 153 | /* EFFECTS: rtswitch is changed to reflect the switches passed. | ||
| 154 | /* | ||
| 155 | /********************** END OF SPECIFICATIONS *******************************/ | ||
| 156 | void main(argc,argv) /* wrw! */ | ||
| 157 | int argc; | ||
| 158 | char *argv[]; | ||
| 159 | { | ||
| 160 | WORD retcode; | ||
| 161 | union REGS inregs,outregs; /*AN000*/ | ||
| 162 | WORD i; /*loop counter */ | ||
| 163 | WORD j; /*arrary subcript */ | ||
| 164 | BYTE *c; | ||
| 165 | DWORD drive_map; | ||
| 166 | DWORD prev_address; | ||
| 167 | WORD prev_action; | ||
| 168 | |||
| 169 | /**********************************/ | ||
| 170 | /** PRELOAD MESSAGES **/ | ||
| 171 | /**********************************/ | ||
| 172 | sysloadmsg(&inregs,&outregs); /*;AN000;6 Preload messages */ | ||
| 173 | if (outregs.x.cflag & CARRY) /*;AN000;6 If there was an error */ | ||
| 174 | { /*;AN000;6*/ | ||
| 175 | sysdispmsg(&outregs,&outregs); /*;AN000;6 Display the error message */ | ||
| 176 | exit_routine(UNEXPECTED); /*;AN000;6 and terminate */ | ||
| 177 | } /*;AN000;6*/ | ||
| 178 | |||
| 179 | |||
| 180 | /*********************************************/ | ||
| 181 | /* Parse the drive and file name entered */ | ||
| 182 | /*********************************************/ | ||
| 183 | parse_command_line /*;AN000;4*/ | ||
| 184 | ( /*;AN000;4*/ | ||
| 185 | argc, /*;AN000;4*/ | ||
| 186 | argv /*;AN000;4*/ | ||
| 187 | ); /*;AN000;4*/ | ||
| 188 | |||
| 189 | /*********************************************/ | ||
| 190 | /* Make sure APPEND /X is not active */ | ||
| 191 | /*********************************************/ | ||
| 192 | check_appendX(); /*;AN000;2 */ | ||
| 193 | |||
| 194 | |||
| 195 | /*********************************************/ | ||
| 196 | /* Take control of Control Break Interrupt */ | ||
| 197 | /*********************************************/ | ||
| 198 | retcode = DOSSETSIGHANDLER | ||
| 199 | ( | ||
| 200 | (void far *)signal_handler_routine, /* Signal handler address */ | ||
| 201 | (DWORD far *)&prev_address, /* Address of previous handler */ | ||
| 202 | (unsigned far *)&prev_action, /* Address of previous action */ | ||
| 203 | (unsigned)INSTALL_SIGNAL, /* Indicate request type */ | ||
| 204 | (unsigned)CTRL_C /* Signal number */ | ||
| 205 | ); | ||
| 206 | |||
| 207 | retcode = DOSSETSIGHANDLER | ||
| 208 | ( | ||
| 209 | (void far *)signal_handler_routine, /* Signal handler address */ | ||
| 210 | (DWORD far *)&prev_address, /* Address of previous handler */ | ||
| 211 | (unsigned far *)&prev_action, /* Address of previous action */ | ||
| 212 | (unsigned)INSTALL_SIGNAL, /* Indicate request type */ | ||
| 213 | (unsigned)CTRL_BREAK /* Signal number */ | ||
| 214 | ); | ||
| 215 | |||
| 216 | /*********************************/ | ||
| 217 | /* Take control of Hard Errors */ | ||
| 218 | /*********************************/ | ||
| 219 | set_int24_vector(); /*;AN000; Set Critical error vector (int 24h) */ | ||
| 220 | |||
| 221 | |||
| 222 | /************************************************************/ | ||
| 223 | /* call dorestore (RTDO.C) to actually do the restoring */ | ||
| 224 | /************************************************************/ | ||
| 225 | dorestore(srcd,destd,inpath,infname,infext,infspec,&td); | ||
| 226 | |||
| 227 | /************************************************************/ | ||
| 228 | /* output a msg in the following situations: */ | ||
| 229 | /* if flag indicates no file found */ | ||
| 230 | /************************************************************/ | ||
| 231 | if (set_reset_test_flag(&control_flag,FOUND,TEST)==FALSE) | ||
| 232 | { | ||
| 233 | /*warning! No files were found to restore*/ | ||
| 234 | display_it(NO_FILE_TO_RESTORE,STND_ERR_DEV,0,NO_RESPTYPE,(BYTE)UTIL_MSG); /*;AN000;6*/ | ||
| 235 | exit_routine(NOFILES); | ||
| 236 | } | ||
| 237 | |||
| 238 | exit_routine(NORMAL); | ||
| 239 | |||
| 240 | } /* end of main*/ | ||
diff --git a/v4.0/src/CMD/RESTORE/RESTORE.LNK b/v4.0/src/CMD/RESTORE/RESTORE.LNK new file mode 100644 index 0000000..b5c50a3 --- /dev/null +++ b/v4.0/src/CMD/RESTORE/RESTORE.LNK | |||
| @@ -0,0 +1,17 @@ | |||
| 1 | /STACK:50000 + | ||
| 2 | restore + | ||
| 3 | restpars + | ||
| 4 | rtt1 + | ||
| 5 | rtt3 + | ||
| 6 | rtdo + | ||
| 7 | rtdo1 + | ||
| 8 | rtold + | ||
| 9 | rtold1 + | ||
| 10 | rtnew + | ||
| 11 | rtnew1 + | ||
| 12 | rtfile + | ||
| 13 | rtfile1 + | ||
| 14 | _parse + | ||
| 15 | _msgret | ||
| 16 | restore.exe,,..\..\mapper\mapper + ..\..\inc\comsubs; | ||
| 17 | \ No newline at end of file | ||
diff --git a/v4.0/src/CMD/RESTORE/RESTORE.SKL b/v4.0/src/CMD/RESTORE/RESTORE.SKL new file mode 100644 index 0000000..81bf2cc --- /dev/null +++ b/v4.0/src/CMD/RESTORE/RESTORE.SKL | |||
| @@ -0,0 +1,46 @@ | |||
| 1 | ;========================================================== | ||
| 2 | |||
| 3 | :util RESTORE ;AN000; | ||
| 4 | |||
| 5 | ;--------- | ||
| 6 | :class A | ||
| 7 | ;--------- ;AN000; | ||
| 8 | :use 1 COMMON1 ;AN000; ;For "Incorrect DOS version | ||
| 9 | :def 2 CR,LF,"Source and target drives are the same",CR,LF ;AN000; | ||
| 10 | :def 3 CR,LF,"Invalid number of parameters",CR,LF ;AN000; | ||
| 11 | |||
| 12 | :use 5 COMMON25 ;AN000; ;For "Invalid path | ||
| 13 | :def 6 CR,LF,"Invalid drive specification",CR,LF ;AN000; | ||
| 14 | :def 7 CR,LF,"Warning! No files were found to restore",CR,LF ;AN000; | ||
| 15 | :def 8 CR,LF,"Insert backup diskette %1 in drive %2:",CR,LF ;AN000; | ||
| 16 | :def 9 CR,LF,"Insert restore target in drive %1:",CR,LF ;AN000; | ||
| 17 | :use 10 COMMON28 ;AN000; ;For "Press any key to continue . . .",CR,LF | ||
| 18 | :def 11 CR,LF,"Warning! Diskette is out of sequence",CR,LF ;AN000; | ||
| 19 | "Replace diskette or continue if okay",CR,LF ;AN000; | ||
| 20 | |||
| 21 | :def 12 CR,LF,"The last file was not restored",CR,LF ;AN000; | ||
| 22 | :def 13 CR,LF,"*** Files were backed up %1 ***",CR,LF ;AN000; | ||
| 23 | :def 14 CR,LF,"Source does not contain backup files",CR,LF ;AN000; | ||
| 24 | :def 15 CR,LF,"Insufficient memory",CR,LF ;AN000; | ||
| 25 | :def 16 CR,LF,"Warning! File %1",CR,LF ;AN000; | ||
| 26 | "is a read-only file",CR,LF ;AN000; | ||
| 27 | "Replace the file (Y/N)?" ;AN000; | ||
| 28 | |||
| 29 | :def 17 CR,LF,"Restore file sequence error",CR,LF ;AN000; | ||
| 30 | :def 18 CR,LF,"File creation error",CR,LF ;AN000; | ||
| 31 | :def 19 CR,LF,"Insufficient disk space",CR,LF ;AN000; | ||
| 32 | :def 20 CR,LF,"*** Not able to restore file ***",CR,LF ;AN000; | ||
| 33 | :def 21 CR,LF,"*** Restoring files from drive %1: ***",CR,LF ;AN000; | ||
| 34 | :def 22 CR,LF,"Warning! File %1",CR,LF ;AN000; | ||
| 35 | "was changed after it was backed up",CR,LF ;AN000; | ||
| 36 | "Replace the file (Y/N)?",CR,LF ;AN000; | ||
| 37 | |||
| 38 | :def 23 "Diskette: %1",CR,LF ;AN000; | ||
| 39 | |||
| 40 | :use 27 COMMON23 ;AN000; ;For "Invalid date | ||
| 41 | :use 28 COMMON24 ;AN000; ;For "Invalid time | ||
| 42 | :use 29 COMMON26 ;AN000; ;For "No source drive specified | ||
| 43 | :use 30 COMMON27 ;AN000; ;For "No target drive specified | ||
| 44 | :def 31 CR,LF ;AN000; | ||
| 45 | :end ;AN000; | ||
| 46 | ;========================================================== | ||
diff --git a/v4.0/src/CMD/RESTORE/RESTPARS.C b/v4.0/src/CMD/RESTORE/RESTPARS.C new file mode 100644 index 0000000..6299f75 --- /dev/null +++ b/v4.0/src/CMD/RESTORE/RESTPARS.C | |||
| @@ -0,0 +1,1002 @@ | |||
| 1 | |||
| 2 | /*------------------------------- | ||
| 3 | /* SOURCE FILE NAME: restpars.c | ||
| 4 | /*------------------------------- | ||
| 5 | /* 0 */ | ||
| 6 | #include "rt.h" | ||
| 7 | #include "rt1.h" | ||
| 8 | #include "rt2.h" | ||
| 9 | #include "restpars.h" /*;AN000;4*/ | ||
| 10 | #include "direct.h" | ||
| 11 | #include "string.h" | ||
| 12 | #include "ctype.h" | ||
| 13 | #include "dos.h" /*;AN000;2*/ | ||
| 14 | #include "comsub.h" /* common subroutine def'n */ | ||
| 15 | #include "doscalls.h" | ||
| 16 | #include "error.h" | ||
| 17 | |||
| 18 | /*=============================*/ | ||
| 19 | extern BYTE srcd; /*;AN000;4*/ | ||
| 20 | extern BYTE destd; /*;AN000;4*/ | ||
| 21 | extern BYTE inpath [MAXPATH]; /*;AN000;*/ | ||
| 22 | extern BYTE infname [MAXFNAME]; /*;AN000;*/ | ||
| 23 | extern BYTE infext [MAXFEXT]; /*;AN000;*/ | ||
| 24 | extern BYTE infspec [MAXFSPEC]; /*;AN000;*/ | ||
| 25 | /*=============================*/ | ||
| 26 | |||
| 27 | extern BYTE destddir[MAXPATH+3]; | ||
| 28 | extern BYTE srcddir[MAXPATH+3]; | ||
| 29 | extern BYTE rtswitch; | ||
| 30 | extern BYTE control_flag; | ||
| 31 | extern BYTE control_flag2; | ||
| 32 | extern BYTE filename[12]; | ||
| 33 | extern unsigned control_file_handle; /* !wrw */ | ||
| 34 | extern struct subst_list sublist; /*;AN000;6Message substitution list */ | ||
| 35 | |||
| 36 | struct p_parms parms; /*;AN000;4 Parser data structure */ | ||
| 37 | struct p_parmsx parmsx; /*;AN000;4 Parser data structure */ | ||
| 38 | struct p_pos_blk pos1; /*;AN000;4 Parser data structure */ | ||
| 39 | struct p_pos_blk pos2; /*;AN000;4 Parser data structure */ | ||
| 40 | struct p_sw_blk sw1; /*;AN000;4 /S /P /M /N data structure */ | ||
| 41 | struct p_sw_blk sw2; /*;AN000;4 /E: /L: parser data structure */ | ||
| 42 | struct p_sw_blk sw3; /*;AN000;4 /B: /A: parser data structure */ | ||
| 43 | struct p_result_blk pos_buff; /*;AN000;4 Parser data structure */ | ||
| 44 | struct switchbuff sw_buff; /*;AN000;4 Parser data structure */ | ||
| 45 | struct timebuff time_buff; /*;AN000;4 Parser data structure */ | ||
| 46 | struct datebuff date_buff; /*;AN000;4 Parser data structure */ | ||
| 47 | DWORD noval; /*;AN000;4 Value list for PARSER */ | ||
| 48 | int parse_count = 1; /*;AN000;4*//*;AC002;*/ | ||
| 49 | char curr_parm[128]; /*;AN004; Current parameter being parsed*/ | ||
| 50 | extern struct timedate td; | ||
| 51 | |||
| 52 | /*************************************************/ | ||
| 53 | /* | ||
| 54 | /* SUBROUTINE NAME: parse_command_line | ||
| 55 | /* | ||
| 56 | /* FUNCTION: | ||
| 57 | /* | ||
| 58 | /* Parse the RESTORE command line | ||
| 59 | /* | ||
| 60 | /**************************************************/ | ||
| 61 | void parse_command_line(argc,argv) /*;AN000;4 */ | ||
| 62 | int argc; /*;AN000;4 */ | ||
| 63 | char *argv[]; /*;AN000;4 */ | ||
| 64 | { /*;AN000;4 */ | ||
| 65 | #define EOL -1 /*;AN000;4 */ | ||
| 66 | union REGS inregs, outregs; /*;AN000;4 */ | ||
| 67 | char cmd_line[128]; /*;AN000;4 */ | ||
| 68 | char not_finished = TTRUE; /*;AN000;4 */ | ||
| 69 | int x; /*;AN000;4 */ | ||
| 70 | |||
| 71 | |||
| 72 | /* Copy command line parameters to local area */ | ||
| 73 | cmd_line[0] = NUL; /*;AN000;4*/ | ||
| 74 | for (x=1; x<=argc; x++) /*;AN000;4*/ | ||
| 75 | { /*;AN000;4*/ | ||
| 76 | strcat(cmd_line,argv[x]); /*;AN000;4*/ | ||
| 77 | if (x!=argc) strcat(cmd_line," "); /*;AN000;4*/ | ||
| 78 | } /*;AN000;4*/ | ||
| 79 | |||
| 80 | strcat(cmd_line,"\r"); /* Add CR, LF */ /*;AN004;*/ | ||
| 81 | |||
| 82 | if (argc-1 < 1) /*;AN000;4*/ | ||
| 83 | { /*;AC000;4*/ | ||
| 84 | display_it(NO_SOURCE,STND_ERR_DEV,0,NO_RESPTYPE,(BYTE)UTIL_MSG);/*;AN000;6*/ | ||
| 85 | usererror(INVALIDPARM); /*;AC000;4*/ | ||
| 86 | } /*;AC000;4*/ | ||
| 87 | |||
| 88 | if (argc-1 < 2) /*;AN000;4*/ | ||
| 89 | { /*;AC000;4*/ | ||
| 90 | display_it(NO_TARGET,STND_ERR_DEV,0,NO_RESPTYPE,(BYTE)UTIL_MSG);/*;AN000;6*/ | ||
| 91 | usererror(INVALIDPARM); /*;AC000;4*/ | ||
| 92 | } /*;AC000;4*/ | ||
| 93 | |||
| 94 | /* Check for same source and target drive */ | ||
| 95 | if (com_toupper(*argv[1]) == com_toupper(*argv[2]) /*;AN000;4*/ | ||
| 96 | && (BYTE)*(argv[1]+1) == ':' /*;AN000;4*/ | ||
| 97 | && (BYTE)*(argv[1]+2) == NUL /*;AN000;4*/ | ||
| 98 | && (BYTE)*(argv[2]+1) == ':' /*;AN000;4*/ | ||
| 99 | ) /*;AN000;4*/ | ||
| 100 | { /*;AC000;4*/ | ||
| 101 | display_it(SOURCE_TARGET_SAME,STND_ERR_DEV,0,NO_RESPTYPE,(BYTE)UTIL_MSG);/*;AN000;6*/ | ||
| 102 | usererror(INVALIDPARM); /*;AC000;4*/ | ||
| 103 | } /*;AC000;4*/ | ||
| 104 | |||
| 105 | /* Initialize parser data structures */ | ||
| 106 | parse_init(); /*;AN000;4*/ | ||
| 107 | |||
| 108 | inregs.x.si = (WORD)&cmd_line[0]; /*DS:SI*/ /*;AN000;4 make DS:SI point to source */ | ||
| 109 | inregs.x.cx = 0; /*;AN000;4*/ | ||
| 110 | |||
| 111 | /*********************/ | ||
| 112 | /* PARSE LOOP !!!!!! */ | ||
| 113 | /*********************/ | ||
| 114 | while (not_finished) /*;AN000;4 For all strings in command line */ | ||
| 115 | { /*;AN000;4 */ | ||
| 116 | inregs.x.dx = 0; /*;AN000;4 RESERVED */ | ||
| 117 | inregs.x.di = (WORD)&parms; /*ES:DI*/ /*;AN000;4 address of parm list */ | ||
| 118 | parse(&inregs,&outregs); /*;AN000;4 Call DOS PARSE service routines*/ | ||
| 119 | |||
| 120 | x=0; /* Save the parsed parameter */ /*;AN004;*/ | ||
| 121 | for (inregs.x.si; inregs.x.si<outregs.x.si; inregs.x.si++) /*;AN004;*/ | ||
| 122 | { /*;AN004;*/ | ||
| 123 | curr_parm[x] = *(char *)inregs.x.si; /*;AN004;*/ | ||
| 124 | x++; /*;AN004;*/ | ||
| 125 | } /*;AN004;*/ | ||
| 126 | |||
| 127 | curr_parm[x] = NUL; /*;AN004;*/ | ||
| 128 | |||
| 129 | inregs = outregs; /* Reset registers */ /*;AN000;4 Reset registers*/ | ||
| 130 | |||
| 131 | /* Check for PARSE ERROR*/ | ||
| 132 | if (outregs.x.ax != (WORD)NOERROR) /*;AN000;4*/ | ||
| 133 | { /*;AN000;4*/ | ||
| 134 | if (outregs.x.ax==(WORD)EOL) /* Was it End of line? */ /*;AN000;4*/ | ||
| 135 | not_finished = FFALSE; /*;AN000;4*/ | ||
| 136 | else | ||
| 137 | { /* It was an error */ /*;AN000;4*/ | ||
| 138 | not_finished = FFALSE; /*;AN000;4*/ | ||
| 139 | parse_error(outregs.x.ax,(BYTE)PARSEERR); /*;AN000;4*//*;AC002;*/ | ||
| 140 | } /*;AN000;4*/ | ||
| 141 | } /*;AN000;4*/ | ||
| 142 | |||
| 143 | if (not_finished) /* Parse was successful !*/ /*;AN000;4*/ | ||
| 144 | { /*;AN000;4*/ | ||
| 145 | if ( outregs.x.dx == (WORD)&time_buff || /*;AN000;4*/ | ||
| 146 | outregs.x.dx == (WORD)&date_buff || /*;AN000;4*/ | ||
| 147 | outregs.x.dx == (WORD)&sw_buff /*;AN000;4*/ | ||
| 148 | ) /*;AN000;4*/ | ||
| 149 | process_switch(outregs.x.dx,argv[parse_count]); /*;AN000;4*//*;AC002;*/ | ||
| 150 | } /*;AN000;4*/ | ||
| 151 | |||
| 152 | parse_count++; /*;AN000;4*//*;AC002;*/ | ||
| 153 | } /* End WHILE Parse loop */ /*;AN000;4*/ | ||
| 154 | |||
| 155 | /* Check source and target filespec */ | ||
| 156 | if (strlen(argv[2]) >= 5) /*;AN000;p2591*/ | ||
| 157 | check_for_device_names(argv); /*;AN000;p2591*/ | ||
| 158 | |||
| 159 | check_source_drive(argc,argv); /*;AN000;4*/ | ||
| 160 | check_target_filespec(argc,argv); /*;AN000;4*/ | ||
| 161 | |||
| 162 | return; /*;AN000;4*/ | ||
| 163 | } /* end parser */ /*;AN000;4*/ | ||
| 164 | |||
| 165 | /*************************************************/ | ||
| 166 | /* | ||
| 167 | /* SUBROUTINE NAME: parse_error | ||
| 168 | /* | ||
| 169 | /* FUNCTION: | ||
| 170 | /* | ||
| 171 | /* There was a parse error. Display message and die | ||
| 172 | /* | ||
| 173 | /**************************************************/ | ||
| 174 | void parse_error(msg_num,class) /*;AN000;4*//*;AC002;*/ | ||
| 175 | WORD msg_num; /*;AN000;4*/ | ||
| 176 | BYTE class; /*;AN000;4*/ | ||
| 177 | { /*;AN000;4*/ | ||
| 178 | sublist.value1 = &curr_parm[0]; /*;AN002;*/ | ||
| 179 | sublist.flags1 = LEFT_ALIGN + CHAR_FIELD_ASCIIZ; /*;AN002;*/ | ||
| 180 | sublist.one = 0; /*;AN002;*/ | ||
| 181 | sublist.max_width1 = (BYTE)strlen(curr_parm); /*;AN002;*/ | ||
| 182 | sublist.min_width1 = sublist.max_width1; /*;AN002;*/ | ||
| 183 | |||
| 184 | |||
| 185 | if (msg_num == NO_SOURCE || msg_num == NO_TARGET) /*;AN000;6*/ | ||
| 186 | display_it(msg_num,STND_ERR_DEV,0,NO_RESPTYPE,class); /*;AN000;6*/ | ||
| 187 | else /*;AN000;6*/ | ||
| 188 | display_it(msg_num,STND_ERR_DEV,1,NO_RESPTYPE,class); /*;AN000;6*/ | ||
| 189 | |||
| 190 | |||
| 191 | usererror(INVALIDPARM); /*;AN000;4*//*;AC002;*/ | ||
| 192 | return; /*;AN000;4*/ | ||
| 193 | } /*;AN000;4*/ | ||
| 194 | |||
| 195 | /*************************************************/ | ||
| 196 | /* | ||
| 197 | /* SUBROUTINE NAME: check_date | ||
| 198 | /* | ||
| 199 | /* FUNCTION: | ||
| 200 | /* | ||
| 201 | /* A date parameter was entered. Validate it | ||
| 202 | /* | ||
| 203 | /**************************************************/ | ||
| 204 | void check_date(year,month,day) /*;AN000;4*//*;AC002;*/ | ||
| 205 | WORD year; /*;AN000;4*/ | ||
| 206 | BYTE month; /*;AN000;4*/ | ||
| 207 | BYTE day; /*;AN000;4*/ | ||
| 208 | { /*;AN000;4*/ | ||
| 209 | if (year > 2099 || year < 1980) /*;AC000;4*/ | ||
| 210 | parse_error(INV_DATE,(BYTE)UTILMSG); /*;AC000;4*//*;AC002;*/ | ||
| 211 | |||
| 212 | if (month > 12 || month < 1) /*;AC000;4*/ | ||
| 213 | parse_error(INV_DATE,(BYTE)UTILMSG); /*;AC000;4*//*;AC002;*/ | ||
| 214 | |||
| 215 | if (day > 31 || month < 1) /*;AC000;4*/ | ||
| 216 | parse_error(INV_DATE,(BYTE)UTILMSG); /*;AC000;4*//*;AC002;*/ | ||
| 217 | |||
| 218 | /* Verify day not greater then 30 if Apr,Jun,Sep,Nov */ | ||
| 219 | if ((day>30) && (month==4 || month==6 || month==9 || month==11)) /*;AC000;4*/ | ||
| 220 | parse_error(INV_DATE,(BYTE)UTILMSG); /*;AC000;4*//*;AC002;*/ | ||
| 221 | |||
| 222 | if (month == 2) /* Deal with February */ /*;AC000;4*/ | ||
| 223 | { /*;AC000;4*/ | ||
| 224 | if (day > 29) /* if Feb 30 or above */ /*;AC000;4*/ | ||
| 225 | parse_error(INV_DATE,(BYTE)UTILMSG); /*;AC000;4*//*;AC002;*/ | ||
| 226 | |||
| 227 | if ((year % 4) != 0) /* If not a leap year */ /*;AC000;4*/ | ||
| 228 | if (day > 28) /* if Feb 29 or above */ /*;AC000;4*/ | ||
| 229 | parse_error(INV_DATE,(BYTE)UTILMSG); /*;AC000;4*//*;AC002;*/ | ||
| 230 | } /*;AC000;4*/ | ||
| 231 | |||
| 232 | return; /*;AN000;4*/ | ||
| 233 | } /*;AN000;4*/ | ||
| 234 | /*************************************************/ | ||
| 235 | /* | ||
| 236 | /* SUBROUTINE NAME: check_time | ||
| 237 | /* | ||
| 238 | /* FUNCTION: | ||
| 239 | /* | ||
| 240 | /* A time parameter was entered. Validate it | ||
| 241 | /* | ||
| 242 | /**************************************************/ | ||
| 243 | void check_time(hours,minutes,seconds,hundreds) /*;AN000;4*//*;AC002;*/ | ||
| 244 | BYTE hours; /*;AN000;4*/ | ||
| 245 | BYTE minutes; /*;AN000;4*/ | ||
| 246 | BYTE seconds; /*;AN000;4*/ | ||
| 247 | BYTE hundreds; /*;AN000;4*/ | ||
| 248 | { /*;AN000;4*/ | ||
| 249 | |||
| 250 | if (hours > 23 || hours < 0) /*;AC000;4*/ | ||
| 251 | parse_error(INV_TIME,(BYTE)UTILMSG); /*;AC000;4*//*;AC002;*/ | ||
| 252 | |||
| 253 | if (minutes >= 60 || minutes < 0) /*;AC000;4*/ | ||
| 254 | parse_error(INV_TIME,(BYTE)UTILMSG); /*;AC000;4*//*;AC002;*/ | ||
| 255 | |||
| 256 | if (seconds >= 60 || seconds < 0) /*;AC000;4*/ | ||
| 257 | parse_error(INV_TIME,(BYTE)UTILMSG); /*;AC000;4*//*;AC002;*/ | ||
| 258 | |||
| 259 | return; /*;AN000;4*/ | ||
| 260 | } /*;AN000;4*/ | ||
| 261 | |||
| 262 | /*************************************************/ | ||
| 263 | /* | ||
| 264 | /* SUBROUTINE NAME: parse_init | ||
| 265 | /* | ||
| 266 | /* FUNCTION: | ||
| 267 | /* | ||
| 268 | /* Initialize the parser data structures | ||
| 269 | /* | ||
| 270 | /**************************************************/ | ||
| 271 | #define SSTRING 0x2000 /*;AN000;4*/ | ||
| 272 | #define FILESPEC 0x0200 /*;AN000;4 */ | ||
| 273 | #define CAP_FILETABLE 0x0001 /*;AN000;4 */ | ||
| 274 | #define DRIVELETTER 0x100; /*;AN000;4 */ | ||
| 275 | #define DATESTRING 0x1000 /*;AN000;4 */ | ||
| 276 | #define TIMESTRING 0x0800 /*;AN000;4 */ | ||
| 277 | |||
| 278 | void parse_init() /*;AN000;4 */ | ||
| 279 | |||
| 280 | { /* Initialize PARMS data structure */ /*;AN000;4 */ | ||
| 281 | parms.parmsx_ptr = (WORD)&parmsx; /*;AN000;4 */ | ||
| 282 | parms.p_num_extra = 1; /*;AN000;4 */ | ||
| 283 | parms.p_len_extra_delim = 1; /*;AN000;4 */ | ||
| 284 | parms.p_extra_delim[0] = ';'; /*;AN000;4 */ | ||
| 285 | parms.p_extra_delim[1] = NUL; /*;AN000;4 */ | ||
| 286 | |||
| 287 | /* Initialize PARMSX data structure */ | ||
| 288 | parmsx.p_minpos= 2; /*;AN000;4 */ | ||
| 289 | parmsx.p_maxpos= 2; /*;AN000;4 */ | ||
| 290 | parmsx.pos1_ptr= (WORD)&pos1; /*;AN000;4 */ | ||
| 291 | parmsx.pos2_ptr= (WORD)&pos2; /*;AN000;4 */ | ||
| 292 | parmsx.num_sw = 3; /*;AN000;4 */ | ||
| 293 | parmsx.sw1_ptr = (WORD)&sw1; /*;AN000;4 */ | ||
| 294 | parmsx.sw2_ptr = (WORD)&sw2; /*;AN000;4 */ | ||
| 295 | parmsx.sw3_ptr = (WORD)&sw3; /*;AN000;4 */ | ||
| 296 | parmsx.num_keywords = 0; /*;AN000;4 */ | ||
| 297 | |||
| 298 | /* Initialize POS1 (Source Drive) data structure */ | ||
| 299 | pos1.match_flag = FILESPEC; /*;AN000;4 */ | ||
| 300 | pos1.function_flag = 0; /*;AN000;4 */ | ||
| 301 | pos1.result_buf = (WORD)&pos_buff; /*;AN000;4 */ | ||
| 302 | pos1.value_list = (WORD)&noval; /*;AN000;4 */ | ||
| 303 | pos1.nid = 0; /*;AN000;4 */ | ||
| 304 | |||
| 305 | /* Initialize POS2 (Target FILESPEC) data structure */ | ||
| 306 | pos2.match_flag = SSTRING; /*;AN000;4 */ | ||
| 307 | pos2.function_flag = 0; /*;AN000;4 */ | ||
| 308 | pos2.result_buf = (WORD)&pos_buff; /*;AN000;4 */ | ||
| 309 | pos2.value_list = (WORD)&noval; /*;AN000;4 */ | ||
| 310 | pos2.nid = 0; /*;AN000;4 */ | ||
| 311 | |||
| 312 | /* Initialize SW1 data structure */ | ||
| 313 | sw1.p_match_flag = DATESTRING; /*;AN000;4 */ | ||
| 314 | sw1.p_function_flag = 0; /*;AN000;4 */ | ||
| 315 | sw1.p_result_buf = (WORD)&date_buff; /*;AN000;4 */ | ||
| 316 | sw1.p_value_list = (WORD)&noval; /*;AN000;4 */ | ||
| 317 | sw1.p_nid = 2; /*;AN000;4 */ | ||
| 318 | strcpy(sw1.switch1,"/B"); /*;AN000;4 */ | ||
| 319 | strcpy(sw1.switch2,"/A"); /*;AN000;4 */ | ||
| 320 | |||
| 321 | /* Initialize SW2 data structure */ | ||
| 322 | sw2.p_match_flag = TIMESTRING; /*;AN000;4 */ | ||
| 323 | sw2.p_function_flag = 0; /*;AN000;4 */ | ||
| 324 | sw2.p_result_buf = (WORD)&time_buff; /*;AN000;4 */ | ||
| 325 | sw2.p_value_list = (WORD)&noval; /*;AN000;4 */ | ||
| 326 | sw2.p_nid = 2; /*;AN000;4 */ | ||
| 327 | strcpy(sw2.switch1,"/E"); /*;AN000;4 */ | ||
| 328 | strcpy(sw2.switch2,"/L"); /*;AN000;4 */ | ||
| 329 | |||
| 330 | |||
| 331 | /* Initialize SW3 data structure */ | ||
| 332 | sw3.p_match_flag = 0; /*;AN000;4 */ | ||
| 333 | sw3.p_function_flag = 0; /*;AN000;4 */ | ||
| 334 | sw3.p_result_buf = (WORD)&sw_buff; /*;AN000;4 */ | ||
| 335 | sw3.p_value_list = (WORD)&noval; /*;AN000;4 */ | ||
| 336 | sw3.p_nid = 4; /*;AN000;4 */ | ||
| 337 | strcpy(sw3.switch1,"/S"); /*;AN000;4 */ | ||
| 338 | strcpy(sw3.switch2,"/P"); /*;AN000;4 */ | ||
| 339 | strcpy(sw3.switch3,"/M"); /*;AN000;4 */ | ||
| 340 | strcpy(sw3.switch4,"/N"); /*;AN000;4 */ | ||
| 341 | |||
| 342 | /*********************************************/ | ||
| 343 | /* Also initialize all time and date values */ | ||
| 344 | /*********************************************/ | ||
| 345 | td.earlier_hour = 0; | ||
| 346 | td.earlier_minute = 0; | ||
| 347 | td.earlier_second = 0; | ||
| 348 | td.later_hour = 0; | ||
| 349 | td.later_minute = 0; | ||
| 350 | td.later_second = 0; | ||
| 351 | td.before_year = 0; | ||
| 352 | td.before_month = 0; | ||
| 353 | td.before_day = 0; | ||
| 354 | td.after_year = 0; | ||
| 355 | td.after_month = 0; | ||
| 356 | td.after_day = 0; | ||
| 357 | |||
| 358 | /**************************************************/ | ||
| 359 | /* Also initialize the message substitution list */ | ||
| 360 | /**************************************************/ | ||
| 361 | sublist.sl_size1= SUBLIST_SIZE; /*;AN000;6*/ | ||
| 362 | sublist.sl_size2= SUBLIST_SIZE; /*;AN000;6*/ | ||
| 363 | sublist.one = 1; /*;AN000;6*/ | ||
| 364 | sublist.two = 2; /*;AN000;6*/ | ||
| 365 | sublist.zero1 = 0; /*;AN000;6*/ | ||
| 366 | sublist.zero2 = 0; /*;AN000;6*/ | ||
| 367 | sublist.pad_char1 = ' '; /*;AN000;6*/ | ||
| 368 | sublist.pad_char2 = ' '; /*;AN000;6*/ | ||
| 369 | |||
| 370 | return; /*;AN000;4 */ | ||
| 371 | } /*;AN000;4 */ | ||
| 372 | |||
| 373 | |||
| 374 | /*************************************************/ | ||
| 375 | /* | ||
| 376 | /* SUBROUTINE NAME: check_for_device_names | ||
| 377 | /* | ||
| 378 | /* FUNCTION: | ||
| 379 | /* | ||
| 380 | /* Make sure user not trying to restore a reserved device name | ||
| 381 | /* | ||
| 382 | /**************************************************/ | ||
| 383 | void check_for_device_names(argv) /*;AN000;p2591*/ | ||
| 384 | char *argv[]; /*;AN000;p2591*/ | ||
| 385 | { /*;AN000;p2591*/ | ||
| 386 | union REGS qregs; /*;AN000;p2591*/ | ||
| 387 | char target[128]; /*;AN000;p2591*/ | ||
| 388 | char *t; /*;AN000;p2591*/ | ||
| 389 | |||
| 390 | #define CAPITALIZE_STRING 0x6521 /*;AN000;p2591*/ | ||
| 391 | |||
| 392 | qregs.x.ax = CAPITALIZE_STRING; /*;AN000;p2591*/ | ||
| 393 | qregs.x.dx = (WORD)argv[2]; /*;AN000;p2591*/ | ||
| 394 | strcpy(target,argv[2]); /*;AN000;p2591*/ | ||
| 395 | qregs.x.cx = strlen(target); /*;AN000;p2591*/ | ||
| 396 | intdos(&qregs,&qregs); /*;AN000;p2591*/ | ||
| 397 | strcpy(target,argv[2]); /*;AN000;p2591*/ | ||
| 398 | |||
| 399 | for (t=&target[0]; *t!=NUL; t++) | ||
| 400 | if /*;AN000;p2591*/ | ||
| 401 | ( strcmp(t,"LPT1")==0 || /*;AN000;p2591*/ | ||
| 402 | strcmp(t,"LPT2")==0 || /*;AN000;p2591*/ | ||
| 403 | strcmp(t,"PRN")==0 || /*;AN000;p2591*/ | ||
| 404 | strcmp(t,"CON")==0 || /*;AN000;p2591*/ | ||
| 405 | strcmp(t,"NUL")==0 || /*;AN000;p2591*/ | ||
| 406 | strcmp(t,"AUX")==0 || /*;AN000;p2591*/ | ||
| 407 | strcmp(t,"LPT1:")==0 || /*;AN000;p2591*/ | ||
| 408 | strcmp(t,"LPT2:")==0 || /*;AN000;p2591*/ | ||
| 409 | strcmp(t,"PRN:")==0 || /*;AN000;p2591*/ | ||
| 410 | strcmp(t,"CON:")==0 || /*;AN000;p2591*/ | ||
| 411 | strcmp(t,"NUL:")==0 || /*;AN000;p2591*/ | ||
| 412 | strcmp(t,"AUX:")==0 /*;AN000;p2591*/ | ||
| 413 | ) /*;AN000;p2591*/ | ||
| 414 | { /*;AN000;p2591*/ | ||
| 415 | sublist.value1 = (char far *)t; /*;AN000;p2591*/ | ||
| 416 | sublist.flags1 = LEFT_ALIGN + CHAR_FIELD_ASCIIZ; /*;AN000;p2591*/ | ||
| 417 | sublist.one = 0; /*;AN000;p2591*/ | ||
| 418 | sublist.max_width1 = (BYTE)strlen(t); /*;AN000;p2591*/ | ||
| 419 | sublist.min_width1 = sublist.max_width1; /*;AN000;p2591*/ | ||
| 420 | |||
| 421 | display_it(INVPARM,STND_ERR_DEV,1,NO_RESPTYPE,(BYTE)PARSEERROR);/*;AN000;p2591*/ | ||
| 422 | usererror(INVALIDPARM); /*;AN000;p2591*/ | ||
| 423 | } /*;AN000;p2591*/ | ||
| 424 | |||
| 425 | |||
| 426 | return; /*;AN000;p2591*/ | ||
| 427 | } /*;AN000;p2591*/ | ||
| 428 | |||
| 429 | /*************************************************/ | ||
| 430 | /* | ||
| 431 | /* SUBROUTINE NAME: check_source_drive | ||
| 432 | /* | ||
| 433 | /* FUNCTION: | ||
| 434 | /* | ||
| 435 | /* Verify drive letter and start building srcddir | ||
| 436 | /* | ||
| 437 | /**************************************************/ | ||
| 438 | void check_source_drive(argc,argv) /*;AN000;4*/ | ||
| 439 | int argc; /*;AN000;4*/ | ||
| 440 | char *argv[]; /*;AN000;4*/ | ||
| 441 | { /*;AN000;4*/ | ||
| 442 | WORD retcode; /*;AC000;*/ | ||
| 443 | WORD device_handle; | ||
| 444 | WORD action; | ||
| 445 | BYTE parm; | ||
| 446 | BYTE media_type; | ||
| 447 | WORD dnumwant = 1; | ||
| 448 | BYTE temp_array1[4]; | ||
| 449 | BYTE temp_array2[4]; | ||
| 450 | union REGS qregs; /*;AN000;8*/ | ||
| 451 | |||
| 452 | *argv[1]=(BYTE)com_toupper(*argv[1]); /*;AN000;4*/ | ||
| 453 | |||
| 454 | if ( /*;AN000;4*/ | ||
| 455 | *argv[1] < 'A' || /*;AN000;4*/ | ||
| 456 | *argv[1] > 'Z' || /*;AN000;4*/ | ||
| 457 | *(argv[1]+1)!=':' || /*;AN000;4*/ | ||
| 458 | *(argv[1]+2)!=NUL /*;AN000;4*/ | ||
| 459 | ) /*;AN000;4*/ | ||
| 460 | { /*;AN000;4*/ | ||
| 461 | display_it(INVALID_DRIVE,STND_ERR_DEV,0,NO_RESPTYPE,(BYTE)UTIL_MSG);/*;AN000;6*/ | ||
| 462 | usererror(INVALIDDRIVE); /*;AN000;4*/ | ||
| 463 | } /*;AN000;4*/ | ||
| 464 | |||
| 465 | srcd = (BYTE)*argv[1]; /*;AN000;4*/ | ||
| 466 | srcddir[0] = srcd; /*;AN000;4*/ | ||
| 467 | srcddir[1] = ':'; /*;AN000;4*/ | ||
| 468 | srcddir[2] = NUL; /*;AN000;4*/ | ||
| 469 | |||
| 470 | /***********************************************************************/ | ||
| 471 | /* dosopen to find out whether the src drive exist */ | ||
| 472 | /* and dosdevioctl to find out whether it is a removable drive */ | ||
| 473 | /***********************************************************************/ | ||
| 474 | retcode = /*;AC000;4*/ | ||
| 475 | DOSOPEN /*;AC000;4*/ | ||
| 476 | ( (char far *)&srcddir[0], /*;AC000;4*/ | ||
| 477 | (unsigned far *)&device_handle, /*;AC000;4*/ | ||
| 478 | (unsigned far *)&action, /*;AC000;4*/ | ||
| 479 | (DWORD)0, /*file size*/ /*;AC000;4*/ | ||
| 480 | 0, /*file attribute*/ /*;AC000;4*/ | ||
| 481 | 0x01, /*if file exist, open it*/ /*;AC000;4*/ | ||
| 482 | /*if file not exist, fail it*//*;AC000;4*/ | ||
| 483 | 0x80c2, /*deny write, read only*/ /*;AC000;4*/ | ||
| 484 | (DWORD)0 /*reserved*/ /*;AC000;4*/ | ||
| 485 | ); /*;AC000;4*/ | ||
| 486 | |||
| 487 | if (retcode != NOERROR) /*;AC000;4*/ | ||
| 488 | { /*;AC000;4*/ | ||
| 489 | display_it(INVALID_DRIVE,STND_ERR_DEV,0,NO_RESPTYPE,(BYTE)UTIL_MSG);/*;AN000;6*/ | ||
| 490 | usererror(INVALIDDRIVE); /*;AC000;4*/ | ||
| 491 | } /*;AC000;4*/ | ||
| 492 | |||
| 493 | /************************************/ /*;AC000;4*/ | ||
| 494 | /* See if source drive is removable */ /*;AC000;4*/ | ||
| 495 | /************************************/ /*;AC000;4*/ | ||
| 496 | retcode = /*;AC000;4*/ | ||
| 497 | DOSDEVIOCTL /*;AC000;4*/ | ||
| 498 | ( (char far *)&media_type, /*;AC000;4*/ | ||
| 499 | (char far *)&parm, /*;AC000;4*/ | ||
| 500 | 0x20, /*;AC000;4*/ | ||
| 501 | 0x08, /*;AC000;4*/ | ||
| 502 | device_handle /*;AC000;4*/ | ||
| 503 | ); /*;AC000;4*/ | ||
| 504 | |||
| 505 | if (retcode != NOERROR) /*;AC000;4*/ | ||
| 506 | { display_it(INVALID_DRIVE,STND_ERR_DEV,0,NO_RESPTYPE,(BYTE)UTIL_MSG);/*;AN000;6*/ | ||
| 507 | usererror(INVALIDDRIVE); /*;AC000;4*/ | ||
| 508 | } /*;AC000;4*/ | ||
| 509 | |||
| 510 | #define REMOVABLE 0 /*;AC000;4*/ | ||
| 511 | if (media_type != REMOVABLE) /*;AC000;4*/ | ||
| 512 | set_reset_test_flag(&control_flag2,SRC_HDISK,SET); /*;AC000;4*/ | ||
| 513 | |||
| 514 | else /* Source disk is removable */ /*;AC000;4*/ | ||
| 515 | { /*;AC000;4*/ | ||
| 516 | temp_array1[0] = (BYTE)((dnumwant / 10) + '0'); /*;AC000;4*/ | ||
| 517 | temp_array1[1] = (BYTE)((dnumwant % 10) + '0'); /*;AC000;4*/ | ||
| 518 | temp_array1[2] = NUL; /*;AC000;4*/ | ||
| 519 | temp_array2[0] = srcd; /*;AC000;4*/ | ||
| 520 | temp_array2[1] = NUL; /*;AC000;4*/ | ||
| 521 | |||
| 522 | sublist.value1 = (char far *)temp_array1; /*;AN000;6*/ | ||
| 523 | sublist.flags1 = LEFT_ALIGN + CHAR_FIELD_ASCIIZ; /*;AN000;6*/ | ||
| 524 | sublist.max_width1 = (BYTE)strlen(temp_array1); /*;AN000;6*/ | ||
| 525 | sublist.min_width1 = sublist.max_width1; /*;AN000;6*/ | ||
| 526 | |||
| 527 | sublist.value2 = (char far *)temp_array2; /*;AN000;6*/ | ||
| 528 | sublist.flags2 = LEFT_ALIGN + CHAR_FIELD_ASCIIZ; /*;AN000;6*/ | ||
| 529 | sublist.max_width2 = (BYTE)strlen(temp_array2); /*;AN000;6*/ | ||
| 530 | sublist.min_width2 = sublist.max_width2; /*;AN000;6*/ | ||
| 531 | |||
| 532 | display_it(INSERT_SOURCE_DISK,STND_ERR_DEV,2,NO_RESPTYPE,(BYTE)UTIL_MSG); /*;AN000;6*/ | ||
| 533 | display_it(PRESS_ANY_KEY,STND_ERR_DEV,0,ANY_KEY_RESPTYPE,(BYTE)UTIL_MSG); /*;AN000;6*/ | ||
| 534 | |||
| 535 | /* If single drive system, eliminates double prompting */ | ||
| 536 | /* for user to "Insert diskette for drive %1" */ | ||
| 537 | qregs.x.ax = SETLOGICALDRIVE; /*;AN000;8*/ | ||
| 538 | qregs.h.bl = srcddir[0] - 'A' + 1; /*;AN000;8*/ | ||
| 539 | intdos(&qregs,&qregs); /*;AN000;8*/ | ||
| 540 | |||
| 541 | } /*;AC000;4*/ | ||
| 542 | return; /*;AN000;4*/ | ||
| 543 | } /*;AN000;4*/ | ||
| 544 | |||
| 545 | /*************************************************/ | ||
| 546 | /* | ||
| 547 | /* SUBROUTINE NAME: check_target_filespec | ||
| 548 | /* | ||
| 549 | /* FUNCTION: | ||
| 550 | /* | ||
| 551 | /* Verify the target filespec. | ||
| 552 | /* 1. Validate destination drive, or use default if none specified | ||
| 553 | /* 2. Validate path, or use current dir if not specified | ||
| 554 | /* 3. Validate the file name | ||
| 555 | /* | ||
| 556 | /**************************************************/ | ||
| 557 | void check_target_filespec(argc,argv) /*;AN000;4*/ | ||
| 558 | int argc; /*;AN000;4*/ | ||
| 559 | char *argv[]; /*;AN000;4*/ | ||
| 560 | { /*;AN000;4*/ | ||
| 561 | WORD retcode; /*;AC000;*/ | ||
| 562 | WORD device_handle; | ||
| 563 | WORD action; | ||
| 564 | BYTE parm; | ||
| 565 | BYTE media_type; | ||
| 566 | DWORD drive_map; | ||
| 567 | BYTE temp_destddir[MAXPATH+2]; | ||
| 568 | BYTE temp_array1[4]; | ||
| 569 | BYTE temp_array2[4]; | ||
| 570 | WORD default_drive_num; | ||
| 571 | WORD destd_num; | ||
| 572 | WORD dirlen = MAXPATH; | ||
| 573 | BYTE tdestddir[MAXPATH+3]; | ||
| 574 | BYTE ttdestddir[MAXPATH+3]; | ||
| 575 | BYTE srcf[MAXPATHF]; | ||
| 576 | BYTE argv2_has_switch; | ||
| 577 | BYTE search_string[MAXPATHF+2]; | ||
| 578 | BYTE tempp[MAXPATH]; | ||
| 579 | WORD j,k,z; | ||
| 580 | BYTE *c; | ||
| 581 | BYTE backdir; | ||
| 582 | WORD dnumwant = 1; | ||
| 583 | union REGS qregs; /*;AN000;8*/ | ||
| 584 | |||
| 585 | |||
| 586 | /**************************/ | ||
| 587 | /* Uppercase the string */ | ||
| 588 | /**************************/ | ||
| 589 | #define CAPITALIZE_STRING 0x6521 /*;AN000;p????*/ | ||
| 590 | |||
| 591 | qregs.x.ax = CAPITALIZE_STRING; /*;AN000;p????*/ | ||
| 592 | qregs.x.dx = (WORD)argv[2]; /*;AN000;p????*/ | ||
| 593 | strcpy(tempp,argv[2]); /*;AN000;p????*/ | ||
| 594 | qregs.x.cx = strlen(tempp); /*;AN000;p????*/ | ||
| 595 | intdos(&qregs,&qregs); /*;AN000;p????*/ | ||
| 596 | |||
| 597 | |||
| 598 | /***************************************************/ | ||
| 599 | /* If no drive letter specified, use current drive */ | ||
| 600 | /***************************************************/ | ||
| 601 | if ( /*;AC000;4*/ | ||
| 602 | *(argv[2]+1)!=':' || /*;AC000;4*/ | ||
| 603 | *argv[2] < 'A' || /*;AC000;4*/ | ||
| 604 | *argv[2] > 'Z' /*;AC000;4*/ | ||
| 605 | ) /*;AC000;4*/ | ||
| 606 | { /*;AC000;4*/ | ||
| 607 | DOSQCURDISK /*;AC000;4*/ | ||
| 608 | ( (unsigned far *)&default_drive_num, /*;AC000;4*/ | ||
| 609 | (DWORD far *) &drive_map /*;AC000;4*/ | ||
| 610 | ); /*;AC000;4*/ | ||
| 611 | destd = (BYTE)(default_drive_num + 'A' - 1); /*;AC000;4*/ | ||
| 612 | } /*;AC000;4*/ | ||
| 613 | else /*;AC000;4*/ | ||
| 614 | { /* User specified the destination drive*/ /*;AC000;4*/ | ||
| 615 | destd = (BYTE)*argv[2]; /*;AC000;4*/ | ||
| 616 | argv[2] = argv[2] + 2; /*;AC000;4*/ | ||
| 617 | } /*;AC000;4*/ | ||
| 618 | |||
| 619 | destddir[0] = destd; /*;AC000;4*/ | ||
| 620 | destddir[1] = ':'; /*;AC000;4*/ | ||
| 621 | destddir[2] = NUL; /*;AC000;4*/ | ||
| 622 | |||
| 623 | /***********************************************************************/ | ||
| 624 | /* if source drive and destination drive are the same, output error msg*/ | ||
| 625 | /***********************************************************************/ | ||
| 626 | if (srcd == destd) /*;AC000;4*/ | ||
| 627 | { /*;AC000;4*/ | ||
| 628 | display_it(SOURCE_TARGET_SAME,STND_ERR_DEV,0,NO_RESPTYPE,(BYTE)UTIL_MSG);/*;AN000;6*/ | ||
| 629 | usererror(INVALIDPARM); /*;AC000;4*/ | ||
| 630 | } /*;AC000;4*/ | ||
| 631 | |||
| 632 | /***********************************************************************/ | ||
| 633 | /* dosopen to find out whether the destination drive is exist */ | ||
| 634 | /* and dosdevioctl to find out whether it is a removable drive */ | ||
| 635 | /***********************************************************************/ | ||
| 636 | |||
| 637 | retcode = /*;AC000;4*/ | ||
| 638 | DOSOPEN /*;AC000;4*/ | ||
| 639 | ( (char far *)&destddir[0], /*;AC000;4*/ | ||
| 640 | (unsigned far *)&device_handle, /*;AC000;4*/ | ||
| 641 | (unsigned far *)&action, /*;AC000;4*/ | ||
| 642 | (DWORD)0, /*file size*/ /*;AC000;4*/ | ||
| 643 | 0, /*file attribute*/ /*;AC000;4*/ | ||
| 644 | 0x01, /*if file exist, open it*/ /*;AC000;4*/ | ||
| 645 | /*if file not exist, fail it*/ /*;AC000;4*/ | ||
| 646 | 0x80c2, /*deny write, read only*/ /*;AC000;4*/ | ||
| 647 | (DWORD)0 /*reserved*/ /*;AC000;4*/ | ||
| 648 | ); /*;AC000;4*/ | ||
| 649 | |||
| 650 | if (retcode != NOERROR)/*if open fail*/ /*;AC000;4*/ | ||
| 651 | { /*;AC000;4*/ | ||
| 652 | display_it(INVALID_DRIVE,STND_ERR_DEV,0,NO_RESPTYPE,(BYTE)UTIL_MSG);/*;AN000;6*/ | ||
| 653 | usererror(INVALIDDRIVE); /*;AC000;4*/ | ||
| 654 | } /*;AC000;4*/ | ||
| 655 | |||
| 656 | /************************************/ /*;AC000;4*/ | ||
| 657 | /* See if target drive is removable */ /*;AC000;4*/ | ||
| 658 | /************************************/ /*;AC000;4*/ | ||
| 659 | retcode = /*;AC000;4*/ | ||
| 660 | DOSDEVIOCTL /*;AC000;4*/ | ||
| 661 | ( (char far *)&media_type, /*;AC000;4*/ | ||
| 662 | (char far *)&parm, /*;AC000;4*/ | ||
| 663 | 0x20, /*;AC000;4*/ | ||
| 664 | 0x08, /*;AC000;4*/ | ||
| 665 | device_handle /*;AC000;4*/ | ||
| 666 | ); /*;AC000;4*/ | ||
| 667 | |||
| 668 | if (retcode != NOERROR) /*;AC000;4*/ | ||
| 669 | { display_it(INVALID_DRIVE,STND_ERR_DEV,0,NO_RESPTYPE,(BYTE)UTIL_MSG);/*;AN000;6*/ | ||
| 670 | usererror(INVALIDDRIVE); /*;AC000;4*/ | ||
| 671 | } /*;AC000;4*/ | ||
| 672 | |||
| 673 | if (media_type == REMOVABLE) /*;AC000;4*/ | ||
| 674 | { temp_array1[0] = destd; /*;AC000;4*/ | ||
| 675 | temp_array1[1] = NUL; /*;AC000;4*/ | ||
| 676 | sublist.value1 = (char far *)temp_array1; /*;AN000;6*/ | ||
| 677 | sublist.flags1 = LEFT_ALIGN + CHAR_FIELD_ASCIIZ; /*;AN000;6*/ | ||
| 678 | sublist.max_width1 = (BYTE)strlen(temp_array1); /*;AN000;6*/ | ||
| 679 | sublist.min_width1 = sublist.max_width1; /*;AN000;6*/ | ||
| 680 | |||
| 681 | display_it(INSERT_TARGET_DISK,STND_ERR_DEV,1,NO_RESPTYPE,(BYTE)UTIL_MSG); /*;AN000;6*/ | ||
| 682 | display_it(PRESS_ANY_KEY,STND_ERR_DEV,0,ANY_KEY_RESPTYPE,(BYTE)UTIL_MSG); /*;AN000;6*/ | ||
| 683 | } /*;AC000;4*/ | ||
| 684 | |||
| 685 | /* If single drive system, eliminates double prompting */ | ||
| 686 | /* for user to "Insert diskette for drive %1" */ | ||
| 687 | qregs.x.ax = SETLOGICALDRIVE; /*;AN000;8*/ | ||
| 688 | qregs.h.bl = destddir[0] - 'A' + 1; /*;AN000;8*/ | ||
| 689 | intdos(&qregs,&qregs); /*;AN000;8*/ | ||
| 690 | |||
| 691 | /**********************************************************************/ | ||
| 692 | /* save current directory of destination disk to be reset back later */ | ||
| 693 | /**********************************************************************/ | ||
| 694 | |||
| 695 | destd_num = (WORD) (destd - 'A' +1); /*;AC000;4*/ | ||
| 696 | |||
| 697 | /* get current directory of destd_num (DosQCurDir) */ | ||
| 698 | if ((retcode = /*;AC000;4*/ | ||
| 699 | DOSQCURDIR /*;AC000;4*/ | ||
| 700 | ( destd_num, /*;AC000;4*/ | ||
| 701 | (char far *) tdestddir, /*;AC000;4*/ | ||
| 702 | (unsigned far *) &dirlen) /*;AC000;4*/ | ||
| 703 | ) != 0) /*;AC000;4*/ | ||
| 704 | { /*;AC000;4*/ | ||
| 705 | display_it(INVALID_DRIVE,STND_ERR_DEV,0,NO_RESPTYPE,(BYTE)UTIL_MSG);/*;AN000;6*/ | ||
| 706 | usererror(INVALIDDRIVE); /*;AC000;4*/ | ||
| 707 | } /*;AC000;4*/ | ||
| 708 | |||
| 709 | #define BACKSLASH 0x5c | ||
| 710 | |||
| 711 | if (strlen(tdestddir) != 1) /*;AC000;4*/ | ||
| 712 | { strcpy(temp_destddir,"\\"); /*;AC000;4*/ | ||
| 713 | strcat(temp_destddir,tdestddir); /*;AC000;4*/ | ||
| 714 | strcpy(tdestddir,temp_destddir); /*;AC000;4*/ | ||
| 715 | } /*;AC000;4*/ | ||
| 716 | |||
| 717 | |||
| 718 | /**********************************************************************/ | ||
| 719 | /* The next parameter has to be a file name with or without path, */ | ||
| 720 | /* or a switch. In the case of there is no path, the current path */ | ||
| 721 | /* is used. In the case of there is no file name, the global file */ | ||
| 722 | /* name *.* is used */ | ||
| 723 | /**********************************************************************/ | ||
| 724 | /* argv[2] is a drive spec*/ /*;AC000;4*/ | ||
| 725 | if (*(argv[2]+1)==':' && *argv[2] >= 'A' && *argv[2] <= 'Z' && argc!=2) /*;AC000;4*/ | ||
| 726 | { /*;AN000;6*/ | ||
| 727 | display_it(INVPARM,STND_ERR_DEV,0,NO_RESPTYPE,(BYTE)PARSEERROR);/*;AN000;6*/ | ||
| 728 | usererror(INVALIDPARM); /*;AC000;4*/ | ||
| 729 | } /*;AC000;4*/ | ||
| 730 | else /*;AC000;4*/ | ||
| 731 | { /*if argv[2] is not a drive spec */ /*;AC000;4*/ | ||
| 732 | /*if argv[2] started with '/' (is a switch) or there is no argv[i]*/ /*;AC000;4*/ | ||
| 733 | if (*argv[2] == '/' || *argv[2] == NUL || argc ==2) /*;AC000;4*/ | ||
| 734 | { strcpy(srcf,tdestddir); /*;AC000;4*/ | ||
| 735 | strcat(srcf,"\\*.*"); /*;AC000;4*/ | ||
| 736 | } /*;AC000;4*/ | ||
| 737 | else /*;AC000;4*/ | ||
| 738 | { /*argv[2] does not started with / */ /*;AC000;4*/ | ||
| 739 | /* find out whether part of argv[2] is switch specification */ /*;AC000;4*/ | ||
| 740 | for (k = 0; argv[2][k] != '/' && argv[2][k] != NUL; ++k);/*;AC000;4*/ | ||
| 741 | if (argv[2][k] == '/') /*;AC000;4*/ | ||
| 742 | { /*;AC000;4*/ | ||
| 743 | argv[2][k] = NUL; /*;AC000;4*/ | ||
| 744 | argv2_has_switch = TRUE; /*;AC000;4*/ | ||
| 745 | } /*;AC000;4*/ | ||
| 746 | |||
| 747 | /*if argv[2] is \\, invalid parm */ /*;AC000;4*/ | ||
| 748 | if (argv[2][0] == '\\' && argv[2][1] == '\\' || argv[2][0] == ':') /*;AC000;;4*/ | ||
| 749 | { /*;AN000;6*/ | ||
| 750 | display_it(INVPARM,STND_ERR_DEV,0,NO_RESPTYPE,(BYTE)PARSEERROR);/*;AN000;6*/ | ||
| 751 | usererror(INVALIDPARM); /*;AC000;4*/ | ||
| 752 | } /*;AC000;4*/ | ||
| 753 | |||
| 754 | /*if argv[2] starts with '\' (it is a complete path)*/ /*;AC000;4*/ | ||
| 755 | if (*argv[2] == '\\') /*;AC000;4*/ | ||
| 756 | strcpy(srcf,argv[2]); /*;AC000;4*/ | ||
| 757 | else /*;AC000;4*/ | ||
| 758 | /* it is not a complete path, have to put current path in */ /*;AC000;;4*/ | ||
| 759 | /* front of the string to build a complete path */ /*;AC000;4*/ | ||
| 760 | { strcpy(srcf,tdestddir); /*;AC000;4*/ | ||
| 761 | if (strlen(tdestddir) != 1) /*;AC000;4*/ | ||
| 762 | strcat(srcf,"\\"); /*;AC000;4*/ | ||
| 763 | strcat(srcf,argv[2]); /*;AC000;4*/ | ||
| 764 | } /*endif*/ /*;AC000;4*/ | ||
| 765 | } /*end of argv[2] does not start with '/' */ /*;AC000;4*/ | ||
| 766 | |||
| 767 | j = strlen(srcf); /*;AC000;4*/ | ||
| 768 | z = 0; /*;AC000;4*/ | ||
| 769 | do /*;AC000;4*/ | ||
| 770 | { for (;srcf[z] != '.' && srcf[z] != NUL; ++z); /*;AC000;4*/ | ||
| 771 | if (srcf[z] == '.' && srcf[z+1] == '.' && /*;AC000;4*/ | ||
| 772 | (srcf[z+2] == '\\' || srcf[z+2] == NUL)) /*;AC000;4*/ | ||
| 773 | { backdir = TRUE; /*;AC000;4*/ | ||
| 774 | break; /*;AC000;4*/ | ||
| 775 | } /*;AC000;4*/ | ||
| 776 | z = z+1; /*;AC000;4*/ | ||
| 777 | } /*;AC000;4*/ | ||
| 778 | while (z < j); /*;AC000;4*/ | ||
| 779 | |||
| 780 | /*validate the path*/ /*;AC000;4*/ | ||
| 781 | for (z = j; srcf[z] != '\\'; --z); /*;AC000;4*/ | ||
| 782 | strcpy(tempp,srcf); /*;AC000;4*/ | ||
| 783 | tempp[z] = NUL; /*;AC000;4*/ | ||
| 784 | |||
| 785 | for (z = 0; tempp[z] != '*' && tempp[z] != NUL; ++z); /*;AC000;4*/ | ||
| 786 | if (tempp[z] == '*' ) /*;AC000;4*/ | ||
| 787 | { display_it(PATH_NOT_FOUND,STND_ERR_DEV,1,NO_RESPTYPE,(BYTE)UTIL_MSG); /*;AN000;6*/ | ||
| 788 | usererror(INVALIDPARM); /*;AC000;4*/ | ||
| 789 | } /*;AC000;4*/ | ||
| 790 | |||
| 791 | if (backdir == TRUE) /*;AC000;4*/ | ||
| 792 | { search_string[0] = destd; /*;AC000;4*/ | ||
| 793 | search_string[1] = ':'; /*;AC000;4*/ | ||
| 794 | search_string[2] = NUL; /*;AC000;4*/ | ||
| 795 | if (srcf[0] == NUL) /*;AC000;4*/ | ||
| 796 | strcat(search_string,"\\"); /*;AC000;4*/ | ||
| 797 | else /*;AC000;4*/ | ||
| 798 | strcat(search_string, tempp); /*;AC000;4*/ | ||
| 799 | |||
| 800 | if(chdir(search_string)!=0) /*;AC000;4*/ | ||
| 801 | { sublist.value1 = (char far *)argv[2]; /*;AN000;6*/ | ||
| 802 | sublist.flags1 = LEFT_ALIGN + CHAR_FIELD_ASCIIZ; /*;AN000;6*/ | ||
| 803 | sublist.max_width1 = (BYTE)strlen(argv[2]); /*;AN000;6*/ | ||
| 804 | sublist.min_width1 = sublist.max_width1; /*;AN000;6*/ | ||
| 805 | display_it(PATH_NOT_FOUND,STND_ERR_DEV,1,NO_RESPTYPE,(BYTE)UTIL_MSG); /*;AN000;6*/ | ||
| 806 | usererror(INVALIDPARM); /*;AC000;4*/ | ||
| 807 | } /*;AC000;4*/ | ||
| 808 | |||
| 809 | dirlen = MAXPATH; /*;AC000;4*/ | ||
| 810 | if ((retcode = DOSQCURDIR(destd_num, /*;AC000;4*/ | ||
| 811 | (char far *) ttdestddir, /*;AC000;4*/ | ||
| 812 | (unsigned far *) &dirlen)) != NOERROR) /*;AC000;4*/ | ||
| 813 | { /*;AC000;4*/ | ||
| 814 | com_msg(retcode); /*;AC000;4*/ | ||
| 815 | usererror(retcode); /*;AC000;4*/ | ||
| 816 | } /*;AC000;4*/ | ||
| 817 | /* endif */ /*;AC000;4*/ | ||
| 818 | |||
| 819 | temp_destddir[0] = destd; /*;AC000;4*/ | ||
| 820 | temp_destddir[1] = ':'; /*;AC000;4*/ | ||
| 821 | temp_destddir[2] = NUL; /*;AC000;4*/ | ||
| 822 | strcat(temp_destddir,tdestddir); /*;AC000;4*/ | ||
| 823 | chdir(temp_destddir); /*;AC000;4*/ | ||
| 824 | |||
| 825 | if (strlen(ttdestddir) != 1) /*;AC000;4*/ | ||
| 826 | { strcpy(temp_destddir,"\\"); /*;AC000;4*/ | ||
| 827 | strcat(temp_destddir,ttdestddir); /*;AC000;4*/ | ||
| 828 | strcpy(ttdestddir,temp_destddir); /*;AC000;4*/ | ||
| 829 | } /*;AC000;4*/ | ||
| 830 | |||
| 831 | strcat(ttdestddir,"\\"); /*;AC000;4*/ | ||
| 832 | strcat(ttdestddir,srcf+z+1); /*;AC000;4*/ | ||
| 833 | strcpy(srcf,ttdestddir); /*;AC000;4*/ | ||
| 834 | } /*end of if backdir is true */ /*;AC000;4*/ | ||
| 835 | |||
| 836 | /* The documentation says if path is specified, file name has to */ | ||
| 837 | /* be specified also. This logic actually allows user to specify*/ | ||
| 838 | /* path without specify filename, as long as the path end with */ | ||
| 839 | /* '\'.*/ | ||
| 840 | /*If *srcf ends with '\', add "*.*" to the end*/ /*;AC000;4*/ | ||
| 841 | j = strlen(srcf); /*;AC000;4*/ | ||
| 842 | if (srcf[j-1] == '\\') /*;AC000;4*/ | ||
| 843 | strcat(srcf,"*.*"); /*;AC000;4*/ | ||
| 844 | if (argv2_has_switch == TRUE) /*;AC000;4*/ | ||
| 845 | { *(argv[2]+k) = '/'; /*;AC000;4*/ | ||
| 846 | argv[2] = argv[2] + k; /*;AC000;4*/ | ||
| 847 | } /* end of if argv[2] started with '/' */ /*;AC000;4*/ | ||
| 848 | } /* end of checking for argv[2] */ /*;AC000;4*/ | ||
| 849 | |||
| 850 | /**********************************************************************/ | ||
| 851 | /* add '\' at the beginning of the current destination directory */ | ||
| 852 | /**********************************************************************/ | ||
| 853 | temp_destddir[0] = destd; /*;AC000;4*/ | ||
| 854 | temp_destddir[1] = ':'; /*;AC000;4*/ | ||
| 855 | temp_destddir[2] = NUL; /*;AC000;4*/ | ||
| 856 | strcat(temp_destddir,tdestddir); /*;AC000;4*/ | ||
| 857 | strcpy(destddir,temp_destddir); /*;AC000;4*/ | ||
| 858 | |||
| 859 | /************************************************************************/ | ||
| 860 | /* separate the filename for search into prefix(inpath), */ | ||
| 861 | /* filename(infname), and file extension (infext) */ | ||
| 862 | /* Also take care of the situation that user enter '.' only */ | ||
| 863 | /* for file spec. */ | ||
| 864 | /************************************************************************/ | ||
| 865 | separate(srcf,inpath,infname,infext,infspec); /*;AC000;4*/ | ||
| 866 | if (strlen(infname) > MAXFNAME-1 || /*;AC000;4*/ | ||
| 867 | strlen(infext) > MAXFEXT-1 || /*;AC000;4*/ | ||
| 868 | strlen(inpath) > MAXPATH-1 || /*;AC000;4*/ | ||
| 869 | strcmp(infspec,"LPT1")==0 || /*;AC000;4*/ | ||
| 870 | strcmp(infspec,"LPT2")==0 || /*;AC000;4*/ | ||
| 871 | strcmp(infspec,"PRN")==0 || /*;AC000;4*/ | ||
| 872 | strcmp(infspec,"CON")==0 || /*;AC000;4*/ | ||
| 873 | strcmp(infspec,"NUL")==0 || /*;AC000;4*/ | ||
| 874 | strcmp(infspec,"AUX")==0 || /*;AC000;4*/ | ||
| 875 | strcmp(infspec,"LPT1:")==0 || /*;AC000;4*/ | ||
| 876 | strcmp(infspec,"LPT2:")==0 || /*;AC000;4*/ | ||
| 877 | strcmp(infspec,"PRN:")==0 || /*;AC000;4*/ | ||
| 878 | strcmp(infspec,"CON:")==0 || /*;AC000;4*/ | ||
| 879 | strcmp(infspec,"NUL:")==0 || /*;AC000;4*/ | ||
| 880 | strcmp(infspec,"AUX:")==0 ) /*;AC000;4*/ | ||
| 881 | { /*;AC000;4*/ | ||
| 882 | sublist.value1 = (char far *)&infspec[0]; /*;AN000;6*/ | ||
| 883 | sublist.flags1 = LEFT_ALIGN + CHAR_FIELD_ASCIIZ; /*;AN000;6*/ | ||
| 884 | sublist.one = 0; /* Yes, this is right */ /*;AN000;6*/ | ||
| 885 | sublist.max_width1 = (BYTE)strlen(infspec); /*;AN000;6*/ | ||
| 886 | sublist.min_width1 = sublist.max_width1; /*;AN000;6*/ | ||
| 887 | |||
| 888 | display_it(INVPARM,STND_ERR_DEV,1,NO_RESPTYPE,(BYTE)PARSEERROR);/*;AN000;6*/ | ||
| 889 | usererror(INVALIDPARM); /* invalid parm */ /*;AC000;4*/ | ||
| 890 | } /*;AC000;4*/ | ||
| 891 | |||
| 892 | /************************************************************************/ | ||
| 893 | /* set wildcard flag according to whether there is '*' or/and '?' in */ | ||
| 894 | /* file specification */ | ||
| 895 | /************************************************************************/ | ||
| 896 | c = infspec; /*;AC000;4*/ | ||
| 897 | while (*c) /*;AC000;4*/ | ||
| 898 | { /*;AC000;4*/ | ||
| 899 | if (*c == '*' || *c == '?') /*;AC000;4*/ | ||
| 900 | { set_reset_test_flag(&control_flag,WILDCARD,SET); /*;AC000;4*/ | ||
| 901 | break; /*;AC000;4*/ | ||
| 902 | } /*;AC000;4*/ | ||
| 903 | else /*;AC000;4*/ | ||
| 904 | c = c+1; /*;AC000;4*/ | ||
| 905 | } /*;AC000;4*/ | ||
| 906 | |||
| 907 | |||
| 908 | return; /*;AN000;4*/ | ||
| 909 | } /*;AN000;4*/ | ||
| 910 | |||
| 911 | /*************************************************/ | ||
| 912 | /* | ||
| 913 | /* SUBROUTINE NAME: process_switch | ||
| 914 | /* | ||
| 915 | /* FUNCTION: | ||
| 916 | /* | ||
| 917 | /* Identify the switch (/S,/P,/M,/N,/B:,/A:,/E:,/L:) | ||
| 918 | /* entered and handle it | ||
| 919 | /* | ||
| 920 | /**************************************************/ | ||
| 921 | void process_switch(buff_addr,ptr) /*;AN000;4*//*;AC002;*/ | ||
| 922 | unsigned buff_addr; /*;AN000;4*/ | ||
| 923 | char *ptr; /*;AN002;*/ | ||
| 924 | { /*;AN000;4*/ | ||
| 925 | |||
| 926 | if (buff_addr == (unsigned)&sw_buff) /*;AN000;4*/ | ||
| 927 | { /*;AN000;4*/ | ||
| 928 | if (sw_buff.sw_synonym_ptr == (WORD)&sw3.switch1[0]) /*;AN000;4 /S */ | ||
| 929 | {set_reset_test_flag(&rtswitch, SUB, SET); /*;AN000;4*/ | ||
| 930 | } | ||
| 931 | |||
| 932 | if (sw_buff.sw_synonym_ptr == (WORD)&sw3.switch2[0]) /*;AN000;4 /P */ | ||
| 933 | { /*;AN000;4*/ | ||
| 934 | set_reset_test_flag(&rtswitch, PROMPT, SET); /*;AN000;4*/ | ||
| 935 | set_reset_test_flag(&control_flag, SWITCHES, SET); /*;AN000;4*/ | ||
| 936 | } /*;AN000;4*/ | ||
| 937 | |||
| 938 | if (sw_buff.sw_synonym_ptr == (WORD)&sw3.switch3[0]) /*;AN000;4 /M */ | ||
| 939 | { /*;AN000;4*/ | ||
| 940 | set_reset_test_flag(&rtswitch, Revised, SET); /*;AN000;4*/ | ||
| 941 | set_reset_test_flag(&control_flag, SWITCHES, SET); /*;AN000;4*/ | ||
| 942 | } /*;AN000;4*/ | ||
| 943 | |||
| 944 | if (sw_buff.sw_synonym_ptr == (WORD)&sw3.switch4[0]) /*;AN000;4 /N */ | ||
| 945 | { /*;AN000;4*/ | ||
| 946 | set_reset_test_flag(&rtswitch, NOTEXIST, SET); /*;AN000;4*/ | ||
| 947 | set_reset_test_flag(&control_flag, SWITCHES, SET); /*;AN000;4*/ | ||
| 948 | } /*;AN000;4*/ | ||
| 949 | } /*;AN000;4*/ | ||
| 950 | |||
| 951 | |||
| 952 | if (buff_addr == (unsigned)&time_buff) /*;AN000;4*/ | ||
| 953 | { /*;AN000;4*/ | ||
| 954 | check_time(time_buff.hours,time_buff.minutes,time_buff.seconds,time_buff.hundreds); /*;AN000;4*//*;AC002;*/ | ||
| 955 | |||
| 956 | if (time_buff.tb_synonym_ptr == (WORD)&sw2.switch1[0]) /*;AN000;4 /E */ | ||
| 957 | { /*;AN000;4*/ | ||
| 958 | td.earlier_hour = time_buff.hours; /*;AN000;4*/ | ||
| 959 | td.earlier_minute = time_buff.minutes; /*;AN000;4*/ | ||
| 960 | td.earlier_second = time_buff.seconds; /*;AN000;4*/ | ||
| 961 | set_reset_test_flag(&rtswitch, EARLIER, SET); /*;AN000;4*/ | ||
| 962 | set_reset_test_flag(&control_flag, SWITCHES, SET); /*;AN000;4*/ | ||
| 963 | } /*;AN000;4*/ | ||
| 964 | |||
| 965 | if (time_buff.tb_synonym_ptr == (WORD)&sw2.switch2[0]) /*;AN000;4 /L */ | ||
| 966 | { /*;AN000;4*/ | ||
| 967 | td.later_hour = time_buff.hours; /*;AN000;4*/ | ||
| 968 | td.later_minute = time_buff.minutes; /*;AN000;4*/ | ||
| 969 | td.later_second = time_buff.seconds; /*;AN000;4*/ | ||
| 970 | set_reset_test_flag(&rtswitch, LATER, SET); /*;AN000;4*/ | ||
| 971 | set_reset_test_flag(&control_flag, SWITCHES, SET); /*;AN000;4*/ | ||
| 972 | } /*;AN000;4*/ | ||
| 973 | |||
| 974 | } /*;AN000;4*/ | ||
| 975 | |||
| 976 | |||
| 977 | if (buff_addr == (unsigned)&date_buff) /*;AN000;4*/ | ||
| 978 | { /*;AN000;4*/ | ||
| 979 | check_date(date_buff.year,date_buff.month,date_buff.day); /*;AN000;4*//*;AC002;*/ | ||
| 980 | |||
| 981 | if (date_buff.db_synonym_ptr == (WORD)&sw1.switch1[0]) /*;AN000;4 /B */ | ||
| 982 | { /*;AN000;4*/ | ||
| 983 | td.before_year = date_buff.year; /*;AN000;4*/ | ||
| 984 | td.before_month = date_buff.month; /*;AN000;4*/ | ||
| 985 | td.before_day = date_buff.day; /*;AN000;4*/ | ||
| 986 | set_reset_test_flag(&rtswitch, BEFORE, SET); /*;AN000;4*/ | ||
| 987 | set_reset_test_flag(&control_flag, SWITCHES, SET); /*;AN000;4*/ | ||
| 988 | } /*;AN000;4*/ | ||
| 989 | |||
| 990 | if (date_buff.db_synonym_ptr == (WORD)&sw1.switch2[0]) /*;AN000;4 /A */ | ||
| 991 | { /*;AN000;4*/ | ||
| 992 | td.after_year = date_buff.year; /*;AN000;4*/ | ||
| 993 | td.after_month = date_buff.month; /*;AN000;4*/ | ||
| 994 | td.after_day = date_buff.day; /*;AN000;4*/ | ||
| 995 | set_reset_test_flag(&rtswitch, AFTER, SET); /*;AN000;4*/ | ||
| 996 | set_reset_test_flag(&control_flag, SWITCHES, SET); /*;AN000;4*/ | ||
| 997 | } /*;AN000;4*/ | ||
| 998 | |||
| 999 | } /*;AN000;4*/ | ||
| 1000 | |||
| 1001 | return; /*;AN000;4*/ | ||
| 1002 | } /*;AN000;4*/ | ||
diff --git a/v4.0/src/CMD/RESTORE/RESTPARS.H b/v4.0/src/CMD/RESTORE/RESTPARS.H new file mode 100644 index 0000000..8b9bf95 --- /dev/null +++ b/v4.0/src/CMD/RESTORE/RESTPARS.H | |||
| @@ -0,0 +1,119 @@ | |||
| 1 | /* 0 */ | ||
| 2 | /*-----------------------------------------------------------------------*/ | ||
| 3 | /*- -*/ | ||
| 4 | /*- FILE: PARSE.H -*/ | ||
| 5 | /*- -*/ | ||
| 6 | /*- PURPOSE: Include file for RESTORE.C and other RESTORE source -*/ | ||
| 7 | /*- files. Defines structures and DEFINES for the DOS PARSE-*/ | ||
| 8 | /*- service routines -*/ | ||
| 9 | /*- -*/ | ||
| 10 | /*-----------------------------------------------------------------------*/ | ||
| 11 | |||
| 12 | |||
| 13 | /**********************************************************/ | ||
| 14 | /* STRUCTURE TO DEFINE ADDITIONAL COMMAND LINE DELIMITERS */ | ||
| 15 | /**********************************************************/ | ||
| 16 | struct p_parms /*;AN000;4*/ | ||
| 17 | { /*;AN000;4*/ | ||
| 18 | WORD parmsx_ptr; /* POINTER TO PARMS STRUCTURE *//*;AN000;4*/ | ||
| 19 | BYTE p_num_extra; /* 1 SAYS THAT A DELIMITER LIST FOLLOWS */ /*;AN000;4*/ | ||
| 20 | BYTE p_len_extra_delim; /* NUMBER OF ADDITIONAL DELIMITERS */ /*;AN000;4*/ | ||
| 21 | BYTE p_extra_delim[2]; /* ADDITIONAL DELIMITERS */ /*;AN000;4*/ | ||
| 22 | }; /*;AN000;4*/ | ||
| 23 | |||
| 24 | /***************************************************/ | ||
| 25 | /* STRUCTURE TO DEFINE RESTORE SYNTAX REQUIREMENTS */ | ||
| 26 | /***************************************************/ | ||
| 27 | struct p_parmsx /*;AN000;4*/ | ||
| 28 | { /*;AN000;4*/ | ||
| 29 | BYTE p_minpos; /* THERE ARE 2 REQUIRED POSITIONAL PARMS*/ /*;AN000;4*/ | ||
| 30 | BYTE p_maxpos; /* THERE ARE 2 REQUIRED POSITIONAL PARMS*/ /*;AN000;4*/ | ||
| 31 | WORD pos1_ptr; /* POINTER TO SOURCE FILESPEC DEF AREA*/ /*;AN000;4*/ | ||
| 32 | WORD pos2_ptr; /* POINTER TO TARGET DRIVE DEF AREA*/ /*;AN000;4*/ | ||
| 33 | BYTE num_sw; /* THERE ARE 8 SWITCHES (/S, /P, /M, /N, /E:, /L:, /B:, /A:) */ /*;AN000;4*/ | ||
| 34 | WORD sw1_ptr; /* POINTER TO SWITCH DEFINITION AREA*/ /*;AN000;4*/ | ||
| 35 | WORD sw2_ptr; /* POINTER TO SWITCH DEFINITION AREA*/ /*;AN000;4*/ | ||
| 36 | WORD sw3_ptr; /* POINTER TO SWITCH DEFINITION AREA*/ /*;AN000;4*/ | ||
| 37 | WORD num_keywords; /* NUMBER OF KEYWORDS IN RESTORE SYNTAX*/ /*;AN000;4*/ | ||
| 38 | }; /*;AN000;4*/ | ||
| 39 | |||
| 40 | /****************************************/ | ||
| 41 | /* STRUCTURE TO DEFINE POSITIONAL PARMS */ | ||
| 42 | /****************************************/ | ||
| 43 | struct p_pos_blk /*;AN000;4*/ | ||
| 44 | { /*;AN000;4*/ | ||
| 45 | WORD match_flag; /* Controls type matched */ /*;AN000;4*/ | ||
| 46 | WORD function_flag; /* Function to be included */ /*;AN000;4*/ | ||
| 47 | WORD result_buf; /* Result buffer address */ /*;AN000;4*/ | ||
| 48 | WORD value_list; /* Value list address */ /*;AN000;4*/ | ||
| 49 | BYTE nid; /* # of keyword/SW synonyms (0) *//*;AN000;4*/ | ||
| 50 | }; /*;AN000;4*/ | ||
| 51 | |||
| 52 | /********************************/ | ||
| 53 | /* STRUCTURE TO DEFINE SWITCHES */ | ||
| 54 | /********************************/ | ||
| 55 | struct p_sw_blk /*;AN000;4*/ | ||
| 56 | { /*;AN000;4*/ | ||
| 57 | WORD p_match_flag; /* Controls type matched */ /*;AN000;4*/ | ||
| 58 | WORD p_function_flag; /* Function should be taken */ /*;AN000;4*/ | ||
| 59 | WORD p_result_buf; /* Result buffer address */ /*;AN000;4*/ | ||
| 60 | WORD p_value_list; /* Value list address */ /*;AN000;4*/ | ||
| 61 | BYTE p_nid; /* # of switches */ /*;AN000;4*/ | ||
| 62 | BYTE switch1[3]; /* Save area for switches */ /*;AN000;4*/ | ||
| 63 | BYTE switch2[3]; /* Save area for switches */ /*;AN000;4*/ | ||
| 64 | BYTE switch3[3]; /* Save area for switches */ /*;AN000;4*/ | ||
| 65 | BYTE switch4[3]; /* Save area for switches */ /*;AN000;4*/ | ||
| 66 | }; /*;AN000;4*/ | ||
| 67 | /**/ | ||
| 68 | /*---------------------------------------------------------------------------*/ | ||
| 69 | |||
| 70 | /**************************/ | ||
| 71 | /* RETURN BUFFER FOR TIME */ | ||
| 72 | /**************************/ | ||
| 73 | struct timebuff /*;AN000;4*/ | ||
| 74 | { /*;AN000;4*/ | ||
| 75 | BYTE tb_type; /* TYPE RETURNED*/ /*;AN000;4*/ | ||
| 76 | BYTE tb_item_tag; /* SPACE FOR ITEM TAG*/ /*;AN000;4*/ | ||
| 77 | WORD tb_synonym_ptr; /*;AN000;4*/ | ||
| 78 | BYTE hours; /*;AN000;4*/ | ||
| 79 | BYTE minutes; /*;AN000;4*/ | ||
| 80 | BYTE seconds; /*;AN000;4*/ | ||
| 81 | BYTE hundreds; /*;AN000;4*/ | ||
| 82 | }; /*;AN000;4*/ | ||
| 83 | |||
| 84 | /**************************/ | ||
| 85 | /* RETURN BUFFER FOR DATE */ | ||
| 86 | /**************************/ | ||
| 87 | struct datebuff /*;AN000;4*/ | ||
| 88 | { /*;AN000;4*/ | ||
| 89 | BYTE db_type; /* TYPE RETURNED*/ /*;AN000;4*/ | ||
| 90 | BYTE db_item_tag; /* SPACE FOR ITEM TAG*/ /*;AN000;4*/ | ||
| 91 | WORD db_synonym_ptr; /*;AN000;4*/ | ||
| 92 | WORD year; /*;AN000;4*/ | ||
| 93 | BYTE month; /*;AN000;4*/ | ||
| 94 | BYTE day; /*;AN000;4*/ | ||
| 95 | }; /*;AN000;4*/ | ||
| 96 | |||
| 97 | |||
| 98 | /*******************************************/ | ||
| 99 | /* RETURN BUFFER FOR POSITIONAL PARAMETERS */ | ||
| 100 | /*******************************************/ | ||
| 101 | struct p_result_blk /*;AN000;4*/ | ||
| 102 | { /*;AN000;4*/ | ||
| 103 | BYTE p_type; /* Type returned */ /*;AN000;4*/ | ||
| 104 | BYTE p_item_tag; /* Matched item tag */ /*;AN000;4*/ | ||
| 105 | WORD p_synonym_ptr; /* pointer to Synonym list returned *//*;AN000;4*/ | ||
| 106 | DWORD p_string_ptr; /* Pointer to string */ /*;AN000;4*/ | ||
| 107 | }; /* or drive number in 1st byte /*;AN000;4*/ | ||
| 108 | |||
| 109 | /****************************************/ | ||
| 110 | /* RETURN BUFFER FOR SWITCH INFORMATION */ | ||
| 111 | /****************************************/ | ||
| 112 | struct switchbuff /*;AN000;4*/ | ||
| 113 | { /*;AN000;4*/ | ||
| 114 | BYTE sw_type; /* TYPE RETURNED*/ /*;AN000;4*/ | ||
| 115 | BYTE sw_item_tag; /* Matched item tag */ /*;AN000;4*/ | ||
| 116 | WORD sw_synonym_ptr; /* pointer to switch entered */ /*;AN000;4*/ | ||
| 117 | DWORD sw_string_ptr; /* Pointer to string */ /*;AN000;4*/ | ||
| 118 | }; /*;AN000;4*/ | ||
| 119 | |||
diff --git a/v4.0/src/CMD/RESTORE/RT.H b/v4.0/src/CMD/RESTORE/RT.H new file mode 100644 index 0000000..86a3bec --- /dev/null +++ b/v4.0/src/CMD/RESTORE/RT.H | |||
| @@ -0,0 +1,272 @@ | |||
| 1 | /* 0 */ | ||
| 2 | /*--------------------------------------------------------- | ||
| 3 | /*- | ||
| 4 | /*- RESTORE Utility include file RT.H | ||
| 5 | /*- | ||
| 6 | /*---------------------------------------------------------*/ | ||
| 7 | |||
| 8 | |||
| 9 | /****************************************************************************/ | ||
| 10 | /* This file contains equates for RESTORE utility */ | ||
| 11 | /* The equates for messages can be found in rt2.h */ | ||
| 12 | /****************************************************************************/ | ||
| 13 | |||
| 14 | #define BYTE unsigned char | ||
| 15 | #define WORD unsigned short | ||
| 16 | #define DWORD unsigned long | ||
| 17 | |||
| 18 | #define NOERROR 0 | ||
| 19 | #define CARRY 0x0001 /*;AN000;*/ | ||
| 20 | |||
| 21 | |||
| 22 | /*******************************************/ | ||
| 23 | /* Lengths of CONTROL.xxx structures */ | ||
| 24 | /*******************************************/ | ||
| 25 | #define DHEADLEN 139 /* length of new format disk header */ | ||
| 26 | #define DIRBLKLEN 70 /* length of new format dir block */ | ||
| 27 | #define FHEADLEN34 38 /*;AN000;3 Length of new format file header */ /* !wrw */ | ||
| 28 | #define FHEADLEN33 34 /* length of DOS 3.3 file header */ /* !wrw */ | ||
| 29 | |||
| 30 | /****************************************************************************/ | ||
| 31 | /* The following group of definitions are used to set and test the restore */ | ||
| 32 | /* switch flags. */ | ||
| 33 | /****************************************************************************/ | ||
| 34 | |||
| 35 | #define PROMPT 1 /* Prompt user before restoring hidden and */ | ||
| 36 | /* read-only files. */ | ||
| 37 | #define SUB 2 /* Restore all subdirectories too */ | ||
| 38 | #define BEFORE 4 /* Only restore files written before a date */ | ||
| 39 | #define AFTER 8 /* Only restore files written after a date */ | ||
| 40 | #define EARLIER 16 /* Only restore files written earlier then a time*/ | ||
| 41 | #define LATER 32 /* Only restore files written later than a time */ | ||
| 42 | #define Revised 64 /* Only restore files that have changed */ | ||
| 43 | #define NOTEXIST 128 /* Only restore files that no longer exist on */ | ||
| 44 | /* the destination drive. */ | ||
| 45 | |||
| 46 | |||
| 47 | /****************************************************************************/ | ||
| 48 | /* The following group of definitions are used to set and test the */ | ||
| 49 | /* restore control flags:control_flag. */ | ||
| 50 | /****************************************************************************/ | ||
| 51 | |||
| 52 | #define WILDCARD 1 /* Wildcards in input filespec */ | ||
| 53 | #define OLDNEW 2 /* indicate old format or new format */ | ||
| 54 | #define CREATIT 4 /* Restore file does not exist on dest disk */ | ||
| 55 | #define FOUND 8 /* Found a file to restore */ | ||
| 56 | #define SPLITFILE 16 /* File was backed up onto 2 or more disks */ | ||
| 57 | #define SWITCHES 32 /* There are switches set */ | ||
| 58 | #define SHARERROR 64 /* There is a file not restored due to */ | ||
| 59 | /* sharing error */ | ||
| 60 | #define PARTIAL 128 /* Set if file partially restored */ | ||
| 61 | |||
| 62 | /****************************************************************************/ | ||
| 63 | /* The following group of definitions are used to set and test the restore */ | ||
| 64 | /* control flags:control_flag2 */ | ||
| 65 | /****************************************************************************/ | ||
| 66 | |||
| 67 | #define SPLITCTL 1 /* Indicate whether control.xxx is larger */ | ||
| 68 | /* then MAXCTRL */ | ||
| 69 | #define RTSYSTEM 2 /* The file to be restore is system file */ | ||
| 70 | /* it has to be restored contiguously */ | ||
| 71 | #define COUNTRY 4 /*when the bit is on, country info is available */ | ||
| 72 | #define CPPC 8 /* bit = 1 when CP/DOS, otherwise, PC/DOS */ | ||
| 73 | #define SRC_HDISK 16 /* bit = 1 when the source disk is harddisk */ | ||
| 74 | #define TAR_HDISK 32 /* bit = 1 when the target disk is harddisk */ | ||
| 75 | #define OUTOF_SEQ 64 /* bit = 1 when the disk is out of sequence */ | ||
| 76 | /****************************************************************************/ | ||
| 77 | /* Miscelleneous definitions */ | ||
| 78 | /****************************************************************************/ | ||
| 79 | #define ON 1 /* the tested bit is on*/ | ||
| 80 | #define OFF 0 /* the tested bit is off */ | ||
| 81 | |||
| 82 | #define BACKUPID "BACKUPID.@@@" /* Used to reference that file */ | ||
| 83 | #define HEADLEN 128 /* Backup file header length */ | ||
| 84 | #define MAXARGS 11 /* Max # of arguments */ | ||
| 85 | #define MINARGS 1 /* Minimum # of arguments */ | ||
| 86 | #define MAXBUF 0xffff /* Max size of buf */ | ||
| 87 | #define DOWNSIZE 512 /* Amount to decrement memory request size */ | ||
| 88 | /* by when doing a series of mallocs. */ | ||
| 89 | #define MAXPATH 65 /* Length of space allocate for path names */ | ||
| 90 | #define MAXFNAME 9 /* Max length of file name */ | ||
| 91 | #define MAXFEXT 4 /* Max length of file extension */ | ||
| 92 | #define MAXFSPEC 13 /* Max length of file spec. */ | ||
| 93 | #define MAXPATHF 78 /* Max length of path and file spec */ | ||
| 94 | #define MAXYEARLEN 4 /* Max length of string that represent year */ | ||
| 95 | #define MAXMONTHLEN 2 /* Max length of string that represent month */ | ||
| 96 | #define MAXDAYLEN 2 /* Max length of string that represent day */ | ||
| 97 | #define MINYEAR 1980 /* Min value of input year */ | ||
| 98 | #define MAXYEAR 2079 /* Max value of input year */ | ||
| 99 | #define MAXMONTH 12 /* Max value of input year */ | ||
| 100 | #define MAXDAY 31 /* Max value of input year */ | ||
| 101 | #define MAXHOURLEN 2 /* Max length of string that represent hour */ | ||
| 102 | #define MAXMINUTELEN 2 /* Max length of string that represent minute*/ | ||
| 103 | #define MAXSECONDLEN 2 /* Max length of string that represent second*/ | ||
| 104 | #define NUL 0 /* The null character */ | ||
| 105 | #define NULLC '\000' /* The null character */ | ||
| 106 | #define MAXCTRL 3072 /* size of buffer to contain control.xxx */ | ||
| 107 | #define BKIDLENG 7 /* the lenght of old format disk header */ | ||
| 108 | #define NEWBKIDLENG 139 /* the length of new format disk header */ | ||
| 109 | #define NOTV 0x16 /* all file attrs except vol id */ | ||
| 110 | #define ON 1 /* the tested bit is on*/ | ||
| 111 | #define OFF 0 /* the tested bit is off */ | ||
| 112 | #define TRUE 0 /* return code, no error */ | ||
| 113 | #define FALSE 1 /* return code, there is an error */ | ||
| 114 | #define TTRUE 1 /* return code, no error */ | ||
| 115 | #define FFALSE 0 /* return code, there is an error */ | ||
| 116 | #define LAST_PART 0x01 /* the flag in finfo->fflag */ | ||
| 117 | /* if on, the file is last part of a file */ | ||
| 118 | #define COMPLETE_BIT 0x02 /* the complete bit in fheadnew->flag */ | ||
| 119 | /* if on, the file was backed up sucessfully */ | ||
| 120 | #define USA 0 | ||
| 121 | #define EUR 1 | ||
| 122 | #define JAP 2 | ||
| 123 | #define INSTALL_SIGNAL 2 /* active signal handler routine */ | ||
| 124 | #define DEACTIVE_SIGNAL 1 /* ignor signals */ | ||
| 125 | #define CTRL_C 1 /* control_c signal */ | ||
| 126 | #define CTRL_BREAK 4 /* control break signal */ | ||
| 127 | |||
| 128 | /****************************************************************************/ | ||
| 129 | /* Defines for common subroutines - comgetarg and computmsg */ | ||
| 130 | /****************************************************************************/ | ||
| 131 | |||
| 132 | #define RESPDATA_SIZE 1 /* size of the respdata */ | ||
| 133 | #define STND_IN_DEV 0 /* standard out device */ | ||
| 134 | #define STND_OUT_DEV 1 /* standard out device */ | ||
| 135 | #define STND_ERR_DEV 2 /* standard error device */ | ||
| 136 | #define NO_RESPTYPE 0 /*response type is no user */ | ||
| 137 | /*interaction */ | ||
| 138 | #define ANY_KEY_RESPTYPE 1 /*response type is ask user to enter*/ | ||
| 139 | /*any key. */ | ||
| 140 | #define ENTER_Y 0 /*user enter yes as response */ | ||
| 141 | #define ENTER_N 1 /*user enter no as response */ | ||
| 142 | |||
| 143 | /****************************************************************************/ | ||
| 144 | /* Defines for convert date format */ | ||
| 145 | /****************************************************************************/ | ||
| 146 | |||
| 147 | #define HRSHIFT 11 /* shift 11 bits to get the value of hour */ | ||
| 148 | #define HRMASK 0x1F /* mask to get the value of hour */ | ||
| 149 | #define MNSHIFT 5 /* shift 5 bits to get the value of minute */ | ||
| 150 | #define MNMASK 0x3F /* mask to get the value of minute */ | ||
| 151 | #define SCMASK 0x1F /* mask to get the value of second */ | ||
| 152 | #define MOSHIFT 5 /* shift 5 bits to get the value of month */ | ||
| 153 | #define MOMASK 0x0F /* mask to get the value of month */ | ||
| 154 | #define DYMASK 0x1F /* shift 9 bits to get the value of day */ | ||
| 155 | #define YRSHIFT 9 /* mask to get the value of day */ | ||
| 156 | #define YRMASK 0x7F /* mask to get the value of year */ | ||
| 157 | #define USA 0 | ||
| 158 | #define EUR 1 | ||
| 159 | #define JAP 2 | ||
| 160 | #define LOYR 1980 | ||
| 161 | |||
| 162 | /****************************************************************************/ | ||
| 163 | /* Defines for subroutine set_reset_test_flag */ | ||
| 164 | /****************************************************************************/ | ||
| 165 | #define SET 0 | ||
| 166 | #define RESET 1 | ||
| 167 | #define TEST 2 | ||
| 168 | |||
| 169 | /****************************************************************************/ | ||
| 170 | /* Defines for file attribut byte */ | ||
| 171 | /****************************************************************************/ | ||
| 172 | #define READONLY 1 /*the file is marked read only */ | ||
| 173 | #define HIDDEN 2 /*the file is marked hidden file */ | ||
| 174 | #define SYSTEM 4 /*the file is marked system file */ | ||
| 175 | #define VOLUME 8 /*the entry contains a volume label */ | ||
| 176 | #define SUBDIR 16 /*the entry is a subdirectory name */ | ||
| 177 | #define ARCHIVE 32 /*the archieve bit of the file */ | ||
| 178 | |||
| 179 | /****************************************************************************/ | ||
| 180 | /* Defines for PCDOS return levels */ | ||
| 181 | /****************************************************************************/ | ||
| 182 | |||
| 183 | #define PC_NORMAL 0 | ||
| 184 | /* Normal completion */ | ||
| 185 | #define PC_NOFILES 1 | ||
| 186 | /* no fl were found to restore */ | ||
| 187 | #define PC_SHARERR 2 | ||
| 188 | /* Some file not restored due to sharing error */ | ||
| 189 | #define PC_TUSER 3 | ||
| 190 | /* Terminated by user */ | ||
| 191 | #define PC_OTHER 4 | ||
| 192 | /* Terminated by user */ | ||
| 193 | /****************************************************************************/ | ||
| 194 | /* Defines for CPDOS return codes */ | ||
| 195 | /****************************************************************************/ | ||
| 196 | |||
| 197 | #define NORMAL NO_ERROR | ||
| 198 | /* Normal completion */ | ||
| 199 | #define NOFILES ERROR_FILE_NOT_FOUND | ||
| 200 | /* no fl were found to restore */ | ||
| 201 | #define SHARERR ERROR_SHARING_VIOLATION | ||
| 202 | /* Some file not restored due to sharing error */ | ||
| 203 | #define TUSER 1026 | ||
| 204 | /* Terminated by user */ | ||
| 205 | #define INSUFMEM ERROR_NOT_ENOUGH_MEMORY | ||
| 206 | /* insufficient memory */ | ||
| 207 | #define NOBACKUPFILE 1027 | ||
| 208 | /* source does not contain bk file*/ | ||
| 209 | #define INVALIDPARM ERROR_INVALID_PARAMETER | ||
| 210 | /* invalid parmameter */ | ||
| 211 | #define INVALIDDRIVE ERROR_INVALID_DRIVE | ||
| 212 | /* invalid drive */ | ||
| 213 | #define FILESEQERROR 1028 | ||
| 214 | /* file seq error */ | ||
| 215 | #define TARGETFULL ERROR_DISK_FULL | ||
| 216 | /* target disk is full */ | ||
| 217 | #define UNEXPECTED 999 | ||
| 218 | /* unexpected error */ | ||
| 219 | #define CREATIONERROR 1029 | ||
| 220 | /* file creation error */ | ||
| 221 | /************************************************/ | ||
| 222 | /* Substitution List for Message Retriever */ | ||
| 223 | /************************************************/ | ||
| 224 | /*----------------------- | ||
| 225 | ; SUBLIST Equates | ||
| 226 | ;------------------------*/ | ||
| 227 | #define SUBLIST_SIZE 11 /*;AN000;6 */ | ||
| 228 | |||
| 229 | #define LEFT_ALIGN 0x0 /*;AN000;6 00xxxxxx */ | ||
| 230 | #define RIGHT_ALIGN 0x80 /*;AN000;6 10xxxxxx */ | ||
| 231 | |||
| 232 | #define CHAR_FIELD_CHAR 0x0 /*;AN000;6 a0000000 */ | ||
| 233 | #define CHAR_FIELD_ASCIIZ 0x10 /*;AN000;6 a0010000 */ | ||
| 234 | |||
| 235 | #define UNSGN_BIN_BYTE 0x11 /*;AN000;6 a0010001 - Unsigned BINary to Decimal CHARacter */ | ||
| 236 | #define UNSGN_BIN_WORD 0x21 /*;AN000;6 a0100001 */ | ||
| 237 | #define UNSGN_BIN_DWORD 0x31 /*;AN000;6 a0110001 */ | ||
| 238 | |||
| 239 | #define SGN_BIN_BYTE 0x12 /*;AN000;6 a0010010 - Signed BINary to Decimal CHARacter */ | ||
| 240 | #define SGN_BIN_WORD 0x22 /*;AN000;6 a0100010 */ | ||
| 241 | #define SGN_BIN_DWORD 0x32 /*;AN000;6 a0110010 */ | ||
| 242 | |||
| 243 | #define BIN_HEX_BYTE 0x13 /*;AN000;6 a0010011 - Unsigned BINary to Hexidecimal CHARacter */ | ||
| 244 | #define BIN_HEX_WORD 0x23 /*;AN000;6 a0100011 */ | ||
| 245 | #define BIN_HEX_DWORD 0x33 /*;AN000;6 a0110011 */ | ||
| 246 | |||
| 247 | |||
| 248 | #define DATE_MDY_4 0x34 /*;AN000;6 MONTH,DAY AND YEAR (4 DIGITS)*/ | ||
| 249 | /*------------------------------------*/ | ||
| 250 | /*- MESSAGE CLASSES -*/ | ||
| 251 | /*------------------------------------*/ | ||
| 252 | #define EXTENDED 1 /*;AN000;6*/ | ||
| 253 | #define PARSEERROR 2 /*;AN000;6*/ | ||
| 254 | #define UTIL_MSG -1 /*;AN000;6*/ | ||
| 255 | |||
| 256 | #define CR 0x0d /*;AN000;6*/ | ||
| 257 | #define LF 0x0a /*;AN000;6*/ | ||
| 258 | /*------------------------------- | ||
| 259 | /*- INT 21h | ||
| 260 | /*-------------------------------*/ | ||
| 261 | #define SETLOGICALDRIVE 0x440f /*;AN000;8*/ | ||
| 262 | |||
| 263 | #define INSTALL_CHECK 0xB700 /*;AN000;2*/ | ||
| 264 | #define NOT_INSTALLED 0 /*;AN000;2*/ | ||
| 265 | #define GET_APPEND_VER 0xB702 /*;AN000;2*/ | ||
| 266 | #define NET_APPEND 1 /*;AN000;2*/ | ||
| 267 | #define DOS_APPEND 2 /*;AN000;2*/ | ||
| 268 | #define GET_STATE 0xB706 /*;AN000;2*/ | ||
| 269 | #define SET_STATE 0xB707 /*;AN000;2*/ | ||
| 270 | |||
| 271 | #define APPEND_X_BIT 0x8000 /*;AN000;2*/ | ||
| 272 | |||
diff --git a/v4.0/src/CMD/RESTORE/RT1.H b/v4.0/src/CMD/RESTORE/RT1.H new file mode 100644 index 0000000..e9ab46f --- /dev/null +++ b/v4.0/src/CMD/RESTORE/RT1.H | |||
| @@ -0,0 +1,273 @@ | |||
| 1 | /* 0 */ | ||
| 2 | /*--------------------------------------------------------- | ||
| 3 | /*- | ||
| 4 | /*- RESTORE Utility include file RT1.H | ||
| 5 | /*- | ||
| 6 | /*---------------------------------------------------------*/ | ||
| 7 | |||
| 8 | /****************************************************************************/ | ||
| 9 | /* This file contains equates for structure definitions used in RESTORE */ | ||
| 10 | /* utility. */ | ||
| 11 | /****************************************************************************/ | ||
| 12 | |||
| 13 | /***************************************************************************/ | ||
| 14 | /* dheadnew - structure of disk header in CONTROL.xxx, */ | ||
| 15 | /* used for new format only */ | ||
| 16 | /***************************************************************************/ | ||
| 17 | struct disk_header_new | ||
| 18 | { | ||
| 19 | BYTE dhlength; /* length, in byte , of disk header*/ | ||
| 20 | BYTE id[8]; /* identifies disk as a backup */ | ||
| 21 | BYTE sequence; /* backup diskette sequence num */ | ||
| 22 | /* (binary 1-255) */ | ||
| 23 | BYTE command[128]; /* save area for command line */ | ||
| 24 | /* parameters. */ | ||
| 25 | BYTE lastdisk; /* 0ffh if last targert 0 otherwise*/ | ||
| 26 | }; | ||
| 27 | |||
| 28 | |||
| 29 | /***************************************************************************/ | ||
| 30 | /* dirblk - structure of directory blocks in CONTROL.xxx, */ | ||
| 31 | /* used for new format only */ | ||
| 32 | /***************************************************************************/ | ||
| 33 | struct dir_block | ||
| 34 | { | ||
| 35 | BYTE dblength; /* length, in bytes, of dir block */ | ||
| 36 | BYTE path[63]; | ||
| 37 | /* ascii path of this directory, */ | ||
| 38 | /* drive letter omitted */ | ||
| 39 | WORD numentry; /* num of filenames currently in list*/ | ||
| 40 | DWORD nextdb; /* offset of next directory block */ | ||
| 41 | }; /* =0xffff if last dir block */ | ||
| 42 | |||
| 43 | |||
| 44 | /***************************************************************************/ | ||
| 45 | /* fheadnew - structure of file header in CONTROL.xxx, */ | ||
| 46 | /* used for new format only */ | ||
| 47 | /***************************************************************************/ | ||
| 48 | #define EXT_ATTR_FLAG 4 /*;AN000;3*/ | ||
| 49 | |||
| 50 | struct file_header_new | ||
| 51 | { | ||
| 52 | BYTE fhlength; /* Length, in bytes, of file header */ | ||
| 53 | BYTE fname[12]; /* ASCII file name (from directory)*/ | ||
| 54 | BYTE flag; /* bit 0=1 if last part of file */ | ||
| 55 | /* bit 1=1 if it is backed up successfully */ | ||
| 56 | /* ;AN000;3 bit 2=1 if Extended Attributes are backed up (New for DOS4.00) */ | ||
| 57 | DWORD flength; /* Total length of the file (from directory) */ | ||
| 58 | WORD fsequenc; /* Sequence #, for files that span */ | ||
| 59 | DWORD offset; /* Offset in BACKUP.xxx where this segment begins */ | ||
| 60 | DWORD partsize; /* Length of part of file on current target */ | ||
| 61 | WORD attrib; /* File attribute (from directory) */ | ||
| 62 | WORD ftime; /* Time when file was last Revised (from directory)*/ | ||
| 63 | WORD fdate; /* Date when file was last Revised (from directory)*/ | ||
| 64 | DWORD FH_EA_offset; /*;AN000;3 Offset in BACKUP.xxx where extended attrib begin */ | ||
| 65 | }; | ||
| 66 | |||
| 67 | /*----------------------------------*/ | ||
| 68 | /*- EXTENDED OPEN PARAMETER LIST -*/ | ||
| 69 | /*----------------------------------*/ | ||
| 70 | #define EXTATTBUFLEN 4086 /*;AN000;3*/ | ||
| 71 | struct parm_list /*;AN000;3*/ | ||
| 72 | { /*;AN000;3*/ | ||
| 73 | DWORD ext_attr_addr; /*;AN000;3*/ | ||
| 74 | WORD num_additional; /*;AN000;3*/ | ||
| 75 | }; /*;AN000;3*/ | ||
| 76 | |||
| 77 | |||
| 78 | |||
| 79 | |||
| 80 | |||
| 81 | |||
| 82 | |||
| 83 | |||
| 84 | |||
| 85 | |||
| 86 | /**************************************************************************/ | ||
| 87 | /* Fheadold - structure of file header, used for old format only. */ | ||
| 88 | /* There are 128 bytes totally in file header of the old */ | ||
| 89 | /* format backup disk. Only the first 85 bytes contains */ | ||
| 90 | /* meaningful information. */ | ||
| 91 | /* This is the structure attached to the beginning of every */ | ||
| 92 | /* file backed up with DOS 2.0 through 3.2 inclusive. */ | ||
| 93 | /**************************************************************************/ | ||
| 94 | struct file_header_old | ||
| 95 | { | ||
| 96 | BYTE headflg; /* 0FFh is last sequence of file, 00h if not last*/ | ||
| 97 | BYTE disknum[2]; /* file sequence number */ | ||
| 98 | BYTE fill1[2]; /* not used */ | ||
| 99 | BYTE wherefrom [78]; /* asciiz path and name without drive letter*/ | ||
| 100 | unsigned pathlen; /* length of previous field, not used in this program*/ | ||
| 101 | char garbage[50]; /* Filler */ | ||
| 102 | }; | ||
| 103 | |||
| 104 | |||
| 105 | |||
| 106 | |||
| 107 | /***************************************************************************/ | ||
| 108 | /* dheadold - structure of disk informtion, used by old format only. */ | ||
| 109 | /* There are 128 bytes totally in disk header of the old */ | ||
| 110 | /* format backup disk. Only the first 7 bytes contains */ | ||
| 111 | /* meaningful information. */ | ||
| 112 | /* This is the BACKUPID.@@@ file */ | ||
| 113 | /***************************************************************************/ | ||
| 114 | |||
| 115 | struct disk_header_old | ||
| 116 | { | ||
| 117 | BYTE diskflag; /* 0FFh if last disk, 00h if not last disk. */ | ||
| 118 | /* initialize it to 0FFh when BACKUP.@@@ is created,*/ | ||
| 119 | /* and zero it out when the disk is full */ | ||
| 120 | BYTE disknum[2]; /* Sequence number of the disk. Least significant*/ | ||
| 121 | /* byte first. */ | ||
| 122 | BYTE diskyear[2]; /* Year, LSB first. */ | ||
| 123 | BYTE diskday; /* Month (1 byte) and day (1 byte). */ | ||
| 124 | BYTE diskmonth; /* Month (1 byte) and day (1 byte). */ | ||
| 125 | }; | ||
| 126 | |||
| 127 | |||
| 128 | /***************************************************************************/ | ||
| 129 | /* timedate- structure of buffer to hold time and date data */ | ||
| 130 | /***************************************************************************/ | ||
| 131 | struct timedate { | ||
| 132 | unsigned int earlier_hour; | ||
| 133 | unsigned int earlier_minute; | ||
| 134 | unsigned int earlier_second; | ||
| 135 | unsigned int later_hour; | ||
| 136 | unsigned int later_minute; | ||
| 137 | unsigned int later_second; | ||
| 138 | unsigned int before_year; | ||
| 139 | unsigned int before_month; | ||
| 140 | unsigned int before_day; | ||
| 141 | unsigned int after_year; | ||
| 142 | unsigned int after_month; | ||
| 143 | unsigned int after_day; | ||
| 144 | }; | ||
| 145 | /***************************************************************************/ | ||
| 146 | /* fsinfo - structure of buffer returned from dosqsinfo */ | ||
| 147 | /***************************************************************************/ | ||
| 148 | struct fsinfo { /* file system information */ | ||
| 149 | unsigned long file_system_id; /* file system ID 4 */ | ||
| 150 | unsigned long sectors_per_alloc_unit; /* sectors per allocation unit 4 */ | ||
| 151 | unsigned long number_of_alloc_unit; /* number of allocation unit 4 */ | ||
| 152 | unsigned long available_alloc_unit; /* available allocatuib unit 4 */ | ||
| 153 | unsigned bytes_per_sector; /* number of bytes per sectors 2 */ | ||
| 154 | }; /* total byte size = 18 */ | ||
| 155 | |||
| 156 | #define FSINFO_BYTES sizeof(struct fsinfo) /* total # of bytes for BPB */ | ||
| 157 | |||
| 158 | /***************************************************************************/ | ||
| 159 | /* internat - structure of buffer returned from get country information */ | ||
| 160 | /***************************************************************************/ | ||
| 161 | struct internat { | ||
| 162 | unsigned country_code; /* country code */ | ||
| 163 | unsigned code_page; /* country code page */ | ||
| 164 | unsigned dtformat; /* time date format */ | ||
| 165 | /* 0-usa 1-eur 2-jap */ | ||
| 166 | BYTE currency_sym, /* Currency Symbol 5 bytes */ | ||
| 167 | r1, | ||
| 168 | r2, | ||
| 169 | r3; | ||
| 170 | BYTE r4; /* null terminated */ | ||
| 171 | BYTE thous_sep, /* Thousands separator 2 bytes */ | ||
| 172 | r5; /* null terminated */ | ||
| 173 | BYTE decimal_sep, /* Decimal separator 2 bytes */ | ||
| 174 | r6; /* null terminated */ | ||
| 175 | BYTE datesep, /* Date separator 2 bytes */ | ||
| 176 | r7; /* null terminated */ | ||
| 177 | BYTE timesep, /* Time separator 2 bytes */ | ||
| 178 | r8; /* null terminated */ | ||
| 179 | BYTE bit_field; /* Bit values */ | ||
| 180 | /* Bit 0 = 0 if currency symbol first */ | ||
| 181 | /* = 1 if currency symbol last */ | ||
| 182 | /* Bit 1= 0 if No space after currency symbol*/ | ||
| 183 | /* = 1 if space after currency symbol */ | ||
| 184 | BYTE currency_cents; /* Number of places after currency dec point*/ | ||
| 185 | BYTE tformat; /* 1 if 24 hour time, 0 if 12 hour time */ | ||
| 186 | unsigned long map_call; /* Address of case mapping call (DWORD) */ | ||
| 187 | /* in real mode compatibility API */ | ||
| 188 | BYTE data_sep, /* Data list separator character */ | ||
| 189 | r9; /* null terminated */ | ||
| 190 | unsigned ra[ 5 ]; /* reserved */ | ||
| 191 | } ; | ||
| 192 | |||
| 193 | |||
| 194 | /***************************************************************************/ | ||
| 195 | /* Finfo - structure of file information, used for both old format and */ | ||
| 196 | /* new format. It contains the information which is common */ | ||
| 197 | /* between new and old. */ | ||
| 198 | /***************************************************************************/ | ||
| 199 | struct file_info | ||
| 200 | { | ||
| 201 | BYTE fname[MAXFSPEC+1]; /* ASCII, filename and file extension.*/ | ||
| 202 | BYTE path[MAXPATH+1]; /* ASCII, file path, always started with \ */ | ||
| 203 | /* and not end with \ */ | ||
| 204 | BYTE fflag; /* last disk in case of file expanded */ | ||
| 205 | /* bit 0 = 1 if last part of file */ | ||
| 206 | /* In old format file header, its 0ffh if last. */ | ||
| 207 | /* The old format has to be converted into bit0=1.*/ | ||
| 208 | unsigned dnum; /* sequence number of the file. For file that span */ | ||
| 209 | unsigned attrib; /* file attribute */ | ||
| 210 | unsigned ftime; /* time when the file was created */ | ||
| 211 | unsigned fdate; /* date when the file was created */ | ||
| 212 | unsigned long partsize; /* part size of the file */ | ||
| 213 | unsigned long offset; /* offset of the file in backup.xxx */ | ||
| 214 | BYTE curdir[MAXPATH]; /* current directory of the destination disk.*/ | ||
| 215 | /* The current directory usually is maintained to be*/ | ||
| 216 | /* the directory that reside the file to be restored*/ | ||
| 217 | DWORD ea_offset; /*;AN000;3 Offset in BACKUP.xxx where extended attrib begin */ | ||
| 218 | }; | ||
| 219 | |||
| 220 | /****************************************************************************/ | ||
| 221 | /* dfinfo - destination file information, if the destination file */ | ||
| 222 | /* is exist. Structure of file information, used for both old */ | ||
| 223 | /* format and new format. It contains the information which is*/ | ||
| 224 | /* common between new and old. */ | ||
| 225 | /****************************************************************************/ | ||
| 226 | struct dfile_info { | ||
| 227 | BYTE fname[12]; /* ASCII, filename and file extension.*/ | ||
| 228 | BYTE path[64]; /* ASCII, file path, always started with \ and */ | ||
| 229 | /* not end with \ */ | ||
| 230 | BYTE fflag; /* last disk in case of file expanded */ | ||
| 231 | /* bit 0 = 1 if last part of file */ | ||
| 232 | /* In old format file header, its 0ffh if last. */ | ||
| 233 | /* The old format has to be converted into bit0=1.*/ | ||
| 234 | unsigned short dnum; /* sequence number of the file. For file that span */ | ||
| 235 | unsigned attrib; /* file attribute */ | ||
| 236 | unsigned ftime; /* time when the file was created */ | ||
| 237 | unsigned fdate; /* date when the file was created */ | ||
| 238 | BYTE *curdir; /* current directory of the destination disk. */ | ||
| 239 | /* The current directory usually is maintained to be */ | ||
| 240 | /* the directory that reside the file to be restored */ | ||
| 241 | }; | ||
| 242 | |||
| 243 | /***************************************************************************/ | ||
| 244 | /* dinfo - structure of disk information, used for both old format and */ | ||
| 245 | /* new format. It contains the information which is common */ | ||
| 246 | /* between new and old. */ | ||
| 247 | /***************************************************************************/ | ||
| 248 | struct disk_info { | ||
| 249 | BYTE dflag; /* last backup disk or not */ | ||
| 250 | /* Its 0ffh if last. 00h otherwise */ | ||
| 251 | BYTE disknum; /* sequence number of the file. For file that span */ | ||
| 252 | }; | ||
| 253 | struct subst_list /*;AN000;6 */ | ||
| 254 | { /*;AN000;6 */ | ||
| 255 | BYTE sl_size1; /* Size of List */ /*;AN000;6 */ | ||
| 256 | BYTE zero1; /* Reserved */ /*;AN000;6 */ | ||
| 257 | char far *value1; /* Time, date, or ptr to data item*/ /*;AN000;6 */ | ||
| 258 | BYTE one; /* n of %n */ /*;AN000;6 */ | ||
| 259 | BYTE flags1; /* Data Type flags */ /*;AN000;6 */ | ||
| 260 | BYTE max_width1; /* Maximum FIELD width */ /*;AN000;6 */ | ||
| 261 | BYTE min_width1; /* Minimum FIELD width */ /*;AN000;6 */ | ||
| 262 | BYTE pad_char1; /* Character for pad FIELD */ /*;AN000;6 */ | ||
| 263 | |||
| 264 | BYTE sl_size2; /* Size of List */ /*;AN000;6 */ | ||
| 265 | BYTE zero2; /* Reserved */ /*;AN000;6 */ | ||
| 266 | char far *value2; /* Time; date; or ptr to data item*/ /*;AN000;6 */ | ||
| 267 | BYTE two; /* n of %n */ /*;AN000;6 */ | ||
| 268 | BYTE flags2; /* Data Type flags */ /*;AN000;6 */ | ||
| 269 | BYTE max_width2; /* Maximum FIELD width */ /*;AN000;6 */ | ||
| 270 | BYTE min_width2; /* Minimum FIELD width */ /*;AN000;6 */ | ||
| 271 | BYTE pad_char2; /* Character for pad FIELD */ /*;AN000;6 */ | ||
| 272 | }; /*;AN000;6 */ | ||
| 273 | |||
diff --git a/v4.0/src/CMD/RESTORE/RT2.H b/v4.0/src/CMD/RESTORE/RT2.H new file mode 100644 index 0000000..95270b6 --- /dev/null +++ b/v4.0/src/CMD/RESTORE/RT2.H | |||
| @@ -0,0 +1,136 @@ | |||
| 1 | /* 0 */ | ||
| 2 | /*--------------------------------------------------------- | ||
| 3 | /*- | ||
| 4 | /*- RESTORE Utility include file RT2.H | ||
| 5 | /*- | ||
| 6 | /*---------------------------------------------------------*/ | ||
| 7 | |||
| 8 | |||
| 9 | |||
| 10 | /*------------------------------------*/ | ||
| 11 | /* MESSAGE DEFINITIONS */ | ||
| 12 | /*------------------------------------*/ | ||
| 13 | #define INVPARM 10 /* Parse class */ /*;AN000;6*/ | ||
| 14 | |||
| 15 | #define INVALID_DOS_VER 1 /*;AN000;6*/ | ||
| 16 | #define SOURCE_TARGET_SAME 2 /*;AN000;6*/ | ||
| 17 | #define INVALID_NUM_PARM 3 /*;AN000;6*/ | ||
| 18 | #define PATH_NOT_FOUND 5 /*;AN000;6*/ | ||
| 19 | #define INVALID_DRIVE 6 /*;AN000;6*/ | ||
| 20 | #define NO_FILE_TO_RESTORE 7 /*;AN000;6*/ | ||
| 21 | #define INSERT_SOURCE_DISK 8 /*;AN000;6*/ | ||
| 22 | #define INSERT_TARGET_DISK 9 /*;AN000;6*/ | ||
| 23 | #define PRESS_ANY_KEY 10 /*;AN000;6*/ | ||
| 24 | #define DISK_OUT_OF_SEQUENCE 11 /*;AN000;6*/ | ||
| 25 | #define LAST_FILE_NOT_RESTORED 12 /*;AN000;6*/ | ||
| 26 | #define FILES_WERE_BACKUP_ON 13 /*;AN000;6*/ | ||
| 27 | #define SOURCE_NO_BACKUP_FILE 14 /*;AN000;6*/ | ||
| 28 | #define INSUFFICIENT_MEMORY 15 /*;AN000;6*/ | ||
| 29 | #define FILE_IS_READONLY 16 /*;AN000;6*/ | ||
| 30 | #define FILE_SEQUENCE_ERROR 17 /*;AN000;6*/ | ||
| 31 | #define FILE_CREATION_ERROR 18 /*;AN000;6*/ | ||
| 32 | #define TARGET_IS_FULL 19 /*;AN000;6*/ | ||
| 33 | #define NOT_ABLE_TO_RESTORE_FILE 20 /*;AN000;6*/ | ||
| 34 | #define RESTORE_FILE_FROM_DRIVE 21 /*;AN000;6*/ | ||
| 35 | #define FILE_WAS_CHANGED 22 /*;AN000;6*/ | ||
| 36 | #define DISKETTE_NUM 23 /*;AN000;6*/ | ||
| 37 | |||
| 38 | #define INV_DATE 27 /*;AN000;6*/ | ||
| 39 | #define INV_TIME 28 /*;AN000;6*/ | ||
| 40 | #define NO_SOURCE 29 /*;AN000;6*/ | ||
| 41 | #define NO_TARGET 30 /*;AN000;6*/ | ||
| 42 | #define CRLF 31 /*;AN000;6*/ | ||
| 43 | |||
| 44 | #define FILE_TO_BE_RESTORED 99 /*;AN000;6*/ | ||
| 45 | |||
| 46 | /*------------------------------------*/ | ||
| 47 | /*- MESSAGE CLASSES -*/ | ||
| 48 | /*------------------------------------*/ | ||
| 49 | #define EXTENDED 1 /*;AN000;6*/ | ||
| 50 | #define PARSEERR 2 /*;AN000;6*/ | ||
| 51 | #define UTILMSG -1 /*;AN000;6*/ | ||
| 52 | |||
| 53 | /* 0*/ | ||
| 54 | /*----------------------------------*/ | ||
| 55 | /*- SUBROUTINE DECLARATIONS */ | ||
| 56 | /*----------------------------------*/ | ||
| 57 | void main(int ,char *[0]); | ||
| 58 | void set_input_switches(WORD,BYTE * *,WORD *,struct timedate *); | ||
| 59 | void verify_input_switches(BYTE *,struct timedate *); | ||
| 60 | int set_reset_test_flag(BYTE *,BYTE ,int ); | ||
| 61 | void separate(BYTE *,BYTE *,BYTE *,BYTE *,BYTE *); | ||
| 62 | void initbuf(DWORD *); | ||
| 63 | void init_control_buf(unsigned long ,unsigned int *); | ||
| 64 | void usererror(WORD ); | ||
| 65 | void unexperror(WORD ); | ||
| 66 | void exit_routine(WORD ); | ||
| 67 | void pascal far signal_handler_routine(void ); | ||
| 68 | extern unsigned far pascal set_int24_vector(void); /*;AN000;*/ | ||
| 69 | void com_msg(WORD ); | ||
| 70 | int checkdosver(void ); | ||
| 71 | void dorestore(BYTE ,BYTE ,BYTE *,BYTE *,BYTE *,BYTE *,struct timedate *); | ||
| 72 | void check_bkdisk_old(struct disk_header_old *, struct disk_info *,BYTE,unsigned int *); | ||
| 73 | void check_bkdisk_new(struct disk_header_new far *,struct disk_info *,BYTE,unsigned int *,unsigned int *); | ||
| 74 | void print_info(int ,int ,int); | ||
| 75 | WORD pathmatch(BYTE *,BYTE *); | ||
| 76 | WORD switchmatch(struct file_info *,BYTE,BYTE,struct timedate *); | ||
| 77 | |||
| 78 | int check_flheader_old(struct file_info *,unsigned char *,unsigned int , | ||
| 79 | unsigned int ,unsigned int ,unsigned long ,unsigned int ,unsigned char , | ||
| 80 | unsigned char ,unsigned char *,unsigned char *,unsigned int *); | ||
| 81 | |||
| 82 | int readonly_or_changed(unsigned int ,unsigned char ,unsigned char *, unsigned char *); | ||
| 83 | int fspecmatch(char *,char *); | ||
| 84 | WORD open_dest_file(struct file_info *,BYTE ); | ||
| 85 | void build_path_create_file(BYTE *,BYTE,BYTE,DWORD); /*;AC000;3*/ | ||
| 86 | int set_attributes_and_close(struct file_info *, BYTE); | ||
| 87 | int dos_write_error(DWORD ,BYTE ); | ||
| 88 | int findfile_new(struct file_info *,WORD *,unsigned int *,BYTE *,BYTE *,WORD far * *,WORD far * *,unsigned int *,BYTE *); | ||
| 89 | int findnew_new(struct file_info *,WORD *,WORD *,BYTE *,BYTE *, WORD far * *,WORD far * *,WORD *,BYTE *); | ||
| 90 | |||
| 91 | void search_src_disk_old(struct disk_info *,struct file_info *,struct disk_header_old *, | ||
| 92 | struct disk_header_new far *,struct file_header_new far *, | ||
| 93 | unsigned char,unsigned char,unsigned long,unsigned int *,unsigned char *,unsigned char *, | ||
| 94 | unsigned char *,unsigned char *,struct timedate *); | ||
| 95 | |||
| 96 | void search_src_disk_new(struct disk_info *,struct file_info *,struct disk_header_old *, | ||
| 97 | struct disk_header_new far *,struct file_header_new far *, | ||
| 98 | unsigned char,unsigned char,unsigned int *,unsigned long,unsigned char *,unsigned char *, | ||
| 99 | unsigned char *,unsigned int *,struct timedate *); | ||
| 100 | |||
| 101 | int findfirst_new(struct file_info *,WORD *,unsigned int *,BYTE *,BYTE *,WORD far**,WORD far**,unsigned int *,BYTE *); | ||
| 102 | int findnext_new (struct file_info *,WORD *,unsigned int *,BYTE *,BYTE *,WORD far**,WORD far**,unsigned int *,BYTE *); | ||
| 103 | |||
| 104 | void restore_a_file(struct file_info *,struct disk_info *,unsigned long,unsigned int *, | ||
| 105 | struct file_header_new far *,struct disk_header_old *,struct disk_header_new far *,unsigned char,unsigned char, | ||
| 106 | unsigned char *,unsigned char *,unsigned char *,unsigned int *,unsigned int *); | ||
| 107 | |||
| 108 | /*---------------------------------------- | ||
| 109 | /*- ADDED FOR DOS 4.00 | ||
| 110 | /*----------------------------------------*/ | ||
| 111 | int cdecl sprintf(char *,const char *, ...); | ||
| 112 | int cdecl printf(const char *,...); | ||
| 113 | void check_time(BYTE,BYTE,BYTE,BYTE); /*;AN000;4*//*;AC002;*/ | ||
| 114 | void check_date(WORD,BYTE,BYTE); /*;AN000;4*//*;AC002;*/ | ||
| 115 | void parse_error(WORD,BYTE); /*;AN000;4*//*;AC002;*/ | ||
| 116 | void parse_init(void); /*;AN000;4*/ | ||
| 117 | void process_switch(unsigned,char *); /*;AN000;4*//*;AC002;*/ | ||
| 118 | void check_source_drive(int,char * []); /*;AN000;4*/ | ||
| 119 | void check_target_filespec(int,char * []); /*;AN000;4*/ | ||
| 120 | void display_it(WORD,WORD,WORD,WORD,BYTE); /*;AN000;6*/ | ||
| 121 | void parse_command_line(int, char * []); /*;AN000;4*/ | ||
| 122 | void check_appendX(void); /*;AN000;2*/ | ||
| 123 | void read_in_first_dirblock(void); /* !wrw */ | ||
| 124 | void read_in_a_fileheader(void); /* !wrw */ | ||
| 125 | void read_in_next_dirblock(void); /* !wrw */ | ||
| 126 | void get_fileheader_length(void); /*;AN000;3*/ | ||
| 127 | WORD create_the_file(BYTE,DWORD); /*;AN000;3*/ | ||
| 128 | void read_the_extended_attributes(DWORD); /*;AN000;3*/ | ||
| 129 | void check_for_device_names(char * []); /*;AN000;p2591*/ | ||
| 130 | WORD chek_DBCS(char *,WORD,char); /*;AN005;*/ | ||
| 131 | void Get_DBCS_vector(void); /*;AN005;*/ | ||
| 132 | |||
| 133 | extern void sysloadmsg(union REGS *, union REGS *); /*_msgret *//*;AN000;6 */ | ||
| 134 | extern void sysdispmsg(union REGS *, union REGS *); /*_msgret *//*;AN000;6 */ | ||
| 135 | extern void parse (union REGS *, union REGS *); /* _parse *//*;AN000;4 */ | ||
| 136 | |||
diff --git a/v4.0/src/CMD/RESTORE/RTDO.C b/v4.0/src/CMD/RESTORE/RTDO.C new file mode 100644 index 0000000..bd736b5 --- /dev/null +++ b/v4.0/src/CMD/RESTORE/RTDO.C | |||
| @@ -0,0 +1,376 @@ | |||
| 1 | |||
| 2 | /*------------------------------------ | ||
| 3 | /* SOURCE FILE NAME: RTDO.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 "stdio.h" | ||
| 13 | #include "string.h" | ||
| 14 | #include "dos.h" /*;AN000;2*/ | ||
| 15 | #include "comsub.h" /* common subroutine def'n */ | ||
| 16 | #include "doscalls.h" | ||
| 17 | #include "error.h" | ||
| 18 | |||
| 19 | BYTE *buf_pointer; | ||
| 20 | unsigned control_file_pointer; | ||
| 21 | unsigned src_file_handle; | ||
| 22 | struct FileFindBuf filefindbuf; | ||
| 23 | struct FileFindBuf dfilefindbuf; | ||
| 24 | BYTE far *control_buf_pointer; | ||
| 25 | unsigned int control_bufsize; /* !wrw */ | ||
| 26 | |||
| 27 | extern unsigned char srcddir[MAXPATH+3]; | ||
| 28 | extern unsigned char rtswitch; | ||
| 29 | extern unsigned char control_flag; | ||
| 30 | extern unsigned char control_flag2; | ||
| 31 | extern unsigned control_file_handle; /* !wrw */ | ||
| 32 | extern struct subst_list sublist; /*;AN000;6 Message substitution list */ | ||
| 33 | |||
| 34 | /***************** START OF SPECIFICATION ******************************** | ||
| 35 | /* | ||
| 36 | /* SUBROUTINE NAME : Dorestore | ||
| 37 | /* | ||
| 38 | /* DESCRIPTIVE NAME : Searching all disks and restore the matching files. | ||
| 39 | /* | ||
| 40 | /* FUNCTION: This routine does the following: | ||
| 41 | /* 1. Initialize the buffer | ||
| 42 | /* 2. Change directory to the one which will hold the first | ||
| 43 | /* files to be restored. | ||
| 44 | /* 3. If the source drive is removable | ||
| 45 | /* Ouput the message to the screen for user to insert a | ||
| 46 | /* diskette and hit a key when ready. | ||
| 47 | /* 4. If the target drive is removable | ||
| 48 | /* Ouput the message to the screen for user to insert a | ||
| 49 | /* diskette and hit a key when ready. | ||
| 50 | /* 5. Check whether the diskette contains old or new data | ||
| 51 | /* format. | ||
| 52 | /* 6. ouput "file were backup xx-xx-xx" | ||
| 53 | /* | ||
| 54 | /* For each diskette, do the following: | ||
| 55 | /* 5. Call check_bkdisk_old or check_bkdisk_new to check whethe | ||
| 56 | /* it is a backup diskette and whether it is in correct | ||
| 57 | /* sequence number. | ||
| 58 | /* 6. Call search_src_disk_old or search_src_disk_new to search | ||
| 59 | /* the entire diskette to find matching files and | ||
| 60 | /* restore them. | ||
| 61 | /* | ||
| 62 | /* | ||
| 63 | /********************** END OF SPECIFICATIONS *******************************/ | ||
| 64 | void dorestore(srcd,destd,inpath,infname,infext,infspec,dt) /* wrw! */ | ||
| 65 | BYTE srcd; | ||
| 66 | BYTE destd; | ||
| 67 | BYTE *inpath; | ||
| 68 | BYTE *infname; | ||
| 69 | BYTE *infext; | ||
| 70 | BYTE *infspec; | ||
| 71 | struct timedate *dt; | ||
| 72 | { | ||
| 73 | BYTE string[MAXPATH+2]; | ||
| 74 | struct disk_header_old dheadold; | ||
| 75 | struct disk_header_new dheadnew; | ||
| 76 | struct file_header_new fheadnew; | ||
| 77 | struct disk_info dinfo; | ||
| 78 | struct file_info finfo; | ||
| 79 | unsigned int control_bufsize; | ||
| 80 | unsigned dirlen = MAXPATH; | ||
| 81 | WORD dyear; | ||
| 82 | WORD dmonth; | ||
| 83 | WORD dday; | ||
| 84 | |||
| 85 | BYTE c; | ||
| 86 | BYTE done; /*;AN000;p????*/ | ||
| 87 | BYTE path_to_be_chdir[MAXPATH]; | ||
| 88 | WORD srcd_num; | ||
| 89 | BYTE temp_srcddir[MAXPATH]; | ||
| 90 | unsigned int dnumwant = 1; | ||
| 91 | DWORD bufsize; | ||
| 92 | BYTE temp_array1[4]; /*temparary array to build parameters for substitution list */ | ||
| 93 | BYTE temp_array2[4]; | ||
| 94 | |||
| 95 | /*declaration for dosfindfirst */ | ||
| 96 | unsigned dirhandle = 1; | ||
| 97 | unsigned attribute = NOTV; | ||
| 98 | unsigned search_cnt = 1; /* # of entries to find */ | ||
| 99 | unsigned buf_len = sizeof(struct FileFindBuf); | ||
| 100 | BYTE search_string[MAXPATHF+2]; | ||
| 101 | WORD retcode; | ||
| 102 | /*end decleration for ffirst and fnext*/ | ||
| 103 | |||
| 104 | union REGS qregs; /*;AN000;8*/ | ||
| 105 | DWORD date; /*;AN000;6*/ | ||
| 106 | |||
| 107 | /****************************************************************/ | ||
| 108 | /* change dest drive directory to the one which will hold the */ | ||
| 109 | /* first file to be restored */ | ||
| 110 | /****************************************************************/ | ||
| 111 | string[0] = destd; | ||
| 112 | string[1] = ':'; | ||
| 113 | string[2] = NULLC; | ||
| 114 | strcat(string,inpath); | ||
| 115 | /*if chdir sucessful, save the directory in finfo->curdir*/ | ||
| 116 | /*if fail, the path is not exist, and needs to be rebuild*/ | ||
| 117 | if(chdir(string)==0) | ||
| 118 | strcpy(finfo.curdir,inpath); | ||
| 119 | |||
| 120 | /*****************************************************************/ | ||
| 121 | /*if the source disk is hard disk get the current dir of the srcd*/ | ||
| 122 | /* chdir the source disk to be in \backup directory */ | ||
| 123 | /*****************************************************************/ | ||
| 124 | /**************************************/ | ||
| 125 | /* if the source disk is a hard disk */ | ||
| 126 | /**************************************/ | ||
| 127 | /* save current directory of source disk to be reset back later */ | ||
| 128 | /* convert character srcd into integer form */ | ||
| 129 | /**************************************/ | ||
| 130 | |||
| 131 | srcd_num = (WORD)(srcd - 'A' +1); | ||
| 132 | |||
| 133 | /**************************************/ | ||
| 134 | /* get current directory of srcd (DosQCurDir) */ | ||
| 135 | /**************************************/ | ||
| 136 | if ((retcode = DOSQCURDIR(srcd_num,(char far *) srcddir,(unsigned far *)&dirlen)) != 0) | ||
| 137 | { | ||
| 138 | display_it(INVALID_DRIVE,STND_ERR_DEV,0,NO_RESPTYPE,(BYTE)UTIL_MSG);/*;AN000;6*/ | ||
| 139 | usererror(INVALIDDRIVE); | ||
| 140 | } | ||
| 141 | |||
| 142 | temp_srcddir[0] = srcd; | ||
| 143 | temp_srcddir[1] = ':'; | ||
| 144 | temp_srcddir[2] = NULLC; | ||
| 145 | if (strlen(srcddir) != 1) | ||
| 146 | strcat(temp_srcddir,"\\"); | ||
| 147 | strcat(temp_srcddir,srcddir); | ||
| 148 | strcpy(srcddir,temp_srcddir); | ||
| 149 | |||
| 150 | path_to_be_chdir[0] = srcd; | ||
| 151 | path_to_be_chdir[1] = ':'; | ||
| 152 | path_to_be_chdir[2] = NULLC; | ||
| 153 | if (set_reset_test_flag(&control_flag2,SRC_HDISK,TEST) == TRUE) | ||
| 154 | strcat(path_to_be_chdir,"\\BACKUP"); | ||
| 155 | else | ||
| 156 | strcat(path_to_be_chdir,"\\"); | ||
| 157 | |||
| 158 | if(chdir(path_to_be_chdir)!=0) | ||
| 159 | { display_it(SOURCE_NO_BACKUP_FILE,STND_ERR_DEV,0,NO_RESPTYPE,(BYTE)UTIL_MSG); /*;AN000;6*/ | ||
| 160 | usererror(NOBACKUPFILE); | ||
| 161 | } | ||
| 162 | |||
| 163 | /*****************************************************************/ | ||
| 164 | /* Identify whether the inserted diskette is a old format backup */ | ||
| 165 | /* diskette or a new format backup diskette */ | ||
| 166 | /* BACKUP.@@@ or BACKUP.xxx with xxx numeric characters has */ | ||
| 167 | /* to be on the diskette */ | ||
| 168 | /*****************************************************************/ | ||
| 169 | search_string[0] = srcd; | ||
| 170 | search_string[1] = ':'; | ||
| 171 | search_string[2] = NULLC; | ||
| 172 | strcat(search_string, "BACKUP*.???"); | ||
| 173 | |||
| 174 | /***********************/ | ||
| 175 | /* Find the first file */ | ||
| 176 | /***********************/ | ||
| 177 | done = FFALSE; /*;AN000;p????*/ | ||
| 178 | |||
| 179 | retcode = /*;AN000;p????*/ | ||
| 180 | DOSFINDFIRST /*;AN000;p????*/ | ||
| 181 | ( /*;AN000;p????*/ | ||
| 182 | (char far *)search_string, /*;AN000;p????*/ | ||
| 183 | (unsigned far *)&dirhandle, /*;AN000;p????*/ | ||
| 184 | attribute, /*;AN000;p????*/ | ||
| 185 | (struct FileFindBuf far *)&filefindbuf, /*;AN000;p????*/ | ||
| 186 | buf_len, /*;AN000;p????*/ | ||
| 187 | (unsigned far *)&search_cnt, /*;AN000;p????*/ | ||
| 188 | (DWORD) 0 /*;AN000;p????*/ | ||
| 189 | ); /*;AN000;p????*/ | ||
| 190 | |||
| 191 | if (retcode != NOERROR) /*;AN000;p????*/ | ||
| 192 | { display_it(SOURCE_NO_BACKUP_FILE,STND_ERR_DEV,0,NO_RESPTYPE,(BYTE)UTIL_MSG); /*;AN000;p????*/ | ||
| 193 | usererror(NOBACKUPFILE); /*;AN000;p????*/ | ||
| 194 | } /*;AN000;p????*/ | ||
| 195 | |||
| 196 | /*****************************/ | ||
| 197 | /* Skip over subdirectories */ | ||
| 198 | while((retcode = filefindbuf.attributes & SUBDIR) == SUBDIR) /*;AN000;p????*/ | ||
| 199 | { /*;AN000;p????*/ | ||
| 200 | search_cnt = 1; /*;AN000;p????*/ | ||
| 201 | |||
| 202 | retcode = /*;AN000;p????*/ | ||
| 203 | DOSFINDNEXT /*;AN000;p????*/ | ||
| 204 | ( dirhandle, /*;AN000;p????*/ | ||
| 205 | (struct FileFindBuf far *)&filefindbuf, /*;AN000;p????*/ | ||
| 206 | buf_len, /*;AN000;p????*/ | ||
| 207 | (unsigned far *)&search_cnt /*;AN000;p????*/ | ||
| 208 | ); /*;AN000;p????*/ | ||
| 209 | |||
| 210 | if (retcode != NOERROR) /*;AN000;p????*/ | ||
| 211 | { display_it(SOURCE_NO_BACKUP_FILE,STND_ERR_DEV,0,NO_RESPTYPE,(BYTE)UTIL_MSG); /*;AN000;p????*/ | ||
| 212 | usererror(NOBACKUPFILE); /*;AN000;p????*/ | ||
| 213 | } /*;AN000;p????*/ | ||
| 214 | } /*;AN000;p????*/ | ||
| 215 | |||
| 216 | /****************************************/ | ||
| 217 | /* Loop through looking at file names */ | ||
| 218 | /****************************************/ | ||
| 219 | do /*;AN000;p????*/ | ||
| 220 | { /* Is it old BACKUP ??? */ /*;AN000;p????*/ | ||
| 221 | if (strcmp(filefindbuf.file_name,BACKUPID)==0) /*;AN000;p????*/ | ||
| 222 | { /*;AN000;p????*/ | ||
| 223 | set_reset_test_flag(&control_flag,OLDNEW,SET); /*;AN000;p????*/ | ||
| 224 | done = TTRUE; /*;AN000;p????*/ | ||
| 225 | } /*;AN000;p????*/ | ||
| 226 | else /*;AN000;p????*/ | ||
| 227 | { /* Is it new BACKUP ??? */ /*;AN000;p????*/ | ||
| 228 | if ((filefindbuf.file_name[6] == '.') && /*;AN000;p????*/ | ||
| 229 | (filefindbuf.file_name[7] >= '0') && /*;AN000;p????*/ | ||
| 230 | (filefindbuf.file_name[7] <= '9') && /*;AN000;p????*/ | ||
| 231 | (filefindbuf.file_name[8] >= '0') && /*;AN000;p????*/ | ||
| 232 | (filefindbuf.file_name[8] <= '9') && /*;AN000;p????*/ | ||
| 233 | (filefindbuf.file_name[9] >= '0') && /*;AN000;p????*/ | ||
| 234 | (filefindbuf.file_name[9] <= '9') && /*;AN000;p????*/ | ||
| 235 | (filefindbuf.file_name[10] == NULLC) ) /*;AN000;p????*/ | ||
| 236 | { /*;AN000;p????*/ | ||
| 237 | set_reset_test_flag(&control_flag,OLDNEW,RESET); /*;AN000;p????*/ | ||
| 238 | init_control_buf((unsigned long)0,&control_bufsize);/*;AN000;p????*/ | ||
| 239 | done = TTRUE; /*;AN000;p????*/ | ||
| 240 | } /*;AN000;p????*/ | ||
| 241 | } | ||
| 242 | |||
| 243 | if (!done) | ||
| 244 | do | ||
| 245 | { /*;AN000;p????*/ | ||
| 246 | search_cnt = 1; /*;AN000;p????*/ | ||
| 247 | retcode = /*;AN000;p????*/ | ||
| 248 | DOSFINDNEXT /*;AN000;p????*/ | ||
| 249 | ( dirhandle, /*;AN000;p????*/ | ||
| 250 | (struct FileFindBuf far *)&filefindbuf, /*;AN000;p????*/ | ||
| 251 | buf_len, /*;AN000;p????*/ | ||
| 252 | (unsigned far *)&search_cnt /*;AN000;p????*/ | ||
| 253 | ); /*;AN000;p????*/ | ||
| 254 | |||
| 255 | if (retcode != NOERROR) /*;AN000;p????*/ | ||
| 256 | { display_it(SOURCE_NO_BACKUP_FILE,STND_ERR_DEV,0,NO_RESPTYPE,(BYTE)UTIL_MSG); /*;AN000;p????*/ | ||
| 257 | usererror(NOBACKUPFILE); /*;AN000;p????*/ | ||
| 258 | } /*;AN000;p????*/ | ||
| 259 | |||
| 260 | } /* end while */ /*;AN000;p????*/ | ||
| 261 | while(filefindbuf.attributes & SUBDIR == SUBDIR); | ||
| 262 | |||
| 263 | } /* end DO loop */ /*;AN000;p????*/ | ||
| 264 | while (!done); /*;AN000;p????*/ | ||
| 265 | |||
| 266 | |||
| 267 | retcode = DOSFINDCLOSE(dirhandle); | ||
| 268 | |||
| 269 | /***************************************/ | ||
| 270 | /* Display the date of the backup disk */ | ||
| 271 | /***************************************/ | ||
| 272 | dyear = (filefindbuf.write_date >> YRSHIFT & YRMASK) + LOYR; | ||
| 273 | dmonth = filefindbuf.write_date >> MOSHIFT & MOMASK; | ||
| 274 | dday = filefindbuf.write_date & DYMASK; | ||
| 275 | date = dyear + (dday*16777216) + (dmonth*65536); /*;AN000;6*/ | ||
| 276 | |||
| 277 | sublist.value1 = (char far *)date; /*;AN000;6*/ | ||
| 278 | sublist.flags1 = LEFT_ALIGN + DATE_MDY_4; /*;AN000;6*/ | ||
| 279 | sublist.max_width1 = (BYTE)10; /*;AN000;6*/ | ||
| 280 | sublist.min_width1 = sublist.max_width1; /*;AN000;6*/ | ||
| 281 | display_it(FILES_WERE_BACKUP_ON,STND_OUT_DEV,1,NO_RESPTYPE,(BYTE)UTIL_MSG);/*;AN000;6*/ | ||
| 282 | |||
| 283 | /*****************************************************************/ | ||
| 284 | /*start a loop to check and restore each diskette */ | ||
| 285 | /*****************************************************************/ | ||
| 286 | initbuf(&bufsize); /* !wrw */ | ||
| 287 | |||
| 288 | for (;;) | ||
| 289 | { | ||
| 290 | |||
| 291 | /*****************************************************************/ | ||
| 292 | /* check whether the inserted diskette is a backup diskette */ | ||
| 293 | /*****************************************************************/ | ||
| 294 | /*if old, check_bkdisk_old else check_bkdisk_new*/ | ||
| 295 | |||
| 296 | if (set_reset_test_flag(&control_flag,OLDNEW,TEST) == TRUE) | ||
| 297 | check_bkdisk_old(&dheadold, &dinfo, srcd, &dnumwant); | ||
| 298 | else | ||
| 299 | check_bkdisk_new((struct disk_header_new far *)&dheadnew, &dinfo, srcd, &dnumwant,&control_bufsize); | ||
| 300 | |||
| 301 | /*****************************************************************/ | ||
| 302 | /* At this point a real backup diskette which is in correct sequence number */ | ||
| 303 | /* has been found. In the case of new format, the file CONTROL.xxx is open.*/ | ||
| 304 | /*****************************************************************/ | ||
| 305 | /* restored the diskette */ | ||
| 306 | /*****************************************************************/ | ||
| 307 | |||
| 308 | /*if old*/ | ||
| 309 | if (set_reset_test_flag(&control_flag,OLDNEW,TEST) == TRUE) | ||
| 310 | search_src_disk_old(&dinfo,&finfo,&dheadold,(struct disk_header_new far *)&dheadnew, | ||
| 311 | (struct file_header_new far *)&fheadnew,srcd,destd,bufsize,&dnumwant, | ||
| 312 | inpath,infname,infext,infspec,dt); | ||
| 313 | else | ||
| 314 | search_src_disk_new(&dinfo,&finfo,&dheadold,(struct disk_header_new far *)&dheadnew, | ||
| 315 | (struct file_header_new far *)&fheadnew,srcd,destd,&dnumwant,bufsize, | ||
| 316 | inpath,infname,infspec,&control_bufsize,dt); | ||
| 317 | |||
| 318 | printf("\n"); | ||
| 319 | set_reset_test_flag(&control_flag2,OUTOF_SEQ,RESET); | ||
| 320 | /************************************************************************/ | ||
| 321 | /*if ( bk disk is not the last one && (the file spec is WILDCARD or file*/ | ||
| 322 | /*not found yet or SUB flag in rtswitches is on)), then prompt for user */ | ||
| 323 | /*to insert another diskette and loop again. */ | ||
| 324 | /************************************************************************/ | ||
| 325 | if ((dinfo.dflag!=0xff) && | ||
| 326 | ((set_reset_test_flag(&control_flag,WILDCARD,TEST) == TRUE) || | ||
| 327 | (set_reset_test_flag(&control_flag,FOUND,TEST) == FALSE) || | ||
| 328 | (set_reset_test_flag(&rtswitch,SUB,TEST) == TRUE))) | ||
| 329 | { | ||
| 330 | /**********************************************************/ | ||
| 331 | /* output message for user to insert another diskette and */ | ||
| 332 | /* "strike any key when ready" */ | ||
| 333 | /* with response type 4 (wait for a key to be hit) */ | ||
| 334 | /**********************************************************/ | ||
| 335 | |||
| 336 | if (control_file_handle != 0xffff) /* !wrw */ | ||
| 337 | { /* !wrw */ | ||
| 338 | DOSCLOSE(control_file_handle); /* !wrw */ | ||
| 339 | control_file_handle = 0xffff; /* !wrw */ | ||
| 340 | } /* !wrw */ | ||
| 341 | |||
| 342 | temp_array1[0] = (char)((dnumwant / 10) + '0'); | ||
| 343 | temp_array1[1] = (char)((dnumwant % 10) + '0'); | ||
| 344 | temp_array1[2] = NULLC; | ||
| 345 | temp_array2[0] = srcd; | ||
| 346 | temp_array2[1] = NULLC; | ||
| 347 | |||
| 348 | sublist.value1 = (char far *)temp_array1; /*;AN000;6 */ | ||
| 349 | sublist.flags1 = LEFT_ALIGN + CHAR_FIELD_ASCIIZ; /*;AN000;6 */ | ||
| 350 | sublist.max_width1 = (BYTE)strlen(temp_array1); /*;AN000;6 */ | ||
| 351 | sublist.min_width1 = sublist.max_width1; /*;AN000;6 */ | ||
| 352 | |||
| 353 | sublist.value2 = (char far *)temp_array2; /*;AN000;6 */ | ||
| 354 | sublist.flags2 = LEFT_ALIGN + CHAR_FIELD_ASCIIZ; /*;AN000;6 */ | ||
| 355 | sublist.max_width2 = (BYTE)strlen(temp_array2); /*;AN000;6 */ | ||
| 356 | sublist.min_width2 = sublist.max_width2; /*;AN000;6 */ | ||
| 357 | |||
| 358 | display_it(INSERT_SOURCE_DISK,STND_ERR_DEV,2,NO_RESPTYPE,(BYTE)UTIL_MSG); /*;AN000;6*/ | ||
| 359 | display_it(PRESS_ANY_KEY,STND_ERR_DEV,0,ANY_KEY_RESPTYPE,(BYTE)UTIL_MSG); /*;AN000;6*/ | ||
| 360 | |||
| 361 | /* If single drive system, eliminates double prompting */ | ||
| 362 | /* for user to "Insert diskette for drive %1" */ | ||
| 363 | qregs.x.ax = SETLOGICALDRIVE; /*;AN000;8*/ | ||
| 364 | qregs.h.bl = srcddir[0] - 'A' + 1; /*;AN000;8*/ | ||
| 365 | intdos(&qregs,&qregs); /*;AN000;8*/ | ||
| 366 | |||
| 367 | continue; | ||
| 368 | } | ||
| 369 | else | ||
| 370 | break; | ||
| 371 | |||
| 372 | } /*end of for loop*/ | ||
| 373 | |||
| 374 | |||
| 375 | return; | ||
| 376 | } /*;AN000;*/ | ||
diff --git a/v4.0/src/CMD/RESTORE/RTDO1.C b/v4.0/src/CMD/RESTORE/RTDO1.C new file mode 100644 index 0000000..29bc973 --- /dev/null +++ b/v4.0/src/CMD/RESTORE/RTDO1.C | |||
| @@ -0,0 +1,420 @@ | |||
| 1 | |||
| 2 | /*----------------------------- | ||
| 3 | /* SOURCE FILE NAME: RTDO1.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 "string.h" | ||
| 12 | #include "dos.h" /*;AN000;2*/ | ||
| 13 | #include "comsub.h" /* common subroutine def'n */ | ||
| 14 | #include "doscalls.h" | ||
| 15 | #include "error.h" | ||
| 16 | |||
| 17 | struct disk_header_new russ_disk_header; /* !wrw */ | ||
| 18 | unsigned control_file_handle = 0xffff; /* !wrw */ | ||
| 19 | |||
| 20 | extern BYTE control_flag2; | ||
| 21 | extern BYTE far *control_buf_pointer; | ||
| 22 | extern unsigned control_selector; | ||
| 23 | extern struct FileFindBuf filefindbuf; | ||
| 24 | extern struct internat ctry; /* data area for get country info */ | ||
| 25 | extern struct subst_list sublist; /*;AN000;6 Message substitution list */ | ||
| 26 | /***************** START OF SPECIFICATION ******************************** | ||
| 27 | /* | ||
| 28 | /* SUBROUTINE NAME : check_bkdisk_new | ||
| 29 | /* | ||
| 30 | /* DESCRIPTIVE NAME : For new format only, check to see whether the disk | ||
| 31 | /* is a backup disk, and whether the disk is in right | ||
| 32 | /* sequence. | ||
| 33 | /* | ||
| 34 | /* FUNCTION: The routine does the following: | ||
| 35 | /* 1. Find the file CONTROL.xxx. If the file is not there | ||
| 36 | /* the disk is not a backup disk. | ||
| 37 | /* 2. validate the extension of control.xxx | ||
| 38 | /* 3. Check the sequence number of the disk to make sure | ||
| 39 | /* its in sequence. | ||
| 40 | /* 4. Open the file CONTROL.xxx. | ||
| 41 | /* 5. Read the file CONTROL.xxx in. | ||
| 42 | /* 6. Fill dinfo with correct information. | ||
| 43 | /* 7. Output a message to the screen to confirm that | ||
| 44 | /* the disk is going to be restored. | ||
| 45 | /* | ||
| 46 | /* NOTES: This subroutine also take care of situation that user | ||
| 47 | /* insert a old format diskette while the RESTORE started with | ||
| 48 | /* new format diskettes. | ||
| 49 | /* | ||
| 50 | /* When the inserted disk does not contain the file CONTROL.xxx, | ||
| 51 | /* a message "source file does not contains backup files" is | ||
| 52 | /* output to the user. If the user wants to change diskette | ||
| 53 | /* and try again, next diskette will be read. | ||
| 54 | /* | ||
| 55 | /* When disk is out of sequence, a 'warning' is given to user, | ||
| 56 | /* if the user still wants to proceed the restoring by doing | ||
| 57 | /* nothing but hit a key, the same diskette will be read again. | ||
| 58 | /* In case of expanded file, another check for dnum of the expand | ||
| 59 | /* file will guarantee the disk in sequence. | ||
| 60 | /* | ||
| 61 | /* | ||
| 62 | /********************** END OF SPECIFICATIONS *******************************/ | ||
| 63 | void check_bkdisk_new(dheadnew, dinfo, srcd, dnumwant,control_bufsize) /* wrw! */ | ||
| 64 | |||
| 65 | struct disk_header_new far *dheadnew; | ||
| 66 | struct disk_info *dinfo; | ||
| 67 | BYTE srcd; | ||
| 68 | unsigned int *dnumwant; | ||
| 69 | unsigned int *control_bufsize; | ||
| 70 | { | ||
| 71 | WORD dnumok = FALSE; | ||
| 72 | WORD disknum; /*disk number carried by the file name backup.xxx*/ | ||
| 73 | BYTE fname_to_be_opened[13]; | ||
| 74 | WORD numread; | ||
| 75 | BYTE temp_array1[4]; | ||
| 76 | BYTE temp_array2[4]; | ||
| 77 | BYTE c; | ||
| 78 | WORD read_count; | ||
| 79 | WORD action; | ||
| 80 | |||
| 81 | |||
| 82 | /*declaration for dosfindfirst */ | ||
| 83 | unsigned dirhandle = 0xffff; | ||
| 84 | unsigned attribute = NOTV; | ||
| 85 | unsigned search_cnt = 1; | ||
| 86 | unsigned buf_len = sizeof(struct FileFindBuf); | ||
| 87 | BYTE search_string[MAXPATHF+2]; | ||
| 88 | WORD retcode; | ||
| 89 | /*end decleration for ffirst and fnext*/ | ||
| 90 | /*****************************/ | ||
| 91 | /*search for control.xxx */ | ||
| 92 | /*****************************/ | ||
| 93 | for (;;) | ||
| 94 | { | ||
| 95 | /*DosFindFirst, using the filename CONTROL.???*/ | ||
| 96 | search_string[0] = srcd; | ||
| 97 | search_string[1] = ':'; | ||
| 98 | search_string[2] = NULLC; | ||
| 99 | strcat(search_string, "CONTROL.???"); | ||
| 100 | dirhandle = 0xffff; | ||
| 101 | search_cnt = 1; | ||
| 102 | |||
| 103 | retcode = /* Find the 1st filename that */ | ||
| 104 | DOSFINDFIRST( /* matches specified fspec*/ | ||
| 105 | (char far *)search_string, /* File path name*/ | ||
| 106 | (unsigned far *)&dirhandle, /* Directory search handle */ | ||
| 107 | attribute, /* Search attribute */ | ||
| 108 | (struct FileFindBuf far *)&filefindbuf, | ||
| 109 | buf_len, /* Result buffer length */ | ||
| 110 | (unsigned far *)&search_cnt, /* Number of entries to find */ | ||
| 111 | (DWORD) 0 | ||
| 112 | ); | ||
| 113 | |||
| 114 | if (retcode != NOERROR) | ||
| 115 | { display_it(SOURCE_NO_BACKUP_FILE,STND_ERR_DEV,0,NO_RESPTYPE,(BYTE)UTIL_MSG);/*;AN000;6*/ | ||
| 116 | usererror(NOBACKUPFILE); | ||
| 117 | } | ||
| 118 | else | ||
| 119 | { | ||
| 120 | /*if the directory found is a subdirectory, find next one*/ | ||
| 121 | while((retcode = filefindbuf.attributes & SUBDIR) == SUBDIR) | ||
| 122 | { | ||
| 123 | search_cnt = 1; | ||
| 124 | retcode = DOSFINDNEXT(dirhandle, | ||
| 125 | (struct FileFindBuf far *)&filefindbuf, | ||
| 126 | buf_len, | ||
| 127 | (unsigned far *)&search_cnt); | ||
| 128 | if (retcode != 0) | ||
| 129 | { display_it(SOURCE_NO_BACKUP_FILE,STND_ERR_DEV,0,NO_RESPTYPE,(BYTE)UTIL_MSG);/*;AN000;6*/ | ||
| 130 | usererror(NOBACKUPFILE); | ||
| 131 | } | ||
| 132 | } /*end while */ | ||
| 133 | } /*end of file control.xxx not found*/ | ||
| 134 | |||
| 135 | retcode = DOSFINDCLOSE(dirhandle); | ||
| 136 | |||
| 137 | /********************************************************************/ | ||
| 138 | /* validate the file extension of control.xxx to make sure they are */ | ||
| 139 | /* three numeric characters */ | ||
| 140 | /********************************************************************/ | ||
| 141 | if ((filefindbuf.file_name[7] != '.') || (filefindbuf.file_name[8] < '0') || | ||
| 142 | (filefindbuf.file_name[8] > '9') || (filefindbuf.file_name[9] < '0') || | ||
| 143 | (filefindbuf.file_name[9] > '9') || (filefindbuf.file_name[10] < '0') || | ||
| 144 | (filefindbuf.file_name[10] > '9') || (filefindbuf.file_name[11] != NULLC) ) | ||
| 145 | { display_it(SOURCE_NO_BACKUP_FILE,STND_ERR_DEV,0,NO_RESPTYPE,(BYTE)UTIL_MSG);/*;AN000;6*/ | ||
| 146 | usererror(NOBACKUPFILE); | ||
| 147 | } | ||
| 148 | |||
| 149 | /********************************************************************/ | ||
| 150 | /* check the disk sequence number of the disk */ | ||
| 151 | /********************************************************************/ | ||
| 152 | if (dnumok == TRUE) | ||
| 153 | { | ||
| 154 | if (disknum != *dnumwant) | ||
| 155 | set_reset_test_flag(&control_flag2,OUTOF_SEQ,SET); | ||
| 156 | dnumok = FALSE; | ||
| 157 | } | ||
| 158 | else | ||
| 159 | { | ||
| 160 | disknum = (filefindbuf.file_name[8]-'0')*100 + | ||
| 161 | (filefindbuf.file_name[9]-'0')*10 | ||
| 162 | +filefindbuf.file_name[10]-'0'; | ||
| 163 | if (disknum != *dnumwant) | ||
| 164 | { | ||
| 165 | display_it(DISK_OUT_OF_SEQUENCE,STND_ERR_DEV,0,NO_RESPTYPE,(BYTE)UTIL_MSG);/*;AN000;6*/ | ||
| 166 | display_it(PRESS_ANY_KEY,STND_ERR_DEV,0,ANY_KEY_RESPTYPE,(BYTE)UTIL_MSG); /*;AN000;6*/ | ||
| 167 | |||
| 168 | /* When disk is out of sequence, a 'warning' is given to user. */ | ||
| 169 | /* If the user still wants to proceed the restoring by doing */ | ||
| 170 | /* nothing but hit a key, the same diskette will be read again.*/ | ||
| 171 | dnumok = TRUE; | ||
| 172 | |||
| 173 | continue; | ||
| 174 | } /*endif*/ | ||
| 175 | } /*endif of dnumok = FALSE*/ | ||
| 176 | |||
| 177 | /********************************************************************/ | ||
| 178 | /* open control.xxx */ | ||
| 179 | /********************************************************************/ | ||
| 180 | fname_to_be_opened[0] = srcd; | ||
| 181 | fname_to_be_opened[1] = ':'; | ||
| 182 | fname_to_be_opened[2] = NULLC; | ||
| 183 | strcat(fname_to_be_opened,filefindbuf.file_name); | ||
| 184 | |||
| 185 | retcode = | ||
| 186 | DOSOPEN | ||
| 187 | ( (char far *)&fname_to_be_opened[0], | ||
| 188 | (unsigned far *)&control_file_handle, /* !wrw */ | ||
| 189 | (unsigned far *)&action, | ||
| 190 | (DWORD)0, | ||
| 191 | 0, | ||
| 192 | 0x01, | ||
| 193 | 0x00c0, | ||
| 194 | (DWORD)0 | ||
| 195 | ); | ||
| 196 | |||
| 197 | if (retcode != NOERROR) | ||
| 198 | { display_it(SOURCE_NO_BACKUP_FILE,STND_ERR_DEV,0,NO_RESPTYPE,(BYTE)UTIL_MSG);/*;AN000;6*/ | ||
| 199 | usererror(NOBACKUPFILE); | ||
| 200 | } | ||
| 201 | |||
| 202 | /********************************************************************/ | ||
| 203 | /* READ DISK_HEADER INTO STATIC DISKHEADER STRUCTURE wrw */ | ||
| 204 | /********************************************************************/ | ||
| 205 | |||
| 206 | retcode = | ||
| 207 | DOSREAD | ||
| 208 | ( /* !wrw */ | ||
| 209 | control_file_handle, /* !wrw */ | ||
| 210 | (char far *)&russ_disk_header, /* !wrw */ | ||
| 211 | (unsigned short)DHEADLEN, /* !wrw */ | ||
| 212 | (unsigned far *)&read_count /* !wrw */ | ||
| 213 | ); /* !wrw */ | ||
| 214 | |||
| 215 | if (retcode != NOERROR || (DWORD)read_count != (DWORD)DHEADLEN) /* !wrw */ | ||
| 216 | { display_it(SOURCE_NO_BACKUP_FILE,STND_ERR_DEV,0,NO_RESPTYPE,(BYTE)UTIL_MSG);/*;AN000;6*/ | ||
| 217 | unexperror(NOBACKUPFILE); | ||
| 218 | } | ||
| 219 | |||
| 220 | /********************************************************************/ | ||
| 221 | /* get and store dheadnew information into dinfo */ | ||
| 222 | /********************************************************************/ | ||
| 223 | dheadnew = (struct disk_header_new far *)&russ_disk_header; /* !wrw */ | ||
| 224 | |||
| 225 | dinfo->disknum = dheadnew->sequence; | ||
| 226 | dinfo->dflag = dheadnew->lastdisk; | ||
| 227 | |||
| 228 | /* At this point, the diskette has passed all the checking, and */ | ||
| 229 | /* should be a ok diskette. break out of the loop.*/ | ||
| 230 | break; | ||
| 231 | |||
| 232 | } /*end of "for (;;)" loop */ | ||
| 233 | |||
| 234 | /********************************************************************/ | ||
| 235 | /* output confirm msg "restore file from drive d:" */ | ||
| 236 | /********************************************************************/ | ||
| 237 | temp_array1[0] = srcd; | ||
| 238 | temp_array1[1] = NULLC; | ||
| 239 | |||
| 240 | sublist.value1 = (char far *)temp_array1; /*;AN000;6 */ | ||
| 241 | sublist.flags1 = LEFT_ALIGN + CHAR_FIELD_ASCIIZ; /*;AN000;6 */ | ||
| 242 | sublist.max_width1 = (BYTE)strlen(temp_array1); /*;AN000;6 */ | ||
| 243 | sublist.min_width1 = sublist.max_width1; /*;AN000;6 */ | ||
| 244 | |||
| 245 | display_it(RESTORE_FILE_FROM_DRIVE,STND_OUT_DEV,1,NO_RESPTYPE,(BYTE)UTIL_MSG);/*;AN000;6*/ | ||
| 246 | |||
| 247 | /********************************************************************/ | ||
| 248 | /* if the source disk is removable, output diskette number also */ | ||
| 249 | /********************************************************************/ | ||
| 250 | if (set_reset_test_flag(&control_flag2,SRC_HDISK,TEST) == FALSE) | ||
| 251 | { | ||
| 252 | temp_array2[0] = (dinfo->disknum / 10) + '0'; | ||
| 253 | temp_array2[1] = (dinfo->disknum % 10) + '0'; | ||
| 254 | temp_array2[2] = NULLC; | ||
| 255 | |||
| 256 | sublist.value1 = (char far *)temp_array2; /*;AN000;6*/ | ||
| 257 | sublist.flags1 = LEFT_ALIGN + CHAR_FIELD_ASCIIZ; /*;AN000;6*/ | ||
| 258 | sublist.max_width1 = (BYTE)strlen(temp_array2); /*;AN000;6*/ | ||
| 259 | sublist.min_width1 = sublist.max_width1; /*;AN000;6*/ | ||
| 260 | |||
| 261 | display_it(DISKETTE_NUM,STND_OUT_DEV,1,NO_RESPTYPE,(BYTE)UTIL_MSG);/*;AN000;6*/ | ||
| 262 | } | ||
| 263 | |||
| 264 | *dnumwant = dinfo->disknum + 1; | ||
| 265 | |||
| 266 | return; /*;AN000;*/ | ||
| 267 | } /*end of subroutine */ | ||
| 268 | |||
| 269 | /***************** START OF SPECIFICATION ******************************** | ||
| 270 | /* | ||
| 271 | /* SUBROUTINE NAME : check_bkdisk_old | ||
| 272 | /* | ||
| 273 | /* DESCRIPTIVE NAME : For old format only, check to see whether the disk | ||
| 274 | /* is a backup disk, and whether the disk is in right | ||
| 275 | /* sequence. | ||
| 276 | /* | ||
| 277 | /* FUNCTION: The routine does the following: | ||
| 278 | /* 1. Open the file BACKUPID.@@@. If the file is not there, | ||
| 279 | /* the disk is not a backup disk. | ||
| 280 | /* 3. Check the sequence number of the disk to make sure | ||
| 281 | /* its in sequence. | ||
| 282 | /* 4. Fill dinfo with correct information. | ||
| 283 | /* 5. Output a message to the screen to confirm that | ||
| 284 | /* the disk is going to be restored. | ||
| 285 | /* | ||
| 286 | /* NOTES: This subroutine also take care of situation that user | ||
| 287 | /* insert a new format diskette while the RESTORE started with | ||
| 288 | /* old format diskettes. | ||
| 289 | /* | ||
| 290 | /* When the inserted disk does not contain the file BACKUP.@@@, | ||
| 291 | /* a message "source file does not contains backup files" is | ||
| 292 | /* output to the user. If the user wants to change diskette | ||
| 293 | /* and try again, next diskette will be read. | ||
| 294 | /* | ||
| 295 | /* When disk is out of sequence, a 'warning' is given to user, | ||
| 296 | /* if the user still wants to proceed the restoring by doing | ||
| 297 | /* nothing but hit a key, the same diskette will be read again. | ||
| 298 | /* In case of expanded file, another check for dnum of the expand | ||
| 299 | /* file will guarantee the disk in sequence. | ||
| 300 | /* | ||
| 301 | /* | ||
| 302 | /********************** END OF SPECIFICATIONS *******************************/ | ||
| 303 | void check_bkdisk_old(dheadold, dinfo, srcd, dnumwant) /* wrw! */ | ||
| 304 | struct disk_header_old *dheadold; | ||
| 305 | struct disk_info *dinfo; | ||
| 306 | BYTE srcd; | ||
| 307 | unsigned int *dnumwant; | ||
| 308 | { | ||
| 309 | WORD retcode; | ||
| 310 | WORD action; | ||
| 311 | |||
| 312 | int dnumok = FALSE; | ||
| 313 | unsigned file_pointer; | ||
| 314 | char fname_to_be_opened[13]; | ||
| 315 | int numread; | ||
| 316 | int dyear; | ||
| 317 | int dmonth; | ||
| 318 | int dday; | ||
| 319 | char temp_array1[4]; | ||
| 320 | char temp_array2[4]; | ||
| 321 | BYTE c; | ||
| 322 | |||
| 323 | /********************************************************************/ | ||
| 324 | /* open and read backupid.@@@. Store information in backupid.@@@ */ | ||
| 325 | /* into dinfo */ | ||
| 326 | /********************************************************************/ | ||
| 327 | |||
| 328 | for (;;) | ||
| 329 | { | ||
| 330 | fname_to_be_opened[0] = srcd; | ||
| 331 | fname_to_be_opened[1] = ':'; | ||
| 332 | fname_to_be_opened[2] = NULLC; | ||
| 333 | strcat(fname_to_be_opened,BACKUPID); | ||
| 334 | retcode = | ||
| 335 | DOSOPEN( | ||
| 336 | (char far *)&fname_to_be_opened[0],(unsigned far *)&file_pointer, | ||
| 337 | (unsigned far *)&action,(DWORD)0,0,0x01,0x00c0,(DWORD)0 | ||
| 338 | ); | ||
| 339 | |||
| 340 | if (retcode != NOERROR) | ||
| 341 | { display_it(SOURCE_NO_BACKUP_FILE,STND_ERR_DEV,0,NO_RESPTYPE,(BYTE)UTIL_MSG);/*;AN000;6*/ | ||
| 342 | usererror(NOBACKUPFILE); | ||
| 343 | } | ||
| 344 | |||
| 345 | /*read BKIDLENG (7) bytes from the file and store into dheadold*/ | ||
| 346 | retcode = DOSREAD( file_pointer, | ||
| 347 | (char far *)dheadold, | ||
| 348 | BKIDLENG, | ||
| 349 | (unsigned far *)&numread); | ||
| 350 | /*if return code of read indicate less than 11 bytes been read*/ | ||
| 351 | if (retcode != 0 || numread < BKIDLENG) { | ||
| 352 | /*unexperror "source file does not contains backup files"*/ | ||
| 353 | display_it(SOURCE_NO_BACKUP_FILE,STND_ERR_DEV,0,NO_RESPTYPE,(BYTE)UTIL_MSG);/*;AN000;6*/ | ||
| 354 | unexperror(NOBACKUPFILE); | ||
| 355 | } /*endif */ | ||
| 356 | dinfo->disknum = dheadold->disknum[0] + dheadold->disknum[1] * 10; | ||
| 357 | dyear = dheadold->diskyear[0] + dheadold->diskyear[1]*256; | ||
| 358 | dinfo->dflag = dheadold->diskflag; | ||
| 359 | |||
| 360 | /*close the file*/ | ||
| 361 | DOSCLOSE(file_pointer); | ||
| 362 | |||
| 363 | /********************************************************************/ | ||
| 364 | /* check disk sequence number */ | ||
| 365 | /********************************************************************/ | ||
| 366 | if (dnumok == TRUE) { | ||
| 367 | if ((WORD)dinfo->disknum != *dnumwant) { | ||
| 368 | set_reset_test_flag(&control_flag2,OUTOF_SEQ,SET); | ||
| 369 | } | ||
| 370 | dnumok = FALSE; | ||
| 371 | } | ||
| 372 | else { | ||
| 373 | if ((WORD)dinfo->disknum != *dnumwant) { | ||
| 374 | /*When disk is out of sequence, a 'warning' is given to user, | ||
| 375 | if the user still wants to proceed the restoring by doing | ||
| 376 | nothing but hit a key, the same diskette will be read again.*/ | ||
| 377 | display_it(DISK_OUT_OF_SEQUENCE,STND_ERR_DEV,0,NO_RESPTYPE,(BYTE)UTIL_MSG); /*;AN000;6*/ | ||
| 378 | display_it(PRESS_ANY_KEY,STND_ERR_DEV,0,ANY_KEY_RESPTYPE,(BYTE)UTIL_MSG); /*;AN000;6*/ | ||
| 379 | dnumok = TRUE; | ||
| 380 | continue; | ||
| 381 | } /*endif*/ | ||
| 382 | } /*endif*/ | ||
| 383 | |||
| 384 | /*at this point, the diskette has passed all the checking, and | ||
| 385 | should be a ok diskette. break out of the loop.*/ | ||
| 386 | break; | ||
| 387 | } /*end of loop*/ | ||
| 388 | |||
| 389 | /********************************************************************/ | ||
| 390 | /* output a confirm msg "restoring files from drive d:" */ | ||
| 391 | /********************************************************************/ | ||
| 392 | temp_array1[0] = srcd; | ||
| 393 | temp_array1[1] = NULLC; | ||
| 394 | sublist.value1 = (char far *)temp_array1; /*;AN000;6 */ | ||
| 395 | sublist.flags1 = LEFT_ALIGN + CHAR_FIELD_ASCIIZ; /*;AN000;6 */ | ||
| 396 | sublist.max_width1 = (BYTE)strlen(temp_array1); /*;AN000;6 */ | ||
| 397 | sublist.min_width1 = sublist.max_width1; /*;AN000;6 */ | ||
| 398 | display_it(RESTORE_FILE_FROM_DRIVE,STND_OUT_DEV,1,NO_RESPTYPE,(BYTE)UTIL_MSG); /*;AN000;6*/ | ||
| 399 | |||
| 400 | /********************************************************************/ | ||
| 401 | /* if the source disk is removable, output msg "diskette xx" */ | ||
| 402 | /********************************************************************/ | ||
| 403 | if (set_reset_test_flag(&control_flag2,SRC_HDISK,TEST) == FALSE) | ||
| 404 | { | ||
| 405 | temp_array2[0] = (dinfo->disknum / 10) + '0'; | ||
| 406 | temp_array2[1] = (dinfo->disknum % 10) + '0'; | ||
| 407 | temp_array2[2] = NULLC; | ||
| 408 | |||
| 409 | sublist.value1 = (char far *)temp_array2; /*;AN000;6 */ | ||
| 410 | sublist.flags1 = LEFT_ALIGN + CHAR_FIELD_ASCIIZ; /*;AN000;6 */ | ||
| 411 | sublist.max_width1 = (BYTE)strlen(temp_array2); /*;AN000;6 */ | ||
| 412 | sublist.min_width1 = sublist.max_width1; /*;AN000;6 */ | ||
| 413 | display_it(DISKETTE_NUM,STND_OUT_DEV,1,NO_RESPTYPE,(BYTE)UTIL_MSG); /*;AN000;6*/ | ||
| 414 | } | ||
| 415 | |||
| 416 | *dnumwant = dinfo->disknum + 1; | ||
| 417 | return; /*;AN000;*/ | ||
| 418 | } /*end of subroutine */ | ||
| 419 | |||
| 420 | \ No newline at end of file | ||
diff --git a/v4.0/src/CMD/RESTORE/RTFILE.C b/v4.0/src/CMD/RESTORE/RTFILE.C new file mode 100644 index 0000000..d853f52 --- /dev/null +++ b/v4.0/src/CMD/RESTORE/RTFILE.C | |||
| @@ -0,0 +1,598 @@ | |||
| 1 | |||
| 2 | /*---------------------------- | ||
| 3 | /* SOURCE FILE NAME: rtfile.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 "string.h" | ||
| 12 | #include "stdio.h" | ||
| 13 | #include "dos.h" /*;AN000;2*/ | ||
| 14 | #include "comsub.h" /* common subroutine def'n */ | ||
| 15 | #include "doscalls.h" | ||
| 16 | #include "error.h" | ||
| 17 | |||
| 18 | extern BYTE rtswitch; | ||
| 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; | ||
| 26 | |||
| 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 */ | ||
| 34 | |||
| 35 | /***************** START OF SPECIFICATION *********************************/ | ||
| 36 | /* */ | ||
| 37 | /* SUBROUTINE NAME : restore_a_file */ | ||
| 38 | /* */ | ||
| 39 | /* DESCRIPTIVE NAME : restore a file found onto the destination disk. */ | ||
| 40 | /* */ | ||
| 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 */ | ||
| 43 | /* the path. */ | ||
| 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. */ | ||
| 53 | /* */ | ||
| 54 | /********************** END OF SPECIFICATIONS *******************************/ | ||
| 55 | |||
| 56 | void restore_a_file(finfo,dinfo,bufsize,control_bufsize, /* wrw! */ | ||
| 57 | fheadnew,dheadold,dheadnew, | ||
| 58 | srcd,destd,inpath,infname,infspec,dnumwant,dirhandle) | ||
| 59 | |||
| 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; | ||
| 67 | BYTE srcd; | ||
| 68 | BYTE destd; | ||
| 69 | unsigned char *inpath; | ||
| 70 | unsigned char *infname; | ||
| 71 | unsigned char *infspec; | ||
| 72 | unsigned int *dnumwant; | ||
| 73 | unsigned int *dirhandle; | ||
| 74 | { | ||
| 75 | BYTE c; | ||
| 76 | BYTE temp_array1[4]; | ||
| 77 | BYTE temp_array2[4]; | ||
| 78 | BYTE temp_fname[MAXFSPEC]; | ||
| 79 | WORD action; | ||
| 80 | WORD first_time=TRUE; | ||
| 81 | |||
| 82 | /*declaration for dosfindfirst */ | ||
| 83 | WORD temp_dirhandle; | ||
| 84 | WORD next_dirhandle; | ||
| 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*/ | ||
| 90 | |||
| 91 | BYTE outstring[MAXPATHF+2]; | ||
| 92 | WORD retcode; | ||
| 93 | DWORD iterate_num; | ||
| 94 | DWORD i; /* wrw! */ | ||
| 95 | WORD numread; | ||
| 96 | WORD numwrite; | ||
| 97 | DWORD int remainder; | ||
| 98 | DWORD part_size; | ||
| 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]; | ||
| 103 | WORD found = FALSE; | ||
| 104 | WORD *dirptr; | ||
| 105 | WORD *flptr; | ||
| 106 | WORD read_count; | ||
| 107 | DWORD newptr; | ||
| 108 | WORD next_file_pointer; | ||
| 109 | unsigned int dnum; | ||
| 110 | DWORD temp_offset; | ||
| 111 | |||
| 112 | BYTE my_own_dirpath[MAXPATH]; | ||
| 113 | int x; /*;AN000;8*/ | ||
| 114 | union REGS qregs; /*;AN000;8*/ | ||
| 115 | |||
| 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); | ||
| 121 | |||
| 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 | /*********************************************************************/ | ||
| 127 | /*open_dest_file*/ | ||
| 128 | retcode=open_dest_file(finfo,destd); | ||
| 129 | |||
| 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*/ | ||
| 133 | else | ||
| 134 | { | ||
| 135 | /*setflag PARTIAL*/ | ||
| 136 | set_reset_test_flag(&control_flag,PARTIAL,SET); | ||
| 137 | |||
| 138 | /*********************************************************************/ | ||
| 139 | /* This loop will be processed once for each part of the source file */ | ||
| 140 | /*********************************************************************/ | ||
| 141 | for ( ; ; ) | ||
| 142 | { | ||
| 143 | |||
| 144 | /*********************************************************************/ | ||
| 145 | /* compare source file size and buf size to determine the */ | ||
| 146 | /* iteration of reading and writing */ | ||
| 147 | /*********************************************************************/ | ||
| 148 | part_size = finfo->partsize; | ||
| 149 | /*if old*/ | ||
| 150 | if (set_reset_test_flag(&control_flag,OLDNEW,TEST)==TRUE) | ||
| 151 | part_size = part_size - HEADLEN; | ||
| 152 | |||
| 153 | iterate_num = part_size / bufsize; | ||
| 154 | /*if remain of of filesize/bufsize != 0, add 1 to iterate_num*/ | ||
| 155 | remainder = part_size % bufsize; | ||
| 156 | if (remainder > 0) | ||
| 157 | ++iterate_num; | ||
| 158 | |||
| 159 | /*********************************************************************/ | ||
| 160 | /*loop through each of the iteration */ | ||
| 161 | /*********************************************************************/ | ||
| 162 | for (i = 1; i <= iterate_num; ++i) | ||
| 163 | { | ||
| 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) | ||
| 169 | { | ||
| 170 | retcode = DOSREAD( src_file_handle, | ||
| 171 | (char far *)&buf_pointer[0], | ||
| 172 | (unsigned)bufsize, | ||
| 173 | (unsigned far *)&numread); | ||
| 174 | |||
| 175 | if (retcode != 0) | ||
| 176 | { | ||
| 177 | com_msg(retcode); | ||
| 178 | unexperror(retcode); | ||
| 179 | } | ||
| 180 | } | ||
| 181 | else | ||
| 182 | { /*new format*/ | ||
| 183 | /***************************************************************/ | ||
| 184 | /* if new format, search backup.xxx for the file to be restored*/ | ||
| 185 | /* and read it. */ | ||
| 186 | /***************************************************************/ | ||
| 187 | temp_offset = finfo->offset + bufsize * (i - 1); | ||
| 188 | retcode = | ||
| 189 | DOSCHGFILEPTR | ||
| 190 | (src_file_handle, | ||
| 191 | (DWORD) temp_offset, | ||
| 192 | (unsigned) 0, | ||
| 193 | (DWORD far *) &newptr | ||
| 194 | ); | ||
| 195 | |||
| 196 | if (i == iterate_num) | ||
| 197 | { | ||
| 198 | part_size = part_size - bufsize * (iterate_num -1); | ||
| 199 | retcode = | ||
| 200 | DOSREAD | ||
| 201 | ( src_file_handle, | ||
| 202 | (char far *)&buf_pointer[0], | ||
| 203 | (unsigned)part_size, | ||
| 204 | (unsigned far *)&numread | ||
| 205 | ); | ||
| 206 | } | ||
| 207 | else | ||
| 208 | { | ||
| 209 | retcode = | ||
| 210 | DOSREAD | ||
| 211 | (src_file_handle, | ||
| 212 | (char far *)&buf_pointer[0], | ||
| 213 | (unsigned)bufsize, | ||
| 214 | (unsigned far *)&numread | ||
| 215 | ); | ||
| 216 | |||
| 217 | } /*end of i == iterate_num */ | ||
| 218 | } /*end of new format */ | ||
| 219 | |||
| 220 | /*************************************************************/ | ||
| 221 | /* write to dest file */ | ||
| 222 | /*************************************************************/ | ||
| 223 | retcode = | ||
| 224 | DOSWRITE | ||
| 225 | (dest_file_handle, | ||
| 226 | (char far *)&buf_pointer[0], | ||
| 227 | (unsigned) numread, | ||
| 228 | (unsigned far *) &numwrite | ||
| 229 | ); | ||
| 230 | |||
| 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); | ||
| 237 | } | ||
| 238 | /*end iteration loop*/ | ||
| 239 | |||
| 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); | ||
| 247 | |||
| 248 | |||
| 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 */ | ||
| 255 | |||
| 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); | ||
| 264 | |||
| 265 | if (first_time == TRUE) | ||
| 266 | { temp_dirhandle = *dirhandle; | ||
| 267 | first_time = FALSE; | ||
| 268 | retcode = DOSFINDCLOSE(temp_dirhandle); | ||
| 269 | } | ||
| 270 | } | ||
| 271 | else | ||
| 272 | { | ||
| 273 | DOSCLOSE(src_file_handle); | ||
| 274 | DOSCLOSE(control_file_handle); /* !wrw */ | ||
| 275 | control_file_handle = 0xffff; /* !wrw */ | ||
| 276 | } | ||
| 277 | |||
| 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 | /*****************************************************************/ | ||
| 283 | |||
| 284 | if (control_file_handle != 0xffff) /* !wrw */ | ||
| 285 | { /* !wrw */ | ||
| 286 | DOSCLOSE(control_file_handle); /* !wrw */ | ||
| 287 | control_file_handle = 0xffff; /* !wrw */ | ||
| 288 | } /* !wrw */ | ||
| 289 | |||
| 290 | printf("\n"); | ||
| 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; | ||
| 296 | |||
| 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 */ | ||
| 301 | |||
| 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 */ | ||
| 306 | |||
| 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*/ | ||
| 309 | |||
| 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*/ | ||
| 315 | |||
| 316 | /**************************************************/ | ||
| 317 | /**************************************************/ | ||
| 318 | if (set_reset_test_flag(&control_flag,OLDNEW,TEST) == TRUE) | ||
| 319 | check_bkdisk_old(dheadold,dinfo,srcd,dnumwant); | ||
| 320 | else | ||
| 321 | check_bkdisk_new(dheadnew,dinfo,srcd,dnumwant,control_bufsize); | ||
| 322 | |||
| 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.*/ | ||
| 326 | |||
| 327 | /*****************************************************************/ | ||
| 328 | /*increament file sequence number */ | ||
| 329 | /*****************************************************************/ | ||
| 330 | file_seq_num = file_seq_num + 1; | ||
| 331 | |||
| 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 | { /**************************************************************/ | ||
| 337 | /* if old format, */ | ||
| 338 | /*DosFindFirst:find the first file on the diskette (non-vol id*/ | ||
| 339 | /*entry) */ | ||
| 340 | /**************************************************************/ | ||
| 341 | search_string[0] = srcd; | ||
| 342 | search_string[1] = ':'; | ||
| 343 | search_string[2] = NULLC; | ||
| 344 | strcat(search_string, src_fname); | ||
| 345 | |||
| 346 | next_dirhandle = 0xffff; /* directory handle */ | ||
| 347 | |||
| 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*/ | ||
| 356 | (DWORD) 0 | ||
| 357 | ); | ||
| 358 | |||
| 359 | if (retcode != 0) | ||
| 360 | { | ||
| 361 | display_it(NOT_ABLE_TO_RESTORE_FILE,STND_ERR_DEV,0,NO_RESPTYPE,(BYTE)UTIL_MSG); /*;AN000;6*/ | ||
| 362 | unexperror(retcode); | ||
| 363 | } | ||
| 364 | |||
| 365 | |||
| 366 | /*if the directory found is a subdirectory, find next one*/ | ||
| 367 | while((retcode = filefindbuf.attributes & SUBDIR) == SUBDIR) | ||
| 368 | { | ||
| 369 | search_cnt = 1; | ||
| 370 | retcode = DOSFINDNEXT(next_dirhandle, | ||
| 371 | (struct FileFindBuf far *)&filefindbuf, | ||
| 372 | buf_len, | ||
| 373 | (unsigned far *)&search_cnt); | ||
| 374 | |||
| 375 | if (retcode != 0) | ||
| 376 | { | ||
| 377 | display_it(NOT_ABLE_TO_RESTORE_FILE,STND_ERR_DEV,0,NO_RESPTYPE,(BYTE)UTIL_MSG); /*;AN000;6*/ | ||
| 378 | unexperror(retcode); | ||
| 379 | } | ||
| 380 | |||
| 381 | } /*end while */ | ||
| 382 | |||
| 383 | retcode = DOSFINDCLOSE(next_dirhandle); | ||
| 384 | |||
| 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); | ||
| 390 | retcode = | ||
| 391 | check_flheader_old | ||
| 392 | ( finfo, temp_fname, | ||
| 393 | filefindbuf.write_date, filefindbuf.write_time, | ||
| 394 | filefindbuf.attributes, filefindbuf.file_size, | ||
| 395 | file_seq_num, srcd, destd, infspec, inpath, dnumwant | ||
| 396 | ); | ||
| 397 | |||
| 398 | if (retcode != 0) | ||
| 399 | { | ||
| 400 | display_it(NOT_ABLE_TO_RESTORE_FILE,STND_ERR_DEV,0,NO_RESPTYPE,(BYTE)UTIL_MSG); /*;AN000;6*/ | ||
| 401 | unexperror(retcode); | ||
| 402 | } | ||
| 403 | |||
| 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); | ||
| 410 | } | ||
| 411 | |||
| 412 | } | ||
| 413 | else | ||
| 414 | { /*new format*/ | ||
| 415 | /**********************************************/ | ||
| 416 | /* Find the file on the CONTROL.xxx first */ | ||
| 417 | /**********************************************/ | ||
| 418 | |||
| 419 | /* findfirst_new on the new diskette using the filename.??? */ | ||
| 420 | retcode = | ||
| 421 | findfirst_new | ||
| 422 | ( finfo, &found, &done_searching, | ||
| 423 | finfo->path, finfo->fname, (WORD far **) &dirptr, /* wrw! */ | ||
| 424 | (WORD far **) &flptr, &numentry, my_own_dirpath | ||
| 425 | ); /* wrw! */ | ||
| 426 | |||
| 427 | while (retcode != 0 ) | ||
| 428 | { | ||
| 429 | display_it(NOT_ABLE_TO_RESTORE_FILE,STND_ERR_DEV,0,NO_RESPTYPE,(BYTE)UTIL_MSG); /*;AN000;6*/ | ||
| 430 | unexperror(CREATIONERROR); | ||
| 431 | } | ||
| 432 | |||
| 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); | ||
| 436 | } | ||
| 437 | |||
| 438 | /**************************************************************/ | ||
| 439 | /* open file backup.xxx */ | ||
| 440 | /**************************************************************/ | ||
| 441 | /*the current disk is one less than the disk num wanted*/ | ||
| 442 | dnum = *dnumwant -1; | ||
| 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'); | ||
| 449 | dnum = dnum % 100; | ||
| 450 | file_tobe_opened[10] = (char)((dnum / 10) + '0'); | ||
| 451 | dnum = dnum % 10; | ||
| 452 | file_tobe_opened[11] = (char)(dnum + '0'); | ||
| 453 | file_tobe_opened[12] = NULLC; | ||
| 454 | |||
| 455 | retcode = | ||
| 456 | DOSOPEN | ||
| 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*/ | ||
| 465 | (DWORD)0 | ||
| 466 | ); /*reserved*/ | ||
| 467 | |||
| 468 | if (retcode != 0) | ||
| 469 | { display_it(NOT_ABLE_TO_RESTORE_FILE,STND_ERR_DEV,0,NO_RESPTYPE,(BYTE)UTIL_MSG); /*;AN000;6*/ | ||
| 470 | unexperror(retcode); | ||
| 471 | } | ||
| 472 | |||
| 473 | } | ||
| 474 | /*end of if new format*/ | ||
| 475 | |||
| 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*/ | ||
| 479 | |||
| 480 | /*set flag to be SPLITFILE*/ | ||
| 481 | set_reset_test_flag(&control_flag,SPLITFILE,SET); | ||
| 482 | |||
| 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,"\\"); | ||
| 490 | |||
| 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*/ | ||
| 501 | |||
| 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*/ | ||
| 505 | |||
| 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); | ||
| 511 | |||
| 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) | ||
| 517 | { | ||
| 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, ".*"); | ||
| 526 | |||
| 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 */ | ||
| 536 | ( DWORD) 0 | ||
| 537 | ); | ||
| 538 | |||
| 539 | /*if not found return*/ | ||
| 540 | if (retcode != 0) | ||
| 541 | temp_dirhandle = 0xffff; | ||
| 542 | else | ||
| 543 | { | ||
| 544 | |||
| 545 | /*if the directory found is a subdirectory, find next one*/ | ||
| 546 | while((retcode = filefindbuf.attributes & SUBDIR) == SUBDIR) | ||
| 547 | { | ||
| 548 | search_cnt = 1; | ||
| 549 | retcode = DOSFINDNEXT(temp_dirhandle, | ||
| 550 | (struct FileFindBuf far *)&filefindbuf, | ||
| 551 | buf_len, | ||
| 552 | (unsigned far *)&search_cnt); | ||
| 553 | if (retcode != 0) | ||
| 554 | temp_dirhandle = 0xffff; | ||
| 555 | } /*end while */ | ||
| 556 | |||
| 557 | if(strcmp(filefindbuf.file_name,BACKUPID)==0 || | ||
| 558 | strcmp(filefindbuf.file_name,src_fname)==0 ) | ||
| 559 | { | ||
| 560 | retcode =DOSFINDNEXT(temp_dirhandle, | ||
| 561 | (struct FileFindBuf far *)&filefindbuf, | ||
| 562 | buf_len, | ||
| 563 | (unsigned far *)&search_cnt); | ||
| 564 | |||
| 565 | if (retcode != 0) | ||
| 566 | temp_dirhandle = 0xffff; | ||
| 567 | |||
| 568 | else | ||
| 569 | { | ||
| 570 | if(strcmp(filefindbuf.file_name,BACKUPID)==0 || | ||
| 571 | strcmp(filefindbuf.file_name,src_fname)==0 ) | ||
| 572 | { | ||
| 573 | retcode =DOSFINDNEXT(temp_dirhandle, | ||
| 574 | (struct FileFindBuf far *)&filefindbuf, | ||
| 575 | buf_len, | ||
| 576 | (unsigned far *)&search_cnt); | ||
| 577 | |||
| 578 | if (retcode != 0) | ||
| 579 | temp_dirhandle = 0xffff; | ||
| 580 | } | ||
| 581 | |||
| 582 | } /*end of the rc is 0 */ | ||
| 583 | } /*end of if strcomp is sucessful*/ | ||
| 584 | |||
| 585 | } | ||
| 586 | *dirhandle = temp_dirhandle; | ||
| 587 | |||
| 588 | } /*end of if the file was splitted */ | ||
| 589 | |||
| 590 | |||
| 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 */ | ||
| 596 | |||
| 597 | } /*end of restore_a_file subroutine*/ | ||
| 598 | \ No newline at end of file | ||
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 | |||
| 18 | char ext_attrib_buff[4086]; /*;AN000;3*/ | ||
| 19 | |||
| 20 | extern BYTE rtswitch; | ||
| 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; | ||
| 28 | |||
| 29 | extern 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 ******************************/ | ||
| 48 | WORD open_dest_file(finfo,destd) | ||
| 49 | struct file_info *finfo; | ||
| 50 | BYTE 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 ********************************/ | ||
| 132 | void build_path_create_file(in_path,destd,fflag,ea_offset) | ||
| 133 | BYTE *in_path; | ||
| 134 | BYTE destd; | ||
| 135 | BYTE fflag; /*;AN000;3*/ | ||
| 136 | DWORD 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*/ | ||
| 208 | WORD create_the_file(fflag,ea_offset) /*;AN000;3*/ | ||
| 209 | BYTE fflag; /*;AN000;3*/ | ||
| 210 | DWORD 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(®,®); /*;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 | /********************************************************/ | ||
| 252 | void read_the_extended_attributes(ea_offset) /*;AN000;3*/ | ||
| 253 | DWORD 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 ********************************/ | ||
| 305 | int set_attributes_and_close(finfo,destd) | ||
| 306 | struct file_info *finfo; | ||
| 307 | BYTE 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 | |||
| 372 | return(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 *******************************/ | ||
| 391 | int dos_write_error(buf_size,destd) | ||
| 392 | DWORD buf_size; | ||
| 393 | BYTE 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*/ | ||
diff --git a/v4.0/src/CMD/RESTORE/RTNEW.C b/v4.0/src/CMD/RESTORE/RTNEW.C new file mode 100644 index 0000000..c4c9cb6 --- /dev/null +++ b/v4.0/src/CMD/RESTORE/RTNEW.C | |||
| @@ -0,0 +1,244 @@ | |||
| 1 | |||
| 2 | /*------------------------------ | ||
| 3 | /* SOURCE FILE NAME: RTNEW.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 "string.h" | ||
| 12 | #include "dos.h" /*;AN000;2*/ | ||
| 13 | #include "comsub.h" /* common subroutine def'n */ | ||
| 14 | #include "doscalls.h" | ||
| 15 | #include "error.h" | ||
| 16 | |||
| 17 | extern BYTE control_flag; | ||
| 18 | extern BYTE control_flag2; | ||
| 19 | extern unsigned far *control_buf_pointer; | ||
| 20 | extern unsigned control_file_handle; /* !wrw */ | ||
| 21 | extern unsigned src_file_handle; | ||
| 22 | unsigned int done_searching; /* !wrw */ | ||
| 23 | unsigned int numentry; | ||
| 24 | extern struct subst_list sublist; /*;AN000;6 Message substitution list */ | ||
| 25 | |||
| 26 | /***************** START OF SPECIFICATION ******************************** | ||
| 27 | /* | ||
| 28 | /* SUBROUTINE NAME : search_src_disk_new | ||
| 29 | /* | ||
| 30 | /* DESCRIPTIVE NAME : For new format only, search the entire disk for | ||
| 31 | /* matching files. | ||
| 32 | /* | ||
| 33 | /* FUNCTION: Call subroutine findfirst_new and fnext_new to find all the | ||
| 34 | /* files which match the filename and file extension specified | ||
| 35 | /* in the command line. | ||
| 36 | /* | ||
| 37 | /* Whenever there is a file found, subroutine filematch | ||
| 38 | /* is called to match the file path, and file extension. | ||
| 39 | /* If file path and file extension match the specification, | ||
| 40 | /* subroutine switchmatch is called to match the file | ||
| 41 | /* attributes, file modes, time, and date, then file sequence | ||
| 42 | /* is checked. | ||
| 43 | /* | ||
| 44 | /* If the file matches all the specification, subroutine | ||
| 45 | /* restore_a_file is called to actually restore the file. | ||
| 46 | /* | ||
| 47 | /* | ||
| 48 | /********************* END OF SPECIFICATIONS ********************************/ | ||
| 49 | void search_src_disk_new(dinfo,finfo,dheadold,dheadnew,fheadnew, /* wrw! */ | ||
| 50 | srcd,destd,dnumwant,buf_size, | ||
| 51 | inpath,infname,infspec,control_buf_size,td) | ||
| 52 | |||
| 53 | struct disk_info *dinfo; | ||
| 54 | struct file_info *finfo; | ||
| 55 | struct disk_header_new far *dheadnew; | ||
| 56 | struct file_header_new far *fheadnew; | ||
| 57 | struct disk_header_old *dheadold; | ||
| 58 | BYTE srcd; | ||
| 59 | BYTE destd; | ||
| 60 | unsigned int *dnumwant; /*num of next disk*/ | ||
| 61 | unsigned long buf_size; | ||
| 62 | unsigned *control_buf_size; | ||
| 63 | unsigned char *inpath; | ||
| 64 | unsigned char *infname; | ||
| 65 | unsigned char *infspec; | ||
| 66 | struct timedate *td; | ||
| 67 | |||
| 68 | { | ||
| 69 | BYTE outstring[MAXPATH+MAXFSPEC]; | ||
| 70 | WORD file_seq_num = 1; | ||
| 71 | WORD first_file_on_diskette = TRUE; | ||
| 72 | BYTE file_tobe_opened[MAXFSPEC+2]; | ||
| 73 | WORD dnum; | ||
| 74 | WORD found = FALSE; | ||
| 75 | WORD far *dirptr; | ||
| 76 | WORD far *flptr; | ||
| 77 | WORD retcode; | ||
| 78 | WORD action; | ||
| 79 | BYTE dir_path[MAXPATH]; | ||
| 80 | unsigned int my_own_little_dirhandle = 0; /* !wrw */ | ||
| 81 | union REGS qregs; /*;AN000;8*/ | ||
| 82 | int x; /*;AN000;8*/ | ||
| 83 | |||
| 84 | done_searching = FALSE; /* !wrw */ | ||
| 85 | |||
| 86 | /***********************************************************************/ | ||
| 87 | /*search the file control.xxx and try to find the file with match file */ | ||
| 88 | /*name and file path */ | ||
| 89 | /***********************************************************************/ | ||
| 90 | |||
| 91 | retcode = findfirst_new(finfo,&found,&done_searching,inpath, | ||
| 92 | infspec,&dirptr,&flptr,&numentry,dir_path); | ||
| 93 | |||
| 94 | if (retcode != TRUE) | ||
| 95 | return; | ||
| 96 | |||
| 97 | /***********************************************************************/ | ||
| 98 | /*open file backup.xxx */ | ||
| 99 | /***********************************************************************/ | ||
| 100 | /*the current disk is one less than the disk num wanted*/ | ||
| 101 | dnum = *dnumwant -1; | ||
| 102 | /*make the file name to be opened*/ | ||
| 103 | file_tobe_opened[0] = srcd; | ||
| 104 | file_tobe_opened[1] = ':'; | ||
| 105 | file_tobe_opened[2] = NULLC; | ||
| 106 | strcat(file_tobe_opened,"BACKUP."); | ||
| 107 | file_tobe_opened[9] = (char)((dnum / 100) + '0'); | ||
| 108 | dnum = dnum % 100; | ||
| 109 | file_tobe_opened[10] = (char)((dnum / 10) + '0'); | ||
| 110 | dnum = dnum % 10; | ||
| 111 | file_tobe_opened[11] = (char)(dnum + '0'); | ||
| 112 | file_tobe_opened[12] = NULLC; | ||
| 113 | |||
| 114 | retcode = | ||
| 115 | DOSOPEN | ||
| 116 | ((char far *)&file_tobe_opened[0], | ||
| 117 | (unsigned far *)&src_file_handle, | ||
| 118 | (unsigned far *)&action, | ||
| 119 | (DWORD)0, | ||
| 120 | 0, | ||
| 121 | 0x01, | ||
| 122 | 0x00c0, | ||
| 123 | (DWORD)0 | ||
| 124 | ); | ||
| 125 | |||
| 126 | |||
| 127 | if (retcode != NOERROR) | ||
| 128 | { | ||
| 129 | display_it(NOT_ABLE_TO_RESTORE_FILE,STND_ERR_DEV,0,NO_RESPTYPE,(BYTE)UTIL_MSG); /*;AN000;6*/ | ||
| 130 | unexperror(retcode); | ||
| 131 | } | ||
| 132 | |||
| 133 | /***********************************************************************/ | ||
| 134 | /*start loop to find next until no more file found */ | ||
| 135 | /***********************************************************************/ | ||
| 136 | do | ||
| 137 | { | ||
| 138 | /******************************************/ | ||
| 139 | /* if it is system file, find next one */ | ||
| 140 | /******************************************/ | ||
| 141 | if | ||
| 142 | ( | ||
| 143 | (strcmp(finfo->fname,"IBMBIO.COM")==0 || | ||
| 144 | strcmp(finfo->fname,"IBMDOS.COM")==0 || | ||
| 145 | strcmp(finfo->fname,"CMD.EXE")==0 || | ||
| 146 | strcmp(finfo->fname,"COMMAND.COM")==0 | ||
| 147 | ) /*;AN003;*/ | ||
| 148 | && strcmp(finfo->path,"\\")==0 /*;AN003;*/ | ||
| 149 | ) | ||
| 150 | { /* Do not RESTORE the file */ | ||
| 151 | } | ||
| 152 | else | ||
| 153 | { | ||
| 154 | |||
| 155 | /***********************************************************************/ | ||
| 156 | /*if there are any switches set in the input line, call switch match. */ | ||
| 157 | /* if switchmatch returns FALSE, then find next file */ | ||
| 158 | /***********************************************************************/ | ||
| 159 | if ((set_reset_test_flag(&control_flag,SWITCHES,TEST) == FALSE) || | ||
| 160 | (set_reset_test_flag(&control_flag,SWITCHES,TEST) == TRUE && | ||
| 161 | ((retcode = switchmatch(finfo, srcd, destd, td)) == TRUE) )) | ||
| 162 | { | ||
| 163 | |||
| 164 | /***********************************************************************/ | ||
| 165 | /* if the diskette is out of sequence, then do not check the sequence */ | ||
| 166 | /* number of the 1st file. Otherwise, check sequence number */ | ||
| 167 | /***********************************************************************/ | ||
| 168 | if (set_reset_test_flag(&control_flag2,OUTOF_SEQ,TEST) == TRUE && | ||
| 169 | first_file_on_diskette == TRUE && finfo->dnum != file_seq_num) | ||
| 170 | { | ||
| 171 | } | ||
| 172 | else | ||
| 173 | { | ||
| 174 | if (finfo->dnum != file_seq_num) | ||
| 175 | { | ||
| 176 | display_it(FILE_SEQUENCE_ERROR,STND_ERR_DEV,0,NO_RESPTYPE,(BYTE)UTIL_MSG); /*;AN000;6*/ | ||
| 177 | unexperror(FILESEQERROR); | ||
| 178 | } | ||
| 179 | |||
| 180 | /***********************************************************************/ | ||
| 181 | /* msg: output one line of outstring on the screen */ | ||
| 182 | /* to confirm that a file has been restored sucessfully */ | ||
| 183 | /***********************************************************************/ | ||
| 184 | strcpy(outstring,finfo->path); | ||
| 185 | if (strlen(finfo->path) != 1 ) | ||
| 186 | strcat(outstring,"\\"); | ||
| 187 | |||
| 188 | strcat(outstring,finfo->fname); | ||
| 189 | x = strlen(outstring); | ||
| 190 | outstring[x] = CR; /*;AN000;6*/ | ||
| 191 | outstring[x+1] = LF; /*;AN000;6*/ | ||
| 192 | outstring[x+2] = NUL; /*;AN000;6*/ | ||
| 193 | qregs.x.ax = 0x4000; /*;AN000;6*/ | ||
| 194 | qregs.x.bx = 0x0001; /*;AN000;6*/ | ||
| 195 | qregs.x.cx = (WORD)strlen(outstring); /*;AN000;6*/ | ||
| 196 | qregs.x.dx = (unsigned int)&outstring[0]; /*;AN000;6*/ | ||
| 197 | intdos(&qregs,&qregs); /*;AN000;6*/ | ||
| 198 | |||
| 199 | /***********************************************************************/ | ||
| 200 | /* restore the file */ | ||
| 201 | /***********************************************************************/ | ||
| 202 | restore_a_file(finfo,dinfo,buf_size,control_buf_size, | ||
| 203 | fheadnew,dheadold,dheadnew, | ||
| 204 | srcd,destd,inpath,infname,infspec,dnumwant,&my_own_little_dirhandle); /* wrw! */ | ||
| 205 | |||
| 206 | first_file_on_diskette = FALSE; | ||
| 207 | |||
| 208 | if (set_reset_test_flag(&control_flag,SPLITFILE,TEST)==TRUE) | ||
| 209 | { | ||
| 210 | set_reset_test_flag(&control_flag,SPLITFILE,RESET); | ||
| 211 | /*do findfirst, the file found should be the splitted file*/ | ||
| 212 | |||
| 213 | /* retcode= findfirst_new( finfo, &found, &done_searching, inpath, */ | ||
| 214 | /* infspec, &dirptr, &flptr,&numentry,dir_path ); */ | ||
| 215 | } | ||
| 216 | |||
| 217 | } /*end of if disk and file out of sequence*/ | ||
| 218 | |||
| 219 | } /*end of if switch match is ok */ | ||
| 220 | |||
| 221 | } /*end of if root directory and DOS system files */ | ||
| 222 | |||
| 223 | /***********************************************************************/ | ||
| 224 | /* if has not search to the end of the diskette, find next file */ | ||
| 225 | /***********************************************************************/ | ||
| 226 | if (done_searching == FALSE) | ||
| 227 | { | ||
| 228 | found = FALSE; | ||
| 229 | retcode= findnext_new(finfo,&found,&done_searching,inpath,infspec, | ||
| 230 | &dirptr,&flptr,&numentry,dir_path ); | ||
| 231 | |||
| 232 | } | ||
| 233 | else | ||
| 234 | break; | ||
| 235 | |||
| 236 | } /* end do while loop */ | ||
| 237 | while( retcode == TRUE); | ||
| 238 | |||
| 239 | DOSCLOSE(src_file_handle); | ||
| 240 | |||
| 241 | return; /* !wrw */ | ||
| 242 | |||
| 243 | } /*end of subroutine*/ | ||
| 244 | |||
diff --git a/v4.0/src/CMD/RESTORE/RTNEW1.C b/v4.0/src/CMD/RESTORE/RTNEW1.C new file mode 100644 index 0000000..c449192 --- /dev/null +++ b/v4.0/src/CMD/RESTORE/RTNEW1.C | |||
| @@ -0,0 +1,627 @@ | |||
| 1 | |||
| 2 | /*------------------------------ | ||
| 3 | /* SOURCE FILE NAME: RTNEW1.C | ||
| 4 | /*------------------------------ | ||
| 5 | /* 0 */ | ||
| 6 | #include "rt.h" | ||
| 7 | #include "rt1.h" | ||
| 8 | #include "rt2.h" | ||
| 9 | #include "restpars.h" /*;AN000;4*/ | ||
| 10 | #include "string.h" | ||
| 11 | #include "dos.h" /*;AN000;2*/ | ||
| 12 | #include "comsub.h" /* common subroutine def'n */ | ||
| 13 | #include "doscalls.h" | ||
| 14 | #include "error.h" | ||
| 15 | |||
| 16 | |||
| 17 | #define LAST_DIRBLOCK 0xffffffff /* !wrw */ | ||
| 18 | BYTE got_first_fh; /* !wrw */ | ||
| 19 | |||
| 20 | struct dir_block russ_dir_block; /* Current directory block /* !wrw */ | ||
| 21 | extern BYTE backup_level; /* Tells which DOS version made the BACKUP*/ /*;AN000;3*/ | ||
| 22 | |||
| 23 | struct file_header_new russ_file_header;/* Current file_header /* !wrw */ | ||
| 24 | unsigned short tot_num_fh_read_in; /* Num FH read in so far /* !wrw */ | ||
| 25 | unsigned short num_fh_in_buffer; /* Num FH currently in buff /* !wrw */ | ||
| 26 | unsigned short num_fh_in_buf_processed; /* Number of FH in the buffer that have been processed /* !wrw */ | ||
| 27 | struct file_header_new far *fheadnew; /* Global pointer to FH /* !wrw */ | ||
| 28 | |||
| 29 | |||
| 30 | BYTE fileheader_length; /*;AN000;3 Length of a file header */ | ||
| 31 | |||
| 32 | extern BYTE rtswitch; | ||
| 33 | extern BYTE control_flag; | ||
| 34 | extern BYTE control_flag2; | ||
| 35 | extern char far *control_buf_pointer; | ||
| 36 | extern unsigned control_file_handle; | ||
| 37 | extern WORD control_bufsize; /* !wrw */ | ||
| 38 | |||
| 39 | |||
| 40 | /* 0 */ | ||
| 41 | /***************** START OF SPECIFICATION ******************************** | ||
| 42 | /* | ||
| 43 | /* SUBROUTINE NAME : findfile_new | ||
| 44 | /* | ||
| 45 | /* DESCRIPTIVE NAME : Find a file with matching file name from | ||
| 46 | /* the file CONTROL.xxx. | ||
| 47 | /* | ||
| 48 | /* FUNCTION: For new format only, search through all directory blocks | ||
| 49 | /* and all file headers until a file header with matched file | ||
| 50 | /* path, name and extension is found. also store information | ||
| 51 | /* into fhead and finfo if file is found which match the | ||
| 52 | /* filename and file extension specified in the command line. | ||
| 53 | /* | ||
| 54 | /* NOTES: Path name for comparison has to started with \ and end with \. | ||
| 55 | /* | ||
| 56 | /********************** END OF SPECIFICATIONS *******************************/ | ||
| 57 | int findfile_new( finfo, found, done_searching, inpath, | ||
| 58 | infspec, dirptr, flptr, numentry, dir_path) | ||
| 59 | |||
| 60 | struct file_info *finfo; | ||
| 61 | WORD *found; | ||
| 62 | unsigned int *done_searching; | ||
| 63 | BYTE *inpath; | ||
| 64 | BYTE *infspec; | ||
| 65 | WORD far **dirptr; | ||
| 66 | WORD far **flptr; | ||
| 67 | unsigned int *numentry; | ||
| 68 | BYTE *dir_path; | ||
| 69 | { | ||
| 70 | struct dir_block far *dirblk; | ||
| 71 | char temp_path[MAXPATH]; | ||
| 72 | char temp_fname[MAXFSPEC]; | ||
| 73 | WORD i; | ||
| 74 | WORD rc; | ||
| 75 | |||
| 76 | |||
| 77 | dirblk = (struct dir_block far *)&russ_dir_block; /* !wrw */ | ||
| 78 | fheadnew = (struct file_header_new far *)&russ_file_header; /* !wrw */ | ||
| 79 | |||
| 80 | /******************************************************************/ | ||
| 81 | /* search the directory block for the one that has the right path */ | ||
| 82 | /*******************************************************************/ | ||
| 83 | while ((*done_searching == FALSE) && (*found == FALSE)) | ||
| 84 | { | ||
| 85 | temp_path[0] = '\\'; | ||
| 86 | for (i = 0; i <= (MAXPATH-2); ++i) | ||
| 87 | temp_path[i+1] = dirblk->path[i]; | ||
| 88 | |||
| 89 | temp_path[MAXPATH-1] = NULLC; | ||
| 90 | |||
| 91 | /*****************************/ | ||
| 92 | /* While path does not match */ | ||
| 93 | /*****************************/ | ||
| 94 | |||
| 95 | while (pathmatch(inpath,temp_path) == FALSE) | ||
| 96 | { | ||
| 97 | if (dirblk->nextdb == LAST_DIRBLOCK) /* !wrw */ | ||
| 98 | { | ||
| 99 | *found = FALSE; | ||
| 100 | *done_searching = TRUE; | ||
| 101 | break; | ||
| 102 | } | ||
| 103 | else | ||
| 104 | { | ||
| 105 | read_in_next_dirblock(); /* !wrw */ | ||
| 106 | temp_path[0] = '\\'; | ||
| 107 | for (i = 0; i <= (MAXPATH-2); ++i) | ||
| 108 | temp_path[i+1] = dirblk->path[i]; | ||
| 109 | temp_path[MAXPATH-1] = NULLC; | ||
| 110 | continue; | ||
| 111 | } | ||
| 112 | /*end of if not last dirblk*/ | ||
| 113 | |||
| 114 | } /*end while loop, searching for the right path in directory block*/ | ||
| 115 | /*if done searching, break out of the big loop to exit*/ | ||
| 116 | |||
| 117 | if (*done_searching == TRUE) | ||
| 118 | break; | ||
| 119 | |||
| 120 | /***************************************************/ | ||
| 121 | /* directory block with correct path has been found*/ | ||
| 122 | /***************************************************/ | ||
| 123 | |||
| 124 | /*get the total number of file headers in the directory block*/ | ||
| 125 | *numentry = (unsigned int)russ_dir_block.numentry; /* !wrw */ | ||
| 126 | |||
| 127 | if (got_first_fh == FALSE) /* !wrw */ | ||
| 128 | read_in_a_fileheader(); /*#### /* !wrw */ | ||
| 129 | |||
| 130 | /****************************************************/ | ||
| 131 | /* search all the file headers under this directory */ | ||
| 132 | /* block to find the one with right file name */ | ||
| 133 | /****************************************************/ | ||
| 134 | for (;;) | ||
| 135 | { | ||
| 136 | |||
| 137 | if ((rc = fheadnew->flag & COMPLETE_BIT) != COMPLETE_BIT) | ||
| 138 | { | ||
| 139 | if (*numentry) | ||
| 140 | --(*numentry); | ||
| 141 | if (*numentry==0) | ||
| 142 | { | ||
| 143 | if (dirblk->nextdb == LAST_DIRBLOCK) /* !wrw */ | ||
| 144 | { | ||
| 145 | *found = FALSE; | ||
| 146 | *done_searching = TRUE; | ||
| 147 | break; /*exit FOR loop, go back to WHILE loop*/ | ||
| 148 | } | ||
| 149 | else | ||
| 150 | { | ||
| 151 | read_in_next_dirblock(); /* !wrw */ | ||
| 152 | break; /*exit FOR loop, go back to WHILE loop*/ | ||
| 153 | } | ||
| 154 | } | ||
| 155 | else | ||
| 156 | { | ||
| 157 | read_in_a_fileheader(); /* !wrw */ | ||
| 158 | continue; | ||
| 159 | } | ||
| 160 | } | ||
| 161 | |||
| 162 | for (i = 0; i <= (MAXFSPEC-2); ++i) | ||
| 163 | temp_fname[i] = fheadnew->fname[i]; | ||
| 164 | temp_fname[MAXFSPEC-1] = NULLC; | ||
| 165 | |||
| 166 | if (fspecmatch(infspec,temp_fname)==TRUE) | ||
| 167 | { | ||
| 168 | *found = TRUE; | ||
| 169 | break; | ||
| 170 | } | ||
| 171 | else /* This file header is not the right one*/ | ||
| 172 | { | ||
| 173 | if (*numentry) | ||
| 174 | --(*numentry); | ||
| 175 | if (*numentry == 0) | ||
| 176 | { | ||
| 177 | if (dirblk->nextdb == LAST_DIRBLOCK) | ||
| 178 | { | ||
| 179 | *found = FALSE; | ||
| 180 | *done_searching = TRUE; | ||
| 181 | break; /*exit FOR loop, go back to WHILE loop*/ | ||
| 182 | } | ||
| 183 | else | ||
| 184 | { | ||
| 185 | read_in_next_dirblock(); /* !wrw */ | ||
| 186 | break; | ||
| 187 | } /*end of if not last dir block */ | ||
| 188 | } | ||
| 189 | else /*point to the next file header and loop again*/ | ||
| 190 | read_in_a_fileheader(); /* !wrw */ | ||
| 191 | |||
| 192 | } | ||
| 193 | |||
| 194 | } /* end for (;;) loop to search all file headers in a directory block */ | ||
| 195 | |||
| 196 | } /*end of while loop*/ | ||
| 197 | |||
| 198 | |||
| 199 | |||
| 200 | /*******************************************************************/ | ||
| 201 | /* if a file is found, save the information in the disk header and */ | ||
| 202 | /* file header */ | ||
| 203 | /*******************************************************************/ | ||
| 204 | if (*found == TRUE) | ||
| 205 | { | ||
| 206 | /* Store information from dir blk into finfo */ | ||
| 207 | if (strcmp(dir_path,"no path from fnext") == 0) | ||
| 208 | strcpy(finfo->path,temp_path); | ||
| 209 | else | ||
| 210 | { | ||
| 211 | finfo->path[0] = '\\'; | ||
| 212 | finfo->path[1] = NULLC; | ||
| 213 | strcat(finfo->path,dir_path); | ||
| 214 | } | ||
| 215 | |||
| 216 | /*store information from file header into finfo*/ | ||
| 217 | for (i = 0; i <= (MAXFSPEC-2); ++i) | ||
| 218 | finfo->fname[i] = fheadnew->fname[i]; | ||
| 219 | finfo->fname[MAXFSPEC-1] = NULLC; | ||
| 220 | finfo->fflag = fheadnew->flag; | ||
| 221 | finfo->dnum = fheadnew->fsequenc; | ||
| 222 | finfo->ftime = fheadnew->ftime; | ||
| 223 | finfo->fdate = fheadnew->fdate; | ||
| 224 | finfo->attrib = fheadnew->attrib; | ||
| 225 | finfo->partsize = fheadnew->partsize; | ||
| 226 | finfo->offset = fheadnew->offset; | ||
| 227 | |||
| 228 | if ((fheadnew->flag & EXT_ATTR_FLAG) == EXT_ATTR_FLAG) /*;AN000;3*/ | ||
| 229 | finfo->ea_offset = fheadnew->FH_EA_offset; /*;AN000;3*/ | ||
| 230 | |||
| 231 | if (*numentry) | ||
| 232 | --(*numentry); | ||
| 233 | |||
| 234 | if (*numentry == 0) | ||
| 235 | { | ||
| 236 | if (dirblk->nextdb == LAST_DIRBLOCK) | ||
| 237 | *done_searching = TRUE; | ||
| 238 | else | ||
| 239 | { | ||
| 240 | read_in_next_dirblock(); /* !wrw */ | ||
| 241 | read_in_a_fileheader(); /* !wrw */ | ||
| 242 | *numentry = dirblk->numentry; | ||
| 243 | } | ||
| 244 | } | ||
| 245 | else | ||
| 246 | read_in_a_fileheader(); /* !wrw */ | ||
| 247 | |||
| 248 | *dirptr=(WORD far *)dirblk; | ||
| 249 | *flptr=(WORD far *)fheadnew; | ||
| 250 | |||
| 251 | return (TRUE); | ||
| 252 | } /*end of if found */ | ||
| 253 | else | ||
| 254 | return (FALSE); | ||
| 255 | |||
| 256 | return(TRUE); /*;AN000;*/ | ||
| 257 | } /*end of subroutine */ | ||
| 258 | |||
| 259 | /* 0 */ | ||
| 260 | /***************** START OF SPECIFICATION ******************************** | ||
| 261 | /* | ||
| 262 | /* SUBROUTINE NAME : findnext_new | ||
| 263 | /* | ||
| 264 | /* DESCRIPTIVE NAME : For new format only, continue at the point | ||
| 265 | /* findfirst_new or previous findnext_new exit, search | ||
| 266 | /* the entire file of CONTROL.xxx to find matching file | ||
| 267 | /* names. | ||
| 268 | /* | ||
| 269 | /* FUNCTION: Continue at where findfirst_new or previous findnext_new | ||
| 270 | /* stop, search the current directory blocks for the matching | ||
| 271 | /* file path, if fail to find a file, then call findfile to | ||
| 272 | /* search all directory block. | ||
| 273 | /* | ||
| 274 | /* | ||
| 275 | /********************** END OF SPECIFICATIONS *******************************/ | ||
| 276 | int findnext_new(finfo, found, done_searching, in_path, | ||
| 277 | infspec, dirptr, flptr, numentry, dir_path) | ||
| 278 | |||
| 279 | struct file_info *finfo; | ||
| 280 | WORD *found; | ||
| 281 | unsigned int *done_searching; | ||
| 282 | BYTE *in_path; | ||
| 283 | BYTE *infspec; | ||
| 284 | WORD far **dirptr; | ||
| 285 | WORD far **flptr; | ||
| 286 | unsigned int *numentry; | ||
| 287 | BYTE *dir_path; | ||
| 288 | { | ||
| 289 | struct dir_block far *dirblk; | ||
| 290 | WORD retcode; | ||
| 291 | WORD i; | ||
| 292 | BYTE temp_fname[MAXFSPEC]; | ||
| 293 | WORD rc; | ||
| 294 | char temp_path[MAXPATH]; | ||
| 295 | |||
| 296 | dirblk=(struct dir_block far *)*dirptr; | ||
| 297 | fheadnew=(struct file_header_new far *)*flptr; | ||
| 298 | strcpy(dir_path,"no path from fnext"); | ||
| 299 | |||
| 300 | temp_path[0] = '\\'; | ||
| 301 | for (i = 0; i <= (MAXPATH-2); ++i) | ||
| 302 | temp_path[i+1] = dirblk->path[i]; | ||
| 303 | |||
| 304 | temp_path[MAXPATH-1] = NULLC; | ||
| 305 | |||
| 306 | /****************************************/ | ||
| 307 | /* Should we process this subdirectory ?*/ | ||
| 308 | /****************************************/ | ||
| 309 | if (pathmatch(in_path,temp_path) == TRUE) | ||
| 310 | { | ||
| 311 | |||
| 312 | /*************************************************/ | ||
| 313 | /*complete the scanning current db to find a file*/ | ||
| 314 | /*************************************************/ | ||
| 315 | for (;;) | ||
| 316 | { | ||
| 317 | if ((rc = fheadnew->flag & COMPLETE_BIT) != COMPLETE_BIT) | ||
| 318 | { | ||
| 319 | if (*numentry) | ||
| 320 | --(*numentry); | ||
| 321 | |||
| 322 | if (*numentry==0) | ||
| 323 | { | ||
| 324 | if (dirblk->nextdb == LAST_DIRBLOCK) | ||
| 325 | { | ||
| 326 | *found = FALSE; | ||
| 327 | *done_searching = TRUE; | ||
| 328 | break; | ||
| 329 | } | ||
| 330 | else | ||
| 331 | { | ||
| 332 | read_in_next_dirblock(); /* !wrw */ | ||
| 333 | break; /* !wrw */ | ||
| 334 | } | ||
| 335 | } /* !wrw */ | ||
| 336 | else /* There are more files from current dirblock. Get them */ | ||
| 337 | { /* !wrw */ | ||
| 338 | read_in_a_fileheader(); /* !wrw */ | ||
| 339 | continue; /* !wrw */ | ||
| 340 | } | ||
| 341 | } | ||
| 342 | /*endif*/ | ||
| 343 | |||
| 344 | /* If this file header is the right one)*/ | ||
| 345 | for (i = 0; i <= (MAXFSPEC-2); ++i) | ||
| 346 | temp_fname[i] = fheadnew->fname[i]; | ||
| 347 | |||
| 348 | temp_fname[MAXFSPEC-1] = NULLC; | ||
| 349 | |||
| 350 | if (fspecmatch(infspec,temp_fname)==TRUE) | ||
| 351 | { | ||
| 352 | *found = TRUE; | ||
| 353 | for (i = 0; i <= (MAXPATH-2); ++i) | ||
| 354 | dir_path[i] = dirblk->path[i]; | ||
| 355 | break; | ||
| 356 | } | ||
| 357 | else /*if this file header is not the right one*/ | ||
| 358 | { | ||
| 359 | if (*numentry) | ||
| 360 | --(*numentry); | ||
| 361 | if (*numentry == 0) /* If no more files in this directory block */ | ||
| 362 | { | ||
| 363 | if (dirblk->nextdb == LAST_DIRBLOCK) /* If this is the last dirblock on current source disk */ | ||
| 364 | { | ||
| 365 | *found = FALSE; | ||
| 366 | *done_searching = TRUE; | ||
| 367 | break; | ||
| 368 | } | ||
| 369 | else | ||
| 370 | { | ||
| 371 | read_in_next_dirblock(); /* !wrw */ | ||
| 372 | break; /* !wrw */ | ||
| 373 | } /*end of if not last dir block */ /* !wrw */ | ||
| 374 | } /* !wrw */ | ||
| 375 | else /* !wrw */ | ||
| 376 | read_in_a_fileheader(); /* !wrw */ | ||
| 377 | } | ||
| 378 | } /*end loop searching all file headers in dir block */ | ||
| 379 | } /*end of if the path match inpath*/ | ||
| 380 | |||
| 381 | else | ||
| 382 | *found = FALSE; | ||
| 383 | |||
| 384 | |||
| 385 | /********************************************************************/ | ||
| 386 | /* If fail to find a file in the current directory block, call */ | ||
| 387 | /* filefind_new to find next. */ | ||
| 388 | /* If already found or done searching, call findfile_new to store */ | ||
| 389 | /* information in finfo and dinfo */ | ||
| 390 | /********************************************************************/ | ||
| 391 | |||
| 392 | *dirptr=(WORD far *)dirblk; | ||
| 393 | *flptr=(WORD far *)fheadnew; | ||
| 394 | |||
| 395 | retcode = findfile_new(finfo,found,done_searching,in_path,infspec,dirptr, | ||
| 396 | flptr,numentry, dir_path); | ||
| 397 | |||
| 398 | return(retcode); | ||
| 399 | } | ||
| 400 | |||
| 401 | /* 0 */ | ||
| 402 | /***************** START OF SPECIFICATION ******************************** | ||
| 403 | /* | ||
| 404 | /* SUBROUTINE NAME : findfirst_new | ||
| 405 | /* | ||
| 406 | /* DESCRIPTIVE NAME : For new format only, search the entire file | ||
| 407 | /* of CONTROL.xxx to find matching file names. | ||
| 408 | /* | ||
| 409 | /* FUNCTION: search directory blocks one after the other to find the | ||
| 410 | /* directory block with the matching file path, then search | ||
| 411 | /* the entire directory block to find the file with matching | ||
| 412 | /* file name. | ||
| 413 | /* | ||
| 414 | /* | ||
| 415 | /********************** END OF SPECIFICATIONS *******************************/ | ||
| 416 | int findfirst_new(finfo,found,done_searching,in_path,infspec,dirptr,flptr,numentry,dir_path) | ||
| 417 | |||
| 418 | struct file_info *finfo; | ||
| 419 | WORD *found; | ||
| 420 | unsigned int *done_searching; | ||
| 421 | BYTE *in_path; | ||
| 422 | BYTE *infspec; | ||
| 423 | WORD far **dirptr; | ||
| 424 | WORD far **flptr; | ||
| 425 | unsigned int *numentry; | ||
| 426 | BYTE *dir_path; | ||
| 427 | { | ||
| 428 | struct dir_block far *dirblk; | ||
| 429 | WORD retcode; | ||
| 430 | |||
| 431 | strcpy(dir_path,"no path from fnext"); | ||
| 432 | dirblk = (struct dir_block far *)&russ_dir_block; /* !wrw */ | ||
| 433 | read_in_first_dirblock(); /* !wrw */ | ||
| 434 | |||
| 435 | if (got_first_fh == FALSE) /* !wrw */ | ||
| 436 | read_in_a_fileheader(); /*### /* !wrw */ | ||
| 437 | |||
| 438 | *found = FALSE; | ||
| 439 | *done_searching = FALSE; | ||
| 440 | *dirptr=(WORD far *)dirblk; | ||
| 441 | *flptr=(WORD far *)fheadnew; | ||
| 442 | |||
| 443 | retcode = findfile_new(finfo,found,done_searching,in_path, | ||
| 444 | infspec,dirptr,flptr,numentry,dir_path); | ||
| 445 | |||
| 446 | return(retcode); | ||
| 447 | } /*end of findfirst_new */ | ||
| 448 | |||
| 449 | |||
| 450 | |||
| 451 | |||
| 452 | /* 0 */ | ||
| 453 | /*********************************************************************/ | ||
| 454 | /* | ||
| 455 | /* SUBROUTINE NAME: read_in_next_dirblock | ||
| 456 | /* | ||
| 457 | /* FUNCTION: | ||
| 458 | /* Reads in a directory block | ||
| 459 | /* Figures out if it was put there by DOS 3.3 or 4.0 | ||
| 460 | /*********************************************************************/ | ||
| 461 | void read_in_next_dirblock() /* !wrw */ | ||
| 462 | { | ||
| 463 | |||
| 464 | WORD retcode; /* return code save area */ /* !wrw */ | ||
| 465 | WORD read_count; /* num bytes read in */ /* !wrw */ | ||
| 466 | DWORD file_pointer; /* current file pointer, returned by lseek !wrw */ | ||
| 467 | |||
| 468 | retcode = /* !wrw */ | ||
| 469 | DOSCHGFILEPTR /* !wrw */ | ||
| 470 | ( /* !wrw */ | ||
| 471 | control_file_handle, /* Handle */ /* !wrw */ | ||
| 472 | russ_dir_block.nextdb, /* New location */ /* !wrw */ | ||
| 473 | (BYTE)0, /* MOVE METHOD */ /* !wrw */ | ||
| 474 | (DWORD far *)&file_pointer /* !wrw */ | ||
| 475 | ); /* !wrw */ | ||
| 476 | |||
| 477 | retcode = | ||
| 478 | DOSREAD | ||
| 479 | ( /* !wrw */ | ||
| 480 | control_file_handle, /* !wrw */ | ||
| 481 | (char far *)&russ_dir_block, /* !wrw */ | ||
| 482 | (unsigned short)DIRBLKLEN, /* !wrw */ | ||
| 483 | (unsigned far *)&read_count /* !wrw */ | ||
| 484 | ); /* !wrw */ | ||
| 485 | /* !wrw */ | ||
| 486 | if (retcode != NOERROR) /* !wrw */ | ||
| 487 | { /* !wrw */ | ||
| 488 | display_it(SOURCE_NO_BACKUP_FILE,STND_ERR_DEV,0,NO_RESPTYPE,(BYTE)UTIL_MSG); /*;AN000;6*/ | ||
| 489 | unexperror(NOBACKUPFILE); /* !wrw */ | ||
| 490 | } | ||
| 491 | |||
| 492 | got_first_fh = FALSE; /* !wrw */ | ||
| 493 | get_fileheader_length(); /*;AN000;3*/ | ||
| 494 | |||
| 495 | return; /* !wrw */ | ||
| 496 | } /* !wrw */ | ||
| 497 | |||
| 498 | |||
| 499 | /*********************************************************************/ | ||
| 500 | /* | ||
| 501 | /* SUBROUTINE NAME: read_in_first_dirblock | ||
| 502 | /* | ||
| 503 | /* FUNCTION: | ||
| 504 | /* Reads in the first directory block | ||
| 505 | /* Figures out if it was put there by DOS 3.3 or 4.0 | ||
| 506 | /*********************************************************************/ | ||
| 507 | |||
| 508 | void read_in_first_dirblock() /* !wrw */ | ||
| 509 | { | ||
| 510 | |||
| 511 | WORD retcode; /* return code save area */ /* !wrw */ | ||
| 512 | WORD read_count; /* num bytes read in */ /* !wrw */ | ||
| 513 | |||
| 514 | /********************************************************************/ | ||
| 515 | /* READ DIRECTORY_BLOCK INTO STATIC DATA AREA */ | ||
| 516 | /********************************************************************/ | ||
| 517 | |||
| 518 | retcode = DOSREAD( /* !wrw */ | ||
| 519 | control_file_handle, /* !wrw */ | ||
| 520 | (char far *)&russ_dir_block, /* !wrw */ | ||
| 521 | (unsigned short)DIRBLKLEN, /* !wrw */ | ||
| 522 | (unsigned far *)&read_count /* !wrw */ | ||
| 523 | ); /* !wrw */ | ||
| 524 | |||
| 525 | if (retcode != 0) /* !wrw */ | ||
| 526 | { /* !wrw */ | ||
| 527 | display_it(SOURCE_NO_BACKUP_FILE,STND_ERR_DEV,0,NO_RESPTYPE,(BYTE)UTIL_MSG); /*;AN000;6*/ | ||
| 528 | unexperror(NOBACKUPFILE); /* !wrw */ | ||
| 529 | } | ||
| 530 | |||
| 531 | got_first_fh = FALSE; /* !wrw */ | ||
| 532 | get_fileheader_length(); /*;AN000;3*/ | ||
| 533 | |||
| 534 | return; /* end subroutine */ /* !wrw */ | ||
| 535 | } /* !wrw */ | ||
| 536 | |||
| 537 | /**************************************************************/ | ||
| 538 | /* | ||
| 539 | /* SUBROUTINE: get_fileheader_length | ||
| 540 | /* | ||
| 541 | /* FUNCTION: Gets the length of a file header | ||
| 542 | /* Sets BACKUP_LEVEL to indicate which | ||
| 543 | /**************************************************************/ | ||
| 544 | void get_fileheader_length() | ||
| 545 | { | ||
| 546 | WORD retcode; /*;AN000;3*/ | ||
| 547 | WORD read_count; /*;AN000;3*/ | ||
| 548 | DWORD file_position; /*;AN000;3*/ | ||
| 549 | |||
| 550 | /* Save current file pointer */ | ||
| 551 | retcode = /*;AN000;3*/ | ||
| 552 | DOSCHGFILEPTR /*;AN000;3*/ | ||
| 553 | ( /*;AN000;3*/ | ||
| 554 | control_file_handle, /* Handle */ /*;AN000;3*/ | ||
| 555 | (DWORD)0, /* New location *//*;AN000;3*/ | ||
| 556 | (BYTE)1, /* MOVE METHOD *//*;AN000;3*/ | ||
| 557 | (DWORD far *)&file_position /*;AN000;3*/ | ||
| 558 | ); /*;AN000;3*/ | ||
| 559 | |||
| 560 | if (retcode != 0) /*;AN000;3*/ | ||
| 561 | { /*;AN000;3*/ | ||
| 562 | display_it(SOURCE_NO_BACKUP_FILE,STND_ERR_DEV,0,NO_RESPTYPE,(BYTE)UTIL_MSG); /*;AN000;6*/ | ||
| 563 | unexperror(NOBACKUPFILE); /*;AN000;3*/ | ||
| 564 | } | ||
| 565 | |||
| 566 | /* Read in file header length*/ | ||
| 567 | retcode = /*;AN000;3*/ | ||
| 568 | DOSREAD /*;AN000;3*/ | ||
| 569 | ( /*;AN000;3*/ | ||
| 570 | control_file_handle, /*;AN000;3*/ | ||
| 571 | (char far *)&fileheader_length, /*;AN000;3*/ | ||
| 572 | (unsigned short)2, /*;AN000;3*/ | ||
| 573 | (unsigned far *)&read_count /*;AN000;3*/ | ||
| 574 | ); /*;AN000;3*/ | ||
| 575 | |||
| 576 | if (retcode != 0 || read_count != 2) /*;AN000;3*/ | ||
| 577 | { /*;AN000;3*/ | ||
| 578 | display_it(SOURCE_NO_BACKUP_FILE,STND_ERR_DEV,0,NO_RESPTYPE,(BYTE)UTIL_MSG); /*;AN000;6*/ | ||
| 579 | unexperror(NOBACKUPFILE); /*;AN000;3*/ | ||
| 580 | } | ||
| 581 | |||
| 582 | /* Reset file pointer */ | ||
| 583 | retcode = /*;AN000;3*/ | ||
| 584 | DOSCHGFILEPTR /*;AN000;3*/ | ||
| 585 | ( /*;AN000;3*/ | ||
| 586 | control_file_handle, /* Handle */ /*;AN000;3*/ | ||
| 587 | file_position, /* New location *//*;AN000;3*/ | ||
| 588 | (BYTE)0, /* MOVE METHOD *//*;AN000;3*/ | ||
| 589 | (DWORD far *)&file_position /*;AN000;3*/ | ||
| 590 | ); /*;AN000;3*/ | ||
| 591 | |||
| 592 | return; | ||
| 593 | } /* end get_fileheader_length() */ | ||
| 594 | |||
| 595 | |||
| 596 | /* 0 */ | ||
| 597 | /**************************************************************/ | ||
| 598 | /* | ||
| 599 | /* SUBROUTINE: read_in_a_fileheader | ||
| 600 | /* | ||
| 601 | /* FUNCTION: Reads in a file header | ||
| 602 | /* | ||
| 603 | /**************************************************************/ | ||
| 604 | void read_in_a_fileheader() /* !wrw */ | ||
| 605 | { /* !wrw */ | ||
| 606 | WORD retcode; /* return code save area */ /* !wrw */ | ||
| 607 | WORD read_count; /* num bytes read in */ /* !wrw */ | ||
| 608 | |||
| 609 | retcode = DOSREAD /* !wrw */ | ||
| 610 | ( /* !wrw */ | ||
| 611 | control_file_handle, /* !wrw */ | ||
| 612 | (char far *)&russ_file_header, /* !wrw */ | ||
| 613 | fileheader_length, /* !wrw */ | ||
| 614 | (unsigned far *)&read_count /* !wrw */ | ||
| 615 | ); /* !wrw */ | ||
| 616 | |||
| 617 | if (retcode != NOERROR) /* !wrw */ | ||
| 618 | { /* !wrw */ | ||
| 619 | display_it(SOURCE_NO_BACKUP_FILE,STND_ERR_DEV,0,NO_RESPTYPE,(BYTE)UTIL_MSG); /*;AN000;6*/ | ||
| 620 | unexperror(NOBACKUPFILE); /* !wrw */ | ||
| 621 | } /* !wrw */ | ||
| 622 | |||
| 623 | got_first_fh = TRUE; /* !wrw */ | ||
| 624 | fheadnew = (struct file_header_new far *)&russ_file_header; /* !wrw */ | ||
| 625 | |||
| 626 | return; /* !wrw */ | ||
| 627 | } /* !wrw */ | ||
diff --git a/v4.0/src/CMD/RESTORE/RTOLD.C b/v4.0/src/CMD/RESTORE/RTOLD.C new file mode 100644 index 0000000..a345d76 --- /dev/null +++ b/v4.0/src/CMD/RESTORE/RTOLD.C | |||
| @@ -0,0 +1,266 @@ | |||
| 1 | |||
| 2 | /*---------------------------- | ||
| 3 | /* SOURCE FILE NAME: RTOLD.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 "string.h" | ||
| 12 | #include "dos.h" /*;AN000;2*/ | ||
| 13 | #include "comsub.h" /* common subroutine def'n */ | ||
| 14 | #include "doscalls.h" | ||
| 15 | #include "error.h" | ||
| 16 | |||
| 17 | extern BYTE rtswitch; | ||
| 18 | extern BYTE control_flag; | ||
| 19 | extern BYTE control_flag2; | ||
| 20 | extern BYTE far *buf_pointer; | ||
| 21 | extern unsigned src_file_handle; | ||
| 22 | extern struct FileFindBuf filefindbuf; | ||
| 23 | extern struct subst_list sublist; /*;AN000;6 Message substitution list */ | ||
| 24 | |||
| 25 | /***************** START OF SPECIFICATION *********************************/ | ||
| 26 | /* */ | ||
| 27 | /* SUBROUTINE NAME : search_src_disk_old */ | ||
| 28 | /* */ | ||
| 29 | /* DESCRIPTIVE NAME : For old format only, search the entire disk for */ | ||
| 30 | /* matching files. */ | ||
| 31 | /* */ | ||
| 32 | /* FUNCTION: Using find first and find next to find all the files */ | ||
| 33 | /* which match the filename specified in the input */ | ||
| 34 | /* cammand line. */ | ||
| 35 | /* */ | ||
| 36 | /* Whenever there is a file found, subroutine filespecmatch */ | ||
| 37 | /* is called to match the file path, and file extension. */ | ||
| 38 | /* If file path and file extension match the specification, */ | ||
| 39 | /* subroutine switchmatch is called to match the file */ | ||
| 40 | /* attributes, file modes, time, and date, then file sequence */ | ||
| 41 | /* number is checked. */ | ||
| 42 | /* */ | ||
| 43 | /* If the file matches all the specification, subroutine */ | ||
| 44 | /* restore_a_file is called to actually restore the file. */ | ||
| 45 | /* */ | ||
| 46 | /* */ | ||
| 47 | /********************** END OF SPECIFICATIONS *******************************/ | ||
| 48 | void search_src_disk_old(dinfo,finfo,dheadold,dheadnew,fheadnew, /* wrw! */ | ||
| 49 | srcd,destd,buf_size,dnumwant, | ||
| 50 | inpath,infname,infext,infspec,td) | ||
| 51 | |||
| 52 | struct disk_info *dinfo; | ||
| 53 | struct file_info *finfo; | ||
| 54 | struct disk_header_old *dheadold; | ||
| 55 | struct file_header_new far *fheadnew; | ||
| 56 | struct disk_header_new far *dheadnew; | ||
| 57 | BYTE srcd; | ||
| 58 | BYTE destd; | ||
| 59 | unsigned long buf_size; | ||
| 60 | unsigned int *dnumwant; | ||
| 61 | unsigned char *inpath; | ||
| 62 | unsigned char *infname; | ||
| 63 | unsigned char *infext; | ||
| 64 | unsigned char *infspec; | ||
| 65 | struct timedate *td; | ||
| 66 | |||
| 67 | { | ||
| 68 | BYTE outstring[MAXPATH+MAXFSPEC]; | ||
| 69 | WORD file_seq_num=1; | ||
| 70 | WORD first_file_on_diskette = TRUE; | ||
| 71 | WORD first_time_in_loop = TRUE; | ||
| 72 | WORD return_code; | ||
| 73 | DWORD partsize; | ||
| 74 | unsigned int control_bufsize; | ||
| 75 | BYTE temp_fname[MAXFNAME]; | ||
| 76 | BYTE temp_path[MAXPATH]; | ||
| 77 | WORD temp_dirhandle; | ||
| 78 | |||
| 79 | |||
| 80 | /*declaration for dosfindfirst */ | ||
| 81 | unsigned dirhandle = 0xffff; /* directory handle */ | ||
| 82 | unsigned search_cnt = 1; /* # of entries to find */ | ||
| 83 | unsigned buf_len = sizeof(struct FileFindBuf); | ||
| 84 | BYTE search_string[MAXPATHF+2]; | ||
| 85 | WORD retcode; | ||
| 86 | /*end decleration for ffirst and fnext*/ | ||
| 87 | union REGS qregs; /*;AN000;8*/ | ||
| 88 | int x; /*;AN000;8*/ | ||
| 89 | |||
| 90 | /*************************************************************************/ | ||
| 91 | /* FIND THE FIRST FILE ON SOURCE */ | ||
| 92 | /*************************************************************************/ | ||
| 93 | search_string[0] = srcd; | ||
| 94 | search_string[1] = ':'; | ||
| 95 | search_string[2] = NULLC; | ||
| 96 | strcat(search_string, infname); | ||
| 97 | strcat(search_string, ".*"); | ||
| 98 | |||
| 99 | retcode = /* Find the 1st filename that */ | ||
| 100 | DOSFINDFIRST( /* matches specified file spec*/ | ||
| 101 | ( char far * ) search_string, /* File path name */ | ||
| 102 | ( unsigned far * ) &dirhandle, /* Directory search handle */ | ||
| 103 | (unsigned) NOTV, /* Search attribute */ | ||
| 104 | (struct FileFindBuf far *) &filefindbuf, | ||
| 105 | buf_len, /* Result buffer length */ | ||
| 106 | ( unsigned far * ) &search_cnt, /* Number of entries to find */ | ||
| 107 | ( DWORD) 0 | ||
| 108 | ); | ||
| 109 | |||
| 110 | |||
| 111 | /*************************************************************************/ | ||
| 112 | /* IF CANNOT FIND ANY FILES ON SOURCE, RETURN */ | ||
| 113 | /*************************************************************************/ | ||
| 114 | if (retcode != 0) | ||
| 115 | return; | ||
| 116 | |||
| 117 | |||
| 118 | |||
| 119 | |||
| 120 | /*************************************************************************/ | ||
| 121 | /* start DO loop to find next until no more file found */ | ||
| 122 | /*************************************************************************/ | ||
| 123 | do | ||
| 124 | { | ||
| 125 | /*if the directory found is a subdirectory, find next one*/ | ||
| 126 | if((retcode = filefindbuf.attributes & 0x0010) != 0x0010) | ||
| 127 | { | ||
| 128 | /* SKIP BACKUPID */ | ||
| 129 | if (strcmp(filefindbuf.file_name,BACKUPID) != 0) | ||
| 130 | { | ||
| 131 | if (first_time_in_loop == FALSE) | ||
| 132 | DOSCLOSE(src_file_handle); | ||
| 133 | else | ||
| 134 | first_time_in_loop = FALSE; | ||
| 135 | |||
| 136 | /*************************************************************************/ | ||
| 137 | /*check_flheader_old: open and read file header, */ | ||
| 138 | /*************************************************************************/ | ||
| 139 | strcpy(temp_fname,filefindbuf.file_name); | ||
| 140 | retcode = check_flheader_old( finfo, temp_fname, | ||
| 141 | filefindbuf.write_date, filefindbuf.write_time, | ||
| 142 | filefindbuf.attributes, filefindbuf.file_size, | ||
| 143 | file_seq_num, srcd, destd, infspec, inpath, dnumwant); | ||
| 144 | |||
| 145 | if (retcode == 0) { | ||
| 146 | |||
| 147 | /*************************/ | ||
| 148 | /* SKIP SYSTEM FILES */ | ||
| 149 | if ((set_reset_test_flag(&control_flag2,CPPC,TEST) == FALSE) && | ||
| 150 | (strcmp(finfo->fname,"IBMBIO.COM")==0 || | ||
| 151 | strcmp(finfo->fname,"IBMDOS.COM")==0 || | ||
| 152 | strcmp(finfo->fname,"COMMAND.COM")==0 )) | ||
| 153 | {} | ||
| 154 | else { | ||
| 155 | |||
| 156 | /*************************************************************************/ | ||
| 157 | /*if there is any switches set in the input line */ | ||
| 158 | /*switchmatch (this subroutine search the hard disk for the dest */ | ||
| 159 | /*************************************************************************/ | ||
| 160 | if ((set_reset_test_flag(&control_flag,SWITCHES,TEST) == FALSE) || | ||
| 161 | (set_reset_test_flag(&control_flag,SWITCHES,TEST) == TRUE && | ||
| 162 | ((retcode = switchmatch(finfo, srcd, destd, td)) == TRUE) )) { | ||
| 163 | |||
| 164 | /*************************************************************************/ | ||
| 165 | /*if dnum in fheadold.disknum is not 1 and is not in sequence, error */ | ||
| 166 | /*************************************************************************/ | ||
| 167 | if (set_reset_test_flag(&control_flag2,OUTOF_SEQ,TEST) == TRUE && | ||
| 168 | first_file_on_diskette == TRUE && finfo->dnum != 1) | ||
| 169 | {} | ||
| 170 | else | ||
| 171 | { | ||
| 172 | if (finfo->dnum != 1 || finfo->dnum != file_seq_num) | ||
| 173 | { | ||
| 174 | display_it(FILE_SEQUENCE_ERROR,STND_ERR_DEV,0,NO_RESPTYPE,(BYTE)UTIL_MSG); /*;AN000;6*/ | ||
| 175 | unexperror(FILESEQERROR); | ||
| 176 | } | ||
| 177 | /*endif*/ | ||
| 178 | /*************************************************************************/ | ||
| 179 | /* output msg to indicate which file is to be restored */ | ||
| 180 | /*************************************************************************/ | ||
| 181 | /*outstring = inpath\infspec*/ | ||
| 182 | strcpy(outstring,finfo->path); | ||
| 183 | if (strlen(finfo->path) != 1 ) | ||
| 184 | strcat(outstring,"\\"); | ||
| 185 | |||
| 186 | strcat(outstring,finfo->fname); | ||
| 187 | x = strlen(outstring); | ||
| 188 | outstring[x] = CR; /*;AN000;6*/ | ||
| 189 | outstring[x+1] = LF; /*;AN000;6*/ | ||
| 190 | outstring[x+2] = NUL; /*;AN000;6*/ | ||
| 191 | qregs.x.ax = 0x4000; /*;AN000;6*/ | ||
| 192 | qregs.x.bx = 0x0001; /*;AN000;6*/ | ||
| 193 | qregs.x.cx = (WORD)strlen(outstring); /*;AN000;6*/ | ||
| 194 | qregs.x.dx = (unsigned int)&outstring[0]; /*;AN000;6*/ | ||
| 195 | intdos(&qregs,&qregs); /*;AN000;6*/ | ||
| 196 | |||
| 197 | |||
| 198 | /*************************************************************************/ | ||
| 199 | /* call restore_a_file to restore the file */ | ||
| 200 | /*************************************************************************/ | ||
| 201 | restore_a_file(finfo,dinfo,buf_size,&control_bufsize, | ||
| 202 | fheadnew,dheadold,dheadnew, | ||
| 203 | srcd,destd,inpath,infname,infspec,dnumwant,&dirhandle); | ||
| 204 | |||
| 205 | first_file_on_diskette = FALSE; | ||
| 206 | |||
| 207 | /*************************************************************************/ | ||
| 208 | /* if the file just restored is a split file, and last file, exit loop */ | ||
| 209 | /*************************************************************************/ | ||
| 210 | if (set_reset_test_flag(&control_flag,SPLITFILE,TEST)==TRUE) | ||
| 211 | { | ||
| 212 | set_reset_test_flag(&control_flag,SPLITFILE,RESET); | ||
| 213 | |||
| 214 | if (dirhandle == 0xffff) | ||
| 215 | break; | ||
| 216 | else | ||
| 217 | { | ||
| 218 | retcode = 0; | ||
| 219 | continue; | ||
| 220 | } | ||
| 221 | } /*end of if file splitted*/ | ||
| 222 | |||
| 223 | |||
| 224 | } /*end of if disk and file out of sequence*/ | ||
| 225 | } /*end of switch match fail*/ | ||
| 226 | } /*end of PC/DOS and it is system files*/ | ||
| 227 | } /*end of if check file header is ok */ | ||
| 228 | } /*end of if file name is not BACKUPID*/ | ||
| 229 | } /*end of if the directory found is a subdirectory*/ | ||
| 230 | |||
| 231 | search_cnt = 1; | ||
| 232 | |||
| 233 | retcode = | ||
| 234 | DOSFINDNEXT | ||
| 235 | (dirhandle, | ||
| 236 | (struct FileFindBuf far *)&filefindbuf, | ||
| 237 | buf_len, | ||
| 238 | (unsigned far *)&search_cnt | ||
| 239 | ); | ||
| 240 | |||
| 241 | } | ||
| 242 | while(retcode == 0); /* END MAIN DO LOOP */ | ||
| 243 | |||
| 244 | DOSCLOSE(src_file_handle); | ||
| 245 | /*************************************************************************/ | ||
| 246 | /* if error during findnext, error exit */ | ||
| 247 | /*************************************************************************/ | ||
| 248 | if (retcode != ERROR_NO_MORE_FILES && retcode != 0) | ||
| 249 | { | ||
| 250 | com_msg(retcode); | ||
| 251 | unexperror(retcode); | ||
| 252 | } | ||
| 253 | |||
| 254 | |||
| 255 | if (dirhandle != 0xffff) | ||
| 256 | { | ||
| 257 | if ((retcode = DOSFINDCLOSE(dirhandle)) != 0) | ||
| 258 | { | ||
| 259 | com_msg(retcode); | ||
| 260 | unexperror(retcode); | ||
| 261 | } | ||
| 262 | } | ||
| 263 | |||
| 264 | |||
| 265 | return; | ||
| 266 | } /*end of subroutine*/ | ||
diff --git a/v4.0/src/CMD/RESTORE/RTOLD1.C b/v4.0/src/CMD/RESTORE/RTOLD1.C new file mode 100644 index 0000000..25df45c --- /dev/null +++ b/v4.0/src/CMD/RESTORE/RTOLD1.C | |||
| @@ -0,0 +1,657 @@ | |||
| 1 | |||
| 2 | /*------------------------------- | ||
| 3 | /* SOURCE FILE NAME: RTOLD1.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 "string.h" | ||
| 12 | #include "dos.h" /*;AN000;2*/ | ||
| 13 | #include "comsub.h" /* common subroutine def'n */ | ||
| 14 | #include "doscalls.h" | ||
| 15 | #include "error.h" | ||
| 16 | #include "stdio.h" | ||
| 17 | |||
| 18 | extern BYTE rtswitch; | ||
| 19 | extern BYTE control_flag; | ||
| 20 | extern BYTE control_flag2; | ||
| 21 | extern char far *buf_pointer; | ||
| 22 | extern unsigned src_file_handle; | ||
| 23 | extern struct FileFindBuf filefindbuf; | ||
| 24 | extern struct FileFindBuf dfilefindbuf; | ||
| 25 | BYTE src_fname[MAXFNAME]; | ||
| 26 | extern struct subst_list sublist; /*;AN000;6 Message substitution list */ | ||
| 27 | extern char response_buff[5]; /*;AN000;6*/ | ||
| 28 | struct file_header_old fheadold; /*;AN000;*/ | ||
| 29 | |||
| 30 | /***************** START OF SPECIFICATION ******************************** | ||
| 31 | /* | ||
| 32 | /* SUBROUTINE NAME : pathmatch | ||
| 33 | /* | ||
| 34 | /* DESCRIPTIVE NAME : Compare two paths and return TRUE or FALSE | ||
| 35 | /* according to whether they match or not. | ||
| 36 | /* | ||
| 37 | /* NOTES: Global characters * and ? are meaningless in the file path name | ||
| 38 | /* Assume both path pattern and path subject are not end with \ | ||
| 39 | /* | ||
| 40 | /* INPUT: (PARAMETERS) | ||
| 41 | /* subject - the file path to be compared. | ||
| 42 | /* pattern - the file path to be compared against. | ||
| 43 | /* | ||
| 44 | /********************** END OF SPECIFICATIONS *******************************/ | ||
| 45 | WORD pathmatch(patterns,subjects) | ||
| 46 | |||
| 47 | BYTE *patterns; /* the string to be matched with */ | ||
| 48 | BYTE *subjects; /* the string to be matched */ | ||
| 49 | { | ||
| 50 | BYTE *pattern; /* the working pointer to point to the pattern */ | ||
| 51 | BYTE *subject; /* the working pointer to point to the subject */ | ||
| 52 | int z; | ||
| 53 | |||
| 54 | /*save the pointers to both strings*/ | ||
| 55 | pattern = patterns; | ||
| 56 | subject = subjects; | ||
| 57 | |||
| 58 | /* loop until matched or unmatched is determined */ | ||
| 59 | for (;;) | ||
| 60 | { | ||
| 61 | if (*pattern == *subject) | ||
| 62 | { | ||
| 63 | if (*pattern != NULLC) /* not finish scanning yet*/ | ||
| 64 | { | ||
| 65 | pattern+=1; /* advance the pointer by 1 */ | ||
| 66 | subject+=1; /* advance the pointer by 1 */ | ||
| 67 | continue; /* continue on comparing again */ | ||
| 68 | } | ||
| 69 | else | ||
| 70 | return(TRUE); | ||
| 71 | } | ||
| 72 | else | ||
| 73 | { /* if subject is longer than pattern and SUB flag in rtswitches is on */ | ||
| 74 | if (set_reset_test_flag(&rtswitch, SUB, TEST)==TRUE) | ||
| 75 | { | ||
| 76 | if ((*pattern == NULLC && *subject == '\\') || | ||
| 77 | (patterns[0] == '\\' && patterns[1] == NULLC)) | ||
| 78 | return(TRUE); | ||
| 79 | else | ||
| 80 | return(FALSE); | ||
| 81 | } | ||
| 82 | else | ||
| 83 | return(FALSE); | ||
| 84 | } | ||
| 85 | } | ||
| 86 | return(TRUE); /*;AN000;*/ | ||
| 87 | } | ||
| 88 | |||
| 89 | /***************** START OF SPECIFICATION ******************************** | ||
| 90 | /* | ||
| 91 | /* SUBROUTINE NAME : fspecmatch | ||
| 92 | /* | ||
| 93 | /* DESCRIPTIVE NAME : Compare two file spec. and return TRUE or FALSE | ||
| 94 | /* according to whether they match or not. | ||
| 95 | /* | ||
| 96 | /* FUNCTION: This subroutine compare the file names and file extensions | ||
| 97 | /* to determine whether they are match or not. | ||
| 98 | /* TRUE is returned if they are match, otherwise, FALSE | ||
| 99 | /* is returned. | ||
| 100 | /* | ||
| 101 | /* NOTES: * and ? are acceptable in the file name and file extension. | ||
| 102 | /* | ||
| 103 | /********************** END OF SPECIFICATIONS *******************************/ | ||
| 104 | fspecmatch(patterns, subjects) | ||
| 105 | char *patterns; | ||
| 106 | char *subjects; | ||
| 107 | { | ||
| 108 | char *pattern; | ||
| 109 | char *subject; | ||
| 110 | int z; | ||
| 111 | |||
| 112 | pattern = patterns; | ||
| 113 | subject = subjects; | ||
| 114 | |||
| 115 | for (;;) | ||
| 116 | { | ||
| 117 | if (*pattern == '*') | ||
| 118 | { | ||
| 119 | /*advance pointer in pattern until find '.' or nullc*/ | ||
| 120 | for (;*pattern != '.' && *pattern != NULLC; ++pattern); | ||
| 121 | if (*pattern == NULLC) | ||
| 122 | { | ||
| 123 | |||
| 124 | /* pattern has no extension, so make sure subject doesn't either */ | ||
| 125 | /* find end or '.' in subject */ | ||
| 126 | |||
| 127 | for (;*subject != '.' && *subject != NULLC; ++subject); | ||
| 128 | |||
| 129 | if (*subject == NULLC || *(subject+1) == '.') | ||
| 130 | return(TRUE); | ||
| 131 | else /* subject has extension, so return FALSE */ | ||
| 132 | return(FALSE); | ||
| 133 | } | ||
| 134 | else | ||
| 135 | { | ||
| 136 | if ( *(pattern+1) == '*') | ||
| 137 | return(TRUE); | ||
| 138 | else | ||
| 139 | { | ||
| 140 | /*advance pointer in subject until find '.' or nullc*/ | ||
| 141 | for (;*subject != '.' && *subject != NULLC; ++subject); | ||
| 142 | if (*subject == NULLC ) | ||
| 143 | { | ||
| 144 | if (*(pattern+1) != NULLC) | ||
| 145 | return(FALSE); | ||
| 146 | else | ||
| 147 | return(TRUE); | ||
| 148 | } | ||
| 149 | else | ||
| 150 | { | ||
| 151 | pattern+=1; | ||
| 152 | subject+=1; | ||
| 153 | continue; | ||
| 154 | } /*end of if *subject is not NULL*/ | ||
| 155 | } /*end of if *(pattern+1) is not '*' */ | ||
| 156 | } /*end of if *pattern == NULLC */ | ||
| 157 | } | ||
| 158 | else | ||
| 159 | { | ||
| 160 | if (*pattern == *subject || *pattern == '?') | ||
| 161 | { | ||
| 162 | if (*pattern != NULLC) | ||
| 163 | { | ||
| 164 | pattern+=1; | ||
| 165 | subject+=1; | ||
| 166 | continue; | ||
| 167 | } | ||
| 168 | else | ||
| 169 | return(TRUE); | ||
| 170 | } | ||
| 171 | else | ||
| 172 | if (*pattern == '.' && *(pattern+1) == '*' && *subject == NULLC) | ||
| 173 | return(TRUE); | ||
| 174 | else | ||
| 175 | return(FALSE); | ||
| 176 | } | ||
| 177 | |||
| 178 | } /*end of for loop*/ | ||
| 179 | |||
| 180 | } /*end of subroutine */ | ||
| 181 | |||
| 182 | /***************** START OF SPECIFICATION ******************************** | ||
| 183 | /* | ||
| 184 | /* SUBROUTINE NAME : switchmatch | ||
| 185 | /* | ||
| 186 | /* DESCRIPTIVE NAME : Check the file attributes, and/or file modes | ||
| 187 | /* against the switches set in the input command | ||
| 188 | /* line. | ||
| 189 | /* | ||
| 190 | /* FUNCTION: this subroutine search the hard disk for the dest | ||
| 191 | /* file first. If dest file is found, the attributs of the | ||
| 192 | /* destination file will be used for checking. | ||
| 193 | /* | ||
| 194 | /* Check the switches set in the input command line one by | ||
| 195 | /* one, whenever a switch not match is found, FALSE is returne | ||
| 196 | /* In the case a switch is match, TRUE is not returned until al | ||
| 197 | /* switches is checked. | ||
| 198 | /* | ||
| 199 | /* | ||
| 200 | /********************** END OF SPECIFICATIONS *******************************/ | ||
| 201 | WORD switchmatch(finfo, srcd, destd, td) | ||
| 202 | struct file_info *finfo; | ||
| 203 | BYTE srcd; | ||
| 204 | BYTE destd; | ||
| 205 | struct timedate *td; | ||
| 206 | { | ||
| 207 | WORD yy; | ||
| 208 | WORD mm; | ||
| 209 | WORD dd; | ||
| 210 | WORD hh; | ||
| 211 | WORD mn; | ||
| 212 | WORD ss; | ||
| 213 | WORD action; | ||
| 214 | unsigned file_pointer; | ||
| 215 | WORD retcode; | ||
| 216 | int z; | ||
| 217 | |||
| 218 | /*declaration for dosqfileinfo*/ | ||
| 219 | struct FileStatus fileinfo_buf; | ||
| 220 | WORD destdnum; | ||
| 221 | WORD buflen = sizeof(struct FileStatus); | ||
| 222 | unsigned attributes; | ||
| 223 | |||
| 224 | /*declaration for dosfindfirst */ | ||
| 225 | unsigned ddirhandle = 0xffff; | ||
| 226 | unsigned attribute = NOTV; | ||
| 227 | unsigned search_cnt = 1; | ||
| 228 | unsigned buf_len = sizeof(struct FileFindBuf); | ||
| 229 | BYTE search_string[MAXPATHF+2]; | ||
| 230 | /*end decleration for ffirst and fnext*/ | ||
| 231 | |||
| 232 | /***********************************************************************/ | ||
| 233 | /* Search hard file for the path and name of file about to be restored */ | ||
| 234 | /* and get the file information of the file on the hard disk */ | ||
| 235 | /***********************************************************************/ | ||
| 236 | search_string[0] = destd; | ||
| 237 | search_string[1] = ':'; | ||
| 238 | search_string[2] = NULLC; | ||
| 239 | strcat(search_string, finfo->path); | ||
| 240 | if (strlen(finfo->path) != 1) | ||
| 241 | strcat(search_string, "\\"); | ||
| 242 | strcat(search_string, finfo->fname); | ||
| 243 | |||
| 244 | retcode = DOSOPEN( (char far *)&search_string[0], | ||
| 245 | (unsigned far *)&file_pointer, | ||
| 246 | (unsigned far *)&action, | ||
| 247 | (DWORD)0, /*file size*/ | ||
| 248 | 0, /*file attribute*/ | ||
| 249 | 0x01, /*if file exist, open*/ | ||
| 250 | /*if file not exist, fail*/ | ||
| 251 | 0x00c0, /*deny write, read write access*/ | ||
| 252 | (DWORD)0 ); /*reserved*/ | ||
| 253 | /***********************************************************************/ | ||
| 254 | /*if open fail (means the file does not exist on the hard disk), then */ | ||
| 255 | /* return true */ | ||
| 256 | /***********************************************************************/ | ||
| 257 | if (retcode != NOERROR) { | ||
| 258 | /*set flag CREATIT*/ | ||
| 259 | set_reset_test_flag(&control_flag,CREATIT,SET); | ||
| 260 | /*return TRUE*/ | ||
| 261 | return (TRUE); | ||
| 262 | } | ||
| 263 | /*********************************************************************/ | ||
| 264 | /* call DosQFileInfo: Request date and time of the dest file */ | ||
| 265 | /*********************************************************************/ | ||
| 266 | retcode = DOSQFILEINFO ( | ||
| 267 | (unsigned)file_pointer, /* File handle */ | ||
| 268 | (unsigned)1, /* File info data required */ | ||
| 269 | (char far *)&fileinfo_buf, /* File info buffer */ | ||
| 270 | (unsigned)buflen); /* File info buffer size */ | ||
| 271 | |||
| 272 | |||
| 273 | if (retcode != NOERROR) { | ||
| 274 | com_msg(retcode); | ||
| 275 | unexperror(retcode); | ||
| 276 | } | ||
| 277 | |||
| 278 | if ((retcode = DOSQFILEMODE((char far *)&search_string[0], | ||
| 279 | (unsigned far *) &attributes, | ||
| 280 | (DWORD) 0)) !=0) { | ||
| 281 | com_msg(retcode); | ||
| 282 | unexperror(retcode); | ||
| 283 | } | ||
| 284 | |||
| 285 | |||
| 286 | DOSCLOSE(file_pointer); | ||
| 287 | /***********************************************************************/ | ||
| 288 | /*if NOTEXIST flag is on */ | ||
| 289 | /***********************************************************************/ | ||
| 290 | if (set_reset_test_flag(&rtswitch,NOTEXIST,TEST) == TRUE) { | ||
| 291 | return(FALSE); | ||
| 292 | } | ||
| 293 | |||
| 294 | /***********************************************************************/ | ||
| 295 | /*if BEFORE or AFTER is on, convert date into integer form */ | ||
| 296 | /***********************************************************************/ | ||
| 297 | if (set_reset_test_flag(&rtswitch,BEFORE,TEST) == TRUE || | ||
| 298 | set_reset_test_flag(&rtswitch,AFTER,TEST) == TRUE ) { | ||
| 299 | /*convert the input date into correct numbers.*/ | ||
| 300 | /*Both new and old format have date in the form of date returned from*/ | ||
| 301 | /*ffirst*/ | ||
| 302 | /*the input date is in the form of: yyyyyyymmmmddddd*/ | ||
| 303 | yy = (fileinfo_buf.write_date >> YRSHIFT & YRMASK) + LOYR; | ||
| 304 | mm = fileinfo_buf.write_date >> MOSHIFT & MOMASK; | ||
| 305 | dd = fileinfo_buf.write_date & DYMASK; | ||
| 306 | } | ||
| 307 | /*endif*/ | ||
| 308 | |||
| 309 | /***********************************************************************/ | ||
| 310 | /*if BEFORE flag is on */ | ||
| 311 | /***********************************************************************/ | ||
| 312 | if (set_reset_test_flag(&rtswitch,BEFORE,TEST) == TRUE) { | ||
| 313 | if ( yy > td->before_year ) { | ||
| 314 | return(FALSE); | ||
| 315 | } | ||
| 316 | |||
| 317 | if (yy == td->before_year && mm > td->before_month) { | ||
| 318 | return(FALSE); | ||
| 319 | } | ||
| 320 | |||
| 321 | if (yy == td->before_year && mm == td->before_month && | ||
| 322 | dd > td->before_day) { | ||
| 323 | return(FALSE); | ||
| 324 | } | ||
| 325 | } | ||
| 326 | /*endif*/ | ||
| 327 | |||
| 328 | /***********************************************************************/ | ||
| 329 | /*if AFTER flag is on */ | ||
| 330 | /***********************************************************************/ | ||
| 331 | if (set_reset_test_flag(&rtswitch,AFTER,TEST) == TRUE) { | ||
| 332 | if (yy < td->after_year ) { | ||
| 333 | return(FALSE); | ||
| 334 | } | ||
| 335 | |||
| 336 | if (yy == td->after_year && mm < td->after_month) { | ||
| 337 | return(FALSE); | ||
| 338 | } | ||
| 339 | |||
| 340 | if (yy == td->after_year && mm == td->after_month && dd < td->after_day) { | ||
| 341 | return(FALSE); | ||
| 342 | } | ||
| 343 | } | ||
| 344 | /*endif*/ | ||
| 345 | |||
| 346 | /***********************************************************************/ | ||
| 347 | /*if EARLIER or LATER is on, convert date time into integer form */ | ||
| 348 | /***********************************************************************/ | ||
| 349 | if (set_reset_test_flag(&rtswitch,EARLIER,TEST) == TRUE || | ||
| 350 | set_reset_test_flag(&rtswitch,LATER,TEST) == TRUE) { | ||
| 351 | /* convert the input time into correct numbers. */ | ||
| 352 | /* Both new and old format have time in the form of date returned */ | ||
| 353 | /* from ffirst. */ | ||
| 354 | /* the input time is in the form of: hhhhhmmmmmmsssss */ | ||
| 355 | hh = fileinfo_buf.write_time >> HRSHIFT & HRMASK; | ||
| 356 | mn = fileinfo_buf.write_time >> MNSHIFT & MNMASK; | ||
| 357 | ss = fileinfo_buf.write_time & SCMASK; | ||
| 358 | } | ||
| 359 | /*endif*/ | ||
| 360 | |||
| 361 | /***********************************************************************/ | ||
| 362 | /*if EARLIER flag is on */ | ||
| 363 | /***********************************************************************/ | ||
| 364 | if (set_reset_test_flag(&rtswitch,EARLIER,TEST) == TRUE) { | ||
| 365 | if (hh > td->earlier_hour) { | ||
| 366 | return(FALSE); | ||
| 367 | } | ||
| 368 | |||
| 369 | if (hh == td->earlier_hour && mn > td->earlier_minute) { | ||
| 370 | return(FALSE); | ||
| 371 | } | ||
| 372 | |||
| 373 | if (hh == td->earlier_hour && mn == td->earlier_minute && | ||
| 374 | ss > td->earlier_second) { | ||
| 375 | return(FALSE); | ||
| 376 | } | ||
| 377 | } | ||
| 378 | /*endif*/ | ||
| 379 | |||
| 380 | /***********************************************************************/ | ||
| 381 | /*if LATER flag is on */ | ||
| 382 | /***********************************************************************/ | ||
| 383 | if (set_reset_test_flag(&rtswitch,LATER,TEST) == TRUE) { | ||
| 384 | if (hh < td->later_hour) { | ||
| 385 | return(FALSE); | ||
| 386 | } | ||
| 387 | |||
| 388 | if (hh == td->later_hour && mn < td->later_minute) { | ||
| 389 | return(FALSE); | ||
| 390 | } | ||
| 391 | |||
| 392 | if (hh == td->later_hour && mn == td->later_minute && | ||
| 393 | ss < td->later_second) { | ||
| 394 | return(FALSE); | ||
| 395 | } | ||
| 396 | } | ||
| 397 | /*endif*/ | ||
| 398 | |||
| 399 | /*************************************************************************/ | ||
| 400 | /* if Revised flag is on and fileinfo->attrib indicate file has not */ | ||
| 401 | /* been Revised, return FALSE */ | ||
| 402 | /*************************************************************************/ | ||
| 403 | if (set_reset_test_flag(&rtswitch,Revised,TEST) == TRUE) { | ||
| 404 | if((retcode = attributes & 0x0020) != 0x0020) { | ||
| 405 | return(FALSE); | ||
| 406 | } | ||
| 407 | } | ||
| 408 | /*endif*/ | ||
| 409 | |||
| 410 | /***********************************************************************/ | ||
| 411 | /* if PROMPT and fileinfo->file_attrib indicate READONLY, or CHANGED*/ | ||
| 412 | /***********************************************************************/ | ||
| 413 | if ((set_reset_test_flag(&rtswitch,PROMPT,TEST) == TRUE) && | ||
| 414 | (((retcode = attributes & 0x0001) == 0x0001) || | ||
| 415 | ((retcode = attributes & 0x0020) == 0x0020) )) | ||
| 416 | { | ||
| 417 | /*call subroutine to ask whether the user really wants to restore */ | ||
| 418 | retcode = readonly_or_changed(attributes,destd,finfo->fname,finfo->path); | ||
| 419 | if (retcode == FALSE) { | ||
| 420 | return(FALSE); | ||
| 421 | } | ||
| 422 | /*endif*/ | ||
| 423 | } | ||
| 424 | /*endif*/ | ||
| 425 | |||
| 426 | /***********************************************************************/ | ||
| 427 | /* if pass all the switch testing, return TRUE */ | ||
| 428 | /***********************************************************************/ | ||
| 429 | return(TRUE); | ||
| 430 | |||
| 431 | } /*end of subroutine switch_match */ | ||
| 432 | |||
| 433 | /***************** START OF SPECIFICATION ******************************** | ||
| 434 | /* | ||
| 435 | /* SUBROUTINE NAME : check_flheader_old | ||
| 436 | /* | ||
| 437 | /* DESCRIPTIVE NAME : Check the information in the file header of | ||
| 438 | /* the file to be restored. | ||
| 439 | /* | ||
| 440 | /* FUNCTION: For old format only, Open the file to be restored, get | ||
| 441 | /* header informtion | ||
| 442 | /* | ||
| 443 | /* | ||
| 444 | /********************** END OF SPECIFICATIONS *******************************/ | ||
| 445 | int check_flheader_old | ||
| 446 | ( finfo,f_name,f_date,f_time,f_attrib,f_len, | ||
| 447 | file_seq_num,srcd,destd,infspec,inpath,dnumwant | ||
| 448 | ) | ||
| 449 | |||
| 450 | struct file_info *finfo; | ||
| 451 | unsigned char *f_name; /* name string */ | ||
| 452 | unsigned f_date; /* file's date */ | ||
| 453 | unsigned f_time; /* file's time */ | ||
| 454 | unsigned f_attrib; /* file's attribute */ | ||
| 455 | unsigned long f_len; /* file length */ | ||
| 456 | unsigned int file_seq_num; | ||
| 457 | BYTE srcd; | ||
| 458 | BYTE destd; | ||
| 459 | BYTE *infspec; | ||
| 460 | BYTE *inpath; | ||
| 461 | unsigned int *dnumwant; | ||
| 462 | { | ||
| 463 | WORD temp_dnumwant; | ||
| 464 | WORD numread; | ||
| 465 | WORD action; | ||
| 466 | BYTE file_to_be_opened[15]; | ||
| 467 | BYTE string_to_be_separate[79]; | ||
| 468 | BYTE path[65]; | ||
| 469 | BYTE name[9]; | ||
| 470 | BYTE ext[4]; | ||
| 471 | BYTE spec[13]; | ||
| 472 | WORD i; /*loop counter*/ | ||
| 473 | WORD retcode; | ||
| 474 | int z; | ||
| 475 | |||
| 476 | temp_dnumwant = *dnumwant; /*to fix a bug that dosread change the | ||
| 477 | value of dnumwant */ | ||
| 478 | |||
| 479 | |||
| 480 | /***********************************************************************/ | ||
| 481 | /*open the file to be restored as deny write and read access */ | ||
| 482 | /***********************************************************************/ | ||
| 483 | strcpy(src_fname,f_name); | ||
| 484 | file_to_be_opened[0] = srcd; | ||
| 485 | file_to_be_opened[1] = ':'; | ||
| 486 | file_to_be_opened[2] = NULLC; | ||
| 487 | strcat(file_to_be_opened,f_name); | ||
| 488 | retcode = DOSOPEN( (char far *)&file_to_be_opened[0], | ||
| 489 | (unsigned far *)&src_file_handle, | ||
| 490 | (unsigned far *)&action, | ||
| 491 | (DWORD)0, /*file size*/ | ||
| 492 | 0, /*file attribute*/ | ||
| 493 | 0x01, /*if file exist, open it*/ | ||
| 494 | /*if file not exist, fail it*/ | ||
| 495 | 0x00c0, /*deny write, read only*/ | ||
| 496 | (DWORD)0 ); /*reserved*/ | ||
| 497 | |||
| 498 | /*if open fail*/ | ||
| 499 | if (retcode != 0) { | ||
| 500 | /****not able to restore the file****/ | ||
| 501 | display_it(NOT_ABLE_TO_RESTORE_FILE,STND_ERR_DEV,0,NO_RESPTYPE,(BYTE)UTIL_MSG); /*;AN000;6*/ | ||
| 502 | unexperror(retcode); | ||
| 503 | } | ||
| 504 | /*endif*/ | ||
| 505 | |||
| 506 | /***********************************************************************/ | ||
| 507 | /*read 128 bytes header information from the file into fheadold */ | ||
| 508 | /***********************************************************************/ | ||
| 509 | retcode = DOSREAD( src_file_handle, | ||
| 510 | (char far *)&fheadold, | ||
| 511 | HEADLEN, | ||
| 512 | (unsigned far *)&numread); | ||
| 513 | /*if read fail*/ | ||
| 514 | if (retcode != 0 ) | ||
| 515 | { | ||
| 516 | display_it(NOT_ABLE_TO_RESTORE_FILE,STND_ERR_DEV,0,NO_RESPTYPE,(BYTE)UTIL_MSG); /*;AN000;6*/ | ||
| 517 | unexperror(retcode); | ||
| 518 | } | ||
| 519 | /*end of if read fail */ | ||
| 520 | |||
| 521 | /*if the number of read is less than HEADLEN, return FALSE */ | ||
| 522 | if (numread != HEADLEN) | ||
| 523 | return(FALSE); | ||
| 524 | |||
| 525 | /* save disk number */ | ||
| 526 | finfo->dnum = fheadold.disknum[1]* 10 + fheadold.disknum[0]; | ||
| 527 | |||
| 528 | if (fheadold.wherefrom[0] != '\\') | ||
| 529 | return(FALSE); | ||
| 530 | strcpy(string_to_be_separate,fheadold.wherefrom); | ||
| 531 | separate(string_to_be_separate,path,name,ext,spec); | ||
| 532 | |||
| 533 | /***********************************************************************/ | ||
| 534 | /* match the path and file spec. */ | ||
| 535 | /***********************************************************************/ | ||
| 536 | if | ||
| 537 | ( pathmatch(inpath,path) == FALSE || | ||
| 538 | fspecmatch(infspec,spec) == FALSE | ||
| 539 | ) | ||
| 540 | { | ||
| 541 | *dnumwant = temp_dnumwant; | ||
| 542 | return(FALSE); | ||
| 543 | } | ||
| 544 | |||
| 545 | /***********************************************************************/ | ||
| 546 | /*Store some information from filefindbuf into finfo */ | ||
| 547 | /***********************************************************************/ | ||
| 548 | finfo->ftime = f_time; | ||
| 549 | finfo->fdate = f_date; | ||
| 550 | finfo->attrib = f_attrib; | ||
| 551 | finfo->partsize = f_len; | ||
| 552 | |||
| 553 | /***********************************************************************/ | ||
| 554 | /*Store filename and path information from fheadold into finfo */ | ||
| 555 | /***********************************************************************/ | ||
| 556 | strcpy(finfo->fname,spec); | ||
| 557 | strcpy(finfo->path,path); | ||
| 558 | |||
| 559 | /***********************************************************************/ | ||
| 560 | /* store some other information from fheadold to finfo */ | ||
| 561 | /***********************************************************************/ | ||
| 562 | if (fheadold.headflg == 0xff) | ||
| 563 | finfo->fflag= LAST_PART; | ||
| 564 | else | ||
| 565 | finfo->fflag= 0; | ||
| 566 | |||
| 567 | *dnumwant = temp_dnumwant; | ||
| 568 | return(TRUE); | ||
| 569 | |||
| 570 | /*return nothing*/ | ||
| 571 | |||
| 572 | } /*end of subroutine*/ | ||
| 573 | |||
| 574 | |||
| 575 | /***************** START OF SPECIFICATION ******************************** | ||
| 576 | /* | ||
| 577 | /* SUBROUTINE NAME : readonly_or_changed | ||
| 578 | /* | ||
| 579 | /* DESCRIPTIVE NAME : handle the situration that a read only file | ||
| 580 | /* or is found, or the file has been Revised. | ||
| 581 | /* | ||
| 582 | /* FUNCTION: In the case that a readonly file is found, or the file | ||
| 583 | /* on the destination disk has been Revised since last backup, | ||
| 584 | /* this subroutine output a warning message to the user, and | ||
| 585 | /* prompt for user to enter yes or no depending on whether | ||
| 586 | /* the user wants to proceed restoring the file. | ||
| 587 | /* | ||
| 588 | /* | ||
| 589 | /********************* END OF SPECIFICATIONS ********************************/ | ||
| 590 | #define CHECK_YES_NO 0x6523 /*;AN000;6*/ | ||
| 591 | #define YES_NO_RESPTYPE 0xc1 /*;AN000;6*/ | ||
| 592 | #define YES 1 /*;AN000;6*/ | ||
| 593 | |||
| 594 | int readonly_or_changed(attrib,destd,fspec,fpath) | ||
| 595 | |||
| 596 | unsigned attrib; | ||
| 597 | unsigned char destd; | ||
| 598 | unsigned char *fspec; | ||
| 599 | unsigned char *fpath; | ||
| 600 | { | ||
| 601 | |||
| 602 | union REGS inregs, outregs; /*;AN000;6 Register set */ | ||
| 603 | WORD retcode; | ||
| 604 | |||
| 605 | char file_to_be_chmode[MAXPATHF+2]; | ||
| 606 | DWORD dw = 0L; | ||
| 607 | int z; | ||
| 608 | |||
| 609 | sublist.value1 = (char far *)fspec; /*;AN000;6 */ | ||
| 610 | sublist.flags1 = LEFT_ALIGN + CHAR_FIELD_ASCIIZ; /*;AN000;6 */ | ||
| 611 | sublist.max_width1 = (BYTE)strlen(fspec); /*;AN000;6 */ | ||
| 612 | sublist.min_width1 = sublist.max_width1; /*;AN000;6 */ | ||
| 613 | |||
| 614 | /***********************************************************************/ | ||
| 615 | /* if readonly, output msg and wait for user's prompt */ | ||
| 616 | /***********************************************************************/ | ||
| 617 | do /*;AN000;6*/ | ||
| 618 | { /*;AN000;6*/ | ||
| 619 | if((retcode = attrib & 0x0001) == 0x0001) | ||
| 620 | display_it(FILE_IS_READONLY,STND_ERR_DEV,1,YES_NO_RESPTYPE,(BYTE)UTIL_MSG); /*;AN000;6*/ | ||
| 621 | else | ||
| 622 | display_it(FILE_WAS_CHANGED,STND_ERR_DEV,1,YES_NO_RESPTYPE,(BYTE)UTIL_MSG); /*;AN000;6*/ | ||
| 623 | |||
| 624 | |||
| 625 | inregs.x.ax = (unsigned)CHECK_YES_NO; /*;AN000;6*/ | ||
| 626 | inregs.h.dl = response_buff[0]; /*;AN000;6*/ | ||
| 627 | int86(0x21,&inregs,&outregs); /*;AN000;6*/ | ||
| 628 | display_it(CRLF,STND_ERR_DEV,0,NO_RESPTYPE,(BYTE)UTIL_MSG); /*;AN000;6*/ | ||
| 629 | } /*;AN000;6*/ | ||
| 630 | while (outregs.h.al > 1); /*;AN000;6*/ | ||
| 631 | |||
| 632 | /***********************************************************************/ | ||
| 633 | /* if user's input is 'Y', return TRUE, else return FALSE */ | ||
| 634 | /***********************************************************************/ | ||
| 635 | if (outregs.x.ax == YES) /*;AN000;6*/ | ||
| 636 | { file_to_be_chmode[0] = destd; | ||
| 637 | file_to_be_chmode[1] = ':'; | ||
| 638 | file_to_be_chmode[2] = NULLC; | ||
| 639 | strcat(file_to_be_chmode,fpath); | ||
| 640 | if (strlen(fpath) != 1) { | ||
| 641 | strcat(file_to_be_chmode,"\\"); | ||
| 642 | } | ||
| 643 | strcat(file_to_be_chmode,fspec); | ||
| 644 | /* change the file attribute to be 0, that is, reset it */ | ||
| 645 | if ((retcode = DOSSETFILEMODE((char far *)file_to_be_chmode,(unsigned) 0x00, dw)) != 0) | ||
| 646 | { | ||
| 647 | com_msg(retcode); | ||
| 648 | unexperror(retcode); | ||
| 649 | } | ||
| 650 | return(TRUE); | ||
| 651 | } | ||
| 652 | else { | ||
| 653 | return(FALSE); | ||
| 654 | } | ||
| 655 | /* endif */ | ||
| 656 | } /* end of subroutine readonly_or_changed */ | ||
| 657 | |||
diff --git a/v4.0/src/CMD/RESTORE/RTT.C b/v4.0/src/CMD/RESTORE/RTT.C new file mode 100644 index 0000000..d581d30 --- /dev/null +++ b/v4.0/src/CMD/RESTORE/RTT.C | |||
| @@ -0,0 +1,409 @@ | |||
| 1 | static char *SCCSID = "@(#)rtt.c 8.1 86/09/20"; | ||
| 2 | |||
| 3 | /* 0 */ | ||
| 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*/ | ||
diff --git a/v4.0/src/CMD/RESTORE/RTT1.C b/v4.0/src/CMD/RESTORE/RTT1.C new file mode 100644 index 0000000..7b75f75 --- /dev/null +++ b/v4.0/src/CMD/RESTORE/RTT1.C | |||
| @@ -0,0 +1,79 @@ | |||
| 1 | |||
| 2 | /*---------------------------- | ||
| 3 | /* SOURCE FILE NAME: RTT1.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 "dos.h" /*;AN000;2*/ | ||
| 12 | #include "comsub.h" /* common subroutine def'n */ | ||
| 13 | #include "doscalls.h" | ||
| 14 | #include "error.h" | ||
| 15 | |||
| 16 | extern BYTE destddir[MAXPATH+3]; | ||
| 17 | extern BYTE srcddir[MAXPATH+3]; | ||
| 18 | extern BYTE rtswitch; | ||
| 19 | extern BYTE control_flag; | ||
| 20 | extern BYTE control_flag2; | ||
| 21 | extern BYTE filename[12]; | ||
| 22 | extern unsigned control_file_handle; /* !wrw */ | ||
| 23 | extern BYTE append_indicator; /*;AN000;2*/ | ||
| 24 | extern WORD original_append_func; /*;AN000;2*/ | ||
| 25 | |||
| 26 | /*************************************************/ | ||
| 27 | /* | ||
| 28 | /* SUBROUTINE NAME: check_appendX | ||
| 29 | /* | ||
| 30 | /* FUNCTION: | ||
| 31 | /* Check APPEND /X status. If it is not active, | ||
| 32 | /* do nothing. If it is active, then turn it off | ||
| 33 | /* and set flag indicating that we must reset it later. | ||
| 34 | /* | ||
| 35 | /***************************************************/ | ||
| 36 | void check_appendX() /*;AN000;2*/ | ||
| 37 | { /*;AN000;2*/ | ||
| 38 | union REGS gregs; /*;AN000;2 Register set */ | ||
| 39 | |||
| 40 | gregs.x.ax = INSTALL_CHECK; /*;AN000;2 Get installed state*/ | ||
| 41 | int86(0x2f,&gregs,&gregs); /*;AN000;2*/ | ||
| 42 | |||
| 43 | /*****************************************************/ | ||
| 44 | /* 1) See if append is active | ||
| 45 | /* 2) If so, figure out if PCDOS or PCNET version | ||
| 46 | /*****************************************************/ | ||
| 47 | if (gregs.h.al == 0) /*;AN000;2 Zero if not installed*/ | ||
| 48 | append_indicator = NOT_INSTALLED; /*;AN000;2 */ | ||
| 49 | else /*;AN000;2 See which APPEND it is*/ | ||
| 50 | { /*;AN000;2*/ | ||
| 51 | gregs.x.ax = GET_APPEND_VER; /*;AN000;2*/ | ||
| 52 | int86(0x2f,&gregs,&gregs); /*;AN000;2*/ | ||
| 53 | |||
| 54 | if (gregs.h.al == (BYTE)-1) /*;AN000;2 -1 if PCDOS version*/ | ||
| 55 | append_indicator = DOS_APPEND; /*;AN000;2*/ | ||
| 56 | else /*;AN000;2*/ | ||
| 57 | append_indicator = NET_APPEND; /*;AN000;2*/ | ||
| 58 | } /*;AN000;2*/ | ||
| 59 | |||
| 60 | /*****************************************************/ | ||
| 61 | /* If it is the PCDOS append | ||
| 62 | /* 1) Get the current append functions (returned in BX) | ||
| 63 | /* 2) Reset append with /X support off | ||
| 64 | /*****************************************************/ | ||
| 65 | if (append_indicator == DOS_APPEND) /*;AN000;2*/ | ||
| 66 | { /*;AN000;2*/ | ||
| 67 | gregs.x.ax = GET_STATE; /*;AN000;2 Get active APPEND functions*/ | ||
| 68 | int86(0x2f,&gregs,&gregs); /*;AN000;2*/ | ||
| 69 | original_append_func = gregs.x.bx; /*;AN000;2*/ | ||
| 70 | |||
| 71 | gregs.x.ax = SET_STATE; /*;AN000;2*/ | ||
| 72 | gregs.x.bx = gregs.x.bx & (!APPEND_X_BIT); /*;AN000;2*/ | ||
| 73 | int86(0x2f,&gregs,&gregs); /*;AN000;2*/ | ||
| 74 | |||
| 75 | } /*;AN000;2*/ | ||
| 76 | |||
| 77 | return; /*;AN000;2*/ | ||
| 78 | } /*;AN000;2*/ | ||
| 79 | \ No newline at end of file | ||
diff --git a/v4.0/src/CMD/RESTORE/RTT2.C b/v4.0/src/CMD/RESTORE/RTT2.C new file mode 100644 index 0000000..92d50de --- /dev/null +++ b/v4.0/src/CMD/RESTORE/RTT2.C | |||
| @@ -0,0 +1,488 @@ | |||
| 1 | static char *SCCSID = "@(#)rtt2.c 8.4 86/10/19"; | ||
| 2 | /* 0 */ | ||
| 3 | #include <direct.h> | ||
| 4 | #include "rt.h" | ||
| 5 | #include "rt1.h" | ||
| 6 | #include "rt2.h" | ||
| 7 | #include <comsub.h> /* common subroutine def'n */ | ||
| 8 | #include <doscalls.h> | ||
| 9 | #include <wrwdefs.h> /* wrw! */ | ||
| 10 | |||
| 11 | extern unsigned char rtswitch; | ||
| 12 | extern unsigned char control_flag; | ||
| 13 | extern unsigned char control_flag2; | ||
| 14 | extern struct internat ctry; /* data area for country info*/ | ||
| 15 | |||
| 16 | /***************** START OF SPECIFICATION *********************************/ | ||
| 17 | /* */ | ||
| 18 | /* SUBROUTINE NAME : valid_input_time */ | ||
| 19 | /* */ | ||
| 20 | /* DESCRIPTIVE NAME : to validate and convert the time input from the */ | ||
| 21 | /* command line. */ | ||
| 22 | /* */ | ||
| 23 | /* FUNCTION: This subroutine validate the time input from the command lin */ | ||
| 24 | /* against the country dependent information, and convert */ | ||
| 25 | /* the deta into three integers which are hour, minute, and */ | ||
| 26 | /* second. */ | ||
| 27 | /* NOTES: */ | ||
| 28 | /* */ | ||
| 29 | /* INPUT: (PARAMETERS) */ | ||
| 30 | /* in_string - the string from command line which contains date */ | ||
| 31 | /* information. */ | ||
| 32 | /* OUTPUT: */ | ||
| 33 | /* inhour - the input hour after converted */ | ||
| 34 | /* inminute - the input minute after converted */ | ||
| 35 | /* insecond - the input second after converted */ | ||
| 36 | /* */ | ||
| 37 | /* EXIT-NORMAL: returns TRUE if the time is valid */ | ||
| 38 | /* */ | ||
| 39 | /* EXIT-ERROR: returns FALSE if the time is invalid */ | ||
| 40 | /* */ | ||
| 41 | /* EFFECTS: */ | ||
| 42 | /* */ | ||
| 43 | /* INTERNAL REFERENCES: */ | ||
| 44 | /* ROUTINES: */ | ||
| 45 | /* usererror */ | ||
| 46 | /* unexperror */ | ||
| 47 | /* putmsg */ | ||
| 48 | /* set_reset_test_flag */ | ||
| 49 | /* */ | ||
| 50 | /* EXTERNAL REFERENCES: */ | ||
| 51 | /* ROUTINES: */ | ||
| 52 | /* */ | ||
| 53 | /********************** END OF SPECIFICATIONS *******************************/ | ||
| 54 | int valid_input_time(in_string, inhour, inminute, insecond) | ||
| 55 | unsigned char *in_string; /*the input string */ | ||
| 56 | unsigned int *inhour; /*the input hour */ | ||
| 57 | unsigned int *inminute; /*the input minute */ | ||
| 58 | unsigned int *insecond; /*the input second */ | ||
| 59 | { | ||
| 60 | unsigned char chour[10]; | ||
| 61 | unsigned char cminute[10]; | ||
| 62 | unsigned char csecond[10]; | ||
| 63 | unsigned int i,j,z; /*working pointer*/ | ||
| 64 | unsigned int no_second = FALSE; | ||
| 65 | unsigned char string[20]; | ||
| 66 | |||
| 67 | /*declaration for get country information*/ | ||
| 68 | unsigned int byte_len; | ||
| 69 | unsigned buflen = sizeof( struct internat ); /* length of data area */ | ||
| 70 | unsigned int retcode; | ||
| 71 | long country = 0L; | ||
| 72 | |||
| 73 | /************************************************/ | ||
| 74 | /* find the string for hour */ | ||
| 75 | /************************************************/ | ||
| 76 | #ifdef DEBUG | ||
| 77 | printf("\ntime to be validate %s",in_string); | ||
| 78 | #endif | ||
| 79 | /*save the pointer of input string*/ | ||
| 80 | strcpy(string,in_string); | ||
| 81 | |||
| 82 | /* search the first occurance of country->timesep */ | ||
| 83 | for (i = 0; (string[i] != NULLC) && (string[i] != ctry.timesep && | ||
| 84 | string[i] != ':' && string[i] != '.'); ++i); | ||
| 85 | |||
| 86 | if (string[i] == NULLC) { /*if not found*/ | ||
| 87 | #ifdef DEBUG | ||
| 88 | printf("\nno time seperator"); | ||
| 89 | #endif | ||
| 90 | return(FALSE); | ||
| 91 | } | ||
| 92 | |||
| 93 | string[i] = NULLC; /*replace it with NULLC*/ | ||
| 94 | |||
| 95 | /*get the string which represent hour*/ | ||
| 96 | strcpy(chour,string); | ||
| 97 | /*put the rest of the string into cminute*/ | ||
| 98 | strcpy(cminute,string+i+1); | ||
| 99 | |||
| 100 | /************************************************/ | ||
| 101 | /* validate hour */ | ||
| 102 | /************************************************/ | ||
| 103 | if (strlen(chour) > MAXHOURLEN || strlen(chour)<1 ) { | ||
| 104 | #ifdef DEBUG | ||
| 105 | printf("\ninvalid hour length"); | ||
| 106 | #endif | ||
| 107 | return(FALSE); | ||
| 108 | } | ||
| 109 | |||
| 110 | /* convert the string into integer form*/ | ||
| 111 | *inhour = 0; | ||
| 112 | for (j=0; chour[j] != NULLC ; ++j) { | ||
| 113 | if (chour[j] < '0' || chour[j] > '9') { | ||
| 114 | #ifdef DEBUG | ||
| 115 | printf("\nhour value not 0-9"); | ||
| 116 | #endif | ||
| 117 | return(FALSE); | ||
| 118 | } | ||
| 119 | *inhour = *inhour*10 + chour[j]-'0'; | ||
| 120 | } | ||
| 121 | |||
| 122 | if (*inhour > 23 || *inhour < 0) { | ||
| 123 | #ifdef DEBUG | ||
| 124 | printf("\ninvalid hour value"); | ||
| 125 | #endif | ||
| 126 | return(FALSE); | ||
| 127 | } | ||
| 128 | |||
| 129 | /************************************************/ | ||
| 130 | /* find the string for minute */ | ||
| 131 | /************************************************/ | ||
| 132 | /*search the next occurance of country->timesep*/ | ||
| 133 | for (i = 0; (cminute[i] != NULLC) && (cminute[i] != ctry.timesep && | ||
| 134 | cminute[i] != ':' && cminute[i] != '.'); ++i); | ||
| 135 | |||
| 136 | if (cminute[i] == NULLC) { /*if not found*/ | ||
| 137 | no_second = TRUE; | ||
| 138 | } | ||
| 139 | |||
| 140 | /*put NULLC at the end of string which represent minute*/ | ||
| 141 | cminute[i] = NULLC; /*replace it with NULLC*/ | ||
| 142 | strcpy(csecond,cminute+i+1); | ||
| 143 | |||
| 144 | /************************************************/ | ||
| 145 | /* validate minute */ | ||
| 146 | /************************************************/ | ||
| 147 | if (strlen(cminute) > MAXMINUTELEN || strlen(cminute)<1 ) { | ||
| 148 | #ifdef DEBUG | ||
| 149 | printf("\ninvalid min length"); | ||
| 150 | #endif | ||
| 151 | return(FALSE); | ||
| 152 | } | ||
| 153 | |||
| 154 | /*convert the string into integer*/ | ||
| 155 | *inminute = 0; | ||
| 156 | for (j=0; cminute[j] != NULLC ; ++j) { | ||
| 157 | if (cminute[j] < '0' || cminute[j] > '9') { | ||
| 158 | #ifdef DEBUG | ||
| 159 | printf("\ninvalid min value, not 0-9"); | ||
| 160 | #endif | ||
| 161 | return(FALSE); | ||
| 162 | } | ||
| 163 | *inminute = *inminute*10 + cminute[j]-'0'; | ||
| 164 | } | ||
| 165 | |||
| 166 | if (*inminute > 59 || *inminute < 0) { | ||
| 167 | #ifdef DEBUG | ||
| 168 | printf("\ninvalid min value"); | ||
| 169 | #endif | ||
| 170 | return(FALSE); | ||
| 171 | } | ||
| 172 | |||
| 173 | /***************************************************/ | ||
| 174 | /* if user input second, get the string for second */ | ||
| 175 | /***************************************************/ | ||
| 176 | if (no_second == TRUE) | ||
| 177 | return(TRUE); | ||
| 178 | else { | ||
| 179 | |||
| 180 | /************************************************/ | ||
| 181 | /* validate second */ | ||
| 182 | /************************************************/ | ||
| 183 | if (strlen(csecond) > MAXSECONDLEN || strlen(csecond) < 1 ) { | ||
| 184 | #ifdef DEBUG | ||
| 185 | printf("\ninvalid second length"); | ||
| 186 | #endif | ||
| 187 | return(FALSE); | ||
| 188 | } | ||
| 189 | |||
| 190 | /*convert the rest of the string into integer*/ | ||
| 191 | *insecond = 0; | ||
| 192 | for (j=0; csecond[j] != NULLC; ++j) | ||
| 193 | { | ||
| 194 | if (csecond[j] < '0' || csecond[j] > '9') { | ||
| 195 | #ifdef DEBUG | ||
| 196 | printf("\ninvalid second, 0-9"); | ||
| 197 | #endif | ||
| 198 | return(FALSE); | ||
| 199 | } | ||
| 200 | *insecond = *insecond*10 + csecond[j]-'0'; | ||
| 201 | } | ||
| 202 | |||
| 203 | if (*insecond > 59 || *insecond < 0) { | ||
| 204 | #ifdef DEBUG | ||
| 205 | printf("\ninvalid second value"); | ||
| 206 | #endif | ||
| 207 | return(FALSE); | ||
| 208 | } | ||
| 209 | } /*end of if no_second is true */ | ||
| 210 | return(TRUE); | ||
| 211 | |||
| 212 | } /*end of subroutine*/ | ||
| 213 | /***************** START OF SPECIFICATION *********************************/ | ||
| 214 | /* */ | ||
| 215 | /* SUBROUTINE NAME : valid_input_date */ | ||
| 216 | /* */ | ||
| 217 | /* DESCRIPTIVE NAME : to validate and convert the date input from the */ | ||
| 218 | /* command line. */ | ||
| 219 | /* */ | ||
| 220 | /* FUNCTION: This subroutine validate the date input from the command lin */ | ||
| 221 | /* against the country dependent information, and convert */ | ||
| 222 | /* the deta into three integers which are year, month, and day. */ | ||
| 223 | /* NOTES: */ | ||
| 224 | /* */ | ||
| 225 | /* INPUT: (PARAMETERS) */ | ||
| 226 | /* in_string - the string from command line which contains date */ | ||
| 227 | /* information. */ | ||
| 228 | /* OUTPUT: */ | ||
| 229 | /* inyear - the input year after converted */ | ||
| 230 | /* inmonth - the input month after converted */ | ||
| 231 | /* inday - the input day after converted */ | ||
| 232 | /* */ | ||
| 233 | /* EXIT-NORMAL: returns TRUE if the date is valid */ | ||
| 234 | /* */ | ||
| 235 | /* EXIT-ERROR: returns FALSE if the date is invalid */ | ||
| 236 | /* */ | ||
| 237 | /* EFFECTS: */ | ||
| 238 | /* */ | ||
| 239 | /* INTERNAL REFERENCES: */ | ||
| 240 | /* ROUTINES: */ | ||
| 241 | /* usererror */ | ||
| 242 | /* unexperror */ | ||
| 243 | /* putmsg */ | ||
| 244 | /* set_reset_test_flag */ | ||
| 245 | /* */ | ||
| 246 | /* EXTERNAL REFERENCES: */ | ||
| 247 | /* ROUTINES: */ | ||
| 248 | /* */ | ||
| 249 | /********************** END OF SPECIFICATIONS *******************************/ | ||
| 250 | int valid_input_date(in_string,inyear,inmonth,inday) | ||
| 251 | |||
| 252 | unsigned char *in_string; | ||
| 253 | unsigned int *inyear; | ||
| 254 | unsigned int *inmonth; | ||
| 255 | unsigned int *inday; | ||
| 256 | { | ||
| 257 | unsigned char c1[10]; | ||
| 258 | unsigned char c2[10]; | ||
| 259 | unsigned char c3[10]; | ||
| 260 | unsigned char cyear[10]; | ||
| 261 | unsigned char cmonth[10]; | ||
| 262 | unsigned char cday[10]; | ||
| 263 | unsigned int in1; | ||
| 264 | unsigned int in2; | ||
| 265 | unsigned int in3; | ||
| 266 | unsigned int i,j,z; /*working pointer*/ | ||
| 267 | unsigned char string[30]; | ||
| 268 | unsigned int remainder; | ||
| 269 | |||
| 270 | #ifdef DEBUG | ||
| 271 | printf("\ndate to be validate %s",in_string); | ||
| 272 | #endif | ||
| 273 | /************************************************/ | ||
| 274 | /* separate the input date string into 3 parts */ | ||
| 275 | /************************************************/ | ||
| 276 | /*save the pointer to the input string*/ | ||
| 277 | strcpy(string,in_string); | ||
| 278 | |||
| 279 | /* search the first occurance of country->datesep */ | ||
| 280 | for (i = 0; (string[i] != NULLC) && (string[i] != ctry.datesep && | ||
| 281 | string[i] != '/' && string[i] != '-' && string[i] != '.'); ++i); | ||
| 282 | |||
| 283 | if (string[i] == NULLC) { /*if not found*/ | ||
| 284 | #ifdef DEBUG | ||
| 285 | printf("\ninvalid date sep"); | ||
| 286 | #endif | ||
| 287 | return(FALSE); | ||
| 288 | } | ||
| 289 | |||
| 290 | string[i] = NULLC; /*replace it with NULLC*/ | ||
| 291 | |||
| 292 | /*get the string which represent year*/ | ||
| 293 | strcpy(c1,string); | ||
| 294 | /*put the rest of the string into c2*/ | ||
| 295 | strcpy(c2,string+i+1); | ||
| 296 | |||
| 297 | /*search the next occurance of country->datesep*/ | ||
| 298 | for (i = 0; (c2[i] != NULLC) && (c2[i] != ctry.datesep && | ||
| 299 | c2[i] != '/' && c2[i] != '-' && c2[i] != '.'); ++i); | ||
| 300 | |||
| 301 | if (c2[i] == NULLC) { /*if not found*/ | ||
| 302 | #ifdef DEBUG | ||
| 303 | printf("\nno 2nd date sep"); | ||
| 304 | #endif | ||
| 305 | return(FALSE); | ||
| 306 | } | ||
| 307 | |||
| 308 | /*put NULLC at the end of string which represent month*/ | ||
| 309 | c2[i] = NULLC; /*replace it with NULLC*/ | ||
| 310 | strcpy(c3,c2+i+1); | ||
| 311 | |||
| 312 | /************************************************/ | ||
| 313 | /* convert all 3 strings to integers */ | ||
| 314 | /************************************************/ | ||
| 315 | in1 = 0; | ||
| 316 | for (j=0; c1[j] != NULLC ; ++j) { | ||
| 317 | if (c1[j] < '0' || c1[j] > '9') { | ||
| 318 | #ifdef DEBUG | ||
| 319 | printf("\ninvalid 1st in date not 0-9"); | ||
| 320 | #endif | ||
| 321 | return(FALSE); | ||
| 322 | } | ||
| 323 | in1 = in1*10 + c1[j]-'0'; | ||
| 324 | } | ||
| 325 | |||
| 326 | in2 = 0; | ||
| 327 | for (j=0; c2[j] != NULLC ; ++j) { | ||
| 328 | if (c2[j] < '0' || c2[j] > '9') { | ||
| 329 | #ifdef DEBUG | ||
| 330 | printf("\ninvalid 2nd in date not 0-9"); | ||
| 331 | #endif | ||
| 332 | return(FALSE); | ||
| 333 | } | ||
| 334 | in2 = in2*10 + c2[j]-'0'; | ||
| 335 | } | ||
| 336 | |||
| 337 | in3 = 0; | ||
| 338 | for (j=0; c3[j] != NULLC ; ++j) { | ||
| 339 | if (c3[j] < '0' || c3[j] > '9') { | ||
| 340 | #ifdef DEBUG | ||
| 341 | printf("\ninvalid 3rd in date not 0-9"); | ||
| 342 | #endif | ||
| 343 | return(FALSE); | ||
| 344 | } | ||
| 345 | in3 = in3*10 + c3[j]-'0'; | ||
| 346 | } | ||
| 347 | /************************************************/ | ||
| 348 | /* identify what these 3 integers are stand for */ | ||
| 349 | /************************************************/ | ||
| 350 | switch (ctry.dtformat) { | ||
| 351 | case USA: | ||
| 352 | *inmonth = in1; | ||
| 353 | *inday = in2; | ||
| 354 | *inyear = in3; | ||
| 355 | strcpy(cmonth,c1); | ||
| 356 | strcpy(cday,c2); | ||
| 357 | strcpy(cyear,c3); | ||
| 358 | break; | ||
| 359 | case EUR: | ||
| 360 | *inday = in1; | ||
| 361 | *inmonth = in2; | ||
| 362 | *inyear = in3; | ||
| 363 | strcpy(cday,c1); | ||
| 364 | strcpy(cmonth,c2); | ||
| 365 | strcpy(cyear,c3); | ||
| 366 | break; | ||
| 367 | case JAP: | ||
| 368 | *inyear = in1; | ||
| 369 | *inmonth = in2; | ||
| 370 | *inday = in3; | ||
| 371 | strcpy(cyear,c1); | ||
| 372 | strcpy(cmonth,c2); | ||
| 373 | strcpy(cday,c3); | ||
| 374 | break; | ||
| 375 | default: | ||
| 376 | #ifdef DEBUG | ||
| 377 | printf("\ninvalid country code %d",ctry.dtformat); | ||
| 378 | #endif | ||
| 379 | unexperror(UNEXPECTED); | ||
| 380 | break; | ||
| 381 | } | ||
| 382 | /************************************************/ | ||
| 383 | /* validate the value of year */ | ||
| 384 | /************************************************/ | ||
| 385 | if (strlen(cyear) > MAXYEARLEN || strlen(cyear)<1 ) { | ||
| 386 | #ifdef DEBUG | ||
| 387 | printf("\ninvalid year len"); | ||
| 388 | #endif | ||
| 389 | return(FALSE); | ||
| 390 | } | ||
| 391 | |||
| 392 | if (*inyear <= 99 && *inyear >= 80) | ||
| 393 | *inyear = *inyear + 1900; | ||
| 394 | if (*inyear <= 79 && *inyear >= 00) | ||
| 395 | *inyear = *inyear + 2000; | ||
| 396 | |||
| 397 | /*validate the value of year */ | ||
| 398 | if (*inyear > MAXYEAR || *inyear < MINYEAR) { | ||
| 399 | #ifdef DEBUG | ||
| 400 | printf("\ninvalid year value"); | ||
| 401 | #endif | ||
| 402 | return(FALSE); | ||
| 403 | } | ||
| 404 | |||
| 405 | /************************************************/ | ||
| 406 | /* validate the value of month */ | ||
| 407 | /************************************************/ | ||
| 408 | if (strlen(cmonth) > MAXMONTHLEN || strlen(cmonth)<1 ) { | ||
| 409 | #ifdef DEBUG | ||
| 410 | printf("\ninvalid month length"); | ||
| 411 | #endif | ||
| 412 | return(FALSE); | ||
| 413 | } | ||
| 414 | |||
| 415 | /*validate the value of year */ | ||
| 416 | if (*inmonth > MAXMONTH || *inmonth <= 0) { | ||
| 417 | #ifdef DEBUG | ||
| 418 | printf("\ninvalid month value"); | ||
| 419 | #endif | ||
| 420 | return(FALSE); | ||
| 421 | } | ||
| 422 | |||
| 423 | /************************************************/ | ||
| 424 | /* validate the value of day */ | ||
| 425 | /************************************************/ | ||
| 426 | if (strlen(cday) > MAXDAYLEN || strlen(cday)<1 ) { | ||
| 427 | #ifdef DEBUG | ||
| 428 | printf("\ninvalid day len"); | ||
| 429 | #endif | ||
| 430 | return(FALSE); | ||
| 431 | } | ||
| 432 | |||
| 433 | /*validate the value of year */ | ||
| 434 | if (*inday > MAXDAY || *inday <= 0 ) { | ||
| 435 | #ifdef DEBUG | ||
| 436 | printf("\ninvalid day value"); | ||
| 437 | #endif | ||
| 438 | return(FALSE); | ||
| 439 | } | ||
| 440 | if ((*inmonth == 1 || *inmonth == 3 || *inmonth == 5 || | ||
| 441 | *inmonth == 7 || *inmonth == 8 || *inmonth == 10 || | ||
| 442 | *inmonth == 12 ) && (*inday > 31 || *inday < 1)) { | ||
| 443 | #ifdef DEBUG | ||
| 444 | printf("\ninvalid day value"); | ||
| 445 | #endif | ||
| 446 | return(FALSE); | ||
| 447 | } | ||
| 448 | else { | ||
| 449 | if ((*inmonth == 4 || *inmonth == 6 || *inmonth == 9 || | ||
| 450 | *inmonth == 11 ) && (*inday > 30 || *inday < 1)) { | ||
| 451 | #ifdef DEBUG | ||
| 452 | printf("\ninvalid day value"); | ||
| 453 | #endif | ||
| 454 | return(FALSE); | ||
| 455 | } | ||
| 456 | else { | ||
| 457 | if (*inmonth == 2) { | ||
| 458 | /*check for leap year */ | ||
| 459 | remainder = *inyear % 4; | ||
| 460 | if (remainder == 0) { | ||
| 461 | if (*inday > 29 || *inday < 1) { | ||
| 462 | #ifdef DEBUG | ||
| 463 | printf("\ninvalid day value"); | ||
| 464 | #endif | ||
| 465 | return(FALSE); | ||
| 466 | } | ||
| 467 | } | ||
| 468 | else { | ||
| 469 | if (*inday > 28 || *inday < 1) { | ||
| 470 | #ifdef DEBUG | ||
| 471 | printf("\ninvalid day value"); | ||
| 472 | #endif | ||
| 473 | return(FALSE); | ||
| 474 | } | ||
| 475 | } | ||
| 476 | } | ||
| 477 | } | ||
| 478 | } | ||
| 479 | |||
| 480 | /************************************************/ | ||
| 481 | /* if there is no error found, return TRUE */ | ||
| 482 | /************************************************/ | ||
| 483 | return(TRUE); | ||
| 484 | |||
| 485 | } /*end of subroutine valid_input_date*/ | ||
| 486 | |||
| 487 | /**************************/ | ||
| 488 | \ No newline at end of file | ||
diff --git a/v4.0/src/CMD/RESTORE/RTT3.C b/v4.0/src/CMD/RESTORE/RTT3.C new file mode 100644 index 0000000..e3edd0c --- /dev/null +++ b/v4.0/src/CMD/RESTORE/RTT3.C | |||
| @@ -0,0 +1,619 @@ | |||
| 1 | |||
| 2 | /*--------------------------------- | ||
| 3 | /* SOURCE FILE NAME: RTT3.C | ||
| 4 | /*--------------------------------- | ||
| 5 | /* 0 */ | ||
| 6 | |||
| 7 | #include "rt.h" | ||
| 8 | #include "rt1.h" | ||
| 9 | #include "rt2.h" | ||
| 10 | #include "direct.h" | ||
| 11 | #include "string.h" | ||
| 12 | #include "dos.h" /*;AN000;2*/ | ||
| 13 | #include "comsub.h" /* common subroutine def'n */ | ||
| 14 | #include "doscalls.h" | ||
| 15 | #include "error.h" | ||
| 16 | #include "process.h" /*;AN000;p972*/ | ||
| 17 | |||
| 18 | extern BYTE filename[12]; | ||
| 19 | extern BYTE destddir[MAXPATH+3]; | ||
| 20 | extern BYTE srcddir[MAXPATH+3]; | ||
| 21 | extern BYTE rtswitch; | ||
| 22 | extern BYTE control_flag; | ||
| 23 | extern BYTE control_flag2; | ||
| 24 | char far *buf_pointer; | ||
| 25 | char far *control_buf_pointer; | ||
| 26 | unsigned control_selector; | ||
| 27 | extern BYTE dest_file_spec[MAXFSPEC]; | ||
| 28 | extern unsigned dest_file_handle; | ||
| 29 | extern BYTE append_indicator; /*;AN000;2*/ | ||
| 30 | extern WORD original_append_func; /*;AN000;2*/ | ||
| 31 | extern struct subst_list sublist; /*;AN000;6 Message substitution list */ | ||
| 32 | extern char response_buff[5]; /*;AN000;6*/ | ||
| 33 | BYTE far *DBCS_ptr; /*;AN005;*/ | ||
| 34 | char got_dbcs_vector = FFALSE; /*;AN005;*/ | ||
| 35 | |||
| 36 | /***************** START OF SPECIFICATION ******************************** | ||
| 37 | /* | ||
| 38 | /* SUBROUTINE NAME : set_reset_test_flag | ||
| 39 | /* | ||
| 40 | /* DESCRIPTIVE NAME : to set a flag, reset a flag, or test a flag. | ||
| 41 | /* | ||
| 42 | /* FUNCTION: This subroutine is called when there is a need to set | ||
| 43 | /* a flag, reset a flag, or test a flag. | ||
| 44 | /* NOTES: | ||
| 45 | /* | ||
| 46 | /* INPUT: (PARAMETERS) | ||
| 47 | /* flag - the flag to be set, reset, or tested. | ||
| 48 | /* targetbt - the target bit to be set, reset, or tested. | ||
| 49 | /* choice - = 1 if want to set | ||
| 50 | /* = 2 if want to reset | ||
| 51 | /* = 3 if want to test | ||
| 52 | /* | ||
| 53 | /********************* END OF SPECIFICATIONS ********************************/ | ||
| 54 | int set_reset_test_flag(flag,targetbt,choice) | ||
| 55 | |||
| 56 | BYTE *flag; /*the flag to be tested against*/ | ||
| 57 | BYTE targetbt; /*the byte to be tested */ | ||
| 58 | int choice; | ||
| 59 | { | ||
| 60 | BYTE temp; | ||
| 61 | |||
| 62 | |||
| 63 | switch (choice) { | ||
| 64 | case SET: | ||
| 65 | *flag = *flag | targetbt; | ||
| 66 | break; | ||
| 67 | |||
| 68 | case RESET: | ||
| 69 | *flag = *flag & ~targetbt; | ||
| 70 | break; | ||
| 71 | |||
| 72 | case TEST: | ||
| 73 | temp = *flag & targetbt; | ||
| 74 | if (temp == 0) { | ||
| 75 | return(FALSE); /*the tested bit is off*/ | ||
| 76 | } | ||
| 77 | else { | ||
| 78 | return(TRUE); /*the tested bit is on */ | ||
| 79 | } | ||
| 80 | break; | ||
| 81 | |||
| 82 | default: | ||
| 83 | unexperror(UNEXPECTED); | ||
| 84 | break; | ||
| 85 | } /*end of switch */ | ||
| 86 | |||
| 87 | return(FALSE); /* wrw! */ | ||
| 88 | |||
| 89 | } | ||
| 90 | /***************** START OF SPECIFICATION ******************************** | ||
| 91 | /* | ||
| 92 | /* SUBROUTINE NAME : separate | ||
| 93 | /* | ||
| 94 | /* DESCRIPTIVE NAME : Separate the given input string into 3 parts; | ||
| 95 | /* which is the path, filename, file extension, and | ||
| 96 | /* file specification. | ||
| 97 | /* | ||
| 98 | /* FUNCTION: The subroutine searches the input string for the last '\', | ||
| 99 | /* which separates the path and file specification, and then | ||
| 100 | /* searches the file specification for '.', which separates | ||
| 101 | /* the filename and file extension. Also take care the | ||
| 102 | /* situation of the user enter '.' for file specification. | ||
| 103 | /* This subroutine also validate the file specification | ||
| 104 | /* and each path entered by the user by calling common | ||
| 105 | /* subroutine Comverflnm. | ||
| 106 | /* | ||
| 107 | /* NOTE: The input string must start with '\' | ||
| 108 | /* All the output string are terminated by 00h | ||
| 109 | /* | ||
| 110 | /* INPUT: (PARAMETERS) | ||
| 111 | /* instring - input string to be separated into path, filename, | ||
| 112 | /* and file extension. | ||
| 113 | /* | ||
| 114 | /* OUTPUT: | ||
| 115 | /* path - output path name, always starts with '\' and not end | ||
| 116 | /* with '\' | ||
| 117 | /* filename - output file name | ||
| 118 | /* fileext - output file extension | ||
| 119 | /* filespec - output file name and file extension | ||
| 120 | /* | ||
| 121 | /********************** END OF SPECIFICATIONS *******************************/ | ||
| 122 | void separate(instring,path,filename,fileext,filespec) | ||
| 123 | BYTE *instring; /* point to beginning of input string */ | ||
| 124 | BYTE *path; /* point to beginning of path string */ | ||
| 125 | BYTE *filename; /* point to beginning of file name */ | ||
| 126 | BYTE *fileext; /* point to beginning of file ext. */ | ||
| 127 | BYTE *filespec; /* point to beginning of file spec */ | ||
| 128 | { | ||
| 129 | BYTE *iptr; /* working pointer */ | ||
| 130 | BYTE *fptr; /* working pointer */ | ||
| 131 | WORD i; /*;AN005;*/ | ||
| 132 | |||
| 133 | /*++++++++++++++++++++++++++++++++++++++++++++++++++++++*/ | ||
| 134 | /* Find last non-DBCS backslash character */ | ||
| 135 | /* fptr = com_strrchr(instring,'\\'); /*;AN000;p2532*/ | ||
| 136 | |||
| 137 | for ( /*;AN005;*/ | ||
| 138 | i=strlen(instring); /*;AN005;*/ | ||
| 139 | (i>=0) && (!chek_DBCS(instring,i,'\\')); /*;AN005;*/ | ||
| 140 | i-- /*;AN005;*/ | ||
| 141 | ) /*;AN005;*/ | ||
| 142 | {}; /*;AN005;*/ | ||
| 143 | |||
| 144 | fptr = instring + i; /*;AN005;*/ | ||
| 145 | /*++++++++++++++++++++++++++++++++++++++++++++++++++++++*/ | ||
| 146 | |||
| 147 | if (fptr!=instring || instring[0] == '\\') | ||
| 148 | { | ||
| 149 | *fptr = NULLC; /*;AC000;*/ | ||
| 150 | strcpy(path, instring); | ||
| 151 | if (path[0] == NULLC) | ||
| 152 | strcpy(path,"\\"); | ||
| 153 | *fptr = '\\'; | ||
| 154 | ++fptr; | ||
| 155 | strcpy(filespec, fptr); | ||
| 156 | |||
| 157 | if (filespec[0] == '.' && filespec[1] == NULLC) | ||
| 158 | { | ||
| 159 | strcpy(filename, "*"); | ||
| 160 | strcpy(fileext, "*"); | ||
| 161 | strcpy(filespec, "*.*"); | ||
| 162 | } | ||
| 163 | else | ||
| 164 | { /*else if filespec is not '.'*/ | ||
| 165 | for (iptr = fptr; *iptr!='.' && *iptr != NULLC; ++iptr); | ||
| 166 | |||
| 167 | if (*iptr == '.') | ||
| 168 | { | ||
| 169 | *iptr = NULLC; | ||
| 170 | strcpy(filename, fptr); | ||
| 171 | *iptr = '.'; | ||
| 172 | |||
| 173 | iptr = iptr+1; | ||
| 174 | strcpy(fileext, iptr); | ||
| 175 | } | ||
| 176 | else | ||
| 177 | { | ||
| 178 | strcpy(filename, filespec); | ||
| 179 | *fileext = NULLC; | ||
| 180 | } | ||
| 181 | |||
| 182 | } | ||
| 183 | |||
| 184 | } | ||
| 185 | else | ||
| 186 | {} | ||
| 187 | |||
| 188 | return; | ||
| 189 | } | ||
| 190 | |||
| 191 | |||
| 192 | |||
| 193 | |||
| 194 | |||
| 195 | /***************** START OF SPECIFICATION ******************************** | ||
| 196 | /* | ||
| 197 | /* SUBROUTINE NAME : initbuf | ||
| 198 | /* | ||
| 199 | /* DESCRIPTIVE NAME : Initialize buffer for reading and writting. | ||
| 200 | /* | ||
| 201 | /* FUNCTION: Allocate up to 64 K bytes buffer for reading and writing | ||
| 202 | /* data, and make sure its size is divisible by the sector | ||
| 203 | /* size of the restore drive. | ||
| 204 | /* | ||
| 205 | /* NOTES: | ||
| 206 | /* | ||
| 207 | /********************** END OF SPECIFICATIONS *******************************/ | ||
| 208 | |||
| 209 | void initbuf(bufsize_long) | ||
| 210 | DWORD *bufsize_long; | ||
| 211 | { | ||
| 212 | unsigned bufsize; | ||
| 213 | WORD selector; | ||
| 214 | WORD retcode; | ||
| 215 | |||
| 216 | bufsize = MAXBUF; /*64K-1 */ | ||
| 217 | /*do while allocate bufsize fail, bufsize = bufsize - DOWNSIZE*/ | ||
| 218 | for (;;) { | ||
| 219 | retcode = DOSALLOCSEG( (unsigned ) bufsize, /*buf length */ | ||
| 220 | ( unsigned far * ) &selector, /* buf pointer*/ | ||
| 221 | ( unsigned) 0 ); /* no sharing */ | ||
| 222 | if ( retcode != 0) | ||
| 223 | { | ||
| 224 | if (bufsize > DOWNSIZE) | ||
| 225 | bufsize = bufsize - DOWNSIZE; | ||
| 226 | else | ||
| 227 | break; | ||
| 228 | } | ||
| 229 | else | ||
| 230 | break; | ||
| 231 | } | ||
| 232 | if (bufsize != 0 && bufsize <= DOWNSIZE ) { | ||
| 233 | display_it(INSUFFICIENT_MEMORY,STND_ERR_DEV,0,NO_RESPTYPE,(BYTE)UTIL_MSG);/*;AN000;6*/ | ||
| 234 | usererror(INSUFMEM); | ||
| 235 | } | ||
| 236 | |||
| 237 | FP_SEG( buf_pointer ) = selector; | ||
| 238 | FP_OFF( buf_pointer ) = 0 ; | ||
| 239 | |||
| 240 | if (bufsize == 0) | ||
| 241 | *bufsize_long = (DWORD)MAXBUF; | ||
| 242 | else | ||
| 243 | *bufsize_long = (DWORD)bufsize; | ||
| 244 | } /*end of subroutine*/ | ||
| 245 | |||
| 246 | /***************** START OF SPECIFICATION ******************************** | ||
| 247 | /* | ||
| 248 | /* SUBROUTINE NAME : init_control_buf | ||
| 249 | /* | ||
| 250 | /* DESCRIPTIVE NAME : Initialize buffer for control.XXX. | ||
| 251 | /* | ||
| 252 | /* FUNCTION: Allocate buffer for reading in control.xxx | ||
| 253 | /* | ||
| 254 | /* OUTPUT: | ||
| 255 | /* control_bufsize - the size of buffer | ||
| 256 | /* | ||
| 257 | /* | ||
| 258 | /********************** END OF SPECIFICATIONS *******************************/ | ||
| 259 | void init_control_buf(control_file_len,control_bufsize) /* !wrw */ | ||
| 260 | DWORD control_file_len; /* !wrw */ | ||
| 261 | unsigned int *control_bufsize; /* !wrw */ | ||
| 262 | { /* !wrw */ | ||
| 263 | unsigned bufsize; /* !wrw */ | ||
| 264 | WORD retcode; /* !wrw */ | ||
| 265 | |||
| 266 | bufsize = 3072; /* !wrw */ | ||
| 267 | |||
| 268 | |||
| 269 | retcode = DOSALLOCSEG( (unsigned ) bufsize, /* !wrw */ | ||
| 270 | ( unsigned far * ) &control_selector, /* !wrw */ | ||
| 271 | ( unsigned) 0 ); /* !wrw */ | ||
| 272 | |||
| 273 | |||
| 274 | if ( retcode != 0) /* If there is insufficient memory /* !wrw */ | ||
| 275 | { /* !wrw */ | ||
| 276 | display_it(INSUFFICIENT_MEMORY,STND_ERR_DEV,0,NO_RESPTYPE,(BYTE)UTIL_MSG); /*;AN000;6*/ | ||
| 277 | usererror(INSUFMEM); | ||
| 278 | } /* !wrw */ | ||
| 279 | |||
| 280 | FP_SEG( control_buf_pointer ) = control_selector; /* !wrw */ | ||
| 281 | FP_OFF( control_buf_pointer ) = 0 ; /* !wrw */ | ||
| 282 | |||
| 283 | *control_bufsize = bufsize; /* !wrw */ | ||
| 284 | |||
| 285 | } /*end of subroutine*/ /* !wrw */ | ||
| 286 | |||
| 287 | /***************** START OF SPECIFICATION ******************************** | ||
| 288 | /* | ||
| 289 | /* SUBROUTINE NAME : unexperror | ||
| 290 | /* | ||
| 291 | /* DESCRIPTIVE NAME : exit the program because of something really bad | ||
| 292 | /* occures | ||
| 293 | /* | ||
| 294 | /* FUNCTION: Exit the program because of unexpected error | ||
| 295 | /* | ||
| 296 | /* | ||
| 297 | /********************** END OF SPECIFICATIONS *******************************/ | ||
| 298 | void unexperror(retcode) | ||
| 299 | WORD retcode; | ||
| 300 | { | ||
| 301 | exit_routine(retcode); | ||
| 302 | return; | ||
| 303 | } | ||
| 304 | |||
| 305 | /***************** START OF SPECIFICATION ******************************** | ||
| 306 | /* | ||
| 307 | /* SUBROUTINE NAME : usererror | ||
| 308 | /* | ||
| 309 | /* DESCRIPTIVE NAME : exit the program because of a user error | ||
| 310 | /* | ||
| 311 | /********************** END OF SPECIFICATIONS *******************************/ | ||
| 312 | void usererror(retcode) | ||
| 313 | WORD retcode; | ||
| 314 | { | ||
| 315 | unexperror(retcode); | ||
| 316 | return; | ||
| 317 | } | ||
| 318 | |||
| 319 | /***************** START OF SPECIFICATION ******************************** | ||
| 320 | /* | ||
| 321 | /* SUBROUTINE NAME : exit_routine | ||
| 322 | /* | ||
| 323 | /* DESCRIPTIVE NAME : exit the program | ||
| 324 | /* | ||
| 325 | /* FUNCTION: 1. output msg if there is a sharing error. | ||
| 326 | /* 2. if PCDOS, convert return codes to error levels | ||
| 327 | /* 3. exit the program | ||
| 328 | /* | ||
| 329 | /* NOTES: | ||
| 330 | /* | ||
| 331 | /* INPUT: (PARAMETERS) | ||
| 332 | /* retcode - the reason of error | ||
| 333 | /* | ||
| 334 | /* | ||
| 335 | /********************** END OF SPECIFICATIONS *******************************/ | ||
| 336 | void exit_routine(retcode) | ||
| 337 | WORD retcode; | ||
| 338 | { | ||
| 339 | union REGS regs; /*;AN000;2*/ | ||
| 340 | |||
| 341 | chdir (destddir); | ||
| 342 | |||
| 343 | chdir (srcddir); | ||
| 344 | |||
| 345 | /* if flag indicates there is a SHAREERROR */ | ||
| 346 | if (retcode == NORMAL && | ||
| 347 | set_reset_test_flag(&control_flag,SHARERROR,TEST)==TRUE) | ||
| 348 | retcode = SHARERR; | ||
| 349 | |||
| 350 | switch(retcode) | ||
| 351 | { | ||
| 352 | case NORMAL: retcode = PC_NORMAL; | ||
| 353 | break; | ||
| 354 | case NOFILES: retcode = PC_NOFILES; | ||
| 355 | break; | ||
| 356 | case SHARERR: retcode = PC_SHARERR; | ||
| 357 | break; | ||
| 358 | case TUSER: retcode = PC_TUSER; | ||
| 359 | break; | ||
| 360 | default: retcode = PC_OTHER; | ||
| 361 | break; | ||
| 362 | } /* end switch */ | ||
| 363 | |||
| 364 | |||
| 365 | if (append_indicator == DOS_APPEND) /*;AN000;2 If append /x was reset*/ | ||
| 366 | { /*;AN000;2*/ | ||
| 367 | regs.x.ax = SET_STATE; /*;AN000;2*/ | ||
| 368 | regs.x.bx = original_append_func; /*;AN000;2*/ | ||
| 369 | int86(0x2f,®s,®s); /*;AN000;2*/ | ||
| 370 | } /*;AN000;2*/ | ||
| 371 | |||
| 372 | exit(retcode); /*;AN000;p972*/ | ||
| 373 | |||
| 374 | } | ||
| 375 | /***************** START OF SPECIFICATION ******************************** | ||
| 376 | /* | ||
| 377 | /* SUBROUTINE NAME : signal_handler_routine | ||
| 378 | /* | ||
| 379 | /* DESCRIPTIVE NAME : handle the situation that the user terminate | ||
| 380 | /* the program by Control-break. | ||
| 381 | /* | ||
| 382 | /* FUNCTION: This subroutine change the directory of the | ||
| 383 | /* destination disk back to the original directory. | ||
| 384 | /* If there is a file in the middle of restoring, close | ||
| 385 | /* the file, deleted the partially restored file, and | ||
| 386 | /* output a message. | ||
| 387 | /* Then exit with error level TUSER. | ||
| 388 | /* | ||
| 389 | /* | ||
| 390 | /********************** END OF SPECIFICATIONS *******************************/ | ||
| 391 | void pascal far signal_handler_routine() | ||
| 392 | { | ||
| 393 | WORD retcode; | ||
| 394 | |||
| 395 | DWORD dw = 0L; /* reserved double word*/ | ||
| 396 | |||
| 397 | /*change dir to the original directory of the destination disk*/ | ||
| 398 | |||
| 399 | /**************************************************************/ | ||
| 400 | /*if PARTIAL flag is on, close and delete the destination file*/ | ||
| 401 | /**************************************************************/ | ||
| 402 | if (set_reset_test_flag(&control_flag,PARTIAL,TEST) == TRUE) { | ||
| 403 | /* close the partially completed destination file*/ | ||
| 404 | DOSCLOSE(dest_file_handle); | ||
| 405 | /* delete the partially completed destination file*/ | ||
| 406 | if ((retcode = DOSDELETE((char far *) dest_file_spec, dw)) != 0) { | ||
| 407 | /*set file mode to 0*/ | ||
| 408 | if ((retcode = DOSSETFILEMODE((char far *)dest_file_spec, | ||
| 409 | (unsigned) 0x00, dw)) != 0) | ||
| 410 | { | ||
| 411 | com_msg(retcode); | ||
| 412 | unexperror(retcode); | ||
| 413 | } | ||
| 414 | /* delete the partially completed destination file*/ | ||
| 415 | if ((retcode = DOSDELETE((char far *) dest_file_spec, dw)) != 0) { | ||
| 416 | com_msg(retcode); | ||
| 417 | unexperror(retcode); | ||
| 418 | } | ||
| 419 | } | ||
| 420 | display_it(LAST_FILE_NOT_RESTORED,STND_ERR_DEV,0,NO_RESPTYPE,(BYTE)UTIL_MSG); /*;AN000;6*/ | ||
| 421 | } | ||
| 422 | exit_routine(TUSER); | ||
| 423 | |||
| 424 | } /* end of signal_handler*/ | ||
| 425 | |||
| 426 | /************************************************************/ | ||
| 427 | /* | ||
| 428 | /* SUBROUTINE NAME: display_it (added for DOS 4.00) | ||
| 429 | /* | ||
| 430 | /* SUBROUTINE FUNCTION: | ||
| 431 | /* Display the requested message to the standard output device. | ||
| 432 | /* | ||
| 433 | /* INPUT: | ||
| 434 | /* 1) (WORD) Number of the message to be displayed. | ||
| 435 | /* 2) (WORD) Handle to be written to. | ||
| 436 | /* 3) (WORD) Substitution Count | ||
| 437 | /* 4) (WORD) Flag indicating user should "Strike any key..." | ||
| 438 | /* | ||
| 439 | /* OUTPUT: | ||
| 440 | /* The message corresponding to the requested msg number will | ||
| 441 | /* be written to the requested handle. If requested, substitution | ||
| 442 | /* text will be inserted as required. The Substitution List | ||
| 443 | /* is global and, if used, will be initialized by DISPLAY_MSG | ||
| 444 | /* before calling this routine. | ||
| 445 | /* | ||
| 446 | /* NORMAL EXIT: | ||
| 447 | /* Message will be successfully written to requested handle. | ||
| 448 | /* | ||
| 449 | /* ERROR EXIT: | ||
| 450 | /* None. Note that theoretically an error can be returned from | ||
| 451 | /* SYSDISPMSG, but there is nothing that the application can do. | ||
| 452 | /* | ||
| 453 | /* | ||
| 454 | /************************************************************/ | ||
| 455 | #define CLASS -1 /* Goes in DH register */ /*;AN000;6*/ | ||
| 456 | #define NUL_POINTER 0 /* Pointer to nothing */ /*;AN000;6*/ | ||
| 457 | |||
| 458 | void display_it(msg_number,handle,subst_count,waitflag,class) /*;AN000;6*/ | ||
| 459 | |||
| 460 | WORD msg_number; /*;AN000;6*/ | ||
| 461 | WORD handle; /*;AN000;6*/ | ||
| 462 | WORD subst_count; /*;AN000;6*/ | ||
| 463 | WORD waitflag; /*;AN000;6*/ | ||
| 464 | BYTE class; /*;AN000;6*/ | ||
| 465 | { /*;AN000;6*/ | ||
| 466 | union REGS reg; /*;AN000;6*/ | ||
| 467 | |||
| 468 | reg.x.ax = msg_number; /*;AN000;6*/ | ||
| 469 | reg.x.bx = handle; /*;AN000;6*/ | ||
| 470 | reg.x.cx = subst_count; /*;AN000;6*/ | ||
| 471 | reg.h.dh = class; /*;AN000;6*/ | ||
| 472 | reg.h.dl = (BYTE)waitflag; /*;AN000;6*/ | ||
| 473 | reg.x.di = (BYTE)&response_buff[0]; /*;AN000;6*/ | ||
| 474 | reg.x.si = (WORD)(char far *)&sublist; /*;AN000;6*/ | ||
| 475 | |||
| 476 | sysdispmsg(®,®); /*;AN000;6*/ | ||
| 477 | response_buff[0] = reg.h.al; /* User input */ /*;AN000;6*/ | ||
| 478 | |||
| 479 | return; /*;AN000;6 */ | ||
| 480 | } /*;AN000;6 */ | ||
| 481 | /***************** START OF SPECIFICATION ******************************** | ||
| 482 | /* | ||
| 483 | /* SUBROUTINE NAME : com_msg | ||
| 484 | /* | ||
| 485 | /* DESCRIPTIVE NAME : the routine to output a message according to | ||
| 486 | /* the return codes returned from API calls. | ||
| 487 | /* | ||
| 488 | /* FUNCTION: 1. if CP/DOS, then call rctomid | ||
| 489 | /* | ||
| 490 | /* NOTES: | ||
| 491 | /* | ||
| 492 | /* INPUT: (PARAMETERS) | ||
| 493 | /* retcode - return code used to call rctomid | ||
| 494 | /* | ||
| 495 | /* | ||
| 496 | /********************** END OF SPECIFICATIONS *******************************/ | ||
| 497 | void com_msg(retcode) | ||
| 498 | WORD retcode; | ||
| 499 | { | ||
| 500 | /* Was IF CPDOS */ | ||
| 501 | display_it(rctomid(retcode),STND_ERR_DEV,0,NO_RESPTYPE,(BYTE)UTIL_MSG); /*;AN000;6*/ | ||
| 502 | |||
| 503 | return; | ||
| 504 | |||
| 505 | } | ||
| 506 | /*ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ*/ | ||
| 507 | /* */ | ||
| 508 | /* Subroutine Name: chek_DBCS() */ | ||
| 509 | /* */ | ||
| 510 | /* (Ripped off and Revised from ATTRIB.C) */ | ||
| 511 | /* */ | ||
| 512 | /* Subroutine Function: */ | ||
| 513 | /* Given an array and a position in the array, check if the character */ | ||
| 514 | /* is a non-DBCS character. */ | ||
| 515 | /* */ | ||
| 516 | /* Input: array, character position, character */ | ||
| 517 | /* */ | ||
| 518 | /* Output: TRUE - if array[position-1] != DBCS character AND */ | ||
| 519 | /* array[position] == character. */ | ||
| 520 | /* FALSE - otherwise */ | ||
| 521 | /* */ | ||
| 522 | /*ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ*/ | ||
| 523 | WORD chek_DBCS(array,position,character) /*;AN005;*/ | ||
| 524 | char *array; /*;AN005;*/ | ||
| 525 | WORD position; /*;AN005;*/ | ||
| 526 | char character; /*;AN005;*/ | ||
| 527 | { /*;AN005;*/ | ||
| 528 | BYTE far *ptr; /*;AN005;*/ | ||
| 529 | WORD i; /*;AN005;*/ | ||
| 530 | char c; /*;AN005;*/ | ||
| 531 | char darray[128]; /* DBCS array, put "D" in every position*/ /*;AN005;*/ | ||
| 532 | /* that corresponds to the first byte */ | ||
| 533 | /* of a DBCS character. */ | ||
| 534 | if (!got_dbcs_vector) /*;AN005;*/ | ||
| 535 | Get_DBCS_vector(); /*;AN005;*/ | ||
| 536 | |||
| 537 | for (i=0;i<128;i++) /*;AN005;*/ | ||
| 538 | darray[i] = ' '; /*;AN005;*/ | ||
| 539 | |||
| 540 | /* Check each character, starting with the first in string, for DBCS */ | ||
| 541 | /* characters and mark each with a "D" in the corresponding darray. */ | ||
| 542 | for (i=0;i<position;i++) /*;AN005;*/ | ||
| 543 | { /*;AN005;*/ | ||
| 544 | c = array[i]; /*;AN005;*/ | ||
| 545 | |||
| 546 | /* look thru DBCS table to determine if character is first byte */ | ||
| 547 | /* of a double byte character */ | ||
| 548 | for (ptr=DBCS_ptr; (WORD)*(WORD far *)ptr != 0; ptr += 2) /*;AN005;*/ | ||
| 549 | { /*;AN005;*/ | ||
| 550 | |||
| 551 | /* check if byte is within range values of DOS DBCS table */ | ||
| 552 | if (c >= *ptr && c <= *(ptr+1)) /*;AN005;*/ | ||
| 553 | { /*;AN005;*/ | ||
| 554 | darray[i] = 'D'; /*;AN005;*/ | ||
| 555 | i++; /* skip over second byte of DBCS */ /*;AN005;*/ | ||
| 556 | break; /*;AN005;*/ | ||
| 557 | } /*;AN005;*/ | ||
| 558 | } /*;AN005;*/ | ||
| 559 | } /*;AN005;*/ | ||
| 560 | |||
| 561 | /* if character is not DBCS then check to see if it is == to character */ | ||
| 562 | if (darray[position-1] != 'D' && character == array[position]) /*;AN005;*/ | ||
| 563 | return (TTRUE); /*;AN005;*/ | ||
| 564 | else /*;AN005;*/ | ||
| 565 | return (FFALSE); /*;AN005;*/ | ||
| 566 | } /*;AN005;*/ | ||
| 567 | |||
| 568 | /*ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ*/ | ||
| 569 | /* */ | ||
| 570 | /* Subroutine Name: Get_DBCS_vector() */ | ||
| 571 | /* */ | ||
| 572 | /* Subroutine Function: */ | ||
| 573 | /* Gets the double-byte table vector. */ | ||
| 574 | /* Puts it in global variable DBCS_ptr */ | ||
| 575 | /*ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ*/ | ||
| 576 | void Get_DBCS_vector() /*;AN005;*/ | ||
| 577 | { /*;AN005;*/ | ||
| 578 | union REGS inregs,outregs; /*;AN005;*/ | ||
| 579 | struct SREGS segregs; /*;AN005;*/ | ||
| 580 | char fix_es_reg[2]; /*;AN005;*/ | ||
| 581 | WORD *ptr; /*;AN005;*/ | ||
| 582 | DWORD far *addr_ptr; /*;AN005;*/ | ||
| 583 | WORD *buffer; /*;AN005;*/ | ||
| 584 | |||
| 585 | /***********************************/ | ||
| 586 | /* Allocate a buffer */ | ||
| 587 | /***********************************/ | ||
| 588 | inregs.x.ax = 0x4800; /* Allocate */ /*;AN005;*/ | ||
| 589 | inregs.x.bx = 1; /* Num paragraphs */ /*;AN005;*/ | ||
| 590 | intdos(&inregs,&outregs); /* Int 21h */ /*;AN005;*/ | ||
| 591 | buffer = (WORD *)outregs.x.ax; /* Segment of buffer */ /*;AN005;*/ | ||
| 592 | |||
| 593 | inregs.x.ax = 0x6507; /* get extended country info */ /*;AN005;*/ | ||
| 594 | inregs.x.bx = 0xffff; /* use active code page */ /*;AN005;*/ | ||
| 595 | inregs.x.cx = 5; /* 5 bytes of return data */ /*;AN005;*/ | ||
| 596 | inregs.x.dx = 0xffff; /* use default country */ /*;AN005;*/ | ||
| 597 | inregs.x.di = 0; /* buffer offset */ /*;AN005;*/ | ||
| 598 | segregs.es = (WORD)buffer; /* buffer segment */ /*;AN005;*/ | ||
| 599 | segregs.ds = (WORD)buffer; /* buffer segment */ /*;AN005;*/ | ||
| 600 | intdosx(&inregs,&outregs,&segregs); /*;AN005;*/ | ||
| 601 | strcpy(fix_es_reg,NUL); /*;AN005;*/ | ||
| 602 | |||
| 603 | outregs.x.di++; /* skip over id byte */ /*;AN005;*/ | ||
| 604 | |||
| 605 | /* make a far ptr from ES:[DI] */ | ||
| 606 | addr_ptr = 0; /*;AN005;*/ | ||
| 607 | ptr = (WORD *)&addr_ptr; /*;AN005;*/ | ||
| 608 | *ptr = (WORD)outregs.x.di; /* get offset */ /*;AN005;*/ | ||
| 609 | ptr++; /*;AN005;*/ | ||
| 610 | *ptr = (WORD)segregs.es; /* get segment */ /*;AN005;*/ | ||
| 611 | DBCS_ptr = (BYTE far *)*addr_ptr; /*;AN005;*/ | ||
| 612 | DBCS_ptr += 2; /* skip over table length */ /*;AN005;*/ | ||
| 613 | |||
| 614 | /* DBCS_ptr points to DBCS table */ | ||
| 615 | strcpy(fix_es_reg,NUL); /*;AN005;*/ | ||
| 616 | got_dbcs_vector = TTRUE; /*;AN005;*/ | ||
| 617 | return; /*;AN005;*/ | ||
| 618 | } /*;AN005;*/ | ||
| 619 | |||
diff --git a/v4.0/src/CMD/RESTORE/WRWDEFS.H b/v4.0/src/CMD/RESTORE/WRWDEFS.H new file mode 100644 index 0000000..b8cfb13 --- /dev/null +++ b/v4.0/src/CMD/RESTORE/WRWDEFS.H | |||
| @@ -0,0 +1,77 @@ | |||
| 1 | |||
| 2 | |||
| 3 | /* built in 'c' functions */ | ||
| 4 | |||
| 5 | int sprintf(); | ||
| 6 | int printf(); | ||
| 7 | char *strcat(char *,char *); | ||
| 8 | int strlen(char *); | ||
| 9 | char *strcpy(char *, char *); | ||
| 10 | int strncmp(char *,char *,unsigned int); | ||
| 11 | int strcmp(char *,char *); | ||
| 12 | |||
| 13 | /* li functions */ | ||
| 14 | int chdir(char *); | ||
| 15 | int mkdir(char *); | ||
| 16 | |||
| 17 | void search_src_disk_old(struct disk_info *, | ||
| 18 | struct file_info *, | ||
| 19 | struct disk_header_old *, | ||
| 20 | struct disk_header_new far *, | ||
| 21 | struct file_header_old *, | ||
| 22 | struct file_header_new far *, | ||
| 23 | unsigned char, | ||
| 24 | unsigned char, | ||
| 25 | unsigned long, | ||
| 26 | unsigned int *, | ||
| 27 | unsigned char *, | ||
| 28 | unsigned char *, | ||
| 29 | unsigned char *, | ||
| 30 | unsigned char *, | ||
| 31 | struct timedate *); | ||
| 32 | |||
| 33 | void search_src_disk_new(struct disk_info *, | ||
| 34 | struct file_info *, | ||
| 35 | struct disk_header_old *, | ||
| 36 | struct disk_header_new far *, | ||
| 37 | struct file_header_old *, | ||
| 38 | struct file_header_new far *, | ||
| 39 | unsigned char, | ||
| 40 | unsigned char, | ||
| 41 | unsigned int *, | ||
| 42 | unsigned long, | ||
| 43 | unsigned char *, | ||
| 44 | unsigned char *, | ||
| 45 | unsigned char *, | ||
| 46 | unsigned int *, | ||
| 47 | struct timedate *); | ||
| 48 | |||
| 49 | |||
| 50 | int findfirst_new( struct file_info *, | ||
| 51 | unsigned int *, | ||
| 52 | unsigned int *, | ||
| 53 | unsigned char *, | ||
| 54 | unsigned char *, | ||
| 55 | unsigned int far**, | ||
| 56 | unsigned int far**, | ||
| 57 | unsigned int *, | ||
| 58 | unsigned char *); | ||
| 59 | |||
| 60 | |||
| 61 | void restore_a_file(struct file_info *, | ||
| 62 | struct disk_info *, | ||
| 63 | unsigned long, | ||
| 64 | unsigned int *, | ||
| 65 | struct file_header_old *, | ||
| 66 | struct file_header_new far *, | ||
| 67 | struct disk_header_old *, | ||
| 68 | struct disk_header_new far *, | ||
| 69 | unsigned char, | ||
| 70 | unsigned char, | ||
| 71 | unsigned char *, | ||
| 72 | unsigned char *, | ||
| 73 | unsigned char *, | ||
| 74 | unsigned int *, | ||
| 75 | unsigned int *); | ||
| 76 | |||
| 77 | \ No newline at end of file | ||
diff --git a/v4.0/src/CMD/RESTORE/_MSGRET.ASM b/v4.0/src/CMD/RESTORE/_MSGRET.ASM new file mode 100644 index 0000000..92597f6 --- /dev/null +++ b/v4.0/src/CMD/RESTORE/_MSGRET.ASM | |||
| @@ -0,0 +1,242 @@ | |||
| 1 | page 60,132 | ||
| 2 | name _msgret | ||
| 3 | title C to Message Retriever | ||
| 4 | ;------------------------------------------------------------------- | ||
| 5 | ; | ||
| 6 | ; MODULE: _msgret | ||
| 7 | ; | ||
| 8 | ; PURPOSE: Supplies an interface between C programs and | ||
| 9 | ; the DOS 3.3 message retriever | ||
| 10 | ; | ||
| 11 | ; CALLING FORMAT: | ||
| 12 | ; sysloadmsg(&inregs,&outregs); | ||
| 13 | ; sysdispmsg(&inregs,&outregs); | ||
| 14 | ; | ||
| 15 | ; DATE: 5-21-87 | ||
| 16 | ; | ||
| 17 | ;------------------------------------------------------------------- | ||
| 18 | |||
| 19 | INCLUDE SYSMSG.INC ;PERMIT SYSTEM MESSAGE HANDLER DEFINITION ;AN000; | ||
| 20 | |||
| 21 | MSG_UTILNAME <RESTORE> ;IDENTIFY THE COMPONENT ;AN000; | ||
| 22 | |||
| 23 | .8087 | ||
| 24 | _TEXT SEGMENT BYTE PUBLIC 'CODE' | ||
| 25 | _TEXT ENDS | ||
| 26 | _DATA SEGMENT WORD PUBLIC 'DATA' | ||
| 27 | _DATA ENDS | ||
| 28 | CONST SEGMENT WORD PUBLIC 'CONST' | ||
| 29 | CONST ENDS | ||
| 30 | _BSS SEGMENT WORD PUBLIC 'BSS' | ||
| 31 | _BSS ENDS | ||
| 32 | DGROUP GROUP CONST, _BSS, _DATA | ||
| 33 | ASSUME CS: _TEXT, DS: _TEXT, SS: DGROUP, ES: DGROUP | ||
| 34 | |||
| 35 | |||
| 36 | public _sysloadmsg | ||
| 37 | public _sysdispmsg | ||
| 38 | |||
| 39 | ;------------------------------------------------------------------- | ||
| 40 | ;------------------------------------------------------------------- | ||
| 41 | |||
| 42 | _DATA segment | ||
| 43 | .XLIST | ||
| 44 | .XCREF | ||
| 45 | MSG_SERVICES <MSGDATA> ;DATA AREA FOR THE MESSAGE HANDLER ;AN000; | ||
| 46 | .LIST | ||
| 47 | .CREF | ||
| 48 | _DATA ends | ||
| 49 | |||
| 50 | |||
| 51 | _TEXT segment | ||
| 52 | |||
| 53 | ;------------------------------------------------------------------- | ||
| 54 | ;DEFAULT=CHECK DOS VERSION | ||
| 55 | ;DEFAULT=NEARmsg | ||
| 56 | ;DEFAULT=INPUTmsg | ||
| 57 | ;DEFAULT=NUMmsg | ||
| 58 | ;DEFAULT=NO TIMEmsg | ||
| 59 | ;DEFAULT=NO DATEmsg | ||
| 60 | .XLIST | ||
| 61 | .XCREF | ||
| 62 | MSG_SERVICES <LOADmsg,INPUTmsg,DISPLAYmsg,CHARmsg,NUMmsg,DATEmsg,FARmsg> ;AN000;6 | ||
| 63 | MSG_SERVICES <RESTORE.CTL,RESTORE.CLA,RESTORE.CL1,RESTORE.CL2> ;AN000;6 | ||
| 64 | .LIST | ||
| 65 | .CREF | ||
| 66 | ;------------------------------------------------------------------- | ||
| 67 | |||
| 68 | _sysloadmsg proc near | ||
| 69 | |||
| 70 | push bp ; save user's base pointer | ||
| 71 | mov bp,sp ; set bp to current sp | ||
| 72 | push di ; save some registers | ||
| 73 | push si | ||
| 74 | |||
| 75 | ; copy C inregs into proper registers | ||
| 76 | |||
| 77 | mov di,[bp+4] ; fix di (arg 0) | ||
| 78 | |||
| 79 | ;------------------------------------------------------------------- | ||
| 80 | |||
| 81 | mov ax,[di+0ah] ; load di | ||
| 82 | push ax ; the di value from inregs is now on stack | ||
| 83 | |||
| 84 | mov ax,[di+00] ; get inregs.x.ax | ||
| 85 | mov bx,[di+02] ; get inregs.x.bx | ||
| 86 | mov cx,[di+04] ; get inregs.x.cx | ||
| 87 | mov dx,[di+06] ; get inregs.x.dx | ||
| 88 | mov si,[di+08] ; get inregs.x.si | ||
| 89 | pop di ; get inregs.x.di from stack | ||
| 90 | |||
| 91 | push bp ; save base pointer | ||
| 92 | |||
| 93 | ;------------------------------------------------------------------- | ||
| 94 | call sysloadmsg ; call the message retriever | ||
| 95 | ;------------------------------------------------------------------- | ||
| 96 | |||
| 97 | pop bp ; restore base pointer | ||
| 98 | push di ; the di value from call is now on stack | ||
| 99 | mov di,[bp+6] ; fix di (arg 1) | ||
| 100 | |||
| 101 | mov [di+00],ax ; load outregs.x.ax | ||
| 102 | mov [di+02],bx ; load outregs.x.bx | ||
| 103 | mov [di+04],cx ; load outregs.x.cx | ||
| 104 | mov [di+06],dx ; load outregs.x.dx | ||
| 105 | mov [di+08],si ; load outregs.x.si | ||
| 106 | |||
| 107 | lahf ; get flags into ax | ||
| 108 | mov al,ah ; move into low byte | ||
| 109 | mov [di+0ch],ax ; load outregs.x.cflag | ||
| 110 | |||
| 111 | pop ax ; get di from stack | ||
| 112 | mov [di+0ah],ax ; load outregs.x.di | ||
| 113 | |||
| 114 | ;------------------------------------------------------------------- | ||
| 115 | |||
| 116 | pop si ; restore registers | ||
| 117 | pop di | ||
| 118 | mov sp,bp ; restore sp | ||
| 119 | pop bp ; restore user's bp | ||
| 120 | ret | ||
| 121 | |||
| 122 | _sysloadmsg endp | ||
| 123 | |||
| 124 | |||
| 125 | ;_sysgetmsg proc near | ||
| 126 | ; | ||
| 127 | ; push bp ; save user's base pointer | ||
| 128 | ; mov bp,sp ; set bp to current sp | ||
| 129 | ; push di ; save some registers | ||
| 130 | ; push si | ||
| 131 | ; | ||
| 132 | ;; copy C inregs into proper registers | ||
| 133 | ; | ||
| 134 | ; mov di,[bp+4] ; fix di (arg 0) | ||
| 135 | ; | ||
| 136 | ;;------------------------------------------------------------------- | ||
| 137 | ; | ||
| 138 | ; mov ax,[di+0ah] ; load di | ||
| 139 | ; push ax ; the di value from inregs is now on stack | ||
| 140 | ; | ||
| 141 | ; mov ax,[di+00] ; get inregs.x.ax | ||
| 142 | ; mov bx,[di+02] ; get inregs.x.bx | ||
| 143 | ; mov cx,[di+04] ; get inregs.x.cx | ||
| 144 | ; mov dx,[di+06] ; get inregs.x.dx | ||
| 145 | ; mov si,[di+08] ; get inregs.x.si | ||
| 146 | ; pop di ; get inregs.x.di from stack | ||
| 147 | ; | ||
| 148 | ; push bp ; save base pointer | ||
| 149 | ; | ||
| 150 | ;;------------------------------------------------------------------- | ||
| 151 | ; call sysgetmsg ; call the message retriever | ||
| 152 | ;;------------------------------------------------------------------- | ||
| 153 | ; | ||
| 154 | ; pop bp ; restore base pointer | ||
| 155 | ; push di ; the di value from call is now on stack | ||
| 156 | ; mov di,[bp+6] ; fix di (arg 1) | ||
| 157 | ; | ||
| 158 | ; mov [di+00],ax ; load outregs.x.ax | ||
| 159 | ; mov [di+02],bx ; load outregs.x.bx | ||
| 160 | ; mov [di+04],cx ; load outregs.x.cx | ||
| 161 | ; mov [di+06],dx ; load outregs.x.dx | ||
| 162 | ; mov [di+08],si ; load outregs.x.si | ||
| 163 | ; | ||
| 164 | ; lahf ; get flags into ax | ||
| 165 | ; mov al,ah ; move into low byte | ||
| 166 | ; mov [di+0ch],ax ; load outregs.x.cflag | ||
| 167 | ; | ||
| 168 | ; pop ax ; get di from stack | ||
| 169 | ; mov [di+0ah],ax ; load outregs.x.di | ||
| 170 | ; | ||
| 171 | ;;------------------------------------------------------------------- | ||
| 172 | ; | ||
| 173 | ; pop si ; restore registers | ||
| 174 | ; pop di | ||
| 175 | ; mov sp,bp ; restore sp | ||
| 176 | ; pop bp ; restore user's bp | ||
| 177 | ; ret | ||
| 178 | ; | ||
| 179 | ;_sysgetmsg endp | ||
| 180 | |||
| 181 | _sysdispmsg proc near | ||
| 182 | |||
| 183 | push bp ; save user's base pointer | ||
| 184 | mov bp,sp ; set bp to current sp | ||
| 185 | push di ; save some registers | ||
| 186 | push si | ||
| 187 | |||
| 188 | ; copy C inregs into proper registers | ||
| 189 | |||
| 190 | mov di,[bp+4] ; fix di (arg 0) | ||
| 191 | |||
| 192 | ;------------------------------------------------------------------- | ||
| 193 | |||
| 194 | mov ax,[di+0ah] ; load di | ||
| 195 | push ax ; the di value from inregs is now on stack | ||
| 196 | |||
| 197 | mov ax,[di+00] ; get inregs.x.ax | ||
| 198 | mov bx,[di+02] ; get inregs.x.bx | ||
| 199 | mov cx,[di+04] ; get inregs.x.cx | ||
| 200 | mov dx,[di+06] ; get inregs.x.dx | ||
| 201 | mov si,[di+08] ; get inregs.x.si | ||
| 202 | pop di ; get inregs.x.di from stack | ||
| 203 | |||
| 204 | push bp ; save base pointer | ||
| 205 | |||
| 206 | ;------------------------------------------------------------------- | ||
| 207 | call sysdispmsg ; call the message retriever | ||
| 208 | ;------------------------------------------------------------------- | ||
| 209 | |||
| 210 | pop bp ; restore base pointer | ||
| 211 | push di ; the di value from call is now on stack | ||
| 212 | mov di,[bp+6] ; fix di (arg 1) | ||
| 213 | |||
| 214 | mov [di+00],ax ; load outregs.x.ax | ||
| 215 | mov [di+02],bx ; load outregs.x.bx | ||
| 216 | mov [di+04],cx ; load outregs.x.cx | ||
| 217 | mov [di+06],dx ; load outregs.x.dx | ||
| 218 | mov [di+08],si ; load outregs.x.si | ||
| 219 | |||
| 220 | lahf ; get flags into ax | ||
| 221 | mov al,ah ; move into low byte | ||
| 222 | mov [di+0ch],ax ; load outregs.x.cflag | ||
| 223 | |||
| 224 | pop ax ; get di from stack | ||
| 225 | mov [di+0ah],ax ; load outregs.x.di | ||
| 226 | |||
| 227 | ;------------------------------------------------------------------- | ||
| 228 | |||
| 229 | pop si ; restore registers | ||
| 230 | pop di | ||
| 231 | mov sp,bp ; restore sp | ||
| 232 | pop bp ; restore user's bp | ||
| 233 | ret | ||
| 234 | |||
| 235 | _sysdispmsg endp | ||
| 236 | |||
| 237 | include msgdcl.inc | ||
| 238 | |||
| 239 | _TEXT ends ; end code segment | ||
| 240 | end | ||
| 241 | |||
| 242 | \ No newline at end of file | ||
diff --git a/v4.0/src/CMD/RESTORE/_PARSE.ASM b/v4.0/src/CMD/RESTORE/_PARSE.ASM new file mode 100644 index 0000000..9685fe6 --- /dev/null +++ b/v4.0/src/CMD/RESTORE/_PARSE.ASM | |||
| @@ -0,0 +1,115 @@ | |||
| 1 | page 60,132 | ||
| 2 | name _parse | ||
| 3 | title C to PARSER interface | ||
| 4 | ;------------------------------------------------------------------- | ||
| 5 | ; | ||
| 6 | ; MODULE: _parse | ||
| 7 | ; | ||
| 8 | ; PURPOSE: Supplies an interface between C programs and | ||
| 9 | ; the DOS 3.3 parser | ||
| 10 | ; | ||
| 11 | ; CALLING FORMAT: | ||
| 12 | ; parse(&inregs,&outregs); | ||
| 13 | ; | ||
| 14 | ; DATE: 5-21-87 | ||
| 15 | ; | ||
| 16 | ;------------------------------------------------------------------- | ||
| 17 | |||
| 18 | ; extrn sysparse:far | ||
| 19 | |||
| 20 | public _parse | ||
| 21 | |||
| 22 | ;------------------------------------------------------------------- | ||
| 23 | FarSW equ 0 ; make sysparse be a NEAR proc | ||
| 24 | TimeSW equ 1 ; Check time format | ||
| 25 | FileSW equ 1 ; Check file specification | ||
| 26 | CAPSW equ 1 ; Perform CAPS if specified | ||
| 27 | CmpxSW equ 0 ; Check complex list | ||
| 28 | NumSW equ 0 ; Check numeric value | ||
| 29 | KeySW equ 0 ; Support keywords | ||
| 30 | SwSW equ 1 ; Support switches | ||
| 31 | Val1SW equ 0 ; Support value definition 1 | ||
| 32 | Val2SW equ 0 ; Support value definition 2 | ||
| 33 | Val3SW equ 0 ; Support value definition 3 | ||
| 34 | DrvSW equ 1 ; Support drive only format | ||
| 35 | QusSW equ 0 ; Support quoted string format | ||
| 36 | IncSW equ 0 ; Dont include PSDATA, I just did it | ||
| 37 | BaseSW equ 1 ; DS points to data | ||
| 38 | ;------------------------------------------------------------------- | ||
| 39 | |||
| 40 | DGROUP GROUP _DATA | ||
| 41 | PGROUP GROUP _TEXT | ||
| 42 | |||
| 43 | _DATA segment byte public 'DATA' | ||
| 44 | include psdata.inc | ||
| 45 | _DATA ends | ||
| 46 | |||
| 47 | _TEXT segment byte public 'CODE' | ||
| 48 | |||
| 49 | ASSUME CS: PGROUP | ||
| 50 | ASSUME DS: DGROUP | ||
| 51 | |||
| 52 | ;------------------------------------------------------------------- | ||
| 53 | .xlist | ||
| 54 | include parse.asm ; include the parser | ||
| 55 | .list | ||
| 56 | ;------------------------------------------------------------------- | ||
| 57 | |||
| 58 | _parse proc near | ||
| 59 | |||
| 60 | push bp ; save user's base pointer | ||
| 61 | mov bp,sp ; set bp to current sp | ||
| 62 | push di ; save some registers | ||
| 63 | push si | ||
| 64 | |||
| 65 | ; copy C inregs into proper registers | ||
| 66 | |||
| 67 | mov di,[bp+4] ; fix di (arg 0) | ||
| 68 | |||
| 69 | ;------------------------------------------------------------------- | ||
| 70 | |||
| 71 | mov ax,[di+0ah] ; load di | ||
| 72 | push ax ; the di value from inregs is now on stack | ||
| 73 | |||
| 74 | mov ax,[di+00] ; get inregs.x.ax | ||
| 75 | mov bx,[di+02] ; get inregs.x.bx | ||
| 76 | mov cx,[di+04] ; get inregs.x.cx | ||
| 77 | mov dx,[di+06] ; get inregs.x.dx | ||
| 78 | mov si,[di+08] ; get inregs.x.si | ||
| 79 | pop di ; get inregs.x.di from stack | ||
| 80 | |||
| 81 | push bp ; save base pointer | ||
| 82 | ;------------------------------------------------------------------- | ||
| 83 | call sysparse ; call the parser | ||
| 84 | ;------------------------------------------------------------------- | ||
| 85 | pop bp ; restore base pointer | ||
| 86 | push di ; the di value from call is now on stack | ||
| 87 | mov di,[bp+6] ; fix di (arg 1) | ||
| 88 | |||
| 89 | mov [di+00],ax ; load outregs.x.ax | ||
| 90 | mov [di+02],bx ; load outregs.x.bx | ||
| 91 | mov [di+04],cx ; load outregs.x.cx | ||
| 92 | mov [di+06],dx ; load outregs.x.dx | ||
| 93 | mov [di+08],si ; load outregs.x.si | ||
| 94 | |||
| 95 | lahf ; get flags into ax | ||
| 96 | mov al,ah ; move into low byte | ||
| 97 | mov [di+0ch],ax ; load outregs.x.cflag | ||
| 98 | |||
| 99 | pop ax ; get di from stack | ||
| 100 | mov [di+0ah],ax ; load outregs.x.di | ||
| 101 | |||
| 102 | ;------------------------------------------------------------------- | ||
| 103 | |||
| 104 | pop si ; restore registers | ||
| 105 | pop di | ||
| 106 | mov sp,bp ; restore sp | ||
| 107 | pop bp ; restore user's bp | ||
| 108 | ret | ||
| 109 | |||
| 110 | _parse endp | ||
| 111 | |||
| 112 | _TEXT ends ; end code segment | ||
| 113 | end | ||
| 114 | |||
| 115 | \ No newline at end of file | ||