Importing usr.bin/finger
This commit is contained in:
		
							parent
							
								
									92f7a4ab20
								
							
						
					
					
						commit
						406cdd95a6
					
				| @ -9,7 +9,7 @@ SUBDIR=	add_route arp ash at backup basename btrace \ | ||||
| 	dd decomp16 DESCRIBE devmand devsize df dhcpd \
 | ||||
| 	dhrystone diff dirname diskctl dumpcore \
 | ||||
| 	eject env expand factor fbdctl \
 | ||||
| 	find finger fingerd fix fold format fortune fsck.mfs \
 | ||||
| 	find fingerd fix fold format fortune fsck.mfs \
 | ||||
| 	gcore gcov-pull getty grep hexdump host \
 | ||||
| 	hostaddr id ifconfig ifdef \
 | ||||
| 	intr ipcrm ipcs irdpd isoread last \
 | ||||
|  | ||||
| @ -1,4 +0,0 @@ | ||||
| PROG=	finger | ||||
| MAN= | ||||
| 
 | ||||
| .include <bsd.prog.mk> | ||||
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							| @ -5,7 +5,7 @@ MAN=	ash.1 at.1 basename.1 \ | ||||
| 	df.1 dhrystone.1 dosdir.1 dosread.1 doswrite.1 \
 | ||||
| 	dumpcore.1 eject.1 \
 | ||||
| 	env.1 expand.1 factor.1 \
 | ||||
| 	finger.1 flexdoc.1 fold.1 format.1 fortune.1 \
 | ||||
| 	flexdoc.1 fold.1 format.1 fortune.1 \
 | ||||
| 	fsck.mfs.1 host.1 hostaddr.1 ifdef.1 \
 | ||||
| 	isodir.1 isoinfo.1 isoread.1 \
 | ||||
| 	last.1 loadfont.1 loadkeys.1 logger.1 \
 | ||||
