📄 file.c
字号:
(void) fputc('\b', cshout); (void) fputc('\b', cshout); switch (Strlen(recognized_part)) { case 0: /* erase two Characters: ^[ */ (void) fputc(' ', cshout); (void) fputc(' ', cshout); (void) fputc('\b', cshout); (void) fputc('\b', cshout); break; case 1: /* overstrike the ^, erase the [ */ (void) fprintf(cshout, "%s", vis_str(recognized_part)); (void) fputc(' ', cshout); (void) fputc('\b', cshout); break; default: /* overstrike both Characters ^[ */ (void) fprintf(cshout, "%s", vis_str(recognized_part)); break; } (void) fflush(cshout);}/* * Parse full path in file into 2 parts: directory and file names * Should leave final slash (/) at end of dir. */static voidextract_dir_and_name(path, dir, name) Char *path, *dir, *name;{ register Char *p; p = Strrchr(path, '/'); if (p == NULL) { copyn(name, path, MAXNAMLEN); dir[0] = '\0'; } else { copyn(name, ++p, MAXNAMLEN); copyn(dir, path, p - path); }}static Char *getentry(dir_fd, looking_for_lognames) DIR *dir_fd; int looking_for_lognames;{ register struct passwd *pw; register struct dirent *dirp; if (looking_for_lognames) { if ((pw = getpwent()) == NULL) return (NULL); return (str2short(pw->pw_name)); } if ((dirp = readdir(dir_fd)) != NULL) return (str2short(dirp->d_name)); return (NULL);}static voidfree_items(items) register Char **items;{ register int i; for (i = 0; items[i]; i++) xfree((ptr_t) items[i]); xfree((ptr_t) items);}#define FREE_ITEMS(items) { \ int omask;\\ omask = sigblock(sigmask(SIGINT));\ free_items(items);\ items = NULL;\ (void) sigsetmask(omask);\}/* * Perform a RECOGNIZE or LIST command on string "word". */static inttsearch(word, command, max_word_length) Char *word; COMMAND command; int max_word_length;{ static Char **items = NULL; register DIR *dir_fd; register numitems = 0, ignoring = TRUE, nignored = 0; register name_length, looking_for_lognames; Char tilded_dir[MAXPATHLEN + 1], dir[MAXPATHLEN + 1]; Char name[MAXNAMLEN + 1], extended_name[MAXNAMLEN + 1]; Char *entry;#define MAXITEMS 1024 if (items != NULL) FREE_ITEMS(items); looking_for_lognames = (*word == '~') && (Strchr(word, '/') == NULL); if (looking_for_lognames) { (void) setpwent(); copyn(name, &word[1], MAXNAMLEN); /* name sans ~ */ dir_fd = NULL; } else { extract_dir_and_name(word, dir, name); if (tilde(tilded_dir, dir) == 0) return (0); dir_fd = opendir(*tilded_dir ? short2str(tilded_dir) : "."); if (dir_fd == NULL) return (0); }again: /* search for matches */ name_length = Strlen(name); for (numitems = 0; (entry = getentry(dir_fd, looking_for_lognames)) != NULL;) { if (!is_prefix(name, entry)) continue; /* Don't match . files on null prefix match */ if (name_length == 0 && entry[0] == '.' && !looking_for_lognames) continue; if (command == LIST) { if (numitems >= MAXITEMS) { (void) fprintf(csherr, "\nYikes!! Too many %s!!\n", looking_for_lognames ? "names in password file" : "files"); break; } if (items == NULL) items = (Char **) xcalloc(sizeof(items[0]), MAXITEMS); items[numitems] = (Char *) xmalloc((size_t) (Strlen(entry) + 1) * sizeof(Char)); copyn(items[numitems], entry, MAXNAMLEN); numitems++; } else { /* RECOGNIZE command */ if (ignoring && ignored(entry)) nignored++; else if (recognize(extended_name, entry, name_length, ++numitems)) break; } } if (ignoring && numitems == 0 && nignored > 0) { ignoring = FALSE; nignored = 0; if (looking_for_lognames) (void) setpwent(); else rewinddir(dir_fd); goto again; } if (looking_for_lognames) (void) endpwent(); else (void) closedir(dir_fd); if (numitems == 0) return (0); if (command == RECOGNIZE) { if (looking_for_lognames) copyn(word, STRtilde, 1); else /* put back dir part */ copyn(word, dir, max_word_length); /* add extended name */ catn(word, extended_name, max_word_length); return (numitems); } else { /* LIST */ qsort((ptr_t) items, numitems, sizeof(items[0]), (int (*) __P((const void *, const void *))) sortscmp); print_by_column(looking_for_lognames ? NULL : tilded_dir, items, numitems); if (items != NULL) FREE_ITEMS(items); } return (0);}/* * Object: extend what user typed up to an ambiguity. * Algorithm: * On first match, copy full entry (assume it'll be the only match) * On subsequent matches, shorten extended_name to the first * Character mismatch between extended_name and entry. * If we shorten it back to the prefix length, stop searching. */static intrecognize(extended_name, entry, name_length, numitems) Char *extended_name, *entry; int name_length, numitems;{ if (numitems == 1) /* 1st match */ copyn(extended_name, entry, MAXNAMLEN); else { /* 2nd & subsequent matches */ register Char *x, *ent; register int len = 0; x = extended_name; for (ent = entry; *x && *x == *ent++; x++, len++) continue; *x = '\0'; /* Shorten at 1st Char diff */ if (len == name_length) /* Ambiguous to prefix? */ return (-1); /* So stop now and save time */ } return (0);}/* * Return true if check matches initial Chars in template. * This differs from PWB imatch in that if check is null * it matches anything. */static intis_prefix(check, template) register Char *check, *template;{ do if (*check == 0) return (TRUE); while (*check++ == *template++); return (FALSE);}/* * Return true if the Chars in template appear at the * end of check, I.e., are it's suffix. */static intis_suffix(check, template) Char *check, *template;{ register Char *c, *t; for (c = check; *c++;) continue; for (t = template; *t++;) continue; for (;;) { if (t == template) return 1; if (c == check || *--t != *--c) return 0; }}inttenex(inputline, inputline_size) Char *inputline; int inputline_size;{ register int numitems, num_read; char tinputline[BUFSIZ]; setup_tty(ON); while ((num_read = read(SHIN, tinputline, BUFSIZ)) > 0) { int i; static Char delims[] = {' ', '\'', '"', '\t', ';', '&', '<', '>', '(', ')', '|', '^', '%', '\0'}; register Char *str_end, *word_start, last_Char, should_retype; register int space_left; COMMAND command; for (i = 0; i < num_read; i++) inputline[i] = (unsigned char) tinputline[i]; last_Char = inputline[num_read - 1] & ASCII; if (last_Char == '\n' || num_read == inputline_size) break; command = (last_Char == ESC) ? RECOGNIZE : LIST; if (command == LIST) (void) fputc('\n', cshout); str_end = &inputline[num_read]; if (last_Char == ESC) --str_end; /* wipeout trailing cmd Char */ *str_end = '\0'; /* * Find LAST occurence of a delimiter in the inputline. The word start * is one Character past it. */ for (word_start = str_end; word_start > inputline; --word_start) if (Strchr(delims, word_start[-1])) break; space_left = inputline_size - (word_start - inputline) - 1; numitems = tsearch(word_start, command, space_left); if (command == RECOGNIZE) { /* print from str_end on */ print_recognized_stuff(str_end); if (numitems != 1) /* Beep = No match/ambiguous */ beep(); } /* * Tabs in the input line cause trouble after a pushback. tty driver * won't backspace over them because column positions are now * incorrect. This is solved by retyping over current line. */ should_retype = FALSE; if (Strchr(inputline, '\t')) { /* tab Char in input line? */ back_to_col_1(); should_retype = TRUE; } if (command == LIST) /* Always retype after a LIST */ should_retype = TRUE; if (should_retype) printprompt(); pushback(inputline); if (should_retype) retype(); } setup_tty(OFF); return (num_read);}static intignored(entry) register Char *entry;{ struct varent *vp; register Char **cp; if ((vp = adrof(STRfignore)) == NULL || (cp = vp->vec) == NULL) return (FALSE); for (; *cp != NULL; cp++) if (is_suffix(entry, *cp)) return (TRUE); return (FALSE);}#endif /* FILEC */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -