[BACK]Return to rusers.c CVS log [TXT][DIR] Up to [local] / src / usr.bin / rusers

Diff for /src/usr.bin/rusers/rusers.c between version 1.17 and 1.18

version 1.17, 2001/11/06 02:46:29 version 1.18, 2001/11/06 20:51:19
Line 83 
Line 83 
 #define LINE_WIDTH 8  #define LINE_WIDTH 8
 #define NAME_WIDTH 8  #define NAME_WIDTH 8
   
 int search_host(struct in_addr);  #define MAX_BROADCAST_SIZE 1400
 void remember_host(char **);  
   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 fmt_idle(int, char *, size_t);
 void print_longline(int, u_int, char *, char *, char *, char *, int);  
 void onehost(char *);  void onehost(char *);
 void allhosts(void);  void allhosts(void);
   void sorthosts(void);
 void alarmclock(int);  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(char *, struct sockaddr_in *);
 bool_t rusers_reply_3(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 *,  enum clnt_stat get_reply(int, in_port_t, u_long, struct rpc_msg *,
     struct rmtcallres *, bool_t (*)());      struct rmtcallres *, bool_t (*)());
 __dead void usage(void);  __dead void usage(void);
   
 int longopt;  int aflag, hflag, iflag, lflag, uflag;
 int allopt;  u_int nentries, maxentries;
 long termwidth;  long termwidth;
 extern char *__progname;  extern char *__progname;
   
 struct host_list {  
         struct host_list *next;  
         struct in_addr addr;  
 } *hosts;  
   
 #define MAX_BROADCAST_SIZE 1400  
   
 int  int
 main(int argc, char **argv)  main(int argc, char **argv)
 {  {
Line 115 
Line 121 
         char *cp, *ep;          char *cp, *ep;
         int ch;          int ch;
   
         while ((ch = getopt(argc, argv, "al")) != -1)          while ((ch = getopt(argc, argv, "ahilu")) != -1)
                 switch (ch) {                  switch (ch) {
                 case 'a':                  case 'a':
                         allopt++;                          aflag = 1;
                         break;                          break;
                   case 'h':
                           hflag = 1;
                           break;
                   case 'i':
                           iflag = 1;
                           break;
                 case 'l':                  case 'l':
                         longopt++;                          lflag = 1;
                         break;                          break;
                   case 'u':
                           uflag = 1;
                           break;
                 default:                  default:
                         usage();                          usage();
                         /*NOTREACHED*/                          /*NOTREACHED*/
                 }                  }
   
           if (hflag + iflag + uflag > 1)
                   usage();
   
         if (isatty(STDOUT_FILENO)) {          if (isatty(STDOUT_FILENO)) {
                 if ((cp = getenv("COLUMNS")) != NULL && *cp != '\0') {                  if ((cp = getenv("COLUMNS")) != NULL && *cp != '\0') {
                         termwidth = strtol(cp, &ep, 10);                          termwidth = strtol(cp, &ep, 10);
Line 143 
Line 161 
                         termwidth = 80;                          termwidth = 80;
         }          }
         setlinebuf(stdout);          setlinebuf(stdout);
         if (argc == optind)  
                 allhosts();          if (argc == optind) {
         else {                  if (hflag || iflag || uflag) {
                           puts("Collecting responses...");
                           allhosts();
                           sorthosts();
                   } else
                           allhosts();
           } else {
                 for (; optind < argc; optind++)                  for (; optind < argc; optind++)
                         (void) onehost(argv[optind]);                          (void) onehost(argv[optind]);
         }          }
   
         exit(0);          exit(0);
 }  }
   
 int  struct host_info *
 search_host(struct in_addr addr)  add_host(char *host)
 {  {
         struct host_list *hp;          int i;
   
         if (!hosts)  
                 return(0);  
   
         for (hp = hosts; hp != NULL; hp = hp->next) {          for (i = 0; i < nentries; i++) {
                 if (hp->addr.s_addr == addr.s_addr)                  /* Existing entry. */
                         return(1);                  if (strcmp(host, hostinfo[i].host) == 0)
                           return(NULL);
         }          }
         return(0);  
 }  
   
 void          /* New entry, allocate space if needed and store. */
 remember_host(char **ap)          if (nentries == maxentries) {
 {                  maxentries += 128;
         struct host_list *hp;                  hostinfo = realloc(hostinfo,
                       sizeof(*hostinfo) * maxentries);
         for (; *ap; ap++) {                  if (hostinfo == NULL)
                 if (!(hp = malloc(sizeof(struct host_list))))  
                         err(1, NULL);                          err(1, NULL);
                 hp->addr.s_addr = *(in_addr_t *)*ap;  
                 hp->next = hosts;  
                 hosts = hp;  
         }          }
           if ((hostinfo[nentries].host = strdup(host)) == NULL)
                   err(1, NULL);
           return(&hostinfo[nentries++]);
 }  }
   
 void  void
Line 217 
Line 237 
         }          }
 }  }
   
 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  bool_t
 rusers_reply(char *replyp, struct sockaddr_in *raddrp)  rusers_reply(char *replyp, struct sockaddr_in *raddrp)
 {  {
         char user[RNUSERS_MAXUSERLEN + 1];  
         char utline[RNUSERS_MAXLINELEN + 1];  
         utmpidlearr *up = (utmpidlearr *)replyp;          utmpidlearr *up = (utmpidlearr *)replyp;
           struct host_info *entry;
         struct hostent *hp;          struct hostent *hp;
         char *host, *taddrs[2];          rusers_utmp *ut;
           char *host;
         int i;          int i;
   
         if (search_host(raddrp->sin_addr))          if (!aflag && up->uia_cnt == 0)
                 return(0);                  return(0);
   
         if (!allopt && !up->uia_cnt)  
                 return(0);  
   
         hp = gethostbyaddr((char *)&raddrp->sin_addr,          hp = gethostbyaddr((char *)&raddrp->sin_addr,
             sizeof(struct in_addr), AF_INET);              sizeof(struct in_addr), AF_INET);
         if (hp) {          if (hp)
                 host = hp->h_name;                  host = hp->h_name;
                 remember_host(hp->h_addr_list);          else
         } else {  
                 host = inet_ntoa(raddrp->sin_addr);                  host = inet_ntoa(raddrp->sin_addr);
                 taddrs[0] = (char *)&raddrp->sin_addr;          if ((entry = add_host(host)) == NULL)
                 taddrs[1] = NULL;                  return(0);
                 remember_host(taddrs);  
           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 (!longopt)          if (!hflag && !iflag && !uflag) {
                 printf("%-*.*s ", HOST_WIDTH, HOST_WIDTH, host);                  print_entry(entry);
                   for (i = 0, ut = entry->users; i < entry->count; i++, ut++) {
         for (i = 0; i < up->uia_cnt; i++) {                          free(ut->ut_user);
                 /* NOTE: strncpy() used below for non-terminated strings. */                          free(ut->ut_line);
                 strncpy(user, up->uia_arr[i]->ui_utmp.ut_name,                          free(ut->ut_host);
                     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(' ');  
                 }                  }
                   free(entry->users);
         }          }
         if (!longopt)  
                 putchar('\n');  
   
         return(0);          return(0);
 }  }
Line 300 
Line 293 
 bool_t  bool_t
 rusers_reply_3(char *replyp, struct sockaddr_in *raddrp)  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;          utmp_array *up3 = (utmp_array *)replyp;
           struct host_info *entry;
         struct hostent *hp;          struct hostent *hp;
         char *host, *taddrs[2];          rusers_utmp *ut;
           char *host;
         int i;          int i;
   
         if (search_host(raddrp->sin_addr))          if (!aflag && !up3->utmp_array_len)
                 return(0);                  return(0);
   
         if (!allopt && !up3->utmp_array_len)  
                 return(0);  
   
         hp = gethostbyaddr((char *)&raddrp->sin_addr,          hp = gethostbyaddr((char *)&raddrp->sin_addr,
             sizeof(struct in_addr), AF_INET);              sizeof(struct in_addr), AF_INET);
         if (hp) {          if (hp)
                 host = hp->h_name;                  host = hp->h_name;
                 remember_host(hp->h_addr_list);          else
         } else {  
                 host = inet_ntoa(raddrp->sin_addr);                  host = inet_ntoa(raddrp->sin_addr);
                 taddrs[0] = (char *)&raddrp->sin_addr;          if ((entry = add_host(host)) == NULL)
                 taddrs[1] = NULL;                  return(0);
                 remember_host(taddrs);  
           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 (!longopt)          if (!hflag && !iflag && !uflag) {
                 printf("%-*.*s ", HOST_WIDTH, HOST_WIDTH, host);                  print_entry(entry);
                   for (i = 0, ut = entry->users; i < entry->count; i++, ut++) {
         for (i = 0; i < up3->utmp_array_len; i++) {                          free(ut->ut_user);
                 /* NOTE: strncpy() used below for non-terminated strings. */                          free(ut->ut_line);
                 strncpy(user, up3->utmp_array_val[i].ut_user,                          free(ut->ut_host);
                     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(' ');  
                 }                  }
                   free(entry->users);
         }          }
         if (!longopt)  
                 putchar('\n');  
   
         return(0);          return(0);
 }  }
Line 366 
Line 358 
         if (hp == NULL)          if (hp == NULL)
                 errx(1, "unknown host \"%s\"", host);                  errx(1, "unknown host \"%s\"", host);
   
         /* try version 3 first */          /* Try version 3 first. */
         rusers_clnt = clnt_create(host, RUSERSPROG, RUSERSVERS_3, "udp");          rusers_clnt = clnt_create(host, RUSERSPROG, RUSERSVERS_3, "udp");
         if (rusers_clnt == NULL) {          if (rusers_clnt == NULL) {
                 clnt_pcreateerror(__progname);                  clnt_pcreateerror(__progname);
Line 391 
Line 383 
                 exit(1);                  exit(1);
         }          }
   
         /* fall back to version 2 */          /* Fall back to version 2. */
         rusers_clnt = clnt_create(host, RUSERSPROG, RUSERSVERS_IDLE, "udp");          rusers_clnt = clnt_create(host, RUSERSPROG, RUSERSVERS_IDLE, "udp");
         if (rusers_clnt == NULL) {          if (rusers_clnt == NULL) {
                 clnt_pcreateerror(__progname);                  clnt_pcreateerror(__progname);
Line 597 
Line 589 
                  */                   */
                 timeout.it_value.tv_sec = 5;                  timeout.it_value.tv_sec = 5;
                 timeout.it_value.tv_usec = 0;                  timeout.it_value.tv_usec = 0;
                 for (;;) {                  while (timerisset(&timeout.it_value)) {
                         FD_SET(sock[0], fds);                          FD_SET(sock[0], fds);
                         FD_SET(sock[1], fds);                          FD_SET(sock[1], fds);
                         setitimer(ITIMER_REAL, &timeout, NULL);                          setitimer(ITIMER_REAL, &timeout, NULL);
Line 639 
Line 631 
 }  }
   
 void  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)  alarmclock(int signo)
 {  {
   
         ;               /* just interupt */          ;               /* 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  void
 usage(void)  usage(void)
 {  {
   
         fprintf(stderr, "usage: %s [-la] [hosts ...]\n", __progname);          fprintf(stderr, "usage: %s [-al] [-h | -i | -u] [hosts ...]\n",
               __progname);
         exit(1);          exit(1);
 }  }

Legend:
Removed from v.1.17  
changed lines
  Added in v.1.18