* Copyright (c) 1989 The Regents of the University of California.
* 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
* 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
static char sccsid
[] = "@(#)util.c 5.14 (Berkeley) 1/17/91";
find_idle_and_ttywrite(w
)
(void)sprintf(tbuf
, "%s/%s", _PATH_DEV
, w
->tty
);
if (stat(tbuf
, &sb
) < 0) {
"finger: %s: %s\n", tbuf
, strerror(errno
));
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
);
register struct passwd
*pw
;
pn
->realname
= pn
->office
= pn
->officephone
= pn
->homephone
= NULL
;
pn
->name
= strdup(pw
->pw_name
);
pn
->dir
= strdup(pw
->pw_dir
);
pn
->shell
= strdup(pw
->pw_shell
);
/* why do we skip asterisks!?!? */
(void)strcpy(bp
= tbuf
, pw
->pw_gecos
);
/* ampersands get replaced by the login name */
if (!(p
= strsep(&bp
, ",")))
for (t
= name
; *t
= *p
; ++p
)
(void)strcpy(t
, pw
->pw_name
);
pn
->realname
= strdup(name
);
pn
->office
= ((p
= strsep(&bp
, ",")) && *p
) ?
pn
->officephone
= ((p
= strsep(&bp
, ",")) && *p
) ?
pn
->homephone
= ((p
= strsep(&bp
, ",")) && *p
) ?
/* why do we skip asterisks!?!? */
(void)strcpy(p
= tbuf
, pw
->pw_gecos
);
/* ampersands get replaced by the login name */
if (!(p
= strtok(p
, ",")))
for (t
= name
; *t
= *p
; ++p
)
(void)strcpy(t
, pw
->pw_name
);
for (t
= name
; p
= strtok(t
, "\t "); t
= (char *)NULL
)
if (!strcasecmp(p
, user
))
/* some systems may not maintain lastlog, don't report errors. */
fd
= open(_PATH_LASTLOG
, O_RDONLY
, 0);
lseek(fd
, (long)pn
->uid
* sizeof(ll
), L_SET
) !=
(long)pn
->uid
* sizeof(ll
) ||
read(fd
, (char *)&ll
, sizeof(ll
)) != sizeof(ll
)) {
/* as if never logged in */
ll
.ll_line
[0] = ll
.ll_host
[0] = NULL
;
if ((w
= pn
->whead
) == NULL
)
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
)
* 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)
bcopy(ll
.ll_line
, w
->tty
, UT_LINESIZE
);
bcopy(ll
.ll_host
, w
->host
, UT_HOSTSIZE
);
w
->host
[UT_HOSTSIZE
] = 0;
register WHERE
*w
= walloc(pn
);
bcopy(ut
->ut_line
, w
->tty
, UT_LINESIZE
);
bcopy(ut
->ut_host
, w
->host
, UT_HOSTSIZE
);
w
->host
[UT_HOSTSIZE
] = 0;
w
->loginat
= (time_t)ut
->ut_time
;
find_idle_and_ttywrite(w
);
register struct passwd
*pw
;
register PERSON
*pn
, **pp
;
for (pp
= htab
+ hash(pw
->pw_name
);
*pp
!= NULL
&& strcmp((*pp
)->name
, pw
->pw_name
) != 0;
if ((pn
= *pp
) == NULL
) {
/* name may be only UT_NAMESIZE long and not terminated */
for (pn
= htab
[hash(name
)];
pn
!= NULL
&& strncmp(pn
->name
, name
, UT_NAMESIZE
) != 0;
/* name may be only UT_NAMESIZE long and not terminated */
for (i
= UT_NAMESIZE
; --i
>= 0 && *name
;)
h
= ((h
<< 2 | h
>> HBITS
- 2) ^ *name
++) & HMASK
;
if ((p
= (PERSON
*)malloc((u_int
) sizeof(PERSON
))) == NULL
) {
(void)fprintf(stderr
, "finger: out of space.\n");
if ((w
= (WHERE
*)malloc((u_int
) sizeof(WHERE
))) == NULL
) {
(void)fprintf(stderr
, "finger: out of space.\n");
pn
->whead
= pn
->wtail
= w
;
/* don't touch anything if the user has their own formatting */
case 11: /* +0-123-456-7890 */
case 10: /* 012-345-6789 */