Index: stable/4/usr.bin/finger/extern.h =================================================================== --- stable/4/usr.bin/finger/extern.h (revision 65340) +++ stable/4/usr.bin/finger/extern.h (revision 65341) @@ -1,50 +1,52 @@ /*- * 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.2 (Berkeley) 4/28/95 + * $FreeBSD$ */ 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 *)); PERSON *find_person __P((char *)); int hide __P((struct passwd *)); 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)); +int show_text __P((char *, char *, char *)); Index: stable/4/usr.bin/finger/finger.1 =================================================================== --- stable/4/usr.bin/finger/finger.1 (revision 65340) +++ stable/4/usr.bin/finger/finger.1 (revision 65341) @@ -1,237 +1,235 @@ .\" 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 .\" 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.3 (Berkeley) 5/5/94 .\" $FreeBSD$ .\" .Dd August 1, 1997 .Dt FINGER 1 .Os BSD 4 .Sh NAME .Nm finger .Nd user information lookup program .Sh SYNOPSIS .Nm finger .Op Fl lmpshoT .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, and either office location and office phone number, or the remote host. If .Fl h is given, the remote host is printed (the default). If .Fl o is given, the office location and office phone number is printed instead. .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 the dayname if less than 6 days, else 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 h When used in conjunction with the .Fl s option, the name of the remote host is displayed instead of the office location and office phone. .Pp .It Fl o When used in conjunction with the .Fl s option, the office location and office phone information is displayed instead of the name of the remote host. .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, mail status, 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''. Numbers specified as four digits are printed as ``xNNNN''. .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 Mail status is shown as ``No Mail.'' if there is no mail at all, ``Mail last read DDD MMM ## HH:MM YYYY (TZ)'' if the person has looked at their mailbox since new mail arriving, or ``New mail received ...'', ``Unread since ...'' if they have new mail. .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. .Pp .It Fl T Disable the use of T/TCP (see .Xr ttcp 4 ). This option is needed to finger hosts with a broken TCP implementation. .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. .Pp If the file .Dq Pa .nofinger exists in the user's home directory, .Nm finger behaves as if the user in question does not exist. .Pp The optional .Xr finger.conf 5 configuration file can be used to specify aliases. -This is particularly useful where a user's login name is not their -preferred mail address. Since .Xr finger 1 is invoked by -.Xr fingerd 8 -these aliases will work for both local and network queries. +.Xr fingerd 8 , +aliases will work for both local and network queries. .Sh ENVIRONMENT .Nm Finger utilizes the following environment variable, if it exists: .Bl -tag -width Fl .It Ev FINGER This variable may be set with favored options to .Nm finger . .El .Sh FILES .Bl -tag -width /var/log/lastlog -compact .It Pa /etc/finger.conf alias definition data base .It Pa /var/log/lastlog last login data base .El .Sh SEE ALSO .Xr chpass 1 , .Xr w 1 , .Xr who 1 , .Xr ttcp 4 , .Xr finger.conf 5 , .Xr fingerd 8 . .Rs .%A D. Zimmerman .%T The Finger User Information Protocol .%R RFC 1288 .%D December, 1991 .Re .Sh HISTORY The .Nm finger command appeared in .Bx 3.0 . .Sh BUGS The current FINGER protocol RFC requires that the client keep the connection fully open until the server closes. This prevents the use of the optimal three-packet T/TCP exchange. (Servers which depend on this requirement are bogus but have nonetheless been observed in the Internet at large.) Index: stable/4/usr.bin/finger/finger.c =================================================================== --- stable/4/usr.bin/finger/finger.c (revision 65340) +++ stable/4/usr.bin/finger/finger.c (revision 65341) @@ -1,377 +1,389 @@ /* * 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. */ /* * Luke Mewburn added the following on 940622: * - mail status ("No Mail", "Mail read:...", or "New Mail ..., * Unread since ...".) * - 4 digit phone extensions (3210 is printed as x3210.) * - host/office toggling in short format with -h & -o. * - short day names (`Tue' printed instead of `Jun 21' if the * login time is < 6 days. */ #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 #if 0 static char sccsid[] = "@(#)finger.c 8.5 (Berkeley) 5/4/95"; #else static const char rcsid[] = "$FreeBSD$"; #endif #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 either remote host information (default) or office location/phone * number, depending on if -h or -o is used respectively. * 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 #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "finger.h" #include "pathnames.h" DB *db; time_t now; int entries, lflag, mflag, pplan, sflag, oflag, Tflag; char tbuf[1024]; static void loginlist __P((void)); static void usage __P((void)); static void userlist __P((int, char **)); int option(argc, argv) int argc; char **argv; { int ch; optind = 1; /* reset getopt */ while ((ch = getopt(argc, argv, "lmpshoT")) != -1) 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 'h': oflag = 0; /* remote host info */ break; case 'o': oflag = 1; /* office info */ break; case 'T': Tflag = 1; /* disable T/TCP */ break; case '?': default: usage(); } return optind; } static void usage() { (void)fprintf(stderr, "usage: finger [-lmpshoT] [login ...]\n"); exit(1); } int main(argc, argv) int argc; char **argv; { int envargc, argcnt; char *envargv[3]; struct passwd *pw; if (getuid() == 0 || geteuid() == 0) { if ((pw = getpwnam(UNPRIV_NAME)) && pw->pw_uid > 0) { setgid(pw->pw_gid); setuid(pw->pw_uid); } else { setgid(UNPRIV_UGID); setuid(UNPRIV_UGID); } } (void) setlocale(LC_ALL, ""); /* remove this line to get remote host */ oflag = 1; /* default to old "office" behavior */ /* * Process environment variables followed by command line arguments. */ if ((envargv[1] = getenv("FINGER"))) { envargc = 2; envargv[0] = "finger"; envargv[2] = NULL; (void) option(envargc, envargv); } argcnt = option(argc, argv); argc -= argcnt; argv += argcnt; (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(); } return (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(1, "%s", _PATH_UTMP); name[UT_NAMESIZE] = '\0'; 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; if (hide(pw)) continue; pn = enter_person(pw); } enter_where(&user, 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); } } 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; FILE *conf_fp; char conf_alias[LINE_MAX]; char *conf_realname; int conf_length; + int nip; if ((nargv = malloc((argc+1) * sizeof(char *))) == NULL || (used = calloc(argc, sizeof(int))) == NULL) err(1, NULL); /* 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 finger alias configuration file of the form * alias:(user|alias), ignoring comment lines beginning '#'. */ if ((conf_fp = fopen(_PATH_FINGERCONF, "r")) != NULL) { while(fgets(conf_alias, sizeof(conf_alias), conf_fp) != NULL) { conf_length = strlen(conf_alias); if (*conf_alias == '#' || conf_alias[--conf_length] != '\n') continue; conf_alias[conf_length] = '\0'; /* Remove trailing LF */ if ((conf_realname = strchr(conf_alias, ':')) == NULL) continue; *conf_realname = '\0'; /* Replace : with NUL */ for (p = argv; *p; ++p) { if (strcmp(*p, conf_alias) == NULL) { if ((*p = strdup(conf_realname+1)) == NULL) { err(1, NULL); } } } } (void)fclose(conf_fp); } /* * Traverse the list of possible login names and check the login name - * and real name against the name specified by the user. + * and real name against the name specified by the user. If the name + * begins with a '/', try to read the file of that name instead of + * gathering the traditional finger information. */ if (mflag) - for (p = argv; *p; ++p) - if (((pw = getpwnam(*p)) != NULL) && !hide(pw)) - enter_person(pw); - else - warnx("%s: no such user", *p); + for (p = argv; *p; ++p) { + if (**p != '/' || !show_text("", *p, "")) { + if (((pw = getpwnam(*p)) != NULL) && !hide(pw)) + enter_person(pw); + else + warnx("%s: no such user", *p); + } + } else { - while ((pw = getpwent()) != NULL) { + nip = 0; + while (nip < argc && (pw = getpwent()) != NULL) { for (p = argv, ip = used; *p; ++p, ++ip) - if (match(pw, *p) && !hide(pw)) { + if (**p == '/' && *ip != 1 + && show_text("", *p, "")) { + *ip = 1; + nip++; + } else if (match(pw, *p) && !hide(pw)) { enter_person(pw); *ip = 1; + nip++; } } for (p = argv, ip = used; *p; ++p, ++ip) if (!*ip) warnx("%s: no such user", *p); } /* Handle network requests. */ net: for (p = nargv; *p;) { netfinger(*p++); if (*p || entries) printf("\n"); } 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(1, "%s", _PATH_UTMP); 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) { 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); } } Index: stable/4/usr.bin/finger/finger.conf.5 =================================================================== --- stable/4/usr.bin/finger/finger.conf.5 (revision 65340) +++ stable/4/usr.bin/finger/finger.conf.5 (revision 65341) @@ -1,82 +1,91 @@ .\"Copyright (c) 2000 Mark Knight .\"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. .\" .\"THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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. .\" .\"$FreeBSD$ .\" .Dd August 16, 2000 .Dt FINGER.CONF 5 .Os .Sh NAME .Nm finger.conf .Nd .Xr finger 1 alias configuration file .Sh DESCRIPTION The optional .Nm file is used to provide aliases that can be fingered by local and network users. This may be useful where a user's login name is not the same -as their preferred mail address. +as their preferred mail address, or for providing virtual login names +than can be fingered. .Pp Lines beginning with ``#'' are comments. Other lines must consist of an alias name and a target name separated by a colon. -A target name should be either a user, or a forward -reference to another alias. +A target name should be either a user, a forward +reference to another alias or the path of a world readable file. +.Pp +Where an alias points to a file, the contents of that file will be displayed +when the alias is fingered. .Sh EXAMPLES .Bd -literal # /etc/finger.conf alias definition file # # Format alias:(user|alias) # # Individual aliases # markk:mkn john.smith:dev329 john:dev329 +sue:/etc/finger/sue.txt +# +# Network status message +# +status:/usr/local/etc/status.txt # # Administrative redirects # root:admin postmaster:admin abuse:admin # # For the time being, 'sod' is sysadmin. # admin:sod .Ed .Sh FILES .Bl -tag -width /etc/finger.conf -compact .It Pa /etc/finger.conf .Xr finger 1 alias definition data base .El .Sh SEE ALSO .Xr finger 1 .Sh HISTORY Support for the .Nm file was submitted by Mark Knight and first appeared in .Fx 4.2 . Index: stable/4/usr.bin/finger/lprint.c =================================================================== --- stable/4/usr.bin/finger/lprint.c (revision 65340) +++ stable/4/usr.bin/finger/lprint.c (revision 65341) @@ -1,362 +1,362 @@ /* * 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 #if 0 static char sccsid[] = "@(#)lprint.c 8.3 (Berkeley) 4/28/95"; #else static const char rcsid[] = "$FreeBSD$"; #endif #endif /* not lint */ #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "finger.h" +#include "pathnames.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((unsigned char)); void lflag_print() { extern int pplan; register PERSON *pn; register int sflag, r; PERSON *tmp; DBT data, key; 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_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 *tzn; char t[80]; /* * long format -- * login name * real name * home directory * shell * office, office phone, home phone if available * mail status */ (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); strftime(t, sizeof(t), "%c", 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); strftime(t, sizeof(t), "%c", tp); tzn = tp->tm_zone; if (now - w->loginat > 86400 * 365 / 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'); } if (pn->mailrecv == -1) printf("No Mail.\n"); else if (pn->mailrecv > pn->mailread) { tp = localtime(&pn->mailrecv); strftime(t, sizeof(t), "%c", tp); tzn = tp->tm_zone; printf("New mail received %.16s %.4s (%s)\n", t, t + 20, tzn); tp = localtime(&pn->mailread); strftime(t, sizeof(t), "%c", tp); tzn = tp->tm_zone; printf(" Unread since %.16s %.4s (%s)\n", t, t + 20, tzn); } else { tp = localtime(&pn->mailread); strftime(t, sizeof(t), "%c", tp); tzn = tp->tm_zone; printf("Mail last read %.16s %.4s (%s)\n", t, t + 20, tzn); } } 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 +int show_text(directory, file_name, header) char *directory, *file_name, *header; { struct stat sb; register FILE *fp; register int ch, cnt; register char *p, lastc; 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); + if (*header != '\0') + (void)printf("%s: ", header); for (p = tbuf, cnt = nr; cnt--; ++p) if (*p != '\r') 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); + if (*header != '\0') + (void)printf("%s:\n", header); while ((ch = getc(fp)) != EOF) if (ch != '\r') vputc(lastc = ch); if (lastc != '\n') (void)putchar('\n'); (void)fclose(fp); return(1); } static void vputc(ch) register unsigned char ch; { int meta; if (!isprint(ch) && !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); } } Index: stable/4/usr.bin/finger/pathnames.h =================================================================== --- stable/4/usr.bin/finger/pathnames.h (revision 65340) +++ stable/4/usr.bin/finger/pathnames.h (revision 65341) @@ -1,31 +1,39 @@ /*- * Copyright (c) 2000 Mark Knight * 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. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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. * * $FreeBSD$ */ +#ifndef PATHNAMES_H + +#define _PATH_FORWARD ".forward" +#define _PATH_PLAN ".plan" +#define _PATH_PROJECT ".project" + #ifndef _PATH_FINGERCONF #define _PATH_FINGERCONF "/etc/finger.conf" #endif /* _PATH_FINGERCONF */ + +#endif /* PATHNAMES_H */