]> git.saurik.com Git - apple/system_cmds.git/blobdiff - sa.tproj/usrdb.c
system_cmds-496.tar.gz
[apple/system_cmds.git] / sa.tproj / usrdb.c
index dda96ae80b450c252493bb5ca516e6f2525279da..277987ae4fadf780bd06d9a5fe82e0f0d4f76178 100644 (file)
  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  */
 
  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  */
 
-#ifndef lint
-static const char rcsid[] =
-  "$FreeBSD: src/usr.sbin/sa/usrdb.c,v 1.12 2002/07/15 16:05:15 des Exp $";
-#endif /* not lint */
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD: src/usr.sbin/sa/usrdb.c,v 1.16 2007/05/22 06:51:38 dds Exp $");
 
 #include <sys/param.h>
 #include <sys/types.h>
 
 #include <sys/param.h>
 #include <sys/types.h>
@@ -47,87 +45,81 @@ static const char rcsid[] =
 #include "extern.h"
 #include "pathnames.h"
 
 #include "extern.h"
 #include "pathnames.h"
 
-static int uid_compare __P((const DBT *, const DBT *));
+static int uid_compare(const DBT *, const DBT *);
 
 static DB      *usracct_db;
 
 
 static DB      *usracct_db;
 
+/* Legacy format in AHZV1 units. */
+struct userinfov1 {
+       uid_t           ui_uid;                 /* user id; for consistency */
+       u_quad_t        ui_calls;               /* number of invocations */
+       u_quad_t        ui_utime;               /* user time */
+       u_quad_t        ui_stime;               /* system time */
+       u_quad_t        ui_mem;                 /* memory use */
+       u_quad_t        ui_io;                  /* number of disk i/o ops */
+};
+
+/*
+ * Convert a v1 data record into the current version.
+ * Return 0 if OK, -1 on error, setting errno.
+ */
+static int
+v1_to_v2(DBT *key, DBT *data)
+{
+       struct userinfov1 uiv1;
+       static struct userinfo uiv2;
+       static uid_t uid;
+
+       if (key->size != sizeof(u_long) || data->size != sizeof(uiv1)) {
+               errno = EFTYPE;
+               return (-1);
+       }
+
+       /* Convert key. */
+       key->size = sizeof(uid_t);
+       uid = (uid_t)*(u_long *)(key->data);
+       key->data = &uid;
+
+       /* Convert data. */
+       memcpy(&uiv1, data->data, data->size);
+       memset(&uiv2, 0, sizeof(uiv2));
+       uiv2.ui_uid = uiv1.ui_uid;
+       uiv2.ui_calls = uiv1.ui_calls;
+       uiv2.ui_utime = ((double)uiv1.ui_utime / AHZV1) * 1000000;
+       uiv2.ui_stime = ((double)uiv1.ui_stime / AHZV1) * 1000000;
+       uiv2.ui_mem = uiv1.ui_mem;
+       uiv2.ui_io = uiv1.ui_io;
+       data->size = sizeof(uiv2);
+       data->data = &uiv2;
+
+       return (0);
+}
+
+/* Copy usrdb_file to in-memory usracct_db. */
 int
 usracct_init()
 {
 int
 usracct_init()
 {
-       DB *saved_usracct_db;
        BTREEINFO bti;
        BTREEINFO bti;
-       int error;
 
        bzero(&bti, sizeof bti);
        bti.compare = uid_compare;
 
 
        bzero(&bti, sizeof bti);
        bti.compare = uid_compare;
 
-       usracct_db = dbopen(NULL, O_RDWR, 0, DB_BTREE, &bti);
-       if (usracct_db == NULL)
-               return (-1);
-
-       error = 0;
-       if (!iflag) {
-               DBT key, data;
-               int serr, nerr;
-
-               saved_usracct_db = dbopen(_PATH_USRACCT, O_RDONLY, 0, DB_BTREE,
-                   &bti);
-               if (saved_usracct_db == NULL) {
-                       error = (errno == ENOENT) ? 0 : -1;
-                       if (error)
-                               warn("retrieving user accounting summary");
-                       goto out;
-               }
-
-               serr = DB_SEQ(saved_usracct_db, &key, &data, R_FIRST);
-               if (serr < 0) {
-                       warn("retrieving user accounting summary");
-                       error = -1;
-                       goto closeout;
-               }
-               while (serr == 0) {
-                       nerr = DB_PUT(usracct_db, &key, &data, 0);
-                       if (nerr < 0) {
-                               warn("initializing user accounting stats");
-                               error = -1;
-                               break;
-                       }
-
-                       serr = DB_SEQ(saved_usracct_db, &key, &data, R_NEXT);
-                       if (serr < 0) {
-                               warn("retrieving user accounting summary");
-                               error = -1;
-                               break;
-                       }
-               }
-
-closeout:
-               if (DB_CLOSE(saved_usracct_db) < 0) {
-                       warn("closing user accounting summary");
-                       error = -1;
-               }
-       }
-
-out:
-       if (error != 0)
-               usracct_destroy();
-       return (error);
+       return (db_copy_in(&usracct_db, usrdb_file, "user accounting",
+           &bti, v1_to_v2));
 }
 
 void
 usracct_destroy()
 {
 }
 
 void
 usracct_destroy()
 {
-       if (DB_CLOSE(usracct_db) < 0)
-               warn("destroying user accounting stats");
+       db_destroy(usracct_db, "user accounting");
 }
 
 int
 }
 
 int
