Mercurial > illumos > onarm
annotate usr/src/cmd/acctadm/main.c @ 4:1a15d5aaf794
synchronized with onnv_86 (6202) in onnv-gate
author | Koji Uno <koji.uno@sun.com> |
---|---|
date | Mon, 31 Aug 2009 14:38:03 +0900 |
parents | c9caec207d52 |
children |
rev | line source |
---|---|
0 | 1 /* |
2 * CDDL HEADER START | |
3 * | |
4 * The contents of this file are subject to the terms of the | |
5 * Common Development and Distribution License, Version 1.0 only | |
6 * (the "License"). You may not use this file except in compliance | |
7 * with the License. | |
8 * | |
9 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE | |
10 * or http://www.opensolaris.org/os/licensing. | |
11 * See the License for the specific language governing permissions | |
12 * and limitations under the License. | |
13 * | |
14 * When distributing Covered Code, include this CDDL HEADER in each | |
15 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. | |
16 * If applicable, add the following below this CDDL HEADER, with the | |
17 * fields enclosed by brackets "[]" replaced with your own identifying | |
18 * information: Portions Copyright [yyyy] [name of copyright owner] | |
19 * | |
20 * CDDL HEADER END | |
21 */ | |
22 /* | |
23 * Copyright 1999-2002 Sun Microsystems, Inc. All rights reserved. | |
24 * Use is subject to license terms. | |
25 */ | |
26 | |
4
1a15d5aaf794
synchronized with onnv_86 (6202) in onnv-gate
Koji Uno <koji.uno@sun.com>
parents:
0
diff
changeset
|
27 #pragma ident "%Z%%M% %I% %E% SMI" |
0 | 28 |
29 #include <sys/acctctl.h> | |
30 #include <stdio.h> | |
31 #include <stdlib.h> | |
32 #include <unistd.h> | |
33 #include <string.h> | |
34 #include <errno.h> | |
35 #include <libintl.h> | |
36 #include <locale.h> | |
37 | |
38 #include "utils.h" | |
39 #include "aconf.h" | |
40 #include "res.h" | |
41 | |
42 static const char USAGE[] = "\ | |
43 Usage:\n\ | |
44 acctadm [ {process | task | flow} ]\n\ | |
45 acctadm -u\n\ | |
46 acctadm -r [ {process | task | flow} ]\n\ | |
47 acctadm -x|-E|-D {process | task | flow}\n\ | |
48 acctadm -f filename {process | task | flow}\n\ | |
49 acctadm -e resources -d resources {process | task | flow}\n"; | |
50 | |
51 static const char OPTS[] = "ruxf:e:d:ED"; | |
52 static const char PATH_CONFIG[] = "/etc/acctadm.conf"; | |
53 | |
54 static void | |
55 usage() | |
56 { | |
57 (void) fprintf(stderr, gettext(USAGE)); | |
58 exit(E_USAGE); | |
59 } | |
60 | |
61 int | |
62 main(int argc, char *argv[]) | |
63 { | |
64 int c; /* options character */ | |
65 int type = 0; /* type of accounting */ | |
66 int modified = 0; /* have we modified the /etc/acctadm.conf? */ | |
67 acctconf_t ac; /* current configuration */ | |
68 char *typestr = NULL; /* type of accounting argument string */ | |
69 char *enabled = NULL; /* enabled resources string */ | |
70 char *disabled = NULL; /* disabled resources string */ | |
71 char *file = NULL; | |
72 int Eflg = 0; | |
73 int Dflg = 0; | |
74 int rflg = 0; | |
75 int uflg = 0; | |
76 int xflg = 0; | |
77 int optcnt = 0; | |
78 int state; | |
79 | |
80 (void) setlocale(LC_ALL, ""); | |
81 (void) textdomain(TEXT_DOMAIN); | |
82 (void) setprogname(argv[0]); | |
83 | |
84 for (; optind < argc; optind++) { | |
85 while ((c = getopt(argc, argv, OPTS)) != (int)EOF) { | |
86 switch (c) { | |
87 case 'd': | |
88 disabled = optarg; | |
89 break; | |
90 case 'e': | |
91 enabled = optarg; | |
92 break; | |
93 case 'D': | |
94 Dflg = 1; | |
95 optcnt++; | |
96 break; | |
97 case 'E': | |
98 Eflg = 1; | |
99 optcnt++; | |
100 break; | |
101 case 'f': | |
102 file = optarg; | |
103 optcnt++; | |
104 break; | |
105 case 'r': | |
106 rflg = 1; | |
107 optcnt++; | |
108 break; | |
109 case 'u': | |
110 uflg = 1; | |
111 optcnt++; | |
112 break; | |
113 case 'x': | |
114 xflg = 1; | |
115 optcnt++; | |
116 break; | |
117 case '?': | |
118 default: | |
119 usage(); | |
120 } | |
121 } | |
122 if (optind < argc) { | |
123 if (typestr != NULL) { | |
124 warn(gettext("illegal argument -- %s\n"), | |
125 argv[optind]); | |
126 usage(); | |
127 } else { | |
128 typestr = argv[optind]; | |
129 } | |
130 } | |
131 } | |
132 if (typestr != NULL) { | |
133 if (strcmp(typestr, "process") == 0 || | |
134 strcmp(typestr, "proc") == 0) | |
135 type |= AC_PROC; | |
136 else if (strcmp(typestr, "task") == 0) | |
137 type |= AC_TASK; | |
138 else if (strcmp(typestr, "flow") == 0) | |
139 type |= AC_FLOW; | |
140 else { | |
141 warn(gettext("unknown accounting type -- %s\n"), | |
142 typestr); | |
143 usage(); | |
144 } | |
145 } else | |
146 type = AC_PROC | AC_TASK | AC_FLOW; | |
147 | |
148 /* | |
149 * check for invalid options | |
150 */ | |
151 if (optcnt > 1) | |
152 usage(); | |
153 | |
154 if ((enabled || disabled) && (rflg || Dflg || uflg || xflg || Eflg)) | |
155 usage(); | |
156 | |
157 if ((file || xflg || Dflg || Eflg || enabled || disabled) && | |
158 !typestr) { | |
159 warn(gettext("accounting type must be specified\n")); | |
160 usage(); | |
161 } | |
162 | |
163 if ((file || enabled || disabled || xflg || uflg || Dflg || Eflg) && | |
164 geteuid() != 0) | |
165 die(gettext("must be root to change extended " | |
166 "accounting configuration\n")); | |
167 | |
168 if (rflg) { | |
169 printgroups(type); | |
170 return (E_SUCCESS); | |
171 } | |
172 | |
173 /* | |
174 * If no arguments has been passed then just print out the current | |
175 * state, save it in the configuration file and exit. | |
176 */ | |
177 if (!enabled && !disabled && !file && | |
178 !Eflg && !rflg && !Dflg && !uflg && !xflg) { | |
179 aconf_init(&ac); | |
180 aconf_print(&ac, stdout, type); | |
181 return (E_SUCCESS); | |
182 } | |
183 | |
184 if (uflg) { | |
185 if (aconf_open(&ac, PATH_CONFIG) == -1) | |
186 return (E_ERROR); | |
187 if (aconf_setup(&ac) == -1) | |
188 exit(E_ERROR); | |
189 modified++; | |
190 } | |
191 | |
192 if (xflg) { | |
193 /* | |
194 * Turn off the specified accounting and close its file | |
195 */ | |
196 state = AC_OFF; | |
197 if (acctctl(type | AC_STATE_SET, &state, sizeof (int)) == -1) | |
198 die(gettext("cannot disable accounting")); | |
199 if (aconf_str2enable(&ac, AC_STR_NO, type) == -1) | |
200 die(gettext("cannot modify configuration file\n")); | |
201 if (acctctl(type | AC_FILE_SET, NULL, 0) == -1) | |
202 die(gettext("cannot close accounting file")); | |
203 if (aconf_str2file(&ac, AC_STR_NONE, type) == -1) | |
204 die(gettext("cannot modify configuration file\n")); | |
205 modified++; | |
206 } | |
207 | |
208 if (enabled || disabled) { | |
209 char *tracked, *untracked; | |
210 ac_res_t *buf; | |
211 | |
212 /* | |
213 * Enable/disable resources | |
214 */ | |
215 if ((buf = malloc(AC_BUFSIZE)) == NULL) | |
216 die(gettext("not enough memory\n")); | |
217 (void) memset(buf, 0, AC_BUFSIZE); | |
218 if (acctctl(type | AC_RES_GET, buf, AC_BUFSIZE) == -1) { | |
219 free(buf); | |
220 die(gettext("cannot obtain list of resources\n")); | |
221 } | |
222 if (disabled) | |
223 str2buf(buf, disabled, AC_OFF, type); | |
224 if (enabled) | |
225 str2buf(buf, enabled, AC_ON, type); | |
226 if (acctctl(type | AC_RES_SET, buf, AC_BUFSIZE) == -1) { | |
227 free(buf); | |
228 die(gettext("cannot enable or disable resources\n")); | |
229 } | |
230 tracked = buf2str(buf, AC_BUFSIZE, AC_ON, type); | |
231 untracked = buf2str(buf, AC_BUFSIZE, AC_OFF, type); | |
232 if (aconf_str2tracked(&ac, tracked, type) == -1 || | |
233 aconf_str2untracked(&ac, untracked, type)) { | |
234 free(buf); | |
235 free(tracked); | |
236 free(untracked); | |
237 die(gettext("cannot modify configuration file\n")); | |
238 } | |
239 free(tracked); | |
240 free(untracked); | |
241 free(buf); | |
242 modified++; | |
243 } | |
244 | |
245 if (file) { | |
246 /* | |
247 * Open new accounting file | |
248 */ | |
249 state = AC_ON; | |
250 if (aconf_str2file(&ac, file, type) == -1) | |
251 die(gettext("cannot modify configuration file")); | |
252 if (acctctl(type | AC_FILE_SET, file, strlen(file) + 1) == -1) | |
253 die(gettext("cannot open accounting file")); | |
254 if (aconf_str2enable(&ac, AC_STR_YES, type) == -1) | |
255 die(gettext("cannot modify configuration file")); | |
256 if (acctctl(type | AC_STATE_SET, &state, sizeof (int)) == -1) | |
257 die(gettext("cannot enable accounting")); | |
258 modified++; | |
259 } | |
260 | |
261 if (Dflg) { | |
262 /* | |
263 * Disable accounting | |
264 */ | |
265 state = AC_OFF; | |
266 if (acctctl(type | AC_STATE_SET, &state, sizeof (int)) == -1) | |
267 die(gettext("cannot disable accounting")); | |
268 if (aconf_str2enable(&ac, AC_STR_NO, type) == -1) | |
269 die(gettext("cannot modify configuration file")); | |
270 modified++; | |
271 } | |
272 | |
273 if (Eflg) { | |
274 /* | |
275 * Enable accounting | |
276 */ | |
277 state = AC_ON; | |
278 if (acctctl(type | AC_STATE_SET, &state, sizeof (int)) == -1) | |
279 die(gettext("cannot enable accounting")); | |
280 if (aconf_str2enable(&ac, AC_STR_YES, type) == -1) | |
281 die(gettext("cannot modify configuration file")); | |
282 modified++; | |
283 } | |
284 | |
285 if (modified) { | |
286 /* | |
287 * If we're modifying the configuration, then write out | |
288 * the new configuration file | |
289 */ | |
290 if (aconf_create(&ac, PATH_CONFIG) == -1) | |
291 return (E_ERROR); | |
292 aconf_init(&ac); | |
293 if (aconf_write(&ac) == -1) | |
294 return (E_ERROR); | |
295 } | |
296 | |
297 if (aconf_close(&ac) == -1) | |
298 die(gettext("failed to close configuration file")); | |
299 return (E_SUCCESS); | |
300 } |