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 5*074e084fSml93401 * Common Development and Distribution License (the "License"). 6*074e084fSml93401 * 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 /* 22*074e084fSml93401 * 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 #pragma ident "%Z%%M% %I% %E% SMI" 277c478bd9Sstevel@tonic-gate 287c478bd9Sstevel@tonic-gate #include <stdlib.h> 297c478bd9Sstevel@tonic-gate #include <stdio.h> 307c478bd9Sstevel@tonic-gate #include <libintl.h> 317c478bd9Sstevel@tonic-gate #include <string.h> 327c478bd9Sstevel@tonic-gate #include <sys/acctctl.h> 337c478bd9Sstevel@tonic-gate 347c478bd9Sstevel@tonic-gate #include "utils.h" 357c478bd9Sstevel@tonic-gate #include "aconf.h" 367c478bd9Sstevel@tonic-gate #include "res.h" 377c478bd9Sstevel@tonic-gate 387c478bd9Sstevel@tonic-gate /* 397c478bd9Sstevel@tonic-gate * resource names 407c478bd9Sstevel@tonic-gate */ 417c478bd9Sstevel@tonic-gate static ac_resname_t ac_names[] = { 427c478bd9Sstevel@tonic-gate /* 437c478bd9Sstevel@tonic-gate * Process accounting resources 447c478bd9Sstevel@tonic-gate */ 457c478bd9Sstevel@tonic-gate { AC_PROC, AC_PROC_PID, "pid" }, 467c478bd9Sstevel@tonic-gate { AC_PROC, AC_PROC_UID, "uid" }, 477c478bd9Sstevel@tonic-gate { AC_PROC, AC_PROC_GID, "gid" }, 487c478bd9Sstevel@tonic-gate { AC_PROC, AC_PROC_PROJID, "projid" }, 497c478bd9Sstevel@tonic-gate { AC_PROC, AC_PROC_TASKID, "taskid" }, 507c478bd9Sstevel@tonic-gate { AC_PROC, AC_PROC_CPU, "cpu" }, 517c478bd9Sstevel@tonic-gate { AC_PROC, AC_PROC_TIME, "time" }, 527c478bd9Sstevel@tonic-gate { AC_PROC, AC_PROC_COMMAND, "command" }, 537c478bd9Sstevel@tonic-gate { AC_PROC, AC_PROC_TTY, "tty" }, 547c478bd9Sstevel@tonic-gate { AC_PROC, AC_PROC_HOSTNAME, "host" }, 557c478bd9Sstevel@tonic-gate { AC_PROC, AC_PROC_MICROSTATE, "mstate" }, 567c478bd9Sstevel@tonic-gate { AC_PROC, AC_PROC_FLAG, "flag" }, 577c478bd9Sstevel@tonic-gate { AC_PROC, AC_PROC_ANCPID, "ancpid" }, 587c478bd9Sstevel@tonic-gate { AC_PROC, AC_PROC_WAIT_STATUS, "wait-status" }, 597c478bd9Sstevel@tonic-gate { AC_PROC, AC_PROC_ZONENAME, "zone" }, 607c478bd9Sstevel@tonic-gate { AC_PROC, AC_PROC_MEM, "memory" }, 617c478bd9Sstevel@tonic-gate 627c478bd9Sstevel@tonic-gate /* 637c478bd9Sstevel@tonic-gate * Task accounting resources 647c478bd9Sstevel@tonic-gate */ 657c478bd9Sstevel@tonic-gate { AC_TASK, AC_TASK_TASKID, "taskid" }, 667c478bd9Sstevel@tonic-gate { AC_TASK, AC_TASK_PROJID, "projid" }, 677c478bd9Sstevel@tonic-gate { AC_TASK, AC_TASK_CPU, "cpu" }, 687c478bd9Sstevel@tonic-gate { AC_TASK, AC_TASK_TIME, "time" }, 697c478bd9Sstevel@tonic-gate { AC_TASK, AC_TASK_HOSTNAME, "host" }, 707c478bd9Sstevel@tonic-gate { AC_TASK, AC_TASK_MICROSTATE, "mstate" }, 717c478bd9Sstevel@tonic-gate { AC_TASK, AC_TASK_ANCTASKID, "anctaskid" }, 727c478bd9Sstevel@tonic-gate { AC_TASK, AC_TASK_ZONENAME, "zone" }, 737c478bd9Sstevel@tonic-gate 747c478bd9Sstevel@tonic-gate /* 757c478bd9Sstevel@tonic-gate * Flow accounting resources 767c478bd9Sstevel@tonic-gate */ 777c478bd9Sstevel@tonic-gate { AC_FLOW, AC_FLOW_SADDR, "saddr" }, 787c478bd9Sstevel@tonic-gate { AC_FLOW, AC_FLOW_DADDR, "daddr" }, 797c478bd9Sstevel@tonic-gate { AC_FLOW, AC_FLOW_SPORT, "sport" }, 807c478bd9Sstevel@tonic-gate { AC_FLOW, AC_FLOW_DPORT, "dport" }, 817c478bd9Sstevel@tonic-gate { AC_FLOW, AC_FLOW_PROTOCOL, "proto" }, 827c478bd9Sstevel@tonic-gate { AC_FLOW, AC_FLOW_DSFIELD, "dsfield" }, 837c478bd9Sstevel@tonic-gate { AC_FLOW, AC_FLOW_NBYTES, "nbytes" }, 847c478bd9Sstevel@tonic-gate { AC_FLOW, AC_FLOW_NPKTS, "npkts" }, 857c478bd9Sstevel@tonic-gate { AC_FLOW, AC_FLOW_CTIME, "ctime" }, 867c478bd9Sstevel@tonic-gate { AC_FLOW, AC_FLOW_LSEEN, "lseen" }, 877c478bd9Sstevel@tonic-gate { AC_FLOW, AC_FLOW_PROJID, "projid" }, 887c478bd9Sstevel@tonic-gate { AC_FLOW, AC_FLOW_UID, "uid" }, 897c478bd9Sstevel@tonic-gate { AC_FLOW, AC_FLOW_ANAME, "action" }, 907c478bd9Sstevel@tonic-gate 917c478bd9Sstevel@tonic-gate /* 927c478bd9Sstevel@tonic-gate * These are included for compatibility with old acctadm that 937c478bd9Sstevel@tonic-gate * didn't have resource groups for individual accounting types. 947c478bd9Sstevel@tonic-gate * It was possible to have resource "pid" enabled for task 957c478bd9Sstevel@tonic-gate * accounting even though we couldn't actually track it. 967c478bd9Sstevel@tonic-gate */ 977c478bd9Sstevel@tonic-gate { AC_TASK, AC_NONE, "pid" }, 987c478bd9Sstevel@tonic-gate { AC_TASK, AC_NONE, "uid" }, 997c478bd9Sstevel@tonic-gate { AC_TASK, AC_NONE, "gid" }, 1007c478bd9Sstevel@tonic-gate { AC_TASK, AC_NONE, "command" }, 1017c478bd9Sstevel@tonic-gate { AC_TASK, AC_NONE, "tty" }, 1027c478bd9Sstevel@tonic-gate { AC_TASK, AC_NONE, "flag" }, 1037c478bd9Sstevel@tonic-gate 1047c478bd9Sstevel@tonic-gate { AC_NONE, AC_NONE, NULL } 1057c478bd9Sstevel@tonic-gate }; 1067c478bd9Sstevel@tonic-gate 1077c478bd9Sstevel@tonic-gate /* 1087c478bd9Sstevel@tonic-gate * resource groups 1097c478bd9Sstevel@tonic-gate */ 1107c478bd9Sstevel@tonic-gate static ac_group_t ac_groups[] = { 1117c478bd9Sstevel@tonic-gate { AC_PROC, "extended", 1127c478bd9Sstevel@tonic-gate { AC_PROC_PID, AC_PROC_UID, AC_PROC_GID, AC_PROC_CPU, 1137c478bd9Sstevel@tonic-gate AC_PROC_TIME, AC_PROC_COMMAND, AC_PROC_TTY, AC_PROC_PROJID, 1147c478bd9Sstevel@tonic-gate AC_PROC_TASKID, AC_PROC_ANCPID, AC_PROC_WAIT_STATUS, 1157c478bd9Sstevel@tonic-gate AC_PROC_ZONENAME, AC_PROC_FLAG, AC_PROC_MEM, 1167c478bd9Sstevel@tonic-gate AC_PROC_MICROSTATE, AC_NONE } }, 1177c478bd9Sstevel@tonic-gate { AC_PROC, "basic", 1187c478bd9Sstevel@tonic-gate { AC_PROC_PID, AC_PROC_UID, AC_PROC_GID, AC_PROC_CPU, 1197c478bd9Sstevel@tonic-gate AC_PROC_TIME, AC_PROC_COMMAND, AC_PROC_TTY, AC_PROC_FLAG, 1207c478bd9Sstevel@tonic-gate AC_NONE } }, 1217c478bd9Sstevel@tonic-gate { AC_TASK, "extended", 1227c478bd9Sstevel@tonic-gate { AC_TASK_TASKID, AC_TASK_PROJID, AC_TASK_CPU, AC_TASK_TIME, 1237c478bd9Sstevel@tonic-gate AC_TASK_HOSTNAME, AC_TASK_MICROSTATE, AC_TASK_ANCTASKID, 1247c478bd9Sstevel@tonic-gate AC_TASK_ZONENAME, AC_NONE } }, 1257c478bd9Sstevel@tonic-gate { AC_TASK, "basic", 1267c478bd9Sstevel@tonic-gate { AC_TASK_TASKID, AC_TASK_PROJID, AC_TASK_CPU, AC_TASK_TIME, 1277c478bd9Sstevel@tonic-gate AC_NONE } }, 1287c478bd9Sstevel@tonic-gate { AC_FLOW, "extended", 1297c478bd9Sstevel@tonic-gate { AC_FLOW_SADDR, AC_FLOW_DADDR, AC_FLOW_SPORT, AC_FLOW_DPORT, 1307c478bd9Sstevel@tonic-gate AC_FLOW_PROTOCOL, AC_FLOW_DSFIELD, AC_FLOW_NBYTES, 1317c478bd9Sstevel@tonic-gate AC_FLOW_NPKTS, AC_FLOW_ANAME, AC_FLOW_CTIME, AC_FLOW_LSEEN, 1327c478bd9Sstevel@tonic-gate AC_FLOW_PROJID, AC_FLOW_UID, AC_NONE } }, 1337c478bd9Sstevel@tonic-gate { AC_FLOW, "basic", 1347c478bd9Sstevel@tonic-gate { AC_FLOW_SADDR, AC_FLOW_DADDR, AC_FLOW_SPORT, AC_FLOW_DPORT, 1357c478bd9Sstevel@tonic-gate AC_FLOW_PROTOCOL, AC_FLOW_NBYTES, AC_FLOW_NPKTS, AC_FLOW_ANAME, 1367c478bd9Sstevel@tonic-gate AC_NONE } }, 1377c478bd9Sstevel@tonic-gate { AC_NONE, NULL, 1387c478bd9Sstevel@tonic-gate { AC_NONE } } 1397c478bd9Sstevel@tonic-gate }; 1407c478bd9Sstevel@tonic-gate 1417c478bd9Sstevel@tonic-gate /* 1427c478bd9Sstevel@tonic-gate * this function returns the id of the named resource 1437c478bd9Sstevel@tonic-gate */ 1447c478bd9Sstevel@tonic-gate static int 1457c478bd9Sstevel@tonic-gate name2id(char *name, int type) 1467c478bd9Sstevel@tonic-gate { 1477c478bd9Sstevel@tonic-gate ac_resname_t *acname = ac_names; 1487c478bd9Sstevel@tonic-gate while (acname->ar_type != AC_NONE) { 1497c478bd9Sstevel@tonic-gate if (acname->ar_type == type && 1507c478bd9Sstevel@tonic-gate strcmp(acname->ar_name, name) == 0) { 1517c478bd9Sstevel@tonic-gate if (acname->ar_id == AC_NONE) 1527c478bd9Sstevel@tonic-gate /* 1537c478bd9Sstevel@tonic-gate * For compatibility with older versions. 1547c478bd9Sstevel@tonic-gate */ 1557c478bd9Sstevel@tonic-gate return (-1); 1567c478bd9Sstevel@tonic-gate else 1577c478bd9Sstevel@tonic-gate return (acname->ar_id); 1587c478bd9Sstevel@tonic-gate } 1597c478bd9Sstevel@tonic-gate acname++; 1607c478bd9Sstevel@tonic-gate } 1617c478bd9Sstevel@tonic-gate return (0); 1627c478bd9Sstevel@tonic-gate } 1637c478bd9Sstevel@tonic-gate 1647c478bd9Sstevel@tonic-gate /* 1657c478bd9Sstevel@tonic-gate * this function gives name of the resource by its id 1667c478bd9Sstevel@tonic-gate */ 1677c478bd9Sstevel@tonic-gate static char * 1687c478bd9Sstevel@tonic-gate id2name(int id, int type) 1697c478bd9Sstevel@tonic-gate { 1707c478bd9Sstevel@tonic-gate ac_resname_t *acname = ac_names; 1717c478bd9Sstevel@tonic-gate while (acname->ar_id != AC_NONE) { 1727c478bd9Sstevel@tonic-gate if (acname->ar_type == type && 1737c478bd9Sstevel@tonic-gate acname->ar_id == id) 1747c478bd9Sstevel@tonic-gate return (acname->ar_name); 1757c478bd9Sstevel@tonic-gate acname++; 1767c478bd9Sstevel@tonic-gate } 1777c478bd9Sstevel@tonic-gate return (NULL); 1787c478bd9Sstevel@tonic-gate } 1797c478bd9Sstevel@tonic-gate 1807c478bd9Sstevel@tonic-gate static void 1817c478bd9Sstevel@tonic-gate printgroup(int type) 1827c478bd9Sstevel@tonic-gate { 1837c478bd9Sstevel@tonic-gate int r, g, id; 1847c478bd9Sstevel@tonic-gate 1857c478bd9Sstevel@tonic-gate for (g = 0; ac_groups[g].ag_type != AC_NONE; g++) { 1867c478bd9Sstevel@tonic-gate if (ac_groups[g].ag_type != type) 1877c478bd9Sstevel@tonic-gate continue; 1887c478bd9Sstevel@tonic-gate (void) printf("%-9s", ac_groups[g].ag_name); 1897c478bd9Sstevel@tonic-gate (void) printf("%s", id2name(ac_groups[g].ag_mem[0], type)); 1907c478bd9Sstevel@tonic-gate for (r = 1; (id = ac_groups[g].ag_mem[r]) != AC_NONE; r++) 1917c478bd9Sstevel@tonic-gate (void) printf(",%s", id2name(id, type)); 1927c478bd9Sstevel@tonic-gate (void) printf("\n"); 1937c478bd9Sstevel@tonic-gate } 1947c478bd9Sstevel@tonic-gate } 1957c478bd9Sstevel@tonic-gate 1967c478bd9Sstevel@tonic-gate 1977c478bd9Sstevel@tonic-gate /* 1987c478bd9Sstevel@tonic-gate * this function prints the list of resource groups and their members 1997c478bd9Sstevel@tonic-gate */ 2007c478bd9Sstevel@tonic-gate void 2017c478bd9Sstevel@tonic-gate printgroups(int type) 2027c478bd9Sstevel@tonic-gate { 2037c478bd9Sstevel@tonic-gate int header = 0; 2047c478bd9Sstevel@tonic-gate 2057c478bd9Sstevel@tonic-gate if ((type & AC_PROC) && (type & AC_TASK) && (type & AC_FLOW)) 2067c478bd9Sstevel@tonic-gate header = 1; 2077c478bd9Sstevel@tonic-gate 2087c478bd9Sstevel@tonic-gate if (type & AC_PROC) { 2097c478bd9Sstevel@tonic-gate if (header == 1) 2107c478bd9Sstevel@tonic-gate (void) printf("process:\n"); 2117c478bd9Sstevel@tonic-gate printgroup(AC_PROC); 2127c478bd9Sstevel@tonic-gate } 2137c478bd9Sstevel@tonic-gate if (type & AC_TASK) { 2147c478bd9Sstevel@tonic-gate if (header == 1) 2157c478bd9Sstevel@tonic-gate (void) printf("task:\n"); 2167c478bd9Sstevel@tonic-gate printgroup(AC_TASK); 2177c478bd9Sstevel@tonic-gate } 2187c478bd9Sstevel@tonic-gate if (type & AC_FLOW) { 2197c478bd9Sstevel@tonic-gate if (header == 1) 2207c478bd9Sstevel@tonic-gate (void) printf("flow:\n"); 2217c478bd9Sstevel@tonic-gate printgroup(AC_FLOW); 2227c478bd9Sstevel@tonic-gate } 2237c478bd9Sstevel@tonic-gate } 2247c478bd9Sstevel@tonic-gate 2257c478bd9Sstevel@tonic-gate /* 2267c478bd9Sstevel@tonic-gate * this function sets the state of the particular resource 2277c478bd9Sstevel@tonic-gate */ 2287c478bd9Sstevel@tonic-gate static void 2297c478bd9Sstevel@tonic-gate resset(ac_res_t *res, int id, int state) 2307c478bd9Sstevel@tonic-gate { 2317c478bd9Sstevel@tonic-gate ac_res_t *resp; 2327c478bd9Sstevel@tonic-gate resp = (ac_res_t *)((uintptr_t)res + (sizeof (ac_res_t) * (id - 1))); 2337c478bd9Sstevel@tonic-gate resp->ar_state = state; 2347c478bd9Sstevel@tonic-gate resp->ar_id = id; 2357c478bd9Sstevel@tonic-gate } 2367c478bd9Sstevel@tonic-gate 2377c478bd9Sstevel@tonic-gate /* 2387c478bd9Sstevel@tonic-gate * this function gets the state of the particular resource 2397c478bd9Sstevel@tonic-gate */ 2407c478bd9Sstevel@tonic-gate static int 2417c478bd9Sstevel@tonic-gate resget(ac_res_t *res, int id) 2427c478bd9Sstevel@tonic-gate { 2437c478bd9Sstevel@tonic-gate ac_res_t *resp; 2447c478bd9Sstevel@tonic-gate resp = (ac_res_t *)((uintptr_t)res + (sizeof (ac_res_t) * (id - 1))); 2457c478bd9Sstevel@tonic-gate return (resp->ar_state); 2467c478bd9Sstevel@tonic-gate } 2477c478bd9Sstevel@tonic-gate 2487c478bd9Sstevel@tonic-gate /* 2497c478bd9Sstevel@tonic-gate * this function converts a string of resources into a buffer which then 2507c478bd9Sstevel@tonic-gate * can be used for acctctl() system call 2517c478bd9Sstevel@tonic-gate */ 2527c478bd9Sstevel@tonic-gate void 2537c478bd9Sstevel@tonic-gate str2buf(ac_res_t *buf, char *str, int state, int type) 2547c478bd9Sstevel@tonic-gate { 2557c478bd9Sstevel@tonic-gate int i, j, id, ok; 2567c478bd9Sstevel@tonic-gate char *p, *g, *copy; 2577c478bd9Sstevel@tonic-gate 2587c478bd9Sstevel@tonic-gate if (strcmp(str, AC_STR_NONE) == 0) 2597c478bd9Sstevel@tonic-gate return; 2607c478bd9Sstevel@tonic-gate /* 2617c478bd9Sstevel@tonic-gate * Take a lap through str, processing resources, modifying buf copy 2627c478bd9Sstevel@tonic-gate * as appropriate and making sure that all resource names are valid. 2637c478bd9Sstevel@tonic-gate */ 2647c478bd9Sstevel@tonic-gate if ((copy = malloc(strlen(str) + 1)) == NULL) 2657c478bd9Sstevel@tonic-gate die(gettext("not enough memory\n")); 2667c478bd9Sstevel@tonic-gate (void) memcpy(copy, str, strlen(str) + 1); 2677c478bd9Sstevel@tonic-gate p = strtok(copy, ", "); 2687c478bd9Sstevel@tonic-gate while (p != NULL) { 2697c478bd9Sstevel@tonic-gate /* 2707c478bd9Sstevel@tonic-gate * check if str contains any resource groups 2717c478bd9Sstevel@tonic-gate */ 2727c478bd9Sstevel@tonic-gate for (ok = 0, i = 0; (g = ac_groups[i].ag_name) != NULL; i++) { 2737c478bd9Sstevel@tonic-gate if (strcmp(p, g) == 0 && ac_groups[i].ag_type == type) { 2747c478bd9Sstevel@tonic-gate for (j = 0; (id = ac_groups[i].ag_mem[j]) != 2757c478bd9Sstevel@tonic-gate AC_NONE; j++) 2767c478bd9Sstevel@tonic-gate resset(buf, id, state); 2777c478bd9Sstevel@tonic-gate ok = 1; 2787c478bd9Sstevel@tonic-gate break; 2797c478bd9Sstevel@tonic-gate } 2807c478bd9Sstevel@tonic-gate } 2817c478bd9Sstevel@tonic-gate if (ok == 0) { 2827c478bd9Sstevel@tonic-gate id = name2id(p, type); 2837c478bd9Sstevel@tonic-gate if (id > 0) 2847c478bd9Sstevel@tonic-gate resset(buf, id, state); 2857c478bd9Sstevel@tonic-gate else if (id == 0) 2867c478bd9Sstevel@tonic-gate die(gettext("unknown %s resource: %s\n"), 287*074e084fSml93401 ac_type_name(type), p); 2887c478bd9Sstevel@tonic-gate } 2897c478bd9Sstevel@tonic-gate p = strtok(NULL, ", "); 2907c478bd9Sstevel@tonic-gate } 2917c478bd9Sstevel@tonic-gate free(copy); 2927c478bd9Sstevel@tonic-gate } 2937c478bd9Sstevel@tonic-gate 2947c478bd9Sstevel@tonic-gate /* 2957c478bd9Sstevel@tonic-gate * this function converts a buffer into a string of resource names. 2967c478bd9Sstevel@tonic-gate * state (on/off) for resources of interest is selected by the third argument. 2977c478bd9Sstevel@tonic-gate * accounting type is selected by the fourth argument. 2987c478bd9Sstevel@tonic-gate * it is caller's responsibility to free the allocated string buffer. 2997c478bd9Sstevel@tonic-gate */ 3007c478bd9Sstevel@tonic-gate char * 3017c478bd9Sstevel@tonic-gate buf2str(ac_res_t *buffer, size_t bufsz, int state, int type) 3027c478bd9Sstevel@tonic-gate { 3037c478bd9Sstevel@tonic-gate int i, j, ok, id; 3047c478bd9Sstevel@tonic-gate char *str, *g; 3057c478bd9Sstevel@tonic-gate ac_res_t *buf, *cur; 3067c478bd9Sstevel@tonic-gate 3077c478bd9Sstevel@tonic-gate if ((buf = malloc(bufsz)) == NULL || 3087c478bd9Sstevel@tonic-gate (str = malloc(MAXRESLEN)) == NULL) 3097c478bd9Sstevel@tonic-gate die(gettext("not enough memory\n")); 3107c478bd9Sstevel@tonic-gate (void) memset(str, 0, MAXRESLEN); 3117c478bd9Sstevel@tonic-gate (void) memcpy(buf, buffer, bufsz); 3127c478bd9Sstevel@tonic-gate /* 3137c478bd9Sstevel@tonic-gate * check if buf has any resource groups in it 3147c478bd9Sstevel@tonic-gate */ 3157c478bd9Sstevel@tonic-gate for (i = 0; (g = ac_groups[i].ag_name) != NULL; i++) { 3167c478bd9Sstevel@tonic-gate if (ac_groups[i].ag_type != type) 3177c478bd9Sstevel@tonic-gate continue; 3187c478bd9Sstevel@tonic-gate for (j = 0; (id = ac_groups[i].ag_mem[j]) != AC_NONE; j++) { 3197c478bd9Sstevel@tonic-gate ok = 1; 3207c478bd9Sstevel@tonic-gate if (resget(buf, id) != state) { 3217c478bd9Sstevel@tonic-gate ok = 0; 3227c478bd9Sstevel@tonic-gate break; 3237c478bd9Sstevel@tonic-gate } 3247c478bd9Sstevel@tonic-gate } 3257c478bd9Sstevel@tonic-gate if (ok) { /* buf contains this resource group */ 3267c478bd9Sstevel@tonic-gate if (strlen(str) != 0) 3277c478bd9Sstevel@tonic-gate (void) strcat(str, ","); 3287c478bd9Sstevel@tonic-gate (void) strcat(str, g); 3297c478bd9Sstevel@tonic-gate for (j = 0; (id = ac_groups[i].ag_mem[j]) != AC_NONE; 3307c478bd9Sstevel@tonic-gate j++) 3317c478bd9Sstevel@tonic-gate resset(buf, id, 3327c478bd9Sstevel@tonic-gate state == AC_ON ? AC_OFF : AC_ON); 3337c478bd9Sstevel@tonic-gate ok = 0; 3347c478bd9Sstevel@tonic-gate } 3357c478bd9Sstevel@tonic-gate } 3367c478bd9Sstevel@tonic-gate /* 3377c478bd9Sstevel@tonic-gate * browse through the rest of the buf for all remaining resources 3387c478bd9Sstevel@tonic-gate * that are not a part of any groups 3397c478bd9Sstevel@tonic-gate */ 3407c478bd9Sstevel@tonic-gate for (cur = buf; cur->ar_id != AC_NONE; cur++) { 3417c478bd9Sstevel@tonic-gate if (cur->ar_state == state) { 3427c478bd9Sstevel@tonic-gate if (strlen(str) != 0) 3437c478bd9Sstevel@tonic-gate (void) strcat(str, ","); 3447c478bd9Sstevel@tonic-gate if (id2name(cur->ar_id, type) == NULL) 3457c478bd9Sstevel@tonic-gate die(gettext("unknown %s resource id (%d)\n"), 346*074e084fSml93401 ac_type_name(type), cur->ar_id); 3477c478bd9Sstevel@tonic-gate (void) strcat(str, id2name(cur->ar_id, type)); 3487c478bd9Sstevel@tonic-gate } 3497c478bd9Sstevel@tonic-gate } 3507c478bd9Sstevel@tonic-gate if (strlen(str) == 0) 3517c478bd9Sstevel@tonic-gate (void) strcpy(str, AC_STR_NONE); 3527c478bd9Sstevel@tonic-gate free(buf); 3537c478bd9Sstevel@tonic-gate return (str); 3547c478bd9Sstevel@tonic-gate } 355