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 (c) 1999 by Sun Microsystems, Inc. 24*7c478bd9Sstevel@tonic-gate * All rights reserved. 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 31*7c478bd9Sstevel@tonic-gate #pragma ident "%Z%%M% %I% %E% SMI" /* SVr4.0 1.15*/ 32*7c478bd9Sstevel@tonic-gate 33*7c478bd9Sstevel@tonic-gate 34*7c478bd9Sstevel@tonic-gate # include <stdio.h> 35*7c478bd9Sstevel@tonic-gate # include <fcntl.h> 36*7c478bd9Sstevel@tonic-gate # include <errno.h> 37*7c478bd9Sstevel@tonic-gate # include <sys/types.h> 38*7c478bd9Sstevel@tonic-gate # include <sys/stat.h> 39*7c478bd9Sstevel@tonic-gate # include <signal.h> 40*7c478bd9Sstevel@tonic-gate # include <unistd.h> 41*7c478bd9Sstevel@tonic-gate # include <sac.h> 42*7c478bd9Sstevel@tonic-gate # include "misc.h" 43*7c478bd9Sstevel@tonic-gate # include "structs.h" 44*7c478bd9Sstevel@tonic-gate # include "adm.h" 45*7c478bd9Sstevel@tonic-gate # include "extern.h" 46*7c478bd9Sstevel@tonic-gate 47*7c478bd9Sstevel@tonic-gate 48*7c478bd9Sstevel@tonic-gate /* 49*7c478bd9Sstevel@tonic-gate * functions 50*7c478bd9Sstevel@tonic-gate */ 51*7c478bd9Sstevel@tonic-gate 52*7c478bd9Sstevel@tonic-gate char *pflags(); 53*7c478bd9Sstevel@tonic-gate char *getfield(); 54*7c478bd9Sstevel@tonic-gate void add_pm(); 55*7c478bd9Sstevel@tonic-gate void cleandirs(); 56*7c478bd9Sstevel@tonic-gate void rem_pm(); 57*7c478bd9Sstevel@tonic-gate void start_pm(); 58*7c478bd9Sstevel@tonic-gate void kill_pm(); 59*7c478bd9Sstevel@tonic-gate void enable_pm(); 60*7c478bd9Sstevel@tonic-gate void disable_pm(); 61*7c478bd9Sstevel@tonic-gate void list_pms(); 62*7c478bd9Sstevel@tonic-gate void read_db(); 63*7c478bd9Sstevel@tonic-gate void sendcmd(); 64*7c478bd9Sstevel@tonic-gate void checkresp(); 65*7c478bd9Sstevel@tonic-gate void single_print(); 66*7c478bd9Sstevel@tonic-gate void catch(); 67*7c478bd9Sstevel@tonic-gate void usage(); 68*7c478bd9Sstevel@tonic-gate 69*7c478bd9Sstevel@tonic-gate # define START 0x1 /* -s seen */ 70*7c478bd9Sstevel@tonic-gate # define KILL 0x2 /* -k seen */ 71*7c478bd9Sstevel@tonic-gate # define ENABLE 0x4 /* -e seen */ 72*7c478bd9Sstevel@tonic-gate # define DISABLE 0x8 /* -d seen */ 73*7c478bd9Sstevel@tonic-gate # define PLIST 0x10 /* -l seen */ 74*7c478bd9Sstevel@tonic-gate # define LIST 0x20 /* -L seen */ 75*7c478bd9Sstevel@tonic-gate # define DBREAD 0x40 /* -x seen */ 76*7c478bd9Sstevel@tonic-gate # define CONFIG 0x80 /* -G seen */ 77*7c478bd9Sstevel@tonic-gate # define PCONFIG 0x100 /* -g seen */ 78*7c478bd9Sstevel@tonic-gate # define ADD 0x200 /* -a or other required options seen */ 79*7c478bd9Sstevel@tonic-gate # define REMOVE 0x400 /* -r seen */ 80*7c478bd9Sstevel@tonic-gate 81*7c478bd9Sstevel@tonic-gate /* 82*7c478bd9Sstevel@tonic-gate * common error messages 83*7c478bd9Sstevel@tonic-gate */ 84*7c478bd9Sstevel@tonic-gate 85*7c478bd9Sstevel@tonic-gate # define NOTPRIV "User not privileged for operation" 86*7c478bd9Sstevel@tonic-gate # define SACERR "Can not contact SAC" 87*7c478bd9Sstevel@tonic-gate # define BADINP "Embedded newlines not allowed" 88*7c478bd9Sstevel@tonic-gate 89*7c478bd9Sstevel@tonic-gate 90*7c478bd9Sstevel@tonic-gate int Saferrno; /* internal `errno' for exit */ 91*7c478bd9Sstevel@tonic-gate 92*7c478bd9Sstevel@tonic-gate 93*7c478bd9Sstevel@tonic-gate /* 94*7c478bd9Sstevel@tonic-gate * main - scan args for sacadm and call appropriate handling code 95*7c478bd9Sstevel@tonic-gate */ 96*7c478bd9Sstevel@tonic-gate 97*7c478bd9Sstevel@tonic-gate main(argc, argv) 98*7c478bd9Sstevel@tonic-gate int argc; 99*7c478bd9Sstevel@tonic-gate char *argv[]; 100*7c478bd9Sstevel@tonic-gate { 101*7c478bd9Sstevel@tonic-gate int c; /* option letter */ 102*7c478bd9Sstevel@tonic-gate uid_t uid; /* invoker's real uid */ 103*7c478bd9Sstevel@tonic-gate int ret; /* return code from check_version */ 104*7c478bd9Sstevel@tonic-gate int flag = 0; /* flag to record requested operations */ 105*7c478bd9Sstevel@tonic-gate int errflg = 0; /* error indicator */ 106*7c478bd9Sstevel@tonic-gate int version = -1; /* argument to -v */ 107*7c478bd9Sstevel@tonic-gate int count = 0; /* argument to -n */ 108*7c478bd9Sstevel@tonic-gate int badcnt = 0; /* count of bad args to -f */ 109*7c478bd9Sstevel@tonic-gate int sawaflag = 0; /* true if actually saw -a */ 110*7c478bd9Sstevel@tonic-gate int conflag = 0; /* true if output should be in condensed form */ 111*7c478bd9Sstevel@tonic-gate long flags = 0; /* arguments to -f */ 112*7c478bd9Sstevel@tonic-gate FILE *fp; /* scratch file pointer */ 113*7c478bd9Sstevel@tonic-gate char *pmtag = NULL; /* argument to -p */ 114*7c478bd9Sstevel@tonic-gate char *type = NULL; /* argument to -t */ 115*7c478bd9Sstevel@tonic-gate char *script = NULL; /* argument to -z */ 116*7c478bd9Sstevel@tonic-gate char *command = NULL; /* argument to -c */ 117*7c478bd9Sstevel@tonic-gate char *comment = " "; /* argument to -y */ 118*7c478bd9Sstevel@tonic-gate char badargs[BADFARGSIZE]; /* place to hold bad args to -f */ 119*7c478bd9Sstevel@tonic-gate char buf[SIZE]; /* scratch buffer */ 120*7c478bd9Sstevel@tonic-gate register char *p; /* scratch pointer */ 121*7c478bd9Sstevel@tonic-gate 122*7c478bd9Sstevel@tonic-gate if (argc == 1) 123*7c478bd9Sstevel@tonic-gate usage(argv[0]); 124*7c478bd9Sstevel@tonic-gate while ((c = getopt(argc, argv, "ac:def:GgkLln:p:rst:v:xy:z:")) != -1) { 125*7c478bd9Sstevel@tonic-gate switch (c) { 126*7c478bd9Sstevel@tonic-gate case 'a': 127*7c478bd9Sstevel@tonic-gate flag |= ADD; 128*7c478bd9Sstevel@tonic-gate sawaflag = 1; 129*7c478bd9Sstevel@tonic-gate break; 130*7c478bd9Sstevel@tonic-gate case 'c': 131*7c478bd9Sstevel@tonic-gate flag |= ADD; 132*7c478bd9Sstevel@tonic-gate if (strchr(optarg, '\n')) { 133*7c478bd9Sstevel@tonic-gate Saferrno = E_BADARGS; 134*7c478bd9Sstevel@tonic-gate error(BADINP); 135*7c478bd9Sstevel@tonic-gate } 136*7c478bd9Sstevel@tonic-gate command = optarg; 137*7c478bd9Sstevel@tonic-gate if (*command != '/') { 138*7c478bd9Sstevel@tonic-gate Saferrno = E_BADARGS; 139*7c478bd9Sstevel@tonic-gate error("command must be a full pathname"); 140*7c478bd9Sstevel@tonic-gate } 141*7c478bd9Sstevel@tonic-gate break; 142*7c478bd9Sstevel@tonic-gate case 'd': 143*7c478bd9Sstevel@tonic-gate flag |= DISABLE; 144*7c478bd9Sstevel@tonic-gate break; 145*7c478bd9Sstevel@tonic-gate case 'e': 146*7c478bd9Sstevel@tonic-gate flag |= ENABLE; 147*7c478bd9Sstevel@tonic-gate break; 148*7c478bd9Sstevel@tonic-gate case 'f': 149*7c478bd9Sstevel@tonic-gate flag |= ADD; 150*7c478bd9Sstevel@tonic-gate while (*optarg) { 151*7c478bd9Sstevel@tonic-gate switch (*optarg++) { 152*7c478bd9Sstevel@tonic-gate case 'd': 153*7c478bd9Sstevel@tonic-gate flags |= D_FLAG; 154*7c478bd9Sstevel@tonic-gate break; 155*7c478bd9Sstevel@tonic-gate case 'x': 156*7c478bd9Sstevel@tonic-gate flags |= X_FLAG; 157*7c478bd9Sstevel@tonic-gate break; 158*7c478bd9Sstevel@tonic-gate default: 159*7c478bd9Sstevel@tonic-gate if (badcnt < (BADFARGSIZE -1)) 160*7c478bd9Sstevel@tonic-gate badargs[badcnt++] = *(optarg - 1); 161*7c478bd9Sstevel@tonic-gate break; 162*7c478bd9Sstevel@tonic-gate } 163*7c478bd9Sstevel@tonic-gate } 164*7c478bd9Sstevel@tonic-gate /* null terminate just in case anything is there */ 165*7c478bd9Sstevel@tonic-gate badargs[badcnt] = '\0'; 166*7c478bd9Sstevel@tonic-gate break; 167*7c478bd9Sstevel@tonic-gate case 'G': 168*7c478bd9Sstevel@tonic-gate flag |= CONFIG; 169*7c478bd9Sstevel@tonic-gate break; 170*7c478bd9Sstevel@tonic-gate case 'g': 171*7c478bd9Sstevel@tonic-gate flag |= PCONFIG; 172*7c478bd9Sstevel@tonic-gate break; 173*7c478bd9Sstevel@tonic-gate case 'k': 174*7c478bd9Sstevel@tonic-gate flag |= KILL; 175*7c478bd9Sstevel@tonic-gate break; 176*7c478bd9Sstevel@tonic-gate case 'L': 177*7c478bd9Sstevel@tonic-gate flag |= LIST; 178*7c478bd9Sstevel@tonic-gate break; 179*7c478bd9Sstevel@tonic-gate case 'l': 180*7c478bd9Sstevel@tonic-gate flag |= PLIST; 181*7c478bd9Sstevel@tonic-gate break; 182*7c478bd9Sstevel@tonic-gate case 'n': 183*7c478bd9Sstevel@tonic-gate flag |= ADD; 184*7c478bd9Sstevel@tonic-gate count = atoi(optarg); 185*7c478bd9Sstevel@tonic-gate if (count < 0) { 186*7c478bd9Sstevel@tonic-gate Saferrno = E_BADARGS; 187*7c478bd9Sstevel@tonic-gate error("restart count can not be negative"); 188*7c478bd9Sstevel@tonic-gate } 189*7c478bd9Sstevel@tonic-gate break; 190*7c478bd9Sstevel@tonic-gate case 'p': 191*7c478bd9Sstevel@tonic-gate pmtag = optarg; 192*7c478bd9Sstevel@tonic-gate if (strchr(optarg, '\n')) { 193*7c478bd9Sstevel@tonic-gate Saferrno = E_BADARGS; 194*7c478bd9Sstevel@tonic-gate error(BADINP); 195*7c478bd9Sstevel@tonic-gate } 196*7c478bd9Sstevel@tonic-gate if (strlen(pmtag) > PMTAGSIZE) { 197*7c478bd9Sstevel@tonic-gate pmtag[PMTAGSIZE] = '\0'; 198*7c478bd9Sstevel@tonic-gate (void) fprintf(stderr, "tag too long, truncated to <%s>\n", pmtag); 199*7c478bd9Sstevel@tonic-gate } 200*7c478bd9Sstevel@tonic-gate for (p = pmtag; *p; p++) { 201*7c478bd9Sstevel@tonic-gate if (!isalnum(*p)) { 202*7c478bd9Sstevel@tonic-gate Saferrno = E_BADARGS; 203*7c478bd9Sstevel@tonic-gate error("port monitor tag must be alphanumeric"); 204*7c478bd9Sstevel@tonic-gate } 205*7c478bd9Sstevel@tonic-gate } 206*7c478bd9Sstevel@tonic-gate break; 207*7c478bd9Sstevel@tonic-gate case 'r': 208*7c478bd9Sstevel@tonic-gate flag |= REMOVE; 209*7c478bd9Sstevel@tonic-gate break; 210*7c478bd9Sstevel@tonic-gate case 's': 211*7c478bd9Sstevel@tonic-gate flag |= START; 212*7c478bd9Sstevel@tonic-gate break; 213*7c478bd9Sstevel@tonic-gate case 't': 214*7c478bd9Sstevel@tonic-gate type = optarg; 215*7c478bd9Sstevel@tonic-gate if (strchr(optarg, '\n')) { 216*7c478bd9Sstevel@tonic-gate Saferrno = E_BADARGS; 217*7c478bd9Sstevel@tonic-gate error(BADINP); 218*7c478bd9Sstevel@tonic-gate } 219*7c478bd9Sstevel@tonic-gate if (strlen(type) > PMTYPESIZE) { 220*7c478bd9Sstevel@tonic-gate type[PMTYPESIZE] = '\0'; 221*7c478bd9Sstevel@tonic-gate (void) fprintf(stderr, "type too long, truncated to <%s>\n", type); 222*7c478bd9Sstevel@tonic-gate } 223*7c478bd9Sstevel@tonic-gate for (p = type; *p; p++) { 224*7c478bd9Sstevel@tonic-gate if (!isalnum(*p)) { 225*7c478bd9Sstevel@tonic-gate Saferrno = E_BADARGS; 226*7c478bd9Sstevel@tonic-gate error("port monitor type must be alphanumeric"); 227*7c478bd9Sstevel@tonic-gate } 228*7c478bd9Sstevel@tonic-gate } 229*7c478bd9Sstevel@tonic-gate break; 230*7c478bd9Sstevel@tonic-gate case 'v': 231*7c478bd9Sstevel@tonic-gate flag |= ADD; 232*7c478bd9Sstevel@tonic-gate version = atoi(optarg); 233*7c478bd9Sstevel@tonic-gate if (version < 0) { 234*7c478bd9Sstevel@tonic-gate Saferrno = E_BADARGS; 235*7c478bd9Sstevel@tonic-gate error("version number can not be negative"); 236*7c478bd9Sstevel@tonic-gate } 237*7c478bd9Sstevel@tonic-gate break; 238*7c478bd9Sstevel@tonic-gate case 'x': 239*7c478bd9Sstevel@tonic-gate flag |= DBREAD; 240*7c478bd9Sstevel@tonic-gate break; 241*7c478bd9Sstevel@tonic-gate case 'y': 242*7c478bd9Sstevel@tonic-gate flag |= ADD; 243*7c478bd9Sstevel@tonic-gate if (strchr(optarg, '\n')) { 244*7c478bd9Sstevel@tonic-gate Saferrno = E_BADARGS; 245*7c478bd9Sstevel@tonic-gate error(BADINP); 246*7c478bd9Sstevel@tonic-gate } 247*7c478bd9Sstevel@tonic-gate comment = optarg; 248*7c478bd9Sstevel@tonic-gate break; 249*7c478bd9Sstevel@tonic-gate case 'z': 250*7c478bd9Sstevel@tonic-gate if (strchr(optarg, '\n')) { 251*7c478bd9Sstevel@tonic-gate Saferrno = E_BADARGS; 252*7c478bd9Sstevel@tonic-gate error(BADINP); 253*7c478bd9Sstevel@tonic-gate } 254*7c478bd9Sstevel@tonic-gate script = optarg; 255*7c478bd9Sstevel@tonic-gate break; 256*7c478bd9Sstevel@tonic-gate case '?': 257*7c478bd9Sstevel@tonic-gate errflg++; 258*7c478bd9Sstevel@tonic-gate } 259*7c478bd9Sstevel@tonic-gate } 260*7c478bd9Sstevel@tonic-gate if (errflg || (optind < argc)) 261*7c478bd9Sstevel@tonic-gate usage(argv[0]); 262*7c478bd9Sstevel@tonic-gate 263*7c478bd9Sstevel@tonic-gate if (badcnt) { 264*7c478bd9Sstevel@tonic-gate /* bad flags were given to -f */ 265*7c478bd9Sstevel@tonic-gate Saferrno = E_BADARGS; 266*7c478bd9Sstevel@tonic-gate (void) sprintf(buf, 267*7c478bd9Sstevel@tonic-gate "Invalid request, %s are not valid arguments for \"-f\"", 268*7c478bd9Sstevel@tonic-gate badargs); 269*7c478bd9Sstevel@tonic-gate error(buf); 270*7c478bd9Sstevel@tonic-gate } 271*7c478bd9Sstevel@tonic-gate 272*7c478bd9Sstevel@tonic-gate if ((ret = check_version(VERSION, SACTAB)) == 1) { 273*7c478bd9Sstevel@tonic-gate Saferrno = E_SAFERR; 274*7c478bd9Sstevel@tonic-gate error("_sactab version number is incorrect"); 275*7c478bd9Sstevel@tonic-gate } 276*7c478bd9Sstevel@tonic-gate else if (ret == 2) { 277*7c478bd9Sstevel@tonic-gate (void) sprintf(buf, "could not open %s", SACTAB); 278*7c478bd9Sstevel@tonic-gate Saferrno = E_SYSERR; 279*7c478bd9Sstevel@tonic-gate error(buf); 280*7c478bd9Sstevel@tonic-gate } 281*7c478bd9Sstevel@tonic-gate else if (ret == 3) { 282*7c478bd9Sstevel@tonic-gate (void) sprintf(buf, "%s file is corrupt", SACTAB); 283*7c478bd9Sstevel@tonic-gate Saferrno = E_SAFERR; 284*7c478bd9Sstevel@tonic-gate error(buf); 285*7c478bd9Sstevel@tonic-gate } 286*7c478bd9Sstevel@tonic-gate uid = getuid(); 287*7c478bd9Sstevel@tonic-gate switch (flag) { 288*7c478bd9Sstevel@tonic-gate case ADD: 289*7c478bd9Sstevel@tonic-gate if (uid) { 290*7c478bd9Sstevel@tonic-gate Saferrno = E_NOPRIV; 291*7c478bd9Sstevel@tonic-gate error(NOTPRIV); 292*7c478bd9Sstevel@tonic-gate } 293*7c478bd9Sstevel@tonic-gate if (!sawaflag || !pmtag || !type || !command || (version < 0)) 294*7c478bd9Sstevel@tonic-gate usage(argv[0]); 295*7c478bd9Sstevel@tonic-gate add_pm(pmtag, type, command, version, flags, count, script, comment); 296*7c478bd9Sstevel@tonic-gate break; 297*7c478bd9Sstevel@tonic-gate case REMOVE: 298*7c478bd9Sstevel@tonic-gate if (uid) { 299*7c478bd9Sstevel@tonic-gate Saferrno = E_NOPRIV; 300*7c478bd9Sstevel@tonic-gate error(NOTPRIV); 301*7c478bd9Sstevel@tonic-gate } 302*7c478bd9Sstevel@tonic-gate if (!pmtag || type || script) 303*7c478bd9Sstevel@tonic-gate usage(argv[0]); 304*7c478bd9Sstevel@tonic-gate rem_pm(pmtag); 305*7c478bd9Sstevel@tonic-gate break; 306*7c478bd9Sstevel@tonic-gate case START: 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 (!pmtag || type || script) 312*7c478bd9Sstevel@tonic-gate usage(argv[0]); 313*7c478bd9Sstevel@tonic-gate start_pm(pmtag); 314*7c478bd9Sstevel@tonic-gate break; 315*7c478bd9Sstevel@tonic-gate case KILL: 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 || type || script) 321*7c478bd9Sstevel@tonic-gate usage(argv[0]); 322*7c478bd9Sstevel@tonic-gate kill_pm(pmtag); 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 || type || script) 330*7c478bd9Sstevel@tonic-gate usage(argv[0]); 331*7c478bd9Sstevel@tonic-gate enable_pm(pmtag); 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 || type || script) 339*7c478bd9Sstevel@tonic-gate usage(argv[0]); 340*7c478bd9Sstevel@tonic-gate disable_pm(pmtag); 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_pms(pmtag, type, conflag); 349*7c478bd9Sstevel@tonic-gate break; 350*7c478bd9Sstevel@tonic-gate case DBREAD: 351*7c478bd9Sstevel@tonic-gate if (uid) { 352*7c478bd9Sstevel@tonic-gate Saferrno = E_NOPRIV; 353*7c478bd9Sstevel@tonic-gate error(NOTPRIV); 354*7c478bd9Sstevel@tonic-gate } 355*7c478bd9Sstevel@tonic-gate if (type || script) 356*7c478bd9Sstevel@tonic-gate usage(argv[0]); 357*7c478bd9Sstevel@tonic-gate read_db(pmtag); 358*7c478bd9Sstevel@tonic-gate break; 359*7c478bd9Sstevel@tonic-gate case CONFIG: 360*7c478bd9Sstevel@tonic-gate if (script && uid) { 361*7c478bd9Sstevel@tonic-gate Saferrno = E_NOPRIV; 362*7c478bd9Sstevel@tonic-gate error(NOTPRIV); 363*7c478bd9Sstevel@tonic-gate } 364*7c478bd9Sstevel@tonic-gate if (type || pmtag) 365*7c478bd9Sstevel@tonic-gate usage(argv[0]); 366*7c478bd9Sstevel@tonic-gate (void) do_config(script, "_sysconfig"); 367*7c478bd9Sstevel@tonic-gate break; 368*7c478bd9Sstevel@tonic-gate case PCONFIG: 369*7c478bd9Sstevel@tonic-gate if (script && uid) { 370*7c478bd9Sstevel@tonic-gate Saferrno = E_NOPRIV; 371*7c478bd9Sstevel@tonic-gate error(NOTPRIV); 372*7c478bd9Sstevel@tonic-gate } 373*7c478bd9Sstevel@tonic-gate if (!pmtag || type) 374*7c478bd9Sstevel@tonic-gate usage(argv[0]); 375*7c478bd9Sstevel@tonic-gate fp = fopen(SACTAB, "r"); 376*7c478bd9Sstevel@tonic-gate if (fp == NULL) { 377*7c478bd9Sstevel@tonic-gate Saferrno = E_SYSERR; 378*7c478bd9Sstevel@tonic-gate error("Could not open _sactab"); 379*7c478bd9Sstevel@tonic-gate } 380*7c478bd9Sstevel@tonic-gate if (!find_pm(fp, pmtag)) { 381*7c478bd9Sstevel@tonic-gate Saferrno = E_NOEXIST; 382*7c478bd9Sstevel@tonic-gate (void) sprintf(buf, "Invalid request, %s does not exist", pmtag); 383*7c478bd9Sstevel@tonic-gate error(buf); 384*7c478bd9Sstevel@tonic-gate } 385*7c478bd9Sstevel@tonic-gate (void) fclose(fp); 386*7c478bd9Sstevel@tonic-gate (void) sprintf(buf, "%s/_config", pmtag); 387*7c478bd9Sstevel@tonic-gate (void) do_config(script, buf); 388*7c478bd9Sstevel@tonic-gate break; 389*7c478bd9Sstevel@tonic-gate default: 390*7c478bd9Sstevel@tonic-gate /* we only get here if more than one flag bit was set */ 391*7c478bd9Sstevel@tonic-gate usage(argv[0]); 392*7c478bd9Sstevel@tonic-gate /* NOTREACHED */ 393*7c478bd9Sstevel@tonic-gate } 394*7c478bd9Sstevel@tonic-gate quit(); 395*7c478bd9Sstevel@tonic-gate /* NOTREACHED */ 396*7c478bd9Sstevel@tonic-gate } 397*7c478bd9Sstevel@tonic-gate 398*7c478bd9Sstevel@tonic-gate 399*7c478bd9Sstevel@tonic-gate /* 400*7c478bd9Sstevel@tonic-gate * usage - print out a usage message 401*7c478bd9Sstevel@tonic-gate * 402*7c478bd9Sstevel@tonic-gate * args: cmdname - the name command was invoked with 403*7c478bd9Sstevel@tonic-gate */ 404*7c478bd9Sstevel@tonic-gate 405*7c478bd9Sstevel@tonic-gate void 406*7c478bd9Sstevel@tonic-gate usage(cmdname) 407*7c478bd9Sstevel@tonic-gate char *cmdname; 408*7c478bd9Sstevel@tonic-gate { 409*7c478bd9Sstevel@tonic-gate (void) fprintf(stderr, "Usage:\t%s -a -p pmtag -t type -c cmd -v ver [ -f dx ] [ -n count ]\n", cmdname); 410*7c478bd9Sstevel@tonic-gate (void) fprintf(stderr, "\t\t[ -y comment ] [ -z script]\n"); 411*7c478bd9Sstevel@tonic-gate (void) fprintf(stderr, "\t%s -r -p pmtag\n", cmdname); 412*7c478bd9Sstevel@tonic-gate (void) fprintf(stderr, "\t%s -s -p pmtag\n", cmdname); 413*7c478bd9Sstevel@tonic-gate (void) fprintf(stderr, "\t%s -k -p pmtag\n", cmdname); 414*7c478bd9Sstevel@tonic-gate (void) fprintf(stderr, "\t%s -e -p pmtag\n", cmdname); 415*7c478bd9Sstevel@tonic-gate (void) fprintf(stderr, "\t%s -d -p pmtag\n", cmdname); 416*7c478bd9Sstevel@tonic-gate (void) fprintf(stderr, "\t%s -l [ -p pmtag | -t type ]\n", cmdname); 417*7c478bd9Sstevel@tonic-gate (void) fprintf(stderr, "\t%s -L [ -p pmtag | -t type ]\n", cmdname); 418*7c478bd9Sstevel@tonic-gate (void) fprintf(stderr, "\t%s -g -p pmtag [ -z script ]\n", cmdname); 419*7c478bd9Sstevel@tonic-gate (void) fprintf(stderr, "\t%s -G [ -z script ]\n", cmdname); 420*7c478bd9Sstevel@tonic-gate (void) fprintf(stderr, "\t%s -x [ -p pmtag ]\n", cmdname); 421*7c478bd9Sstevel@tonic-gate Saferrno = E_BADARGS; 422*7c478bd9Sstevel@tonic-gate quit(); 423*7c478bd9Sstevel@tonic-gate } 424*7c478bd9Sstevel@tonic-gate 425*7c478bd9Sstevel@tonic-gate 426*7c478bd9Sstevel@tonic-gate /* 427*7c478bd9Sstevel@tonic-gate * add_pm - add a port monitor entry 428*7c478bd9Sstevel@tonic-gate * 429*7c478bd9Sstevel@tonic-gate * args: tag - port monitor's tag 430*7c478bd9Sstevel@tonic-gate * type - port monitor's type 431*7c478bd9Sstevel@tonic-gate * command - command string to invoke port monitor 432*7c478bd9Sstevel@tonic-gate * version - version number of port monitor's pmtab 433*7c478bd9Sstevel@tonic-gate * flags - port monitor flags 434*7c478bd9Sstevel@tonic-gate * count - restart count 435*7c478bd9Sstevel@tonic-gate * script - port monitor's configuration script 436*7c478bd9Sstevel@tonic-gate * comment - comment describing port monitor 437*7c478bd9Sstevel@tonic-gate */ 438*7c478bd9Sstevel@tonic-gate 439*7c478bd9Sstevel@tonic-gate void 440*7c478bd9Sstevel@tonic-gate add_pm(tag, type, command, version, flags, count, script, comment) 441*7c478bd9Sstevel@tonic-gate char *tag; 442*7c478bd9Sstevel@tonic-gate char *type; 443*7c478bd9Sstevel@tonic-gate char *command; 444*7c478bd9Sstevel@tonic-gate int version; 445*7c478bd9Sstevel@tonic-gate long flags; 446*7c478bd9Sstevel@tonic-gate int count; 447*7c478bd9Sstevel@tonic-gate char *script; 448*7c478bd9Sstevel@tonic-gate char *comment; 449*7c478bd9Sstevel@tonic-gate { 450*7c478bd9Sstevel@tonic-gate FILE *fp; /* file pointer for _sactab */ 451*7c478bd9Sstevel@tonic-gate int fd; /* scratch file descriptor */ 452*7c478bd9Sstevel@tonic-gate struct stat statbuf; /* file status info */ 453*7c478bd9Sstevel@tonic-gate char buf[SIZE]; /* scratch buffer */ 454*7c478bd9Sstevel@tonic-gate char fname[SIZE]; /* scratch buffer for building names */ 455*7c478bd9Sstevel@tonic-gate register int i; /* scratch variable */ 456*7c478bd9Sstevel@tonic-gate 457*7c478bd9Sstevel@tonic-gate fp = fopen(SACTAB, "r"); 458*7c478bd9Sstevel@tonic-gate if (fp == NULL) { 459*7c478bd9Sstevel@tonic-gate Saferrno = E_SYSERR; 460*7c478bd9Sstevel@tonic-gate error("Could not open _sactab"); 461*7c478bd9Sstevel@tonic-gate } 462*7c478bd9Sstevel@tonic-gate if (find_pm(fp, tag)) { 463*7c478bd9Sstevel@tonic-gate Saferrno = E_DUP; 464*7c478bd9Sstevel@tonic-gate (void) sprintf(buf, "Invalid request, %s already exists", tag); 465*7c478bd9Sstevel@tonic-gate error(buf); 466*7c478bd9Sstevel@tonic-gate } 467*7c478bd9Sstevel@tonic-gate (void) fclose(fp); 468*7c478bd9Sstevel@tonic-gate 469*7c478bd9Sstevel@tonic-gate /* 470*7c478bd9Sstevel@tonic-gate * create the directories for it if needed and put in initial files 471*7c478bd9Sstevel@tonic-gate * (/etc/saf and /var/saf) 472*7c478bd9Sstevel@tonic-gate */ 473*7c478bd9Sstevel@tonic-gate 474*7c478bd9Sstevel@tonic-gate for (i = 0; i < 2; i++) { 475*7c478bd9Sstevel@tonic-gate /* i == 0 do /etc/saf i == 1 do /var/saf */ 476*7c478bd9Sstevel@tonic-gate (void) sprintf(fname, "%s/%s", (i == 0 ) ? HOME : ALTHOME, tag); 477*7c478bd9Sstevel@tonic-gate if (access(fname, 0) == 0) { 478*7c478bd9Sstevel@tonic-gate /* something is there, find out what it is */ 479*7c478bd9Sstevel@tonic-gate if (stat(fname, &statbuf) < 0) { 480*7c478bd9Sstevel@tonic-gate Saferrno = E_SYSERR; 481*7c478bd9Sstevel@tonic-gate (void) sprintf(buf, "could not stat <%s>", fname); 482*7c478bd9Sstevel@tonic-gate error(buf); 483*7c478bd9Sstevel@tonic-gate } 484*7c478bd9Sstevel@tonic-gate if ((statbuf.st_mode & S_IFMT) != S_IFDIR) { 485*7c478bd9Sstevel@tonic-gate Saferrno = E_SYSERR; 486*7c478bd9Sstevel@tonic-gate (void) sprintf(buf, "<%s> exists and is not a directory", fname); 487*7c478bd9Sstevel@tonic-gate error(buf); 488*7c478bd9Sstevel@tonic-gate } 489*7c478bd9Sstevel@tonic-gate /* note: this removes the directory too */ 490*7c478bd9Sstevel@tonic-gate (void) sprintf(buf, "rm -rf %s", fname); 491*7c478bd9Sstevel@tonic-gate if (system(buf) < 0) { 492*7c478bd9Sstevel@tonic-gate Saferrno = E_SYSERR; 493*7c478bd9Sstevel@tonic-gate (void) sprintf(buf, "could not remove files under <%s>", fname); 494*7c478bd9Sstevel@tonic-gate error(buf); 495*7c478bd9Sstevel@tonic-gate } 496*7c478bd9Sstevel@tonic-gate } 497*7c478bd9Sstevel@tonic-gate 498*7c478bd9Sstevel@tonic-gate /* 499*7c478bd9Sstevel@tonic-gate * create the directory 500*7c478bd9Sstevel@tonic-gate */ 501*7c478bd9Sstevel@tonic-gate 502*7c478bd9Sstevel@tonic-gate if (mkdir(fname, 0755) < 0) { 503*7c478bd9Sstevel@tonic-gate Saferrno = E_SYSERR; 504*7c478bd9Sstevel@tonic-gate (void) sprintf(buf, "could not create directory <%s>", fname); 505*7c478bd9Sstevel@tonic-gate cleandirs(tag); 506*7c478bd9Sstevel@tonic-gate error(buf); 507*7c478bd9Sstevel@tonic-gate } 508*7c478bd9Sstevel@tonic-gate } 509*7c478bd9Sstevel@tonic-gate 510*7c478bd9Sstevel@tonic-gate /* 511*7c478bd9Sstevel@tonic-gate * put in the config script, if specified 512*7c478bd9Sstevel@tonic-gate */ 513*7c478bd9Sstevel@tonic-gate 514*7c478bd9Sstevel@tonic-gate if (script) { 515*7c478bd9Sstevel@tonic-gate (void) sprintf(fname, "%s/_config", tag); 516*7c478bd9Sstevel@tonic-gate if (do_config(script, fname)) { 517*7c478bd9Sstevel@tonic-gate cleandirs(tag); 518*7c478bd9Sstevel@tonic-gate /* do_config put out any messages */ 519*7c478bd9Sstevel@tonic-gate quit(); 520*7c478bd9Sstevel@tonic-gate } 521*7c478bd9Sstevel@tonic-gate } 522*7c478bd9Sstevel@tonic-gate 523*7c478bd9Sstevel@tonic-gate /* 524*7c478bd9Sstevel@tonic-gate * create the communications pipe, but first make sure that the 525*7c478bd9Sstevel@tonic-gate * permissions we specify are what we get 526*7c478bd9Sstevel@tonic-gate */ 527*7c478bd9Sstevel@tonic-gate 528*7c478bd9Sstevel@tonic-gate (void) umask(0); 529*7c478bd9Sstevel@tonic-gate (void) sprintf(fname, "%s/%s/_pmpipe", HOME, tag); 530*7c478bd9Sstevel@tonic-gate if (mknod(fname, S_IFIFO | 0600, 0) < 0) { 531*7c478bd9Sstevel@tonic-gate Saferrno = E_SYSERR; 532*7c478bd9Sstevel@tonic-gate cleandirs(tag); 533*7c478bd9Sstevel@tonic-gate error("could not create communications pipe"); 534*7c478bd9Sstevel@tonic-gate } 535*7c478bd9Sstevel@tonic-gate 536*7c478bd9Sstevel@tonic-gate /* 537*7c478bd9Sstevel@tonic-gate * create the _pid file 538*7c478bd9Sstevel@tonic-gate */ 539*7c478bd9Sstevel@tonic-gate 540*7c478bd9Sstevel@tonic-gate (void) sprintf(fname, "%s/%s/_pid", HOME, tag); 541*7c478bd9Sstevel@tonic-gate if ((fd = creat(fname, 0644)) < 0) { 542*7c478bd9Sstevel@tonic-gate Saferrno = E_SYSERR; 543*7c478bd9Sstevel@tonic-gate cleandirs(tag); 544*7c478bd9Sstevel@tonic-gate error("could not create _pid file"); 545*7c478bd9Sstevel@tonic-gate } 546*7c478bd9Sstevel@tonic-gate (void) close(fd); 547*7c478bd9Sstevel@tonic-gate 548*7c478bd9Sstevel@tonic-gate /* 549*7c478bd9Sstevel@tonic-gate * create the _pmtab file 550*7c478bd9Sstevel@tonic-gate */ 551*7c478bd9Sstevel@tonic-gate 552*7c478bd9Sstevel@tonic-gate (void) sprintf(fname, "%s/%s/_pmtab", HOME, tag); 553*7c478bd9Sstevel@tonic-gate if ((fd = creat(fname, 0644)) < 0) { 554*7c478bd9Sstevel@tonic-gate Saferrno = E_SYSERR; 555*7c478bd9Sstevel@tonic-gate cleandirs(tag); 556*7c478bd9Sstevel@tonic-gate error("could not create _pmtab file"); 557*7c478bd9Sstevel@tonic-gate } 558*7c478bd9Sstevel@tonic-gate (void) sprintf(buf, "%s%d\n", VSTR, version); 559*7c478bd9Sstevel@tonic-gate if (write(fd, buf, (unsigned) strlen(buf)) != strlen(buf)) { 560*7c478bd9Sstevel@tonic-gate (void) close(fd); 561*7c478bd9Sstevel@tonic-gate (void) unlink(fname); 562*7c478bd9Sstevel@tonic-gate Saferrno = E_SYSERR; 563*7c478bd9Sstevel@tonic-gate cleandirs(tag); 564*7c478bd9Sstevel@tonic-gate error("error initializing _pmtab"); 565*7c478bd9Sstevel@tonic-gate } 566*7c478bd9Sstevel@tonic-gate (void) close(fd); 567*7c478bd9Sstevel@tonic-gate 568*7c478bd9Sstevel@tonic-gate /* 569*7c478bd9Sstevel@tonic-gate * isolate the command name, but remember it since strtok() trashes it 570*7c478bd9Sstevel@tonic-gate */ 571*7c478bd9Sstevel@tonic-gate 572*7c478bd9Sstevel@tonic-gate (void) strcpy(buf, command); 573*7c478bd9Sstevel@tonic-gate (void) strtok(command, " \t"); 574*7c478bd9Sstevel@tonic-gate 575*7c478bd9Sstevel@tonic-gate /* 576*7c478bd9Sstevel@tonic-gate * check out the command - let addition succeed if it doesn't exist (assume 577*7c478bd9Sstevel@tonic-gate * it will be added later); fail anything else 578*7c478bd9Sstevel@tonic-gate */ 579*7c478bd9Sstevel@tonic-gate 580*7c478bd9Sstevel@tonic-gate if (access(command, 0) == 0) { 581*7c478bd9Sstevel@tonic-gate if (stat(command, &statbuf) < 0) { 582*7c478bd9Sstevel@tonic-gate Saferrno = E_SYSERR; 583*7c478bd9Sstevel@tonic-gate (void) fprintf(stderr, "Could not stat <%s>\n", command); 584*7c478bd9Sstevel@tonic-gate cleandirs(tag); 585*7c478bd9Sstevel@tonic-gate quit(); 586*7c478bd9Sstevel@tonic-gate } 587*7c478bd9Sstevel@tonic-gate if (!(statbuf.st_mode & 0111)) { 588*7c478bd9Sstevel@tonic-gate Saferrno = E_BADARGS; 589*7c478bd9Sstevel@tonic-gate (void) fprintf(stderr, "%s not executable\n", command); 590*7c478bd9Sstevel@tonic-gate cleandirs(tag); 591*7c478bd9Sstevel@tonic-gate quit(); 592*7c478bd9Sstevel@tonic-gate } 593*7c478bd9Sstevel@tonic-gate if ((statbuf.st_mode & S_IFMT) != S_IFREG) { 594*7c478bd9Sstevel@tonic-gate Saferrno = E_BADARGS; 595*7c478bd9Sstevel@tonic-gate (void) fprintf(stderr, "%s not a regular file\n", command); 596*7c478bd9Sstevel@tonic-gate cleandirs(tag); 597*7c478bd9Sstevel@tonic-gate quit(); 598*7c478bd9Sstevel@tonic-gate } 599*7c478bd9Sstevel@tonic-gate } 600*7c478bd9Sstevel@tonic-gate else { 601*7c478bd9Sstevel@tonic-gate (void) fprintf(stderr, "warning - %s does not exist\n", command); 602*7c478bd9Sstevel@tonic-gate } 603*7c478bd9Sstevel@tonic-gate 604*7c478bd9Sstevel@tonic-gate /* 605*7c478bd9Sstevel@tonic-gate * add the line 606*7c478bd9Sstevel@tonic-gate */ 607*7c478bd9Sstevel@tonic-gate 608*7c478bd9Sstevel@tonic-gate fp = fopen(SACTAB, "a"); 609*7c478bd9Sstevel@tonic-gate if (fp == NULL) { 610*7c478bd9Sstevel@tonic-gate Saferrno = E_SYSERR; 611*7c478bd9Sstevel@tonic-gate cleandirs(tag); 612*7c478bd9Sstevel@tonic-gate error("Could not open _sactab"); 613*7c478bd9Sstevel@tonic-gate } 614*7c478bd9Sstevel@tonic-gate (void) fprintf(fp, "%s:%s:%s:%d:%s\t#%s\n", tag, type, 615*7c478bd9Sstevel@tonic-gate (flags ? pflags(flags, FALSE) : ""), count, buf, 616*7c478bd9Sstevel@tonic-gate (comment ? comment : "")); 617*7c478bd9Sstevel@tonic-gate (void) fclose(fp); 618*7c478bd9Sstevel@tonic-gate 619*7c478bd9Sstevel@tonic-gate 620*7c478bd9Sstevel@tonic-gate /* 621*7c478bd9Sstevel@tonic-gate * tell the SAC to read _sactab if its there (i.e. single user) 622*7c478bd9Sstevel@tonic-gate */ 623*7c478bd9Sstevel@tonic-gate 624*7c478bd9Sstevel@tonic-gate if (sac_home()) 625*7c478bd9Sstevel@tonic-gate read_db(NULL); 626*7c478bd9Sstevel@tonic-gate return; 627*7c478bd9Sstevel@tonic-gate } 628*7c478bd9Sstevel@tonic-gate 629*7c478bd9Sstevel@tonic-gate 630*7c478bd9Sstevel@tonic-gate /* 631*7c478bd9Sstevel@tonic-gate * cleandirs - remove anything that might have been created (i.e. failed 632*7c478bd9Sstevel@tonic-gate * addition. Saferrno is set elsewhere; this is strictly an attempt 633*7c478bd9Sstevel@tonic-gate * to clean up what mess we've left, so don't check to see if the 634*7c478bd9Sstevel@tonic-gate * cleanup worked. 635*7c478bd9Sstevel@tonic-gate * 636*7c478bd9Sstevel@tonic-gate * args: tag - tag of port monitor whose trees should be removed 637*7c478bd9Sstevel@tonic-gate */ 638*7c478bd9Sstevel@tonic-gate 639*7c478bd9Sstevel@tonic-gate void 640*7c478bd9Sstevel@tonic-gate cleandirs(tag) 641*7c478bd9Sstevel@tonic-gate char *tag; 642*7c478bd9Sstevel@tonic-gate { 643*7c478bd9Sstevel@tonic-gate char buf[SIZE]; /* scratch buffer */ 644*7c478bd9Sstevel@tonic-gate 645*7c478bd9Sstevel@tonic-gate /* note: this removes the directory too, first zap /etc/saf/<tag> */ 646*7c478bd9Sstevel@tonic-gate (void) sprintf(buf, "rm -rf %s/%s", HOME, tag); 647*7c478bd9Sstevel@tonic-gate (void) system(buf); 648*7c478bd9Sstevel@tonic-gate 649*7c478bd9Sstevel@tonic-gate /* now remove /var/saf/<tag> */ 650*7c478bd9Sstevel@tonic-gate (void) sprintf(buf, "%s/%s", ALTHOME, tag); 651*7c478bd9Sstevel@tonic-gate (void) rmdir(buf); 652*7c478bd9Sstevel@tonic-gate } 653*7c478bd9Sstevel@tonic-gate 654*7c478bd9Sstevel@tonic-gate 655*7c478bd9Sstevel@tonic-gate /* 656*7c478bd9Sstevel@tonic-gate * rem_pm - remove a port monitor 657*7c478bd9Sstevel@tonic-gate * 658*7c478bd9Sstevel@tonic-gate * args: tag - tag of port monitor to be removed 659*7c478bd9Sstevel@tonic-gate */ 660*7c478bd9Sstevel@tonic-gate 661*7c478bd9Sstevel@tonic-gate void 662*7c478bd9Sstevel@tonic-gate rem_pm(tag) 663*7c478bd9Sstevel@tonic-gate char *tag; 664*7c478bd9Sstevel@tonic-gate { 665*7c478bd9Sstevel@tonic-gate FILE *fp; /* file pointer for _sactab */ 666*7c478bd9Sstevel@tonic-gate FILE *tfp; /* file pointer for temp file */ 667*7c478bd9Sstevel@tonic-gate int line; /* line number entry is on */ 668*7c478bd9Sstevel@tonic-gate char *tname; /* temp file name */ 669*7c478bd9Sstevel@tonic-gate char buf[SIZE]; /* scratch buffer */ 670*7c478bd9Sstevel@tonic-gate 671*7c478bd9Sstevel@tonic-gate fp = fopen(SACTAB, "r"); 672*7c478bd9Sstevel@tonic-gate if (fp == NULL) { 673*7c478bd9Sstevel@tonic-gate Saferrno = E_SYSERR; 674*7c478bd9Sstevel@tonic-gate error("Could not open _sactab"); 675*7c478bd9Sstevel@tonic-gate } 676*7c478bd9Sstevel@tonic-gate if ((line = find_pm(fp, tag)) == 0) { 677*7c478bd9Sstevel@tonic-gate Saferrno = E_NOEXIST; 678*7c478bd9Sstevel@tonic-gate (void) sprintf(buf, "Invalid request, %s does not exist", tag); 679*7c478bd9Sstevel@tonic-gate error(buf); 680*7c478bd9Sstevel@tonic-gate } 681*7c478bd9Sstevel@tonic-gate tname = make_tempname("_sactab"); 682*7c478bd9Sstevel@tonic-gate tfp = open_temp(tname); 683*7c478bd9Sstevel@tonic-gate if (line != 1) { 684*7c478bd9Sstevel@tonic-gate if (copy_file(fp, tfp, 1, line - 1)) { 685*7c478bd9Sstevel@tonic-gate (void) unlink(tname); 686*7c478bd9Sstevel@tonic-gate Saferrno = E_SYSERR; 687*7c478bd9Sstevel@tonic-gate error("error accessing temp file"); 688*7c478bd9Sstevel@tonic-gate } 689*7c478bd9Sstevel@tonic-gate } 690*7c478bd9Sstevel@tonic-gate if (copy_file(fp, tfp, line + 1, -1)) { 691*7c478bd9Sstevel@tonic-gate (void) unlink(tname); 692*7c478bd9Sstevel@tonic-gate Saferrno = E_SYSERR; 693*7c478bd9Sstevel@tonic-gate error("error accessing temp file"); 694*7c478bd9Sstevel@tonic-gate } 695*7c478bd9Sstevel@tonic-gate (void) fclose(fp); 696*7c478bd9Sstevel@tonic-gate if (fclose(tfp) == EOF) { 697*7c478bd9Sstevel@tonic-gate (void) unlink(tname); 698*7c478bd9Sstevel@tonic-gate Saferrno = E_SYSERR; 699*7c478bd9Sstevel@tonic-gate error("error closing tempfile"); 700*7c478bd9Sstevel@tonic-gate } 701*7c478bd9Sstevel@tonic-gate /* note - replace only returns if successful */ 702*7c478bd9Sstevel@tonic-gate replace("_sactab", tname); 703*7c478bd9Sstevel@tonic-gate 704*7c478bd9Sstevel@tonic-gate /* 705*7c478bd9Sstevel@tonic-gate * tell the SAC to read _sactab if its there (i.e. single user) 706*7c478bd9Sstevel@tonic-gate */ 707*7c478bd9Sstevel@tonic-gate 708*7c478bd9Sstevel@tonic-gate if (sac_home()) 709*7c478bd9Sstevel@tonic-gate read_db(NULL); 710*7c478bd9Sstevel@tonic-gate return; 711*7c478bd9Sstevel@tonic-gate } 712*7c478bd9Sstevel@tonic-gate 713*7c478bd9Sstevel@tonic-gate 714*7c478bd9Sstevel@tonic-gate /* 715*7c478bd9Sstevel@tonic-gate * start_pm - start a particular port monitor 716*7c478bd9Sstevel@tonic-gate * 717*7c478bd9Sstevel@tonic-gate * args: tag - tag of port monitor to be started 718*7c478bd9Sstevel@tonic-gate */ 719*7c478bd9Sstevel@tonic-gate 720*7c478bd9Sstevel@tonic-gate void 721*7c478bd9Sstevel@tonic-gate start_pm(tag) 722*7c478bd9Sstevel@tonic-gate char *tag; 723*7c478bd9Sstevel@tonic-gate { 724*7c478bd9Sstevel@tonic-gate struct admcmd cmd; /* command structure */ 725*7c478bd9Sstevel@tonic-gate register struct admcmd *ap = &cmd; /* and a pointer to it */ 726*7c478bd9Sstevel@tonic-gate 727*7c478bd9Sstevel@tonic-gate ap->ac_mtype = AC_START; 728*7c478bd9Sstevel@tonic-gate (void) strcpy(ap->ac_tag, tag); 729*7c478bd9Sstevel@tonic-gate ap->ac_pid = getpid(); 730*7c478bd9Sstevel@tonic-gate sendcmd(ap, NULL, tag); 731*7c478bd9Sstevel@tonic-gate return; 732*7c478bd9Sstevel@tonic-gate } 733*7c478bd9Sstevel@tonic-gate 734*7c478bd9Sstevel@tonic-gate 735*7c478bd9Sstevel@tonic-gate /* 736*7c478bd9Sstevel@tonic-gate * kill_pm - stop a particular port monitor 737*7c478bd9Sstevel@tonic-gate * 738*7c478bd9Sstevel@tonic-gate * args: tag - tag of port monitor to be stopped 739*7c478bd9Sstevel@tonic-gate */ 740*7c478bd9Sstevel@tonic-gate 741*7c478bd9Sstevel@tonic-gate void 742*7c478bd9Sstevel@tonic-gate kill_pm(tag) 743*7c478bd9Sstevel@tonic-gate char *tag; 744*7c478bd9Sstevel@tonic-gate { 745*7c478bd9Sstevel@tonic-gate struct admcmd cmd; /* command structure */ 746*7c478bd9Sstevel@tonic-gate register struct admcmd *ap = &cmd; /* and a pointer to it */ 747*7c478bd9Sstevel@tonic-gate 748*7c478bd9Sstevel@tonic-gate ap->ac_mtype = AC_KILL; 749*7c478bd9Sstevel@tonic-gate (void) strcpy(ap->ac_tag, tag); 750*7c478bd9Sstevel@tonic-gate ap->ac_pid = getpid(); 751*7c478bd9Sstevel@tonic-gate sendcmd(ap, NULL, tag); 752*7c478bd9Sstevel@tonic-gate return; 753*7c478bd9Sstevel@tonic-gate } 754*7c478bd9Sstevel@tonic-gate 755*7c478bd9Sstevel@tonic-gate 756*7c478bd9Sstevel@tonic-gate /* 757*7c478bd9Sstevel@tonic-gate * enable_pm - enable a particular port monitor 758*7c478bd9Sstevel@tonic-gate * 759*7c478bd9Sstevel@tonic-gate * args: tag - tag of port monitor to be enabled 760*7c478bd9Sstevel@tonic-gate */ 761*7c478bd9Sstevel@tonic-gate 762*7c478bd9Sstevel@tonic-gate void 763*7c478bd9Sstevel@tonic-gate enable_pm(tag) 764*7c478bd9Sstevel@tonic-gate char *tag; 765*7c478bd9Sstevel@tonic-gate { 766*7c478bd9Sstevel@tonic-gate struct admcmd cmd; /* command structure */ 767*7c478bd9Sstevel@tonic-gate register struct admcmd *ap = &cmd; /* and a pointer to it */ 768*7c478bd9Sstevel@tonic-gate 769*7c478bd9Sstevel@tonic-gate ap->ac_mtype = AC_ENABLE; 770*7c478bd9Sstevel@tonic-gate (void) strcpy(ap->ac_tag, tag); 771*7c478bd9Sstevel@tonic-gate ap->ac_pid = getpid(); 772*7c478bd9Sstevel@tonic-gate sendcmd(ap, NULL, tag); 773*7c478bd9Sstevel@tonic-gate return; 774*7c478bd9Sstevel@tonic-gate } 775*7c478bd9Sstevel@tonic-gate 776*7c478bd9Sstevel@tonic-gate 777*7c478bd9Sstevel@tonic-gate /* 778*7c478bd9Sstevel@tonic-gate * disable_pm - disable a particular port monitor 779*7c478bd9Sstevel@tonic-gate * 780*7c478bd9Sstevel@tonic-gate * args: tag - tag of port monitor to be disabled 781*7c478bd9Sstevel@tonic-gate */ 782*7c478bd9Sstevel@tonic-gate 783*7c478bd9Sstevel@tonic-gate void 784*7c478bd9Sstevel@tonic-gate disable_pm(tag) 785*7c478bd9Sstevel@tonic-gate char *tag; 786*7c478bd9Sstevel@tonic-gate { 787*7c478bd9Sstevel@tonic-gate struct admcmd cmd; /* command structure */ 788*7c478bd9Sstevel@tonic-gate register struct admcmd *ap = &cmd; /* and a pointer to it */ 789*7c478bd9Sstevel@tonic-gate 790*7c478bd9Sstevel@tonic-gate ap->ac_mtype = AC_DISABLE; 791*7c478bd9Sstevel@tonic-gate (void) strcpy(ap->ac_tag, tag); 792*7c478bd9Sstevel@tonic-gate ap->ac_pid = getpid(); 793*7c478bd9Sstevel@tonic-gate sendcmd(ap, NULL, tag); 794*7c478bd9Sstevel@tonic-gate return; 795*7c478bd9Sstevel@tonic-gate } 796*7c478bd9Sstevel@tonic-gate 797*7c478bd9Sstevel@tonic-gate 798*7c478bd9Sstevel@tonic-gate /* 799*7c478bd9Sstevel@tonic-gate * read_db - tell SAC or a port monitor to read its administrative file. 800*7c478bd9Sstevel@tonic-gate * 801*7c478bd9Sstevel@tonic-gate * args: tag - tag of port monitor that should read its administrative 802*7c478bd9Sstevel@tonic-gate * file. If NULL, it means SAC should. 803*7c478bd9Sstevel@tonic-gate */ 804*7c478bd9Sstevel@tonic-gate 805*7c478bd9Sstevel@tonic-gate void 806*7c478bd9Sstevel@tonic-gate read_db(tag) 807*7c478bd9Sstevel@tonic-gate char *tag; 808*7c478bd9Sstevel@tonic-gate { 809*7c478bd9Sstevel@tonic-gate struct admcmd cmd; /* command structure */ 810*7c478bd9Sstevel@tonic-gate register struct admcmd *ap = &cmd; /* and a pointer to it */ 811*7c478bd9Sstevel@tonic-gate 812*7c478bd9Sstevel@tonic-gate ap->ac_mtype = (tag) ? AC_PMREAD : AC_SACREAD; 813*7c478bd9Sstevel@tonic-gate if (tag) 814*7c478bd9Sstevel@tonic-gate (void) strcpy(ap->ac_tag, tag); 815*7c478bd9Sstevel@tonic-gate ap->ac_pid = getpid(); 816*7c478bd9Sstevel@tonic-gate sendcmd(ap, NULL, tag); 817*7c478bd9Sstevel@tonic-gate return; 818*7c478bd9Sstevel@tonic-gate } 819*7c478bd9Sstevel@tonic-gate 820*7c478bd9Sstevel@tonic-gate 821*7c478bd9Sstevel@tonic-gate /* 822*7c478bd9Sstevel@tonic-gate * list_pms - request information about port monitors from SAC and output 823*7c478bd9Sstevel@tonic-gate * requested info 824*7c478bd9Sstevel@tonic-gate * 825*7c478bd9Sstevel@tonic-gate * args: pmtag - tag of port monitor to be listed (may be null) 826*7c478bd9Sstevel@tonic-gate * pmtype - type of port monitors to be listed (may be null) 827*7c478bd9Sstevel@tonic-gate * oflag - true if output should be easily parseable 828*7c478bd9Sstevel@tonic-gate */ 829*7c478bd9Sstevel@tonic-gate 830*7c478bd9Sstevel@tonic-gate void 831*7c478bd9Sstevel@tonic-gate list_pms(pmtag, pmtype, oflag) 832*7c478bd9Sstevel@tonic-gate char *pmtag; 833*7c478bd9Sstevel@tonic-gate char *pmtype; 834*7c478bd9Sstevel@tonic-gate int oflag; 835*7c478bd9Sstevel@tonic-gate { 836*7c478bd9Sstevel@tonic-gate struct admcmd acmd; /* command structure */ 837*7c478bd9Sstevel@tonic-gate register struct admcmd *ap = &acmd; /* and a pointer to it */ 838*7c478bd9Sstevel@tonic-gate int nprint = 0; /* count # of PMs printed */ 839*7c478bd9Sstevel@tonic-gate char *p; /* scratch pointer */ 840*7c478bd9Sstevel@tonic-gate char *tag; /* returned tag */ 841*7c478bd9Sstevel@tonic-gate char *type; /* returned type */ 842*7c478bd9Sstevel@tonic-gate char *flags; /* returned flags */ 843*7c478bd9Sstevel@tonic-gate char *rsmax; /* returned restart count */ 844*7c478bd9Sstevel@tonic-gate char *state; /* returned state */ 845*7c478bd9Sstevel@tonic-gate char *cmd; /* returned command string */ 846*7c478bd9Sstevel@tonic-gate char *comment; /* returned comment string */ 847*7c478bd9Sstevel@tonic-gate 848*7c478bd9Sstevel@tonic-gate /* 849*7c478bd9Sstevel@tonic-gate * if sac isn't there (single user), provide info direct from _sactab 850*7c478bd9Sstevel@tonic-gate * note: when this routine returns, the process exits, so there is no 851*7c478bd9Sstevel@tonic-gate * need to free up any memory 852*7c478bd9Sstevel@tonic-gate */ 853*7c478bd9Sstevel@tonic-gate 854*7c478bd9Sstevel@tonic-gate p = NULL; 855*7c478bd9Sstevel@tonic-gate if (sac_home()) { 856*7c478bd9Sstevel@tonic-gate ap->ac_mtype = AC_STATUS; 857*7c478bd9Sstevel@tonic-gate ap->ac_tag[0] = '\0'; 858*7c478bd9Sstevel@tonic-gate ap->ac_pid = getpid(); 859*7c478bd9Sstevel@tonic-gate sendcmd(ap, &p, NULL); 860*7c478bd9Sstevel@tonic-gate } 861*7c478bd9Sstevel@tonic-gate else { 862*7c478bd9Sstevel@tonic-gate single_print(&p); 863*7c478bd9Sstevel@tonic-gate } 864*7c478bd9Sstevel@tonic-gate 865*7c478bd9Sstevel@tonic-gate /* 866*7c478bd9Sstevel@tonic-gate * SAC sends back info in condensed form, we have to separate it out 867*7c478bd9Sstevel@tonic-gate * fields come in ':' separated, records are separated by newlines 868*7c478bd9Sstevel@tonic-gate */ 869*7c478bd9Sstevel@tonic-gate 870*7c478bd9Sstevel@tonic-gate while (p && *p) { 871*7c478bd9Sstevel@tonic-gate tag = getfield(&p, ':'); /* PM tag */ 872*7c478bd9Sstevel@tonic-gate type = getfield(&p, ':'); /* PM type */ 873*7c478bd9Sstevel@tonic-gate flags = getfield(&p, ':'); /* flags */ 874*7c478bd9Sstevel@tonic-gate rsmax = getfield(&p, ':'); /* restart count */ 875*7c478bd9Sstevel@tonic-gate state = pstate((unchar) atoi(getfield(&p, ':'))); /* state in nice output format */ 876*7c478bd9Sstevel@tonic-gate cmd = getfield(&p, ':'); /* command */ 877*7c478bd9Sstevel@tonic-gate comment = getfield(&p, '\n'); /* comment */ 878*7c478bd9Sstevel@tonic-gate 879*7c478bd9Sstevel@tonic-gate 880*7c478bd9Sstevel@tonic-gate /* 881*7c478bd9Sstevel@tonic-gate * print out if no selectors specified, else check to see if 882*7c478bd9Sstevel@tonic-gate * a selector matched 883*7c478bd9Sstevel@tonic-gate */ 884*7c478bd9Sstevel@tonic-gate 885*7c478bd9Sstevel@tonic-gate if ((!pmtag && !pmtype) || (pmtag && !strcmp(pmtag, tag)) || (pmtype && !strcmp(pmtype, type))) { 886*7c478bd9Sstevel@tonic-gate if (oflag) { 887*7c478bd9Sstevel@tonic-gate (void) printf("%s:%s:%s:%s:%s:%s#%s\n", tag, type, pflags(atol(flags), FALSE), 888*7c478bd9Sstevel@tonic-gate rsmax, state, cmd, comment); 889*7c478bd9Sstevel@tonic-gate } 890*7c478bd9Sstevel@tonic-gate else { 891*7c478bd9Sstevel@tonic-gate if (nprint == 0) { 892*7c478bd9Sstevel@tonic-gate (void) printf("PMTAG PMTYPE FLGS RCNT STATUS COMMAND\n"); 893*7c478bd9Sstevel@tonic-gate } 894*7c478bd9Sstevel@tonic-gate (void) printf("%-14s %-14s %-4s %-4s %-10s %s #%s\n", tag, type, pflags(atol(flags), TRUE), 895*7c478bd9Sstevel@tonic-gate rsmax, state, cmd, comment); 896*7c478bd9Sstevel@tonic-gate } 897*7c478bd9Sstevel@tonic-gate nprint++; 898*7c478bd9Sstevel@tonic-gate } 899*7c478bd9Sstevel@tonic-gate } 900*7c478bd9Sstevel@tonic-gate /* 901*7c478bd9Sstevel@tonic-gate * if we didn't find any valid ones, indicate an error (note: 1 and 902*7c478bd9Sstevel@tonic-gate * only 1 of the if statements should be true) 903*7c478bd9Sstevel@tonic-gate */ 904*7c478bd9Sstevel@tonic-gate if (nprint == 0) { 905*7c478bd9Sstevel@tonic-gate if (pmtype) 906*7c478bd9Sstevel@tonic-gate (void) fprintf(stderr, "Invalid request, %s does not exist\n", pmtype); 907*7c478bd9Sstevel@tonic-gate else if (pmtag) 908*7c478bd9Sstevel@tonic-gate (void) fprintf(stderr, "Invalid request, %s does not exist\n", pmtag); 909*7c478bd9Sstevel@tonic-gate else if (!pmtag && !pmtype) 910*7c478bd9Sstevel@tonic-gate (void) fprintf(stderr, "No port monitors defined\n"); 911*7c478bd9Sstevel@tonic-gate Saferrno = E_NOEXIST; 912*7c478bd9Sstevel@tonic-gate } 913*7c478bd9Sstevel@tonic-gate return; 914*7c478bd9Sstevel@tonic-gate } 915*7c478bd9Sstevel@tonic-gate 916*7c478bd9Sstevel@tonic-gate 917*7c478bd9Sstevel@tonic-gate /* 918*7c478bd9Sstevel@tonic-gate * getfield - retrieve and return a field from the sac "status" string (input 919*7c478bd9Sstevel@tonic-gate * argument is modified to point to next field as a side-effect) 920*7c478bd9Sstevel@tonic-gate * 921*7c478bd9Sstevel@tonic-gate * args: p - address of remaining portion of string 922*7c478bd9Sstevel@tonic-gate * sepchar - field terminator character 923*7c478bd9Sstevel@tonic-gate */ 924*7c478bd9Sstevel@tonic-gate 925*7c478bd9Sstevel@tonic-gate char * 926*7c478bd9Sstevel@tonic-gate getfield(p, sepchar) 927*7c478bd9Sstevel@tonic-gate char **p; 928*7c478bd9Sstevel@tonic-gate char sepchar; 929*7c478bd9Sstevel@tonic-gate { 930*7c478bd9Sstevel@tonic-gate char *savep; /* for saving argument */ 931*7c478bd9Sstevel@tonic-gate 932*7c478bd9Sstevel@tonic-gate savep = *p; 933*7c478bd9Sstevel@tonic-gate *p = strchr(*p, sepchar); 934*7c478bd9Sstevel@tonic-gate if (*p == NULL) { 935*7c478bd9Sstevel@tonic-gate Saferrno = E_SAFERR; 936*7c478bd9Sstevel@tonic-gate (void) fprintf(stderr, "Improper message from SAC\n"); 937*7c478bd9Sstevel@tonic-gate return(NULL); 938*7c478bd9Sstevel@tonic-gate } 939*7c478bd9Sstevel@tonic-gate **p = '\0'; 940*7c478bd9Sstevel@tonic-gate (*p)++; 941*7c478bd9Sstevel@tonic-gate return(savep); 942*7c478bd9Sstevel@tonic-gate } 943*7c478bd9Sstevel@tonic-gate 944*7c478bd9Sstevel@tonic-gate 945*7c478bd9Sstevel@tonic-gate /* 946*7c478bd9Sstevel@tonic-gate * single_print - print out _sactab if sac not at home (should only happen 947*7c478bd9Sstevel@tonic-gate * in single user mode 948*7c478bd9Sstevel@tonic-gate * 949*7c478bd9Sstevel@tonic-gate * args: p - address of pointer where formatted data should be 950*7c478bd9Sstevel@tonic-gate * placed (space allocated here) 951*7c478bd9Sstevel@tonic-gate */ 952*7c478bd9Sstevel@tonic-gate 953*7c478bd9Sstevel@tonic-gate void 954*7c478bd9Sstevel@tonic-gate single_print(p) 955*7c478bd9Sstevel@tonic-gate char **p; 956*7c478bd9Sstevel@tonic-gate { 957*7c478bd9Sstevel@tonic-gate FILE *fp; /* file pointer for _sactab */ 958*7c478bd9Sstevel@tonic-gate struct stat statbuf; /* file status info */ 959*7c478bd9Sstevel@tonic-gate register char *tp1; /* scratch pointer */ 960*7c478bd9Sstevel@tonic-gate register char *tp2; /* scratch pointer */ 961*7c478bd9Sstevel@tonic-gate struct sactab stab; /* place to hold parsed info */ 962*7c478bd9Sstevel@tonic-gate register struct sactab *sp = &stab; /* and a pointer to it */ 963*7c478bd9Sstevel@tonic-gate char buf[SIZE]; /* scratch buffer */ 964*7c478bd9Sstevel@tonic-gate 965*7c478bd9Sstevel@tonic-gate fp = fopen(SACTAB, "r"); 966*7c478bd9Sstevel@tonic-gate if (fp == NULL) { 967*7c478bd9Sstevel@tonic-gate Saferrno = E_SYSERR; 968*7c478bd9Sstevel@tonic-gate error("Could not open _sactab"); 969*7c478bd9Sstevel@tonic-gate } 970*7c478bd9Sstevel@tonic-gate if (fstat(fileno(fp), &statbuf) < 0) { 971*7c478bd9Sstevel@tonic-gate Saferrno = E_SYSERR; 972*7c478bd9Sstevel@tonic-gate error("could not stat _sactab"); 973*7c478bd9Sstevel@tonic-gate } 974*7c478bd9Sstevel@tonic-gate 975*7c478bd9Sstevel@tonic-gate /* 976*7c478bd9Sstevel@tonic-gate * allocate space to build return string, twice file size should be more 977*7c478bd9Sstevel@tonic-gate * than enough (and make sure it's zero'ed out) 978*7c478bd9Sstevel@tonic-gate */ 979*7c478bd9Sstevel@tonic-gate 980*7c478bd9Sstevel@tonic-gate tp1 = calloc(2 * statbuf.st_size, sizeof(char)); 981*7c478bd9Sstevel@tonic-gate if (tp1 == NULL) { 982*7c478bd9Sstevel@tonic-gate Saferrno = E_SYSERR; 983*7c478bd9Sstevel@tonic-gate error("could not allocate storage"); 984*7c478bd9Sstevel@tonic-gate } 985*7c478bd9Sstevel@tonic-gate 986*7c478bd9Sstevel@tonic-gate /* 987*7c478bd9Sstevel@tonic-gate * read the file and build the string 988*7c478bd9Sstevel@tonic-gate */ 989*7c478bd9Sstevel@tonic-gate 990*7c478bd9Sstevel@tonic-gate while (fgets(buf, SIZE, fp)) { 991*7c478bd9Sstevel@tonic-gate tp2 = trim(buf); 992*7c478bd9Sstevel@tonic-gate if (*tp2 == '\0') 993*7c478bd9Sstevel@tonic-gate continue; 994*7c478bd9Sstevel@tonic-gate parse(tp2, &stab); 995*7c478bd9Sstevel@tonic-gate (void) sprintf(buf, "%s:%s:%d:%d:%d:%s:%s\n", sp->sc_tag, sp->sc_type, 996*7c478bd9Sstevel@tonic-gate sp->sc_flags, sp->sc_rsmax, SSTATE, sp->sc_cmd, sp->sc_comment); 997*7c478bd9Sstevel@tonic-gate (void) strcat(tp1, buf); 998*7c478bd9Sstevel@tonic-gate free(sp->sc_cmd); 999*7c478bd9Sstevel@tonic-gate free(sp->sc_comment); 1000*7c478bd9Sstevel@tonic-gate } 1001*7c478bd9Sstevel@tonic-gate if (!feof(fp)) { 1002*7c478bd9Sstevel@tonic-gate Saferrno = E_SYSERR; 1003*7c478bd9Sstevel@tonic-gate error("error reading _sactab"); 1004*7c478bd9Sstevel@tonic-gate } 1005*7c478bd9Sstevel@tonic-gate (void) fclose(fp); 1006*7c478bd9Sstevel@tonic-gate 1007*7c478bd9Sstevel@tonic-gate /* 1008*7c478bd9Sstevel@tonic-gate * point at the just-built string 1009*7c478bd9Sstevel@tonic-gate */ 1010*7c478bd9Sstevel@tonic-gate 1011*7c478bd9Sstevel@tonic-gate *p = tp1; 1012*7c478bd9Sstevel@tonic-gate return; 1013*7c478bd9Sstevel@tonic-gate } 1014*7c478bd9Sstevel@tonic-gate 1015*7c478bd9Sstevel@tonic-gate 1016*7c478bd9Sstevel@tonic-gate /* 1017*7c478bd9Sstevel@tonic-gate * openpipe - open up command pipe to SAC 1018*7c478bd9Sstevel@tonic-gate */ 1019*7c478bd9Sstevel@tonic-gate 1020*7c478bd9Sstevel@tonic-gate openpipe() 1021*7c478bd9Sstevel@tonic-gate { 1022*7c478bd9Sstevel@tonic-gate int fd; /* file descriptor associated with command pipe */ 1023*7c478bd9Sstevel@tonic-gate 1024*7c478bd9Sstevel@tonic-gate fd = open(CMDPIPE, O_RDWR); 1025*7c478bd9Sstevel@tonic-gate if (fd < 0) { 1026*7c478bd9Sstevel@tonic-gate Saferrno = E_SYSERR; 1027*7c478bd9Sstevel@tonic-gate error(SACERR); 1028*7c478bd9Sstevel@tonic-gate } 1029*7c478bd9Sstevel@tonic-gate 1030*7c478bd9Sstevel@tonic-gate /* 1031*7c478bd9Sstevel@tonic-gate * lock pipe to insure serial access, lock will disappear if process dies 1032*7c478bd9Sstevel@tonic-gate */ 1033*7c478bd9Sstevel@tonic-gate 1034*7c478bd9Sstevel@tonic-gate if (lockf(fd, F_LOCK, 0) < 0) { 1035*7c478bd9Sstevel@tonic-gate Saferrno = E_SYSERR; 1036*7c478bd9Sstevel@tonic-gate error("unable to lock command pipe"); 1037*7c478bd9Sstevel@tonic-gate } 1038*7c478bd9Sstevel@tonic-gate return(fd); 1039*7c478bd9Sstevel@tonic-gate } 1040*7c478bd9Sstevel@tonic-gate 1041*7c478bd9Sstevel@tonic-gate 1042*7c478bd9Sstevel@tonic-gate /* 1043*7c478bd9Sstevel@tonic-gate * sendcmd - send a command to the SAC 1044*7c478bd9Sstevel@tonic-gate * 1045*7c478bd9Sstevel@tonic-gate * args: ap - pointer to command to send 1046*7c478bd9Sstevel@tonic-gate * info - pointer to return information from the SAC 1047*7c478bd9Sstevel@tonic-gate * tag - tag of port monitor to which the command applies (may 1048*7c478bd9Sstevel@tonic-gate * be NULL) 1049*7c478bd9Sstevel@tonic-gate */ 1050*7c478bd9Sstevel@tonic-gate 1051*7c478bd9Sstevel@tonic-gate void 1052*7c478bd9Sstevel@tonic-gate sendcmd(ap, info, tag) 1053*7c478bd9Sstevel@tonic-gate struct admcmd *ap; 1054*7c478bd9Sstevel@tonic-gate char **info; 1055*7c478bd9Sstevel@tonic-gate char *tag; 1056*7c478bd9Sstevel@tonic-gate { 1057*7c478bd9Sstevel@tonic-gate int fd; /* file descriptor of command pipe */ 1058*7c478bd9Sstevel@tonic-gate 1059*7c478bd9Sstevel@tonic-gate fd = openpipe(); 1060*7c478bd9Sstevel@tonic-gate if (write(fd, ap, sizeof(struct admcmd)) < 0) { 1061*7c478bd9Sstevel@tonic-gate Saferrno = E_SYSERR; 1062*7c478bd9Sstevel@tonic-gate error(SACERR); 1063*7c478bd9Sstevel@tonic-gate } 1064*7c478bd9Sstevel@tonic-gate checkresp(fd, info, tag); 1065*7c478bd9Sstevel@tonic-gate 1066*7c478bd9Sstevel@tonic-gate /* 1067*7c478bd9Sstevel@tonic-gate * unlock the command pipe - not really necessary since we're about to close 1068*7c478bd9Sstevel@tonic-gate */ 1069*7c478bd9Sstevel@tonic-gate 1070*7c478bd9Sstevel@tonic-gate (void) lockf(fd, F_ULOCK, 0); 1071*7c478bd9Sstevel@tonic-gate (void) close(fd); 1072*7c478bd9Sstevel@tonic-gate return; 1073*7c478bd9Sstevel@tonic-gate } 1074*7c478bd9Sstevel@tonic-gate 1075*7c478bd9Sstevel@tonic-gate 1076*7c478bd9Sstevel@tonic-gate /* 1077*7c478bd9Sstevel@tonic-gate * checkresp - check the SAC's response to our command 1078*7c478bd9Sstevel@tonic-gate * 1079*7c478bd9Sstevel@tonic-gate * args: fd - file descriptor of command pipe 1080*7c478bd9Sstevel@tonic-gate * info - pointer to return and info send along by SAC 1081*7c478bd9Sstevel@tonic-gate * tag - tag of port monitor that the command had been 1082*7c478bd9Sstevel@tonic-gate * for, only used for error reporting 1083*7c478bd9Sstevel@tonic-gate */ 1084*7c478bd9Sstevel@tonic-gate 1085*7c478bd9Sstevel@tonic-gate void 1086*7c478bd9Sstevel@tonic-gate checkresp(fd, info, tag) 1087*7c478bd9Sstevel@tonic-gate int fd; 1088*7c478bd9Sstevel@tonic-gate char **info; 1089*7c478bd9Sstevel@tonic-gate char *tag; 1090*7c478bd9Sstevel@tonic-gate { 1091*7c478bd9Sstevel@tonic-gate struct admack ack; /* acknowledgment struct */ 1092*7c478bd9Sstevel@tonic-gate register struct admack *ak = &ack; /* and a pointer to it */ 1093*7c478bd9Sstevel@tonic-gate pid_t pid; /* my pid */ 1094*7c478bd9Sstevel@tonic-gate struct sigaction sigact; /* signal handler setup */ 1095*7c478bd9Sstevel@tonic-gate 1096*7c478bd9Sstevel@tonic-gate /* 1097*7c478bd9Sstevel@tonic-gate * make sure this ack is meant for me, put an alarm around the read 1098*7c478bd9Sstevel@tonic-gate * so we don't hang out forever. 1099*7c478bd9Sstevel@tonic-gate */ 1100*7c478bd9Sstevel@tonic-gate 1101*7c478bd9Sstevel@tonic-gate pid = getpid(); 1102*7c478bd9Sstevel@tonic-gate sigact.sa_flags = 0; 1103*7c478bd9Sstevel@tonic-gate sigact.sa_handler = catch; 1104*7c478bd9Sstevel@tonic-gate (void) sigemptyset(&sigact.sa_mask); 1105*7c478bd9Sstevel@tonic-gate (void) sigaddset(&sigact.sa_mask, SIGALRM); 1106*7c478bd9Sstevel@tonic-gate (void) sigaction(SIGALRM, &sigact, NULL); 1107*7c478bd9Sstevel@tonic-gate (void) alarm(10); 1108*7c478bd9Sstevel@tonic-gate do { 1109*7c478bd9Sstevel@tonic-gate if (read(fd, ak, sizeof(ack)) != sizeof(ack)) { 1110*7c478bd9Sstevel@tonic-gate Saferrno = E_SACNOTRUN; 1111*7c478bd9Sstevel@tonic-gate error(SACERR); 1112*7c478bd9Sstevel@tonic-gate } 1113*7c478bd9Sstevel@tonic-gate } while (pid != ak->ak_pid); 1114*7c478bd9Sstevel@tonic-gate (void) alarm(0); 1115*7c478bd9Sstevel@tonic-gate 1116*7c478bd9Sstevel@tonic-gate /* 1117*7c478bd9Sstevel@tonic-gate * check out what happened 1118*7c478bd9Sstevel@tonic-gate */ 1119*7c478bd9Sstevel@tonic-gate 1120*7c478bd9Sstevel@tonic-gate switch (ak->ak_resp) { 1121*7c478bd9Sstevel@tonic-gate case AK_ACK: 1122*7c478bd9Sstevel@tonic-gate /* everything was A-OK */ 1123*7c478bd9Sstevel@tonic-gate if (info && ak->ak_size) { 1124*7c478bd9Sstevel@tonic-gate /* there is return info and a place to put it */ 1125*7c478bd9Sstevel@tonic-gate if ((*info = malloc((unsigned) (ak->ak_size + 1))) == NULL) { 1126*7c478bd9Sstevel@tonic-gate Saferrno = E_SYSERR; 1127*7c478bd9Sstevel@tonic-gate error("could not allocate storage"); 1128*7c478bd9Sstevel@tonic-gate } 1129*7c478bd9Sstevel@tonic-gate if (read(fd, *info, (unsigned) ak->ak_size) != ak->ak_size) { 1130*7c478bd9Sstevel@tonic-gate Saferrno = E_SYSERR; 1131*7c478bd9Sstevel@tonic-gate error(SACERR); 1132*7c478bd9Sstevel@tonic-gate } 1133*7c478bd9Sstevel@tonic-gate /* make sure "string" is null-terminated */ 1134*7c478bd9Sstevel@tonic-gate (*info)[ak->ak_size] = '\0'; 1135*7c478bd9Sstevel@tonic-gate } 1136*7c478bd9Sstevel@tonic-gate return; 1137*7c478bd9Sstevel@tonic-gate /* something went wrong - see what */ 1138*7c478bd9Sstevel@tonic-gate case AK_PMRUN: 1139*7c478bd9Sstevel@tonic-gate Saferrno = E_PMRUN; 1140*7c478bd9Sstevel@tonic-gate (void) fprintf(stderr, "Port monitor, %s, is already running\n", tag); 1141*7c478bd9Sstevel@tonic-gate break; 1142*7c478bd9Sstevel@tonic-gate case AK_PMNOTRUN: 1143*7c478bd9Sstevel@tonic-gate Saferrno = E_PMNOTRUN; 1144*7c478bd9Sstevel@tonic-gate (void) fprintf(stderr, "Port monitor, %s, is not running\n", tag); 1145*7c478bd9Sstevel@tonic-gate break; 1146*7c478bd9Sstevel@tonic-gate case AK_NOPM: 1147*7c478bd9Sstevel@tonic-gate Saferrno = E_NOEXIST; 1148*7c478bd9Sstevel@tonic-gate (void) fprintf(stderr, "Invalid request, %s does not exist\n", tag); 1149*7c478bd9Sstevel@tonic-gate break; 1150*7c478bd9Sstevel@tonic-gate case AK_UNKNOWN: 1151*7c478bd9Sstevel@tonic-gate Saferrno = E_SAFERR; 1152*7c478bd9Sstevel@tonic-gate (void) fprintf(stderr, "Internal error - sent invalid command\n"); 1153*7c478bd9Sstevel@tonic-gate break; 1154*7c478bd9Sstevel@tonic-gate case AK_NOCONTACT: 1155*7c478bd9Sstevel@tonic-gate Saferrno = E_SAFERR; 1156*7c478bd9Sstevel@tonic-gate (void) fprintf(stderr, "Could not contact %s\n", tag); 1157*7c478bd9Sstevel@tonic-gate break; 1158*7c478bd9Sstevel@tonic-gate case AK_PMLOCK: 1159*7c478bd9Sstevel@tonic-gate Saferrno = E_SAFERR; 1160*7c478bd9Sstevel@tonic-gate (void) fprintf(stderr, "Could not start %s - _pid file locked\n", tag); 1161*7c478bd9Sstevel@tonic-gate break; 1162*7c478bd9Sstevel@tonic-gate case AK_RECOVER: 1163*7c478bd9Sstevel@tonic-gate Saferrno = E_RECOVER; 1164*7c478bd9Sstevel@tonic-gate (void) fprintf(stderr, "Port monitor, %s, is in recovery\n", tag); 1165*7c478bd9Sstevel@tonic-gate break; 1166*7c478bd9Sstevel@tonic-gate case AK_REQFAIL: 1167*7c478bd9Sstevel@tonic-gate Saferrno = E_SAFERR; 1168*7c478bd9Sstevel@tonic-gate (void) fprintf(stderr, "This request could not be completed - see sac log file for details\n"); 1169*7c478bd9Sstevel@tonic-gate break; 1170*7c478bd9Sstevel@tonic-gate default: 1171*7c478bd9Sstevel@tonic-gate Saferrno = E_SAFERR; 1172*7c478bd9Sstevel@tonic-gate (void) fprintf(stderr, "unknown response\n"); 1173*7c478bd9Sstevel@tonic-gate break; 1174*7c478bd9Sstevel@tonic-gate } 1175*7c478bd9Sstevel@tonic-gate } 1176*7c478bd9Sstevel@tonic-gate 1177*7c478bd9Sstevel@tonic-gate 1178*7c478bd9Sstevel@tonic-gate /* 1179*7c478bd9Sstevel@tonic-gate * catch - catcher for SIGALRM, don't need to do anything 1180*7c478bd9Sstevel@tonic-gate */ 1181*7c478bd9Sstevel@tonic-gate 1182*7c478bd9Sstevel@tonic-gate void 1183*7c478bd9Sstevel@tonic-gate catch() 1184*7c478bd9Sstevel@tonic-gate { 1185*7c478bd9Sstevel@tonic-gate } 1186*7c478bd9Sstevel@tonic-gate 1187*7c478bd9Sstevel@tonic-gate 1188*7c478bd9Sstevel@tonic-gate /* 1189*7c478bd9Sstevel@tonic-gate * pflags - put port monitor flags into intelligible form for output 1190*7c478bd9Sstevel@tonic-gate * 1191*7c478bd9Sstevel@tonic-gate * args: flags - binary representation of flags 1192*7c478bd9Sstevel@tonic-gate * dflag - true if a "-" should be returned if no flags 1193*7c478bd9Sstevel@tonic-gate */ 1194*7c478bd9Sstevel@tonic-gate 1195*7c478bd9Sstevel@tonic-gate char * 1196*7c478bd9Sstevel@tonic-gate pflags(flags, dflag) 1197*7c478bd9Sstevel@tonic-gate long flags; 1198*7c478bd9Sstevel@tonic-gate int dflag; 1199*7c478bd9Sstevel@tonic-gate { 1200*7c478bd9Sstevel@tonic-gate register int i; /* scratch counter */ 1201*7c478bd9Sstevel@tonic-gate static char buf[SIZE]; /* formatted flags */ 1202*7c478bd9Sstevel@tonic-gate 1203*7c478bd9Sstevel@tonic-gate if (flags == 0) { 1204*7c478bd9Sstevel@tonic-gate if (dflag) 1205*7c478bd9Sstevel@tonic-gate return("-"); 1206*7c478bd9Sstevel@tonic-gate else 1207*7c478bd9Sstevel@tonic-gate return(""); 1208*7c478bd9Sstevel@tonic-gate } 1209*7c478bd9Sstevel@tonic-gate i = 0; 1210*7c478bd9Sstevel@tonic-gate if (flags & D_FLAG) { 1211*7c478bd9Sstevel@tonic-gate buf[i++] = 'd'; 1212*7c478bd9Sstevel@tonic-gate flags &= ~D_FLAG; 1213*7c478bd9Sstevel@tonic-gate } 1214*7c478bd9Sstevel@tonic-gate if (flags & X_FLAG) { 1215*7c478bd9Sstevel@tonic-gate buf[i++] = 'x'; 1216*7c478bd9Sstevel@tonic-gate flags &= ~X_FLAG; 1217*7c478bd9Sstevel@tonic-gate } 1218*7c478bd9Sstevel@tonic-gate if (flags) { 1219*7c478bd9Sstevel@tonic-gate (void) fprintf(stderr, "Bad information from SAC\n"); 1220*7c478bd9Sstevel@tonic-gate exit(1); 1221*7c478bd9Sstevel@tonic-gate } 1222*7c478bd9Sstevel@tonic-gate buf[i] = '\0'; 1223*7c478bd9Sstevel@tonic-gate return(buf); 1224*7c478bd9Sstevel@tonic-gate } 1225*7c478bd9Sstevel@tonic-gate 1226*7c478bd9Sstevel@tonic-gate 1227*7c478bd9Sstevel@tonic-gate /* 1228*7c478bd9Sstevel@tonic-gate * sac_home - returns true is sac has a lock on its logfile, false 1229*7c478bd9Sstevel@tonic-gate * otherwise (useful to avoid errors for administrative actions in 1230*7c478bd9Sstevel@tonic-gate * single user mode) 1231*7c478bd9Sstevel@tonic-gate */ 1232*7c478bd9Sstevel@tonic-gate 1233*7c478bd9Sstevel@tonic-gate sac_home() 1234*7c478bd9Sstevel@tonic-gate { 1235*7c478bd9Sstevel@tonic-gate int fd; /* fd to sac logfile */ 1236*7c478bd9Sstevel@tonic-gate 1237*7c478bd9Sstevel@tonic-gate fd = open(LOGFILE, O_RDONLY); 1238*7c478bd9Sstevel@tonic-gate if (fd < 0) { 1239*7c478bd9Sstevel@tonic-gate fprintf(stderr, "warning - could not ascertain sac status\n"); 1240*7c478bd9Sstevel@tonic-gate return(FALSE); 1241*7c478bd9Sstevel@tonic-gate } 1242*7c478bd9Sstevel@tonic-gate if (lockf(fd, F_TEST, 0) < 0) { 1243*7c478bd9Sstevel@tonic-gate /* everything is ok */ 1244*7c478bd9Sstevel@tonic-gate (void) close(fd); 1245*7c478bd9Sstevel@tonic-gate return(TRUE); 1246*7c478bd9Sstevel@tonic-gate } 1247*7c478bd9Sstevel@tonic-gate else { 1248*7c478bd9Sstevel@tonic-gate /* no one home */ 1249*7c478bd9Sstevel@tonic-gate (void) close(fd); 1250*7c478bd9Sstevel@tonic-gate return(FALSE); 1251*7c478bd9Sstevel@tonic-gate } 1252*7c478bd9Sstevel@tonic-gate } 1253