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 5074e084fSml93401 * Common Development and Distribution License (the "License"). 6074e084fSml93401 * 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 /* 22074e084fSml93401 * 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 897c478bd9Sstevel@tonic-gate /* 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 116*da14cebeSEric Cheng /* 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 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 * 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 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 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 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 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 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"), 331074e084fSml93401 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 * 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"), 390074e084fSml93401 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