386BSD 0.0 development
authorWilliam F. Jolitz <wjolitz@soda.berkeley.edu>
Fri, 26 Apr 1991 22:19:04 +0000 (14:19 -0800)
committerWilliam F. Jolitz <wjolitz@soda.berkeley.edu>
Fri, 26 Apr 1991 22:19:04 +0000 (14:19 -0800)
Work on file usr/src/usr.bin/wc/wc.c
Work on file usr/src/usr.bin/what/what.1
Work on file usr/src/usr.bin/what/what.c
Work on file usr/src/usr.bin/who/who.1
Work on file usr/src/usr.bin/who/who.c

Co-Authored-By: Lynne Greer Jolitz <ljolitz@cardio.ucsf.edu>
Synthesized-from: 386BSD-0.0/src

usr/src/usr.bin/wc/wc.c [new file with mode: 0644]
usr/src/usr.bin/what/what.1 [new file with mode: 0644]
usr/src/usr.bin/what/what.c [new file with mode: 0644]
usr/src/usr.bin/who/who.1 [new file with mode: 0644]
usr/src/usr.bin/who/who.c [new file with mode: 0644]

diff --git a/usr/src/usr.bin/wc/wc.c b/usr/src/usr.bin/wc/wc.c
new file mode 100644 (file)
index 0000000..99b79ab
--- /dev/null
@@ -0,0 +1,246 @@
+/*
+ * Copyright (c) 1980, 1987 Regents of the University of California.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *     This product includes software developed by the University of
+ *     California, Berkeley and its contributors.
+ * 4. 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 BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef lint
+char copyright[] =
+"@(#) Copyright (c) 1980, 1987 Regents of the University of California.\n\
+ All rights reserved.\n";
+#endif /* not lint */
+
+#ifndef lint
+static char sccsid[] = "@(#)wc.c       5.7 (Berkeley) 3/2/91";
+#endif /* not lint */
+
+/* wc line, word and char count */
+
+#include <sys/param.h>
+#include <sys/stat.h>
+#include <sys/file.h>
+#include <stdio.h>
+
+#define DEL    0177                    /* del char */
+#define NL     012                     /* newline char */
+#define SPACE  040                     /* space char */
+#define TAB    011                     /* tab char */
+
+static long    tlinect, twordct, tcharct;
+static int     doline, doword, dochar;
+
+main(argc, argv)
+       int argc;
+       char **argv;
+{
+       extern int optind;
+       register int ch;
+       int total;
+
+       /*
+        * wc is unusual in that its flags are on by default, so,
+        * if you don't get any arguments, you have to turn them
+        * all on.
+        */
+       if (argc > 1 && argv[1][0] == '-' && argv[1][1]) {
+               while ((ch = getopt(argc, argv, "lwc")) != EOF)
+                       switch((char)ch) {
+                       case 'l':
+                               doline = 1;
+                               break;
+                       case 'w':
+                               doword = 1;
+                               break;
+                       case 'c':
+                               dochar = 1;
+                               break;
+                       case '?':
+                       default:
+                               fputs("usage: wc [-lwc] [files]\n", stderr);
+                               exit(1);
+                       }
+               argv += optind;
+               argc -= optind;
+       }
+       else {
+               ++argv;
+               --argc;
+               doline = doword = dochar = 1;
+       }
+
+       total = 0;
+       if (!*argv) {
+               cnt((char *)NULL);
+               putchar('\n');
+       }
+       else do {
+               cnt(*argv);
+               printf(" %s\n", *argv);
+               ++total;
+       } while(*++argv);
+
+       if (total > 1) {
+               if (doline)
+                       printf(" %7ld", tlinect);
+               if (doword)
+                       printf(" %7ld", twordct);
+               if (dochar)
+                       printf(" %7ld", tcharct);
+               puts(" total");
+       }
+       exit(0);
+}
+
+cnt(file)
+       char *file;
+{
+       register u_char *C;
+       register short gotsp;
+       register int len;
+       register long linect, wordct, charct;
+       struct stat sbuf;
+       int fd;
+       u_char buf[MAXBSIZE];
+
+       linect = wordct = charct = 0;
+       if (file) {
+               if ((fd = open(file, O_RDONLY, 0)) < 0) {
+                       perror(file);
+                       exit(1);
+               }
+               if (!doword) {
+                       /*
+                        * line counting is split out because it's a lot
+                        * faster to get lines than to get words, since
+                        * the word count requires some logic.
+                        */
+                       if (doline) {
+                               while(len = read(fd, buf, MAXBSIZE)) {
+                                       if (len == -1) {
+                                               perror(file);
+                                               exit(1);
+                                       }
+                                       charct += len;
+                                       for (C = buf; len--; ++C)
+                                               if (*C == '\n')
+                                                       ++linect;
+                               }
+                               tlinect += linect;
+                               printf(" %7ld", linect);
+                               if (dochar) {
+                                       tcharct += charct;
+                                       printf(" %7ld", charct);
+                               }
+                               close(fd);
+                               return;
+                       }
+                       /*
+                        * if all we need is the number of characters and
+                        * it's a directory or a regular or linked file, just
+                        * stat the puppy.  We avoid testing for it not being
+                        * a special device in case someone adds a new type
+                        * of inode.
+                        */
+                       if (dochar) {
+                               if (fstat(fd, &sbuf)) {
+                                       perror(file);
+                                       exit(1);
+                               }
+                               if (sbuf.st_mode & (S_IFREG | S_IFLNK | S_IFDIR)) {
+                                       printf(" %7ld", sbuf.st_size);
+                                       tcharct += sbuf.st_size;
+                                       close(fd);
+                                       return;
+                               }
+                       }
+               }
+       }
+       else
+               fd = 0;
+       /* do it the hard way... */
+       for (gotsp = 1; len = read(fd, buf, MAXBSIZE);) {
+               if (len == -1) {
+                       perror(file);
+                       exit(1);
+               }
+               charct += len;
+               for (C = buf; len--; ++C)
+                       switch(*C) {
+                               case NL:
+                                       ++linect;
+                               case TAB:
+                               case SPACE:
+                                       gotsp = 1;
+                                       continue;
+                               default:
+#ifdef notdef
+                                       /*
+                                        * This line of code implements the
+                                        * original V7 wc algorithm, i.e.
+                                        * a non-printing character doesn't
+                                        * toggle the "word" count, so that
+                                        * "  ^D^F  " counts as 6 spaces,
+                                        * while "foo^D^Fbar" counts as 8
+                                        * characters.
+                                        *
+                                        * test order is important -- gotsp
+                                        * will normally be NO, so test it
+                                        * first
+                                        */
+                                       if (gotsp && *C > SPACE && *C < DEL) {
+#endif
+                                       /*
+                                        * This line implements the manual
+                                        * page, i.e. a word is a "maximal
+                                        * string of characters delimited by
+                                        * spaces, tabs or newlines."  Notice
+                                        * nothing was said about a character
+                                        * being printing or non-printing.
+                                        */
+                                       if (gotsp) {
+                                               gotsp = 0;
+                                               ++wordct;
+                                       }
+                       }
+       }
+       if (doline) {
+               tlinect += linect;
+               printf(" %7ld", linect);
+       }
+       if (doword) {
+               twordct += wordct;
+               printf(" %7ld", wordct);
+       }
+       if (dochar) {
+               tcharct += charct;
+               printf(" %7ld", charct);
+       }
+       close(fd);
+}
diff --git a/usr/src/usr.bin/what/what.1 b/usr/src/usr.bin/what/what.1
new file mode 100644 (file)
index 0000000..05de04a
--- /dev/null
@@ -0,0 +1,68 @@
+.\" Copyright (c) 1980, 1991 Regents of the University of California.
+.\" All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\"    notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\"    notice, this list of conditions and the following disclaimer in the
+.\"    documentation and/or other materials provided with the distribution.
+.\" 3. All advertising materials mentioning features or use of this software
+.\"    must display the following acknowledgement:
+.\"    This product includes software developed by the University of
+.\"    California, Berkeley and its contributors.
+.\" 4. 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 BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\"     @(#)what.1     6.4 (Berkeley) 4/23/91
+.\"
+.Dd April 23, 1991
+.Dt WHAT 1
+.Os BSD 4
+.Sh NAME
+.Nm what
+.Nd "show what versions of object modules were used to construct a file"
+.Sh SYNOPSIS
+.Nm what
+.Ar name Ar ...
+.Sh DESCRIPTION
+.Nm What
+reads each file
+.Ar name
+and searches for sequences of the form
+.Dq \&@(#)
+as inserted by the source code control system.  It prints the remainder
+of the string following this marker, up to a null character, newline, double
+quote, or
+.Dq \&> character.
+.Sh BUGS
+As
+.Bx
+is not licensed to distribute
+.Tn SCCS
+this is a rewrite of the
+.Nm what
+command which is part of
+.Tn SCCS ,
+and may not behave exactly the same as that
+command does.
+.Sh HISTORY
+The
+.Nm
+command appeared in
+.Bx 4.0 .
diff --git a/usr/src/usr.bin/what/what.c b/usr/src/usr.bin/what/what.c
new file mode 100644 (file)
index 0000000..a893d22
--- /dev/null
@@ -0,0 +1,86 @@
+/*
+ * Copyright (c) 1980, 1988 Regents of the University of California.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *     This product includes software developed by the University of
+ *     California, Berkeley and its contributors.
+ * 4. 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 BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef lint
+char copyright[] =
+"@(#) Copyright (c) 1980, 1988 Regents of the University of California.\n\
+ All rights reserved.\n";
+#endif /* not lint */
+
+#ifndef lint
+static char sccsid[] = "@(#)what.c     5.5 (Berkeley) 3/2/91";
+#endif /* not lint */
+
+#include <stdio.h>
+
+/*
+ * what
+ */
+/* ARGSUSED */
+main(argc, argv)
+       int argc;
+       char **argv;
+{
+       if (!*++argv) 
+               search();
+       else do {
+               if (!freopen(*argv, "r", stdin)) {
+                       perror(*argv);
+                       exit(1);
+               }
+               printf("%s\n", *argv);
+               search();
+       } while(*++argv);
+       exit(0);
+}
+
+search()
+{
+       register int c;
+
+       while ((c = getchar()) != EOF) {
+loop:          if (c != '@')
+                       continue;
+               if ((c = getchar()) != '(')
+                       goto loop;
+               if ((c = getchar()) != '#')
+                       goto loop;
+               if ((c = getchar()) != ')')
+                       goto loop;
+               putchar('\t');
+               while ((c = getchar()) != EOF && c && c != '"' &&
+                   c != '>' && c != '\n')
+                       putchar(c);
+               putchar('\n');
+       }
+}
diff --git a/usr/src/usr.bin/who/who.1 b/usr/src/usr.bin/who/who.1
new file mode 100644 (file)
index 0000000..9d9ab88
--- /dev/null
@@ -0,0 +1,105 @@
+.\" Copyright (c) 1986, 1991 Regents of the University of California.
+.\" All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\"    notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\"    notice, this list of conditions and the following disclaimer in the
+.\"    documentation and/or other materials provided with the distribution.
+.\" 3. All advertising materials mentioning features or use of this software
+.\"    must display the following acknowledgement:
+.\"    This product includes software developed by the University of
+.\"    California, Berkeley and its contributors.
+.\" 4. 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 BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\"     @(#)who.1      6.5 (Berkeley) 4/23/91
+.\"
+.Dd April 23, 1991
+.Dt WHO 1
+.Os
+.Sh NAME
+.Nm who
+.Nd display who is logged in
+.Sh SYNOPSIS
+.Nm who
+.Op Ar am I
+.Op Ar file 
+.Sh DESCRIPTION
+The utility
+.Nm who
+displays
+a list of all users currently logged on, showing for each user
+the login name,
+tty name, the date and time of login, and hostname if not local.
+.Pp
+Available options:
+.Pp
+.Bl -tag -width file
+.It Ar \&am I
+Returns the invoker's real user name. 
+.It Ar file
+By default,
+.Nm who
+gathers information from the file
+.Pa /var/run/utmp .
+An alternate
+.Ar file
+may be specified which is usually
+.Pa /var/run/wtmp
+(or
+.Pa /var/run/wtmp.[0-6]
+depending on site policy as
+.Pa wtmp
+can grow quite large and daily versions may or may not
+kept around after compression by
+.Xr ac 8 ) .
+The
+.Pa wtmp
+file contains a record of every login, logout,
+crash, shutdown and date change
+since
+.Pa wtmp
+was last truncated or
+created.
+.El
+.Pp
+If
+.Pa /var/log/wtmp
+is being used as the file, the user name may be empty
+or one of the special characters '|', '}' and '~'.  Logouts produce
+an output line without any user name.  For more information on the
+special characters, see
+.Xr utmp 5 .
+.Sh FILES
+.Bl -tag -width /var/log/wtmp.[0-6] -compact
+.It Pa /var/run/utmp
+.It Pa /var/log/wtmp
+.It Pa /var/log/wtmp.[0-6]
+.El
+.Sh SEE ALSO
+.Xr last 1 ,
+.Xr users 1 ,
+.Xr getuid 2 ,
+.Xr utmp 5
+.Sh HISTORY
+A
+.Nm
+command appeared in
+.At v6 .
diff --git a/usr/src/usr.bin/who/who.c b/usr/src/usr.bin/who/who.c
new file mode 100644 (file)
index 0000000..9b6c43d
--- /dev/null
@@ -0,0 +1,135 @@
+/*
+ * 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, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *     This product includes software developed by the University of
+ *     California, Berkeley and its contributors.
+ * 4. 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 BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef lint
+char copyright[] =
+"@(#) Copyright (c) 1989 The Regents of the University of California.\n\
+ All rights reserved.\n";
+#endif /* not lint */
+
+#ifndef lint
+static char sccsid[] = "@(#)who.c      5.11 (Berkeley) 6/1/90";
+#endif /* not lint */
+
+#include <sys/types.h>
+#include <sys/file.h>
+#include <sys/time.h>
+#include <pwd.h>
+#include <utmp.h>
+#include <stdio.h>
+
+main(argc, argv)
+       int argc;
+       char **argv;
+{
+       register char *p;
+       struct utmp usr;
+       struct passwd *pw;
+       FILE *ufp, *file();
+       char *t, *rindex(), *strcpy(), *strncpy(), *ttyname();
+       time_t time();
+
+       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(0);
+}
+
+output(up)
+       struct utmp *up;
+{
+       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');
+}
+
+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);
+}