10Sstevel@tonic-gate /*
20Sstevel@tonic-gate * CDDL HEADER START
30Sstevel@tonic-gate *
40Sstevel@tonic-gate * The contents of this file are subject to the terms of the
50Sstevel@tonic-gate * Common Development and Distribution License, Version 1.0 only
60Sstevel@tonic-gate * (the "License"). You may not use this file except in compliance
70Sstevel@tonic-gate * with the License.
80Sstevel@tonic-gate *
90Sstevel@tonic-gate * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
100Sstevel@tonic-gate * or http://www.opensolaris.org/os/licensing.
110Sstevel@tonic-gate * See the License for the specific language governing permissions
120Sstevel@tonic-gate * and limitations under the License.
130Sstevel@tonic-gate *
140Sstevel@tonic-gate * When distributing Covered Code, include this CDDL HEADER in each
150Sstevel@tonic-gate * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
160Sstevel@tonic-gate * If applicable, add the following below this CDDL HEADER, with the
170Sstevel@tonic-gate * fields enclosed by brackets "[]" replaced with your own identifying
180Sstevel@tonic-gate * information: Portions Copyright [yyyy] [name of copyright owner]
190Sstevel@tonic-gate *
200Sstevel@tonic-gate * CDDL HEADER END
210Sstevel@tonic-gate */
220Sstevel@tonic-gate /*
23*640Sbasabi * Copyright 2005 Sun Microsystems, Inc. All rights reserved.
240Sstevel@tonic-gate * Use is subject to license terms.
250Sstevel@tonic-gate */
260Sstevel@tonic-gate
270Sstevel@tonic-gate /* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */
280Sstevel@tonic-gate /* All Rights Reserved */
290Sstevel@tonic-gate
300Sstevel@tonic-gate
310Sstevel@tonic-gate #pragma ident "%Z%%M% %I% %E% SMI"
320Sstevel@tonic-gate
330Sstevel@tonic-gate /*
340Sstevel@tonic-gate * nlsadmin.c -- control program for the network listener service
350Sstevel@tonic-gate *
360Sstevel@tonic-gate * This program replaces a previous version of nlsadmin.
370Sstevel@tonic-gate *
380Sstevel@tonic-gate * This version of nlsadmin works with the service access facility to
390Sstevel@tonic-gate * control the network listener. The functionality of the SVR3.2 nlsadmin
400Sstevel@tonic-gate * command is supported through calls to the more general sacadm and pmadm
410Sstevel@tonic-gate * commands available through SAF. Users should migrate away from nlsadmin
420Sstevel@tonic-gate * to sacadm and pmadm for these functions.
430Sstevel@tonic-gate *
440Sstevel@tonic-gate * The -m option of the SVR3.2 nlsadmin command is now ignored.
450Sstevel@tonic-gate *
460Sstevel@tonic-gate * The -t option associates an address with service code 1 (same as in SVR3.2).
470Sstevel@tonic-gate * The -l option associates an address with service code 0.
480Sstevel@tonic-gate *
490Sstevel@tonic-gate * nlsadmin also contains new functionality -- the ability to format a
500Sstevel@tonic-gate * "listener-specific" string to put in the _pmtab database. This
510Sstevel@tonic-gate * functionality is required by SAF.
520Sstevel@tonic-gate */
530Sstevel@tonic-gate
540Sstevel@tonic-gate #include <sys/types.h>
550Sstevel@tonic-gate #include <sys/stat.h>
560Sstevel@tonic-gate #include <stdio.h>
57*640Sbasabi #include <stdlib.h>
580Sstevel@tonic-gate #include <ctype.h>
590Sstevel@tonic-gate #include <errno.h>
600Sstevel@tonic-gate #include <string.h>
610Sstevel@tonic-gate #include <sac.h>
620Sstevel@tonic-gate #include "nlsadmin.h"
630Sstevel@tonic-gate
640Sstevel@tonic-gate #define OPTIONS "a:c:d:e:ikl:mo:p:qr:st:vw:xy:z:A:N:VDR:"
650Sstevel@tonic-gate #ifndef FALSE
660Sstevel@tonic-gate #define TRUE 1
670Sstevel@tonic-gate #define FALSE 0
680Sstevel@tonic-gate #endif
690Sstevel@tonic-gate /*
700Sstevel@tonic-gate * defines for -q exit codes: QZERO is used for conditions that the
710Sstevel@tonic-gate * man page documents as returning 0, QONE for those that return 1
720Sstevel@tonic-gate */
730Sstevel@tonic-gate #define QZERO 0
740Sstevel@tonic-gate #define QONE 1
750Sstevel@tonic-gate
760Sstevel@tonic-gate /*
770Sstevel@tonic-gate * defines for simulated standard error format code
780Sstevel@tonic-gate */
790Sstevel@tonic-gate #define MM_NOSEV 0
800Sstevel@tonic-gate #define MM_HALT 1
810Sstevel@tonic-gate #define MM_ERROR 2
820Sstevel@tonic-gate #define MM_WARNING 3
830Sstevel@tonic-gate #define MM_INFO 4
840Sstevel@tonic-gate
850Sstevel@tonic-gate char *Nlsname; /* set to argv[0] */
860Sstevel@tonic-gate char Label[25]; /* label component for fmtmsg */
870Sstevel@tonic-gate int Quietflag = FALSE; /* set to TRUE when -q used */
880Sstevel@tonic-gate
890Sstevel@tonic-gate extern int errno;
900Sstevel@tonic-gate void nlsmesg();
910Sstevel@tonic-gate uid_t geteuid();
920Sstevel@tonic-gate char *nexttok();
930Sstevel@tonic-gate char *pflags();
940Sstevel@tonic-gate char *gencmdstr();
950Sstevel@tonic-gate
960Sstevel@tonic-gate struct svcfields {
970Sstevel@tonic-gate char *pmtag;
980Sstevel@tonic-gate char *pmtype;
990Sstevel@tonic-gate char *svc_code;
1000Sstevel@tonic-gate char *flags;
1010Sstevel@tonic-gate char *id;
1020Sstevel@tonic-gate char *res1;
1030Sstevel@tonic-gate char *res2;
1040Sstevel@tonic-gate char *res3;
1050Sstevel@tonic-gate char *addr;
1060Sstevel@tonic-gate char *rpc;
1070Sstevel@tonic-gate char *lflags;
1080Sstevel@tonic-gate char *modules;
1090Sstevel@tonic-gate char *command;
1100Sstevel@tonic-gate char *comment;
1110Sstevel@tonic-gate };
1120Sstevel@tonic-gate
113*640Sbasabi void no_permission(void) __NORETURN;
114*640Sbasabi void usage(int flag);
1150Sstevel@tonic-gate
116*640Sbasabi int
main(int argc,char ** argv)117*640Sbasabi main(int argc, char **argv)
1180Sstevel@tonic-gate {
1190Sstevel@tonic-gate extern char *optarg;
1200Sstevel@tonic-gate extern int optind;
1210Sstevel@tonic-gate int c; /* used for return from getopt */
1220Sstevel@tonic-gate char *addrptr = NULL; /* set when -A address is used */
1230Sstevel@tonic-gate char *rpcptr = NULL; /* set when -R rpcinfo is used */
1240Sstevel@tonic-gate char *cmdptr = NULL; /* set with -c command */
1250Sstevel@tonic-gate char *comptr = NULL; /* set with -y comment (old) */
1260Sstevel@tonic-gate char *idptr = NULL; /* set with -w id (old) */
1270Sstevel@tonic-gate char *lptr = NULL; /* set with -l addr (old) */
1280Sstevel@tonic-gate char *moduleptr = NULL; /* set with -m modules */
1290Sstevel@tonic-gate char *pipeptr = NULL; /* set with -o pipe */
1300Sstevel@tonic-gate char *svcptr = NULL; /* set when service code used (old) */
1310Sstevel@tonic-gate char *tptr = NULL; /* set when -t addr used (old) */
1320Sstevel@tonic-gate char *netspec = NULL; /* set to the network specification */
1330Sstevel@tonic-gate int flag = 0; /* bit flag of type of command */
1340Sstevel@tonic-gate int exitcode = 0; /* exit status of this command */
1350Sstevel@tonic-gate int lflags = 0; /* listener flags */
1360Sstevel@tonic-gate char buf[BUFSIZ]; /* temp buffer #1 */
1370Sstevel@tonic-gate char mesg[BUFSIZ]; /* temp buffer #2 */
1380Sstevel@tonic-gate FILE *fp; /* used for checking netspec */
1390Sstevel@tonic-gate char *ptr; /* temp pointer */
1400Sstevel@tonic-gate char *ptr2; /* temp pointer */
1410Sstevel@tonic-gate int sawsep = 0; /* flag for RPC separator */
1420Sstevel@tonic-gate
1430Sstevel@tonic-gate Nlsname = argv[0];
1440Sstevel@tonic-gate sprintf(Label, "UX:%.14s", argv[0]); /* for standard message fmt */
1450Sstevel@tonic-gate
1460Sstevel@tonic-gate while ((c = getopt(argc, argv, OPTIONS)) != -1) {
1470Sstevel@tonic-gate switch (c) {
1480Sstevel@tonic-gate case 'a':
1490Sstevel@tonic-gate if ( (flag && (flag != CMDFLAG)) || svcptr || Quietflag
1500Sstevel@tonic-gate || addrptr || rpcptr || lflags)
1510Sstevel@tonic-gate usage(INCONSISTENT);
1520Sstevel@tonic-gate svcptr = optarg;
1530Sstevel@tonic-gate break;
1540Sstevel@tonic-gate case 'c':
1550Sstevel@tonic-gate if ( (flag && (flag != CMDFLAG)) || cmdptr || Quietflag )
1560Sstevel@tonic-gate usage(INCONSISTENT);
1570Sstevel@tonic-gate cmdptr = optarg;
1580Sstevel@tonic-gate flag |= CMDFLAG;
1590Sstevel@tonic-gate break;
1600Sstevel@tonic-gate case 'd':
1610Sstevel@tonic-gate if ( flag || svcptr || Quietflag || comptr || addrptr
1620Sstevel@tonic-gate || rpcptr || cmdptr || idptr || lflags )
1630Sstevel@tonic-gate usage(INCONSISTENT);
1640Sstevel@tonic-gate svcptr = optarg;
1650Sstevel@tonic-gate flag |= DISFLAG;
1660Sstevel@tonic-gate break;
1670Sstevel@tonic-gate case 'e':
1680Sstevel@tonic-gate if ( flag || svcptr || Quietflag || comptr || addrptr
1690Sstevel@tonic-gate || rpcptr || cmdptr || idptr || lflags )
1700Sstevel@tonic-gate usage(INCONSISTENT);
1710Sstevel@tonic-gate svcptr = optarg;
1720Sstevel@tonic-gate flag |= ENAFLAG;
1730Sstevel@tonic-gate break;
1740Sstevel@tonic-gate case 'i':
1750Sstevel@tonic-gate if ( flag || svcptr || Quietflag || comptr || addrptr
1760Sstevel@tonic-gate || rpcptr || cmdptr || idptr || lflags )
1770Sstevel@tonic-gate usage(INCONSISTENT);
1780Sstevel@tonic-gate flag |= INIFLAG;
1790Sstevel@tonic-gate break;
1800Sstevel@tonic-gate case 'k':
1810Sstevel@tonic-gate if ( flag || svcptr || Quietflag || comptr || addrptr
1820Sstevel@tonic-gate || rpcptr || cmdptr || idptr || lflags )
1830Sstevel@tonic-gate usage(INCONSISTENT);
1840Sstevel@tonic-gate flag |= KILFLAG;
1850Sstevel@tonic-gate break;
1860Sstevel@tonic-gate case 'l':
1870Sstevel@tonic-gate if ( ( flag && (flag != ADRFLAG)) || svcptr || lptr
1880Sstevel@tonic-gate || Quietflag || comptr || addrptr || rpcptr
1890Sstevel@tonic-gate || cmdptr || idptr || lflags )
1900Sstevel@tonic-gate usage(INCONSISTENT);
1910Sstevel@tonic-gate lptr = optarg;
1920Sstevel@tonic-gate flag |= ADRFLAG;
1930Sstevel@tonic-gate break;
1940Sstevel@tonic-gate case 'm':
1950Sstevel@tonic-gate if ( (flag && (flag != CMDFLAG)) || Quietflag || rpcptr || lflags )
1960Sstevel@tonic-gate usage(INCONSISTENT);
1970Sstevel@tonic-gate flag |= CMDFLAG;
1980Sstevel@tonic-gate break;
1990Sstevel@tonic-gate case 'o':
2000Sstevel@tonic-gate if ( flag || svcptr || Quietflag || comptr || idptr || netspec )
2010Sstevel@tonic-gate usage(INCONSISTENT);
2020Sstevel@tonic-gate pipeptr = optarg;
2030Sstevel@tonic-gate flag |= PIPFLAG;
2040Sstevel@tonic-gate break;
2050Sstevel@tonic-gate case 'p':
2060Sstevel@tonic-gate if ( (flag && (flag != CMDFLAG) && (flag != PIPFLAG)) || Quietflag )
2070Sstevel@tonic-gate usage(INCONSISTENT);
2080Sstevel@tonic-gate moduleptr = optarg;
2090Sstevel@tonic-gate break;
2100Sstevel@tonic-gate case 'q':
2110Sstevel@tonic-gate if ( (flag && (flag != ZZZFLAG)) || Quietflag || comptr
2120Sstevel@tonic-gate || rpcptr || lflags || idptr )
2130Sstevel@tonic-gate usage(INCONSISTENT);
2140Sstevel@tonic-gate Quietflag = TRUE;
2150Sstevel@tonic-gate break;
2160Sstevel@tonic-gate case 'r':
2170Sstevel@tonic-gate if ( flag || svcptr || Quietflag || comptr || addrptr
2180Sstevel@tonic-gate || rpcptr || cmdptr || idptr || lflags )
2190Sstevel@tonic-gate usage(INCONSISTENT);
2200Sstevel@tonic-gate flag |= REMFLAG;
2210Sstevel@tonic-gate svcptr = optarg;
2220Sstevel@tonic-gate break;
2230Sstevel@tonic-gate case 's':
2240Sstevel@tonic-gate if ( flag || svcptr || Quietflag || comptr || addrptr
2250Sstevel@tonic-gate || rpcptr || cmdptr || idptr || lflags )
2260Sstevel@tonic-gate usage(INCONSISTENT);
2270Sstevel@tonic-gate flag |= STAFLAG;
2280Sstevel@tonic-gate break;
2290Sstevel@tonic-gate case 't':
2300Sstevel@tonic-gate if ( (flag && (flag != ADRFLAG)) || svcptr || tptr
2310Sstevel@tonic-gate || Quietflag || comptr || addrptr || rpcptr
2320Sstevel@tonic-gate || cmdptr || idptr || lflags )
2330Sstevel@tonic-gate usage(INCONSISTENT);
2340Sstevel@tonic-gate tptr = optarg;
2350Sstevel@tonic-gate flag |= ADRFLAG;
2360Sstevel@tonic-gate break;
2370Sstevel@tonic-gate case 'v':
2380Sstevel@tonic-gate if ( flag || svcptr || Quietflag || comptr || rpcptr
2390Sstevel@tonic-gate || addrptr || idptr || lflags )
2400Sstevel@tonic-gate usage(INCONSISTENT);
2410Sstevel@tonic-gate flag |= VBSFLAG;
2420Sstevel@tonic-gate break;
2430Sstevel@tonic-gate case 'w':
2440Sstevel@tonic-gate if ( (flag && (flag != CMDFLAG)) || Quietflag || idptr
2450Sstevel@tonic-gate || rpcptr || addrptr || lflags )
2460Sstevel@tonic-gate usage(INCONSISTENT);
2470Sstevel@tonic-gate idptr = optarg;
2480Sstevel@tonic-gate break;
2490Sstevel@tonic-gate case 'x':
2500Sstevel@tonic-gate if ( flag || svcptr || Quietflag || netspec || comptr
2510Sstevel@tonic-gate || rpcptr || addrptr || lflags || idptr )
2520Sstevel@tonic-gate usage(INCONSISTENT);
2530Sstevel@tonic-gate flag |= NETFLAG;
2540Sstevel@tonic-gate break;
2550Sstevel@tonic-gate case 'y':
2560Sstevel@tonic-gate if ( (flag && (flag != CMDFLAG)) || Quietflag || comptr
2570Sstevel@tonic-gate || rpcptr || addrptr || lflags )
2580Sstevel@tonic-gate usage(INCONSISTENT);
2590Sstevel@tonic-gate comptr = optarg;
2600Sstevel@tonic-gate break;
2610Sstevel@tonic-gate case 'z':
2620Sstevel@tonic-gate if ( flag || svcptr || comptr || addrptr || rpcptr
2630Sstevel@tonic-gate || idptr || lflags )
2640Sstevel@tonic-gate usage(INCONSISTENT);
2650Sstevel@tonic-gate flag |= ZZZFLAG;
2660Sstevel@tonic-gate svcptr = optarg;
2670Sstevel@tonic-gate break;
2680Sstevel@tonic-gate case 'A':
2690Sstevel@tonic-gate if ( (flag && (flag != CMDFLAG) && (flag != PIPFLAG))
2700Sstevel@tonic-gate || netspec || svcptr || idptr || comptr )
2710Sstevel@tonic-gate usage(INCONSISTENT);
2720Sstevel@tonic-gate addrptr = optarg;
2730Sstevel@tonic-gate break;
2740Sstevel@tonic-gate case 'D':
2750Sstevel@tonic-gate if ( (flag && (flag != CMDFLAG) && (flag != PIPFLAG))
2760Sstevel@tonic-gate || netspec || svcptr || idptr || comptr || addrptr
2770Sstevel@tonic-gate || lflags )
2780Sstevel@tonic-gate usage(INCONSISTENT);
2790Sstevel@tonic-gate lflags |= DFLAG;
2800Sstevel@tonic-gate break;
2810Sstevel@tonic-gate case 'N':
2820Sstevel@tonic-gate if ( netspec )
2830Sstevel@tonic-gate usage(INCONSISTENT);
2840Sstevel@tonic-gate netspec = optarg;
2850Sstevel@tonic-gate break;
2860Sstevel@tonic-gate case 'R':
2870Sstevel@tonic-gate if ( (flag && (flag != CMDFLAG) && (flag != PIPFLAG))
2880Sstevel@tonic-gate || netspec || svcptr || idptr || comptr )
2890Sstevel@tonic-gate usage(INCONSISTENT);
2900Sstevel@tonic-gate for (ptr = optarg; *ptr; ++ptr) {
2910Sstevel@tonic-gate if ((*ptr == ':') && !sawsep) {
2920Sstevel@tonic-gate /*
2930Sstevel@tonic-gate * skip separator - note that if
2940Sstevel@tonic-gate * separator has been seen, it's not
2950Sstevel@tonic-gate * a digit so it will generate a usage
2960Sstevel@tonic-gate * message below like we want
2970Sstevel@tonic-gate */
2980Sstevel@tonic-gate sawsep++;
2990Sstevel@tonic-gate continue;
3000Sstevel@tonic-gate }
3010Sstevel@tonic-gate if (!isdigit(*ptr))
3020Sstevel@tonic-gate usage(USAGE);
3030Sstevel@tonic-gate }
3040Sstevel@tonic-gate ptr = strchr(optarg, ':');
3050Sstevel@tonic-gate if (ptr)
3060Sstevel@tonic-gate /* change the ':' to a ',' */
3070Sstevel@tonic-gate *ptr = ',';
3080Sstevel@tonic-gate else
3090Sstevel@tonic-gate usage(USAGE);
3100Sstevel@tonic-gate rpcptr = optarg;
3110Sstevel@tonic-gate break;
3120Sstevel@tonic-gate case 'V':
3130Sstevel@tonic-gate if ( flag || svcptr || Quietflag || comptr || netspec
3140Sstevel@tonic-gate || rpcptr || addrptr || idptr || lflags )
3150Sstevel@tonic-gate usage(INCONSISTENT);
3160Sstevel@tonic-gate flag |= VERFLAG;
3170Sstevel@tonic-gate break;
3180Sstevel@tonic-gate case '?':
3190Sstevel@tonic-gate usage(USAGE);
3200Sstevel@tonic-gate }
321*640Sbasabi /* NOTREACHED */
3220Sstevel@tonic-gate }
3230Sstevel@tonic-gate
3240Sstevel@tonic-gate if ((optind < argc) && ! netspec)
3250Sstevel@tonic-gate netspec = argv[optind++];
3260Sstevel@tonic-gate if (optind < argc)
3270Sstevel@tonic-gate usage(USAGE);
3280Sstevel@tonic-gate
3290Sstevel@tonic-gate
3300Sstevel@tonic-gate /* determine if this command requires a netspec */
3310Sstevel@tonic-gate if (flag != CMDFLAG) {
3320Sstevel@tonic-gate /* if flag is CMDFLAG, more complicated checking of netspec
3330Sstevel@tonic-gate * is done below in switch
3340Sstevel@tonic-gate */
3350Sstevel@tonic-gate if ((flag == PIPFLAG || flag == VERFLAG || flag == NETFLAG)) {
3360Sstevel@tonic-gate if (netspec)
3370Sstevel@tonic-gate usage(USAGE);
3380Sstevel@tonic-gate }
3390Sstevel@tonic-gate else if (!netspec)
3400Sstevel@tonic-gate usage(USAGE);
3410Sstevel@tonic-gate }
3420Sstevel@tonic-gate
3430Sstevel@tonic-gate if (netspec && (flag != INIFLAG)) {
3440Sstevel@tonic-gate sprintf(buf, SAC_LSPM, netspec);
3450Sstevel@tonic-gate
3460Sstevel@tonic-gate if ((fp = popen(buf, "r")) == NULL) {
3470Sstevel@tonic-gate nlsmesg(MM_ERROR, "System error");
3480Sstevel@tonic-gate exit(NLS_SYSERR);
3490Sstevel@tonic-gate }
3500Sstevel@tonic-gate
3510Sstevel@tonic-gate if (fgets(buf, BUFSIZ, fp) == NULL) {
3520Sstevel@tonic-gate nlsmesg(MM_ERROR, "Invalid network specification");
3530Sstevel@tonic-gate exit(NLS_BADPM);
3540Sstevel@tonic-gate }
3550Sstevel@tonic-gate else {
3560Sstevel@tonic-gate ptr = strchr(buf, ':');
3570Sstevel@tonic-gate ptr++;
3580Sstevel@tonic-gate ptr2 = strchr(ptr, ':');
3590Sstevel@tonic-gate *ptr2 = NULL;
3600Sstevel@tonic-gate if (strcmp(ptr, LISTENTYPE) != 0) {
3610Sstevel@tonic-gate sprintf(mesg, "Network specification \"%s\" is not of type %s", netspec, LISTENTYPE);
3620Sstevel@tonic-gate nlsmesg(MM_ERROR, mesg);
3630Sstevel@tonic-gate exit(NLS_BADPM);
3640Sstevel@tonic-gate }
3650Sstevel@tonic-gate }
3660Sstevel@tonic-gate
3670Sstevel@tonic-gate pclose(fp);
3680Sstevel@tonic-gate }
3690Sstevel@tonic-gate
3700Sstevel@tonic-gate if (svcptr) {
3710Sstevel@tonic-gate /* check to see if service code is "correct" -- right range
3720Sstevel@tonic-gate * and format. The -m flag is ignored, so no check for
3730Sstevel@tonic-gate * "administrative" service codes (0-100) is done.
3740Sstevel@tonic-gate */
3750Sstevel@tonic-gate c = strlen(svcptr);
3760Sstevel@tonic-gate if ((c == 0) || (c >= SVC_CODE_SZ)) {
3770Sstevel@tonic-gate sprintf(mesg, "Service code contains more than %d characters", SVC_CODE_SZ);
3780Sstevel@tonic-gate nlsmesg(MM_ERROR, mesg);
3790Sstevel@tonic-gate exit(NLS_SERV);
3800Sstevel@tonic-gate }
3810Sstevel@tonic-gate }
3820Sstevel@tonic-gate
3830Sstevel@tonic-gate switch (flag) {
3840Sstevel@tonic-gate default:
3850Sstevel@tonic-gate usage(USAGE);
3860Sstevel@tonic-gate break;
3870Sstevel@tonic-gate case NONE:
3880Sstevel@tonic-gate if ( svcptr || comptr || rpcptr || lflags || idptr )
3890Sstevel@tonic-gate usage(INCONSISTENT);
3900Sstevel@tonic-gate exitcode = prt_nets(netspec);
3910Sstevel@tonic-gate break;
3920Sstevel@tonic-gate case INIFLAG:
3930Sstevel@tonic-gate if (geteuid() != ROOT)
3940Sstevel@tonic-gate no_permission();
3950Sstevel@tonic-gate exitcode = add_pm(netspec);
3960Sstevel@tonic-gate break;
3970Sstevel@tonic-gate case CMDFLAG:
3980Sstevel@tonic-gate if ( svcptr || comptr || idptr || netspec ) {
3990Sstevel@tonic-gate if (geteuid() != ROOT)
4000Sstevel@tonic-gate no_permission();
4010Sstevel@tonic-gate if ((exitcode = old_addsvc(svcptr, "", cmdptr, comptr, moduleptr, idptr, NULL, netspec)) != NLS_OK)
4020Sstevel@tonic-gate switch (exitcode) {
4030Sstevel@tonic-gate case NLS_SERV:
4040Sstevel@tonic-gate nlsmesg(MM_ERROR, "Service code already exists");
4050Sstevel@tonic-gate break;
4060Sstevel@tonic-gate default:
4070Sstevel@tonic-gate nlsmesg(MM_ERROR, "Could not add service");
4080Sstevel@tonic-gate break;
4090Sstevel@tonic-gate }
4100Sstevel@tonic-gate }
4110Sstevel@tonic-gate else {
4120Sstevel@tonic-gate if (netspec)
4130Sstevel@tonic-gate usage(INCONSISTENT);
4140Sstevel@tonic-gate exitcode = prt_cmd(cmdptr, CFLAG | lflags, moduleptr, addrptr, rpcptr);
4150Sstevel@tonic-gate }
4160Sstevel@tonic-gate break;
4170Sstevel@tonic-gate case PIPFLAG:
4180Sstevel@tonic-gate if (geteuid() != ROOT)
4190Sstevel@tonic-gate no_permission();
4200Sstevel@tonic-gate exitcode = prt_cmd(pipeptr, PFLAG | lflags, moduleptr, addrptr, rpcptr);
4210Sstevel@tonic-gate break;
4220Sstevel@tonic-gate case VERFLAG:
4230Sstevel@tonic-gate printf("%d\n", VERSION);
4240Sstevel@tonic-gate exit(NLS_OK);
4250Sstevel@tonic-gate break;
4260Sstevel@tonic-gate case DISFLAG:
4270Sstevel@tonic-gate if (geteuid() != ROOT)
4280Sstevel@tonic-gate no_permission();
4290Sstevel@tonic-gate exitcode = disable_svc(svcptr, netspec);
4300Sstevel@tonic-gate break;
4310Sstevel@tonic-gate case ENAFLAG:
4320Sstevel@tonic-gate if (geteuid() != ROOT)
4330Sstevel@tonic-gate no_permission();
4340Sstevel@tonic-gate exitcode = enable_svc(svcptr, netspec);
4350Sstevel@tonic-gate break;
4360Sstevel@tonic-gate case KILFLAG:
4370Sstevel@tonic-gate if (geteuid() != ROOT)
4380Sstevel@tonic-gate no_permission();
4390Sstevel@tonic-gate exitcode = kill_listener(netspec);
4400Sstevel@tonic-gate break;
4410Sstevel@tonic-gate case ADRFLAG:
4420Sstevel@tonic-gate /* check for root permissions in setup_addr */
4430Sstevel@tonic-gate exitcode = setup_addr(lptr, tptr, netspec);
4440Sstevel@tonic-gate break;
4450Sstevel@tonic-gate case REMFLAG:
4460Sstevel@tonic-gate if (geteuid() != ROOT)
4470Sstevel@tonic-gate no_permission();
4480Sstevel@tonic-gate exitcode = remove_svc(svcptr, netspec, TRUE);
4490Sstevel@tonic-gate break;
4500Sstevel@tonic-gate case STAFLAG:
4510Sstevel@tonic-gate if (geteuid() != ROOT)
4520Sstevel@tonic-gate no_permission();
4530Sstevel@tonic-gate exitcode = start_listener(netspec);
4540Sstevel@tonic-gate break;
4550Sstevel@tonic-gate case VBSFLAG:
4560Sstevel@tonic-gate exitcode = prt_svcs(NULL, netspec);
4570Sstevel@tonic-gate break;
4580Sstevel@tonic-gate case NETFLAG:
4590Sstevel@tonic-gate exitcode = prt_nets(NULL);
4600Sstevel@tonic-gate break;
4610Sstevel@tonic-gate case ZZZFLAG:
4620Sstevel@tonic-gate exitcode = prt_svcs(svcptr, netspec);
4630Sstevel@tonic-gate break;
4640Sstevel@tonic-gate }
4650Sstevel@tonic-gate if (exitcode == NLS_SYSERR)
4660Sstevel@tonic-gate nlsmesg(MM_ERROR, "System error in SAC command");
467*640Sbasabi return (exitcode);
4680Sstevel@tonic-gate }
4690Sstevel@tonic-gate
4700Sstevel@tonic-gate
4710Sstevel@tonic-gate static char umsg[] = "usage: %s -x\n\
4720Sstevel@tonic-gate %s [ options ] netspec\n\
4730Sstevel@tonic-gate %s [ options ] -N port_monitor_tag\n\
4740Sstevel@tonic-gate %s -V\n\
4750Sstevel@tonic-gate %s -c cmd | -o pipename [ -p modules ] [ -A addr | -D ] \\\n\
4760Sstevel@tonic-gate [ -R prognum:versnum ]\n\
4770Sstevel@tonic-gate \n\
4780Sstevel@tonic-gate [ options ] are:\n\
4790Sstevel@tonic-gate [ -a svc_code -c \"cmd\" -y \"cmt\" [-p modules] [-w id] ]\n\
4800Sstevel@tonic-gate [-q] | [-v] | [-s] | [-k] | [-i] |\n\
4810Sstevel@tonic-gate [-e svc_code] | [-d svc_code] | [-r svc_code] | [[-q] -z svc_code]\n\
4820Sstevel@tonic-gate [[-l addr | -] [-t addr | -]] |\n\
4830Sstevel@tonic-gate ";
4840Sstevel@tonic-gate
485*640Sbasabi void
usage(int flag)486*640Sbasabi usage(int flag)
4870Sstevel@tonic-gate {
4880Sstevel@tonic-gate switch (flag) {
4890Sstevel@tonic-gate case INCONSISTENT:
4900Sstevel@tonic-gate nlsmesg(MM_ERROR, "Inconsistent options");
4910Sstevel@tonic-gate break;
4920Sstevel@tonic-gate case MISSINGARG:
4930Sstevel@tonic-gate nlsmesg(MM_ERROR, "Missing argument");
4940Sstevel@tonic-gate break;
4950Sstevel@tonic-gate case USAGE:
4960Sstevel@tonic-gate break;
4970Sstevel@tonic-gate }
4980Sstevel@tonic-gate fprintf(stderr, umsg, Nlsname, Nlsname, Nlsname, Nlsname, Nlsname);
4990Sstevel@tonic-gate exit(NLS_CMD);
5000Sstevel@tonic-gate }
5010Sstevel@tonic-gate
5020Sstevel@tonic-gate
5030Sstevel@tonic-gate /*
5040Sstevel@tonic-gate * no_permission: print out error message and exit when the user needs to
5050Sstevel@tonic-gate * needs to be root and isn't.
5060Sstevel@tonic-gate */
5070Sstevel@tonic-gate
508*640Sbasabi void
no_permission(void)509*640Sbasabi no_permission(void)
5100Sstevel@tonic-gate {
5110Sstevel@tonic-gate nlsmesg(MM_ERROR, "Must be super user");
5120Sstevel@tonic-gate exit(NLS_PERM);
5130Sstevel@tonic-gate }
5140Sstevel@tonic-gate
5150Sstevel@tonic-gate /*
5160Sstevel@tonic-gate * nlsmesg: print out either an error or a warning message. severity must
5170Sstevel@tonic-gate * be either MM_ERROR or MM_WARNING. this routine will be converted
5180Sstevel@tonic-gate * to use the standard message format later.
5190Sstevel@tonic-gate */
5200Sstevel@tonic-gate
5210Sstevel@tonic-gate void
nlsmesg(int severity,char * text)522*640Sbasabi nlsmesg(int severity, char *text)
5230Sstevel@tonic-gate {
5240Sstevel@tonic-gate int class;
5250Sstevel@tonic-gate
5260Sstevel@tonic-gate if (severity == MM_ERROR)
5270Sstevel@tonic-gate fprintf(stderr, "%s: error: %s\n", Nlsname, text);
5280Sstevel@tonic-gate else
5290Sstevel@tonic-gate fprintf(stderr, "%s: warning: %s\n", Nlsname, text);
5300Sstevel@tonic-gate return;
5310Sstevel@tonic-gate }
5320Sstevel@tonic-gate
5330Sstevel@tonic-gate /*
5340Sstevel@tonic-gate * prt_cmd: print out the listener-dependent string for sacadm.
5350Sstevel@tonic-gate */
5360Sstevel@tonic-gate
537*640Sbasabi int
prt_cmd(char * path,long flags,char * modules,char * addr,char * rpcp)538*640Sbasabi prt_cmd(char *path, long flags, char *modules, char *addr, char *rpcp)
539*640Sbasabi /* path: full path of command or pipe */
540*640Sbasabi /* flags: listener flags */
541*640Sbasabi /* PFLAG for pipe */
542*640Sbasabi /* CFLAG for command */
543*640Sbasabi /* DFLAG for dynamic addr */
544*640Sbasabi /* modules: STREAMS modules to push */
545*640Sbasabi /* addr: private address */
546*640Sbasabi /* rpcp: RPC prog and ver # */
5470Sstevel@tonic-gate {
5480Sstevel@tonic-gate struct stat sbuf;
5490Sstevel@tonic-gate char mesgbuf[BUFSIZ];
5500Sstevel@tonic-gate char *tmp;
5510Sstevel@tonic-gate
5520Sstevel@tonic-gate if (*path != '/') {
5530Sstevel@tonic-gate nlsmesg(MM_ERROR, "Must specify full path name");
5540Sstevel@tonic-gate return(NLS_CMD);
5550Sstevel@tonic-gate }
5560Sstevel@tonic-gate
5570Sstevel@tonic-gate if ((tmp = strchr(path, ' ')) != NULL)
5580Sstevel@tonic-gate *tmp = NULL;
5590Sstevel@tonic-gate
5600Sstevel@tonic-gate if (stat(path, &sbuf) < 0) {
5610Sstevel@tonic-gate if (errno != EFAULT) {
5620Sstevel@tonic-gate sprintf(mesgbuf, "%s does not exist", path);
5630Sstevel@tonic-gate nlsmesg(MM_WARNING, mesgbuf);
5640Sstevel@tonic-gate }
5650Sstevel@tonic-gate else
5660Sstevel@tonic-gate return(NLS_SYSERR);
5670Sstevel@tonic-gate }
5680Sstevel@tonic-gate
5690Sstevel@tonic-gate if (tmp)
5700Sstevel@tonic-gate *tmp = ' ';
5710Sstevel@tonic-gate
5720Sstevel@tonic-gate printf("%s:%s:%s:%s:%s\n", (addr ? addr : ""), (rpcp ? rpcp : ""),
5730Sstevel@tonic-gate pflags(flags), (modules ? modules : ""), path);
5740Sstevel@tonic-gate return(NLS_OK);
5750Sstevel@tonic-gate }
5760Sstevel@tonic-gate
5770Sstevel@tonic-gate /*
5780Sstevel@tonic-gate * old_addsvc: use pmadm to add a service code to the listener. this will
5790Sstevel@tonic-gate * not allow specification of a private address -- use pmadm!
5800Sstevel@tonic-gate */
5810Sstevel@tonic-gate
582*640Sbasabi int
old_addsvc(char * svc,char * addr,char * cmd,char * com,char * module,char * id,char * flags,char * netspec)583*640Sbasabi old_addsvc(char *svc, char *addr, char *cmd, char *com, char *module,
584*640Sbasabi char *id, char *flags, char *netspec)
5850Sstevel@tonic-gate {
5860Sstevel@tonic-gate char buf[BUFSIZ];
5870Sstevel@tonic-gate char mesgbuf[BUFSIZ];
5880Sstevel@tonic-gate int rtn;
5890Sstevel@tonic-gate struct stat sbuf;
5900Sstevel@tonic-gate char *tmp;
5910Sstevel@tonic-gate
5920Sstevel@tonic-gate if (!svc || !cmd || !com || !netspec)
5930Sstevel@tonic-gate usage(MISSINGARG);
5940Sstevel@tonic-gate
5950Sstevel@tonic-gate /* create "port-monitor specific" info in the same way as prt_cmd */
5960Sstevel@tonic-gate
5970Sstevel@tonic-gate if (*cmd != '/') {
5980Sstevel@tonic-gate nlsmesg(MM_ERROR, "Must specify full path name");
5990Sstevel@tonic-gate return(NLS_CMD);
6000Sstevel@tonic-gate }
6010Sstevel@tonic-gate
6020Sstevel@tonic-gate if ((tmp = strchr(cmd, ' ')) != NULL)
6030Sstevel@tonic-gate *tmp = NULL;
6040Sstevel@tonic-gate
6050Sstevel@tonic-gate if (stat(cmd, &sbuf) < 0) {
6060Sstevel@tonic-gate if (errno != EFAULT) {
6070Sstevel@tonic-gate sprintf(mesgbuf, "%s does not exist", cmd);
6080Sstevel@tonic-gate nlsmesg(MM_WARNING, mesgbuf);
6090Sstevel@tonic-gate }
6100Sstevel@tonic-gate else
6110Sstevel@tonic-gate return(NLS_SYSERR);
6120Sstevel@tonic-gate }
6130Sstevel@tonic-gate
6140Sstevel@tonic-gate if (tmp)
6150Sstevel@tonic-gate *tmp = ' ';
6160Sstevel@tonic-gate
6170Sstevel@tonic-gate if (addr)
6180Sstevel@tonic-gate sprintf(mesgbuf, "'%s::c:%s:%s'", addr, module ? module : "" , cmd);
6190Sstevel@tonic-gate else
6200Sstevel@tonic-gate sprintf(mesgbuf, "'::c:%s:%s'", module ? module : "" , cmd);
6210Sstevel@tonic-gate
6220Sstevel@tonic-gate if (flags && *flags)
6230Sstevel@tonic-gate sprintf(buf, PM_ADDSVCF, netspec, svc, (id)?id:DEFAULTID, flags, mesgbuf, VERSION, com ? com : "");
6240Sstevel@tonic-gate else
6250Sstevel@tonic-gate sprintf(buf, PM_ADDSVC, netspec, svc, (id)?id:DEFAULTID, mesgbuf, VERSION, com ? com : "");
6260Sstevel@tonic-gate
6270Sstevel@tonic-gate if ((rtn = system(buf)) < 0) {
6280Sstevel@tonic-gate return(NLS_SYSERR);
6290Sstevel@tonic-gate }
6300Sstevel@tonic-gate rtn = (rtn>>8) & 0xff; /* get child return value out of exit word */
6310Sstevel@tonic-gate
6320Sstevel@tonic-gate switch (rtn) {
6330Sstevel@tonic-gate case 0:
6340Sstevel@tonic-gate return(NLS_OK);
6350Sstevel@tonic-gate break;
6360Sstevel@tonic-gate case E_BADARGS:
6370Sstevel@tonic-gate case E_SAFERR:
6380Sstevel@tonic-gate case E_SYSERR:
6390Sstevel@tonic-gate case E_NOEXIST:
6400Sstevel@tonic-gate case E_PMRUN:
6410Sstevel@tonic-gate case E_PMNOTRUN:
6420Sstevel@tonic-gate case E_RECOVER:
6430Sstevel@tonic-gate case E_SACNOTRUN:
6440Sstevel@tonic-gate default:
6450Sstevel@tonic-gate return(NLS_SYSERR);
6460Sstevel@tonic-gate break;
6470Sstevel@tonic-gate case E_DUP:
6480Sstevel@tonic-gate return(NLS_SERV);
6490Sstevel@tonic-gate break;
6500Sstevel@tonic-gate case E_NOPRIV:
6510Sstevel@tonic-gate no_permission();
6520Sstevel@tonic-gate break;
6530Sstevel@tonic-gate }
654*640Sbasabi /* NOTREACHED */
6550Sstevel@tonic-gate }
6560Sstevel@tonic-gate
6570Sstevel@tonic-gate /*
6580Sstevel@tonic-gate * prt_nets: print the status of one network, or all nets if netspec
6590Sstevel@tonic-gate * is NULL
6600Sstevel@tonic-gate */
661*640Sbasabi int
prt_nets(char * netspec)662*640Sbasabi prt_nets(char *netspec)
6630Sstevel@tonic-gate {
6640Sstevel@tonic-gate char buf[BUFSIZ];
6650Sstevel@tonic-gate FILE *fp;
6660Sstevel@tonic-gate char *name;
6670Sstevel@tonic-gate char *state;
6680Sstevel@tonic-gate char *type;
6690Sstevel@tonic-gate int found = FALSE;
6700Sstevel@tonic-gate int rtn = NLS_OK;
6710Sstevel@tonic-gate
6720Sstevel@tonic-gate if (netspec == NULL)
6730Sstevel@tonic-gate sprintf(buf, SAC_LSTY, LISTENTYPE);
6740Sstevel@tonic-gate else
6750Sstevel@tonic-gate sprintf(buf, SAC_LSPM, netspec);
6760Sstevel@tonic-gate
6770Sstevel@tonic-gate if ((fp = popen(buf, "r")) == NULL)
6780Sstevel@tonic-gate return(NLS_SYSERR);
6790Sstevel@tonic-gate
6800Sstevel@tonic-gate while (fgets(buf, BUFSIZ, fp) != NULL) {
6810Sstevel@tonic-gate if ((name = nexttok(buf, ":")) == NULL)
6820Sstevel@tonic-gate return(NLS_SYSERR);
6830Sstevel@tonic-gate if ((type = nexttok(NULL, ":")) == NULL)
6840Sstevel@tonic-gate return(NLS_SYSERR);
6850Sstevel@tonic-gate
6860Sstevel@tonic-gate if (strcmp(type, LISTENTYPE) != 0)
6870Sstevel@tonic-gate continue; /* ignore other types of port monitors */
6880Sstevel@tonic-gate
6890Sstevel@tonic-gate found = TRUE;
6900Sstevel@tonic-gate if (nexttok(NULL, ":") == NULL)
6910Sstevel@tonic-gate return(NLS_SYSERR);
6920Sstevel@tonic-gate if (nexttok(NULL, ":") == NULL)
6930Sstevel@tonic-gate return(NLS_SYSERR);
6940Sstevel@tonic-gate if ((state = nexttok(NULL, ":")) == NULL)
6950Sstevel@tonic-gate return(NLS_SYSERR);
6960Sstevel@tonic-gate if (strcmp(state, "ENABLED") == NULL ||
6970Sstevel@tonic-gate strcmp(state, "STARTING") == NULL) {
6980Sstevel@tonic-gate rtn = QZERO;
6990Sstevel@tonic-gate if (!Quietflag)
7000Sstevel@tonic-gate printf("%s\t%s\n", name, "ACTIVE");
7010Sstevel@tonic-gate }
7020Sstevel@tonic-gate else {
7030Sstevel@tonic-gate rtn = QONE;
7040Sstevel@tonic-gate if (!Quietflag)
7050Sstevel@tonic-gate printf("%s\t%s\n", name, "INACTIVE");
7060Sstevel@tonic-gate }
7070Sstevel@tonic-gate }
7080Sstevel@tonic-gate pclose(fp);
7090Sstevel@tonic-gate
7100Sstevel@tonic-gate if (netspec && !found) {
7110Sstevel@tonic-gate nlsmesg(MM_ERROR, "Invalid network specification");
7120Sstevel@tonic-gate return(NLS_BADPM);
7130Sstevel@tonic-gate }
7140Sstevel@tonic-gate
7150Sstevel@tonic-gate if (netspec)
7160Sstevel@tonic-gate return(rtn);
7170Sstevel@tonic-gate else
7180Sstevel@tonic-gate return(NLS_OK);
7190Sstevel@tonic-gate
7200Sstevel@tonic-gate }
7210Sstevel@tonic-gate
7220Sstevel@tonic-gate
7230Sstevel@tonic-gate /*
7240Sstevel@tonic-gate * print info about service on netspec, or all services on netspec
7250Sstevel@tonic-gate * if svc is NULL
7260Sstevel@tonic-gate */
7270Sstevel@tonic-gate
728*640Sbasabi int
prt_svcs(char * svc,char * netspec)729*640Sbasabi prt_svcs(char *svc, char *netspec)
7300Sstevel@tonic-gate {
7310Sstevel@tonic-gate char buf[BUFSIZ];
7320Sstevel@tonic-gate char mesg[BUFSIZ];
7330Sstevel@tonic-gate FILE *fp;
7340Sstevel@tonic-gate struct svcfields entry;
7350Sstevel@tonic-gate int rtn;
7360Sstevel@tonic-gate int found = FALSE;
7370Sstevel@tonic-gate char *p;
7380Sstevel@tonic-gate
7390Sstevel@tonic-gate if (svc == NULL)
7400Sstevel@tonic-gate sprintf(buf, PM_LSALL, netspec);
7410Sstevel@tonic-gate else
7420Sstevel@tonic-gate sprintf(buf, PM_LSONE, netspec, svc);
7430Sstevel@tonic-gate
7440Sstevel@tonic-gate if ((fp = popen(buf, "r")) == NULL)
7450Sstevel@tonic-gate return(NLS_SYSERR);
7460Sstevel@tonic-gate
7470Sstevel@tonic-gate while (fgets(buf, BUFSIZ, fp) != NULL) {
7480Sstevel@tonic-gate if ((rtn = svc_format(buf, &entry)) != 0) {
7490Sstevel@tonic-gate switch (rtn) {
7500Sstevel@tonic-gate case NOTLISTEN:
7510Sstevel@tonic-gate continue;
7520Sstevel@tonic-gate break;
7530Sstevel@tonic-gate case BADPMFMT:
7540Sstevel@tonic-gate return(NLS_SYSERR);
7550Sstevel@tonic-gate break;
7560Sstevel@tonic-gate case BADLISFMT:
7570Sstevel@tonic-gate sprintf(mesg, "Entry for code \"%s\" has incorrect format", entry.svc_code);
7580Sstevel@tonic-gate nlsmesg(MM_WARNING, mesg);
7590Sstevel@tonic-gate continue;
7600Sstevel@tonic-gate break;
7610Sstevel@tonic-gate }
7620Sstevel@tonic-gate }
7630Sstevel@tonic-gate found = TRUE;
7640Sstevel@tonic-gate
7650Sstevel@tonic-gate if (!Quietflag) {
7660Sstevel@tonic-gate printf("%s\t", entry.svc_code);
7670Sstevel@tonic-gate if (*entry.addr)
7680Sstevel@tonic-gate printf("%s\t", entry.addr);
7690Sstevel@tonic-gate else if (strchr(entry.lflags, 'd'))
7700Sstevel@tonic-gate printf("DYNAMIC\t");
7710Sstevel@tonic-gate else
7720Sstevel@tonic-gate printf("NOADDR\t");
7730Sstevel@tonic-gate
7740Sstevel@tonic-gate if (strchr(entry.flags, 'x') == NULL)
7750Sstevel@tonic-gate printf("ENABLED \t");
7760Sstevel@tonic-gate else
7770Sstevel@tonic-gate printf("DISABLED\t");
7780Sstevel@tonic-gate
7790Sstevel@tonic-gate
7800Sstevel@tonic-gate printf("%s\t%s\t%s\t%s\t# %s",
7810Sstevel@tonic-gate (*entry.rpc)?entry.rpc:"NORPC", entry.id,
7820Sstevel@tonic-gate (*entry.modules)?entry.modules:"NOMODULES",
7830Sstevel@tonic-gate entry.command, (*entry.comment)?entry.comment:"");
7840Sstevel@tonic-gate }
7850Sstevel@tonic-gate else {
7860Sstevel@tonic-gate if (strchr(entry.flags, 'x') == NULL)
7870Sstevel@tonic-gate return(QZERO);
7880Sstevel@tonic-gate else
7890Sstevel@tonic-gate return(QONE);
7900Sstevel@tonic-gate }
7910Sstevel@tonic-gate }
7920Sstevel@tonic-gate
7930Sstevel@tonic-gate pclose(fp);
7940Sstevel@tonic-gate
7950Sstevel@tonic-gate if (rtn == NOTLISTEN) { /* check last return to see if error */
7960Sstevel@tonic-gate sprintf(mesg, "Network specification \"%s\" is not of type %s", netspec, LISTENTYPE);
7970Sstevel@tonic-gate nlsmesg(MM_ERROR, mesg);
7980Sstevel@tonic-gate return(NLS_BADPM);
7990Sstevel@tonic-gate }
8000Sstevel@tonic-gate if (svc && !found) {
8010Sstevel@tonic-gate if (!Quietflag) {
8020Sstevel@tonic-gate sprintf(mesg, "Service \"%s\" unknown", svc);
8030Sstevel@tonic-gate nlsmesg(MM_ERROR, mesg);
8040Sstevel@tonic-gate }
8050Sstevel@tonic-gate return(NLS_SERV);
8060Sstevel@tonic-gate }
8070Sstevel@tonic-gate
8080Sstevel@tonic-gate return(NLS_OK);
8090Sstevel@tonic-gate }
8100Sstevel@tonic-gate
8110Sstevel@tonic-gate /*
8120Sstevel@tonic-gate * disable_svc: use pmadm to disable a service
8130Sstevel@tonic-gate */
8140Sstevel@tonic-gate
815*640Sbasabi int
disable_svc(char * svc,char * netspec)816*640Sbasabi disable_svc(char *svc, char *netspec)
8170Sstevel@tonic-gate {
8180Sstevel@tonic-gate char buf[BUFSIZ];
8190Sstevel@tonic-gate int rtn;
8200Sstevel@tonic-gate
8210Sstevel@tonic-gate sprintf(buf, PM_DISABLE, netspec, svc);
8220Sstevel@tonic-gate
8230Sstevel@tonic-gate if ((rtn = system(buf)) < 0) {
8240Sstevel@tonic-gate return(NLS_SYSERR);
8250Sstevel@tonic-gate }
8260Sstevel@tonic-gate rtn = (rtn>>8) & 0xff; /* get child return value out of exit word */
8270Sstevel@tonic-gate
8280Sstevel@tonic-gate switch (rtn) {
8290Sstevel@tonic-gate case 0:
8300Sstevel@tonic-gate return(NLS_OK);
8310Sstevel@tonic-gate break;
8320Sstevel@tonic-gate case E_BADARGS:
8330Sstevel@tonic-gate case E_SAFERR:
8340Sstevel@tonic-gate case E_SYSERR:
8350Sstevel@tonic-gate case E_PMRUN:
8360Sstevel@tonic-gate case E_PMNOTRUN:
8370Sstevel@tonic-gate case E_RECOVER:
8380Sstevel@tonic-gate case E_SACNOTRUN:
8390Sstevel@tonic-gate default:
8400Sstevel@tonic-gate return(NLS_SYSERR);
8410Sstevel@tonic-gate break;
8420Sstevel@tonic-gate case E_NOEXIST:
8430Sstevel@tonic-gate case E_DUP:
8440Sstevel@tonic-gate nlsmesg(MM_ERROR, "Non-existent service.");
8450Sstevel@tonic-gate return(NLS_SERV);
8460Sstevel@tonic-gate break;
8470Sstevel@tonic-gate case E_NOPRIV:
8480Sstevel@tonic-gate no_permission();
8490Sstevel@tonic-gate break;
8500Sstevel@tonic-gate }
851*640Sbasabi /* NOTREACHED */
8520Sstevel@tonic-gate }
8530Sstevel@tonic-gate
8540Sstevel@tonic-gate
855*640Sbasabi int
enable_svc(char * svc,char * netspec)856*640Sbasabi enable_svc(char *svc, char *netspec)
8570Sstevel@tonic-gate {
8580Sstevel@tonic-gate char buf[BUFSIZ];
8590Sstevel@tonic-gate int rtn;
8600Sstevel@tonic-gate
8610Sstevel@tonic-gate sprintf(buf, PM_ENABLE, netspec, svc);
8620Sstevel@tonic-gate
8630Sstevel@tonic-gate if ((rtn = system(buf)) < 0) {
8640Sstevel@tonic-gate return(NLS_SYSERR);
8650Sstevel@tonic-gate }
8660Sstevel@tonic-gate rtn = (rtn>>8) & 0xff; /* get child return value out of exit word */
8670Sstevel@tonic-gate
8680Sstevel@tonic-gate switch (rtn) {
8690Sstevel@tonic-gate case 0:
8700Sstevel@tonic-gate return(NLS_OK);
8710Sstevel@tonic-gate break;
8720Sstevel@tonic-gate case E_BADARGS:
8730Sstevel@tonic-gate case E_SAFERR:
8740Sstevel@tonic-gate case E_SYSERR:
8750Sstevel@tonic-gate case E_PMRUN:
8760Sstevel@tonic-gate case E_PMNOTRUN:
8770Sstevel@tonic-gate case E_RECOVER:
8780Sstevel@tonic-gate case E_SACNOTRUN:
8790Sstevel@tonic-gate default:
8800Sstevel@tonic-gate return(NLS_SYSERR);
8810Sstevel@tonic-gate break;
8820Sstevel@tonic-gate case E_NOEXIST:
8830Sstevel@tonic-gate case E_DUP:
8840Sstevel@tonic-gate nlsmesg(MM_ERROR, "Non-existent service.");
8850Sstevel@tonic-gate return(NLS_SERV);
8860Sstevel@tonic-gate break;
8870Sstevel@tonic-gate case E_NOPRIV:
8880Sstevel@tonic-gate no_permission();
8890Sstevel@tonic-gate break;
8900Sstevel@tonic-gate }
891*640Sbasabi /* NOTREACHED */
8920Sstevel@tonic-gate }
8930Sstevel@tonic-gate
8940Sstevel@tonic-gate
895*640Sbasabi int
remove_svc(char * svc,char * netspec,int printerrors)896*640Sbasabi remove_svc(char *svc, char *netspec, int printerrors)
8970Sstevel@tonic-gate {
8980Sstevel@tonic-gate char buf[BUFSIZ];
8990Sstevel@tonic-gate int rtn;
9000Sstevel@tonic-gate
9010Sstevel@tonic-gate sprintf(buf, PM_REMSVC, netspec, svc);
9020Sstevel@tonic-gate
9030Sstevel@tonic-gate if ((rtn = system(buf)) < 0) {
9040Sstevel@tonic-gate return(NLS_SYSERR);
9050Sstevel@tonic-gate }
9060Sstevel@tonic-gate rtn = (rtn>>8) & 0xff; /* get child return value out of exit word */
9070Sstevel@tonic-gate
9080Sstevel@tonic-gate switch (rtn) {
9090Sstevel@tonic-gate case 0:
9100Sstevel@tonic-gate return(NLS_OK);
9110Sstevel@tonic-gate break;
9120Sstevel@tonic-gate case E_BADARGS:
9130Sstevel@tonic-gate case E_SAFERR:
9140Sstevel@tonic-gate case E_SYSERR:
9150Sstevel@tonic-gate case E_PMRUN:
9160Sstevel@tonic-gate case E_PMNOTRUN:
9170Sstevel@tonic-gate case E_RECOVER:
9180Sstevel@tonic-gate case E_SACNOTRUN:
9190Sstevel@tonic-gate default:
9200Sstevel@tonic-gate return(NLS_SYSERR);
9210Sstevel@tonic-gate break;
9220Sstevel@tonic-gate case E_NOEXIST:
9230Sstevel@tonic-gate case E_DUP:
9240Sstevel@tonic-gate if (printerrors)
9250Sstevel@tonic-gate nlsmesg(MM_ERROR, "Non-existent service.");
9260Sstevel@tonic-gate return(NLS_SERV);
9270Sstevel@tonic-gate break;
9280Sstevel@tonic-gate case E_NOPRIV:
9290Sstevel@tonic-gate no_permission();
9300Sstevel@tonic-gate break;
9310Sstevel@tonic-gate }
932*640Sbasabi /* NOTREACHED */
9330Sstevel@tonic-gate }
9340Sstevel@tonic-gate
9350Sstevel@tonic-gate
936*640Sbasabi int
kill_listener(char * netspec)937*640Sbasabi kill_listener(char *netspec)
9380Sstevel@tonic-gate {
9390Sstevel@tonic-gate char buf[BUFSIZ];
9400Sstevel@tonic-gate char mesg[BUFSIZ];
9410Sstevel@tonic-gate int rtn;
9420Sstevel@tonic-gate
9430Sstevel@tonic-gate sprintf(buf, SAC_KILLPM, netspec);
9440Sstevel@tonic-gate
9450Sstevel@tonic-gate if ((rtn = system(buf)) < 0) {
9460Sstevel@tonic-gate return(NLS_SYSERR);
9470Sstevel@tonic-gate }
9480Sstevel@tonic-gate rtn = (rtn>>8) & 0xff; /* get child return value out of exit word */
9490Sstevel@tonic-gate
9500Sstevel@tonic-gate switch (rtn) {
9510Sstevel@tonic-gate case 0:
9520Sstevel@tonic-gate return(NLS_OK);
9530Sstevel@tonic-gate break;
9540Sstevel@tonic-gate case E_BADARGS:
9550Sstevel@tonic-gate case E_DUP:
9560Sstevel@tonic-gate case E_SAFERR:
9570Sstevel@tonic-gate case E_SYSERR:
9580Sstevel@tonic-gate case E_PMRUN:
9590Sstevel@tonic-gate case E_RECOVER:
9600Sstevel@tonic-gate case E_SACNOTRUN:
9610Sstevel@tonic-gate default:
9620Sstevel@tonic-gate return(NLS_SYSERR);
9630Sstevel@tonic-gate break;
9640Sstevel@tonic-gate case E_PMNOTRUN:
9650Sstevel@tonic-gate sprintf(mesg, "No listener active on network \"%s\"", netspec);
9660Sstevel@tonic-gate nlsmesg(MM_ERROR, mesg);
9670Sstevel@tonic-gate return(NLS_FAILED);
9680Sstevel@tonic-gate case E_NOEXIST:
9690Sstevel@tonic-gate nlsmesg(MM_ERROR, "Non-existent port monitor.");
9700Sstevel@tonic-gate return(NLS_SERV);
9710Sstevel@tonic-gate break;
9720Sstevel@tonic-gate case E_NOPRIV:
9730Sstevel@tonic-gate no_permission();
9740Sstevel@tonic-gate break;
9750Sstevel@tonic-gate }
976*640Sbasabi /* NOTREACHED */
9770Sstevel@tonic-gate }
9780Sstevel@tonic-gate
9790Sstevel@tonic-gate
9800Sstevel@tonic-gate /*
9810Sstevel@tonic-gate * add_pm: add a port monitor (initialize directories) using sacadm
9820Sstevel@tonic-gate */
9830Sstevel@tonic-gate
984*640Sbasabi int
add_pm(char * netspec)985*640Sbasabi add_pm(char *netspec)
9860Sstevel@tonic-gate {
9870Sstevel@tonic-gate char buf[BUFSIZ];
9880Sstevel@tonic-gate char mesg[BUFSIZ];
9890Sstevel@tonic-gate int rtn;
9900Sstevel@tonic-gate
9910Sstevel@tonic-gate sprintf(buf, SAC_ADDPM, netspec, LISTENTYPE, gencmdstr(netspec), VERSION);
9920Sstevel@tonic-gate
9930Sstevel@tonic-gate if ((rtn = system(buf)) < 0) {
9940Sstevel@tonic-gate return(NLS_SYSERR);
9950Sstevel@tonic-gate }
9960Sstevel@tonic-gate rtn = (rtn>>8) & 0xff; /* get child return value out of exit word */
9970Sstevel@tonic-gate
9980Sstevel@tonic-gate switch (rtn) {
9990Sstevel@tonic-gate case 0:
10000Sstevel@tonic-gate old_addsvc(NLPSSVCCODE, NULL, NLPSSRV, "NLPS server", "", "root", NULL, netspec);
10010Sstevel@tonic-gate return(NLS_OK);
10020Sstevel@tonic-gate break;
10030Sstevel@tonic-gate case E_BADARGS:
10040Sstevel@tonic-gate case E_SAFERR:
10050Sstevel@tonic-gate case E_SYSERR:
10060Sstevel@tonic-gate case E_RECOVER:
10070Sstevel@tonic-gate case E_NOEXIST:
10080Sstevel@tonic-gate case E_PMNOTRUN:
10090Sstevel@tonic-gate case E_SACNOTRUN:
10100Sstevel@tonic-gate default:
10110Sstevel@tonic-gate return(NLS_SYSERR);
10120Sstevel@tonic-gate break;
10130Sstevel@tonic-gate case E_DUP:
10140Sstevel@tonic-gate case E_PMRUN:
10150Sstevel@tonic-gate nlsmesg(MM_ERROR, "Listener already initialized");
10160Sstevel@tonic-gate return(NLS_FAILED);
10170Sstevel@tonic-gate break;
10180Sstevel@tonic-gate case E_NOPRIV:
10190Sstevel@tonic-gate no_permission();
10200Sstevel@tonic-gate break;
10210Sstevel@tonic-gate }
1022*640Sbasabi /* NOTREACHED */
10230Sstevel@tonic-gate }
10240Sstevel@tonic-gate
10250Sstevel@tonic-gate
10260Sstevel@tonic-gate /*
10270Sstevel@tonic-gate * gencmdstr: generate the correct string to invoke the listener (starlan
10280Sstevel@tonic-gate * requires special handling)
10290Sstevel@tonic-gate */
10300Sstevel@tonic-gate
10310Sstevel@tonic-gate char *
gencmdstr(char * netspec)1032*640Sbasabi gencmdstr(char *netspec)
10330Sstevel@tonic-gate {
10340Sstevel@tonic-gate static char buf[BUFSIZ];
10350Sstevel@tonic-gate
10360Sstevel@tonic-gate (void) strcpy(buf, LISTENCMD);
10370Sstevel@tonic-gate if (!strcmp(netspec, "starlan"))
10380Sstevel@tonic-gate (void) strcat(buf, " -m slan");
10390Sstevel@tonic-gate (void) strcat(buf, " ");
10400Sstevel@tonic-gate (void) strcat(buf, netspec);
10410Sstevel@tonic-gate return(buf);
10420Sstevel@tonic-gate }
10430Sstevel@tonic-gate
10440Sstevel@tonic-gate
10450Sstevel@tonic-gate /*
10460Sstevel@tonic-gate * start_listener: start the listener
10470Sstevel@tonic-gate */
10480Sstevel@tonic-gate
1049*640Sbasabi int
start_listener(char * netspec)1050*640Sbasabi start_listener(char *netspec)
10510Sstevel@tonic-gate {
10520Sstevel@tonic-gate char buf[BUFSIZ];
10530Sstevel@tonic-gate char scratch[BUFSIZ];
10540Sstevel@tonic-gate int rtn;
10550Sstevel@tonic-gate
10560Sstevel@tonic-gate sprintf(buf, SAC_STARTPM, netspec);
10570Sstevel@tonic-gate
10580Sstevel@tonic-gate if ((rtn = system(buf)) < 0)
10590Sstevel@tonic-gate return(NLS_SYSERR);
10600Sstevel@tonic-gate rtn = (rtn>>8) & 0xff;
10610Sstevel@tonic-gate switch (rtn) {
10620Sstevel@tonic-gate case 0:
10630Sstevel@tonic-gate break;
10640Sstevel@tonic-gate case E_BADARGS:
10650Sstevel@tonic-gate case E_SAFERR:
10660Sstevel@tonic-gate case E_SYSERR:
10670Sstevel@tonic-gate case E_RECOVER:
10680Sstevel@tonic-gate case E_PMNOTRUN:
10690Sstevel@tonic-gate case E_SACNOTRUN:
10700Sstevel@tonic-gate default:
10710Sstevel@tonic-gate return(NLS_SYSERR);
10720Sstevel@tonic-gate break;
10730Sstevel@tonic-gate case E_NOEXIST:
10740Sstevel@tonic-gate case E_DUP:
10750Sstevel@tonic-gate nlsmesg(MM_ERROR, "Non-existent port monitor.");
10760Sstevel@tonic-gate return(NLS_BADPM);
10770Sstevel@tonic-gate break;
10780Sstevel@tonic-gate case E_PMRUN:
10790Sstevel@tonic-gate nlsmesg(MM_ERROR, "Listener already running");
10800Sstevel@tonic-gate return(NLS_FAILED);
10810Sstevel@tonic-gate case E_NOPRIV:
10820Sstevel@tonic-gate no_permission();
10830Sstevel@tonic-gate break;
10840Sstevel@tonic-gate }
10850Sstevel@tonic-gate
10860Sstevel@tonic-gate sprintf(buf, SAC_ENABLPM, netspec);
10870Sstevel@tonic-gate
10880Sstevel@tonic-gate if ((rtn = system(buf)) < 0) {
10890Sstevel@tonic-gate return(NLS_SYSERR);
10900Sstevel@tonic-gate }
10910Sstevel@tonic-gate rtn = (rtn>>8) & 0xff;
10920Sstevel@tonic-gate switch (rtn) {
10930Sstevel@tonic-gate case 0:
10940Sstevel@tonic-gate return(NLS_OK);
10950Sstevel@tonic-gate break;
10960Sstevel@tonic-gate case E_BADARGS:
10970Sstevel@tonic-gate case E_SAFERR:
10980Sstevel@tonic-gate case E_SYSERR:
10990Sstevel@tonic-gate case E_RECOVER:
11000Sstevel@tonic-gate case E_SACNOTRUN:
11010Sstevel@tonic-gate default:
11020Sstevel@tonic-gate return(NLS_SYSERR);
11030Sstevel@tonic-gate break;
11040Sstevel@tonic-gate case E_NOEXIST:
11050Sstevel@tonic-gate case E_DUP:
11060Sstevel@tonic-gate nlsmesg(MM_ERROR, "Non-existent port monitor.");
11070Sstevel@tonic-gate return(NLS_BADPM);
11080Sstevel@tonic-gate break;
11090Sstevel@tonic-gate case E_PMRUN:
11100Sstevel@tonic-gate nlsmesg(MM_ERROR, "Listener already running");
11110Sstevel@tonic-gate return(NLS_FAILED);
11120Sstevel@tonic-gate case E_PMNOTRUN:
11130Sstevel@tonic-gate nlsmesg(MM_ERROR, "Listener start failed");
11140Sstevel@tonic-gate return(NLS_FAILED);
11150Sstevel@tonic-gate case E_NOPRIV:
11160Sstevel@tonic-gate no_permission();
11170Sstevel@tonic-gate break;
11180Sstevel@tonic-gate }
1119*640Sbasabi /* NOTREACHED */
11200Sstevel@tonic-gate }
11210Sstevel@tonic-gate
11220Sstevel@tonic-gate
11230Sstevel@tonic-gate /*
11240Sstevel@tonic-gate * setup_addr: setup the -l and -t addresses.
11250Sstevel@tonic-gate */
11260Sstevel@tonic-gate
1127*640Sbasabi int
setup_addr(char * laddr,char * taddr,char * netspec)1128*640Sbasabi setup_addr(char *laddr, char *taddr, char *netspec)
11290Sstevel@tonic-gate {
11300Sstevel@tonic-gate char buf[BUFSIZ];
11310Sstevel@tonic-gate char mesg[BUFSIZ];
11320Sstevel@tonic-gate char *p;
11330Sstevel@tonic-gate int rtn;
11340Sstevel@tonic-gate int qlisten = FALSE;
11350Sstevel@tonic-gate int qtty = FALSE;
11360Sstevel@tonic-gate FILE *fp;
11370Sstevel@tonic-gate struct svcfields entry;
11380Sstevel@tonic-gate
11390Sstevel@tonic-gate if (laddr && *laddr == '-')
11400Sstevel@tonic-gate qlisten = TRUE;
11410Sstevel@tonic-gate
11420Sstevel@tonic-gate if (taddr && *taddr == '-')
11430Sstevel@tonic-gate qtty = TRUE;
11440Sstevel@tonic-gate
11450Sstevel@tonic-gate if (laddr) {
11460Sstevel@tonic-gate sprintf(buf, PM_LSONE, netspec, NLPSSVCCODE);
11470Sstevel@tonic-gate
11480Sstevel@tonic-gate if ((fp = popen(buf, "r")) == NULL) {
11490Sstevel@tonic-gate return(NLS_SYSERR);
11500Sstevel@tonic-gate }
11510Sstevel@tonic-gate
11520Sstevel@tonic-gate if (fgets(buf, BUFSIZ, fp) != NULL) {
11530Sstevel@tonic-gate if ((rtn = svc_format(buf, &entry)) != 0) {
11540Sstevel@tonic-gate switch (rtn) {
11550Sstevel@tonic-gate case NOTLISTEN:
11560Sstevel@tonic-gate nlsmesg(MM_ERROR, "Incorrect port monitor type. Must be of type listen");
11570Sstevel@tonic-gate return(NLS_FAILED);
11580Sstevel@tonic-gate break;
11590Sstevel@tonic-gate case BADPMFMT:
11600Sstevel@tonic-gate return(NLS_SYSERR);
11610Sstevel@tonic-gate break;
11620Sstevel@tonic-gate case BADLISFMT:
11630Sstevel@tonic-gate sprintf(mesg, "Entry for code \"%s\" has incorrect format", entry.svc_code);
11640Sstevel@tonic-gate nlsmesg(MM_WARNING, mesg);
11650Sstevel@tonic-gate break;
11660Sstevel@tonic-gate }
11670Sstevel@tonic-gate }
11680Sstevel@tonic-gate else {
11690Sstevel@tonic-gate if (qlisten)
11700Sstevel@tonic-gate printf("%s\n", entry.addr);
11710Sstevel@tonic-gate else {
11720Sstevel@tonic-gate if (geteuid() != ROOT)
11730Sstevel@tonic-gate no_permission();
11740Sstevel@tonic-gate /* add address */
11750Sstevel@tonic-gate remove_svc(NLPSSVCCODE, netspec, FALSE);
11760Sstevel@tonic-gate p = strchr(entry.comment, '\n');
11770Sstevel@tonic-gate if (p)
11780Sstevel@tonic-gate *p = '\0';
11790Sstevel@tonic-gate old_addsvc(NLPSSVCCODE, laddr, entry.command, entry.comment, entry.modules, entry.id, entry.flags, netspec);
11800Sstevel@tonic-gate }
11810Sstevel@tonic-gate }
11820Sstevel@tonic-gate pclose(fp);
11830Sstevel@tonic-gate }
11840Sstevel@tonic-gate else if (!qlisten)
11850Sstevel@tonic-gate nlsmesg(MM_WARNING, "NLPS service not defined");
11860Sstevel@tonic-gate }
11870Sstevel@tonic-gate if (taddr) {
11880Sstevel@tonic-gate sprintf(buf, PM_LSONE, netspec, TTYSVCCODE);
11890Sstevel@tonic-gate
11900Sstevel@tonic-gate if ((fp = popen(buf, "r")) == NULL) {
11910Sstevel@tonic-gate return(NLS_SYSERR);
11920Sstevel@tonic-gate }
11930Sstevel@tonic-gate
11940Sstevel@tonic-gate if (fgets(buf, BUFSIZ, fp) != NULL) {
11950Sstevel@tonic-gate if ((rtn = svc_format(buf, &entry)) != 0) {
11960Sstevel@tonic-gate switch (rtn) {
11970Sstevel@tonic-gate case NOTLISTEN:
11980Sstevel@tonic-gate nlsmesg(MM_ERROR, "Incorrect port monitor type. Must be of type listen");
11990Sstevel@tonic-gate return(NLS_FAILED);
12000Sstevel@tonic-gate break;
12010Sstevel@tonic-gate case BADPMFMT:
12020Sstevel@tonic-gate return(NLS_SYSERR);
12030Sstevel@tonic-gate break;
12040Sstevel@tonic-gate case BADLISFMT:
12050Sstevel@tonic-gate sprintf(mesg, "Entry for code \"%s\" has incorrect format", entry.svc_code);
12060Sstevel@tonic-gate nlsmesg(MM_WARNING, mesg);
12070Sstevel@tonic-gate break;
12080Sstevel@tonic-gate }
12090Sstevel@tonic-gate }
12100Sstevel@tonic-gate else {
12110Sstevel@tonic-gate if (qtty)
12120Sstevel@tonic-gate printf("%s\n", entry.addr);
12130Sstevel@tonic-gate else {
12140Sstevel@tonic-gate if (geteuid() != ROOT)
12150Sstevel@tonic-gate no_permission();
12160Sstevel@tonic-gate /* add address */
12170Sstevel@tonic-gate remove_svc(TTYSVCCODE, netspec, FALSE);
12180Sstevel@tonic-gate p = strchr(entry.comment, '\n');
12190Sstevel@tonic-gate if (p)
12200Sstevel@tonic-gate *p = '\0';
12210Sstevel@tonic-gate old_addsvc(TTYSVCCODE, taddr, entry.command, entry.comment, entry.modules, entry.id, entry.flags, netspec);
12220Sstevel@tonic-gate }
12230Sstevel@tonic-gate }
12240Sstevel@tonic-gate pclose(fp);
12250Sstevel@tonic-gate }
12260Sstevel@tonic-gate else if (!qtty)
12270Sstevel@tonic-gate nlsmesg(MM_WARNING, "remote login service not defined");
12280Sstevel@tonic-gate }
12290Sstevel@tonic-gate return(NLS_OK);
12300Sstevel@tonic-gate }
12310Sstevel@tonic-gate
12320Sstevel@tonic-gate
12330Sstevel@tonic-gate /*
12340Sstevel@tonic-gate * svc_format: scan a line of output from pmadm to separate it into fields.
12350Sstevel@tonic-gate * returns BADPMFMT for missing fields or incorrect syntax.
12360Sstevel@tonic-gate * NOTLISTEN is the port monitor type is not listen.
12370Sstevel@tonic-gate * BADLISFMT if the listener-specific data is incorrect.
12380Sstevel@tonic-gate * NLS_OK if everything checked out and data is broken
12390Sstevel@tonic-gate * into the structure.
12400Sstevel@tonic-gate */
12410Sstevel@tonic-gate
1242*640Sbasabi int
svc_format(char * buf,struct svcfields * entry)1243*640Sbasabi svc_format(char *buf, struct svcfields *entry)
12440Sstevel@tonic-gate {
12450Sstevel@tonic-gate char *ptr; /* temporary pointer into buffer */
12460Sstevel@tonic-gate char *tmp; /* temporary pointer into buffer */
12470Sstevel@tonic-gate
12480Sstevel@tonic-gate entry->pmtag = buf;
12490Sstevel@tonic-gate if ((ptr = strchr(buf, ':')) == NULL)
12500Sstevel@tonic-gate return(BADPMFMT);
12510Sstevel@tonic-gate *ptr++ = NULL;
12520Sstevel@tonic-gate entry->pmtype = ptr;
12530Sstevel@tonic-gate if ((ptr = strchr(entry->pmtype, ':')) == NULL)
12540Sstevel@tonic-gate return(BADPMFMT);
12550Sstevel@tonic-gate *ptr++ = NULL;
12560Sstevel@tonic-gate entry->svc_code = ptr;
12570Sstevel@tonic-gate
12580Sstevel@tonic-gate if (strcmp(entry->pmtype, LISTENTYPE) != 0)
12590Sstevel@tonic-gate return(NOTLISTEN);
12600Sstevel@tonic-gate
12610Sstevel@tonic-gate if ((ptr = strchr(entry->svc_code, ':')) == NULL)
12620Sstevel@tonic-gate return(BADPMFMT);
12630Sstevel@tonic-gate *ptr++ = NULL;
12640Sstevel@tonic-gate entry->flags = ptr;
12650Sstevel@tonic-gate if ((ptr = strchr(entry->flags, ':')) == NULL)
12660Sstevel@tonic-gate return(BADPMFMT);
12670Sstevel@tonic-gate *ptr++ = NULL;
12680Sstevel@tonic-gate entry->id = ptr;
12690Sstevel@tonic-gate if ((ptr = strchr(entry->id, ':')) == NULL)
12700Sstevel@tonic-gate return(BADPMFMT);
12710Sstevel@tonic-gate *ptr++ = NULL;
12720Sstevel@tonic-gate entry->res1 = ptr;
12730Sstevel@tonic-gate if ((ptr = strchr(entry->res1, ':')) == NULL)
12740Sstevel@tonic-gate return(BADPMFMT);
12750Sstevel@tonic-gate *ptr++ = NULL;
12760Sstevel@tonic-gate entry->res2 = ptr;
12770Sstevel@tonic-gate if ((ptr = strchr(entry->res2, ':')) == NULL)
12780Sstevel@tonic-gate return(BADPMFMT);
12790Sstevel@tonic-gate *ptr++ = NULL;
12800Sstevel@tonic-gate entry->res3 = ptr;
12810Sstevel@tonic-gate if ((ptr = strchr(entry->res3, ':')) == NULL)
12820Sstevel@tonic-gate return(BADPMFMT);
12830Sstevel@tonic-gate *ptr++ = NULL;
12840Sstevel@tonic-gate entry->addr = ptr;
12850Sstevel@tonic-gate if ((ptr = strchr(entry->addr, ':')) == NULL)
12860Sstevel@tonic-gate return(BADLISFMT);
12870Sstevel@tonic-gate *ptr++ = NULL;
12880Sstevel@tonic-gate entry->rpc = ptr;
12890Sstevel@tonic-gate if ((ptr = strchr(entry->rpc, ':')) == NULL)
12900Sstevel@tonic-gate return(BADLISFMT);
12910Sstevel@tonic-gate *ptr++ = NULL;
12920Sstevel@tonic-gate if (*entry->rpc) {
12930Sstevel@tonic-gate if ((tmp = strchr(entry->rpc, ',')) == NULL)
12940Sstevel@tonic-gate return(BADLISFMT);
12950Sstevel@tonic-gate *tmp = ':';
12960Sstevel@tonic-gate }
12970Sstevel@tonic-gate entry->lflags = ptr;
12980Sstevel@tonic-gate if ((ptr = strchr(entry->lflags, ':')) == NULL)
12990Sstevel@tonic-gate return(BADLISFMT);
13000Sstevel@tonic-gate *ptr++ = NULL;
13010Sstevel@tonic-gate entry->modules = ptr;
13020Sstevel@tonic-gate if ((ptr = strchr(entry->modules, ':')) == NULL)
13030Sstevel@tonic-gate return(BADLISFMT);
13040Sstevel@tonic-gate *ptr++ = NULL;
13050Sstevel@tonic-gate entry->command = ptr;
13060Sstevel@tonic-gate if ((ptr = strchr(entry->command, '#')) == NULL)
13070Sstevel@tonic-gate return(BADLISFMT);
13080Sstevel@tonic-gate *ptr++ = NULL;
13090Sstevel@tonic-gate entry->comment = ptr;
13100Sstevel@tonic-gate return(NLS_OK);
13110Sstevel@tonic-gate }
13120Sstevel@tonic-gate
13130Sstevel@tonic-gate
13140Sstevel@tonic-gate /*
13150Sstevel@tonic-gate * nexttok - return next token, essentially a strtok, but it can
13160Sstevel@tonic-gate * deal with null fields and strtok can not
13170Sstevel@tonic-gate *
13180Sstevel@tonic-gate * args: str - the string to be examined, NULL if we should
13190Sstevel@tonic-gate * examine the remembered string
13200Sstevel@tonic-gate * delim - the list of valid delimiters
13210Sstevel@tonic-gate */
13220Sstevel@tonic-gate
13230Sstevel@tonic-gate
13240Sstevel@tonic-gate char *
nexttok(char * str,char * delim)1325*640Sbasabi nexttok(char *str, char *delim)
13260Sstevel@tonic-gate {
13270Sstevel@tonic-gate static char *savep; /* the remembered string */
13280Sstevel@tonic-gate register char *p; /* pointer to start of token */
13290Sstevel@tonic-gate register char *ep; /* pointer to end of token */
13300Sstevel@tonic-gate
13310Sstevel@tonic-gate p = (str == NULL) ? savep : str ;
13320Sstevel@tonic-gate if (p == NULL)
13330Sstevel@tonic-gate return(NULL);
13340Sstevel@tonic-gate ep = strpbrk(p, delim);
13350Sstevel@tonic-gate if (ep == NULL) {
13360Sstevel@tonic-gate savep = NULL;
13370Sstevel@tonic-gate return(p);
13380Sstevel@tonic-gate }
13390Sstevel@tonic-gate savep = ep + 1;
13400Sstevel@tonic-gate *ep = '\0';
13410Sstevel@tonic-gate return(p);
13420Sstevel@tonic-gate }
13430Sstevel@tonic-gate
13440Sstevel@tonic-gate
13450Sstevel@tonic-gate /*
13460Sstevel@tonic-gate * pflags - put flags into intelligible form for output
13470Sstevel@tonic-gate *
13480Sstevel@tonic-gate * args: flags - binary representation of flags
13490Sstevel@tonic-gate */
13500Sstevel@tonic-gate
13510Sstevel@tonic-gate char *
pflags(long flags)1352*640Sbasabi pflags(long flags)
13530Sstevel@tonic-gate {
13540Sstevel@tonic-gate register int i; /* scratch counter */
13550Sstevel@tonic-gate static char buf[BUFSIZ]; /* formatted flags */
13560Sstevel@tonic-gate
13570Sstevel@tonic-gate if (flags == 0)
13580Sstevel@tonic-gate return("");
13590Sstevel@tonic-gate i = 0;
13600Sstevel@tonic-gate if (flags & CFLAG) {
13610Sstevel@tonic-gate buf[i++] = 'c';
13620Sstevel@tonic-gate flags &= ~CFLAG;
13630Sstevel@tonic-gate }
13640Sstevel@tonic-gate if (flags & DFLAG) {
13650Sstevel@tonic-gate buf[i++] = 'd';
13660Sstevel@tonic-gate flags &= ~DFLAG;
13670Sstevel@tonic-gate }
13680Sstevel@tonic-gate if (flags & PFLAG) {
13690Sstevel@tonic-gate buf[i++] = 'p';
13700Sstevel@tonic-gate flags &= ~PFLAG;
13710Sstevel@tonic-gate }
13720Sstevel@tonic-gate if (flags) {
13730Sstevel@tonic-gate nlsmesg(MM_ERROR, "Internal error in pflags");
13740Sstevel@tonic-gate exit(NLS_FAILED);
13750Sstevel@tonic-gate }
13760Sstevel@tonic-gate buf[i] = '\0';
13770Sstevel@tonic-gate return(buf);
13780Sstevel@tonic-gate }
1379