home *** CD-ROM | disk | FTP | other *** search
- #include <stdio.h>
- #include <sys/types.h>
- #include <sys/file.h>
- #include <sys/fs/s5dir.h>
- #include <sys/signal.h>
- #include <sys/user.h>
- #include <fcntl.h>
-
- #include <sys/immu.h>
- #include <sys/region.h>
- #include <sys/param.h>
- #include <sys/proc.h>
-
- #include <sys/sysi86.h>
-
- #include <utmp.h>
- #include <sys/stat.h>
- #include <time.h>
-
- #include <sys/ipc.h>
- #include <sys/shm.h>
-
- struct info {
- struct info *next;
- struct utmp ut; /* need user, line, and time */
- time_t atime; /* last mod time of line, for idle */
- dev_t device; /* device id of the line */
- char *command; /* user.u_psargs[] */
- time_t jcpu; /* sum of all children and current */
- time_t pcpu; /* cpu of current processes */
- };
-
- char *month[] = { "Jan", "Feb", "Mar", "Apr", "May", "Jun",
- "Jul", "Aug", "Sep", "Oct", "Nov", "Dec" };
- char *weekday[] = { "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat" };
-
- main(argc, argv)
- int argc;
- char *argv[];
- {
- struct utmp *utp;
- struct user uu;
- struct proc pp, *pro;
- struct stat stbuf;
- struct info *ip, *head;
- struct tm *tmp, nowtm;
- int pid, fd, s, nusers;
- int c, errflag, hflag, sflag;
- short pgrp;
- char *user = NULL;
- time_t now, boot;
- extern int optind;
- extern char *calloc(), *malloc();
-
- errflag = hflag = sflag = 0;
- while ((c = getopt(argc, argv, "hls")) != EOF) {
- switch (c) {
- case 'h': ++hflag; break;
- case 's': ++sflag; break;
- case 'l': sflag = 0; break;
- default: ++errflag; break;
- }
- }
- if (optind < argc)
- user = argv[optind++];
- if (errflag || optind < argc) {
- fprintf(stderr, "Usage: %s [-hls] [user]\n", argv[0]);
- exit(1);
- }
- (void) chdir("/dev");
- now = time(0);
- nowtm = *(localtime(&now));
- ip = head = NULL;
- nusers = 0;
- /* find out all the tty devices used (from utmp) */
- while ((utp = (struct utmp *)getutent()) != NULL) {
- if (utp->ut_type == BOOT_TIME)
- boot = utp->ut_time;
- if (utp->ut_type != USER_PROCESS)
- continue;
- ++nusers;
- if (ip != NULL) {
- ip->next = (struct info *)calloc(1, sizeof (struct info));
- ip = ip->next;
- } else
- ip = (struct info *)calloc(1, sizeof (struct info));
- ip->command = "-";
- ip->jcpu = ip->pcpu = 0;
- if (head == NULL)
- head = ip;
- ip->ut = *utp;
- if (stat(utp->ut_line, &stbuf) < 0) {
- ip->atime = now;
- ip->device = 0;
- } else {
- ip->atime = stbuf.st_atime;
- ip->device = stbuf.st_rdev;
- }
- }
- boot = now - boot;
- if (!strcmp(argv[0],"uptime")) {
- uptime(&nowtm, boot, nusers);
- exit(0);
- }
- if ((fd = open("/dev/kmem", O_RDONLY)) < 0) {
- perror("/dev/kmem");
- exit(1);
- }
-
- for (ip = head; ip != NULL; ip = ip->next) {
- if (sysi86(RDUBLK, ip->ut.ut_pid, &uu, sizeof uu) < sizeof uu) {
- perror("sysi86");
- exit(1);
- }
- if (ip == NULL)
- continue;
-
- for(pro=uu.u_procp;pro;pro=pp.p_child) {
- (void) lseek(fd, (ulong)pro, 0);
- read(fd, &pp, sizeof pp);
- }
-
- if (sysi86(RDUBLK, pp.p_pid, &uu, sizeof uu) < sizeof uu) {
- perror("sysi86");
- exit(1);
- }
-
- (void) lseek(fd, (ulong)(uu.u_ttyp), 0);
- read(fd, &pgrp, sizeof pgrp);
-
- if (pgrp == pp.p_pgrp) {
- ip->command = malloc(strlen(uu.u_psargs)+1);
- strcpy(ip->command, uu.u_psargs);
- }
- ip->pcpu += uu.u_utime + uu.u_stime;
- ip->jcpu += uu.u_utime + uu.u_stime + uu.u_cutime + uu.u_cstime;
-
- #if 0
- printf("pid=%d ttyp=%x ttyd=%x ttyip=%x procp=%x args=%s\n", pid,
- uu.u_ttyp, uu.u_ttyd, uu.u_ttyip, uu.u_procp,
- uu.u_psargs);
- printf("uid=%d pid=%d ppid=%d flag=%x pp.p_pgrp=%d pgrp=%d\n",
- pp.p_uid, pp.p_pid, pp.p_ppid, pp.p_flag,
- pp.p_pgrp, pgrp);
- #endif
- }
- close(fd);
-
- if (!hflag) {
- uptime(&nowtm, boot, nusers);
- printf("User tty login@ idle JCPU PCPU what\n");
- }
-
- for (ip = head; ip != NULL; ip = ip->next) {
- if (user && strncmp(user, ip->ut.ut_user, 8) != 0)
- continue;
- printf("%-8.8s %-8.8s ", ip->ut.ut_user, ip->ut.ut_line);
- tmp = localtime(&ip->ut.ut_time);
- if (now - ip->ut.ut_time > 60*60*24*7) /* > 1 week */
- printf("%2d%3s%2d", tmp->tm_mday,
- month[tmp->tm_mon], tmp->tm_year%100);
- else if (now - ip->ut.ut_time > 60*60*24) /* > 1 day */
- printf("%3s%2d%2s", weekday[tmp->tm_wday],
- (tmp->tm_hour % 12) +
- ((tmp->tm_hour % 12) == 0 ? 12 : 0),
- (tmp->tm_hour < 12) ? "am" : "pm");
- else
- printtime(tmp);
- s = now-(ip->atime);
- if (s < 60)
- printf(" ");
- else if (s < 60*60)
- printf(" %2d", s/60);
- else
- printf("%3d:%02d", s/(60*60), (s%(60*60))/60);
- printcpu(ip->jcpu);
- printcpu(ip->pcpu);
- printf(" %s\n", ip->command);
- }
- exit(0);
- }
-
- printtime(tmp)
- struct tm *tmp;
- {
- printf("%2d:%02d%2s",
- (tmp->tm_hour % 12) + ((tmp->tm_hour % 12) == 0 ? 12 : 0),
- tmp->tm_min, (tmp->tm_hour < 12) ? "am" : "pm");
- }
-
- printcpu(s)
- int s;
- {
- if (s < 100)
- printf(" ");
- else if (s < 6000)
- printf("%7d", s/100);
- else
- printf("%4d:%02d", (s/100/60), (s/100)%60);
- }
-
- uptime(nowtmp, sinceboot, nusers)
- struct tm *nowtmp;
- time_t sinceboot;
- int nusers;
- {
- int id;
- float *lav;
-
- putchar(' ');
- printtime(nowtmp);
- printf(" up ");
- if (sinceboot > 2*24*60*60)
- printf("%d days, ", sinceboot/24/60/60);
- else if (sinceboot > 24*60*60)
- printf("%d day, ", sinceboot/24/60/60);
- sinceboot %= 24*60*60;
- if (sinceboot > 60*60)
- printf("%2d:%02d", sinceboot/60/60, (sinceboot%(60*60))/60);
- else
- printf("%d mins", sinceboot/60);
- printf(", %d user%s", nusers, nusers == 1 ? "," : "s,");
- printf(" load average: ");
- id = shmget(ftok("/dev/kmem", 'lav'), 4 * sizeof (float), 0400);
- if (id < 0
- || (lav = (float *)shmat(id, (char *)0, SHM_RDONLY)) == (float *)-1)
- printf("hard to get\n");
- else {
- printf("%.2f, %.2f, %.2f\n", lav[0], lav[1], lav[2]);
- (void) shmdt(lav);
- }
- }
-