📄 ckufio.c
字号:
/* Z C H D I R -- Change directory */zchdir(dirnam) char *dirnam; { char *hd; if (*dirnam == '\0') hd = getenv("HOME"); else hd = dirnam; return((chdir(hd) == 0) ? 1 : 0);}/* Z H O M E -- Return pointer to user's home directory */char *zhome() { return(getenv("HOME"));}/* Z G T D I R -- Return pointer to user's current directory */char *zgtdir() {#ifdef MAXPATHLEN#define CWDBL MAXPATHLEN#else#define CWDBL 100#endif#ifdef UXIII char cwdbuf[CWDBL+1]; char *buf; char *getcwd(); buf = cwdbuf; return(getcwd(buf,CWDBL));#else#ifdef BSD4 char cwdbuf[CWDBL+1]; char *buf; char *getwd(); buf = cwdbuf; return(getwd(buf));#else return("(directory unknown)");#endif#endif}/* Z X C M D -- Run a system command so its output can be read like a file */zxcmd(comand) char *comand; { int pipes[2]; if (pipe(pipes) != 0) { debug(F100,"zxcmd pipe failure","",0); return(0); /* can't make pipe, fail */ }#ifdef aegis if ((pid = vfork()) == 0) { /* child */#else if ((pid = fork()) == 0) { /* child */#endif/*#if BSD4*/ /* Code from Dave Tweten@AMES-NAS */ /* readapted to use getpwuid to find login shell */ /* -- H. Fischer */ char *shpath, *shname, *shptr; /* to find desired shell */#ifndef aegis struct passwd *p; extern struct passwd * getpwuid(); extern int getuid(); char *defShel = "/bin/sh"; /* default shell */#endif close(pipes[0]); /* close input side of pipe */ close(0); /* close stdin */ if (open("/dev/null",0) < 0) return(0); /* replace input by null */#ifndef UXIII dup2(pipes[1],1); /* replace stdout & stderr */ dup2(pipes[1],2); /* by the pipe */#else close(1); /* simulate dup2 */ if (dup(pipes[1]) != 1 ) conol("trouble duping stdout in routine zxcmd\n"); close(2); /* simulate dup2 */ if (dup(pipes[1]) != 2 ) conol("trouble duping stderr in routine zxcmd\n");#endif close(pipes[1]); /* get rid of this copy of the pipe */#ifdef aegis if ((shpath = getenv("SERVERSHELL")) == NULL) shpath = "/bin/sh";#else/**** shptr = shname = shpath = getenv("SHELL"); /* What shell? */ p = getpwuid( getuid() ); /* get login data */ if ( p == (struct passwd *) NULL || !*(p->pw_shell) ) shpath = defShel; else shpath = p->pw_shell;#endif shptr = shname = shpath; while (*shptr != '\0') if (*shptr++ == '/') shname = shptr; debug(F100,"zxcmd...","",0); debug(F110,shpath,shname,0);/* Remove the following uid calls if they cause trouble... */#ifdef BSD4 setegid(getgid()); /* Override 4.3BSD csh */ seteuid(getuid()); /* security checks */#endif /* bsd4 */ execl(shpath,shname,"-c",comand,(char *)NULL); /* Execute the cmd */ exit(0); /* just punt if it failed. */ } else if (pid == -1) { debug(F100,"zxcmd fork failure","",0); return(0); } close(pipes[1]); /* don't need the output side */ fp[ZIFILE] = fdopen(pipes[0],"r"); /* open a stream for it */ fp[ZSYSFN] = fp[ZIFILE]; /* Remember. */ return(1);}/* Z C L O S F - wait for the child fork to terminate and close the pipe. */zclosf() { int wstat; if (kill(pid,9) == 0) { debug(F101,"zclosf pid =","",pid); while ((wstat = wait((int *)0)) != pid && wstat != -1) ; pid = 0; } fclose(fp[ZIFILE]); fp[ZIFILE] = fp[ZSYSFN] = NULL; return(1);}/* Z X P A N D -- Expand a wildcard string into an array of strings *//* Returns the number of files that match fn1, with data structures set up so that first file (if any) will be returned by the next znext() call.*/zxpand(fn) char *fn; { fcount = fgen(fn,mtchs,MAXWLD); /* Look up the file. */ if (fcount > 0) { mtchptr = mtchs; /* Save pointer for next. */ } debug(F111,"zxpand",mtchs[0],fcount); return(fcount);}/* Z N E X T -- Get name of next file from list created by zxpand(). *//* Returns >0 if there's another file, with its name copied into the arg string, or 0 if no more files in list.*/znext(fn) char *fn; { if (fcount-- > 0) strcpy(fn,*mtchptr++); else *fn = '\0'; debug(F111,"znext",fn,fcount+1); return(fcount+1);}/* Z N E W N -- Make a new name for the given file */znewn(fn,s) char *fn, **s; {#ifdef BSD4 static char buf[256];#else static char buf[100];#endif char *bp, *xp; int len = 0, n = 0, d = 0, t, i, power = 1;#ifdef MAXNAMLEN int max = MAXNAMLEN;#else int max = 14;#endif bp = buf; while (*fn) { /* Copy name into buf */ *bp++ = *fn++; len++; } if (len > max-2) { /* Don't let it get too long */ bp = buf + max-2; len = max - 2; } for (i = 1; i < 4; i++) { /* Try up to 999 times */ power *= 10; *bp++ = '*'; /* Put a star on the end */ *bp-- = '\0'; n = zxpand(buf); /* Expand the resulting wild name */ while (n-- > 0) { /* Find any existing name~d files */ xp = *mtchptr++; xp += len; if (*xp == '~') { t = atoi(xp+1); if (t > d) d = t; /* Get maximum d */ } } if (d < power-1) { sprintf(bp,"~%d",d+1); /* Make name~(d+1) */ *s = buf; return; } bp--; len--; }/* If we ever get here, we'll overwrite the xxx~100 file... */}/* Directory Functions for Unix, written by Jeff Damens, CUCCA, 1984. *//* * The path structure is used to represent the name to match. * Each slash-separated segment of the name is kept in one * such structure, and they are linked together, to make * traversing the name easier. */struct path { char npart[MAXNAMLEN]; /* name part of path segment */ struct path *fwd; /* forward ptr */ };#ifdef PROVX1#define SSPACE 500#else#ifdef BSD29#define SSPACE 500#else#ifdef aegis#define SSPACE 10000 /* size of string-generating buffer */static char bslash; /* backslash character if active */#else#define SSPACE 2000 /* size of string-generating buffer */#endif#endif#endifstatic char sspace[SSPACE]; /* buffer to generate names in */static char *freeptr,**resptr; /* copies of caller's arguments */static int remlen; /* remaining length in caller's array*/static int numfnd; /* number of matches found *//* * splitpath: * takes a string and splits the slash-separated portions into * a list of path structures. Returns the head of the list. The * structures are allocated by malloc, so they must be freed. * Splitpath is used internally by the filename generator. * * Input: A string. * Returns: A linked list of the slash-separated segments of the input. */struct path *splitpath(p)char *p;{ struct path *head,*cur,*prv; int i; head = prv = NULL; if (*p == '/') p++; /* skip leading slash */ while (*p != '\0') { cur = (struct path *) malloc(sizeof (struct path)); debug(F101,"splitpath malloc","",cur); if (cur == NULL) fatal("malloc fails in splitpath()"); cur -> fwd = NULL; if (head == NULL) head = cur; else prv -> fwd = cur; /* link into chain */ prv = cur;#ifdef aegis /* treat backslash as "../" */ if (bslash && *p == bslash) { strcpy(cur->npart, ".."); ++p; } else { for (i=0; i < MAXNAMLEN && *p && *p != '/' && *p != bslash; i++) cur -> npart[i] = *p++; cur -> npart[i] = '\0'; /* end this segment */ if (i >= MAXNAMLEN) while (*p && *p != '/' && *p != bslash) p++; } if (*p == '/') p++;#else for (i=0; i < MAXNAMLEN && *p != '/' && *p != '\0'; i++) cur -> npart[i] = *p++; cur -> npart[i] = '\0'; /* end this segment */ if (i >= MAXNAMLEN) while (*p != '/' && *p != '\0') p++; if (*p == '/') p++;#endif } return(head);}/* * fgen: * This is the actual name generator. It is passed a string, * possibly containing wildcards, and an array of character pointers. * It finds all the matching filenames and stores them into the array. * The returned strings are allocated from a static buffer local to * this module (so the caller doesn't have to worry about deallocating * them); this means that successive calls to fgen will wipe out * the results of previous calls. This isn't a problem here * because we process one wildcard string at a time. * * Input: a wildcard string, an array to write names to, the * length of the array. * Returns: the number of matches. The array is filled with filenames * that matched the pattern. If there wasn't enough room in the * array, -1 is returned. * By: Jeff Damens, CUCCA, 1984. */fgen(pat,resarry,len)char *pat,*resarry[];int len;{ struct path *head; char scratch[100],*sptr;#ifdef aegis char *getenv(), *index(), *namechars; int tilde = 0, bquote = 0; if ((namechars = getenv("NAMECHARS")) != NULL) { if (index(namechars, '~' ) != NULL) tilde = '~'; if (index(namechars, '\\') != NULL) bslash = '\\'; if (index(namechars, '`' ) != NULL) bquote = '`'; } else { tilde = '~'; bslash = '\\'; bquote = '`'; } sptr = scratch; /* copy "`node_data", etc. anchors */ if (bquote && *pat == bquote) while (*pat && *pat != '/' && *pat != bslash) *sptr++ = *pat++; else if (tilde && *pat == tilde) *sptr++ = *pat++; while (*pat == '/') *sptr++ = *pat++; if (sptr == scratch) { strcpy(scratch,"./"); sptr = scratch+2; } /* init buffer correctly */ head = splitpath(pat);#else head = splitpath(pat); if (*pat == '/') { scratch[0] = '/'; sptr = scratch+1; } else { strcpy(scratch,"./"); sptr = scratch+2; } /* init buffer correctly */#endif numfnd = 0; /* none found yet */ freeptr = sspace; /* this is where matches are copied */ resptr = resarry; /* static copies of these so*/ remlen = len; /* recursive calls can alter them */ traverse(head,scratch,sptr); /* go walk the directory tree */ for (; head != NULL; head = head -> fwd) free(head); /* return the path segments */ return(numfnd); /* and return the number of matches */}/* traverse: * Walks the directory tree looking for matches to its arguments. * The algorithm is, briefly: * If the current pattern segment contains no wildcards, that * segment is added to what we already have. If the name so far * exists, we call ourselves recursively with the next segment * in the pattern string; otherwise, we just return. * * If the current pattern segment contains wildcards, we open the name * we've accumulated so far (assuming it is really a directory), then read * each filename in it, and, if it matches the wildcard pattern segment, add * that filename to what we have so far and call ourselves recursively on the * next segment. * * Finally, when no more pattern segments remain, we add what's accumulated * so far to the result array and increment the number of matches. * * Input: a pattern path list (as generated by splitpath), a string * pointer that points to what we've traversed so far (this * can be initialized to "/" to start the search at the root * directory, or to "./" to start the search at the current * directory), and a string pointer to the end of the string * in the previous argument. * Returns: nothing. */traverse(pl,sofar,endcur)struct path *pl;char *sofar,*endcur;{#ifdef BSD42 DIR *fd, *opendir(); struct direct *dirbuf;#else#ifdef BSD29 DIR *fd, *opendir(); struct direct *dirbuf;#else int fd; struct direct dir_entry; struct direct *dirbuf = &dir_entry;#endif#endif struct stat statbuf; if (pl == NULL) { *--endcur = '\0'; /* end string, overwrite trailing / */ addresult(sofar); return; } if (!iswild(pl -> npart)) { strcpy(endcur,pl -> npart); endcur += strlen(pl -> npart); *endcur = '\0'; /* end current string */ if (stat(sofar,&statbuf) == 0) /* if current piece exists */ { *endcur++ = '/'; /* add slash to end */ *endcur = '\0'; /* and end the string */ traverse(pl -> fwd,sofar,endcur); } return; }/* cont'd... *//*...traverse, cont'd *//* segment contains wildcards, have to search directory */ *endcur = '\0'; /* end current string */ if (stat(sofar,&statbuf) == -1) return; /* doesn't exist, forget it */ if ((statbuf.st_mode & S_IFDIR) == 0) return; /* not a directory, skip */#ifdef BSD42 /* ==BSD4 */ if ((fd = opendir(sofar)) == NULL) return; /* can't open, forget it */ while (dirbuf = readdir(fd))#else#ifdef BSD29 /* ==BSD29 */ if ((fd = opendir(sofar)) == NULL) return; /* can't open, forget it */ while (dirbuf = readdir(fd))#else if ((fd = open(sofar,O_RDONLY)) < 0) return; /* can't open, forget it */ while ( read(fd,dirbuf,sizeof dir_entry) )#endif#endif{ strncpy(nambuf,dirbuf->d_name,MAXNAMLEN); /* Get a null terminated copy!!! */ nambuf[MAXNAMLEN] = '\0'; if (dirbuf->d_ino != 0 && match(pl -> npart,nambuf)) { char *eos; strcpy(endcur,nambuf); eos = endcur + strlen(nambuf); *eos = '/'; /* end this segment */ traverse(pl -> fwd,sofar,eos+1); }}#ifdef BSD42 /* ==BSD4 */ closedir(fd);#else#ifdef BSD29 closedir(fd);#else close(fd);#endif#endif}/* * addresult: * Adds a result string to the result array. Increments the number * of matches found, copies the found string into our string * buffer, and puts a pointer to the buffer into the caller's result * array. Our free buffer pointer is updated. If there is no * more room in the caller's array, the number of matches is set to -1. * Input: a result string. * Returns: nothing. */addresult(str)char *str;{ int l; if (strncmp(str,"./",2) == 0) str += 2; if (--remlen < 0) { numfnd = -1; return; } l = strlen(str) + 1; /* size this will take up */ if ((freeptr + l) > &sspace[SSPACE-1]) { numfnd = -1; /* do not record if not enough space */ return; } strcpy(freeptr,str); *resptr++ = freeptr; freeptr += l; numfnd++;}iswild(str)char *str;{ char c; while ((c = *str++) != '\0') if (c == '*' || c == '?') return(1); return(0);}/* * match: * pattern matcher. Takes a string and a pattern possibly containing * the wildcard characters '*' and '?'. Returns true if the pattern * matches the string, false otherwise. * by: Jeff Damens, CUCCA * * Input: a string and a wildcard pattern. * Returns: 1 if match, 0 if no match. */match(pattern,string) char *pattern,*string; { char *psave,*ssave; /* back up pointers for failure */ psave = ssave = NULL; while (1) { for (; *pattern == *string; pattern++,string++) /* skip first */ if (*string == '\0') return(1); /* end of strings, succeed */ if (*string != '\0' && *pattern == '?') { pattern++; /* '?', let it match */ string++; } else if (*pattern == '*') { /* '*' ... */ psave = ++pattern; /* remember where we saw it */ ssave = string; /* let it match 0 chars */ } else if (ssave != NULL && *ssave != '\0') { /* if not at end */ /* ...have seen a star */ string = ++ssave; /* skip 1 char from string */ pattern = psave; /* and back up pattern */ } else return(0); /* otherwise just fail */ }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -