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