/*
- * Extended `who' command, version 1.3.
+ * Extended `who' command, version 1.9.
*
- * (c) 1996 Martin Mares <mj@k332.feld.cvut.cz>
+ * (c) 1996--1999 Martin Mares <mj@atrey.karlin.mff.cuni.cz>
*
- * 1.3 (16-96-96) - idle derived from atime instead of mtime.
- * - displaying of current command fixed.
+ * 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 <stdio.h>
#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];
- };
+ struct procrec *next;
+ int pid, ppid, pgrp, sess;
+ int usr, state;
+ time_t ctim, tim;
+ char cmd_line[1];
+};
static struct procrec *first_procrec;
struct utrec {
- struct utrec *next;
- pid_t login_pid;
- char line_id[4];
- time_t login_time, click_time, total_time;
- char user_name[UT_NAMESIZE+1];
- int usr;
- char host_name[17];
- char line_name[12];
- int mesg, detach;
- struct procrec *proc;
- };
+ struct utrec *next;
+ pid_t login_pid;
+ char line_id[4];
+ time_t login_time, click_time, total_time;
+ char user_name[UT_NAMESIZE+1];
+ int usr;
+ 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 *
xmalloc(int i)
{
-void *z;
- z = malloc(i);
- if (!z)
- {
- fprintf(stderr, "xwho: out of memory!\n");
- exit(1);
- }
- return z;
+ void *z;
+ z = malloc(i);
+ if (!z)
+ {
+ fprintf(stderr, "ywho: out of memory!\n");
+ exit(1);
+ }
+ return z;
}
static void
strcpy_padded(char *to, char *from, int size)
{
- memcpy(to, from, size);
- to[size] = 0;
+ memcpy(to, from, size);
+ to[size] = 0;
}
static void
readutmp(void)
{
-static struct utmp *ut;
-static struct passwd *pw;
- utmpname(UTMP_FILE);
- while (ut = getutent())
- if (ut->ut_type == USER_PROCESS && ut->ut_user[0])
- {
- struct utrec *u = xmalloc(sizeof(struct utrec));
- struct stat st;
- char device[32];
- u->next = first_utrec;
- first_utrec = u;
- u->login_pid = ut->ut_pid;
- u->line_id[0] = ut->ut_id[0];
- u->line_id[1] = ut->ut_id[1];
- u->line_id[2] = 0;
- u->login_time = ut->ut_time;
- strcpy_padded(u->user_name, ut->ut_user, UT_NAMESIZE);
- pw = getpwnam(u->user_name);
- if (pw)
- u->usr = pw->pw_uid;
- else
- u->usr = -1;
- strcpy_padded(u->host_name, ut->ut_host, 16);
- strcpy(u->line_name, ut->ut_line);
- if (!u->line_id[0])
- {
- char *z = u->line_name;
- if (!strncmp(u->line_name, "tty", 3))
- z += 3;
- strncpy(u->line_id, z, 3);
- u->line_id[3] = 0;
- }
- strcpy(device, "/dev/");
- strcat(device, u->line_name);
- if (stat(device, &st))
- u->mesg = 2;
- else
- {
- u->mesg = !!(S_IWOTH & st.st_mode);
- u->click_time = st.st_atime;
- if (u->click_time < st.st_atime)
- u->click_time = st.st_atime;
- if (u->click_time < st.st_ctime)
- u->click_time = st.st_ctime;
- }
- u->detach = 0;
- usercnt++;
+ static struct utmp *ut;
+ static struct passwd *pw;
+ utmpname(UTMP_FILE);
+ while (ut = getutent())
+ if (ut->ut_type == USER_PROCESS && ut->ut_user[0])
+ {
+ 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->line_id[0] = ut->ut_id[0];
+ u->line_id[1] = ut->ut_id[1];
+ u->line_id[2] = 0;
+ u->login_time = ut->ut_time;
+ strcpy_padded(u->user_name, ut->ut_user, UT_NAMESIZE);
+ pw = getpwnam(u->user_name);
+ if (pw)
+ u->usr = pw->pw_uid;
+ else
+ u->usr = -1;
+ 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_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);
+ if (stat(device, &st))
+ u->mesg = 2;
+ else
+ {
+ u->mesg = !!(S_IWGRP & st.st_mode);
+ u->click_time = st.st_atime;
+#if 0
+ if (u->click_time < st.st_mtime)
+ u->click_time = st.st_mtime;
+ if (u->click_time < st.st_ctime)
+ u->click_time = st.st_ctime;
+#endif
+ }
+ u->detach = 0;
+ usercnt++;
#ifdef DEBUG
- printf("UT %s %s %d %d\n", u->user_name, u->host_name,
- u->usr, u->login_pid);
+ printf("UT %s %s %d %d\n", u->user_name, u->host_name,
+ u->usr, u->login_pid);
#endif
- }
- endutent();
+ }
+ endutent();
}
static void
puttime(int s)
{
-int d, h, m;
- if (s < 100)
- printf("%4ds", s);
- else
- {
- m = s/60;
- s %= 60;
- h = m/60;
- m %= 60;
- if (h < 100)
- printf("%02d.%02d", h, m);
- else
- {
- d = h/24;
- h %= 24;
- if (d < 100)
- printf("%2dd%02d", d, h);
- else
- printf("%4dd", d);
- }
- }
+ int d, h, m;
+ if (s < 100)
+ printf("%4ds", s);
+ else
+ {
+ m = s/60;
+ s %= 60;
+ h = m/60;
+ m %= 60;
+ if (h < 100)
+ printf("%02d.%02d", h, m);
+ else
+ {
+ d = h/24;
+ h %= 24;
+ if (d < 100)
+ printf("%2dd%02d", d, h);
+ else
+ printf("%4dd", d);
+ }
+ }
}
static void
memory(unsigned int i)
{
- if (i < 1000)
- printf("%dB", i);
- else
- {
- i = (i+511)/1024;
- if (i < 1000)
- printf("%dK", i);
- else
- {
- i = (i+511)/1024;
- if (i < 1000)
- printf("%dM", i);
- else
- printf("%dG", (i+511U)/1024U);
- }
- }
+ if (i < 10240)
+ printf("%dB", i);
+ else
+ {
+ i = (i+511U)/1024U;
+ if (i < 2048)
+ printf("%dK", i);
+ else
+ {
+ i = (i+511)/1024;
+ if (i < 2048)
+ printf("%dM", i);
+ else
+ printf("%dG", (i+511U)/1024U);
+ }
+ }
}
static void
dispsys(void)
{
-FILE *f;
-char line[256], a[32], b[32], c[32];
-char *z, *w;
- w = NULL;
- if (f = fopen("/proc/version", "r"))
- {
- fgets(line, 256, f);
- z = strchr(line, '(');
- if (z)
- {
- while (z != line && z[-1] == ' ')
- z--;
- }
- else
- z = line + strlen(line) - 1;
- *z = 0;
- z = strstr(line, " version");
- if (z)
- memmove(z, z+8, strlen(z+8)+1);
- printf(line);
- fclose(f);
- }
- if (f = fopen("/proc/cpuinfo", "r"))
- {
- strcpy(a, "???");
- b[0] = 0;
- c[0] = 0;
- for(;;)
- {
- fgets(line, 256, f);
- if (feof(f))
- break;
- if (!strncmp(line, "cpu\t\t: ", 7))
- {
- z = line+7;
- w = a;
- }
- else if (!strncmp(line, "model\t\t: ", 9))
- {
- z = line+9;
- w = b;
- }
- else if (!strncmp(line, "mask\t\t: ", 8))
- {
- z = line+8;
- w = c;
- }
- else
- z = NULL;
- if (z)
- {
- line[strlen(line)-1] = 0;
- strcpy(w, z);
- if (!strcmp(w, "Unknown"))
- w[0] = 0;
- }
- }
- printf(" on %s", a);
- if (*b)
- printf("-%s", b);
- if (*c)
- printf("-%s", c);
- fclose(f);
- }
- if (f = fopen("/proc/uptime", "r"))
- {
- int p,q,p1,q1;
- fgets(line, 256, f);
- sscanf(line, "%d.%d%d.%d", &p, &p1, &q, &q1);
- printf(", up ");
- puttime(p);
- printf(", run ");
- puttime(p-q);
- fclose(f);
- }
+ FILE *f;
+ char line[256], a[32], b[32], c[32];
+ char *z, *w;
+ w = NULL;
+ if (f = fopen("/proc/version", "r"))
+ {
+ fgets(line, 256, f);
+ z = strchr(line, '(');
+ if (z)
{
- struct tm *tm;
- now = time(NULL);
- tm = localtime(&now);
- printf(" at %02d-%02d-%02d/%d %02d.%02d:%02d\n", tm->tm_mday, tm->tm_mon+1,
- tm->tm_year, (tm->tm_wday+6)%7, tm->tm_hour, tm->tm_min, tm->tm_sec);
+ while (z != line && z[-1] == ' ')
+ z--;
}
- if (f = fopen("/proc/loadavg", "r"))
- {
- int i = 3;
- fgets(line, 256, f);
- *strchr(line, '\n') = 0;
- z = line-1;
- while (i-- && z)
- {
- *z = '/';
- z = strchr(z, ' ');
- }
- if (z)
- {
- char *k;
- *z++ = 0;
- k = strchr(z, ' ');
- if (k)
- *k = 0;
- printf("R/T=%s, ", z);
- }
- else
- z = line;
- printf("LAV=%s", line);
- fclose(f);
- }
- if (f = fopen("/proc/meminfo", "r"))
+ else
+ z = line + strlen(line) - 1;
+ *z = 0;
+ z = strstr(line, " version");
+ if (z)
+ memmove(z, z+8, strlen(z+8)+1);
+ printf(line);
+ fclose(f);
+ }
+ if (f = fopen("/proc/cpuinfo", "r"))
+ {
+ strcpy(a, "???");
+ b[0] = 0;
+ c[0] = 0;
+ for(;;)
+ {
+ fgets(line, 256, f);
+ if (feof(f))
+ break;
+ if (!strncmp(line, "cpu\t\t: ", 7))
+ {
+ 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))
{
- int total, used, free, shared, buffers, totals, useds, frees;
- fgets(line, 256, f);
- fgets(line, 256, f);
- sscanf(line, "Mem:%d%d%d%d%d", &total, &used, &free, &shared, &buffers);
- fgets(line, 256, f);
- sscanf(line, "Swap:%d%d%d", &totals, &useds, &frees);
- printf(", free ");
- memory(free+buffers);
- printf(" of RAM");
- if (useds)
- {
- printf(", used ");
- memory(useds);
- printf(" of swap");
- }
+ z[3] = ' ';
+ if ((w = strstr(z, "tm w/ multimedia")))
+ strcpy(w, "-1\n");
+ else if ((w = strstr(z, "(tm) 3D")))
+ strcpy(w, "-2\n");
}
- printf(", %d user%s.\n", usercnt, usercnt == 1 ? "" : "s");
+ w = b;
+ }
+ else if (!strncmp(line, "mask\t\t: ", 8))
+ {
+ z = line+8;
+ w = c;
+ }
+ else
+ z = NULL;
+ if (z)
+ {
+ line[strlen(line)-1] = 0;
+ strcpy(w, z);
+ if (!strcmp(w, "Unknown"))
+ w[0] = 0;
+ }
+ }
+ printf(" on %s", *b ? b : a);
+ if (*c)
+ printf("/%s", c);
+ fclose(f);
+ }
+ if (f = fopen("/proc/uptime", "r"))
+ {
+ int p,q,p1,q1;
+ fgets(line, 256, f);
+ sscanf(line, "%d.%d%d.%d", &p, &p1, &q, &q1);
+ printf(", up ");
+ puttime(p);
+ printf(", run ");
+ puttime(p-q);
+ fclose(f);
+ }
+ {
+ struct tm *tm;
+ now = time(NULL);
+ tm = localtime(&now);
+ printf(" at %02d-%02d-%02d/%d %02d.%02d:%02d\n", tm->tm_mday, tm->tm_mon+1,
+ tm->tm_year, (tm->tm_wday+6)%7, tm->tm_hour, tm->tm_min, tm->tm_sec);
+ }
+ if (f = fopen("/proc/loadavg", "r"))
+ {
+ int i = 3;
+ fgets(line, 256, f);
+ *strchr(line, '\n') = 0;
+ z = line-1;
+ while (i-- && z)
+ {
+ *z = '/';
+ z = strchr(z, ' ');
+ }
+ if (z)
+ {
+ char *k;
+ *z++ = 0;
+ k = strchr(z, ' ');
+ if (k)
+ *k = 0;
+ printf("R/T=%s, ", z);
+ }
+ else
+ z = line;
+ printf("LAV=%s", line);
+ fclose(f);
+ }
+ if (f = fopen("/proc/meminfo", "r"))
+ {
+ int free, buffers, stotal, sfree;
+ free = buffers = stotal = sfree = 0;
+ while (fgets(line, 256, f))
+ {
+ if (!strncmp(line, "MemFree:", 8))
+ sscanf(line+8, "%d", &free);
+ else if (!strncmp(line, "Buffers:", 8))
+ sscanf(line+8, "%d", &buffers);
+ else if (!strncmp(line, "SwapTotal:", 10))
+ sscanf(line+10, "%d", &stotal);
+ else if (!strncmp(line, "SwapFree:", 9))
+ sscanf(line+9, "%d", &sfree);
+ }
+ printf(", free ");
+ memory(1024*(free+buffers));
+ printf(" of RAM");
+ if (stotal != sfree)
+ {
+ printf(", used ");
+ memory(1024*(stotal - sfree));
+ printf(" of swap");
+ }
+ }
+ printf(", %d user%s.\n", usercnt, usercnt == 1 ? "" : "s");
}
static void
readproc(void)
{
-DIR *d;
-struct dirent *e;
- if (d = opendir("/proc"))
+ 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;
+ if (sscanf(e->d_name, "%d", &i)==1)
+ {
+ struct procrec *p = xmalloc(sizeof(struct procrec) + cmdcols);
+ struct stat st;
+ char name[256], eman[1024];
+ int fil;
+ p->pid = i;
+ strcpy(name, "/proc/");
+ strcat(name, e->d_name);
+ if (!stat(name, &st))
{
- while (e = readdir(d))
+ p->next = first_procrec;
+ first_procrec = p;
+ p->usr = st.st_uid;
+ strcpy(eman, name);
+ strcat(eman, "/cmdline");
+ if ((fil = open(eman, O_RDONLY)) >= 0)
+ {
+ int z = read(fil, p->cmd_line, cmdcols);
+ if (z < 0)
+ z = 0;
+ p->cmd_line[z] = 0x91;
+ close(fil);
+ }
+ strcpy(eman, name);
+ strcat(eman, "/stat");
+ if ((fil = open(eman, O_RDONLY)) >= 0)
+ {
+ int z = read(fil, eman, 1023);
+ char *k;
+ int trash, utim, stim, cutim, cstim;
+ if (z < 0)
+ z = 0;
+ eman[z] = 0;
+ k = strchr(eman, ')');
+ if (k)
{
- int i;
- sscanf(e->d_name, "%d", &i);
- if (i)
- {
- struct procrec *p = xmalloc(sizeof(struct procrec));
- struct stat st;
- char name[256], eman[1024];
- int fil;
- p->pid = i;
- strcpy(name, "/proc/");
- strcat(name, e->d_name);
- if (!stat(name, &st))
- {
- p->next = first_procrec;
- first_procrec = p;
- p->usr = st.st_uid;
- strcpy(eman, name);
- strcat(eman, "/cmdline");
- if ((fil = open(eman, O_RDONLY)) >= 0)
- {
- int z = read(fil, p->cmd_line, 33);
- if (z < 0)
- z = 0;
- p->cmd_line[z] = 0xff;
- close(fil);
- }
- strcpy(eman, name);
- strcat(eman, "/stat");
- if ((fil = open(eman, O_RDONLY)) >= 0)
- {
- int z = read(fil, eman, 1023);
- char *k;
- int trash, utim, stim, cutim, cstim;
- if (z < 0)
- z = 0;
- eman[z] = 0;
- k = strchr(eman, ')');
- if (k)
- {
- p->state = k[1];
- if (p->state == 'Z')
- zombies++;
- sscanf(k+3, "%d%d%d%d%d%d%d%d%d%d%d%d%d%d",
- &p->ppid, &p->pgrp, &p->sess, &trash, &trash,
- &trash, &trash, &trash, &trash, &trash, &utim,
- &stim, &cutim, &cstim);
- }
- p->tim = utim + stim;
- p->ctim = cutim + cstim;
- close(fil);
- }
- }
- }
+ p->state = k[2];
+ if (p->state == 'Z')
+ zombies++;
+ sscanf(k+4, "%d%d%d%d%d%d%d%d%d%d%d%d%d%d",
+ &p->ppid, &p->pgrp, &p->sess, &trash, &trash,
+ &trash, &trash, &trash, &trash, &trash, &utim,
+ &stim, &cutim, &cstim);
}
- closedir(d);
- }
- else
- {
- perror("unable to scan /proc");
- exit(1);
+ p->tim = utim + stim;
+ p->ctim = cutim + cstim;
+ close(fil);
+ }
}
+ }
+ }
+ closedir(d);
+ }
+ else
+ {
+ perror("unable to scan /proc");
+ exit(1);
+ }
}
static void
solve(void)
{
-struct utrec *u = first_utrec;
-struct procrec *m, *n, *o, *q;
-struct passwd *pw;
- while (u)
+ struct utrec *u = first_utrec;
+ struct procrec *m, *n, *o, *q;
+ struct passwd *pw;
+ while (u)
+ {
+ m = first_procrec;
+ while (m && m->pid != u->login_pid)
+ m = m->next;
+ o = m;
+ if (m)
+ {
+ retry:
+ n = first_procrec;
+ q = o;
+ while (n)
+ {
+ if (q->sess == n->sess)
+ n->usr = -1;
+ if (q->pid == n->ppid && n->usr == -1)
{
- m = first_procrec;
- while (m && m->pid != u->login_pid)
- m = m->next;
- o = m;
- if (m)
- {
- retry:
- n = first_procrec;
- q = o;
- while (n)
- {
- if (q->sess == n->sess)
- n->usr = -1;
- if (q->pid == n->ppid && n->usr == -1)
- {
- o = n;
- goto retry;
- }
- n = n->next;
- }
- }
- u->proc = o;
- if (m)
- u->total_time = m->ctim;
+ o = n;
+ goto retry;
+ }
+ n = n->next;
+ }
+ }
+ u->proc = o;
+ if (m)
+ u->total_time = m->ctim;
#ifdef DEBUG
- if (o)
- {
- printf("%s %s\n", u->user_name, o->cmd_line);
- }
+ if (o)
+ {
+ printf("%s %s\n", u->user_name, o->cmd_line);
+ }
#endif
- u = u->next;
- }
- for(u=first_utrec; u; u=u->next)
- {
- for(m=first_procrec; m; m=m->next)
- if (u->usr == m->usr)
- {
- m->usr = -1;
- u->detach++;
+ u = u->next;
+ }
+ for(u=first_utrec; u; u=u->next)
+ {
+ for(m=first_procrec; m; m=m->next)
+ if (u->usr == m->usr)
+ {
+ m->usr = -1;
+ u->detach++;
#ifdef DEBUG
- printf("** %s %s\n", u->user_name, m->cmd_line);
+ printf("** %s %s\n", u->user_name, m->cmd_line);
#endif
- }
- }
- for(m=first_procrec; m; m=m->next)
- if (m->usr >= 2 && m->ppid == 1) /* Exclude no_user,root,bin */
- {
- for(u=first_utrec; u; u=u->next)
- if (u->usr == m->usr)
- break;
- if (!u)
- {
- u = xmalloc(sizeof(struct utrec));
- u->next = first_utrec;
- first_utrec = u;
- u->login_pid = 0;
- u->line_id[0] = 0;
- pw = getpwuid(u->usr = m->usr);
- if (pw)
- strcpy(u->user_name, pw->pw_name);
- else
- sprintf(u->user_name, "<%d>", m->usr);
- u->host_name[0] = 0;
- u->line_name[0] = 0;
- u->mesg = 3;
- u->detach = 0;
- u->proc = NULL;
- u->total_time = 0;
- }
- if (!u->proc)
- u->proc = m;
- u->total_time += m->ctim;
- u->detach ++;
+ }
+ }
+ for(m=first_procrec; m; m=m->next)
+ if (m->usr >= 2 && m->ppid == 1) /* Exclude no_user,root,bin */
+ {
+ for(u=first_utrec; u; u=u->next)
+ if (u->usr == m->usr)
+ break;
+ if (!u)
+ {
+ u = xmalloc(sizeof(struct utrec));
+ u->next = first_utrec;
+ first_utrec = u;
+ u->login_pid = 0;
+ u->line_id[0] = 0;
+ pw = getpwuid(u->usr = m->usr);
+ if (pw)
+ strcpy(u->user_name, pw->pw_name);
+ else
+ sprintf(u->user_name, "<%d>", m->usr);
+ u->host_name[0] = 0;
+ u->line_name[0] = 0;
+ u->mesg = 3;
+ u->detach = 0;
+ u->proc = NULL;
+ u->total_time = 0;
+ }
+ if (!u->proc)
+ u->proc = m;
+ u->total_time += m->ctim;
+ u->detach ++;
#ifdef DEBUG
- printf("// %s %s\n", u->user_name, m->cmd_line);
+ printf("// %s %s\n", u->user_name, m->cmd_line);
#endif
- }
+ }
}
static inline int
comp(struct utrec *a, struct utrec *b)
{
-int k;
- if (b->mesg == 3)
- return -1;
- k = strcmp(a->user_name, b->user_name);
- if (k)
- return k;
- if (!a->host_name[0] && b->host_name[0])
- return -1;
- return strcmp(a->line_id, b->line_id);
+ int k;
+ if (b->mesg == 3)
+ return -1;
+ k = strcmp(a->user_name, b->user_name);
+ if (k)
+ return k;
+ if (!a->host_name[0] && b->host_name[0])
+ return -1;
+ return strcmp(a->line_id, b->line_id);
}
static void
sort(void)
{
-struct utrec *fi = NULL;
-struct utrec *z, **y, **m, **l;
- l = &fi;
- while (first_utrec)
- {
- y = &first_utrec;
- m = y;
- while (z = *y)
- {
- if (comp(z, *m) < 0)
- m = y;
- y = &z->next;
- }
- z = *m;
- *m = z->next;
- *l = z;
- z->next = NULL;
- l = &z->next;
- }
- first_utrec = fi;
+ struct utrec *fi = NULL;
+ struct utrec *z, **y, **m, **l;
+ l = &fi;
+ while (first_utrec)
+ {
+ y = &first_utrec;
+ m = y;
+ while (z = *y)
+ {
+ if (comp(z, *m) < 0)
+ m = y;
+ y = &z->next;
+ }
+ z = *m;
+ *m = z->next;
+ *l = z;
+ z->next = NULL;
+ l = &z->next;
+ }
+ first_utrec = fi;
}
static void
show(void)
{
-struct utrec *u;
-int i;
-unsigned char *c;
- printf("Name Li MD From LogT IdleT RunT Command\n");
- 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 ",
- u->user_name,
- u->line_id,
- u->mesg ? ' ' : '-',
- u->detach ? 'D' : ' ',
- u->host_name);
- if (u->mesg <= 1)
- {
- if (u->login_time > now)
- u->login_time = now;
- puttime(now - u->login_time);
- putchar(' ');
- if (u->click_time > now)
- u->click_time = now;
- if (now - u->click_time >= 60)
- puttime(now - u->click_time);
- else
- printf(" ");
- }
- else
- printf("????? ");
- if (u->proc)
- {
- putchar(' ');
- puttime((unsigned)u->total_time/(unsigned)HZ);
- putchar(' ');
- i = 24;
- c = u->proc->cmd_line;
- while (*c != 0xff && i--)
- {
- putchar(*c ? *c : ' ');
- c++;
- }
- }
- else
- printf(" <nothing>");
- putchar('\n');
- }
+ struct utrec *u;
+ unsigned char *c;
+ printf("Name Li MD %-*s LogT IdleT RunT Command\n", maxhost, "From");
+ for(u=first_utrec; u; u=u->next)
+ {
+ 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)
+ {
+ if (u->login_time > now)
+ u->login_time = now;
+ puttime(now - u->login_time);
+ putchar(' ');
+ if (u->click_time > now)
+ u->click_time = now;
+ if (now - u->click_time >= 60)
+ puttime(now - u->click_time);
+ else
+ printf(" ");
+ }
+ else
+ printf("????? ");
+ if (u->proc)
+ {
+ putchar(' ');
+ puttime((unsigned)u->total_time/(unsigned)HZ);
+ putchar(' ');
+ for (c = u->proc->cmd_line; *c != 0x91; c++)
+ {
+ if (*c < 0x20 || (*c >= 0x7f && *c < 0xa0))
+ putchar(' ');
+ else
+ putchar(*c);
+ }
+ }
+ else
+ printf(" <nothing>");
+ putchar('\n');
+ }
}
int main(void)
{
- readutmp();
- dispsys();
- readproc();
- solve();
- sort();
- show();
- if (zombies)
- {
- printf("There %s %d zombie%s walking around.",
- zombies == 1 ? "is" : "are",
- zombies,
- zombies == 1 ? "" : "s" );
- }
- return 0;
+ readutmp();
+ dispsys();
+ readproc();
+ solve();
+ sort();
+ show();
+ if (zombies)
+ {
+ printf("!!! There %s %d zombie%s walking around.\n",
+ zombies == 1 ? "is" : "are",
+ zombies,
+ zombies == 1 ? "" : "s" );
+ }
+ return 0;
}