ag@elgar.UUCP (Keith Gabryelski) (11/09/88)
Posting-number: Volume 5, Issue 36 Submitted-by: "Keith Gabryelski" <ag@elgar.UUCP> Archive-name: s5finger/Part3 [I should note that this is untested: it's proving too difficult to get at my System V and BSD accounts, all I can depend on is this. For now, at least. The future may depend on how well Dynix's dual-universe stuff works. ++bsa] #! /bin/sh # This is a shell archive, meaning: # 1. Remove everything above the #! /bin/sh line. # 2. Save the resulting text in a file. # 3. Execute the file with /bin/sh (not csh) to create the files: # watson # birthday_card # defs.h # inquire.c # inqrots.c # This archive created: Sun Oct 30 14:55:26 1988 export PATH; PATH=/bin:$PATH if test -f 'watson' then echo shar: will not over-write existing file "'watson'" else cat << \SHAR_EOF > 'watson' : # # watson - for the finger distribution. # Written by Keith Gabryelski # Released into public domain September 1, 1988. # Please keep this header. # # This is an interactive data base handler for the whois database. # novice_directory=/usr/lib/finger/watson # # getyorn() - SOP, get `y' or `n' and return some status relating to them. # getyorn() { while : do echo "$1 [y/n]? \c" IFS="$NORMAL_IFS" read yorn dummy case $yorn in y*|Y*) return 0 ;; n*|N*) return 1 ;; esac echo "Please answer Y or N." done } # # getyornorq() # getyornorq() { while : do echo "$1 [y/n/q]? \c" IFS="$NORMAL_IFS" read yorn dummy case $yorn in y*|Y*) return 0 ;; n*|N*) return 1 ;; q*|Q*) exit 1 ;; esac echo "Please answer Y, N, or Q." done } quiter() { getyornorq "Do you really want to quit" && { rm -f "$watfile" "$remark" "$remarkfile" exit 1 } } # # get_line # get_line() { name="$1" lastanswer="$2" stty quit \^\[ IFS= while : do echo "Your current $name is\c" if [ "x$lastanswer" = "x" ] then echo " blank." else echo ":\n\t\"$lastanswer\"" fi if [ $novice = TRUE ] then echo "Enter a new $name, press the [Return] key to accept this one, or" echo "press the [ESC] key to leave this field blank." fi echo " New $name: \c" blankp=FALSE trap "blankp=TRUE" "3" read answer if [ $blankp = FALSE ] then if [ "x$answer" = "x" ] then trap "" 3 stty quit $quit answer="$lastanswer" return 0 fi fi lastanswer="$answer" done } get_nickname() { if [ "$novice" = TRUE ] && [ -r "$nickname_novice_file" ] then cat "$nickname_novice_file" fi get_line nickname "$nickname" if [ "x$nickname" != "x$answer" ] then nickname="$answer" changes_made=TRUE fi } get_workaddress() { if [ "$novice" = TRUE ] && [ -r "$workaddress_novice_file" ] then cat "$workaddress_novice_file" fi get_line workaddress "$work_address" if [ "x$work_address" != "x$answer" ] then work_address="$answer" changes_made=TRUE fi } get_workphone() { if [ "$novice" = TRUE ] && [ -r "$workphone_novice_file" ] then cat "$workphone_novice_file" fi get_line workphone "$work_phone" if [ "x$work_phone" != "x$answer" ] then work_phone="$answer" changes_made=TRUE fi } get_homeaddress() { if [ "$novice" = TRUE ] && [ -r "$homeaddress_novice_file" ] then cat "$homeaddress_novice_file" fi get_line homeaddress "$home_address" if [ "x$home_address" != "x$answer" ] then home_address="$answer" changes_made=TRUE fi } get_homephone() { if [ "$novice" = TRUE ] && [ -r "$homephone_novice_file" ] then cat "$homephone_novice_file" fi get_line homephone "$home_phone" if [ "x$home_phone" != "x$answer" ] then home_phone="$answer" changes_made=TRUE fi } get_project() { if [ "$novice" = TRUE ] && [ -r "$project_novice_file" ] then cat "$project_novice_file" fi get_line project "$project" if [ "x$project" != "x$answer" ] then project="$answer" changes_made=TRUE fi } get_supervisor() { if [ "$novice" = TRUE ] && [ -r "$supervisor_novice_file" ] then cat "$supervisor_novice_file" fi get_line supervisor "$supervisor" if [ "x$supervisor" != "x$answer" ] then supervisor="$answer" changes_made=TRUE fi } get_birthday() { if [ "$novice" = TRUE ] && [ -r "$birthday_novice_file" ] then cat "$birthday_novice_file" fi get_line birthday "$birthday" if [ "x$birthday" != "x$answer" ] then birthday="$answer" changes_made=TRUE fi } get_remark() { if [ "$novice" = TRUE ] && [ -r "$remark_novice_file" ] then cat "$remark_novice_file" fi answer="$remark" echo "Your current remark is:" grep -n "^" $answer | sed -n -e 's/^\([0-9]*:\)\(.*\)/\1 \2/' -e 's/^/Line /p' while : do echo "edit, quit, ?, or [Return]: \c" IFS="$NORMAL_IFS" read ans garbage case $ans in \?) echo "?\t\tHelp list." echo "edit\t\tEdit remark using favorite editor." echo "quit\t\tUse current remark." echo "[Return]\tEnter remark in line by line." ;; e*) mv $answer $remarkfile $EDITOR $remarkfile break ;; q*) return 0 ;; "") echo "Enter your remark. A blank line ends input." > $remarkfile # linenumber=1 stty quit \^\[ IFS= while : do # # No longer handles linenumber because of "Stack Overflow" messages. # echo "Line $linenumber: \c" echo "Line: \c" blankp=FALSE trap "blankp=TRUE" "3" read answer if [ $blankp = FALSE ] then if [ "x$answer" = "x" ] then trap "" 3 stty quit $quit break fi fi echo "$answer" >> $remarkfile # linenumber=`expr "$linenumber" + 1` done break ;; *) echo "Invalid answer, try again." ;; esac done mv $remarkfile $remark changes_made=TRUE } progname="$0" if [ "$1" = "" ] then username="$LOGNAME" else username="$1" fi if [ "x$EDITOR" = "x" ] then EDITOR=emacs fi nickname= work_address= work_phone= home_address= home_phone= birthday= project= supervisor= remark="/tmp/rem$$" changes_made=FALSE watfile="/tmp/watson$$" remarkfile="/tmp/remark$$" firstimer="$novice_directory/firstimer" nickname_novice_file="$novice_directory/nickname" homephone_novice_file="$novice_directory/homephone" homeaddress_novice_file="$novice_directory/homeaddress" workphone_novice_file="$novice_directory/workphone" workaddress_novice_file="$novice_directory/workaddress" project_novice_file="$novice_directory/project" supervisor_novice_file="$novice_directory/supervisor" birthday_novice_file="$novice_directory/birthday" remark_novice_file="$novice_directory/remark" quit=`stty -a | sed -n -e "s/.*quit = \([^; ]*\).*/\1/p"` trap quiter "2" if [ "$PG" = "" ] then PG=cat fi # # Do they already exist in the database? # sed -n -e "/^${username}/{ p q }" /etc/passwd > $watfile pass=`cat $watfile` if [ "$pass" = "" ] then echo "There is no user \`$username' in /etc/passwd." exit 1 fi passwd_uid=`sed -n -e "s/^${username}:[^:]*:\([^:]*\).*/\1/p" $watfile` passwd_gid=`sed -n -e "s/^${username}:[^:]*:[^:]*:\([^:]*\).*/\1/p" $watfile` fullname=`sed -n -e "s/^${username}:[^:]*:[^:]*:[^:]*:\([^:]*\).*/\1/p" $watfile` home_dir=`sed -n -e "s/^${username}:[^:]*:[^:]*:[^:]*:[^:]*:\([^:]*\).*/\1/p" $watfile` login_shell=`sed -n -e "s/^${username}:[^:]*:[^:]*:[^:]*:[^:]*:[^:]*:\([^:]*\).*/\1/p" $watfile` if inquire -exist $username then echo "Entry \`$username' is for \"$fullname\"." novice=FALSE else getyorn "Would you like help" && $PG $firstimer inquire -write $username novice=TRUE fi nickname="`inquire $username -nickname`" work_address="`inquire $username -workaddress`" work_phone="`inquire $username -workphone`" home_address="`inquire $username -homeaddress`" home_phone="`inquire $username -homephone`" birthday="`inquire $username -birthday`" project="`inquire $username -project`" supervisor="`inquire $username -supervisor`" inquire $username -remark > $remark NORMAL_IFS="$IFS" while : do if [ "$novice" = TRUE ] then echo "Type \`?' for a list of commands." fi echo "watson> \c" IFS="$NORMAL_IFS" read command garbage case $command in "") ;; \?) echo "? abort all birthday exit" echo "help homeaddress homephone list nickname" echo "nonovice novice project quit remark" echo "supervisor whois workaddress workphone" ;; abort|quit|q) if [ "$changes_made" = TRUE ] then getyornorq "Quit without saving changes" && { rm -f "$watfile" "$remark" "$remarkfile" exit 1 } else rm -f "$watfile" "$remark" "$remarkfile" exit 1 fi ;; help) $PG $firstimer ;; list) echo "Nickname = $nickname" echo "Work Address = $work_address" echo "Work Phone = $work_phone" echo "Home Address = $home_address" echo "Home Phone = $home_phone" echo "Birthday = $birthday" echo "Project = $project" echo "Supervisor = $supervisor" echo "Remarks:" grep -n "^" $remark | sed -n -e 's/^\([0-9]*:\)\(.*\)/\1 \2/' -e 's/^/Line /p' ;; nonovice) novice=FALSE echo "Novice mode OFF." ;; novice) novice=TRUE echo "Novice mode ON." ;; # # Either I'm broken or this Bourne shell is broken. # "done"|"exit") if [ "$changes_made" = TRUE ] then echo "Saving changes...\c" inquire -write $username -nickname "$nickname" -homeaddress "$home_address" -homephone "$home_phone" -workaddress "$work_address" -workphone "$work_phone" -birthday "$birthday" -project "$project" -supervisor "$supervisor" -remark < $remark echo " " fi rm -f "$watfile" "$remark" "$remarkfile" exit 0 ;; whois) finger "$username" terpri=FALSE if [ "x$nickname" != "x" ] then echo "($nickname) \c" terpri=TRUE fi if [ "x$home_dir" != "x" ] then echo "<$home_dir> \c" terpri=TRUE fi if [ "x$project" != "x" ] || [ "x$supervisor" != "x" ] then echo "Hacking $project\c" if [ "x$supervisor" != "x" ] then echo " for $supervisor\c" fi terpri=TRUE fi if [ $terpri = TRUE ] then echo fi echo "[$passwd_uid, $passwd_gid] [$login_shell]\c" if [ "x$birthday" = "x" ] then echo else echo " Birthday $birthday" fi if [ "x$home_address" != "x" ] || [ "x$home_phone" != "x" ] then echo "Home \c" if [ "x$home_address" != "x" ] then echo "$home_address; \c" fi if [ "x$home_phone" != "x" ] then echo "Phone $home_phone\c" fi echo fi if [ "x$work_address" != "x" ] || [ "x$work_phone" != "x" ] then echo "Work \c" if [ "x$work_address" != "x" ] then echo "$work_address; \c" fi if [ "x$work_phone" != "x" ] then echo "Phone $work_phone\c" fi echo fi if [ "x`cat $remark`" != "x" ] then cat $remark fi ;; all) get_nickname get_birthday get_project get_supervisor get_homeaddress get_homephone get_workaddress get_workphone get_remark ;; birthday) get_birthday ;; homeaddress) get_homeaddress ;; homephone) get_homephone ;; nickname) get_nickname ;; project) get_project ;; remark) get_remark ;; supervisor) get_supervisor ;; workaddress) get_workaddress ;; workphone) get_workphone ;; !*) sh -c "`expr "x$command" : "x!\(.*\)"`" echo "!" ;; *) echo "Invalid command \`$command'." echo "Type \`?' for a list of commands or type \`help' for help" ;; esac done SHAR_EOF chmod +x 'watson' fi # end of overwriting check if test -f 'birthday_card' then echo shar: will not over-write existing file "'birthday_card'" else cat << \SHAR_EOF > 'birthday_card' hhh hhh hhhh hhhh hhh hhh hhh hhh hhh hhh hhh hhh hhhhhhhhhhhhhh hhhhhhhhhhhhhh aaaa pppppp pppppp yy yy hhh hhh aaaaaa pp pp pp pp yy yy hhh hhh aa pp pp pp pp yy yy hhh hhh aaaaaaa ppppppp ppppppp yyy hhh hhh aaaaaaaa pp pp yy hhh hhh aa aa pp pp yy hhhh hhh aaaaaaaa pp pp yy hhh hhh aaaaa aa pp pp yy BBB BBBBBBBBBBBB BBBBBBBBBBBBB BBB BBB BBB BBB BBB BBB BBBBBBBBBBBBB BBBBBBBBBBBB ii tt hh dd yy yy BBB BBB ii r rrrrrr tt hh dd aaaaa yy yy BBB BBB rrrr rrr ttttttt hh dd aa yyyy BBB BBB ii rr r tt hh hhhh dd aaaaa yy BBB BBB ii rr tt hhh hhh dddddd aa aa yy BBBBBBBBBBBBB ii rr tt hh hh dd dd aa aa yy BBBBBBBBBBBB ii rr tt hh hh dd ddd aa aa yy BBB iiii rrrr ttt hh hh ddddd d aaaa a yy SHAR_EOF fi # end of overwriting check if test -f 'defs.h' then echo shar: will not over-write existing file "'defs.h'" else cat << \SHAR_EOF > 'defs.h' /* ** defs.h - For the finger distribution. ** ** Written by Keith Gabryelski ** Released into public domain September 1, 1988. ** Please keep this header. */ /* ** Your system type. Define only one. Also look at the end of ** finger.h */ #define SCO_XENIX_386 /* SCO Xenix 386 machines. */ /*#define SCO_XENIX_286 /* SCO Xenix 286 machines - NOT TESTED. */ /*#define UNIX_PC /* The 3B1 and 7300 machines. */ /*#define SYSV_3B5 /* The 3B5 machine - NOT TESTED. */ /* ** NLIST_FILE is used to store kernel symbols so we don't have to nlist ** the kernel every time. */ #define NLIST_FILE "/usr/lib/finger/nlist" /* ** WHOIS_DBASE_DIR - ** A directory for keeping data base files on individual users. */ #define WHOIS_DBASE_DIR "/usr/lib/finger/dbase" /* ** BIRTHDAY_CARD - ** The birthday that the birthday wizard will send to users at the ** appropriate time. **/ #define BIRTHDAY_CARD "/usr/lib/finger/birthday_card" /* ** PLAN_FILE - ** Name of the users plan file. This file contains the users over all ** `plan' in life. It is kept in the users home directory. */ #define PLAN_FILE ".plan" /* ** FORWARD_FILE - ** File containing site and user name where mail is forwarded for ** the user. This file is kept in the users home directory. */ #define FORWARD_FILE ".forward" /* ** MAIL_SPOOL_DIR ** Where is mail kept? */ #define MAIL_SPOOL_DIR "/usr/spool/mail" /* ** MAILER - ** How do we mail things? */ #define MAILER "/usr/bin/smail" /* ** Below here are things you probably do not want to change. */ #undef TRUE #undef FALSE #define TRUE 1 #define FALSE 0 #define FAIL -1 #define OK 0 #define STAT_OWRITE 0x002 /* ** Below here are things that cannot be modified or the distribution ** will surely not work. ** ** Thanks should also go out to Neil Pert for awesome percussion. -MQH */ #define SIGNIFICANT_OTHER "Marla Gabryelski" #define MUSICIAN "Brian_Eno" #define SONG "Third_Uncle" #define VERNUM 1 #define PATCHLEVEL 0 #define AUTHOR "Keith M. Gabryelski" #define ADDRESS "ag@elgar.UUCP" #define ALTPATH "ag@portnoy.UUCP" #define THANKS1 "ford@kenobi.UUCP (Mike Ditto)" SHAR_EOF fi # end of overwriting check if test -f 'inquire.c' then echo shar: will not over-write existing file "'inquire.c'" else cat << \SHAR_EOF > 'inquire.c' /* ** inquire.c - For the finger distribution. ** ** Written by Keith Gabryelski ** Released into public domain September 1, 1988. ** Please keep this header. ** ** Non interactive database handler. */ #include <stdio.h> #include <sys/types.h> #include <fcntl.h> #include "defs.h" #include "ttyloc.h" #include "dbase.h" extern char *getlogin(); extern int errno; extern char *mymalloc(), *myrealloc(); char *progname; #define GET_OR_SET(VARIABLE, NAME) if (!writemode) puts(VARIABLE);\ else if (argc--)\ { VARIABLE = mymalloc(strlen(*argv)+1);\ strcpy(VARIABLE, *argv++);\ } else {fprintf(stderr,\ "%s: %s given with no argument.\n",\ progname, NAME); exit(-1);} main(argc, argv) int argc; char **argv; { char *name = NULL, *word; int writemode = FALSE, existmode = FALSE; struct finger f; progname = *argv++; --argc; if (argc) { if(!strcmp(*argv, "-write")) { --argc; ++argv; writemode = TRUE; } else if (!strcmp(*argv, "-exist")) { --argc; ++argv; existmode = TRUE; } } if (!argc || (argc && **argv == '-')) { if ((name = getlogin()) == NULL) { fprintf(stderr, "%s: can't figure you out.\n", progname); exit(-1); } } else { name = *argv++; --argc; } #ifdef DEBUG printf("name = `%s'.\n", name); #endif /* DEBUG */ strncpy(f.uname, name, sizeof(f.uname)); get_dbase_info(&f); if (existmode) exit(!f.valid_whois); if (!writemode && !f.valid_whois) { fprintf(stderr, "%s: No data base entry for `%s'.\n", progname, f.uname); exit(2); } while (argc--) { word = *argv++; if (!strcmp(word, "-nickname")) { GET_OR_SET(f.nickname, "-nickname"); } else if (!strcmp(word, "-workaddress")) { GET_OR_SET(f.work_addr, "-workaddress"); } else if (!strcmp(word, "-workphone")) { GET_OR_SET(f.work_phone, "-workphone"); } else if (!strcmp(word, "-homeaddress")) { GET_OR_SET(f.home_addr, "-homeaddress"); } else if (!strcmp(word, "-homephone")) { GET_OR_SET(f.home_phone, "-homephone"); } else if (!strcmp(word, "-birthday")) { GET_OR_SET(f.birthday, "-birthday"); } else if (!strcmp(word, "-project")) { GET_OR_SET(f.project, "-project"); } else if (!strcmp(word, "-supervisor")) { GET_OR_SET(f.supervisor, "-supervisor"); } else if (!strcmp(word, "-remark")) { if (!writemode) puts(f.remark); else { if (argc) { --argc; f.remark = mymalloc(strlen(*argv)+1); strcpy(f.remark, *argv++); } else { char *line = mymalloc(1), buffer[BUFSIZ]; line[0] = '\0'; while (fgets(buffer, BUFSIZ, stdin) != NULL) { line = myrealloc(line, strlen(line) + strlen(buffer) + 1); strcat(line, buffer); } f.remark = line; } } } else { fprintf(stderr, "%s: invalid switch `%s'.\n", progname, word); usage(); } } if (writemode) exit(set_dbase_info(&f)); exit(0); } usage() { fprintf(stderr, "%s: usage %s {-write | -exist | } [username] [-option]\n", progname, progname); exit(-1); } set_dbase_info(f) struct finger *f; { char whoisname[sizeof(WHOIS_DBASE_DIR) + sizeof('/') + sizeof(f->uname)]; char *buf; int fd; strcpy(whoisname, WHOIS_DBASE_DIR); strcat(whoisname, "/"); strcat(whoisname, f->uname); if ((fd = open(whoisname, O_CREAT|O_TRUNC|O_WRONLY, 0622)) == -1) { fprintf(stderr, "%s\n", puterr(errno)); return(1); } buf = mymalloc(strlen(f->nickname) + 1 + strlen(f->work_addr) + 1 + strlen(f->work_phone) + 1 + strlen(f->home_addr) + 1 + strlen(f->home_phone) + 1 + strlen(f->birthday) + 1 + strlen(f->project) + 1 + strlen(f->supervisor) + 1 + strlen(f->remark)+1); sprintf(buf, "%s\n%s\n%s\n%s\n%s\n%s\n%s\n%s\n%s", f->nickname, f->work_addr, f->work_phone, f->home_addr, f->home_phone, f->birthday, f->project, f->supervisor, f->remark); #ifdef DEBUG printf("dbase '%s'.\n", buf); #endif /* DEBUG */ write(fd, buf, strlen(buf)); close(fd); return(0); } SHAR_EOF fi # end of overwriting check if test -f 'inqrots.c' then echo shar: will not over-write existing file "'inqrots.c'" else cat << \SHAR_EOF > 'inqrots.c' /* ** watrots.c - routines to read in a decipher dbase file. ** - For the finger distribution. ** ** Written by Keith Gabryelski ** Released into public domain September 1, 1988. ** Please keep this header. ** ** Some basic routines used to handle data base management. */ #include <stdio.h> #include <sys/types.h> #include <sys/stat.h> #include <a.out.h> #include <fcntl.h> #include "defs.h" #include "ttyloc.h" #include "dbase.h" extern char *mymalloc(), *myrealloc(); #define GET_NEXT_LINE() {cp = bp; if (bp != NULL) \ {while (*bp != '\n' && bp < bufferend) *bp++; \ if (bp >= bufferend) bp = NULL; \ else *bp++ = '\0';}} void get_dbase_info(f) struct finger *f; { char *bp, *cp, *dp, *buffer = NULL, *bufferend; char whoisname[sizeof(WHOIS_DBASE_DIR) + sizeof('/') + sizeof(f->uname)]; int fd; struct stat stbuf; strcpy(whoisname, WHOIS_DBASE_DIR); strcat(whoisname, "/"); strcat(whoisname, f->uname); f->work_addr = f->home_addr = f->work_phone = f->birthday = f->home_phone = f->project = f->supervisor = f->remark = f->nickname = ""; if ((fd = open(whoisname, O_RDONLY)) != -1 && fstat(fd, &stbuf) != -1) { f->valid_whois = TRUE; buffer = myrealloc(buffer, stbuf.st_size + 1); bufferend = buffer + stbuf.st_size; bp = buffer; dp = NULL; if (read(fd, buffer, stbuf.st_size) > 0) { GET_NEXT_LINE(); if (cp != NULL) { f->nickname = mymalloc(strlen(cp) + 1); strcpy(f->nickname, cp); } GET_NEXT_LINE(); if (cp != NULL) { f->work_addr = mymalloc(strlen(cp) + 1); strcpy(f->work_addr, cp); } GET_NEXT_LINE(); if (cp != NULL) { f->work_phone = mymalloc(strlen(cp) + 1); strcpy(f->work_phone, cp); } GET_NEXT_LINE(); if (cp != NULL) { f->home_addr = mymalloc(strlen(cp) + 1); strcpy(f->home_addr, cp); } GET_NEXT_LINE(); if (cp != NULL) { f->home_phone = mymalloc(strlen(cp) + 1); strcpy(f->home_phone, cp); } GET_NEXT_LINE(); if (cp != NULL) { f->birthday = mymalloc(strlen(cp) + 1); strcpy(f->birthday, cp); } GET_NEXT_LINE(); if (cp != NULL) { f->project = mymalloc(strlen(cp) + 1); strcpy(f->project, cp); } GET_NEXT_LINE(); if (cp != NULL) { f->supervisor = mymalloc(strlen(cp) + 1); strcpy(f->supervisor, cp); } cp = bp; /* Get remark. */ if (bp != NULL) { while (bp < bufferend) bp++; *bp++ = '\0'; f->remark = mymalloc(bp - cp); strcpy(f->remark, cp); } } close(fd); } else f->valid_whois = FALSE; } SHAR_EOF fi # end of overwriting check # End of shell archive exit 0 -- ag@elgar.CTS.COM Keith Gabryelski ...!{ucsd, jack}!elgar!ag