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 */
31 #pragma ident "%Z%%M% %I% %E% SMI"
34 * nlsadmin.c -- control program for the network listener service
36 * This program replaces a previous version of nlsadmin.
38 * This version of nlsadmin works with the service access facility to
39 * control the network listener. The functionality of the SVR3.2 nlsadmin
40 * command is supported through calls to the more general sacadm and pmadm
41 * commands available through SAF. Users should migrate away from nlsadmin
42 * to sacadm and pmadm for these functions.
44 * The -m option of the SVR3.2 nlsadmin command is now ignored.
46 * The -t option associates an address with service code 1 (same as in SVR3.2).
47 * The -l option associates an address with service code 0.
49 * nlsadmin also contains new functionality -- the ability to format a
50 * "listener-specific" string to put in the _pmtab database. This
51 * functionality is required by SAF.
54 #include <sys/types.h>
64 #define OPTIONS "a:c:d:e:ikl:mo:p:qr:st:vw:xy:z:A:N:VDR:"
70 * defines for -q exit codes: QZERO is used for conditions that the
71 * man page documents as returning 0, QONE for those that return 1
77 * defines for simulated standard error format code
85 char *Nlsname
; /* set to argv[0] */
86 char Label
[25]; /* label component for fmtmsg */
87 int Quietflag
= FALSE
; /* set to TRUE when -q used */
113 void no_permission(void) __NORETURN
;
114 void usage(int flag
);
117 main(int argc
, char **argv
)
121 int c
; /* used for return from getopt */
122 char *addrptr
= NULL
; /* set when -A address is used */
123 char *rpcptr
= NULL
; /* set when -R rpcinfo is used */
124 char *cmdptr
= NULL
; /* set with -c command */
125 char *comptr
= NULL
; /* set with -y comment (old) */
126 char *idptr
= NULL
; /* set with -w id (old) */
127 char *lptr
= NULL
; /* set with -l addr (old) */
128 char *moduleptr
= NULL
; /* set with -m modules */
129 char *pipeptr
= NULL
; /* set with -o pipe */
130 char *svcptr
= NULL
; /* set when service code used (old) */
131 char *tptr
= NULL
; /* set when -t addr used (old) */
132 char *netspec
= NULL
; /* set to the network specification */
133 int flag
= 0; /* bit flag of type of command */
134 int exitcode
= 0; /* exit status of this command */
135 int lflags
= 0; /* listener flags */
136 char buf
[BUFSIZ
]; /* temp buffer #1 */
137 char mesg
[BUFSIZ
]; /* temp buffer #2 */
138 FILE *fp
; /* used for checking netspec */
139 char *ptr
; /* temp pointer */
140 char *ptr2
; /* temp pointer */
141 int sawsep
= 0; /* flag for RPC separator */
144 sprintf(Label
, "UX:%.14s", argv
[0]); /* for standard message fmt */
146 while ((c
= getopt(argc
, argv
, OPTIONS
)) != -1) {
149 if ( (flag
&& (flag
!= CMDFLAG
)) || svcptr
|| Quietflag
150 || addrptr
|| rpcptr
|| lflags
)
155 if ( (flag
&& (flag
!= CMDFLAG
)) || cmdptr
|| Quietflag
)
161 if ( flag
|| svcptr
|| Quietflag
|| comptr
|| addrptr
162 || rpcptr
|| cmdptr
|| idptr
|| lflags
)
168 if ( flag
|| svcptr
|| Quietflag
|| comptr
|| addrptr
169 || rpcptr
|| cmdptr
|| idptr
|| lflags
)
175 if ( flag
|| svcptr
|| Quietflag
|| comptr
|| addrptr
176 || rpcptr
|| cmdptr
|| idptr
|| lflags
)
181 if ( flag
|| svcptr
|| Quietflag
|| comptr
|| addrptr
182 || rpcptr
|| cmdptr
|| idptr
|| lflags
)
187 if ( ( flag
&& (flag
!= ADRFLAG
)) || svcptr
|| lptr
188 || Quietflag
|| comptr
|| addrptr
|| rpcptr
189 || cmdptr
|| idptr
|| lflags
)
195 if ( (flag
&& (flag
!= CMDFLAG
)) || Quietflag
|| rpcptr
|| lflags
)
200 if ( flag
|| svcptr
|| Quietflag
|| comptr
|| idptr
|| netspec
)
206 if ( (flag
&& (flag
!= CMDFLAG
) && (flag
!= PIPFLAG
)) || Quietflag
)
211 if ( (flag
&& (flag
!= ZZZFLAG
)) || Quietflag
|| comptr
212 || rpcptr
|| lflags
|| idptr
)
217 if ( flag
|| svcptr
|| Quietflag
|| comptr
|| addrptr
218 || rpcptr
|| cmdptr
|| idptr
|| lflags
)
224 if ( flag
|| svcptr
|| Quietflag
|| comptr
|| addrptr
225 || rpcptr
|| cmdptr
|| idptr
|| lflags
)
230 if ( (flag
&& (flag
!= ADRFLAG
)) || svcptr
|| tptr
231 || Quietflag
|| comptr
|| addrptr
|| rpcptr
232 || cmdptr
|| idptr
|| lflags
)
238 if ( flag
|| svcptr
|| Quietflag
|| comptr
|| rpcptr
239 || addrptr
|| idptr
|| lflags
)
244 if ( (flag
&& (flag
!= CMDFLAG
)) || Quietflag
|| idptr
245 || rpcptr
|| addrptr
|| lflags
)
250 if ( flag
|| svcptr
|| Quietflag
|| netspec
|| comptr
251 || rpcptr
|| addrptr
|| lflags
|| idptr
)
256 if ( (flag
&& (flag
!= CMDFLAG
)) || Quietflag
|| comptr
257 || rpcptr
|| addrptr
|| lflags
)
262 if ( flag
|| svcptr
|| comptr
|| addrptr
|| rpcptr
269 if ( (flag
&& (flag
!= CMDFLAG
) && (flag
!= PIPFLAG
))
270 || netspec
|| svcptr
|| idptr
|| comptr
)
275 if ( (flag
&& (flag
!= CMDFLAG
) && (flag
!= PIPFLAG
))
276 || netspec
|| svcptr
|| idptr
|| comptr
|| addrptr
287 if ( (flag
&& (flag
!= CMDFLAG
) && (flag
!= PIPFLAG
))
288 || netspec
|| svcptr
|| idptr
|| comptr
)
290 for (ptr
= optarg
; *ptr
; ++ptr
) {
291 if ((*ptr
== ':') && !sawsep
) {
293 * skip separator - note that if
294 * separator has been seen, it's not
295 * a digit so it will generate a usage
296 * message below like we want
304 ptr
= strchr(optarg
, ':');
306 /* change the ':' to a ',' */
313 if ( flag
|| svcptr
|| Quietflag
|| comptr
|| netspec
314 || rpcptr
|| addrptr
|| idptr
|| lflags
)
324 if ((optind
< argc
) && ! netspec
)
325 netspec
= argv
[optind
++];
330 /* determine if this command requires a netspec */
331 if (flag
!= CMDFLAG
) {
332 /* if flag is CMDFLAG, more complicated checking of netspec
333 * is done below in switch
335 if ((flag
== PIPFLAG
|| flag
== VERFLAG
|| flag
== NETFLAG
)) {
343 if (netspec
&& (flag
!= INIFLAG
)) {
344 sprintf(buf
, SAC_LSPM
, netspec
);
346 if ((fp
= popen(buf
, "r")) == NULL
) {
347 nlsmesg(MM_ERROR
, "System error");
351 if (fgets(buf
, BUFSIZ
, fp
) == NULL
) {
352 nlsmesg(MM_ERROR
, "Invalid network specification");
356 ptr
= strchr(buf
, ':');
358 ptr2
= strchr(ptr
, ':');
360 if (strcmp(ptr
, LISTENTYPE
) != 0) {
361 sprintf(mesg
, "Network specification \"%s\" is not of type %s", netspec
, LISTENTYPE
);
362 nlsmesg(MM_ERROR
, mesg
);
371 /* check to see if service code is "correct" -- right range
372 * and format. The -m flag is ignored, so no check for
373 * "administrative" service codes (0-100) is done.
376 if ((c
== 0) || (c
>= SVC_CODE_SZ
)) {
377 sprintf(mesg
, "Service code contains more than %d characters", SVC_CODE_SZ
);
378 nlsmesg(MM_ERROR
, mesg
);
388 if ( svcptr
|| comptr
|| rpcptr
|| lflags
|| idptr
)
390 exitcode
= prt_nets(netspec
);
393 if (geteuid() != ROOT
)
395 exitcode
= add_pm(netspec
);
398 if ( svcptr
|| comptr
|| idptr
|| netspec
) {
399 if (geteuid() != ROOT
)
401 if ((exitcode
= old_addsvc(svcptr
, "", cmdptr
, comptr
, moduleptr
, idptr
, NULL
, netspec
)) != NLS_OK
)
404 nlsmesg(MM_ERROR
, "Service code already exists");
407 nlsmesg(MM_ERROR
, "Could not add service");
414 exitcode
= prt_cmd(cmdptr
, CFLAG
| lflags
, moduleptr
, addrptr
, rpcptr
);
418 if (geteuid() != ROOT
)
420 exitcode
= prt_cmd(pipeptr
, PFLAG
| lflags
, moduleptr
, addrptr
, rpcptr
);
423 printf("%d\n", VERSION
);
427 if (geteuid() != ROOT
)
429 exitcode
= disable_svc(svcptr
, netspec
);
432 if (geteuid() != ROOT
)
434 exitcode
= enable_svc(svcptr
, netspec
);
437 if (geteuid() != ROOT
)
439 exitcode
= kill_listener(netspec
);
442 /* check for root permissions in setup_addr */
443 exitcode
= setup_addr(lptr
, tptr
, netspec
);
446 if (geteuid() != ROOT
)
448 exitcode
= remove_svc(svcptr
, netspec
, TRUE
);
451 if (geteuid() != ROOT
)
453 exitcode
= start_listener(netspec
);
456 exitcode
= prt_svcs(NULL
, netspec
);
459 exitcode
= prt_nets(NULL
);
462 exitcode
= prt_svcs(svcptr
, netspec
);
465 if (exitcode
== NLS_SYSERR
)
466 nlsmesg(MM_ERROR
, "System error in SAC command");
471 static char umsg
[] = "usage: %s -x\n\
472 %s [ options ] netspec\n\
473 %s [ options ] -N port_monitor_tag\n\
475 %s -c cmd | -o pipename [ -p modules ] [ -A addr | -D ] \\\n\
476 [ -R prognum:versnum ]\n\
479 [ -a svc_code -c \"cmd\" -y \"cmt\" [-p modules] [-w id] ]\n\
480 [-q] | [-v] | [-s] | [-k] | [-i] |\n\
481 [-e svc_code] | [-d svc_code] | [-r svc_code] | [[-q] -z svc_code]\n\
482 [[-l addr | -] [-t addr | -]] |\n\
490 nlsmesg(MM_ERROR
, "Inconsistent options");
493 nlsmesg(MM_ERROR
, "Missing argument");
498 fprintf(stderr
, umsg
, Nlsname
, Nlsname
, Nlsname
, Nlsname
, Nlsname
);
504 * no_permission: print out error message and exit when the user needs to
505 * needs to be root and isn't.
511 nlsmesg(MM_ERROR
, "Must be super user");
516 * nlsmesg: print out either an error or a warning message. severity must
517 * be either MM_ERROR or MM_WARNING. this routine will be converted
518 * to use the standard message format later.
522 nlsmesg(int severity
, char *text
)
526 if (severity
== MM_ERROR
)
527 fprintf(stderr
, "%s: error: %s\n", Nlsname
, text
);
529 fprintf(stderr
, "%s: warning: %s\n", Nlsname
, text
);
534 * prt_cmd: print out the listener-dependent string for sacadm.
538 prt_cmd(char *path
, long flags
, char *modules
, char *addr
, char *rpcp
)
539 /* path: full path of command or pipe */
540 /* flags: listener flags */
542 /* CFLAG for command */
543 /* DFLAG for dynamic addr */
544 /* modules: STREAMS modules to push */
545 /* addr: private address */
546 /* rpcp: RPC prog and ver # */
549 char mesgbuf
[BUFSIZ
];
553 nlsmesg(MM_ERROR
, "Must specify full path name");
557 if ((tmp
= strchr(path
, ' ')) != NULL
)
560 if (stat(path
, &sbuf
) < 0) {
561 if (errno
!= EFAULT
) {
562 sprintf(mesgbuf
, "%s does not exist", path
);
563 nlsmesg(MM_WARNING
, mesgbuf
);
572 printf("%s:%s:%s:%s:%s\n", (addr
? addr
: ""), (rpcp
? rpcp
: ""),
573 pflags(flags
), (modules
? modules
: ""), path
);
578 * old_addsvc: use pmadm to add a service code to the listener. this will
579 * not allow specification of a private address -- use pmadm!
583 old_addsvc(char *svc
, char *addr
, char *cmd
, char *com
, char *module
,
584 char *id
, char *flags
, char *netspec
)
587 char mesgbuf
[BUFSIZ
];
592 if (!svc
|| !cmd
|| !com
|| !netspec
)
595 /* create "port-monitor specific" info in the same way as prt_cmd */
598 nlsmesg(MM_ERROR
, "Must specify full path name");
602 if ((tmp
= strchr(cmd
, ' ')) != NULL
)
605 if (stat(cmd
, &sbuf
) < 0) {
606 if (errno
!= EFAULT
) {
607 sprintf(mesgbuf
, "%s does not exist", cmd
);
608 nlsmesg(MM_WARNING
, mesgbuf
);
618 sprintf(mesgbuf
, "'%s::c:%s:%s'", addr
, module
? module
: "" , cmd
);
620 sprintf(mesgbuf
, "'::c:%s:%s'", module
? module
: "" , cmd
);
623 sprintf(buf
, PM_ADDSVCF
, netspec
, svc
, (id
)?id
:DEFAULTID
, flags
, mesgbuf
, VERSION
, com
? com
: "");
625 sprintf(buf
, PM_ADDSVC
, netspec
, svc
, (id
)?id
:DEFAULTID
, mesgbuf
, VERSION
, com
? com
: "");
627 if ((rtn
= system(buf
)) < 0) {
630 rtn
= (rtn
>>8) & 0xff; /* get child return value out of exit word */
658 * prt_nets: print the status of one network, or all nets if netspec
662 prt_nets(char *netspec
)
673 sprintf(buf
, SAC_LSTY
, LISTENTYPE
);
675 sprintf(buf
, SAC_LSPM
, netspec
);
677 if ((fp
= popen(buf
, "r")) == NULL
)
680 while (fgets(buf
, BUFSIZ
, fp
) != NULL
) {
681 if ((name
= nexttok(buf
, ":")) == NULL
)
683 if ((type
= nexttok(NULL
, ":")) == NULL
)
686 if (strcmp(type
, LISTENTYPE
) != 0)
687 continue; /* ignore other types of port monitors */
690 if (nexttok(NULL
, ":") == NULL
)
692 if (nexttok(NULL
, ":") == NULL
)
694 if ((state
= nexttok(NULL
, ":")) == NULL
)
696 if (strcmp(state
, "ENABLED") == NULL
||
697 strcmp(state
, "STARTING") == NULL
) {
700 printf("%s\t%s\n", name
, "ACTIVE");
705 printf("%s\t%s\n", name
, "INACTIVE");
710 if (netspec
&& !found
) {
711 nlsmesg(MM_ERROR
, "Invalid network specification");
724 * print info about service on netspec, or all services on netspec
729 prt_svcs(char *svc
, char *netspec
)
734 struct svcfields entry
;
740 sprintf(buf
, PM_LSALL
, netspec
);
742 sprintf(buf
, PM_LSONE
, netspec
, svc
);
744 if ((fp
= popen(buf
, "r")) == NULL
)
747 while (fgets(buf
, BUFSIZ
, fp
) != NULL
) {
748 if ((rtn
= svc_format(buf
, &entry
)) != 0) {
757 sprintf(mesg
, "Entry for code \"%s\" has incorrect format", entry
.svc_code
);
758 nlsmesg(MM_WARNING
, mesg
);
766 printf("%s\t", entry
.svc_code
);
768 printf("%s\t", entry
.addr
);
769 else if (strchr(entry
.lflags
, 'd'))
774 if (strchr(entry
.flags
, 'x') == NULL
)
775 printf("ENABLED \t");
777 printf("DISABLED\t");
780 printf("%s\t%s\t%s\t%s\t# %s",
781 (*entry
.rpc
)?entry
.rpc
:"NORPC", entry
.id
,
782 (*entry
.modules
)?entry
.modules
:"NOMODULES",
783 entry
.command
, (*entry
.comment
)?entry
.comment
:"");
786 if (strchr(entry
.flags
, 'x') == NULL
)
795 if (rtn
== NOTLISTEN
) { /* check last return to see if error */
796 sprintf(mesg
, "Network specification \"%s\" is not of type %s", netspec
, LISTENTYPE
);
797 nlsmesg(MM_ERROR
, mesg
);
802 sprintf(mesg
, "Service \"%s\" unknown", svc
);
803 nlsmesg(MM_ERROR
, mesg
);
812 * disable_svc: use pmadm to disable a service
816 disable_svc(char *svc
, char *netspec
)
821 sprintf(buf
, PM_DISABLE
, netspec
, svc
);
823 if ((rtn
= system(buf
)) < 0) {
826 rtn
= (rtn
>>8) & 0xff; /* get child return value out of exit word */
844 nlsmesg(MM_ERROR
, "Non-existent service.");
856 enable_svc(char *svc
, char *netspec
)
861 sprintf(buf
, PM_ENABLE
, netspec
, svc
);
863 if ((rtn
= system(buf
)) < 0) {
866 rtn
= (rtn
>>8) & 0xff; /* get child return value out of exit word */
884 nlsmesg(MM_ERROR
, "Non-existent service.");
896 remove_svc(char *svc
, char *netspec
, int printerrors
)
901 sprintf(buf
, PM_REMSVC
, netspec
, svc
);
903 if ((rtn
= system(buf
)) < 0) {
906 rtn
= (rtn
>>8) & 0xff; /* get child return value out of exit word */
925 nlsmesg(MM_ERROR
, "Non-existent service.");
937 kill_listener(char *netspec
)
943 sprintf(buf
, SAC_KILLPM
, netspec
);
945 if ((rtn
= system(buf
)) < 0) {
948 rtn
= (rtn
>>8) & 0xff; /* get child return value out of exit word */
965 sprintf(mesg
, "No listener active on network \"%s\"", netspec
);
966 nlsmesg(MM_ERROR
, mesg
);
969 nlsmesg(MM_ERROR
, "Non-existent port monitor.");
981 * add_pm: add a port monitor (initialize directories) using sacadm
985 add_pm(char *netspec
)
991 sprintf(buf
, SAC_ADDPM
, netspec
, LISTENTYPE
, gencmdstr(netspec
), VERSION
);
993 if ((rtn
= system(buf
)) < 0) {
996 rtn
= (rtn
>>8) & 0xff; /* get child return value out of exit word */
1000 old_addsvc(NLPSSVCCODE
, NULL
, NLPSSRV
, "NLPS server", "", "root", NULL
, netspec
);
1015 nlsmesg(MM_ERROR
, "Listener already initialized");
1027 * gencmdstr: generate the correct string to invoke the listener (starlan
1028 * requires special handling)
1032 gencmdstr(char *netspec
)
1034 static char buf
[BUFSIZ
];
1036 (void) strcpy(buf
, LISTENCMD
);
1037 if (!strcmp(netspec
, "starlan"))
1038 (void) strcat(buf
, " -m slan");
1039 (void) strcat(buf
, " ");
1040 (void) strcat(buf
, netspec
);
1046 * start_listener: start the listener
1050 start_listener(char *netspec
)
1053 char scratch
[BUFSIZ
];
1056 sprintf(buf
, SAC_STARTPM
, netspec
);
1058 if ((rtn
= system(buf
)) < 0)
1060 rtn
= (rtn
>>8) & 0xff;
1075 nlsmesg(MM_ERROR
, "Non-existent port monitor.");
1079 nlsmesg(MM_ERROR
, "Listener already running");
1086 sprintf(buf
, SAC_ENABLPM
, netspec
);
1088 if ((rtn
= system(buf
)) < 0) {
1091 rtn
= (rtn
>>8) & 0xff;
1106 nlsmesg(MM_ERROR
, "Non-existent port monitor.");
1110 nlsmesg(MM_ERROR
, "Listener already running");
1113 nlsmesg(MM_ERROR
, "Listener start failed");
1124 * setup_addr: setup the -l and -t addresses.
1128 setup_addr(char *laddr
, char *taddr
, char *netspec
)
1134 int qlisten
= FALSE
;
1137 struct svcfields entry
;
1139 if (laddr
&& *laddr
== '-')
1142 if (taddr
&& *taddr
== '-')
1146 sprintf(buf
, PM_LSONE
, netspec
, NLPSSVCCODE
);
1148 if ((fp
= popen(buf
, "r")) == NULL
) {
1152 if (fgets(buf
, BUFSIZ
, fp
) != NULL
) {
1153 if ((rtn
= svc_format(buf
, &entry
)) != 0) {
1156 nlsmesg(MM_ERROR
, "Incorrect port monitor type. Must be of type listen");
1163 sprintf(mesg
, "Entry for code \"%s\" has incorrect format", entry
.svc_code
);
1164 nlsmesg(MM_WARNING
, mesg
);
1170 printf("%s\n", entry
.addr
);
1172 if (geteuid() != ROOT
)
1175 remove_svc(NLPSSVCCODE
, netspec
, FALSE
);
1176 p
= strchr(entry
.comment
, '\n');
1179 old_addsvc(NLPSSVCCODE
, laddr
, entry
.command
, entry
.comment
, entry
.modules
, entry
.id
, entry
.flags
, netspec
);
1185 nlsmesg(MM_WARNING
, "NLPS service not defined");
1188 sprintf(buf
, PM_LSONE
, netspec
, TTYSVCCODE
);
1190 if ((fp
= popen(buf
, "r")) == NULL
) {
1194 if (fgets(buf
, BUFSIZ
, fp
) != NULL
) {
1195 if ((rtn
= svc_format(buf
, &entry
)) != 0) {
1198 nlsmesg(MM_ERROR
, "Incorrect port monitor type. Must be of type listen");
1205 sprintf(mesg
, "Entry for code \"%s\" has incorrect format", entry
.svc_code
);
1206 nlsmesg(MM_WARNING
, mesg
);
1212 printf("%s\n", entry
.addr
);
1214 if (geteuid() != ROOT
)
1217 remove_svc(TTYSVCCODE
, netspec
, FALSE
);
1218 p
= strchr(entry
.comment
, '\n');
1221 old_addsvc(TTYSVCCODE
, taddr
, entry
.command
, entry
.comment
, entry
.modules
, entry
.id
, entry
.flags
, netspec
);
1227 nlsmesg(MM_WARNING
, "remote login service not defined");
1234 * svc_format: scan a line of output from pmadm to separate it into fields.
1235 * returns BADPMFMT for missing fields or incorrect syntax.
1236 * NOTLISTEN is the port monitor type is not listen.
1237 * BADLISFMT if the listener-specific data is incorrect.
1238 * NLS_OK if everything checked out and data is broken
1239 * into the structure.
1243 svc_format(char *buf
, struct svcfields
*entry
)
1245 char *ptr
; /* temporary pointer into buffer */
1246 char *tmp
; /* temporary pointer into buffer */
1249 if ((ptr
= strchr(buf
, ':')) == NULL
)
1252 entry
->pmtype
= ptr
;
1253 if ((ptr
= strchr(entry
->pmtype
, ':')) == NULL
)
1256 entry
->svc_code
= ptr
;
1258 if (strcmp(entry
->pmtype
, LISTENTYPE
) != 0)
1261 if ((ptr
= strchr(entry
->svc_code
, ':')) == NULL
)
1265 if ((ptr
= strchr(entry
->flags
, ':')) == NULL
)
1269 if ((ptr
= strchr(entry
->id
, ':')) == NULL
)
1273 if ((ptr
= strchr(entry
->res1
, ':')) == NULL
)
1277 if ((ptr
= strchr(entry
->res2
, ':')) == NULL
)
1281 if ((ptr
= strchr(entry
->res3
, ':')) == NULL
)
1285 if ((ptr
= strchr(entry
->addr
, ':')) == NULL
)
1289 if ((ptr
= strchr(entry
->rpc
, ':')) == NULL
)
1293 if ((tmp
= strchr(entry
->rpc
, ',')) == NULL
)
1297 entry
->lflags
= ptr
;
1298 if ((ptr
= strchr(entry
->lflags
, ':')) == NULL
)
1301 entry
->modules
= ptr
;
1302 if ((ptr
= strchr(entry
->modules
, ':')) == NULL
)
1305 entry
->command
= ptr
;
1306 if ((ptr
= strchr(entry
->command
, '#')) == NULL
)
1309 entry
->comment
= ptr
;
1315 * nexttok - return next token, essentially a strtok, but it can
1316 * deal with null fields and strtok can not
1318 * args: str - the string to be examined, NULL if we should
1319 * examine the remembered string
1320 * delim - the list of valid delimiters
1325 nexttok(char *str
, char *delim
)
1327 static char *savep
; /* the remembered string */
1328 register char *p
; /* pointer to start of token */
1329 register char *ep
; /* pointer to end of token */
1331 p
= (str
== NULL
) ? savep
: str
;
1334 ep
= strpbrk(p
, delim
);
1346 * pflags - put flags into intelligible form for output
1348 * args: flags - binary representation of flags
1354 register int i
; /* scratch counter */
1355 static char buf
[BUFSIZ
]; /* formatted flags */
1360 if (flags
& CFLAG
) {
1364 if (flags
& DFLAG
) {
1368 if (flags
& PFLAG
) {
1373 nlsmesg(MM_ERROR
, "Internal error in pflags");