1 /* $NetBSD: usrdb.c,v 1.10 2001/01/05 03:27:28 lukem Exp $ */
4 * Copyright (c) 1994 Christopher G. Demetriou
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 * 3. All advertising materials mentioning features or use of this software
16 * must display the following acknowledgement:
17 * This product includes software developed for the
18 * NetBSD Project. See http://www.NetBSD.org/ for
19 * information about NetBSD.
20 * 4. The name of the author may not be used to endorse or promote products
21 * derived from this software without specific prior written permission.
23 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
24 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
25 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
26 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
27 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
28 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
29 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
30 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
31 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
32 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
34 * <<Id: LICENSE,v 1.2 2000/06/14 15:57:33 cgd Exp>>
37 #include <sys/cdefs.h>
39 __RCSID("$NetBSD: usrdb.c,v 1.10 2001/01/05 03:27:28 lukem Exp $");
42 #include <sys/types.h>
51 #include "pathnames.h"
53 static int uid_compare
__P((const DBT
*, const DBT
*));
55 static DB
*usracct_db
;
65 memset(&bti
, 0, sizeof(bti
));
66 bti
.compare
= uid_compare
;
68 usracct_db
= dbopen(NULL
, O_RDWR
|O_CREAT
|O_TRUNC
, 0644, DB_BTREE
, &bti
);
69 if (usracct_db
== NULL
)
77 saved_usracct_db
= dbopen(_PATH_USRACCT
, O_RDONLY
, 0, DB_BTREE
,
79 if (saved_usracct_db
== NULL
) {
80 error
= (errno
== ENOENT
) ? 0 : -1;
82 warn("retrieving user accounting summary");
86 serr
= DB_SEQ(saved_usracct_db
, &key
, &data
, R_FIRST
);
88 warn("retrieving user accounting summary");
93 nerr
= DB_PUT(usracct_db
, &key
, &data
, R_NOOVERWRITE
);
95 warn("initializing user accounting stats");
100 warnx("duplicate key in `%s': %s",
101 _PATH_USRACCT
, fmt(&key
));
103 warnx("too many duplicate keys;"
104 " `%s' possibly corrupted.",
111 serr
= DB_SEQ(saved_usracct_db
, &key
, &data
, R_NEXT
);
113 warn("retrieving user accounting summary");
120 if (DB_CLOSE(saved_usracct_db
) < 0) {
121 warn("closing user accounting summary");
135 if (DB_CLOSE(usracct_db
) < 0)
136 warn("destroying user accounting stats");
141 const struct cmdinfo
*ci
;
144 struct userinfo newui
;
150 key
.size
= sizeof(uid
);
152 rv
= DB_GET(usracct_db
, &key
, &data
, 0);
154 warn("get key %d from user accounting stats", uid
);
156 } else if (rv
== 0) { /* it's there; copy whole thing */
157 /* add the old data to the new data */
158 memcpy(&newui
, data
.data
, data
.size
);
159 if (newui
.ui_uid
!= uid
) {
160 warnx("key %d != expected record number %d",
162 warnx("inconsistent user accounting stats");
165 } else { /* it's not there; zero it and copy the key */
166 memset(&newui
, 0, sizeof(newui
));
167 newui
.ui_uid
= ci
->ci_uid
;
170 newui
.ui_calls
+= ci
->ci_calls
;
171 newui
.ui_utime
+= ci
->ci_utime
;
172 newui
.ui_stime
+= ci
->ci_stime
;
173 newui
.ui_mem
+= ci
->ci_mem
;
174 newui
.ui_io
+= ci
->ci_io
;
177 data
.size
= sizeof(newui
);
178 rv
= DB_PUT(usracct_db
, &key
, &data
, 0);
180 warn("add key %d to user accounting stats", uid
);
182 } else if (rv
!= 0) {
183 warnx("DB_PUT returned 1");
193 DB
*saved_usracct_db
;
196 int error
, serr
, nerr
;
198 memset(&bti
, 0, sizeof(bti
));
199 bti
.compare
= uid_compare
;
201 saved_usracct_db
= dbopen(_PATH_USRACCT
, O_RDWR
|O_CREAT
|O_TRUNC
, 0644,
203 if (saved_usracct_db
== NULL
) {
204 warn("creating user accounting summary");
210 serr
= DB_SEQ(usracct_db
, &key
, &data
, R_FIRST
);
212 warn("retrieving user accounting stats");
216 nerr
= DB_PUT(saved_usracct_db
, &key
, &data
, 0);
218 warn("saving user accounting summary");
223 serr
= DB_SEQ(usracct_db
, &key
, &data
, R_NEXT
);
225 warn("retrieving user accounting stats");
231 if (DB_SYNC(saved_usracct_db
, 0) < 0) {
232 warn("syncing process accounting summary");
235 if (DB_CLOSE(saved_usracct_db
) < 0) {
236 warn("closing process accounting summary");
246 struct userinfo uistore
, *ui
= &uistore
;
250 rv
= DB_SEQ(usracct_db
, &key
, &data
, R_FIRST
);
252 warn("retrieving user accounting stats");
255 memcpy(ui
, data
.data
, sizeof(struct userinfo
));
257 printf("%-8s %9llu ",
258 user_from_uid(ui
->ui_uid
, 0),
259 (unsigned long long)ui
->ui_calls
);
261 t
= (double) (ui
->ui_utime
+ ui
->ui_stime
) /
263 if (t
< 0.0001) /* kill divide by zero */
266 printf("%12.2f%s ", t
/ 60.0, "cpu");
268 /* ui->ui_calls is always != 0 */
271 (unsigned long long)(ui
->ui_io
/ ui
->ui_calls
),
275 (unsigned long long)ui
->ui_io
, "tio");
277 /* t is always >= 0.0001; see above */
279 printf("%12llu%s", (unsigned long long)(ui
->ui_mem
/ t
),
282 printf("%12llu%s", (unsigned long long)ui
->ui_mem
,
287 rv
= DB_SEQ(usracct_db
, &key
, &data
, R_NEXT
);
289 warn("retrieving user accounting stats");
299 memcpy(&d1
, k1
->data
, sizeof(d1
));
300 memcpy(&d2
, k2
->data
, sizeof(d2
));