source: trunk/athena/bin/lpr/lpd.c @ 8159

Revision 8159, 17.4 KB checked in by miki, 29 years ago (diff)
Solaris2.4 does not export anymore validuser
Line 
1/*
2 *      $Source: /afs/dev.mit.edu/source/repository/athena/bin/lpr/lpd.c,v $
3 *      $Author: miki $
4 *      $Locker:  $
5 *      $Header: /afs/dev.mit.edu/source/repository/athena/bin/lpr/lpd.c,v 1.19 1995-11-30 19:42:37 miki Exp $
6 */
7
8/*
9 * Copyright (c) 1983 Regents of the University of California.
10 * All rights reserved.  The Berkeley software License Agreement
11 * specifies the terms and conditions for redistribution.
12 */
13
14#ifndef lint
15char copyright[] =
16"@(#) Copyright (c) 1983 Regents of the University of California.\n\
17 All rights reserved.\n";
18
19static char sccsid[] = "@(#)lpd.c       5.4 (Berkeley) 5/6/86";
20static char *rcsid_lpd_c = "$Id: lpd.c,v 1.19 1995-11-30 19:42:37 miki Exp $";
21#endif
22
23/*
24 * lpd -- line printer daemon.
25 *
26 * Listen for a connection and perform the requested operation.
27 * Operations are:
28 *      \1printer\n
29 *              check the queue for jobs and print any found.
30 *      \2printer\n
31 *              receive a job from another machine and queue it.
32 *      \3printer [users ...] [jobs ...]\n
33 *              return the current state of the queue (short form).
34 *      \4printer [users ...] [jobs ...]\n
35 *              return the current state of the queue (long form).
36 *      \5printer person [users ...] [jobs ...]\n
37 *              remove jobs from the queue.
38 *      kprinter\nkerberos credentials
39 *              Uses kerberos authentication
40 *
41 * Strategy to maintain protected spooling area:
42 *      1. Spooling area is writable only by daemon and spooling group
43 *      2. lpr runs setuid root and setgrp spooling group; it uses
44 *         root to access any file it wants (verifying things before
45 *         with an access call) and group id to know how it should
46 *         set up ownership of files in the spooling area.
47 *      3. Files in spooling area are owned by root, group spooling
48 *         group, with mode 660.
49 *      4. lpd, lpq and lprm run setuid daemon and setgrp spooling group to
50 *         access files and printer.  Users can't get to anything
51 *         w/o help of lpq and lprm programs.
52 */
53
54#include "lp.h"
55#ifdef POSIX
56#if !defined(ultrix)
57#include "posix.h"    /* for flock() */
58#endif
59#else
60#include "nonposix.h"
61#endif
62#ifdef ZEPHYR
63#undef STAT
64#include <zephyr/zephyr.h>
65#endif
66
67int     lflag;                          /* log requests flag */
68
69void reapchild();
70void mcleanup();
71
72#ifdef KERBEROS
73KTEXT_ST kticket;
74AUTH_DAT kdata;
75int kauth;
76int sin_len;
77struct sockaddr_in faddr;
78char krbname[ANAME_SZ + INST_SZ + REALM_SZ + 3];
79char kprincipal[ANAME_SZ];
80char kinstance[INST_SZ];
81char krealm[REALM_SZ];
82char local_realm[REALM_SZ];
83char kversion[9];
84int kflag;                     /* Is the current job authentc */
85int kerror;                    /* They tried sending auth, but it failed */
86int kerberos_override = -1;    /* Does command option override KA in printcap? */
87int kerberos_cf = 0;           /* Are we using a kerberized cf file? */
88int use_kerberos;
89#endif KERBEROS
90
91#ifdef LACL
92char from_host[MAXHOSTNAMELEN];
93#endif
94
95main(argc, argv)
96        int argc;
97        char **argv;
98{
99        int f, funix, finet, options=0, defreadfds, fromlen;
100        struct sockaddr_un sockun, fromunix;
101        struct sockaddr_in sin, frominet;
102        struct hostent *hp;
103        int  lfd;
104#if defined(POSIX) && !defined(ultrix)
105        sigset_t omask, mask;
106#else
107        int omask;
108#endif
109
110#ifdef ZEPHYR
111        ZInitialize();
112#endif ZEPHYR
113
114        gethostname(host, sizeof(host));
115        if(hp = gethostbyname(host)) strcpy(host, hp -> h_name);
116
117        name = argv[0];
118
119        while (--argc > 0) {
120                argv++;
121                if (argv[0][0] == '-')
122                        switch (argv[0][1]) {
123                        case 'd':
124                                options |= SO_DEBUG;
125                                break;
126                        case 'l':
127                                lflag++;
128                                break;
129#ifdef KERBEROS
130                        case 'u':
131                                kerberos_override = 0;
132                                break;
133                        case 'k':
134                                kerberos_override = 1;
135                                break;
136#endif KERBEROS
137                        }
138        }
139#ifndef DEBUG
140        /*
141         * Set up standard environment by detaching from the parent.
142         */
143        if (fork())
144                exit(0);
145        for (f = 0; f < 5; f++)
146                (void) close(f);
147        (void) open("/dev/null", O_RDONLY);
148        (void) open("/dev/null", O_WRONLY);
149        (void) dup(1);
150#if !defined(SOLARIS) && !defined(_AIX)
151        f = open("/dev/tty", O_RDWR);
152        if (f > 0) {
153                ioctl(f, TIOCNOTTY, 0);
154                (void) close(f);
155        } 
156#endif
157#endif
158
159#ifdef LOG_LPR
160        openlog("lpd", LOG_PID, LOG_LPR);
161#else
162        openlog("lpd", LOG_PID);
163#endif
164        if (lflag) syslog(LOG_INFO, "daemon started");
165        (void) umask(0);
166        lfd = open(MASTERLOCK, O_WRONLY|O_CREAT, 0644);
167        if (lfd < 0) {
168                syslog(LOG_ERR, "%s: %m", MASTERLOCK);
169                exit(1);
170        }
171        if (flock(lfd, LOCK_EX|LOCK_NB) < 0) {
172                if (errno == EWOULDBLOCK)       /* active deamon present */
173                        exit(0);
174                syslog(LOG_ERR, "%s: %m", MASTERLOCK);
175                exit(1);
176        }
177        ftruncate(lfd, 0);
178        /*
179         * write process id for others to know
180         */
181        sprintf(line, "%u\n", getpid());
182        f = strlen(line);
183        if (write(lfd, line, f) != f) {
184                syslog(LOG_ERR, "%s: %m", MASTERLOCK);
185                exit(1);
186        }
187        signal(SIGCHLD, reapchild);
188        /*
189         * Restart all the printers.
190         */
191        startup();
192        (void) UNLINK(SOCKETNAME);
193        funix = socket(AF_UNIX, SOCK_STREAM, 0);
194        if (funix < 0) {
195                syslog(LOG_ERR, "socket: %m");
196                exit(1);
197        }
198#define mask(s) (1 << ((s) - 1))
199#if defined(POSIX) && !defined(ultrix)
200        (void) sigemptyset(&mask);
201
202        (void) sigaddset (&mask, SIGHUP);
203        (void) sigaddset (&mask, SIGINT);
204        (void) sigaddset (&mask, SIGTERM);
205        (void) sigprocmask (SIG_BLOCK, &mask, &omask);
206#else
207        omask = sigblock(mask(SIGHUP)|mask(SIGINT)|mask(SIGQUIT)|mask(SIGTERM));
208#endif
209        signal(SIGHUP, mcleanup);
210        signal(SIGINT, mcleanup);
211        signal(SIGQUIT, mcleanup);
212        signal(SIGTERM, mcleanup);
213        sockun.sun_family = AF_UNIX;
214        strcpy(sockun.sun_path, SOCKETNAME);
215        if (bind(funix,
216             (struct sockaddr *)&sockun, strlen(sockun.sun_path) + 2) < 0) {
217                syslog(LOG_ERR, "ubind: %m");
218                exit(1);
219        }
220#if defined(POSIX) && !defined(ultrix)
221        sigprocmask(SIG_SETMASK, &omask, NULL);
222#else
223        sigsetmask(omask);
224#endif
225        defreadfds = 1 << funix;
226        listen(funix, 5);
227        finet = socket(AF_INET, SOCK_STREAM, 0);
228        if (finet >= 0) {
229                struct servent *sp;
230
231                if (options & SO_DEBUG)
232                        if (setsockopt(finet, SOL_SOCKET, SO_DEBUG, 0, 0) < 0) {
233                                syslog(LOG_ERR, "setsockopt (SO_DEBUG): %m");
234                                mcleanup();
235                        }
236                sp = getservbyname("printer", "tcp");
237                if (sp == NULL) {
238                        syslog(LOG_ERR, "printer/tcp: unknown service");
239                        mcleanup();
240                }
241                sin.sin_family = AF_INET;
242                sin.sin_addr.s_addr = INADDR_ANY;
243                sin.sin_port = sp->s_port;
244                if (bind(finet, (struct sockaddr *)&sin, sizeof(sin)) < 0) {
245                        syslog(LOG_ERR, "bind: %m");
246                        mcleanup();
247                }
248                defreadfds |= 1 << finet;
249                listen(finet, 5);
250        }
251        /*
252         * Main loop: accept, do a request, continue.
253         */
254        for (;;) {
255                int domain, nfds, s, readfds = defreadfds;
256                nfds = select(20, &readfds, 0, 0, 0);
257                if (nfds <= 0) {
258                        if (nfds < 0 && errno != EINTR)
259                                syslog(LOG_WARNING, "select: %m");
260                        continue;
261                }
262                if (readfds & (1 << funix)) {
263                        domain = AF_UNIX, fromlen = sizeof(fromunix);
264                        s = accept(funix,
265                            (struct sockaddr *)&fromunix, &fromlen);
266                } else if (readfds & (1 << finet)) {
267                        domain = AF_INET, fromlen = sizeof(frominet);
268                        s = accept(finet, &frominet, &fromlen);
269                }
270                if (s < 0) {
271                        if (errno != EINTR)
272                                syslog(LOG_WARNING, "accept: %m");
273                        continue;
274                }
275
276                if (fork() == 0) {
277#if defined(_AIX) || defined(SOLARIS)
278                        signal(SIGCHLD, SIG_DFL);
279#else
280                        signal(SIGCHLD, SIG_IGN);
281#endif
282                        signal(SIGCHLD, SIG_DFL);
283                        signal(SIGHUP, SIG_IGN);
284                        signal(SIGINT, SIG_IGN);
285                        signal(SIGQUIT, SIG_IGN);
286                        signal(SIGTERM, SIG_IGN);
287                        (void) close(funix);
288                        (void) close(finet);
289                        dup2(s, 1);
290                        (void) close(s);
291                        if (domain == AF_INET)
292                                chkhost(&frominet);
293                        doit();
294                        exit(0);
295                }
296                (void) close(s);
297        }
298}
299void
300reapchild()
301{
302#if !defined(POSIX) || defined(ultrix)
303        union wait status;
304#else
305        int status;
306#endif
307
308#if defined(POSIX) && !defined(ultrix)
309        while (waitpid(-1,&status,WNOHANG) >0)
310#else
311        while (wait3(&status, WNOHANG, 0) > 0)
312#endif
313                ;
314}
315void
316mcleanup()
317{
318        if (lflag)
319                syslog(LOG_INFO, "exiting");
320        UNLINK(SOCKETNAME);
321        exit(0);
322}
323
324/*
325 * Stuff for handling job specifications
326 */
327char    *user[MAXUSERS];        /* users to process */
328int     users;                  /* # of users in user array */
329int     requ[MAXREQUESTS];      /* job number of spool entries */
330int     requests;               /* # of spool requests */
331char    *person;                /* name of person doing lprm */
332
333char    fromb[32];      /* buffer for client's machine name */
334char    cbuf[BUFSIZ];   /* command line buffer */
335char    *cmdnames[] = {
336        "null",
337        "printjob",
338        "recvjob",
339        "displayq short",
340        "displayq long",
341        "rmjob"
342};
343
344
345#ifdef KERBEROS
346require_kerberos(printer)
347char *printer;
348{
349        int status;
350        short KA;
351        int use_kerberos;
352       
353#ifdef HESIOD
354        if ((status = pgetent(line, printer)) <= 0) {
355                if (pralias(alibuf, printer))
356                        printer = alibuf;
357                if ((status = hpgetent(line, printer)) < 1)
358                        fatal("unknown printer");
359        }
360#else
361        if ((status = pgetent(line, printer)) < 0) {
362                fatal("can't open printer description file");
363        } else if (status == 0)
364                fatal("unknown printer");
365#endif HESIOD                   
366        KA = pgetnum("ka");
367        if (KA > 0)
368                use_kerberos = 1;
369        else
370                use_kerberos = 0;
371        if (kerberos_override > -1)
372                use_kerberos = kerberos_override;
373       
374        return(use_kerberos);
375}
376#endif KERBEROS
377
378
379doit()
380{
381        register char *cp;
382        register int n;
383       
384#ifdef KERBEROS
385        kflag = 0;
386        kerberos_cf = 0;
387        kerror = 0;
388#endif KERBEROS
389
390
391        for (;;) {
392                cp = cbuf;
393                do {
394                        if (cp >= &cbuf[sizeof(cbuf) - 1])
395                                fatal("Command line too long");
396                        if ((n = read(1, cp, 1)) != 1) {
397                                if (n < 0)
398                                        fatal("Lost connection");
399                                return;
400                        }
401                } while (*cp++ != '\n');
402                *--cp = '\0';
403                cp = cbuf;
404                if (lflag) {
405                        if (*cp >= '\1' && *cp <= '\5')
406                                syslog(LOG_INFO, "%s requests %s %s",
407                                        from, cmdnames[*cp], cp+1);
408#ifdef KERBEROS
409                        else if (*cp == 'k')
410                                syslog(LOG_INFO, "%s sent kerberos credentials",
411                                       from);
412#endif KERBEROS
413                        else
414                                syslog(LOG_INFO, "bad request (%d) from %s",
415                                        *cp, from);
416                }
417                switch (*cp++) {
418                case '\1':      /* check the queue and print any jobs there */
419                        printer = cp;
420                        printjob();
421                        break;
422                case '\2':      /* receive files to be queued */
423                        printer = cp;
424#ifdef KERBEROS
425                        if (require_kerberos(printer)) {
426                            if (kflag)
427                                kerberos_cf = 1;
428                            else {
429                                /* Return an error and abort */
430                                syslog(LOG_DEBUG,"%s: Cannot receive job before authentication",printer);
431                                putchar('\2');
432                                exit(1);
433                            }
434                        }
435#endif KERBEROS
436                        recvjob();
437                        break;
438                case '\3':      /* display the queue (short form) */
439                case '\4':      /* display the queue (long form) */
440                        printer = cp;
441                        while (*cp) {
442                                if (*cp != ' ') {
443                                        cp++;
444                                        continue;
445                                }
446                                *cp++ = '\0';
447                                while (isspace(*cp))
448                                        cp++;
449                                if (*cp == '\0')
450                                        break;
451                                if (isdigit(*cp)) {
452                                        if (requests >= MAXREQUESTS)
453                                                fatal("Too many requests");
454                                        requ[requests++] = atoi(cp);
455                                } else {
456                                        if (users >= MAXUSERS)
457                                                fatal("Too many users");
458                                        user[users++] = cp;
459                                }
460                        }
461                        displayq(cbuf[0] - '\3');
462                        exit(0);
463                case '\5':      /* remove a job from the queue */
464                        printer = cp;
465                        while (*cp && *cp != ' ')
466                                cp++;
467                        if (!*cp)
468                                break;
469                        *cp++ = '\0';
470                        person = cp;
471                        while (*cp) {
472                                if (*cp != ' ') {
473                                        cp++;
474                                        continue;
475                                }
476                                *cp++ = '\0';
477                                while (isspace(*cp))
478                                        cp++;
479                                if (*cp == '\0')
480                                        break;
481                                if (isdigit(*cp)) {
482                                        if (requests >= MAXREQUESTS)
483                                                fatal("Too many requests");
484                                        requ[requests++] = atoi(cp);
485                                } else {
486                                        if (users >= MAXUSERS)
487                                                fatal("Too many users");
488                                        user[users++] = cp;
489                                }
490                        }
491#ifdef KERBEROS
492                        if (require_kerberos(printer)) {
493                            if (kflag) {
494                                kerberos_cf = 1;
495                                make_kname(kprincipal, kinstance,
496                                           krealm, krbname);
497                                person = krbname;
498                            }
499                            else
500                                /* This message gets sent to the user */
501                                    {
502                                        printf("Kerberos authentication required to remove job.\n");
503                                        exit(1);
504                                    }
505                        }
506#endif KERBEROS
507                        rmjob();
508                        break;
509#ifdef KERBEROS
510                case 'k':       /* Parse kerberos credentials */
511                        printer = cp;
512                        kprincipal[0] = krealm[0] = '\0';
513                        memset(&kticket, 0, sizeof(KTEXT_ST));
514                        memset(&kdata, 0,   sizeof(AUTH_DAT));
515                        sin_len = sizeof (struct sockaddr_in);
516                        if (getpeername(1, &faddr, &sin_len) < 0) {
517                                /* return error and exit */
518                                fatal("Could not get peername");
519                        }
520                        /* Tell remote side that kerberos is accepted here! */
521                        putchar('\0');
522                        fflush(stdout);
523                        strcpy(kinstance, "*");
524                        kauth = krb_recvauth(0L, 1, &kticket, KLPR_SERVICE,
525                                             kinstance,
526                                             &faddr,
527                                             (struct sockaddr_in *)NULL,
528                                             &kdata, "", NULL,
529                                             kversion);
530                        if (kauth != KSUCCESS) {
531                                /* return error and exit */
532                                /* We cannot call fatal - not really
533                                   in protocol yet. We will set error
534                                   for return later. */
535                            putchar('\3');
536                            syslog(LOG_DEBUG,"%s: Sending back auth failed", printer);
537                            exit(1);
538                            break;
539                        }
540                        strncpy(kprincipal, kdata.pname,  ANAME_SZ);
541                        strncpy(kinstance,  kdata.pinst,  INST_SZ);
542                        krb_get_lrealm(local_realm, 1);
543                        if (strncmp(kdata.prealm, local_realm, REALM_SZ))
544                            strncpy(krealm, kdata.prealm, REALM_SZ);
545#ifdef DEBUG
546                        if (krealm[0] == '\0')
547                                syslog(LOG_DEBUG,"Authentication for %s.%s",
548                                       kprincipal, kinstance);
549                        else
550                                syslog(LOG_DEBUG,"Authentication for %s.%s@%s",
551                                       kprincipal, kinstance, krealm);
552#endif DEBUG
553                        /* Ackknowledge accepted */
554                        kflag = 1;
555                        putchar('\0');
556                        fflush(stdout);
557                        break;
558#endif KERBEROS
559                default:
560                        fatal("Illegal service request");
561                        break;
562                }
563        }
564}
565
566/*
567 * Make a pass through the printcap database and start printing any
568 * files left from the last time the machine went down.
569 */
570startup()
571{
572        char buf[BUFSIZ];
573        register char *cp;
574        int pid;
575
576        printer = buf;
577
578        /*
579         * Restart the daemons.
580         */
581        while (getprent(buf) > 0) {
582                for (cp = buf; *cp; cp++)
583                        if (*cp == '|' || *cp == ':') {
584                                *cp = '\0';
585                                break;
586                        }
587                if ((pid = fork()) < 0) {
588                        syslog(LOG_WARNING, "startup: cannot fork");
589                        mcleanup();
590                }
591                if (!pid) {
592                        endprent();
593                        printjob();
594                }
595        }
596}
597
598#define DUMMY ":nobody::"
599
600/*
601 * Check to see if the from host has access to the line printer.
602 */
603chkhost(f)
604        struct sockaddr_in *f;
605{
606  /* The following definitions define what consititutes an "athena machine":
607   */
608#ifdef WS
609#ifdef NET
610#undef NET
611#endif
612#define NET(x)  (((x) >> 24) & 0xff)
613#define SUBNET(x) (((x) >> 16) & 0xff)
614#define HHOST(x) (((x) >> 8) & 0xff)
615#define LHOST ((x) & 0xff)
616#define ATHENA_NETWORK 18
617#endif
618
619        register struct hostent *hp;
620        register FILE *hostf;
621        register char *cp, *sp;
622        unsigned long hold_net;
623        char ahost[50];
624        int first = 1;
625        extern char *inet_ntoa();
626        int baselen = -1;
627
628        f->sin_port = ntohs(f->sin_port);
629        if (f->sin_family != AF_INET || f->sin_port >= IPPORT_RESERVED)
630                fatal("Malformed from address");
631        hp = gethostbyaddr(&f->sin_addr, sizeof(struct in_addr), f->sin_family);
632        if (hp == 0)
633                fatal("Host name for your address (%s) unknown",
634                        inet_ntoa(f->sin_addr));
635
636        strcpy(fromb, hp->h_name);
637        from = fromb;
638#ifdef LACL
639        strcpy(from_host, fromb);
640#endif
641        if (!strcasecmp(from, host))
642                return;
643#ifdef WS
644        /* Code for workstation printing only which permits any machine on the
645           Athena network, and in the namespace, to print, even if not
646           in /etc/hosts.equiv or /etc/hosts.lpd */
647
648        hold_net = ntohl(f->sin_addr.s_addr);
649        if (NET(hold_net) == ATHENA_NETWORK)
650            return;
651#endif
652        sp = fromb;
653        cp = ahost;
654        while (*sp) {
655                if (*sp == '.') {
656                        if (baselen == -1)
657                                baselen = sp - fromb;
658                        *cp++ = *sp++;
659                } else {
660                        *cp++ = isupper(*sp) ? tolower(*sp++) : *sp++;
661                }
662        }
663        *cp = '\0';
664
665        hostf = fopen("/etc/hosts.equiv", "r");
666again:
667        if (hostf) {
668                if (!_validuser(hostf, ahost, DUMMY, DUMMY, baselen)) {
669                        (void) fclose(hostf);
670                        return;
671                }
672                (void) fclose(hostf);
673        }
674        if (first == 1) {
675                first = 0;
676                hostf = fopen("/etc/hosts.lpd", "r");
677                goto again;
678        }
679        printer = (char *) NULL;
680        fatal("Your host does not have line printer access");
681}
682
683/*
684 * A version of startdaemon for routines within lpd.
685 * We're already here.... why open a connection to ourselves?
686 */
687
688startdaemon(pr)
689        char    *pr;
690{
691        int     pid;
692       
693        if ((pid = fork()) == 0) {
694                printer = malloc(strlen(pr) + 1);
695                strcpy(printer, pr);
696                if (lflag)
697                        syslog(LOG_INFO, "startdaemon(%s) succeeded", printer);
698                printjob();
699        } else if (pid < 0) {
700                perr("fork");
701                return(0);
702        } else
703                return(1);
704}
705
706static
707perr(msg)
708        char *msg;
709{
710        extern char *name;
711        extern int sys_nerr;
712        extern char *sys_errlist[];
713        extern int errno;
714
715        if (lflag)
716                syslog(LOG_INFO, "%s: %s: %m", name, msg);
717        printf("%s: %s: ", name, msg);
718        fputs(errno < sys_nerr ? sys_errlist[errno] : "Unknown error" , stdout);
719        putchar('\n');
720}
721
722#if defined(_AUX_SOURCE) || defined(SOLARIS)
723_validuser(hostf, rhost, luser, ruser, baselen)
724char *rhost, *luser, *ruser;
725FILE *hostf;
726int baselen;
727{
728        char *user;
729        char ahost[MAXHOSTNAMELEN];
730        register char *p;
731
732        while (fgets(ahost, sizeof (ahost), hostf)) {
733                p = ahost;
734                while (*p != '\n' && *p != ' ' && *p != '\t' && *p != '\0') {
735                        *p = isupper(*p) ? tolower(*p) : *p;
736                        p++;
737                }
738                if (*p == ' ' || *p == '\t') {
739                        *p++ = '\0';
740                        while (*p == ' ' || *p == '\t')
741                                p++;
742                        user = p;
743                        while (*p != '\n' && *p != ' ' && *p != '\t' && *p != '\0')
744                                p++;
745                } else
746                        user = p;
747                *p = '\0';
748                if (_checkhost(rhost, ahost, baselen) &&
749                    !strcmp(ruser, *user ? user : luser)) {
750                        return (0);
751                }
752        }
753        return (-1);
754}
755
756_checkhost(rhost, lhost, len)
757char *rhost, *lhost;
758int len;
759{
760        static char ldomain[MAXHOSTNAMELEN + 1];
761        static char *domainp = NULL;
762        static int nodomain = 0;
763        register char *cp;
764
765        if (len == -1)
766                return(!strcmp(rhost, lhost));
767        if (strncmp(rhost, lhost, len))
768                return(0);
769        if (!strcmp(rhost, lhost))
770                return(1);
771        if (*(lhost + len) != '\0')
772                return(0);
773        if (nodomain)
774                return(0);
775        if (!domainp) {
776                if (gethostname(ldomain, sizeof(ldomain)) == -1) {
777                        nodomain = 1;
778                        return(0);
779                }
780                ldomain[MAXHOSTNAMELEN] = NULL;
781                if ((domainp = strchr(ldomain, '.')) == (char *)NULL) {
782                        nodomain = 1;
783                        return(0);
784                }
785                for (cp = ++domainp; *cp; ++cp)
786                        if (islower(*cp))
787                                *cp = toupper(*cp);
788        }
789        return(!strcmp(domainp, rhost + len +1));
790
791}
792#endif
Note: See TracBrowser for help on using the repository browser.