Home | History | Annotate | Line # | Download | only in rpc.pcnfsd
pcnfsd_misc.c revision 1.13
      1  1.13    plunky /*	$NetBSD: pcnfsd_misc.c,v 1.13 2011/08/31 16:24:59 plunky Exp $	*/
      2   1.2       gwr 
      3   1.1       jtc /* RE_SID: @(%)/usr/dosnfs/shades_SCCS/unix/pcnfsd/v2/src/SCCS/s.pcnfsd_misc.c 1.5 92/01/24 19:59:13 SMI */
      4   1.1       jtc /*
      5   1.1       jtc **=====================================================================
      6   1.1       jtc ** Copyright (c) 1986,1987,1988,1989,1990,1991 by Sun Microsystems, Inc.
      7   1.1       jtc **	@(#)pcnfsd_misc.c	1.5	1/24/92
      8   1.1       jtc **=====================================================================
      9   1.1       jtc */
     10   1.1       jtc /*
     11   1.1       jtc **=====================================================================
     12   1.1       jtc **             I N C L U D E   F I L E   S E C T I O N                *
     13   1.1       jtc **                                                                    *
     14   1.1       jtc ** If your port requires different include files, add a suitable      *
     15   1.1       jtc ** #define in the customization section, and make the inclusion or    *
     16   1.1       jtc ** exclusion of the files conditional on this.                        *
     17   1.1       jtc **=====================================================================
     18   1.1       jtc */
     19   1.1       jtc 
     20   1.1       jtc #include <sys/file.h>
     21   1.3     lukem #include <sys/ioctl.h>
     22   1.3     lukem #include <sys/socket.h>
     23   1.3     lukem #include <sys/stat.h>
     24   1.1       jtc #include <sys/time.h>
     25   1.3     lukem #include <sys/wait.h>
     26   1.3     lukem 
     27   1.3     lukem #include <netinet/in.h>
     28   1.3     lukem #include <arpa/inet.h>
     29   1.3     lukem 
     30   1.3     lukem #include <ctype.h>
     31   1.3     lukem #include <errno.h>
     32   1.1       jtc #include <netdb.h>
     33   1.3     lukem #include <pwd.h>
     34   1.3     lukem #include <signal.h>
     35   1.3     lukem #include <stdio.h>
     36   1.3     lukem #include <stdlib.h>
     37   1.1       jtc #include <string.h>
     38   1.3     lukem #include <unistd.h>
     39   1.6  christos #include <util.h>
     40   1.1       jtc 
     41   1.1       jtc #ifdef ISC_2_0
     42   1.1       jtc #include <sys/fcntl.h>
     43   1.1       jtc #endif
     44   1.1       jtc 
     45   1.1       jtc #ifdef SHADOW_SUPPORT
     46   1.1       jtc #include <shadow.h>
     47   1.1       jtc #endif
     48   1.1       jtc 
     49   1.1       jtc #ifdef WTMP
     50   1.3     lukem int     wtmp_enabled = 1;
     51   1.1       jtc #endif
     52   1.1       jtc 
     53   1.3     lukem #include "common.h"
     54   1.3     lukem #include "pcnfsd.h"
     55   1.3     lukem #include "extern.h"
     56   1.1       jtc 
     57   1.1       jtc /*
     58   1.1       jtc **---------------------------------------------------------------------
     59   1.3     lukem ** Other #define's
     60   1.1       jtc **---------------------------------------------------------------------
     61   1.1       jtc */
     62   1.1       jtc 
     63   1.1       jtc #define	zchar		0x5b
     64   1.1       jtc 
     65   1.3     lukem char    tempstr[256];
     66   1.3     lukem 
     67   1.3     lukem char   *mapfont __P((char, char, char));
     68   1.3     lukem void	myhandler __P((int));
     69   1.3     lukem void	start_watchdog __P((int));
     70   1.3     lukem void	stop_watchdog __P((void));
     71   1.1       jtc 
     72   1.1       jtc /*
     73   1.1       jtc **=====================================================================
     74   1.3     lukem **                      C O D E   S E C T I O N                       *
     75   1.3     lukem **=====================================================================
     76   1.1       jtc */
     77   1.1       jtc /*
     78   1.1       jtc **---------------------------------------------------------------------
     79   1.3     lukem **                          Support procedures
     80   1.1       jtc **---------------------------------------------------------------------
     81   1.1       jtc */
     82   1.1       jtc 
     83   1.1       jtc 
     84   1.1       jtc void
     85   1.1       jtc scramble(s1, s2)
     86   1.3     lukem 	char   *s1;
     87   1.3     lukem 	char   *s2;
     88   1.1       jtc {
     89   1.3     lukem 	while (*s1) {
     90   1.3     lukem 		*s2++ = (*s1 ^ zchar) & 0x7f;
     91   1.3     lukem 		s1++;
     92   1.3     lukem 	}
     93   1.1       jtc 	*s2 = 0;
     94   1.1       jtc }
     95   1.1       jtc 
     96   1.1       jtc 
     97   1.1       jtc 
     98   1.3     lukem struct passwd *
     99   1.1       jtc get_password(usrnam)
    100   1.3     lukem 	char   *usrnam;
    101   1.1       jtc {
    102   1.3     lukem 	struct passwd *p;
    103   1.3     lukem 	static struct passwd localp;
    104   1.5   mycroft 	__aconst char *pswd, *ushell;
    105   1.1       jtc 
    106   1.1       jtc 
    107   1.1       jtc #ifdef SHADOW_SUPPORT
    108   1.3     lukem 	struct spwd *sp;
    109   1.3     lukem 	int     shadowfile;
    110   1.1       jtc #endif
    111   1.1       jtc 
    112   1.1       jtc #ifdef SHADOW_SUPPORT
    113   1.3     lukem /*
    114   1.3     lukem **--------------------------------------------------------------
    115   1.3     lukem ** Check the existence of SHADOW.  If it is there, then we are
    116   1.3     lukem ** running a two-password-file system.
    117   1.3     lukem **--------------------------------------------------------------
    118   1.3     lukem */
    119   1.1       jtc 	if (access(SHADOW, 0))
    120   1.3     lukem 		shadowfile = 0;	/* SHADOW is not there */
    121   1.1       jtc 	else
    122   1.3     lukem 		shadowfile = 1;
    123   1.1       jtc 
    124   1.1       jtc 	setpwent();
    125   1.1       jtc 	if (shadowfile)
    126   1.3     lukem 		(void) setspent();	/* Setting the shadow password file */
    127  1.13    plunky 	if ((p = getpwnam(usrnam)) == NULL ||
    128  1.13    plunky 	    (shadowfile && (sp = getspnam(usrnam)) == NULL))
    129  1.13    plunky 		return (NULL);
    130   1.3     lukem 
    131   1.3     lukem 	if (shadowfile) {
    132   1.3     lukem 		pswd = sp->sp_pwdp;
    133   1.3     lukem 		(void) endspent();
    134   1.3     lukem 	} else
    135   1.3     lukem 		pswd = p->pw_passwd;
    136   1.1       jtc 
    137   1.1       jtc #else
    138   1.1       jtc 	p = getpwnam(usrnam);
    139  1.13    plunky 	if (p == NULL)
    140  1.13    plunky 		return (NULL);
    141   1.1       jtc 	pswd = p->pw_passwd;
    142   1.1       jtc #endif
    143   1.1       jtc 
    144   1.1       jtc #ifdef ISC_2_0
    145   1.3     lukem /* *----------------------------------------------------------- * We
    146   1.3     lukem  * may have an 'x' in which case look in /etc/shadow ..
    147   1.3     lukem  * *----------------------------------------------------------- */
    148   1.3     lukem 	if (((strlen(pswd)) == 1) && pswd[0] == 'x') {
    149   1.3     lukem 		struct spwd *shadow = getspnam(usrnam);
    150   1.3     lukem 
    151   1.3     lukem 		if (!shadow)
    152  1.13    plunky 			return (NULL);
    153   1.3     lukem 		pswd = shadow->sp_pwdp;
    154   1.3     lukem 	}
    155   1.1       jtc #endif
    156   1.1       jtc 	localp = *p;
    157   1.1       jtc 	localp.pw_passwd = pswd;
    158   1.1       jtc #ifdef USE_GETUSERSHELL
    159   1.1       jtc 
    160   1.1       jtc 	setusershell();
    161   1.3     lukem 	while (ushell = getusershell()) {
    162   1.3     lukem 		if (!strcmp(ushell, localp.pw_shell)) {
    163   1.1       jtc 			ok = 1;
    164   1.1       jtc 			break;
    165   1.1       jtc 		}
    166   1.1       jtc 	}
    167   1.1       jtc 	endusershell();
    168   1.3     lukem 	if (!ok)
    169  1.13    plunky 		return (NULL);
    170   1.1       jtc #else
    171   1.1       jtc /*
    172   1.3     lukem * the best we can do is to ensure that the shell ends in "sh"
    173   1.3     lukem */
    174   1.1       jtc 	ushell = localp.pw_shell;
    175   1.3     lukem 	if (strlen(ushell) < 2)
    176  1.13    plunky 		return (NULL);
    177   1.1       jtc 	ushell += strlen(ushell) - 2;
    178   1.3     lukem 	if (strcmp(ushell, "sh"))
    179  1.13    plunky 		return (NULL);
    180   1.1       jtc 
    181   1.1       jtc #endif
    182   1.1       jtc 	return (&localp);
    183   1.1       jtc }
    184   1.1       jtc 
    185   1.3     lukem 
    186   1.3     lukem 
    187   1.1       jtc /*
    188   1.1       jtc **---------------------------------------------------------------------
    189   1.3     lukem **                      Print support procedures
    190   1.1       jtc **---------------------------------------------------------------------
    191   1.1       jtc */
    192   1.1       jtc 
    193   1.3     lukem 
    194   1.3     lukem char   *
    195  1.12  drochner mapfont(char f, char i, char b)
    196   1.1       jtc {
    197   1.3     lukem 	static char fontname[64];
    198   1.1       jtc 
    199   1.1       jtc 	fontname[0] = 0;	/* clear it out */
    200   1.1       jtc 
    201   1.1       jtc 	switch (f) {
    202   1.1       jtc 	case 'c':
    203  1.10    itojun 		(void) strlcpy(fontname, "Courier", sizeof(fontname));
    204   1.1       jtc 		break;
    205   1.1       jtc 	case 'h':
    206  1.10    itojun 		(void) strlcpy(fontname, "Helvetica", sizeof(fontname));
    207   1.1       jtc 		break;
    208   1.1       jtc 	case 't':
    209  1.10    itojun 		(void) strlcpy(fontname, "Times", sizeof(fontname));
    210   1.1       jtc 		break;
    211   1.1       jtc 	default:
    212  1.10    itojun 		(void) strlcpy(fontname, "Times-Roman", sizeof(fontname));
    213   1.3     lukem 		goto finis;
    214   1.1       jtc 	}
    215   1.1       jtc 	if (i != 'o' && b != 'b') {	/* no bold or oblique */
    216   1.1       jtc 		if (f == 't')	/* special case Times */
    217  1.10    itojun 			(void) strlcat(fontname, "-Roman", sizeof(fontname));
    218   1.1       jtc 		goto finis;
    219   1.1       jtc 	}
    220  1.10    itojun 	(void) strlcat(fontname, "-", sizeof(fontname));
    221   1.1       jtc 	if (b == 'b')
    222  1.10    itojun 		(void) strlcat(fontname, "Bold", sizeof(fontname));
    223   1.1       jtc 	if (i == 'o')		/* o-blique */
    224  1.10    itojun 		(void) strlcat(fontname, f == 't' ? "Italic" : "Oblique",
    225  1.10    itojun 		    sizeof(fontname));
    226   1.1       jtc 
    227   1.1       jtc finis:	return (&fontname[0]);
    228   1.1       jtc }
    229   1.1       jtc /*
    230   1.3     lukem * run_ps630 performs the Diablo 630 emulation filtering process. ps630
    231   1.3     lukem * was broken in certain Sun releases: it would not accept point size or
    232   1.3     lukem * font changes. If your version is fixed, undefine the symbol
    233   1.3     lukem * PS630_IS_BROKEN and rebuild pc-nfsd.
    234   1.3     lukem */
    235   1.1       jtc /* #define PS630_IS_BROKEN 1 */
    236   1.1       jtc 
    237   1.1       jtc void
    238   1.1       jtc run_ps630(f, opts)
    239   1.3     lukem 	char   *f;
    240   1.3     lukem 	char   *opts;
    241   1.1       jtc {
    242   1.3     lukem 	char    temp_file[256];
    243   1.3     lukem 	char    commbuf[256];
    244   1.3     lukem 	int     i;
    245   1.1       jtc 
    246  1.10    itojun 	(void) strlcpy(temp_file, f, sizeof(temp_file));
    247  1.10    itojun 	(void) strlcat(temp_file, "X", sizeof(temp_file)); /* intermediate file name */
    248   1.1       jtc 
    249   1.1       jtc #ifndef PS630_IS_BROKEN
    250  1.10    itojun 	(void) snprintf(commbuf, sizeof(commbuf), "ps630 -s %c%c -p %s -f ",
    251   1.3     lukem 	    opts[2], opts[3], temp_file);
    252  1.10    itojun 	(void) strlcat(commbuf, mapfont(opts[4], opts[5], opts[6]),
    253  1.10    itojun 	    sizeof(commbuf));
    254  1.10    itojun 	(void) strlcat(commbuf, " -F ", sizeof(commbuf));
    255  1.10    itojun 	(void) strlcat(commbuf, mapfont(opts[7], opts[8], opts[9]),
    256  1.10    itojun 	    sizeof(commbuf));
    257  1.10    itojun 	(void) strlcat(commbuf, "  ", sizeof(commbuf));
    258  1.10    itojun 	(void) strlcat(commbuf, f, sizeof(commbuf));
    259   1.3     lukem #else				/* PS630_IS_BROKEN */
    260   1.3     lukem /*
    261   1.3     lukem  * The pitch and font features of ps630 appear to be broken at
    262   1.3     lukem  * this time.
    263   1.3     lukem  */
    264  1.10    itojun 	(void) snprintf(commbuf, sizeof(commbuf), "ps630 -p %s %s",
    265  1.10    itojun 	    temp_file, f);
    266   1.3     lukem #endif				/* PS630_IS_BROKEN */
    267   1.1       jtc 
    268   1.1       jtc 
    269   1.3     lukem 	if ((i = system(commbuf)) != 0) {
    270   1.1       jtc 		/*
    271   1.1       jtc 		 * Under (un)certain conditions, ps630 may return -1 even
    272   1.1       jtc 		 * if it worked. Hence the commenting out of this error
    273   1.1       jtc 		 * report.
    274   1.1       jtc 		 */
    275   1.1       jtc 		 /* (void)fprintf(stderr, "\n\nrun_ps630 rc = %d\n", i) */ ;
    276   1.1       jtc 		/* exit(1); */
    277   1.1       jtc 	}
    278   1.1       jtc 	if (rename(temp_file, f)) {
    279   1.1       jtc 		perror("run_ps630: rename");
    280   1.1       jtc 		exit(1);
    281   1.1       jtc 	}
    282   1.1       jtc 	return;
    283   1.1       jtc }
    284   1.1       jtc 
    285   1.1       jtc 
    286   1.1       jtc 
    287   1.3     lukem 
    288   1.3     lukem 
    289   1.1       jtc /*
    290   1.1       jtc **---------------------------------------------------------------------
    291   1.3     lukem **                      WTMP update support
    292   1.1       jtc **---------------------------------------------------------------------
    293   1.1       jtc */
    294   1.1       jtc 
    295   1.1       jtc 
    296   1.1       jtc #ifdef WTMP
    297   1.1       jtc void
    298   1.1       jtc wlogin(name, req)
    299   1.3     lukem 	char   *name;
    300   1.1       jtc 	struct svc_req *req;
    301   1.1       jtc {
    302   1.1       jtc 	struct sockaddr_in *who;
    303   1.1       jtc 	struct hostent *hp;
    304   1.6  christos 	char *host;
    305   1.1       jtc 
    306   1.3     lukem 	if (!wtmp_enabled)
    307   1.1       jtc 		return;
    308   1.1       jtc 
    309   1.3     lukem /* Get network address of client. */
    310   1.1       jtc 	who = &req->rq_xprt->xp_raddr;
    311   1.1       jtc 
    312   1.3     lukem /* Get name of connected client */
    313   1.3     lukem 	hp = gethostbyaddr((char *) &who->sin_addr,
    314   1.3     lukem 	    sizeof(struct in_addr),
    315   1.3     lukem 	    who->sin_family);
    316   1.1       jtc 
    317   1.6  christos 	if (hp) {
    318   1.1       jtc 		host = hp->h_name;
    319   1.1       jtc 	} else {
    320   1.1       jtc 		host = inet_ntoa(who->sin_addr);
    321   1.1       jtc 	}
    322   1.1       jtc 
    323   1.6  christos #ifdef SUPPORT_UTMP
    324   1.7  christos 	logwtmp("PC-NFS", name, host);
    325   1.6  christos #endif
    326   1.6  christos #ifdef SUPPORT_UTMPX
    327   1.8  christos 	logwtmpx("PC-NFS", name, host, 0, USER_PROCESS);
    328   1.6  christos #endif
    329   1.1       jtc }
    330   1.3     lukem #endif				/* WTMP */
    331   1.3     lukem 
    332   1.3     lukem 
    333   1.1       jtc /*
    334   1.1       jtc **---------------------------------------------------------------------
    335   1.3     lukem **                      Run-process-as-user procedures
    336   1.1       jtc **---------------------------------------------------------------------
    337   1.1       jtc */
    338   1.1       jtc 
    339   1.1       jtc 
    340   1.1       jtc #define	READER_FD	0
    341   1.1       jtc #define	WRITER_FD	1
    342   1.1       jtc 
    343   1.3     lukem static int child_pid;
    344   1.1       jtc 
    345   1.3     lukem static char cached_user[64] = "";
    346   1.3     lukem static uid_t cached_uid;
    347   1.3     lukem static gid_t cached_gid;
    348   1.3     lukem 
    349   1.3     lukem static struct sigaction old_action;
    350   1.3     lukem static struct sigaction new_action;
    351   1.3     lukem static struct itimerval timer;
    352   1.1       jtc 
    353   1.3     lukem int     interrupted = 0;
    354   1.3     lukem static FILE *pipe_handle;
    355   1.1       jtc 
    356   1.3     lukem void
    357   1.3     lukem myhandler(dummy)
    358   1.3     lukem 	int     dummy;
    359   1.1       jtc {
    360   1.3     lukem 	interrupted = 1;
    361   1.3     lukem 	fclose(pipe_handle);
    362   1.3     lukem 	kill(child_pid, SIGKILL);
    363   1.3     lukem 	msg_out("rpc.pcnfsd: su_popen timeout - killed child process");
    364   1.1       jtc }
    365   1.1       jtc 
    366   1.3     lukem void
    367   1.3     lukem start_watchdog(n)
    368   1.3     lukem 	int     n;
    369   1.1       jtc {
    370   1.3     lukem /*
    371   1.3     lukem  * Setup SIGALRM handler, force interrupt of ongoing syscall
    372   1.3     lukem  */
    373   1.1       jtc 
    374   1.1       jtc 	new_action.sa_handler = myhandler;
    375   1.1       jtc 	sigemptyset(&(new_action.sa_mask));
    376   1.1       jtc 	new_action.sa_flags = 0;
    377   1.1       jtc #ifdef SA_INTERRUPT
    378   1.1       jtc 	new_action.sa_flags |= SA_INTERRUPT;
    379   1.1       jtc #endif
    380   1.1       jtc 	sigaction(SIGALRM, &new_action, &old_action);
    381   1.1       jtc 
    382   1.3     lukem /*
    383   1.3     lukem  * Set interval timer for n seconds
    384   1.3     lukem  */
    385   1.1       jtc 	timer.it_interval.tv_sec = 0;
    386   1.1       jtc 	timer.it_interval.tv_usec = 0;
    387   1.1       jtc 	timer.it_value.tv_sec = n;
    388   1.1       jtc 	timer.it_value.tv_usec = 0;
    389   1.1       jtc 	setitimer(ITIMER_REAL, &timer, NULL);
    390   1.1       jtc 	interrupted = 0;
    391   1.1       jtc 
    392   1.1       jtc }
    393   1.1       jtc 
    394   1.3     lukem void
    395   1.3     lukem stop_watchdog()
    396   1.1       jtc {
    397   1.3     lukem /*
    398   1.3     lukem  * Cancel timer
    399   1.3     lukem  */
    400   1.1       jtc 
    401   1.1       jtc 	timer.it_interval.tv_sec = 0;
    402   1.1       jtc 	timer.it_interval.tv_usec = 0;
    403   1.1       jtc 	timer.it_value.tv_sec = 0;
    404   1.1       jtc 	timer.it_value.tv_usec = 0;
    405   1.1       jtc 	setitimer(ITIMER_REAL, &timer, NULL);
    406   1.1       jtc 
    407   1.3     lukem /*
    408   1.3     lukem  * restore old signal handling
    409   1.3     lukem  */
    410   1.1       jtc 	sigaction(SIGALRM, &old_action, NULL);
    411   1.1       jtc }
    412   1.1       jtc 
    413   1.3     lukem FILE   *
    414   1.1       jtc su_popen(user, cmd, maxtime)
    415   1.3     lukem 	char   *user;
    416   1.3     lukem 	char   *cmd;
    417   1.3     lukem 	int     maxtime;
    418   1.1       jtc {
    419   1.3     lukem 	int     p[2];
    420   1.3     lukem 	int     parent_fd, child_fd, pid;
    421   1.1       jtc 	struct passwd *pw;
    422   1.1       jtc 
    423   1.1       jtc 	if (strcmp(cached_user, user)) {
    424   1.1       jtc 		pw = getpwnam(user);
    425   1.1       jtc 		if (!pw)
    426   1.1       jtc 			pw = getpwnam("nobody");
    427   1.1       jtc 		if (pw) {
    428   1.1       jtc 			cached_uid = pw->pw_uid;
    429   1.1       jtc 			cached_gid = pw->pw_gid;
    430  1.10    itojun 			strlcpy(cached_user, user, sizeof(cached_user));
    431   1.1       jtc 		} else {
    432   1.1       jtc 			cached_uid = (uid_t) (-2);
    433   1.1       jtc 			cached_gid = (gid_t) (-2);
    434   1.1       jtc 			cached_user[0] = '\0';
    435   1.1       jtc 		}
    436   1.1       jtc 	}
    437   1.1       jtc 	if (pipe(p) < 0) {
    438   1.1       jtc 		msg_out("rpc.pcnfsd: unable to create pipe in su_popen");
    439   1.1       jtc 		return (NULL);
    440   1.1       jtc 	}
    441   1.1       jtc 	parent_fd = p[READER_FD];
    442   1.1       jtc 	child_fd = p[WRITER_FD];
    443   1.1       jtc 	if ((pid = fork()) == 0) {
    444   1.3     lukem 		int     i;
    445   1.1       jtc 
    446   1.1       jtc 		for (i = 0; i < 10; i++)
    447   1.1       jtc 			if (i != child_fd)
    448   1.1       jtc 				(void) close(i);
    449   1.1       jtc 		if (child_fd != 1) {
    450   1.1       jtc 			(void) dup2(child_fd, 1);
    451   1.1       jtc 			(void) close(child_fd);
    452   1.1       jtc 		}
    453   1.1       jtc 		dup2(1, 2);	/* let's get stderr as well */
    454   1.1       jtc 
    455   1.1       jtc 		(void) setgid(cached_gid);
    456   1.1       jtc 		(void) setuid(cached_uid);
    457   1.1       jtc 
    458  1.13    plunky 		(void) execl("/bin/sh", "sh", "-c", cmd, NULL);
    459   1.1       jtc 		_exit(255);
    460   1.1       jtc 	}
    461   1.1       jtc 	if (pid == -1) {
    462   1.1       jtc 		msg_out("rpc.pcnfsd: fork failed");
    463   1.1       jtc 		close(parent_fd);
    464   1.1       jtc 		close(child_fd);
    465   1.1       jtc 		return (NULL);
    466   1.1       jtc 	}
    467   1.1       jtc 	child_pid = pid;
    468   1.1       jtc 	close(child_fd);
    469   1.1       jtc 	start_watchdog(maxtime);
    470   1.1       jtc 	pipe_handle = fdopen(parent_fd, "r");
    471   1.1       jtc 	return (pipe_handle);
    472   1.1       jtc }
    473   1.1       jtc 
    474   1.1       jtc int
    475   1.1       jtc su_pclose(ptr)
    476   1.3     lukem 	FILE   *ptr;
    477   1.1       jtc {
    478   1.3     lukem 	int     pid, status;
    479   1.1       jtc 
    480   1.1       jtc 	stop_watchdog();
    481   1.1       jtc 
    482   1.1       jtc 	fclose(ptr);
    483   1.1       jtc 	if (child_pid == -1)
    484   1.1       jtc 		return (-1);
    485   1.1       jtc 	while ((pid = wait(&status)) != child_pid && pid != -1);
    486   1.1       jtc 	return (pid == -1 ? -1 : status);
    487   1.1       jtc }
    488   1.1       jtc 
    489   1.3     lukem 
    490   1.3     lukem 
    491   1.1       jtc /*
    492   1.1       jtc ** The following routine reads a file "/etc/pcnfsd.conf" if present,
    493   1.1       jtc ** and uses it to replace certain builtin elements, like the
    494   1.1       jtc ** name of the print spool directory. The configuration file
    495   1.1       jtc ** Is the usual kind: Comments begin with '#', blank lines are ignored,
    496   1.1       jtc ** and valid lines are of the form
    497   1.1       jtc **
    498   1.1       jtc **	<keyword><whitespace><value>
    499   1.1       jtc **
    500   1.1       jtc ** The following keywords are recognized:
    501   1.1       jtc **
    502   1.1       jtc **	spooldir
    503   1.1       jtc **	printer name alias-for command
    504   1.1       jtc **	wtmp yes|no
    505   1.1       jtc */
    506  1.11  dholland static void
    507  1.11  dholland config_from_file(void)
    508   1.1       jtc {
    509   1.3     lukem 	FILE   *fd;
    510   1.3     lukem 	char    buff[1024];
    511   1.3     lukem 	char   *cp;
    512   1.3     lukem 	char   *kw;
    513   1.3     lukem 	char   *val;
    514   1.3     lukem 	char   *arg1;
    515   1.3     lukem 	char   *arg2;
    516   1.1       jtc 
    517   1.3     lukem 	if ((fd = fopen("/etc/pcnfsd.conf", "r")) == NULL)
    518   1.1       jtc 		return;
    519   1.3     lukem 	while (fgets(buff, 1024, fd)) {
    520   1.1       jtc 		cp = strchr(buff, '\n');
    521   1.1       jtc 		*cp = '\0';
    522   1.1       jtc 		cp = strchr(buff, '#');
    523   1.3     lukem 		if (cp)
    524   1.1       jtc 			*cp = '\0';
    525   1.1       jtc 		kw = strtok(buff, " \t");
    526   1.3     lukem 		if (kw == NULL)
    527   1.1       jtc 			continue;
    528   1.1       jtc 		val = strtok(NULL, " \t");
    529   1.3     lukem 		if (val == NULL)
    530   1.1       jtc 			continue;
    531   1.3     lukem 		if (!strcasecmp(kw, "spooldir")) {
    532  1.10    itojun 			strlcpy(sp_name, val, sizeof(sp_name));
    533   1.1       jtc 			continue;
    534   1.1       jtc 		}
    535   1.1       jtc #ifdef WTMP
    536   1.3     lukem 		if (!strcasecmp(kw, "wtmp")) {
    537   1.1       jtc 			/* assume default is YES, just look for negatives */
    538   1.3     lukem 			if (!strcasecmp(val, "no") ||
    539   1.3     lukem 			    !strcasecmp(val, "off") ||
    540   1.3     lukem 			    !strcasecmp(val, "disable") ||
    541   1.3     lukem 			    !strcmp(val, "0"))
    542   1.9    simonb 				wtmp_enabled = 0;
    543   1.1       jtc 			continue;
    544   1.1       jtc 		}
    545   1.3     lukem #endif
    546   1.3     lukem 		if (!strcasecmp(kw, "printer")) {
    547   1.1       jtc 			arg1 = strtok(NULL, " \t");
    548   1.1       jtc 			arg2 = strtok(NULL, "");
    549   1.3     lukem 			(void) add_printer_alias(val, arg1, arg2);
    550   1.1       jtc 			continue;
    551   1.1       jtc 		}
    552   1.1       jtc /*
    553   1.1       jtc ** Add new cases here
    554   1.1       jtc */
    555   1.1       jtc 	}
    556   1.1       jtc 	fclose(fd);
    557   1.1       jtc }
    558   1.1       jtc 
    559  1.11  dholland /*
    560  1.11  dholland ** hack for main() - call config_from_file() then the real main
    561  1.11  dholland ** in the rpcgen output, which is hacked by CPPFLAGS to be "mymain"
    562  1.11  dholland */
    563  1.11  dholland #undef main
    564  1.11  dholland 
    565  1.11  dholland int mymain(int argc, char *argv[]);
    566  1.11  dholland 
    567  1.11  dholland int
    568  1.11  dholland main(int argc, char *argv[])
    569  1.11  dholland {
    570  1.11  dholland 	config_from_file();
    571  1.11  dholland 	return mymain(argc, argv);
    572  1.11  dholland }
    573   1.1       jtc 
    574   1.1       jtc /*
    575   1.1       jtc ** strembedded - returns true if s1 is embedded (in any case) in s2
    576   1.1       jtc */
    577   1.1       jtc 
    578   1.3     lukem int
    579   1.3     lukem strembedded(s1, s2)
    580   1.3     lukem 	const char   *s1;
    581   1.3     lukem 	const char   *s2;
    582   1.1       jtc {
    583   1.3     lukem 	while (*s2) {
    584   1.3     lukem 		if (!strcasecmp(s1, s2))
    585   1.1       jtc 			return 1;
    586   1.1       jtc 		s2++;
    587   1.1       jtc 	}
    588   1.1       jtc 	return 0;
    589   1.1       jtc }
    590