summaryrefslogtreecommitdiffstats
path: root/bin/csh/file.c
diff options
context:
space:
mode:
authorobrien <obrien@FreeBSD.org>2000-04-18 07:31:36 +0000
committerobrien <obrien@FreeBSD.org>2000-04-18 07:31:36 +0000
commit6d573144b323d585e9999b045a7cdfb0f3f8d491 (patch)
tree6f3237f7547194d4258d65f1e1ecc234ebd3692f /bin/csh/file.c
parenta0eba154d3e138792cbfc004135e7ab7310e0e6a (diff)
downloadFreeBSD-src-6d573144b323d585e9999b045a7cdfb0f3f8d491.zip
FreeBSD-src-6d573144b323d585e9999b045a7cdfb0f3f8d491.tar.gz
Upgrade csh.
Diffstat (limited to 'bin/csh/file.c')
-rw-r--r--bin/csh/file.c685
1 files changed, 0 insertions, 685 deletions
diff --git a/bin/csh/file.c b/bin/csh/file.c
deleted file mode 100644
index a1f5ab2..0000000
--- a/bin/csh/file.c
+++ /dev/null
@@ -1,685 +0,0 @@
-/*-
- * 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 lint
-#if 0
-static char sccsid[] = "@(#)file.c 8.2 (Berkeley) 3/19/94";
-#else
-static const char rcsid[] =
- "$FreeBSD$";
-#endif
-#endif /* not lint */
-
-#ifdef FILEC
-
-#include <sys/param.h>
-#include <sys/stat.h>
-#include <termios.h>
-#include <dirent.h>
-#include <pwd.h>
-#include <stdlib.h>
-#include <unistd.h>
-#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 void
-setup_tty(on)
- int on;
-{
- struct termios tchars;
-
- (void) tcgetattr(SHIN, &tchars);
-
- if (on) {
- tchars.c_cc[VEOL] = ESC;
- if (tchars.c_lflag & ICANON)
- on = TCSADRAIN;
- else {
- on = TCSAFLUSH;
- tchars.c_lflag |= ICANON;
- }
- }
- else {
- tchars.c_cc[VEOL] = _POSIX_VDISABLE;
- on = TCSADRAIN;
- }
-
- (void) tcsetattr(SHIN, on, &tchars);
-}
-
-/*
- * Move back to beginning of current line
- */
-static void
-back_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 void
-pushback(string)
- Char *string;
-{
- 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 void
-catn(des, src, count)
- Char *des, *src;
- 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 void
-copyn(des, src, count)
- Char *des, *src;
- int count;
-{
- while (--count >= 0)
- if ((*des++ = *src++) == 0)
- return;
- *des = '\0';
-}
-
-static Char
-filetype(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 void
-print_by_column(dir, items, count)
- Char *dir, *items[];
- int count;
-{
- 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) {
- 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;
-{
- Char *o, *p;
- 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 void
-retype()
-{
- struct termios tty;
-
- (void) tcgetattr(SHOUT, &tty);
- tty.c_lflag |= PENDIN;
- (void) tcsetattr(SHOUT, TCSANOW, &tty);
-}
-
-static void
-beep()
-{
- if (adrof(STRnobeep) == 0)
- (void) write(SHOUT, "\007", 1);
-}
-
-/*
- * Erase that silly ^[ and
- * print the recognized part of the string
- */
-static void
-print_recognized_stuff(recognized_part)
- Char *recognized_part;
-{
- /* An optimized erasing of that silly ^[ */
- (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 void
-extract_dir_and_name(path, dir, name)
- Char *path, *dir, *name;
-{
- 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;
-{
- struct passwd *pw;
- 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 void
-free_items(items)
- Char **items;
-{
- 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 int
-tsearch(word, command, max_word_length)
- Char *word;
- COMMAND command;
- int max_word_length;
-{
- static Char **items = NULL;
- DIR *dir_fd;
- int numitems = 0, ignoring = TRUE, nignored = 0;
- int 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) {
- 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)
- 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 int
-recognize(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 */
- Char *x, *ent;
- 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 int
-is_prefix(check, template)
- 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 int
-is_suffix(check, template)
- Char *check, *template;
-{
- 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;
- }
-}
-
-int
-tenex(inputline, inputline_size)
- Char *inputline;
- int inputline_size;
-{
- 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'};
- Char *str_end, *word_start, last_Char, should_retype;
- 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 int
-ignored(entry)
- Char *entry;
-{
- struct varent *vp;
- 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 */
OpenPOWER on IntegriCloud