|  | ||||
| @ -1,84 +0,0 @@ | ||||
| .\" Copyright (c) 1980 Regents of the University of California. | ||||
| .\" All rights reserved.  The Berkeley software License Agreement | ||||
| .\" specifies the terms and conditions for redistribution. | ||||
| .\" | ||||
| .\"	@(#)finger.1	6.4 (Berkeley) 5/10/86 | ||||
| .\" | ||||
| .TH FINGER 1 "May 10, 1986" | ||||
| .UC 4 | ||||
| .SH NAME | ||||
| finger \- user information lookup program | ||||
| .SH SYNOPSIS | ||||
| .B finger | ||||
| [ | ||||
| options | ||||
| ] name ... | ||||
| .SH DESCRIPTION | ||||
| By default | ||||
| .B finger | ||||
| lists the login name, full name, terminal name and write status | ||||
| (as a `*' before the terminal name if write permission is denied), | ||||
| idle time, login time, and office location and phone number | ||||
| (if they are known) for each current UNIX user. | ||||
| (Idle time is minutes if it is a single integer, hours and minutes if a ':' | ||||
| is present, or days and hours if a 'd' is present.) | ||||
| .PP | ||||
| A longer format also exists and is used by | ||||
| .B finger | ||||
| whenever a list of people's names is given.  (Account names as well as | ||||
| first and last names of users are accepted.) | ||||
| This format is multi-line, and includes all the information described above | ||||
| as well as the user's home | ||||
| directory and login shell, any plan which the person has placed in the file | ||||
| .B \&.plan | ||||
| in their home | ||||
| directory, and the project on which they are working from the file | ||||
| .B \&.project | ||||
| also in the home directory. | ||||
| .PP | ||||
| .B Finger | ||||
| may be used to lookup users on a remote machine.  The format is to specify | ||||
| the user as ``user@host.''  If the user name is left off, the | ||||
| standard format listing is provided on the remote machine. | ||||
| .PP | ||||
| .B Finger | ||||
| options include: | ||||
| .TP | ||||
| .B \-m | ||||
| Match arguments only on user name. | ||||
| .TP | ||||
| .B \-l | ||||
| Force long output format. | ||||
| .TP | ||||
| .B \-p | ||||
| Suppress printing of the | ||||
| .B \&.plan | ||||
| files | ||||
| .TP | ||||
| .B \-s | ||||
| Force short output format. | ||||
| .SH FILES | ||||
| .ta 2i | ||||
| /etc/utmp	who file | ||||
| .br | ||||
| /etc/passwd	for users names, offices, ... | ||||
| .br | ||||
| /usr/adm/lastlog	last login times | ||||
| .br | ||||
| ~/.plan	plans | ||||
| .br | ||||
| ~/.project	projects | ||||
| .SH "SEE ALSO" | ||||
| .BR chfn (1), | ||||
| .BR w (1), | ||||
| .BR who (1). | ||||
| .SH AUTHOR | ||||
| Earl T. Cohen | ||||
| .SH BUGS | ||||
| Only the first line of the | ||||
| .B .project | ||||
| file is printed. | ||||
| .PP | ||||
| There is no way to pass arguments to the remote machine as | ||||
| .B finger | ||||
| uses an internet standard port. | ||||
| @ -133,6 +133,7 @@ | ||||
| 2012/10/17 12:00:00,usr.bin/col | ||||
| 2012/10/17 12:00:00,usr.bin/ctags | ||||
| 2011/09/01 13:37:33,usr.bin/du | ||||
| 2013/05/31 12:00:00,usr.bin/finger | ||||
| 2013/03/22 12:00:00,usr.bin/from | ||||
| 2013/04/05 12:00:00,usr.bin/ftp | ||||
| 2013/03/18 12:00:00,usr.bin/head | ||||
|  | ||||
| @ -9,7 +9,7 @@ SUBDIR= \ | ||||
| 	cal chpass cksum \
 | ||||
| 	col ctags \
 | ||||
| 	du \
 | ||||
| 	\
 | ||||
| 	finger \
 | ||||
| 	from ftp \
 | ||||
| 	genassym getopt head \
 | ||||
| 	indent infocmp join \
 | ||||
|  | ||||
							
								
								
									
										18
									
								
								usr.bin/finger/Makefile
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										18
									
								
								usr.bin/finger/Makefile
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,18 @@ | ||||
| #	$NetBSD: Makefile,v 1.11 2007/05/28 12:06:26 tls Exp $
 | ||||
| #	from: @(#)Makefile	8.1 (Berkeley) 6/6/93
 | ||||
| 
 | ||||
| .include <bsd.own.mk> | ||||
| 
 | ||||
| USE_FORT?= yes	# network client | ||||
| 
 | ||||
| PROG=	finger | ||||
| SRCS=	finger.c lprint.c net.c sprint.c util.c utmpentry.c | ||||
| 
 | ||||
| .PATH.c: ${NETBSDSRCDIR}/usr.bin/who | ||||
| CPPFLAGS+=-I${NETBSDSRCDIR}/usr.bin/who -DSUPPORT_UTMPX -DSUPPORT_UTMP | ||||
| 
 | ||||
| .if (${USE_INET6} != "no") | ||||
| CPPFLAGS+=-DINET6 | ||||
| .endif | ||||
| 
 | ||||
| .include <bsd.prog.mk> | ||||
							
								
								
									
										57
									
								
								usr.bin/finger/extern.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										57
									
								
								usr.bin/finger/extern.h
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,57 @@ | ||||
| /*	$NetBSD: extern.h,v 1.10 2006/01/04 01:17:54 perry Exp $	*/ | ||||
| 
 | ||||
| /*-
 | ||||
|  * 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. 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 | ||||
|  */ | ||||
| 
 | ||||
| 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 eightflag; | ||||
| extern int pplan; | ||||
| 
 | ||||
| void	 enter_lastlog(PERSON *); | ||||
| PERSON	*enter_person(struct passwd *); | ||||
| void	 enter_where(struct utmpentry *, PERSON *); | ||||
| void	 expandusername(const char *, const char *, char *, int); | ||||
| PERSON	*find_person(char *); | ||||
| int	 hash(char *); | ||||
| void	 lflag_print(void); | ||||
| int	 match(struct passwd *, char *); | ||||
| void	 netfinger(char *); | ||||
| PERSON	*palloc(void); | ||||
| char	*prphone(char *); | ||||
| int	 psort(const void *, const void *); | ||||
| void	 sflag_print(void); | ||||
| PERSON **sort(void); | ||||
							
								
								
									
										213
									
								
								usr.bin/finger/finger.1
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										213
									
								
								usr.bin/finger/finger.1
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,213 @@ | ||||
| .\"	$NetBSD: finger.1,v 1.16 2012/06/10 17:45:59 dholland Exp $ | ||||
| .\" | ||||
| .\" 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. 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. | ||||
| .\" | ||||
| .\"	from: @(#)finger.1	8.3 (Berkeley) 5/5/94 | ||||
| .\" | ||||
| .Dd June 10, 2012 | ||||
| .Dt FINGER 1 | ||||
| .Os | ||||
| .Sh NAME | ||||
| .Nm finger | ||||
| .Nd user information lookup program | ||||
| .Sh SYNOPSIS | ||||
| .Nm | ||||
| .Op Fl 8ghlmops | ||||
| .Op Ar user ... | ||||
| .Op Ar user@host ... | ||||
| .Sh DESCRIPTION | ||||
| The | ||||
| .Nm | ||||
| displays information about the system users. | ||||
| .Pp | ||||
| Options are: | ||||
| .Bl -tag -width flag | ||||
| .It Fl 8 | ||||
| Pass through 8-bit data. | ||||
| This option is intended for enabling 8-bit | ||||
| data output in the | ||||
| .Xr fingerd 8 | ||||
| service. | ||||
| Using this from the command line is | ||||
| .Em dangerous , | ||||
| as the output data may include control characters for your terminal. | ||||
| .It Fl g | ||||
| This option restricts the gecos output to only the users' real names. | ||||
| .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. | ||||
| .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 | ||||
| .Dq hh:mm . | ||||
| Idle times greater than a day are presented as | ||||
| .Dq d day[s]hh:mm . | ||||
| .Pp | ||||
| Phone numbers specified as eleven digits are printed as | ||||
| .Dq +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 | ||||
| .Dq xN-NNNN . | ||||
| Numbers specified as four digits are printed as | ||||
| .Dq xNNNN . | ||||
| .Pp | ||||
| If write permission is denied to the device, the phrase | ||||
| .Dq (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 | ||||
| .Dq \&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 | ||||
| .Dq New mail received ... , | ||||
| .Dq Unread since \&... | ||||
| if they have new mail. | ||||
| .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 | ||||
| is case insensitive. | ||||
| .It Fl o | ||||
| When used in conjunction with the | ||||
| .Fl s | ||||
| option, the office location and office phone information is displayed. | ||||
| This is the default. | ||||
| .It Fl p | ||||
| Prevents | ||||
| the | ||||
| .Fl l | ||||
| option of | ||||
| .Nm | ||||
| from displaying the contents of the | ||||
| .Dq Pa .forward , | ||||
| .Dq Pa .plan | ||||
| and | ||||
| .Dq Pa .project | ||||
| files. | ||||
| .It Fl s | ||||
| .Nm | ||||
| displays the user's login name, real name, terminal name and write | ||||
| status (as a | ||||
| .Dq * | ||||
| 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 | ||||
| .Fl h | ||||
| is given, the remote is printed. | ||||
| If | ||||
| .Fl o | ||||
| is given, the office location and phone number is printed instead | ||||
| (the default). | ||||
| .Pp | ||||
| Idle time is in minutes if it is a single integer, hours and minutes | ||||
| if a | ||||
| .Dq \&: | ||||
| is present, or days if a | ||||
| .Dq d | ||||
| is present. | ||||
| Login time is displayed as the dayname if less than six 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. | ||||
| .El | ||||
| .Pp | ||||
| If no options are specified, | ||||
| .Nm | ||||
| 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 | ||||
| will print an entry for each user currently logged into the system. | ||||
| .Pp | ||||
| .Nm | ||||
| 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 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 | ||||
| command appeared in | ||||
| .Bx 3.0 . | ||||
							
								
								
									
										301
									
								
								usr.bin/finger/finger.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										301
									
								
								usr.bin/finger/finger.c
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,301 @@ | ||||
| /*	$NetBSD: finger.c,v 1.29 2009/04/12 06:18:54 lukem Exp $	*/ | ||||
| 
 | ||||
| /*
 | ||||
|  * 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. 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 <lukem@NetBSD.org> added the following on 961121: | ||||
|  *    - 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. | ||||
|  */ | ||||
| 
 | ||||
| #include <sys/cdefs.h> | ||||
| #ifndef lint | ||||
| __COPYRIGHT("@(#) Copyright (c) 1989, 1993\
 | ||||
|  The Regents of the University of California.  All rights reserved."); | ||||
| #endif /* not lint */ | ||||
| 
 | ||||
| #ifndef lint | ||||
| #if 0 | ||||
| static char sccsid[] = "@(#)finger.c	8.5 (Berkeley) 5/4/95"; | ||||
| #else | ||||
| __RCSID("$NetBSD: finger.c,v 1.29 2009/04/12 06:18:54 lukem Exp $"); | ||||
| #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 <sys/param.h> | ||||
| 
 | ||||
| #include <db.h> | ||||
| #include <err.h> | ||||
| #include <errno.h> | ||||
| #include <fcntl.h> | ||||
| #include <pwd.h> | ||||
| #include <stdio.h> | ||||
| #include <stdlib.h> | ||||
| #include <string.h> | ||||
| #include <time.h> | ||||
| #include <unistd.h> | ||||
| 
 | ||||
| #include <locale.h> | ||||
| #include <langinfo.h> | ||||
| 
 | ||||
| #include "utmpentry.h" | ||||
| 
 | ||||
| #include "finger.h" | ||||
| #include "extern.h" | ||||
| 
 | ||||
| DB *db; | ||||
| time_t now; | ||||
| int entries, gflag, lflag, mflag, oflag, sflag, eightflag, pplan; | ||||
| char tbuf[1024]; | ||||
| struct utmpentry *ehead; | ||||
| 
 | ||||
| static void loginlist(void); | ||||
| static void userlist(int, char **); | ||||
| int main(int, char **); | ||||
| 
 | ||||
| int | ||||
| main(int argc, char **argv) | ||||
| { | ||||
| 	int ch; | ||||
| 
 | ||||
| 	/* Allow user's locale settings to affect character output. */ | ||||
| 	setlocale(LC_CTYPE, ""); | ||||
| 
 | ||||
| 	/*
 | ||||
| 	 * Reset back to the C locale, unless we are using a known | ||||
| 	 * single-byte 8-bit locale. | ||||
| 	 */ | ||||
| 	if (strncmp(nl_langinfo(CODESET), "ISO8859-", 8)) | ||||
| 		setlocale(LC_CTYPE, "C"); | ||||
| 
 | ||||
| 	oflag = 1;		/* default to old "office" behavior */ | ||||
| 
 | ||||
| 	while ((ch = getopt(argc, argv, "lmpshog8")) != -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 'g': | ||||
| 			gflag = 1;		/* no gecos info, besides name */ | ||||
| 			break; | ||||
| 		case '8': | ||||
| 			eightflag = 1;		/* 8-bit pass-through */ | ||||
| 			break; | ||||
| 		case '?': | ||||
| 		default: | ||||
| 			(void)fprintf(stderr, | ||||
| 			    "usage: finger [-lmpshog8] [login ...]\n"); | ||||
| 			exit(1); | ||||
| 		} | ||||
| 	argc -= optind; | ||||
| 	argv += optind; | ||||
| 
 | ||||
| 	(void)time(&now); | ||||
| 	setpassent(1); | ||||
| 	entries = getutentries(NULL, &ehead); | ||||
| 	if (argc == 0) { | ||||
| 		/*
 | ||||
| 		 * 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(void) | ||||
| { | ||||
| 	PERSON *pn; | ||||
| 	DBT data, key; | ||||
| 	struct passwd *pw; | ||||
| 	int r, seqflag; | ||||
| 	struct utmpentry *ep; | ||||
| 
 | ||||
| 	for (ep = ehead; ep; ep = ep->next) { | ||||
| 		if ((pn = find_person(ep->name)) == NULL) { | ||||
| 			if ((pw = getpwnam(ep->name)) == NULL) | ||||
| 				continue; | ||||
| 			pn = enter_person(pw); | ||||
| 		} | ||||
| 		enter_where(ep, pn); | ||||
| 	} | ||||
| 	if (db && lflag) | ||||
| 		for (seqflag = R_FIRST;; seqflag = R_NEXT) { | ||||
| 			PERSON *tmp; | ||||
| 
 | ||||
| 			r = (*db->seq)(db, &key, &data, seqflag); | ||||
| 			if (r == -1) | ||||
| 				err(1, "db seq"); | ||||
| 			if (r == 1) | ||||
| 				break; | ||||
| 			memmove(&tmp, data.data, sizeof tmp); | ||||
| 			enter_lastlog(tmp); | ||||
| 		} | ||||
| } | ||||
| 
 | ||||
| static void | ||||
| userlist(int argc, char **argv) | ||||
| { | ||||
| 	PERSON *pn; | ||||
| 	DBT data, key; | ||||
| 	struct passwd *pw; | ||||
| 	int r, seqflag, *used, *ip; | ||||
| 	char **ap, **nargv, **np, **p; | ||||
| 	struct utmpentry *ep; | ||||
| 
 | ||||
| 	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 (strchr(*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)) != NULL) | ||||
| 				enter_person(pw); | ||||
| 			else | ||||
| 				warnx("%s: no such user", *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) | ||||
| 				warnx("%s: no such user", *p); | ||||
| 	} | ||||
| 
 | ||||
| 	/* Handle network requests. */ | ||||
| net: | ||||
| 	for (p = nargv; *p;) | ||||
| 		netfinger(*p++); | ||||
| 
 | ||||
| 	if (entries == 0) | ||||
| 		goto done; | ||||
| 
 | ||||
| 	/*
 | ||||
| 	 * Scan thru the list of users currently logged in, saving | ||||
| 	 * appropriate data whenever a match occurs. | ||||
| 	 */ | ||||
| 	for (ep = ehead; ep; ep = ep->next) { | ||||
| 		if ((pn = find_person(ep->name)) == NULL) | ||||
| 			continue; | ||||
| 		enter_where(ep, pn); | ||||
| 	} | ||||
| 	if (db != NULL) | ||||
| 		for (seqflag = R_FIRST;; seqflag = R_NEXT) { | ||||
| 			PERSON *tmp; | ||||
| 
 | ||||
| 			r = (*db->seq)(db, &key, &data, seqflag); | ||||
| 			if (r == -1) | ||||
| 				err(1, "db seq"); | ||||
| 			if (r == 1) | ||||
| 				break; | ||||
| 			memmove(&tmp, data.data, sizeof tmp); | ||||
| 			enter_lastlog(tmp); | ||||
| 		} | ||||
| done: | ||||
| 	free(nargv); | ||||
| 	free(used); | ||||
| } | ||||
							
								
								
									
										67
									
								
								usr.bin/finger/finger.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										67
									
								
								usr.bin/finger/finger.h
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,67 @@ | ||||
| /*	$NetBSD: finger.h,v 1.10 2007/05/05 16:55:17 christos Exp $	*/ | ||||
| 
 | ||||
| /*
 | ||||
|  * 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. 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. | ||||
|  * | ||||
|  *	from: @(#)finger.h	8.1 (Berkeley) 6/6/93 | ||||
|  */ | ||||
| 
 | ||||
| 
 | ||||
| /*
 | ||||
|  * All unique persons are linked in a list headed by "head" and linkd | ||||
|  * by the "next" field, as well as kept in a hash table. | ||||
|  */ | ||||
| 
 | ||||
| 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 */ | ||||
| 	time_t mailread;		/* last time mail was read */ | ||||
| 	time_t mailrecv;		/* last time mail was read */ | ||||
| 	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;			/* tty line */ | ||||
| 	char *host;			/* remote host name */ | ||||
| } WHERE; | ||||
							
								
								
									
										389
									
								
								usr.bin/finger/lprint.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										389
									
								
								usr.bin/finger/lprint.c
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,389 @@ | ||||
| /*	$NetBSD: lprint.c,v 1.23 2013/01/18 22:10:31 christos Exp $	*/ | ||||
| 
 | ||||
| /*
 | ||||
|  * 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. 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. | ||||
|  */ | ||||
| 
 | ||||
| #include <sys/cdefs.h> | ||||
| #ifndef lint | ||||
| #if 0 | ||||
| static char sccsid[] = "@(#)lprint.c	8.3 (Berkeley) 4/28/95"; | ||||
| #else | ||||
| __RCSID( "$NetBSD: lprint.c,v 1.23 2013/01/18 22:10:31 christos Exp $"); | ||||
| #endif | ||||
| #endif /* not lint */ | ||||
| 
 | ||||
| #include <sys/types.h> | ||||
| #include <sys/stat.h> | ||||
| #include <sys/time.h> | ||||
| #include <fcntl.h> | ||||
| #include <tzfile.h> | ||||
| #include <db.h> | ||||
| #include <err.h> | ||||
| #include <pwd.h> | ||||
| #include <errno.h> | ||||
| #include <unistd.h> | ||||
| #include <stdio.h> | ||||
| #include <string.h> | ||||
| #include <time.h> | ||||
| #include <ctype.h> | ||||
| #include <paths.h> | ||||
| #include <vis.h> | ||||
| 
 | ||||
| #include "utmpentry.h" | ||||
| #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(const char *, int); | ||||
| static void	lprint(PERSON *); | ||||
| static int	show_text(const char *, const char *, const char *); | ||||
| static void	vputc(int); | ||||
| 
 | ||||
| #ifdef __SVR4 | ||||
| #define TIMEZONE(a)	tzname[0] | ||||
| #else | ||||
| #define TIMEZONE(a)	(a)->tm_zone | ||||
| #endif | ||||
| 
 | ||||
| void | ||||
| lflag_print(void) | ||||
| { | ||||
| 	PERSON *pn; | ||||
| 	int sflag, r; | ||||
| 	PERSON *tmp; | ||||
| 	DBT data, key; | ||||
| 
 | ||||
| 	if (db == NULL) | ||||
| 		return; | ||||
| 
 | ||||
| 	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 size_t | ||||
| visify(char *buf, size_t blen, const char *str) | ||||
| { | ||||
| 	int len = strnvisx(buf, blen, str, strlen(str), VIS_WHITE|VIS_CSTYLE); | ||||
| 	if (len == -1) { | ||||
| 		buf[0] = '\0'; | ||||
| 		return 0; | ||||
| 	} | ||||
| 	return len; | ||||
| } | ||||
| 
 | ||||
| static void | ||||
| fmt_time(char *buf, size_t blen, time_t ti, time_t n) | ||||
| { | ||||
| 	struct tm *tp = localtime(&ti); | ||||
| 	if (tp != NULL) { | ||||
| 		char *t = asctime(tp); | ||||
| 		char *tzn = TIMEZONE(tp); | ||||
| 		if (n == (time_t)-1 || | ||||
| 		    n - ti > SECSPERDAY * DAYSPERNYEAR / 2) | ||||
| 			snprintf(buf, blen, "%.16s %.4s (%s)", t, t + 20, tzn); | ||||
| 		else | ||||
| 			snprintf(buf, blen, "%.16s (%s)", t, tzn); | ||||
| 	} else | ||||
| 		snprintf(buf, blen, "[*bad time 0x%llx*]", (long long)ti); | ||||
| } | ||||
| 
 | ||||
| /*
 | ||||
|  * 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. | ||||
|  */ | ||||
| static int | ||||
| print_idle(time_t t, int maxlen, size_t hostlen, size_t ttylen) { | ||||
| 
 | ||||
| 	int cpr; | ||||
| 	struct tm *delta = gmtime(&t); | ||||
| 
 | ||||
| 	if (delta == NULL) | ||||
| 		return printf("Bad idle 0x%llx", (long long)t); | ||||
| 
 | ||||
| 	if (delta->tm_yday == 0 && delta->tm_hour == 0 && delta->tm_min == 0) | ||||
| 		return 0; | ||||
| 
 | ||||
| 	cpr = printf("%-*s idle ", (int)(maxlen - ttylen + 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 (hostlen) { | ||||
| 		putchar(','); | ||||
| 		++cpr; | ||||
| 	} | ||||
| 	return cpr; | ||||
| } | ||||
| 
 | ||||
| static void | ||||
| lprint(PERSON *pn) | ||||
| { | ||||
| 	WHERE *w; | ||||
| 	int cpr, len, maxlen; | ||||
| 	int oddfield; | ||||
| 	char timebuf[128], ttybuf[64], hostbuf[512]; | ||||
| 	size_t ttylen, hostlen; | ||||
| 
 | ||||
| 	cpr = 0; | ||||
| 	/*
 | ||||
| 	 * 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); | ||||
| 
 | ||||
| 	if (gflag) | ||||
| 		goto no_gecos; | ||||
| 	/*
 | ||||
| 	 * 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(timebuf, sizeof(timebuf), "%s: %s, %s", | ||||
| 		    OFFICE_TAG, pn->office, prphone(pn->officephone)); | ||||
| 		oddfield = demi_print(timebuf, oddfield); | ||||
| 	} else { | ||||
| 		if (pn->office) { | ||||
| 			(void)snprintf(timebuf, sizeof(timebuf), "%s: %s", | ||||
| 			    OFFICE_TAG, pn->office); | ||||
| 			oddfield = demi_print(timebuf, oddfield); | ||||
| 		} | ||||
| 		if (pn->officephone) { | ||||
| 			(void)snprintf(timebuf, sizeof(timebuf), "%s: %s", | ||||
| 			    OFFICE_PHONE_TAG, prphone(pn->officephone)); | ||||
| 			oddfield = demi_print(timebuf, oddfield); | ||||
| 		} | ||||
| 	} | ||||
| 	if (pn->homephone) { | ||||
| 		(void)snprintf(timebuf, sizeof(timebuf), "%s: %s", "Home Phone", | ||||
| 		    prphone(pn->homephone)); | ||||
| 		oddfield = demi_print(timebuf, oddfield); | ||||
| 	} | ||||
| 	if (oddfield) | ||||
| 		putchar('\n'); | ||||
| 
 | ||||
| no_gecos: | ||||
| 	/*
 | ||||
| 	 * 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) { | ||||
| 		visify(ttybuf, sizeof(ttybuf), w->tty); | ||||
| 		if ((len = strlen(ttybuf)) > maxlen) | ||||
| 			maxlen = len; | ||||
| 	} | ||||
| 	/* find rest of entries for user */ | ||||
| 	for (w = pn->whead; w != NULL; w = w->next) { | ||||
| 		ttylen = visify(ttybuf, sizeof(ttybuf), w->tty); | ||||
| 		hostlen = visify(hostbuf, sizeof(hostbuf), w->host); | ||||
| 		switch (w->info) { | ||||
| 		case LOGGEDIN: | ||||
| 			fmt_time(timebuf, sizeof(timebuf), w->loginat, -1); | ||||
| 			cpr = printf("On since %s on %s", timebuf, ttybuf); | ||||
| 
 | ||||
| 			cpr += print_idle(w->idletime, maxlen, hostlen, | ||||
| 			    ttylen); | ||||
| 
 | ||||
| 			if (!w->writable) | ||||
| 				cpr += printf(" (messages off)"); | ||||
| 			break; | ||||
| 		case LASTLOG: | ||||
| 			if (w->loginat == 0) { | ||||
| 				(void)printf("Never logged in."); | ||||
| 				break; | ||||
| 			} | ||||
| 			fmt_time(timebuf, sizeof(timebuf), w->loginat, now); | ||||
| 			cpr = printf("Last login %s on %s", timebuf, ttybuf); | ||||
| 			break; | ||||
| 		} | ||||
| 		if (hostlen) { | ||||
| 			if (LINE_LEN < (cpr + 6 + hostlen)) | ||||
| 				(void)printf("\n   "); | ||||
| 			(void)printf(" from %s", hostbuf); | ||||
| 		} | ||||
| 		putchar('\n'); | ||||
| 	} | ||||
| 	if (pn->mailrecv == -1) | ||||
| 		printf("No Mail.\n"); | ||||
| 	else if (pn->mailrecv > pn->mailread) { | ||||
| 		fmt_time(timebuf, sizeof(timebuf), pn->mailrecv, -1); | ||||
| 		printf("New mail received %s\n", timebuf); | ||||
| 		fmt_time(timebuf, sizeof(timebuf), pn->mailread, -1); | ||||
| 		printf("     Unread since %s\n", timebuf); | ||||
| 	} else { | ||||
| 		fmt_time(timebuf, sizeof(timebuf), pn->mailread, -1); | ||||
| 		printf("Mail last read %s\n", timebuf); | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| static int | ||||
| demi_print(const 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(const char *directory, const char *file_name, const char *header)	 | ||||
| { | ||||
| 	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 ((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 <= (off_t)(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 = (unsigned char)*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(int ch) | ||||
| { | ||||
| 	char visout[5], *s2; | ||||
| 
 | ||||
| 	if (eightflag || isprint(ch) || isspace(ch)) { | ||||
| 	    (void)putchar(ch); | ||||
| 	    return; | ||||
| 	} | ||||
| 	ch = toascii(ch); | ||||
| 	vis(visout, ch, VIS_SAFE|VIS_NOSLASH, 0); | ||||
| 	for (s2 = visout; *s2; s2++) | ||||
| 		(void)putchar(*s2); | ||||
| } | ||||
							
								
								
									
										159
									
								
								usr.bin/finger/net.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										159
									
								
								usr.bin/finger/net.c
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,159 @@ | ||||
| /*	$NetBSD: net.c,v 1.23 2009/04/12 06:18:54 lukem Exp $	*/ | ||||
| 
 | ||||
| /*
 | ||||
|  * 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. 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. | ||||
|  */ | ||||
| 
 | ||||
| #include <sys/cdefs.h> | ||||
| #ifndef lint | ||||
| #if 0 | ||||
| static char sccsid[] = "@(#)net.c	8.4 (Berkeley) 4/28/95"; | ||||
| #else | ||||
| __RCSID("$NetBSD: net.c,v 1.23 2009/04/12 06:18:54 lukem Exp $"); | ||||
| #endif | ||||
| #endif /* not lint */ | ||||
| 
 | ||||
| #include <sys/types.h> | ||||
| #include <sys/socket.h> | ||||
| 
 | ||||
| #include <netinet/in.h> | ||||
| 
 | ||||
| #include <arpa/inet.h> | ||||
| 
 | ||||
| #include <netdb.h> | ||||
| #include <time.h> | ||||
| #include <db.h> | ||||
| #include <unistd.h> | ||||
| #include <pwd.h> | ||||
| #include <stdio.h> | ||||
| #include <string.h> | ||||
| #include <ctype.h> | ||||
| #include <err.h> | ||||
| 
 | ||||
| #include "utmpentry.h" | ||||
| 
 | ||||
| #include "finger.h" | ||||
| #include "extern.h" | ||||
| 
 | ||||
| void | ||||
| netfinger(char *name) | ||||
| { | ||||
| 	FILE *fp; | ||||
| 	int c, lastc; | ||||
| 	int s; | ||||
| 	char *host; | ||||
| 	struct addrinfo hints, *res, *res0; | ||||
| 	int error; | ||||
| 	const char *emsg = NULL; | ||||
| 
 | ||||
| 	lastc = 0; | ||||
| 	if (!(host = strrchr(name, '@'))) | ||||
| 		return; | ||||
| 	*host++ = '\0'; | ||||
| 	memset(&hints, 0, sizeof(hints)); | ||||
| 	hints.ai_family = PF_UNSPEC; | ||||
| 	hints.ai_socktype = SOCK_STREAM; | ||||
| 	hints.ai_flags = AI_CANONNAME; | ||||
| 	error = getaddrinfo(host, "finger", &hints, &res0); | ||||
| 	if (error) { | ||||
| 		warnx("%s: %s", gai_strerror(error), host); | ||||
| 		return; | ||||
| 	} | ||||
| 
 | ||||
| 	s = -1; | ||||
| 	for (res = res0; res; res = res->ai_next) { | ||||
| 		s = socket(res->ai_family, res->ai_socktype, res->ai_protocol); | ||||
| 		if (s < 0) { | ||||
| 			emsg = "socket"; | ||||
| 			continue; | ||||
| 		} | ||||
| 
 | ||||
| 		if (connect(s, res->ai_addr, res->ai_addrlen)) { | ||||
| 			close(s); | ||||
| 			s = -1; | ||||
| 			emsg = "connect"; | ||||
| 			continue; | ||||
| 		} | ||||
| 
 | ||||
| 		break; | ||||
| 	} | ||||
| 	if (s < 0) { | ||||
| 		if (emsg != NULL) | ||||
| 			warn("%s", emsg); | ||||
| 		return; | ||||
| 	} | ||||
| 
 | ||||
| 	/* have network connection; identify the host connected with */ | ||||
| 	(void)printf("[%s]\n", res0->ai_canonname ? res0->ai_canonname : host); | ||||
| 
 | ||||
| 	/* -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> followed by a newline character, only output | ||||
| 	 * one newline. | ||||
| 	 * | ||||
| 	 * If a character isn't printable and it isn't a space, we strip the | ||||
| 	 * 8th bit and set the 7th bit.  Every ASCII character with bit 7 set | ||||
| 	 * is printable. | ||||
| 	 */ | ||||
| 	if ((fp = fdopen(s, "r")) != NULL) | ||||
| 		while ((c = getc(fp)) != EOF) { | ||||
| 			if (c == '\r') { | ||||
| 				if (lastc == '\r')	/* ^M^M - skip dupes */ | ||||
| 					continue; | ||||
| 				c = '\n'; | ||||
| 				lastc = '\r'; | ||||
| 			} else { | ||||
| 				if (!(eightflag || isprint(c) || isspace(c))) { | ||||
| 					c &= 0x7f; | ||||
| 					c |= 0x40; | ||||
| 				} | ||||
| 				if (lastc != '\r' || c != '\n') | ||||
| 					lastc = c; | ||||
| 				else { | ||||
| 					lastc = '\n'; | ||||
| 					continue; | ||||
| 				} | ||||
| 			} | ||||
| 			putchar(c); | ||||
| 		} | ||||
| 	if (lastc != '\n') | ||||
| 		putchar('\n'); | ||||
| 	(void)fclose(fp); | ||||
| } | ||||
							
								
								
									
										173
									
								
								usr.bin/finger/sprint.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										173
									
								
								usr.bin/finger/sprint.c
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,173 @@ | ||||
| /*	$NetBSD: sprint.c,v 1.17 2006/01/04 01:17:54 perry Exp $	*/ | ||||
| 
 | ||||
| /*
 | ||||
|  * 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. 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. | ||||
|  */ | ||||
| 
 | ||||
| #include <sys/cdefs.h> | ||||
| #ifndef lint | ||||
| #if 0 | ||||
| static char sccsid[] = "@(#)sprint.c	8.3 (Berkeley) 4/28/95"; | ||||
| #else | ||||
| __RCSID("$NetBSD: sprint.c,v 1.17 2006/01/04 01:17:54 perry Exp $"); | ||||
| #endif | ||||
| #endif /* not lint */ | ||||
| 
 | ||||
| #include <sys/param.h> | ||||
| #include <sys/time.h> | ||||
| 
 | ||||
| #include <time.h> | ||||
| #include <tzfile.h> | ||||
| #include <db.h> | ||||
| #include <err.h> | ||||
| #include <pwd.h> | ||||
| #include <errno.h> | ||||
| #include <stdio.h> | ||||
| #include <stdlib.h> | ||||
| #include <string.h> | ||||
| 
 | ||||
| #include "utmpentry.h" | ||||
| 
 | ||||
| #include "finger.h" | ||||
| #include "extern.h" | ||||
| 
 | ||||
| static void	  stimeprint(WHERE *); | ||||
| 
 | ||||
| void | ||||
| sflag_print(void) | ||||
| { | ||||
| 	PERSON *pn; | ||||
| 	WHERE *w; | ||||
| 	int sflag, r; | ||||
| 	char *p; | ||||
| 	PERSON *tmp; | ||||
| 	DBT data, key; | ||||
| 
 | ||||
| 	if (db == NULL) | ||||
| 		return; | ||||
| 
 | ||||
| 	/*
 | ||||
| 	 * short format -- | ||||
| 	 *	login name | ||||
| 	 *	real name | ||||
| 	 *	terminal name | ||||
| 	 *	if terminal writable (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 months, | ||||
| 	 *		show year instead of time.  If < 6 days, | ||||
| 	 *		show day name instead of month & day. | ||||
| 	 *	if -h given | ||||
| 	 *		remote host | ||||
| 	 *	else if -o given (overriding -h) (default) | ||||
| 	 *		office location | ||||
| 	 *		office phone | ||||
| 	 */ | ||||
| #define	MAXREALNAME	18 | ||||
| 	(void)printf("%-*s %-*s %s %s\n", maxname, "Login", MAXREALNAME, | ||||
| 	    "Name", " Tty      Idle  Login Time  ", (gflag) ? "" : | ||||
| 	    (oflag) ? "Office     Office Phone" : "Where"); | ||||
| 
 | ||||
| 	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 ", (int)maxname,  | ||||
| 			    (int)maxname, | ||||
| 			    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("%-7.7s ", w->tty); | ||||
| 			else | ||||
| 				(void)printf("        "); | ||||
| 			if (w->info == LOGGEDIN) { | ||||
| 				stimeprint(w); | ||||
| 				(void)printf("  "); | ||||
| 			} else | ||||
| 				(void)printf("    *  "); | ||||
| 			p = ctime(&w->loginat); | ||||
| 			if (now - w->loginat < SECSPERDAY * (DAYSPERWEEK - 1)) | ||||
| 				(void)printf("%.3s %-8.5s", p, p + 11); | ||||
| 			else if (now - w->loginat | ||||
| 			      < SECSPERDAY * DAYSPERNYEAR / 2) | ||||
| 				(void)printf("%.6s %-5.5s", p + 4, p + 11); | ||||
| 			else | ||||
| 				(void)printf("%.6s %-5.4s", p + 4, p + 20); | ||||
| office: | ||||
| 			if (gflag) | ||||
| 				goto no_gecos; | ||||
| 			putchar(' '); | ||||
| 			if (oflag) { | ||||
| 				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)); | ||||
| 			} else | ||||
| 				(void)printf("%.*s", MAXHOSTNAMELEN, w->host); | ||||
| no_gecos: | ||||
| 			putchar('\n'); | ||||
| 		} | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| static void | ||||
| stimeprint(WHERE *w) | ||||
| { | ||||
| 	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); | ||||
| } | ||||
							
								
								
									
										409
									
								
								usr.bin/finger/util.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										409
									
								
								usr.bin/finger/util.c
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,409 @@ | ||||
| /*	$NetBSD: util.c,v 1.28 2009/04/12 06:18:54 lukem Exp $	*/ | ||||
| 
 | ||||
| /*
 | ||||
|  * 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. 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. | ||||
|  */ | ||||
| 
 | ||||
| /*
 | ||||
|  * Portions Copyright (c) 1983, 1995, 1996 Eric P. Allman | ||||
|  * | ||||
|  * 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. | ||||
|  */ | ||||
| 
 | ||||
| #include <sys/cdefs.h> | ||||
| #ifndef lint | ||||
| #if 0 | ||||
| static char sccsid[] = "@(#)util.c	8.3 (Berkeley) 4/28/95"; | ||||
| #else | ||||
| __RCSID("$NetBSD: util.c,v 1.28 2009/04/12 06:18:54 lukem Exp $"); | ||||
| #endif | ||||
| #endif /* not lint */ | ||||
| 
 | ||||
| #include <sys/param.h> | ||||
| #include <sys/stat.h> | ||||
| 
 | ||||
| #include <db.h> | ||||
| #include <ctype.h> | ||||
| #include <err.h> | ||||
| #include <errno.h> | ||||
| #include <fcntl.h> | ||||
| #include <paths.h> | ||||
| #include <pwd.h> | ||||
| #include <stdio.h> | ||||
| #include <stdlib.h> | ||||
| #include <string.h> | ||||
| #include <unistd.h> | ||||
| #include <utmp.h> | ||||
| 
 | ||||
| #include "utmpentry.h" | ||||
| 
 | ||||
| #include "finger.h" | ||||
| #include "extern.h" | ||||
| 
 | ||||
| static void	 find_idle_and_ttywrite(WHERE *); | ||||
| static void	 userinfo(PERSON *, struct passwd *); | ||||
| static WHERE	*walloc(PERSON *); | ||||
| 
 | ||||
| int | ||||
| match(struct passwd *pw, char *user) | ||||
| { | ||||
| 	char *p; | ||||
| 	char *bp, name[1024]; | ||||
| 
 | ||||
| 	if (!strcasecmp(pw->pw_name, user)) | ||||
| 		return(1); | ||||
| 
 | ||||
| 	(void)strlcpy(bp = tbuf, pw->pw_gecos, sizeof(tbuf)); | ||||
| 
 | ||||
| 	/* Ampersands get replaced by the login name. */ | ||||
| 	if (!(p = strsep(&bp, ","))) | ||||
| 		return(0); | ||||
| 
 | ||||
| 	expandusername(p, pw->pw_name, name, sizeof(name)); | ||||
| 	bp = name; | ||||
| 	while ((p = strsep(&bp, "\t "))) | ||||
| 		if (!strcasecmp(p, user)) | ||||
| 			return(1); | ||||
| 	return(0); | ||||
| } | ||||
| 
 | ||||
| /* inspired by usr.sbin/sendmail/util.c::buildfname */ | ||||
| void | ||||
| expandusername(const char *gecos, const char *login, char *buf, int buflen) | ||||
| { | ||||
| 	const char *p; | ||||
| 	char *bp; | ||||
| 
 | ||||
| 	/* why do we skip asterisks!?!? */ | ||||
| 	if (*gecos == '*') | ||||
| 		gecos++; | ||||
| 	bp = buf; | ||||
| 
 | ||||
| 	/* copy gecos, interpolating & to be full name */ | ||||
| 	for (p = gecos; *p != '\0'; p++) { | ||||
| 		if (bp >= &buf[buflen - 1]) { | ||||
| 			/* buffer overflow - just use login name */ | ||||
| 			snprintf(buf, buflen, "%s", login); | ||||
| 			buf[buflen - 1] = '\0'; | ||||
| 			return; | ||||
| 		} | ||||
| 		if (*p == '&') { | ||||
| 			/* interpolate full name */ | ||||
| 			snprintf(bp, buflen - (bp - buf), "%s", login); | ||||
| 			*bp = toupper((unsigned char)*bp); | ||||
| 			bp += strlen(bp); | ||||
| 		} | ||||
| 		else | ||||
| 			*bp++ = *p; | ||||
| 	} | ||||
| 	*bp = '\0'; | ||||
| } | ||||
| 
 | ||||
| void | ||||
| enter_lastlog(PERSON *pn) | ||||
| { | ||||
| 	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, (off_t)pn->uid * sizeof(ll), SEEK_SET) != | ||||
| 	    (off_t)pn->uid * (off_t)sizeof(ll) || | ||||
| 	    read(fd, (char *)&ll, sizeof(ll)) != sizeof(ll)) { | ||||
| 			/* as if never logged in */ | ||||
| 			ll.ll_line[0] = ll.ll_host[0] = '\0'; | ||||
| 			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; | ||||
| 		if ((w->tty = malloc(UT_LINESIZE + 1)) == NULL) | ||||
| 			err(1, NULL); | ||||
| 		memcpy(w->tty, ll.ll_line, UT_LINESIZE); | ||||
| 		w->tty[UT_LINESIZE] = '\0'; | ||||
| 		if ((w->host = malloc(UT_HOSTSIZE + 1)) == NULL) | ||||
| 			err(1, NULL); | ||||
| 		memcpy(w->host, ll.ll_host, UT_HOSTSIZE); | ||||
| 		w->host[UT_HOSTSIZE] = '\0'; | ||||
| 		w->loginat = ll.ll_time; | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| void | ||||
| enter_where(struct utmpentry *ep, PERSON *pn) | ||||
| { | ||||
| 	WHERE *w = walloc(pn); | ||||
| 
 | ||||
| 	w->info = LOGGEDIN; | ||||
| 	w->tty = ep->line; | ||||
| 	w->host = ep->host; | ||||
| 	w->loginat = (time_t)ep->tv.tv_sec; | ||||
| 	find_idle_and_ttywrite(w); | ||||
| } | ||||
| 
 | ||||
| PERSON * | ||||
| enter_person(struct passwd *pw) | ||||
| { | ||||
| 	DBT data, key; | ||||
| 	PERSON *pn; | ||||
| 
 | ||||
| 	if (db == NULL && | ||||
| 	    (db = dbopen(NULL, O_RDWR, 0, DB_BTREE, NULL)) == NULL) | ||||
| 		err(1, NULL); | ||||
| 
 | ||||
| 	key.data = (char *)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(); | ||||
| 		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); | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| PERSON * | ||||
| find_person(char *name) | ||||
| { | ||||
| 	DBT data, key; | ||||
| 	PERSON *p; | ||||
| 
 | ||||
| 	if (!db) | ||||
| 		return(NULL); | ||||
| 
 | ||||
| 	key.data = name; | ||||
| 	key.size = strlen(name); | ||||
| 
 | ||||
| 	if ((*db->get)(db, &key, &data, 0)) | ||||
| 		return (NULL); | ||||
| 	memmove(&p, data.data, sizeof p); | ||||
| 	return (p); | ||||
| } | ||||
| 
 | ||||
| PERSON * | ||||
| palloc(void) | ||||
| { | ||||
| 	PERSON *p; | ||||
| 
 | ||||
| 	if ((p = malloc((u_int) sizeof(PERSON))) == NULL) | ||||
| 		err(1, NULL); | ||||
| 	return(p); | ||||
| } | ||||
| 
 | ||||
| static WHERE * | ||||
| walloc(PERSON *pn) | ||||
| { | ||||
| 	WHERE *w; | ||||
| 
 | ||||
| 	if ((w = malloc((u_int) sizeof(WHERE))) == NULL) | ||||
| 		err(1, NULL); | ||||
| 	if (pn->whead == NULL) | ||||
| 		pn->whead = pn->wtail = w; | ||||
| 	else { | ||||
| 		pn->wtail->next = w; | ||||
| 		pn->wtail = w; | ||||
| 	} | ||||
| 	w->next = NULL; | ||||
| 	return(w); | ||||
| } | ||||
| 
 | ||||
| char * | ||||
| prphone(char *num) | ||||
| { | ||||
| 	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((unsigned char)*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 */ | ||||
| 	case 4:				/* x1234 */ | ||||
| 		*p++ = 'x'; | ||||
| 		*p++ = *num++; | ||||
| 		break; | ||||
| 	default: | ||||
| 		return(num); | ||||
| 	} | ||||
| 	if (len != 4) { | ||||
| 		*p++ = '-'; | ||||
| 		*p++ = *num++; | ||||
| 	} | ||||
| 	*p++ = *num++; | ||||
| 	*p++ = *num++; | ||||
| 	*p++ = *num++; | ||||
| 	*p = '\0'; | ||||
| 	return(pbuf); | ||||
| } | ||||
| 
 | ||||
| static void | ||||
| find_idle_and_ttywrite(WHERE *w) | ||||
| { | ||||
| 	struct stat sb; | ||||
| 
 | ||||
| 	(void)snprintf(tbuf, sizeof(tbuf), "%s/%s", _PATH_DEV, w->tty); | ||||
| 	if (stat(tbuf, &sb) < 0) { | ||||
| 		warn("%s", 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(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)strlcpy(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_MAILDIR, | ||||
| 	    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; | ||||
| 	} | ||||
| } | ||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user
	 Thomas Cort
						Thomas Cort