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
main(int argc,char * argv[])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
usage(cmdname)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
add_pm(tag,type,command,version,flags,count,script,comment)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
cleandirs(tag)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
rem_pm(tag)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
start_pm(tag)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
kill_pm(tag)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
enable_pm(tag)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
disable_pm(tag)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
read_db(tag)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
list_pms(pmtag,pmtype,oflag)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 *
getfield(p,sepchar)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
single_print(p)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
openpipe()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
sendcmd(ap,info,tag)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
checkresp(fd,info,tag)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
catch()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 *
pflags(flags,dflag)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
sac_home()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
invoke_rm(char * fname)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