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 /* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */ 23 /* All Rights Reserved */ 24 25 26 /* 27 * Copyright 2005 Sun Microsystems, Inc. All rights reserved. 28 * Use is subject to license terms. 29 */ 30 31 /* 32 * acctprc 33 * reads std. input (acct.h format), 34 * writes std. output (tacct format) 35 * sorted by uid 36 * adds login names 37 */ 38 39 #include <stdio.h> 40 #include <sys/types.h> 41 #include <sys/param.h> 42 #include "acctdef.h" 43 #include <sys/acct.h> 44 #include <string.h> 45 #include <search.h> 46 #include <stdlib.h> 47 48 struct acct ab; 49 struct ptmp pb; 50 struct tacct tb; 51 52 struct utab { 53 uid_t ut_uid; 54 char ut_name[NSZ]; 55 float ut_cpu[2]; /* cpu time (mins) */ 56 float ut_kcore[2]; /* kcore-mins */ 57 long ut_pc; /* # processes */ 58 } * ub; 59 static int usize; 60 void **root = NULL; 61 62 void output(void); 63 void enter(struct ptmp *); 64 65 int 66 main(int argc, char **argv) 67 { 68 long elaps[2]; 69 ulong_t etime, stime; 70 unsigned long mem; 71 #ifdef uts 72 float expand(); 73 #else 74 ulong_t expand(); 75 #endif 76 77 while (fread(&ab, sizeof(ab), 1, stdin) == 1) { 78 if (!MYKIND(ab.ac_flag)) 79 continue; 80 pb.pt_uid = ab.ac_uid; 81 CPYN(pb.pt_name, NULL); 82 /* 83 * approximate cpu P/NP split as same as elapsed time 84 */ 85 if ((etime = SECS(expand(ab.ac_etime))) == 0) 86 etime = 1; 87 stime = expand(ab.ac_stime) + expand(ab.ac_utime); 88 mem = expand(ab.ac_mem); 89 if(pnpsplit(ab.ac_btime, etime, elaps) == 0) { 90 fprintf(stderr, "acctprc: could not calculate prime/non-prime hours\n"); 91 92 exit(1); 93 } 94 pb.pt_cpu[0] = (double)stime * (double)elaps[0] / etime; 95 pb.pt_cpu[1] = (stime > pb.pt_cpu[0])? stime - pb.pt_cpu[0] : 0; 96 pb.pt_cpu[1] = stime - pb.pt_cpu[0]; 97 if (stime) 98 pb.pt_mem = (mem + stime - 1) / stime; 99 else 100 pb.pt_mem = 0; /* unlikely */ 101 enter(&pb); 102 } 103 output(); 104 exit(0); 105 } 106 107 int node_compare(const void *node1, const void *node2) 108 { 109 if (((const struct utab *)node1)->ut_uid > \ 110 ((const struct utab *)node2)->ut_uid) 111 return(1); 112 else if (((const struct utab *)node1)->ut_uid < \ 113 ((const struct utab *)node2)->ut_uid) 114 return(-1); 115 else return(0); 116 } 117 118 void 119 enter(struct ptmp *p) 120 { 121 double memk; 122 struct utab **pt; 123 124 if ((ub = (struct utab *)malloc(sizeof (struct utab))) == NULL) { 125 fprintf(stderr, "acctprc: malloc fail!\n"); 126 exit(2); 127 } 128 129 ub->ut_uid = p->pt_uid; 130 CPYN(ub->ut_name, p->pt_name); 131 ub->ut_cpu[0] = MINT(p->pt_cpu[0]); 132 ub->ut_cpu[1] = MINT(p->pt_cpu[1]); 133 memk = KCORE(pb.pt_mem); 134 ub->ut_kcore[0] = memk * MINT(p->pt_cpu[0]); 135 ub->ut_kcore[1] = memk * MINT(p->pt_cpu[1]); 136 ub->ut_pc = 1; 137 138 if (*(pt = (struct utab **)tsearch((void *)ub, (void **)&root, \ 139 node_compare)) == NULL) { 140 fprintf(stderr, "Not enough space available to build tree\n"); 141 exit(1); 142 } 143 144 if (*pt != ub) { 145 (*pt)->ut_cpu[0] += MINT(p->pt_cpu[0]); 146 (*pt)->ut_cpu[1] += MINT(p->pt_cpu[1]); 147 (*pt)->ut_kcore[0] += memk * MINT(p->pt_cpu[0]); 148 (*pt)->ut_kcore[1] += memk * MINT(p->pt_cpu[1]); 149 (*pt)->ut_pc++; 150 free(ub); 151 } 152 } 153 154 void print_node(const void *node, VISIT order, int level) { 155 156 if (order == postorder || order == leaf) { 157 tb.ta_uid = (*(struct utab **)node)->ut_uid; 158 CPYN(tb.ta_name, (char *)uidtonam((*(struct utab **)node)->ut_uid)); 159 tb.ta_cpu[0] = (*(struct utab **)node)->ut_cpu[0]; 160 tb.ta_cpu[1] = (*(struct utab **)node)->ut_cpu[1]; 161 tb.ta_kcore[0] = (*(struct utab **)node)->ut_kcore[0]; 162 tb.ta_kcore[1] = (*(struct utab **)node)->ut_kcore[1]; 163 tb.ta_pc = (*(struct utab **)node)->ut_pc; 164 fwrite(&tb, sizeof(tb), 1, stdout); 165 } 166 } 167 168 void 169 output(void) 170 { 171 twalk((struct utab *)root, print_node); 172 } 173