📄 interactive.c
字号:
strcpy(name, ap->glob.gl_pathv[ap->glob.gl_pathc - ap->argcnt]); if (--ap->argcnt == 0) { ap->freeglob = 0; globfree(&ap->glob); }# undef rawname}/* * Strip off the next token of the input. */static char *copynext(input, output) char *input, *output;{ register char *cp, *bp; char quote; for (cp = input; *cp == ' ' || *cp == '\t'; cp++) /* skip to argument */; bp = output; while (*cp != ' ' && *cp != '\t' && *cp != '\0') { /* * Handle back slashes. */ if (*cp == '\\') { if (*++cp == '\0') { fprintf(stderr, "command lines cannot be continued\n"); continue; } *bp++ = *cp++; continue; } /* * The usual unquoted case. */ if (*cp != '\'' && *cp != '"') { *bp++ = *cp++; continue; } /* * Handle single and double quotes. */ quote = *cp++; while (*cp != quote && *cp != '\0') *bp++ = *cp++ | 0200; if (*cp++ == '\0') { fprintf(stderr, "missing %c\n", quote); cp--; continue; } } *bp = '\0'; return (cp);}/* * Canonicalize file names to always start with ``./'' and * remove any imbedded "." and ".." components. */voidcanon(rawname, canonname) char *rawname, *canonname;{ register char *cp, *np; if (strcmp(rawname, ".") == 0 || strncmp(rawname, "./", 2) == 0) (void) strcpy(canonname, ""); else if (rawname[0] == '/') (void) strcpy(canonname, "."); else (void) strcpy(canonname, "./"); (void) strcat(canonname, rawname); /* * Eliminate multiple and trailing '/'s */ for (cp = np = canonname; *np != '\0'; cp++) { *cp = *np++; while (*cp == '/' && *np == '/') np++; } *cp = '\0'; if (*--cp == '/') *cp = '\0'; /* * Eliminate extraneous "." and ".." from pathnames. */ for (np = canonname; *np != '\0'; ) { np++; cp = np; while (*np != '/' && *np != '\0') np++; if (np - cp == 1 && *cp == '.') { cp--; (void) strcpy(cp, np); np = cp; } if (np - cp == 2 && strncmp(cp, "..", 2) == 0) { cp--; while (cp > &canonname[1] && *--cp != '/') /* find beginning of name */; (void) strcpy(cp, np); np = cp; } }}/* * Do an "ls" style listing of a directory */static voidprintlist(name, basename) char *name; char *basename;{ register struct afile *fp, *list, *listp; register struct direct *dp; struct afile single; RST_DIR *dirp; int entries, len; dp = pathsearch(name); if (dp == NULL || (!dflag && TSTINO(dp->d_ino, dumpmap) == 0)) return; if ((dirp = rst_opendir(name)) == NULL) { entries = 1; list = &single; mkentry(dp, list); len = strlen(basename) + 1; if (strlen(name) - len > single.len) { freename(single.fname); single.fname = savename(&name[len]); single.len = strlen(single.fname); } } else { entries = 0; while (dp = rst_readdir(dirp)) entries++; rst_closedir(dirp); list = (struct afile *)malloc(entries * sizeof(struct afile)); if (list == NULL) { fprintf(stderr, "ls: out of memory\n"); return; } if ((dirp = rst_opendir(name)) == NULL) panic("directory reopen failed\n"); fprintf(stderr, "%s:\n", name); entries = 0; listp = list; while (dp = rst_readdir(dirp)) { if (dp == NULL || dp->d_ino == 0) break; if (!dflag && TSTINO(dp->d_ino, dumpmap) == 0) continue; if (vflag == 0 && (strcmp(dp->d_name, ".") == 0 || strcmp(dp->d_name, "..") == 0)) continue; mkentry(dp, listp++); entries++; } rst_closedir(dirp); if (entries == 0) { fprintf(stderr, "\n"); free(list); return; } qsort((char *)list, entries, sizeof(struct afile), fcmp); } formatf(list, entries); if (dirp != NULL) { for (fp = listp - 1; fp >= list; fp--) freename(fp->fname); fprintf(stderr, "\n"); free(list); }}/* * Read the contents of a directory. */static voidmkentry(dp, fp) struct direct *dp; register struct afile *fp;{ char *cp; struct entry *np; fp->fnum = dp->d_ino; fp->fname = savename(dp->d_name); for (cp = fp->fname; *cp; cp++) if (!vflag && (*cp < ' ' || *cp >= 0177)) *cp = '?'; fp->len = cp - fp->fname; if (dflag && TSTINO(fp->fnum, dumpmap) == 0) fp->prefix = '^'; else if ((np = lookupino(fp->fnum)) != NULL && (np->e_flags & NEW)) fp->prefix = '*'; else fp->prefix = ' '; switch(dp->d_type) { default: fprintf(stderr, "Warning: undefined file type %d\n", dp->d_type); /* fall through */ case DT_REG: fp->postfix = ' '; break; case DT_LNK: fp->postfix = '@'; break; case DT_FIFO: case DT_SOCK: fp->postfix = '='; break; case DT_CHR: case DT_BLK: fp->postfix = '#'; break; case DT_UNKNOWN: case DT_DIR: if (inodetype(dp->d_ino) == NODE) fp->postfix = '/'; else fp->postfix = ' '; break; } return;}/* * Print out a pretty listing of a directory */static voidformatf(list, nentry) register struct afile *list; int nentry;{ register struct afile *fp, *endlist; int width, bigino, haveprefix, havepostfix; int i, j, w, precision, columns, lines; width = 0; haveprefix = 0; havepostfix = 0; bigino = ROOTINO; endlist = &list[nentry]; for (fp = &list[0]; fp < endlist; fp++) { if (bigino < fp->fnum) bigino = fp->fnum; if (width < fp->len) width = fp->len; if (fp->prefix != ' ') haveprefix = 1; if (fp->postfix != ' ') havepostfix = 1; } if (haveprefix) width++; if (havepostfix) width++; if (vflag) { for (precision = 0, i = bigino; i > 0; i /= 10) precision++; width += precision + 1; } width++; columns = 81 / width; if (columns == 0) columns = 1; lines = (nentry + columns - 1) / columns; for (i = 0; i < lines; i++) { for (j = 0; j < columns; j++) { fp = &list[j * lines + i]; if (vflag) { fprintf(stderr, "%*d ", precision, fp->fnum); fp->len += precision + 1; } if (haveprefix) { putc(fp->prefix, stderr); fp->len++; } fprintf(stderr, "%s", fp->fname); if (havepostfix) { putc(fp->postfix, stderr); fp->len++; } if (fp + lines >= endlist) { fprintf(stderr, "\n"); break; } for (w = fp->len; w < width; w++) putc(' ', stderr); } }}/* * Skip over directory entries that are not on the tape * * First have to get definition of a dirent. */#undef DIRBLKSIZ#include <dirent.h>#undef d_inostruct dirent *glob_readdir(dirp) RST_DIR *dirp;{ struct direct *dp; static struct dirent adirent; while ((dp = rst_readdir(dirp)) != NULL) { if (dp->d_ino == 0) continue; if (dflag || TSTINO(dp->d_ino, dumpmap)) break; } if (dp == NULL) return (NULL); adirent.d_fileno = dp->d_ino; adirent.d_namlen = dp->d_namlen; bcopy(dp->d_name, adirent.d_name, dp->d_namlen + 1); return (&adirent);}/* * Return st_mode information in response to stat or lstat calls */static intglob_stat(name, stp) const char *name; struct stat *stp;{ register struct direct *dp; dp = pathsearch(name); if (dp == NULL || (!dflag && TSTINO(dp->d_ino, dumpmap) == 0)) return (-1); if (inodetype(dp->d_ino) == NODE) stp->st_mode = IFDIR; else stp->st_mode = IFREG; return (0);}/* * Comparison routine for qsort. */static intfcmp(f1, f2) register const void *f1, *f2;{ return (strcmp(((struct afile *)f1)->fname, ((struct afile *)f2)->fname));}/* * respond to interrupts */voidonintr(signo) int signo;{ if (command == 'i' && runshell) longjmp(reset, 1); if (reply("restore interrupted, continue") == FAIL) done(1);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -