diff options
author | rgrimes <rgrimes@FreeBSD.org> | 1994-05-27 12:33:43 +0000 |
---|---|---|
committer | rgrimes <rgrimes@FreeBSD.org> | 1994-05-27 12:33:43 +0000 |
commit | f9ab90d9d6d02989a075d0f0074496d5b1045e4b (patch) | |
tree | add7e996bac5289cdc55e6935750c352505560a9 /usr.bin/finger | |
parent | be22b15ae2ff8d7fe06b6e14fddf0c5b444a95da (diff) | |
download | FreeBSD-src-f9ab90d9d6d02989a075d0f0074496d5b1045e4b.zip FreeBSD-src-f9ab90d9d6d02989a075d0f0074496d5b1045e4b.tar.gz |
BSD 4.4 Lite Usr.bin Sources
Diffstat (limited to 'usr.bin/finger')
-rw-r--r-- | usr.bin/finger/Makefile | 6 | ||||
-rw-r--r-- | usr.bin/finger/extern.h | 50 | ||||
-rw-r--r-- | usr.bin/finger/finger.1 | 161 | ||||
-rw-r--r-- | usr.bin/finger/finger.c | 257 | ||||
-rw-r--r-- | usr.bin/finger/finger.h | 63 | ||||
-rw-r--r-- | usr.bin/finger/lprint.c | 333 | ||||
-rw-r--r-- | usr.bin/finger/net.c | 148 | ||||
-rw-r--r-- | usr.bin/finger/sprint.c | 148 | ||||
-rw-r--r-- | usr.bin/finger/util.c | 381 |
9 files changed, 1547 insertions, 0 deletions
diff --git a/usr.bin/finger/Makefile b/usr.bin/finger/Makefile new file mode 100644 index 0000000..944f1d0 --- /dev/null +++ b/usr.bin/finger/Makefile @@ -0,0 +1,6 @@ +# @(#)Makefile 8.1 (Berkeley) 6/6/93 + +PROG= finger +SRCS= finger.c lprint.c net.c sprint.c util.c + +.include <bsd.prog.mk> diff --git a/usr.bin/finger/extern.h b/usr.bin/finger/extern.h new file mode 100644 index 0000000..2b675f1 --- /dev/null +++ b/usr.bin/finger/extern.h @@ -0,0 +1,50 @@ +/*- + * Copyright (c) 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. + * + * @(#)extern.h 8.1 (Berkeley) 6/6/93 + */ + +extern char tbuf[1024]; /* Temp buffer for anybody. */ +extern int entries; /* Number of people. */ +extern DB *db; /* Database. */ + +void enter_lastlog __P((PERSON *)); +PERSON *enter_person __P((struct passwd *)); +void enter_where __P((struct utmp *, PERSON *)); +void err __P((const char *, ...)); +PERSON *find_person __P((char *)); +void lflag_print __P((void)); +int match __P((struct passwd *, char *)); +void netfinger __P((char *)); +PERSON *palloc __P((void)); +char *prphone __P((char *)); +void sflag_print __P((void)); diff --git a/usr.bin/finger/finger.1 b/usr.bin/finger/finger.1 new file mode 100644 index 0000000..069f9cd --- /dev/null +++ b/usr.bin/finger/finger.1 @@ -0,0 +1,161 @@ +.\" Copyright (c) 1989, 1990, 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. +.\" +.\" @(#)finger.1 8.2 (Berkeley) 2/16/94 +.\" +.Dd February 16, 1994 +.Dt FINGER 1 +.Os BSD 4 +.Sh NAME +.Nm finger +.Nd user information lookup program +.Sh SYNOPSIS +.Nm finger +.Op Fl lmsp +.Op Ar user ... +.Op Ar user@host ... +.Sh DESCRIPTION +The +.Nm finger +displays information about the system users. +.Pp +Options are: +.Bl -tag -width flag +.It Fl s +.Nm Finger +displays the user's login name, real name, terminal name and write +status (as a ``*'' before the terminal name if write permission is +denied), idle time, login time, office location and office phone +number. +.Pp +Idle time is in minutes if it is a single integer, hours and minutes +if a ``:'' is present, or days if a ``d'' is present. +Login time is displayed as month, day, hours and minutes, unless +more than six months ago, in which case the year is displayed rather +than the hours and minutes. +.Pp +Unknown devices as well as nonexistent idle and login times are +displayed as single asterisks. +.Pp +.It Fl l +Produces a multi-line format displaying all of the information +described for the +.Fl s +option as well as the user's home directory, home phone number, login +shell, and the contents of the files +.Dq Pa .forward , +.Dq Pa .plan +and +.Dq Pa .project +from the user's home directory. +.Pp +If idle time is at least a minute and less than a day, it is +presented in the form ``hh:mm''. +Idle times greater than a day are presented as ``d day[s]hh:mm''. +.Pp +Phone numbers specified as eleven digits are printed as ``+N-NNN-NNN-NNNN''. +Numbers specified as ten or seven digits are printed as the appropriate +subset of that string. +Numbers specified as five digits are printed as ``xN-NNNN''. +.Pp +If write permission is denied to the device, the phrase ``(messages off)'' +is appended to the line containing the device name. +One entry per user is displayed with the +.Fl l +option; if a user is logged on multiple times, terminal information +is repeated once per login. +.Pp +.It Fl p +Prevents +the +.Fl l +option of +.Nm finger +from displaying the contents of the +.Dq Pa .forward , +.Dq Pa .plan +and +.Dq Pa .project +files. +.It Fl m +Prevent matching of +.Ar user +names. +.Ar User +is usually a login name; however, matching will also be done on the +users' real names, unless the +.Fl m +option is supplied. +All name matching performed by +.Nm finger +is case insensitive. +.El +.Pp +If no options are specified, +.Nm finger +defaults to the +.Fl l +style output if operands are provided, otherwise to the +.Fl s +style. +Note that some fields may be missing, in either format, if information +is not available for them. +.Pp +If no arguments are specified, +.Nm finger +will print an entry for each user currently logged into the system. +.Pp +.Nm Finger +may be used to look up users on a remote machine. +The format is to specify a +.Ar user +as +.Dq Li user@host , +or +.Dq Li @host , +where the default output +format for the former is the +.Fl l +style, and the default output format for the latter is the +.Fl s +style. +The +.Fl l +option is the only option that may be passed to a remote machine. +.Sh SEE ALSO +.Xr chpass 1 , +.Xr w 1 , +.Xr who 1 , +.Sh HISTORY +The +.Nm finger +command appeared in +.Bx 3.0 . diff --git a/usr.bin/finger/finger.c b/usr.bin/finger/finger.c new file mode 100644 index 0000000..5a16765 --- /dev/null +++ b/usr.bin/finger/finger.c @@ -0,0 +1,257 @@ +/* + * Copyright (c) 1989, 1993 + * The Regents of the University of California. All rights reserved. + * + * This code is derived from software contributed to Berkeley by + * Tony Nardo of the Johns Hopkins University/Applied Physics Lab. + * + * 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 +static char copyright[] = +"@(#) Copyright (c) 1989, 1993\n\ + The Regents of the University of California. All rights reserved.\n"; +#endif /* not lint */ + +#ifndef lint +static char sccsid[] = "@(#)finger.c 8.2 (Berkeley) 9/30/93"; +#endif /* not lint */ + +/* + * Finger prints out information about users. It is not portable since + * certain fields (e.g. the full user name, office, and phone numbers) are + * extracted from the gecos field of the passwd file which other UNIXes + * may not have or may use for other things. + * + * There are currently two output formats; the short format is one line + * per user and displays login name, tty, login time, real name, idle time, + * and office location/phone number. The long format gives the same + * information (in a more legible format) as well as home directory, shell, + * mail info, and .plan/.project files. + */ + +#include <sys/param.h> +#include <fcntl.h> +#include <time.h> +#include <pwd.h> +#include <utmp.h> +#include <errno.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <db.h> +#include "finger.h" + +DB *db; +time_t now; +int entries, lflag, mflag, pplan, sflag; +char tbuf[1024]; + +static void loginlist __P((void)); +static void userlist __P((int, char **)); + +main(argc, argv) + int argc; + char **argv; +{ + int ch; + + while ((ch = getopt(argc, argv, "lmps")) != EOF) + switch(ch) { + case 'l': + lflag = 1; /* long format */ + break; + case 'm': + mflag = 1; /* force exact match of names */ + break; + case 'p': + pplan = 1; /* don't show .plan/.project */ + break; + case 's': + sflag = 1; /* short format */ + break; + case '?': + default: + (void)fprintf(stderr, + "usage: finger [-lmps] [login ...]\n"); + exit(1); + } + argc -= optind; + argv += optind; + + (void)time(&now); + setpassent(1); + if (!*argv) { + /* + * Assign explicit "small" format if no names given and -l + * not selected. Force the -s BEFORE we get names so proper + * screening will be done. + */ + if (!lflag) + sflag = 1; /* if -l not explicit, force -s */ + loginlist(); + if (entries == 0) + (void)printf("No one logged on.\n"); + } else { + userlist(argc, argv); + /* + * Assign explicit "large" format if names given and -s not + * explicitly stated. Force the -l AFTER we get names so any + * remote finger attempts specified won't be mishandled. + */ + if (!sflag) + lflag = 1; /* if -s not explicit, force -l */ + } + if (entries) + if (lflag) + lflag_print(); + else + sflag_print(); + exit(0); +} + +static void +loginlist() +{ + register PERSON *pn; + DBT data, key; + struct passwd *pw; + struct utmp user; + int r, sflag; + char name[UT_NAMESIZE + 1]; + + if (!freopen(_PATH_UTMP, "r", stdin)) + err("%s: %s", _PATH_UTMP, strerror(errno)); + name[UT_NAMESIZE] = NULL; + while (fread((char *)&user, sizeof(user), 1, stdin) == 1) { + if (!user.ut_name[0]) + continue; + if ((pn = find_person(user.ut_name)) == NULL) { + bcopy(user.ut_name, name, UT_NAMESIZE); + if ((pw = getpwnam(name)) == NULL) + continue; + pn = enter_person(pw); + } + enter_where(&user, pn); + } + if (db && lflag) + for (sflag = R_FIRST;; sflag = R_NEXT) { + r = (*db->seq)(db, &key, &data, sflag); + if (r == -1) + err("db seq: %s", strerror(errno)); + if (r == 1) + break; + enter_lastlog(*(PERSON **)data.data); + } +} + +static void +userlist(argc, argv) + register int argc; + register char **argv; +{ + register PERSON *pn; + DBT data, key; + struct utmp user; + struct passwd *pw; + int r, sflag, *used, *ip; + char **ap, **nargv, **np, **p; + + if ((nargv = malloc((argc+1) * sizeof(char *))) == NULL || + (used = calloc(argc, sizeof(int))) == NULL) + err("%s", strerror(errno)); + + /* Pull out all network requests. */ + for (ap = p = argv, np = nargv; *p; ++p) + if (index(*p, '@')) + *np++ = *p; + else + *ap++ = *p; + + *np++ = NULL; + *ap++ = NULL; + + if (!*argv) + goto net; + + /* + * Traverse the list of possible login names and check the login name + * and real name against the name specified by the user. + */ + if (mflag) + for (p = argv; *p; ++p) + if (pw = getpwnam(*p)) + enter_person(pw); + else + (void)fprintf(stderr, + "finger: %s: no such user\n", *p); + else { + while (pw = getpwent()) + for (p = argv, ip = used; *p; ++p, ++ip) + if (match(pw, *p)) { + enter_person(pw); + *ip = 1; + } + for (p = argv, ip = used; *p; ++p, ++ip) + if (!*ip) + (void)fprintf(stderr, + "finger: %s: no such user\n", *p); + } + + /* Handle network requests. */ +net: for (p = nargv; *p;) + netfinger(*p++); + + if (entries == 0) + return; + + /* + * Scan thru the list of users currently logged in, saving + * appropriate data whenever a match occurs. + */ + if (!freopen(_PATH_UTMP, "r", stdin)) + err("%s: %s", _PATH_UTMP, strerror(errno)); + while (fread((char *)&user, sizeof(user), 1, stdin) == 1) { + if (!user.ut_name[0]) + continue; + if ((pn = find_person(user.ut_name)) == NULL) + continue; + enter_where(&user, pn); + } + if (db) + for (sflag = R_FIRST;; sflag = R_NEXT) { + r = (*db->seq)(db, &key, &data, sflag); + if (r == -1) + err("db seq: %s", strerror(errno)); + if (r == 1) + break; + enter_lastlog(*(PERSON **)data.data); + } +} diff --git a/usr.bin/finger/finger.h b/usr.bin/finger/finger.h new file mode 100644 index 0000000..5104425 --- /dev/null +++ b/usr.bin/finger/finger.h @@ -0,0 +1,63 @@ +/* + * Copyright (c) 1989, 1993 + * The Regents of the University of California. All rights reserved. + * + * This code is derived from software contributed to Berkeley by + * Tony Nardo of the Johns Hopkins University/Applied Physics Lab. + * + * 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. + * + * @(#)finger.h 8.1 (Berkeley) 6/6/93 + */ + +typedef struct person { + uid_t uid; /* user id */ + char *dir; /* user's home directory */ + char *homephone; /* pointer to home phone no. */ + char *name; /* login name */ + char *office; /* pointer to office name */ + char *officephone; /* pointer to office phone no. */ + char *realname; /* pointer to full name */ + char *shell; /* user's shell */ + struct where *whead, *wtail; /* list of where user is or has been */ +} PERSON; + +enum status { LASTLOG, LOGGEDIN }; + +typedef struct where { + struct where *next; /* next place user is or has been */ + enum status info; /* type/status of request */ + short writable; /* tty is writable */ + time_t loginat; /* time of (last) login */ + time_t idletime; /* how long idle (if logged in) */ + char tty[UT_LINESIZE+1]; /* null terminated tty line */ + char host[UT_HOSTSIZE+1]; /* null terminated remote host name */ +} WHERE; + +#include "extern.h" diff --git a/usr.bin/finger/lprint.c b/usr.bin/finger/lprint.c new file mode 100644 index 0000000..d079c24 --- /dev/null +++ b/usr.bin/finger/lprint.c @@ -0,0 +1,333 @@ +/* + * Copyright (c) 1989, 1993 + * The Regents of the University of California. All rights reserved. + * + * This code is derived from software contributed to Berkeley by + * Tony Nardo of the Johns Hopkins University/Applied Physics Lab. + * + * 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 +static char sccsid[] = "@(#)lprint.c 8.1 (Berkeley) 6/6/93"; +#endif /* not lint */ + +#include <sys/types.h> +#include <sys/stat.h> +#include <sys/time.h> +#include <fcntl.h> +#include <time.h> +#include <tzfile.h> +#include <db.h> +#include <pwd.h> +#include <utmp.h> +#include <errno.h> +#include <unistd.h> +#include <stdio.h> +#include <ctype.h> +#include <string.h> +#include <paths.h> +#include "finger.h" + +#define LINE_LEN 80 +#define TAB_LEN 8 /* 8 spaces between tabs */ +#define _PATH_FORWARD ".forward" +#define _PATH_PLAN ".plan" +#define _PATH_PROJECT ".project" + +static int demi_print __P((char *, int)); +static void lprint __P((PERSON *)); +static int show_text __P((char *, char *, char *)); +static void vputc __P((int)); + +void +lflag_print() +{ + extern int pplan; + register PERSON *pn; + register int sflag, r; + DBT data, key; + + for (sflag = R_FIRST;; sflag = R_NEXT) { + r = (*db->seq)(db, &key, &data, sflag); + if (r == -1) + err("db seq: %s", strerror(errno)); + if (r == 1) + break; + pn = *(PERSON **)data.data; + if (sflag != R_FIRST) + putchar('\n'); + lprint(pn); + if (!pplan) { + (void)show_text(pn->dir, + _PATH_FORWARD, "Mail forwarded to"); + (void)show_text(pn->dir, _PATH_PROJECT, "Project"); + if (!show_text(pn->dir, _PATH_PLAN, "Plan")) + (void)printf("No Plan.\n"); + } + } +} + +static void +lprint(pn) + register PERSON *pn; +{ + extern time_t now; + register struct tm *delta; + register WHERE *w; + register int cpr, len, maxlen; + struct tm *tp; + int oddfield; + char *t, *tzn; + + /* + * long format -- + * login name + * real name + * home directory + * shell + * office, office phone, home phone if available + */ + (void)printf("Login: %-15s\t\t\tName: %s\nDirectory: %-25s", + pn->name, pn->realname, pn->dir); + (void)printf("\tShell: %-s\n", *pn->shell ? pn->shell : _PATH_BSHELL); + + /* + * try and print office, office phone, and home phone on one line; + * if that fails, do line filling so it looks nice. + */ +#define OFFICE_TAG "Office" +#define OFFICE_PHONE_TAG "Office Phone" + oddfield = 0; + if (pn->office && pn->officephone && + strlen(pn->office) + strlen(pn->officephone) + + sizeof(OFFICE_TAG) + 2 <= 5 * TAB_LEN) { + (void)snprintf(tbuf, sizeof(tbuf), "%s: %s, %s", + OFFICE_TAG, pn->office, prphone(pn->officephone)); + oddfield = demi_print(tbuf, oddfield); + } else { + if (pn->office) { + (void)snprintf(tbuf, sizeof(tbuf), "%s: %s", + OFFICE_TAG, pn->office); + oddfield = demi_print(tbuf, oddfield); + } + if (pn->officephone) { + (void)snprintf(tbuf, sizeof(tbuf), "%s: %s", + OFFICE_PHONE_TAG, prphone(pn->officephone)); + oddfield = demi_print(tbuf, oddfield); + } + } + if (pn->homephone) { + (void)snprintf(tbuf, sizeof(tbuf), "%s: %s", "Home Phone", + prphone(pn->homephone)); + oddfield = demi_print(tbuf, oddfield); + } + if (oddfield) + putchar('\n'); + + /* + * long format con't: * if logged in + * terminal + * idle time + * if messages allowed + * where logged in from + * if not logged in + * when last logged in + */ + /* find out longest device name for this user for formatting */ + for (w = pn->whead, maxlen = -1; w != NULL; w = w->next) + if ((len = strlen(w->tty)) > maxlen) + maxlen = len; + /* find rest of entries for user */ + for (w = pn->whead; w != NULL; w = w->next) { + switch (w->info) { + case LOGGEDIN: + tp = localtime(&w->loginat); + t = asctime(tp); + tzn = tp->tm_zone; + cpr = printf("On since %.16s (%s) on %s", + t, tzn, w->tty); + /* + * idle time is tough; if have one, print a comma, + * then spaces to pad out the device name, then the + * idle time. Follow with a comma if a remote login. + */ + delta = gmtime(&w->idletime); + if (delta->tm_yday || delta->tm_hour || delta->tm_min) { + cpr += printf("%-*s idle ", + maxlen - strlen(w->tty) + 1, ","); + if (delta->tm_yday > 0) { + cpr += printf("%d day%s ", + delta->tm_yday, + delta->tm_yday == 1 ? "" : "s"); + } + cpr += printf("%d:%02d", + delta->tm_hour, delta->tm_min); + if (*w->host) { + putchar(','); + ++cpr; + } + } + if (!w->writable) + cpr += printf(" (messages off)"); + break; + case LASTLOG: + if (w->loginat == 0) { + (void)printf("Never logged in."); + break; + } + tp = localtime(&w->loginat); + t = asctime(tp); + tzn = tp->tm_zone; + if (now - w->loginat > SECSPERDAY * DAYSPERNYEAR / 2) + cpr = + printf("Last login %.16s %.4s (%s) on %s", + t, t + 20, tzn, w->tty); + else + cpr = printf("Last login %.16s (%s) on %s", + t, tzn, w->tty); + break; + } + if (*w->host) { + if (LINE_LEN < (cpr + 6 + strlen(w->host))) + (void)printf("\n "); + (void)printf(" from %s", w->host); + } + putchar('\n'); + } +} + +static int +demi_print(str, oddfield) + char *str; + int oddfield; +{ + static int lenlast; + int lenthis, maxlen; + + lenthis = strlen(str); + if (oddfield) { + /* + * We left off on an odd number of fields. If we haven't + * crossed the midpoint of the screen, and we have room for + * the next field, print it on the same line; otherwise, + * print it on a new line. + * + * Note: we insist on having the right hand fields start + * no less than 5 tabs out. + */ + maxlen = 5 * TAB_LEN; + if (maxlen < lenlast) + maxlen = lenlast; + if (((((maxlen / TAB_LEN) + 1) * TAB_LEN) + + lenthis) <= LINE_LEN) { + while(lenlast < (4 * TAB_LEN)) { + putchar('\t'); + lenlast += TAB_LEN; + } + (void)printf("\t%s\n", str); /* force one tab */ + } else { + (void)printf("\n%s", str); /* go to next line */ + oddfield = !oddfield; /* this'll be undone below */ + } + } else + (void)printf("%s", str); + oddfield = !oddfield; /* toggle odd/even marker */ + lenlast = lenthis; + return(oddfield); +} + +static int +show_text(directory, file_name, header) + char *directory, *file_name, *header; +{ + struct stat sb; + register FILE *fp; + register int ch, cnt, lastc; + register char *p; + int fd, nr; + + (void)snprintf(tbuf, sizeof(tbuf), "%s/%s", directory, file_name); + if ((fd = open(tbuf, O_RDONLY)) < 0 || fstat(fd, &sb) || + sb.st_size == 0) + return(0); + + /* If short enough, and no newlines, show it on a single line.*/ + if (sb.st_size <= LINE_LEN - strlen(header) - 5) { + nr = read(fd, tbuf, sizeof(tbuf)); + if (nr <= 0) { + (void)close(fd); + return(0); + } + for (p = tbuf, cnt = nr; cnt--; ++p) + if (*p == '\n') + break; + if (cnt <= 1) { + (void)printf("%s: ", header); + for (p = tbuf, cnt = nr; cnt--; ++p) + vputc(lastc = *p); + if (lastc != '\n') + (void)putchar('\n'); + (void)close(fd); + return(1); + } + else + (void)lseek(fd, 0L, SEEK_SET); + } + if ((fp = fdopen(fd, "r")) == NULL) + return(0); + (void)printf("%s:\n", header); + while ((ch = getc(fp)) != EOF) + vputc(lastc = ch); + if (lastc != '\n') + (void)putchar('\n'); + (void)fclose(fp); + return(1); +} + +static void +vputc(ch) + register int ch; +{ + int meta; + + if (!isascii(ch)) { + (void)putchar('M'); + (void)putchar('-'); + ch = toascii(ch); + meta = 1; + } else + meta = 0; + if (isprint(ch) || !meta && (ch == ' ' || ch == '\t' || ch == '\n')) + (void)putchar(ch); + else { + (void)putchar('^'); + (void)putchar(ch == '\177' ? '?' : ch | 0100); + } +} diff --git a/usr.bin/finger/net.c b/usr.bin/finger/net.c new file mode 100644 index 0000000..51f1b43 --- /dev/null +++ b/usr.bin/finger/net.c @@ -0,0 +1,148 @@ +/* + * Copyright (c) 1989, 1993 + * The Regents of the University of California. All rights reserved. + * + * This code is derived from software contributed to Berkeley by + * Tony Nardo of the Johns Hopkins University/Applied Physics Lab. + * + * 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 +static char sccsid[] = "@(#)net.c 8.3 (Berkeley) 1/2/94"; +#endif /* not lint */ + +#include <sys/types.h> +#include <sys/socket.h> +#include <netinet/in.h> +#include <arpa/inet.h> +#include <netdb.h> +#include <db.h> +#include <unistd.h> +#include <pwd.h> +#include <utmp.h> +#include <stdio.h> +#include <ctype.h> +#include <string.h> +#include "finger.h" + +void +netfinger(name) + char *name; +{ + extern int lflag; + register FILE *fp; + register int c, lastc; + struct in_addr defaddr; + struct hostent *hp, def; + struct servent *sp; + struct sockaddr_in sin; + int s; + char *alist[1], *host; + + if (!(host = rindex(name, '@'))) + return; + *host++ = NULL; + if (isdigit(*host) && (defaddr.s_addr = inet_addr(host)) != -1) { + def.h_name = host; + def.h_addr_list = alist; + def.h_addr = (char *)&defaddr; + def.h_length = sizeof(struct in_addr); + def.h_addrtype = AF_INET; + def.h_aliases = 0; + hp = &def; + } else if (!(hp = gethostbyname(host))) { + (void)fprintf(stderr, + "finger: unknown host: %s\n", host); + return; + } + if (!(sp = getservbyname("finger", "tcp"))) { + (void)fprintf(stderr, "finger: tcp/finger: unknown service\n"); + return; + } + sin.sin_family = hp->h_addrtype; + bcopy(hp->h_addr, (char *)&sin.sin_addr, hp->h_length); + sin.sin_port = sp->s_port; + if ((s = socket(hp->h_addrtype, SOCK_STREAM, 0)) < 0) { + perror("finger: socket"); + return; + } + + /* have network connection; identify the host connected with */ + (void)printf("[%s]\n", hp->h_name); + if (connect(s, (struct sockaddr *)&sin, sizeof(sin)) < 0) { + perror("finger: connect"); + (void)close(s); + return; + } + + /* -l flag for remote fingerd */ + if (lflag) + write(s, "/W ", 3); + /* send the name followed by <CR><LF> */ + (void)write(s, name, strlen(name)); + (void)write(s, "\r\n", 2); + + /* + * Read from the remote system; once we're connected, we assume some + * data. If none arrives, we hang until the user interrupts. + * + * If we see a <CR> or a <CR> with the high bit set, treat it as + * a newline; if followed by a newline character, only output one + * newline. + * + * Otherwise, all high bits are stripped; if it isn't printable and + * it isn't a space, we can simply set the 7th bit. Every ASCII + * character with bit 7 set is printable. + */ + if (fp = fdopen(s, "r")) + while ((c = getc(fp)) != EOF) { + c &= 0x7f; + if (c == 0x0d) { + if (lastc == '\r') /* ^M^M - skip dupes */ + continue; + c = '\n'; + lastc = '\r'; + } else { + if (!isprint(c) && !isspace(c)) + c |= 0x40; + if (lastc != '\r' || c != '\n') + lastc = c; + else { + lastc = '\n'; + continue; + } + } + putchar(c); + } + if (lastc != '\n') + putchar('\n'); + putchar('\n'); + (void)fclose(fp); +} diff --git a/usr.bin/finger/sprint.c b/usr.bin/finger/sprint.c new file mode 100644 index 0000000..68deb76 --- /dev/null +++ b/usr.bin/finger/sprint.c @@ -0,0 +1,148 @@ +/* + * Copyright (c) 1989, 1993 + * The Regents of the University of California. All rights reserved. + * + * This code is derived from software contributed to Berkeley by + * Tony Nardo of the Johns Hopkins University/Applied Physics Lab. + * + * 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 +static char sccsid[] = "@(#)sprint.c 8.1 (Berkeley) 6/6/93"; +#endif /* not lint */ + +#include <sys/types.h> +#include <sys/time.h> +#include <time.h> +#include <tzfile.h> +#include <db.h> +#include <pwd.h> +#include <errno.h> +#include <utmp.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include "finger.h" + +static void stimeprint __P((WHERE *)); + +void +sflag_print() +{ + extern time_t now; + register PERSON *pn; + register WHERE *w; + register int sflag, r; + register char *p; + DBT data, key; + + /* + * short format -- + * login name + * real name + * terminal name (the XX of ttyXX) + * if terminal writeable (add an '*' to the terminal name + * if not) + * if logged in show idle time and day logged in, else + * show last login date and time. If > 6 moths, + * show year instead of time. + * office location + * office phone + */ +#define MAXREALNAME 20 + (void)printf("%-*s %-*s %s\n", UT_NAMESIZE, "Login", MAXREALNAME, + "Name", "Tty Idle Login Time Office Office Phone"); + + for (sflag = R_FIRST;; sflag = R_NEXT) { + r = (*db->seq)(db, &key, &data, sflag); + if (r == -1) + err("db seq: %s", strerror(errno)); + if (r == 1) + break; + pn = *(PERSON **)data.data; + + for (w = pn->whead; w != NULL; w = w->next) { + (void)printf("%-*.*s %-*.*s ", UT_NAMESIZE, UT_NAMESIZE, + pn->name, MAXREALNAME, MAXREALNAME, + pn->realname ? pn->realname : ""); + if (!w->loginat) { + (void)printf(" * * No logins "); + goto office; + } + (void)putchar(w->info == LOGGEDIN && !w->writable ? + '*' : ' '); + if (*w->tty) + (void)printf("%-2.2s ", + w->tty[0] != 't' || w->tty[1] != 't' || + w->tty[2] != 'y' ? w->tty : w->tty + 3); + else + (void)printf(" "); + if (w->info == LOGGEDIN) { + stimeprint(w); + (void)printf(" "); + } else + (void)printf(" * "); + p = ctime(&w->loginat); + (void)printf("%.6s", p + 4); + if (now - w->loginat >= SECSPERDAY * DAYSPERNYEAR / 2) + (void)printf(" %.4s", p + 20); + else + (void)printf(" %.5s", p + 11); +office: if (pn->office) + (void)printf(" %-10.10s", pn->office); + else if (pn->officephone) + (void)printf(" %-10.10s", " "); + if (pn->officephone) + (void)printf(" %-.15s", + prphone(pn->officephone)); + putchar('\n'); + } + } +} + +static void +stimeprint(w) + WHERE *w; +{ + register struct tm *delta; + + delta = gmtime(&w->idletime); + if (!delta->tm_yday) + if (!delta->tm_hour) + if (!delta->tm_min) + (void)printf(" "); + else + (void)printf("%5d", delta->tm_min); + else + (void)printf("%2d:%02d", + delta->tm_hour, delta->tm_min); + else + (void)printf("%4dd", delta->tm_yday); +} diff --git a/usr.bin/finger/util.c b/usr.bin/finger/util.c new file mode 100644 index 0000000..c27cf1b --- /dev/null +++ b/usr.bin/finger/util.c @@ -0,0 +1,381 @@ +/* + * Copyright (c) 1989, 1993 + * The Regents of the University of California. All rights reserved. + * + * This code is derived from software contributed to Berkeley by + * Tony Nardo of the Johns Hopkins University/Applied Physics Lab. + * + * 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 +static char sccsid[] = "@(#)util.c 8.1 (Berkeley) 6/6/93"; +#endif /* not lint */ + +#include <sys/param.h> +#include <sys/stat.h> +#include <fcntl.h> +#include <db.h> +#include <pwd.h> +#include <utmp.h> +#include <errno.h> +#include <unistd.h> +#include <stdio.h> +#include <ctype.h> +#include <stdlib.h> +#include <string.h> +#include <paths.h> +#include "finger.h" + +static void find_idle_and_ttywrite __P((WHERE *)); +static void userinfo __P((PERSON *, struct passwd *)); +static WHERE *walloc __P((PERSON *)); + +int +match(pw, user) + struct passwd *pw; + char *user; +{ + register char *p, *t; + char name[1024]; + + if (!strcasecmp(pw->pw_name, user)) + return(1); + + /* + * XXX + * Why do we skip asterisks!?!? + */ + (void)strcpy(p = tbuf, pw->pw_gecos); + if (*p == '*') + ++p; + + /* Ampersands get replaced by the login name. */ + if ((p = strtok(p, ",")) == NULL) + return(0); + + for (t = name; *t = *p; ++p) + if (*t == '&') { + (void)strcpy(t, pw->pw_name); + while (*++t); + } + else + ++t; + for (t = name; p = strtok(t, "\t "); t = NULL) + if (!strcasecmp(p, user)) + return(1); + return(0); +} + +void +enter_lastlog(pn) + register PERSON *pn; +{ + register WHERE *w; + static int opened, fd; + struct lastlog ll; + char doit = 0; + + /* some systems may not maintain lastlog, don't report errors. */ + if (!opened) { + fd = open(_PATH_LASTLOG, O_RDONLY, 0); + opened = 1; + } + if (fd == -1 || + lseek(fd, (long)pn->uid * sizeof(ll), SEEK_SET) != + (long)pn->uid * sizeof(ll) || + read(fd, (char *)&ll, sizeof(ll)) != sizeof(ll)) { + /* as if never logged in */ + ll.ll_line[0] = ll.ll_host[0] = NULL; + ll.ll_time = 0; + } + if ((w = pn->whead) == NULL) + doit = 1; + else if (ll.ll_time != 0) { + /* if last login is earlier than some current login */ + for (; !doit && w != NULL; w = w->next) + if (w->info == LOGGEDIN && w->loginat < ll.ll_time) + doit = 1; + /* + * and if it's not any of the current logins + * can't use time comparison because there may be a small + * discrepency since login calls time() twice + */ + for (w = pn->whead; doit && w != NULL; w = w->next) + if (w->info == LOGGEDIN && + strncmp(w->tty, ll.ll_line, UT_LINESIZE) == 0) + doit = 0; + } + if (doit) { + w = walloc(pn); + w->info = LASTLOG; + bcopy(ll.ll_line, w->tty, UT_LINESIZE); + w->tty[UT_LINESIZE] = 0; + bcopy(ll.ll_host, w->host, UT_HOSTSIZE); + w->host[UT_HOSTSIZE] = 0; + w->loginat = ll.ll_time; + } +} + +void +enter_where(ut, pn) + struct utmp *ut; + PERSON *pn; +{ + register WHERE *w; + + w = walloc(pn); + w->info = LOGGEDIN; + bcopy(ut->ut_line, w->tty, UT_LINESIZE); + w->tty[UT_LINESIZE] = 0; + bcopy(ut->ut_host, w->host, UT_HOSTSIZE); + w->host[UT_HOSTSIZE] = 0; + w->loginat = (time_t)ut->ut_time; + find_idle_and_ttywrite(w); +} + +PERSON * +enter_person(pw) + register struct passwd *pw; +{ + DBT data, key; + PERSON *pn; + + if (db == NULL && + (db = dbopen(NULL, O_RDWR, 0, DB_BTREE, NULL)) == NULL) + err("%s", strerror(errno)); + + key.data = pw->pw_name; + key.size = strlen(pw->pw_name); + + switch((*db->get)(db, &key, &data, 0)) { + case 0: + return(*(PERSON **)data.data); + default: + case -1: + err("db get: %s", strerror(errno)); + /* NOTREACHED */ + case 1: + ++entries; + pn = palloc(); + userinfo(pn, pw); + pn->whead = NULL; + + data.size = sizeof(PERSON *); + data.data = &pn; + if ((*db->put)(db, &key, &data, 0)) + err("%s", strerror(errno)); + return(pn); + } +} + +PERSON * +find_person(name) + char *name; +{ + register int cnt; + DBT data, key; + char buf[UT_NAMESIZE + 1]; + + if (!db) + return(NULL); + + /* Name may be only UT_NAMESIZE long and not NUL terminated. */ + for (cnt = 0; cnt < UT_NAMESIZE && *name; ++name, ++cnt) + buf[cnt] = *name; + buf[cnt] = '\0'; + key.data = buf; + key.size = cnt; + + return((*db->get)(db, &key, &data, 0) ? NULL : *(PERSON **)data.data); +} + +PERSON * +palloc() +{ + PERSON *p; + + if ((p = malloc((u_int) sizeof(PERSON))) == NULL) + err("%s", strerror(errno)); + return(p); +} + +static WHERE * +walloc(pn) + register PERSON *pn; +{ + register WHERE *w; + + if ((w = malloc((u_int) sizeof(WHERE))) == NULL) + err("%s", strerror(errno)); + if (pn->whead == NULL) + pn->whead = pn->wtail = w; + else { + pn->wtail->next = w; + pn->wtail = w; + } + w->next = NULL; + return(w); +} + +char * +prphone(num) + char *num; +{ + register char *p; + int len; + static char pbuf[15]; + + /* don't touch anything if the user has their own formatting */ + for (p = num; *p; ++p) + if (!isdigit(*p)) + return(num); + len = p - num; + p = pbuf; + switch(len) { + case 11: /* +0-123-456-7890 */ + *p++ = '+'; + *p++ = *num++; + *p++ = '-'; + /* FALLTHROUGH */ + case 10: /* 012-345-6789 */ + *p++ = *num++; + *p++ = *num++; + *p++ = *num++; + *p++ = '-'; + /* FALLTHROUGH */ + case 7: /* 012-3456 */ + *p++ = *num++; + *p++ = *num++; + *p++ = *num++; + break; + case 5: /* x0-1234 */ + *p++ = 'x'; + *p++ = *num++; + break; + default: + return(num); + } + *p++ = '-'; + *p++ = *num++; + *p++ = *num++; + *p++ = *num++; + *p++ = *num++; + *p = '\0'; + return(pbuf); +} + +static void +find_idle_and_ttywrite(w) + register WHERE *w; +{ + extern time_t now; + struct stat sb; + + (void)snprintf(tbuf, sizeof(tbuf), "%s/%s", _PATH_DEV, w->tty); + if (stat(tbuf, &sb) < 0) { + (void)fprintf(stderr, + "finger: %s: %s\n", tbuf, strerror(errno)); + return; + } + w->idletime = now < sb.st_atime ? 0 : now - sb.st_atime; + +#define TALKABLE 0220 /* tty is writable if 220 mode */ + w->writable = ((sb.st_mode & TALKABLE) == TALKABLE); +} + +static void +userinfo(pn, pw) + register PERSON *pn; + register struct passwd *pw; +{ + register char *p, *t; + char *bp, name[1024]; + + pn->realname = pn->office = pn->officephone = pn->homephone = NULL; + + pn->uid = pw->pw_uid; + pn->name = strdup(pw->pw_name); + pn->dir = strdup(pw->pw_dir); + pn->shell = strdup(pw->pw_shell); + + /* why do we skip asterisks!?!? */ + (void)strcpy(bp = tbuf, pw->pw_gecos); + if (*bp == '*') + ++bp; + + /* ampersands get replaced by the login name */ + if (!(p = strsep(&bp, ","))) + return; + for (t = name; *t = *p; ++p) + if (*t == '&') { + (void)strcpy(t, pw->pw_name); + if (islower(*t)) + *t = toupper(*t); + while (*++t); + } + else + ++t; + pn->realname = strdup(name); + pn->office = ((p = strsep(&bp, ",")) && *p) ? + strdup(p) : NULL; + pn->officephone = ((p = strsep(&bp, ",")) && *p) ? + strdup(p) : NULL; + pn->homephone = ((p = strsep(&bp, ",")) && *p) ? + strdup(p) : NULL; +} + +#if __STDC__ +#include <stdarg.h> +#else +#include <varargs.h> +#endif + +void +#if __STDC__ +err(const char *fmt, ...) +#else +err(fmt, va_alist) + char *fmt; + va_dcl +#endif +{ + va_list ap; +#if __STDC__ + va_start(ap, fmt); +#else + va_start(ap); +#endif + (void)fprintf(stderr, "finger: "); + (void)vfprintf(stderr, fmt, ap); + va_end(ap); + (void)fprintf(stderr, "\n"); + exit(1); + /* NOTREACHED */ +} |