Migrate finger(1) away from <utmp.h>.

Unfortunately it also uses lastlog, which means we must resort to local
extensions of the utmpx-interface. Because the user name and TTY name
are now nul-terminated, there is no need to copy around strings as
often.
This commit is contained in:
Ed Schouten 2009-12-28 20:54:34 +00:00
parent 1c80ec0a6b
commit 70ad88f354
8 changed files with 54 additions and 68 deletions

View File

@ -5,4 +5,7 @@ PROG= finger
SRCS= finger.c lprint.c net.c sprint.c util.c
MAN= finger.1 finger.conf.5
DPADD= ${LIBULOG}
LDADD= -lulog
.include <bsd.prog.mk>

View File

@ -51,8 +51,8 @@ extern int invoker_root; /* Invoked by root */
void enter_lastlog(PERSON *);
PERSON *enter_person(struct passwd *);
void enter_where(struct utmp *, PERSON *);
PERSON *find_person(const char *);
void enter_where(struct utmpx *, PERSON *);
PERSON *find_person(char *);
int hide(struct passwd *);
void lflag_print(void);
int match(struct passwd *, const char *);

View File

@ -82,8 +82,9 @@ __FBSDID("$FreeBSD$");
#include <stdlib.h>
#include <string.h>
#include <time.h>
#define _ULOG_POSIX_NAMES
#include <ulog.h>
#include <unistd.h>
#include <utmp.h>
#include <locale.h>
#include "finger.h"
@ -233,29 +234,26 @@ loginlist(void)
PERSON *pn;
DBT data, key;
struct passwd *pw;
struct utmp user;
struct utmpx *user;
int r, sflag1;
char name[UT_NAMESIZE + 1];
if (kflag)
errx(1, "can't list logins without reading utmp");
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])
setutxent();
while ((user = getutxent()) != NULL) {
if (user->ut_type != USER_PROCESS)
continue;
if ((pn = find_person(user.ut_name)) == NULL) {
bcopy(user.ut_name, name, UT_NAMESIZE);
if ((pw = getpwnam(name)) == NULL)
if ((pn = find_person(user->ut_user)) == NULL) {
if ((pw = getpwnam(user->ut_user)) == NULL)
continue;
if (hide(pw))
continue;
pn = enter_person(pw);
}
enter_where(&user, pn);
enter_where(user, pn);
}
endutxent();
if (db && lflag)
for (sflag1 = R_FIRST;; sflag1 = R_NEXT) {
PERSON *tmp;
@ -275,7 +273,7 @@ userlist(int argc, char **argv)
{
PERSON *pn;
DBT data, key;
struct utmp user;
struct utmpx *user;
struct passwd *pw;
int r, sflag1, *used, *ip;
char **ap, **nargv, **np, **p;
@ -384,15 +382,15 @@ net: for (p = nargv; *p;) {
* 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])
setutxent();
while ((user = getutxent()) != NULL) {
if (user->ut_type != USER_PROCESS)
continue;
if ((pn = find_person(user.ut_name)) == NULL)
if ((pn = find_person(user->ut_user)) == NULL)
continue;
enter_where(&user, pn);
enter_where(user, pn);
}
endutxent();
if (db)
for (sflag1 = R_FIRST;; sflag1 = R_NEXT) {
PERSON *tmp;

View File

@ -62,8 +62,8 @@ typedef struct where {
short writable; /* tty is writable */
time_t loginat; /* time of (last) login */
time_t idletime; /* how long idle (if logged in) */
char tty[UT_LINESIZE+1]; /* null terminated tty line */
char host[UT_HOSTSIZE+1]; /* null terminated remote host name */
char tty[sizeof ((struct utmpx *)0)->ut_line]; /* tty line */
char host[sizeof ((struct utmpx *)0)->ut_host]; /* host name */
} WHERE;
#define UNPRIV_NAME "nobody" /* Preferred privilege level */

View File

@ -56,8 +56,9 @@ __FBSDID("$FreeBSD$");
#include <pwd.h>
#include <stdio.h>
#include <string.h>
#define _ULOG_POSIX_NAMES
#include <ulog.h>
#include <unistd.h>
#include <utmp.h>
#include "finger.h"
#include "pathnames.h"

View File

@ -54,8 +54,9 @@ __FBSDID("$FreeBSD$");
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define _ULOG_POSIX_NAMES
#include <ulog.h>
#include <unistd.h>
#include <utmp.h>
#include "finger.h"
static void cleanup(int sig);

View File

@ -43,6 +43,7 @@ static char sccsid[] = "@(#)sprint.c 8.3 (Berkeley) 4/28/95";
#include <sys/cdefs.h>
__FBSDID("$FreeBSD$");
#include <sys/param.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <db.h>
@ -52,7 +53,8 @@ __FBSDID("$FreeBSD$");
#include <stdio.h>
#include <string.h>
#include <time.h>
#include <utmp.h>
#define _ULOG_POSIX_NAMES
#include <ulog.h>
#include "finger.h"
static void stimeprint(WHERE *);
@ -88,7 +90,7 @@ sflag_print(void)
*/
#define MAXREALNAME 16
#define MAXHOSTNAME 17 /* in reality, hosts are never longer than 16 */
(void)printf("%-*s %-*s%s %s\n", UT_NAMESIZE, "Login", MAXREALNAME,
(void)printf("%-*s %-*s%s %s\n", MAXLOGNAME, "Login", MAXREALNAME,
"Name", " TTY Idle Login Time ", (gflag) ? "" :
oflag ? "Office Phone" : "Where");
@ -105,7 +107,7 @@ sflag_print(void)
namelen = MAXREALNAME;
if (w->info == LOGGEDIN && !w->writable)
--namelen; /* leave space before `*' */
(void)printf("%-*.*s %-*.*s", UT_NAMESIZE, UT_NAMESIZE,
(void)printf("%-*.*s %-*.*s", MAXLOGNAME, MAXLOGNAME,
pn->name, MAXREALNAME, namelen,
pn->realname ? pn->realname : "");
if (!w->loginat) {

View File

@ -56,8 +56,9 @@ __FBSDID("$FreeBSD$");
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define _ULOG_POSIX_NAMES
#include <ulog.h>
#include <unistd.h>
#include <utmp.h>
#include "finger.h"
#include "pathnames.h"
@ -109,29 +110,18 @@ void
enter_lastlog(PERSON *pn)
{
WHERE *w;
static int opened, fd;
struct lastlog ll;
struct ulog_utmpx *ut;
char doit = 0;
/* some systems may not maintain lastlog, don't report errors. */
if (!opened) {
fd = open(_PATH_LASTLOG, O_RDONLY, 0);
opened = 1;
}
if (fd == -1 ||
lseek(fd, (long)pn->uid * sizeof(ll), SEEK_SET) !=
(long)pn->uid * sizeof(ll) ||
read(fd, (char *)&ll, sizeof(ll)) != sizeof(ll)) {
/* as if never logged in */
ll.ll_line[0] = ll.ll_host[0] = '\0';
ll.ll_time = 0;
}
ulog_setutxfile(UTXI_USER, NULL);
ut = ulog_getutxuser(pn->name);
if ((w = pn->whead) == NULL)
doit = 1;
else if (ll.ll_time != 0) {
else if (ut != NULL && ut->ut_type == USER_PROCESS) {
/* 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)
if (w->info == LOGGEDIN &&
w->loginat < ut->ut_tv.tv_sec)
doit = 1;
/*
* and if it's not any of the current logins
@ -140,32 +130,29 @@ enter_lastlog(PERSON *pn)
*/
for (w = pn->whead; doit && w != NULL; w = w->next)
if (w->info == LOGGEDIN &&
strncmp(w->tty, ll.ll_line, UT_LINESIZE) == 0)
strcmp(w->tty, ut->ut_line) == 0)
doit = 0;
}
if (doit) {
if (ut != NULL && doit) {
w = walloc(pn);
w->info = LASTLOG;
bcopy(ll.ll_line, w->tty, UT_LINESIZE);
w->tty[UT_LINESIZE] = 0;
bcopy(ll.ll_host, w->host, UT_HOSTSIZE);
w->host[UT_HOSTSIZE] = 0;
w->loginat = ll.ll_time;
strcpy(w->tty, ut->ut_line);
strcpy(w->host, ut->ut_host);
w->loginat = ut->ut_tv.tv_sec;
}
ulog_endutxent();
}
void
enter_where(struct utmp *ut, PERSON *pn)
enter_where(struct utmpx *ut, PERSON *pn)
{
WHERE *w;
w = walloc(pn);
w->info = LOGGEDIN;
bcopy(ut->ut_line, w->tty, UT_LINESIZE);
w->tty[UT_LINESIZE] = 0;
bcopy(ut->ut_host, w->host, UT_HOSTSIZE);
w->host[UT_HOSTSIZE] = 0;
w->loginat = (time_t)ut->ut_time;
strcpy(w->tty, ut->ut_line);
strcpy(w->host, ut->ut_host);
w->loginat = ut->ut_tv.tv_sec;
find_idle_and_ttywrite(w);
}
@ -205,14 +192,12 @@ enter_person(struct passwd *pw)
}
PERSON *
find_person(const char *name)
find_person(char *name)
{
struct passwd *pw;
int cnt;
DBT data, key;
PERSON *p;
char buf[UT_NAMESIZE + 1];
if (!db)
return(NULL);
@ -220,12 +205,8 @@ find_person(const char *name)
if ((pw = getpwnam(name)) && hide(pw))
return(NULL);
/* Name may be only UT_NAMESIZE long and not NUL terminated. */
for (cnt = 0; cnt < UT_NAMESIZE && *name; ++name, ++cnt)
buf[cnt] = *name;
buf[cnt] = '\0';
key.data = buf;
key.size = cnt;
key.data = name;
key.size = strlen(name);
if ((*db->get)(db, &key, &data, 0))
return (NULL);