📄 ckucmd.c
字号:
#ifdef OS2o_again:#endif /* OS2 */ if (tries == 1)#endif /* DOCHKVAR */ if (f) { /* If a conversion function is given */ zq = atxbuf; /* do the conversion. */ atxn = CMDBL; if ((x = (*f)(s,&zq,&atxn)) < 0) return(-2); s = atxbuf; if (!*s) /* Result empty, substitute default */ s = xdef; } debug(F111,"cmofi 2",s,x);#ifdef DTILDE dirp = tilde_expand(s); /* Expand tilde, if any, */ if (*dirp != '\0') { /* right in the atom buffer. */ if (setatm(dirp,1) < 0) { printf("?Name too long\n"); return(-9); } } s = atmbuf; debug(F110,"cmofi 3",s,0);#endif /* DTILDE */ if (iswild(s)) { printf("?Wildcards not allowed - %s\n",s); return(-2); } debug(F110,"cmofi 4",s,0);#ifdef CK_TMPDIR /* isdir() function required for this! */ if (isdir(s)) { debug(F110,"cmofi 5: is directory",s,0); *xp = s; return(2); }#endif /* CK_TMPDIR */ if (strcmp(s,CTTNAM) && (zchko(s) < 0)) { /* OK to write to console */#ifdef COMMENT#ifdef OS2/* We don't try again because we already prescanned the string to see if if it contained anything that could be used by zzstring().*/ if (tries++ < 1) goto o_again;#endif /* OS2 */#endif /* COMMENT *//* Note: there are certain circumstances where zchko() can give a false positive, so don't rely on it to catch every conceivable situation in which the given output file can't be created. In other words, we print a message and fail here if we KNOW the file can't be created. If we succeed but the file can't be opened, the code that tries to open the file has to print a message.*/ debug(F110,"cmofi 6: failure",s,0); printf("?Write permission denied - %s\n",s);#ifdef CKCHANNELIO z_error = FX_ACC;#endif /* CKCHANNELIO */ return(-9); } else { debug(F110,"cmofi 7: ok",s,0); *xp = s; return(x); }}/* C M I F I -- Parse the name of an existing file *//* This function depends on the external functions: zchki() - Check if input file exists and is readable. zxpand() - Expand a wild file specification into a list. znext() - Return next file name from list. If these functions aren't available, then use cmfld() to parse filenames.*//* Returns -4 EOF -3 if no input present when required, -2 if file does not exist or is not readable, -1 if reparse needed, 0 or 1 otherwise, with: xp pointing to name, wild = 1 if name contains '*' or '?', 0 otherwise.*//* C M I O F I -- Parse an input file OR the name of a nonexistent file. Use this when an existing file is wanted (so we get help, completion, etc), but if a file of the given name does not exist, the name of a new file is accepted. For example, with the EDIT command (edit an existing file, or create a new file). Returns -9 if file does not exist. It is up to the caller to check creatability.*/static int nomsg = 0;intcmiofi(xhlp,xdef,xp,wild,f) char *xhlp, *xdef, **xp; int *wild; xx_strp f; { int msgsave, x; msgsave = nomsg; nomsg = 1; x = cmifi2(xhlp,xdef,xp,wild,0,NULL,f,0); nomsg = msgsave; return(x);}intcmifi(xhlp,xdef,xp,wild,f) char *xhlp, *xdef, **xp; int *wild; xx_strp f; { return(cmifi2(xhlp,xdef,xp,wild,0,NULL,f,0));}/* cmifip() is called when we want to supply a path or path list to search in case the filename that the user gives is (a) not absolute, and (b) can't be found as given. The path string can be the name of a single directory, or a list of directories separated by the PATHSEP character, defined in ckucmd.h. Look in ckuusr.c and ckuus3.c for examples of usage.*/intcmifip(xhlp,xdef,xp,wild,d,path,f) char *xhlp,*xdef,**xp; int *wild, d; char * path; xx_strp f; { return(cmifi2(xhlp,xdef,xp,wild,0,path,f,0));}/* C M D I R -- Parse a directory name *//* This function depends on the external functions: isdir(s) - Check if string s is the name of a directory zchki(s) - Check if input file s exists and what type it is. If these functions aren't available, then use cmfld() to parse dir names. Returns -9 For all sorts of reasons, after printing appropriate error message. -4 EOF -3 if no input present when required, -2 if out of space or other internal error, -1 if reparse needed, 0 or 1, with xp pointing to name, if directory specified,*/intcmdir(xhlp,xdef,xp,f) char *xhlp, *xdef, **xp; xx_strp f; { int wild; return(cmifi2(xhlp,xdef,xp,&wild,0,NULL,f,1));}/* Like CMDIR but includes PATH search */intcmdirp(xhlp,xdef,xp,path,f) char *xhlp, *xdef, **xp; char * path; xx_strp f; { int wild; return(cmifi2(xhlp,xdef,xp,&wild,0,path,f,1));}/* cmifi2() is the base filename parser called by cmifi, cmifip, cmdir, etc. Use it directly when you also want to parse a directory or device name as an input file, as in the DIRECTORY command. Call with: xhlp -- help message on ? xdef -- default response xp -- pointer to result (in our space, must be copied from here) wild -- flag set upon return to indicate if filespec was wild d -- 0 to parse files, 1 to parse files or directories path -- search path for files f -- pointer to string processing function (e.g. to evaluate variables) dirflg -- 1 to parse *only* directories, 0 otherwise*/intcmifi2(xhlp,xdef,xp,wild,d,path,f,dirflg) char *xhlp,*xdef,**xp; int *wild, d; char * path; xx_strp f; int dirflg; { extern int recursive, diractive; int i, x, itsadir, xc, expanded = 0, nfiles = 0; long y; char *sp = NULL, *zq, *np = NULL; char *sv = NULL, *p = NULL;#ifdef DTILDE char *dirp;#endif /* DTILDE */#ifndef NOPARTIAL#ifndef OS2#ifdef OSK /* This large array is dynamic for OS-9 -- should do for others too... */ extern char **mtchs;#else#ifdef UNIX /* OK, for UNIX too */ extern char **mtchs;#else#ifdef VMS extern char **mtchs;#else extern char *mtchs[];#endif /* VMS */#endif /* UNIX */#endif /* OSK */#endif /* OS2 */#endif /* NOPARTIAL */ if (!xhlp) xhlp = ""; if (!xdef) xdef = ""; cmfldflgs = 0; if (path) if (!*path) path = NULL; if (path) { /* Make a copy we can poke */ x = strlen(path); np = (char *) malloc(x + 1); if (np) { strcpy(np, path); path = sp = np; } } debug(F110,"cmifi2 path",path,0); ckstrncpy(cmdefault,xdef,CMDEFAULT); /* Copy default */ xdef = cmdefault; inword = 0; /* Initialize counts & pointers */ cc = 0; xc = 0; *xp = ""; /* Pointer to result string */ if ((x = cmflgs) != 1) { /* Already confirmed? */#ifdef BS_DIRSEP dirnamflg = 1; x = gtword(0); /* No, get a word */ dirnamflg = 0;#else x = gtword(0); /* No, get a word */#endif /* BS_DIRSEP */ } else { /* If so, use default, if any. */ if (setatm(xdef,1) < 0) { printf("?Default name too long\n"); if (np) free(np); return(-9); } } i_path: *xp = atmbuf; /* Point to result. */ while (1) { xc += cc; /* Count this character. */ debug(F111,"cmifi gtword",atmbuf,xc); debug(F101,"cmifi switch x","",x); switch (x) { /* x = gtword() return code */ case -10: if (gtimer() > timelimit) {#ifdef IKSD extern int inserver; if (inserver) { printf("\r\nIKSD IDLE TIMEOUT: %d sec\r\n", timelimit); doexit(GOOD_EXIT,0); }#endif /* IKSD */ if (!quiet) printf("?Timed out\n"); return(-10); } else { x = gtword(0); continue; } case -9: printf("Command or field too long\n"); case -4: /* EOF */ case -2: /* Out of space. */ case -1: /* Reparse needed */ if (np) free(np); return(x); case 0: /* SP or NL */ case 1: if (xc == 0) /* If no input... */ *xp = xdef; /* substitute the default */ if (**xp == NUL) { /* If field still empty return -3. */ if (np) free(np); return(-3); } *xp = brstrip(*xp); /* Strip braces */ debug(F110,"cmifi brstrip",*xp,0);#ifndef NOSPL if (f) { /* If a conversion function is given */#ifdef DOCHKVAR char *s = *xp; /* See if there are any variables in */ int x; while (*s) { /* the string and if so, expand them */ if (chkvar(s)) {#endif /* DOCHKVAR */ zq = atxbuf; atxn = CMDBL; if ((*f)(*xp,&zq,&atxn) < 0) { if (np) free(np); return(-2); } *xp = atxbuf; if (!atxbuf[0]) *xp = xdef;#ifdef DOCHKVAR break; } s++; }#endif /* DOCHKVAR */ }#endif /* NOSPL */#ifdef DTILDE dirp = tilde_expand(*xp); /* Expand tilde, if any, */ if (*dirp != '\0') { /* in the atom buffer. */ if (setatm(dirp,1) < 0) { printf("Expanded name too long\n"); if (np) free(np); return(-9); } } *xp = atmbuf;#endif /* DTILDE */ debug(F110,"cmifi tilde_expand",*xp,0); if (!sv) { /* Only do this once */ sv = malloc((int)strlen(*xp)+1); /* Make a safe copy */ if (!sv) { printf("?cmifi: malloc error\n"); if (np) free(np); return(-9); } strcpy(sv,*xp); debug(F110,"cmifi sv",sv,0); }/* This is to get around "cd /" failing because "too many directories match" */ expanded = 0; /* Didn't call zxpand */#ifdef datageneral debug(F110,"cmifi isdir 1",*xp,0); { int y; char *s; s = *xp; y = strlen(s); if (y > 1 && (s[y-1] == ':' || s[y-1] == '^' || s[y-1] == '=') ) s[y-1] = NUL; } debug(F110,"cmifi isdir 2",*xp,0);#endif /* datageneral */#ifdef VMS if (dirflg) { if (!strcmp(*xp,"..")) { /* For UNIXers... */ setatm("-",0); *xp = atmbuf; } else if (!strcmp(*xp,".")) { setatm("[]",0); *xp = atmbuf; } }#endif /* VMS */ itsadir = isdir(*xp); /* Is it a directory? */ debug(F111,"cmifi itsadir",*xp,itsadir);#ifdef VMS /* If they said "blah" where "blah.dir" is a directory... */ /* change it to [.blah]. */ if (!itsadir) { char tmpbuf[600]; int flag = 0; char c, * p; p = *xp; while ((c = *p++) && !flag) if (ckstrchr(".[]:*?<>",c)) flag = 1; debug(F111,"cmifi VMS dirname flag",*xp,flag); if (!flag) { sprintf(tmpbuf,"[.%s]",*xp); itsadir = isdir(tmpbuf); if (itsadir) { setatm(tmpbuf,0); *xp = atmbuf; } debug(F111,"cmifi VMS dirname flag itsadir",*xp,itsadir); } } else if (itsadir == 1 && *(xp[0]) == '.' && *(xp[1])) { char *p; if (p = malloc(cc + 4)) { sprintf(p,"[%s]",*xp); setatm(p,0); *xp = atmbuf; debug(F110,"cmdir .foo",*xp,0); free(p); } } else if (itsadir == 2 && !diractive) { int x; /* [FOO]BAR.DIR instead of [FOO.BAR] */ char *p; p = malloc(cc + 4); if (p) { x = cvtdir(*xp,p); /* Convert to [FOO.BAR] */ if (x > 0) { setatm(p,0); *xp = atmbuf; debug(F110,"cmdir cvtdir",*xp,0); } free(p); } }#endif /* VMS */ if (dirflg) { /* Parsing a directory name? */ /* Yes, does it contain wildcards? */ if (iswild(*xp) || diractive && (!strcmp(*xp,".") || !strcmp(*xp,"..")) ) { nzxopts = ZX_DIRONLY; /* Match only directory names */ if (matchdot) nzxopts |= ZX_MATCHDOT; if (recursive) nzxopts |= ZX_RECURSE; y = nzxpand(*xp,nzxopts); nfiles = y; expanded = 1; } else {#ifdef VMS/* This is to allow (e.g.) "cd foo", where FOO.DIR;1 is in the current directory.*/ debug(F111,"cmdir itsadir",*xp,itsadir); if (!itsadir) { char *s; int n; s = *xp; n = strlen(s); if (n > 0 &&#ifdef COMMENT *s != '[' && s[n-1] != ']' && *s != '<' && s[n-1] != '>' &&#else ckindex("[",s,0,0,1) == 0 && ckindex("<",s,0,0,1) == 0 &&#endif /* COMMENT */ s[n-1] != ':') { char * dirbuf = NULL; dirbuf = (char *)malloc(n+4); if (dirbuf) { if (*s == '.') sprintf(dirbuf,"[%s]",s); else sprintf(dirbuf,"[.%s]",s); itsadir = isdir(dirbuf); debug(F111,"cmdir dirbuf",dirbuf,itsadir); if (itsadir) { setatm(dirbuf,0); *xp = atmbuf; debug(F110,"cmdir new *xp",*xp,0); } free(dirbuf); }/* This is to allow CDPATH to work in VMS... */ } else if (n > 0) { char * p; int i, j, k, d; char rb[2] = "]"; if (p = malloc(x + 8)) {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -