Added xten, controller for the X-10 driver
[unix-history] / usr.sbin / sa / usrdb.c
CommitLineData
7e7051a8
GR
1/*
2 * Copyright (c) 1994 Christopher G. Demetriou
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
13 * 3. All advertising materials mentioning features or use of this software
14 * must display the following acknowledgement:
15 * This product includes software developed by Christopher G. Demetriou.
16 * 4. The name of the author may not be used to endorse or promote products
17 * derived from this software without specific prior written permission
18 *
19 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
20 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
21 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
22 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
23 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
24 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
25 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
26 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
27 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
28 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29 */
30
31#ifndef LINT
32static char rcsid[] = "$Id: usrdb.c,v 1.1 1994/03/24 18:42:01 cgd Exp $";
33#endif
34
35#include <sys/types.h>
36#include <sys/acct.h>
37#include <err.h>
38#include <errno.h>
39#include <fcntl.h>
7e7051a8
GR
40#include "extern.h"
41#include "pathnames.h"
42
43static int uid_compare __P((const DBT *, const DBT *));
44
45static DB *usracct_db;
46
47int
48usracct_init()
49{
50 DB *saved_usracct_db;
51 BTREEINFO bti;
52 int error;
53
54 bzero(&bti, sizeof bti);
55 bti.compare = uid_compare;
56
57 usracct_db = dbopen(NULL, O_RDWR, 0, DB_BTREE, &bti);
58 if (usracct_db == NULL)
59 return (-1);
60
61 error = 0;
62 if (!iflag) {
63 DBT key, data;
64 int serr, nerr;
65
66 saved_usracct_db = dbopen(_PATH_USRACCT, O_RDONLY, 0, DB_BTREE,
67 &bti);
68 if (saved_usracct_db == NULL) {
69 error = (errno == ENOENT) ? 0 : -1;
70 if (error)
71 warn("retrieving user accounting summary");
72 goto out;
73 }
74
75 serr = DB_SEQ(saved_usracct_db, &key, &data, R_FIRST);
76 if (serr < 0) {
77 warn("retrieving user accounting summary");
78 error = -1;
79 goto closeout;
80 }
81 while (serr == 0) {
82 nerr = DB_PUT(usracct_db, &key, &data, 0);
83 if (nerr < 0) {
84 warn("initializing user accounting stats");
85 error = -1;
86 break;
87 }
88
89 serr = DB_SEQ(saved_usracct_db, &key, &data, R_NEXT);
90 if (serr < 0) {
91 warn("retrieving user accounting summary");
92 error = -1;
93 break;
94 }
95 }
96
97closeout:
98 if (DB_CLOSE(saved_usracct_db) < 0) {
99 warn("closing user accounting summary");
100 error = -1;
101 }
102 }
103
104out:
105 if (error != 0)
106 usracct_destroy();
107 return (error);
108}
109
110void
111usracct_destroy()
112{
113 if (DB_CLOSE(usracct_db) < 0)
114 warn("destroying user accounting stats");
115}
116
117int
118usracct_add(ci)
119 const struct cmdinfo *ci;
120{
121 DBT key, data;
122 struct userinfo newui;
123 u_long uid;
124 int rv;
125
126 uid = ci->ci_uid;
127 key.data = &uid;
128 key.size = sizeof uid;
129
130 rv = DB_GET(usracct_db, &key, &data, 0);
131 if (rv < 0) {
132 warn("get key %d from user accounting stats", uid);
133 return (-1);
134 } else if (rv == 0) { /* it's there; copy whole thing */
135 /* add the old data to the new data */
136 bcopy(data.data, &newui, data.size);
137 if (newui.ui_uid != uid) {
138 warnx("key %d != expected record number %d",
139 newui.ui_uid, uid);
140 warnx("inconsistent user accounting stats");
141 return (-1);
142 }
143 } else { /* it's not there; zero it and copy the key */
144 bzero(&newui, sizeof newui);
145 newui.ui_uid = ci->ci_uid;
146 }
147
148 newui.ui_calls += ci->ci_calls;
149 newui.ui_utime += ci->ci_utime;
150 newui.ui_stime += ci->ci_stime;
151 newui.ui_mem += ci->ci_mem;
152 newui.ui_io += ci->ci_io;
153
154 data.data = &newui;
155 data.size = sizeof newui;
156 rv = DB_PUT(usracct_db, &key, &data, 0);
157 if (rv < 0) {
158 warn("add key %d to user accounting stats", uid);
159 return (-1);
160 } else if (rv != 0) {
161 warnx("DB_PUT returned 1");
162 return (-1);
163 }
164
165 return (0);
166}
167
168int
169usracct_update()
170{
171 DB *saved_usracct_db;
172 DBT key, data;
173 BTREEINFO bti;
174 u_long uid;
175 int error, serr, nerr;
176
177 bzero(&bti, sizeof bti);
178 bti.compare = uid_compare;
179
180 saved_usracct_db = dbopen(_PATH_USRACCT, O_RDWR|O_CREAT|O_TRUNC, 0644,
181 DB_BTREE, &bti);
182 if (saved_usracct_db == NULL) {
183 warn("creating user accounting summary");
184 return (-1);
185 }
186
187 error = 0;
188
189 serr = DB_SEQ(usracct_db, &key, &data, R_FIRST);
190 if (serr < 0) {
191 warn("retrieving user accounting stats");
192 error = -1;
193 }
194 while (serr == 0) {
195 nerr = DB_PUT(saved_usracct_db, &key, &data, 0);
196 if (nerr < 0) {
197 warn("saving user accounting summary");
198 error = -1;
199 break;
200 }
201
202 serr = DB_SEQ(usracct_db, &key, &data, R_NEXT);
203 if (serr < 0) {
204 warn("retrieving user accounting stats");
205 error = -1;
206 break;
207 }
208 }
209
210 if (DB_SYNC(saved_usracct_db, 0) < 0) {
211 warn("syncing process accounting summary");
212 error = -1;
213 }
214out:
215 if (DB_CLOSE(saved_usracct_db) < 0) {
216 warn("closing process accounting summary");
217 error = -1;
218 }
219 return error;
220}
221
222void
223usracct_print()
224{
225 DBT key, data;
226 struct userinfo *ui;
7e7051a8
GR
227 double t;
228 int rv;
229
230 rv = DB_SEQ(usracct_db, &key, &data, R_FIRST);
231 if (rv < 0)
232 warn("retrieving user accounting stats");
233
234 while (rv == 0) {
235 ui = (struct userinfo *) data.data;
236
7e7051a8 237 printf("%-8s %9qu ",
5ee462aa 238 user_from_uid(ui->ui_uid, 0), ui->ui_calls);
7e7051a8
GR
239
240 t = (double) (ui->ui_utime + ui->ui_stime) /
241 (double) AHZ;
242 if (t < 0.0001) /* kill divide by zero */
243 t = 0.0001;
244
245 printf("%12.2lf%s ", t / 60.0, "cpu");
246
247 /* ui->ui_calls is always != 0 */
248 if (dflag)
249 printf("%12qu%s", ui->ui_io / ui->ui_calls, "avio");
250 else
251 printf("%12qu%s", ui->ui_io, "tio");
252
253 /* t is always >= 0.0001; see above */
254 if (kflag)
255 printf("%12qu%s", ui->ui_mem / t, "k");
256 else
257 printf("%12qu%s", ui->ui_mem, "k*sec");
258
259 printf("\n");
260
261 rv = DB_SEQ(usracct_db, &key, &data, R_NEXT);
262 if (rv < 0)
263 warn("retrieving user accounting stats");
264 }
265}
266
267static int
268uid_compare(k1, k2)
269 const DBT *k1, *k2;
270{
271 u_long d1, d2;
272
273 bcopy(k1->data, &d1, sizeof d1);
274 bcopy(k2->data, &d2, sizeof d2);
275
276 if (d1 < d2)
277 return -1;
278 else if (d1 == d2)
279 return 0;
280 else
281 return 1;
282}