]> git.saurik.com Git - apple/system_cmds.git/blobdiff - ac.tproj/ac.c
system_cmds-735.20.1.tar.gz
[apple/system_cmds.git] / ac.tproj / ac.c
index f23915c0a8696706062c08f36b79a16f89280719..00aaa06256b13f078879f336cc67a17d01137ec0 100644 (file)
@@ -1,8 +1,8 @@
 /*
- * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
+ * Copyright (c) 1999-2016 Apple Inc. All rights reserved.
  *
  * @APPLE_LICENSE_HEADER_START@
- * 
+ *
  * "Portions Copyright (c) 1999 Apple Computer, Inc.  All Rights
  * Reserved.  This file contains Original Code and/or Modifications of
  * Original Code as defined in and that are subject to the Apple Public
@@ -10,7 +10,7 @@
  * except in compliance with the License.  Please obtain a copy of the
  * License at http://www.apple.com/publicsource and read it before using
  * this file.
- * 
+ *
  * The Original Code and all software distributed under the License are
  * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
  * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
  * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT.  Please see the
  * License for the specific language governing rights and limitations
  * under the License."
- * 
+ *
  * @APPLE_LICENSE_HEADER_END@
  */
 /*
  *      Copyright (c) 1994 Christopher G. Demetriou.
  *      @(#)Copyright (c) 1994, Simon J. Gerraty.
- *      
+ *
  *      This is free software.  It comes with NO WARRANTY.
- *      Permission to use, modify and distribute this source code 
+ *      Permission to use, modify and distribute this source code
  *      is granted subject to the following conditions.
- *      1/ that the above copyright notice and this notice 
- *      are preserved in all copies and that due credit be given 
- *      to the author.  
- *      2/ that any changes to this code are clearly commented 
- *      as such so that the author does not get blamed for bugs 
+ *      1/ that the above copyright notice and this notice
+ *      are preserved in all copies and that due credit be given
+ *      to the author.
+ *      2/ that any changes to this code are clearly commented
+ *      as such so that the author does not get blamed for bugs
  *      other than his own.
  */
 
 #ifndef lint
-static char rcsid[] = "$Id: ac.c,v 1.1.1.2 2000/01/11 02:09:57 wsanchez Exp $";
+#include <sys/cdefs.h>
+__unused static char rcsid[] = "$Id: ac.c,v 1.2 2006/02/07 05:51:22 lindak Exp $";
 #endif
 
 #include <sys/types.h>
@@ -49,15 +50,17 @@ static char rcsid[] = "$Id: ac.c,v 1.1.1.2 2000/01/11 02:09:57 wsanchez Exp $";
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
-#include <utmp.h>
+#include <utmpx.h>
 #include <unistd.h>
 
+#define UT_NAMESIZE 8 /* from utmp.h; only for formatting */
+
 /*
  * this is for our list of currently logged in sessions
  */
 struct utmp_list {
        struct utmp_list *next;
-       struct utmp usr;
+       struct utmpx usr;
 };
 
 /*
@@ -65,7 +68,7 @@ struct utmp_list {
  */
 struct user_list {
        struct user_list *next;
-       char    name[UT_NAMESIZE+1];
+       char    name[_UTX_USERSIZE+1];
        time_t  secs;
 };
 
