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