4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License, Version 1.0 only
6 * (the "License"). You may not use this file except in compliance
9 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
10 * or http://www.opensolaris.org/os/licensing.
11 * See the License for the specific language governing permissions
12 * and limitations under the License.
14 * When distributing Covered Code, include this CDDL HEADER in each
15 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
16 * If applicable, add the following below this CDDL HEADER, with the
17 * fields enclosed by brackets "[]" replaced with your own identifying
18 * information: Portions Copyright [yyyy] [name of copyright owner]
23 * Copyright 2005 Sun Microsystems, Inc. All rights reserved.
24 * Use is subject to license terms.
27 /* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */
28 /* All Rights Reserved */
32 * nlsadmin.c -- control program for the network listener service
34 * This program replaces a previous version of nlsadmin.
36 * This version of nlsadmin works with the service access facility to
37 * control the network listener. The functionality of the SVR3.2 nlsadmin
38 * command is supported through calls to the more general sacadm and pmadm
39 * commands available through SAF. Users should migrate away from nlsadmin
40 * to sacadm and pmadm for these functions.
42 * The -m option of the SVR3.2 nlsadmin command is now ignored.
44 * The -t option associates an address with service code 1 (same as in SVR3.2).
45 * The -l option associates an address with service code 0.
47 * nlsadmin also contains new functionality -- the ability to format a
48 * "listener-specific" string to put in the _pmtab database. This
49 * functionality is required by SAF.
52 #include <sys/types.h>
62 #define OPTIONS "a:c:d:e:ikl:mo:p:qr:st:vw:xy:z:A:N:VDR:"
68 * defines for -q exit codes: QZERO is used for conditions that the
69 * man page documents as returning 0, QONE for those that return 1
75 * defines for simulated standard error format code
83 char *Nlsname
; /* set to argv[0] */
84 char Label
[25]; /* label component for fmtmsg */
85 int Quietflag
= FALSE
; /* set to TRUE when -q used */
111 void no_permission(void) __NORETURN
;
112 void usage(int flag
);
115 main(int argc
, char **argv
)
119 int c
; /* used for return from getopt */
120 char *addrptr
= NULL
; /* set when -A address is used */
121 char *rpcptr
= NULL
; /* set when -R rpcinfo is used */
122 char *cmdptr
= NULL
; /* set with -c command */
123 char *comptr
= NULL
; /* set with -y comment (old) */
124 char *idptr
= NULL
; /* set with -w id (old) */
125 char *lptr
= NULL
; /* set with -l addr (old) */
126 char *moduleptr
= NULL
; /* set with -m modules */
127 char *pipeptr
= NULL
; /* set with -o pipe */
128 char *svcptr
= NULL
; /* set when service code used (old) */
129 char *tptr
= NULL
; /* set when -t addr used (old) */
130 char *netspec
= NULL
; /* set to the network specification */
131 int flag
= 0; /* bit flag of type of command */
132 int exitcode
= 0; /* exit status of this command */
133 int lflags
= 0; /* listener flags */
134 char buf
[BUFSIZ
]; /* temp buffer #1 */
135 char mesg
[BUFSIZ
]; /* temp buffer #2 */
136 FILE *fp
; /* used for checking netspec */
137 char *ptr
; /* temp pointer */
138 char *ptr2
; /* temp pointer */
139 int sawsep
= 0; /* flag for RPC separator */
142 sprintf(Label
, "UX:%.14s", argv
[0]); /* for standard message fmt */
144 while ((c
= getopt(argc
, argv
, OPTIONS
)) != -1) {
147 if ( (flag
&& (flag
!= CMDFLAG
)) || svcptr
|| Quietflag
148 || addrptr
|| rpcptr
|| lflags
)
153 if ( (flag
&& (flag
!= CMDFLAG
)) || cmdptr
|| Quietflag
)
159 if ( flag
|| svcptr
|| Quietflag
|| comptr
|| addrptr
160 || rpcptr
|| cmdptr
|| idptr
|| lflags
)
166 if ( flag
|| svcptr
|| Quietflag
|| comptr
|| addrptr
167 || rpcptr
|| cmdptr
|| idptr
|| lflags
)
173 if ( flag
|| svcptr
|| Quietflag
|| comptr
|| addrptr
174 || rpcptr
|| cmdptr
|| idptr
|| lflags
)
179 if ( flag
|| svcptr
|| Quietflag
|| comptr
|| addrptr
180 || rpcptr
|| cmdptr
|| idptr
|| lflags
)
185 if ( ( flag
&& (flag
!= ADRFLAG
)) || svcptr
|| lptr
186 || Quietflag
|| comptr
|| addrptr
|| rpcptr
187 || cmdptr
|| idptr
|| lflags
)
193 if ( (flag
&& (flag
!= CMDFLAG
)) || Quietflag
|| rpcptr
|| lflags
)
198 if ( flag
|| svcptr
|| Quietflag
|| comptr
|| idptr
|| netspec
)
204 if ( (flag
&& (flag
!= CMDFLAG
) && (flag
!= PIPFLAG
)) || Quietflag
)
209 if ( (flag
&& (flag
!= ZZZFLAG
)) || Quietflag
|| comptr
210 || rpcptr
|| lflags
|| idptr
)
215 if ( flag
|| svcptr
|| Quietflag
|| comptr
|| addrptr
216 || rpcptr
|| cmdptr
|| idptr
|| lflags
)
222 if ( flag
|| svcptr
|| Quietflag
|| comptr
|| addrptr
223 || rpcptr
|| cmdptr
|| idptr
|| lflags
)
228 if ( (flag
&& (flag
!= ADRFLAG
)) || svcptr
|| tptr
229 || Quietflag
|| comptr
|| addrptr
|| rpcptr
230 || cmdptr
|| idptr
|| lflags
)
236 if ( flag
|| svcptr
|| Quietflag
|| comptr
|| rpcptr
237 || addrptr
|| idptr
|| lflags
)
242 if ( (flag
&& (flag
!= CMDFLAG
)) || Quietflag
|| idptr
243 || rpcptr
|| addrptr
|| lflags
)
248 if ( flag
|| svcptr
|| Quietflag
|| netspec
|| comptr
249 || rpcptr
|| addrptr
|| lflags
|| idptr
)
254 if ( (flag
&& (flag
!= CMDFLAG
)) || Quietflag
|| comptr
255 || rpcptr
|| addrptr
|| lflags
)
260 if ( flag
|| svcptr
|| comptr
|| addrptr
|| rpcptr
267 if ( (flag
&& (flag
!= CMDFLAG
) && (flag
!= PIPFLAG
))
268 || netspec
|| svcptr
|| idptr
|| comptr
)
273 if ( (flag
&& (flag
!= CMDFLAG
) && (flag
!= PIPFLAG
))
274 || netspec
|| svcptr
|| idptr
|| comptr
|| addrptr
285 if ( (flag
&& (flag
!= CMDFLAG
) && (flag
!= PIPFLAG
))
286 || netspec
|| svcptr
|| idptr
|| comptr
)
288 for (ptr
= optarg
; *ptr
; ++ptr
) {
289 if ((*ptr
== ':') && !sawsep
) {
291 * skip separator - note that if
292 * separator has been seen, it's not
293 * a digit so it will generate a usage
294 * message below like we want
302 ptr
= strchr(optarg
, ':');
304 /* change the ':' to a ',' */
311 if ( flag
|| svcptr
|| Quietflag
|| comptr
|| netspec
312 || rpcptr
|| addrptr
|| idptr
|| lflags
)
322 if ((optind
< argc
) && ! netspec
)
323 netspec
= argv
[optind
++];
328 /* determine if this command requires a netspec */
329 if (flag
!= CMDFLAG
) {
330 /* if flag is CMDFLAG, more complicated checking of netspec
331 * is done below in switch
333 if ((flag
== PIPFLAG
|| flag
== VERFLAG
|| flag
== NETFLAG
)) {
341 if (netspec
&& (flag
!= INIFLAG
)) {
342 sprintf(buf
, SAC_LSPM
, netspec
);
344 if ((fp
= popen(buf
, "r")) == NULL
) {
345 nlsmesg(MM_ERROR
, "System error");
349 if (fgets(buf
, BUFSIZ
, fp
) == NULL
) {
350 nlsmesg(MM_ERROR
, "Invalid network specification");
354 ptr
= strchr(buf
, ':');
356 ptr2
= strchr(ptr
, ':');
358 if (strcmp(ptr
, LISTENTYPE
) != 0) {
359 sprintf(mesg
, "Network specification \"%s\" is not of type %s", netspec
, LISTENTYPE
);
360 nlsmesg(MM_ERROR
, mesg
);
369 /* check to see if service code is "correct" -- right range
370 * and format. The -m flag is ignored, so no check for
371 * "administrative" service codes (0-100) is done.
374 if ((c
== 0) || (c
>= SVC_CODE_SZ
)) {
375 sprintf(mesg
, "Service code contains more than %d characters", SVC_CODE_SZ
);
376 nlsmesg(MM_ERROR
, mesg
);
386 if ( svcptr
|| comptr
|| rpcptr
|| lflags
|| idptr
)
388 exitcode
= prt_nets(netspec
);
391 if (geteuid() != ROOT
)
393 exitcode
= add_pm(netspec
);
396 if ( svcptr
|| comptr
|| idptr
|| netspec
) {
397 if (geteuid() != ROOT
)
399 if ((exitcode
= old_addsvc(svcptr
, "", cmdptr
, comptr
, moduleptr
, idptr
, NULL
, netspec
)) != NLS_OK
)
402 nlsmesg(MM_ERROR
, "Service code already exists");
405 nlsmesg(MM_ERROR
, "Could not add service");
412 exitcode
= prt_cmd(cmdptr
, CFLAG
| lflags
, moduleptr
, addrptr
, rpcptr
);
416 if (geteuid() != ROOT
)
418 exitcode
= prt_cmd(pipeptr
, PFLAG
| lflags
, moduleptr
, addrptr
, rpcptr
);
421 printf("%d\n", VERSION
);
425 if (geteuid() != ROOT
)
427 exitcode
= disable_svc(svcptr
, netspec
);
430 if (geteuid() != ROOT
)
432 exitcode
= enable_svc(svcptr
, netspec
);
435 if (geteuid() != ROOT
)
437 exitcode
= kill_listener(netspec
);
440 /* check for root permissions in setup_addr */
441 exitcode
= setup_addr(lptr
, tptr
, netspec
);
444 if (geteuid() != ROOT
)
446 exitcode
= remove_svc(svcptr
, netspec
, TRUE
);
449 if (geteuid() != ROOT
)
451 exitcode
= start_listener(netspec
);
454 exitcode
= prt_svcs(NULL
, netspec
);
457 exitcode
= prt_nets(NULL
);
460 exitcode
= prt_svcs(svcptr
, netspec
);
463 if (exitcode
== NLS_SYSERR
)
464 nlsmesg(MM_ERROR
, "System error in SAC command");
469 static char umsg
[] = "usage: %s -x\n\
470 %s [ options ] netspec\n\
471 %s [ options ] -N port_monitor_tag\n\
473 %s -c cmd | -o pipename [ -p modules ] [ -A addr | -D ] \\\n\
474 [ -R prognum:versnum ]\n\
477 [ -a svc_code -c \"cmd\" -y \"cmt\" [-p modules] [-w id] ]\n\
478 [-q] | [-v] | [-s] | [-k] | [-i] |\n\
479 [-e svc_code] | [-d svc_code] | [-r svc_code] | [[-q] -z svc_code]\n\
480 [[-l addr | -] [-t addr | -]] |\n\
488 nlsmesg(MM_ERROR
, "Inconsistent options");
491 nlsmesg(MM_ERROR
, "Missing argument");
496 fprintf(stderr
, umsg
, Nlsname
, Nlsname
, Nlsname
, Nlsname
, Nlsname
);
502 * no_permission: print out error message and exit when the user needs to
503 * needs to be root and isn't.
509 nlsmesg(MM_ERROR
, "Must be super user");
514 * nlsmesg: print out either an error or a warning message. severity must
515 * be either MM_ERROR or MM_WARNING. this routine will be converted
516 * to use the standard message format later.
520 nlsmesg(int severity
, char *text
)
524 if (severity
== MM_ERROR
)
525 fprintf(stderr
, "%s: error: %s\n", Nlsname
, text
);
527 fprintf(stderr
, "%s: warning: %s\n", Nlsname
, text
);
532 * prt_cmd: print out the listener-dependent string for sacadm.
536 prt_cmd(char *path
, long flags
, char *modules
, char *addr
, char *rpcp
)
537 /* path: full path of command or pipe */
538 /* flags: listener flags */
540 /* CFLAG for command */
541 /* DFLAG for dynamic addr */
542 /* modules: STREAMS modules to push */
543 /* addr: private address */
544 /* rpcp: RPC prog and ver # */
547 char mesgbuf
[BUFSIZ
];
551 nlsmesg(MM_ERROR
, "Must specify full path name");
555 if ((tmp
= strchr(path
, ' ')) != NULL
)
558 if (stat(path
, &sbuf
) < 0) {
559 if (errno
!= EFAULT
) {
560 sprintf(mesgbuf
, "%s does not exist", path
);
561 nlsmesg(MM_WARNING
, mesgbuf
);
570 printf("%s:%s:%s:%s:%s\n", (addr
? addr
: ""), (rpcp
? rpcp
: ""),
571 pflags(flags
), (modules
? modules
: ""), path
);
576 * old_addsvc: use pmadm to add a service code to the listener. this will
577 * not allow specification of a private address -- use pmadm!
581 old_addsvc(char *svc
, char *addr
, char *cmd
, char *com
, char *module
,
582 char *id
, char *flags
, char *netspec
)
585 char mesgbuf
[BUFSIZ
];
590 if (!svc
|| !cmd
|| !com
|| !netspec
)
593 /* create "port-monitor specific" info in the same way as prt_cmd */
596 nlsmesg(MM_ERROR
, "Must specify full path name");
600 if ((tmp
= strchr(cmd
, ' ')) != NULL
)
603 if (stat(cmd
, &sbuf
) < 0) {
604 if (errno
!= EFAULT
) {
605 sprintf(mesgbuf
, "%s does not exist", cmd
);
606 nlsmesg(MM_WARNING
, mesgbuf
);
616 sprintf(mesgbuf
, "'%s::c:%s:%s'", addr
, module
? module
: "" , cmd
);
618 sprintf(mesgbuf
, "'::c:%s:%s'", module
? module
: "" , cmd
);
621 sprintf(buf
, PM_ADDSVCF
, netspec
, svc
, (id
)?id
:DEFAULTID
, flags
, mesgbuf
, VERSION
, com
? com
: "");
623 sprintf(buf
, PM_ADDSVC
, netspec
, svc
, (id
)?id
:DEFAULTID
, mesgbuf
, VERSION
, com
? com
: "");
625 if ((rtn
= system(buf
)) < 0) {
628 rtn
= (rtn
>>8) & 0xff; /* get child return value out of exit word */
656 * prt_nets: print the status of one network, or all nets if netspec
660 prt_nets(char *netspec
)
671 sprintf(buf
, SAC_LSTY
, LISTENTYPE
);
673 sprintf(buf
, SAC_LSPM
, netspec
);
675 if ((fp
= popen(buf
, "r")) == NULL
)
678 while (fgets(buf
, BUFSIZ
, fp
) != NULL
) {
679 if ((name
= nexttok(buf
, ":")) == NULL
)
681 if ((type
= nexttok(NULL
, ":")) == NULL
)
684 if (strcmp(type
, LISTENTYPE
) != 0)
685 continue; /* ignore other types of port monitors */
688 if (nexttok(NULL
, ":") == NULL
)
690 if (nexttok(NULL
, ":") == NULL
)
692 if ((state
= nexttok(NULL
, ":")) == NULL
)
694 if (strcmp(state
, "ENABLED") == 0 ||
695 strcmp(state
, "STARTING") == 0) {
698 printf("%s\t%s\n", name
, "ACTIVE");
703 printf("%s\t%s\n", name
, "INACTIVE");
708 if (netspec
&& !found
) {
709 nlsmesg(MM_ERROR
, "Invalid network specification");
722 * print info about service on netspec, or all services on netspec
727 prt_svcs(char *svc
, char *netspec
)
732 struct svcfields entry
;
738 sprintf(buf
, PM_LSALL
, netspec
);
740 sprintf(buf
, PM_LSONE
, netspec
, svc
);
742 if ((fp
= popen(buf
, "r")) == NULL
)
745 while (fgets(buf
, BUFSIZ
, fp
) != NULL
) {
746 if ((rtn
= svc_format(buf
, &entry
)) != 0) {
755 sprintf(mesg
, "Entry for code \"%s\" has incorrect format", entry
.svc_code
);
756 nlsmesg(MM_WARNING
, mesg
);
764 printf("%s\t", entry
.svc_code
);
766 printf("%s\t", entry
.addr
);
767 else if (strchr(entry
.lflags
, 'd'))
772 if (strchr(entry
.flags
, 'x') == NULL
)
773 printf("ENABLED \t");
775 printf("DISABLED\t");
778 printf("%s\t%s\t%s\t%s\t# %s",
779 (*entry
.rpc
)?entry
.rpc
:"NORPC", entry
.id
,
780 (*entry
.modules
)?entry
.modules
:"NOMODULES",
781 entry
.command
, (*entry
.comment
)?entry
.comment
:"");
784 if (strchr(entry
.flags
, 'x') == NULL
)
793 if (rtn
== NOTLISTEN
) { /* check last return to see if error */
794 sprintf(mesg
, "Network specification \"%s\" is not of type %s", netspec
, LISTENTYPE
);
795 nlsmesg(MM_ERROR
, mesg
);
800 sprintf(mesg
, "Service \"%s\" unknown", svc
);
801 nlsmesg(MM_ERROR
, mesg
);
810 * disable_svc: use pmadm to disable a service
814 disable_svc(char *svc
, char *netspec
)
819 sprintf(buf
, PM_DISABLE
, netspec
, svc
);
821 if ((rtn
= system(buf
)) < 0) {
824 rtn
= (rtn
>>8) & 0xff; /* get child return value out of exit word */
842 nlsmesg(MM_ERROR
, "Non-existent service.");
854 enable_svc(char *svc
, char *netspec
)
859 sprintf(buf
, PM_ENABLE
, netspec
, svc
);
861 if ((rtn
= system(buf
)) < 0) {
864 rtn
= (rtn
>>8) & 0xff; /* get child return value out of exit word */
882 nlsmesg(MM_ERROR
, "Non-existent service.");
894 remove_svc(char *svc
, char *netspec
, int printerrors
)
899 sprintf(buf
, PM_REMSVC
, netspec
, svc
);
901 if ((rtn
= system(buf
)) < 0) {
904 rtn
= (rtn
>>8) & 0xff; /* get child return value out of exit word */
923 nlsmesg(MM_ERROR
, "Non-existent service.");
935 kill_listener(char *netspec
)
941 sprintf(buf
, SAC_KILLPM
, netspec
);
943 if ((rtn
= system(buf
)) < 0) {
946 rtn
= (rtn
>>8) & 0xff; /* get child return value out of exit word */
963 sprintf(mesg
, "No listener active on network \"%s\"", netspec
);
964 nlsmesg(MM_ERROR
, mesg
);
967 nlsmesg(MM_ERROR
, "Non-existent port monitor.");
979 * add_pm: add a port monitor (initialize directories) using sacadm
983 add_pm(char *netspec
)
989 sprintf(buf
, SAC_ADDPM
, netspec
, LISTENTYPE
, gencmdstr(netspec
), VERSION
);
991 if ((rtn
= system(buf
)) < 0) {
994 rtn
= (rtn
>>8) & 0xff; /* get child return value out of exit word */
998 old_addsvc(NLPSSVCCODE
, NULL
, NLPSSRV
, "NLPS server", "", "root", NULL
, netspec
);
1013 nlsmesg(MM_ERROR
, "Listener already initialized");
1025 * gencmdstr: generate the correct string to invoke the listener (starlan
1026 * requires special handling)
1030 gencmdstr(char *netspec
)
1032 static char buf
[BUFSIZ
];
1034 (void) strcpy(buf
, LISTENCMD
);
1035 if (!strcmp(netspec
, "starlan"))
1036 (void) strcat(buf
, " -m slan");
1037 (void) strcat(buf
, " ");
1038 (void) strcat(buf
, netspec
);
1044 * start_listener: start the listener
1048 start_listener(char *netspec
)
1051 char scratch
[BUFSIZ
];
1054 sprintf(buf
, SAC_STARTPM
, netspec
);
1056 if ((rtn
= system(buf
)) < 0)
1058 rtn
= (rtn
>>8) & 0xff;
1073 nlsmesg(MM_ERROR
, "Non-existent port monitor.");
1077 nlsmesg(MM_ERROR
, "Listener already running");
1084 sprintf(buf
, SAC_ENABLPM
, netspec
);
1086 if ((rtn
= system(buf
)) < 0) {
1089 rtn
= (rtn
>>8) & 0xff;
1104 nlsmesg(MM_ERROR
, "Non-existent port monitor.");
1108 nlsmesg(MM_ERROR
, "Listener already running");
1111 nlsmesg(MM_ERROR
, "Listener start failed");
1122 * setup_addr: setup the -l and -t addresses.
1126 setup_addr(char *laddr
, char *taddr
, char *netspec
)
1132 int qlisten
= FALSE
;
1135 struct svcfields entry
;
1137 if (laddr
&& *laddr
== '-')
1140 if (taddr
&& *taddr
== '-')
1144 sprintf(buf
, PM_LSONE
, netspec
, NLPSSVCCODE
);
1146 if ((fp
= popen(buf
, "r")) == NULL
) {
1150 if (fgets(buf
, BUFSIZ
, fp
) != NULL
) {
1151 if ((rtn
= svc_format(buf
, &entry
)) != 0) {
1154 nlsmesg(MM_ERROR
, "Incorrect port monitor type. Must be of type listen");
1161 sprintf(mesg
, "Entry for code \"%s\" has incorrect format", entry
.svc_code
);
1162 nlsmesg(MM_WARNING
, mesg
);
1168 printf("%s\n", entry
.addr
);
1170 if (geteuid() != ROOT
)
1173 remove_svc(NLPSSVCCODE
, netspec
, FALSE
);
1174 p
= strchr(entry
.comment
, '\n');
1177 old_addsvc(NLPSSVCCODE
, laddr
, entry
.command
, entry
.comment
, entry
.modules
, entry
.id
, entry
.flags
, netspec
);
1183 nlsmesg(MM_WARNING
, "NLPS service not defined");
1186 sprintf(buf
, PM_LSONE
, netspec
, TTYSVCCODE
);
1188 if ((fp
= popen(buf
, "r")) == NULL
) {
1192 if (fgets(buf
, BUFSIZ
, fp
) != NULL
) {
1193 if ((rtn
= svc_format(buf
, &entry
)) != 0) {
1196 nlsmesg(MM_ERROR
, "Incorrect port monitor type. Must be of type listen");
1203 sprintf(mesg
, "Entry for code \"%s\" has incorrect format", entry
.svc_code
);
1204 nlsmesg(MM_WARNING
, mesg
);
1210 printf("%s\n", entry
.addr
);
1212 if (geteuid() != ROOT
)
1215 remove_svc(TTYSVCCODE
, netspec
, FALSE
);
1216 p
= strchr(entry
.comment
, '\n');
1219 old_addsvc(TTYSVCCODE
, taddr
, entry
.command
, entry
.comment
, entry
.modules
, entry
.id
, entry
.flags
, netspec
);
1225 nlsmesg(MM_WARNING
, "remote login service not defined");
1232 * svc_format: scan a line of output from pmadm to separate it into fields.
1233 * returns BADPMFMT for missing fields or incorrect syntax.
1234 * NOTLISTEN is the port monitor type is not listen.
1235 * BADLISFMT if the listener-specific data is incorrect.
1236 * NLS_OK if everything checked out and data is broken
1237 * into the structure.
1241 svc_format(char *buf
, struct svcfields
*entry
)
1243 char *ptr
; /* temporary pointer into buffer */
1244 char *tmp
; /* temporary pointer into buffer */
1247 if ((ptr
= strchr(buf
, ':')) == NULL
)
1250 entry
->pmtype
= ptr
;
1251 if ((ptr
= strchr(entry
->pmtype
, ':')) == NULL
)
1254 entry
->svc_code
= ptr
;
1256 if (strcmp(entry
->pmtype
, LISTENTYPE
) != 0)
1259 if ((ptr
= strchr(entry
->svc_code
, ':')) == NULL
)
1263 if ((ptr
= strchr(entry
->flags
, ':')) == NULL
)
1267 if ((ptr
= strchr(entry
->id
, ':')) == NULL
)
1271 if ((ptr
= strchr(entry
->res1
, ':')) == NULL
)
1275 if ((ptr
= strchr(entry
->res2
, ':')) == NULL
)
1279 if ((ptr
= strchr(entry
->res3
, ':')) == NULL
)
1283 if ((ptr
= strchr(entry
->addr
, ':')) == NULL
)
1287 if ((ptr
= strchr(entry
->rpc
, ':')) == NULL
)
1291 if ((tmp
= strchr(entry
->rpc
, ',')) == NULL
)
1295 entry
->lflags
= ptr
;
1296 if ((ptr
= strchr(entry
->lflags
, ':')) == NULL
)
1299 entry
->modules
= ptr
;
1300 if ((ptr
= strchr(entry
->modules
, ':')) == NULL
)
1303 entry
->command
= ptr
;
1304 if ((ptr
= strchr(entry
->command
, '#')) == NULL
)
1307 entry
->comment
= ptr
;
1313 * nexttok - return next token, essentially a strtok, but it can
1314 * deal with null fields and strtok can not
1316 * args: str - the string to be examined, NULL if we should
1317 * examine the remembered string
1318 * delim - the list of valid delimiters
1323 nexttok(char *str
, char *delim
)
1325 static char *savep
; /* the remembered string */
1326 register char *p
; /* pointer to start of token */
1327 register char *ep
; /* pointer to end of token */
1329 p
= (str
== NULL
) ? savep
: str
;
1332 ep
= strpbrk(p
, delim
);
1344 * pflags - put flags into intelligible form for output
1346 * args: flags - binary representation of flags
1352 register int i
; /* scratch counter */
1353 static char buf
[BUFSIZ
]; /* formatted flags */
1358 if (flags
& CFLAG
) {
1362 if (flags
& DFLAG
) {
1366 if (flags
& PFLAG
) {
1371 nlsmesg(MM_ERROR
, "Internal error in pflags");