Remove building with NOCRYPTO option
[minix3.git] / usr.bin / last / last.c
blob19cba10818f078a7e32b2cd2582de369f6c6de8d
1 /* $NetBSD: last.c,v 1.36 2012/03/15 03:04:05 dholland Exp $ */
3 /*
4 * Copyright (c) 1987, 1993, 1994
5 * The Regents of the University of California. All rights reserved.
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 * 3. Neither the name of the University nor the names of its contributors
16 * may be used to endorse or promote products derived from this software
17 * without specific prior written permission.
19 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
20 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
23 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
25 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29 * SUCH DAMAGE.
32 #include <sys/cdefs.h>
33 #ifndef lint
34 __COPYRIGHT("@(#) Copyright (c) 1987, 1993, 1994\
35 The Regents of the University of California. All rights reserved.");
36 #endif /* not lint */
38 #ifndef lint
39 #if 0
40 static char sccsid[] = "@(#)last.c 8.2 (Berkeley) 4/2/94";
41 #endif
42 __RCSID("$NetBSD: last.c,v 1.36 2012/03/15 03:04:05 dholland Exp $");
43 #endif /* not lint */
45 #include <sys/param.h>
46 #include <sys/stat.h>
48 #include <err.h>
49 #include <errno.h>
50 #include <fcntl.h>
51 #include <paths.h>
52 #include <stdio.h>
53 #include <stdlib.h>
54 #include <string.h>
55 #include <time.h>
56 #include <tzfile.h>
57 #include <unistd.h>
58 #include <arpa/inet.h>
59 #ifdef SUPPORT_UTMPX
60 #include <utmpx.h>
61 #endif
62 #ifdef SUPPORT_UTMP
63 #include <utmp.h>
64 #endif
65 #include <util.h>
67 #ifndef UT_NAMESIZE
68 #define UT_NAMESIZE 8
69 #define UT_LINESIZE 8
70 #define UT_HOSTSIZE 16
71 #endif
72 #ifndef SIGNATURE
73 #define SIGNATURE -1
74 #endif
78 #define NO 0 /* false/no */
79 #define YES 1 /* true/yes */
81 #define TBUFLEN 30 /* length of time string buffer */
82 #define TFMT "%a %b %d %R" /* strftime format string */
83 #define LTFMT "%a %b %d %Y %T" /* strftime long format string */
84 #define TFMTS "%R" /* strftime format string - time only */
85 #define LTFMTS "%T" /* strftime long format string - " */
87 /* fmttime() flags */
88 #define FULLTIME 0x1 /* show year, seconds */
89 #define TIMEONLY 0x2 /* show time only, not date */
90 #define GMT 0x4 /* show time at GMT, for offsets only */
92 #define MAXUTMP 1024
94 typedef struct arg {
95 const char *name; /* argument */
96 #define HOST_TYPE -2
97 #define TTY_TYPE -3
98 #define USER_TYPE -4
99 int type; /* type of arg */
100 struct arg *next; /* linked list pointer */
101 } ARG;
102 static ARG *arglist; /* head of linked list */
104 typedef struct ttytab {
105 time_t logout; /* log out time */
106 char tty[128]; /* terminal name */
107 struct ttytab *next; /* linked list pointer */
108 } TTY;
109 static TTY *ttylist; /* head of linked list */
111 static time_t currentout; /* current logout value */
112 static long maxrec; /* records to display */
113 static int fulltime = 0; /* Display seconds? */
114 static int xflag; /* Assume file is wtmpx format */
116 static void addarg(int, const char *);
117 static TTY *addtty(const char *);
118 static void hostconv(char *);
119 static const char *ttyconv(char *);
120 #ifdef SUPPORT_UTMPX
121 static void wtmpx(const char *, int, int, int, int);
122 #endif
123 #ifdef SUPPORT_UTMP
124 static void wtmp(const char *, int, int, int, int);
125 #endif
126 static char *fmttime(time_t, int);
127 __dead static void usage(void);
129 static
130 void usage(void)
132 (void)fprintf(stderr, "usage: %s [-#%s] [-nTx] [-f file]"
133 " [-H hostsize] [-h host] [-L linesize]\n"
134 "\t [-N namesize] [-t tty] [user ...]\n", getprogname(),
135 #ifdef NOTYET_SUPPORT_UTMPX
137 #else
139 #endif
141 exit(EXIT_FAILURE);
145 main(int argc, char *argv[])
147 int ch;
148 char *p;
149 const char *file = NULL;
150 int namesize = UT_NAMESIZE;
151 int linesize = UT_LINESIZE;
152 int hostsize = UT_HOSTSIZE;
153 int numeric = 0;
155 maxrec = -1;
157 while ((ch = getopt(argc, argv, "0123456789f:H:h:L:nN:Tt:x")) != -1)
158 switch (ch) {
159 case '0': case '1': case '2': case '3': case '4':
160 case '5': case '6': case '7': case '8': case '9':
162 * kludge: last was originally designed to take
163 * a number after a dash.
165 if (maxrec == -1) {
166 p = argv[optind - 1];
167 if (p[0] == '-' && p[1] == ch && !p[2])
168 maxrec = atol(++p);
169 else if (optind < argc)
170 maxrec = atol(argv[optind] + 1);
171 else
172 usage();
173 if (!maxrec)
174 return 0;
176 break;
177 case 'f':
178 file = optarg;
179 if ('\0' == file[0])
180 usage();
181 break;
182 case 'H':
183 hostsize = atoi(optarg);
184 if (hostsize < 1)
185 usage();
186 break;
187 case 'h':
188 hostconv(optarg);
189 addarg(HOST_TYPE, optarg);
190 break;
191 case 'L':
192 linesize = atoi(optarg);
193 if (linesize < 1)
194 usage();
195 break;
196 case 'N':
197 namesize = atoi(optarg);
198 if (namesize < 1)
199 usage();
200 break;
201 case 'n':
202 numeric = 1;
203 break;
204 case 'T':
205 fulltime = 1;
206 break;
207 case 't':
208 addarg(TTY_TYPE, ttyconv(optarg));
209 break;
210 case 'x':
211 xflag = 1;
212 break;
213 case '?':
214 default:
215 usage();
218 if (argc) {
219 setlinebuf(stdout);
220 for (argv += optind; *argv; ++argv) {
221 #define COMPATIBILITY
222 #ifdef COMPATIBILITY
223 /* code to allow "last p5" to work */
224 addarg(TTY_TYPE, ttyconv(*argv));
225 #endif
226 addarg(USER_TYPE, *argv);
229 if (file == NULL) {
230 #ifdef SUPPORT_UTMPX
231 if (access(_PATH_WTMPX, R_OK) == 0)
232 file = _PATH_WTMPX;
233 else
234 #endif
235 #ifdef SUPPORT_UTMP
236 if (access(_PATH_WTMP, R_OK) == 0)
237 file = _PATH_WTMP;
238 #endif
239 if (file == NULL)
240 #if defined(SUPPORT_UTMPX) && defined(SUPPORT_UTMP)
241 errx(EXIT_FAILURE, "Cannot access `%s' or `%s'", _PATH_WTMPX,
242 _PATH_WTMP);
243 #elif defined(SUPPORT_UTMPX)
244 errx(EXIT_FAILURE, "Cannot access `%s'", _PATH_WTMPX);
245 #elif defined(SUPPORT_UTMP)
246 errx(EXIT_FAILURE, "Cannot access `%s'", _PATH_WTMP);
247 #else
248 errx(EXIT_FAILURE, "No utmp or utmpx support compiled in.");
249 #endif
251 #if defined(SUPPORT_UTMPX) && defined(SUPPORT_UTMP)
252 if (file[strlen(file) - 1] == 'x' || xflag)
253 wtmpx(file, namesize, linesize, hostsize, numeric);
254 else
255 wtmp(file, namesize, linesize, hostsize, numeric);
256 #elif defined(SUPPORT_UTMPX)
257 wtmpx(file, namesize, linesize, hostsize, numeric);
258 #elif defined(SUPPORT_UTMP)
259 wtmp(file, namesize, linesize, hostsize, numeric);
260 #else
261 errx(EXIT_FAILURE, "No utmp or utmpx support compiled in.");
262 #endif
263 exit(EXIT_SUCCESS);
268 * addarg --
269 * add an entry to a linked list of arguments
271 static void
272 addarg(int type, const char *arg)
274 ARG *cur;
276 if (!(cur = (ARG *)malloc(sizeof(ARG))))
277 err(EXIT_FAILURE, "malloc failure");
278 cur->next = arglist;
279 cur->type = type;
280 cur->name = arg;
281 arglist = cur;
285 * addtty --
286 * add an entry to a linked list of ttys
288 static TTY *
289 addtty(const char *tty)
291 TTY *cur;
293 if (!(cur = (TTY *)malloc(sizeof(TTY))))
294 err(EXIT_FAILURE, "malloc failure");
295 cur->next = ttylist;
296 cur->logout = currentout;
297 memmove(cur->tty, tty, sizeof(cur->tty));
298 return (ttylist = cur);
302 * hostconv --
303 * convert the hostname to search pattern; if the supplied host name
304 * has a domain attached that is the same as the current domain, rip
305 * off the domain suffix since that's what login(1) does.
307 static void
308 hostconv(char *arg)
310 static int first = 1;
311 static char *hostdot, name[MAXHOSTNAMELEN + 1];
312 char *argdot;
314 if (!(argdot = strchr(arg, '.')))
315 return;
316 if (first) {
317 first = 0;
318 if (gethostname(name, sizeof(name)))
319 err(EXIT_FAILURE, "gethostname");
320 name[sizeof(name) - 1] = '\0';
321 hostdot = strchr(name, '.');
323 if (hostdot && !strcasecmp(hostdot, argdot))
324 *argdot = '\0';
328 * ttyconv --
329 * convert tty to correct name.
331 static const char *
332 ttyconv(char *arg)
334 char *mval;
336 if (!strcmp(arg, "co"))
337 return ("console");
339 * kludge -- we assume that all tty's end with
340 * a two character suffix.
342 if (strlen(arg) == 2) {
343 if (asprintf(&mval, "tty%s", arg) == -1)
344 err(EXIT_FAILURE, "malloc failure");
345 return (mval);
347 if (!strncmp(arg, _PATH_DEV, sizeof(_PATH_DEV) - 1))
348 return (&arg[sizeof(_PATH_DEV) - 1]);
349 return (arg);
353 * fmttime --
354 * return pointer to (static) formatted time string.
356 static char *
357 fmttime(time_t t, int flags)
359 struct tm *tm;
360 static char tbuf[TBUFLEN];
362 tm = (flags & GMT) ? gmtime(&t) : localtime(&t);
363 if (tm == NULL) {
364 strcpy(tbuf, "????");
365 return tbuf;
367 strftime(tbuf, sizeof(tbuf),
368 (flags & TIMEONLY)
369 ? (flags & FULLTIME ? LTFMTS : TFMTS)
370 : (flags & FULLTIME ? LTFMT : TFMT),
371 tm);
372 return (tbuf);
375 #ifdef SUPPORT_UTMP
376 #define TYPE(a) 0
377 #define NAMESIZE UT_NAMESIZE
378 #define LINESIZE UT_LINESIZE
379 #define HOSTSIZE UT_HOSTSIZE
380 #define ut_timefld ut_time
381 #define HAS_UT_SS 0
382 #include "want.c"
383 #undef TYPE /*(a)*/
384 #undef NAMESIZE
385 #undef LINESIZE
386 #undef HOSTSIZE
387 #undef ut_timefld
388 #undef HAS_UT_SS
389 #endif
391 #ifdef SUPPORT_UTMPX
392 #define utmp utmpx
393 #define want wantx
394 #define wtmp wtmpx
395 #define gethost gethostx
396 #define buf bufx
397 #define onintr onintrx
398 #define TYPE(a) (a)->ut_type
399 #define NAMESIZE UTX_USERSIZE
400 #define LINESIZE UTX_LINESIZE
401 #define HOSTSIZE UTX_HOSTSIZE
402 #define ut_timefld ut_xtime
403 #define HAS_UT_SS 1
404 #include "want.c"
405 #endif