source: trunk/athena/bin/lpr/recvjob.c @ 6936

Revision 6936, 17.6 KB checked in by probe, 31 years ago (diff)
Changed kerberize_cf() to fixup_cf() and call it ALWAYS. We use this routine to insert the "q" card which specifies the queue name as was given to us from the client. This allows us to do per-queue processing (such as duplex printing). (The Kerberos specific portions of fixup_cf are under #ifdef KERBEROS)
Line 
1/*
2 *      $Source: /afs/dev.mit.edu/source/repository/athena/bin/lpr/recvjob.c,v $
3 *      $Author: probe $
4 *      $Locker:  $
5 *      $Header: /afs/dev.mit.edu/source/repository/athena/bin/lpr/recvjob.c,v 1.11 1993-10-09 18:22:58 probe Exp $
6 */
7
8#ifndef lint
9static char *rcsid_recvjob_c = "$Header: /afs/dev.mit.edu/source/repository/athena/bin/lpr/recvjob.c,v 1.11 1993-10-09 18:22:58 probe Exp $";
10#endif lint
11
12/*
13 * Copyright (c) 1983 Regents of the University of California.
14 * All rights reserved.  The Berkeley software License Agreement
15 * specifies the terms and conditions for redistribution.
16 */
17
18#ifndef lint
19static char sccsid[] = "@(#)recvjob.c   5.4 (Berkeley) 6/6/86";
20#endif not lint
21
22/*
23 * Receive printer jobs from the network, queue them and
24 * start the printer daemon.
25 */
26
27#include "lp.h"
28#ifdef _AUX_SOURCE
29#include <sys/sysmacros.h>
30#include <ufs/ufsparam.h>
31#endif
32
33#if (!defined(AIX) || !defined(i386)) && (!defined(_IBMR2))
34#ifdef VFS
35#ifdef SOLARIS
36#include <sys/fs/ufs_fs.h>
37#else
38#include <ufs/fs.h>
39#endif
40#else
41#include <sys/fs.h>
42#endif VFS
43#endif
44
45#ifdef PQUOTA
46#include "quota.h"
47#include <sys/time.h>
48#endif
49
50#ifdef _IBMR2
51#include <sys/select.h>
52#endif
53
54#if BUFSIZ != 1024
55#undef BUFSIZ
56#define BUFSIZ 1024
57#endif
58
59char    *sp = "";
60#define ack()   (void) write(1, sp, 1);
61
62int     lflag;                  /* should we log a trace? */
63char    tfname[40];             /* tmp copy of cf before linking */
64char    dfname[40];             /* data files */
65char    cfname[40];             /* control fle - fix compiler bug */
66int     minfree;                /* keep at least minfree blocks available */
67char    *ddev;                  /* disk device (for checking free space) */
68int     dfd;                    /* file system device descriptor */
69#ifdef KERBEROS
70char    tempfile[40];           /* Same size as used for cfname and tfname */
71extern int kflag;
72#endif KERBEROS
73
74#ifdef _AUX_SOURCE
75/* They defined fds_bits correctly, but lose by not defining this */
76#define FD_ZERO(p)  ((p)->fds_bits[0] = 0)
77#define FD_SET(n, p)   ((p)->fds_bits[0] |= (1 << (n)))
78#define FD_ISSET(n, p)   ((p)->fds_bits[0] & (1 << (n)))
79#endif
80
81char    *find_dev();
82
83recvjob()
84{
85        struct stat stb;
86        char *bp = pbuf;
87        int status, rcleanup();
88
89        /*
90         * Perform lookup for printer name or abbreviation
91         */
92        if(lflag) syslog(LOG_INFO, "in recvjob");
93#ifdef HESIOD
94        if ((status = pgetent(line, printer)) <= 0) {
95                if (pralias(alibuf, printer))
96                        printer = alibuf;
97                if ((status = hpgetent(line, printer)) < 1)
98                        frecverr("unknown printer %s", printer);
99        }
100#else
101        if ((status = pgetent(line, printer)) < 0) {
102                frecverr("cannot open printer description file");
103        }
104        else if (status == 0)
105                frecverr("unknown printer %s", printer);
106#endif HESIOD
107        if ((LF = pgetstr("lf", &bp)) == NULL)
108                LF = DEFLOGF;
109        if ((SD = pgetstr("sd", &bp)) == NULL)
110                SD = DEFSPOOL;
111        if ((LO = pgetstr("lo", &bp)) == NULL)
112                LO = DEFLOCK;
113#ifdef PQUOTA
114        RQ = pgetstr("rq", &bp);
115        QS = pgetstr("qs", &bp);
116#endif PQUOTA       
117#ifdef LACL
118        AC = pgetstr("ac", &bp);
119        PA = pgetflag("pa");
120        RA = pgetflag("ra");
121#endif /* LACL */
122           
123        (void) close(2);                        /* set up log file */
124        if (open(LF, O_WRONLY|O_APPEND, 0664) < 0) {
125                syslog(LOG_ERR, "%s: %m", LF);
126                (void) open("/dev/null", O_WRONLY);
127        }
128
129        if (chdir(SD) < 0)
130                frecverr("%s: %s: %m", printer, SD);
131        if (stat(LO, &stb) == 0) {
132                if (stb.st_mode & 010) {
133                        /* queue is disabled */
134                        putchar('\1');          /* return error code */
135                        exit(1);
136                }
137        } else if (stat(SD, &stb) < 0)
138                frecverr("%s: %s: %m", printer, SD);
139        minfree = read_number("minfree");
140        ddev = find_dev(stb.st_dev, S_IFBLK);
141        if ((dfd = open(ddev, O_RDONLY)) < 0)
142                syslog(LOG_WARNING, "%s: %s: %m", printer, ddev);
143
144        signal(SIGTERM, rcleanup);
145        signal(SIGPIPE, rcleanup);
146
147        if(lflag) syslog(LOG_INFO, "Reading job");
148        if (readjob())
149          {
150            if (lflag) syslog(LOG_INFO, "Printing job..");
151            printjob();
152          }
153       
154}
155
156char *
157find_dev(dev, type)
158        register dev_t dev;
159        register int type;
160{
161        register DIR *dfd = opendir("/dev");
162#if defined(_IBMR2) || defined(POSIX)
163        struct dirent *dir;
164#else
165        struct direct *dir;
166#endif
167        struct stat stb;
168        char devname[MAXNAMLEN+6];
169        char *dp;
170
171        strcpy(devname, "/dev/");
172        while ((dir = readdir(dfd))) {
173                strcpy(devname + 5, dir->d_name);
174                if (stat(devname, &stb))
175                        continue;
176                if ((stb.st_mode & S_IFMT) != type)
177                        continue;
178                if (dev == stb.st_rdev) {
179                        closedir(dfd);
180                        dp = (char *)malloc(strlen(devname)+1);
181                        strcpy(dp, devname);
182                        return(dp);
183                }
184        }
185        closedir(dfd);
186#ifdef SOLARIS
187        frecverr("cannot find device %d, %d", __major(dev), __minor(dev));
188#else
189        frecverr("cannot find device %d, %d", major(dev), minor(dev));
190#endif
191        /*NOTREACHED*/
192}
193
194/*
195 * Read printer jobs sent by lpd and copy them to the spooling directory.
196 * Return the number of jobs successfully transfered.
197 */
198readjob()
199{
200        register int size, nfiles;
201        register char *cp;
202#if defined(PQUOTA) || defined(LACL)
203        char *cret;
204#endif
205#ifdef PQUOTA
206        char *check_quota();
207#endif
208#ifdef LACL
209        char *check_lacl(), *check_remhost();
210#endif
211
212        if (lflag) syslog(LOG_INFO, "In readjob");
213        ack();
214        nfiles = 0;
215        for (;;) {
216                /*
217                 * Read a command to tell us what to do
218                 */
219                cp = line;
220                do {
221                        if ((size = read(1, cp, 1)) != 1) {
222                                if (size < 0)
223                                        frecverr("%s: Lost connection",printer);
224                                if (lflag) syslog(LOG_INFO, "Returning from readjobs");
225                                return(nfiles);
226                        }
227                } while (*cp++ != '\n');
228                *--cp = '\0';
229                cp = line;
230                switch (*cp++) {
231                case '\1':      /* cleanup because data sent was bad */
232                        rcleanup();
233                        continue;
234
235                case '\2':      /* read cf file */
236                        size = 0;
237                        while (*cp >= '0' && *cp <= '9')
238                                size = size * 10 + (*cp++ - '0');
239                        if (*cp++ != ' ')
240                                break;
241                        /*
242                         * host name has been authenticated, we use our
243                         * view of the host name since we may be passed
244                         * something different than what gethostbyaddr()
245                         * returns
246                         */
247                        strcpy(cp + 6, from);
248                        strcpy(cfname, cp);
249                        strcpy(tfname, cp);
250                        tfname[0] = 't';
251#ifdef KERBEROS
252                        strcpy(tempfile, tfname);
253                        tempfile[0] = 'T';
254#endif KERBEROS
255                        if (!chksize(size)) {
256                                (void) write(1, "\2", 1);
257                                continue;
258                        }
259                           
260                        /* Don't send final acknowledge beacuse we may wish to
261                           send error below */
262                        if (!readfile(tfname, size, 0)) {
263                            syslog(LOG_DEBUG, "Failed read");
264                                rcleanup();
265                                continue;
266                        }
267
268                        if (!fixup_cf(tfname, tempfile)) {
269                                rcleanup();
270                                continue;
271                        }
272
273#ifdef LACL
274                        if(RA && ((cret = check_remhost()) != 0)) {
275                            (void) write(1, cret, 1);
276                            rcleanup();
277                            continue;
278                        }
279
280                        if(AC && (cret = check_lacl(tfname)) != 0) {
281                            /* We return !=0 for error. Old clients
282                               stupidly don't print any error in this sit.
283                               We do a cleanup cause we can't expect
284                               client to do so. */
285                            (void) write(1, cret, 1);
286#ifdef DEBUG
287                            syslog(LOG_DEBUG, "Got %s", cret);
288#endif DEBUG
289                            rcleanup();
290                            continue;
291                        }
292#endif /*LACL*/
293
294#ifdef PQUOTA
295                        if(kerberos_cf && (RQ != NULL) &&
296                           (cret = check_quota(tfname)) != 0) {
297                            /* We return !=0 for error. Old clients
298                               stupidly don't print any error in this sit.
299                               We do a cleanup cause we can't expect
300                               client to do so. */
301                            (void) write(1, cret, 1);
302#ifdef DEBUG
303                            syslog(LOG_DEBUG, "Got %s", cret);
304#endif DEBUG
305                            rcleanup();
306                            continue;
307                        }
308#endif PQUOTA
309
310                        /* Send acknowldege, cause we didn't before */
311                        ack();
312
313                        if (link(tfname, cfname) < 0)
314                                frecverr("%s: %m", tfname);
315                        (void) UNLINK(tfname);
316                        tfname[0] = '\0';
317                        nfiles++;
318                        continue;
319
320                case '\3':      /* read df file */
321                        size = 0;
322                        while (*cp >= '0' && *cp <= '9')
323                                size = size * 10 + (*cp++ - '0');
324                        if (*cp++ != ' ')
325                                break;
326                        if (!chksize(size)) {
327                                (void) write(1, "\2", 1);
328                                continue;
329                        }
330
331                        (void) strcpy(dfname, cp);
332                        if (index(dfname, '/'))
333                                frecverr("illegal path name");
334                        (void) readfile(dfname, size, 1);
335                        continue;
336                }
337                frecverr("protocol screwup");
338        }
339}
340
341/*
342 * Read files send by lpd and copy them to the spooling directory.
343 */
344readfile(file, size, acknowledge)
345        char *file;
346        int size;
347        int acknowledge;
348{
349        register char *cp;
350        char buf[BUFSIZ];
351        register int i, j, amt;
352        int fd, err;
353
354        fd = open(file, O_WRONLY|O_CREAT, FILMOD);
355        if (fd < 0)
356                frecverr("%s: %m", file);
357        ack();
358        err = 0;
359        for (i = 0; i < size; i += BUFSIZ) {
360                amt = BUFSIZ;
361                cp = buf;
362                if (i + amt > size)
363                        amt = size - i;
364                do {
365                        j = read(1, cp, amt);
366                        if (j <= 0)
367                                frecverr("Lost connection");
368                        amt -= j;
369                        cp += j;
370                } while (amt > 0);
371                amt = BUFSIZ;
372                if (i + amt > size)
373                        amt = size - i;
374                if (write(fd, buf, amt) != amt) {
375                        err++;
376                        break;
377                }
378        }
379        (void) close(fd);
380        if (err)
381                frecverr("%s: write error", file);
382        if (noresponse()) {             /* file sent had bad data in it */
383                (void) UNLINK(file);
384                return(0);     
385            }
386        if(acknowledge)
387            ack();
388        return(1);
389}
390
391fixup_cf(file, tfile)
392char *file, *tfile;
393{
394        FILE *cfp, *tfp;
395        char kname[ANAME_SZ + INST_SZ + REALM_SZ + 3];
396        char oldname[ANAME_SZ + INST_SZ + REALM_SZ + 3];
397
398        oldname[0] = '\0';
399
400        /* Form a complete string name consisting of principal,
401         * instance and realm
402         */
403        make_kname(kprincipal, kinstance, krealm, kname);
404
405        /* If we cannot open tf file, then return error */
406        if ((cfp = fopen(file, "r")) == NULL)
407                return (0);
408
409        /* Read the control file for the person sending the job */
410        while (getline(cfp)) {
411                if (line[0] == 'P') {
412                        strncpy(oldname, line+1, sizeof(oldname)-1);
413                        break;
414                }
415        }
416        fclose(cfp);
417
418        /* Have we got a name in oldname, if not, then return error */
419        if (oldname[0] == '\0')
420                return(0);
421
422        /* Does kname match oldname. If so do nothing */
423        if (!strcmp(kname, oldname))
424                return(1); /* all a-okay */
425
426        /* hmm, doesnt match, guess we have to change the name in
427         * the control file by doing the following :
428         *
429         * (1) Move 'file' to 'tfile'
430         * (2) Copy all of 'tfile' back to 'file' but
431         *     changing the persons name
432         */
433        if (link(file, tfile) < 0)
434                return(0);
435        (void) UNLINK(file);
436
437        /* If we cannot open tf file, then return error */
438        if ((tfp = fopen(tfile, "r")) == NULL)
439                return (0);
440        if ((cfp = fopen(file, "w")) == NULL) {
441                (void) fclose(tfp);
442                return (0);
443        }
444
445        while (getline(tfp)) {
446                /* Ignore any queue name that was specified in the original
447                 * .cf file -- we'll be adding it in shortly...
448                 */
449                if (line[0] == 'q') continue;
450
451#ifdef KERBEROS
452                if (kerberos_cf) {
453                    if (line[0] == 'P')
454                        strcpy(&line[1], kname);
455                    else if (line[0] == 'L')
456                        strcpy(&line[1], kname);
457                }
458#endif
459                fprintf(cfp, "%s\n", line);
460
461        }
462        fprintf(cfp, "q%s\n", printer);
463
464        (void) fclose(cfp);
465        (void) fclose(tfp);
466        (void) UNLINK(tfile);
467
468        return(1);
469}
470
471noresponse()
472{
473        char resp;
474
475        if (read(1, &resp, 1) != 1)
476                frecverr("Lost connection");
477        if (resp == '\0')
478                return(0);
479        return(1);
480}
481
482/*
483 * Check to see if there is enough space on the disk for size bytes.
484 * 1 == OK, 0 == Not OK.
485 */
486chksize(size)
487        int size;
488{
489#if (defined(AIX) && defined(i386)) || defined(_IBMR2)
490        /* This is really not appropriate, but maybe someday XXX */
491        return 1;
492#else
493        int spacefree;
494        struct fs fs;
495
496        if (dfd < 0 || lseek(dfd, (long)(SBLOCK * DEV_BSIZE), 0) < 0)
497                return(1);
498        if (read(dfd, (char *)&fs, sizeof fs) != sizeof fs)
499                return(1);
500        spacefree = (fs.fs_cstotal.cs_nbfree * fs.fs_frag +
501                fs.fs_cstotal.cs_nffree - fs.fs_dsize * fs.fs_minfree / 100) *
502                        fs.fs_fsize / 1024;
503        size = (size + 1023) / 1024;
504        if (minfree + size > spacefree)
505                return(0);
506        return(1);
507#endif /* AIX & i386 */
508}
509
510read_number(fn)
511        char *fn;
512{
513        char lin[80];
514        register FILE *fp;
515
516        if ((fp = fopen(fn, "r")) == NULL)
517                return (0);
518        if (fgets(lin, 80, fp) == NULL) {
519                fclose(fp);
520                return (0);
521        }
522        fclose(fp);
523        return (atoi(lin));
524}
525
526/*
527 * Remove all the files associated with the current job being transfered.
528 */
529rcleanup()
530{
531
532        /* This was cretinous code.. which regularly walked off the end
533         * of the name space...  I changed the != to a >=..
534         */
535
536        if (tfname[0])
537                (void) UNLINK(tfname);
538#ifdef KERBEROS
539        if (tempfile[0])
540                (void) UNLINK(tempfile);
541#endif KERBEROS
542        if (dfname[0])
543                do {
544                        do
545                                (void) UNLINK(dfname);
546                        while (dfname[2]-- >= 'A');
547                        dfname[2] = 'z';
548                } while (dfname[0]-- >= 'd');
549        dfname[0] = '\0';
550}
551
552/* VARARGS1 */
553frecverr(msg, a1, a2)
554        char *msg;
555{
556        rcleanup();
557        syslog(LOG_ERR, msg, a1, a2);
558        putchar('\1');          /* return error code */
559        exit(1);
560}
561
562#ifdef PQUOTA
563
564char* check_quota(file)
565char file[];
566    {
567        struct hostent *hp;
568        char outbuf[BUFSIZ], inbuf[BUFSIZ];
569        int t, act=0, s1;
570        FILE *cfp;
571        struct sockaddr_in sin_c;
572        int fd, retry;
573        struct servent *servname;
574        struct timeval tp;
575        fd_set set;
576
577        if(RQ == NULL)
578            return 0;
579        if((hp = gethostbyname(RQ)) == NULL) {
580            syslog(LOG_WARNING, "Cannot resolve quota servername %s", RQ);
581            return 0;
582        }
583
584        /* Setup output buffer.... */
585        outbuf[0] = (char) UDPPROTOCOL;
586
587        /* Generate a sequence number... Since we fork the only realistic
588           thing to use is the time... */
589        t = htonl(time((char *) 0));
590        bcopy(&t, outbuf + 1, 4);
591        strncpy(outbuf + 4, printer, 30);
592
593
594        if(QS == NULL)
595            outbuf[39] = '\0';
596        else
597            strncpy(outbuf + 39, QS, 20);
598        /* If can't open the control file, then there is some error...
599           We'll return allowed to print, but somewhere else it will be caught.
600           Is this proper? XXX
601           */
602
603        if ((cfp = fopen(file, "r")) == NULL)
604                return 0;
605
606        /* Read the control file for the person sending the job */
607        while (getline(cfp)) {
608                if (line[0] == 'Q' || line[0] == 'A') { /* 'A' for old clients */
609                    if(sscanf(line + 1, "%d", &act) != 1) act=0;
610                    break;
611                }
612        }
613        fclose(cfp);
614
615        act = htonl(act);
616        bcopy(&act, outbuf + 35, 4);
617
618        strncpy(outbuf + 59, kprincipal, ANAME_SZ);
619        strncpy(outbuf + 59 + ANAME_SZ, kinstance, INST_SZ);
620        strncpy(outbuf + 59 + ANAME_SZ + INST_SZ, krealm, REALM_SZ);
621
622        if((fd = socket(AF_INET, SOCK_DGRAM, 0)) < 0) {
623            syslog(LOG_WARNING, "Could not create UDP socket\n");
624            /* Allow print */
625            return 0;
626        }
627
628        bzero((char *)&sin_c, sizeof(sin_c));
629        sin_c.sin_family = AF_INET;
630        servname = getservbyname(QUOTASERVENTNAME,"udp");
631        if(!servname)
632            sin_c.sin_port = htons(QUOTASERVENT);
633        else
634            sin_c.sin_port = servname->s_port;
635
636        bcopy(hp->h_addr_list[0], &sin_c.sin_addr,hp->h_length);
637
638        if(connect(fd, &sin_c, sizeof(sin_c)) < 0) {
639            syslog(LOG_WARNING, "Could not connect with UDP - quota server down?");
640            /* This means that the quota serve is down */
641            /* Allow printing */
642            return 0;
643        }
644
645        for(retry = 0; retry < RETRY_COUNT; retry++) {
646            if(send(fd, outbuf, 59+ANAME_SZ+REALM_SZ+INST_SZ+1,0)<
647               59+ANAME_SZ+REALM_SZ+INST_SZ+1) {
648                syslog(LOG_WARNING, "Send failed to quota");
649                continue;
650            }
651
652            FD_ZERO(&set);
653            FD_SET(fd, &set);
654            tp.tv_sec = UDPTIMEOUT;
655            tp.tv_usec = 0;
656
657            /* So, select and wait for reply */
658            if((s1=select(fd+1, &set, 0, 0, &tp))==0) {
659                /*Time out, retry */
660                continue;
661            }
662
663            if(s1 < 0) {
664                /* Error, which makes no sense. Oh well, display */
665                syslog(LOG_WARNING, "Error in UDP return errno=%d", errno);
666                /* Allow print */
667                return 0;
668            }
669
670            if((s1=recv(fd, inbuf, 36)) != 36) {
671                syslog(LOG_WARNING, "Receive error in UDP contacting quota");
672                /* Retry */
673                continue;
674            }
675
676            if(bcmp(inbuf, outbuf, 35)) {
677                /* Wrong packet */
678#ifdef DEBUG
679                syslog(LOG_DEBUG, "Packet not for me on UDP");
680#endif
681                continue;
682            }
683
684            /* Packet good, send response */
685            switch ((int) inbuf[35]) {
686            case ALLOWEDTOPRINT:
687#ifdef DEBUG
688                syslog(LOG_DEBUG, "Allowed to print!!");
689#endif
690                return 0;
691            case NOALLOWEDTOPRINT:
692                return "\4";
693            case UNKNOWNUSER:
694                return "\3";
695            case UNKNOWNGROUP:
696                return "\5";
697            case USERNOTINGROUP:
698                return "\6";
699            case USERDELETED:
700                return "\7";
701            case GROUPDELETED:
702                return "\10";
703            default:
704                break;
705                /* Bogus, retry */
706            }
707                   
708        }
709
710        if(retry == RETRY_COUNT) {
711            /* We timed out in contacting... Allow printing*/
712            return 0;
713        }
714        return 0;
715    }
716
717#endif
718
719#ifdef LACL
720char *check_lacl(file)
721char *file;
722    {
723        FILE *cfp;
724        char person[BUFSIZ];
725#ifdef KERBEROS
726        extern char local_realm[];
727#endif
728        person[0] = '\0';
729
730        if(!AC) {
731            syslog("lpd: ACL file not set");
732            return NULL;
733        }
734        if(access(AC, R_OK)) {
735            syslog(LOG_ERR, "lpd: Could not find ACL file %s", AC);
736            return NULL;
737        }
738        if ((cfp = fopen(file, "r")) == NULL)
739                return 0;
740
741        /* Read the control file for the person sending the job */
742        while (getline(cfp)) {
743                if (line[0] == 'P' && line[1]) {
744                    strcpy(person, line + 1);
745                    break;
746                }
747        }
748        fclose(cfp);
749
750        if(!person[0]) {
751#ifdef DEBUG
752            syslog(LOG_DEBUG, "Person not found :%s", line);
753#endif
754            goto notfound;
755        }
756#ifdef DEBUG
757        else
758            syslog(LOG_DEBUG, "Found person :%s:%s", line, person);
759#endif
760
761#ifdef KERBEROS
762        /* Now to tack the realm on */
763        if(kerberos_cf && !index(person, '@')) {
764            strcat(person,"@");
765            strcat(person, local_realm);
766        }
767
768#endif /* KERBEROS */
769
770#ifdef DEBUG
771        syslog(LOG_DEBUG, "Checking on :%s: ", person);
772#endif
773
774        /* Now see if the person is in AC */
775
776        if ((cfp = fopen(AC, "r")) == NULL)
777                return 0;
778           
779        while(getline(cfp)) {
780            if(!strcasecmp(person, line)) {
781                fclose(cfp);
782                goto found;
783            }
784        }
785        fclose(cfp);
786
787    notfound:
788        if(PA) return "\4"; /* NOALLOWEDTOPRINT */
789        else return NULL;
790
791    found:
792        if(PA) return NULL;
793        else return "\4"; /* NOALLOWEDTOPRINT */
794    }
795
796char *
797check_remhost()
798{
799    register char *cp, *sp;
800    extern char from_host[];
801    register FILE *hostf;
802    char ahost[MAXHOSTNAMELEN];
803    int baselen = -1;
804
805    if(!strcasecmp(from_host, host)) return NULL;
806#if 0
807    syslog(LOG_DEBUG, "About to check on %s\n", from_host);
808#endif
809    sp = from_host;
810    cp = ahost;
811    while (*sp) {
812        if (*sp == '.') {
813            if (baselen == -1)
814                baselen = sp - from_host;
815            *cp++ = *sp++;
816        } else {
817            *cp++ = isupper(*sp) ? tolower(*sp++) : *sp++;
818        }
819    }
820    *cp = '\0';
821    hostf = fopen("/etc/hosts.lpd", "r");
822#define DUMMY ":nobody::"
823    if (hostf) {
824        if (!_validuser(hostf, ahost, DUMMY, DUMMY, baselen)) {
825            (void) fclose(hostf);
826            return NULL;
827        }
828        (void) fclose(hostf);
829        return "\4";
830    } else {
831        /* Could not open hosts.lpd file */
832        return NULL;
833    }
834}
835#endif /* LACL */
Note: See TracBrowser for help on using the repository browser.