diff --git a/usr.bin/finger/Makefile b/usr.bin/finger/Makefile index 6a0aff989bd4..3ddd293899aa 100644 --- a/usr.bin/finger/Makefile +++ b/usr.bin/finger/Makefile @@ -1,5 +1,5 @@ -# $NetBSD: Makefile,v 1.3 1997/01/09 20:19:17 tls Exp $ -# from: @(#)Makefile 5.3 (Berkeley) 5/11/90 +# $NetBSD: Makefile,v 1.4 1997/10/19 08:13:23 mrg Exp $ +# from: @(#)Makefile 8.1 (Berkeley) 6/6/93 PROG= finger SRCS= finger.c lprint.c net.c sprint.c util.c diff --git a/usr.bin/finger/extern.h b/usr.bin/finger/extern.h index 2055da5e177c..f0ac24f2d234 100644 --- a/usr.bin/finger/extern.h +++ b/usr.bin/finger/extern.h @@ -36,12 +36,12 @@ extern time_t now; /* Current time. */ extern char tbuf[1024]; /* Temp buffer for anybody. */ extern int entries; /* Number of people. */ +extern DB *db; /* Database. */ extern int lflag; extern int oflag; extern int gflag; extern int pplan; -int demi_print __P((char *, int)); void enter_lastlog __P((PERSON *)); PERSON *enter_person __P((struct passwd *)); void enter_where __P((struct utmp *, PERSON *)); @@ -49,16 +49,10 @@ void expandusername __P((char *, char *, char *, int)); PERSON *find_person __P((char *)); int hash __P((char *)); void lflag_print __P((void)); -void loginlist __P((void)); -void lprint __P((PERSON *)); int match __P((struct passwd *, char *)); void netfinger __P((char *)); PERSON *palloc __P((void)); char *prphone __P((char *)); int psort __P((const void *, const void *)); void sflag_print __P((void)); -int show_text __P((char *, char *, char *)); PERSON **sort __P((void)); -void stimeprint __P((WHERE *)); -void userlist __P((int, char **)); -void vputc __P((int)); diff --git a/usr.bin/finger/finger.1 b/usr.bin/finger/finger.1 index 8f392987e5f4..465196c96e3e 100644 --- a/usr.bin/finger/finger.1 +++ b/usr.bin/finger/finger.1 @@ -1,7 +1,7 @@ -.\" $NetBSD: finger.1,v 1.8 1997/09/09 02:41:07 mrg Exp $ +.\" $NetBSD: finger.1,v 1.9 1997/10/19 08:13:29 mrg Exp $ .\" -.\" Copyright (c) 1989, 1990 The Regents of the University of California. -.\" All rights reserved. +.\" Copyright (c) 1989, 1990, 1993, 1994 +.\" 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 @@ -31,8 +31,7 @@ .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF .\" SUCH DAMAGE. .\" -.\" from: @(#)finger.1 6.14 (Berkeley) 7/27/91 -.\" $NetBSD: finger.1,v 1.8 1997/09/09 02:41:07 mrg Exp $ +.\" from: @(#)finger.1 8.3 (Berkeley) 5/5/94 .\" .Dd November 21, 1996 .Dt FINGER 1 @@ -41,21 +40,21 @@ .Nm finger .Nd user information lookup program .Sh SYNOPSIS -.Nm finger +.Nm .Op Fl lmpshog .Op Ar user ... .Op Ar user@host ... .Sh DESCRIPTION The -.Nm finger +.Nm displays information about the system users. .Pp Options are: .Bl -tag -width flag .It Fl s -.Nm Finger +.Nm displays the user's login name, real name, terminal name and write -status (as a ``*'' before the terminal name if write permission is +status (as a ``*'' after the terminal name if write permission is denied), idle time, login time, and either office location and office phone number, or the remote host. If @@ -134,7 +133,7 @@ Prevents the .Fl l option of -.Nm finger +.Nm from displaying the contents of the .Dq Pa .plan and @@ -150,12 +149,12 @@ users' real names, unless the .Fl m option is supplied. All name matching performed by -.Nm finger +.Nm is case insensitive. .El .Pp If no options are specified, -.Nm finger +.Nm defaults to the .Fl l style output if operands are provided, otherwise to the @@ -165,10 +164,10 @@ 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 +.Nm will print an entry for each user currently logged into the system. .Pp -.Nm Finger +.Nm may be used to look up users on a remote machine. The format is to specify a .Ar user @@ -185,12 +184,17 @@ style. The .Fl l option is the only option that may be passed to a remote machine. +.Sh FILES +.Bl -tag -width /var/log/lastlog -compact +.It Pa /var/log/lastlog +last login data base +.El .Sh SEE ALSO .Xr chpass 1 , .Xr w 1 , .Xr who 1 .Sh HISTORY The -.Nm finger +.Nm command appeared in .Bx 3.0 . diff --git a/usr.bin/finger/finger.c b/usr.bin/finger/finger.c index e891559d871a..81a23d9caaae 100644 --- a/usr.bin/finger/finger.c +++ b/usr.bin/finger/finger.c @@ -1,8 +1,8 @@ -/* $NetBSD: finger.c,v 1.9 1997/10/18 14:49:48 lukem Exp $ */ +/* $NetBSD: finger.c,v 1.10 1997/10/19 08:13:32 mrg Exp $ */ /* - * Copyright (c) 1989 The Regents of the University of California. - * All rights reserved. + * 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. @@ -46,15 +46,18 @@ * login time is < 6 days. */ +#include #ifndef lint -char copyright[] = -"@(#) Copyright (c) 1989 The Regents of the University of California.\n\ - All rights reserved.\n"; +__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[] = "from: @(#)finger.c 5.22 (Berkeley) 6/29/90";*/ -static char rcsid[] = "$NetBSD: finger.c,v 1.9 1997/10/18 14:49:48 lukem Exp $"; +#if 0 +static char sccsid[] = "@(#)finger.c 8.5 (Berkeley) 5/4/95"; +#else +__RCSID("$NetBSD: finger.c,v 1.10 1997/10/19 08:13:32 mrg Exp $"); +#endif #endif /* not lint */ /* @@ -72,24 +75,36 @@ static char rcsid[] = "$NetBSD: finger.c,v 1.9 1997/10/18 14:49:48 lukem Exp $"; */ #include -#include + +#include +#include +#include +#include +#include #include #include #include #include +#include +#include + #include "finger.h" #include "extern.h" +DB *db; time_t now; -int entries, lflag, sflag, mflag, oflag, gflag, pplan; +int entries, gflag, lflag, mflag, oflag, sflag, pplan; char tbuf[1024]; +static void loginlist __P((void)); +static void userlist __P((int, char **)); +int main __P((int, char **)); + int main(argc, argv) int argc; char **argv; { - extern int optind; int ch; oflag = 1; /* default to old "office" behavior */ @@ -149,27 +164,26 @@ main(argc, argv) if (!sflag) lflag = 1; /* if -s not explicit, force -l */ } - if (entries != 0) { + if (entries) if (lflag) lflag_print(); else sflag_print(); - } - exit(0); + return (0); } -void +static void loginlist() { 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)) { - (void)fprintf(stderr, "finger: can't read %s.\n", _PATH_UTMP); - exit(2); - } + if (!freopen(_PATH_UTMP, "r", stdin)) + err(1, "cant read %s", _PATH_UTMP); name[UT_NAMESIZE] = '\0'; while (fread((char *)&user, sizeof(user), 1, stdin) == 1) { if (!user.ut_name[0]) @@ -182,76 +196,82 @@ loginlist() } enter_where(&user, pn); } - for (pn = phead; lflag && pn != NULL; pn = pn->next) - enter_lastlog(pn); + if (db && lflag) + for (sflag = R_FIRST;; sflag = R_NEXT) { + PERSON *tmp; + + r = (*db->seq)(db, &key, &data, sflag); + if (r == -1) + err(1, "db seq"); + if (r == 1) + break; + memmove(&tmp, data.data, sizeof tmp); + enter_lastlog(tmp); + } } -void +static void userlist(argc, argv) int argc; char **argv; { - register int i; register PERSON *pn; - PERSON *nethead, **nettail; + DBT data, key; struct utmp user; struct passwd *pw; - int dolocal, *used; + int r, sflag, *used, *ip; + char **ap, **nargv, **np, **p; - if (!(used = (int *)calloc((u_int)argc, (u_int)sizeof(int)))) { - (void)fprintf(stderr, "finger: out of space.\n"); - exit(1); - } + if ((nargv = malloc((argc+1) * sizeof(char *))) == NULL || + (used = calloc(argc, sizeof(int))) == NULL) +#ifdef __GNUC__ + err(1, "%s", ""); /* XXX gcc */ +#else + err(1, NULL); +#endif - /* pull out all network requests */ - for (i = 0, dolocal = 0, nettail = &nethead; i < argc; i++) { - if (!strchr(argv[i], '@')) { - dolocal = 1; - continue; - } - pn = palloc(); - *nettail = pn; - nettail = &pn->next; - pn->name = argv[i]; - used[i] = -1; - } - *nettail = NULL; + /* Pull out all network requests. */ + for (ap = p = argv, np = nargv; *p; ++p) + if (index(*p, '@')) + *np++ = *p; + else + *ap++ = *p; - if (!dolocal) + *np++ = NULL; + *ap++ = NULL; + + if (!*argv) goto net; /* - * traverse the list of possible login names and check the login name + * 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 (i = 0; i < argc; i++) - if (used[i] >= 0 && (pw = getpwnam(argv[i]))) { + for (p = argv; *p; ++p) + if ((pw = getpwnam(*p)) != NULL) enter_person(pw); - used[i] = 1; - } - } else while ((pw = getpwent()) != NULL) - for (i = 0; i < argc; i++) - if (used[i] >= 0 && - (!strcasecmp(pw->pw_name, argv[i]) || - match(pw, argv[i]))) { - enter_person(pw); - used[i] = 1; - } - - /* list errors */ - for (i = 0; i < argc; i++) - if (!used[i]) - (void)fprintf(stderr, - "finger: %s: no such user.\n", argv[i]); - - /* handle network requests */ -net: for (pn = nethead; pn; pn = pn->next) { - netfinger(pn->name); - if (pn->next || entries) - putchar('\n'); + else + (void)fprintf(stderr, + "finger: %s: no such user\n", *p); + } else { + while ((pw = getpwent()) != NULL) + 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; @@ -259,10 +279,8 @@ net: for (pn = nethead; pn; pn = pn->next) { * Scan thru the list of users currently logged in, saving * appropriate data whenever a match occurs. */ - if (!freopen(_PATH_UTMP, "r", stdin)) { - (void)fprintf( stderr, "finger: can't read %s.\n", _PATH_UTMP); - exit(1); - } + if (!freopen(_PATH_UTMP, "r", stdin)) + err(1, "%s", _PATH_UTMP); while (fread((char *)&user, sizeof(user), 1, stdin) == 1) { if (!user.ut_name[0]) continue; @@ -270,6 +288,16 @@ net: for (pn = nethead; pn; pn = pn->next) { continue; enter_where(&user, pn); } - for (pn = phead; pn != NULL; pn = pn->next) - enter_lastlog(pn); + if (db) + for (sflag = R_FIRST;; sflag = R_NEXT) { + PERSON *tmp; + + r = (*db->seq)(db, &key, &data, sflag); + if (r == -1) + err(1, "db seq"); + if (r == 1) + break; + memmove(&tmp, data.data, sizeof tmp); + enter_lastlog(tmp); + } } diff --git a/usr.bin/finger/finger.h b/usr.bin/finger/finger.h index 60b67e510de4..b6c2f9a72f8e 100644 --- a/usr.bin/finger/finger.h +++ b/usr.bin/finger/finger.h @@ -1,8 +1,8 @@ -/* $NetBSD: finger.h,v 1.5 1997/01/09 20:19:21 tls Exp $ */ +/* $NetBSD: finger.h,v 1.6 1997/10/19 08:13:35 mrg Exp $ */ /* - * Copyright (c) 1989 The Regents of the University of California. - * All rights reserved. + * 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. @@ -35,13 +35,9 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * from: @(#)finger.h 5.5 (Berkeley) 6/1/90 - * $NetBSD: finger.h,v 1.5 1997/01/09 20:19:21 tls Exp $ + * from: @(#)finger.h 8.1 (Berkeley) 6/6/93 */ -#include -#include - #define _PATH_MAILSPOOL "/var/mail" /* @@ -50,8 +46,6 @@ */ typedef struct person { - struct person *next; /* link to next person */ - struct person *hlink; /* link to next person in hash bucket */ uid_t uid; /* user id */ char *dir; /* user's home directory */ char *homephone; /* pointer to home phone no. */ @@ -62,13 +56,13 @@ typedef struct person { char *shell; /* user's shell */ time_t mailread; /* last time mail was read */ time_t mailrecv; /* last time mail was read */ - struct where *whead, *wtail; /* list of where he is or has been */ + 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 he is or has been */ + 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 */ @@ -77,12 +71,4 @@ typedef struct where { char host[UT_HOSTSIZE+1]; /* null terminated remote host name */ } WHERE; -#define HBITS 8 /* number of bits in hash code */ -#define HSIZE (1 << 8) /* hash table size */ -#define HMASK (HSIZE - 1) /* hash code mask */ - -PERSON *htab[HSIZE]; /* the buckets */ -PERSON *phead, *ptail; /* the linked list of all people */ - -PERSON *enter_person(), *find_person(), *palloc(); -WHERE *walloc(); +#include "extern.h" diff --git a/usr.bin/finger/lprint.c b/usr.bin/finger/lprint.c index ebb980d01e1f..8e0c5ba46bd9 100644 --- a/usr.bin/finger/lprint.c +++ b/usr.bin/finger/lprint.c @@ -1,8 +1,8 @@ -/* $NetBSD: lprint.c,v 1.8 1997/09/09 02:41:09 mrg Exp $ */ +/* $NetBSD: lprint.c,v 1.9 1997/10/19 08:13:38 mrg Exp $ */ /* - * Copyright (c) 1989 The Regents of the University of California. - * All rights reserved. + * 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. @@ -36,49 +36,79 @@ * SUCH DAMAGE. */ +#include #ifndef lint -/*static char sccsid[] = "from: @(#)lprint.c 5.13 (Berkeley) 10/31/90";*/ -static char rcsid[] = "$NetBSD: lprint.c,v 1.8 1997/09/09 02:41:09 mrg Exp $"; +#if 0 +static char sccsid[] = "@(#)lprint.c 8.3 (Berkeley) 4/28/95"; +#else +__RCSID( "$NetBSD: lprint.c,v 1.9 1997/10/19 08:13:38 mrg Exp $"); +#endif #endif /* not lint */ #include -#include #include #include +#include +#include #include +#include +#include +#include +#include +#include +#include #include #include #include #include +#include #include #include + #include "finger.h" #include "extern.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() { PERSON *pn; + int sflag, r; + PERSON *tmp; + DBT data, key; - for (pn = phead;;) { + for (sflag = R_FIRST;; sflag = R_NEXT) { + r = (*db->seq)(db, &key, &data, sflag); + if (r == -1) + err(1, "db seq"); + if (r == 1) + break; + memmove(&tmp, data.data, sizeof tmp); + pn = tmp; + if (sflag != R_FIRST) + putchar('\n'); lprint(pn); if (!pplan) { - (void)show_text(pn->dir, _PATH_PROJECT, "Project:"); - if (!show_text(pn->dir, _PATH_PLAN, "Plan:")) + (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"); } - if (!(pn = pn->next)) - break; - putchar('\n'); } } -void +static void lprint(pn) PERSON *pn; { @@ -115,20 +145,18 @@ lprint(pn) 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)); + (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); + (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)); + (void)snprintf(tbuf, sizeof(tbuf), "%s: %s", + OFFICE_PHONE_TAG, prphone(pn->officephone)); oddfield = demi_print(tbuf, oddfield); } } @@ -231,7 +259,7 @@ no_gecos: } } -int +static int demi_print(str, oddfield) char *str; int oddfield; @@ -271,18 +299,47 @@ demi_print(str, oddfield) return(oddfield); } -int +static int show_text(directory, file_name, header) char *directory, *file_name, *header; { - int ch, lastc; + struct stat sb; FILE *fp; + int ch, cnt, lastc; + char *p; + int fd, nr; lastc = 0; (void)snprintf(tbuf, sizeof(tbuf), "%s/%s", directory, file_name); - if ((fp = fopen(tbuf, "r")) == NULL) + if ((fd = open(tbuf, O_RDONLY)) < 0 || fstat(fd, &sb) || + sb.st_size == 0) return(0); - (void)printf("%s\n", header); + + /* 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') @@ -291,7 +348,7 @@ show_text(directory, file_name, header) return(1); } -void +static void vputc(ch) int ch; { diff --git a/usr.bin/finger/net.c b/usr.bin/finger/net.c index 30ba2f30d1d3..5cfc3091e067 100644 --- a/usr.bin/finger/net.c +++ b/usr.bin/finger/net.c @@ -1,8 +1,8 @@ -/* $NetBSD: net.c,v 1.9 1997/05/17 19:42:25 pk Exp $ */ +/* $NetBSD: net.c,v 1.10 1997/10/19 08:13:42 mrg Exp $ */ /* - * Copyright (c) 1989 The Regents of the University of California. - * All rights reserved. + * 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. @@ -36,20 +36,32 @@ * SUCH DAMAGE. */ +#include #ifndef lint -/*static char sccsid[] = "from: @(#)net.c 5.5 (Berkeley) 6/1/90";*/ -static char rcsid[] = "$NetBSD: net.c,v 1.9 1997/05/17 19:42:25 pk Exp $"; +#if 0 +static char sccsid[] = "@(#)net.c 8.4 (Berkeley) 4/28/95"; +#else +__RCSID("$NetBSD: net.c,v 1.10 1997/10/19 08:13:42 mrg Exp $"); +#endif #endif /* not lint */ #include #include + #include + #include + #include +#include +#include +#include +#include #include #include #include #include + #include "finger.h" #include "extern.h" @@ -122,7 +134,7 @@ netfinger(name) while ((c = getc(fp)) != EOF) { c &= 0x7f; if (c == '\r') { - if (lastc == '\r') + if (lastc == '\r') /* ^M^M - skip dupes */ continue; c = '\n'; lastc = '\r'; @@ -140,5 +152,6 @@ netfinger(name) } if (lastc != '\n') putchar('\n'); + putchar('\n'); (void)fclose(fp); } diff --git a/usr.bin/finger/sprint.c b/usr.bin/finger/sprint.c index 7cc50219703b..0066b5ba7544 100644 --- a/usr.bin/finger/sprint.c +++ b/usr.bin/finger/sprint.c @@ -1,8 +1,8 @@ -/* $NetBSD: sprint.c,v 1.7 1997/09/09 02:41:10 mrg Exp $ */ +/* $NetBSD: sprint.c,v 1.8 1997/10/19 08:13:46 mrg Exp $ */ /* - * Copyright (c) 1989 The Regents of the University of California. - * All rights reserved. + * 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. @@ -36,29 +36,44 @@ * SUCH DAMAGE. */ +#include #ifndef lint -/*static char sccsid[] = "from: @(#)sprint.c 5.8 (Berkeley) 12/4/90";*/ -static char rcsid[] = "$NetBSD: sprint.c,v 1.7 1997/09/09 02:41:10 mrg Exp $"; +#if 0 +static char sccsid[] = "@(#)sprint.c 8.3 (Berkeley) 4/28/95"; +#else +__RCSID("$NetBSD: sprint.c,v 1.8 1997/10/19 08:13:46 mrg Exp $"); +#endif #endif /* not lint */ -#include +#include #include + +#include #include +#include +#include +#include +#include +#include #include #include +#include + #include "finger.h" #include "extern.h" +static void stimeprint __P((WHERE *)); + void sflag_print() { PERSON *pn; WHERE *w; - int cnt; + int sflag, r; char *p; - PERSON **list; + PERSON *tmp; + DBT data, key; - list = sort(); /* * short format -- * login name @@ -77,12 +92,19 @@ sflag_print() * office phone */ #define MAXREALNAME 20 -#define MAXHOSTNAME 20 (void)printf("%-*s %-*s %s %s\n", UT_NAMESIZE, "Login", MAXREALNAME, "Name", "Tty Idle Login Time ", (gflag) ? "" : (oflag) ? "Office Office Phone" : "Where"); - for (cnt = 0; cnt < entries; ++cnt) { - pn = list[cnt]; + + for (sflag = R_FIRST;; sflag = R_NEXT) { + r = (*db->seq)(db, &key, &data, sflag); + if (r == -1) + err(1, "db seq"); + if (r == 1) + break; + memmove(&tmp, data.data, sizeof tmp); + pn = tmp; + for (w = pn->whead; w != NULL; w = w->next) { (void)printf("%-*.*s %-*.*s ", UT_NAMESIZE, UT_NAMESIZE, pn->name, MAXREALNAME, MAXREALNAME, @@ -126,37 +148,14 @@ office: (void)printf(" %-.15s", prphone(pn->officephone)); } else - (void)printf("%.*s", MAXHOSTNAME, w->host); + (void)printf("%.*s", MAXHOSTNAMELEN, w->host); no_gecos: putchar('\n'); } } } -PERSON ** -sort() -{ - PERSON *pn, **lp; - PERSON **list; - - if (!(list = (PERSON **)malloc((u_int)(entries * sizeof(PERSON *))))) { - (void)fprintf(stderr, "finger: out of space.\n"); - exit(1); - } - for (lp = list, pn = phead; pn != NULL; pn = pn->next) - *lp++ = pn; - (void)qsort(list, entries, sizeof(PERSON *), psort); - return(list); -} - -int -psort(p, t) - const void *p, *t; -{ - return(strcmp((*(PERSON **)p)->name, (*(PERSON **)t)->name)); -} - -void +static void stimeprint(w) WHERE *w; { diff --git a/usr.bin/finger/util.c b/usr.bin/finger/util.c index ac5fb2b01257..f4a0e622f4ec 100644 --- a/usr.bin/finger/util.c +++ b/usr.bin/finger/util.c @@ -1,8 +1,8 @@ -/* $NetBSD: util.c,v 1.10 1997/05/17 19:42:27 pk Exp $ */ +/* $NetBSD: util.c,v 1.11 1997/10/19 08:13:50 mrg Exp $ */ /* - * Copyright (c) 1989 The Regents of the University of California. - * All rights reserved. + * Copyright (c) 1989, 1993 + * The Regents of the University of California. All rights reserved. * Portions Copyright (c) 1983, 1995, 1996 Eric P. Allman * * This code is derived from software contributed to Berkeley by @@ -37,87 +37,37 @@ * SUCH DAMAGE. */ +#include #ifndef lint -/*static char sccsid[] = "from: @(#)util.c 5.14 (Berkeley) 1/17/91";*/ -static char rcsid[] = "$NetBSD: util.c,v 1.10 1997/05/17 19:42:27 pk Exp $"; +#if 0 +static char sccsid[] = "@(#)util.c 8.3 (Berkeley) 4/28/95"; +#else +__RCSID("$NetBSD: util.c,v 1.11 1997/10/19 08:13:50 mrg Exp $"); +#endif #endif /* not lint */ -#include -#include #include #include -#include + +#include +#include +#include +#include +#include +#include +#include #include #include -#include #include -#include -#include #include +#include + #include "finger.h" #include "extern.h" -void -find_idle_and_ttywrite(w) - WHERE *w; -{ - 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); -} - -void -userinfo(pn, pw) - PERSON *pn; - struct passwd *pw; -{ - char *p; - char *bp, name[1024]; - struct stat sb; - - 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); - - (void)strncpy(bp = tbuf, pw->pw_gecos, sizeof(tbuf)); - - /* ampersands get replaced by the login name */ - if (!(p = strsep(&bp, ","))) - return; - expandusername(p, pw->pw_name, name, sizeof(name)); - 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; - (void)snprintf(tbuf, sizeof(tbuf), "%s/%s", _PATH_MAILSPOOL, - pw->pw_name); - pn->mailrecv = -1; /* -1 == not_valid */ - if (stat(tbuf, &sb) < 0) { - if (errno != ENOENT) { - (void)fprintf(stderr, - "finger: %s: %s\n", tbuf, strerror(errno)); - return; - } - } else if (sb.st_size != 0) { - pn->mailrecv = sb.st_mtime; - pn->mailread = sb.st_atime; - } -} +static void find_idle_and_ttywrite __P((WHERE *)); +static void userinfo __P((PERSON *, struct passwd *)); +static WHERE *walloc __P((PERSON *)); int match(pw, user) @@ -127,13 +77,17 @@ match(pw, user) char *p, *t; char name[1024]; + if (!strcasecmp(pw->pw_name, user)) + return(1); + (void)strncpy(p = tbuf, pw->pw_gecos, sizeof(tbuf)); - /* ampersands get replaced by the login name */ - if (!(p = strtok(p, ","))) + /* Ampersands get replaced by the login name. */ + if ((p = strtok(p, ",")) == NULL) return(0); + expandusername(p, pw->pw_name, name, sizeof(name)); - for (t = name; (p = strtok(t, "\t ")) != NULL; t = (char *)NULL) + for (t = name; (p = strtok(t, "\t ")) != NULL; t = NULL) if (!strcasecmp(p, user)) return(1); return(0); @@ -189,7 +143,7 @@ enter_lastlog(pn) opened = 1; } if (fd == -1 || - lseek(fd, (off_t)(pn->uid * sizeof(ll)), SEEK_SET) != + lseek(fd, (off_t)pn->uid * sizeof(ll), SEEK_SET) != (long)pn->uid * sizeof(ll) || read(fd, (char *)&ll, sizeof(ll)) != sizeof(ll)) { /* as if never logged in */ @@ -229,8 +183,9 @@ enter_where(ut, pn) struct utmp *ut; PERSON *pn; { - WHERE *w = walloc(pn); + WHERE *w; + w = walloc(pn); w->info = LOGGEDIN; bcopy(ut->ut_line, w->tty, UT_LINESIZE); w->tty[UT_LINESIZE] = 0; @@ -244,55 +199,65 @@ PERSON * enter_person(pw) struct passwd *pw; { - PERSON *pn, **pp; + DBT data, key; + PERSON *pn; - for (pp = htab + hash(pw->pw_name); - *pp != NULL && strcmp((*pp)->name, pw->pw_name) != 0; - pp = &(*pp)->hlink) - ; - if ((pn = *pp) == NULL) { + if (db == NULL && + (db = dbopen(NULL, O_RDWR, 0, DB_BTREE, NULL)) == NULL) +#ifdef __GNUC__ + err(1, "%s", ""); +#else + err(1, NULL); +#endif + + key.data = pw->pw_name; + key.size = strlen(pw->pw_name); + + switch ((*db->get)(db, &key, &data, 0)) { + case 0: + memmove(&pn, data.data, sizeof pn); + return (pn); + default: + case -1: + err(1, "db get"); + /* NOTREACHED */ + case 1: + ++entries; pn = palloc(); - entries++; - if (phead == NULL) - phead = ptail = pn; - else { - ptail->next = pn; - ptail = pn; - } - pn->next = NULL; - pn->hlink = NULL; - *pp = pn; userinfo(pn, pw); pn->whead = NULL; + + data.size = sizeof(PERSON *); + data.data = &pn; + if ((*db->put)(db, &key, &data, 0)) + err(1, "db put"); + return (pn); } - return(pn); } PERSON * find_person(name) char *name; { - PERSON *pn; + int cnt; + DBT data, key; + PERSON *p; + char buf[UT_NAMESIZE + 1]; - /* name may be only UT_NAMESIZE long and not terminated */ - for (pn = htab[hash(name)]; - pn != NULL && strncmp(pn->name, name, UT_NAMESIZE) != 0; - pn = pn->hlink) - ; - return(pn); -} + if (!db) + return(NULL); -int -hash(name) - char *name; -{ - int h, i; + /* 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; - h = 0; - /* name may be only UT_NAMESIZE long and not terminated */ - for (i = UT_NAMESIZE; --i >= 0 && *name;) - h = ((h << 2 | h >> (HBITS - 2)) ^ *name++) & HMASK; - return(h); + if ((*db->get)(db, &key, &data, 0)) + return (NULL); + memmove(&p, data.data, sizeof p); + return (p); } PERSON * @@ -300,23 +265,27 @@ palloc() { PERSON *p; - if ((p = (PERSON *)malloc((u_int) sizeof(PERSON))) == NULL) { - (void)fprintf(stderr, "finger: out of space.\n"); - exit(1); - } + if ((p = malloc((u_int) sizeof(PERSON))) == NULL) +#ifdef __GNUC__ + err(1, "%s", ""); +#else + err(1, NULL); +#endif return(p); } -WHERE * +static WHERE * walloc(pn) PERSON *pn; { WHERE *w; - if ((w = (WHERE *)malloc((u_int) sizeof(WHERE))) == NULL) { - (void)fprintf(stderr, "finger: out of space.\n"); - exit(1); - } + if ((w = malloc((u_int) sizeof(WHERE))) == NULL) +#ifdef __GNUC__ + err(1, "%s", ""); +#else + err(1, NULL); +#endif if (pn->whead == NULL) pn->whead = pn->wtail = w; else { @@ -376,3 +345,66 @@ prphone(num) *p = '\0'; return(pbuf); } + +static void +find_idle_and_ttywrite(w) + 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) { + warn(tbuf); + 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) + PERSON *pn; + struct passwd *pw; +{ + char *p; + char *bp, name[1024]; + struct stat sb; + + 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); + + (void)strncpy(bp = tbuf, pw->pw_gecos, sizeof(tbuf)); + tbuf[sizeof(tbuf) - 1] = '\0'; + + /* ampersands get replaced by the login name */ + if (!(p = strsep(&bp, ","))) + return; + expandusername(p, pw->pw_name, name, sizeof(name)); + 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; + (void)snprintf(tbuf, sizeof(tbuf), "%s/%s", _PATH_MAILSPOOL, + pw->pw_name); + pn->mailrecv = -1; /* -1 == not_valid */ + if (stat(tbuf, &sb) < 0) { + if (errno != ENOENT) { + (void)fprintf(stderr, + "finger: %s: %s\n", tbuf, strerror(errno)); + return; + } + } else if (sb.st_size != 0) { + pn->mailrecv = sb.st_mtime; + pn->mailread = sb.st_atime; + } +}