17c478bd9Sstevel@tonic-gate /* 27c478bd9Sstevel@tonic-gate * CDDL HEADER START 37c478bd9Sstevel@tonic-gate * 47c478bd9Sstevel@tonic-gate * The contents of this file are subject to the terms of the 5*22c9e08bSsn199410 * Common Development and Distribution License (the "License"). 6*22c9e08bSsn199410 * You may not use this file except in compliance with the License. 77c478bd9Sstevel@tonic-gate * 87c478bd9Sstevel@tonic-gate * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 97c478bd9Sstevel@tonic-gate * or http://www.opensolaris.org/os/licensing. 107c478bd9Sstevel@tonic-gate * See the License for the specific language governing permissions 117c478bd9Sstevel@tonic-gate * and limitations under the License. 127c478bd9Sstevel@tonic-gate * 137c478bd9Sstevel@tonic-gate * When distributing Covered Code, include this CDDL HEADER in each 147c478bd9Sstevel@tonic-gate * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 157c478bd9Sstevel@tonic-gate * If applicable, add the following below this CDDL HEADER, with the 167c478bd9Sstevel@tonic-gate * fields enclosed by brackets "[]" replaced with your own identifying 177c478bd9Sstevel@tonic-gate * information: Portions Copyright [yyyy] [name of copyright owner] 187c478bd9Sstevel@tonic-gate * 197c478bd9Sstevel@tonic-gate * CDDL HEADER END 207c478bd9Sstevel@tonic-gate */ 217c478bd9Sstevel@tonic-gate /* 22*22c9e08bSsn199410 * Copyright 2006 Sun Microsystems, Inc. All rights reserved. 2334e48580Sdp * Use is subject to license terms. 247c478bd9Sstevel@tonic-gate */ 257c478bd9Sstevel@tonic-gate 267c478bd9Sstevel@tonic-gate /* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */ 277c478bd9Sstevel@tonic-gate /* All Rights Reserved */ 287c478bd9Sstevel@tonic-gate 2934e48580Sdp #pragma ident "%Z%%M% %I% %E% SMI" 307c478bd9Sstevel@tonic-gate 317c478bd9Sstevel@tonic-gate 327c478bd9Sstevel@tonic-gate #include <stdio.h> 3334e48580Sdp #include <stdlib.h> 3434e48580Sdp #include <strings.h> 357c478bd9Sstevel@tonic-gate #include <fcntl.h> 367c478bd9Sstevel@tonic-gate #include <errno.h> 377c478bd9Sstevel@tonic-gate #include <sys/types.h> 38*22c9e08bSsn199410 #include <sys/wait.h> 397c478bd9Sstevel@tonic-gate #include <sys/stat.h> 407c478bd9Sstevel@tonic-gate #include <signal.h> 417c478bd9Sstevel@tonic-gate #include <unistd.h> 427c478bd9Sstevel@tonic-gate #include <sac.h> 43*22c9e08bSsn199410 #include <spawn.h> 447c478bd9Sstevel@tonic-gate #include "misc.h" 457c478bd9Sstevel@tonic-gate #include "structs.h" 467c478bd9Sstevel@tonic-gate #include "adm.h" 477c478bd9Sstevel@tonic-gate #include "extern.h" 487c478bd9Sstevel@tonic-gate 497c478bd9Sstevel@tonic-gate 507c478bd9Sstevel@tonic-gate /* 517c478bd9Sstevel@tonic-gate * functions 527c478bd9Sstevel@tonic-gate */ 537c478bd9Sstevel@tonic-gate 547c478bd9Sstevel@tonic-gate char *pflags(); 557c478bd9Sstevel@tonic-gate char *getfield(); 567c478bd9Sstevel@tonic-gate void add_pm(); 577c478bd9Sstevel@tonic-gate void cleandirs(); 587c478bd9Sstevel@tonic-gate void rem_pm(); 597c478bd9Sstevel@tonic-gate void start_pm(); 607c478bd9Sstevel@tonic-gate void kill_pm(); 617c478bd9Sstevel@tonic-gate void enable_pm(); 627c478bd9Sstevel@tonic-gate void disable_pm(); 637c478bd9Sstevel@tonic-gate void list_pms(); 647c478bd9Sstevel@tonic-gate void read_db(); 657c478bd9Sstevel@tonic-gate void sendcmd(); 667c478bd9Sstevel@tonic-gate void checkresp(); 677c478bd9Sstevel@tonic-gate void single_print(); 687c478bd9Sstevel@tonic-gate void catch(); 697c478bd9Sstevel@tonic-gate void usage(); 70*22c9e08bSsn199410 static int invoke_rm(char *); 717c478bd9Sstevel@tonic-gate 727c478bd9Sstevel@tonic-gate # define START 0x1 /* -s seen */ 737c478bd9Sstevel@tonic-gate # define KILL 0x2 /* -k seen */ 747c478bd9Sstevel@tonic-gate # define ENABLE 0x4 /* -e seen */ 757c478bd9Sstevel@tonic-gate # define DISABLE 0x8 /* -d seen */ 767c478bd9Sstevel@tonic-gate # define PLIST 0x10 /* -l seen */ 777c478bd9Sstevel@tonic-gate # define LIST 0x20 /* -L seen */ 787c478bd9Sstevel@tonic-gate # define DBREAD 0x40 /* -x seen */ 797c478bd9Sstevel@tonic-gate # define CONFIG 0x80 /* -G seen */ 807c478bd9Sstevel@tonic-gate # define PCONFIG 0x100 /* -g seen */ 817c478bd9Sstevel@tonic-gate # define ADD 0x200 /* -a or other required options seen */ 827c478bd9Sstevel@tonic-gate # define REMOVE 0x400 /* -r seen */ 837c478bd9Sstevel@tonic-gate 847c478bd9Sstevel@tonic-gate /* 857c478bd9Sstevel@tonic-gate * common error messages 867c478bd9Sstevel@tonic-gate */ 877c478bd9Sstevel@tonic-gate 887c478bd9Sstevel@tonic-gate # define NOTPRIV "User not privileged for operation" 897c478bd9Sstevel@tonic-gate # define SACERR "Can not contact SAC" 907c478bd9Sstevel@tonic-gate # define BADINP "Embedded newlines not allowed" 917c478bd9Sstevel@tonic-gate 927c478bd9Sstevel@tonic-gate 937c478bd9Sstevel@tonic-gate int Saferrno; /* internal `errno' for exit */ 947c478bd9Sstevel@tonic-gate 957c478bd9Sstevel@tonic-gate 967c478bd9Sstevel@tonic-gate /* 977c478bd9Sstevel@tonic-gate * main - scan args for sacadm and call appropriate handling code 987c478bd9Sstevel@tonic-gate */ 997c478bd9Sstevel@tonic-gate 10034e48580Sdp int 10134e48580Sdp main(int argc, char *argv[]) 1027c478bd9Sstevel@tonic-gate { 1037c478bd9Sstevel@tonic-gate int c; /* option letter */ 1047c478bd9Sstevel@tonic-gate uid_t uid; /* invoker's real uid */ 1057c478bd9Sstevel@tonic-gate int ret; /* return code from check_version */ 1067c478bd9Sstevel@tonic-gate int flag = 0; /* flag to record requested operations */ 1077c478bd9Sstevel@tonic-gate int errflg = 0; /* error indicator */ 1087c478bd9Sstevel@tonic-gate int version = -1; /* argument to -v */ 1097c478bd9Sstevel@tonic-gate int count = 0; /* argument to -n */ 1107c478bd9Sstevel@tonic-gate int badcnt = 0; /* count of bad args to -f */ 1117c478bd9Sstevel@tonic-gate int sawaflag = 0; /* true if actually saw -a */ 1127c478bd9Sstevel@tonic-gate int conflag = 0; /* true if output should be in condensed form */ 1137c478bd9Sstevel@tonic-gate long flags = 0; /* arguments to -f */ 1147c478bd9Sstevel@tonic-gate FILE *fp; /* scratch file pointer */ 1157c478bd9Sstevel@tonic-gate char *pmtag = NULL; /* argument to -p */ 1167c478bd9Sstevel@tonic-gate char *type = NULL; /* argument to -t */ 1177c478bd9Sstevel@tonic-gate char *script = NULL; /* argument to -z */ 1187c478bd9Sstevel@tonic-gate char *command = NULL; /* argument to -c */ 1197c478bd9Sstevel@tonic-gate char *comment = " "; /* argument to -y */ 1207c478bd9Sstevel@tonic-gate char badargs[BADFARGSIZE]; /* place to hold bad args to -f */ 1217c478bd9Sstevel@tonic-gate char buf[SIZE]; /* scratch buffer */ 1227c478bd9Sstevel@tonic-gate register char *p; /* scratch pointer */ 1237c478bd9Sstevel@tonic-gate 1247c478bd9Sstevel@tonic-gate if (argc == 1) 1257c478bd9Sstevel@tonic-gate usage(argv[0]); 1267c478bd9Sstevel@tonic-gate while ((c = getopt(argc, argv, "ac:def:GgkLln:p:rst:v:xy:z:")) != -1) { 1277c478bd9Sstevel@tonic-gate switch (c) { 1287c478bd9Sstevel@tonic-gate case 'a': 1297c478bd9Sstevel@tonic-gate flag |= ADD; 1307c478bd9Sstevel@tonic-gate sawaflag = 1; 1317c478bd9Sstevel@tonic-gate break; 1327c478bd9Sstevel@tonic-gate case 'c': 1337c478bd9Sstevel@tonic-gate flag |= ADD; 1347c478bd9Sstevel@tonic-gate if (strchr(optarg, '\n')) { 1357c478bd9Sstevel@tonic-gate Saferrno = E_BADARGS; 1367c478bd9Sstevel@tonic-gate error(BADINP); 1377c478bd9Sstevel@tonic-gate } 1387c478bd9Sstevel@tonic-gate command = optarg; 1397c478bd9Sstevel@tonic-gate if (*command != '/') { 1407c478bd9Sstevel@tonic-gate Saferrno = E_BADARGS; 1417c478bd9Sstevel@tonic-gate error("command must be a full pathname"); 1427c478bd9Sstevel@tonic-gate } 1437c478bd9Sstevel@tonic-gate break; 1447c478bd9Sstevel@tonic-gate case 'd': 1457c478bd9Sstevel@tonic-gate flag |= DISABLE; 1467c478bd9Sstevel@tonic-gate break; 1477c478bd9Sstevel@tonic-gate case 'e': 1487c478bd9Sstevel@tonic-gate flag |= ENABLE; 1497c478bd9Sstevel@tonic-gate break; 1507c478bd9Sstevel@tonic-gate case 'f': 1517c478bd9Sstevel@tonic-gate flag |= ADD; 1527c478bd9Sstevel@tonic-gate while (*optarg) { 1537c478bd9Sstevel@tonic-gate switch (*optarg++) { 1547c478bd9Sstevel@tonic-gate case 'd': 1557c478bd9Sstevel@tonic-gate flags |= D_FLAG; 1567c478bd9Sstevel@tonic-gate break; 1577c478bd9Sstevel@tonic-gate case 'x': 1587c478bd9Sstevel@tonic-gate flags |= X_FLAG; 1597c478bd9Sstevel@tonic-gate break; 1607c478bd9Sstevel@tonic-gate default: 1617c478bd9Sstevel@tonic-gate if (badcnt < (BADFARGSIZE -1)) 1627c478bd9Sstevel@tonic-gate badargs[badcnt++] = *(optarg - 1); 1637c478bd9Sstevel@tonic-gate break; 1647c478bd9Sstevel@tonic-gate } 1657c478bd9Sstevel@tonic-gate } 1667c478bd9Sstevel@tonic-gate /* null terminate just in case anything is there */ 1677c478bd9Sstevel@tonic-gate badargs[badcnt] = '\0'; 1687c478bd9Sstevel@tonic-gate break; 1697c478bd9Sstevel@tonic-gate case 'G': 1707c478bd9Sstevel@tonic-gate flag |= CONFIG; 1717c478bd9Sstevel@tonic-gate break; 1727c478bd9Sstevel@tonic-gate case 'g': 1737c478bd9Sstevel@tonic-gate flag |= PCONFIG; 1747c478bd9Sstevel@tonic-gate break; 1757c478bd9Sstevel@tonic-gate case 'k': 1767c478bd9Sstevel@tonic-gate flag |= KILL; 1777c478bd9Sstevel@tonic-gate break; 1787c478bd9Sstevel@tonic-gate case 'L': 1797c478bd9Sstevel@tonic-gate flag |= LIST; 1807c478bd9Sstevel@tonic-gate break; 1817c478bd9Sstevel@tonic-gate case 'l': 1827c478bd9Sstevel@tonic-gate flag |= PLIST; 1837c478bd9Sstevel@tonic-gate break; 1847c478bd9Sstevel@tonic-gate case 'n': 1857c478bd9Sstevel@tonic-gate flag |= ADD; 1867c478bd9Sstevel@tonic-gate count = atoi(optarg); 1877c478bd9Sstevel@tonic-gate if (count < 0) { 1887c478bd9Sstevel@tonic-gate Saferrno = E_BADARGS; 1897c478bd9Sstevel@tonic-gate error("restart count can not be negative"); 1907c478bd9Sstevel@tonic-gate } 1917c478bd9Sstevel@tonic-gate break; 1927c478bd9Sstevel@tonic-gate case 'p': 1937c478bd9Sstevel@tonic-gate pmtag = optarg; 1947c478bd9Sstevel@tonic-gate if (strchr(optarg, '\n')) { 1957c478bd9Sstevel@tonic-gate Saferrno = E_BADARGS; 1967c478bd9Sstevel@tonic-gate error(BADINP); 1977c478bd9Sstevel@tonic-gate } 1987c478bd9Sstevel@tonic-gate if (strlen(pmtag) > PMTAGSIZE) { 1997c478bd9Sstevel@tonic-gate pmtag[PMTAGSIZE] = '\0'; 2007c478bd9Sstevel@tonic-gate (void) fprintf(stderr, "tag too long, truncated to <%s>\n", pmtag); 2017c478bd9Sstevel@tonic-gate } 2027c478bd9Sstevel@tonic-gate for (p = pmtag; *p; p++) { 2037c478bd9Sstevel@tonic-gate if (!isalnum(*p)) { 2047c478bd9Sstevel@tonic-gate Saferrno = E_BADARGS; 2057c478bd9Sstevel@tonic-gate error("port monitor tag must be alphanumeric"); 2067c478bd9Sstevel@tonic-gate } 2077c478bd9Sstevel@tonic-gate } 2087c478bd9Sstevel@tonic-gate break; 2097c478bd9Sstevel@tonic-gate case 'r': 2107c478bd9Sstevel@tonic-gate flag |= REMOVE; 2117c478bd9Sstevel@tonic-gate break; 2127c478bd9Sstevel@tonic-gate case 's': 2137c478bd9Sstevel@tonic-gate flag |= START; 2147c478bd9Sstevel@tonic-gate break; 2157c478bd9Sstevel@tonic-gate case 't': 2167c478bd9Sstevel@tonic-gate type = optarg; 2177c478bd9Sstevel@tonic-gate if (strchr(optarg, '\n')) { 2187c478bd9Sstevel@tonic-gate Saferrno = E_BADARGS; 2197c478bd9Sstevel@tonic-gate error(BADINP); 2207c478bd9Sstevel@tonic-gate } 2217c478bd9Sstevel@tonic-gate if (strlen(type) > PMTYPESIZE) { 2227c478bd9Sstevel@tonic-gate type[PMTYPESIZE] = '\0'; 2237c478bd9Sstevel@tonic-gate (void) fprintf(stderr, "type too long, truncated to <%s>\n", type); 2247c478bd9Sstevel@tonic-gate } 2257c478bd9Sstevel@tonic-gate for (p = type; *p; p++) { 2267c478bd9Sstevel@tonic-gate if (!isalnum(*p)) { 2277c478bd9Sstevel@tonic-gate Saferrno = E_BADARGS; 2287c478bd9Sstevel@tonic-gate error("port monitor type must be alphanumeric"); 2297c478bd9Sstevel@tonic-gate } 2307c478bd9Sstevel@tonic-gate } 2317c478bd9Sstevel@tonic-gate break; 2327c478bd9Sstevel@tonic-gate case 'v': 2337c478bd9Sstevel@tonic-gate flag |= ADD; 2347c478bd9Sstevel@tonic-gate version = atoi(optarg); 2357c478bd9Sstevel@tonic-gate if (version < 0) { 2367c478bd9Sstevel@tonic-gate Saferrno = E_BADARGS; 2377c478bd9Sstevel@tonic-gate error("version number can not be negative"); 2387c478bd9Sstevel@tonic-gate } 2397c478bd9Sstevel@tonic-gate break; 2407c478bd9Sstevel@tonic-gate case 'x': 2417c478bd9Sstevel@tonic-gate flag |= DBREAD; 2427c478bd9Sstevel@tonic-gate break; 2437c478bd9Sstevel@tonic-gate case 'y': 2447c478bd9Sstevel@tonic-gate flag |= ADD; 2457c478bd9Sstevel@tonic-gate if (strchr(optarg, '\n')) { 2467c478bd9Sstevel@tonic-gate Saferrno = E_BADARGS; 2477c478bd9Sstevel@tonic-gate error(BADINP); 2487c478bd9Sstevel@tonic-gate } 2497c478bd9Sstevel@tonic-gate comment = optarg; 2507c478bd9Sstevel@tonic-gate break; 2517c478bd9Sstevel@tonic-gate case 'z': 2527c478bd9Sstevel@tonic-gate if (strchr(optarg, '\n')) { 2537c478bd9Sstevel@tonic-gate Saferrno = E_BADARGS; 2547c478bd9Sstevel@tonic-gate error(BADINP); 2557c478bd9Sstevel@tonic-gate } 2567c478bd9Sstevel@tonic-gate script = optarg; 2577c478bd9Sstevel@tonic-gate break; 2587c478bd9Sstevel@tonic-gate case '?': 2597c478bd9Sstevel@tonic-gate errflg++; 2607c478bd9Sstevel@tonic-gate } 2617c478bd9Sstevel@tonic-gate } 2627c478bd9Sstevel@tonic-gate if (errflg || (optind < argc)) 2637c478bd9Sstevel@tonic-gate usage(argv[0]); 2647c478bd9Sstevel@tonic-gate 2657c478bd9Sstevel@tonic-gate if (badcnt) { 2667c478bd9Sstevel@tonic-gate /* bad flags were given to -f */ 2677c478bd9Sstevel@tonic-gate Saferrno = E_BADARGS; 2687c478bd9Sstevel@tonic-gate (void) sprintf(buf, 2697c478bd9Sstevel@tonic-gate "Invalid request, %s are not valid arguments for \"-f\"", 2707c478bd9Sstevel@tonic-gate badargs); 2717c478bd9Sstevel@tonic-gate error(buf); 2727c478bd9Sstevel@tonic-gate } 2737c478bd9Sstevel@tonic-gate 2747c478bd9Sstevel@tonic-gate if ((ret = check_version(VERSION, SACTAB)) == 1) { 2757c478bd9Sstevel@tonic-gate Saferrno = E_SAFERR; 2767c478bd9Sstevel@tonic-gate error("_sactab version number is incorrect"); 2777c478bd9Sstevel@tonic-gate } 2787c478bd9Sstevel@tonic-gate else if (ret == 2) { 2797c478bd9Sstevel@tonic-gate (void) sprintf(buf, "could not open %s", SACTAB); 2807c478bd9Sstevel@tonic-gate Saferrno = E_SYSERR; 2817c478bd9Sstevel@tonic-gate error(buf); 2827c478bd9Sstevel@tonic-gate } 2837c478bd9Sstevel@tonic-gate else if (ret == 3) { 2847c478bd9Sstevel@tonic-gate (void) sprintf(buf, "%s file is corrupt", SACTAB); 2857c478bd9Sstevel@tonic-gate Saferrno = E_SAFERR; 2867c478bd9Sstevel@tonic-gate error(buf); 2877c478bd9Sstevel@tonic-gate } 2887c478bd9Sstevel@tonic-gate uid = getuid(); 2897c478bd9Sstevel@tonic-gate switch (flag) { 2907c478bd9Sstevel@tonic-gate case ADD: 2917c478bd9Sstevel@tonic-gate if (uid) { 2927c478bd9Sstevel@tonic-gate Saferrno = E_NOPRIV; 2937c478bd9Sstevel@tonic-gate error(NOTPRIV); 2947c478bd9Sstevel@tonic-gate } 2957c478bd9Sstevel@tonic-gate if (!sawaflag || !pmtag || !type || !command || (version < 0)) 2967c478bd9Sstevel@tonic-gate usage(argv[0]); 2977c478bd9Sstevel@tonic-gate add_pm(pmtag, type, command, version, flags, count, script, comment); 2987c478bd9Sstevel@tonic-gate break; 2997c478bd9Sstevel@tonic-gate case REMOVE: 3007c478bd9Sstevel@tonic-gate if (uid) { 3017c478bd9Sstevel@tonic-gate Saferrno = E_NOPRIV; 3027c478bd9Sstevel@tonic-gate error(NOTPRIV); 3037c478bd9Sstevel@tonic-gate } 3047c478bd9Sstevel@tonic-gate if (!pmtag || type || script) 3057c478bd9Sstevel@tonic-gate usage(argv[0]); 3067c478bd9Sstevel@tonic-gate rem_pm(pmtag); 3077c478bd9Sstevel@tonic-gate break; 3087c478bd9Sstevel@tonic-gate case START: 3097c478bd9Sstevel@tonic-gate if (uid) { 3107c478bd9Sstevel@tonic-gate Saferrno = E_NOPRIV; 3117c478bd9Sstevel@tonic-gate error(NOTPRIV); 3127c478bd9Sstevel@tonic-gate } 3137c478bd9Sstevel@tonic-gate if (!pmtag || type || script) 3147c478bd9Sstevel@tonic-gate usage(argv[0]); 3157c478bd9Sstevel@tonic-gate start_pm(pmtag); 3167c478bd9Sstevel@tonic-gate break; 3177c478bd9Sstevel@tonic-gate case KILL: 3187c478bd9Sstevel@tonic-gate if (uid) { 3197c478bd9Sstevel@tonic-gate Saferrno = E_NOPRIV; 3207c478bd9Sstevel@tonic-gate error(NOTPRIV); 3217c478bd9Sstevel@tonic-gate } 3227c478bd9Sstevel@tonic-gate if (!pmtag || type || script) 3237c478bd9Sstevel@tonic-gate usage(argv[0]); 3247c478bd9Sstevel@tonic-gate kill_pm(pmtag); 3257c478bd9Sstevel@tonic-gate break; 3267c478bd9Sstevel@tonic-gate case ENABLE: 3277c478bd9Sstevel@tonic-gate if (uid) { 3287c478bd9Sstevel@tonic-gate Saferrno = E_NOPRIV; 3297c478bd9Sstevel@tonic-gate error(NOTPRIV); 3307c478bd9Sstevel@tonic-gate } 3317c478bd9Sstevel@tonic-gate if (!pmtag || type || script) 3327c478bd9Sstevel@tonic-gate usage(argv[0]); 3337c478bd9Sstevel@tonic-gate enable_pm(pmtag); 3347c478bd9Sstevel@tonic-gate break; 3357c478bd9Sstevel@tonic-gate case DISABLE: 3367c478bd9Sstevel@tonic-gate if (uid) { 3377c478bd9Sstevel@tonic-gate Saferrno = E_NOPRIV; 3387c478bd9Sstevel@tonic-gate error(NOTPRIV); 3397c478bd9Sstevel@tonic-gate } 3407c478bd9Sstevel@tonic-gate if (!pmtag || type || script) 3417c478bd9Sstevel@tonic-gate usage(argv[0]); 3427c478bd9Sstevel@tonic-gate disable_pm(pmtag); 3437c478bd9Sstevel@tonic-gate break; 3447c478bd9Sstevel@tonic-gate case LIST: 3457c478bd9Sstevel@tonic-gate conflag = 1; 3467c478bd9Sstevel@tonic-gate /* fall through */ 3477c478bd9Sstevel@tonic-gate case PLIST: 3487c478bd9Sstevel@tonic-gate if ((pmtag && type) || script) 3497c478bd9Sstevel@tonic-gate usage(argv[0]); 3507c478bd9Sstevel@tonic-gate list_pms(pmtag, type, conflag); 3517c478bd9Sstevel@tonic-gate break; 3527c478bd9Sstevel@tonic-gate case DBREAD: 3537c478bd9Sstevel@tonic-gate if (uid) { 3547c478bd9Sstevel@tonic-gate Saferrno = E_NOPRIV; 3557c478bd9Sstevel@tonic-gate error(NOTPRIV); 3567c478bd9Sstevel@tonic-gate } 3577c478bd9Sstevel@tonic-gate if (type || script) 3587c478bd9Sstevel@tonic-gate usage(argv[0]); 3597c478bd9Sstevel@tonic-gate read_db(pmtag); 3607c478bd9Sstevel@tonic-gate break; 3617c478bd9Sstevel@tonic-gate case CONFIG: 3627c478bd9Sstevel@tonic-gate if (script && uid) { 3637c478bd9Sstevel@tonic-gate Saferrno = E_NOPRIV; 3647c478bd9Sstevel@tonic-gate error(NOTPRIV); 3657c478bd9Sstevel@tonic-gate } 3667c478bd9Sstevel@tonic-gate if (type || pmtag) 3677c478bd9Sstevel@tonic-gate usage(argv[0]); 3687c478bd9Sstevel@tonic-gate (void) do_config(script, "_sysconfig"); 3697c478bd9Sstevel@tonic-gate break; 3707c478bd9Sstevel@tonic-gate case PCONFIG: 3717c478bd9Sstevel@tonic-gate if (script && uid) { 3727c478bd9Sstevel@tonic-gate Saferrno = E_NOPRIV; 3737c478bd9Sstevel@tonic-gate error(NOTPRIV); 3747c478bd9Sstevel@tonic-gate } 3757c478bd9Sstevel@tonic-gate if (!pmtag || type) 3767c478bd9Sstevel@tonic-gate usage(argv[0]); 3777c478bd9Sstevel@tonic-gate fp = fopen(SACTAB, "r"); 3787c478bd9Sstevel@tonic-gate if (fp == NULL) { 3797c478bd9Sstevel@tonic-gate Saferrno = E_SYSERR; 3807c478bd9Sstevel@tonic-gate error("Could not open _sactab"); 3817c478bd9Sstevel@tonic-gate } 3827c478bd9Sstevel@tonic-gate if (!find_pm(fp, pmtag)) { 3837c478bd9Sstevel@tonic-gate Saferrno = E_NOEXIST; 3847c478bd9Sstevel@tonic-gate (void) sprintf(buf, "Invalid request, %s does not exist", pmtag); 3857c478bd9Sstevel@tonic-gate error(buf); 3867c478bd9Sstevel@tonic-gate } 3877c478bd9Sstevel@tonic-gate (void) fclose(fp); 3887c478bd9Sstevel@tonic-gate (void) sprintf(buf, "%s/_config", pmtag); 3897c478bd9Sstevel@tonic-gate (void) do_config(script, buf); 3907c478bd9Sstevel@tonic-gate break; 3917c478bd9Sstevel@tonic-gate default: 3927c478bd9Sstevel@tonic-gate /* we only get here if more than one flag bit was set */ 3937c478bd9Sstevel@tonic-gate usage(argv[0]); 3947c478bd9Sstevel@tonic-gate /* NOTREACHED */ 3957c478bd9Sstevel@tonic-gate } 3967c478bd9Sstevel@tonic-gate quit(); 3977c478bd9Sstevel@tonic-gate /* NOTREACHED */ 39834e48580Sdp return (0); 3997c478bd9Sstevel@tonic-gate } 4007c478bd9Sstevel@tonic-gate 4017c478bd9Sstevel@tonic-gate 4027c478bd9Sstevel@tonic-gate /* 4037c478bd9Sstevel@tonic-gate * usage - print out a usage message 4047c478bd9Sstevel@tonic-gate * 4057c478bd9Sstevel@tonic-gate * args: cmdname - the name command was invoked with 4067c478bd9Sstevel@tonic-gate */ 4077c478bd9Sstevel@tonic-gate 4087c478bd9Sstevel@tonic-gate void 4097c478bd9Sstevel@tonic-gate usage(cmdname) 4107c478bd9Sstevel@tonic-gate char *cmdname; 4117c478bd9Sstevel@tonic-gate { 4127c478bd9Sstevel@tonic-gate (void) fprintf(stderr, "Usage:\t%s -a -p pmtag -t type -c cmd -v ver [ -f dx ] [ -n count ]\n", cmdname); 4137c478bd9Sstevel@tonic-gate (void) fprintf(stderr, "\t\t[ -y comment ] [ -z script]\n"); 4147c478bd9Sstevel@tonic-gate (void) fprintf(stderr, "\t%s -r -p pmtag\n", cmdname); 4157c478bd9Sstevel@tonic-gate (void) fprintf(stderr, "\t%s -s -p pmtag\n", cmdname); 4167c478bd9Sstevel@tonic-gate (void) fprintf(stderr, "\t%s -k -p pmtag\n", cmdname); 4177c478bd9Sstevel@tonic-gate (void) fprintf(stderr, "\t%s -e -p pmtag\n", cmdname); 4187c478bd9Sstevel@tonic-gate (void) fprintf(stderr, "\t%s -d -p pmtag\n", cmdname); 4197c478bd9Sstevel@tonic-gate (void) fprintf(stderr, "\t%s -l [ -p pmtag | -t type ]\n", cmdname); 4207c478bd9Sstevel@tonic-gate (void) fprintf(stderr, "\t%s -L [ -p pmtag | -t type ]\n", cmdname); 4217c478bd9Sstevel@tonic-gate (void) fprintf(stderr, "\t%s -g -p pmtag [ -z script ]\n", cmdname); 4227c478bd9Sstevel@tonic-gate (void) fprintf(stderr, "\t%s -G [ -z script ]\n", cmdname); 4237c478bd9Sstevel@tonic-gate (void) fprintf(stderr, "\t%s -x [ -p pmtag ]\n", cmdname); 4247c478bd9Sstevel@tonic-gate Saferrno = E_BADARGS; 4257c478bd9Sstevel@tonic-gate quit(); 4267c478bd9Sstevel@tonic-gate } 4277c478bd9Sstevel@tonic-gate 4287c478bd9Sstevel@tonic-gate 4297c478bd9Sstevel@tonic-gate /* 4307c478bd9Sstevel@tonic-gate * add_pm - add a port monitor entry 4317c478bd9Sstevel@tonic-gate * 4327c478bd9Sstevel@tonic-gate * args: tag - port monitor's tag 4337c478bd9Sstevel@tonic-gate * type - port monitor's type 4347c478bd9Sstevel@tonic-gate * command - command string to invoke port monitor 4357c478bd9Sstevel@tonic-gate * version - version number of port monitor's pmtab 4367c478bd9Sstevel@tonic-gate * flags - port monitor flags 4377c478bd9Sstevel@tonic-gate * count - restart count 4387c478bd9Sstevel@tonic-gate * script - port monitor's configuration script 4397c478bd9Sstevel@tonic-gate * comment - comment describing port monitor 4407c478bd9Sstevel@tonic-gate */ 4417c478bd9Sstevel@tonic-gate 4427c478bd9Sstevel@tonic-gate void 4437c478bd9Sstevel@tonic-gate add_pm(tag, type, command, version, flags, count, script, comment) 4447c478bd9Sstevel@tonic-gate char *tag; 4457c478bd9Sstevel@tonic-gate char *type; 4467c478bd9Sstevel@tonic-gate char *command; 4477c478bd9Sstevel@tonic-gate int version; 4487c478bd9Sstevel@tonic-gate long flags; 4497c478bd9Sstevel@tonic-gate int count; 4507c478bd9Sstevel@tonic-gate char *script; 4517c478bd9Sstevel@tonic-gate char *comment; 4527c478bd9Sstevel@tonic-gate { 4537c478bd9Sstevel@tonic-gate FILE *fp; /* file pointer for _sactab */ 4547c478bd9Sstevel@tonic-gate int fd; /* scratch file descriptor */ 4557c478bd9Sstevel@tonic-gate struct stat statbuf; /* file status info */ 4567c478bd9Sstevel@tonic-gate char buf[SIZE]; /* scratch buffer */ 4577c478bd9Sstevel@tonic-gate char fname[SIZE]; /* scratch buffer for building names */ 4587c478bd9Sstevel@tonic-gate register int i; /* scratch variable */ 459*22c9e08bSsn199410 int retval = 0; /* return value from invoke_rm() function */ 4607c478bd9Sstevel@tonic-gate 4617c478bd9Sstevel@tonic-gate fp = fopen(SACTAB, "r"); 4627c478bd9Sstevel@tonic-gate if (fp == NULL) { 4637c478bd9Sstevel@tonic-gate Saferrno = E_SYSERR; 4647c478bd9Sstevel@tonic-gate error("Could not open _sactab"); 4657c478bd9Sstevel@tonic-gate } 4667c478bd9Sstevel@tonic-gate if (find_pm(fp, tag)) { 4677c478bd9Sstevel@tonic-gate Saferrno = E_DUP; 4687c478bd9Sstevel@tonic-gate (void) sprintf(buf, "Invalid request, %s already exists", tag); 4697c478bd9Sstevel@tonic-gate error(buf); 4707c478bd9Sstevel@tonic-gate } 4717c478bd9Sstevel@tonic-gate (void) fclose(fp); 4727c478bd9Sstevel@tonic-gate 4737c478bd9Sstevel@tonic-gate /* 4747c478bd9Sstevel@tonic-gate * create the directories for it if needed and put in initial files 4757c478bd9Sstevel@tonic-gate * (/etc/saf and /var/saf) 4767c478bd9Sstevel@tonic-gate */ 4777c478bd9Sstevel@tonic-gate 4787c478bd9Sstevel@tonic-gate for (i = 0; i < 2; i++) { 4797c478bd9Sstevel@tonic-gate /* i == 0 do /etc/saf i == 1 do /var/saf */ 4807c478bd9Sstevel@tonic-gate (void) sprintf(fname, "%s/%s", (i == 0 ) ? HOME : ALTHOME, tag); 4817c478bd9Sstevel@tonic-gate if (access(fname, 0) == 0) { 4827c478bd9Sstevel@tonic-gate /* something is there, find out what it is */ 4837c478bd9Sstevel@tonic-gate if (stat(fname, &statbuf) < 0) { 4847c478bd9Sstevel@tonic-gate Saferrno = E_SYSERR; 4857c478bd9Sstevel@tonic-gate (void) sprintf(buf, "could not stat <%s>", fname); 4867c478bd9Sstevel@tonic-gate error(buf); 4877c478bd9Sstevel@tonic-gate } 4887c478bd9Sstevel@tonic-gate if ((statbuf.st_mode & S_IFMT) != S_IFDIR) { 4897c478bd9Sstevel@tonic-gate Saferrno = E_SYSERR; 4907c478bd9Sstevel@tonic-gate (void) sprintf(buf, "<%s> exists and is not a directory", fname); 4917c478bd9Sstevel@tonic-gate error(buf); 4927c478bd9Sstevel@tonic-gate } 4937c478bd9Sstevel@tonic-gate /* note: this removes the directory too */ 494*22c9e08bSsn199410 if ((retval = invoke_rm(fname)) != 0) { 4957c478bd9Sstevel@tonic-gate Saferrno = E_SYSERR; 496*22c9e08bSsn199410 if (snprintf(buf, sizeof (buf), 497*22c9e08bSsn199410 "could not remove files under <%s>", 498*22c9e08bSsn199410 fname) >= sizeof (buf)) { 499*22c9e08bSsn199410 snprintf(buf, sizeof (buf), 500*22c9e08bSsn199410 "tag too long"); 501*22c9e08bSsn199410 } 5027c478bd9Sstevel@tonic-gate error(buf); 5037c478bd9Sstevel@tonic-gate } 5047c478bd9Sstevel@tonic-gate } 5057c478bd9Sstevel@tonic-gate 5067c478bd9Sstevel@tonic-gate /* 5077c478bd9Sstevel@tonic-gate * create the directory 5087c478bd9Sstevel@tonic-gate */ 5097c478bd9Sstevel@tonic-gate 5107c478bd9Sstevel@tonic-gate if (mkdir(fname, 0755) < 0) { 5117c478bd9Sstevel@tonic-gate Saferrno = E_SYSERR; 5127c478bd9Sstevel@tonic-gate (void) sprintf(buf, "could not create directory <%s>", fname); 5137c478bd9Sstevel@tonic-gate cleandirs(tag); 5147c478bd9Sstevel@tonic-gate error(buf); 5157c478bd9Sstevel@tonic-gate } 5167c478bd9Sstevel@tonic-gate } 5177c478bd9Sstevel@tonic-gate 5187c478bd9Sstevel@tonic-gate /* 5197c478bd9Sstevel@tonic-gate * put in the config script, if specified 5207c478bd9Sstevel@tonic-gate */ 5217c478bd9Sstevel@tonic-gate 5227c478bd9Sstevel@tonic-gate if (script) { 5237c478bd9Sstevel@tonic-gate (void) sprintf(fname, "%s/_config", tag); 5247c478bd9Sstevel@tonic-gate if (do_config(script, fname)) { 5257c478bd9Sstevel@tonic-gate cleandirs(tag); 5267c478bd9Sstevel@tonic-gate /* do_config put out any messages */ 5277c478bd9Sstevel@tonic-gate quit(); 5287c478bd9Sstevel@tonic-gate } 5297c478bd9Sstevel@tonic-gate } 5307c478bd9Sstevel@tonic-gate 5317c478bd9Sstevel@tonic-gate /* 5327c478bd9Sstevel@tonic-gate * create the communications pipe, but first make sure that the 5337c478bd9Sstevel@tonic-gate * permissions we specify are what we get 5347c478bd9Sstevel@tonic-gate */ 5357c478bd9Sstevel@tonic-gate 5367c478bd9Sstevel@tonic-gate (void) umask(0); 5377c478bd9Sstevel@tonic-gate (void) sprintf(fname, "%s/%s/_pmpipe", HOME, tag); 5387c478bd9Sstevel@tonic-gate if (mknod(fname, S_IFIFO | 0600, 0) < 0) { 5397c478bd9Sstevel@tonic-gate Saferrno = E_SYSERR; 5407c478bd9Sstevel@tonic-gate cleandirs(tag); 5417c478bd9Sstevel@tonic-gate error("could not create communications pipe"); 5427c478bd9Sstevel@tonic-gate } 5437c478bd9Sstevel@tonic-gate 5447c478bd9Sstevel@tonic-gate /* 5457c478bd9Sstevel@tonic-gate * create the _pid file 5467c478bd9Sstevel@tonic-gate */ 5477c478bd9Sstevel@tonic-gate 5487c478bd9Sstevel@tonic-gate (void) sprintf(fname, "%s/%s/_pid", HOME, tag); 5497c478bd9Sstevel@tonic-gate if ((fd = creat(fname, 0644)) < 0) { 5507c478bd9Sstevel@tonic-gate Saferrno = E_SYSERR; 5517c478bd9Sstevel@tonic-gate cleandirs(tag); 5527c478bd9Sstevel@tonic-gate error("could not create _pid file"); 5537c478bd9Sstevel@tonic-gate } 5547c478bd9Sstevel@tonic-gate (void) close(fd); 5557c478bd9Sstevel@tonic-gate 5567c478bd9Sstevel@tonic-gate /* 5577c478bd9Sstevel@tonic-gate * create the _pmtab file 5587c478bd9Sstevel@tonic-gate */ 5597c478bd9Sstevel@tonic-gate 5607c478bd9Sstevel@tonic-gate (void) sprintf(fname, "%s/%s/_pmtab", HOME, tag); 5617c478bd9Sstevel@tonic-gate if ((fd = creat(fname, 0644)) < 0) { 5627c478bd9Sstevel@tonic-gate Saferrno = E_SYSERR; 5637c478bd9Sstevel@tonic-gate cleandirs(tag); 5647c478bd9Sstevel@tonic-gate error("could not create _pmtab file"); 5657c478bd9Sstevel@tonic-gate } 5667c478bd9Sstevel@tonic-gate (void) sprintf(buf, "%s%d\n", VSTR, version); 5677c478bd9Sstevel@tonic-gate if (write(fd, buf, (unsigned) strlen(buf)) != strlen(buf)) { 5687c478bd9Sstevel@tonic-gate (void) close(fd); 5697c478bd9Sstevel@tonic-gate (void) unlink(fname); 5707c478bd9Sstevel@tonic-gate Saferrno = E_SYSERR; 5717c478bd9Sstevel@tonic-gate cleandirs(tag); 5727c478bd9Sstevel@tonic-gate error("error initializing _pmtab"); 5737c478bd9Sstevel@tonic-gate } 5747c478bd9Sstevel@tonic-gate (void) close(fd); 5757c478bd9Sstevel@tonic-gate 5767c478bd9Sstevel@tonic-gate /* 5777c478bd9Sstevel@tonic-gate * isolate the command name, but remember it since strtok() trashes it 5787c478bd9Sstevel@tonic-gate */ 5797c478bd9Sstevel@tonic-gate 580*22c9e08bSsn199410 if (strlcpy(buf, command, sizeof (buf)) >= sizeof (buf)) { 581*22c9e08bSsn199410 Saferrno = E_SYSERR; 582*22c9e08bSsn199410 cleandirs(tag); 583*22c9e08bSsn199410 error("command string too long"); 584*22c9e08bSsn199410 } 585*22c9e08bSsn199410 5867c478bd9Sstevel@tonic-gate (void) strtok(command, " \t"); 5877c478bd9Sstevel@tonic-gate 5887c478bd9Sstevel@tonic-gate /* 5897c478bd9Sstevel@tonic-gate * check out the command - let addition succeed if it doesn't exist (assume 5907c478bd9Sstevel@tonic-gate * it will be added later); fail anything else 5917c478bd9Sstevel@tonic-gate */ 5927c478bd9Sstevel@tonic-gate 5937c478bd9Sstevel@tonic-gate if (access(command, 0) == 0) { 5947c478bd9Sstevel@tonic-gate if (stat(command, &statbuf) < 0) { 5957c478bd9Sstevel@tonic-gate Saferrno = E_SYSERR; 5967c478bd9Sstevel@tonic-gate (void) fprintf(stderr, "Could not stat <%s>\n", command); 5977c478bd9Sstevel@tonic-gate cleandirs(tag); 5987c478bd9Sstevel@tonic-gate quit(); 5997c478bd9Sstevel@tonic-gate } 6007c478bd9Sstevel@tonic-gate if (!(statbuf.st_mode & 0111)) { 6017c478bd9Sstevel@tonic-gate Saferrno = E_BADARGS; 6027c478bd9Sstevel@tonic-gate (void) fprintf(stderr, "%s not executable\n", command); 6037c478bd9Sstevel@tonic-gate cleandirs(tag); 6047c478bd9Sstevel@tonic-gate quit(); 6057c478bd9Sstevel@tonic-gate } 6067c478bd9Sstevel@tonic-gate if ((statbuf.st_mode & S_IFMT) != S_IFREG) { 6077c478bd9Sstevel@tonic-gate Saferrno = E_BADARGS; 6087c478bd9Sstevel@tonic-gate (void) fprintf(stderr, "%s not a regular file\n", command); 6097c478bd9Sstevel@tonic-gate cleandirs(tag); 6107c478bd9Sstevel@tonic-gate quit(); 6117c478bd9Sstevel@tonic-gate } 6127c478bd9Sstevel@tonic-gate } 6137c478bd9Sstevel@tonic-gate else { 6147c478bd9Sstevel@tonic-gate (void) fprintf(stderr, "warning - %s does not exist\n", command); 6157c478bd9Sstevel@tonic-gate } 6167c478bd9Sstevel@tonic-gate 6177c478bd9Sstevel@tonic-gate /* 6187c478bd9Sstevel@tonic-gate * add the line 6197c478bd9Sstevel@tonic-gate */ 6207c478bd9Sstevel@tonic-gate 6217c478bd9Sstevel@tonic-gate fp = fopen(SACTAB, "a"); 6227c478bd9Sstevel@tonic-gate if (fp == NULL) { 6237c478bd9Sstevel@tonic-gate Saferrno = E_SYSERR; 6247c478bd9Sstevel@tonic-gate cleandirs(tag); 6257c478bd9Sstevel@tonic-gate error("Could not open _sactab"); 6267c478bd9Sstevel@tonic-gate } 6277c478bd9Sstevel@tonic-gate (void) fprintf(fp, "%s:%s:%s:%d:%s\t#%s\n", tag, type, 6287c478bd9Sstevel@tonic-gate (flags ? pflags(flags, FALSE) : ""), count, buf, 6297c478bd9Sstevel@tonic-gate (comment ? comment : "")); 6307c478bd9Sstevel@tonic-gate (void) fclose(fp); 6317c478bd9Sstevel@tonic-gate 6327c478bd9Sstevel@tonic-gate 6337c478bd9Sstevel@tonic-gate /* 6347c478bd9Sstevel@tonic-gate * tell the SAC to read _sactab if its there (i.e. single user) 6357c478bd9Sstevel@tonic-gate */ 6367c478bd9Sstevel@tonic-gate 6377c478bd9Sstevel@tonic-gate if (sac_home()) 6387c478bd9Sstevel@tonic-gate read_db(NULL); 6397c478bd9Sstevel@tonic-gate return; 6407c478bd9Sstevel@tonic-gate } 6417c478bd9Sstevel@tonic-gate 6427c478bd9Sstevel@tonic-gate 6437c478bd9Sstevel@tonic-gate /* 6447c478bd9Sstevel@tonic-gate * cleandirs - remove anything that might have been created (i.e. failed 6457c478bd9Sstevel@tonic-gate * addition. Saferrno is set elsewhere; this is strictly an attempt 6467c478bd9Sstevel@tonic-gate * to clean up what mess we've left, so don't check to see if the 6477c478bd9Sstevel@tonic-gate * cleanup worked. 6487c478bd9Sstevel@tonic-gate * 6497c478bd9Sstevel@tonic-gate * args: tag - tag of port monitor whose trees should be removed 6507c478bd9Sstevel@tonic-gate */ 6517c478bd9Sstevel@tonic-gate 6527c478bd9Sstevel@tonic-gate void 6537c478bd9Sstevel@tonic-gate cleandirs(tag) 6547c478bd9Sstevel@tonic-gate char *tag; 6557c478bd9Sstevel@tonic-gate { 6567c478bd9Sstevel@tonic-gate char buf[SIZE]; /* scratch buffer */ 6577c478bd9Sstevel@tonic-gate 6587c478bd9Sstevel@tonic-gate /* note: this removes the directory too, first zap /etc/saf/<tag> */ 659*22c9e08bSsn199410 if (snprintf(buf, sizeof (buf), "%s/%s", HOME, tag) >= sizeof (buf)) 660*22c9e08bSsn199410 (void) fprintf(stderr, "tag too long\n"); 661*22c9e08bSsn199410 else 662*22c9e08bSsn199410 (void) invoke_rm(buf); 6637c478bd9Sstevel@tonic-gate 6647c478bd9Sstevel@tonic-gate /* now remove /var/saf/<tag> */ 665*22c9e08bSsn199410 if (snprintf(buf, sizeof (buf), "%s/%s", ALTHOME, tag) >= sizeof (buf)) 666*22c9e08bSsn199410 (void) fprintf(stderr, "tag too long\n"); 667*22c9e08bSsn199410 else 6687c478bd9Sstevel@tonic-gate (void) rmdir(buf); 6697c478bd9Sstevel@tonic-gate } 6707c478bd9Sstevel@tonic-gate 6717c478bd9Sstevel@tonic-gate 6727c478bd9Sstevel@tonic-gate /* 6737c478bd9Sstevel@tonic-gate * rem_pm - remove a port monitor 6747c478bd9Sstevel@tonic-gate * 6757c478bd9Sstevel@tonic-gate * args: tag - tag of port monitor to be removed 6767c478bd9Sstevel@tonic-gate */ 6777c478bd9Sstevel@tonic-gate 6787c478bd9Sstevel@tonic-gate void 6797c478bd9Sstevel@tonic-gate rem_pm(tag) 6807c478bd9Sstevel@tonic-gate char *tag; 6817c478bd9Sstevel@tonic-gate { 6827c478bd9Sstevel@tonic-gate FILE *fp; /* file pointer for _sactab */ 6837c478bd9Sstevel@tonic-gate FILE *tfp; /* file pointer for temp file */ 6847c478bd9Sstevel@tonic-gate int line; /* line number entry is on */ 6857c478bd9Sstevel@tonic-gate char *tname; /* temp file name */ 6867c478bd9Sstevel@tonic-gate char buf[SIZE]; /* scratch buffer */ 6877c478bd9Sstevel@tonic-gate 6887c478bd9Sstevel@tonic-gate fp = fopen(SACTAB, "r"); 6897c478bd9Sstevel@tonic-gate if (fp == NULL) { 6907c478bd9Sstevel@tonic-gate Saferrno = E_SYSERR; 6917c478bd9Sstevel@tonic-gate error("Could not open _sactab"); 6927c478bd9Sstevel@tonic-gate } 6937c478bd9Sstevel@tonic-gate if ((line = find_pm(fp, tag)) == 0) { 6947c478bd9Sstevel@tonic-gate Saferrno = E_NOEXIST; 6957c478bd9Sstevel@tonic-gate (void) sprintf(buf, "Invalid request, %s does not exist", tag); 6967c478bd9Sstevel@tonic-gate error(buf); 6977c478bd9Sstevel@tonic-gate } 6987c478bd9Sstevel@tonic-gate tname = make_tempname("_sactab"); 6997c478bd9Sstevel@tonic-gate tfp = open_temp(tname); 7007c478bd9Sstevel@tonic-gate if (line != 1) { 7017c478bd9Sstevel@tonic-gate if (copy_file(fp, tfp, 1, line - 1)) { 7027c478bd9Sstevel@tonic-gate (void) unlink(tname); 7037c478bd9Sstevel@tonic-gate Saferrno = E_SYSERR; 7047c478bd9Sstevel@tonic-gate error("error accessing temp file"); 7057c478bd9Sstevel@tonic-gate } 7067c478bd9Sstevel@tonic-gate } 7077c478bd9Sstevel@tonic-gate if (copy_file(fp, tfp, line + 1, -1)) { 7087c478bd9Sstevel@tonic-gate (void) unlink(tname); 7097c478bd9Sstevel@tonic-gate Saferrno = E_SYSERR; 7107c478bd9Sstevel@tonic-gate error("error accessing temp file"); 7117c478bd9Sstevel@tonic-gate } 7127c478bd9Sstevel@tonic-gate (void) fclose(fp); 7137c478bd9Sstevel@tonic-gate if (fclose(tfp) == EOF) { 7147c478bd9Sstevel@tonic-gate (void) unlink(tname); 7157c478bd9Sstevel@tonic-gate Saferrno = E_SYSERR; 7167c478bd9Sstevel@tonic-gate error("error closing tempfile"); 7177c478bd9Sstevel@tonic-gate } 7187c478bd9Sstevel@tonic-gate /* note - replace only returns if successful */ 7197c478bd9Sstevel@tonic-gate replace("_sactab", tname); 7207c478bd9Sstevel@tonic-gate 7217c478bd9Sstevel@tonic-gate /* 7227c478bd9Sstevel@tonic-gate * tell the SAC to read _sactab if its there (i.e. single user) 7237c478bd9Sstevel@tonic-gate */ 7247c478bd9Sstevel@tonic-gate 7257c478bd9Sstevel@tonic-gate if (sac_home()) 7267c478bd9Sstevel@tonic-gate read_db(NULL); 7277c478bd9Sstevel@tonic-gate return; 7287c478bd9Sstevel@tonic-gate } 7297c478bd9Sstevel@tonic-gate 7307c478bd9Sstevel@tonic-gate 7317c478bd9Sstevel@tonic-gate /* 7327c478bd9Sstevel@tonic-gate * start_pm - start a particular port monitor 7337c478bd9Sstevel@tonic-gate * 7347c478bd9Sstevel@tonic-gate * args: tag - tag of port monitor to be started 7357c478bd9Sstevel@tonic-gate */ 7367c478bd9Sstevel@tonic-gate 7377c478bd9Sstevel@tonic-gate void 7387c478bd9Sstevel@tonic-gate start_pm(tag) 7397c478bd9Sstevel@tonic-gate char *tag; 7407c478bd9Sstevel@tonic-gate { 7417c478bd9Sstevel@tonic-gate struct admcmd cmd; /* command structure */ 7427c478bd9Sstevel@tonic-gate register struct admcmd *ap = &cmd; /* and a pointer to it */ 7437c478bd9Sstevel@tonic-gate 7447c478bd9Sstevel@tonic-gate ap->ac_mtype = AC_START; 7457c478bd9Sstevel@tonic-gate (void) strcpy(ap->ac_tag, tag); 7467c478bd9Sstevel@tonic-gate ap->ac_pid = getpid(); 7477c478bd9Sstevel@tonic-gate sendcmd(ap, NULL, tag); 7487c478bd9Sstevel@tonic-gate return; 7497c478bd9Sstevel@tonic-gate } 7507c478bd9Sstevel@tonic-gate 7517c478bd9Sstevel@tonic-gate 7527c478bd9Sstevel@tonic-gate /* 7537c478bd9Sstevel@tonic-gate * kill_pm - stop a particular port monitor 7547c478bd9Sstevel@tonic-gate * 7557c478bd9Sstevel@tonic-gate * args: tag - tag of port monitor to be stopped 7567c478bd9Sstevel@tonic-gate */ 7577c478bd9Sstevel@tonic-gate 7587c478bd9Sstevel@tonic-gate void 7597c478bd9Sstevel@tonic-gate kill_pm(tag) 7607c478bd9Sstevel@tonic-gate char *tag; 7617c478bd9Sstevel@tonic-gate { 7627c478bd9Sstevel@tonic-gate struct admcmd cmd; /* command structure */ 7637c478bd9Sstevel@tonic-gate register struct admcmd *ap = &cmd; /* and a pointer to it */ 7647c478bd9Sstevel@tonic-gate 7657c478bd9Sstevel@tonic-gate ap->ac_mtype = AC_KILL; 7667c478bd9Sstevel@tonic-gate (void) strcpy(ap->ac_tag, tag); 7677c478bd9Sstevel@tonic-gate ap->ac_pid = getpid(); 7687c478bd9Sstevel@tonic-gate sendcmd(ap, NULL, tag); 7697c478bd9Sstevel@tonic-gate return; 7707c478bd9Sstevel@tonic-gate } 7717c478bd9Sstevel@tonic-gate 7727c478bd9Sstevel@tonic-gate 7737c478bd9Sstevel@tonic-gate /* 7747c478bd9Sstevel@tonic-gate * enable_pm - enable a particular port monitor 7757c478bd9Sstevel@tonic-gate * 7767c478bd9Sstevel@tonic-gate * args: tag - tag of port monitor to be enabled 7777c478bd9Sstevel@tonic-gate */ 7787c478bd9Sstevel@tonic-gate 7797c478bd9Sstevel@tonic-gate void 7807c478bd9Sstevel@tonic-gate enable_pm(tag) 7817c478bd9Sstevel@tonic-gate char *tag; 7827c478bd9Sstevel@tonic-gate { 7837c478bd9Sstevel@tonic-gate struct admcmd cmd; /* command structure */ 7847c478bd9Sstevel@tonic-gate register struct admcmd *ap = &cmd; /* and a pointer to it */ 7857c478bd9Sstevel@tonic-gate 7867c478bd9Sstevel@tonic-gate ap->ac_mtype = AC_ENABLE; 7877c478bd9Sstevel@tonic-gate (void) strcpy(ap->ac_tag, tag); 7887c478bd9Sstevel@tonic-gate ap->ac_pid = getpid(); 7897c478bd9Sstevel@tonic-gate sendcmd(ap, NULL, tag); 7907c478bd9Sstevel@tonic-gate return; 7917c478bd9Sstevel@tonic-gate } 7927c478bd9Sstevel@tonic-gate 7937c478bd9Sstevel@tonic-gate 7947c478bd9Sstevel@tonic-gate /* 7957c478bd9Sstevel@tonic-gate * disable_pm - disable a particular port monitor 7967c478bd9Sstevel@tonic-gate * 7977c478bd9Sstevel@tonic-gate * args: tag - tag of port monitor to be disabled 7987c478bd9Sstevel@tonic-gate */ 7997c478bd9Sstevel@tonic-gate 8007c478bd9Sstevel@tonic-gate void 8017c478bd9Sstevel@tonic-gate disable_pm(tag) 8027c478bd9Sstevel@tonic-gate char *tag; 8037c478bd9Sstevel@tonic-gate { 8047c478bd9Sstevel@tonic-gate struct admcmd cmd; /* command structure */ 8057c478bd9Sstevel@tonic-gate register struct admcmd *ap = &cmd; /* and a pointer to it */ 8067c478bd9Sstevel@tonic-gate 8077c478bd9Sstevel@tonic-gate ap->ac_mtype = AC_DISABLE; 8087c478bd9Sstevel@tonic-gate (void) strcpy(ap->ac_tag, tag); 8097c478bd9Sstevel@tonic-gate ap->ac_pid = getpid(); 8107c478bd9Sstevel@tonic-gate sendcmd(ap, NULL, tag); 8117c478bd9Sstevel@tonic-gate return; 8127c478bd9Sstevel@tonic-gate } 8137c478bd9Sstevel@tonic-gate 8147c478bd9Sstevel@tonic-gate 8157c478bd9Sstevel@tonic-gate /* 8167c478bd9Sstevel@tonic-gate * read_db - tell SAC or a port monitor to read its administrative file. 8177c478bd9Sstevel@tonic-gate * 8187c478bd9Sstevel@tonic-gate * args: tag - tag of port monitor that should read its administrative 8197c478bd9Sstevel@tonic-gate * file. If NULL, it means SAC should. 8207c478bd9Sstevel@tonic-gate */ 8217c478bd9Sstevel@tonic-gate 8227c478bd9Sstevel@tonic-gate void 8237c478bd9Sstevel@tonic-gate read_db(tag) 8247c478bd9Sstevel@tonic-gate char *tag; 8257c478bd9Sstevel@tonic-gate { 8267c478bd9Sstevel@tonic-gate struct admcmd cmd; /* command structure */ 8277c478bd9Sstevel@tonic-gate register struct admcmd *ap = &cmd; /* and a pointer to it */ 8287c478bd9Sstevel@tonic-gate 8297c478bd9Sstevel@tonic-gate ap->ac_mtype = (tag) ? AC_PMREAD : AC_SACREAD; 8307c478bd9Sstevel@tonic-gate if (tag) 8317c478bd9Sstevel@tonic-gate (void) strcpy(ap->ac_tag, tag); 8327c478bd9Sstevel@tonic-gate ap->ac_pid = getpid(); 8337c478bd9Sstevel@tonic-gate sendcmd(ap, NULL, tag); 8347c478bd9Sstevel@tonic-gate return; 8357c478bd9Sstevel@tonic-gate } 8367c478bd9Sstevel@tonic-gate 8377c478bd9Sstevel@tonic-gate 8387c478bd9Sstevel@tonic-gate /* 8397c478bd9Sstevel@tonic-gate * list_pms - request information about port monitors from SAC and output 8407c478bd9Sstevel@tonic-gate * requested info 8417c478bd9Sstevel@tonic-gate * 8427c478bd9Sstevel@tonic-gate * args: pmtag - tag of port monitor to be listed (may be null) 8437c478bd9Sstevel@tonic-gate * pmtype - type of port monitors to be listed (may be null) 8447c478bd9Sstevel@tonic-gate * oflag - true if output should be easily parseable 8457c478bd9Sstevel@tonic-gate */ 8467c478bd9Sstevel@tonic-gate 8477c478bd9Sstevel@tonic-gate void 8487c478bd9Sstevel@tonic-gate list_pms(pmtag, pmtype, oflag) 8497c478bd9Sstevel@tonic-gate char *pmtag; 8507c478bd9Sstevel@tonic-gate char *pmtype; 8517c478bd9Sstevel@tonic-gate int oflag; 8527c478bd9Sstevel@tonic-gate { 8537c478bd9Sstevel@tonic-gate struct admcmd acmd; /* command structure */ 8547c478bd9Sstevel@tonic-gate register struct admcmd *ap = &acmd; /* and a pointer to it */ 8557c478bd9Sstevel@tonic-gate int nprint = 0; /* count # of PMs printed */ 8567c478bd9Sstevel@tonic-gate char *p; /* scratch pointer */ 8577c478bd9Sstevel@tonic-gate char *tag; /* returned tag */ 8587c478bd9Sstevel@tonic-gate char *type; /* returned type */ 8597c478bd9Sstevel@tonic-gate char *flags; /* returned flags */ 8607c478bd9Sstevel@tonic-gate char *rsmax; /* returned restart count */ 8617c478bd9Sstevel@tonic-gate char *state; /* returned state */ 8627c478bd9Sstevel@tonic-gate char *cmd; /* returned command string */ 8637c478bd9Sstevel@tonic-gate char *comment; /* returned comment string */ 8647c478bd9Sstevel@tonic-gate 8657c478bd9Sstevel@tonic-gate /* 8667c478bd9Sstevel@tonic-gate * if sac isn't there (single user), provide info direct from _sactab 8677c478bd9Sstevel@tonic-gate * note: when this routine returns, the process exits, so there is no 8687c478bd9Sstevel@tonic-gate * need to free up any memory 8697c478bd9Sstevel@tonic-gate */ 8707c478bd9Sstevel@tonic-gate 8717c478bd9Sstevel@tonic-gate p = NULL; 8727c478bd9Sstevel@tonic-gate if (sac_home()) { 8737c478bd9Sstevel@tonic-gate ap->ac_mtype = AC_STATUS; 8747c478bd9Sstevel@tonic-gate ap->ac_tag[0] = '\0'; 8757c478bd9Sstevel@tonic-gate ap->ac_pid = getpid(); 8767c478bd9Sstevel@tonic-gate sendcmd(ap, &p, NULL); 8777c478bd9Sstevel@tonic-gate } 8787c478bd9Sstevel@tonic-gate else { 8797c478bd9Sstevel@tonic-gate single_print(&p); 8807c478bd9Sstevel@tonic-gate } 8817c478bd9Sstevel@tonic-gate 8827c478bd9Sstevel@tonic-gate /* 8837c478bd9Sstevel@tonic-gate * SAC sends back info in condensed form, we have to separate it out 8847c478bd9Sstevel@tonic-gate * fields come in ':' separated, records are separated by newlines 8857c478bd9Sstevel@tonic-gate */ 8867c478bd9Sstevel@tonic-gate 8877c478bd9Sstevel@tonic-gate while (p && *p) { 8887c478bd9Sstevel@tonic-gate tag = getfield(&p, ':'); /* PM tag */ 8897c478bd9Sstevel@tonic-gate type = getfield(&p, ':'); /* PM type */ 8907c478bd9Sstevel@tonic-gate flags = getfield(&p, ':'); /* flags */ 8917c478bd9Sstevel@tonic-gate rsmax = getfield(&p, ':'); /* restart count */ 8927c478bd9Sstevel@tonic-gate state = pstate((unchar) atoi(getfield(&p, ':'))); /* state in nice output format */ 8937c478bd9Sstevel@tonic-gate cmd = getfield(&p, ':'); /* command */ 8947c478bd9Sstevel@tonic-gate comment = getfield(&p, '\n'); /* comment */ 8957c478bd9Sstevel@tonic-gate 8967c478bd9Sstevel@tonic-gate 8977c478bd9Sstevel@tonic-gate /* 8987c478bd9Sstevel@tonic-gate * print out if no selectors specified, else check to see if 8997c478bd9Sstevel@tonic-gate * a selector matched 9007c478bd9Sstevel@tonic-gate */ 9017c478bd9Sstevel@tonic-gate 9027c478bd9Sstevel@tonic-gate if ((!pmtag && !pmtype) || (pmtag && !strcmp(pmtag, tag)) || (pmtype && !strcmp(pmtype, type))) { 9037c478bd9Sstevel@tonic-gate if (oflag) { 9047c478bd9Sstevel@tonic-gate (void) printf("%s:%s:%s:%s:%s:%s#%s\n", tag, type, pflags(atol(flags), FALSE), 9057c478bd9Sstevel@tonic-gate rsmax, state, cmd, comment); 9067c478bd9Sstevel@tonic-gate } 9077c478bd9Sstevel@tonic-gate else { 9087c478bd9Sstevel@tonic-gate if (nprint == 0) { 9097c478bd9Sstevel@tonic-gate (void) printf("PMTAG PMTYPE FLGS RCNT STATUS COMMAND\n"); 9107c478bd9Sstevel@tonic-gate } 9117c478bd9Sstevel@tonic-gate (void) printf("%-14s %-14s %-4s %-4s %-10s %s #%s\n", tag, type, pflags(atol(flags), TRUE), 9127c478bd9Sstevel@tonic-gate rsmax, state, cmd, comment); 9137c478bd9Sstevel@tonic-gate } 9147c478bd9Sstevel@tonic-gate nprint++; 9157c478bd9Sstevel@tonic-gate } 9167c478bd9Sstevel@tonic-gate } 9177c478bd9Sstevel@tonic-gate /* 9187c478bd9Sstevel@tonic-gate * if we didn't find any valid ones, indicate an error (note: 1 and 9197c478bd9Sstevel@tonic-gate * only 1 of the if statements should be true) 9207c478bd9Sstevel@tonic-gate */ 9217c478bd9Sstevel@tonic-gate if (nprint == 0) { 9227c478bd9Sstevel@tonic-gate if (pmtype) 9237c478bd9Sstevel@tonic-gate (void) fprintf(stderr, "Invalid request, %s does not exist\n", pmtype); 9247c478bd9Sstevel@tonic-gate else if (pmtag) 9257c478bd9Sstevel@tonic-gate (void) fprintf(stderr, "Invalid request, %s does not exist\n", pmtag); 9267c478bd9Sstevel@tonic-gate else if (!pmtag && !pmtype) 9277c478bd9Sstevel@tonic-gate (void) fprintf(stderr, "No port monitors defined\n"); 9287c478bd9Sstevel@tonic-gate Saferrno = E_NOEXIST; 9297c478bd9Sstevel@tonic-gate } 9307c478bd9Sstevel@tonic-gate return; 9317c478bd9Sstevel@tonic-gate } 9327c478bd9Sstevel@tonic-gate 9337c478bd9Sstevel@tonic-gate 9347c478bd9Sstevel@tonic-gate /* 9357c478bd9Sstevel@tonic-gate * getfield - retrieve and return a field from the sac "status" string (input 9367c478bd9Sstevel@tonic-gate * argument is modified to point to next field as a side-effect) 9377c478bd9Sstevel@tonic-gate * 9387c478bd9Sstevel@tonic-gate * args: p - address of remaining portion of string 9397c478bd9Sstevel@tonic-gate * sepchar - field terminator character 9407c478bd9Sstevel@tonic-gate */ 9417c478bd9Sstevel@tonic-gate 9427c478bd9Sstevel@tonic-gate char * 9437c478bd9Sstevel@tonic-gate getfield(p, sepchar) 9447c478bd9Sstevel@tonic-gate char **p; 9457c478bd9Sstevel@tonic-gate char sepchar; 9467c478bd9Sstevel@tonic-gate { 9477c478bd9Sstevel@tonic-gate char *savep; /* for saving argument */ 9487c478bd9Sstevel@tonic-gate 9497c478bd9Sstevel@tonic-gate savep = *p; 9507c478bd9Sstevel@tonic-gate *p = strchr(*p, sepchar); 9517c478bd9Sstevel@tonic-gate if (*p == NULL) { 9527c478bd9Sstevel@tonic-gate Saferrno = E_SAFERR; 9537c478bd9Sstevel@tonic-gate (void) fprintf(stderr, "Improper message from SAC\n"); 9547c478bd9Sstevel@tonic-gate return(NULL); 9557c478bd9Sstevel@tonic-gate } 9567c478bd9Sstevel@tonic-gate **p = '\0'; 9577c478bd9Sstevel@tonic-gate (*p)++; 9587c478bd9Sstevel@tonic-gate return(savep); 9597c478bd9Sstevel@tonic-gate } 9607c478bd9Sstevel@tonic-gate 9617c478bd9Sstevel@tonic-gate 9627c478bd9Sstevel@tonic-gate /* 9637c478bd9Sstevel@tonic-gate * single_print - print out _sactab if sac not at home (should only happen 9647c478bd9Sstevel@tonic-gate * in single user mode 9657c478bd9Sstevel@tonic-gate * 9667c478bd9Sstevel@tonic-gate * args: p - address of pointer where formatted data should be 9677c478bd9Sstevel@tonic-gate * placed (space allocated here) 9687c478bd9Sstevel@tonic-gate */ 9697c478bd9Sstevel@tonic-gate 9707c478bd9Sstevel@tonic-gate void 9717c478bd9Sstevel@tonic-gate single_print(p) 9727c478bd9Sstevel@tonic-gate char **p; 9737c478bd9Sstevel@tonic-gate { 9747c478bd9Sstevel@tonic-gate FILE *fp; /* file pointer for _sactab */ 9757c478bd9Sstevel@tonic-gate struct stat statbuf; /* file status info */ 9767c478bd9Sstevel@tonic-gate register char *tp1; /* scratch pointer */ 9777c478bd9Sstevel@tonic-gate register char *tp2; /* scratch pointer */ 9787c478bd9Sstevel@tonic-gate struct sactab stab; /* place to hold parsed info */ 9797c478bd9Sstevel@tonic-gate register struct sactab *sp = &stab; /* and a pointer to it */ 9807c478bd9Sstevel@tonic-gate char buf[SIZE]; /* scratch buffer */ 9817c478bd9Sstevel@tonic-gate 9827c478bd9Sstevel@tonic-gate fp = fopen(SACTAB, "r"); 9837c478bd9Sstevel@tonic-gate if (fp == NULL) { 9847c478bd9Sstevel@tonic-gate Saferrno = E_SYSERR; 9857c478bd9Sstevel@tonic-gate error("Could not open _sactab"); 9867c478bd9Sstevel@tonic-gate } 9877c478bd9Sstevel@tonic-gate if (fstat(fileno(fp), &statbuf) < 0) { 9887c478bd9Sstevel@tonic-gate Saferrno = E_SYSERR; 9897c478bd9Sstevel@tonic-gate error("could not stat _sactab"); 9907c478bd9Sstevel@tonic-gate } 9917c478bd9Sstevel@tonic-gate 9927c478bd9Sstevel@tonic-gate /* 9937c478bd9Sstevel@tonic-gate * allocate space to build return string, twice file size should be more 9947c478bd9Sstevel@tonic-gate * than enough (and make sure it's zero'ed out) 9957c478bd9Sstevel@tonic-gate */ 9967c478bd9Sstevel@tonic-gate 9977c478bd9Sstevel@tonic-gate tp1 = calloc(2 * statbuf.st_size, sizeof(char)); 9987c478bd9Sstevel@tonic-gate if (tp1 == NULL) { 9997c478bd9Sstevel@tonic-gate Saferrno = E_SYSERR; 10007c478bd9Sstevel@tonic-gate error("could not allocate storage"); 10017c478bd9Sstevel@tonic-gate } 10027c478bd9Sstevel@tonic-gate 10037c478bd9Sstevel@tonic-gate /* 10047c478bd9Sstevel@tonic-gate * read the file and build the string 10057c478bd9Sstevel@tonic-gate */ 10067c478bd9Sstevel@tonic-gate 10077c478bd9Sstevel@tonic-gate while (fgets(buf, SIZE, fp)) { 10087c478bd9Sstevel@tonic-gate tp2 = trim(buf); 10097c478bd9Sstevel@tonic-gate if (*tp2 == '\0') 10107c478bd9Sstevel@tonic-gate continue; 10117c478bd9Sstevel@tonic-gate parse(tp2, &stab); 10127c478bd9Sstevel@tonic-gate (void) sprintf(buf, "%s:%s:%d:%d:%d:%s:%s\n", sp->sc_tag, sp->sc_type, 10137c478bd9Sstevel@tonic-gate sp->sc_flags, sp->sc_rsmax, SSTATE, sp->sc_cmd, sp->sc_comment); 10147c478bd9Sstevel@tonic-gate (void) strcat(tp1, buf); 10157c478bd9Sstevel@tonic-gate free(sp->sc_cmd); 10167c478bd9Sstevel@tonic-gate free(sp->sc_comment); 10177c478bd9Sstevel@tonic-gate } 10187c478bd9Sstevel@tonic-gate if (!feof(fp)) { 10197c478bd9Sstevel@tonic-gate Saferrno = E_SYSERR; 10207c478bd9Sstevel@tonic-gate error("error reading _sactab"); 10217c478bd9Sstevel@tonic-gate } 10227c478bd9Sstevel@tonic-gate (void) fclose(fp); 10237c478bd9Sstevel@tonic-gate 10247c478bd9Sstevel@tonic-gate /* 10257c478bd9Sstevel@tonic-gate * point at the just-built string 10267c478bd9Sstevel@tonic-gate */ 10277c478bd9Sstevel@tonic-gate 10287c478bd9Sstevel@tonic-gate *p = tp1; 10297c478bd9Sstevel@tonic-gate return; 10307c478bd9Sstevel@tonic-gate } 10317c478bd9Sstevel@tonic-gate 10327c478bd9Sstevel@tonic-gate 10337c478bd9Sstevel@tonic-gate /* 10347c478bd9Sstevel@tonic-gate * openpipe - open up command pipe to SAC 10357c478bd9Sstevel@tonic-gate */ 10367c478bd9Sstevel@tonic-gate 103734e48580Sdp int 10387c478bd9Sstevel@tonic-gate openpipe() 10397c478bd9Sstevel@tonic-gate { 10407c478bd9Sstevel@tonic-gate int fd; /* file descriptor associated with command pipe */ 10417c478bd9Sstevel@tonic-gate 10427c478bd9Sstevel@tonic-gate fd = open(CMDPIPE, O_RDWR); 10437c478bd9Sstevel@tonic-gate if (fd < 0) { 10447c478bd9Sstevel@tonic-gate Saferrno = E_SYSERR; 10457c478bd9Sstevel@tonic-gate error(SACERR); 10467c478bd9Sstevel@tonic-gate } 10477c478bd9Sstevel@tonic-gate 10487c478bd9Sstevel@tonic-gate /* 10497c478bd9Sstevel@tonic-gate * lock pipe to insure serial access, lock will disappear if process dies 10507c478bd9Sstevel@tonic-gate */ 10517c478bd9Sstevel@tonic-gate 10527c478bd9Sstevel@tonic-gate if (lockf(fd, F_LOCK, 0) < 0) { 10537c478bd9Sstevel@tonic-gate Saferrno = E_SYSERR; 10547c478bd9Sstevel@tonic-gate error("unable to lock command pipe"); 10557c478bd9Sstevel@tonic-gate } 10567c478bd9Sstevel@tonic-gate return(fd); 10577c478bd9Sstevel@tonic-gate } 10587c478bd9Sstevel@tonic-gate 10597c478bd9Sstevel@tonic-gate 10607c478bd9Sstevel@tonic-gate /* 10617c478bd9Sstevel@tonic-gate * sendcmd - send a command to the SAC 10627c478bd9Sstevel@tonic-gate * 10637c478bd9Sstevel@tonic-gate * args: ap - pointer to command to send 10647c478bd9Sstevel@tonic-gate * info - pointer to return information from the SAC 10657c478bd9Sstevel@tonic-gate * tag - tag of port monitor to which the command applies (may 10667c478bd9Sstevel@tonic-gate * be NULL) 10677c478bd9Sstevel@tonic-gate */ 10687c478bd9Sstevel@tonic-gate 10697c478bd9Sstevel@tonic-gate void 10707c478bd9Sstevel@tonic-gate sendcmd(ap, info, tag) 10717c478bd9Sstevel@tonic-gate struct admcmd *ap; 10727c478bd9Sstevel@tonic-gate char **info; 10737c478bd9Sstevel@tonic-gate char *tag; 10747c478bd9Sstevel@tonic-gate { 10757c478bd9Sstevel@tonic-gate int fd; /* file descriptor of command pipe */ 10767c478bd9Sstevel@tonic-gate 10777c478bd9Sstevel@tonic-gate fd = openpipe(); 10787c478bd9Sstevel@tonic-gate if (write(fd, ap, sizeof(struct admcmd)) < 0) { 10797c478bd9Sstevel@tonic-gate Saferrno = E_SYSERR; 10807c478bd9Sstevel@tonic-gate error(SACERR); 10817c478bd9Sstevel@tonic-gate } 10827c478bd9Sstevel@tonic-gate checkresp(fd, info, tag); 10837c478bd9Sstevel@tonic-gate 10847c478bd9Sstevel@tonic-gate /* 10857c478bd9Sstevel@tonic-gate * unlock the command pipe - not really necessary since we're about to close 10867c478bd9Sstevel@tonic-gate */ 10877c478bd9Sstevel@tonic-gate 10887c478bd9Sstevel@tonic-gate (void) lockf(fd, F_ULOCK, 0); 10897c478bd9Sstevel@tonic-gate (void) close(fd); 10907c478bd9Sstevel@tonic-gate return; 10917c478bd9Sstevel@tonic-gate } 10927c478bd9Sstevel@tonic-gate 10937c478bd9Sstevel@tonic-gate 10947c478bd9Sstevel@tonic-gate /* 10957c478bd9Sstevel@tonic-gate * checkresp - check the SAC's response to our command 10967c478bd9Sstevel@tonic-gate * 10977c478bd9Sstevel@tonic-gate * args: fd - file descriptor of command pipe 10987c478bd9Sstevel@tonic-gate * info - pointer to return and info send along by SAC 10997c478bd9Sstevel@tonic-gate * tag - tag of port monitor that the command had been 11007c478bd9Sstevel@tonic-gate * for, only used for error reporting 11017c478bd9Sstevel@tonic-gate */ 11027c478bd9Sstevel@tonic-gate 11037c478bd9Sstevel@tonic-gate void 11047c478bd9Sstevel@tonic-gate checkresp(fd, info, tag) 11057c478bd9Sstevel@tonic-gate int fd; 11067c478bd9Sstevel@tonic-gate char **info; 11077c478bd9Sstevel@tonic-gate char *tag; 11087c478bd9Sstevel@tonic-gate { 11097c478bd9Sstevel@tonic-gate struct admack ack; /* acknowledgment struct */ 11107c478bd9Sstevel@tonic-gate register struct admack *ak = &ack; /* and a pointer to it */ 11117c478bd9Sstevel@tonic-gate pid_t pid; /* my pid */ 11127c478bd9Sstevel@tonic-gate struct sigaction sigact; /* signal handler setup */ 11137c478bd9Sstevel@tonic-gate 11147c478bd9Sstevel@tonic-gate /* 11157c478bd9Sstevel@tonic-gate * make sure this ack is meant for me, put an alarm around the read 11167c478bd9Sstevel@tonic-gate * so we don't hang out forever. 11177c478bd9Sstevel@tonic-gate */ 11187c478bd9Sstevel@tonic-gate 11197c478bd9Sstevel@tonic-gate pid = getpid(); 11207c478bd9Sstevel@tonic-gate sigact.sa_flags = 0; 11217c478bd9Sstevel@tonic-gate sigact.sa_handler = catch; 11227c478bd9Sstevel@tonic-gate (void) sigemptyset(&sigact.sa_mask); 11237c478bd9Sstevel@tonic-gate (void) sigaddset(&sigact.sa_mask, SIGALRM); 11247c478bd9Sstevel@tonic-gate (void) sigaction(SIGALRM, &sigact, NULL); 11257c478bd9Sstevel@tonic-gate (void) alarm(10); 11267c478bd9Sstevel@tonic-gate do { 11277c478bd9Sstevel@tonic-gate if (read(fd, ak, sizeof(ack)) != sizeof(ack)) { 11287c478bd9Sstevel@tonic-gate Saferrno = E_SACNOTRUN; 11297c478bd9Sstevel@tonic-gate error(SACERR); 11307c478bd9Sstevel@tonic-gate } 11317c478bd9Sstevel@tonic-gate } while (pid != ak->ak_pid); 11327c478bd9Sstevel@tonic-gate (void) alarm(0); 11337c478bd9Sstevel@tonic-gate 11347c478bd9Sstevel@tonic-gate /* 11357c478bd9Sstevel@tonic-gate * check out what happened 11367c478bd9Sstevel@tonic-gate */ 11377c478bd9Sstevel@tonic-gate 11387c478bd9Sstevel@tonic-gate switch (ak->ak_resp) { 11397c478bd9Sstevel@tonic-gate case AK_ACK: 11407c478bd9Sstevel@tonic-gate /* everything was A-OK */ 11417c478bd9Sstevel@tonic-gate if (info && ak->ak_size) { 11427c478bd9Sstevel@tonic-gate /* there is return info and a place to put it */ 11437c478bd9Sstevel@tonic-gate if ((*info = malloc((unsigned) (ak->ak_size + 1))) == NULL) { 11447c478bd9Sstevel@tonic-gate Saferrno = E_SYSERR; 11457c478bd9Sstevel@tonic-gate error("could not allocate storage"); 11467c478bd9Sstevel@tonic-gate } 11477c478bd9Sstevel@tonic-gate if (read(fd, *info, (unsigned) ak->ak_size) != ak->ak_size) { 11487c478bd9Sstevel@tonic-gate Saferrno = E_SYSERR; 11497c478bd9Sstevel@tonic-gate error(SACERR); 11507c478bd9Sstevel@tonic-gate } 11517c478bd9Sstevel@tonic-gate /* make sure "string" is null-terminated */ 11527c478bd9Sstevel@tonic-gate (*info)[ak->ak_size] = '\0'; 11537c478bd9Sstevel@tonic-gate } 11547c478bd9Sstevel@tonic-gate return; 11557c478bd9Sstevel@tonic-gate /* something went wrong - see what */ 11567c478bd9Sstevel@tonic-gate case AK_PMRUN: 11577c478bd9Sstevel@tonic-gate Saferrno = E_PMRUN; 11587c478bd9Sstevel@tonic-gate (void) fprintf(stderr, "Port monitor, %s, is already running\n", tag); 11597c478bd9Sstevel@tonic-gate break; 11607c478bd9Sstevel@tonic-gate case AK_PMNOTRUN: 11617c478bd9Sstevel@tonic-gate Saferrno = E_PMNOTRUN; 11627c478bd9Sstevel@tonic-gate (void) fprintf(stderr, "Port monitor, %s, is not running\n", tag); 11637c478bd9Sstevel@tonic-gate break; 11647c478bd9Sstevel@tonic-gate case AK_NOPM: 11657c478bd9Sstevel@tonic-gate Saferrno = E_NOEXIST; 11667c478bd9Sstevel@tonic-gate (void) fprintf(stderr, "Invalid request, %s does not exist\n", tag); 11677c478bd9Sstevel@tonic-gate break; 11687c478bd9Sstevel@tonic-gate case AK_UNKNOWN: 11697c478bd9Sstevel@tonic-gate Saferrno = E_SAFERR; 11707c478bd9Sstevel@tonic-gate (void) fprintf(stderr, "Internal error - sent invalid command\n"); 11717c478bd9Sstevel@tonic-gate break; 11727c478bd9Sstevel@tonic-gate case AK_NOCONTACT: 11737c478bd9Sstevel@tonic-gate Saferrno = E_SAFERR; 11747c478bd9Sstevel@tonic-gate (void) fprintf(stderr, "Could not contact %s\n", tag); 11757c478bd9Sstevel@tonic-gate break; 11767c478bd9Sstevel@tonic-gate case AK_PMLOCK: 11777c478bd9Sstevel@tonic-gate Saferrno = E_SAFERR; 11787c478bd9Sstevel@tonic-gate (void) fprintf(stderr, "Could not start %s - _pid file locked\n", tag); 11797c478bd9Sstevel@tonic-gate break; 11807c478bd9Sstevel@tonic-gate case AK_RECOVER: 11817c478bd9Sstevel@tonic-gate Saferrno = E_RECOVER; 11827c478bd9Sstevel@tonic-gate (void) fprintf(stderr, "Port monitor, %s, is in recovery\n", tag); 11837c478bd9Sstevel@tonic-gate break; 11847c478bd9Sstevel@tonic-gate case AK_REQFAIL: 11857c478bd9Sstevel@tonic-gate Saferrno = E_SAFERR; 11867c478bd9Sstevel@tonic-gate (void) fprintf(stderr, "This request could not be completed - see sac log file for details\n"); 11877c478bd9Sstevel@tonic-gate break; 11887c478bd9Sstevel@tonic-gate default: 11897c478bd9Sstevel@tonic-gate Saferrno = E_SAFERR; 11907c478bd9Sstevel@tonic-gate (void) fprintf(stderr, "unknown response\n"); 11917c478bd9Sstevel@tonic-gate break; 11927c478bd9Sstevel@tonic-gate } 11937c478bd9Sstevel@tonic-gate } 11947c478bd9Sstevel@tonic-gate 11957c478bd9Sstevel@tonic-gate 11967c478bd9Sstevel@tonic-gate /* 11977c478bd9Sstevel@tonic-gate * catch - catcher for SIGALRM, don't need to do anything 11987c478bd9Sstevel@tonic-gate */ 11997c478bd9Sstevel@tonic-gate 12007c478bd9Sstevel@tonic-gate void 12017c478bd9Sstevel@tonic-gate catch() 12027c478bd9Sstevel@tonic-gate { 12037c478bd9Sstevel@tonic-gate } 12047c478bd9Sstevel@tonic-gate 12057c478bd9Sstevel@tonic-gate 12067c478bd9Sstevel@tonic-gate /* 12077c478bd9Sstevel@tonic-gate * pflags - put port monitor flags into intelligible form for output 12087c478bd9Sstevel@tonic-gate * 12097c478bd9Sstevel@tonic-gate * args: flags - binary representation of flags 12107c478bd9Sstevel@tonic-gate * dflag - true if a "-" should be returned if no flags 12117c478bd9Sstevel@tonic-gate */ 12127c478bd9Sstevel@tonic-gate 12137c478bd9Sstevel@tonic-gate char * 12147c478bd9Sstevel@tonic-gate pflags(flags, dflag) 12157c478bd9Sstevel@tonic-gate long flags; 12167c478bd9Sstevel@tonic-gate int dflag; 12177c478bd9Sstevel@tonic-gate { 12187c478bd9Sstevel@tonic-gate register int i; /* scratch counter */ 12197c478bd9Sstevel@tonic-gate static char buf[SIZE]; /* formatted flags */ 12207c478bd9Sstevel@tonic-gate 12217c478bd9Sstevel@tonic-gate if (flags == 0) { 12227c478bd9Sstevel@tonic-gate if (dflag) 12237c478bd9Sstevel@tonic-gate return("-"); 12247c478bd9Sstevel@tonic-gate else 12257c478bd9Sstevel@tonic-gate return(""); 12267c478bd9Sstevel@tonic-gate } 12277c478bd9Sstevel@tonic-gate i = 0; 12287c478bd9Sstevel@tonic-gate if (flags & D_FLAG) { 12297c478bd9Sstevel@tonic-gate buf[i++] = 'd'; 12307c478bd9Sstevel@tonic-gate flags &= ~D_FLAG; 12317c478bd9Sstevel@tonic-gate } 12327c478bd9Sstevel@tonic-gate if (flags & X_FLAG) { 12337c478bd9Sstevel@tonic-gate buf[i++] = 'x'; 12347c478bd9Sstevel@tonic-gate flags &= ~X_FLAG; 12357c478bd9Sstevel@tonic-gate } 12367c478bd9Sstevel@tonic-gate if (flags) { 12377c478bd9Sstevel@tonic-gate (void) fprintf(stderr, "Bad information from SAC\n"); 12387c478bd9Sstevel@tonic-gate exit(1); 12397c478bd9Sstevel@tonic-gate } 12407c478bd9Sstevel@tonic-gate buf[i] = '\0'; 12417c478bd9Sstevel@tonic-gate return(buf); 12427c478bd9Sstevel@tonic-gate } 12437c478bd9Sstevel@tonic-gate 12447c478bd9Sstevel@tonic-gate 12457c478bd9Sstevel@tonic-gate /* 12467c478bd9Sstevel@tonic-gate * sac_home - returns true is sac has a lock on its logfile, false 12477c478bd9Sstevel@tonic-gate * otherwise (useful to avoid errors for administrative actions in 12487c478bd9Sstevel@tonic-gate * single user mode) 12497c478bd9Sstevel@tonic-gate */ 12507c478bd9Sstevel@tonic-gate 125134e48580Sdp int 12527c478bd9Sstevel@tonic-gate sac_home() 12537c478bd9Sstevel@tonic-gate { 12547c478bd9Sstevel@tonic-gate int fd; /* fd to sac logfile */ 12557c478bd9Sstevel@tonic-gate 12567c478bd9Sstevel@tonic-gate fd = open(LOGFILE, O_RDONLY); 12577c478bd9Sstevel@tonic-gate if (fd < 0) { 12587c478bd9Sstevel@tonic-gate fprintf(stderr, "warning - could not ascertain sac status\n"); 12597c478bd9Sstevel@tonic-gate return(FALSE); 12607c478bd9Sstevel@tonic-gate } 12617c478bd9Sstevel@tonic-gate if (lockf(fd, F_TEST, 0) < 0) { 12627c478bd9Sstevel@tonic-gate /* everything is ok */ 12637c478bd9Sstevel@tonic-gate (void) close(fd); 12647c478bd9Sstevel@tonic-gate return(TRUE); 12657c478bd9Sstevel@tonic-gate } 12667c478bd9Sstevel@tonic-gate else { 12677c478bd9Sstevel@tonic-gate /* no one home */ 12687c478bd9Sstevel@tonic-gate (void) close(fd); 12697c478bd9Sstevel@tonic-gate return(FALSE); 12707c478bd9Sstevel@tonic-gate } 12717c478bd9Sstevel@tonic-gate } 1272*22c9e08bSsn199410 1273*22c9e08bSsn199410 /* 1274*22c9e08bSsn199410 * invoke_rm - deletes the argument directory and all its files/subdirectories 1275*22c9e08bSsn199410 */ 1276*22c9e08bSsn199410 static int 1277*22c9e08bSsn199410 invoke_rm(char *fname) 1278*22c9e08bSsn199410 { 1279*22c9e08bSsn199410 pid_t cpid; /* process ID of the child process */ 1280*22c9e08bSsn199410 int cstatus; /* status of child process */ 1281*22c9e08bSsn199410 char *argvec[4]; 1282*22c9e08bSsn199410 1283*22c9e08bSsn199410 argvec[0] = "rm"; 1284*22c9e08bSsn199410 argvec[1] = "-rf"; 1285*22c9e08bSsn199410 argvec[2] = fname; 1286*22c9e08bSsn199410 argvec[3] = NULL; 1287*22c9e08bSsn199410 1288*22c9e08bSsn199410 if (posix_spawn(&cpid, "/usr/bin/rm", NULL, NULL, 1289*22c9e08bSsn199410 (char *const *)argvec, NULL)) 1290*22c9e08bSsn199410 return (-1); 1291*22c9e08bSsn199410 if (waitpid(cpid, &cstatus, 0) == -1) 1292*22c9e08bSsn199410 return (-1); 1293*22c9e08bSsn199410 1294*22c9e08bSsn199410 return ((WIFEXITED(cstatus) == 0) ? 99 : WEXITSTATUS(cstatus)); 1295*22c9e08bSsn199410 } 1296