📄 ckucmd.c
字号:
#include "ckcsym.h"char *cmdv = "Command package 8.0.157, 11 May 2003";/* C K U C M D -- Interactive command package for Unix *//* Author: Frank da Cruz (fdc@columbia.edu), Columbia University Academic Information Systems, New York City. Copyright (C) 1985, 2004, Trustees of Columbia University in the City of New York. All rights reserved. See the C-Kermit COPYING.TXT file or the copyright text in the ckcmai.c module for disclaimer and permissions.*/#define TOKPRECHECK#define DOCHKVAR/* Command-terminal-to-C-Kermit character mask */#ifdef OS2 /* K95 */int cmdmsk = 255; /* (always was 255) */#else /* All others... */int cmdmsk = 255; /* 31 Dec 2000 (was 127) */#endif /* OS2 */#ifdef BS_DIRSEP /* Directory separator is backslash */#undef BS_DIRSEP#endif /* BS_DIRSEP */#ifdef OS2#define BS_DIRSEP#endif /* BS_DIRSEP */#define CKUCMD_C#include "ckcdeb.h" /* Formats for debug(), etc. */#include "ckcker.h" /* Needed for BIGBUFOK definition */#include "ckcnet.h" /* Needed for server-side Telnet */#include "ckucmd.h" /* Needed for everything */#include "ckuusr.h" /* Needed for prompt length */#ifndef NOARROWKEYS#ifndef NOESCSEQ#ifdef VMSORUNIX#define USE_ARROWKEYS /* Use arrow keys for command recall */#endif /* VMSORUNIX */#endif /* NOESCSEQ */#endif /* NOARROWKEYS */#undef CKUCMD_C_PROTOTYP( int unhex, (char) );_PROTOTYP( static VOID cmdclrscn, (void) );#ifdef CKLEARN_PROTOTYP( VOID learncmd, (char *) );#endif /* CKLEARN */static char *moname[] = { "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"};struct keytab cmonths[] = { { "april", 4, 0 }, { "august", 8, 0 }, { "december", 12, 0 }, { "february", 2, 0 }, { "january", 1, 0 }, { "july", 7, 0 }, { "june", 6, 0 }, { "march", 3, 0 }, { "may", 5, 0 }, { "november", 11, 0 }, { "october", 10, 0 }, { "september", 9, 0 }};#ifndef NOICP /* The rest only if interactive command parsing selected */#ifndef NOSPL_PROTOTYP( int chkvar, (char *) );extern int askflag;#endif /* NOSPL */#ifdef CKROOTextern int ckrooterr;#endif /* CKROOT */#ifdef IKSDextern int inserver;#endif /* IKSD */int cmfldflgs = 0; /* Flags for cmfld() */int cmkwflgs = 0; /* Flags from last keyword parse */static int blocklvl = 0; /* Block nesting level */static int linebegin = 0; /* Flag for at start of a line */static int quoting = 1; /* Quoting is allowed */static int swarg = 0; /* Parsing a switch argument */static int xcmfdb = 0; /* Flag for parsing chained fdbs... */static int chsrc = 0; /* Source of character, 1 = tty */static int newcmd = 0; /* See addcmd() */#ifdef BS_DIRSEPstatic int dirnamflg = 0;#endif /* BS_DIRSEP *//*Modeled after the DECSYSTEM-20 command parser (the COMND JSYS), RIP. Features: . parses and verifies keywords, filenames, text strings, numbers, other data . displays appropriate menu or help message when user types "?" . does keyword and filename completion when user types ESC or TAB . does partial keyword and filename completion . accepts any unique abbreviation for a keyword . allows keywords to have attributes, like "invisible" and "abbreviation" . can supply defaults for fields omitted by user . provides command retry and recall . provides character, word, and line deletion (but only from the end) . accepts input from keyboard, command files, macros, or redirected stdin . allows for full or half duplex operation, character or line input . allows \-escapes for special characters . allows specification of a user exit to expand variables, etc. . settable prompt, protected from deletion, dynamically re-evaluated each time . allows chained parse functions.Functions: cmsetp - Set prompt (cmprom is prompt string) cmsavp - Save current prompt cmgetp = Get current prompt prompt - Issue prompt cmini - Clear the command buffer (before parsing a new command) cmres - Reset command buffer pointers (before reparsing) cmkey - Parse a keyword or token (also cmkey2) cmswi - Parse a switch cmnum - Parse a number cmifi - Parse an input file name cmofi - Parse an output file name (also cmifip, cmifi2, ...) cmdir - Parse a directory name (also cmdirp) cmfld - Parse an arbitrary field cmtxt - Parse a text string cmdate - Parse a date-time string cmcfm - Parse command confirmation (end of line) cmfdb - Parse any of a list of the foregoing (chained parse functions)Return codes: -9: like -2 except this module already printed the error message -3: no input provided when required -2: input was invalid (e.g. not a number when a number was required) -1: reparse required (user deleted into a preceding field) 0 or greater: successSee individual functions for greater detail.Before using these routines, the caller should #include "ckucmd.h" and set theprogram's prompt by calling cmsetp(). If the file parsing functions cmifi,cmofi, or cmdir are to be used, this module must be linked with a ck?fio filesystem support module for the appropriate system, e.g. ckufio for Unix. Ifthe caller puts the terminal in character wakeup ("cbreak") mode with no echo,then these functions will provide line editing -- character, word, and linedeletion, as well as keyword and filename completion upon ESC and helpstrings, keyword, or file menus upon '?'. If the caller puts the terminalinto character wakeup/noecho mode, care should be taken to restore it beforeexit from or interruption of the program. If the character wakeup mode is notset, the system's own line editor may be used.NOTE: Contrary to expectations, many #ifdef's have been added to this module.Any operation requiring an #ifdef (like clear screen, get character fromkeyboard, erase character from screen, etc) should eventually be turned into acall to a function that is defined in ck?tio.c, but then all the ck?tio.cmodules would have to be changed...*//* Includes */#include "ckcker.h"#include "ckcasc.h" /* ASCII character symbols */#include "ckucmd.h" /* Command parsing definitions */#ifdef OSF13#ifdef CK_ANSIC#ifdef _NO_PROTO#undef _NO_PROTO#endif /* _NO_PROTO */#endif /* CK_ANSIC */#endif /* OSF13 */#include <errno.h> /* Error number symbols */#ifdef OS2#ifndef NT#define INCL_NOPM#define INCL_VIO /* Needed for ckocon.h */#include <os2.h>#undef COMMENT#else#define APIRET ULONG#include <windows.h>#endif /* NT */#include "ckocon.h"#include <io.h>#endif /* OS2 */#ifdef NT#define stricmp _stricmp#endif /* NT */#ifdef OSK#define cc ccount /* OS-9/68K compiler bug */#endif /* OSK */#ifdef GEMDOS /* Atari ST */#ifdef putchar#undef putchar#endif /* putchar */#define putchar(x) conoc(x)#endif /* GEMDOS */#ifdef CK_AUTODLextern int cmdadl, justone;#endif /* CK_AUTODL */extern int timelimit, nzxopts, nopush, nolocal, xcmdsrc, keepallchars;#ifdef CKSYSLOG#ifdef UNIX#ifdef CKXPRINTF /* Our printf macro conflicts with */#undef printf /* use of "printf" in syslog.h */#endif /* CKXPRINTF */#ifdef RTAIX#include <sys/syslog.h>#else /* RTAIX */#include <syslog.h>#endif /* RTAIX */#ifdef CKXPRINTF#define printf ckxprintf#endif /* CKXPRINTF */#endif /* UNIX */#endif /* CKSYSLOG *//* Local variables */staticint psetf = 0, /* Flag that prompt has been set */ cc = 0, /* Character count */ dpx = 0, /* Duplex (0 = full) */ inword = 0; /* In the middle of getting a word */char *dfprom = "Command? "; /* Default prompt */int cmflgs; /* Command flags */int cmfsav; /* A saved version of them */static char pushc = NUL;static char brkchar = NUL;#define CMDEFAULT 1023static char cmdefault[CMDEFAULT+1];#ifdef DCMDBUFchar *cmdbuf = NULL; /* Command buffer */char *savbuf = NULL; /* Buffer to save copy of command */char *atmbuf = NULL; /* Atom buffer - for current field */char *atxbuf = NULL; /* For expanding the atom buffer */static char *atybuf = NULL; /* For copying atom buffer */static char *filbuf = NULL; /* File name buffer */static char *cmprom = NULL; /* Program's prompt */static char *cmprxx = NULL; /* Program's prompt, unevaluated */#ifdef CK_RECALL/* Command recall is available only if we can make profligate use of malloc().*/#define R_MAX 10 /* How many commands to save */int cm_recall = R_MAX; /* Size of command recall buffer */int on_recall = 1; /* Recall feature is ON */static int no_recall = 0; /* Recall OFF for this cmd only */static int force_add = 0; /* Force cmd into recall buffer */static int last_recall = -1; /* Last recall-related action *//* -1 = none 0 = CR (a command was entered) 1 = Up 2 = Down*/int in_recall = 0; /* Recall buffers are init'd */static int current = -1, /* Pointer to current command */ rlast = -1; /* Index of last command in buffer */static char **recall = NULL; /* Array of recall buffer pointers */#endif /* CK_RECALL */#else /* !DCMDBUF */char cmdbuf[CMDBL+4]; /* Command buffer */char savbuf[CMDBL+4]; /* Buffer to save copy of command */char atmbuf[ATMBL+4]; /* Atom buffer */char atxbuf[CMDBL+4]; /* For expanding the atom buffer */static char atybuf[ATMBL+4]; /* For copying atom buffer */static char filbuf[ATMBL+4]; /* File name buffer */static char cmprom[PROMPTL+1]; /* Program's prompt */static char cmprxx[PROMPTL+1]; /* Program's prompt, unevaluated */#endif /* DCMDBUF *//* Command buffer pointers */#define PPVLEN 24char ppvnambuf[PPVLEN+1] = { NUL, NUL };char * cmbptr = NULL; /* Current position (for export) */static char *bp, /* Current command buffer position */ *pp, /* Start of current field */ *np; /* Start of next field */static int ungw, /* For ungetting words */ atxn; /* Expansion buffer (atxbuf) length */#ifdef OS2extern int wideresult;#endif /* OS2 */extern int cmd_cols, cmd_rows, local, quiet;#ifdef TNCODE#ifdef IAC#undef IAC#endif /* IAC */#define IAC 255#endif /* TNCODE */_PROTOTYP( static int gtword, (int) );_PROTOTYP( static int addbuf, (char *) );_PROTOTYP( static int setatm, (char *, int) );_PROTOTYP( static VOID cmdnewl, (char) );_PROTOTYP( static VOID cmdchardel, (void) );_PROTOTYP( static VOID cmdecho, (char, int) );_PROTOTYP( static int test, (int, int) );#ifdef GEMDOS_PROTOTYP( extern char *strchr, (char *, int) );#endif /* GEMDOS */extern char * dftty;/* The following are for use with chained FDB's */static int crflag = 0; /* Carriage return was typed */static int qmflag = 0; /* Question mark was typed */static int esflag = 0; /* Escape was typed *//* Directory separator */#ifdef GEMDOSstatic char dirsep = '\\';#else#ifdef datageneralstatic char dirsep = ':';#else#ifdef MACstatic char dirsep = ':';#else#ifdef VMSstatic char dirsep = '.';#else#ifdef STRATUSstatic char dirsep = '>';#elsestatic char dirsep = '/'; /* UNIX, OS/2, OS-9, Amiga, etc. */#endif /* STRATUS */#endif /* VMS */#endif /* MAC */#endif /* datageneral */#endif /* GEMDOS *//* H A S N O P A T H *//* Returns 0 if filespec s includes any path segments; 1 if it doesn't. */inthasnopath(s) char * s; { char * p = NULL; if (!s) return(0); if (!*s) return(0); zstrip(s,&p); return(ckstrcmp(s,p,CKMAXPATH,filecase) == 0 ? 1 : 0);}/* C K S P R E A D -- Print string double-spaced */static char * sprptr = NULL;static char *ckspread(s) char * s; { int n = 0; char * p; n = strlen(s); if (sprptr) free(sprptr); sprptr = malloc(n + n + 3); if (sprptr) { p = sprptr; while (*s) { *p++ = *s++; *p++ = SP; } *p = NUL; } return(sprptr ? sprptr : "");}/* T E S T -- Bit test */static inttest(x,m) int x, m; { /* Returns 1 if any bits from m are on in x, else 0 */ return((x & m) ? 1 : 0);}/* K W D H E L P -- Given a keyword table, print keywords in columns. *//* Call with: s - keyword table n - number of entries pat - pattern (left substring) that must match for each keyword pre - prefix to add to each keyword post - suffix to add to each keyword off - offset on first screenful, allowing room for introductory text xhlp - 1 to print any CM_INV keywords that are not also abbreviations. 2 to print CM_INV keywords if CM_HLP also set 4 if it's a switch table (to show ':' if CM_ARG) Arranges keywords in columns with width based on longest keyword. Does "more?" prompting at end of screen. Uses global cmd_rows and cmd_cols for screen size.*/VOIDkwdhelp(s,n,pat,pre,post,off,xhlp) struct keytab s[]; int n, off, xhlp; char *pat, *pre, *post;/* kwdhelp */ { int width = 0; int cc; int cols, height, i, j, k, lc, n2 = 0; char *b = NULL, *p, *q; char *pa, *px; char **s2 = NULL; char *tmpbuf = NULL; cc = strlen(pat); if (!s) return; /* Nothing to do */ if (n < 1) return; /* Ditto */ if (off < 0) off = 0; /* Offset for first page */ if (!pre) pre = ""; /* Handle null string pointers */ if (!post) post = ""; lc = off; /* Screen-line counter */ if (xhlp & 4) /* For switches */ tmpbuf = (char *)malloc(TMPBUFSIZ+1); if ((s2 = (char **) malloc(n * sizeof(char *)))) { for (i = 0; i < n; i++) { /* Find longest keyword */ s2[i] = NULL; if (ckstrcmp(s[i].kwd,pat,cc,0)) continue; if (s[i].flgs & CM_PSH /* NOPUSH or nopush screening */#ifndef NOPUSH && nopush#endif /* NOPUSH */ ) continue; if (s[i].flgs & CM_LOC /* NOLOCAL or nolocal screening */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -