# HG changeset patch # User David Edmondson # Date 1257196206 28800 # Node ID 5c243175898c2bdf05e2faae3be3e6e90988495c # Parent 2e39e3d31413bf052b609ccbf18a774103a097b9 6886511 finger should sort its output by username diff -r 2e39e3d31413 -r 5c243175898c usr/src/cmd/cmd-inet/usr.bin/finger.c --- a/usr/src/cmd/cmd-inet/usr.bin/finger.c Tue Nov 03 01:23:54 2009 +0800 +++ b/usr/src/cmd/cmd-inet/usr.bin/finger.c Mon Nov 02 13:10:06 2009 -0800 @@ -20,7 +20,7 @@ */ /* - * Copyright 2006 Sun Microsystems, Inc. All rights reserved. + * Copyright 2009 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ @@ -37,8 +37,6 @@ * contributors. */ -#pragma ident "%Z%%M% %I% %E% SMI" - /* * This is a finger program. It prints out useful information about users * by digging it up from various system files. @@ -167,6 +165,7 @@ int unshort; FILE *lf; /* LASTLOG file pointer */ struct person *person1; /* list of people */ +size_t nperson; /* number of people */ time_t tloc; /* current time */ char usagestr[] = "Usage: " @@ -193,6 +192,7 @@ void quickprint(struct person *pers); void shortprint(struct person *pers); void stimeprint(time_t *dt); +void sort_by_username(void); int @@ -252,7 +252,10 @@ doall(); else donames(&argv[optind]); - if (person1) + + sort_by_username(); + + if (nperson > 0) print(); return (0); /* NOTREACHED */ @@ -272,12 +275,12 @@ setpwent(); fwopen(); } - while (u = getutxent()) { + while ((u = getutxent()) != NULL) { if (u->ut_name[0] == 0 || nonuserx(*u) || u->ut_type != USER_PROCESS) continue; - if (person1 == 0) + if (person1 == NULL) p = person1 = malloc(sizeof (*p)); else { p->link = malloc(sizeof (*p)); @@ -290,7 +293,7 @@ bcopy(u->ut_host, p->host, HMAX); p->host[HMAX] = 0; p->loginat = u->ut_tv.tv_sec; - p->pwd = 0; + p->pwd = NULL; p->loggedin = 1; if (unquick && (pw = getpwnam(name))) { p->pwd = pwdcopy(pw); @@ -299,17 +302,19 @@ } else p->name = strdup(name); p->ttyloc = NULL; + + nperson++; } if (unquick) { fwclose(); endpwent(); } endutxent(); - if (person1 == 0) { + if (nperson == 0) { (void) printf("No one logged on\n"); return; } - p->link = 0; + p->link = NULL; } void @@ -324,10 +329,10 @@ * logged in */ unshort = !small; - for (; *argv != 0; argv++) { + for (; *argv != NULL; argv++) { if (netfinger(*argv)) continue; - if (person1 == 0) + if (person1 == NULL) p = person1 = malloc(sizeof (*p)); else { p->link = malloc(sizeof (*p)); @@ -336,24 +341,26 @@ p->name = *argv; p->loggedin = 0; p->original = 1; - p->pwd = 0; + p->pwd = NULL; + + nperson++; } - if (person1 == 0) + if (nperson == 0) return; - p->link = 0; + p->link = NULL; /* * if we are doing it, read /etc/passwd for the useful info */ if (unquick) { setpwent(); if (!match) { - for (p = person1; p != 0; p = p->link) { - if (pw = getpwnam(p->name)) + for (p = person1; p != NULL; p = p->link) { + if ((pw = getpwnam(p->name)) != NULL) p->pwd = pwdcopy(pw); } } else { - while ((pw = getpwent()) != 0) { - for (p = person1; p != 0; p = p->link) { + while ((pw = getpwent()) != NULL) { + for (p = person1; p != NULL; p = p->link) { if (!p->original) continue; if (strcmp(p->name, pw->pw_name) != 0 && @@ -361,7 +368,7 @@ p->name)) { continue; } - if (p->pwd == 0) { + if (p->pwd == NULL) { p->pwd = pwdcopy(pw); } else { struct person *new; @@ -380,6 +387,8 @@ p->original = 0; p->link = new; p = new; + + nperson++; } } } @@ -388,14 +397,15 @@ } /* Now get login information */ setutxent(); - while (u = getutxent()) { + while ((u = getutxent()) != NULL) { if (u->ut_name[0] == 0 || u->ut_type != USER_PROCESS) continue; - for (p = person1; p != 0; p = p->link) { + for (p = person1; p != NULL; p = p->link) { p->ttyloc = NULL; if (p->loggedin == 2) continue; - if (strncmp(p->pwd ? p->pwd->pw_name : p->name, + if (strncmp((p->pwd != NULL) ? + p->pwd->pw_name : p->name, u->ut_name, NMAX) != 0) continue; if (p->loggedin == 0) { @@ -421,13 +431,15 @@ p->loggedin = 2; p->link = new; p = new; + + nperson++; } } } endutxent(); if (unquick) { fwopen(); - for (p = person1; p != 0; p = p->link) + for (p = person1; p != NULL; p = p->link) decode(p); fwclose(); } @@ -461,7 +473,7 @@ (void) putchar('\n'); } } - for (p = person1; p != 0; p = p->link) { + for (p = person1; p != NULL; p = p->link) { if (!unquick) { quickprint(p); continue; @@ -471,14 +483,14 @@ continue; } personprint(p); - if (p->pwd != 0 && !AlreadyPrinted(p->pwd->pw_uid)) { + if (p->pwd != NULL && !AlreadyPrinted(p->pwd->pw_uid)) { AnyMail(p->pwd->pw_name); if (hack) { struct stat sbuf; s = malloc(strlen(p->pwd->pw_dir) + - sizeof (PROJ)); - if (s) { + sizeof (PROJ)); + if (s != NULL) { (void) strcpy(s, p->pwd->pw_dir); (void) strcat(s, PROJ); if (stat(s, &sbuf) != -1 && @@ -496,8 +508,8 @@ struct stat sbuf; s = malloc(strlen(p->pwd->pw_dir) + - sizeof (PLAN)); - if (s) { + sizeof (PLAN)); + if (s != NULL) { (void) strcpy(s, p->pwd->pw_dir); (void) strcat(s, PLAN); if (stat(s, &sbuf) == -1 || @@ -513,7 +525,7 @@ } } } - if (p->link != 0) + if (p->link != NULL) (void) putchar('\n'); } } @@ -548,12 +560,12 @@ if (idle) { findidle(pers); (void) printf("%c%-12s %-16.16s", - pers->writable ? ' ' : '*', - pers->tty, ctime(&pers->loginat)); + pers->writable ? ' ' : '*', + pers->tty, ctime(&pers->loginat)); ltimeprint(" ", &pers->idletime, ""); } else { (void) printf(" %-12s %-16.16s", - pers->tty, ctime(&pers->loginat)); + pers->tty, ctime(&pers->loginat)); } (void) putchar('\n'); } else { @@ -570,13 +582,13 @@ { char *p; - if (pers->pwd == 0) { + if (pers->pwd == NULL) { (void) printf("%-15s ???\n", pers->name); return; } (void) printf("%-8s", pers->pwd->pw_name); if (wide) { - if (pers->realname) { + if (pers->realname != NULL) { (void) printf(" %-20.20s", pers->realname); } else { (void) printf(" ??? "); @@ -621,9 +633,9 @@ void personprint(struct person *pers) { - if (pers->pwd == 0) { + if (pers->pwd == NULL) { (void) printf("Login name: %-10s\t\t\tIn real life: ???\n", - pers->name); + pers->name); return; } (void) printf("Login name: %-10s", pers->pwd->pw_name); @@ -632,7 +644,7 @@ } else { (void) printf(" "); } - if (pers->realname) { + if (pers->realname != NULL) { (void) printf("In real life: %s", pers->realname); } if (unbrief) { @@ -644,11 +656,11 @@ char *ep = ctime(&pers->loginat); if (*pers->host) { (void) printf("\nOn since %15.15s on %s from %s", - &ep[4], pers->tty, pers->host); + &ep[4], pers->tty, pers->host); ltimeprint("\n", &pers->idletime, " Idle Time"); } else { (void) printf("\nOn since %15.15s on %-12s", - &ep[4], pers->tty); + &ep[4], pers->tty); ltimeprint("\n", &pers->idletime, " Idle Time"); } } else if (pers->loginat == 0) { @@ -656,7 +668,7 @@ } else if (tloc - pers->loginat > 180 * 24 * 60 * 60) { char *ep = ctime(&pers->loginat); (void) printf("\nLast login %10.10s, %4.4s on %s", - ep, ep+20, pers->tty); + ep, ep+20, pers->tty); if (*pers->host) { (void) printf(" from %s", pers->host); } @@ -680,8 +692,8 @@ char buffer[256]; char *bp, *gp, *lp; - pers->realname = 0; - if (pers->pwd == 0) + pers->realname = NULL; + if (pers->pwd == NULL) return; gp = pers->pwd->pw_gecos; bp = buffer; @@ -721,7 +733,7 @@ void fwopen(void) { - if ((lf = fopen(LASTLOG, "r")) == (FILE *)NULL) + if ((lf = fopen(LASTLOG, "r")) == NULL) (void) fprintf(stderr, "finger: %s open error\n", LASTLOG); } @@ -730,7 +742,7 @@ { struct lastlog ll; - if (lf != (FILE *)NULL) { + if (lf != NULL) { if (fseeko(lf, (off_t)pers->pwd->pw_uid * (off_t)sizeof (ll), SEEK_SET) == 0) { if (fread((char *)&ll, sizeof (ll), 1, lf) == 1) { @@ -766,7 +778,7 @@ void fwclose(void) { - if (lf != (FILE *)0) + if (lf != NULL) (void) fclose(lf); } @@ -778,9 +790,7 @@ findidle(struct person *pers) { struct stat ttystatus; -#ifdef sun struct stat inputdevstatus; -#endif #define TTYLEN (sizeof ("/dev/") - 1) static char buffer[TTYLEN + LMAX + 1] = "/dev/"; time_t t; @@ -793,7 +803,6 @@ exit(4); } lastinputtime = ttystatus.st_atime; -#ifdef sun if (strcmp(pers->tty, "console") == 0) { /* * On the console, the user may be running a window system; if @@ -811,7 +820,6 @@ lastinputtime = inputdevstatus.st_atime; } } -#endif t = time(NULL); if (t < lastinputtime) pers->idletime = (time_t)0; @@ -841,7 +849,7 @@ (void) printf("%3d:", delta->tm_hour); else (void) printf("%1d:%02d", - delta->tm_hour, delta->tm_min); + delta->tm_hour, delta->tm_min); else (void) printf("%3dd", delta->tm_yday); } @@ -865,15 +873,15 @@ (void) printf("%d days", delta->tm_yday); else if (delta->tm_yday > 0) (void) printf("%d day%s %d hour%s", - delta->tm_yday, delta->tm_yday == 1 ? "" : "s", - delta->tm_hour, delta->tm_hour == 1 ? "" : "s"); + delta->tm_yday, delta->tm_yday == 1 ? "" : "s", + delta->tm_hour, delta->tm_hour == 1 ? "" : "s"); else if (delta->tm_hour >= 10) (void) printf("%d hours", delta->tm_hour); else if (delta->tm_hour > 0) (void) printf("%d hour%s %d minute%s", - delta->tm_hour, delta->tm_hour == 1 ? "" : "s", - delta->tm_min, delta->tm_min == 1 ? "" : "s"); + delta->tm_hour, delta->tm_hour == 1 ? "" : "s", + delta->tm_min, delta->tm_min == 1 ? "" : "s"); else if (delta->tm_min >= 10) (void) printf("%2d minutes", delta->tm_min); @@ -881,10 +889,10 @@ (void) printf("%2d seconds", delta->tm_sec); else (void) printf("%d minute%s %d second%s", - delta->tm_min, - delta->tm_min == 1 ? "" : "s", - delta->tm_sec, - delta->tm_sec == 1 ? "" : "s"); + delta->tm_min, + delta->tm_min == 1 ? "" : "s", + delta->tm_sec, + delta->tm_sec == 1 ? "" : "s"); (void) printf("%s", after); } @@ -1292,7 +1300,7 @@ char *timestr; mbxpath = malloc(strlen(name) + strlen(MAILDIR) + 1); - if (mbxpath == (char *)NULL) + if (mbxpath == NULL) return; (void) strcpy(mbxpath, mbxdir); /* copy preamble into path name */ @@ -1396,7 +1404,7 @@ (void) fflush(stdout); while (select(fd + 1, &readfds, (fd_set *) 0, - &exceptfds, &tv) != -1) { + &exceptfds, &tv) != -1) { unsigned char buf[BUFSIZ]; int nread; @@ -1413,7 +1421,7 @@ (void) putchar((int)*p); else if (isascii(*p)) (void) fputs(unctrl(*p), - stdout); + stdout); } } else break; @@ -1473,3 +1481,55 @@ (void) defopen(NULL); /* close default file */ } } + +int +person_compare(const void *p1, const void *p2) +{ + const struct person *pp1 = *(struct person **)p1; + const struct person *pp2 = *(struct person **)p2; + int r; + + /* + * Sort by username. + */ + r = strcmp(pp1->name, pp2->name); + + if (r != 0) + return (r); + + /* + * If usernames are the same, sort by idle time. + */ + r = pp1->idletime - pp2->idletime; + + return (r); +} + +void +sort_by_username() +{ + struct person **sortable, *loop; + size_t i; + + sortable = malloc(sizeof (sortable[0]) * nperson); + + if (sortable == NULL) + return; + + for (i = 0, loop = person1; i < nperson; i++) { + struct person *next = loop->link; + + sortable[i] = loop; + loop->link = NULL; + + loop = next; + } + + qsort(sortable, nperson, sizeof (sortable[0]), person_compare); + + for (i = 1; i < nperson; i++) + sortable[i-1]->link = sortable[i]; + person1 = sortable[0]; + + free(sortable); +}