📄 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
#endif
static 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 + -