📄 ckufio.c
字号:
else if (islower(*cp)) *pp++ = toupper(*cp); /* Uppercase letters */ else if (*cp == '~') *pp++ = 'X'; /* Change tilde to 'X' */ else if (*cp == '#') *pp++ = 'X'; /* Change number sign to 'X' */ else if ((*cp == '.') && (++dc > 1)) *pp++ = 'X'; /* & extra dots */ else *pp++ = *cp; } *pp = '\0'; /* Tie it off. */ cp = name2; /* If nothing before dot, */ if (*work == '.') *cp++ = 'X'; /* insert 'X' */ strcpy(cp,work); debug(F110," name2",name2,0);} /* 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 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) return(0); /* can't make pipe, fail */ if ((pid = fork()) == 0) { /* child *//*#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 */ 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 *//**** 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; shptr = shname = shpath; while (*shptr != '\0') if (*shptr++ == '/') shname = shptr; debug(F100,"zxcmd...","",0); debug(F110,shpath,shname,0); execl(shpath,shname,"-c",comand,NULL); /* Execute the command *//**** execl("/bin/sh","sh","-c",comand,NULL); /* Execute the command */ exit(0); /* just punt if it didnt work */ } 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; fclose(fp[ZIFILE]); fp[ZIFILE] = fp[ZSYSFN] = NULL; while ((wstat = wait(0)) != pid && wstat != -1) ; 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#define SSPACE 2000 /* size of string-generating buffer */#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; 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++; } 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; head = splitpath(pat); if (*pat == '/') { scratch[0] = '/'; sptr = scratch+1; } else { strcpy(scratch,"./"); sptr = scratch+2; } /* init buffer correctly */ 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]) { 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 + -