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

Revision 12350, 17.3 KB checked in by ghudson, 26 years ago (diff)
Some RCS ID cleanup: delete $Log$ and replace other RCS keywords with $Id$.
Line 
1/*
2 *      $Id: lpd.c,v 1.24 1999-01-22 23:10:38 ghudson Exp $
3 */
4
5/*
6 * Copyright (c) 1983 Regents of the University of California.
7 * All rights reserved.  The Berkeley software License Agreement
8 * specifies the terms and conditions for redistribution.
9 */
10
11#ifndef lint
12char copyright[] =
13"@(#) Copyright (c) 1983 Regents of the University of California.\n\
14 All rights reserved.\n";
15
16static char sccsid[] = "@(#)lpd.c       5.4 (Berkeley) 5/6/86";
17static char *rcsid_lpd_c = "$Id: lpd.c,v 1.24 1999-01-22 23:10:38 ghudson Exp $";
18#endif
19
20/*
21 * lpd -- line printer daemon.
22 *
23 * Listen for a connection and perform the requested operation.
24 * Operations are:
25 *      \1printer\n
26 *              check the queue for jobs and print any found.
27 *      \2printer\n
28 *              receive a job from another machine and queue it.
29 *      \3printer [users ...] [jobs ...]\n
30 *              return the current state of the queue (short form).
31 *      \4printer [users ...] [jobs ...]\n
32 *              return the current state of the queue (long form).
33 *      \5printer person [users ...] [jobs ...]\n
34 *              remove jobs from the queue.
35 *      kprinter\nkerberos credentials
36 *              Uses kerberos authentication
37 *
38 * Strategy to maintain protected spooling area:
39 *      1. Spooling area is writable only by daemon and spooling group
40 *      2. lpr runs setuid root and setgrp spooling group; it uses
41 *         root to access any file it wants (verifying things before
42 *         with an access call) and group id to know how it should
43 *         set up ownership of files in the spooling area.
44 *      3. Files in spooling area are owned by root, group spooling
45 *         group, with mode 660.
46 *      4. lpd, lpq and lprm run setuid daemon and setgrp spooling group to
47 *         access files and printer.  Users can't get to anything
48 *         w/o help of lpq and lprm programs.
49 */
50
51#include "lp.h"
52#ifdef POSIX
53#if !defined(ultrix)
54#include "posix.h"    /* for flock() */
55#endif
56#else
57#include "nonposix.h"
58#endif
59#ifdef ZEPHYR
60#undef STAT
61#include <zephyr/zephyr.h>
62#endif
63
64int     lflag;                          /* log requests flag */
65
66void reapchild();
67void mcleanup();
68
69#ifdef KERBEROS
70KTEXT_ST kticket;
71AUTH_DAT kdata;
72int kauth;
73int sin_len;
74struct sockaddr_in faddr;
75char krbname[ANAME_SZ + INST_SZ + REALM_SZ + 3];
76char kprincipal[ANAME_SZ];
77char kinstance[INST_SZ];
78char krealm[REALM_SZ];
79char local_realm[REALM_SZ];
80char kversion[9];
81int kflag;                     /* Is the current job authentc */
82int kerror;                    /* They tried sending auth, but it failed */
83int kerberos_override = -1;    /* Does command option override KA in printcap? */
84int kerberos_cf = 0;           /* Are we using a kerberized cf file? */
85int use_kerberos;
86#endif KERBEROS
87
88#ifdef LACL
89char from_host[MAXHOSTNAMELEN + 1];
90#endif
91
92main(argc, argv)
93        int argc;
94        char **argv;
95{
96        int f, funix, finet, options=0, defreadfds, fromlen, one=1;
97        struct sockaddr_un sockun, fromunix;
98        struct sockaddr_in sin, frominet;
99        struct hostent *hp;
100        int  lfd;
101#if defined(POSIX) && !defined(ultrix)
102        sigset_t omask, mask;
103#else
104        int omask;
105#endif
106
107#ifdef ZEPHYR
108        ZInitialize();
109#endif ZEPHYR
110
111        gethostname(host, sizeof(host));
112        if(hp = gethostbyname(host)) {
113                strncpy(host, hp -> h_name, sizeof(host));
114                host[sizeof(host) - 1] = '\0';
115        }
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                setsockopt(finet, SOL_SOCKET, SO_REUSEADDR, (char *) &one, sizeof(one));
245                if (bind(finet, (struct sockaddr *)&sin, sizeof(sin)) < 0) {
246                        syslog(LOG_ERR, "bind: %m");
247                        mcleanup();
248                }
249                defreadfds |= 1 << finet;
250                listen(finet, 5);
251        }
252        /*
253         * Main loop: accept, do a request, continue.
254         */
255        for (;;) {
256                int domain, nfds, s, readfds = defreadfds;
257                nfds = select(20, &readfds, 0, 0, 0);
258                if (nfds <= 0) {
259                        if (nfds < 0 && errno != EINTR)
260                                syslog(LOG_WARNING, "select: %m");
261                        continue;
262                }
263                if (readfds & (1 << funix)) {
264                        domain = AF_UNIX, fromlen = sizeof(fromunix);
265                        s = accept(funix,
266                            (struct sockaddr *)&fromunix, &fromlen);
267                } else if (readfds & (1 << finet)) {
268                        domain = AF_INET, fromlen = sizeof(frominet);
269                        s = accept(finet, &frominet, &fromlen);
270                }
271                if (s < 0) {
272                        if (errno != EINTR)
273                                syslog(LOG_WARNING, "accept: %m");
274                        continue;
275                }
276
277                if (fork() == 0) {
278#if defined(_AIX) || defined(SOLARIS)
279                        signal(SIGCHLD, SIG_DFL);
280#else
281                        signal(SIGCHLD, SIG_IGN);
282#endif
283                        signal(SIGCHLD, SIG_DFL);
284                        signal(SIGHUP, SIG_IGN);
285                        signal(SIGINT, SIG_IGN);
286                        signal(SIGQUIT, SIG_IGN);
287                        signal(SIGTERM, SIG_IGN);
288                        (void) close(funix);
289                        (void) close(finet);
290                        dup2(s, 1);
291                        (void) close(s);
292#ifdef CHECK_NETWORK
293                        if (domain == AF_INET)
294                                chkhost(&frominet);
295#endif
296                        doit();
297                        exit(0);
298                }
299                (void) close(s);
300        }
301}
302void
303reapchild()
304{
305#if !defined(POSIX) || defined(ultrix)
306        union wait status;
307#else
308        int status;
309#endif
310
311#if defined(POSIX) && !defined(ultrix)
312        while (waitpid(-1,&status,WNOHANG) >0)
313#else
314        while (wait3(&status, WNOHANG, 0) > 0)
315#endif
316                ;
317}
318void
319mcleanup()
320{
321        if (lflag)
322                syslog(LOG_INFO, "exiting");
323        UNLINK(SOCKETNAME);
324        exit(0);
325}
326
327/*
328 * Stuff for handling job specifications
329 */
330char    *user[MAXUSERS];        /* users to process */
331int     users;                  /* # of users in user array */
332int     requ[MAXREQUESTS];      /* job number of spool entries */
333int     requests;               /* # of spool requests */
334char    *person;                /* name of person doing lprm */
335
336char    fromb[MAXHOSTNAMELEN + 1];      /* buffer for client's machine name */
337char    cbuf[BUFSIZ];   /* command line buffer */
338char    *cmdnames[] = {
339        "null",
340        "printjob",
341        "recvjob",
342        "displayq short",
343        "displayq long",
344        "rmjob"
345};
346
347
348#ifdef KERBEROS
349require_kerberos(printer)
350char *printer;
351{
352        int status;
353        short KA;
354        int use_kerberos;
355       
356#ifdef HESIOD
357        if ((status = pgetent(line, printer)) <= 0) {
358                if (pralias(alibuf, printer))
359                        printer = alibuf;
360                if ((status = hpgetent(line, printer)) < 1)
361                        fatal("unknown printer");
362        }
363#else
364        if ((status = pgetent(line, printer)) < 0) {
365                fatal("can't open printer description file");
366        } else if (status == 0)
367                fatal("unknown printer");
368#endif HESIOD                   
369        KA = pgetnum("ka");
370        if (KA > 0)
371                use_kerberos = 1;
372        else
373                use_kerberos = 0;
374        if (kerberos_override > -1)
375                use_kerberos = kerberos_override;
376       
377        return(use_kerberos);
378}
379#endif KERBEROS
380
381
382doit()
383{
384        register char *cp;
385        register int n;
386       
387#ifdef KERBEROS
388        kflag = 0;
389        kerberos_cf = 0;
390        kerror = 0;
391#endif KERBEROS
392
393
394        for (;;) {
395                cp = cbuf;
396                do {
397                        if (cp >= &cbuf[sizeof(cbuf) - 1])
398                                fatal("Command line too long");
399                        if ((n = read(1, cp, 1)) != 1) {
400                                if (n < 0)
401                                        fatal("Lost connection");
402                                return;
403                        }
404                } while (*cp++ != '\n');
405                *--cp = '\0';
406                cp = cbuf;
407                if (lflag) {
408                        if (*cp >= '\1' && *cp <= '\5')
409                                syslog(LOG_INFO, "%s requests %s %s",
410                                        from, cmdnames[*cp], cp+1);
411#ifdef KERBEROS
412                        else if (*cp == 'k')
413                                syslog(LOG_INFO, "%s sent kerberos credentials",
414                                       from);
415#endif KERBEROS
416                        else
417                                syslog(LOG_INFO, "bad request (%d) from %s",
418                                        *cp, from);
419                }
420                switch (*cp++) {
421                case '\1':      /* check the queue and print any jobs there */
422                        printer = cp;
423                        printjob();
424                        break;
425                case '\2':      /* receive files to be queued */
426                        printer = cp;
427#ifdef KERBEROS
428                        if (require_kerberos(printer)) {
429                            if (kflag)
430                                kerberos_cf = 1;
431                            else {
432                                /* Return an error and abort */
433                                syslog(LOG_DEBUG,"%s: Cannot receive job before authentication",printer);
434                                putchar('\2');
435                                exit(1);
436                            }
437                        }
438#endif KERBEROS
439                        recvjob();
440                        break;
441                case '\3':      /* display the queue (short form) */
442                case '\4':      /* display the queue (long form) */
443                        printer = cp;
444                        while (*cp) {
445                                if (*cp != ' ') {
446                                        cp++;
447                                        continue;
448                                }
449                                *cp++ = '\0';
450                                while (isspace(*cp))
451                                        cp++;
452                                if (*cp == '\0')
453                                        break;
454                                if (isdigit(*cp)) {
455                                        if (requests >= MAXREQUESTS)
456                                                fatal("Too many requests");
457                                        requ[requests++] = atoi(cp);
458                                } else {
459                                        if (users >= MAXUSERS)
460                                                fatal("Too many users");
461                                        user[users++] = cp;
462                                }
463                        }
464                        displayq(cbuf[0] - '\3');
465                        exit(0);
466                case '\5':      /* remove a job from the queue */
467                        printer = cp;
468                        while (*cp && *cp != ' ')
469                                cp++;
470                        if (!*cp)
471                                break;
472                        *cp++ = '\0';
473                        person = cp;
474                        while (*cp) {
475                                if (*cp != ' ') {
476                                        cp++;
477                                        continue;
478                                }
479                                *cp++ = '\0';
480                                while (isspace(*cp))
481                                        cp++;
482                                if (*cp == '\0')
483                                        break;
484                                if (isdigit(*cp)) {
485                                        if (requests >= MAXREQUESTS)
486                                                fatal("Too many requests");
487                                        requ[requests++] = atoi(cp);
488                                } else {
489                                        if (users >= MAXUSERS)
490                                                fatal("Too many users");
491                                        user[users++] = cp;
492                                }
493                        }
494#ifdef KERBEROS
495                        if (require_kerberos(printer)) {
496                            if (kflag) {
497                                kerberos_cf = 1;
498                                make_kname(kprincipal, kinstance,
499                                           krealm, krbname);
500                                person = krbname;
501                            }
502                            else
503                                /* This message gets sent to the user */
504                                    {
505                                        printf("Kerberos authentication required to remove job.\n");
506                                        exit(1);
507                                    }
508                        }
509#endif KERBEROS
510                        rmjob();
511                        break;
512#ifdef KERBEROS
513                case 'k':       /* Parse kerberos credentials */
514                        printer = cp;
515                        kprincipal[0] = krealm[0] = '\0';
516                        memset(&kticket, 0, sizeof(KTEXT_ST));
517                        memset(&kdata, 0,   sizeof(AUTH_DAT));
518                        sin_len = sizeof (struct sockaddr_in);
519                        if (getpeername(1, &faddr, &sin_len) < 0) {
520                                /* return error and exit */
521                                fatal("Could not get peername");
522                        }
523                        /* Tell remote side that kerberos is accepted here! */
524                        putchar('\0');
525                        fflush(stdout);
526                        strcpy(kinstance, "*");
527                        kauth = krb_recvauth(0L, 1, &kticket, KLPR_SERVICE,
528                                             kinstance,
529                                             &faddr,
530                                             (struct sockaddr_in *)NULL,
531                                             &kdata, "", NULL,
532                                             kversion);
533                        if (kauth != KSUCCESS) {
534                                /* return error and exit */
535                                /* We cannot call fatal - not really
536                                   in protocol yet. We will set error
537                                   for return later. */
538                            putchar('\3');
539                            syslog(LOG_DEBUG,"%s: Sending back auth failed", printer);
540                            exit(1);
541                            break;
542                        }
543                        strncpy(kprincipal, kdata.pname,  ANAME_SZ);
544                        strncpy(kinstance,  kdata.pinst,  INST_SZ);
545                        krb_get_lrealm(local_realm, 1);
546                        if (strncmp(kdata.prealm, local_realm, REALM_SZ))
547                            strncpy(krealm, kdata.prealm, REALM_SZ);
548#ifdef DEBUG
549                        if (krealm[0] == '\0')
550                                syslog(LOG_DEBUG,"Authentication for %s.%s",
551                                       kprincipal, kinstance);
552                        else
553                                syslog(LOG_DEBUG,"Authentication for %s.%s@%s",
554                                       kprincipal, kinstance, krealm);
555#endif DEBUG
556                        /* Ackknowledge accepted */
557                        kflag = 1;
558                        putchar('\0');
559                        fflush(stdout);
560                        break;
561#endif KERBEROS
562                default:
563                        fatal("Illegal service request");
564                        break;
565                }
566        }
567}
568
569/*
570 * Make a pass through the printcap database and start printing any
571 * files left from the last time the machine went down.
572 */
573startup()
574{
575        char buf[BUFSIZ];
576        register char *cp;
577        int pid;
578
579        printer = buf;
580
581        /*
582         * Restart the daemons.
583         */
584        while (getprent(buf) > 0) {
585                for (cp = buf; *cp; cp++)
586                        if (*cp == '|' || *cp == ':') {
587                                *cp = '\0';
588                                break;
589                        }
590                if ((pid = fork()) < 0) {
591                        syslog(LOG_WARNING, "startup: cannot fork");
592                        mcleanup();
593                }
594                if (!pid) {
595                        endprent();
596                        printjob();
597                }
598        }
599}
600
601#define DUMMY ":nobody::"
602
603/*
604 * Check to see if the from host has access to the line printer.
605 */
606chkhost(f)
607        struct sockaddr_in *f;
608{
609  /* The following definitions define what consititutes an "athena machine":
610   */
611#ifdef WS
612#ifdef NET
613#undef NET
614#endif
615#define NET(x)  (((x) >> 24) & 0xff)
616#define SUBNET(x) (((x) >> 16) & 0xff)
617#define HHOST(x) (((x) >> 8) & 0xff)
618#define LHOST ((x) & 0xff)
619#define ATHENA_NETWORK 18
620#endif
621
622        register struct hostent *hp;
623        register FILE *hostf;
624        register char *cp, *sp;
625        unsigned long hold_net;
626        char ahost[MAXHOSTNAMELEN + 1];
627        int first = 1;
628        extern char *inet_ntoa();
629        int baselen = -1;
630
631        f->sin_port = ntohs(f->sin_port);
632        if (f->sin_family != AF_INET || f->sin_port >= IPPORT_RESERVED)
633                fatal("Malformed from address");
634        hp = gethostbyaddr(&f->sin_addr, sizeof(struct in_addr), f->sin_family);
635        if (hp == 0)
636                fatal("Host name for your address (%s) unknown",
637                        inet_ntoa(f->sin_addr));
638
639        strncpy(fromb, hp->h_name, sizeof(fromb));
640        fromb[sizeof(fromb) - 1] = '\0';
641        from = fromb;
642#ifdef LACL
643        strcpy(from_host, fromb);
644#endif
645        if (!strcasecmp(from, host))
646                return;
647#ifdef WS
648        /* Code for workstation printing only which permits any machine on the
649           Athena network, and in the namespace, to print, even if not
650           in /etc/hosts.equiv or /etc/hosts.lpd */
651
652        hold_net = ntohl(f->sin_addr.s_addr);
653        if (NET(hold_net) == ATHENA_NETWORK)
654            return;
655#endif
656        sp = fromb;
657        cp = ahost;
658        while (*sp) {
659                if (*sp == '.') {
660                        if (baselen == -1)
661                                baselen = sp - fromb;
662                        *cp++ = *sp++;
663                } else {
664                        *cp++ = isupper(*sp) ? tolower(*sp++) : *sp++;
665                }
666        }
667        *cp = '\0';
668
669        hostf = fopen("/etc/hosts.equiv", "r");
670again:
671        if (hostf) {
672                if (!validuser(hostf, ahost, DUMMY, DUMMY, baselen)) {
673                        (void) fclose(hostf);
674                        return;
675                }
676                (void) fclose(hostf);
677        }
678        if (first == 1) {
679                first = 0;
680                hostf = fopen("/etc/hosts.lpd", "r");
681                goto again;
682        }
683        printer = (char *) NULL;
684        fatal("%s: Your host does not have line printer access", from);
685}
686
687/*
688 * A version of startdaemon for routines within lpd.
689 * We're already here.... why open a connection to ourselves?
690 */
691
692startdaemon(pr)
693        char    *pr;
694{
695        int     pid;
696       
697        if ((pid = fork()) == 0) {
698                printer = malloc(strlen(pr) + 1);
699                if (!printer)
700                        return(0);     
701                strcpy(printer, pr);
702                if (lflag)
703                        syslog(LOG_INFO, "startdaemon(%s) succeeded", printer);
704                printjob();
705        } else if (pid < 0) {
706                perr("fork");
707                return(0);
708        } else
709                return(1);
710}
711
712static
713perr(msg)
714        char *msg;
715{
716        extern char *name;
717
718        if (lflag)
719                syslog(LOG_INFO, "%s: %s: %m", name, msg);
720        printf("%s: %s: %s\n", name, msg, strerror(errno));
721}
722
723validuser(hostf, rhost, luser, ruser, baselen)
724char *rhost, *luser, *ruser;
725FILE *hostf;
726int baselen;
727{
728        char *user;
729        char ahost[MAXHOSTNAMELEN + 1];
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
756checkhost(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}
Note: See TracBrowser for help on using the repository browser.