-static char *sccsid = "@(#)lastcomm.c 4.2 (Berkeley) %G%";
-#
+static char *sccsid = "@(#)lastcomm.c 4.4 (Berkeley) 82/07/17";
/*
* last command
*/
# include <stdio.h>
-# include <sys/types.h>
+# include <sys/param.h>
# include <sys/acct.h>
+# include <sys/dir.h>
# include <signal.h>
# include <pwd.h>
# include <stat.h>
+# include <utmp.h>
+# include <struct.h>
-# define N_USER 1000
+# define N_USER 4000 /* highest alloc user # */
+# define N_DEVS 43 /* hash value for device names */
+# define NDEVS 500 /* max number of file names in /dev */
struct acct acct_buff [BUFSIZ / sizeof (struct acct)];
-char yes = 1,
- no = 0,
+char user_list [N_USER][fldsiz(utmp, ut_name) + 1];
- user_list [1000][9];
+struct devhash {
+ dev_t dev_dev;
+ char dev_name [fldsiz(utmp, ut_line) + 1];
+ struct devhash * dev_nxt;
+}
+ * dev_hash [ N_DEVS ],
+ * dev_chain ;
+# define HASH(d) (((int) d) % N_DEVS)
time_t expand ();
+char * flagbits();
+char * tername();
struct passwd
*passwd,
struct stat stat_buff;
+# define equal(a, b) (strcmp(a, b) == 0)
+
main (argc, argv)
char **argv;
{
*/
while (passwd = getpwent ())
{
- if (user_list[passwd->pw_uid][0])
+ if (user_list[passwd->pw_uid][0]==0)
move (passwd->pw_name, user_list [passwd->pw_uid]);
}
+ /*
+ * find dev numbers corresponding to names in /dev
+ */
+ setupdevs();
+
acct_desc = open ("/usr/adm/acct", 0);
if (acct_desc < 0)
{
n_entry = n_byte / sizeof acct_buff [0];
for (i = n_entry - 1; i >= 0; i--)
{
- if (!*user_list [acct_buff [i].ac_uid]) continue;
+ if (!*user_list [acct_buff [i].ac_uid])
+ continue;
/*
* get the times
*/
*/
for (p = acct_buff [i].ac_comm; *p; p++)
{
- if (*p < '!' || '~' < *p) *p = '?';
+ if (*p < '!' || '~' < *p)
+ *p = '?';
}
for (j = 1; j < argc; j++)
{
||
equal
(
- user_list [acct_buff [i].ac_uid],
+ user_list[acct_buff[i].ac_uid],
argv [j]
)
+ ||
+ equal
+ (
+ tername(acct_buff[i].ac_tty),
+ argv[j]
+ )
)
{
break;
{
printf
(
- "%-10s %-8s %6.2f %.16s\n",
- acct_buff [i].ac_comm,
- user_list [acct_buff [i].ac_uid],
- x / 60.0,
- ctime (&acct_buff [i].ac_btime)
+ "%-*s %s %-*s %-*s %6.2f %.16s\n"
+ , fldsiz(acct, ac_comm)
+ , acct_buff [i].ac_comm
+ , flagbits(acct_buff [i].ac_flag)
+ , fldsiz(utmp, ut_name)
+ , user_list [acct_buff [i].ac_uid]
+ , fldsiz(utmp, ut_line)
+ , tername(acct_buff [i].ac_tty)
+ , x / 60.0
+ , ctime (&acct_buff [i].ac_btime)
);
}
}
move (a, b)
char *a, *b;
{
- while (*b++ = *a++);
+ while (*b++ = *a++)
+ ;
}
-equal (a, b)
-char *a, *b;
+char *
+flagbits(f)
+register int f;
{
- for (;; a++, b++)
- {
- if (*a != *b) return no;
- if (!*a) return yes;
+ register int i = 0;
+ static char flags[20];
+
+# define BIT(flag, ch) flags[i++] = ( f & flag ) ? ch : ' '
+
+ BIT( ASU, 'S');
+ BIT( AFORK, 'F');
+ BIT( ACOMPAT, 'C');
+ BIT( ACORE, 'D');
+ BIT( AXSIG, 'X');
+
+ flags[i] = '\0';
+
+ return(flags);
+}
+
+setupdevs()
+{
+ register DIR * fd;
+ register struct devhash * hashtab;
+ register ndevs = NDEVS;
+ struct direct * dp;
+
+ if ((fd = opendir("/dev")) == NULL) {
+ perror("/dev");
+ return;
+ }
+
+ if ((hashtab = (struct devhash *)malloc(NDEVS * sizeof(struct devhash)))
+ == (struct devhash *) 0) {
+ fprintf(stderr, "No mem for dev table\n");
+ return;
+ }
+
+ while (dp = readdir(fd)) {
+ if (dp->d_ino == 0)
+ continue;
+#ifdef MELB
+ if (dp->d_name[0] != 't' && strcmp(dp->d_name, "console"))
+ continue;
+#endif
+ strncpy(hashtab->dev_name, dp->d_name, fldsiz(utmp, ut_line));
+ hashtab->dev_name[fldsiz(utmp, ut_line)] = 0;
+ hashtab->dev_nxt = dev_chain;
+ dev_chain = hashtab;
+ hashtab++;
+ if (--ndevs <= 0)
+ break;
+ }
+ closedir(fd);
+}
+
+char *
+tername(dev)
+dev_t dev;
+{
+ register struct devhash *hp, *nhp;
+ struct stat statb;
+ char name [fldsiz(devhash, dev_name) + 6];
+ static dev_t lastdev = (dev_t) -1;
+ static char *lastname;
+
+ if (dev == NODEV)
+ return("__");
+
+ if (dev == lastdev)
+ return(lastname);
+
+ for (hp = dev_hash[HASH(dev)]; hp; hp = hp->dev_nxt)
+ if (hp->dev_dev == dev) {
+ lastdev = dev;
+ return(lastname = hp->dev_name);
+ }
+
+ for (hp = dev_chain; hp; hp = nhp) {
+ nhp = hp->dev_nxt;
+ strcpy(name, "/dev/");
+ strcat(name, hp->dev_name);
+ if (stat(name, &statb) < 0) /* name truncated usually */
+ continue;
+ if ((statb.st_mode & S_IFMT) != S_IFCHR)
+ continue;
+ hp->dev_dev = statb.st_rdev;
+ hp->dev_nxt = dev_hash[HASH(hp->dev_dev)];
+ dev_hash[HASH(hp->dev_dev)] = hp;
+ if (hp->dev_dev == dev) {
+ dev_chain = nhp;
+ lastdev = dev;
+ return(lastname = hp->dev_name);
+ }
}
+
+ dev_chain = (struct devhash *) 0;
+ return("??");
}