/*
- * Extended `who' command, version 1.8.
+ * Extended `who' command, version 1.9.
*
- * (c) 1996--1998 Martin Mares <mj@atrey.karlin.mff.cuni.cz>
+ * (c) 1996--1999 Martin Mares <mj@atrey.karlin.mff.cuni.cz>
*
* This software may be freely distributed and used according to the terms
* of the GNU General Public License. See file COPYING in any of the GNU packages.
#include <pwd.h>
#include <sys/stat.h>
#include <asm/param.h>
+#include <sys/ioctl.h>
+#include <ctype.h>
#undef DEBUG
+#define MAXHOSTSIZE 24
struct procrec {
struct procrec *next;
int pid, ppid, pgrp, sess;
int usr, state;
time_t ctim, tim;
- char cmd_line[34];
+ char cmd_line[1];
};
static struct procrec *first_procrec;
time_t login_time, click_time, total_time;
char user_name[UT_NAMESIZE+1];
int usr;
- char host_name[17];
+ char host_name[MAXHOSTSIZE+1];
char line_name[12];
int mesg, detach;
struct procrec *proc;
};
static struct utrec *first_utrec;
-static int usercnt, zombies;
+static int usercnt, zombies, maxhost = 10;
static time_t now;
static void *
struct utrec *u = xmalloc(sizeof(struct utrec));
struct stat st;
char device[32];
+ size_t hlen;
u->next = first_utrec;
first_utrec = u;
u->login_pid = ut->ut_pid;
u->usr = pw->pw_uid;
else
u->usr = -1;
- strcpy_padded(u->host_name, ut->ut_host, 16);
+ strcpy_padded(u->host_name, ut->ut_host,
+ (MAXHOSTSIZE > UT_HOSTSIZE ? UT_HOSTSIZE : MAXHOSTSIZE));
+ if ((hlen = strlen(u->host_name)) > maxhost)
+ maxhost = hlen;
strcpy(u->line_name, ut->ut_line);
- if (!u->line_id[0])
+ if (*u->line_name)
{
char *z = u->line_name;
if (!strncmp(u->line_name, "tty", 3))
z += 3;
+ if (!strncmp(z, "pts/", 4))
+ z += 3;
strncpy(u->line_id, z, 3);
u->line_id[3] = 0;
+ if (u->line_id[0] == '/')
+ u->line_id[0] = 'P';
}
strcpy(device, "/dev/");
strcat(device, u->line_name);
z = line+7;
w = a;
}
+ else if (!strncmp(line, "cpu family\t: ",13))
+ {
+ z = line+13; strcpy(z + 1, "86\n");
+ w = a;
+ }
else if (!strncmp(line, "model\t\t: ", 9))
{
z = line+9;
w = b;
}
+ else if (!strncmp(line, "model name\t: ", 13))
+ {
+ z = line+13;
+ if (!strncmp(z, "AMD-K6", 6))
+ {
+ z[3] = ' ';
+ if ((w = strstr(z, "tm w/ multimedia")))
+ strcpy(w, "-1\n");
+ else if ((w = strstr(z, "(tm) 3D")))
+ strcpy(w, "-2\n");
+ }
+ w = b;
+ }
else if (!strncmp(line, "mask\t\t: ", 8))
{
z = line+8;
w[0] = 0;
}
}
- printf(" on %s", a);
- if (*b)
- printf("-%s", b);
+ printf(" on %s", *b ? b : a);
if (*c)
- printf("-%s", c);
+ printf("/%s", c);
fclose(f);
}
if (f = fopen("/proc/uptime", "r"))
{
DIR *d;
struct dirent *e;
+ struct winsize win;
+ unsigned cmdcols = 0;
+#define LEFTSIZE 29
+
+ if (!ioctl(1, TIOCGWINSZ, &win) && win.ws_col >= LEFTSIZE + maxhost + 10 && win.ws_col < 1024)
+ cmdcols = win.ws_col;
+ else cmdcols = 80;
+ cmdcols -= LEFTSIZE + maxhost;
if (d = opendir("/proc"))
{
while (e = readdir(d))
{
int i;
- sscanf(e->d_name, "%d", &i);
- if (i)
+ if (sscanf(e->d_name, "%d", &i)==1)
{
- struct procrec *p = xmalloc(sizeof(struct procrec));
+ struct procrec *p = xmalloc(sizeof(struct procrec) + cmdcols);
struct stat st;
char name[256], eman[1024];
int fil;
strcat(eman, "/cmdline");
if ((fil = open(eman, O_RDONLY)) >= 0)
{
- int z = read(fil, p->cmd_line, sizeof(p->cmd_line) - 1);
+ int z = read(fil, p->cmd_line, cmdcols);
if (z < 0)
z = 0;
p->cmd_line[z] = 0x91;
show(void)
{
struct utrec *u;
- int i;
unsigned char *c;
- printf("Name Li MD From LogT IdleT RunT Command\n");
+ printf("Name Li MD %-*s LogT IdleT RunT Command\n", maxhost, "From");
for(u=first_utrec; u; u=u->next)
{
- if (!u->line_id[1])
- {
- if (u->line_id[0])
- {
- u->line_id[1] = u->line_id[0];
- u->line_id[0] = 'c';
- }
- else
- u->line_id[0] = u->line_id[1] = '-';
- }
- printf("%-8.8s %-3s %c%c %-17.17s ",
+ if (isdigit(u->line_id[0]))
+ sprintf(u->line_id, "c%d", atoi(u->line_id));
+ if (!u->line_id[0])
+ strcpy(u->line_id, "--");
+ printf("%-8.8s %-3s %c%c %-*.*s ",
u->user_name,
u->line_id,
u->mesg ? ' ' : '-',
u->detach ? 'D' : ' ',
+ maxhost,
+ maxhost,
u->host_name);
if (u->mesg <= 1)
{
putchar(' ');
puttime((unsigned)u->total_time/(unsigned)HZ);
putchar(' ');
- i = 24;
- c = u->proc->cmd_line;
- while (*c != 0x91 && i--)
+ for (c = u->proc->cmd_line; *c != 0x91; c++)
{
if (*c < 0x20 || (*c >= 0x7f && *c < 0xa0))
putchar(' ');
else
putchar(*c);
- c++;
}
}
else