- Visual C++源码
- Visual Basic源码
- C++ Builder源码
- Java源码
- Delphi源码
- C/C++源码
- PHP源码
- Perl源码
- Python源码
- Asm源码
- Pascal源码
- Borland C++源码
- Others源码
- SQL源码
- VBScript源码
- JavaScript源码
- ASP/ASPX源码
- C#源码
- Flash/ActionScript源码
- matlab源码
- PowerBuilder源码
- LabView源码
- Flex源码
- MathCAD源码
- VBA源码
- IDL源码
- Lisp/Scheme源码
- VHDL源码
- Objective-C源码
- Fortran源码
- tcl/tk源码
- QT源码
BATCH.C
资源名称:drdossrc.zip [点击查看]
上传用户:xiaogehua
上传日期:2007-01-08
资源大小:1183k
文件大小:70k
源码类别:
操作系统开发
开发平台:
Asm
- /*
- ; File : $Workfile: BATCH.C$
- ;
- ; Description :
- ;
- ; Original Author : DIGITAL RESEARCH
- ;
- ; Last Edited By : $CALDERA$
- ;
- ;-----------------------------------------------------------------------;
- ; Copyright Work of Caldera, Inc. All Rights Reserved.
- ;
- ; THIS WORK IS A COPYRIGHT WORK AND CONTAINS CONFIDENTIAL,
- ; PROPRIETARY AND TRADE SECRET INFORMATION OF CALDERA, INC.
- ; ACCESS TO THIS WORK IS RESTRICTED TO (I) CALDERA, INC. EMPLOYEES
- ; WHO HAVE A NEED TO KNOW TO PERFORM TASKS WITHIN THE SCOPE OF
- ; THEIR ASSIGNMENTS AND (II) ENTITIES OTHER THAN CALDERA, INC. WHO
- ; HAVE ACCEPTED THE CALDERA OPENDOS SOURCE LICENSE OR OTHER CALDERA LICENSE
- ; AGREEMENTS. EXCEPT UNDER THE EXPRESS TERMS OF THE CALDERA LICENSE
- ; AGREEMENT NO PART OF THIS WORK MAY BE USED, PRACTICED, PERFORMED,
- ; COPIED, DISTRIBUTED, REVISED, MODIFIED, TRANSLATED, ABRIDGED,
- ; CONDENSED, EXPANDED, COLLECTED, COMPILED, LINKED, RECAST,
- ; TRANSFORMED OR ADAPTED WITHOUT THE PRIOR WRITTEN CONSENT OF
- ; CALDERA, INC. ANY USE OR EXPLOITATION OF THIS WORK WITHOUT
- ; AUTHORIZATION COULD SUBJECT THE PERPETRATOR TO CRIMINAL AND
- ; CIVIL LIABILITY.
- ;-----------------------------------------------------------------------;
- ;
- ; *** Current Edit History ***
- ; *** End of Current Edit History ***
- ;
- ; $Log$
- ; ENDLOG
- */
- /*
- * 27 Oct 87 Improve GOTO command to ignore trailing white space, only
- * match on the first 8 characters and only allow valid
- * filename characters.
- * 28 Oct 87 Correct duplicate prompt display when a batch file label
- * is read and the echo flag is ON.
- * 9 Nov 87 Change Batch file termination so that Output Redirection is
- * correctly handled.
- * 13 Jan 88 If prompt display is aborted because of a critical error
- * the following prompt will be forced to "$n$g".
- * 25 Jan 88 Support redirection on the FOR command correctly
- * 24 Feb 88 Generate batch file parameter %0 correctly as WS200 install
- * requires that the drive specifier be present. Garry Silvey
- * 5 May 88 Batch paramater %0 is now a copied from the invoking command
- * line.
- * 18 May 88 Support the ESC_CHAR in the command line.
- * 20 May 88 Disable MULTI_CHAR support in DOSPLUS when the user enters the
- * first command.
- * 26 May 88 Added STACK switch and support $q in prompt.
- * 27 May 88 Added string undefs.
- * 6 Jun 88 Call resident portion to do readline (SideKick+ problem)
- * 23 Jun 88 Support CR only delimited batch files and if errorlevel ==
- * syntax used in installation files.
- * 6 Jul 88 Support the FOR ... CALL syntax correctly. (IMS)
- * 17 Aug 88 Jump to labels followed by comments (Ashton Tate By-Line)
- * 21 Sep 88 Use KEYIN_FLG to allow the default ECHO state to be ON.
- * 16 Nov 88 Disable BACK_CHAR in Concurrent DOS.
- * 21 Dec 88 Allow leading whitespace before labels
- * 5 Jan 89 Support Quoted strings in Batch files.
- * 18 Apr 89 Support Quoted strings in IF command
- * 19 Apr 89 Quotes in IF command: "x == "x" parses, "x=x" == "x.. doesn't
- * 24 Apr 89 Increase MAX_LINE to 128 for pctools ver 5
- * 19 May 89 Take out support for quoted strings in IF command
- * 05 Jun 89 Do not echo command or display the prompt during FOR command.
- * Restore support for batch files with long lines.
- * 02 Nov 89 batch_line bodge which substitutes 0xFF for 0x00 changed - we
- * now substitute 'rn', then throw away rest of the line.
- * 01 Dec 89 batch_line - trailing % at end of line is discarded
- * 15 Dec 89 "if errorlevel -1" allowed
- * 30 Jan 90 Added int2e_start and int2e_finish to save and restore
- * important batch file variables to allow novell menu program
- * to use int 2e to invoke batch files.
- * 30 Jan 90 Forced batch data structures to appear on segment boundaries;
- * Added dummy memory descriptor before batch structure;
- * Put segment address of batch structure in batch_seg_ptr;
- * All so novell can find and patch the drive letter of
- * autoexec.bat during a remote boot.
- * 6-Mar-90 Watcom C v 7.0
- * 7-Mar-90 allow ESC_CHAR through unless followed by MULTI/BACK_CHAR
- * 14-Mar-90 Reduce batch_buf to 32 bytes like wot dos is
- * 20-Mar-90 Batch structures allocated by mem_alloc (ie. MS_M_ALLOC)
- * rather than on heap. Batch file nesting no longer heap limited.
- * 27-Mar-90 Allow "=", "==", "===" etc in "if errorlevel==n"
- * 10-Apr-90 Make errorlevel 999 same as errorlevel 231 (mod 256)
- * 8-May-90 Don't echo getcmd unless batch file (eg. "dir|more" shouldn't
- * echo "C:>more")
- * 23-May-90 batch_read no longer repeatedly deblanks line (which leads
- * to the buffer happily wandering up memory).
- * 30-May-90 "if ab de==ef" form doesn't generate syntax error
- * 13-Jun-90 batch_line rejects unmatched "|" as syntax error
- * 20-Sep-90 is_filechar() and is_pathchar() now take pointer instead of byte
- * Changed batch_char() to return pointer instead of byte,
- * renamed to batch_ptr().
- * Amended make_label(), batch_start() and cmd_for() to check for
- * DBCS lead bytes.
- * 24-Sep-90 Add $m and $u option to PROMPT to display status of mail
- and user name respectively
- * 27-Sep-90 Add IF USERID <userid> COMMAND
- IF LOGINNAME <loginname> COMMAND
- IF GROUPNAME <groupname> COMMAND
- IF ASK ["string"] <char> COMMAND
- .. AND .. OR .. to IF processing
- INPUT ["string"] <environment-variable>
- INPUTC ["string"] <environment-variable>
- * 10-Oct-90 inherit batch files from TMP when TSR auto-loads CDOS.COM
- (a bodge for Stellar)
- * 25-Oct-90 inherit echoflg from TMP when TSR auto-loads CDOS.COM
- * 31-Oct-90 change IF ASK command to IF KEY command
- DRDOS BUXTON
- ------------
- * 25-Apr-91 '!' is now ignored during COMMAND /C processing.
- * 28-May-91 leading white space is now ignored before labels.
- * 09-Jun-91 Added GOSUB, RETURN and SWITCH commands.
- * 24-Jul-91 if batch_seg_ptr is poked to zero all batch processing is
- terminated.
- * 26-Jul-91 batch files are now read into a far buffer. This avoids
- reading directly to seg FFFF if we happen to be there and so
- solves some NOVELL problems.
- * 18-Jun-92 Support ? in batch files as in config.sys.
- * 23-Jun-92 $u in prompt causes LOGINNAME in environment to be displayed.
- * 07-Jul-92 IF EXIST now finds hidden files.
- */
- #include "defines.h"
- #include <string.h>
- #if defined(MWC) && defined(strlen)
- #undef strcmp /* These are defined as macros in string.h */
- #undef strcpy /* which are expanded in line under */
- #undef strlen /* Metaware C. These undefs avoid this. */
- #endif
- #include <portab.h>
- #if !defined(DOSPLUS)
- #include <ccpm.h>
- #endif
- #include "command.h"
- #include "toupper.h"
- #include "support.h"
- #include "dosif.h"
- #include "global.h"
- #include "dos.h"
- #include <setjmp.h>
- /*RG-01*/
- #if defined(CDOSTMP) || defined(CDOS)
- #include <pd.h>
- #define PATH_LEN 65 /* max path length (null terminated) */
- EXTERN PD FAR * CDECL pd; /* Far pointer to Current PD */
- EXTERN VOID CDECL cmd_set(BYTE *); /* COMINT.C */
- #if !defined (NOSECURITY)
- #include "security.h"
- #include "login.h"
- #endif
- #endif
- /*RG-01-end*/
- EXTERN VOID CDECL cmd_pause();
- EXTERN BOOLEAN parse(BYTE *);
- EXTERN UWORD boot_key_scan_code; /* in COM.C */
- /*RG-03*/
- BOOLEAN if_context=FALSE;
- BOOLEAN ifcond=FALSE;
- /*RG-03-end*/
- EXTERN jmp_buf break_env;
- #define MAX_LINE 128 /* Maximum No of Chars in input line */
- #if defined(CPM)
- EXTERN UWORD user; /* USER Number variable for CPM.EXE */
- #endif
- EXTERN BYTE msg_prmeq[]; /* Static Environ String "PROMPT=" */
- #if 0
- #define FCONTROL struct fcc
- MLOCAL FCONTROL {
- BOOLEAN sflg; /* FOR File Search Flag */
- DTA search; /* FOR Search structure */
- BYTE *files; /* FOR File list */
- BYTE *cmd; /* FOR Command Line */
- BYTE forvar; /* FOR variable char */
- };
- #endif
- MLOCAL FCONTROL *forptr;
- #if 0
- #define BCONTROL struct bcc
- GLOBAL BCONTROL {
- BCONTROL FAR *bcontrol; /* Previous Batch Control Structure */
- BOOLEAN eof; /* End of File Flag */
- LONG offset; /* Offset in BATCH file */
- LONG ret_offset[4]; /* return offset from gosub */
- BYTE *batcmd; /* Batch File Input parameters */
- UWORD batshift; /* Shift Offset */
- BYTE batfile[MAX_PATHLEN]; /* Batch File Name */
- UWORD stream; /* Stream for this Batch File */
- FCONTROL *fcontrol; /* Pointer to previous FOR command */
- BYTE *heap_start; /* Heap pointer before extra bytes */
- WORD heap_size; /* are added to shift to segment */
- BYTE save_area[1]; /* boundary. - EJH */
- } FAR *batch, FAR *batch_save; /* Master Batch Control Stucture */
- #endif
- /* Handle 255 is closed */
- #define CLOSED 0xff
- /* Keyboard Variables */
- GLOBAL BYTE kbdbuf[MAX_LINE+2]= {0};/* Keyboard Input Buffer */
- GLOBAL BYTE *kbdptr = kbdbuf+2; /* Keyboard Buffer Pointer */
- MLOCAL BOOLEAN keyin_flg = FALSE; /* This flag is set to TRUE when the */
- /* initial command line buffer setup */
- /* by INIT() has been exhausted. */
- MLOCAL WORD batchflg_save; /* Used during INT 2E handling. */
- MLOCAL WORD echoflg_save; /* ditto above */
- GLOBAL WORD echoflg_save2; /* saves echo state when batch file */
- /* execed. */
- /*
- * Batch file buffering control structures.
- */
- MLOCAL LONG batch_off; /* Offset of buffered data in File */
- MLOCAL WORD batch_cnt = 0; /* Number of bytes in buffer */
- MLOCAL BYTE batch_buf[32];
- MLOCAL BYTE batch_eof[] = "x1a"; /* End of file string */
- MLOCAL BYTE batch_sep[] = "t ;,="; /* Batch Command line option delimiters */
- EXTERN VOID CDECL cmd_ver(BYTE *); /* COMINT.C Display Version */
- EXTERN VOID docmd(BYTE *, BOOLEAN); /* COM.C */
- EXTERN VOID CDECL int_break(VOID); /* COM.C */
- GLOBAL BOOLEAN getcmd(BYTE *);
- GLOBAL VOID for_end();
- GLOBAL VOID batch_start(BYTE *, BYTE *, BYTE *);
- GLOBAL VOID batch_end(VOID);
- GLOBAL VOID batch_close(VOID);
- MLOCAL VOID for_in(BYTE *);
- MLOCAL WORD batch_open(VOID);
- MLOCAL VOID batch_read(BYTE *, BOOLEAN);
- MLOCAL VOID batch_line(BYTE *, BOOLEAN);
- MLOCAL BYTE *batch_ptr(VOID);
- MLOCAL VOID prompt(VOID);
- MLOCAL BOOLEAN novell_extension(BYTE *, BYTE *);
- #if !defined(CDOSTMP)
- EXTERN UWORD FAR *batch_seg_ptr; /* For novell remote boot. see CSTART.ASM */
- #endif
- #if defined(CDOS) || defined(CDOSTMP)
- #define TmpPspEchoFlgPtr 0x58 /* Magic location to keep echo flag */
- #define TmpPspDataSeg 0x5a /* Magic location to keep Data Seg */
- #define TmpPspBatchSeg 0x5c /* Magic location to keep Batch Ptr */
- #define TmpPspMpad 0x5e /* Magic location to keep unlinked MPAD */
- #endif
- #if defined(CDOS)
- typedef struct _mpad
- {
- UWORD link; /* address of next MPAD */
- UWORD start; /* seg of allocation unit */
- UWORD length; /* length in paras */
- UWORD res0x06; /* reserved */
- UWORD xios; /* Process id */
- } MPAD;
- GLOBAL VOID inherit_TMP_state(VOID);
- #endif
- /*.pa*/
- GLOBAL BOOLEAN getcmd(line) /* read command line */
- BYTE *line;
- {
- BYTE *s;
- BOOLEAN quote = FALSE;
- BOOLEAN cancel_prompt = FALSE;
- #if defined(DOSPLUS)
- WORD i;
- BYTE cmd_name[16];
- #endif
- back_flag = FALSE; /* Disable BackGround Processing*/
- *line = '';
- FOREVER {
- if(for_flag) { /* If Processing a FOR command */
- for_in(line); /* then call then use the FOR_IN*/
- return NO; /* routine to fill the keyboard */
- } /* buffer and then return */
- if(!batchflg) /* If no batch processing then */
- break; /* skip further tests */
- batch_restart:
- #if defined(DOSPLUS)
- if (!*batch_seg_ptr) { /* if batch_seg_ptr has been set to */
- batch_endall(); /* zero terminate all batch files */
- return NO;
- }
- #endif
- if(batchflg && batch->eof) { /* Close the batch file if at */
- batch_end(); /* the end of the file. */
- if(batchflg == 0) /* BREAK if batch processing */
- return NO; /* is complete. */
- continue;
- }
- if(!batch_open()) /* Open the file and read a line*/
- return YES; /* from the file */
- batch_read(line, NO); /* Read Line */
- if(batch->eof) /* If the end of the batch file */
- batch_close(); /* has been detected then close */
- /* the file. */
- if (*line == '?' || boot_key_scan_code == 0x4200) {
- optional_line(line);
- }
- if(*line == '@') { /* If first character in the */
- strcpy(line, line+1); /* command line is '@' donot */
- return NO; /* echo the command and move the*/
- } /* string down 1 character. */
- if (!cancel_prompt) {
- if(crlfflg && echoflg)
- crlf();
- prompt();
- }
- return echoflg;
- }
- if(!*kbdptr) { /* Set the Keyboard Input flag */
- keyin_flg = TRUE; /* after a initial command line */
- /* buffer has been exhausted */
- #if 1
- if (c_option) { /* insert an EXIT command if we */
- kbdptr = &kbdbuf[2]; /* are processing a /C command */
- strcpy(&kbdbuf[2],"exit");
- }
- #endif
- }
- if (!*kbdptr) { /* Check for existing line */
- /* NEIL */
- if(crlfflg && echoflg)
- crlf();
- /* NEIL end */
- prompt(); /* issue command line prompt */
- allow_pexec = FALSE;
- /* $x in prompt string may cause batchflg to be set. */
- /* If so we must jump to batch processing code. */
- if (batchflg) {
- cancel_prompt = TRUE;
- goto batch_restart;
- }
- kbdptr = ""; /* Force KBDPTR to point to ''*/
- /* in case we get ABORTED and */
- /* drop through here again. */
- kbdbuf[0] = MAX_LINE; /* set max. input length */
- kbdbuf[kbdbuf[1]+2] = 'r'; /* Terminate current line. */
- #if defined(CDOSTMP)
- system(C_READSTR, kbdbuf); /* read a line */
- #else
- readline(kbdbuf);
- #endif
- crlf();
- kbdbuf[kbdbuf[1] + 2]=''; /* terminate input */
- kbdptr = kbdbuf + 2;
- }
- s = kbdptr;
- while(*s) {
- if(*s == '"') /* Check for a " character and */
- quote = !quote; /* update the flag correctly */
- #if !defined(DOSPLUS)
- if(*s == ESC_CHAR && /* If the Escape character has */
- !quote && /* been specified then do not */
- ((*(s+1) == MULTI_CHAR) || (*(s+1) == BACK_CHAR))) {
- *line++ = *++s; /* process the following char. */
- s++;
- continue;
- }
- #endif
- #if defined(DOSPLUS) /* Disable MULTI_CHAR support */
- if(!(keyin_flg||c_option||k_option))
- /* after the init command line */
- #endif /* has been exhausted. */
- if(*s == MULTI_CHAR && /* If a Multiple command char */
- !quote) { /* and the QUOTE flag is FALSE */
- s++; /* then break the command here */
- break; /* and save the rest of the line*/
- } /* for next time. */
- #if FALSE /* defined(CDOSTMP) */
- if(*s == BACK_CHAR && /* If a Back Ground processing */
- !quote) { /* and the QUOTE flag is FALSE */
- s++; /* then treat as for MULTI_CHAR */
- back_flag = TRUE; /* except that the current */
- break; /* command is executed in the */
- } /* background. */
- #endif
- if(*s == PIPE_CHAR && /* If a Pipe enable character */
- !quote) { /* and the QUOTE flag is FALSE */
- s++; /* then break the command here */
- pipe_out = YES; /* and save the rest of the line*/
- break; /* for next time. */
- }
- copy_char(&line, &s); /* Just save the character */
- }
- *line = ''; /* Terminate the Buffer */
- kbdptr = deblank(s); /* Copy the possibly null length*/
- return NO; /* string to KBDBUF for next */
- /* next invocation and save CCP */
- }
- MLOCAL VOID for_in(line) /* A FOR command is currently */
- BYTE *line; /* executing so build the line */
- { /* from the internal FOR data */
- BYTE *s,*t; /* initialized by CMD_FOR */
- BYTE *bp1, *fp;
- WORD i;
- FOREVER {
- fp = forptr->files; /* Get the next string and stop */
- if(strlen(fp) == 0) { /* if its the zero length string */
- *line = ''; /* which marks the end of the FOR */
- crlfflg = YES; /* search list. */
- for_end();
- return;
- }
- if(!iswild(fp)) { /* If not an ambiguous file */
- forptr->sflg = NO; /* then update the FOR */
- forptr->files += strlen(fp)+1; /* pointer to the next file */
- break; /* in the search list. */
- }
- if(forptr->sflg) /* Search for the next file */
- i = ms_x_next(&forptr->search); /* file on the disk if */
- else /* FOR_SFLG otherwise get first */
- i = ms_x_first(fp, ATTR_RO, &forptr->search);
- if(i < 0) { /* If the search failed */
- forptr->sflg = NO; /* then update the FOR */
- forptr->files += strlen(fp)+1; /* pointer to the next file */
- continue; /* in the search list. */
- } /* and get the next entry */
- fp = (BYTE *) heap();
- strip_path(forptr->files, fp); /* Extract the Path */
- strcat(fp, forptr->search.fname); /* and then add the matching */
- forptr->sflg = YES; /* filename and update the */
- strupr(fp); /* variables. */
- break; /* Force name to uppercase */
- }
- s = forptr->cmd;
- t = line;
- while (*s && (t - line) < MAX_LINE) { /* Copy the command */
- if(*s == '%' && *(s+1) == forptr->forvar) { /* line looking for */
- s += 2; /* the imbedded %c and insert*/
- bp1 = fp; /* the current substition */
- while(*bp1 && (t - line) < MAX_LINE) /* string pointed at by FP */
- copy_char(&t, &bp1);
- continue;
- }
- copy_char(&t, &s);
- }
- *t = ''; /* and terminate the string */
- }
- /*.pa*/
- /*
- * BATCH FILE CONTROL ROUTINES
- * ===========================
- *
- * The following routines provide the interface from COMMAND.COM to
- * a batch file. BATCH_START sets up all the local variables to enable
- * batch processing while BATCH_END terminates batch processing. BATCH_READ
- * reads a line of data from the batch file and expands it to contain the
- * command line variables and variables from the environment.
- */
- GLOBAL VOID batch_start(argv0, path, tail)
- BYTE *argv0; /* Invoking Command */
- BYTE *path; /* Complete filename */
- BYTE *tail; /* Command Line Options */
- {
- BYTE *s2;
- BYTE dirbuf[MAX_PATHLEN];
- WORD i;
- if(batchflg) /* If a batch file is currently */
- batch_close(); /* close it. So minimum number */
- /* of handles are used. */
- s2 = path; /* Save the original Path */
- if((path = d_check(path)) == NULL) /* Check that the file */
- return; /* exists. */
- batch_new(); /* new incarnation of batch */
- forptr = (FCONTROL *) NULL; /* Disable current FOR control */
- for_flag = NO; /* and Global FOR flag */
- /*
- * Generate the full path specification for the batch file
- * and store in the batch control information. If the user
- * has specified the full path use it otherwise determine the
- * full path using ms_x_curdir.
- */
- if (ddrive != -1 && *path != *pathchar) {
- ms_x_curdir(ddrive+1, dirbuf);
- sprintf(heap(), "%c:%s%s%s%s", ddrive + 'A',
- pathchar,
- dirbuf,
- (*dirbuf ? pathchar : ""),
- path);
- }
- else if (ddrive != -1)
- sprintf(heap(), "%c:%s", ddrive + 'A', path);
- else
- ms_x_expand(heap(), path);
- for (i=0; i<MAX_PATHLEN; i++) /* save the batch pathname */
- batch->batfile[i] = heap()[i];
- batch->batfile[MAX_PATHLEN-1] = 0;
- /*
- * Copy the invoking command and the individual elements
- * of the command line into a buffer ready for processing
- */
- batch->batcmd = (BYTE *)heap(); /* Initialize Parameter Buffer */
- strcpy(heap(), argv0); /* Copy the invoking command */
- heap_get(strlen(heap())+1); /* and protect the buffer */
- while(*tail) { /* While there are command line */
- s2 = (BYTE *)heap(); /* parameters copy them */
- while(*tail && strchr(batch_sep, *tail))
- tail = skip_char(tail);
- while(*tail && !strchr(batch_sep, *tail))
- copy_char(&s2, &tail);
- *s2++ = '';
- heap_get(strlen(heap()) + 1);
- }
- *(WORD *)heap_get(2) = 0; /* Double NULL is a terminator */
- /* for command line params */
- if(in_flag & REDIR_ACTIVE) /* If Input redirection has been */
- in_flag |= REDIR_BATCH; /* enabled for this command force*/
- /* it on for the complete command*/
- if(out_flag & REDIR_ACTIVE) /* If Output redirection has been*/
- out_flag |= REDIR_BATCH; /* enabled for this command force*/
- /* it on for the complete command*/
- batchflg++; /* increment batch flag */
- crlfflg = YES; /* print CR/LF after this */
- }
- GLOBAL VOID batch_endall() /* This terminates BATCH */
- { /* processing by closing ALL */
- while(batchflg) { /* active batch files */
- batch_end();
- }
- }
- GLOBAL VOID batch_end() /* This function is called for */
- { /* both NORMAL and ABNORMAL */
- if(batchflg == 0) /* termination of batch file */
- return; /* processing */
- boot_key_scan_code = 0;
- batch_close(); /* Close the Batch file */
- for_end(); /* Terminate Any FOR command */
- batch_old(); /* Restore the previous batch */
- /* control structures to heap */
- if(--batchflg == 0) {
- *batch_seg_ptr = 0;
- echoflg = echoflg_save2; /* Restore the original ECHO */
- crlfflg = YES; /* flag and set CR/LF flag when */
- } /* returning to the keyboard. */
- }
- MLOCAL BOOLEAN batch_open()
- {
- WORD h, i;
- BYTE *name;
- if(batch->eof) { /* If the End of the batch file */
- batch_end(); /* was discovered last time then*/
- return FALSE; /* End Batch file input and exit*/
- }
- if(batch->stream != CLOSED)
- return batch->stream;
- name = heap();
- for (i=0; i<MAX_PATHLEN; i++)
- name[i] = batch->batfile[i];
- while ((h = ms_x_open(name, OPEN_READ)) < 0) {
- err_flag = TRUE;
- eprintf(MSG_BATMISS, name); /* prompt for batch file */
- heap_get(strlen(name)+1);
- cmd_pause("");
- heap_set(name);
- }
- err_flag = FALSE;
- batch->stream = h;
- return TRUE;
- }
- GLOBAL VOID batch_close()
- {
- if(batchflg != 0 &&
- batch->stream != CLOSED) { /* Check if the batch file */
- batch_cnt = 0; /* currently open if YES */
- ms_x_close(batch->stream); /* then flush the internal */
- batch->stream = CLOSED; /* buffer and close file. */
- }
- }
- #if defined(DOSPLUS)
- GLOBAL VOID inherit_batch_file(bc)
- BCONTROL FAR *bc;
- {
- WORD i;
- BYTE FAR *p_heap;
- BYTE *l_heap;
- /* inherit any parent batch file first */
- if (bc->bcontrol) inherit_batch_file(bc->bcontrol);
- /* create a new batch structure */
- batch_new();
- batch->offset = bc->offset; /* continue at same offset */
- for (i=0;i<4;i++) batch->ret_offset[i] = bc->ret_offset[i];
- batch->batshift = bc->batshift;
- for (i=0; i<MAX_PATHLEN; i++) /* get the batch pathname */
- batch->batfile[i] = bc->batfile[i];
- batch->batfile[MAX_PATHLEN-1] = 0;
- /* get command line */
- p_heap = MK_FP(*parent_psp+16,bc->batcmd);
- l_heap = heap();
- while (1) {
- while(*p_heap) *l_heap++ = *p_heap++;
- *l_heap++ = *p_heap++;
- if (*p_heap == 0) {
- *l_heap = 0;
- break;
- }
- }
- heap_get(l_heap-heap());
- batchflg++;
- }
- GLOBAL VOID inherit_parent_state()
- {
- UWORD FAR *p;
- BCONTROL FAR *bc;
- UWORD root_psp;
- root_psp = *parent_psp;
- while(1) {
- p = MK_FP(root_psp-1,8);
- if (p[0] == 0x4F43 && p[1] == 0x4D4D &&
- p[2] == 0x4E41 && p[3] == 0x0044) break;
- p = MK_FP(root_psp,0x16);
- root_psp = *p;
- }
- p = MK_FP(root_psp+16,batch_seg_ptr);
- #if 0
- printf("batch_seg_ptr = %04X:%04Xn",p);
- printf("parent batch_seg_ptr = %04Xn",*p);
- #endif
- if (*p == 0 || *p == 0xFFFF) return;
- bc = MK_FP(*p,0);
- inherit_batch_file(bc);
- *p = 0;
- p = MK_FP(root_psp+16,&echoflg);
- echoflg = *p;
- }
- #endif
- GLOBAL VOID batch_new()
- /* save current batch file heap contexts to high memory */
- {
- BYTE *hp_start;
- WORD hp_size;
- UWORD i;
- BCONTROL FAR *bc;
- #if defined(CDOSTMP)
- UWORD FAR *ptr;
- #endif
- if (batchflg != 0)
- hp_start = batch->heap_start;
- else
- hp_start = heap();
- hp_size = heap() - hp_start;
- i = (sizeof(BCONTROL) + hp_size + 15)/16;
- mem_alloc(&bc, &i, i, i); /* allocate new batch structure */
- if (i == 0) { /* if we can't allocate one */
- longjmp(break_env, IA_HEAP);/* then pretend heap has run out*/
- } /* to force termination. */
- bc->bcontrol = batch; /* Link to Previous Structure */
- batch = bc; /* make this current batch struc*/
- batch->eof = NO; /* Have not found the EOF yet */
- batch->offset = 0L; /* start at beginning of File */
- for (i=0;i<4;i++) batch->ret_offset[i] = 0L;
- batch->batshift = 0; /* No Shift Factor */
- batch->stream = CLOSED; /* Batch file is not open */
- batch->fcontrol = forptr; /* Save current FOR control */
- batch->heap_start = hp_start; /* Save original heap */
- batch->heap_size = hp_size;
- for (i=0; i < hp_size; i++) {
- batch->save_area[i] = hp_start[i];
- }
- heap_set(hp_start); /* free up heap used by old batch */
- #if defined(CDOSTMP)
- ptr = MK_FP(pd->P_PSP, TmpPspEchoFlgPtr);
- *ptr = (UWORD)&echoflg;
- ptr = (UWORD FAR *) &ptr; /* coerce a FAR * to local data */
- i = FP_SEG(ptr); /* so we can get local data segment */
- ptr = MK_FP(pd->P_PSP, TmpPspDataSeg);
- *ptr = i; /* save local data segment */
- ptr = MK_FP(pd->P_PSP, TmpPspBatchSeg);
- *ptr = (UWORD)(((ULONG)batch) >> 16);
- #else
- /* Get segment address of batch and put it where novell */
- /* can find it. */
- *batch_seg_ptr = (UWORD)(((ULONG)batch) >> 16);
- #endif
- }
- MLOCAL VOID batch_old()
- /* restore current batch file heap contents from high memory */
- {
- BCONTROL FAR *bc;
- UWORD i;
- #if defined(CDOSTMP)
- UWORD FAR *ptr;
- #endif
- heap_set(batch->heap_start+batch->heap_size);
- for (i=0; i<batch->heap_size; i++) {
- batch->heap_start[i] = batch->save_area[i];
- }
- bc = batch;
- forptr = batch->fcontrol; /* Restore the previous for */
- for_flag = (BOOLEAN) forptr; /* control structures */
- batch = batch->bcontrol; /* restore ptr to previous batch */
- mem_free(&bc); /* free up batch memory */
- #if defined(CDOSTMP)
- ptr = MK_FP(pd->P_PSP, TmpPspBatchSeg);
- *ptr = (UWORD)(((ULONG)batch) >> 16);
- #endif
- }
- /*
- * Read lines repeatedly from the batch file until a line in
- * the correct format is read from the batch file or the EOF
- * has been reached.
- */
- MLOCAL VOID batch_read(line, goto_flg)
- BYTE *line; /* Command Line Buffer */
- BOOLEAN goto_flg; /* Goto Command Flag */
- {
- BYTE *l; /* we need to deblank line */
- do {
- batch_line(line, goto_flg); /* Read the next line from */
- l = deblank(line); /* the batch file and return*/
- if(*l != ';') {
- if(goto_flg && *l == ':') /* a line in the correct */
- return; /* format. */
- if(!goto_flg && *l != ':')
- return;
- }
- } while(!batch->eof);
- }
- /*
- * Read one line from the batch file and place the expanded data into
- * the buffer LINE.
- */
- MLOCAL VOID batch_line(line, goto_flg)
- BYTE *line; /* Command Line Buffer */
- BOOLEAN goto_flg; /* Goto Command Flag */
- {
- REG WORD i;
- REG BYTE *s;
- WORD n, env_start;
- BYTE c, *bp;
- BYTE env_str[128];
- BOOLEAN quote = FALSE;
- LONG old_offset;
- int j;
- env_start = NULL; /* Copy the environment into a */
- #if 0
- /* 'eject any line starting with 'rem' */
- old_offset = batch->offset;
- i=0;
- do{
- switch(c=*batch_ptr()){
- case 0x1a:
- batch->eof = YES; /* We have come to the end */
- c = 'r'; /* of the batch file so set */
- break; /* flag and mark end of line*/
- default:
- if (i < MAX_LINE)
- line[i++] = c;
- if (dbcs_lead(c)) {
- if ((c = *batch_ptr()) >= ' ' && i < MAX_LINE)
- line[i++] = c;
- }
- }/*switch*/
- }while(c!='r');
- if (*batch_ptr() != 'n') batch->offset--;
- line[i]=0;
- j=0;
- while(line[j]){
- if (line[j] != ' ')
- break;
- j++;
- }
- if (( strlwr(line[j]) == 'r') &&
- ( strlwr(line[j+1]) == 'e') &&
- ( strlwr(line[j+2]) == 'm') &&
- ( strlwr(line[j+3]) == ' ')){
- if (echoflg)
- printf("%sn",line);
- line[0]='';
- return;
- }
- batch->offset = old_offset;
- batch->eof = NO;
- #endif
- /*rbf-end*/
- /* process line */
- i = 0;
- do {
- switch(c = *batch_ptr()) {
- case '': /* In OS/2 install.bat file */
- #if 0
- if (i < MAX_LINE) /* "ECHO " displays blank */
- line[i++] = 'r'; /* line - so we insert a CR */
- while (c != 'r') { /* then swallow rest of line */
- c = *batch_ptr(); /* read next character - if */
- if (c == 0x1a) /* it's an EOF mark then use */
- goto end_of_file; /* end-of-file code else end */
- } /* up falling into 'r' code */
- #else
- c = *batch_ptr();
- if ((c == 'r') && (i < MAX_LINE))
- line[i++] = 'r';
- #endif
- case 'r': /* carriage return */
- if(*batch_ptr() != 'n') /* skip line feed */
- batch->offset--; /* if present */
- break;
- case '"': /* Support Quoted strings */
- quote = !quote; /* in batch files. */
- goto save_it;
- case PIPE_CHAR: /* Handle Piped Output */
- if(goto_flg || quote) /* Ignore this character if */
- goto save_it; /* we are searching for a */
- /* Label or Quote. */
- line[i] = '';
- c = *deblank(line); /* normal case we just */
- if ((c !='') && (c != ':') && following_command()) {
- c = 'r'; /* simulate a CR and set */
- pipe_out = YES; /* Pipe Output flag. */
- } else if (c == ':') { /* if it's a label */
- for(;(c != 'r') && (c != 0x1A); c = *batch_ptr())
- if (c == 0x1A) /* eat rest of the line */
- batch->eof = YES;
- if(*batch_ptr() != 'n')/* skip line feed */
- batch->offset--; /* if present */
- c = 'r';
- } else { /* if it's a syntax error */
- swallow_line(line); /* discard the rest of line */
- i = 0; /* start again with new line */
- }
- break;
- case '%': /* The following code checks to see if the */
- /* string starting at line[env_start-1] is */
- /* define in the environment if it is then */
- /* its definition replaces it in the input */
- /* line. Otherwise no change is made. */
- if(env_start) {
- env_start--;
- line[i] = ''; /* Terminate Input */
- strcpy(env_str, line+env_start);/* Copy the String */
- strupr(env_str); /* and force string */
- bp = (BYTE *)heap(); /* into Uppercase */
- i = env_start;
- env_start = NULL;
- strcat(env_str,"=");
- if (env_scan(env_str,bp)) {
- if (novell_extension(env_str,bp)) break;
- }
- while(*bp && i < MAX_LINE-1)
- line[i++] = *bp++;
- break;
- }
- c = *batch_ptr();
- if (c == 'r') {
- batch->offset--; /* rewind to point to 'r' */
- break; /* then break to normal code */
- }
- if (c < '0' || c > '9') { /* if not a parameter */
- if(c != '%') /* or a '%' character */
- env_start = i+1; /* save its start address in */
- goto save_it; /* the string and wait for */
- } /* the terminating '%' */
- n = c - '0' + batch->batshift; /* get parameter # 0-9 and */
- /* add in SHIFT offset */
- s = batch->batcmd;
- while(n-- && strlen(s)) /* skip all other parameters */
- s += strlen(s)+1; /* before the one we want */
- if((strlen(s) + i) >= MAX_LINE) /* Break if Greater than MAX_LINE*/
- break;
- strcpy (line + i, s); /* get the substitution */
- i += strlen (s); /* add in its size */
- break;
- case 0x1a:
- end_of_file:
- batch->eof = YES; /* We have come to the end */
- c = 'r'; /* of the batch file so set */
- break; /* flag and mark end of line*/
- default:
- save_it:
- if (i < MAX_LINE)
- line[i++] = c;
- if (dbcs_lead(c)) {
- if ((c = *batch_ptr()) >= ' ' && i < MAX_LINE)
- line[i++] = c;
- }
- }
- } while (c != 'r'); /* repeat until CR */
- line[i] = ''; /* Terminate the line and */
- if(batch->eof)
- return;
- #if 0 /* not DOS compatible */
- if(*batch_ptr() == 0x1A) /* Check if the next this */
- batch->eof = YES; /* the end of the file if */
- else /* YES then set the flag */
- batch->offset--; /* force the character to */
- #endif /* be re-read next time */
- return; /* return to the caller */
- }
- MLOCAL BOOLEAN following_command()
- /* return true if we have a possible command on the rest of the line */
- {
- LONG old_offset;
- BOOLEAN res = FALSE;
- BYTE *s;
- old_offset = batch->offset; /* save batch offset */
- while (TRUE) {
- s = batch_ptr(); /* look ahead at batch file */
- if (*s == 'r' || *s == 0x1a || (!dbcs_lead(*s) && *s == PIPE_CHAR))
- break;
- if (!is_blank(s)) {
- res = TRUE; /* possible command if we */
- break; /* hit non whitespace char */
- }
- if (dbcs_lead(*s)) {
- s = batch_ptr();
- if (*s == 'r' || *s == 0x1a)
- break;
- }
- }
- batch->offset = old_offset; /* restore batch offset */
- return res;
- }
- MLOCAL VOID swallow_line(s)
- BYTE *s;
- /* there is a syntax error on this line - swallow it and say so */
- {
- BYTE c;
- prompt(); /* possibly echo the prompt */
- if (echoflg) /* echo to screen if wanted */
- printf("%s%c",s,PIPE_CHAR);
- do {
- c = *batch_ptr();
- if (c == 0x1a) {
- c = 'r'; /* pretend to be end of line*/
- batch->eof = YES; /* We have come to the end */
- break; /* flag and mark end of line*/
- }
- if (echoflg) /* echo to screen if wanted */
- putc(c);
- } while (c != 'r');
- if (echoflg)
- putc('n');
- if (*batch_ptr() != 'n') /* skip line feed */
- batch->offset--; /* if present */
- eprintf(MSG_SYNTAX); /* report syntax error */
- }
- /*
- * In order to improve performance of the batch file processing
- * the Batch file is read in blocks of BATCH_BUF characters.
- * and the routine BATCH_CHAR then returns a pointer to a character
- * from the buffer (filling the buffer if required).
- */
- MLOCAL BYTE *batch_ptr()
- {
- BYTE FAR *buf;
- UWORD bufsize;
- UWORD i;
- if(batch->eof)
- return(batch_eof);
- if (batch->offset < batch_off ||
- batch->offset >= (batch_off + (LONG) (batch_cnt - 1))) {
- batch_off = batch->offset;
- ms_x_lseek (batch->stream, batch->offset, 0);
- batch_cnt = far_read(batch->stream, gp_far_buff, sizeof(batch_buf));
- if(batch_cnt <= 0) {
- batch->eof = YES;
- return(batch_eof);
- }
- for (i=0; i<sizeof(batch_buf); i++) batch_buf[i] = gp_far_buff[i];
- }
- return(&batch_buf[(UWORD) (batch->offset++ - batch_off)]);
- }
- /*.pa*/
- /*
- * BATCH FILE COMMANDS
- * ===================
- *
- * The following commands are used almost entirely in BATCH files and
- * have little or no meaning outside that environment.
- */
- GLOBAL VOID CDECL cmd_shift ()
- {
- batch->batshift++; /* Increment the Shift Offset */
- }
- MLOCAL WORD label_ignore_char(s)
- BYTE *s;
- {
- if (*s == '=') return(1);
- if (*s == ';') return(1);
- if (*s == ',') return(1);
- if (*s == ' ') return(1);
- return(0);
- }
- /*
- * Extract the first a valid characters from the label and then
- * zero terminate the resulting string.
- */
- MLOCAL BYTE * make_label(label)
- BYTE *label;
- {
- REG BYTE *bp;
- UWORD i;
- label = deblank(label); /* remove leading white space */
- while (label_ignore_char(label))
- label = skip_char(label);
- bp = label;
- while (is_filechar(bp)) /* skip over valid chars */
- bp = skip_char(bp);
- *bp = ''; /* make label zero terminated */
- return label;
- }
- GLOBAL VOID CDECL cmd_goto (label) /* goto label in batch file */
- REG BYTE *label;
- {
- UWORD i;
- BYTE *bp, s[MAX_LINE+2]; /* Allocate buffer for Batch Input */
- if (!batchflg) /* if not in batch mode */
- return; /* this command is ignored */
- if(*label == ':') /* Ignore any leading ':' */
- label++;
- label = make_label(label); /* Convert to Label Format */
- batch->offset = 0L; /* rewind the batch file */
- batch->eof = NO; /* So it cannot be EOF */
- if(!batch_open()) /* Check the Batch file is open */
- return; /* and stop if the function fails. */
- while(!batch->eof) { /* while not end of file read next */
- batch_read(s, YES); /* line and return the next command */
- bp = deblank(s);
- if((*bp == ':') && !strnicmp(make_label(bp+1),label, 8))
- return;
- }
- batch_end(); /* Stop any further batch file */
- crlfflg = YES; /* processing and print the error */
- eprintf(MSG_LABEL, label);
- }
- GLOBAL VOID CDECL cmd_gosub (label) /* gosub label in batch file */
- REG BYTE *label;
- {
- UWORD i;
- BYTE *bp, s[MAX_LINE+2]; /* Allocate buffer for Batch Input */
- if (!batchflg) /* if not in batch mode */
- return; /* this command is ignored */
- if (batch->ret_offset[3] != 0L) {
- batch_end();
- crlfflg = YES;
- eprintf(MSG_GOSUB);
- return;
- }
- if(*label == ':') /* Ignore any leading ':' */
- label++;
- label = make_label(label); /* Convert to Label Format */
- i = 0;
- while (batch->ret_offset[i] != 0L) i++;
- batch->ret_offset[i] = batch->offset;
- batch->offset = 0L; /* rewind the batch file */
- batch->eof = NO; /* So it cannot be EOF */
- if(!batch_open()) /* Check the Batch file is open */
- return; /* and stop if the function fails. */
- while(!batch->eof) { /* while not end of file read next */
- batch_read(s, YES); /* line and return the next command */
- bp = deblank(s);
- if((*bp == ':') && !strnicmp(make_label(bp+1),label, 8))
- return;
- }
- batch_end(); /* Stop any further batch file */
- crlfflg = YES; /* processing and print the error */
- eprintf(MSG_LABEL, label);
- }
- GLOBAL VOID CDECL cmd_return()
- {
- UWORD i;
- if (!batchflg) return;
- if (batch->ret_offset[0] == 0L) {
- batch_end();
- crlfflg = YES;
- eprintf(MSG_RETURN);
- return;
- }
- i = 0;
- while ((batch->ret_offset[i] != 0L)&&(i<4)) i++;
- batch->offset = batch->ret_offset[i-1];
- batch->ret_offset[i-1] = 0L;
- }
- #if SWITCH_ENABLED
- GLOBAL VOID CDECL cmd_switch(list)
- REG BYTE *list;
- {
- BYTE *list_start;
- BYTE *label;
- WORD i,j;
- BYTE c;
- if (!batchflg) return;
- list_start = list;
- switch_retry:
- list = list_start;
- i = psp_poke(STDIN,1);
- #if defined(CDOSTMP)
- c =(BYTE) bdos(C_RAWIO, 0xFD); /* Get a character from console */
- if ((c==0) ||(dbcs_lead(c)))
- bdos(C_RAWIO, 0xFD); /* skip second byte in DBCS pair */
- #else
- c = (BYTE) msdos(MS_C_RAWIN, 0);/* Get a character from console */
- if ((c==0) || (dbcs_lead(c)))
- msdos(MS_C_RAWIN, 0); /* skip second byte in DBCS pair */
- #endif
- psp_poke(STDIN,i);
- if (c==0x03) int_break(); /* check for CTRL-C */
- if (c==0x0d) c = '1'; /* return gives default of 1 */
- i = (WORD) (c - '1');
- if (i<0 || i>8) goto switch_retry; /* ignore invalid keys */
- j = 0;
- while (j<i) {
- while (*list != ',' && *list != 0) list++;
- if (*list == 0) goto switch_retry;
- j++;
- list++;
- list = deblank(list);
- }
- label = list;
- while (*list != ',' && *list != 0) list++;
- *list = 0;
- cmd_gosub(label);
- }
- #endif
- /*.pa*/
- /*
- * The IF command supports the following syntax:-
- *
- * IF [NOT] string1 == string2 COMMAND
- * IF [NOT] ERRORLEVEL n COMMAND
- * IF [NOT] EXIST filename COMMAND
- /*RG-02-
- * IF [NOT] USERID n COMMAND
- * IF [NOT] LOGINNAME string COMMAND
- * IF [NOT] GROUPNAME string COMMAND
- * IF [NOT] KEY ["string"] char COMMAND
- *
- */
- #if defined(CDOSTMP) || defined(CDOS)
- MLOCAL BYTE *if_opt[] = {"exist", "direxist", "errorlevel", "key", "userid", "loginname", "groupname", NULL };
- #else
- MLOCAL BYTE *if_opt[] = {"exist", "direxist", "errorlevel", NULL };
- #endif
- /*RG-02-end*/
- MLOCAL UWORD if_index(cmd)
- BYTE **cmd;
- {
- UWORD i, j;
- for(i = 0; if_opt[i]; i++) { /* Scan Through the option */
- j = strlen(if_opt[i]); /* list and return the index */
- /* of the matching option */
- if(strnicmp(*cmd, if_opt[i], j)) /* and update the string */
- continue; /* pointer. */
- *cmd = deblank(*cmd+j);
- while(*(*cmd) == '=') /* Remove any "=" string */
- (*cmd)++; /* present in the command */
- *cmd = deblank(*cmd); /* Used by many install files*/
- break;
- }
- return i;
- }
- #define OP_EQ 0
- #define OP_NE 1
- #define OP_LE 2
- #define OP_LT 3
- #define OP_GE 4
- #define OP_GT 5
- MLOCAL WORD get_operator(op)
- BYTE *op;
- {
- if (op[0] == '=') return(OP_EQ);
- if (op[0] == '!' && op[1] == '=') return(OP_NE);
- if (op[0] == '<') {
- if (op[1] == '>') return(OP_NE);
- if (op[1] == '=') return(OP_LE);
- return(OP_LT);
- }
- if (op[0] == '>') {
- if (op[1] == '=') return(OP_GE);
- return(OP_GT);
- }
- return(-1);
- }
- MLOCAL LONG get_decimal(s)
- BYTE *s;
- {
- LONG total = 0;
- if (*s == '#') s++;
- while (*s>='0' && *s<='9') {
- total *= 10;
- total += (LONG) (*s-'0');
- s++;
- }
- return(total);
- }
- MLOCAL BOOLEAN CDECL test_cond(cptr)
- BYTE **cptr;
- {
- BYTE *cmd,*str1, *str2, *ptr;
- DTA search;
- BOOLEAN not, cond, neg,is_user;
- BYTE level;
- BYTE c[]=" n";
- WORD attr;
- UWORD userid;
- LONG val1,val2;
- cmd=*cptr;
- not = cond = NO; /* Initialise the Flags */
- if(!strnicmp(cmd = deblank(cmd), "not", 3)) {
- not = YES;
- cmd = deblank(cmd+3);
- }
- switch(if_index(&cmd)) {
- /*
- * EXIST Option extract the possibly ambiguous filename
- * and check if it exists.
- */
- case 0:
- cmd = deblank(get_filename(heap(), cmd, YES));
- cond = !ms_x_first(heap(), ATTR_STD|ATTR_HID, &search);
- break;
- /*
- * DIREXIST Option checks if the given directory exists
- */
- case 1:
- cmd = deblank(get_filename(heap(), cmd, YES));
- attr = ms_x_chmod(heap(), ATTR_ALL, 0);
- if (attr < 0) cond = FALSE;
- else cond = (attr & 0x10);
- break;
- /*
- * ERRORLEVEL Option extract the decimal number from the
- * command line.
- */
- case 2:
- level = 0;
- neg = FALSE;
- if(*cmd =='-') {
- neg = TRUE;
- cmd++;
- }
- if(!isdigit(*cmd)) { /* SYNTAX error if the */
- syntax(); /* first character is not a */
- return FALSE; /* digit. */
- }
- while(isdigit(*cmd))
- level = level * 10 + (*cmd++ - '0');
- level = level & 0x00FF;
- if (neg) level = -level;
- cond = (level<=(err_ret & 0x00FF));
- break;
- /*RG-02*/
- #if !defined(NOXBATCH)
- #if (defined(CDOSTMP) || defined(CDOS))
- /*
- * KEY ["string"] [==] [""] Search for the string "string" and
- * display it if it exists, then read a key and echo it.
- * However, if the string to match is null "" then do a keyboard
- * status check and return TRUE if there is no key there
- */
- case 3:
- cmd = deblank(cmd);
- ptr=cmd;
- if (display_string(&ptr)!=0)
- return FALSE;
- cmd = deblank(ptr);
- while(*cmd == '=') /* Remove any "=" string */
- cmd++;
- cmd = deblank(cmd);
- if ((*cmd==0)||(*(cmd+1)!=' ')) { /* check for condition */
- syntax();
- return FALSE;
- }
- /* read a character from the keyboard */
- c[0]=bdos(C_RAWIO, 0xFD); /* Get a character from console */
- /* echo the char typed */
- if (echoflg) /* echo to screen if wanted */
- putc(c[0]);
- crlf(); /* print cr/lf */
- /* check if it matches */
- if((tolower(c[0])==*cmd)||(toupper(c[0])==*cmd))
- cond=TRUE;
- else
- cond=FALSE;
- /* skip the condition */
- while (*cmd!=' ')
- cmd++; /* skip the char */
- break;
- #endif
- #if !defined (NOSECURITY) && (defined(CDOSTMP) || defined(CDOS))
- /*
- * USERID Option extract the 4 digit hex user id
- * and check if it is us.
- */
- case 4:
- if (!login_enabled())
- return FALSE;
- cmd = deblank(cmd);
- if(aschextobin(cmd)==get_user_on_station())
- cond=TRUE;
- else
- cond=FALSE;
- do { /* skip past the user id */
- if ((*cmd>='0' && *cmd<='9')
- ||(tolower(*cmd)>='a' && tolower(*cmd)<='f'))
- cmd++; /* skip the hex digit */
- else {
- syntax();
- return FALSE;
- }
- } while (*cmd!=' ');
- break;
- /*
- * LOGINNAME Option extract the loginname and check if it is us.
- */
- case 5:
- if (!login_enabled())
- return FALSE;
- is_user=TRUE;
- /*
- * GROUPNAME Option extract the loginname and check if it is us.
- */
- case 6:
- if (!login_enabled())
- return FALSE;
- cmd = deblank(cmd);
- if(aschextobin(user_info.userid)!=get_user_on_station()) {
- if(get_user_info(get_user_on_station())!=0) {
- syntax();
- is_user=cond=FALSE;
- return FALSE;
- }
- }
- if((is_user==TRUE)&&(strncmp(strlwr(cmd),strlwr(user_info.loginname),strlen(user_info.loginname))==0)) {
- cond=TRUE;
- cmd+=strlen(user_info.loginname);
- }
- else if((is_user!=TRUE)&&(strncmp(strlwr(cmd),strlwr(user_info.groupname),strlen(user_info.groupname))==0)) {
- cond=TRUE;
- cmd+=strlen(user_info.groupname);
- }
- else {
- cond=FALSE;
- while (*cmd!=' ')
- cmd++; /* skip the name */
- }
- if (*cmd!=' ') {
- is_user=cond=FALSE;
- }
- is_user=FALSE;
- break;
- #endif
- #endif /*NOXBATCH*/
- /*RG-02-end*/
- /*
- * String comparison option.
- */
- default:
- str1 = cmd; /* Extract String 1 */
- while ((!is_blank(cmd)) && (*cmd != '=') &&
- ((*cmd != '!') || (cmd[1]!= '=')) &&
- (*cmd != '<') && (*cmd != '>')) {
- cmd = skip_char(cmd);
- }
- str2 = cmd;
- cmd = deblank(cmd);
- attr = get_operator(cmd++);
- if (attr == -1) {
- syntax();
- return(FALSE);
- }
- *str2 = 0;
- if (*cmd == '=' || *cmd == '>') cmd++;
- cmd = deblank(cmd);
- str2 = cmd;
- while (!is_blank(cmd)) cmd = skip_char(cmd);
- *cmd++ = 0;
- if (*str1 == '#') {
- val1 = get_decimal(str1);
- val2 = get_decimal(str2);
- switch(attr) {
- case OP_EQ: cond = (val1==val2); break;
- case OP_NE: cond = (val1!=val2); break;
- case OP_LT: cond = (val1<val2); break;
- case OP_LE: cond = (val1<=val2); break;
- case OP_GT: cond = (val1>val2); break;
- case OP_GE: cond = (val1>=val2); break;
- }
- }
- else switch(attr) {
- case OP_EQ:
- cond = (strcmp(str1,str2) == 0);
- break;
- case OP_NE:
- cond = (strcmp(str1,str2) != 0);
- break;
- case OP_LT:
- cond = (strcmp(str1,str2) < 0);
- break;
- case OP_LE:
- cond = (strcmp(str1,str2) <= 0);
- break;
- case OP_GT:
- cond = (strcmp(str1,str2) > 0);
- break;
- case OP_GE:
- cond = (strcmp(str1,str2) >= 0);
- break;
- }
- break;
- }
- if(not) /* if negated condition */
- cond = !cond;
- *cptr=cmd;
- return cond; /* write result back */
- }
- #if !defined(NOXBATCH)
- BOOLEAN is_it_or(BYTE *cmd)
- {
- cmd--;
- if ((*cmd != 0) && (*cmd != 't') && (*cmd != ' '))
- return FALSE;
- cmd++;
- if (strnicmp(cmd, "or", 2) != 0)
- return FALSE;
- cmd+=2;
- if ((*cmd != 't') && (*cmd != ' '))
- return FALSE;
- return TRUE;
- }
- #endif
- GLOBAL VOID CDECL cmd_if(cmd)
- BYTE *cmd;
- {
- BOOLEAN cond;
- ifcond=cond=test_cond(&cmd);
- if(!*deblank(cmd)) { /* and return a SYNTAX error*/
- syntax(); /* if it is empty. */
- return;
- }
- if(!cond) {
- #if !defined(NOXBATCH)
- while (!is_it_or(cmd) &&
- (*cmd != 0)) {
- if (strnicmp(cmd,"ECHO",4)==0) return;
- cmd++;
- }
- if (*cmd==0) return; /* no OR's so quit now */
- if_context = TRUE;
- docmd(deblank(cmd), YES); /* New command starts at "or" */
- #endif
- }
- else {
- cmd = deblank(cmd);
- if (strnicmp(cmd,"AND",3)) {
- if (parse(cmd)) return; /* IF won't have been 'parsed' for */
- /* > or < redirectors so do it now */
- }
- if_context = TRUE;
- /* Execute command if the */
- docmd(cmd, YES); /* condition flag is TRUE */
- }
- if_context=FALSE;
- }
- /*RG-03*/
- #if !defined(NOXBATCH)
- GLOBAL VOID CDECL cmd_or(cmd)
- BYTE *cmd;
- {
- BOOLEAN cond;
- BYTE *org_cmd;
- cond=test_cond(&cmd);
- if(!*deblank(cmd)) { /* and return a SYNTAX error*/
- syntax(); /* if it is empty. */
- return;
- }
- if(!cond) {
- org_cmd = cmd; /* now look for "OR" */
- while (!is_it_or(cmd) &&
- (*cmd != 0)) {
- if (strnicmp(cmd,"ECHO",4)==0) while(*cmd) cmd++;
- else cmd++;
- }
- if (*cmd==0) { /* oh dear, no ORs */
- if (ifcond) /* but so far so good, so do command anyway */
- docmd(deblank(org_cmd), YES);
- return;
- }
- docmd(deblank(cmd), YES); /* New command starts at "or" */
- return;
- }
- else {
- cmd = deblank(cmd);
- if (strnicmp(cmd,"AND",3)) {
- if (parse(cmd)) return; /* IF won't have been 'parsed' for */
- /* > or < redirectors so do it now */
- }
- ifcond=cond; /* Execute command if the */
- docmd(cmd, YES); /* condition flag is TRUE */
- }
- }
- #endif /*NOXBATCH*/
- /*RG-03-end*/
- GLOBAL VOID CDECL cmd_for(s)
- BYTE *s;
- {
- FCONTROL *fc;
- BYTE *bp1;
- fc = (FCONTROL *) heap_get(sizeof(FCONTROL));
- /* Allocate Control Struct */
- if(forptr) /* and prevent nesting of */
- goto for_error; /* FOR Command. */
- s = deblank(s); /* Remove leading blanks */
- if ((*s++ != '%') || /* Get the FOR variable */
- (fc->forvar = *s++) < ' ') /* character and save */
- goto for_error;
- if(strnicmp(s = deblank(s), "in", 2)) /* Check for the correct */
- goto for_error; /* command syntax. */
- s = deblank(s+2);
- if (*s++ != '(')
- goto for_error;
- fc->files = (BYTE *)heap(); /* Allocate FOR parameter */
- while(*s && *s != ')') { /* buffer and scan the */
- bp1 = (BYTE *)heap(); /* command line generating */
- /* zero terminated strings */
- while(strchr(batch_sep, *s)) /* Skip any separators */
- s = skip_char(s);
- while( *s != ')' && /* then copy all valid */
- !strchr(batch_sep, *s)) /* characters into buffer */
- /* then zero terminate */
- copy_char(&bp1, &s);
- *bp1++ = '';
- heap_get(strlen(heap()) + 1); /* Preserve String */
- }
- *(BYTE *)heap_get(1) = ''; /* Final String is zero */
- /* bytes in length */
- s = deblank(s);
- if(*s++ != ')')
- goto for_error;
- if(strnicmp(s = deblank(s), "do", 2))
- goto for_error;
- if(in_flag & REDIR_ACTIVE) /* If Input redirection has been */
- in_flag |= REDIR_FOR; /* enabled for this command force*/
- /* it on for the complete command*/
- if(out_flag & REDIR_ACTIVE) /* If Output redirection has been*/
- out_flag |= REDIR_FOR; /* enabled for this command force*/
- /* it on for the complete command*/
- fc->cmd = (BYTE *)heap_get(strlen(s = deblank(s+2)) +1);
- strcpy(fc->cmd, s);
- fc->sflg = NO; /* File matching inactive */
- for_flag = YES; /* Turn FOR processing ON */
- forptr = fc; /* Save control Structure */
- return;
- for_error: /* When a Syntax error occurs */
- heap_set((BYTE *) fc); /* restore the heap and print */
- syntax(); /* an error message. */
- return;
- }
- GLOBAL VOID for_end()
- {
- if(for_flag) {
- heap_set((BYTE *) forptr); /* Terminate FOR processing */
- forptr = (FCONTROL *) NULL; /* restore the HEAP and reset */
- for_flag = NO; /* control flags. */
- }
- }
- /*.pa*/
- /*
- * This command generates the displayed prompt based on the contents
- * of the string PROMPT= in the environment. Otherwise the default
- * prompt string DEFAULT_PROMPT is used.
- */
- MLOCAL BOOLEAN prompt_flg = FALSE; /* Prompt Flag */
- MLOCAL VOID prompt() /* display command line prompt */
- {
- REG BYTE *cp;
- BYTE buf[MAX_PATHLEN];
- BYTE c;
- #if !STACK
- BYTE cpbuf[MAX_ENVLEN];
- #endif
- /*rbf*/
- #if 1
- BYTE prmptcpbuf[MAX_ENVLEN];
- REG BYTE *prmptcp = prmptcpbuf;
- #endif
- if(!echoflg) /* Return if No Echo */
- return;
- #if defined(CPM)
- cp = heap();
- strcpy(cp, "[CPM] $u$p$g");
- #else
- if(env_scan(msg_prmeq, cp = (BYTE *)heap()))
- strcpy(cp, DEFAULT_PROMPT);
- #endif
- if(prompt_flg) /* If the previous Prompt display */
- strcpy(cp, "$n$g"); /* terminated due to a Critical */
- /* then just display the default */
- prompt_flg = TRUE; /* drive. */
- #if STACK
- cp = stack(strlen(cp) + 1);
- #else
- cp = &cpbuf[0];
- #endif
- strcpy(cp, heap());
- while((c = *cp++) != 0) { /* get next character */
- if (c != '$') /* if not '$', print as is */
- putc (c);
- else {
- c = *cp++;
- switch(tolower(c)) { /* else get next character */
- case '': /* Treat "$" as an invalid */
- cp--; /* prompt command sequence */
- break;
- case 't': /* print current time */
- disp_systime();
- break;
- case 'd': /* print current date */
- disp_sysdate();
- break;
- case 'p': /* print current path */
- if (ms_x_curdir(drive+1, buf) < 0)
- printf(MSG_DRV_INVALID);
- else
- printf("%c:%s%s", drive+'A', pathchar, buf);
- break;
- case 'v': /* print version number */
- cmd_ver("");
- break;
- case 'n': /* print default drive */
- putc((BYTE) drive+'A');
- break;
- case 'g': /* print ">" */
- putc ('>');
- break;
- case 'l': /* print "<" */
- putc ('<');
- break;
- case 'b': /* print "|" */
- putc ('|');
- break;
- case 'q': /* print "=" */
- putc ('=');
- break;
- case '_': /* print CR,LF */
- crlf();
- break;
- case 'h': /* print backspace, space, backspace */
- printf("b b");
- break;
- case 'e': /* print ESC character */
- putc ('33');
- break;
- /*RG-01 */
- #if !defined(NOXBATCH)
- #if !defined (NOSECURITY)
- #if defined(CDOSTMP) || defined(CDOS)
- case 'm': /* print mail status */
- if (login_enabled()) {
- if(chk_mail()) { /* we have mail */
- if(env_scan("MAIL=", heap()))
- printf(MSG_UHAVEMAIL);
- else
- printf("%s",heap());
- }
- }
- break;
- case 'u': /* Display the User Name */
- if (login_enabled()) {
- if((aschextobin(user_info.userid)!=get_user_on_station())||(strlen(user_info.userid)==0)) {
- if(get_user_info(get_user_on_station())!=0)
- printf("#%04X",get_user_on_station());
- else
- printf("%s",user_info.loginname);
- }
- else
- printf("%s",user_info.loginname);
- }
- break;
- #endif
- #endif
- #endif /*NOXBATCH*/
- /*RG-01-end*/
- #if defined(CPM)
- case 'u': /* Display the User Number */
- printf("%d", user);
- break;
- #endif
- #if defined(DOSPLUS)
- case 'u':
- if (!env_scan("LOGINNAME=",heap()))
- printf("%s",heap());
- break;
- #endif
- case '$':
- putc ('$'); /* print single '$' */
- break;
- case 'x':
- if ((allow_pexec)&&(!batchflg)) prompt_exec();
- break;
- default: /* Otherwise the character */
- break;
- }
- }
- }
- prompt_flg = FALSE; /* Prompt display completed OK */
- }
- #if !defined(CDOSTMP)
- /* The following functions are called by the int2e_handler function in
- * COM.C. If a program is run from a batch file and calls INT 2E to
- * execute a new batch file the original batch file must NOT be terminated.
- * Therefore batch and batchflg must be saved, set to zero, and then
- * restored when INT 2E returns. - EJH
- */
- GLOBAL VOID int2e_start()
- {
- batchflg_save = batchflg;
- batchflg = 0;
- batch_save = batch;
- echoflg_save = echoflg;
- echoflg = ECHO_ON;
- }
- GLOBAL VOID int2e_finish()
- {
- batchflg = batchflg_save;
- batch = batch_save;
- echoflg = echoflg_save;
- }
- #endif
- #if defined(CDOS)
- MLOCAL VOID map_user_page(UWORD window_page, UWORD physical_page)
- {
- UWORD pblk[3];
- pblk[0] = window_page;
- pblk[1] = physical_page;
- pblk[2] = 0;
- bdos(181, pblk);
- }
- MLOCAL BYTE FAR * map_pd_mem(UWORD ppd, UWORD wp, UWORD seg, UWORD offset)
- {
- /* Map memory for another process into our memory space so we examine it */
- UWORD base_seg;
- UWORD page;
- PD FAR * pdptr;
- UWORD sysdat;
- UWORD mptbl;
- UWORD FAR * ptr;
- UWORD mp_off;
- UWORD i;
- MPAD FAR * mp;
- sysdat = FP_SEG(pd);
- ptr = MK_FP(sysdat, 0xc8);
- /* DEBUG */
- if (*ptr == 0) /* for DEBUG under XM assume non-banked system */
- return(MK_FP(seg, offset));
- /* DEBUG */
- ptr = MK_FP(sysdat, *ptr + 8);
- mptbl = *ptr;
- /* get segment of 4k page to map */
- base_seg = (seg + (offset+15)/16) & 0xff00;
- /* now find physical page to map */
- pdptr = (PD FAR *) MK_FP(sysdat, ppd);
- for (mp_off = pdptr->P_MPAR; mp_off !=0;) {
- mp = MK_FP(sysdat, mp_off);
- mp_off = mp->link;
- if ((base_seg >= mp->start) &&
- (base_seg < (mp->start + mp->length))) {
- page = mp->xios;
- for (i = 0; i < ((base_seg - mp->start)/1024); i++){
- ptr = MK_FP(mptbl, page*2);
- page = *ptr;
- }
- page = 4*page + (((base_seg - mp->start)/0x0100) & 3);
- map_user_page(wp, page);
- return(MK_FP(wp*0x0100,(seg*16+offset) & 0x0fff));
- }
- }
- /* not found in mpad's - must be non-banked address */
- return(MK_FP(seg, offset));
- }
- MLOCAL VOID ip_poke(UWORD ppd, UWORD wp, UWORD seg, UWORD offset, UBYTE val)
- {
- UBYTE FAR *ptr;
- ptr = map_pd_mem(ppd, wp, seg, offset);
- *ptr = val;
- }
- MLOCAL UBYTE ip_peek(UWORD ppd, UWORD wp, UWORD seg, UWORD offset)
- {
- UBYTE FAR *ptr;
- ptr = map_pd_mem(ppd, wp, seg, offset);
- return(*ptr);
- }
- MLOCAL UWORD ip_peek_word(UWORD ppd, UWORD wp, UWORD seg, UWORD offset)
- {
- return (ip_peek(ppd, wp, seg, offset) +
- 256*ip_peek(ppd, wp, seg, offset+1));
- }
- GLOBAL VOID inherit_TMP_state(VOID)
- /* inherit batch files */
- /* NB. This is bodged - we don't inherit FOR state, or redirection */
- {
- PD FAR *parent;
- UWORD batch_seg;
- UWORD tmp_mpad;
- UWORD mp_off;
- MPAD FAR * mp;
- VOID FAR *window;
- UWORD win_page;
- UWORD i;
- parent = (PD FAR *) MK_FP(FP_SEG(pd), pd->P_PARENT);
- /* verify our parent is a Tmp, forget if it isn't */
- if ((parent->P_NAME[0] != 'T') ||
- (parent->P_NAME[1] != 'm') ||
- (parent->P_NAME[2] != 'p'))
- return;
- /* allocate a 4k aligned window to bank data into */
- i = 2*4096/16;
- mem_alloc(&window, &i, i, i);
- if (i==0)
- return;
- win_page = (FP_SEG(window) + 0x0100) / 0x100;
- batch_seg = ip_peek_word(pd->P_PARENT, win_page,
- parent->P_PSP, TmpPspBatchSeg);
- /* do we have any batch files to inherit */
- if (batch_seg) {
- echoflg = (BOOLEAN)ip_peek_word(pd->P_PARENT, win_page,
- ip_peek_word(pd->P_PARENT, win_page,
- parent->P_PSP, TmpPspDataSeg),
- ip_peek_word(pd->P_PARENT, win_page,
- parent->P_PSP, TmpPspEchoFlgPtr));
- /* recover Tmp's hidden mpads */
- tmp_mpad = ip_peek_word(pd->P_PARENT, win_page,
- parent->P_PSP, TmpPspMpad);
- for (mp_off = parent->P_MPAR; mp_off != 0;) {
- mp = MK_FP(FP_SEG(parent), parent->P_MPAR);
- mp_off = mp->link;
- }
- mp->link = tmp_mpad;
- inherit_batch_file(pd->P_PARENT, win_page, batch_seg);
- mp->link = 0; /* unlink again */
- }
- map_user_page(0, 0); /* force user page to be unmapped */
- bdos(141,0); /* dispatch to re-map TPA memory */
- mem_free(&window); /* free the window */
- }
- MLOCAL VOID inherit_batch_file(UWORD ppd, UWORD win_page, UWORD batch_seg)
- {
- UBYTE FAR * dst;
- BCONTROL FAR *save0;
- FCONTROL *save1;
- BYTE *save2;
- WORD save3;
- UWORD i;
- UWORD data_seg;
- PD FAR *parent;
- /* if we are in a nested batch file, inherit older batch file first */
- i = ip_peek_word(ppd, win_page, batch_seg, 2);
- if (i != 0)
- inherit_batch_file( ppd, win_page, i);
- batch_new(); /* new incarnation of batch */
- save0 = batch->bcontrol; save1 = batch->fcontrol;
- save2 = batch->heap_start; save3 = batch->heap_size;
- dst = (BYTE FAR *) batch; /* copy batch structure */
- for (i=0; i<sizeof(BCONTROL); i++) /* from parental PD */
- dst[i] = ip_peek(ppd, win_page, batch_seg, i);
- /* now terminate parental batch processing by poking EOF */
- ip_poke(ppd, win_page,
- batch_seg, (UWORD) &batch->eof - (UWORD) &batch->bcontrol,
- (UBYTE) TRUE);
- /*
- * Copy the invoking command and the individual elements
- * of the command line into a buffer ready for processing
- */
- parent = (PD FAR *) MK_FP(FP_SEG(pd), pd->P_PARENT);
- data_seg = ip_peek_word(pd->P_PARENT, win_page,
- parent->P_PSP, TmpPspDataSeg);
- i = (UWORD) batch->batcmd;
- batch->batcmd = (BYTE *)heap(); /* Initialize Parameter Buffer */
- while (ip_peek_word(ppd, win_page, data_seg, i) != 0)
- *(BYTE *)heap_get(1) = ip_peek(ppd, win_page, data_seg, i++);
- *(WORD *)heap_get(2) = 0; /* Double NULL is a terminator */
- /* for command line params */
- batch->bcontrol = save0; batch->fcontrol = save1;
- batch->heap_start = save2; batch->heap_size = save3;
- batchflg++; /* increment batch flag */
- crlfflg = YES; /* print CR/LF after this */
- }
- #endif
- EXTERN N_CMD novell_ext_list[];
- EXTERN BYTE FAR * CDECL farptr(BYTE *);
- EXTERN BYTE FAR * CDECL cgroupptr(BYTE *);
- EXTERN BOOLEAN CDECL call_novell(BYTE *, BYTE *, WORD);
- EXTERN BOOLEAN CDECL nov_station(WORD *);
- EXTERN WORD CDECL nov_connection();
- MLOCAL BOOLEAN novell_extension(src,dst)
- BYTE *src;
- BYTE *dst;
- /*
- * Check if src string is a novell string to be expanded. eg login_name.
- * if so, put expansion in dst.
- */
- {
- N_CMD FAR *n_cmd_p;
- BYTE FAR *cpf;
- WORD i;
- for (i=0;src[i] && src[i]!='=';i++);
- src[i] = 0;
- n_cmd_p = (N_CMD FAR *)farptr((BYTE *)&novell_ext_list[0]);
- while(n_cmd_p->string) {
- cpf = cgroupptr(n_cmd_p->string);
- for(i=0; (cpf[i]==src[i]) && src[i]; i++);
- if(cpf[i]==src[i]) {
- (*n_cmd_p->func)(dst);
- return(0);
- }
- n_cmd_p++;
- }
- return(1);
- }
- GLOBAL VOID CDECL get_login_name(dst)
- BYTE *dst;
- {
- struct s_nov_e346_in {
- WORD len;
- BYTE code;
- } nov_e346_in;
- struct s_nov_e346_out {
- WORD len;
- BYTE level;
- LONG id;
- } nov_e346_out;
- struct s_nov_e336_in {
- WORD len;
- BYTE code;
- LONG id;
- } nov_e336_in;
- struct s_nov_e336_out {
- WORD len;
- LONG id;
- WORD type;
- BYTE name[48];
- } nov_e336_out;
- nov_e346_in.len = 1;
- nov_e346_in.code = 0x46;
- nov_e346_out.len = 5;
- nov_e346_out.id = -1L;
- call_novell((BYTE *)&nov_e346_in, (BYTE *)&nov_e346_out, 0xE3);
- if (nov_e346_out.id == -1L) {
- *dst = 0;
- return;
- }
- nov_e336_in.len = 5;
- nov_e336_in.code = 0x36;
- nov_e336_in.id = nov_e346_out.id;
- nov_e336_out.len = 54;
- call_novell((BYTE *)&nov_e336_in, (BYTE *)&nov_e336_out, 0xE3);
- strcpy(dst,nov_e336_out.name);
- }
- GLOBAL VOID CDECL get_pstation(dst)
- BYTE *dst;
- {
- WORD sn[3];
- if (nov_station(sn)) {
- *dst = 0;
- return;
- }
- sprintf(dst,"%04X%04X%04X",sn[0],sn[1],sn[2]);
- }
- GLOBAL VOID CDECL get_full_name(dst)
- BYTE *dst;
- {
- /* scan bindery */
- struct s_nov_e337_in {
- WORD len;
- BYTE code;
- LONG last_object_id;
- WORD object_type;
- BYTE object_name_len;
- BYTE object_name[48];
- } nov_e337_in;
- struct s_nov_e337_out {
- WORD len;
- LONG object_id;
- WORD object_type;
- BYTE object_name[48];
- BYTE object_flag;
- BYTE object_security;
- BYTE object_has_properties;
- } nov_e337_out;
- /* scan property */
- struct s_nov_e33c_in {
- WORD len;
- BYTE code;
- WORD object_type;
- BYTE object_name_len;
- BYTE object_name[48];
- LONG sequence_num;
- BYTE property_name_len;
- BYTE property_name[16];
- } nov_e33c_in;
- struct s_nov_e33c_out {
- WORD len;
- BYTE property_name[16];
- BYTE property_flags;
- BYTE property_security;
- LONG sequence_num;
- BYTE property_has_value;
- BYTE more_properties;
- } nov_e33c_out;
- /* read property */
- struct s_nov_e33d_in {
- WORD len;
- BYTE code;
- WORD object_type;
- BYTE object_name_len;
- BYTE object_name[48];
- BYTE segment_num;
- BYTE property_name_len;
- BYTE property_name[16];
- } nov_e33d_in;
- struct s_nov_e33d_out {
- WORD len;
- BYTE property_value[128];
- BYTE more_segments;
- BYTE property_flags;
- } nov_e33d_out;
- int res;
- get_login_name(nov_e337_in.object_name);
- nov_e337_in.object_name_len = strlen(nov_e337_in.object_name);
- if (!nov_e337_in.object_name_len){
- *dst = 0;
- return;
- }
- nov_e337_in.code = 0x37;
- nov_e337_in.len = sizeof(struct s_nov_e337_in) - 2;
- nov_e337_out.len = sizeof(struct s_nov_e337_out) -2 ;
- nov_e337_in.last_object_id = -1L;
- nov_e337_in.object_type = 0x0100; /*user*/
- for(;;){
- res = call_novell((BYTE *)&nov_e337_in, (BYTE *)&nov_e337_out, 0xe3 );
- if ( res == 0xfc )
- break;
- else if ( res ){
- *dst= 0;
- return;
- }
- if ( nov_e337_out.object_has_properties ){
- nov_e33c_in.code = 0x3c;
- nov_e33c_in.len = sizeof(struct s_nov_e33c_in) - 2;
- nov_e33c_out.len = sizeof(struct s_nov_e33c_out) - 2;
- nov_e33c_in.object_type = nov_e337_out.object_type;
- nov_e33c_in.object_name_len = sizeof( nov_e33c_in.object_name );
- strcpy( nov_e33c_in.object_name, nov_e337_out.object_name );
- nov_e33c_in.sequence_num = -1L;
- nov_e33c_in.property_name_len = 1;
- nov_e33c_in.property_name[0] = '*';
- for(;;){
- res = call_novell( (BYTE *)&nov_e33c_in, (BYTE *)&nov_e33c_out, 0xe3 );
- if ( res == 0xfb )
- break;
- else if ( res ){
- *dst = 0;
- return;
- }
- if ( nov_e33c_out.property_has_value ){
- nov_e33d_in.code = 0x3d;
- nov_e33d_in.len = sizeof (struct s_nov_e33d_in) - 2;
- nov_e33d_out.len = sizeof (struct s_nov_e33d_out) - 2;
- nov_e33d_in.object_type = nov_e337_out.object_type;
- nov_e33d_in.object_name_len = sizeof( nov_e33d_in.object_name );
- strcpy( nov_e33d_in.object_name, nov_e337_out.object_name );
- nov_e33d_in.segment_num = 1;
- nov_e33d_in.property_name_len = strlen( nov_e33c_out.property_name );
- strcpy(nov_e33d_in.property_name, nov_e33c_out.property_name );
- for(;;){
- res = call_novell( (BYTE *)&nov_e33d_in, (BYTE *)&nov_e33d_out, 0xe3);
- if ( res == 0xec )
- break;
- else if ( res ){
- *dst = 0;
- return;
- }
- if (!strcmp(nov_e33c_out.property_name,"IDENTIFICATION")){
- strcpy(dst,nov_e33d_out.property_value);
- return;
- }
- nov_e33d_in.segment_num++;
- }/*for*/
- }/*if*/
- nov_e33c_in.sequence_num = nov_e33c_out.sequence_num;
- }/*for*/
- nov_e337_in.last_object_id = nov_e337_out.object_id;
- }/*if*/
- }/*for*/
- }
- GLOBAL VOID CDECL get_hour(dst)
- BYTE *dst;
- {
- SYSTIME time;
- ms_gettime(&time);
- if (time.hour > 12) time.hour -= 12;
- if (time.hour == 0) time.hour = 12;
- sprintf(dst,"%d",time.hour);
- }
- GLOBAL VOID CDECL get_hour24(dst)
- BYTE *dst;
- {
- SYSTIME time;
- ms_gettime(&time);
- sprintf(dst,"%02d",time.hour);
- }
- GLOBAL VOID CDECL get_minute(dst)
- BYTE *dst;
- {
- SYSTIME time;
- ms_gettime(&time);
- sprintf(dst,"%02d",time.min);
- }
- GLOBAL VOID CDECL get_second(dst)
- BYTE *dst;
- {
- SYSTIME time;
- ms_gettime(&time);
- sprintf(dst,"%02d",time.sec);
- }
- GLOBAL VOID CDECL get_am_pm(dst)
- BYTE *dst;
- {
- SYSTIME time;
- BYTE FAR *p;
- ms_gettime(&time);
- if (time.hour >= 12) p = cgroupptr(PM_TIME);
- else p = cgroupptr(AM_TIME);
- while (*p) *dst++ = *p++;
- *dst = 0;
- }
- GLOBAL VOID CDECL get_greeting(dst)
- BYTE *dst;
- {
- SYSTIME time;
- BYTE FAR *p;
- ms_gettime(&time);
- if (time.hour < 12)
- p = cgroupptr(GREETING_MORNING);
- else if (time.hour < 17)
- p = cgroupptr(GREETING_AFTERNOON);
- else
- p = cgroupptr(GREETING_EVENING);
- while (*p) *dst++ = *p++;
- *dst = 0;
- }
- GLOBAL VOID CDECL get_year(dst)
- BYTE *dst;
- {
- SYSDATE date;
- ms_getdate(&date);
- sprintf(dst,"%d",date.year);
- }
- GLOBAL VOID CDECL get_short_year(dst)
- BYTE *dst;
- {
- SYSDATE date;
- ms_getdate(&date);
- sprintf(dst,"%d",date.year%100);
- }
- GLOBAL VOID CDECL get_month(dst)
- BYTE *dst;
- {
- SYSDATE date;
- ms_getdate(&date);
- sprintf(dst,"%d",date.month);
- }
- GLOBAL VOID CDECL get_month_name(dst)
- BYTE *dst;
- {
- SYSDATE date;
- BYTE *m;
- ms_getdate(&date);
- switch(date.month) {
- case 1: m = JAN_M; break;
- case 2: m = FEB_M; break;
- case 3: m = MAR_M; break;
- case 4: m = APR_M; break;
- case 5: m = MAY_M; break;
- case 6: m = JUN_M; break;
- case 7: m = JUL_M; break;
- case 8: m = AUG_M; break;
- case 9: m = SEP_M; break;
- case 10: m = OCT_M; break;
- case 11: m = NOV_M; break;
- case 12: m = DEC_M; break;
- }
- sprintf(dst,"%s",m);
- }
- GLOBAL VOID CDECL get_day(dst)
- BYTE *dst;
- {
- SYSDATE date;
- ms_getdate(&date);
- sprintf(dst,"%d",date.day);
- }
- GLOBAL VOID CDECL get_nday_of_week(dst)
- BYTE *dst;
- {
- SYSDATE date;
- ms_getdate(&date);
- sprintf(dst,"%d",date.dow+1);
- }
- GLOBAL VOID CDECL get_day_of_week(dst)
- BYTE *dst;
- {
- SYSDATE date;
- ms_getdate(&date);
- sprintf(dst,"%s",day_names(date.dow));
- }
- GLOBAL VOID CDECL get_os_version(dst)
- BYTE *dst;
- {
- env_scan("VER=",dst);
- }
- GLOBAL VOID CDECL get_connection(dst)
- BYTE *dst;
- {
- int i;
- i = nov_connection();
- if (i==-1) {
- *dst = 0;
- return;
- }
- sprintf(dst,"%d",i);
- }