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