-usracct_add(ci)
-       const struct cmdinfo *ci;
+usracct_add(const struct cmdinfo *ci)
 {
        DBT key, data;
        struct userinfo newui;
 {
        DBT key, data;
        struct userinfo newui;
-       u_long uid;
+       uid_t uid;
        int rv;
 
        uid = ci->ci_uid;
        int rv;
 
        uid = ci->ci_uid;
@@ -136,13 +128,13 @@ usracct_add(ci)
 
        rv = DB_GET(usracct_db, &key, &data, 0);
        if (rv < 0) {
 
        rv = DB_GET(usracct_db, &key, &data, 0);
        if (rv < 0) {
-               warn("get key %lu from user accounting stats", uid);
+               warn("get key %u from user accounting stats", uid);
                return (-1);
        } else if (rv == 0) {   /* it's there; copy whole thing */
                /* add the old data to the new data */
                bcopy(data.data, &newui, data.size);
                if (newui.ui_uid != uid) {
                return (-1);
        } else if (rv == 0) {   /* it's there; copy whole thing */
                /* add the old data to the new data */
                bcopy(data.data, &newui, data.size);
                if (newui.ui_uid != uid) {
-                       warnx("key %lu != expected record number %lu",
+                       warnx("key %u != expected record number %u",
                            newui.ui_uid, uid);
                        warnx("inconsistent user accounting stats");
                        return (-1);
                            newui.ui_uid, uid);
                        warnx("inconsistent user accounting stats");
                        return (-1);
@@ -162,7 +154,7 @@ usracct_add(ci)
        data.size = sizeof newui;
        rv = DB_PUT(usracct_db, &key, &data, 0);
        if (rv < 0) {
        data.size = sizeof newui;
        rv = DB_PUT(usracct_db, &key, &data, 0);
        if (rv < 0) {
-               warn("add key %lu to user accounting stats", uid);
+               warn("add key %u to user accounting stats", uid);
                return (-1);
        } else if (rv != 0) {
                warnx("DB_PUT returned 1");
                return (-1);
        } else if (rv != 0) {
                warnx("DB_PUT returned 1");
@@ -172,56 +164,17 @@ usracct_add(ci)
        return (0);
 }
 
        return (0);
 }
 
+/* Copy in-memory usracct_db to usrdb_file. */
 int
 usracct_update()
 {
 int
 usracct_update()
 {
-       DB *saved_usracct_db;
-       DBT key, data;
        BTREEINFO bti;
        BTREEINFO bti;
-       int error, serr, nerr;
 
        bzero(&bti, sizeof bti);
        bti.compare = uid_compare;
 
 
        bzero(&bti, sizeof bti);
        bti.compare = uid_compare;
 
-       saved_usracct_db = dbopen(_PATH_USRACCT, O_RDWR|O_CREAT|O_TRUNC, 0644,
-           DB_BTREE, &bti);
-       if (saved_usracct_db == NULL) {
-               warn("creating user accounting summary");
-               return (-1);
-       }
-
-       error = 0;
-
-       serr = DB_SEQ(usracct_db, &key, &data, R_FIRST);
-       if (serr < 0) {
-               warn("retrieving user accounting stats");
-               error = -1;
-       }
-       while (serr == 0) {
-               nerr = DB_PUT(saved_usracct_db, &key, &data, 0);
-               if (nerr < 0) {
-                       warn("saving user accounting summary");
-                       error = -1;
-                       break;
-               }
-
-               serr = DB_SEQ(usracct_db, &key, &data, R_NEXT);
-               if (serr < 0) {
-                       warn("retrieving user accounting stats");
-                       error = -1;
-                       break;
-               }
-       }
-
-       if (DB_SYNC(saved_usracct_db, 0) < 0) {
-               warn("syncing process accounting summary");
-               error = -1;
-       }
-       if (DB_CLOSE(saved_usracct_db) < 0) {
-               warn("closing process accounting summary");
-               error = -1;
-       }
-       return error;
+       return (db_copy_out(usracct_db, usrdb_file, "user accounting",
+           &bti));
 }
 
 void
 }
 
 void
@@ -242,6 +195,7 @@ usracct_print()
                printf("%-*s %9ju ", MAXLOGNAME - 1,
                    user_from_uid(ui->ui_uid, 0), (uintmax_t)ui->ui_calls);
 
                printf("%-*s %9ju ", MAXLOGNAME - 1,
                    user_from_uid(ui->ui_uid, 0), (uintmax_t)ui->ui_calls);
 
+#ifdef __APPLE__
                t = (double) (ui->ui_utime + ui->ui_stime) /
                    (double) AHZ;
                if (t < 0.0001)         /* kill divide by zero */
                t = (double) (ui->ui_utime + ui->ui_stime) /
                    (double) AHZ;
                if (t < 0.0001)         /* kill divide by zero */
@@ -261,6 +215,26 @@ usracct_print()
                        printf("%12.0f%s", ui->ui_mem / t, "k");
                else
                        printf("%12ju%s", (uintmax_t)ui->ui_mem, "k*sec");
                        printf("%12.0f%s", ui->ui_mem / t, "k");
                else
                        printf("%12ju%s", (uintmax_t)ui->ui_mem, "k*sec");
+#else
+               t = (ui->ui_utime + ui->ui_stime) / 1000000;
+               if (t < 0.000001)               /* kill divide by zero */
+                       t = 0.000001;
+
+               printf("%12.2f%s ", t / 60.0, "cpu");
+
+               /* ui->ui_calls is always != 0 */
+               if (dflag)
+                       printf("%12.0f%s",
+                           ui->ui_io / ui->ui_calls, "avio");
+               else
+                       printf("%12.0f%s", ui->ui_io, "tio");
+
+               /* t is always >= 0.000001; see above. */
+               if (kflag)
+                       printf("%12.0f%s", ui->ui_mem / t, "k");
+               else
+                       printf("%12.0f%s", ui->ui_mem, "k*sec");
+#endif
 
                printf("\n");
 
 
                printf("\n");
 
@@ -271,10 +245,9 @@ usracct_print()
 }
 
 static int
 }
 
 static int
-uid_compare(k1, k2)
-       const DBT *k1, *k2;
+uid_compare(const DBT *k1, const DBT *k2)
 {
 {
-       u_long d1, d2;
+       uid_t d1, d2;
 
        bcopy(k1->data, &d1, sizeof d1);
        bcopy(k2->data, &d2, sizeof d2);
 
        bcopy(k1->data, &d1, sizeof d1);
        bcopy(k2->data, &d2, sizeof d2);