1*7c478bd9Sstevel@tonic-gate /* 2*7c478bd9Sstevel@tonic-gate * CDDL HEADER START 3*7c478bd9Sstevel@tonic-gate * 4*7c478bd9Sstevel@tonic-gate * The contents of this file are subject to the terms of the 5*7c478bd9Sstevel@tonic-gate * Common Development and Distribution License, Version 1.0 only 6*7c478bd9Sstevel@tonic-gate * (the "License"). You may not use this file except in compliance 7*7c478bd9Sstevel@tonic-gate * with the License. 8*7c478bd9Sstevel@tonic-gate * 9*7c478bd9Sstevel@tonic-gate * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 10*7c478bd9Sstevel@tonic-gate * or http://www.opensolaris.org/os/licensing. 11*7c478bd9Sstevel@tonic-gate * See the License for the specific language governing permissions 12*7c478bd9Sstevel@tonic-gate * and limitations under the License. 13*7c478bd9Sstevel@tonic-gate * 14*7c478bd9Sstevel@tonic-gate * When distributing Covered Code, include this CDDL HEADER in each 15*7c478bd9Sstevel@tonic-gate * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 16*7c478bd9Sstevel@tonic-gate * If applicable, add the following below this CDDL HEADER, with the 17*7c478bd9Sstevel@tonic-gate * fields enclosed by brackets "[]" replaced with your own identifying 18*7c478bd9Sstevel@tonic-gate * information: Portions Copyright [yyyy] [name of copyright owner] 19*7c478bd9Sstevel@tonic-gate * 20*7c478bd9Sstevel@tonic-gate * CDDL HEADER END 21*7c478bd9Sstevel@tonic-gate */ 22*7c478bd9Sstevel@tonic-gate /* 23*7c478bd9Sstevel@tonic-gate * Copyright 1998 Sun Microsystems, Inc. All rights reserved. 24*7c478bd9Sstevel@tonic-gate * Use is subject to license terms. 25*7c478bd9Sstevel@tonic-gate */ 26*7c478bd9Sstevel@tonic-gate 27*7c478bd9Sstevel@tonic-gate /* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */ 28*7c478bd9Sstevel@tonic-gate /* All Rights Reserved */ 29*7c478bd9Sstevel@tonic-gate 30*7c478bd9Sstevel@tonic-gate #pragma ident "%Z%%M% %I% %E% SMI" 31*7c478bd9Sstevel@tonic-gate 32*7c478bd9Sstevel@tonic-gate # include <stdio.h> 33*7c478bd9Sstevel@tonic-gate # include <sys/types.h> 34*7c478bd9Sstevel@tonic-gate # include <sys/stat.h> 35*7c478bd9Sstevel@tonic-gate # include <unistd.h> 36*7c478bd9Sstevel@tonic-gate # include "extern.h" 37*7c478bd9Sstevel@tonic-gate # include "misc.h" 38*7c478bd9Sstevel@tonic-gate # include <sac.h> 39*7c478bd9Sstevel@tonic-gate # include "structs.h" 40*7c478bd9Sstevel@tonic-gate 41*7c478bd9Sstevel@tonic-gate # define ADD 0x1 /* -a or other required options seen */ 42*7c478bd9Sstevel@tonic-gate # define REMOVE 0x2 /* -r seen */ 43*7c478bd9Sstevel@tonic-gate # define ENABLE 0x4 /* -e seen */ 44*7c478bd9Sstevel@tonic-gate # define DISABLE 0x8 /* -d seen */ 45*7c478bd9Sstevel@tonic-gate # define PLIST 0x10 /* -l seen */ 46*7c478bd9Sstevel@tonic-gate # define LIST 0x20 /* -L seen */ 47*7c478bd9Sstevel@tonic-gate # define CONFIG 0x40 /* -g seen */ 48*7c478bd9Sstevel@tonic-gate 49*7c478bd9Sstevel@tonic-gate # define U_FLAG 0x1 /* -fu seen */ 50*7c478bd9Sstevel@tonic-gate # define X_FLAG 0x2 /* -fx seen */ 51*7c478bd9Sstevel@tonic-gate 52*7c478bd9Sstevel@tonic-gate /* 53*7c478bd9Sstevel@tonic-gate * functions 54*7c478bd9Sstevel@tonic-gate */ 55*7c478bd9Sstevel@tonic-gate 56*7c478bd9Sstevel@tonic-gate char *pflags(); 57*7c478bd9Sstevel@tonic-gate char *pspec(); 58*7c478bd9Sstevel@tonic-gate struct taglist *find_type(); 59*7c478bd9Sstevel@tonic-gate void usage(); 60*7c478bd9Sstevel@tonic-gate void parseline(); 61*7c478bd9Sstevel@tonic-gate void add_svc(); 62*7c478bd9Sstevel@tonic-gate void rem_svc(); 63*7c478bd9Sstevel@tonic-gate void ed_svc(); 64*7c478bd9Sstevel@tonic-gate void list_svcs(); 65*7c478bd9Sstevel@tonic-gate void doconf(); 66*7c478bd9Sstevel@tonic-gate 67*7c478bd9Sstevel@tonic-gate /* 68*7c478bd9Sstevel@tonic-gate * format of a _pmtab entry - used to hold parsed info 69*7c478bd9Sstevel@tonic-gate */ 70*7c478bd9Sstevel@tonic-gate 71*7c478bd9Sstevel@tonic-gate struct pmtab { 72*7c478bd9Sstevel@tonic-gate char *p_tag; /* service tag */ 73*7c478bd9Sstevel@tonic-gate long p_flags; /* flags */ 74*7c478bd9Sstevel@tonic-gate char *p_id; /* logname to start service as */ 75*7c478bd9Sstevel@tonic-gate char *p_res1; /* reserved field */ 76*7c478bd9Sstevel@tonic-gate char *p_res2; /* reserved field */ 77*7c478bd9Sstevel@tonic-gate char *p_res3; /* reserved field */ 78*7c478bd9Sstevel@tonic-gate char *p_pmspec; /* port monitor specific info */ 79*7c478bd9Sstevel@tonic-gate }; 80*7c478bd9Sstevel@tonic-gate 81*7c478bd9Sstevel@tonic-gate /* 82*7c478bd9Sstevel@tonic-gate * format of a tag list, which is a list of port monitor tags of 83*7c478bd9Sstevel@tonic-gate * a designated type 84*7c478bd9Sstevel@tonic-gate */ 85*7c478bd9Sstevel@tonic-gate 86*7c478bd9Sstevel@tonic-gate struct taglist { 87*7c478bd9Sstevel@tonic-gate struct taglist *t_next; /* next in list */ 88*7c478bd9Sstevel@tonic-gate char t_tag[PMTAGSIZE + 1]; /* PM tag */ 89*7c478bd9Sstevel@tonic-gate char t_type[PMTYPESIZE + 1]; /* PM type */ 90*7c478bd9Sstevel@tonic-gate }; 91*7c478bd9Sstevel@tonic-gate 92*7c478bd9Sstevel@tonic-gate /* 93*7c478bd9Sstevel@tonic-gate * common error messages 94*7c478bd9Sstevel@tonic-gate */ 95*7c478bd9Sstevel@tonic-gate 96*7c478bd9Sstevel@tonic-gate # define NOTPRIV "User not privileged for operation" 97*7c478bd9Sstevel@tonic-gate # define BADINP "Embedded newlines not allowed" 98*7c478bd9Sstevel@tonic-gate 99*7c478bd9Sstevel@tonic-gate int Saferrno; /* internal `errno' for exit */ 100*7c478bd9Sstevel@tonic-gate 101*7c478bd9Sstevel@tonic-gate 102*7c478bd9Sstevel@tonic-gate /* 103*7c478bd9Sstevel@tonic-gate * main - scan args for pmadm and call appropriate handling code 104*7c478bd9Sstevel@tonic-gate */ 105*7c478bd9Sstevel@tonic-gate 106*7c478bd9Sstevel@tonic-gate main(argc, argv) 107*7c478bd9Sstevel@tonic-gate int argc; 108*7c478bd9Sstevel@tonic-gate char *argv[]; 109*7c478bd9Sstevel@tonic-gate { 110*7c478bd9Sstevel@tonic-gate int c; /* option letter */ 111*7c478bd9Sstevel@tonic-gate int ret; /* return code from check_version */ 112*7c478bd9Sstevel@tonic-gate uid_t uid; /* invoker's real uid */ 113*7c478bd9Sstevel@tonic-gate int flag = 0; /* flag to record requested operations */ 114*7c478bd9Sstevel@tonic-gate int errflg = 0; /* error indicator */ 115*7c478bd9Sstevel@tonic-gate int badcnt = 0; /* count of bad args to -f */ 116*7c478bd9Sstevel@tonic-gate int version = -1; /* argument to -v */ 117*7c478bd9Sstevel@tonic-gate int sawaflag = 0; /* true if actually saw -a */ 118*7c478bd9Sstevel@tonic-gate int conflag = 0; /* true if output should be in condensed form */ 119*7c478bd9Sstevel@tonic-gate long flags = 0; /* arguments to -f */ 120*7c478bd9Sstevel@tonic-gate char *pmtag = NULL; /* argument to -p */ 121*7c478bd9Sstevel@tonic-gate char *type = NULL; /* argument to -t */ 122*7c478bd9Sstevel@tonic-gate char *script = NULL; /* argument to -z */ 123*7c478bd9Sstevel@tonic-gate char *comment = " "; /* argument to -y */ 124*7c478bd9Sstevel@tonic-gate char *id = NULL; /* argument to -i */ 125*7c478bd9Sstevel@tonic-gate char *svctag = NULL; /* argument to -s */ 126*7c478bd9Sstevel@tonic-gate char *pmspec = NULL; /* argument to -m */ 127*7c478bd9Sstevel@tonic-gate char badargs[SIZE]; /* place to hold bad args to -f */ 128*7c478bd9Sstevel@tonic-gate char buf[SIZE]; /* scratch buffer */ 129*7c478bd9Sstevel@tonic-gate register char *p; /* scratch pointer */ 130*7c478bd9Sstevel@tonic-gate 131*7c478bd9Sstevel@tonic-gate if (argc == 1) 132*7c478bd9Sstevel@tonic-gate usage(argv[0]); 133*7c478bd9Sstevel@tonic-gate while ((c = getopt(argc, argv, "adef:gi:Llm:p:rs:t:v:y:z:")) != -1) { 134*7c478bd9Sstevel@tonic-gate switch (c) { 135*7c478bd9Sstevel@tonic-gate case 'a': 136*7c478bd9Sstevel@tonic-gate flag |= ADD; 137*7c478bd9Sstevel@tonic-gate sawaflag = 1; 138*7c478bd9Sstevel@tonic-gate break; 139*7c478bd9Sstevel@tonic-gate case 'd': 140*7c478bd9Sstevel@tonic-gate flag |= DISABLE; 141*7c478bd9Sstevel@tonic-gate break; 142*7c478bd9Sstevel@tonic-gate case 'e': 143*7c478bd9Sstevel@tonic-gate flag |= ENABLE; 144*7c478bd9Sstevel@tonic-gate break; 145*7c478bd9Sstevel@tonic-gate case 'f': 146*7c478bd9Sstevel@tonic-gate flag |= ADD; 147*7c478bd9Sstevel@tonic-gate while (*optarg) { 148*7c478bd9Sstevel@tonic-gate switch (*optarg++) { 149*7c478bd9Sstevel@tonic-gate case 'u': 150*7c478bd9Sstevel@tonic-gate flags |= U_FLAG; 151*7c478bd9Sstevel@tonic-gate break; 152*7c478bd9Sstevel@tonic-gate case 'x': 153*7c478bd9Sstevel@tonic-gate flags |= X_FLAG; 154*7c478bd9Sstevel@tonic-gate break; 155*7c478bd9Sstevel@tonic-gate default: 156*7c478bd9Sstevel@tonic-gate badargs[badcnt++] = *(optarg - 1); 157*7c478bd9Sstevel@tonic-gate break; 158*7c478bd9Sstevel@tonic-gate } 159*7c478bd9Sstevel@tonic-gate } 160*7c478bd9Sstevel@tonic-gate /* null terminate just in case anything is there */ 161*7c478bd9Sstevel@tonic-gate badargs[badcnt] = '\0'; 162*7c478bd9Sstevel@tonic-gate break; 163*7c478bd9Sstevel@tonic-gate case 'g': 164*7c478bd9Sstevel@tonic-gate flag |= CONFIG; 165*7c478bd9Sstevel@tonic-gate break; 166*7c478bd9Sstevel@tonic-gate case 'i': 167*7c478bd9Sstevel@tonic-gate if (strchr(optarg, '\n')) { 168*7c478bd9Sstevel@tonic-gate Saferrno = E_BADARGS; 169*7c478bd9Sstevel@tonic-gate error(BADINP); 170*7c478bd9Sstevel@tonic-gate } 171*7c478bd9Sstevel@tonic-gate flag |= ADD; 172*7c478bd9Sstevel@tonic-gate id = optarg; 173*7c478bd9Sstevel@tonic-gate break; 174*7c478bd9Sstevel@tonic-gate case 'L': 175*7c478bd9Sstevel@tonic-gate flag |= LIST; 176*7c478bd9Sstevel@tonic-gate break; 177*7c478bd9Sstevel@tonic-gate case 'l': 178*7c478bd9Sstevel@tonic-gate flag |= PLIST; 179*7c478bd9Sstevel@tonic-gate break; 180*7c478bd9Sstevel@tonic-gate case 'm': 181*7c478bd9Sstevel@tonic-gate if (strchr(optarg, '\n')) { 182*7c478bd9Sstevel@tonic-gate Saferrno = E_BADARGS; 183*7c478bd9Sstevel@tonic-gate error(BADINP); 184*7c478bd9Sstevel@tonic-gate } 185*7c478bd9Sstevel@tonic-gate if (*optarg == '\0') { 186*7c478bd9Sstevel@tonic-gate /* this will generate a usage message below */ 187*7c478bd9Sstevel@tonic-gate errflg++; 188*7c478bd9Sstevel@tonic-gate break; 189*7c478bd9Sstevel@tonic-gate } 190*7c478bd9Sstevel@tonic-gate flag |= ADD; 191*7c478bd9Sstevel@tonic-gate pmspec = optarg; 192*7c478bd9Sstevel@tonic-gate break; 193*7c478bd9Sstevel@tonic-gate case 'p': 194*7c478bd9Sstevel@tonic-gate if (strchr(optarg, '\n')) { 195*7c478bd9Sstevel@tonic-gate Saferrno = E_BADARGS; 196*7c478bd9Sstevel@tonic-gate error(BADINP); 197*7c478bd9Sstevel@tonic-gate } 198*7c478bd9Sstevel@tonic-gate pmtag = optarg; 199*7c478bd9Sstevel@tonic-gate if (strlen(pmtag) > PMTAGSIZE) { 200*7c478bd9Sstevel@tonic-gate pmtag[PMTAGSIZE] = '\0'; 201*7c478bd9Sstevel@tonic-gate (void) fprintf(stderr, "tag too long, truncated to <%s>\n", pmtag); 202*7c478bd9Sstevel@tonic-gate } 203*7c478bd9Sstevel@tonic-gate for (p = pmtag; *p; p++) { 204*7c478bd9Sstevel@tonic-gate if (!isalnum(*p)) { 205*7c478bd9Sstevel@tonic-gate Saferrno = E_BADARGS; 206*7c478bd9Sstevel@tonic-gate error("port monitor tag must be alphanumeric"); 207*7c478bd9Sstevel@tonic-gate } 208*7c478bd9Sstevel@tonic-gate } 209*7c478bd9Sstevel@tonic-gate break; 210*7c478bd9Sstevel@tonic-gate case 'r': 211*7c478bd9Sstevel@tonic-gate flag |= REMOVE; 212*7c478bd9Sstevel@tonic-gate break; 213*7c478bd9Sstevel@tonic-gate case 's': 214*7c478bd9Sstevel@tonic-gate if (strchr(optarg, '\n')) { 215*7c478bd9Sstevel@tonic-gate Saferrno = E_BADARGS; 216*7c478bd9Sstevel@tonic-gate error(BADINP); 217*7c478bd9Sstevel@tonic-gate } 218*7c478bd9Sstevel@tonic-gate svctag = optarg; 219*7c478bd9Sstevel@tonic-gate if (strlen(svctag) > SVCTAGSIZE) { 220*7c478bd9Sstevel@tonic-gate svctag[SVCTAGSIZE] = '\0'; 221*7c478bd9Sstevel@tonic-gate (void) fprintf(stderr, "svctag too long, truncated to <%s>\n", svctag); 222*7c478bd9Sstevel@tonic-gate } 223*7c478bd9Sstevel@tonic-gate for (p = svctag; *p; p++) { 224*7c478bd9Sstevel@tonic-gate if (!isalnum(*p)) { 225*7c478bd9Sstevel@tonic-gate Saferrno = E_BADARGS; 226*7c478bd9Sstevel@tonic-gate error("service tag must be alphanumeric"); 227*7c478bd9Sstevel@tonic-gate } 228*7c478bd9Sstevel@tonic-gate } 229*7c478bd9Sstevel@tonic-gate break; 230*7c478bd9Sstevel@tonic-gate case 't': 231*7c478bd9Sstevel@tonic-gate if (strchr(optarg, '\n')) { 232*7c478bd9Sstevel@tonic-gate Saferrno = E_BADARGS; 233*7c478bd9Sstevel@tonic-gate error(BADINP); 234*7c478bd9Sstevel@tonic-gate } 235*7c478bd9Sstevel@tonic-gate type = optarg; 236*7c478bd9Sstevel@tonic-gate if (strlen(type) > PMTYPESIZE) { 237*7c478bd9Sstevel@tonic-gate type[PMTYPESIZE] = '\0'; 238*7c478bd9Sstevel@tonic-gate (void) fprintf(stderr, "type too long, truncated to <%s>\n", type); 239*7c478bd9Sstevel@tonic-gate } 240*7c478bd9Sstevel@tonic-gate for (p = type; *p; p++) { 241*7c478bd9Sstevel@tonic-gate if (!isalnum(*p)) { 242*7c478bd9Sstevel@tonic-gate Saferrno = E_BADARGS; 243*7c478bd9Sstevel@tonic-gate error("port monitor type must be alphanumeric"); 244*7c478bd9Sstevel@tonic-gate } 245*7c478bd9Sstevel@tonic-gate } 246*7c478bd9Sstevel@tonic-gate break; 247*7c478bd9Sstevel@tonic-gate case 'v': 248*7c478bd9Sstevel@tonic-gate flag |= ADD; 249*7c478bd9Sstevel@tonic-gate version = atoi(optarg); 250*7c478bd9Sstevel@tonic-gate if (version < 0) { 251*7c478bd9Sstevel@tonic-gate Saferrno = E_BADARGS; 252*7c478bd9Sstevel@tonic-gate error("version number can not be negative"); 253*7c478bd9Sstevel@tonic-gate } 254*7c478bd9Sstevel@tonic-gate break; 255*7c478bd9Sstevel@tonic-gate case 'y': 256*7c478bd9Sstevel@tonic-gate if (strchr(optarg, '\n')) { 257*7c478bd9Sstevel@tonic-gate Saferrno = E_BADARGS; 258*7c478bd9Sstevel@tonic-gate error(BADINP); 259*7c478bd9Sstevel@tonic-gate } 260*7c478bd9Sstevel@tonic-gate flag |= ADD; 261*7c478bd9Sstevel@tonic-gate comment = optarg; 262*7c478bd9Sstevel@tonic-gate break; 263*7c478bd9Sstevel@tonic-gate case 'z': 264*7c478bd9Sstevel@tonic-gate if (strchr(optarg, '\n')) { 265*7c478bd9Sstevel@tonic-gate Saferrno = E_BADARGS; 266*7c478bd9Sstevel@tonic-gate error(BADINP); 267*7c478bd9Sstevel@tonic-gate } 268*7c478bd9Sstevel@tonic-gate script = optarg; 269*7c478bd9Sstevel@tonic-gate break; 270*7c478bd9Sstevel@tonic-gate case '?': 271*7c478bd9Sstevel@tonic-gate errflg++; 272*7c478bd9Sstevel@tonic-gate } 273*7c478bd9Sstevel@tonic-gate } 274*7c478bd9Sstevel@tonic-gate if (errflg || (optind < argc)) 275*7c478bd9Sstevel@tonic-gate usage(argv[0]); 276*7c478bd9Sstevel@tonic-gate 277*7c478bd9Sstevel@tonic-gate if (badcnt) { 278*7c478bd9Sstevel@tonic-gate /* bad flags were given to -f */ 279*7c478bd9Sstevel@tonic-gate (void) sprintf(buf, "Invalid request, %s are not valid arguments for \"-f\"", badargs); 280*7c478bd9Sstevel@tonic-gate Saferrno = E_BADARGS; 281*7c478bd9Sstevel@tonic-gate error(buf); 282*7c478bd9Sstevel@tonic-gate } 283*7c478bd9Sstevel@tonic-gate 284*7c478bd9Sstevel@tonic-gate uid = getuid(); 285*7c478bd9Sstevel@tonic-gate 286*7c478bd9Sstevel@tonic-gate /* 287*7c478bd9Sstevel@tonic-gate * don't do anything if _sactab isn't the version we understand 288*7c478bd9Sstevel@tonic-gate */ 289*7c478bd9Sstevel@tonic-gate 290*7c478bd9Sstevel@tonic-gate if ((ret = check_version(VERSION, SACTAB)) == 1) { 291*7c478bd9Sstevel@tonic-gate Saferrno = E_SAFERR; 292*7c478bd9Sstevel@tonic-gate error("_sactab version number is incorrect"); 293*7c478bd9Sstevel@tonic-gate } 294*7c478bd9Sstevel@tonic-gate else if (ret == 2) { 295*7c478bd9Sstevel@tonic-gate (void) sprintf(buf, "could not open %s", SACTAB); 296*7c478bd9Sstevel@tonic-gate Saferrno = E_SYSERR; 297*7c478bd9Sstevel@tonic-gate error(buf); 298*7c478bd9Sstevel@tonic-gate } 299*7c478bd9Sstevel@tonic-gate else if (ret == 3) { 300*7c478bd9Sstevel@tonic-gate (void) sprintf(buf, "%s file is corrupt", SACTAB); 301*7c478bd9Sstevel@tonic-gate Saferrno = E_SAFERR; 302*7c478bd9Sstevel@tonic-gate error(buf); 303*7c478bd9Sstevel@tonic-gate } 304*7c478bd9Sstevel@tonic-gate 305*7c478bd9Sstevel@tonic-gate switch (flag) { 306*7c478bd9Sstevel@tonic-gate case ADD: 307*7c478bd9Sstevel@tonic-gate if (uid) { 308*7c478bd9Sstevel@tonic-gate Saferrno = E_NOPRIV; 309*7c478bd9Sstevel@tonic-gate error(NOTPRIV); 310*7c478bd9Sstevel@tonic-gate } 311*7c478bd9Sstevel@tonic-gate if (!sawaflag || (pmtag && type) || (!pmtag && !type) || !svctag || !id || !pmspec || (version < 0)) 312*7c478bd9Sstevel@tonic-gate usage(argv[0]); 313*7c478bd9Sstevel@tonic-gate add_svc(pmtag, type, svctag, id, pmspec, flags, version, comment, script); 314*7c478bd9Sstevel@tonic-gate break; 315*7c478bd9Sstevel@tonic-gate case REMOVE: 316*7c478bd9Sstevel@tonic-gate if (uid) { 317*7c478bd9Sstevel@tonic-gate Saferrno = E_NOPRIV; 318*7c478bd9Sstevel@tonic-gate error(NOTPRIV); 319*7c478bd9Sstevel@tonic-gate } 320*7c478bd9Sstevel@tonic-gate if (!pmtag || !svctag || type || script) 321*7c478bd9Sstevel@tonic-gate usage(argv[0]); 322*7c478bd9Sstevel@tonic-gate rem_svc(pmtag, svctag); 323*7c478bd9Sstevel@tonic-gate break; 324*7c478bd9Sstevel@tonic-gate case ENABLE: 325*7c478bd9Sstevel@tonic-gate if (uid) { 326*7c478bd9Sstevel@tonic-gate Saferrno = E_NOPRIV; 327*7c478bd9Sstevel@tonic-gate error(NOTPRIV); 328*7c478bd9Sstevel@tonic-gate } 329*7c478bd9Sstevel@tonic-gate if (!pmtag || !svctag || type || script) 330*7c478bd9Sstevel@tonic-gate usage(argv[0]); 331*7c478bd9Sstevel@tonic-gate ed_svc(pmtag, svctag, ENABLE); 332*7c478bd9Sstevel@tonic-gate break; 333*7c478bd9Sstevel@tonic-gate case DISABLE: 334*7c478bd9Sstevel@tonic-gate if (uid) { 335*7c478bd9Sstevel@tonic-gate Saferrno = E_NOPRIV; 336*7c478bd9Sstevel@tonic-gate error(NOTPRIV); 337*7c478bd9Sstevel@tonic-gate } 338*7c478bd9Sstevel@tonic-gate if (!pmtag || !svctag || type || script) 339*7c478bd9Sstevel@tonic-gate usage(argv[0]); 340*7c478bd9Sstevel@tonic-gate ed_svc(pmtag, svctag, DISABLE); 341*7c478bd9Sstevel@tonic-gate break; 342*7c478bd9Sstevel@tonic-gate case LIST: 343*7c478bd9Sstevel@tonic-gate conflag = 1; 344*7c478bd9Sstevel@tonic-gate /* fall through */ 345*7c478bd9Sstevel@tonic-gate case PLIST: 346*7c478bd9Sstevel@tonic-gate if ((pmtag && type) || script) 347*7c478bd9Sstevel@tonic-gate usage(argv[0]); 348*7c478bd9Sstevel@tonic-gate list_svcs(pmtag, type, svctag, conflag); 349*7c478bd9Sstevel@tonic-gate break; 350*7c478bd9Sstevel@tonic-gate case CONFIG: 351*7c478bd9Sstevel@tonic-gate if (script && uid) { 352*7c478bd9Sstevel@tonic-gate Saferrno = E_NOPRIV; 353*7c478bd9Sstevel@tonic-gate error(NOTPRIV); 354*7c478bd9Sstevel@tonic-gate } 355*7c478bd9Sstevel@tonic-gate if ((pmtag && type) || (!pmtag && !type) || !svctag || (type && !script)) 356*7c478bd9Sstevel@tonic-gate usage(argv[0]); 357*7c478bd9Sstevel@tonic-gate doconf(script, pmtag, type, svctag); 358*7c478bd9Sstevel@tonic-gate break; 359*7c478bd9Sstevel@tonic-gate default: 360*7c478bd9Sstevel@tonic-gate /* we only get here if more than one flag bit was set */ 361*7c478bd9Sstevel@tonic-gate usage(argv[0]); 362*7c478bd9Sstevel@tonic-gate /* NOTREACHED */ 363*7c478bd9Sstevel@tonic-gate } 364*7c478bd9Sstevel@tonic-gate quit(); 365*7c478bd9Sstevel@tonic-gate /* NOTREACHED */ 366*7c478bd9Sstevel@tonic-gate } 367*7c478bd9Sstevel@tonic-gate 368*7c478bd9Sstevel@tonic-gate 369*7c478bd9Sstevel@tonic-gate /* 370*7c478bd9Sstevel@tonic-gate * usage - print out a usage message 371*7c478bd9Sstevel@tonic-gate * 372*7c478bd9Sstevel@tonic-gate * args: cmdname - the name command was invoked with 373*7c478bd9Sstevel@tonic-gate */ 374*7c478bd9Sstevel@tonic-gate 375*7c478bd9Sstevel@tonic-gate void 376*7c478bd9Sstevel@tonic-gate usage(cmdname) 377*7c478bd9Sstevel@tonic-gate char *cmdname; 378*7c478bd9Sstevel@tonic-gate { 379*7c478bd9Sstevel@tonic-gate (void) fprintf(stderr, "Usage:\t%s -a [ -p pmtag | -t type ] -s svctag -i id -m \"pmspecific\"\n", cmdname); 380*7c478bd9Sstevel@tonic-gate (void) fprintf(stderr, "\t\t-v version [ -f xu ] [ -y comment ] [ -z script]\n"); 381*7c478bd9Sstevel@tonic-gate (void) fprintf(stderr, "\t%s -r -p pmtag -s svctag\n", cmdname); 382*7c478bd9Sstevel@tonic-gate (void) fprintf(stderr, "\t%s -e -p pmtag -s svctag\n", cmdname); 383*7c478bd9Sstevel@tonic-gate (void) fprintf(stderr, "\t%s -d -p pmtag -s svctag\n", cmdname); 384*7c478bd9Sstevel@tonic-gate (void) fprintf(stderr, "\t%s -l [ -p pmtag | -t type ] [ -s svctag ]\n", cmdname); 385*7c478bd9Sstevel@tonic-gate (void) fprintf(stderr, "\t%s -L [ -p pmtag | -t type ] [ -s svctag ]\n", cmdname); 386*7c478bd9Sstevel@tonic-gate (void) fprintf(stderr, "\t%s -g -p pmtag -s svctag [ -z script ]\n", cmdname); 387*7c478bd9Sstevel@tonic-gate (void) fprintf(stderr, "\t%s -g -s svctag -t type -z script\n", cmdname); 388*7c478bd9Sstevel@tonic-gate Saferrno = E_BADARGS; 389*7c478bd9Sstevel@tonic-gate quit(); 390*7c478bd9Sstevel@tonic-gate } 391*7c478bd9Sstevel@tonic-gate 392*7c478bd9Sstevel@tonic-gate 393*7c478bd9Sstevel@tonic-gate /* 394*7c478bd9Sstevel@tonic-gate * add_svc - add a service entry 395*7c478bd9Sstevel@tonic-gate * 396*7c478bd9Sstevel@tonic-gate * args: tag - port monitor's tag (may be null) 397*7c478bd9Sstevel@tonic-gate * type - port monitor's type (may be null) 398*7c478bd9Sstevel@tonic-gate * svctag - service's tag 399*7c478bd9Sstevel@tonic-gate * id - identity under which service should run 400*7c478bd9Sstevel@tonic-gate * pmspec - uninterpreted port monitor-specific info 401*7c478bd9Sstevel@tonic-gate * flags - service flags 402*7c478bd9Sstevel@tonic-gate * version - version number of port monitor's pmtab 403*7c478bd9Sstevel@tonic-gate * comment - comment describing service 404*7c478bd9Sstevel@tonic-gate * script - service's configuration script 405*7c478bd9Sstevel@tonic-gate */ 406*7c478bd9Sstevel@tonic-gate 407*7c478bd9Sstevel@tonic-gate void 408*7c478bd9Sstevel@tonic-gate add_svc(tag, type, svctag, id, pmspec, flags, version, comment, script) 409*7c478bd9Sstevel@tonic-gate char *tag; 410*7c478bd9Sstevel@tonic-gate char *type; 411*7c478bd9Sstevel@tonic-gate char *svctag; 412*7c478bd9Sstevel@tonic-gate char *id; 413*7c478bd9Sstevel@tonic-gate char *pmspec; 414*7c478bd9Sstevel@tonic-gate long flags; 415*7c478bd9Sstevel@tonic-gate int version; 416*7c478bd9Sstevel@tonic-gate char *comment; 417*7c478bd9Sstevel@tonic-gate char *script; 418*7c478bd9Sstevel@tonic-gate { 419*7c478bd9Sstevel@tonic-gate FILE *fp; /* scratch file pointer */ 420*7c478bd9Sstevel@tonic-gate struct taglist tl; /* 'list' for degenerate case (1 PM) */ 421*7c478bd9Sstevel@tonic-gate register struct taglist *tp = NULL; /* working pointer */ 422*7c478bd9Sstevel@tonic-gate int ret; /* return code from check_version */ 423*7c478bd9Sstevel@tonic-gate char buf[SIZE]; /* scratch buffer */ 424*7c478bd9Sstevel@tonic-gate char fname[SIZE]; /* scratch buffer for building names */ 425*7c478bd9Sstevel@tonic-gate int added; /* count number added */ 426*7c478bd9Sstevel@tonic-gate 427*7c478bd9Sstevel@tonic-gate fp = fopen(SACTAB, "r"); 428*7c478bd9Sstevel@tonic-gate if (fp == NULL) { 429*7c478bd9Sstevel@tonic-gate Saferrno = E_SYSERR; 430*7c478bd9Sstevel@tonic-gate error("Could not open _sactab"); 431*7c478bd9Sstevel@tonic-gate } 432*7c478bd9Sstevel@tonic-gate if (tag && !find_pm(fp, tag)) { 433*7c478bd9Sstevel@tonic-gate (void) sprintf(buf, "Invalid request, %s does not exist", tag); 434*7c478bd9Sstevel@tonic-gate Saferrno = E_NOEXIST; 435*7c478bd9Sstevel@tonic-gate error(buf); 436*7c478bd9Sstevel@tonic-gate } 437*7c478bd9Sstevel@tonic-gate if (type && !(tp = find_type(fp, type))) { 438*7c478bd9Sstevel@tonic-gate (void) sprintf(buf, "Invalid request, %s does not exist", type); 439*7c478bd9Sstevel@tonic-gate Saferrno = E_NOEXIST; 440*7c478bd9Sstevel@tonic-gate error(buf); 441*7c478bd9Sstevel@tonic-gate } 442*7c478bd9Sstevel@tonic-gate (void) fclose(fp); 443*7c478bd9Sstevel@tonic-gate 444*7c478bd9Sstevel@tonic-gate if (tag) { 445*7c478bd9Sstevel@tonic-gate 446*7c478bd9Sstevel@tonic-gate /* 447*7c478bd9Sstevel@tonic-gate * treat the case of 1 PM as a degenerate case of a list of PMs from a 448*7c478bd9Sstevel@tonic-gate * type specification. Build the 'list' here. 449*7c478bd9Sstevel@tonic-gate */ 450*7c478bd9Sstevel@tonic-gate 451*7c478bd9Sstevel@tonic-gate tp = &tl; 452*7c478bd9Sstevel@tonic-gate tp->t_next = NULL; 453*7c478bd9Sstevel@tonic-gate (void) strcpy(tp->t_tag, tag); 454*7c478bd9Sstevel@tonic-gate } 455*7c478bd9Sstevel@tonic-gate 456*7c478bd9Sstevel@tonic-gate added = 0; 457*7c478bd9Sstevel@tonic-gate while (tp) { 458*7c478bd9Sstevel@tonic-gate (void) sprintf(fname, "%s/%s/_pmtab", HOME, tp->t_tag); 459*7c478bd9Sstevel@tonic-gate if ((ret = check_version(version, fname)) == 1) { 460*7c478bd9Sstevel@tonic-gate (void) sprintf(buf, "%s version number is incorrect", fname); 461*7c478bd9Sstevel@tonic-gate Saferrno = E_SAFERR; 462*7c478bd9Sstevel@tonic-gate error(buf); 463*7c478bd9Sstevel@tonic-gate } 464*7c478bd9Sstevel@tonic-gate else if (ret == 2) { 465*7c478bd9Sstevel@tonic-gate (void) sprintf(buf, "could not open %s", fname); 466*7c478bd9Sstevel@tonic-gate Saferrno = E_SYSERR; 467*7c478bd9Sstevel@tonic-gate error(buf); 468*7c478bd9Sstevel@tonic-gate } 469*7c478bd9Sstevel@tonic-gate else if (ret == 3) { 470*7c478bd9Sstevel@tonic-gate (void) sprintf(buf, "%s file is corrupt", fname); 471*7c478bd9Sstevel@tonic-gate Saferrno = E_SAFERR; 472*7c478bd9Sstevel@tonic-gate error(buf); 473*7c478bd9Sstevel@tonic-gate } 474*7c478bd9Sstevel@tonic-gate fp = fopen(fname, "r"); 475*7c478bd9Sstevel@tonic-gate if (fp == NULL) { 476*7c478bd9Sstevel@tonic-gate (void) sprintf(buf, "Could not open %s", fname); 477*7c478bd9Sstevel@tonic-gate Saferrno = E_SYSERR; 478*7c478bd9Sstevel@tonic-gate error(buf); 479*7c478bd9Sstevel@tonic-gate } 480*7c478bd9Sstevel@tonic-gate if (find_svc(fp, tp->t_tag, svctag)) { 481*7c478bd9Sstevel@tonic-gate if (tag) { 482*7c478bd9Sstevel@tonic-gate /* special case of tag only */ 483*7c478bd9Sstevel@tonic-gate (void) sprintf(buf, "Invalid request, %s already exists under %s", svctag, tag); 484*7c478bd9Sstevel@tonic-gate Saferrno = E_DUP; 485*7c478bd9Sstevel@tonic-gate error(buf); 486*7c478bd9Sstevel@tonic-gate } 487*7c478bd9Sstevel@tonic-gate else { 488*7c478bd9Sstevel@tonic-gate (void) fprintf(stderr, "warning - %s already exists under %s - ignoring\n", svctag, tp->t_tag); 489*7c478bd9Sstevel@tonic-gate tp = tp->t_next; 490*7c478bd9Sstevel@tonic-gate (void) fclose(fp); 491*7c478bd9Sstevel@tonic-gate continue; 492*7c478bd9Sstevel@tonic-gate } 493*7c478bd9Sstevel@tonic-gate } 494*7c478bd9Sstevel@tonic-gate (void) fclose(fp); 495*7c478bd9Sstevel@tonic-gate 496*7c478bd9Sstevel@tonic-gate /* 497*7c478bd9Sstevel@tonic-gate * put in the config script, if specified 498*7c478bd9Sstevel@tonic-gate */ 499*7c478bd9Sstevel@tonic-gate 500*7c478bd9Sstevel@tonic-gate if (script) { 501*7c478bd9Sstevel@tonic-gate (void) sprintf(fname, "%s/%s", tp->t_tag, svctag); 502*7c478bd9Sstevel@tonic-gate if (do_config(script, fname)) { 503*7c478bd9Sstevel@tonic-gate /* do_config put out any messages */ 504*7c478bd9Sstevel@tonic-gate tp = tp->t_next; 505*7c478bd9Sstevel@tonic-gate continue; 506*7c478bd9Sstevel@tonic-gate } 507*7c478bd9Sstevel@tonic-gate } 508*7c478bd9Sstevel@tonic-gate 509*7c478bd9Sstevel@tonic-gate /* 510*7c478bd9Sstevel@tonic-gate * add the line 511*7c478bd9Sstevel@tonic-gate */ 512*7c478bd9Sstevel@tonic-gate 513*7c478bd9Sstevel@tonic-gate (void) sprintf(fname, "%s/%s/_pmtab", HOME, tp->t_tag); 514*7c478bd9Sstevel@tonic-gate fp = fopen(fname, "a"); 515*7c478bd9Sstevel@tonic-gate if (fp == NULL) { 516*7c478bd9Sstevel@tonic-gate (void) sprintf(buf, "Could not open %s", fname); 517*7c478bd9Sstevel@tonic-gate Saferrno = E_SYSERR; 518*7c478bd9Sstevel@tonic-gate error(buf); 519*7c478bd9Sstevel@tonic-gate } 520*7c478bd9Sstevel@tonic-gate (void) fprintf(fp, "%s:%s:%s:reserved:reserved:reserved:%s#%s\n", 521*7c478bd9Sstevel@tonic-gate svctag, (flags ? pflags(flags, FALSE) : ""), id, pmspec, 522*7c478bd9Sstevel@tonic-gate (comment ? comment : "")); 523*7c478bd9Sstevel@tonic-gate (void) fclose(fp); 524*7c478bd9Sstevel@tonic-gate added++; 525*7c478bd9Sstevel@tonic-gate 526*7c478bd9Sstevel@tonic-gate /* 527*7c478bd9Sstevel@tonic-gate * tell the SAC to to tell PM to read _pmtab 528*7c478bd9Sstevel@tonic-gate */ 529*7c478bd9Sstevel@tonic-gate 530*7c478bd9Sstevel@tonic-gate (void) tell_sac(tp->t_tag); 531*7c478bd9Sstevel@tonic-gate tp = tp->t_next; 532*7c478bd9Sstevel@tonic-gate } 533*7c478bd9Sstevel@tonic-gate if (added == 0) { 534*7c478bd9Sstevel@tonic-gate Saferrno = E_SAFERR; 535*7c478bd9Sstevel@tonic-gate error("No services added"); 536*7c478bd9Sstevel@tonic-gate } 537*7c478bd9Sstevel@tonic-gate return; 538*7c478bd9Sstevel@tonic-gate } 539*7c478bd9Sstevel@tonic-gate 540*7c478bd9Sstevel@tonic-gate 541*7c478bd9Sstevel@tonic-gate /* 542*7c478bd9Sstevel@tonic-gate * rem_svc - remove a service 543*7c478bd9Sstevel@tonic-gate * 544*7c478bd9Sstevel@tonic-gate * args: pmtag - tag of port monitor responsible for the service 545*7c478bd9Sstevel@tonic-gate * svctag - tag of the service to be removed 546*7c478bd9Sstevel@tonic-gate */ 547*7c478bd9Sstevel@tonic-gate 548*7c478bd9Sstevel@tonic-gate void 549*7c478bd9Sstevel@tonic-gate rem_svc(pmtag, svctag) 550*7c478bd9Sstevel@tonic-gate char *pmtag; 551*7c478bd9Sstevel@tonic-gate char *svctag; 552*7c478bd9Sstevel@tonic-gate { 553*7c478bd9Sstevel@tonic-gate FILE *fp; /* scratch file pointer */ 554*7c478bd9Sstevel@tonic-gate FILE *tfp; /* file pointer for temp file */ 555*7c478bd9Sstevel@tonic-gate int line; /* line number entry is on */ 556*7c478bd9Sstevel@tonic-gate char *tname; /* temp file name */ 557*7c478bd9Sstevel@tonic-gate char buf[SIZE]; /* scratch buffer */ 558*7c478bd9Sstevel@tonic-gate char fname[SIZE]; /* path to correct _pmtab */ 559*7c478bd9Sstevel@tonic-gate 560*7c478bd9Sstevel@tonic-gate fp = fopen(SACTAB, "r"); 561*7c478bd9Sstevel@tonic-gate if (fp == NULL) { 562*7c478bd9Sstevel@tonic-gate Saferrno = E_SYSERR; 563*7c478bd9Sstevel@tonic-gate error("Could not open _sactab"); 564*7c478bd9Sstevel@tonic-gate } 565*7c478bd9Sstevel@tonic-gate if (!find_pm(fp, pmtag)) { 566*7c478bd9Sstevel@tonic-gate (void) sprintf(buf, "Invalid request, %s does not exist", pmtag); 567*7c478bd9Sstevel@tonic-gate Saferrno = E_NOEXIST; 568*7c478bd9Sstevel@tonic-gate error(buf); 569*7c478bd9Sstevel@tonic-gate } 570*7c478bd9Sstevel@tonic-gate (void) fclose(fp); 571*7c478bd9Sstevel@tonic-gate 572*7c478bd9Sstevel@tonic-gate (void) sprintf(fname, "%s/_pmtab", pmtag); 573*7c478bd9Sstevel@tonic-gate (void) sprintf(buf, "%s/%s", HOME, fname); 574*7c478bd9Sstevel@tonic-gate fp = fopen(buf, "r"); 575*7c478bd9Sstevel@tonic-gate if (fp == NULL) { 576*7c478bd9Sstevel@tonic-gate (void) sprintf(buf, "Could not open %s/%s", HOME, fname); 577*7c478bd9Sstevel@tonic-gate Saferrno = E_SYSERR; 578*7c478bd9Sstevel@tonic-gate error(buf); 579*7c478bd9Sstevel@tonic-gate } 580*7c478bd9Sstevel@tonic-gate if ((line = find_svc(fp, pmtag, svctag)) == 0) { 581*7c478bd9Sstevel@tonic-gate (void) sprintf(buf, "Invalid request, %s does not exist under %s", svctag, pmtag); 582*7c478bd9Sstevel@tonic-gate Saferrno = E_NOEXIST; 583*7c478bd9Sstevel@tonic-gate error(buf); 584*7c478bd9Sstevel@tonic-gate } 585*7c478bd9Sstevel@tonic-gate tname = make_tempname(fname); 586*7c478bd9Sstevel@tonic-gate tfp = open_temp(tname); 587*7c478bd9Sstevel@tonic-gate if (line != 1) { 588*7c478bd9Sstevel@tonic-gate if (copy_file(fp, tfp, 1, line - 1)) { 589*7c478bd9Sstevel@tonic-gate (void) unlink(tname); 590*7c478bd9Sstevel@tonic-gate Saferrno = E_SYSERR; 591*7c478bd9Sstevel@tonic-gate error("error accessing temp file"); 592*7c478bd9Sstevel@tonic-gate } 593*7c478bd9Sstevel@tonic-gate } 594*7c478bd9Sstevel@tonic-gate if (copy_file(fp, tfp, line + 1, -1)) { 595*7c478bd9Sstevel@tonic-gate (void) unlink(tname); 596*7c478bd9Sstevel@tonic-gate Saferrno = E_SYSERR; 597*7c478bd9Sstevel@tonic-gate error("error accessing temp file"); 598*7c478bd9Sstevel@tonic-gate } 599*7c478bd9Sstevel@tonic-gate (void) fclose(fp); 600*7c478bd9Sstevel@tonic-gate if (fclose(tfp) == EOF) { 601*7c478bd9Sstevel@tonic-gate (void) unlink(tname); 602*7c478bd9Sstevel@tonic-gate Saferrno = E_SYSERR; 603*7c478bd9Sstevel@tonic-gate error("error closing tempfile"); 604*7c478bd9Sstevel@tonic-gate } 605*7c478bd9Sstevel@tonic-gate /* note - replace only returns if successful */ 606*7c478bd9Sstevel@tonic-gate replace(fname, tname); 607*7c478bd9Sstevel@tonic-gate 608*7c478bd9Sstevel@tonic-gate /* 609*7c478bd9Sstevel@tonic-gate * tell the SAC to to tell PM to read _pmtab 610*7c478bd9Sstevel@tonic-gate */ 611*7c478bd9Sstevel@tonic-gate 612*7c478bd9Sstevel@tonic-gate if (tell_sac(pmtag)) { 613*7c478bd9Sstevel@tonic-gate 614*7c478bd9Sstevel@tonic-gate /* 615*7c478bd9Sstevel@tonic-gate * if we got rid of the service, try to remove the config script too. 616*7c478bd9Sstevel@tonic-gate * Don't check return status since it may not have existed anyhow. 617*7c478bd9Sstevel@tonic-gate */ 618*7c478bd9Sstevel@tonic-gate 619*7c478bd9Sstevel@tonic-gate (void) sprintf(buf, "%s/%s/%s", HOME, pmtag, svctag); 620*7c478bd9Sstevel@tonic-gate (void) unlink(buf); 621*7c478bd9Sstevel@tonic-gate return; 622*7c478bd9Sstevel@tonic-gate } 623*7c478bd9Sstevel@tonic-gate } 624*7c478bd9Sstevel@tonic-gate 625*7c478bd9Sstevel@tonic-gate 626*7c478bd9Sstevel@tonic-gate 627*7c478bd9Sstevel@tonic-gate /* 628*7c478bd9Sstevel@tonic-gate * ed_svc - enable or disable a particular service 629*7c478bd9Sstevel@tonic-gate * 630*7c478bd9Sstevel@tonic-gate * args: pmtag - tag of port monitor responsible for the service 631*7c478bd9Sstevel@tonic-gate * svctag - tag of service to be enabled or disabled 632*7c478bd9Sstevel@tonic-gate * flag - operation to perform (ENABLE or DISABLE) 633*7c478bd9Sstevel@tonic-gate */ 634*7c478bd9Sstevel@tonic-gate 635*7c478bd9Sstevel@tonic-gate void 636*7c478bd9Sstevel@tonic-gate ed_svc(pmtag, svctag, flag) 637*7c478bd9Sstevel@tonic-gate char *pmtag; 638*7c478bd9Sstevel@tonic-gate char *svctag; 639*7c478bd9Sstevel@tonic-gate int flag; 640*7c478bd9Sstevel@tonic-gate { 641*7c478bd9Sstevel@tonic-gate FILE *fp; /* scratch file pointer */ 642*7c478bd9Sstevel@tonic-gate FILE *tfp; /* file pointer for temp file */ 643*7c478bd9Sstevel@tonic-gate int line; /* line number entry is on */ 644*7c478bd9Sstevel@tonic-gate register char *from; /* working pointer */ 645*7c478bd9Sstevel@tonic-gate register char *to; /* working pointer */ 646*7c478bd9Sstevel@tonic-gate char *tname; /* temp file name */ 647*7c478bd9Sstevel@tonic-gate char *p; /* scratch pointer */ 648*7c478bd9Sstevel@tonic-gate char buf[SIZE]; /* scratch buffer */ 649*7c478bd9Sstevel@tonic-gate char tbuf[SIZE]; /* scratch buffer */ 650*7c478bd9Sstevel@tonic-gate char fname[SIZE]; /* path to correct _pmtab */ 651*7c478bd9Sstevel@tonic-gate 652*7c478bd9Sstevel@tonic-gate fp = fopen(SACTAB, "r"); 653*7c478bd9Sstevel@tonic-gate if (fp == NULL) { 654*7c478bd9Sstevel@tonic-gate Saferrno = E_SYSERR; 655*7c478bd9Sstevel@tonic-gate error("Could not open _sactab"); 656*7c478bd9Sstevel@tonic-gate } 657*7c478bd9Sstevel@tonic-gate if (!find_pm(fp, pmtag)) { 658*7c478bd9Sstevel@tonic-gate (void) sprintf(buf, "Invalid request, %s does not exist", pmtag); 659*7c478bd9Sstevel@tonic-gate Saferrno = E_NOEXIST; 660*7c478bd9Sstevel@tonic-gate error(buf); 661*7c478bd9Sstevel@tonic-gate } 662*7c478bd9Sstevel@tonic-gate (void) fclose(fp); 663*7c478bd9Sstevel@tonic-gate 664*7c478bd9Sstevel@tonic-gate (void) sprintf(fname, "%s/_pmtab", pmtag); 665*7c478bd9Sstevel@tonic-gate (void) sprintf(buf, "%s/%s", HOME, fname); 666*7c478bd9Sstevel@tonic-gate fp = fopen(buf, "r"); 667*7c478bd9Sstevel@tonic-gate if (fp == NULL) { 668*7c478bd9Sstevel@tonic-gate (void) sprintf(buf, "Could not open %s/%s", HOME, fname); 669*7c478bd9Sstevel@tonic-gate Saferrno = E_SYSERR; 670*7c478bd9Sstevel@tonic-gate error(buf); 671*7c478bd9Sstevel@tonic-gate } 672*7c478bd9Sstevel@tonic-gate if ((line = find_svc(fp, pmtag, svctag)) == 0) { 673*7c478bd9Sstevel@tonic-gate (void) sprintf(buf, "Invalid request, %s does not exist under %s", svctag, pmtag); 674*7c478bd9Sstevel@tonic-gate Saferrno = E_NOEXIST; 675*7c478bd9Sstevel@tonic-gate error(buf); 676*7c478bd9Sstevel@tonic-gate } 677*7c478bd9Sstevel@tonic-gate tname = make_tempname(fname); 678*7c478bd9Sstevel@tonic-gate tfp = open_temp(tname); 679*7c478bd9Sstevel@tonic-gate if (line != 1) { 680*7c478bd9Sstevel@tonic-gate if (copy_file(fp, tfp, 1, line - 1)) { 681*7c478bd9Sstevel@tonic-gate (void) unlink(tname); 682*7c478bd9Sstevel@tonic-gate Saferrno = E_SYSERR; 683*7c478bd9Sstevel@tonic-gate error("error accessing temp file"); 684*7c478bd9Sstevel@tonic-gate } 685*7c478bd9Sstevel@tonic-gate } 686*7c478bd9Sstevel@tonic-gate 687*7c478bd9Sstevel@tonic-gate /* 688*7c478bd9Sstevel@tonic-gate * Note: find_svc above has already read and parsed this entry, thus 689*7c478bd9Sstevel@tonic-gate * we know it to be well-formed, so just change the flags as appropriate 690*7c478bd9Sstevel@tonic-gate */ 691*7c478bd9Sstevel@tonic-gate 692*7c478bd9Sstevel@tonic-gate if (fgets(buf, SIZE, fp) == NULL) { 693*7c478bd9Sstevel@tonic-gate (void) unlink(tname); 694*7c478bd9Sstevel@tonic-gate Saferrno = E_SYSERR; 695*7c478bd9Sstevel@tonic-gate error("error accessing temp file"); 696*7c478bd9Sstevel@tonic-gate } 697*7c478bd9Sstevel@tonic-gate from = buf; 698*7c478bd9Sstevel@tonic-gate to = tbuf; 699*7c478bd9Sstevel@tonic-gate 700*7c478bd9Sstevel@tonic-gate /* 701*7c478bd9Sstevel@tonic-gate * copy initial portion of entry 702*7c478bd9Sstevel@tonic-gate */ 703*7c478bd9Sstevel@tonic-gate 704*7c478bd9Sstevel@tonic-gate p = strchr(from, DELIMC); 705*7c478bd9Sstevel@tonic-gate for ( ; from <= p; ) 706*7c478bd9Sstevel@tonic-gate *to++ = *from++; 707*7c478bd9Sstevel@tonic-gate 708*7c478bd9Sstevel@tonic-gate /* 709*7c478bd9Sstevel@tonic-gate * isolate and fix the flags 710*7c478bd9Sstevel@tonic-gate */ 711*7c478bd9Sstevel@tonic-gate 712*7c478bd9Sstevel@tonic-gate p = strchr(from, DELIMC); 713*7c478bd9Sstevel@tonic-gate for ( ; from < p; ) { 714*7c478bd9Sstevel@tonic-gate if (*from == 'x') { 715*7c478bd9Sstevel@tonic-gate from++; 716*7c478bd9Sstevel@tonic-gate continue; 717*7c478bd9Sstevel@tonic-gate } 718*7c478bd9Sstevel@tonic-gate *to++ = *from++; 719*7c478bd9Sstevel@tonic-gate } 720*7c478bd9Sstevel@tonic-gate 721*7c478bd9Sstevel@tonic-gate /* 722*7c478bd9Sstevel@tonic-gate * above we removed x flag, if this was a disable operation, stick it in 723*7c478bd9Sstevel@tonic-gate * and also copy the field delimiter 724*7c478bd9Sstevel@tonic-gate */ 725*7c478bd9Sstevel@tonic-gate 726*7c478bd9Sstevel@tonic-gate if (flag == DISABLE) 727*7c478bd9Sstevel@tonic-gate *to++ = 'x'; 728*7c478bd9Sstevel@tonic-gate *to++ = *from++; 729*7c478bd9Sstevel@tonic-gate 730*7c478bd9Sstevel@tonic-gate /* 731*7c478bd9Sstevel@tonic-gate * copy the rest of the line 732*7c478bd9Sstevel@tonic-gate */ 733*7c478bd9Sstevel@tonic-gate 734*7c478bd9Sstevel@tonic-gate for ( ; from < &buf[SIZE - 1] ;) 735*7c478bd9Sstevel@tonic-gate *to++ = *from++; 736*7c478bd9Sstevel@tonic-gate /*** *to = '\0'; BUG: Don't uncomment it ****/ 737*7c478bd9Sstevel@tonic-gate 738*7c478bd9Sstevel@tonic-gate (void) fprintf(tfp, "%s", tbuf); 739*7c478bd9Sstevel@tonic-gate 740*7c478bd9Sstevel@tonic-gate if (copy_file(fp, tfp, line + 1, -1)) { 741*7c478bd9Sstevel@tonic-gate (void) unlink(tname); 742*7c478bd9Sstevel@tonic-gate Saferrno = E_SYSERR; 743*7c478bd9Sstevel@tonic-gate error("error accessing temp file"); 744*7c478bd9Sstevel@tonic-gate } 745*7c478bd9Sstevel@tonic-gate (void) fclose(fp); 746*7c478bd9Sstevel@tonic-gate if (fclose(tfp) == EOF) { 747*7c478bd9Sstevel@tonic-gate (void) unlink(tname); 748*7c478bd9Sstevel@tonic-gate Saferrno = E_SYSERR; 749*7c478bd9Sstevel@tonic-gate error("error closing tempfile"); 750*7c478bd9Sstevel@tonic-gate } 751*7c478bd9Sstevel@tonic-gate /* note - replace only returns if successful */ 752*7c478bd9Sstevel@tonic-gate replace(fname, tname); 753*7c478bd9Sstevel@tonic-gate 754*7c478bd9Sstevel@tonic-gate 755*7c478bd9Sstevel@tonic-gate /* 756*7c478bd9Sstevel@tonic-gate * tell the SAC to to tell PM to read _pmtab 757*7c478bd9Sstevel@tonic-gate */ 758*7c478bd9Sstevel@tonic-gate 759*7c478bd9Sstevel@tonic-gate (void) tell_sac(pmtag); 760*7c478bd9Sstevel@tonic-gate } 761*7c478bd9Sstevel@tonic-gate 762*7c478bd9Sstevel@tonic-gate 763*7c478bd9Sstevel@tonic-gate /* 764*7c478bd9Sstevel@tonic-gate * doconf - take a config script and have it put where it belongs or 765*7c478bd9Sstevel@tonic-gate * output an existing one 766*7c478bd9Sstevel@tonic-gate * 767*7c478bd9Sstevel@tonic-gate * args: script - name of file containing script (if NULL, means 768*7c478bd9Sstevel@tonic-gate * output existing one instead) 769*7c478bd9Sstevel@tonic-gate * tag - tag of port monitor that is responsible for the 770*7c478bd9Sstevel@tonic-gate * designated service (may be null) 771*7c478bd9Sstevel@tonic-gate * type - type of port monitor that is responsible for the 772*7c478bd9Sstevel@tonic-gate * designated service (may be null) 773*7c478bd9Sstevel@tonic-gate * svctag - tag of service whose config script we're operating on 774*7c478bd9Sstevel@tonic-gate */ 775*7c478bd9Sstevel@tonic-gate 776*7c478bd9Sstevel@tonic-gate void 777*7c478bd9Sstevel@tonic-gate doconf(script, tag, type, svctag) 778*7c478bd9Sstevel@tonic-gate char *script; 779*7c478bd9Sstevel@tonic-gate char *tag; 780*7c478bd9Sstevel@tonic-gate char *type; 781*7c478bd9Sstevel@tonic-gate char *svctag; 782*7c478bd9Sstevel@tonic-gate { 783*7c478bd9Sstevel@tonic-gate FILE *fp; /* scratch file pointer */ 784*7c478bd9Sstevel@tonic-gate int added; /* count of config scripts added */ 785*7c478bd9Sstevel@tonic-gate struct taglist tl; /* 'list' for degenerate case (1 PM) */ 786*7c478bd9Sstevel@tonic-gate register struct taglist *tp = NULL; /* working pointer */ 787*7c478bd9Sstevel@tonic-gate char buf[SIZE]; /* scratch buffer */ 788*7c478bd9Sstevel@tonic-gate char fname[SIZE]; /* scratch buffer for names */ 789*7c478bd9Sstevel@tonic-gate 790*7c478bd9Sstevel@tonic-gate fp = fopen(SACTAB, "r"); 791*7c478bd9Sstevel@tonic-gate if (fp == NULL) { 792*7c478bd9Sstevel@tonic-gate Saferrno = E_SYSERR; 793*7c478bd9Sstevel@tonic-gate error("Could not open _sactab"); 794*7c478bd9Sstevel@tonic-gate } 795*7c478bd9Sstevel@tonic-gate if (tag && !find_pm(fp, tag)) { 796*7c478bd9Sstevel@tonic-gate (void) sprintf(buf, "Invalid request, %s does not exist", tag); 797*7c478bd9Sstevel@tonic-gate Saferrno = E_NOEXIST; 798*7c478bd9Sstevel@tonic-gate error(buf); 799*7c478bd9Sstevel@tonic-gate } 800*7c478bd9Sstevel@tonic-gate if (type && !(tp = find_type(fp, type))) { 801*7c478bd9Sstevel@tonic-gate (void) sprintf(buf, "Invalid request, %s does not exist", type); 802*7c478bd9Sstevel@tonic-gate Saferrno = E_NOEXIST; 803*7c478bd9Sstevel@tonic-gate error(buf); 804*7c478bd9Sstevel@tonic-gate } 805*7c478bd9Sstevel@tonic-gate (void) fclose(fp); 806*7c478bd9Sstevel@tonic-gate 807*7c478bd9Sstevel@tonic-gate if (tag) { 808*7c478bd9Sstevel@tonic-gate 809*7c478bd9Sstevel@tonic-gate /* 810*7c478bd9Sstevel@tonic-gate * treat the case of 1 PM as a degenerate case of a list of PMs from a 811*7c478bd9Sstevel@tonic-gate * type specification. Build the 'list' here. 812*7c478bd9Sstevel@tonic-gate */ 813*7c478bd9Sstevel@tonic-gate 814*7c478bd9Sstevel@tonic-gate tp = &tl; 815*7c478bd9Sstevel@tonic-gate tp->t_next = NULL; 816*7c478bd9Sstevel@tonic-gate (void) strcpy(tp->t_tag, tag); 817*7c478bd9Sstevel@tonic-gate } 818*7c478bd9Sstevel@tonic-gate 819*7c478bd9Sstevel@tonic-gate added = 0; 820*7c478bd9Sstevel@tonic-gate while (tp) { 821*7c478bd9Sstevel@tonic-gate (void) sprintf(fname, "%s/%s/_pmtab", HOME, tp->t_tag); 822*7c478bd9Sstevel@tonic-gate fp = fopen(fname, "r"); 823*7c478bd9Sstevel@tonic-gate if (fp == NULL) { 824*7c478bd9Sstevel@tonic-gate (void) sprintf(buf, "Could not open %s", fname); 825*7c478bd9Sstevel@tonic-gate Saferrno = E_SYSERR; 826*7c478bd9Sstevel@tonic-gate error(buf); 827*7c478bd9Sstevel@tonic-gate } 828*7c478bd9Sstevel@tonic-gate if (!find_svc(fp, tp->t_tag, svctag)) { 829*7c478bd9Sstevel@tonic-gate if (tag) { 830*7c478bd9Sstevel@tonic-gate /* special case of tag only */ 831*7c478bd9Sstevel@tonic-gate (void) sprintf(buf, "Invalid request, %s does not exist under %s", svctag, tag); 832*7c478bd9Sstevel@tonic-gate Saferrno = E_NOEXIST; 833*7c478bd9Sstevel@tonic-gate error(buf); 834*7c478bd9Sstevel@tonic-gate } 835*7c478bd9Sstevel@tonic-gate else { 836*7c478bd9Sstevel@tonic-gate (void) fprintf(stderr, "warning - %s does not exist under %s - ignoring\n", svctag, tp->t_tag); 837*7c478bd9Sstevel@tonic-gate Saferrno = E_NOEXIST; 838*7c478bd9Sstevel@tonic-gate tp = tp->t_next; 839*7c478bd9Sstevel@tonic-gate (void) fclose(fp); 840*7c478bd9Sstevel@tonic-gate continue; 841*7c478bd9Sstevel@tonic-gate } 842*7c478bd9Sstevel@tonic-gate } 843*7c478bd9Sstevel@tonic-gate (void) fclose(fp); 844*7c478bd9Sstevel@tonic-gate 845*7c478bd9Sstevel@tonic-gate (void) sprintf(fname, "%s/%s", tp->t_tag, svctag); 846*7c478bd9Sstevel@tonic-gate 847*7c478bd9Sstevel@tonic-gate /* 848*7c478bd9Sstevel@tonic-gate * do_config does all the real work (keep track if any errors occurred) 849*7c478bd9Sstevel@tonic-gate */ 850*7c478bd9Sstevel@tonic-gate 851*7c478bd9Sstevel@tonic-gate if (do_config(script, fname) == 0) 852*7c478bd9Sstevel@tonic-gate added++; 853*7c478bd9Sstevel@tonic-gate tp = tp->t_next; 854*7c478bd9Sstevel@tonic-gate } 855*7c478bd9Sstevel@tonic-gate if (added == 0) { 856*7c478bd9Sstevel@tonic-gate Saferrno = E_SAFERR; 857*7c478bd9Sstevel@tonic-gate error("No configuration scripts installed"); 858*7c478bd9Sstevel@tonic-gate } 859*7c478bd9Sstevel@tonic-gate return; 860*7c478bd9Sstevel@tonic-gate } 861*7c478bd9Sstevel@tonic-gate 862*7c478bd9Sstevel@tonic-gate 863*7c478bd9Sstevel@tonic-gate /* 864*7c478bd9Sstevel@tonic-gate * tell_sac - use sacadm to tell the sac to tell a port monitor to read 865*7c478bd9Sstevel@tonic-gate * its _pmtab. Return TRUE on success, FALSE on failure. 866*7c478bd9Sstevel@tonic-gate * 867*7c478bd9Sstevel@tonic-gate * args: tag - tag of port monitor to be notified 868*7c478bd9Sstevel@tonic-gate */ 869*7c478bd9Sstevel@tonic-gate 870*7c478bd9Sstevel@tonic-gate 871*7c478bd9Sstevel@tonic-gate tell_sac(tag) 872*7c478bd9Sstevel@tonic-gate char *tag; 873*7c478bd9Sstevel@tonic-gate { 874*7c478bd9Sstevel@tonic-gate pid_t pid; /* returned pid from fork */ 875*7c478bd9Sstevel@tonic-gate int status; /* return status from sacadm child */ 876*7c478bd9Sstevel@tonic-gate 877*7c478bd9Sstevel@tonic-gate if ((pid = fork()) < 0) { 878*7c478bd9Sstevel@tonic-gate (void) fprintf(stderr, "warning - fork failed - could not notify <%s> about modified table\n", tag); 879*7c478bd9Sstevel@tonic-gate (void) fprintf(stderr, "try executing the command \"sacadm -x -p %s\"\n", tag); 880*7c478bd9Sstevel@tonic-gate Saferrno = E_SYSERR; 881*7c478bd9Sstevel@tonic-gate return(FALSE); 882*7c478bd9Sstevel@tonic-gate } 883*7c478bd9Sstevel@tonic-gate else if (pid) { 884*7c478bd9Sstevel@tonic-gate /* parent */ 885*7c478bd9Sstevel@tonic-gate (void) wait(&status); 886*7c478bd9Sstevel@tonic-gate if (status) { 887*7c478bd9Sstevel@tonic-gate if (((status >> 8) & 0xff) == E_PMNOTRUN) { 888*7c478bd9Sstevel@tonic-gate (void) fprintf(stderr, "warning - port monitor, %s is not running\n", tag); 889*7c478bd9Sstevel@tonic-gate return (FALSE); 890*7c478bd9Sstevel@tonic-gate } 891*7c478bd9Sstevel@tonic-gate if (((status >> 8) & 0xff) == E_SACNOTRUN) { 892*7c478bd9Sstevel@tonic-gate Saferrno = E_SACNOTRUN; 893*7c478bd9Sstevel@tonic-gate } else { 894*7c478bd9Sstevel@tonic-gate Saferrno = E_SYSERR; 895*7c478bd9Sstevel@tonic-gate } 896*7c478bd9Sstevel@tonic-gate (void) fprintf(stderr, 897*7c478bd9Sstevel@tonic-gate "warning - could not notify <%s> about modified" 898*7c478bd9Sstevel@tonic-gate " table\n", tag); 899*7c478bd9Sstevel@tonic-gate (void) fprintf(stderr, "try executing the command" 900*7c478bd9Sstevel@tonic-gate " \"sacadm -x -p %s\"\n", tag); 901*7c478bd9Sstevel@tonic-gate return(FALSE); 902*7c478bd9Sstevel@tonic-gate } 903*7c478bd9Sstevel@tonic-gate else { 904*7c478bd9Sstevel@tonic-gate return(TRUE); 905*7c478bd9Sstevel@tonic-gate } 906*7c478bd9Sstevel@tonic-gate } 907*7c478bd9Sstevel@tonic-gate else { 908*7c478bd9Sstevel@tonic-gate /* set IFS for security */ 909*7c478bd9Sstevel@tonic-gate (void) putenv("IFS=\" \""); 910*7c478bd9Sstevel@tonic-gate /* muffle sacadm warning messages */ 911*7c478bd9Sstevel@tonic-gate (void) fclose(stderr); 912*7c478bd9Sstevel@tonic-gate (void) fopen("/dev/null", "w"); 913*7c478bd9Sstevel@tonic-gate (void) execl("/usr/sbin/sacadm", "sacadm", "-x", "-p", tag, 0); 914*7c478bd9Sstevel@tonic-gate 915*7c478bd9Sstevel@tonic-gate /* 916*7c478bd9Sstevel@tonic-gate * if we got here, it didn't work, exit status will clue in parent to 917*7c478bd9Sstevel@tonic-gate * put out the warning 918*7c478bd9Sstevel@tonic-gate */ 919*7c478bd9Sstevel@tonic-gate 920*7c478bd9Sstevel@tonic-gate exit(1); 921*7c478bd9Sstevel@tonic-gate } 922*7c478bd9Sstevel@tonic-gate /* NOTREACHED */ 923*7c478bd9Sstevel@tonic-gate } 924*7c478bd9Sstevel@tonic-gate 925*7c478bd9Sstevel@tonic-gate 926*7c478bd9Sstevel@tonic-gate /* 927*7c478bd9Sstevel@tonic-gate * list_svcs - list information about services 928*7c478bd9Sstevel@tonic-gate * 929*7c478bd9Sstevel@tonic-gate * args: pmtag - tag of port monitor responsible for the service 930*7c478bd9Sstevel@tonic-gate * (may be null) 931*7c478bd9Sstevel@tonic-gate * type - type of port monitor responsible for the service 932*7c478bd9Sstevel@tonic-gate * (may be null) 933*7c478bd9Sstevel@tonic-gate * svctag - tag of service to be listed (may be null) 934*7c478bd9Sstevel@tonic-gate * oflag - true if output should be easily parseable 935*7c478bd9Sstevel@tonic-gate */ 936*7c478bd9Sstevel@tonic-gate 937*7c478bd9Sstevel@tonic-gate void 938*7c478bd9Sstevel@tonic-gate list_svcs(pmtag, type, svctag, oflag) 939*7c478bd9Sstevel@tonic-gate char *pmtag; 940*7c478bd9Sstevel@tonic-gate char *type; 941*7c478bd9Sstevel@tonic-gate char *svctag; 942*7c478bd9Sstevel@tonic-gate { 943*7c478bd9Sstevel@tonic-gate FILE *fp; /* scratch file pointer */ 944*7c478bd9Sstevel@tonic-gate register struct taglist *tp; /* pointer to PM list */ 945*7c478bd9Sstevel@tonic-gate int nprint = 0; /* count # of svcs printed */ 946*7c478bd9Sstevel@tonic-gate struct pmtab pmtab; /* place to hold parsed info */ 947*7c478bd9Sstevel@tonic-gate register struct pmtab *pp = &pmtab; /* and a pointer to it */ 948*7c478bd9Sstevel@tonic-gate register char *p; /* working pointer */ 949*7c478bd9Sstevel@tonic-gate char buf[SIZE]; /* scratch buffer */ 950*7c478bd9Sstevel@tonic-gate char fname[SIZE]; /* scratch buffer for building names */ 951*7c478bd9Sstevel@tonic-gate 952*7c478bd9Sstevel@tonic-gate fp = fopen(SACTAB, "r"); 953*7c478bd9Sstevel@tonic-gate if (fp == NULL) { 954*7c478bd9Sstevel@tonic-gate Saferrno = E_SYSERR; 955*7c478bd9Sstevel@tonic-gate error("Could not open _sactab"); 956*7c478bd9Sstevel@tonic-gate } 957*7c478bd9Sstevel@tonic-gate if (pmtag && !find_pm(fp, pmtag)) { 958*7c478bd9Sstevel@tonic-gate (void) sprintf(buf, "Invalid request, %s does not exist", pmtag); 959*7c478bd9Sstevel@tonic-gate Saferrno = E_NOEXIST; 960*7c478bd9Sstevel@tonic-gate error(buf); 961*7c478bd9Sstevel@tonic-gate } 962*7c478bd9Sstevel@tonic-gate rewind(fp); 963*7c478bd9Sstevel@tonic-gate if (type) { 964*7c478bd9Sstevel@tonic-gate tp = find_type(fp, type); 965*7c478bd9Sstevel@tonic-gate if (tp == NULL) { 966*7c478bd9Sstevel@tonic-gate (void) sprintf(buf, "Invalid request, %s does not exist", type); 967*7c478bd9Sstevel@tonic-gate Saferrno = E_NOEXIST; 968*7c478bd9Sstevel@tonic-gate error(buf); 969*7c478bd9Sstevel@tonic-gate } 970*7c478bd9Sstevel@tonic-gate } 971*7c478bd9Sstevel@tonic-gate else 972*7c478bd9Sstevel@tonic-gate tp = find_type(fp, NULL); 973*7c478bd9Sstevel@tonic-gate (void) fclose(fp); 974*7c478bd9Sstevel@tonic-gate 975*7c478bd9Sstevel@tonic-gate while (tp) { 976*7c478bd9Sstevel@tonic-gate if (pmtag && strcmp(tp->t_tag, pmtag)) { 977*7c478bd9Sstevel@tonic-gate /* not interested in this port monitor */ 978*7c478bd9Sstevel@tonic-gate tp = tp->t_next; 979*7c478bd9Sstevel@tonic-gate continue; 980*7c478bd9Sstevel@tonic-gate } 981*7c478bd9Sstevel@tonic-gate (void) sprintf(fname, "%s/%s/_pmtab", HOME, tp->t_tag); 982*7c478bd9Sstevel@tonic-gate fp = fopen(fname, "r"); 983*7c478bd9Sstevel@tonic-gate if (fp == NULL) { 984*7c478bd9Sstevel@tonic-gate (void) sprintf(buf, "Could not open %s", fname); 985*7c478bd9Sstevel@tonic-gate Saferrno = E_SYSERR; 986*7c478bd9Sstevel@tonic-gate error(buf); 987*7c478bd9Sstevel@tonic-gate } 988*7c478bd9Sstevel@tonic-gate while (fgets(buf, SIZE, fp)) { 989*7c478bd9Sstevel@tonic-gate p = trim(buf); 990*7c478bd9Sstevel@tonic-gate if (*p == '\0') 991*7c478bd9Sstevel@tonic-gate continue; 992*7c478bd9Sstevel@tonic-gate parseline(p, pp, tp->t_tag); 993*7c478bd9Sstevel@tonic-gate if (!svctag || !strcmp(pp->p_tag, svctag)) { 994*7c478bd9Sstevel@tonic-gate if (oflag) { 995*7c478bd9Sstevel@tonic-gate (void) printf("%s:%s:%s:%s:%s:%s:%s:%s:%s#%s\n", 996*7c478bd9Sstevel@tonic-gate tp->t_tag, tp->t_type, pp->p_tag, 997*7c478bd9Sstevel@tonic-gate pflags(pp->p_flags, FALSE), 998*7c478bd9Sstevel@tonic-gate pp->p_id, pp->p_res1, pp->p_res2, 999*7c478bd9Sstevel@tonic-gate pp->p_res3,pp->p_pmspec, Comment); 1000*7c478bd9Sstevel@tonic-gate } 1001*7c478bd9Sstevel@tonic-gate else { 1002*7c478bd9Sstevel@tonic-gate if (nprint == 0) { 1003*7c478bd9Sstevel@tonic-gate (void) printf("PMTAG PMTYPE SVCTAG FLGS ID <PMSPECIFIC>\n"); 1004*7c478bd9Sstevel@tonic-gate } 1005*7c478bd9Sstevel@tonic-gate (void) printf("%-14s %-14s %-14s %-4s %-8s %s #%s\n", tp->t_tag, tp->t_type, pp->p_tag, 1006*7c478bd9Sstevel@tonic-gate pflags(pp->p_flags, TRUE), pp->p_id, pspec(pp->p_pmspec), Comment); 1007*7c478bd9Sstevel@tonic-gate } 1008*7c478bd9Sstevel@tonic-gate nprint++; 1009*7c478bd9Sstevel@tonic-gate } 1010*7c478bd9Sstevel@tonic-gate } 1011*7c478bd9Sstevel@tonic-gate if (!feof(fp)) { 1012*7c478bd9Sstevel@tonic-gate (void) sprintf(buf, "error reading %s", fname); 1013*7c478bd9Sstevel@tonic-gate Saferrno = E_SYSERR; 1014*7c478bd9Sstevel@tonic-gate error(buf); 1015*7c478bd9Sstevel@tonic-gate } 1016*7c478bd9Sstevel@tonic-gate else { 1017*7c478bd9Sstevel@tonic-gate (void) fclose(fp); 1018*7c478bd9Sstevel@tonic-gate tp = tp->t_next; 1019*7c478bd9Sstevel@tonic-gate } 1020*7c478bd9Sstevel@tonic-gate } 1021*7c478bd9Sstevel@tonic-gate /* if we didn't find any valid ones, indicate an error */ 1022*7c478bd9Sstevel@tonic-gate if (nprint == 0) { 1023*7c478bd9Sstevel@tonic-gate if (svctag) 1024*7c478bd9Sstevel@tonic-gate (void) fprintf(stderr, "Service <%s> does not exist\n", svctag); 1025*7c478bd9Sstevel@tonic-gate else 1026*7c478bd9Sstevel@tonic-gate (void) fprintf(stderr, "No services defined\n"); 1027*7c478bd9Sstevel@tonic-gate Saferrno = E_NOEXIST; 1028*7c478bd9Sstevel@tonic-gate } 1029*7c478bd9Sstevel@tonic-gate return; 1030*7c478bd9Sstevel@tonic-gate } 1031*7c478bd9Sstevel@tonic-gate 1032*7c478bd9Sstevel@tonic-gate 1033*7c478bd9Sstevel@tonic-gate /* 1034*7c478bd9Sstevel@tonic-gate * find_svc - find an entry in _pmtab for a particular service tag 1035*7c478bd9Sstevel@tonic-gate * 1036*7c478bd9Sstevel@tonic-gate * args: fp - file pointer for _pmtab 1037*7c478bd9Sstevel@tonic-gate * tag - port monitor tag (for error reporting) 1038*7c478bd9Sstevel@tonic-gate * svctag - tag of service we're looking for 1039*7c478bd9Sstevel@tonic-gate */ 1040*7c478bd9Sstevel@tonic-gate 1041*7c478bd9Sstevel@tonic-gate find_svc(fp, tag, svctag) 1042*7c478bd9Sstevel@tonic-gate FILE *fp; 1043*7c478bd9Sstevel@tonic-gate char *tag; 1044*7c478bd9Sstevel@tonic-gate char *svctag; 1045*7c478bd9Sstevel@tonic-gate { 1046*7c478bd9Sstevel@tonic-gate register char *p; /* working pointer */ 1047*7c478bd9Sstevel@tonic-gate int line = 0; /* line number we found entry on */ 1048*7c478bd9Sstevel@tonic-gate struct pmtab pmtab; /* place to hold parsed info */ 1049*7c478bd9Sstevel@tonic-gate static char buf[SIZE]; /* scratch buffer */ 1050*7c478bd9Sstevel@tonic-gate 1051*7c478bd9Sstevel@tonic-gate while (fgets(buf, SIZE, fp)) { 1052*7c478bd9Sstevel@tonic-gate line++; 1053*7c478bd9Sstevel@tonic-gate p = trim(buf); 1054*7c478bd9Sstevel@tonic-gate if (*p == '\0') 1055*7c478bd9Sstevel@tonic-gate continue; 1056*7c478bd9Sstevel@tonic-gate parseline(p, &pmtab, tag); 1057*7c478bd9Sstevel@tonic-gate if (!(strcmp(pmtab.p_tag, svctag))) 1058*7c478bd9Sstevel@tonic-gate return(line); 1059*7c478bd9Sstevel@tonic-gate } 1060*7c478bd9Sstevel@tonic-gate if (!feof(fp)) { 1061*7c478bd9Sstevel@tonic-gate (void) sprintf(buf, "error reading %s/%s/_pmtab", HOME, tag); 1062*7c478bd9Sstevel@tonic-gate Saferrno = E_SYSERR; 1063*7c478bd9Sstevel@tonic-gate error(buf); 1064*7c478bd9Sstevel@tonic-gate } 1065*7c478bd9Sstevel@tonic-gate else 1066*7c478bd9Sstevel@tonic-gate return(0); 1067*7c478bd9Sstevel@tonic-gate /* NOTREACHED */ 1068*7c478bd9Sstevel@tonic-gate } 1069*7c478bd9Sstevel@tonic-gate 1070*7c478bd9Sstevel@tonic-gate 1071*7c478bd9Sstevel@tonic-gate /* 1072*7c478bd9Sstevel@tonic-gate * parseline - parse a line from _pmtab. This routine will return if the 1073*7c478bd9Sstevel@tonic-gate * parse wa successful, otherwise it will output an error and 1074*7c478bd9Sstevel@tonic-gate * exit. 1075*7c478bd9Sstevel@tonic-gate * 1076*7c478bd9Sstevel@tonic-gate * args: p - pointer to the data read from the file (note - this is 1077*7c478bd9Sstevel@tonic-gate * a static data region, so we can point into it) 1078*7c478bd9Sstevel@tonic-gate * pp - pointer to a structure in which the separated fields 1079*7c478bd9Sstevel@tonic-gate * are placed 1080*7c478bd9Sstevel@tonic-gate * tag - port monitor tag (for error reporting) 1081*7c478bd9Sstevel@tonic-gate * 1082*7c478bd9Sstevel@tonic-gate * A line in the file has the following format: 1083*7c478bd9Sstevel@tonic-gate * 1084*7c478bd9Sstevel@tonic-gate * tag:flags:identity:reserved:reserved:reserved:PM_spec_info # comment 1085*7c478bd9Sstevel@tonic-gate */ 1086*7c478bd9Sstevel@tonic-gate 1087*7c478bd9Sstevel@tonic-gate 1088*7c478bd9Sstevel@tonic-gate void 1089*7c478bd9Sstevel@tonic-gate parseline(p, pp, tag) 1090*7c478bd9Sstevel@tonic-gate register char *p; 1091*7c478bd9Sstevel@tonic-gate register struct pmtab *pp; 1092*7c478bd9Sstevel@tonic-gate char *tag; 1093*7c478bd9Sstevel@tonic-gate { 1094*7c478bd9Sstevel@tonic-gate char buf[SIZE]; /* scratch buffer */ 1095*7c478bd9Sstevel@tonic-gate 1096*7c478bd9Sstevel@tonic-gate /* 1097*7c478bd9Sstevel@tonic-gate * get the service tag 1098*7c478bd9Sstevel@tonic-gate */ 1099*7c478bd9Sstevel@tonic-gate 1100*7c478bd9Sstevel@tonic-gate p = nexttok(p, DELIM, FALSE); 1101*7c478bd9Sstevel@tonic-gate if (p == NULL) { 1102*7c478bd9Sstevel@tonic-gate (void) sprintf(buf, "%s/%s/_pmtab is corrupt", HOME, tag); 1103*7c478bd9Sstevel@tonic-gate Saferrno = E_SAFERR; 1104*7c478bd9Sstevel@tonic-gate error(buf); 1105*7c478bd9Sstevel@tonic-gate } 1106*7c478bd9Sstevel@tonic-gate if (strlen(p) > PMTAGSIZE) { 1107*7c478bd9Sstevel@tonic-gate p[PMTAGSIZE] = '\0'; 1108*7c478bd9Sstevel@tonic-gate (void) fprintf(stderr, "tag too long, truncated to <%s>", p); 1109*7c478bd9Sstevel@tonic-gate } 1110*7c478bd9Sstevel@tonic-gate pp->p_tag = p; 1111*7c478bd9Sstevel@tonic-gate 1112*7c478bd9Sstevel@tonic-gate /* 1113*7c478bd9Sstevel@tonic-gate * get the flags 1114*7c478bd9Sstevel@tonic-gate */ 1115*7c478bd9Sstevel@tonic-gate 1116*7c478bd9Sstevel@tonic-gate p = nexttok(NULL, DELIM, FALSE); 1117*7c478bd9Sstevel@tonic-gate if (p == NULL) { 1118*7c478bd9Sstevel@tonic-gate (void) sprintf(buf, "%s/%s/_pmtab is corrupt", HOME, tag); 1119*7c478bd9Sstevel@tonic-gate Saferrno = E_SAFERR; 1120*7c478bd9Sstevel@tonic-gate error(buf); 1121*7c478bd9Sstevel@tonic-gate } 1122*7c478bd9Sstevel@tonic-gate pp->p_flags = 0; 1123*7c478bd9Sstevel@tonic-gate while (*p) { 1124*7c478bd9Sstevel@tonic-gate switch (*p++) { 1125*7c478bd9Sstevel@tonic-gate case 'u': 1126*7c478bd9Sstevel@tonic-gate pp->p_flags |= U_FLAG; 1127*7c478bd9Sstevel@tonic-gate break; 1128*7c478bd9Sstevel@tonic-gate case 'x': 1129*7c478bd9Sstevel@tonic-gate pp->p_flags |= X_FLAG; 1130*7c478bd9Sstevel@tonic-gate break; 1131*7c478bd9Sstevel@tonic-gate default: 1132*7c478bd9Sstevel@tonic-gate (void) sprintf(buf, "Unrecognized flag <%c>", *(p - 1)); 1133*7c478bd9Sstevel@tonic-gate Saferrno = E_SAFERR; 1134*7c478bd9Sstevel@tonic-gate error(buf); 1135*7c478bd9Sstevel@tonic-gate break; 1136*7c478bd9Sstevel@tonic-gate } 1137*7c478bd9Sstevel@tonic-gate } 1138*7c478bd9Sstevel@tonic-gate 1139*7c478bd9Sstevel@tonic-gate /* 1140*7c478bd9Sstevel@tonic-gate * get the identity 1141*7c478bd9Sstevel@tonic-gate */ 1142*7c478bd9Sstevel@tonic-gate 1143*7c478bd9Sstevel@tonic-gate p = nexttok(NULL, DELIM, FALSE); 1144*7c478bd9Sstevel@tonic-gate if (p == NULL) { 1145*7c478bd9Sstevel@tonic-gate (void) sprintf(buf, "%s/%s/_pmtab is corrupt", HOME, tag); 1146*7c478bd9Sstevel@tonic-gate Saferrno = E_SAFERR; 1147*7c478bd9Sstevel@tonic-gate error(buf); 1148*7c478bd9Sstevel@tonic-gate } 1149*7c478bd9Sstevel@tonic-gate pp->p_id = p; 1150*7c478bd9Sstevel@tonic-gate 1151*7c478bd9Sstevel@tonic-gate /* 1152*7c478bd9Sstevel@tonic-gate * get the first reserved field 1153*7c478bd9Sstevel@tonic-gate */ 1154*7c478bd9Sstevel@tonic-gate 1155*7c478bd9Sstevel@tonic-gate p = nexttok(NULL, DELIM, FALSE); 1156*7c478bd9Sstevel@tonic-gate if (p == NULL) { 1157*7c478bd9Sstevel@tonic-gate (void) sprintf(buf, "%s/%s/_pmtab is corrupt", HOME, tag); 1158*7c478bd9Sstevel@tonic-gate Saferrno = E_SAFERR; 1159*7c478bd9Sstevel@tonic-gate error(buf); 1160*7c478bd9Sstevel@tonic-gate } 1161*7c478bd9Sstevel@tonic-gate pp->p_res1 = p; 1162*7c478bd9Sstevel@tonic-gate 1163*7c478bd9Sstevel@tonic-gate /* 1164*7c478bd9Sstevel@tonic-gate * get the second reserved field 1165*7c478bd9Sstevel@tonic-gate */ 1166*7c478bd9Sstevel@tonic-gate 1167*7c478bd9Sstevel@tonic-gate p = nexttok(NULL, DELIM, FALSE); 1168*7c478bd9Sstevel@tonic-gate if (p == NULL) { 1169*7c478bd9Sstevel@tonic-gate (void) sprintf(buf, "%s/%s/_pmtab is corrupt", HOME, tag); 1170*7c478bd9Sstevel@tonic-gate Saferrno = E_SAFERR; 1171*7c478bd9Sstevel@tonic-gate error(buf); 1172*7c478bd9Sstevel@tonic-gate } 1173*7c478bd9Sstevel@tonic-gate pp->p_res2 = p; 1174*7c478bd9Sstevel@tonic-gate 1175*7c478bd9Sstevel@tonic-gate /* 1176*7c478bd9Sstevel@tonic-gate * get the third reserved field 1177*7c478bd9Sstevel@tonic-gate */ 1178*7c478bd9Sstevel@tonic-gate 1179*7c478bd9Sstevel@tonic-gate p = nexttok(NULL, DELIM, FALSE); 1180*7c478bd9Sstevel@tonic-gate if (p == NULL) { 1181*7c478bd9Sstevel@tonic-gate (void) sprintf(buf, "%s/%s/_pmtab is corrupt", HOME, tag); 1182*7c478bd9Sstevel@tonic-gate Saferrno = E_SAFERR; 1183*7c478bd9Sstevel@tonic-gate error(buf); 1184*7c478bd9Sstevel@tonic-gate } 1185*7c478bd9Sstevel@tonic-gate pp->p_res3 = p; 1186*7c478bd9Sstevel@tonic-gate 1187*7c478bd9Sstevel@tonic-gate /* 1188*7c478bd9Sstevel@tonic-gate * the rest is the port monitor specific info 1189*7c478bd9Sstevel@tonic-gate */ 1190*7c478bd9Sstevel@tonic-gate 1191*7c478bd9Sstevel@tonic-gate p = nexttok(NULL, DELIM, TRUE); 1192*7c478bd9Sstevel@tonic-gate if (p == NULL) { 1193*7c478bd9Sstevel@tonic-gate (void) sprintf(buf, "%s/%s/_pmtab is corrupt", HOME, tag); 1194*7c478bd9Sstevel@tonic-gate Saferrno = E_SAFERR; 1195*7c478bd9Sstevel@tonic-gate error(buf); 1196*7c478bd9Sstevel@tonic-gate } 1197*7c478bd9Sstevel@tonic-gate pp->p_pmspec = p; 1198*7c478bd9Sstevel@tonic-gate return; 1199*7c478bd9Sstevel@tonic-gate } 1200*7c478bd9Sstevel@tonic-gate 1201*7c478bd9Sstevel@tonic-gate 1202*7c478bd9Sstevel@tonic-gate /* 1203*7c478bd9Sstevel@tonic-gate * pspec - format port monitor specific information 1204*7c478bd9Sstevel@tonic-gate * 1205*7c478bd9Sstevel@tonic-gate * args: spec - port monitor specific info, separated by 1206*7c478bd9Sstevel@tonic-gate * field separater character (may be escaped by \) 1207*7c478bd9Sstevel@tonic-gate */ 1208*7c478bd9Sstevel@tonic-gate 1209*7c478bd9Sstevel@tonic-gate char * 1210*7c478bd9Sstevel@tonic-gate pspec(spec) 1211*7c478bd9Sstevel@tonic-gate char *spec; 1212*7c478bd9Sstevel@tonic-gate { 1213*7c478bd9Sstevel@tonic-gate static char buf[SIZE]; /* returned string */ 1214*7c478bd9Sstevel@tonic-gate register char *from; /* working pointer */ 1215*7c478bd9Sstevel@tonic-gate register char *to; /* working pointer */ 1216*7c478bd9Sstevel@tonic-gate int newflag; /* flag indicating new field */ 1217*7c478bd9Sstevel@tonic-gate 1218*7c478bd9Sstevel@tonic-gate to = buf; 1219*7c478bd9Sstevel@tonic-gate from = spec; 1220*7c478bd9Sstevel@tonic-gate newflag = 1; 1221*7c478bd9Sstevel@tonic-gate while (*from) { 1222*7c478bd9Sstevel@tonic-gate switch (*from) { 1223*7c478bd9Sstevel@tonic-gate case ':': 1224*7c478bd9Sstevel@tonic-gate if (newflag) { 1225*7c478bd9Sstevel@tonic-gate *to++ = '-'; 1226*7c478bd9Sstevel@tonic-gate } 1227*7c478bd9Sstevel@tonic-gate *to++ = ' '; 1228*7c478bd9Sstevel@tonic-gate from++; 1229*7c478bd9Sstevel@tonic-gate newflag = 1; 1230*7c478bd9Sstevel@tonic-gate break; 1231*7c478bd9Sstevel@tonic-gate case '\\': 1232*7c478bd9Sstevel@tonic-gate if (*(from + 1) == ':') { 1233*7c478bd9Sstevel@tonic-gate *to++ = ':'; 1234*7c478bd9Sstevel@tonic-gate /* skip over \: */ 1235*7c478bd9Sstevel@tonic-gate from += 2; 1236*7c478bd9Sstevel@tonic-gate } 1237*7c478bd9Sstevel@tonic-gate else 1238*7c478bd9Sstevel@tonic-gate *to++ = *from++; 1239*7c478bd9Sstevel@tonic-gate newflag = 0; 1240*7c478bd9Sstevel@tonic-gate break; 1241*7c478bd9Sstevel@tonic-gate default: 1242*7c478bd9Sstevel@tonic-gate newflag = 0; 1243*7c478bd9Sstevel@tonic-gate *to++ = *from++; 1244*7c478bd9Sstevel@tonic-gate } 1245*7c478bd9Sstevel@tonic-gate } 1246*7c478bd9Sstevel@tonic-gate *to = '\0'; 1247*7c478bd9Sstevel@tonic-gate return(buf); 1248*7c478bd9Sstevel@tonic-gate } 1249*7c478bd9Sstevel@tonic-gate 1250*7c478bd9Sstevel@tonic-gate 1251*7c478bd9Sstevel@tonic-gate /* 1252*7c478bd9Sstevel@tonic-gate * pflags - put service flags into intelligible form for output 1253*7c478bd9Sstevel@tonic-gate * 1254*7c478bd9Sstevel@tonic-gate * args: flags - binary representation of flags 1255*7c478bd9Sstevel@tonic-gate * dflag - true if a "-" should be returned if no flags 1256*7c478bd9Sstevel@tonic-gate */ 1257*7c478bd9Sstevel@tonic-gate 1258*7c478bd9Sstevel@tonic-gate char * 1259*7c478bd9Sstevel@tonic-gate pflags(flags, dflag) 1260*7c478bd9Sstevel@tonic-gate long flags; 1261*7c478bd9Sstevel@tonic-gate int dflag; 1262*7c478bd9Sstevel@tonic-gate { 1263*7c478bd9Sstevel@tonic-gate register int i; /* scratch counter */ 1264*7c478bd9Sstevel@tonic-gate static char buf[SIZE]; /* formatted flags */ 1265*7c478bd9Sstevel@tonic-gate 1266*7c478bd9Sstevel@tonic-gate if (flags == 0) { 1267*7c478bd9Sstevel@tonic-gate if (dflag) 1268*7c478bd9Sstevel@tonic-gate return("-"); 1269*7c478bd9Sstevel@tonic-gate else 1270*7c478bd9Sstevel@tonic-gate return(""); 1271*7c478bd9Sstevel@tonic-gate } 1272*7c478bd9Sstevel@tonic-gate i = 0; 1273*7c478bd9Sstevel@tonic-gate if (flags & U_FLAG) { 1274*7c478bd9Sstevel@tonic-gate buf[i++] = 'u'; 1275*7c478bd9Sstevel@tonic-gate flags &= ~U_FLAG; 1276*7c478bd9Sstevel@tonic-gate } 1277*7c478bd9Sstevel@tonic-gate if (flags & X_FLAG) { 1278*7c478bd9Sstevel@tonic-gate buf[i++] = 'x'; 1279*7c478bd9Sstevel@tonic-gate flags &= ~X_FLAG; 1280*7c478bd9Sstevel@tonic-gate } 1281*7c478bd9Sstevel@tonic-gate if (flags) { 1282*7c478bd9Sstevel@tonic-gate Saferrno = E_SAFERR; 1283*7c478bd9Sstevel@tonic-gate error("Internal error in pflags"); 1284*7c478bd9Sstevel@tonic-gate } 1285*7c478bd9Sstevel@tonic-gate buf[i] = '\0'; 1286*7c478bd9Sstevel@tonic-gate return(buf); 1287*7c478bd9Sstevel@tonic-gate } 1288*7c478bd9Sstevel@tonic-gate 1289*7c478bd9Sstevel@tonic-gate 1290*7c478bd9Sstevel@tonic-gate /* 1291*7c478bd9Sstevel@tonic-gate * find_type - find entries in _sactab for a particular port monitor type 1292*7c478bd9Sstevel@tonic-gate * 1293*7c478bd9Sstevel@tonic-gate * args: fp - file pointer for _sactab 1294*7c478bd9Sstevel@tonic-gate * type - type of port monitor we're looking for (if type is 1295*7c478bd9Sstevel@tonic-gate * null, it means find all PMs) 1296*7c478bd9Sstevel@tonic-gate */ 1297*7c478bd9Sstevel@tonic-gate 1298*7c478bd9Sstevel@tonic-gate struct taglist * 1299*7c478bd9Sstevel@tonic-gate find_type(fp, type) 1300*7c478bd9Sstevel@tonic-gate FILE *fp; 1301*7c478bd9Sstevel@tonic-gate char *type; 1302*7c478bd9Sstevel@tonic-gate { 1303*7c478bd9Sstevel@tonic-gate register char *p; /* working pointer */ 1304*7c478bd9Sstevel@tonic-gate struct sactab stab; /* place to hold parsed info */ 1305*7c478bd9Sstevel@tonic-gate register struct sactab *sp = &stab; /* and a pointer to it */ 1306*7c478bd9Sstevel@tonic-gate char buf[SIZE]; /* scratch buffer */ 1307*7c478bd9Sstevel@tonic-gate struct taglist *thead; /* linked list of tags */ 1308*7c478bd9Sstevel@tonic-gate register struct taglist *temp; /* scratch pointer */ 1309*7c478bd9Sstevel@tonic-gate 1310*7c478bd9Sstevel@tonic-gate thead = NULL; 1311*7c478bd9Sstevel@tonic-gate while (fgets(buf, SIZE, fp)) { 1312*7c478bd9Sstevel@tonic-gate p = trim(buf); 1313*7c478bd9Sstevel@tonic-gate if (*p == '\0') 1314*7c478bd9Sstevel@tonic-gate continue; 1315*7c478bd9Sstevel@tonic-gate parse(p, sp); 1316*7c478bd9Sstevel@tonic-gate if ((type == NULL) || !(strcmp(sp->sc_type, type))) { 1317*7c478bd9Sstevel@tonic-gate temp = (struct taglist *) malloc(sizeof(struct taglist)); 1318*7c478bd9Sstevel@tonic-gate if (temp == NULL) { 1319*7c478bd9Sstevel@tonic-gate Saferrno = E_SYSERR; 1320*7c478bd9Sstevel@tonic-gate error("malloc failed"); 1321*7c478bd9Sstevel@tonic-gate } 1322*7c478bd9Sstevel@tonic-gate temp->t_next = thead; 1323*7c478bd9Sstevel@tonic-gate (void) strcpy(temp->t_tag, sp->sc_tag); 1324*7c478bd9Sstevel@tonic-gate (void) strcpy(temp->t_type, sp->sc_type); 1325*7c478bd9Sstevel@tonic-gate thead = temp; 1326*7c478bd9Sstevel@tonic-gate } 1327*7c478bd9Sstevel@tonic-gate } 1328*7c478bd9Sstevel@tonic-gate if (!feof(fp)) { 1329*7c478bd9Sstevel@tonic-gate Saferrno = E_SYSERR; 1330*7c478bd9Sstevel@tonic-gate error("error reading _sactab"); 1331*7c478bd9Sstevel@tonic-gate } 1332*7c478bd9Sstevel@tonic-gate else 1333*7c478bd9Sstevel@tonic-gate return(thead ? thead : NULL); 1334*7c478bd9Sstevel@tonic-gate /* NOTREACHED */ 1335*7c478bd9Sstevel@tonic-gate } 1336