17c478bd9Sstevel@tonic-gate /*
27c478bd9Sstevel@tonic-gate * CDDL HEADER START
37c478bd9Sstevel@tonic-gate *
47c478bd9Sstevel@tonic-gate * The contents of this file are subject to the terms of the
5074e084fSml * Common Development and Distribution License (the "License").
6074e084fSml * You may not use this file except in compliance with the License.
77c478bd9Sstevel@tonic-gate *
87c478bd9Sstevel@tonic-gate * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
97c478bd9Sstevel@tonic-gate * or http://www.opensolaris.org/os/licensing.
107c478bd9Sstevel@tonic-gate * See the License for the specific language governing permissions
117c478bd9Sstevel@tonic-gate * and limitations under the License.
127c478bd9Sstevel@tonic-gate *
137c478bd9Sstevel@tonic-gate * When distributing Covered Code, include this CDDL HEADER in each
147c478bd9Sstevel@tonic-gate * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
157c478bd9Sstevel@tonic-gate * If applicable, add the following below this CDDL HEADER, with the
167c478bd9Sstevel@tonic-gate * fields enclosed by brackets "[]" replaced with your own identifying
177c478bd9Sstevel@tonic-gate * information: Portions Copyright [yyyy] [name of copyright owner]
187c478bd9Sstevel@tonic-gate *
197c478bd9Sstevel@tonic-gate * CDDL HEADER END
207c478bd9Sstevel@tonic-gate */
217c478bd9Sstevel@tonic-gate /*
22074e084fSml * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
237c478bd9Sstevel@tonic-gate * Use is subject to license terms.
247c478bd9Sstevel@tonic-gate */
257c478bd9Sstevel@tonic-gate
267c478bd9Sstevel@tonic-gate #include <stdlib.h>
277c478bd9Sstevel@tonic-gate #include <stdio.h>
287c478bd9Sstevel@tonic-gate #include <libintl.h>
297c478bd9Sstevel@tonic-gate #include <string.h>
307c478bd9Sstevel@tonic-gate #include <sys/acctctl.h>
317c478bd9Sstevel@tonic-gate
327c478bd9Sstevel@tonic-gate #include "utils.h"
337c478bd9Sstevel@tonic-gate #include "aconf.h"
347c478bd9Sstevel@tonic-gate #include "res.h"
357c478bd9Sstevel@tonic-gate
367c478bd9Sstevel@tonic-gate /*
377c478bd9Sstevel@tonic-gate * resource names
387c478bd9Sstevel@tonic-gate */
397c478bd9Sstevel@tonic-gate static ac_resname_t ac_names[] = {
407c478bd9Sstevel@tonic-gate /*
417c478bd9Sstevel@tonic-gate * Process accounting resources
427c478bd9Sstevel@tonic-gate */
437c478bd9Sstevel@tonic-gate { AC_PROC, AC_PROC_PID, "pid" },
447c478bd9Sstevel@tonic-gate { AC_PROC, AC_PROC_UID, "uid" },
457c478bd9Sstevel@tonic-gate { AC_PROC, AC_PROC_GID, "gid" },
467c478bd9Sstevel@tonic-gate { AC_PROC, AC_PROC_PROJID, "projid" },
477c478bd9Sstevel@tonic-gate { AC_PROC, AC_PROC_TASKID, "taskid" },
487c478bd9Sstevel@tonic-gate { AC_PROC, AC_PROC_CPU, "cpu" },
497c478bd9Sstevel@tonic-gate { AC_PROC, AC_PROC_TIME, "time" },
507c478bd9Sstevel@tonic-gate { AC_PROC, AC_PROC_COMMAND, "command" },
517c478bd9Sstevel@tonic-gate { AC_PROC, AC_PROC_TTY, "tty" },
527c478bd9Sstevel@tonic-gate { AC_PROC, AC_PROC_HOSTNAME, "host" },
537c478bd9Sstevel@tonic-gate { AC_PROC, AC_PROC_MICROSTATE, "mstate" },
547c478bd9Sstevel@tonic-gate { AC_PROC, AC_PROC_FLAG, "flag" },
557c478bd9Sstevel@tonic-gate { AC_PROC, AC_PROC_ANCPID, "ancpid" },
567c478bd9Sstevel@tonic-gate { AC_PROC, AC_PROC_WAIT_STATUS, "wait-status" },
577c478bd9Sstevel@tonic-gate { AC_PROC, AC_PROC_ZONENAME, "zone" },
587c478bd9Sstevel@tonic-gate { AC_PROC, AC_PROC_MEM, "memory" },
597c478bd9Sstevel@tonic-gate
607c478bd9Sstevel@tonic-gate /*
617c478bd9Sstevel@tonic-gate * Task accounting resources
627c478bd9Sstevel@tonic-gate */
637c478bd9Sstevel@tonic-gate { AC_TASK, AC_TASK_TASKID, "taskid" },
647c478bd9Sstevel@tonic-gate { AC_TASK, AC_TASK_PROJID, "projid" },
657c478bd9Sstevel@tonic-gate { AC_TASK, AC_TASK_CPU, "cpu" },
667c478bd9Sstevel@tonic-gate { AC_TASK, AC_TASK_TIME, "time" },
677c478bd9Sstevel@tonic-gate { AC_TASK, AC_TASK_HOSTNAME, "host" },
687c478bd9Sstevel@tonic-gate { AC_TASK, AC_TASK_MICROSTATE, "mstate" },
697c478bd9Sstevel@tonic-gate { AC_TASK, AC_TASK_ANCTASKID, "anctaskid" },
707c478bd9Sstevel@tonic-gate { AC_TASK, AC_TASK_ZONENAME, "zone" },
717c478bd9Sstevel@tonic-gate
727c478bd9Sstevel@tonic-gate /*
737c478bd9Sstevel@tonic-gate * Flow accounting resources
747c478bd9Sstevel@tonic-gate */
757c478bd9Sstevel@tonic-gate { AC_FLOW, AC_FLOW_SADDR, "saddr" },
767c478bd9Sstevel@tonic-gate { AC_FLOW, AC_FLOW_DADDR, "daddr" },
777c478bd9Sstevel@tonic-gate { AC_FLOW, AC_FLOW_SPORT, "sport" },
787c478bd9Sstevel@tonic-gate { AC_FLOW, AC_FLOW_DPORT, "dport" },
797c478bd9Sstevel@tonic-gate { AC_FLOW, AC_FLOW_PROTOCOL, "proto" },
807c478bd9Sstevel@tonic-gate { AC_FLOW, AC_FLOW_DSFIELD, "dsfield" },
817c478bd9Sstevel@tonic-gate { AC_FLOW, AC_FLOW_NBYTES, "nbytes" },
827c478bd9Sstevel@tonic-gate { AC_FLOW, AC_FLOW_NPKTS, "npkts" },
837c478bd9Sstevel@tonic-gate { AC_FLOW, AC_FLOW_CTIME, "ctime" },
847c478bd9Sstevel@tonic-gate { AC_FLOW, AC_FLOW_LSEEN, "lseen" },
857c478bd9Sstevel@tonic-gate { AC_FLOW, AC_FLOW_PROJID, "projid" },
867c478bd9Sstevel@tonic-gate { AC_FLOW, AC_FLOW_UID, "uid" },
877c478bd9Sstevel@tonic-gate { AC_FLOW, AC_FLOW_ANAME, "action" },
887c478bd9Sstevel@tonic-gate
89*da14cebeSEric Cheng /*
90*da14cebeSEric Cheng * Net accounting resources
91*da14cebeSEric Cheng */
92*da14cebeSEric Cheng
93*da14cebeSEric Cheng { AC_NET, AC_NET_NAME, "name" },
94*da14cebeSEric Cheng { AC_NET, AC_NET_EHOST, "ehost" },
95*da14cebeSEric Cheng { AC_NET, AC_NET_EDEST, "edest" },
96*da14cebeSEric Cheng { AC_NET, AC_NET_VLAN_TPID, "vlan_pid" },
97*da14cebeSEric Cheng { AC_NET, AC_NET_VLAN_TCI, "vlan_tci" },
98*da14cebeSEric Cheng { AC_NET, AC_NET_SAP, "sap" },
99*da14cebeSEric Cheng { AC_NET, AC_NET_PRIORITY, "priority" },
100*da14cebeSEric Cheng { AC_NET, AC_NET_BWLIMIT, "bwlimit" },
101*da14cebeSEric Cheng { AC_NET, AC_NET_DEVNAME, "devname" },
102*da14cebeSEric Cheng { AC_NET, AC_NET_SADDR, "src_ip" },
103*da14cebeSEric Cheng { AC_NET, AC_NET_DADDR, "dst_ip" },
104*da14cebeSEric Cheng { AC_NET, AC_NET_SPORT, "src_port" },
105*da14cebeSEric Cheng { AC_NET, AC_NET_DPORT, "dst_port" },
106*da14cebeSEric Cheng { AC_NET, AC_NET_PROTOCOL, "protocol" },
107*da14cebeSEric Cheng { AC_NET, AC_NET_DSFIELD, "dsfield" },
108*da14cebeSEric Cheng { AC_NET, AC_NET_CURTIME, "curtime" },
109*da14cebeSEric Cheng { AC_NET, AC_NET_IBYTES, "ibytes" },
110*da14cebeSEric Cheng { AC_NET, AC_NET_OBYTES, "obytes" },
111*da14cebeSEric Cheng { AC_NET, AC_NET_IPKTS, "ipkts" },
112*da14cebeSEric Cheng { AC_NET, AC_NET_OPKTS, "opkts" },
113*da14cebeSEric Cheng { AC_NET, AC_NET_IERRPKTS, "ierrpkts" },
114*da14cebeSEric Cheng { AC_NET, AC_NET_OERRPKTS, "oerrpkts" },
115*da14cebeSEric Cheng
1167c478bd9Sstevel@tonic-gate /*
1177c478bd9Sstevel@tonic-gate * These are included for compatibility with old acctadm that
1187c478bd9Sstevel@tonic-gate * didn't have resource groups for individual accounting types.
1197c478bd9Sstevel@tonic-gate * It was possible to have resource "pid" enabled for task
1207c478bd9Sstevel@tonic-gate * accounting even though we couldn't actually track it.
1217c478bd9Sstevel@tonic-gate */
1227c478bd9Sstevel@tonic-gate { AC_TASK, AC_NONE, "pid" },
1237c478bd9Sstevel@tonic-gate { AC_TASK, AC_NONE, "uid" },
1247c478bd9Sstevel@tonic-gate { AC_TASK, AC_NONE, "gid" },
1257c478bd9Sstevel@tonic-gate { AC_TASK, AC_NONE, "command" },
1267c478bd9Sstevel@tonic-gate { AC_TASK, AC_NONE, "tty" },
1277c478bd9Sstevel@tonic-gate { AC_TASK, AC_NONE, "flag" },
1287c478bd9Sstevel@tonic-gate
1297c478bd9Sstevel@tonic-gate { AC_NONE, AC_NONE, NULL }
1307c478bd9Sstevel@tonic-gate };
1317c478bd9Sstevel@tonic-gate
1327c478bd9Sstevel@tonic-gate /*
1337c478bd9Sstevel@tonic-gate * resource groups
1347c478bd9Sstevel@tonic-gate */
1357c478bd9Sstevel@tonic-gate static ac_group_t ac_groups[] = {
1367c478bd9Sstevel@tonic-gate { AC_PROC, "extended",
1377c478bd9Sstevel@tonic-gate { AC_PROC_PID, AC_PROC_UID, AC_PROC_GID, AC_PROC_CPU,
1387c478bd9Sstevel@tonic-gate AC_PROC_TIME, AC_PROC_COMMAND, AC_PROC_TTY, AC_PROC_PROJID,
1397c478bd9Sstevel@tonic-gate AC_PROC_TASKID, AC_PROC_ANCPID, AC_PROC_WAIT_STATUS,
1407c478bd9Sstevel@tonic-gate AC_PROC_ZONENAME, AC_PROC_FLAG, AC_PROC_MEM,
1417c478bd9Sstevel@tonic-gate AC_PROC_MICROSTATE, AC_NONE } },
1427c478bd9Sstevel@tonic-gate { AC_PROC, "basic",
1437c478bd9Sstevel@tonic-gate { AC_PROC_PID, AC_PROC_UID, AC_PROC_GID, AC_PROC_CPU,
1447c478bd9Sstevel@tonic-gate AC_PROC_TIME, AC_PROC_COMMAND, AC_PROC_TTY, AC_PROC_FLAG,
1457c478bd9Sstevel@tonic-gate AC_NONE } },
1467c478bd9Sstevel@tonic-gate { AC_TASK, "extended",
1477c478bd9Sstevel@tonic-gate { AC_TASK_TASKID, AC_TASK_PROJID, AC_TASK_CPU, AC_TASK_TIME,
1487c478bd9Sstevel@tonic-gate AC_TASK_HOSTNAME, AC_TASK_MICROSTATE, AC_TASK_ANCTASKID,
1497c478bd9Sstevel@tonic-gate AC_TASK_ZONENAME, AC_NONE } },
1507c478bd9Sstevel@tonic-gate { AC_TASK, "basic",
1517c478bd9Sstevel@tonic-gate { AC_TASK_TASKID, AC_TASK_PROJID, AC_TASK_CPU, AC_TASK_TIME,
1527c478bd9Sstevel@tonic-gate AC_NONE } },
1537c478bd9Sstevel@tonic-gate { AC_FLOW, "extended",
1547c478bd9Sstevel@tonic-gate { AC_FLOW_SADDR, AC_FLOW_DADDR, AC_FLOW_SPORT, AC_FLOW_DPORT,
1557c478bd9Sstevel@tonic-gate AC_FLOW_PROTOCOL, AC_FLOW_DSFIELD, AC_FLOW_NBYTES,
1567c478bd9Sstevel@tonic-gate AC_FLOW_NPKTS, AC_FLOW_ANAME, AC_FLOW_CTIME, AC_FLOW_LSEEN,
1577c478bd9Sstevel@tonic-gate AC_FLOW_PROJID, AC_FLOW_UID, AC_NONE } },
1587c478bd9Sstevel@tonic-gate { AC_FLOW, "basic",
1597c478bd9Sstevel@tonic-gate { AC_FLOW_SADDR, AC_FLOW_DADDR, AC_FLOW_SPORT, AC_FLOW_DPORT,
1607c478bd9Sstevel@tonic-gate AC_FLOW_PROTOCOL, AC_FLOW_NBYTES, AC_FLOW_NPKTS, AC_FLOW_ANAME,
1617c478bd9Sstevel@tonic-gate AC_NONE } },
162*da14cebeSEric Cheng { AC_NET, "extended",
163*da14cebeSEric Cheng { AC_NET_NAME, AC_NET_EHOST, AC_NET_EDEST, AC_NET_VLAN_TPID,
164*da14cebeSEric Cheng AC_NET_VLAN_TCI, AC_NET_SAP, AC_NET_PRIORITY,
165*da14cebeSEric Cheng AC_NET_BWLIMIT, AC_NET_DEVNAME, AC_NET_SADDR, AC_NET_DADDR,
166*da14cebeSEric Cheng AC_NET_SPORT, AC_NET_DPORT, AC_NET_PROTOCOL, AC_NET_DSFIELD,
167*da14cebeSEric Cheng AC_NET_CURTIME, AC_NET_IBYTES, AC_NET_OBYTES, AC_NET_IPKTS,
168*da14cebeSEric Cheng AC_NET_OPKTS, AC_NET_IERRPKTS, AC_NET_OERRPKTS, AC_NONE } },
169*da14cebeSEric Cheng { AC_NET, "basic",
170*da14cebeSEric Cheng { AC_NET_NAME, AC_NET_DEVNAME, AC_NET_EHOST, AC_NET_EDEST,
171*da14cebeSEric Cheng AC_NET_VLAN_TPID, AC_NET_VLAN_TCI, AC_NET_SAP,
172*da14cebeSEric Cheng AC_NET_PRIORITY, AC_NET_BWLIMIT, AC_NET_CURTIME, AC_NET_IBYTES,
173*da14cebeSEric Cheng AC_NET_OBYTES, AC_NET_IPKTS, AC_NET_OPKTS, AC_NET_IERRPKTS,
174*da14cebeSEric Cheng AC_NET_OERRPKTS, AC_NONE } },
1757c478bd9Sstevel@tonic-gate { AC_NONE, NULL,
1767c478bd9Sstevel@tonic-gate { AC_NONE } }
1777c478bd9Sstevel@tonic-gate };
1787c478bd9Sstevel@tonic-gate
1797c478bd9Sstevel@tonic-gate /*
1807c478bd9Sstevel@tonic-gate * this function returns the id of the named resource
1817c478bd9Sstevel@tonic-gate */
1827c478bd9Sstevel@tonic-gate static int
name2id(char * name,int type)1837c478bd9Sstevel@tonic-gate name2id(char *name, int type)
1847c478bd9Sstevel@tonic-gate {
1857c478bd9Sstevel@tonic-gate ac_resname_t *acname = ac_names;
1867c478bd9Sstevel@tonic-gate while (acname->ar_type != AC_NONE) {
1877c478bd9Sstevel@tonic-gate if (acname->ar_type == type &&
1887c478bd9Sstevel@tonic-gate strcmp(acname->ar_name, name) == 0) {
1897c478bd9Sstevel@tonic-gate if (acname->ar_id == AC_NONE)
1907c478bd9Sstevel@tonic-gate /*
1917c478bd9Sstevel@tonic-gate * For compatibility with older versions.
1927c478bd9Sstevel@tonic-gate */
1937c478bd9Sstevel@tonic-gate return (-1);
1947c478bd9Sstevel@tonic-gate else
1957c478bd9Sstevel@tonic-gate return (acname->ar_id);
1967c478bd9Sstevel@tonic-gate }
1977c478bd9Sstevel@tonic-gate acname++;
1987c478bd9Sstevel@tonic-gate }
1997c478bd9Sstevel@tonic-gate return (0);
2007c478bd9Sstevel@tonic-gate }
2017c478bd9Sstevel@tonic-gate
2027c478bd9Sstevel@tonic-gate /*
2037c478bd9Sstevel@tonic-gate * this function gives name of the resource by its id
2047c478bd9Sstevel@tonic-gate */
2057c478bd9Sstevel@tonic-gate static char *
id2name(int id,int type)2067c478bd9Sstevel@tonic-gate id2name(int id, int type)
2077c478bd9Sstevel@tonic-gate {
2087c478bd9Sstevel@tonic-gate ac_resname_t *acname = ac_names;
2097c478bd9Sstevel@tonic-gate while (acname->ar_id != AC_NONE) {
2107c478bd9Sstevel@tonic-gate if (acname->ar_type == type &&
2117c478bd9Sstevel@tonic-gate acname->ar_id == id)
2127c478bd9Sstevel@tonic-gate return (acname->ar_name);
2137c478bd9Sstevel@tonic-gate acname++;
2147c478bd9Sstevel@tonic-gate }
2157c478bd9Sstevel@tonic-gate return (NULL);
2167c478bd9Sstevel@tonic-gate }
2177c478bd9Sstevel@tonic-gate
2187c478bd9Sstevel@tonic-gate static void
printgroup(int type)2197c478bd9Sstevel@tonic-gate printgroup(int type)
2207c478bd9Sstevel@tonic-gate {
2217c478bd9Sstevel@tonic-gate int r, g, id;
2227c478bd9Sstevel@tonic-gate
2237c478bd9Sstevel@tonic-gate for (g = 0; ac_groups[g].ag_type != AC_NONE; g++) {
2247c478bd9Sstevel@tonic-gate if (ac_groups[g].ag_type != type)
2257c478bd9Sstevel@tonic-gate continue;
2267c478bd9Sstevel@tonic-gate (void) printf("%-9s", ac_groups[g].ag_name);
2277c478bd9Sstevel@tonic-gate (void) printf("%s", id2name(ac_groups[g].ag_mem[0], type));
2287c478bd9Sstevel@tonic-gate for (r = 1; (id = ac_groups[g].ag_mem[r]) != AC_NONE; r++)
2297c478bd9Sstevel@tonic-gate (void) printf(",%s", id2name(id, type));
2307c478bd9Sstevel@tonic-gate (void) printf("\n");
2317c478bd9Sstevel@tonic-gate }
2327c478bd9Sstevel@tonic-gate }
2337c478bd9Sstevel@tonic-gate
2347c478bd9Sstevel@tonic-gate
2357c478bd9Sstevel@tonic-gate /*
2367c478bd9Sstevel@tonic-gate * this function prints the list of resource groups and their members
2377c478bd9Sstevel@tonic-gate */
2387c478bd9Sstevel@tonic-gate void
printgroups(int type)2397c478bd9Sstevel@tonic-gate printgroups(int type)
2407c478bd9Sstevel@tonic-gate {
2417c478bd9Sstevel@tonic-gate int header = 0;
2427c478bd9Sstevel@tonic-gate
243*da14cebeSEric Cheng if ((type & AC_PROC) && (type & AC_TASK) && (type & AC_FLOW) &&
244*da14cebeSEric Cheng (type & AC_NET)) {
2457c478bd9Sstevel@tonic-gate header = 1;
246*da14cebeSEric Cheng }
2477c478bd9Sstevel@tonic-gate if (type & AC_PROC) {
2487c478bd9Sstevel@tonic-gate if (header == 1)
2497c478bd9Sstevel@tonic-gate (void) printf("process:\n");
2507c478bd9Sstevel@tonic-gate printgroup(AC_PROC);
2517c478bd9Sstevel@tonic-gate }
2527c478bd9Sstevel@tonic-gate if (type & AC_TASK) {
2537c478bd9Sstevel@tonic-gate if (header == 1)
2547c478bd9Sstevel@tonic-gate (void) printf("task:\n");
2557c478bd9Sstevel@tonic-gate printgroup(AC_TASK);
2567c478bd9Sstevel@tonic-gate }
2577c478bd9Sstevel@tonic-gate if (type & AC_FLOW) {
2587c478bd9Sstevel@tonic-gate if (header == 1)
2597c478bd9Sstevel@tonic-gate (void) printf("flow:\n");
2607c478bd9Sstevel@tonic-gate printgroup(AC_FLOW);
2617c478bd9Sstevel@tonic-gate }
262*da14cebeSEric Cheng if (type & AC_NET) {
263*da14cebeSEric Cheng if (header == 1)
264*da14cebeSEric Cheng (void) printf("net:\n");
265*da14cebeSEric Cheng printgroup(AC_NET);
266*da14cebeSEric Cheng }
2677c478bd9Sstevel@tonic-gate }
2687c478bd9Sstevel@tonic-gate
2697c478bd9Sstevel@tonic-gate /*
2707c478bd9Sstevel@tonic-gate * this function sets the state of the particular resource
2717c478bd9Sstevel@tonic-gate */
2727c478bd9Sstevel@tonic-gate static void
resset(ac_res_t * res,int id,int state)2737c478bd9Sstevel@tonic-gate resset(ac_res_t *res, int id, int state)
2747c478bd9Sstevel@tonic-gate {
2757c478bd9Sstevel@tonic-gate ac_res_t *resp;
2767c478bd9Sstevel@tonic-gate resp = (ac_res_t *)((uintptr_t)res + (sizeof (ac_res_t) * (id - 1)));
2777c478bd9Sstevel@tonic-gate resp->ar_state = state;
2787c478bd9Sstevel@tonic-gate resp->ar_id = id;
2797c478bd9Sstevel@tonic-gate }
2807c478bd9Sstevel@tonic-gate
2817c478bd9Sstevel@tonic-gate /*
2827c478bd9Sstevel@tonic-gate * this function gets the state of the particular resource
2837c478bd9Sstevel@tonic-gate */
2847c478bd9Sstevel@tonic-gate static int
resget(ac_res_t * res,int id)2857c478bd9Sstevel@tonic-gate resget(ac_res_t *res, int id)
2867c478bd9Sstevel@tonic-gate {
2877c478bd9Sstevel@tonic-gate ac_res_t *resp;
2887c478bd9Sstevel@tonic-gate resp = (ac_res_t *)((uintptr_t)res + (sizeof (ac_res_t) * (id - 1)));
2897c478bd9Sstevel@tonic-gate return (resp->ar_state);
2907c478bd9Sstevel@tonic-gate }
2917c478bd9Sstevel@tonic-gate
2927c478bd9Sstevel@tonic-gate /*
2937c478bd9Sstevel@tonic-gate * this function converts a string of resources into a buffer which then
2947c478bd9Sstevel@tonic-gate * can be used for acctctl() system call
2957c478bd9Sstevel@tonic-gate */
2967c478bd9Sstevel@tonic-gate void
str2buf(ac_res_t * buf,char * str,int state,int type)2977c478bd9Sstevel@tonic-gate str2buf(ac_res_t *buf, char *str, int state, int type)
2987c478bd9Sstevel@tonic-gate {
2997c478bd9Sstevel@tonic-gate int i, j, id, ok;
3007c478bd9Sstevel@tonic-gate char *p, *g, *copy;
3017c478bd9Sstevel@tonic-gate
3027c478bd9Sstevel@tonic-gate if (strcmp(str, AC_STR_NONE) == 0)
3037c478bd9Sstevel@tonic-gate return;
3047c478bd9Sstevel@tonic-gate /*
3057c478bd9Sstevel@tonic-gate * Take a lap through str, processing resources, modifying buf copy
3067c478bd9Sstevel@tonic-gate * as appropriate and making sure that all resource names are valid.
3077c478bd9Sstevel@tonic-gate */
3087c478bd9Sstevel@tonic-gate if ((copy = malloc(strlen(str) + 1)) == NULL)
3097c478bd9Sstevel@tonic-gate die(gettext("not enough memory\n"));
3107c478bd9Sstevel@tonic-gate (void) memcpy(copy, str, strlen(str) + 1);
3117c478bd9Sstevel@tonic-gate p = strtok(copy, ", ");
3127c478bd9Sstevel@tonic-gate while (p != NULL) {
3137c478bd9Sstevel@tonic-gate /*
3147c478bd9Sstevel@tonic-gate * check if str contains any resource groups
3157c478bd9Sstevel@tonic-gate */
3167c478bd9Sstevel@tonic-gate for (ok = 0, i = 0; (g = ac_groups[i].ag_name) != NULL; i++) {
3177c478bd9Sstevel@tonic-gate if (strcmp(p, g) == 0 && ac_groups[i].ag_type == type) {
3187c478bd9Sstevel@tonic-gate for (j = 0; (id = ac_groups[i].ag_mem[j]) !=
3197c478bd9Sstevel@tonic-gate AC_NONE; j++)
3207c478bd9Sstevel@tonic-gate resset(buf, id, state);
3217c478bd9Sstevel@tonic-gate ok = 1;
3227c478bd9Sstevel@tonic-gate break;
3237c478bd9Sstevel@tonic-gate }
3247c478bd9Sstevel@tonic-gate }
3257c478bd9Sstevel@tonic-gate if (ok == 0) {
3267c478bd9Sstevel@tonic-gate id = name2id(p, type);
3277c478bd9Sstevel@tonic-gate if (id > 0)
3287c478bd9Sstevel@tonic-gate resset(buf, id, state);
3297c478bd9Sstevel@tonic-gate else if (id == 0)
3307c478bd9Sstevel@tonic-gate die(gettext("unknown %s resource: %s\n"),
331074e084fSml ac_type_name(type), p);
3327c478bd9Sstevel@tonic-gate }
3337c478bd9Sstevel@tonic-gate p = strtok(NULL, ", ");
3347c478bd9Sstevel@tonic-gate }
3357c478bd9Sstevel@tonic-gate free(copy);
3367c478bd9Sstevel@tonic-gate }
3377c478bd9Sstevel@tonic-gate
3387c478bd9Sstevel@tonic-gate /*
3397c478bd9Sstevel@tonic-gate * this function converts a buffer into a string of resource names.
3407c478bd9Sstevel@tonic-gate * state (on/off) for resources of interest is selected by the third argument.
3417c478bd9Sstevel@tonic-gate * accounting type is selected by the fourth argument.
3427c478bd9Sstevel@tonic-gate * it is caller's responsibility to free the allocated string buffer.
3437c478bd9Sstevel@tonic-gate */
3447c478bd9Sstevel@tonic-gate char *
buf2str(ac_res_t * buffer,size_t bufsz,int state,int type)3457c478bd9Sstevel@tonic-gate buf2str(ac_res_t *buffer, size_t bufsz, int state, int type)
3467c478bd9Sstevel@tonic-gate {
3477c478bd9Sstevel@tonic-gate int i, j, ok, id;
3487c478bd9Sstevel@tonic-gate char *str, *g;
3497c478bd9Sstevel@tonic-gate ac_res_t *buf, *cur;
3507c478bd9Sstevel@tonic-gate
3517c478bd9Sstevel@tonic-gate if ((buf = malloc(bufsz)) == NULL ||
3527c478bd9Sstevel@tonic-gate (str = malloc(MAXRESLEN)) == NULL)
3537c478bd9Sstevel@tonic-gate die(gettext("not enough memory\n"));
3547c478bd9Sstevel@tonic-gate (void) memset(str, 0, MAXRESLEN);
3557c478bd9Sstevel@tonic-gate (void) memcpy(buf, buffer, bufsz);
3567c478bd9Sstevel@tonic-gate /*
3577c478bd9Sstevel@tonic-gate * check if buf has any resource groups in it
3587c478bd9Sstevel@tonic-gate */
3597c478bd9Sstevel@tonic-gate for (i = 0; (g = ac_groups[i].ag_name) != NULL; i++) {
3607c478bd9Sstevel@tonic-gate if (ac_groups[i].ag_type != type)
3617c478bd9Sstevel@tonic-gate continue;
3627c478bd9Sstevel@tonic-gate for (j = 0; (id = ac_groups[i].ag_mem[j]) != AC_NONE; j++) {
3637c478bd9Sstevel@tonic-gate ok = 1;
3647c478bd9Sstevel@tonic-gate if (resget(buf, id) != state) {
3657c478bd9Sstevel@tonic-gate ok = 0;
3667c478bd9Sstevel@tonic-gate break;
3677c478bd9Sstevel@tonic-gate }
3687c478bd9Sstevel@tonic-gate }
3697c478bd9Sstevel@tonic-gate if (ok) { /* buf contains this resource group */
3707c478bd9Sstevel@tonic-gate if (strlen(str) != 0)
3717c478bd9Sstevel@tonic-gate (void) strcat(str, ",");
3727c478bd9Sstevel@tonic-gate (void) strcat(str, g);
3737c478bd9Sstevel@tonic-gate for (j = 0; (id = ac_groups[i].ag_mem[j]) != AC_NONE;
3747c478bd9Sstevel@tonic-gate j++)
3757c478bd9Sstevel@tonic-gate resset(buf, id,
3767c478bd9Sstevel@tonic-gate state == AC_ON ? AC_OFF : AC_ON);
3777c478bd9Sstevel@tonic-gate ok = 0;
3787c478bd9Sstevel@tonic-gate }
3797c478bd9Sstevel@tonic-gate }
3807c478bd9Sstevel@tonic-gate /*
3817c478bd9Sstevel@tonic-gate * browse through the rest of the buf for all remaining resources
3827c478bd9Sstevel@tonic-gate * that are not a part of any groups
3837c478bd9Sstevel@tonic-gate */
3847c478bd9Sstevel@tonic-gate for (cur = buf; cur->ar_id != AC_NONE; cur++) {
3857c478bd9Sstevel@tonic-gate if (cur->ar_state == state) {
3867c478bd9Sstevel@tonic-gate if (strlen(str) != 0)
3877c478bd9Sstevel@tonic-gate (void) strcat(str, ",");
3887c478bd9Sstevel@tonic-gate if (id2name(cur->ar_id, type) == NULL)
3897c478bd9Sstevel@tonic-gate die(gettext("unknown %s resource id (%d)\n"),
390074e084fSml ac_type_name(type), cur->ar_id);
3917c478bd9Sstevel@tonic-gate (void) strcat(str, id2name(cur->ar_id, type));
3927c478bd9Sstevel@tonic-gate }
3937c478bd9Sstevel@tonic-gate }
3947c478bd9Sstevel@tonic-gate if (strlen(str) == 0)
3957c478bd9Sstevel@tonic-gate (void) strcpy(str, AC_STR_NONE);
3967c478bd9Sstevel@tonic-gate free(buf);
3977c478bd9Sstevel@tonic-gate return (str);
3987c478bd9Sstevel@tonic-gate }
399