📄 file.c
字号:
/*- * Copyright (c) 1980, 1991, 1993 * The Regents of the University of California. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. All advertising materials mentioning features or use of this software * must display the following acknowledgement: * This product includes software developed by the University of * California, Berkeley and its contributors. * 4. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. */#ifndef lintstatic char sccsid[] = "@(#)file.c 8.2 (Berkeley) 3/19/94";#endif /* not lint */#ifdef FILEC#include <sys/param.h>#include <sys/ioctl.h>#include <sys/stat.h>#include <termios.h>#include <dirent.h>#include <pwd.h>#include <stdlib.h>#include <unistd.h>#ifndef SHORT_STRINGS#include <string.h>#endif /* SHORT_STRINGS */#if __STDC__# include <stdarg.h>#else# include <varargs.h>#endif#include "csh.h"#include "extern.h"/* * Tenex style file name recognition, .. and more. * History: * Author: Ken Greer, Sept. 1975, CMU. * Finally got around to adding to the Cshell., Ken Greer, Dec. 1981. */#define ON 1#define OFF 0#ifndef TRUE#define TRUE 1#endif#ifndef FALSE#define FALSE 0#endif#define ESC '\033'typedef enum { LIST, RECOGNIZE} COMMAND;static void setup_tty __P((int));static void back_to_col_1 __P((void));static void pushback __P((Char *));static void catn __P((Char *, Char *, int));static void copyn __P((Char *, Char *, int));static Char filetype __P((Char *, Char *));static void print_by_column __P((Char *, Char *[], int));static Char *tilde __P((Char *, Char *));static void retype __P((void));static void beep __P((void));static void print_recognized_stuff __P((Char *));static void extract_dir_and_name __P((Char *, Char *, Char *));static Char *getentry __P((DIR *, int));static void free_items __P((Char **));static int tsearch __P((Char *, COMMAND, int));static int recognize __P((Char *, Char *, int, int));static int is_prefix __P((Char *, Char *));static int is_suffix __P((Char *, Char *));static int ignored __P((Char *));/* * Put this here so the binary can be patched with adb to enable file * completion by default. Filec controls completion, nobeep controls * ringing the terminal bell on incomplete expansions. */bool filec = 0;static voidsetup_tty(on) int on;{ static struct termios tchars; (void) tcgetattr(SHIN, &tchars); if (on) { tchars.c_cc[VEOL] = ESC; if (tchars.c_lflag & ICANON) on = TCSANOW; else { on = TCSAFLUSH; tchars.c_lflag |= ICANON; } } else { tchars.c_cc[VEOL] = _POSIX_VDISABLE; on = TCSANOW; } (void) tcsetattr(SHIN, TCSANOW, &tchars);}/* * Move back to beginning of current line */static voidback_to_col_1(){ struct termios tty, tty_normal; int omask; omask = sigblock(sigmask(SIGINT)); (void) tcgetattr(SHOUT, &tty); tty_normal = tty; tty.c_iflag &= ~INLCR; tty.c_oflag &= ~ONLCR; (void) tcsetattr(SHOUT, TCSANOW, &tty); (void) write(SHOUT, "\r", 1); (void) tcsetattr(SHOUT, TCSANOW, &tty_normal); (void) sigsetmask(omask);}/* * Push string contents back into tty queue */static voidpushback(string) Char *string;{ register Char *p; struct termios tty, tty_normal; int omask; char c; omask = sigblock(sigmask(SIGINT)); (void) tcgetattr(SHOUT, &tty); tty_normal = tty; tty.c_lflag &= ~(ECHOKE | ECHO | ECHOE | ECHOK | ECHONL | ECHOPRT | ECHOCTL); (void) tcsetattr(SHOUT, TCSANOW, &tty); for (p = string; (c = *p) != '\0'; p++) (void) ioctl(SHOUT, TIOCSTI, (ioctl_t) & c); (void) tcsetattr(SHOUT, TCSANOW, &tty_normal); (void) sigsetmask(omask);}/* * Concatenate src onto tail of des. * Des is a string whose maximum length is count. * Always null terminate. */static voidcatn(des, src, count) register Char *des, *src; register int count;{ while (--count >= 0 && *des) des++; while (--count >= 0) if ((*des++ = *src++) == 0) return; *des = '\0';}/* * Like strncpy but always leave room for trailing \0 * and always null terminate. */static voidcopyn(des, src, count) register Char *des, *src; register int count;{ while (--count >= 0) if ((*des++ = *src++) == 0) return; *des = '\0';}static Charfiletype(dir, file) Char *dir, *file;{ Char path[MAXPATHLEN]; struct stat statb; catn(Strcpy(path, dir), file, sizeof(path) / sizeof(Char)); if (lstat(short2str(path), &statb) == 0) { switch (statb.st_mode & S_IFMT) { case S_IFDIR: return ('/'); case S_IFLNK: if (stat(short2str(path), &statb) == 0 && /* follow it out */ S_ISDIR(statb.st_mode)) return ('>'); else return ('@'); case S_IFSOCK: return ('='); default: if (statb.st_mode & 0111) return ('*'); } } return (' ');}static struct winsize win;/* * Print sorted down columns */static voidprint_by_column(dir, items, count) Char *dir, *items[]; int count;{ register int i, rows, r, c, maxwidth = 0, columns; if (ioctl(SHOUT, TIOCGWINSZ, (ioctl_t) & win) < 0 || win.ws_col == 0) win.ws_col = 80; for (i = 0; i < count; i++) maxwidth = maxwidth > (r = Strlen(items[i])) ? maxwidth : r; maxwidth += 2; /* for the file tag and space */ columns = win.ws_col / maxwidth; if (columns == 0) columns = 1; rows = (count + (columns - 1)) / columns; for (r = 0; r < rows; r++) { for (c = 0; c < columns; c++) { i = c * rows + r; if (i < count) { register int w; (void) fprintf(cshout, "%s", vis_str(items[i])); (void) fputc(dir ? filetype(dir, items[i]) : ' ', cshout); if (c < columns - 1) { /* last column? */ w = Strlen(items[i]) + 1; for (; w < maxwidth; w++) (void) fputc(' ', cshout); } } } (void) fputc('\r', cshout); (void) fputc('\n', cshout); }}/* * Expand file name with possible tilde usage * ~person/mumble * expands to * home_directory_of_person/mumble */static Char *tilde(new, old) Char *new, *old;{ register Char *o, *p; register struct passwd *pw; static Char person[40]; if (old[0] != '~') return (Strcpy(new, old)); for (p = person, o = &old[1]; *o && *o != '/'; *p++ = *o++) continue; *p = '\0'; if (person[0] == '\0') (void) Strcpy(new, value(STRhome)); else { pw = getpwnam(short2str(person)); if (pw == NULL) return (NULL); (void) Strcpy(new, str2short(pw->pw_dir)); } (void) Strcat(new, o); return (new);}/* * Cause pending line to be printed */static voidretype(){ struct termios tty; (void) tcgetattr(SHOUT, &tty); tty.c_lflag |= PENDIN; (void) tcsetattr(SHOUT, TCSANOW, &tty);}static voidbeep(){ if (adrof(STRnobeep) == 0) (void) write(SHOUT, "\007", 1);}/* * Erase that silly ^[ and * print the recognized part of the string */static voidprint_recognized_stuff(recognized_part) Char *recognized_part;{ /* An optimized erasing of that silly ^[ */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -