BSD 4_3_Reno release
[unix-history] / usr / src / usr.bin / who / who.c
index 44a4bbd..6d56161 100644 (file)
 /*
 /*
- * Copyright (c) 1980 Regents of the University of California.
- * All rights reserved.  The Berkeley software License Agreement
- * specifies the terms and conditions for redistribution.
+ * Copyright (c) 1989 The Regents of the University of California.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Michael Fischbein.
+ *
+ * Redistribution and use in source and binary forms are permitted provided
+ * that: (1) source distributions retain this entire copyright notice and
+ * comment, and (2) distributions including binaries display the following
+ * acknowledgement:  ``This product includes software developed by the
+ * University of California, Berkeley and its contributors'' in the
+ * documentation or other materials provided with the distribution and in
+ * all advertising materials mentioning features or use of this software.
+ * Neither the name of the University nor the names of its contributors may
+ * be used to endorse or promote products derived from this software without
+ * specific prior written permission.
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
  */
 
 #ifndef lint
 char copyright[] =
  */
 
 #ifndef lint
 char copyright[] =
-"@(#) Copyright (c) 1980 Regents of the University of California.\n\
+"@(#) Copyright (c) 1989 The Regents of the University of California.\n\
  All rights reserved.\n";
  All rights reserved.\n";
-#endif not lint
+#endif /* not lint */
 
 #ifndef lint
 
 #ifndef lint
-static char sccsid[] = "@(#)who.c      5.2 (Berkeley) %G%";
-#endif not lint
+static char sccsid[] = "@(#)who.c      5.11 (Berkeley) 6/1/90";
+#endif /* not lint */
 
 
-/*
- * who
- */
-
-#include <sys/param.h>
-#include <utmp.h>
+#include <sys/types.h>
+#include <sys/file.h>
+#include <sys/time.h>
 #include <pwd.h>
 #include <pwd.h>
+#include <utmp.h>
 #include <stdio.h>
 #include <stdio.h>
-#include <strings.h>
-#include <ctype.h>
-
-#define NMAX   sizeof(utmp.ut_name)
-#define LMAX   sizeof(utmp.ut_line)
-#define HMAX   sizeof(utmp.ut_host)
 
 
-static struct utmp     utmp;           /* read buffer */
-
-main(argc,argv)
-int    argc;
-char   **argv;
+main(argc, argv)
+       int argc;
+       char **argv;
 {
 {
-       register FILE   *fp;                    /* utmp file pointer */
-       register char   *tp,                    /* tty name */
-                       *fname;                 /* utmp file name */
-       struct passwd   *pw,                    /* user passwd structure */
-                       *getpwuid();
-       char    hostname[MAXHOSTNAMELEN],       /* host name */
-               *ttyname();
-       uid_t   getuid();
-       long    time();
+       register char *p;
+       struct utmp usr;
+       struct passwd *pw;
+       FILE *ufp, *file();
+       char *t, *rindex(), *strcpy(), *strncpy(), *ttyname();
+       time_t time();
 
 
-       switch(argc) {
-               case 2:
-                       fname = argv[1];
-                       break;
-               case 3:
-                       if (!(tp = ttyname(0))) {
-                               /*
-                                * no tty -- use best guess from passwd file.
-                                * next line is a kludge, but as of now getuid
-                                * returns a "uid_t" and getpwuid takes an int.
-                                */
-                               pw = getpwuid((int)getuid());
-                               strncpy(utmp.ut_name,pw ? pw->pw_name : "?",NMAX);
-                               strcpy(utmp.ut_line,"tty??");
-                               time(&utmp.ut_time);
-                               putline();
-                               exit(0);
-                       }
-                       tp = rindex(tp,'/') + 1;
-                       if (gethostname(hostname,sizeof(hostname)) == -1) {
-                               perror("gethostname");
-                               exit(1);
-                       }
-               case 1:
-                       fname = "/etc/utmp";
-                       break;
-               default:
-                       fputs("usage: who [ utmp_file ]\nor who am i\n",stderr);
-                       exit(1);
-       }
-       if (!(fp = fopen(fname,"r"))) {
-               perror(fname);
+       switch (argc) {
+       case 1:                                 /* who */
+               ufp = file(_PATH_UTMP);
+               /* only entries with both name and line fields */
+               while (fread((char *)&usr, sizeof(usr), 1, ufp) == 1)
+                       if (*usr.ut_name && *usr.ut_line)
+                               output(&usr);
+               break;
+       case 2:                                 /* who utmp_file */
+               ufp = file(argv[1]);
+               /* all entries */
+               while (fread((char *)&usr, sizeof(usr), 1, ufp) == 1)
+                       output(&usr);
+               break;
+       case 3:                                 /* who am i */
+               ufp = file(_PATH_UTMP);
+
+               /* search through the utmp and find an entry for this tty */
+               if (p = ttyname(0)) {
+                       /* strip any directory component */
+                       if (t = rindex(p, '/'))
+                               p = t + 1;
+                       while (fread((char *)&usr, sizeof(usr), 1, ufp) == 1)
+                               if (usr.ut_name && !strcmp(usr.ut_line, p)) {
+                                       output(&usr);
+                                       exit(0);
+                               }
+                       /* well, at least we know what the tty is */
+                       (void)strncpy(usr.ut_line, p, UT_LINESIZE);
+               } else
+                       (void)strcpy(usr.ut_line, "tty??");
+               pw = getpwuid(getuid());
+               (void)strncpy(usr.ut_name, pw ? pw->pw_name : "?", UT_NAMESIZE);
+               (void)time(&usr.ut_time);
+               *usr.ut_host = '\0';
+               output(&usr);
+               break;
+       default:
+               (void)fprintf(stderr, "usage: who [ file ]\n       who am i\n");
                exit(1);
        }
                exit(1);
        }
-       while (fread((char *)&utmp,sizeof(utmp),1,fp) == 1)
-               if (argc == 3) {
-                       if (!strcmp(utmp.ut_line,tp)) {
-                               printf("%s!",hostname);
-                               putline();
-                               exit(0);
-                       }
-               }
-               else if (argc != 1 || *utmp.ut_name)
-                       putline();
+       exit(0);
 }
 
 }
 
-putline()
+output(up)
+       struct utmp *up;
 {
 {
-       register char   *cbuf;
-       char    *ctime();
+       char *ctime();
+
+       (void)printf("%-*.*s %-*.*s", UT_NAMESIZE, UT_NAMESIZE, up->ut_name,
+           UT_LINESIZE, UT_LINESIZE, up->ut_line);
+       (void)printf("%.12s", ctime(&up->ut_time) + 4);
+       if (*up->ut_host)
+               printf("\t(%.*s)", UT_HOSTSIZE, up->ut_host);
+       (void)putchar('\n');
+}
 
 
-       cbuf = ctime(&utmp.ut_time) + 4;
-       printf("%-*.*s %-*.*s%.12s",NMAX,NMAX,utmp.ut_name,LMAX,LMAX,utmp.ut_line,cbuf);
-       if (*utmp.ut_host)
-               printf("\t(%.*s)",HMAX,utmp.ut_host);
-       putchar('\n');
+FILE *
+file(name)
+       char *name;
+{
+       extern int errno;
+       FILE *ufp;
+       char *strerror();
+
+       if (!(ufp = fopen(name, "r"))) {
+               (void)fprintf(stderr, "who: %s: %s.\n", name, strerror(errno));
+               exit(1);
+       }
+       return(ufp);
 }
 }