Xref: utzoo alt.sources:1393 comp.unix.xenix:9420 Path: utzoo!yunexus!ists!yunccn!shields From: shields@yunccn.UUCP (Paul Shields) Newsgroups: alt.sources,comp.unix.xenix Subject: Re: Menu software... version 1.35 upgrade to "lush" part 1/1 Summary: Just a Quick Update: you'll need this to run it on MS-DOS... Message-ID: <3890@yunccn.UUCP> Date: 8 Jan 90 23:15:20 GMT Article-I.D.: yunccn.3890 References: <3888@yunccn.UUCP> Organization: Cottage Software Lines: 930 Note: I haven't compiled lush for MS-DOS in at least a year. You may have to work on it. You'll also need a termcap library that will work on MS-DOS. I ported the GNU termcap to MS-DOS and posted it to comp.sources.misc some time ago (last year? I don't recall.) Drop me a note if you can't find it anywhere, and I'll send it to you. #--------------------------------CUT HERE------------------------------------- #! /bin/sh # # This is a shell archive. Save this into a file, edit it # and delete all lines above this comment. Then give this # file to sh by executing the command "sh file". The files # will be extracted into the current directory owned by # you with default permissions. # # The files contained herein are: # # -rw-r--r-- 1 shields staff 1941 Jan 8 17:48 Makefile.MS # -rw-r--r-- 1 shields staff 1185 Jan 8 16:04 config.h # -rw-r--r-- 1 shields staff 1643 Jan 8 16:47 defs.h # -rw-r--r-- 1 shields staff 6587 Jan 8 16:37 edit.c # -rw-r--r-- 1 shields staff 8788 Jan 8 16:51 envinit.c # -rw-r--r-- 1 shields staff 701 Jan 8 16:41 login.c # -rw-r--r-- 1 shields staff 66 Jan 8 17:07 version.h # echo 'x - Makefile.MS' if test -f Makefile.MS; then echo 'shar: not overwriting Makefile.MS'; else sed 's/^X//' << '________This_Is_The_END________' > Makefile.MS X# Makefile.MS - Generic MS-DOS Makefile for lush X# This file is untested, so it will probably need work, especially in X# the link phase. --Note -- Microsoft make won't work on this Makefile. X# Use something like NdMake. X X# You'll probably want to change LIBDIR and BINDIR to something more sane. X# Don't forget to change config.h as well. X XLIBDIR=\usr\lib\lush XBINDIR=\usr\local\bin X X# compiler definitions you might want to have: X# X# -DPROTOTYPE if your compiler can handle prototype statements X# -DMULTIUSER for MSDOS users, if you have getuid(), getpwnam(), ttyname(), getgrpnam() X XDEBUG = XDEFS = -DMSDOS XCFLAGS = $(DEBUG) $(DEFS) XLDFLAGS= XLIBS = -lc -ltermcap X XHFILES = mparse.h mlex.h mfile.h menu.h edit.h lush.h defs.h version.h config.h XCFILES = mparse.c mlex.c mfile.c menu.c edit.c lush.c envinit.c getin.c login.c XOBJS = mparse.obj mlex.obj mfile.obj menu.obj edit.obj lush.obj envinit.obj\ X getin.obj login.obj X X# ----------------------------- dependencies -------------------------------- X Xlush.exe: $(OBJS) X $(CC) $(LDFLAGS) $(OBJS) $(LIBS) -o lush.exe X Xclean: X -del lush.exe X -del errs X -del *.obj X -del *.map X Xinstall: lush.exe lushrc menu X -mkdir $(BINDIR) X -mkdir $(LIBDIR) X copy lush.exe $(BINDIR) X copy lushrc $(LIBDIR) X copy menu $(LIBDIR) X Xmparse.obj: mparse.c mparse.h mlex.h mfile.h menu.h lush.h defs.h config.h X $(CC) $(CFLAGS) mparse.c -c X Xmlex.obj: mlex.c mlex.h mfile.h lush.h defs.h X $(CC) $(CFLAGS) mlex.c -c X Xmfile.obj: mfile.c mfile.h lush.h defs.h X $(CC) $(CFLAGS) mfile.c -c X Xmenu.obj: menu.c menu.h lush.h defs.h config.h X $(CC) $(CFLAGS) menu.c -c X Xedit.obj: edit.c edit.h lush.h defs.h config.h X $(CC) $(CFLAGS) edit.c -c X Xenvinit.obj: envinit.c lush.h defs.h config.h X $(CC) $(CFLAGS) envinit.c -c X Xlogin.obj: login.c defs.h X $(CC) $(CFLAGS) login.c -c X Xgetin.obj: getin.c defs.h X $(CC) $(CFLAGS) getin.c -c X Xlush.obj: lush.c lush.h defs.h config.h version.h X $(CC) $(CFLAGS) lush.c -c ________This_Is_The_END________ if test `wc -l < Makefile.MS` -ne 71; then echo 'shar: Makefile.MS was damaged during transit (should have been 71 lines)' fi fi ; : end of overwriting check echo 'x - config.h' if test -f config.h; then echo 'shar: not overwriting config.h'; else sed 's/^X//' << '________This_Is_The_END________' > config.h X/* config.h - some definitions you might want to change. */ X X#define GLOBALFILE "/usr/lib/lush/lushrc" /* global config file */ X#define MENUFILE "/usr/lib/lush/menu" /* menu file */ X#define ROOTMENU "MAIN_MENU" /* the default root menu */ X X#ifdef MSDOS X#define LUSHRC "~/lushrc" /* user config file */ X/* #define MULTIUSER */ /* if you have the getpwiud() library. */ X#else X#define LUSHRC "~/.lushrc" X#define MULTIUSER /* UNIX is always multiuser, right? */ X#endif X X#define ILLEGAL "|<>;&" /* disallowed user-input characters */ X#define TERM "dumb" /* terminal type if none in environment */ X X/* things you probably don't want to change... */ X#define LJ_MAX 20 /* Max size of setjmp() stack. This governs how X many levels down in the menu hierarchy you can go. */ X X#define MAX_OPTIONS 20 /*(menu.h) max options per menu */ X#define MAX_RESP 10 /*(menu.h) max number of responses per option */ X#define NAME_SIZE 20 /*(menu.h) Max size of a menu name or option word */ X X#define MAX_MENUS 50 /*(mparse.c) max number of menus in the system */ X X#define MAX_TOKENS 200 /*(mlex.c) Max number of lexical tokens. */ ________This_Is_The_END________ if test `wc -l < config.h` -ne 28; then echo 'shar: config.h was damaged during transit (should have been 28 lines)' fi fi ; : end of overwriting check echo 'x - defs.h' if test -f defs.h; then echo 'shar: not overwriting defs.h'; else sed 's/^X//' << '________This_Is_The_END________' > defs.h X/* File: defs.h X Author: PAS X Date: Sept 7, 1987 X Purpose: Contains global definitions for lush and other programs. X */ X/* -- standard headers -------------------------------------------------- */ X X#ifdef DEBUG X#include X#endif X#include X X/* #ifdef MSDOS X#include X#include X#include X#endif */ X X#include X#include X#include X#ifdef MULTIUSER X#include X#include X#endif X#include X#include X#include X X#ifndef PROTOTYPE /* function declarations are not done for us. */ Xextern char *malloc(); Xextern int getopt(); Xextern char *getenv(); Xextern int putenv(); X#ifdef MULTIUSER Xextern char *ttyname(); Xextern char *getlogin(); X#endif X#endif X X/* -- system dependent defs --------------------------------------------- */ X X#ifdef MSDOS X#define access laccess /* our own access() function. */ X#define TTY "con" /* default terminal. */ X#else X#define TTY "/dev/null" /* no default terminal. */ X#endif X X#ifdef MULTIUSER /* have getpwiud() library? */ X#define GROUP "/etc/group" /* various group access permissions. */ X#define PASSWD "/etc/passwd" /* where to find the passwords. */ X#else X#define USER "nobody" /* user name */ X#define HOMEDIR "/" /* home directory */ X#endif X X/* -- immutable defs ---------------------------------------------------- */ X X/* function return values... */ X#define OK 0 X#define ERROR -1 X#define FALSE 0 X#define TRUE 1 X X#define MAX_LEN 255 /* maximum line length in a file */ X#define PATH_LEN 64 /* max length of a path. */ ________This_Is_The_END________ if test `wc -l < defs.h` -ne 67; then echo 'shar: defs.h was damaged during transit (should have been 67 lines)' fi fi ; : end of overwriting check echo 'x - edit.c' if test -f edit.c; then echo 'shar: not overwriting edit.c'; else sed 's/^X//' << '________This_Is_The_END________' > edit.c X/* File: edit.c X Author: Paul Shields X Date: May 15, 1987 X Purpose: this is where the real work is done. X */ X X#include "lush.h" X#ifndef DEBUG X#include X#endif X#include "edit.h" X X#ifdef PROTOTYPE Xint (*funcs[])(char *) = /* array of pointers to functions taking char* and returning int. */ X#else Xint (*funcs[])() = X#endif X{ ChgDir, /* 00 change directory */ X ChkPort, /* 01 check port access */ X ChkTerm, /* 02 check terminal type */ X Pause, /* 03 pause with "Press enter: " message */ X ChkRdAcc, /* 04 check read access to a file list */ X CallCmd, /* 05 system() to a command with parameters */ X SecurChk, /* 06 perform a security check */ X ChkWrAcc, /* 07 check write access to a file list */ X Expert, /* 08 toggle novice/expert mode */ X P1name, /* 09 write prompt, get parameter. */ X P2name, /* 10 write prompt, get second parameter. */ X ChkAccess, /* 11 check read/write access to a file list */ X SetEnvt, /* 12 set environment variable */ X SaveStr, /* 13 save string in (global) recall-buffer */ X P1Recall, /* 14 put recall-buffer in parameter 1 */ X P2Recall /* 15 put recall-buffer in parameter 2 */ X}; X Xstatic char param1[MAX_LEN]; /* parameter for CallCmd. */ Xstatic char param2[MAX_LEN]; /* parameter for CallCmd. */ Xstatic char recall[MAX_LEN]; /* global recall-buffer. */ X Xint ChgDir(dn) /* change to a directory. */ Xchar *dn; X{ X char *buf, pbuf[MAX_LEN]; X X sprintf(pbuf, dn, param1, param2); /* add the parameter(s) to the command. */ X buf = envsubst(pbuf); /* substitute environment variables if nec. */ X X if(chdir(buf) != 0) { X perror(buf); X return ERROR; X } X return OK; X} X Xint lookupfile(nam, str) /* find a string in a file. */ Xchar *nam, *str; X{ X FILE *fp; X char line[MAX_LEN+1]; X int i = strlen(str); X X line[MAX_LEN] = '\0'; X if((fp = fopen(nam, "r")) != NULL) { X while(fgets(line, MAX_LEN, fp) != NULL) X if(strncmp(str, line, i) == 0) { X fclose(fp); X return OK; X } X fclose(fp); X } else X perror(nam); X X return ERROR; X} X Xint ChkPort(c) /* check for local mode */ Xchar *c; X{ X if(lookupfile(c, tty) == OK) X return OK; X X printf("\nThis command is unavailable from TTY %s\n", tty); X return ERROR; X} X Xint ChkTerm(c) /* check for remote mode */ Xchar *c; X{ X if(lookupfile(c, term) == OK) X return OK; X X printf("\nThis command is unavailable on terminals of type %s\n", term); X return ERROR; X} X Xint Pause(c) /* wait for user */ Xchar *c; X{ X getin("Press enter: "); X return OK; X} X Xint ChkRdAcc(list) /* 04 */ Xchar *list; X{ X printf("\nFile Access Check failed\n"); X return ERROR; X} X Xint ChkWrAcc(list) /* 07 */ Xchar *list; X{ X printf("\nFile Access Check failed\n"); X return ERROR; X} X Xint ChkAccess(list) /* 11 */ Xchar *list; X{ X printf("\nFile Access Check failed\n"); X return ERROR; X} X Xint P1name(prompt) Xchar *prompt; X{ X int i; X char *p; X X p = getin(prompt); X X if(strlen(p) > 0) { X /* none of that funny stuff... */ X i = strcspn(p, ILLEGAL); X } X else i=0; X X strncpy(param1, p, i); X param1[i] = '\0'; X X return OK; /* null is ok. */ X} X Xint P2name(prompt) Xchar *prompt; X{ X int i; X char *p; X X p = getin(prompt); X X if(strlen(p) > 0) { X /* none of that funny stuff... */ X i = strcspn(p, ILLEGAL); X } X else i=0; X X strncpy(param2, p, i); X param2[i] = '\0'; X X return OK; /* null is ok. */ X} X Xint CallCmd(cmd) /* use the system function to execute a command. */ Xchar *cmd; /* name of command to call. */ X{ X int ret; X char *buf, pbuf[MAX_LEN]; X X sprintf(pbuf, cmd, param1, param2); /* add the parameter(s) to the command. */ X buf = envsubst(pbuf); /* substitute environment variables if nec. */ X X#ifdef DEBUG X if(debuglevel & 1) X fprintf(stderr,"CallCmd(%s)= system(\"%s\")\n", cmd, buf); X#endif X if((ret = system(buf)) == 0) X return OK; X X#ifdef DEBUG X fprintf(stderr,"--returned error %d--\n", errno); X perror(buf); X#endif X return ERROR; X} X X/* Return TRUE if user is a member of the group, ow FALSE. X */ Xstatic int member(gr) Xchar *gr; X{ X#ifdef MULTIUSER X struct group *grp; X char **n; X X if((grp = getgrnam(gr)) != NULL) { X for(n = grp->gr_mem; *n != NULL && strcmp(user, *n) != 0; n++) X#ifdef DEBUG X if(debuglevel & 1) X fprintf(stderr, "%s ",*n) X#endif X ; X return (*n != NULL); X } X /* else invalid group. */ X printf("\nSystem error verifying group %s. Please consult system administrator\n",gr); X return FALSE; X#else X /* in single-user system, always return TRUE */ X X return TRUE; X#endif X} X Xint SecurChk(gr) /* check to see that the user is a member of the */ Xchar *gr; /* permitted groups... */ X{ X#ifdef DEBUG X if(debuglevel & 1) X fprintf(stderr,"SecurChk(%s) ",gr); X#endif X#ifdef MULTIUSER X if(getuid() == 0) X return OK; X X if(*gr == '!') { /* user must not be member of this group. */ X if(!member(++gr)) return OK; X } else X if(member(gr)) return OK; X X printf("\nYou are not allowed to use this command.\n"); X return ERROR; X#else X return OK; /* single-user system, always return TRUE. */ X#endif X} X Xint Expert(w) /* toggle novice/expert mode */ Xchar *w; X{ X novice ^= TRUE; /* xor */ X return OK; X} X Xint SetEnvt(w) /* set environment variable. allocates memory for it, */ Xchar *w; /* and substitutes parameters, etc. */ X{ X char *buf, pbuf[MAX_LEN]; X X sprintf(pbuf, w, param1, param2); /* add the parameter(s) to the command. */ X buf = envsubst(pbuf); /* substitute environment variables if nec. */ X X if((w = malloc(strlen(buf)+1)) == NULL) /* allocate in static storage */ X return ERROR; X strcpy(w, buf); X X if(putenv(w) != 0) { X free(w); X return ERROR; X } X return OK; X} X Xint SaveStr(w) /* save string in global recall buffer. */ Xchar *w; X{ X strncpy(w, recall, MAX_LEN-1); X recall[MAX_LEN] = 0; X return OK; X} X Xint P1Recall(w) /* save string in global recall buffer. */ Xchar *w; X{ X strcpy(recall, param1); X return OK; X} Xint P2Recall(w) /* save string in global recall buffer. */ Xchar *w; X{ X strcpy(recall, param2); X return OK; X} ________This_Is_The_END________ if test `wc -l < edit.c` -ne 283; then echo 'shar: edit.c was damaged during transit (should have been 283 lines)' fi fi ; : end of overwriting check echo 'x - envinit.c' if test -f envinit.c; then echo 'shar: not overwriting envinit.c'; else sed 's/^X//' << '________This_Is_The_END________' > envinit.c X/* File: envinit.c X Author: Paul Shields X Date: May 13, 1987 X Purpose: sets up variables for the environment. X */ X X#include "lush.h" X#ifndef DEBUG X#include X#endif X X/* We logged into the console, a local tty, or a remote tty. Certain things X are unavailable from a remote tty, so we'll need to compare the environment X variable TTY with a list of permitted devices when the need calls for it. X */ Xchar *root_menu = NULL, /* default main menu name. */ X *menufile = NULL, /* name of menu file. */ X *globalrc = NULL, /* name of global rc file. */ X *userrc = NULL, /* name of user rc file. */ X *user, /* name of the user. */ X *tty, /* TTY environment variable. */ X *term = NULL; /* TERM environment variable. */ X Xchar *CL, *SO, *SE; /* termcap Clear-screen, Stand-out, Unstand-out */ Xint LI, CO; /* lines, columns */ X X Xchar * Xgethome(u) /* allocate and return user home dir or null. */ Xchar *u; X{ X#ifdef MULTIUSER X struct passwd *pw; X /* if u is null, use default of current user. */ X if(u == NULL || strlen(u) == 0) X u = user; X if((pw = getpwnam(u)) == NULL) X return NULL; X if((u = malloc(strlen(pw->pw_dir)+1)) == NULL) X return NULL; X strcpy(u,pw->pw_dir); X return u; X#else X return HOMEDIR; X#endif X} X X/* allocate and store an environment variable. */ Xchar *mputenv(var,def) Xchar *var,*def; X{ X char *ut; X if((ut = malloc(strlen(var)+1+strlen(def)+1)) == NULL) X return NULL; X sprintf(ut, "%s=%s",var,def); X putenv(ut); X return ut; X} X X#define trim(s) {char *tl; while(*s && isspace(*s)) s++; \ X for(tl=s; *tl; tl++) ; for(tl--; tl > s; tl--) \ X { if(isspace(*tl)) *tl = '\0'; else break; } } X X/* Process a line in the global rc. X Allow environment definitions. X Do translation of $VAR and ~user strings. X *** Yet to add: System() out to commands enclosed in ``. X X Side-effects: writes junk into the line. X */ Xstatic int proc_global(line) Xchar *line; X{ X char *tl, *var, *def; X X#ifdef DEBUG X if(debuglevel & 1) X fprintf(stderr,"line: |%s|\n",line); X#endif X X/***/ /* this won't do. need to convert to use the scanner in mparse.c */ X if((tl = strpbrk(line,"#")) != NULL) /* strip comments */ X *tl = '\0'; X X /* look for = and break into two: "A=B" => "A","B" */ X if((def = strpbrk(line, "=")) != NULL) { X var = strtok(line, "="); X def++; X trim(var); /* zap leading/trailing white space */ X trim(def); X tl = envsubst(def); /* do $ and ~ substitutions */ X mputenv(var, tl); X } else { X trim(line); X if(strlen(line) > 0) X return ERROR; X } X return OK; X} X X/* Process a line in the user rc. X Only environment definitions allowed. X Restrict to ones already defined. X */ Xstatic int proc_user(line) Xchar *line; X{ X return proc_global(line); /***/ /* for now, do the same. */ X} X X/* Get and process the global rc file */ Xstatic int getrc_global(name) Xchar *name; X{ X FILE *fp; X char line[MAX_LEN+1]; X int ln; X X if((fp=fopen(name, "r")) == NULL) { X perror(name); X return ERROR; X } X for(ln=1; fgets(line, MAX_LEN, fp) != NULL; ln++) X if(proc_global(line) == ERROR) X fprintf(stderr,"%s: syntax error: line %d\n",name,ln); X fclose(fp); X return OK; X} X X/* Get and process the user rc file */ Xstatic int getrc_user(name) Xchar *name; X{ X FILE *fp; X char line[MAX_LEN+1]; X int ln; X X if((fp=fopen(name, "r")) == NULL) { X perror(name); X return ERROR; X } X for(ln=1; fgets(line, MAX_LEN, fp) != NULL; ln++) X if(proc_user(line) == ERROR) X fprintf(stderr,"%s: syntax error: line %d\n",name,ln); X fclose(fp); X return OK; X} X Xint envinit(argc,argv) Xint argc; Xchar *argv[]; X{ X register char *h; X char *ut; /* temporary */ X int err = 0, c; X extern char *optarg; X X#ifndef MSDOS X if(getenv("SHELL") != argv[0]) /* security. */ X mputenv("SHELL",argv[0]); X#endif X X /* find out who we are. */ X#ifdef MULTIUSER X if((user = getlogin()) == NULL) { X struct passwd *pw; X if((pw = getpwuid(getuid())) == NULL) { X fprintf(stderr,"Can't find your username anywhere.\n"); X return ERROR; X } X ut = pw->pw_name; X if((user = malloc(strlen(ut)+1)) == NULL) X { perror("envinit()"); return ERROR; } X strcpy(user,ut); X } X#else X user=USER; X#endif X mputenv("USER",user); X#ifdef DEBUG X if(debuglevel & 1) X fprintf(stderr,"USER=<%s> ",user); X#endif X X if((ut = getenv("HOME")) == NULL) { X if((ut = gethome(user)) == NULL) { X fprintf(stderr,"No home directory.\n"); X return ERROR; X } X mputenv("HOME",ut); X } X#ifdef DEBUG X if(debuglevel & 1) X fprintf(stderr,"HOME=<%s> ",ut); X#endif X X /* process the command line options... */ X while ((c = getopt(argc, argv, "f:R:M:G:U:")) != EOF) X switch((char)c) { X case 'f': X case 'M': X if((menufile=malloc(strlen(optarg)+1)) == NULL) X { perror("envinit()"); return ERROR; } X strcpy(menufile,optarg); X break; X case 'R': X if((root_menu=malloc(strlen(optarg)+1)) == NULL) X { perror("envinit()"); return ERROR; } X strcpy(root_menu,optarg); X break; X case 'G': X if((globalrc=malloc(strlen(optarg)+1)) == NULL) X { perror("envinit()"); return ERROR; } X strcpy(globalrc,optarg); X break; X case 'U': X if((userrc=malloc(strlen(optarg)+1)) == NULL) X { perror("envinit()"); return ERROR; } X strcpy(userrc,optarg); X break; X case '?': X err = TRUE; X } X if(err) { X fprintf(stderr, "Usage: %s [-G global-config-file] [-M menufile]\n",argv[0]); X fprintf(stderr, " [-R rootmenu] [-U user-config-file]\n"); X return ERROR; X } X X if(globalrc == NULL) /* default global rc file location */ X globalrc = GLOBALFILE; X X#ifdef DEBUG X if(debuglevel & 1) X fprintf(stderr,"global rc=<%s>\n",globalrc); X#endif X /* Now process global rc file... must always exist. */ X getrc_global(globalrc); X X if(menufile == NULL) /* default menu file location */ X if((menufile = getenv("MENUFILE")) == NULL) X menufile = MENUFILE; X X if(root_menu == NULL) /* default root menu name */ X if((root_menu = getenv("ROOTMENU")) == NULL) X root_menu = ROOTMENU; X X if(userrc == NULL) X if((userrc = getenv("LUSHRC")) == NULL) X userrc = LUSHRC; X X#ifdef DEBUG X if(debuglevel & 1) X printf("userrc: <%s>, menufile: <%s>, root_menu: <%s>\n", X userrc, menufile, root_menu); X#endif X /***/ /* note: may need to subst ~ in userrc here. */ X X /* now process the user rc file... */ X getrc_user(userrc); X X if((tty = getenv("TTY")) == NULL) { /* default terminal */ X#ifdef MULTIUSER X if((ut = ttyname(fileno(stdin))) == NULL) X tty = TTY; X else { X tty = malloc(strlen(ut)+1); X strcpy(tty, ut); X } X#else X tty = TTY; X#endif X mputenv("TTY",tty); X } X X if((term = getenv("TERM")) == NULL) { /* default to "dumb" terminal */ X term = TERM; X mputenv("TERM",term); X } X X return OK; X} X X/* Initialize the termcap variables. Some of this code is from MicroEMACS X by Daniel M. Lawrence (and others.) */ Xint Xtcapinit() /* important. call envinit() before this. */ X{ X char *tgetstr(); X int tgetnum(); X char tcbuf[1024]; X static char strbuf[128]; X char *str = strbuf; X X if (term == NULL) { X fprintf(stderr,"Environment variable TERM not defined!\n"); X return ERROR; X } X X if ((tgetent(tcbuf, term)) <= 0) { X fprintf(stderr, "Unknown terminal type %s!\n", term); X return ERROR; X } X X LI = tgetnum("li"); /* lines & columns */ X CO = tgetnum("co"); X X if((CL = tgetstr("cl",&str)) == NULL) /* clear screen */ X CL = "\n------------------------------------------------------------------------------\n"; X X if((SO = tgetstr("so",&str)) == NULL) /* stand-out enter */ X SO = ""; X X if((SE = tgetstr("se", &str)) == NULL) /* stand-out end */ X SE = ""; X X /* caution: we lose access to tcbuf now. don't call any more termcap X functions. CL, SO, and SE are in static memory. */ X X return OK; X} X Xstatic char retbuf[BUFSIZ]; X#define scanword(s, var) {char *tmp; \ X tmp = ++(s); while(isalnum(*(s))) (s)++; \ X strncpy(var, tmp, (s)-tmp); \ X (var)[(s)-tmp] = '\0'; } X Xchar * /* substitute environment values in "$VAR" strings for s. */ Xenvsubst(s) /* returns with static data which is overwritten by the next call. */ Xchar *s; X{ X char *r = retbuf, *tmp; X static char var[MAX_LEN]; X X while(*r = *s) { X if(*s == '\\') /* escape with \$ or \~. */ X *++r = *++s; X if(*s == '$') { /* substitute */ X scanword(s, var); X if((tmp = getenv(var)) == NULL) /* look it up.. */ X tmp = ""; /* Nothing there */ X while(*r = *tmp++) /* copy */ X r++; X continue; X } X if(*s == '~') { /* look for ~user */ X scanword(s, var); X X if((tmp = gethome(var)) == NULL) X tmp = ""; /* no translation */ X X while(*r = *tmp++) /* copy */ X r++; X continue; X } X s++; X r++; X } X X return retbuf; X} ________This_Is_The_END________ if test `wc -l < envinit.c` -ne 362; then echo 'shar: envinit.c was damaged during transit (should have been 362 lines)' fi fi ; : end of overwriting check echo 'x - login.c' if test -f login.c; then echo 'shar: not overwriting login.c'; else sed 's/^X//' << '________This_Is_The_END________' > login.c X/* File: login.c X Author: Paul Shields X Date: May 13, 1987 X Purpose: Miscellaneous esoteric system-dependent functions X */ X X#include "defs.h" X#ifndef NULL X#define NULL (char *)0 X#endif X X/***/ /* the following is a stub. it does nothing. */ Xvoid login(p) /* log in operator. */ Xchar *p; /* oper name */ X{ X#ifdef MULTIUSER X struct passwd *pwd = getpwuid(getuid()); X X if((char *)pwd != NULL) X strcpy(p,pwd->pw_name); /* set operator name */ X#else X strcpy(p,USER); X#endif X X /***/ /* remember login time. */ X} X X/***/ /* the following is a stub. it does nothing. */ Xvoid logout(p) /* log out operator */ Xchar *p; /* oper name */ X{ /* log system use */ X} ________This_Is_The_END________ if test `wc -l < login.c` -ne 32; then echo 'shar: login.c was damaged during transit (should have been 32 lines)' fi fi ; : end of overwriting check echo 'x - version.h' if test -f version.h; then echo 'shar: not overwriting version.h'; else sed 's/^X//' << '________This_Is_The_END________' > version.h X#define VERSION "LUSH version 1.35, Mon Jan 8 17:06:49 EST 1990" ________This_Is_The_END________ if test `wc -l < version.h` -ne 1; then echo 'shar: version.h was damaged during transit (should have been 1 lines)' fi fi ; : end of overwriting check exit 0 -- Paul Shields, shields@nccn.yorku.ca (..!uunet!yunccn!shields)