=================================================================== RCS file: /cvsrepo/anoncvs/cvs/src/usr.bin/rusers/rusers.c,v retrieving revision 1.17 retrieving revision 1.18 diff -c -r1.17 -r1.18 *** src/usr.bin/rusers/rusers.c 2001/11/06 02:46:29 1.17 --- src/usr.bin/rusers/rusers.c 2001/11/06 20:51:19 1.18 *************** *** 1,4 **** ! /* $OpenBSD: rusers.c,v 1.17 2001/11/06 02:46:29 millert Exp $ */ /* * Copyright (c) 2001 Todd C. Miller --- 1,4 ---- ! /* $OpenBSD: rusers.c,v 1.18 2001/11/06 20:51:19 millert Exp $ */ /* * Copyright (c) 2001 Todd C. Miller *************** *** 55,61 **** */ #ifndef lint ! static const char rcsid[] = "$OpenBSD: rusers.c,v 1.17 2001/11/06 02:46:29 millert Exp $"; #endif /* not lint */ #include --- 55,61 ---- */ #ifndef lint ! static const char rcsid[] = "$OpenBSD: rusers.c,v 1.18 2001/11/06 20:51:19 millert Exp $"; #endif /* not lint */ #include *************** *** 83,113 **** #define LINE_WIDTH 8 #define NAME_WIDTH 8 ! int search_host(struct in_addr); ! void remember_host(char **); void fmt_idle(int, char *, size_t); - void print_longline(int, u_int, char *, char *, char *, char *, int); void onehost(char *); void allhosts(void); void alarmclock(int); bool_t rusers_reply(char *, struct sockaddr_in *); bool_t rusers_reply_3(char *, struct sockaddr_in *); enum clnt_stat get_reply(int, in_port_t, u_long, struct rpc_msg *, struct rmtcallres *, bool_t (*)()); __dead void usage(void); ! int longopt; ! int allopt; long termwidth; extern char *__progname; - struct host_list { - struct host_list *next; - struct in_addr addr; - } *hosts; - - #define MAX_BROADCAST_SIZE 1400 - int main(int argc, char **argv) { --- 83,119 ---- #define LINE_WIDTH 8 #define NAME_WIDTH 8 ! #define MAX_BROADCAST_SIZE 1400 ! ! struct host_info { ! u_int count; ! u_int idle; ! char *host; ! rusers_utmp *users; ! } *hostinfo; ! ! void print_entry(struct host_info *); void fmt_idle(int, char *, size_t); void onehost(char *); void allhosts(void); + void sorthosts(void); void alarmclock(int); + char *estrndup(const char *, size_t); + struct host_info *add_host(char *); + int hcompare(const void *, const void *); + int icompare(const void *, const void *); + int ucompare(const void *, const void *); bool_t rusers_reply(char *, struct sockaddr_in *); bool_t rusers_reply_3(char *, struct sockaddr_in *); enum clnt_stat get_reply(int, in_port_t, u_long, struct rpc_msg *, struct rmtcallres *, bool_t (*)()); __dead void usage(void); ! int aflag, hflag, iflag, lflag, uflag; ! u_int nentries, maxentries; long termwidth; extern char *__progname; int main(int argc, char **argv) { *************** *** 115,133 **** char *cp, *ep; int ch; ! while ((ch = getopt(argc, argv, "al")) != -1) switch (ch) { case 'a': ! allopt++; break; case 'l': ! longopt++; break; default: usage(); /*NOTREACHED*/ } if (isatty(STDOUT_FILENO)) { if ((cp = getenv("COLUMNS")) != NULL && *cp != '\0') { termwidth = strtol(cp, &ep, 10); --- 121,151 ---- char *cp, *ep; int ch; ! while ((ch = getopt(argc, argv, "ahilu")) != -1) switch (ch) { case 'a': ! aflag = 1; break; + case 'h': + hflag = 1; + break; + case 'i': + iflag = 1; + break; case 'l': ! lflag = 1; break; + case 'u': + uflag = 1; + break; default: usage(); /*NOTREACHED*/ } + if (hflag + iflag + uflag > 1) + usage(); + if (isatty(STDOUT_FILENO)) { if ((cp = getenv("COLUMNS")) != NULL && *cp != '\0') { termwidth = strtol(cp, &ep, 10); *************** *** 143,184 **** termwidth = 80; } setlinebuf(stdout); ! if (argc == optind) ! allhosts(); ! else { for (; optind < argc; optind++) (void) onehost(argv[optind]); } exit(0); } ! int ! search_host(struct in_addr addr) { ! struct host_list *hp; ! ! if (!hosts) ! return(0); ! for (hp = hosts; hp != NULL; hp = hp->next) { ! if (hp->addr.s_addr == addr.s_addr) ! return(1); } - return(0); - } ! void ! remember_host(char **ap) ! { ! struct host_list *hp; ! ! for (; *ap; ap++) { ! if (!(hp = malloc(sizeof(struct host_list)))) err(1, NULL); - hp->addr.s_addr = *(in_addr_t *)*ap; - hp->next = hosts; - hosts = hp; } } void --- 161,204 ---- termwidth = 80; } setlinebuf(stdout); ! ! if (argc == optind) { ! if (hflag || iflag || uflag) { ! puts("Collecting responses..."); ! allhosts(); ! sorthosts(); ! } else ! allhosts(); ! } else { for (; optind < argc; optind++) (void) onehost(argv[optind]); } + exit(0); } ! struct host_info * ! add_host(char *host) { ! int i; ! for (i = 0; i < nentries; i++) { ! /* Existing entry. */ ! if (strcmp(host, hostinfo[i].host) == 0) ! return(NULL); } ! /* New entry, allocate space if needed and store. */ ! if (nentries == maxentries) { ! maxentries += 128; ! hostinfo = realloc(hostinfo, ! sizeof(*hostinfo) * maxentries); ! if (hostinfo == NULL) err(1, NULL); } + if ((hostinfo[nentries].host = strdup(host)) == NULL) + err(1, NULL); + return(&hostinfo[nentries++]); } void *************** *** 217,298 **** } } - void - print_longline(int ut_time, u_int idle, char *host, char *user, char *line, - char *remhost, int remhostmax) - { - char date[32], idle_time[64]; - char remote[RUSERS_MAXHOSTLEN + 1]; - int len; - - strftime(date, sizeof(date), "%h %d %R", localtime((time_t *)&ut_time)); - date[sizeof(date) - 1] = '\0'; - fmt_idle(idle, idle_time, sizeof(idle_time)); - len = termwidth - - (MAX(strlen(user), NAME_WIDTH) + 1 + HOST_WIDTH + 1 + LINE_WIDTH + - 1 + strlen(date) + 1 + MAX(8, strlen(idle_time)) + 1 + 2); - if (len > 0 && *remhost != '\0') - snprintf(remote, sizeof(remote), "(%.*s)", - MIN(len, remhostmax), remhost); - else - remote[0] = '\0'; - len = HOST_WIDTH - MIN(HOST_WIDTH, strlen(host)) + - LINE_WIDTH - MIN(LINE_WIDTH, strlen(line)); - printf("%-*s %.*s:%.*s%-*s %-12s %8s %s\n", - NAME_WIDTH, user, HOST_WIDTH, host, LINE_WIDTH, line, - len, "", date, idle_time, remote); - } - bool_t rusers_reply(char *replyp, struct sockaddr_in *raddrp) { - char user[RNUSERS_MAXUSERLEN + 1]; - char utline[RNUSERS_MAXLINELEN + 1]; utmpidlearr *up = (utmpidlearr *)replyp; struct hostent *hp; ! char *host, *taddrs[2]; int i; ! if (search_host(raddrp->sin_addr)) return(0); - if (!allopt && !up->uia_cnt) - return(0); - hp = gethostbyaddr((char *)&raddrp->sin_addr, sizeof(struct in_addr), AF_INET); ! if (hp) { host = hp->h_name; ! remember_host(hp->h_addr_list); ! } else { host = inet_ntoa(raddrp->sin_addr); ! taddrs[0] = (char *)&raddrp->sin_addr; ! taddrs[1] = NULL; ! remember_host(taddrs); } ! if (!longopt) ! printf("%-*.*s ", HOST_WIDTH, HOST_WIDTH, host); ! ! for (i = 0; i < up->uia_cnt; i++) { ! /* NOTE: strncpy() used below for non-terminated strings. */ ! strncpy(user, up->uia_arr[i]->ui_utmp.ut_name, ! sizeof(user) - 1); ! user[sizeof(user) - 1] = '\0'; ! if (longopt) { ! strncpy(utline, up->uia_arr[i]->ui_utmp.ut_line, ! sizeof(utline) - 1); ! utline[sizeof(utline) - 1] = '\0'; ! print_longline(up->uia_arr[i]->ui_utmp.ut_time, ! up->uia_arr[i]->ui_idle, host, user, utline, ! up->uia_arr[i]->ui_utmp.ut_host, RNUSERS_MAXHOSTLEN); ! } else { ! fputs(user, stdout); ! putchar(' '); } } - if (!longopt) - putchar('\n'); return(0); } --- 237,291 ---- } } bool_t rusers_reply(char *replyp, struct sockaddr_in *raddrp) { utmpidlearr *up = (utmpidlearr *)replyp; + struct host_info *entry; struct hostent *hp; ! rusers_utmp *ut; ! char *host; int i; ! if (!aflag && up->uia_cnt == 0) return(0); hp = gethostbyaddr((char *)&raddrp->sin_addr, sizeof(struct in_addr), AF_INET); ! if (hp) host = hp->h_name; ! else host = inet_ntoa(raddrp->sin_addr); ! if ((entry = add_host(host)) == NULL) ! return(0); ! ! if ((ut = malloc(up->uia_cnt * sizeof(*ut))) == NULL) ! err(1, NULL); ! entry->users = ut; ! entry->count = up->uia_cnt; ! entry->idle = UINT_MAX; ! for (i = 0; i < up->uia_cnt; i++, ut++) { ! ut->ut_user = estrndup(up->uia_arr[i]->ui_utmp.ut_name, ! RNUSERS_MAXUSERLEN); ! ut->ut_line = estrndup(up->uia_arr[i]->ui_utmp.ut_line, ! RNUSERS_MAXLINELEN); ! ut->ut_host = estrndup(up->uia_arr[i]->ui_utmp.ut_host, ! RNUSERS_MAXHOSTLEN); ! ut->ut_time = up->uia_arr[i]->ui_utmp.ut_time; ! ut->ut_idle = up->uia_arr[i]->ui_idle; ! if (ut->ut_idle < entry->idle) ! entry->idle = ut->ut_idle; } ! if (!hflag && !iflag && !uflag) { ! print_entry(entry); ! for (i = 0, ut = entry->users; i < entry->count; i++, ut++) { ! free(ut->ut_user); ! free(ut->ut_line); ! free(ut->ut_host); } + free(entry->users); } return(0); } *************** *** 300,352 **** bool_t rusers_reply_3(char *replyp, struct sockaddr_in *raddrp) { - char user[RUSERS_MAXUSERLEN + 1]; - char utline[RUSERS_MAXLINELEN + 1]; utmp_array *up3 = (utmp_array *)replyp; struct hostent *hp; ! char *host, *taddrs[2]; int i; ! if (search_host(raddrp->sin_addr)) return(0); - if (!allopt && !up3->utmp_array_len) - return(0); - hp = gethostbyaddr((char *)&raddrp->sin_addr, sizeof(struct in_addr), AF_INET); ! if (hp) { host = hp->h_name; ! remember_host(hp->h_addr_list); ! } else { host = inet_ntoa(raddrp->sin_addr); ! taddrs[0] = (char *)&raddrp->sin_addr; ! taddrs[1] = NULL; ! remember_host(taddrs); } ! if (!longopt) ! printf("%-*.*s ", HOST_WIDTH, HOST_WIDTH, host); ! ! for (i = 0; i < up3->utmp_array_len; i++) { ! /* NOTE: strncpy() used below for non-terminated strings. */ ! strncpy(user, up3->utmp_array_val[i].ut_user, ! sizeof(user) - 1); ! user[sizeof(user) - 1] = '\0'; ! if (longopt) { ! strncpy(utline, up3->utmp_array_val[i].ut_line, ! sizeof(utline) - 1); ! utline[sizeof(utline) - 1] = '\0'; ! print_longline(up3->utmp_array_val[i].ut_time, ! up3->utmp_array_val[i].ut_idle, host, user, utline, ! up3->utmp_array_val[i].ut_host, RUSERS_MAXHOSTLEN); ! } else { ! fputs(user, stdout); ! putchar(' '); } } - if (!longopt) - putchar('\n'); return(0); } --- 293,344 ---- bool_t rusers_reply_3(char *replyp, struct sockaddr_in *raddrp) { utmp_array *up3 = (utmp_array *)replyp; + struct host_info *entry; struct hostent *hp; ! rusers_utmp *ut; ! char *host; int i; ! if (!aflag && !up3->utmp_array_len) return(0); hp = gethostbyaddr((char *)&raddrp->sin_addr, sizeof(struct in_addr), AF_INET); ! if (hp) host = hp->h_name; ! else host = inet_ntoa(raddrp->sin_addr); ! if ((entry = add_host(host)) == NULL) ! return(0); ! ! if ((ut = malloc(up3->utmp_array_len * sizeof(*ut))) == NULL) ! err(1, NULL); ! entry->users = ut; ! entry->count = up3->utmp_array_len; ! entry->idle = UINT_MAX; ! for (i = 0; i < up3->utmp_array_len; i++, ut++) { ! ut->ut_user = estrndup(up3->utmp_array_val[i].ut_user, ! RUSERS_MAXUSERLEN); ! ut->ut_line = estrndup(up3->utmp_array_val[i].ut_line, ! RUSERS_MAXLINELEN); ! ut->ut_host = estrndup(up3->utmp_array_val[i].ut_host, ! RUSERS_MAXHOSTLEN); ! ut->ut_time = up3->utmp_array_val[i].ut_time; ! ut->ut_idle = up3->utmp_array_val[i].ut_idle; ! if (ut->ut_idle < entry->idle) ! entry->idle = ut->ut_idle; } ! if (!hflag && !iflag && !uflag) { ! print_entry(entry); ! for (i = 0, ut = entry->users; i < entry->count; i++, ut++) { ! free(ut->ut_user); ! free(ut->ut_line); ! free(ut->ut_host); } + free(entry->users); } return(0); } *************** *** 366,372 **** if (hp == NULL) errx(1, "unknown host \"%s\"", host); ! /* try version 3 first */ rusers_clnt = clnt_create(host, RUSERSPROG, RUSERSVERS_3, "udp"); if (rusers_clnt == NULL) { clnt_pcreateerror(__progname); --- 358,364 ---- if (hp == NULL) errx(1, "unknown host \"%s\"", host); ! /* Try version 3 first. */ rusers_clnt = clnt_create(host, RUSERSPROG, RUSERSVERS_3, "udp"); if (rusers_clnt == NULL) { clnt_pcreateerror(__progname); *************** *** 391,397 **** exit(1); } ! /* fall back to version 2 */ rusers_clnt = clnt_create(host, RUSERSPROG, RUSERSVERS_IDLE, "udp"); if (rusers_clnt == NULL) { clnt_pcreateerror(__progname); --- 383,389 ---- exit(1); } ! /* Fall back to version 2. */ rusers_clnt = clnt_create(host, RUSERSPROG, RUSERSVERS_IDLE, "udp"); if (rusers_clnt == NULL) { clnt_pcreateerror(__progname); *************** *** 597,603 **** */ timeout.it_value.tv_sec = 5; timeout.it_value.tv_usec = 0; ! for (;;) { FD_SET(sock[0], fds); FD_SET(sock[1], fds); setitimer(ITIMER_REAL, &timeout, NULL); --- 589,595 ---- */ timeout.it_value.tv_sec = 5; timeout.it_value.tv_usec = 0; ! while (timerisset(&timeout.it_value)) { FD_SET(sock[0], fds); FD_SET(sock[1], fds); setitimer(ITIMER_REAL, &timeout, NULL); *************** *** 639,654 **** } void alarmclock(int signo) { ; /* just interupt */ } void usage(void) { ! fprintf(stderr, "usage: %s [-la] [hosts ...]\n", __progname); exit(1); } --- 631,783 ---- } void + print_entry(struct host_info *entry) + { + char date[32], idle_time[64]; + char remote[RUSERS_MAXHOSTLEN + 3]; + struct rusers_utmp *ut; + int i, len; + + if (!lflag) + printf("%-*.*s ", HOST_WIDTH, HOST_WIDTH, entry->host); + + for (i = 0, ut = entry->users; i < entry->count; i++, ut++) { + if (lflag) { + strftime(date, sizeof(date), "%h %d %R", + localtime((time_t *)&ut->ut_time)); + date[sizeof(date) - 1] = '\0'; + fmt_idle(ut->ut_idle, idle_time, sizeof(idle_time)); + len = termwidth - + (MAX(strlen(ut->ut_user), NAME_WIDTH) + 1 + + HOST_WIDTH + 1 + LINE_WIDTH + 1 + strlen(date) + + 1 + MAX(8, strlen(idle_time)) + 1 + 2); + if (len > 0 && ut->ut_host[0] != '\0') + snprintf(remote, sizeof(remote), "(%.*s)", + MIN(len, RUSERS_MAXHOSTLEN), ut->ut_host); + else + remote[0] = '\0'; + len = HOST_WIDTH - MIN(HOST_WIDTH, strlen(entry->host)) + + LINE_WIDTH - MIN(LINE_WIDTH, strlen(ut->ut_line)); + printf("%-*s %.*s:%.*s%-*s %-12s %8s %s\n", + NAME_WIDTH, ut->ut_user, HOST_WIDTH, entry->host, + LINE_WIDTH, ut->ut_line, len, "", date, + idle_time, remote); + } else { + fputs(ut->ut_user, stdout); + putchar(' '); + } + } + if (!lflag) + putchar('\n'); + } + + void + sorthosts() + { + int i; + int (*compar)(const void *, const void *); + + if (hflag) + compar = hcompare; + else if (iflag) + compar = icompare; + else + compar = ucompare; + qsort(hostinfo, nentries, sizeof(*hostinfo), compar); + + for (i = 0; i < nentries; i++) + print_entry(&hostinfo[i]); + } + + int + hcompare(const void *aa, const void *bb) + { + const struct host_info *a = (struct host_info *)aa; + const struct host_info *b = (struct host_info *)bb; + int rval; + + if ((rval = strcasecmp(a->host, b->host)) != 0) + return(rval); + + if (a->idle < b->idle) + return(-1); + else if (a->idle > b->idle) + return(1); + + if (a->count > b->count) + return(-1); + else if (a->count < b->count) + return(1); + + return(0); + } + + int + icompare(const void *aa, const void *bb) + { + const struct host_info *a = (struct host_info *)aa; + const struct host_info *b = (struct host_info *)bb; + + if (a->idle < b->idle) + return(-1); + else if (a->idle > b->idle) + return(1); + + if (a->count > b->count) + return(-1); + else if (a->count < b->count) + return(1); + + return(strcasecmp(a->host, b->host)); + } + + int + ucompare(const void *aa, const void *bb) + { + const struct host_info *a = (struct host_info *)aa; + const struct host_info *b = (struct host_info *)bb; + + if (a->count > b->count) + return(-1); + else if (a->count < b->count) + return(1); + + if (a->idle < b->idle) + return(-1); + else if (a->idle > b->idle) + return(1); + + return(strcasecmp(a->host, b->host)); + } + + void alarmclock(int signo) { ; /* just interupt */ } + char * + estrndup(const char *src, size_t len) + { + char *dst, *end; + + if ((end = memchr(src, '\0', len)) != NULL) + len = end - src; + + if ((dst = malloc(len + 1)) == NULL) + err(1, NULL); + memcpy(dst, src, len); + dst[len] = '\0'; + + return(dst); + } + void usage(void) { ! fprintf(stderr, "usage: %s [-al] [-h | -i | -u] [hosts ...]\n", ! __progname); exit(1); }