home *** CD-ROM | disk | FTP | other *** search
- /* -- Just what the hell am I ??? --- */
- /* (If this is made from MAKEFILE, BSD or USG should be set.) */
-
- #include <stdio.h>
-
- #include "system.h"
-
- /* -- Miscellaneous include files -- */
-
- #include <sys/param.h> /* NCARGS, and others */
- #ifndef M_XENIX
- # include <sys/types.h> /* data types for various files */
- #endif
- #include <sys/stat.h> /* stat data structure for getdir(), statout() */
- #include <sys/dir.h> /* dir data structure for getdir() */
- #include <pwd.h> /* passwd data structure for u_name() */
- #include <grp.h> /* group data structure for g_name() */
- #ifdef BSD
- # include <sys/time.h> /* time data structure for printime() */
- #else
- # include <time.h> /* time data structure for printime() */
- #endif
- #include <signal.h>
-
- #ifndef MAXNAMLEN
- # ifdef BSD
- # define MAXNAMLEN 256
- # else
- # define MAXNAMLEN DIRSIZ
- # endif
- #endif
-
- /* -- make information --
- BUILD
- browse: browse.c
- cc browse.c -O -o browse -ltermlib
- END
- */
-
- /* -- Miscellaneous defines -- */
- #define FALSE 0
- #define TRUE 1
-
- #define MAXENTS 1024
- #define MAXID 16
- #define MAXLINE 81
- #define NCOL 64
- #define MAXNAME 14
- #define FILENAME 256
-
- /* -- Extended directory entry format -- */
- struct entry {
- char *e_name;
- int e_flags;
- #define FTAGGED (1<<0)
- #define FPERMANENT (1<<1)
- struct stat e_stat; /* file status field */
- char e_uname[9]; /* user name */
- char e_gname[9]; /* user's group name */
- }
- *xentries[MAXENTS], **entries=xentries;
- int nentries;
-
- /* -- Look-up cache for user names -- */
- struct idtab {
- int id_id; /* user (or group) id */
- char id_name[9]; /* name[8] + filler */
- }
- u_list[MAXID], /* Matched user id's. */
- g_list[MAXID]; /* ditto group */
- int u_ptr=0, g_ptr=0; /* current entries */
-
- /* -- Global variables -- */
- int ccol=NCOL; /* Width of used display, current column */
- int quickmode; /* short display mode (files only) */
-
- int top, curr; /* Positions of screen in directory */
- #define bottom ((top+nlines>nentries)?nentries:(top+nlines))
- char *dot; /* name of current directory */
- int nlines; /* number of lines displayed on page */
- char display_up; /* Does the display exist? */
- int todump=1; /* Do we want to dump data? */
- int ended; /* Have we quite finished? */
- int intrup; /* Have we been interrupted? */
- char *HOME; /* Where did I start from? */
- char *SHELL; /* How do I run programs? */
-
- /* -- types of functions !!! */
- char *getenv();
- char *malloc();
-
- #define NEW(t) (t *)malloc(sizeof (t))
- #define NIL(t) ((t) 0)
-
- /* -- Code starts here: dummy main -- */
- main(ac, av)
- int ac;
- char **av;
- {
- if(ac>1) chdir(av[1]);
-
- HOME=getenv("HOME");
- SHELL=getenv("SHELL");
-
- intrup=0;
- if(tcl_init()) {
- tinit(getenv("TERM"));
- clear_all();
- browse();
- tend();
- tcl_end();
- }
- exit(0);
- }
-
- clear_all()
- {
- int i;
-
- for(i = 0; i < MAXENTS; i++)
- entries[i] = 0;
- }
-
- char *clone(name)
- char *name;
- {
- char *hold;
-
- hold = (char *)malloc(strlen(name)+1);
-
- if(hold==0)
- return 0;
- strcpy(hold, name);
- return hold;
- }
-
- newname(e, name)
- struct entry *e;
- char *name;
- {
- if(e->e_name)
- free(e->e_name);
- e->e_name = clone(name);
- }
-
- #if BSD
- readent(dp, buffer)
- DIR *dp;
- char *buffer;
- {
- struct direct *ptr;
-
- do {
- ptr = readdir(dp);
- if(!ptr) return 0;
- } while(ptr->d_ino == 0);
-
- strcpy(buffer, ptr->d_name);
- return 1;
- }
- #else
- #define opendir(n) fopen(n, "r")
- #define DIR FILE
- readent(dp, buffer)
- DIR *dp;
- char *buffer;
- {
- struct direct db;
- while(fread(&db, sizeof(struct direct), 1, dp)) {
- if(db.d_ino) {
- strncpy(buffer, db.d_name, MAXNAMLEN);
- buffer[MAXNAMLEN] = 0;
- return 1;
- }
- }
- return 0;
- }
- #define closedir fclose
- #endif
-
- getdir()
- {
- char *u_name(), *g_name();
- DIR *dp;
- static char buffer[MAXNAMLEN+1];
- int i, p;
-
- if(!(dp = opendir("."))) {
- save_errno(".");
- return FALSE;
- }
-
- p = 0;
- for(i = 0; i < nentries; i++) {
- if(entries[i]->e_flags & FPERMANENT) {
- if(p != i) {
- struct entry *hold;
- hold = entries[p];
- entries[p] = entries[i];
- entries[i] = hold;
- }
- p++;
- }
- }
-
- for(nentries = p; !intrup && nentries < MAXENTS; nentries++) {
- if(!entries[nentries]) {
- entries[nentries] = NEW(struct entry);
- if(!entries[nentries])
- break;
- entries[nentries]->e_name = NIL(char *);
- }
-
- if(!readent(dp, buffer))
- break;
-
- if(stat(buffer, &entries[nentries]->e_stat)==-1) {
- closedir(dp);
- save_errno(buffer);
- return FALSE;
- }
-
- newname(entries[nentries], buffer);
-
- entries[nentries]->e_flags = 0;
-
- strcpy(entries[nentries]->e_uname,
- u_name(entries[nentries]->e_stat.st_uid));
-
- strcpy(entries[nentries]->e_gname,
- g_name(entries[nentries]->e_stat.st_gid));
- }
-
- closedir(dp);
-
- if(intrup)
- return FALSE;
-
- if(nentries>=MAXENTS || entries[nentries]==NIL(struct entry *)) {
- save_errmsg(".: Directory too large");
- return FALSE;
- }
-
- sortdir();
-
- if(intrup) {
- save_errmsg("Interrupted");
- return FALSE;
- }
- return TRUE;
- }
-
- at_current()
- {
- at_file(curr);
- }
-
- at_file(file)
- int file;
- {
- if(display_up) {
- if(file < top || file >= top+nlines)
- return 0;
- at(0, curr-top+2);
- } else {
- if(file != curr)
- return 0;
- cmdline();
- }
- return 1;
- }
-
- disp_flags(flags)
- {
- outc((flags&FTAGGED)?'+':((flags&FPERMANENT)?'!':' '));
- }
-
- show_flags(ent)
- {
- if(!display_up) return;
- if(ent < top || ent >= top+nlines) return;
- at(quickmode?0:(ccol-1), ent-top+2);
- disp_flags(entries[ent]->e_flags);
- }
-
- tag(ent, mode, bit)
- {
- switch(bit) {
- case 'P': bit = FPERMANENT; break;
- case 'T': bit = FTAGGED; break;
- }
- switch(mode) {
- case -1: entries[ent]->e_flags &= ~bit; break;
- case 0: entries[ent]->e_flags ^= bit; break;
- case 1: entries[ent]->e_flags |= bit; break;
- }
- show_flags(ent);
- }
-
- tagged(ent)
- {
- return (entries[ent]->e_flags & FTAGGED) ? 1 : 0;
- }
-
- delete_from_display(file)
- int file;
- {
- if(!display_up) return;
-
- if(file>=top+nlines) return;
-
- if(file < top) file = top;
-
- scroll(2+file-top, 2+nlines, 1);
- at(0, 2+nlines-1);
- if(top+nlines >= nentries)
- outc('~');
- else
- dump(bottom, bottom+1);
- }
-
- delete_entry(file)
- int file;
- {
- struct entry *hold;
- int i;
-
- delete_from_display(file);
-
- hold = entries[file];
- for(i=file; i<nentries-1; i++)
- entries[i]=entries[i+1];
- entries[nentries-1]=hold;
- nentries--;
-
- if(file < curr || curr >= nentries) {
- curr--;
- if(top >= nentries) {
- top--;
- display_up = 0;
- todump = 1;
- }
- }
- }
-
- ins_at(ent, i)
- struct entry *ent;
- int i;
- {
- struct entry *hold;
- int j;
-
- /* Allocate slot at end */
- if(!entries[nentries]) {
- entries[nentries] = NEW(struct entry);
- if(!entries[nentries]) {
- save_errno(ent->e_name);
- return 0;
- }
- entries[nentries]->e_name = NIL(char *);
- } else if(entries[nentries]->e_name) {
- free(entries[nentries]->e_name);
- entries[nentries]->e_name = NIL(char *);
- }
-
- /* Copy data into slot */
- *entries[nentries] = *ent;
- entries[nentries]->e_name = clone(ent->e_name);
- if(!entries[nentries]->e_name) {
- save_errno(ent->e_name);
- return 0;
- }
-
- if(i != nentries) {
- /* Rotate slot to middle */
- hold = entries[nentries];
- for(j = nentries; j > i; j--)
- entries[j] = entries[j-1];
- entries[i] = hold;
- }
- nentries++;
-
- if(display_up) {
- if(i < top)
- i = top;
- if(i >= bottom)
- return 1;
- scroll(2+i-top, 2+nlines, -1);
- at(0, 2+i-top);
- dump(i, i+1);
- }
- return 1;
- }
-
- ins_entry(ent)
- struct entry *ent;
- {
- int i;
-
- if(nentries >= MAXENTS) {
- save_errmsg("Too many files");
- return 0;
- }
-
- for(i = 0; i < nentries; i++)
- if(entcmp(&ent, &entries[i]) < 0)
- break;
-
- return ins_at(ent, i);
- }
-
- domove(ent, new_name)
- int ent;
- char *new_name;
- {
- struct entry hold;
- hold = *entries[ent];
-
- if(link(entries[ent]->e_name, new_name)!=0) {
- save_errno(entries[ent]->e_name);
- return 0;
- }
- if(unlink(entries[ent]->e_name)!=0) {
- save_errno(entries[ent]->e_name);
- return 0;
- }
-
- hold.e_name = new_name;
- hold.e_flags &= ~FTAGGED;
-
- delete_entry(ent);
- return ins_entry(&hold);
- }
-
- addfile(name)
- char *name;
- {
- struct entry hold;
-
- if(stat(name, &hold.e_stat)==-1) {
- save_errno(name);
- return FALSE;
- }
-
- hold.e_name = name;
-
- hold.e_flags = 0;
-
- strcpy(hold.e_uname, u_name(hold.e_stat.st_uid));
-
- strcpy(hold.e_gname, g_name(hold.e_stat.st_gid));
-
- return ins_entry(&hold);
- }
-
- pname(name, mode)
- char *name;
- int mode;
- {
- int i;
- char *slash, *rindex();
- int max=quickmode?MAXLINE:(MAXNAME+1);
-
- if((mode&S_IFMT)==S_IFDIR)
- max--;
- else if((mode&S_IFMT)==S_IFREG && (mode&0111))
- max--;
- else if((mode&S_IFMT)!=S_IFREG)
- max--;
-
- if(!quickmode && (slash=rindex(name, '/'))) {
- name=slash;
- outc('<');
- max--;
- }
- for(i=0; i<max && *name; name++)
- i += ctlout(*name);
- standend();
- if(i==max && *name) {
- outc('\b');
- outc('>');
- }
- if((mode&S_IFMT)==S_IFDIR) {
- outc('/');
- }
- else if((mode&S_IFMT)==S_IFREG && (mode&0111)) {
- outc('*');
- }
- else if((mode&S_IFMT)!=S_IFREG) {
- outc('?');
- }
- }
-
- sortdir()
- {
- int entcmp();
- qsort(entries, nentries, sizeof(struct entry *), entcmp);
- }
-
- entcmp(e1, e2)
- struct entry **e1, **e2;
- {
- if((*e1)->e_name[0] == '/') {
- if((*e2)->e_name[0] != '/')
- return 1;
- } else if((*e2)->e_name[0] == '/')
- return -1;
-
- return strcmp((*e1)->e_name, (*e2)->e_name);
- }
-
- dump(start, end)
- int start;
- int end;
- {
- int i;
- int lo = (start<nentries)?start:nentries;
- int hi = (end<nentries)?end:nentries;
-
- for(i=lo; i<hi; i++) {
- statout(entries[i]->e_name,
- &entries[i]->e_stat,
- entries[i]->e_uname,
- entries[i]->e_gname,
- entries[i]->e_flags);
- nl();
- }
- return TRUE;
- }
-
- statout(name, sbuf, user, group, flags)
- char *name;
- struct stat *sbuf;
- char *user, *group;
- int flags;
- {
- int mode = sbuf->st_mode;
-
- if(!quickmode) {
- printf("%5u ", sbuf->st_ino);
-
- if((mode&S_IFMT)==S_IFCHR) outc('c');
- else if((mode&S_IFMT)==S_IFBLK) outc('b');
- else if((mode&S_IFMT)==S_IFDIR) outc('d');
- else if((mode&S_IFMT)==S_IFREG) outc('-');
- else outc('?');
- triad((mode>>6)&7, mode&S_ISUID, 's');
- triad((mode>>3)&7, mode&S_ISGID, 's');
- triad(mode&7, mode&S_ISVTX, 't');
- outc(' ');
-
- printf("%3u ", sbuf->st_nlink);
- printf("%-8s ", user);
- printf("%-8s ", group);
-
- if((mode&S_IFMT)==S_IFREG || (mode&S_IFMT)==S_IFDIR)
- printf("%7ld ", sbuf->st_size);
- else
- printf("%3d,%3d ",
- major(sbuf->st_rdev),
- minor(sbuf->st_rdev));
-
- outc(' ');
- printime(&sbuf->st_mtime);
- }
-
- disp_flags(flags);
- pname(name, sbuf->st_mode);
- }
-
- char *
- u_name(uid)
- int uid;
- {
- int i;
- struct passwd *pwptr, *getpwuid();
-
- for(i=0; i<u_ptr; i++)
- if(u_list[i].id_id==uid)
- return u_list[i].id_name;
-
- if(u_ptr>=MAXID) /* cache full */
- u_ptr = 0; /* simplistic algorithm, wrap to beginning */
- /* with MAXID >> # common id's it's good enough */
-
- u_list[u_ptr].id_id=uid;
-
- if(pwptr=getpwuid(uid)) { /* Copy name */
- for(i=0; pwptr->pw_name[i]>' '; i++)
- u_list[u_ptr].id_name[i]=pwptr->pw_name[i];
- u_list[u_ptr].id_name[i]=0;
- }
- else /* Default to UID */
- sprintf(u_list[u_ptr].id_name, "%d", uid);
-
- return u_list[u_ptr++].id_name;
- }
-
- char *
- g_name(gid)
- int gid;
- {
- int i;
- struct group *grptr, *getgrgid();
-
- for(i=0; i<g_ptr; i++)
- if(g_list[i].id_id==gid)
- return g_list[i].id_name;
-
- if(g_ptr>=MAXID) /* cache full */
- g_ptr = 0; /* simplistic algorithm, wrap to beginning */
- /* with MAXID >> # common id's it's good enough */
-
- g_list[g_ptr].id_id=gid;
-
- if(grptr=getgrgid(gid)) { /* Copy name */
- for(i=0; grptr->gr_name[i]>' '; i++)
- g_list[g_ptr].id_name[i]=grptr->gr_name[i];
- g_list[g_ptr].id_name[i]=0;
- }
- else /* Default to UID */
- sprintf(g_list[g_ptr].id_name, "%d", gid);
-
- return g_list[g_ptr++].id_name;
- }
-
- printime(clock)
- long *clock;
- {
- struct tm *tmbuf, *localtime();
- static char *months[12]= {
- "Jan","Feb","Mar","Apr","May","Jun",
- "Jul","Aug","Sep","Oct","Nov","Dec"
- };
-
- tmbuf=localtime(clock);
- printf("%2d %3s %02d %2d:%02d",
- tmbuf->tm_mday,
- months[tmbuf->tm_mon],
- tmbuf->tm_year,
- tmbuf->tm_hour,
- tmbuf->tm_min);
- }
-
- header()
- {
- if(quickmode)
- printf(" File Name");
- else
- printf(
- "Inode Long mode LNX User Group Size/Dev Modify Time File name"
- );
- nl();
- }
-
- triad(bits, special, code)
- int bits, special;
- char code;
- {
- if(bits&4) outc('r');
- else outc('-');
-
- if(bits&2) outc('w');
- else outc('-');
-
- if(special) outc(code);
- else if(bits&1) outc('x');
- else outc('-');
- }
-
- char *
- pwd()
- #ifdef GETCWD
- {
- static char mydir[FILENAME+1] = "";
- char *getcwd();
-
- return getcwd(mydir, FILENAME);
- }
- #else
- {
- static char buffer[FILENAME+1];
-
- strcpy(buffer, "exec pwd");
- if(tcl_call(buffer, sizeof buffer)) {
- int len = strlen(buffer);
- while(len > 0 && buffer[len-1] <= ' ')
- len--;
- buffer[len] = 0;
- return buffer;
- }
- save_errmsg(buffer);
- return 0;
- }
- #endif
-
- browse()
- {
- int c;
-
- newdir();
- redraw();
- ended=0;
-
- do {
- intrup=0; /* clear interrupt */
- here_i_am();
- fflush(stdout);
- c = getch();
- cmd(c);
- }
- while(!ended);
- }
-
- clearin()
- {
- fseek(stdin, 0L, 1); /* stay here messily */
- }
-
- char *name_of(c)
- int c;
- {
- static char *p, b[80];
- int ctrl = 0;
-
- p = b;
- if(c & 0x80) {
- c &= 0x7F;
- strcpy(b, "meta_");
- p += 5;
- }
-
- switch(c) {
- case '\033':
- strcpy(p, "escape");
- return b;
- case '\034':
- strcpy(p, "ctrl_backslash");
- return b;
- case '\035':
- strcpy(p, "ctrl_close_bracket");
- return b;
- }
-
- if(c < ' ') {
- c += '@';
- ctrl = 1;
- }
-
- switch(c) {
- case ' ': strcpy(p, "space"); break;
- case '$': strcpy(p, "dollar_sign"); break;
- case '\'': strcpy(p, "quote"); break;
- case '"': strcpy(p, "double_quote"); break;
- case ';': strcpy(p, "semicolon"); break;
- case '{': strcpy(p, "open_brace"); break;
- case '}': strcpy(p, "close_brace"); break;
- case '\177': strcpy(p, "delete"); break;
- case '\\': strcpy(p, "backslash"); break;
- case '[': strcpy(p, "open_bracket"); break;
- case ']': strcpy(p, "close_bracket"); break;
- default:
- if(ctrl)
- sprintf(p, "'^%c'", c);
- else
- sprintf(p, "'%c'", c);
- break;
- }
- return b;
- }
-
- cmd(c)
- int c;
- {
- char buffer[80];
-
- if(intrup) {
- cmdline();
- outs("Interrupt");
- return;
- }
-
- sprintf(buffer, "key_%s\n", name_of(c));
- if(!tcl_call(buffer, 80)) {
- cmdline();
- ctlouts(buffer);
- if(!display_up) outc('\n');
- bell();
- }
- }
-
- char *macro(c)
- int c;
- {
- static char buffer[80];
-
- sprintf(buffer, "macro_%s\n", name_of(c));
- if(tcl_call(buffer, 80))
- return buffer;
- else
- return 0;
- }
-
- newdir()
- {
- int result = 1;
-
- if(display_up)
- at(0,0);
- fflush(stdout);
- dot=pwd();
-
- if(!getdir())
- result = 0;
-
- curr=0;
- top=0;
- topline();
- if(display_up)
- todump=TRUE;
-
- return result;
- }
-
- reload()
- {
- if(getdir()) {
- curr=(curr>=bottom)?bottom-1:curr;
- if(display_up) {
- topline();
- todump=TRUE;
- }
- return 1;
- }
- return 0;
- }
-
- topline()
- {
- if(display_up)
- at(0,0);
- printf("%s: %d files", dot, nentries);
- nl();
- }
-
- set_quickmode(mode)
- int mode;
- {
- if(quickmode != mode) {
- quickmode = mode;
- if(display_up) {
- at(0,1);
- header();
- todump = 1;
- }
- }
- }
-
- redraw()
- {
- clear_screen();
- display_up=0;
- topline();
- at(0,1);
- header();
- todump=1;
- display_up=1;
- }
-
- dumpdata()
- {
- at(0,2);
- dump(top,bottom);
- if(top+nlines>nentries) {
- int i;
- at(0, bottom-top+2);
- for(i=bottom-top; i<nlines; i++) {
- outc('~');
- nl();
- }
- }
- }
-
- here_i_am()
- {
- if(todump)
- display_up = 1;
- if(!display_up) {
- cmdline();
- statout(entries[curr]->e_name,
- &entries[curr]->e_stat,
- entries[curr]->e_uname,
- entries[curr]->e_gname,
- entries[curr]->e_flags);
- at(quickmode?1:ccol, nlines+2);
- fflush(stdout);
- } else if(todump) {
- if(!(curr-top > 0 && curr-top < nlines)) {
- top = curr-nlines/2;
- if(top<0) top=0;
- }
- dumpdata();
- at(quickmode?1:ccol, curr-top+2);
- todump=0;
- } else {
- int lines_to_scroll = curr-top;
- if(lines_to_scroll > 0)
- if((lines_to_scroll -= nlines-1) < 0)
- lines_to_scroll = 0;
- if(lines_to_scroll < 1-nlines) {
- top=curr;
- at(0,2);
- dump(top, bottom);
- } else if(lines_to_scroll > nlines-1) {
- top=curr-nlines+1;
- at(0,2);
- dump(top, bottom);
- } else if(lines_to_scroll) {
- scroll(2, nlines+2, lines_to_scroll);
- top += lines_to_scroll;
- if(lines_to_scroll < 0) {
- at(0, 2);
- dump(top, top-lines_to_scroll);
- } else {
- at(0, 2+nlines-lines_to_scroll);
- dump(bottom-lines_to_scroll, bottom);
- }
- }
- at(quickmode?1:ccol, curr-top+2);
- }
- }
-
- bell()
- {
- outc(7);
- }
-
- system(command)
- char *command;
- {
- int status;
- int pid;
- SIGNAL (*sigint)(), (*sigquit)();
- #ifdef BSD
- SIGNAL (*sigtstp)();
- #endif
-
- sigint=signal(SIGINT, SIG_IGN);
- sigquit=signal(SIGQUIT, SIG_IGN);
- #ifdef BSD
- sigtstp = signal(SIGTSTP, SIG_IGN);
- #endif
- end_screenmode();
- cooktty();
- fflush(stdout);
- pid = fork();
- if(pid == 0) {
- signal(SIGINT, SIG_DFL);
- signal(SIGQUIT, SIG_DFL);
- #ifdef BSD
- signal(SIGTSTP, SIG_DFL);
- #endif
- fflush(stdout);
- execl(SHELL, SHELL, "-c", command, (char *)0);
- execl("/bin/sh", "sh", "-c", command, (char *)0);
- perror("/bin/sh");
- exit(-77);
- }
- if(pid==-1) {
- save_errno("browse");
- status = -1;
- } else
- wait(&status);
- signal(SIGINT, sigint);
- signal(SIGQUIT, sigquit);
- #ifdef BSD
- signal(SIGTSTP, sigtstp);
- #endif
- rawtty();
-
- if(status & 0xFF)
- return -(status&0xFF);
- else
- return (status&0xFF00)>>8;
- }
-
- addstring(ptr, buf, ip)
- char *ptr, *buf;
- int *ip;
- {
- while(*ptr)
- ctlout(buf[(*ip)++] = *ptr++);
- standend();
- }
-
- char
- inps(buf, text, termin)
- char *buf;
- char *text;
- char termin;
- {
- int i = 0;
- char c, *txp;
- char *s;
-
- txp=text?text:"!";
-
- while(!intrup &&
- (fflush(stdout), c=getch()) != '\033' &&
- c != '\n' &&
- c != termin)
- switch(c) {
- case '\b':
- case '\177':
- if(i>0) {
- printf("\b \b");
- i--;
- }
- else
- bell();
- break;
- case 'U'-'@':
- txp=text?text:"!";
- case 'X'-'@':
- if(i>0)
- while(i>0) {
- printf("\b \b");
- i--;
- }
- else
- bell();
- break;
- case 'K'-'@':
- if(*txp)
- ctloutc(buf[i++] = *txp++);
- break;
- case '\\':
- outc(c);
- fflush(stdout);
- c=getch();
- if( c=='\\' || c=='\b' || c=='\177' ||
- c=='K'-'@' || c=='U'-'@' || c=='X'-'@' ||
- c==termin || c=='\033' || c=='\n') {
- outc('\b');
- ctloutc(buf[i++]=c);
- break;
- }
- else if(c>='0' && c<='7') {
- int n, val=0;
- for(n=0; n<3 && c>='0' && c<='7'; n++) {
- val = val*8 + c-'0';
- outc('\b');
- ctloutc(val);
- c=getch();
- }
- ungetch(c);
- c=buf[i++]=val;
- break;
- }
- else if(c=='^') {
- outc('\b');
- outc('^');
- fflush(stdout);
- c=getch();
- if(c>='?'&&c<='_') {
- outc('\b');
- ctloutc(buf[i++]=(c-'@')&'\177');
- break;
- }
- else if(c>='`'&&c<='~') {
- outc('\b');
- ctloutc(buf[i++]=c-'`');
- break;
- } /* otherwise default */
- else buf[i++]='^'; /* after adding caret */
- }
- else buf[i++]='\\';
- default:
- if(c=='V'-'@')
- ctloutc(buf[i++] = getch());
- if(s = macro(c))
- addstring(s, buf, &i);
- else
- ctloutc(buf[i++] = c);
- break;
- }
-
- buf[i] = 0;
- return intrup?'\033':c;
- }
-
- ctlouts(s)
- char *s;
- {
- int cnt = 0;
-
- while(*s)
- cnt += ctlout(*s++);
- cnt += standend();
-
- return cnt;
- }
-
- ctloutc(c)
- char c;
- {
- int cnt;
-
- cnt = ctlout(c);
- cnt += standend();
-
- return cnt;
- }
-
- ctlout(c)
- char c;
- {
- int cnt = 0;
- if(c&'\200') {
- cnt += underline();
- cnt += ctlout(c&'\177');
- return cnt;
- }
- else if(c<' ' || c=='\177') {
- cnt += standout();
- outc((c+'@')&'\177');
- cnt++;
- return cnt;
- }
- else {
- cnt += standend();
- outc(c);
- cnt++;
- return cnt;
- }
- }
-
- get_index(file)
- char *file;
- {
- int i;
-
- for(i = 0; i<nentries; i++)
- if(strcmp(entries[i]->e_name, file) == 0)
- return i;
- return -1;
- }
-
- char *file_name(i)
- int i;
- {
- if(i < 0 || i >= nentries)
- return 0;
- else
- return entries[i]->e_name;
- }
-
- enter(dir)
- char *dir;
- {
- if(access(dir, 5)==0 && chdir(dir)==0)
- return newdir();
- save_errno(dir);
- return 0;
- }
-
- isdir(entry)
- struct entry *entry;
- {
- return((entry->e_stat.st_mode&S_IFMT)==S_IFDIR);
- }
-
- getch()
- {
- return getchar();
- }
-
- ungetch(c)
- char c;
- {
- ungetc(c, stdin);
- }
-
-