@@ -74,7 +77,7 @@ struct user_list {
  */
 struct tty_list {
        struct tty_list *next;
-       char    name[UT_LINESIZE+3];
+       char    name[_UTX_USERSIZE+3];
        int     len;
        int     ret;
 };
@@ -83,7 +86,7 @@ struct tty_list {
  * globals - yes yuk
  */
 #ifdef CONSOLE_TTY
-static char    *Console = CONSOLE_TTY;
+static char    *Console = CONSOLE_TTY;
 #endif
 static time_t  Total = 0;
 static time_t  FirstTime = 0;
@@ -104,12 +107,11 @@ static int Debug = 0;
 #endif
 
 int                    main __P((int, char **));
-int                    ac __P((FILE *));
+int                    ac __P((void));
 struct tty_list                *add_tty __P((char *));
 int                    do_tty __P((char *));
-FILE                   *file __P((char *));
-struct utmp_list       *log_in __P((struct utmp_list *, struct utmp *));
-struct utmp_list       *log_out __P((struct utmp_list *, struct utmp *));
+struct utmp_list       *log_in __P((struct utmp_list *, struct utmpx *));
+struct utmp_list       *log_out __P((struct utmp_list *, struct utmpx *));
 int                    on_console __P((struct utmp_list *));
 void                   show __P((char *, time_t));
 void                   show_today __P((struct user_list *, struct utmp_list *,
@@ -118,32 +120,14 @@ void                      show_users __P((struct user_list *));
 struct user_list       *update_user __P((struct user_list *, char *, time_t));
 void                   usage __P((void));
 
-/*
- * open wtmp or die
- */
-FILE *
-file(name)
-       char *name;
-{
-       FILE *fp;
-
-       if ((fp = fopen(name, "r")) == NULL)
-               err(1, "%s", name);
-       /* in case we want to discriminate */
-       if (strcmp(_PATH_WTMP, name))
-               Flags |= AC_W;
-       return fp;
-}
-
 struct tty_list *
-add_tty(name)
-       char *name;
+add_tty(char *name)
 {
        struct tty_list *tp;
        register char *rcp;
 
        Flags |= AC_T;
-       
+
        if ((tp = NEW(struct tty_list)) == NULL)
                err(1, "malloc");
        tp->len = 0;                            /* full match */
@@ -156,7 +140,7 @@ add_tty(name)
        tp->name[sizeof (tp->name) - 1] = '\0';
        if ((rcp = strchr(tp->name, '*')) != NULL) {    /* wild card */
                *rcp = '\0';
-               tp->len = strlen(tp->name);     /* match len bytes only */
+               tp->len = (int)strlen(tp->name);        /* match len bytes only */
        }
        tp->next = Ttys;
        Ttys = tp;
@@ -167,12 +151,11 @@ add_tty(name)
  * should we process the named tty?
  */
 int
-do_tty(name)
-       char *name;
+do_tty(char *name)
 {
        struct tty_list *tp;
        int def_ret = 0;
-       
+
        for (tp = Ttys; tp != NULL; tp = tp->next) {
                if (tp->ret == 0)               /* specific don't */
                        def_ret = 1;            /* default do */
@@ -192,8 +175,7 @@ do_tty(name)
  * is someone logged in on Console?
  */
 int
-on_console(head)
-       struct utmp_list *head;
+on_console(struct utmp_list *head)
 {
        struct utmp_list *up;
 
@@ -210,10 +192,7 @@ on_console(head)
  * update user's login time
  */
 struct user_list *
-update_user(head, name, secs)
-       struct user_list *head;
-       char    *name;
-       time_t  secs;
+update_user(struct user_list *head, char *name, time_t secs)
 {
        struct user_list *up;
 
@@ -229,7 +208,7 @@ update_user(head, name, secs)
         */
        if (Flags & AC_U)
                return head;
-       
+
        if ((up = NEW(struct user_list)) == NULL)
                err(1, "malloc");
        up->next = head;
@@ -241,9 +220,7 @@ update_user(head, name, secs)
 }
 
 int
-main(argc, argv)
-       int     argc;
-       char    **argv;
+main(int argc, char **argv)
 {
        FILE *fp;
        int c;
@@ -273,7 +250,7 @@ main(argc, argv)
                        add_tty(optarg);
                        break;
                case 'w':
-                       fp = file(optarg);
+                       wtmpxname(optarg);
                        break;
                case '?':
                default:
@@ -292,17 +269,8 @@ main(argc, argv)
        }
        if (Flags & AC_D)
                Flags &= ~AC_P;
-       if (fp == NULL) {
-               /*
-                * if _PATH_WTMP does not exist, exit quietly
-                */
-               if (access(_PATH_WTMP, 0) != 0 && errno == ENOENT)
-                       return 0;
-               
-               fp = file(_PATH_WTMP);
-       }
-       ac(fp);
-       
+       ac();
+
        return 0;
 }
 
@@ -310,17 +278,14 @@ main(argc, argv)
  * print login time in decimal hours
  */
 void
-show(name, secs)
-       char *name;
-       time_t secs;
+show(char *name, time_t secs)
 {
        (void)printf("\t%-*s %8.2f\n", UT_NAMESIZE, name,
            ((double)secs / 3600));
 }
 
 void
-show_users(list)
-       struct user_list *list;
+show_users(struct user_list *list)
 {
        struct user_list *lp;
 
@@ -332,10 +297,7 @@ show_users(list)
  * print total login time for 24hr period in decimal hours
  */
 void
-show_today(users, logins, secs)
-       struct user_list *users;
-       struct utmp_list *logins;
-       time_t secs;
+show_today(struct user_list *users, struct utmp_list *logins, time_t secs)
 {
        struct user_list *up;
        struct utmp_list *lp;
@@ -347,18 +309,18 @@ show_today(users, logins, secs)
 
        /* restore the missing second */
        yesterday++;
-       
+
        for (lp = logins; lp != NULL; lp = lp->next) {
-               secs = yesterday - lp->usr.ut_time;
-               Users = update_user(Users, lp->usr.ut_name, secs);
-               lp->usr.ut_time = yesterday;    /* as if they just logged in */
+               secs = yesterday - lp->usr.ut_tv.tv_sec;
+               Users = update_user(Users, lp->usr.ut_user, secs);
+               lp->usr.ut_tv.tv_sec = yesterday;       /* as if they just logged in */
        }
        secs = 0;
        for (up = users; up != NULL; up = up->next) {
                secs += up->secs;
                up->secs = 0;                   /* for next day */
        }
-       if (secs)
+       if (secs)
                (void)printf("%s %11.2f\n", date, ((double)secs / 3600));
 }
 
@@ -368,24 +330,22 @@ show_today(users, logins, secs)
  * been shut down.
  */
 struct utmp_list *
-log_out(head, up)
-       struct utmp_list *head;
-       struct utmp *up;
+log_out(struct utmp_list *head, struct utmpx *up)
 {
        struct utmp_list *lp, *lp2, *tlp;
        time_t secs;
-       
+
        for (lp = head, lp2 = NULL; lp != NULL; )
-               if (*up->ut_line == '~' || strncmp(lp->usr.ut_line, up->ut_line,
+               if (up->ut_type == BOOT_TIME || up->ut_type == SHUTDOWN_TIME || strncmp(lp->usr.ut_line, up->ut_line,
                    sizeof (up->ut_line)) == 0) {
-                       secs = up->ut_time - lp->usr.ut_time;
-                       Users = update_user(Users, lp->usr.ut_name, secs);
+                       secs = up->ut_tv.tv_sec - lp->usr.ut_tv.tv_sec;
+                       Users = update_user(Users, lp->usr.ut_user, secs);
 #ifdef DEBUG
                        if (Debug)
                                printf("%-.*s %-.*s: %-.*s logged out (%2d:%02d:%02d)\n",
-                                   19, ctime(&up->ut_time),
-                                   sizeof (lp->usr.ut_line), lp->usr.ut_line,
-                                   sizeof (lp->usr.ut_name), lp->usr.ut_name,
+                                   19, ctime(&up->ut_tv.tv_sec),
+                                   (int)sizeof (lp->usr.ut_line), lp->usr.ut_line,
+                                   (int)sizeof (lp->usr.ut_user), lp->usr.ut_user,
                                    secs / 3600, (secs % 3600) / 60, secs % 60);
 #endif
                        /*
@@ -410,9 +370,7 @@ log_out(head, up)
  * if do_tty says ok, login a user
  */
 struct utmp_list *
-log_in(head, up)
-       struct utmp_list *head;
-       struct utmp *up;
+log_in(struct utmp_list *head, struct utmpx *up)
 {
        struct utmp_list *lp;
 
@@ -431,15 +389,15 @@ log_in(head, up)
        if (up->ut_host[0] == ':') {
                /*
                 * SunOS 4.0.2 does not treat ":0.0" as special but we
-                * do. 
+                * do.
                 */
                if (on_console(head))
                        return head;
                /*
                 * ok, no recorded login, so they were here when wtmp
-                * started!  Adjust ut_time! 
+                * started!  Adjust ut_tv.tv_sec!
                 */
-               up->ut_time = FirstTime;
+               up->ut_tv.tv_sec = FirstTime;
                /*
                 * this allows us to pick the right logout
                 */
@@ -462,14 +420,14 @@ log_in(head, up)
                err(1, "malloc");
        lp->next = head;
        head = lp;
-       memmove((char *)&lp->usr, (char *)up, sizeof (struct utmp));
+       memmove((char *)&lp->usr, (char *)up, sizeof (struct utmpx));
 #ifdef DEBUG
        if (Debug) {
                printf("%-.*s %-.*s: %-.*s logged in", 19,
-                   ctime(&lp->usr.ut_time), sizeof (up->ut_line),
-                      up->ut_line, sizeof (up->ut_name), up->ut_name);
+                   ctime(&lp->usr.ut_tv.tv_sec), (int)sizeof (up->ut_line),
+                      up->ut_line, (int)sizeof (up->ut_user), up->ut_user);
                if (*up->ut_host)
-                       printf(" (%-.*s)", sizeof (up->ut_host), up->ut_host);
+                       printf(" (%-.*s)", (int)sizeof (up->ut_host), up->ut_host);
                putchar('\n');
        }
 #endif
@@ -477,26 +435,26 @@ log_in(head, up)
 }
 
 int
-ac(fp)
-       FILE    *fp;
+ac(void)
 {
        struct utmp_list *lp, *head = NULL;
-       struct utmp usr;
+       struct utmpx *u, end;
        struct tm *ltm;
        time_t secs = 0;
        int day = -1;
-       
-       while (fread((char *)&usr, sizeof(usr), 1, fp) == 1) {
+
+       setutxent_wtmp(1); /* read in forward direction */
+       while ((u = getutxent_wtmp()) != NULL) {
                if (!FirstTime)
-                       FirstTime = usr.ut_time;
+                       FirstTime = u->ut_tv.tv_sec;
                if (Flags & AC_D) {
-                       ltm = localtime(&usr.ut_time);
+                       ltm = localtime(&u->ut_tv.tv_sec);
                        if (day >= 0 && day != ltm->tm_yday) {
                                day = ltm->tm_yday;
                                /*
                                 * print yesterday's total
                                 */
-                               secs = usr.ut_time;
+                               secs = u->ut_tv.tv_sec;
                                secs -= ltm->tm_sec;
                                secs -= 60 * ltm->tm_min;
                                secs -= 3600 * ltm->tm_hour;
@@ -504,48 +462,50 @@ ac(fp)
                        } else
                                day = ltm->tm_yday;
                }
-               switch(*usr.ut_line) {
-               case '|':
-                       secs = usr.ut_time;
+               switch(u->ut_type) {
+               case OLD_TIME:
+                       secs = u->ut_tv.tv_sec;
                        break;
-               case '{':
-                       secs -= usr.ut_time;
+               case NEW_TIME:
+                       secs -= u->ut_tv.tv_sec;
                        /*
                         * adjust time for those logged in
                         */
                        for (lp = head; lp != NULL; lp = lp->next)
-                               lp->usr.ut_time -= secs;
+                               lp->usr.ut_tv.tv_sec -= secs;
                        break;
-               case '~':                       /* reboot or shutdown */
-                       head = log_out(head, &usr);
-                       FirstTime = usr.ut_time; /* shouldn't be needed */
+               case BOOT_TIME:                 /* reboot or shutdown */
+               case SHUTDOWN_TIME:
+                       head = log_out(head, u);
+                       FirstTime = u->ut_tv.tv_sec; /* shouldn't be needed */
                        break;
-               default:
+               case USER_PROCESS:
                        /*
                         * if they came in on tty[p-y]*, then it is only
                         * a login session if the ut_host field is non-empty
                         */
-                       if (*usr.ut_name) {
-                               if (strncmp(usr.ut_line, "tty", 3) != 0 ||
-                                   strchr("pqrstuvwxy", usr.ut_line[3]) == 0 ||
-                                   *usr.ut_host != '\0')
-                                       head = log_in(head, &usr);
-                       } else
-                               head = log_out(head, &usr);
+                       if (strncmp(u->ut_line, "tty", 3) != 0 ||
+                           strchr("pqrstuvwxy", u->ut_line[3]) == 0 ||
+                           *u->ut_host != '\0')
+                               head = log_in(head, u);
+                       break;
+               case DEAD_PROCESS:
+                       head = log_out(head, u);
                        break;
                }
        }
-       (void)fclose(fp);
-       usr.ut_time = time((time_t *)0);
-       (void)strcpy(usr.ut_line, "~");
-       
+       endutxent_wtmp();
+       bzero(&end, sizeof(end));
+       end.ut_tv.tv_sec = time((time_t *)0);
+       end.ut_type = SHUTDOWN_TIME;
+
        if (Flags & AC_D) {
-               ltm = localtime(&usr.ut_time);
+               ltm = localtime(&end.ut_tv.tv_sec);
                if (day >= 0 && day != ltm->tm_yday) {
                        /*
                         * print yesterday's total
                         */
-                       secs = usr.ut_time;
+                       secs = end.ut_tv.tv_sec;
                        secs -= ltm->tm_sec;
                        secs -= 60 * ltm->tm_min;
                        secs -= 3600 * ltm->tm_hour;
@@ -555,7 +515,7 @@ ac(fp)
        /*
         * anyone still logged in gets time up to now
         */
-       head = log_out(head, &usr);
+       head = log_out(head, &end);
 
        if (Flags & AC_D)
                show_today(Users, head, time((time_t *)0));
@@ -568,7 +528,7 @@ ac(fp)
 }
 
 void
-usage()
+usage(void)
 {
        (void)fprintf(stderr,
 #ifdef CONSOLE_TTY