xref: /illumos-gate/usr/src/cmd/wracct/wracct.c (revision afab0816ecb604f0099a09ad8ee398f0d7b77b1c)
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 2004 Sun Microsystems, Inc.  All rights reserved.
24  * Use is subject to license terms.
25  */
26 
27 #pragma ident	"%Z%%M%	%I%	%E% SMI"
28 
29 /*
30  * wracct - write system accounting records
31  */
32 
33 #include <sys/types.h>
34 #include <sys/procset.h>
35 #include <exacct.h>
36 #include <stdio.h>
37 #include <stdlib.h>
38 #include <libintl.h>
39 #include <strings.h>
40 #include <errno.h>
41 
42 #define	CMDNAME "wracct"
43 #define	USAGE \
44     gettext("Usage: wracct -i id_list [-t partial | interval ] " \
45 	"{process | task}\n")
46 #define	OPTIONS_STRING "i:t:"
47 
48 static void
49 usage(void)
50 {
51 	(void) fprintf(stderr, USAGE);
52 	exit(2);
53 }
54 
55 static long
56 Atol(char *p)
57 {
58 	long l;
59 	char *q;
60 	errno = 0;
61 	l = strtol(p, &q, 10);
62 	if (errno != 0 || q == p || l < 0 || *q != '\0') {
63 		(void) fprintf(stderr, gettext("%s: illegal argument -- %s\n"),
64 		    CMDNAME, p);
65 		exit(2);
66 		/*NOTREACHED*/
67 	} else {
68 		return (l);
69 	}
70 }
71 
72 int
73 main(int argc, char *argv[])
74 {
75 	idtype_t ent_flag = -1;
76 	int rec_flag = EW_PARTIAL;
77 	id_t id = -1;
78 	char *id_sequence = NULL;
79 	char *idlp = NULL;
80 	int c, r;
81 
82 	while ((c = getopt(argc, argv, OPTIONS_STRING)) != EOF) {
83 		switch (c) {
84 			case 't':
85 				if (strcmp(optarg, "partial") == 0) {
86 					rec_flag = EW_PARTIAL;
87 				} else if (strcmp(optarg, "interval") == 0) {
88 					rec_flag = EW_INTERVAL;
89 				} else {
90 					(void) fprintf(stderr,
91 					    gettext("%s: wrong record type\n"),
92 					    CMDNAME);
93 					usage();
94 				}
95 				break;
96 			case 'i':
97 				id_sequence = strdup(optarg);
98 				break;
99 			case '?':
100 			default:
101 				usage();
102 				break;
103 		}
104 	}
105 
106 	if (optind >= argc) {
107 		usage();
108 	}
109 
110 	if (strcmp(argv[optind], "task") == 0) {
111 		ent_flag = P_TASKID;
112 	} else if (strcmp(argv[optind], "process") == 0 ||
113 	    strcmp(argv[optind], "proc") == 0) {
114 		ent_flag = P_PID;
115 	} else {
116 		usage();
117 	}
118 
119 	if (ent_flag == P_PID && rec_flag == EW_INTERVAL) {
120 		(void) fprintf(stderr,
121 		    gettext("%s: interval process records not supported\n"),
122 		    CMDNAME);
123 		exit(2);
124 	}
125 
126 	if (id_sequence == NULL) {
127 		(void) fprintf(stderr,
128 		    gettext("%s: please use -i option to specify ids\n"),
129 		    CMDNAME);
130 		exit(2);
131 	}
132 
133 	for (idlp = strtok(id_sequence, ", \t\n"); idlp != NULL;
134 	    idlp = strtok(NULL, ", \t\n")) {
135 		id = Atol(idlp);
136 		if (wracct(ent_flag, id, rec_flag) < 0) {
137 			r = errno;
138 			(void) fprintf(stderr,
139 			    "%s: operation failed on %s %d: %s\n",
140 			    CMDNAME, (ent_flag == P_TASKID) ? "taskid" : "pid",
141 			    (int)id, strerror(r));
142 			exit(1);
143 		}
144 	}
145 
146 	return (0);
147 }
148