/*
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
* Common Development and Distribution License, Version 1.0 only
* (the "License"). You may not use this file except in compliance
* with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* See the License for the specific language governing permissions
* and limitations under the License.
*
* When distributing Covered Code, include this CDDL HEADER in each
* file and include the License file at usr/src/OPENSOLARIS.LICENSE.
* If applicable, add the following below this CDDL HEADER, with the
* fields enclosed by brackets "[]" replaced with your own identifying
* information: Portions Copyright [yyyy] [name of copyright owner]
*
* CDDL HEADER END
*/
/*
* Copyright (c) 2013 Gary Mills
*
* Copyright 2004 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
/*
* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T
* All Rights Reserved
*/
/*
* University Copyright- Copyright (c) 1982, 1986, 1988
* The Regents of the University of California
* All Rights Reserved
*
* University Acknowledgment- Portions of this document are derived from
* software developed by the University of California, Berkeley, and its
* contributors.
*/
/*
* last
*/
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <strings.h>
#include <signal.h>
#include <pwd.h>
#include <fcntl.h>
#include <utmpx.h>
#include <locale.h>
#include <ctype.h>
/*
* Use the full lengths from utmpx for NMAX, LMAX and HMAX .
*/
/* Print minimum field widths. */
#define linehostnameq(a, b, c, d) \
/* Beware: These are set in main() to exclude the executable name. */
static char **argv;
static int argc;
static char **names;
static int names_num;
/*
* ttnames and logouts are allocated in the blocks of
* CHUNK_SIZE lines whenever needed. The count of the
* current size is maintained in the variable "lines"
* The variable bootxtime is used to hold the time of
* the last BOOT_TIME
* All elements of the logouts are initialised to bootxtime
* everytime the buffer is reallocated.
*/
static char **ttnames;
static int lines;
static char *strspl(char *, char *);
static void onintr(int);
static void reallocate_buffer();
static void memory_alloc(int);
int
{
int i, j;
int aflag = 0;
char *ct;
char *ut_host;
char *ut_user;
int print = 0;
char *crmsg = (char *)0;
long outrec = 0;
#if !defined(TEXT_DOMAIN) /* Should be defined by cc -D */
#endif
(void) textdomain(TEXT_DOMAIN);
perror("last");
exit(2);
}
names_num = 0;
for (i = 0; i < argc; i++) {
if (argv[i][0] == '-') {
/* -[0-9]* sets max # records to print */
continue;
}
switch (argv[i][j]) {
/* -f name sets filename of wtmp file */
case 'f':
} else if (i+1 < argc) {
} else {
gettext("last: argument to "
"-f is missing\n"));
exit(1);
}
goto next_word;
/* -n number sets max # records to print */
case 'n': {
char *arg;
} else if (i+1 < argc) {
} else {
gettext("last: argument to "
"-n is missing\n"));
exit(1);
}
gettext("last: argument to "
"-n is not a number\n"));
exit(1);
}
goto next_word;
}
/* -a displays hostname last on the line */
case 'a':
aflag++;
break;
default:
exit(1);
}
}
continue;
}
/* Not a tty number. */
++names_num;
} else {
/* tty number. Prepend "tty". */
++names_num;
}
}
if (wtmp < 0) {
exit(1);
}
}
lines = CHUNK_SIZE;
exit(2);
}
for (i = 0; i <= lines; i++) {
if (i == lines)
memory_alloc(i);
/*
* LMAX+HMAX+NMAX+3 bytes have been
* allocated for ttnames[i].
* If bp->ut_line is longer than LMAX,
* ut_host is longer than HMAX,
* and ut_user is longer than NMAX,
* truncate it to fit ttnames[i].
*/
LMAX+1);
i, bp);
break;
} else if (linehostnameq(ttnames[i],
break;
}
}
}
if (print) {
"%10.10s %5.5s ",
if (otime == 0 &&
/* timef still has room */
gettext(" still logged in"));
}
} else {
if (otime < 0) {
/*
* TRANSLATION_NOTE
* See other notes on "down"
* and "- %5.5s".
* "-" means "until". This
* is displayed after the
* starting time as in:
* 16:20 - down
* You probably don't want to
* translate this. Should you
* decide to translate this,
* translate "- %5.5s" too.
*/
/* timef still has room */
}
} else {
/* timef still has room */
}
}
/* timef still has room */
}
} else {
/* timef still has room */
}
}
}
}
if (aflag)
(void) printf("%-35.35s %-.*s\n",
else
(void) printf("%-16.16s %-.35s\n",
exit(0);
}
/*
* when the system is down or crashed.
*/
for (i = 0; i < lines; i++)
/*
* TRANSLATION_NOTE
* Translation of this "down " will replace
* the %s in "- %s". "down" is used instead
* of the real time session was ended, probably
* because the session ended by a sudden crash.
*/
}
print = 0; /* reset the print flag */
}
}
/* free() called to prevent lint warning about names */
return (0);
}
static void
{
int j;
static char **tmpttnames;
lines += CHUNK_SIZE;
exit(2);
} else {
}
}
}
static void
memory_alloc(int i)
{
exit(2);
}
}
static void
{
char *ct;
exit(1);
}
static int
{
char **name;
int i;
/* if ut_line = dtremote for the users who did dtremote login */
}
/* if ut_line = dtlocal for the users who did a dtlocal login */
}
/*
* Both dtremote and dtlocal can have multiple entries in
* entries are also checked
*/
return (0);
return (0);
if (names_num == 0) {
return (1);
} else {
return (1);
}
}
}
return (0);
}
static char *
{
perror("last");
exit(2);
}
return (res);
}
static void
{
*print = 1;
else
*print = 0;
}