2 /**************************************************************************/
4 /* UTILITY NAME: Join */
6 /* SOURCE FILE NAME: Join.C */
8 /* STATUS: Join Utility, DOS Version 4.0 */
10 /* FUNCTIONAL DESCRIPTION: This utility allows the splicing of a */
11 /* physical drive to a pathname on another physical drive such that */
12 /* operations performed using the pathname as an argument take place */
13 /* on the physical drive. */
15 /* SYNTAX: [d:][path]JOIN or */
16 /* [d:][path]JOIN d: d:\directory or */
17 /* [d:][path]JOIN d: /D */
19 /* [d:][path] to specify the drive and path that */
20 /* contains the JOIN command file, if it is not */
21 /* in the current directory of the default drive. */
23 /* d: to specify the drive to be connected to a */
24 /* directory on another drive. */
26 /* d:\directory to specify the directory that */
27 /* you will join a drive under. The directory */
28 /* must be at the root and only one level deep. */
30 /* /D to disconnect a join. You must specify the */
31 /* drive letter of the drive whose join you */
35 /* CDS.C - Functions to get/set DOS CDS structures */
36 /* DPB.C - Functions to get DOS DPB structures */
37 /* ERRTST.C - Drive and path validity testing functions */
38 /* SYSVAR.C - Functions to get/set DOS System Variable structures */
39 /* COMSUBS.LIB - DOS DBCS function calls */
40 /* MAPPER.LIB - DOS function calls */
41 /* SLIBC3.LIB - C library functions */
42 /* _MSGRET.SAL - Assembler interface for common DOS message services */
43 /* _PARSE.SAL - Assembler interface for common DOS parser */
45 /* ERROR HANDLING: Error message displayed and utility is terminated. */
47 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
51 /* Converted to CMERGE 03/26/85 by GregT */
53 /* M000 May 23/85 Barrys */
54 /* Disallow splicing similar drives. */
56 /* M001 May 24/85 Barrys */
57 /* The original IBM version of JOIN allowed the delete splice switch */
58 /* "/D" immediately after the drive specification. The argument parsing */
59 /* code has been Revised to allow this combination. */
61 /* M002 June 5/85 Barrys */
62 /* Changed low version check for specific 320. */
64 /* M003 July 15/85 Barrys */
65 /* Checked for any possible switch characters in the other operands. */
67 /* M004 July 15/85 Barrys */
68 /* Moved check for physical drive before check for NET and SHARED tests. */
70 /* 33D0016 July 16/86 RosemarieG */
71 /* Put SHARED test on an equal basis with physical drive check. */
72 /* Last fix (M004) erroneously allowed joining physical or local shared */
73 /* drives. This is because it only performed the SHARED test if the */
74 /* drive failed the physical test. */
77 /* Deletion of source code dealing with parsing and displaying messages */
78 /* and addition of SYSLOADMSG, SYSDISPMSG, SYSPARSE in order to conform */
79 /* to DOS Version 4.0 specifications to utilize common DOS parser and */
80 /* message service routines. */
82 /* AC000: Changed code for DOS Version 4.0 S.M 5/87 */
84 /* AN000: New code for DOS Version 4.0 S.M 5/87 */
85 /* AN000;M = message services */
86 /* AN000;P = parser service */
88 /* Ax001: Changed code req'd - PTM0003919 S.M 3/88 */
89 /* Incorrect message response */
91 /* Ax002: Changed code req'd - PTM0004046 S.M 3/88 */
92 /* Incomplete message response */
94 /**************************************************************************/
99 #include "joinpars.h" /* ;AN000;P Parser structures */
100 #include "jointype.h"
104 /*ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ PARSE EQUATES ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ*/
105 #define ASCII_DRIVE 'A'-1 /* ;AN000;P Convert to Ascii drive */
106 #define CAPRESULT 0x0001 /* ;AN000;P Cap result by file table */
107 #define DRVONLY_OPT 0x0101 /* ;AN000;P Drive only & optional */
108 #define ERRORLEVEL1 1 /* ;AN000;P Parsing error occurred */
109 #define FILESPEC_OPT 0x0201 /* ;AN000;P File spec & optional */
110 #define MAXPOSITION 2 /* ;AN000;P Max positionals in cmdline */
111 #define MINPOSITION 0 /* ;AN000;P Min positionals in cmdline */
112 #define NOCAPPING 0x0000 /* ;AN000;P Do not cap result */
113 #define SWITCH_OPT 0x0000 /* ;AN000;P Optional switch */
115 /*ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ MESSAGE EQUATES ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ*/
116 #define MSG_NOMEM 1 /* ;AN000;M Insufficient memory */
117 #define MSG_PARMNUM 2 /* ;AN000;M Too many parameters */
118 #define MSG_DIRNEMP 3 /* ;AN000;M Directory not empty */
119 #define MSG_BADPARM 4 /* ;AN000;M Invalid parameter */
120 #define MSG_NETERR 5 /* ;AN000;M Cannot %1 a network drive */
121 #define MSG_INVSWTCH 6 /* ;AN000;M Invalid switch */
123 #define BLNK ' ' /* ;AN000;M For sublist.pad_char */
124 #define CARRY 0x0001 /* ;AN000;M Check carry flag */
125 #define D_SWITCH "/D" /* ;AN000;M Only 1 switch */
126 #define EXT_ERR_CLASS 0x01 /* ;AN000;M DOS Extended error class */
129 #define MAXWIDTH 0 /* ;AN000;M 0 ensures no padding */
130 #define MINWIDTH 1 /* ;AN000;M At least 1 char in parm */
131 #define NO_HANDLE 0xffff /* ;AN000;M No handle specified */
132 #define NO_INPUT 0x00 /* ;AN000;M No input characters */
133 #define NO_REPLACE 0x00 /* ;AN000;M No replacable parameters */
135 #define PARSE_ERR_CLASS 0x02 /* ;AN000;M Parse error class */
136 #define RESERVED 0 /* ;AN000;M Reserved byte field */
137 #define STDERR 0x0002 /* ;AN000;M Standard error device handle */
138 #define STDOUT 0x0001 /* ;AN000;M Std output device handle */
139 #define STR_INPUT 16 /* ;AN000;M Byte def for sublist.flags */
140 #define SUB_ID1 1 /* ;AN000;M Only 1 replaceable parameter */
141 #define SUBCNT0 0 /* ;AN000;M 0 substitutions in message */
142 #define SUBCNT1 1 /* ;AN000;M 1 substitution in message */
143 #define SUBLIST_LENGTH 11 /* ;AN000;M Length of sublist structure */
144 #define UTILITY_CLASS 0x0ff /* ;AN000;M Utility message class */
146 /*ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ MISCELLANEOUS ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ*/
147 extern char *strchr() ; /* M003 */
148 extern char *strbscan() ; /* SM extern'd */
150 char cmdln_drive[64] = {0} ; /* ;AN002; Save user's input in */
151 char cmdln_flspec[64] = {0} ; /* ;AN002; order to pass to error */
152 char cmdln_invalid[64] = {0} ; /* ;AN002; */
153 char cmdln_switch[64] = {0} ; /* ;AN002; message, if needed */
154 char fix_es_reg[1] ; /* ;AN000;P Corrects es reg after type-"far" */
155 char p_drive[3] = {0} ; /* ;AN000;P Recvs drive ltr from parser */
156 char p_filespec[64] = {0} ; /* ;AN000;P Recvs filespec from parser */
157 char replparm_JOIN[] = "JOIN" ; /* ;AN000;P Cannot JOIN a network drv */
159 unsigned char source[MAX] = {0} ; /* ;AN000;P buffer for string manipulation */
161 struct sysVarsType SysVars ;
163 /*ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ PARSE STRUCTURES ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ*/
164 struct p_parms p_p ; /* ;AN000;P # of extras & pts to descrptn */
165 struct p_parmsx p_px ; /* ;AN000;P min/max parms & pts to controls */
166 struct p_control_blk p_con1 ; /* ;AN000;P 1st posit parm in cmd str */
167 struct p_control_blk p_con2 ; /* ;AN000;P 2nd posit parm in cmd str */
168 struct p_switch_blk p_swi1 ; /* ;AN000;P /D switch in cmd str */
169 struct p_result_blk rslt1 ; /* ;AN000;P Result blk rtrnd from parser */
170 struct p_fresult_blk rslt2 ; /* ;AN000;P Result blk rtrnd from parser */
171 struct p_result_blk rslt3 ; /* ;AN000;P Result blk rtrnd from parser */
172 struct noval novals = {0} ; /* ;AN000;P Value list not used */
174 union REGS inregs, outregs ; /* ;AN000;P Define register variables */
176 /**************************************************************************/
178 /* SUBROUTINE NAME: main (program entry point) */
180 /* SUBROUTINE FUNCTION: Preload message file */
181 /* Get the command line parameters */
182 /* Parse the command line by calling SYSPARSEC */
183 /* Verify the correctness of the parameters */
184 /* Check for splice deletion switch */
185 /* Determine if directory not empty */
186 /* Check source and destination drives not same */
187 /* Determine if network or shared drive */
188 /* Determine if currently spliced */
189 /* Determine if existing dir or can't mkdir */
190 /* Print messages by calling SYSDISPMSG */
192 /* EXTERNAL ROUTINES: SYSLOADMSG */
196 /* INTERNAL ROUTINES: DoList Parser_Prep */
197 /* Load_Msg dispmsg_terminate */
200 /**************************************************************************/
206 struct findType findbuf ;
209 char path [MAXPATHLEN],*p ;
210 char far * fptr ; /* ;AN000;P Pointer to parser's buffer */
212 int delflag = FALSE ; /* M001 delete splice flag */
213 int dstdrv ; /* M000 dest. drive number */
214 int fchar = 0 ; /* ;AN000;P Parser filespec chars */
216 int index ; /* ;AN000;P Used in creating cmdline string */
217 int more_toparse = TRUE ; /* ;AN000;P While parsing cmdline */
218 int pdrive_flg = FALSE ; /* ;AN000;P Is there a drive letter? */
219 int pflspec_flg = FALSE ; /* ;AN000;P Is there a filespec? */
221 /************************ BEGIN ***********************************************/
223 load_msg() ; /* ;AN000;M Point to msgs & chks DOS ver */
225 for (index = 1; index <= c; index++) /* ;AN000;P Loop through end of cmd line */
227 strcat(source,v[index]) ; /* ;AN000;P Add the argument */
228 strcat(source," ") ; /* ;AN000;P Separate with a space */
230 Parser_Prep(source) ; /* ;AN000;P Initialization for the parser */
232 while (more_toparse) /* ;AN000;P test the flag */
234 index = 0 ; /* ;AN002; Init array index */
235 parse(&inregs,&outregs) ; /* ;AN000;P call the parser */
236 if (outregs.x.ax == P_No_Error) /* ;AN000;P if no error */
238 if (outregs.x.dx == (unsigned short)&rslt1) /* ;AN000;P if result is drv ltr */
240 p_drive[0] = *(rslt1.p_result_buff) ; /* ;AN000;P save the drive letter */
241 p_drive[0] += (char)ASCII_DRIVE ; /* ;AN000;P */
242 p_drive[1] = COLON ; /* ;AN000;P */
243 pdrive_flg = TRUE ; /* ;AN000;P and set the flag */
244 for (inregs.x.si ; inregs.x.si < outregs.x.si ; inregs.x.si++) /* ;AN002; Copy whatever */
245 { /* ;AN002; parser just parsed */
246 cmdln_drive[index] = *(char *)inregs.x.si ; /* ;AN002; */
247 index++ ; /* ;AN002; */
251 if (outregs.x.dx == (unsigned short)&rslt2) /* ;AN000;P if result is filespec */
253 for (fptr = rslt2.fp_result_buff; (char)*fptr != NULL; fptr++) /* ;AN000;P Point to parser's buffer */
255 p_filespec[fchar] = (char)*fptr ; /* ;AN000;P Copy char */
256 fchar++ ; /* ;AN000;P */
258 strcpy(fix_es_reg,NULL) ; /* ;AN000;P (Set es reg correct) */
259 pflspec_flg = TRUE ; /* ;AN000;P and set the flag */
260 for (inregs.x.si ; inregs.x.si < outregs.x.si ; inregs.x.si++) /* ;AN002; Copy whatever */
261 { /* ;AN002; parser just parsed */
262 cmdln_flspec[index] = *(char *)inregs.x.si ; /* ;AN002; */
263 index++ ; /* ;AN002; */
268 for (inregs.x.si ; inregs.x.si < outregs.x.si ; inregs.x.si++) /* ;AN002; Copy whatever */
269 { /* ;AN002; parser just parsed */
270 cmdln_switch[index] = *(char *)inregs.x.si ; /* ;AN002; */
271 index++ ; /* ;AN002; */
273 if (!delflag) /* ;AN000;P Check for dup switch */
274 delflag = TRUE ; /* ;AN000;P it's /D switch */
275 else /* ;AN000;P else it's a dup switch */
276 dispmsg_terminate(MSG_INVSWTCH,cmdln_switch) ; /* ;AN000;P display msg & end */
280 if (outregs.x.ax != P_RC_EOL) /* ;AN000;P there must be an error */
282 for (inregs.x.si ; inregs.x.si < outregs.x.si ; inregs.x.si++) /* ;AN002; Copy whatever */
283 { /* ;AN002; parser just parsed */
284 cmdln_invalid[index] = *(char *)inregs.x.si ; /* ;AN002; */
285 index++ ; /* ;AN002; */
287 switch (outregs.x.ax) /* ;AN000;P See what error the */
288 { /* ;AN000;P parser may have found */
289 case P_Too_Many : dispmsg_terminate(MSG_PARMNUM,cmdln_invalid) ; /* ;AN002; Too many parameters */
290 break ; /* ;AN000;P more_toparse = FALSE */
291 case P_Not_In_SW : dispmsg_terminate(MSG_INVSWTCH,cmdln_invalid) ;/* ;AN002; Invalid switch */
292 break ; /* ;AN000;P more_toparse = FALSE */
293 case P_Op_Missing : /* ;AN000;P Required operand missing */
294 case P_Not_In_Key : /* ;AN000;P Not in kywrd list provided */
295 case P_Out_Of_Range : /* ;AN000;P Out of range specified */
296 case P_Not_In_Val : /* ;AN000;P Not in val list provided */
297 case P_Not_In_Str : /* ;AN000;P Not in strg list provided */
298 case P_Syntax : dispmsg_terminate(MSG_BADPARM,cmdln_invalid) ; /* ;AN000;P incorrect syntax */
299 break ; /* ;AN000;P more_toparse = FALSE */
300 default : dispmsg_terminate(MSG_BADPARM,cmdln_invalid) ; /* ;AN000;P */
301 break ; /* ;AN000;P more_toparse = FALSE */
305 more_toparse = FALSE ; /* ;AN000;P End of the cmdline */
306 inregs.x.cx = outregs.x.cx ; /* ;AN000;P Move the count */
307 inregs.x.si = outregs.x.si ; /* ;AN000;P Move the pointer */
310 if (pdrive_flg && !(pflspec_flg || delflag)) /* ;AN000;P drive & no flspec or delete ? */
311 dispmsg_terminate(MSG_BADPARM,cmdln_drive) ; /* ;AN000;P display error msg & exit utility */
313 if (pflspec_flg && !pdrive_flg) /* ;AN000;P filespec & no drive ? */
314 dispmsg_terminate(MSG_BADPARM,cmdln_flspec) ; /* ;AN000;P display error msg & exit utility */
316 if (delflag && !pdrive_flg) /* ;AN000;P delete & no drive ? */
317 dispmsg_terminate(MSG_BADPARM,cmdln_switch) ; /* ;AN000;P display error msg & exit utility */
319 if (pdrive_flg && pflspec_flg && delflag) /* ;AN000;P drive, filespec & /D ? */
320 dispmsg_terminate(MSG_PARMNUM,cmdln_switch) ; /* ;AN000;P display error msg & exit utility */
322 GetVars(&SysVars) ; /* Access to DOS data structures */
323 strcpy(fix_es_reg,NULL) ; /* ;AN000;P (Set es reg correct) */
326 DoList() ; /* list splices */
329 i = p_drive[0] - 'A' ; /* ;AC000;P Convert to drv # */
330 if (!fGetCDS(i, &CDS))
331 dispmsg_terminate(MSG_BADPARM,cmdln_drive) ; /* ;AC000;M display error msg & exit utility */
333 strcpy(fix_es_reg,NULL) ; /* ;AN000;P (Set es reg correct) */
334 if (delflag == TRUE) /* Deassigning perhaps? */
336 if (!TESTFLAG(CDS.flags, CDSSPLICE))
337 dispmsg_terminate(MSG_BADPARM,cmdln_switch) ; /* ;AC000;M If NOT spliced */
339 if (fPathErr(CDS.text))
340 dispmsg_terminate(MSG_BADPARM,cmdln_drive) ; /* ;AC000;M If prefix of curdir */
342 CDS.text[0] = i + 'A' ;
348 if (i >= SysVars.cDrv)
351 CDS.flags = CDSINUSE ;
353 strcpy(fix_es_reg,NULL) ; /* ;AN000;P (Set es reg correct) */
356 strcpy(fix_es_reg,NULL) ; /* ;AN000;P (Set es reg correct) */
358 strcpy(fix_es_reg,NULL) ; /* ;AN000;P (Set es reg correct) */
362 if (TESTFLAG(CDS.flags,CDSSPLICE))
363 dispmsg_terminate(MSG_BADPARM,cmdln_drive) ; /* ;AC000; If now spliced */
365 rootpath(p_filespec,path) ; /* Get root path */
367 if (i == getdrv() || /* M004 Start */ /* Can't mov curdrv */
368 !fPhysical(i) || /* ;AC000; */
369 fShared(i)) /* 33D0016 RG */
370 { /* Determine if it was a NET error */
371 if (fNet(i) || fShared(i))
372 dispmsg_terminate(MSG_NETERR) ; /* ;AC000;M display error msg & exit utility */
373 dispmsg_terminate(MSG_BADPARM,cmdln_drive) ; /* ;AC000;M display error msg & exit utility */
376 strcpy(fix_es_reg,NULL) ; /* ;AN000;P (Set es reg correct) */
377 if (fPathErr(path) || *strbscan(path+3, "/\\") != 0) /* or curdir prefix */
378 dispmsg_terminate(MSG_BADPARM,cmdln_flspec) ; /* ;AC000; */
380 strcpy(fix_es_reg,NULL) ; /* ;AN000;P (Set es reg correct) */
381 if (fNet(path[0] - 'A') || fShared(path[0] - 'A'))
382 dispmsg_terminate(MSG_NETERR) ; /* ;AC000;M display error msg & exit utility */
384 strcpy(fix_es_reg,NULL) ; /* ;AN000;P (Set es reg correct) */
385 dstdrv = *path - 'A' ; /* M000 Check src and dst drvs ar not same */
386 if (i == dstdrv) /* M000 */
387 dispmsg_terminate (MSG_BADPARM,cmdln_flspec) ; /* M000 */ /* ;AC000; */
388 if (mkdir(path) == -1) /* If can't mkdir or if no dir or */
389 { /* if note is file */
390 if (ffirst(path, A_D, &findbuf) == -1 ||
391 !TESTFLAG(findbuf.attr,A_D))
392 dispmsg_terminate(MSG_BADPARM,cmdln_flspec) ; /* ;AC000;M display error msg & exit utility */
394 p = path + strlen(path) ;
397 if (ffirst(path, 0, &findbuf) != -1)
398 dispmsg_terminate(MSG_DIRNEMP,cmdln_flspec) ; /* ;AC001;M If dir not empty */
403 strcpy(CDS.text, path) ;
404 CDS.flags = CDSINUSE | CDSSPLICE ;
406 strcpy(fix_es_reg,NULL) ; /* ;AN000;P (Set es reg correct) */
408 strcpy(fix_es_reg,NULL) ; /* ;AN000;P (Set es reg correct) */
411 strcpy(fix_es_reg,NULL) ; /* ;AN000;P (Set es reg correct) */
416 /*ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ*/
418 DoList() /* Print list of cur joins */
423 for (i=0 ; fGetCDS(i, &CDS) ; i++)
425 if (TESTFLAG(CDS.flags,CDSSPLICE))
426 printf("%c: => %s\n", i+'A', CDS.text) ;
430 /*ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ*/
431 /**************************************************************************/
433 /* SUBROUTINE NAME: load_msg */
435 /* SUBROUTINE FUNCTION: Load the set of SUBST Utility messages to */
436 /* become available for display_msg call. */
438 /* ERROR EXIT: Utility will be terminated by sysloadmsg if */
439 /* version check is incorrect. */
441 /* EXTERNAL REF: SYSLOADMSG */
443 /**************************************************************************/
445 load_msg() /* ;AN000;M */
447 sysloadmsg(&inregs,&outregs) ; /* ;AN000;M Load utility messages */
448 if (outregs.x.cflag & CARRY) /* ;AN000;M If problem loading msgs */
450 sysdispmsg(&outregs,&outregs) ; /* ;AN000;M then display the err msg */
451 exit(ERRORLEVEL1) ; /* ;AN000;M and exit utility */
453 return ; /* ;AN000;M */
455 /*ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ*/
456 /**************************************************************************/
458 /* SUBROUTINE NAME: display_msg */
460 /* SUBROUTINE FUNCTION: The correct message called by main is displayed */
461 /* to standard out. */
463 /* INPUT: msg_num (message number to display) */
464 /* outline (substitution parameter) */
468 /* ERROR EXIT: Display error message corresponding to number */
469 /* returned in AX. */
471 /* EXTERNAL REF: SYSDISPMSG */
473 /**************************************************************************/
475 display_msg(msg_num,outline) /* ;AN000;M */
476 int msg_num ; /* ;AN000;M Message number #define'd */
477 char *outline ; /* ;AN000;M Substitution parameter */
479 unsigned char function ; /* ;AN000;M Y/N response or press key? */
480 unsigned int message, /* ;AN000;M Message number to display */
481 msg_class, /* ;AN000;M Which class of messages? */
482 sub_cnt, /* ;AN000;M Number of substitutions? */
483 handle ; /* ;AN000;M Display where? */
485 struct sublist /* ;AN000;M */
487 unsigned char size ; /* ;AN000;M Points to next sublist */
488 unsigned char reserved ; /* ;AN000;M Required for disp msg */
489 unsigned far *value ; /* ;AN000;M Data pointer */
490 unsigned char id ; /* ;AN000;M Id of substitution parm (%1) */
491 unsigned char flags ; /* ;AN000;M Format of data - (a0sstttt) */
492 unsigned char max_width ; /* ;AN000;M Maximum field width */
493 unsigned char min_width ; /* ;AN000;M Minimum field width */
494 unsigned char pad_char ; /* ;AN000;M char to pad field */
495 } sublist ; /* ;AN000;M */
497 switch (msg_num) /* ;AN000;M Which msg to display? */
499 case MSG_NOMEM : function = NO_INPUT ; /* ;AN000;M Y/N response or press key? */
500 message = 8 ; /* ;AN000;M Message number to display */
501 msg_class = EXT_ERR_CLASS ; /* ;AN000;M Which class of messages? */
502 sub_cnt = SUBCNT0 ; /* ;AN000;M Number of substitutions? */
503 handle = STDERR ; /* ;AN000;M Display where? */
504 break ; /* ;AN000;M */
505 case MSG_PARMNUM : function = NO_INPUT ; /* ;AN000;M Y/N response or press key? */
506 message = 1 ; /* ;AN000;M Message number to display */
507 msg_class = PARSE_ERR_CLASS ; /* ;AN000;M Which class of messages? */
508 sub_cnt = SUBCNT1 ; /* ;AN000;M Number of substitutions? */
509 handle = STDERR ; /* ;AN000;M Display where? */
510 break ; /* ;AN000;M */
511 case MSG_DIRNEMP : function = NO_INPUT ; /* ;AN000;M Y/N response or press key? */
512 message = 2 ; /* ;AN000;M Message number to display */
513 msg_class = UTILITY_CLASS ; /* ;AN000;M Which class of messages? */
514 sub_cnt = SUBCNT1 ; /* ;AN000;M Number of substitutions? */
515 handle = STDERR ; /* ;AN000;M Display where? */
516 break ; /* ;AN000;M */
517 case MSG_BADPARM : function = NO_INPUT ; /* ;AN000;M Y/N response or press key? */
518 message = 10 ; /* ;AN000;M Message number to display */
519 msg_class = PARSE_ERR_CLASS ; /* ;AN000;M Which class of messages? */
520 sub_cnt = SUBCNT1 ; /* ;AN000;M Number of substitutions? */
521 handle = STDERR ; /* ;AN000;M Display where? */
522 break ; /* ;AN000;M */
523 case MSG_NETERR : function = NO_INPUT ; /* ;AN000;M Y/N response or press key? */
524 message = 12 ; /* ;AN000;M Message number to display */
525 msg_class = UTILITY_CLASS ; /* ;AN000;M Which class of messages? */
526 sub_cnt = SUBCNT1 ; /* ;AN000;M Number of substitutions? */
527 handle = STDERR ; /* ;AN000;M Display where? */
528 break ; /* ;AN000;M */
529 case MSG_INVSWTCH: function = NO_INPUT ; /* ;AN000;M Y/N response or press key? */
530 message = 3 ; /* ;AN000;M Message number to display */
531 msg_class = PARSE_ERR_CLASS ; /* ;AN000;M Which class of messages? */
532 sub_cnt = SUBCNT1 ; /* ;AN000;M Number of substitutions? */
533 handle = STDERR ; /* ;AN000;M Display where? */
534 break ; /* ;AN000;M */
535 default : exit(ERRORLEVEL1) ; /* ;AN000;M */
536 break ; /* ;AN000;M */
539 switch (msg_num) /* ;AN000;M */
541 case MSG_NOMEM : inregs.x.ax = message ; /* ;AN000;M Insufficient memory */
542 inregs.x.bx = handle ; /* ;AN000;M STDERR */
543 inregs.x.cx = sub_cnt ; /* ;AN000;M SUBCNT0 */
544 inregs.h.dl = function ; /* ;AN000;M NO_INPUT */
545 inregs.h.dh = msg_class ; /* ;AN000;M Extended, Parse or Utility */
546 sysdispmsg(&inregs,&outregs) ; /* ;AN000;M Call common msg service */
547 break ; /* ;AN000;M */
548 case MSG_INVSWTCH: /* ;AN000;M Invalid switch */
549 case MSG_DIRNEMP : /* ;AN000;M Directory not empty */
550 case MSG_PARMNUM : /* ;AN000;M Too many parameters */
551 case MSG_BADPARM : sublist.value = (unsigned far *)outline ; /* ;AN000;M Invalid parameter */
552 sublist.size = SUBLIST_LENGTH ; /* ;AN000;M */
553 sublist.reserved = RESERVED ; /* ;AN000;M */
554 sublist.id = 0 ; /* ;AN000;M */
555 sublist.flags = STR_INPUT ; /* ;AN000;M */
556 sublist.max_width = MAXWIDTH ; /* ;AN000;M */
557 sublist.min_width = MINWIDTH ; /* ;AN000;M */
558 sublist.pad_char = (unsigned char)BLNK ; /* ;AN000;M */
559 inregs.x.ax = message ; /* ;AN000;M Cannot JOIN a network drive */
560 inregs.x.bx = handle ; /* ;AN000;M STDERR */
561 inregs.x.si = (unsigned int)&sublist ; /* ;AN000;M Point to the substitution buffer */
562 inregs.x.cx = sub_cnt ; /* ;AN000;M SUBCNT1 */
563 inregs.h.dl = function ; /* ;AN000;M STR_INPUT */
564 inregs.h.dh = msg_class ; /* ;AN000;M Extended, Parse or Utility */
565 sysdispmsg(&inregs,&outregs) ; /* ;AN000;M Call common msg service */
566 break ; /* ;AN000;M */
567 case MSG_NETERR : sublist.value = (unsigned far *)replparm_JOIN ; /* ;AN000;M Cannot JOIN a network drive */
568 sublist.size = SUBLIST_LENGTH ; /* ;AN000;M */
569 sublist.reserved = RESERVED ; /* ;AN000;M */
570 sublist.id = SUB_ID1 ; /* ;AN000;M */
571 sublist.flags = STR_INPUT ; /* ;AN000;M */
572 sublist.max_width = MAXWIDTH ; /* ;AN000;M */
573 sublist.min_width = MINWIDTH ; /* ;AN000;M */
574 sublist.pad_char = (unsigned char)BLNK ; /* ;AN000;M */
575 inregs.x.ax = message ; /* ;AN000;M Cannot JOIN a network drive */
576 inregs.x.bx = handle ; /* ;AN000;M STDERR */
577 inregs.x.si = (unsigned int)&sublist ; /* ;AN000;M Point to the substitution buffer */
578 inregs.x.cx = sub_cnt ; /* ;AN000;M SUBCNT1 */
579 inregs.h.dl = function ; /* ;AN000;M STR_INPUT */
580 inregs.h.dh = msg_class ; /* ;AN000;M Extended, Parse or Utility */
581 sysdispmsg(&inregs,&outregs) ; /* ;AN000;M Call common msg service */
582 break ; /* ;AN000;M */
583 default : exit(ERRORLEVEL1) ; /* ;AN000;M */
584 break ; /* ;AN000;M */
587 if (outregs.x.cflag & CARRY) /* ;AN000;M Is the carry flag set? */
588 { /* ;AN000;M Then setup regs for extd-err */
589 inregs.x.bx = STDERR ; /* ;AN000;M */
590 inregs.x.cx = SUBCNT0 ; /* ;AN000;M */
591 inregs.h.dl = NO_INPUT ; /* ;AN000;M */
592 inregs.h.dh = EXT_ERR_CLASS ; /* ;AN000;M */
593 sysdispmsg(&inregs,&outregs) ; /* ;AN000;M Call to display ext_err msg */
594 exit(ERRORLEVEL1) ; /* ;AN000;M */
596 return ; /* ;AN000;M */
598 /*ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ*/
599 /**************************************************************************/
601 /* SUBROUTINE NAME: dispmsg_terminate */
603 /* SUBROUTINE FUNCTION: Display the message, then terminate the utility.*/
605 /* INPUT: msg_num (#define'd message to display) */
606 /* outline (substitution parameter) */
608 /**************************************************************************/
610 dispmsg_terminate(msg_num,outline) /* ;AN000;P */
611 int msg_num ; /* ;AN000;P Message number #define'd */
612 char *outline ; /* ;AN001;P Substitution parameter */
614 display_msg(msg_num,outline) ; /* ;AN000;P First, display the msg */
615 exit(ERRORLEVEL1) ; /* ;AN000;P Then, terminate utility */
617 /*ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ*/
618 /**************************************************************************/
620 /* SUBROUTINE NAME: Parser_Prep */
622 /* SUBROUTINE FUNCTION: Initialize all structures for the parser. */
624 /* INPUT: source (command line string) */
628 /* EXTERNAL REF: parse */
630 /**************************************************************************/
632 Parser_Prep(source) /* ;AN000;P */
633 char *source ; /* ;AN000;P Commandline */
635 p_p.p_parmsx_address = &p_px ; /* ;AN000;P Address of extended parm list */
636 p_p.p_num_extra = 0 ; /* ;AN000;P No extra declarations */
638 p_px.p_minp = MINPOSITION ; /* ;AN000;P */
639 p_px.p_maxp = MAXPOSITION ; /* ;AN000;P */
640 p_px.p_control1 = &p_con1 ; /* ;AN000;P Point to 1st control blk */
641 p_px.p_control2 = &p_con2 ; /* ;AN000;P Point to 2nd control blk */
642 p_px.p_maxs = 1 ; /* ;AN000;P Specify # of switches */
643 p_px.p_switch = &p_swi1 ; /* ;AN000;P Point to the switch blk */
644 p_px.p_maxk = 0 ; /* ;AN000;P Specify # of keywords */
646 p_con1.p_match_flag = DRVONLY_OPT ; /* ;AN000;P Drive only & optional */
647 p_con1.p_function_flag = NOCAPPING ; /* ;AN000;P Cap result by file table */
648 p_con1.p_result_buf = (unsigned int)&rslt1 ; /* ;AN000;P Point to result blk */
649 p_con1.p_value_list = (unsigned int)&novals ; /* ;AN000;P Point to no value list */
650 p_con1.p_nid = 0 ; /* ;AN000;P Not a switch id */
652 p_con2.p_match_flag = FILESPEC_OPT ; /* ;AN000;P File spec & optional */
653 p_con2.p_function_flag = CAPRESULT ; /* ;AN000;P Cap result by file table */
654 p_con2.p_result_buf = (unsigned int)&rslt2 ; /* ;AN000;P Point to result blk */
655 p_con2.p_value_list = (unsigned int)&novals ; /* ;AN000;P Point to no value list */
656 p_con2.p_nid = 0 ; /* ;AN000;P Not a switch id */
658 p_swi1.sp_match_flag = SWITCH_OPT ; /* ;AN000;P Optional (switch) */
659 p_swi1.sp_function_flag = NOCAPPING ; /* ;AN000;P Cap result by file table */
660 p_swi1.sp_result_buf = (unsigned int)&rslt3 ; /* ;AN000;P Point to result blk */
661 p_swi1.sp_value_list = (unsigned int)&novals ; /* ;AN000;P Point to no value list */
662 p_swi1.sp_nid = 1 ; /* ;AN000;P One switch allowed */
663 strcpy(p_swi1.sp_keyorsw,D_SWITCH) ; /* ;AN000;P Identify the switch */
665 inregs.x.cx = 0 ; /* ;AN000;P Operand ordinal */
666 inregs.x.di = (unsigned int)&p_p ; /* ;AN000;P Address of parm list */
667 inregs.x.si = (unsigned int)source ; /* ;AN000;P Make DS:SI point to source */
668 return ; /* ;AN000; */