ag@elgar.UUCP (Keith Gabryelski) (11/09/88)
Posting-number: Volume 5, Issue 35 Submitted-by: "Keith Gabryelski" <ag@elgar.UUCP> Archive-name: s5finger/Part2 #! /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: # finger.h # ttyloc.c # ttyrots.c # ttyloc.h # doc # novice # This archive created: Sun Oct 30 14:55:24 1988 export PATH; PATH=/bin:$PATH if test -f 'finger.h' then echo shar: will not over-write existing file "'finger.h'" else cat << \SHAR_EOF > 'finger.h' /* ** finger.h - used in finger, ttyloc, and watson. ** ** Written by Keith Gabryelski ** Released into public domain September 1, 1988. ** Please keep this header. ** */ #include "ttyloc.h" #include "dbase.h" #define KMEM_FILE "/dev/kmem" #define MEM_FILE "/dev/mem" #define SWAP_FILE "/dev/swap" #define DEFAULT_IDLE_TIME (30 * 60) /* ** whatarewe - A variable with oodles of info about how this finger should ** look. Ie, are we a whois? Should we show a plan? Should ** we show mail box info. */ #define LONG 0x00000001 /* Pertinent info about this user. */ #define PLAN 0x00000002 /* Show a plan if has one. */ #define MAILBOX 0x00000004 /* Show mailbox info if any. */ #define HIDABLE 0x00000008 /* Unames hidden if repeated? */ #define SORT_BY_NAME 0x00000000 /* Sort list by name. */ #define SORT_BY_IDLE 0x00000010 /* Sort list by Idle time. */ #define SORT_BY_TTY 0x00000020 /* Sort list by ttyname. */ #define SORT_MASK 0x00000030 /* Sort mask for above. */ #define DIALOUT 0x00000040 /* Show DIALOUT lines. (for SCO only)*/ #define WHOIS (LONG|PLAN|MAILBOX) /* whois. */ #define FINGER (HIDABLE) /* default. */ extern void get_dbase_info(); extern char *puterr(), *mymalloc(), *myrealloc(); /* ** Some defines for easy access to nlist struct. */ #define v_addr nl[0].n_value #define proc_addr nl[1].n_value /* ** Below are machine dependent macros and definitions. On XENIX ** p_addr[0].te_frameno has the page number of the user structure in ** /dev/mem. On the 3B1 it's just p_addr[0]. No sweat. */ #ifdef SCO_XENIX_386 /* ** Tested on SCO XENIX 2.2.1. on a Zenith 386. ** */ /* ** Define for all types of SCO systems. */ #define SCO_XENIX #define IN_CORE_USER_STRUCT_ADDRESS ctob(proc[i].p_addr[0].te_frameno) #define SWAPPED_USER_STRUCT_ADDRESS ctob(proc[i].p_addr[0].te_frameno) #endif /* SCO_XENIX_386 */ #ifdef SCO_XENIX_286 /* ** NOT TESTED. THIS SHOULDN'T WORK!!! ** */ /* ** Define for all types of SCO systems. */ #define SCO_XENIX /* ** Couldn't find this in the headers. Is it somewhere? ** dbtob == disk blocks to bytes. */ #define dbtob(blocks) ((blocks) * NBPC * NDPC) #define IN_CORE_USER_STRUCT_ADDRESS ctob(proc[i].p_uaddr) #define SWAPPED_USER_STRUCT_ADDRESS dbtob(proc[i].p_addr.p_daddr) #endif /* SCO_XENIX_286 */ /* ** SCO_XENIX defined for all sco machines. Hardware unrelated. */ #ifdef SCO_XENIX /* ** Stuff that is the same for all SCO systems. */ #define KERNEL_FILE "/xenix" #endif /* SCO_XENIX */ #ifdef UNIX_PC /* ** Tested on an AT&T 3b1 (unix pc) SysV.2 machine. */ #define KERNEL_FILE "/unix" #define IN_CORE_USER_STRUCT_ADDRESS (ctob(proc[i].p_addr[0]) + U_OFFSET) #define SWAPPED_USER_STRUCT_ADDRESS dbtob(proc[i].p_swaddr) /* ** If proc is a pointer to an array of struct proc then we must do ** indirection. It is on the 3b1. */ #define DO_INDIRECTION_ON_PROC /* ** Symbols on the Unix PC do not have prefixed underlines. */ #define NO_PREFIXED_UNDERLINES_IN_SYMBOLS #define NEED_NLIST.H #endif /* UNIX_PC */ #ifdef SYSV_3B5 /* ** Not Tested yet, for I didn't have root privileges on ** the machine. I'm not real sure about SWAPPED_USER_STRUCT_ADDRESS. */ #define KERNEL_FILE "/unix" #define IN_CORE_USER_STRUCT_ADDRESS ctob(proc[i].p_addr) #define SWAPPED_USER_STRUCT_ADDRESS proc[i].p_swaddr /* ** Symbols on the 3B5 do not have prefixed underlines. */ #define NO_PREFIXED_UNDERLINES_IN_SYMBOLS #define NEED_NLIST.H #endif /* SYSV_3B5 */ /* ** nlist structure. */ #ifdef NO_PREFIX_UNDERLINES_IN_SYMBOLS struct nlist nl[] = { { "v", }, { "proc", }, { "", }, }; #else /* !NO_PREFIX_UNDERLINES_IN_SYMBOLS */ struct nlist nl[] = { { "_v", }, { "_proc", }, { "", }, }; #endif /* NO_PREFIX_UNDERLINES_IN_SYMBOLS */ SHAR_EOF fi # end of overwriting check if test -f 'ttyloc.c' then echo shar: will not over-write existing file "'ttyloc.c'" else cat << \SHAR_EOF > 'ttyloc.c' /* ** ttyloc.c - Setup names for ttys. ** - For the finger distribution. ** ** Written by Keith Gabryelski ** Released into public domain September 1, 1988. ** Please keep this header. ** ** Main routine for ttyloc. */ #include <stdio.h> #include <sys/types.h> #include <sys/stat.h> #include <fcntl.h> #include <pwd.h> #include "defs.h" #include "ttyloc.h" extern int errno; extern char *getlogin(), *ttyname(), *strrchr(); extern struct passwd *getpwnam(); extern char *mymalloc(), *myrealloc(); char *progname; /* Our name */ main(argc, argv) int argc; char **argv; { char *ptr, *ttymess = mymalloc(1); char *tty_name = NULL; char *ttyfile, *word; int options, dflag = FALSE, newdefault = FALSE, specified = FALSE; ttymess[0] = '\0'; progname = *argv++; --argc; options = TRUE; while (argc--) { if (**argv != '-') options = FALSE; else if (options) { if (!strcmp(*argv, "--")) options = FALSE; else { /* ** Do the option thing. */ word = *argv+1; while (*word != '\0') switch(*word++) { case 'd': /* Use defaults file (~/.ttyloc). */ dflag = TRUE; if (*word == '\0') { if (argc > 0) if (**argv != '-') { ttyfile = *argv++; /* Use this file. */ --argc; newdefault = TRUE; } } else { ttyfile = word; newdefault = TRUE; } word = ""; break; case 't': /* For a specific TTY. */ if (*word == '\0') /* ttyfrob -- with apologize */ if (argc--) /* to GZT.COLE. */ word = *++argv; else { fprintf(stderr, "%s: `-t' switch specified with no argument.\n", progname); exit(-1); } tty_name = word; word = ""; break; default: fprintf(stderr, "%s: invalid switch '%c'.\n", progname, *word); usage(); } } *argv++; continue; } specified = TRUE; ttymess = myrealloc(ttymess, strlen(ttymess) + strlen(*argv) + sizeof(" ")); strcat(ttymess, *argv++); if (argc) strcat(ttymess, " "); } #ifdef DEBUG if (specified) { puts("specified"); puts(ttymess); } #endif /* DEBUG */ if (tty_name == NULL) { if ((ptr = ttyname(2)) == NULL) /* I can just feel the bogusity */ { fprintf(stderr, "%s: not connected to a tty.\n", progname); exit(-1); } if ((ptr = strrchr(ptr, '/')) != NULL) tty_name = ptr + 1; else { fprintf(stderr, "%s: can't grok your tty.\n", progname); exit(-1); } } if (dflag) if (specified) { fprintf(stderr, "%s: `-d' switch with literal ttyloc string.\n", progname); exit(-1); } else { char *buffer, *bufferend, *bp, *cp; int fd, size; struct stat stbuf; /* Read from default ttyloc file. */ if (!newdefault) /* Tack on users home directory? */ { char *name = getlogin(); struct passwd *pw; if (name == NULL) { fprintf(stderr, "%s: can't figure you out.\n", progname); exit(-1); } if ((pw = getpwnam(name)) == (struct passwd *)NULL) { fprintf(stderr, "%s: can't find your home directory.\n", progname); exit(-1); } ttyfile = mymalloc(strlen(pw->pw_dir) + 1 + sizeof(DEFAULT_TTYLOC_FILE)); strcpy(ttyfile, pw->pw_dir); strcat(ttyfile, "/"); strcat(ttyfile, DEFAULT_TTYLOC_FILE); } if ((fd = open(ttyfile, O_RDONLY)) < 0) { fprintf(stderr, "%s: couldn't open defaults file %s (%s).\n", progname, ttyfile, puterr(errno)); exit(-1); } if (fstat(fd, &stbuf) < 0) { fprintf(stderr, "%s: couldn't stat defaults file %s (%s).\n", progname, ttyfile, puterr(errno)); exit(-1); } size = stbuf.st_size; buffer = mymalloc(size + 1); bufferend = buffer + size; if (read(fd, buffer, size) != size) { fprintf(stderr, "%s: read failed on %s (%s).\n", progname, ttyfile, puterr(errno)); exit(-1); } bp = buffer; while (bp < bufferend) { for (cp = bp; *bp != ':' && bp < bufferend; ++bp) ; *bp++ = '\0'; if (!strcmp(cp, tty_name) || !strcmp(cp, "default")) { ttymess = bp; while (*bp != '\n' && bp < bufferend) bp++; *bp = '\0'; break; } else { while (*bp != '\n' && bp < bufferend) ++bp; if (*bp == '\n' && bp < bufferend) ++bp; } } } if (specified || dflag) { if (set_ttyloc(tty_name, ttymess) == -1) { fprintf(stderr, "%s: couldn't set ttyloc.\n", progname); exit(-1); } } else if ((ptr = get_ttyloc(tty_name)) == NULL) { fprintf(stderr, "%s: No ttyloc entry for %s.\n", progname, tty_name); exit(-1); } else printf("%.*s\n", strnlen(ptr, TTYLOC_LENGTH), ptr); exit(0); } usage() { fprintf(stderr, "%s: usage %s [-d [deffile]] [-t ttyname].\n", progname, progname); exit(-1); } SHAR_EOF fi # end of overwriting check if test -f 'ttyrots.c' then echo shar: will not over-write existing file "'ttyrots.c'" else cat << \SHAR_EOF > 'ttyrots.c' /* ** ttyrots.c - For the finger distribution. ** ** Written by Keith Gabryelski ** Released into public domain September 1, 1988. ** Please keep this header. ** ** Some basic routines used in finger and ttyloc. */ #include <stdio.h> #include <sys/types.h> #include <sys/stat.h> #include <utmp.h> #include <fcntl.h> #include "ttyloc.h" #include "defs.h" extern int errno; extern struct utmp *getutline(); extern struct ltmp *getltline(); extern char *myrealloc(); static char *tlocbuf = NULL; static char * get_default_ttyloc(ttyname) char *ttyname; { char *ttyloc = "", *tlocbufend, *bp, *cp; int fd, size; struct stat stbuf; if ((fd = open(TTYLOCS, O_RDONLY)) < 0 || fstat(fd, &stbuf) < 0) return ttyloc; size = stbuf.st_size; tlocbuf = myrealloc(tlocbuf, size + 1); tlocbufend = tlocbuf + size; if (read(fd, tlocbuf, size) != size) return ttyloc; close(fd); bp = tlocbuf; while (bp < tlocbufend) { for (cp = bp; *bp != ':' && bp < tlocbufend; ++bp) ; *bp++ = '\0'; if (!strcmp(cp, ttyname)) { ttyloc = bp; while (*bp != '\n' && bp < tlocbufend) bp++; *bp = '\0'; break; } else { while (*bp != '\n' && bp < tlocbufend) ++bp; if (*bp == '\n' && bp < tlocbufend) ++bp; } } return ttyloc; } char * get_ttyloc(ttyname) char *ttyname; { char *bp, *cp; struct ltmp *lt; static struct utmp utbuf, *ut; strncpy(utbuf.ut_line, ttyname, sizeof(utbuf.ut_line)); if ((ut = getutline(&utbuf)) == (struct utmp *)NULL) return NULL; bp = get_default_ttyloc(ttyname); if ((lt = getltline(ttyname)) == (struct ltmp *)NULL || lt->lt_time != ut->ut_time) { cp = bp; while (*bp != ':' && *bp != '\0') bp++; *bp = '\0'; return cp; } return lt->lt_loc; } set_ttyloc(ttyname, ttyloc) char *ttyname, *ttyloc; { char *bp, *cp; int l, fd; static struct ltmp lt; static struct utmp utbuf, *ut; strncpy(utbuf.ut_line, ttyname, sizeof(utbuf.ut_line)); if ((ut = getutline(&utbuf)) == (struct utmp *)NULL) return FAIL; if ((fd = open(LTMP, O_CREAT|O_RDWR, 0622)) < 0) return FAIL; while (read(fd, <, sizeof(struct ltmp)) == sizeof(struct ltmp)) if (!strcmp(lt.lt_line, ut->ut_line)) { lseek(fd, (long)-sizeof(struct ltmp), 1); break; } /* lseek to something divisible by sizeof struct ltmp */ lseek(fd, lseek(fd, 0, 1) / (long)sizeof(struct ltmp) * (long)sizeof(struct ltmp), 0); strncpy(lt.lt_line, ut->ut_line, sizeof(lt.lt_line)); lt.lt_time = ut->ut_time; #ifdef DEBUG printf("line = %s, time = %lx.\n", lt.lt_line, lt.lt_time); #endif /* DEBUG */ bp = get_default_ttyloc(ttyname); #ifdef DEBUG printf("bp = `%s'.\n", bp); #endif /* DEBUG */ cp = bp; while (*bp != ':' && *bp != '\0') bp++; if (ttyloc == NULL || *ttyloc == '\0' || *bp == '\0') { *bp = '\0'; strncpy(lt.lt_loc, cp, sizeof(lt.lt_loc)); #ifdef DEBUG printf("put default %s.\n", cp); #endif /* DEBUG */ } else if (*++bp != '\0') { strncpy(lt.lt_loc, bp, sizeof(lt.lt_loc)); l = strnlen(lt.lt_loc, sizeof(lt.lt_loc)); strncpy(lt.lt_loc+l, ": ", sizeof(lt.lt_loc)-l); l = strnlen(lt.lt_loc, sizeof(lt.lt_loc)); strncpy(lt.lt_loc+l, ttyloc, sizeof(lt.lt_loc)-l); #ifdef DEBUG printf("put :+ %s.\n", lt.lt_loc); #endif /* DEBUG */ } else { strncpy(lt.lt_loc, ttyloc, sizeof(lt.lt_loc)); #ifdef DEBUG printf("put ttyloc %s.\n", lt.lt_loc); #endif /* DEBUG */ } write(fd, <, sizeof(struct ltmp)); close(fd); return OK; } struct ltmp * getltline(line) char line[12]; { int fd; static struct ltmp lt; if ((fd = open(LTMP, O_RDONLY)) < 0) return (struct ltmp *)NULL; while (read(fd, <, sizeof(struct ltmp)) == sizeof(struct ltmp)) if (!strcmp(lt.lt_line, line)) { close(fd); return < } close(fd); return (struct ltmp *)NULL; } SHAR_EOF fi # end of overwriting check if test -f 'ttyloc.h' then echo shar: will not over-write existing file "'ttyloc.h'" else cat << \SHAR_EOF > 'ttyloc.h' /* ** ttyloc.h - For the finger distribution. ** ** Written by Keith Gabryelski ** Released into public domain September 1, 1988. ** Please keep this header. */ #define TTYLOCS "/etc/ttylocs" #define LTMP "/etc/ltmp" #define DEFAULT_TTYLOC_FILE ".ttylocs" #define TTYLOC_LENGTH 50 struct ltmp { char lt_line[12]; /* Ttyname. */ char lt_loc[TTYLOC_LENGTH]; /* Ttyloc string. */ time_t lt_time; /* Time stamp from utmp. */ }; extern char *get_ttyloc(); extern int set_ttyloc(); SHAR_EOF fi # end of overwriting check if test ! -d 'doc' then mkdir 'doc' fi cd 'doc' if test -f 'finger.1' then echo shar: will not over-write existing file "'finger.1'" else cat << \SHAR_EOF > 'finger.1' .TH FINGER LOCAL .SH NAME finger, whois, \- Who is on the system. .SH SYNOPSIS .B finger [-DIMPSTlmpw] [-i[hh:]mm] [*] [.] [username] .SH DESCRIPTION .B finger will display users that are currently on the system with some useful information. The format of finger, with examples, are shown below: .nf -Name- -Group- --Full Name-- -What- Idle -TTY- -Loc- ag wheel Keith Gabryelski emacs tty02 window2 ksh 1 tty04 window4 root root The root of all evil sh 15:26*tty01 window1 tyg user Marla Gabryelski ksh 3:18 tty10 window10 .fi In the above example: .RS User `ag' is logged on twice. One on tty02 running emacs with no idle time and also on tty04 at a korn shell prompt with a 1 minute idle time. User `ag' is group wheel and his real name is "Keith Gabryelski". root is logged in on tty01 at a Bounre shell prompt with an idle time of 15 hours and 26 minutes. root's is not receiving messages (denoted by the asterisk by the tty name). tyg (Marla Gabryelski) is logged in on tty10 at a ksh prompt with an idle time of 3 hours and 18 minutes. .RE .B whois displays users that are currently on the system with some in depth information about the users. The format of whois, with examples, are shown below: .nf -Name- -Group- --Full Name-- -What- Idle -TTY- -Console- ag wheel Keith Gabryelski emacs tty02 window2 ksh 9 tty04 window4 (Keith) </u/ag> Hacking finger and other system commands. [100, 50] [/bin/ksh] Birthday June 14 Home 10191 Maya Linda Rd. Apt 51; Phone 619 566-2279 Work Elgar Corporation; 9450 Brown Deer Rd. San Diego; Phone 619 458-0210 [ag has had no mail since Sat Aug 6 16:17:36 1988] Tigger's don't climb trees. Plan: to 'ag'gravate the world... root root The root of all evil sh 15:34*tty01 window1 (root-boy) </> Hacking your id into shreads for I am uid 0! [0, 0] [/bin/sh] [root has had no mail since Fri Aug 5 10:55:16 1988] tyg user Marla Gabryelski ksh 3:25 tty10 window10 (tyg) </u/tyg> Hacking Mah Jongg for the fun of it. [99, 51] [/bin/ksh] Birthday January 11 Home 10191 Maya Linda Rd. Apt 51; Phone 566-2279 Work is boring, so I'm never there.; [tyg has had no mail since Thu Jul 14 23:00:26 1988] The wonderful thing about Tiggers are Tiggers are wonderful things. Their tops are made out of rubber. Their bottoms are made of of springs. They're bouncey trouncey bouncey trouncey FUN! FUN! FUN! FUN! FUN! The wonderful thing about tiggers is ... I'm the only one! A. A. Milne .fi .RS The format is obvious. I shall not explain it. .RE .SH OPTIONS Output of finger can be formated by the following options: .TP -D This options is only valid on SCO Xenix systems. Finger (and whois) will not usually display a port that is used as a DIALOUT. This options will display DIALOUT lines if there are any currently are in use. .TP -I Sort by idle time. From least to longest idle time. -S is implicitly specified with this option. .TP -M Force no display of mailbox info. .TP -P Force no display of plan. .TP -S Show repeated user names on output. .TP -T Sort by tty. -S is implicitly specified with this option. .TP -l Long output. Like whois without mailbox and plan info. .TP -m Display mailbox info if available. .TP -p Display plan if available. .TP -w Do a whois. Like doing a finger -lmp .TP -i[[hh:]mm] Don't show users with idle times greater than `hh' hours and `mm' minutes. Deault is 30 minutes (:30). .TP * Show all users in the data base. .TP \. Show current user (yourself). .TP username Show username whether logged in or not. .SH FILES .nf ~/.plan The plan. /usr/lib/finger/dbase/* database information for whois. /usr/lib/finger/nlist nlist for quick access to the kernel. .fi .SH SEE ALSO bwiz(1), inquire(1), ttyloc(1), watson(1) .SH AUTHOR .RS .PP Keith M. Gabryelski (ag@elgar.UUCP) .RE SHAR_EOF fi # end of overwriting check cd .. if test ! -d 'novice' then mkdir 'novice' fi cd 'novice' if test -f 'nickname' then echo shar: will not over-write existing file "'nickname'" else cat << \SHAR_EOF > 'nickname' This field is should be filled with any nickname you use. SHAR_EOF fi # end of overwriting check if test -f 'workphone' then echo shar: will not over-write existing file "'workphone'" else cat << \SHAR_EOF > 'workphone' Your phone number and/or extension at work. Examples of the typical format of work phones are: (212) 222-1414 222-1414 x42 222-1414 x1414 SHAR_EOF fi # end of overwriting check if test -f 'workaddress' then echo shar: will not over-write existing file "'workaddress'" else cat << \SHAR_EOF > 'workaddress' The place where you work. Usually the name of the company, a street address, and city. Like: Ardvark Emporium; 42 Zoo Place, Anytown SHAR_EOF fi # end of overwriting check if test -f 'homeaddress' then echo shar: will not over-write existing file "'homeaddress'" else cat << \SHAR_EOF > 'homeaddress' Your home address; street address and city. Like: 69 Homey Lane, Anytown USA SHAR_EOF fi # end of overwriting check if test -f 'homephone' then echo shar: will not over-write existing file "'homephone'" else cat << \SHAR_EOF > 'homephone' Your home phone number. SHAR_EOF fi # end of overwriting check if test -f 'birthday' then echo shar: will not over-write existing file "'birthday'" else cat << \SHAR_EOF > 'birthday' The month and day of your birthday (not the year). This must be in the form <month> <day>. As in: July 1 June 14 February 29 SHAR_EOF fi # end of overwriting check if test -f 'supervisor' then echo shar: will not over-write existing file "'supervisor'" else cat << \SHAR_EOF > 'supervisor' Your supervisor's name (or possibly something else). This field will be displayed when users use whois along with your project field in the following format. Hacking PROJECT for SUPERVISOR SHAR_EOF fi # end of overwriting check if test -f 'project' then echo shar: will not over-write existing file "'project'" else cat << \SHAR_EOF > 'project' Your current project. This field will be displayed when users use whois along with your supervisor field in the following format. Hacking PROJECT for SUPERVISOR SHAR_EOF fi # end of overwriting check if test -f 'remark' then echo shar: will not over-write existing file "'remark'" else cat << \SHAR_EOF > 'remark' Some statement that you would like to share with the rest of the users on the system. SHAR_EOF fi # end of overwriting check if test -f 'firstimer' then echo shar: will not over-write existing file "'firstimer'" else cat << \SHAR_EOF > 'firstimer' Watson is an interactive whois data base manager. Watson will ask you questions about yourself and the work you do on this system. The information asked (and stored) by watson will be retrievable by others on the system so they may learn more about you and your work. Questions asked by watson: Nickname: A nick name that you use in place of you real name. Work-Address: The name and address of the company you work for. Work-Phone: Your work phone number Home-Address: Your home address. Home-Phone: Your home phone number. Birthday: The month and day (not year) of your birthday. Project: The project you are currently working on. Supervisor: Your supervisor or insparation. Remarks: Any random remark. You may use a `?' mark for help on commands. Use "done" to save the changes you have made to the database or "quit" to exit without saving current settings. SHAR_EOF fi # end of overwriting check cd .. # End of shell archive exit 0 -- ag@elgar.CTS.COM Keith Gabryelski ...!{ucsd, jack}!elgar!ag