122426Sdist /* 222426Sdist * Copyright (c) 1983 Regents of the University of California. 334203Sbostic * All rights reserved. 434203Sbostic * 534203Sbostic * Redistribution and use in source and binary forms are permitted 634936Sbostic * provided that the above copyright notice and this paragraph are 734936Sbostic * duplicated in all such forms and that any documentation, 834936Sbostic * advertising materials, and other materials related to such 934936Sbostic * distribution and use acknowledge that the software was developed 1034936Sbostic * by the University of California, Berkeley. The name of the 1134936Sbostic * University may not be used to endorse or promote products derived 1234936Sbostic * from this software without specific prior written permission. 1334936Sbostic * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR 1434936Sbostic * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED 1534936Sbostic * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. 1622426Sdist */ 1722426Sdist 1813952Ssam #ifndef lint 19*38736Stef static char sccsid[] = "@(#)common.c 5.5 (Berkeley) 08/22/89"; 2034203Sbostic #endif /* not lint */ 2113952Ssam 2212117Sralph /* 2312117Sralph * Routines and data common to all the line printer functions. 2412117Sralph */ 2512117Sralph 2612117Sralph #include "lp.h" 2712117Sralph 2812117Sralph int DU; /* daeomon user-id */ 2912117Sralph int MX; /* maximum number of blocks to copy */ 3013170Sralph int MC; /* maximum number of copies allowed */ 3112117Sralph char *LP; /* line printer device name */ 3212117Sralph char *RM; /* remote machine name */ 3312117Sralph char *RP; /* remote printer name */ 3412117Sralph char *LO; /* lock file name */ 3512117Sralph char *ST; /* status file name */ 3612117Sralph char *SD; /* spool directory */ 3712117Sralph char *AF; /* accounting file */ 3812117Sralph char *LF; /* log file for error messages */ 3912117Sralph char *OF; /* name of output filter (created once) */ 4012117Sralph char *IF; /* name of input filter (created per job) */ 4112433Sralph char *RF; /* name of fortran text filter (per job) */ 4212117Sralph char *TF; /* name of troff filter (per job) */ 4313235Sralph char *NF; /* name of ditroff filter (per job) */ 4412117Sralph char *DF; /* name of tex filter (per job) */ 4512117Sralph char *GF; /* name of graph(1G) filter (per job) */ 4612117Sralph char *VF; /* name of vplot filter (per job) */ 4712117Sralph char *CF; /* name of cifplot filter (per job) */ 4812117Sralph char *PF; /* name of vrast filter (per job) */ 4912117Sralph char *FF; /* form feed string */ 5012117Sralph char *TR; /* trailer string to be output when Q empties */ 5113170Sralph short SC; /* suppress multiple copies */ 5212117Sralph short SF; /* suppress FF on each print job */ 5312117Sralph short SH; /* suppress header page */ 5412117Sralph short SB; /* short banner instead of normal header */ 5518128Sralph short HL; /* print header last */ 5612117Sralph short RW; /* open LP for reading and writing */ 5712117Sralph short PW; /* page width */ 5812117Sralph short PL; /* page length */ 5912433Sralph short PX; /* page width in pixels */ 6012433Sralph short PY; /* page length in pixels */ 6112117Sralph short BR; /* baud rate if lp is a tty */ 6213170Sralph int FC; /* flags to clear if lp is a tty */ 6313170Sralph int FS; /* flags to set if lp is a tty */ 6413170Sralph int XC; /* flags to clear for local mode */ 6513170Sralph int XS; /* flags to set for local mode */ 6612433Sralph short RS; /* restricted to those with local accounts */ 6712117Sralph 6812117Sralph char line[BUFSIZ]; 6912117Sralph char pbuf[BUFSIZ/2]; /* buffer for printcap strings */ 7012117Sralph char *bp = pbuf; /* pointer into pbuf for pgetent() */ 7112117Sralph char *name; /* program name */ 7212117Sralph char *printer; /* printer name */ 7312117Sralph char host[32]; /* host machine name */ 7412117Sralph char *from = host; /* client's machine name */ 75*38736Stef int sendtorem; /* are we sending to a remote? */ 7612117Sralph 7712117Sralph /* 7812117Sralph * Create a connection to the remote printer server. 7912117Sralph * Most of this code comes from rcmd.c. 8012117Sralph */ 8112528Sralph getport(rhost) 8212528Sralph char *rhost; 8312117Sralph { 8412117Sralph struct hostent *hp; 8512117Sralph struct servent *sp; 8612117Sralph struct sockaddr_in sin; 8712117Sralph int s, timo = 1, lport = IPPORT_RESERVED - 1; 8812874Sralph int err; 8912117Sralph 9012117Sralph /* 9112117Sralph * Get the host address and port number to connect to. 9212117Sralph */ 9312528Sralph if (rhost == NULL) 9412117Sralph fatal("no remote host to connect to"); 9512528Sralph hp = gethostbyname(rhost); 9612117Sralph if (hp == NULL) 9712528Sralph fatal("unknown host %s", rhost); 9812117Sralph sp = getservbyname("printer", "tcp"); 9912117Sralph if (sp == NULL) 10012117Sralph fatal("printer/tcp: unknown service"); 10112117Sralph bzero((char *)&sin, sizeof(sin)); 10212117Sralph bcopy(hp->h_addr, (caddr_t)&sin.sin_addr, hp->h_length); 10312117Sralph sin.sin_family = hp->h_addrtype; 10412117Sralph sin.sin_port = sp->s_port; 10512117Sralph 10612117Sralph /* 10712117Sralph * Try connecting to the server. 10812117Sralph */ 10912117Sralph retry: 11012117Sralph s = rresvport(&lport); 11112117Sralph if (s < 0) 11212117Sralph return(-1); 113*38736Stef if (connect(s, (caddr_t)&sin, sizeof(sin)) < 0) { 11412874Sralph err = errno; 11512874Sralph (void) close(s); 11612874Sralph errno = err; 11712117Sralph if (errno == EADDRINUSE) { 11812117Sralph lport--; 11912117Sralph goto retry; 12012117Sralph } 12112117Sralph if (errno == ECONNREFUSED && timo <= 16) { 12212117Sralph sleep(timo); 12312117Sralph timo *= 2; 12412117Sralph goto retry; 12512117Sralph } 12612117Sralph return(-1); 12712117Sralph } 12812117Sralph return(s); 12912117Sralph } 13012117Sralph 13112117Sralph /* 13212117Sralph * Getline reads a line from the control file cfp, removes tabs, converts 13312117Sralph * new-line to null and leaves it in line. 13412117Sralph * Returns 0 at EOF or the number of characters read. 13512117Sralph */ 13612117Sralph getline(cfp) 13712117Sralph FILE *cfp; 13812117Sralph { 13912117Sralph register int linel = 0; 14012117Sralph register char *lp = line; 14112117Sralph register c; 14212117Sralph 14312117Sralph while ((c = getc(cfp)) != '\n') { 14412117Sralph if (c == EOF) 14512117Sralph return(0); 14612117Sralph if (c == '\t') { 14712117Sralph do { 14812117Sralph *lp++ = ' '; 14912117Sralph linel++; 15012117Sralph } while ((linel & 07) != 0); 15112117Sralph continue; 15212117Sralph } 15312117Sralph *lp++ = c; 15412117Sralph linel++; 15512117Sralph } 15612117Sralph *lp++ = '\0'; 15712117Sralph return(linel); 15812117Sralph } 15912117Sralph 16012117Sralph /* 16112117Sralph * Scan the current directory and make a list of daemon files sorted by 16212117Sralph * creation time. 16312117Sralph * Return the number of entries and a pointer to the list. 16412117Sralph */ 16512117Sralph getq(namelist) 16612117Sralph struct queue *(*namelist[]); 16712117Sralph { 16812117Sralph register struct direct *d; 16912117Sralph register struct queue *q, **queue; 17012117Sralph register int nitems; 17112117Sralph struct stat stbuf; 17212117Sralph int arraysz, compar(); 17312117Sralph DIR *dirp; 17412117Sralph 17513170Sralph if ((dirp = opendir(SD)) == NULL) 17612117Sralph return(-1); 17712117Sralph if (fstat(dirp->dd_fd, &stbuf) < 0) 17812874Sralph goto errdone; 17912117Sralph 18012117Sralph /* 18112117Sralph * Estimate the array size by taking the size of the directory file 18212117Sralph * and dividing it by a multiple of the minimum size entry. 18312117Sralph */ 18412117Sralph arraysz = (stbuf.st_size / 24); 18512117Sralph queue = (struct queue **)malloc(arraysz * sizeof(struct queue *)); 18612117Sralph if (queue == NULL) 18712874Sralph goto errdone; 18812117Sralph 18912117Sralph nitems = 0; 19012117Sralph while ((d = readdir(dirp)) != NULL) { 19112117Sralph if (d->d_name[0] != 'c' || d->d_name[1] != 'f') 19212117Sralph continue; /* daemon control files only */ 19312117Sralph if (stat(d->d_name, &stbuf) < 0) 19412117Sralph continue; /* Doesn't exist */ 19512117Sralph q = (struct queue *)malloc(sizeof(time_t)+strlen(d->d_name)+1); 19612117Sralph if (q == NULL) 19712874Sralph goto errdone; 19812117Sralph q->q_time = stbuf.st_mtime; 19912117Sralph strcpy(q->q_name, d->d_name); 20012117Sralph /* 20112117Sralph * Check to make sure the array has space left and 20212117Sralph * realloc the maximum size. 20312117Sralph */ 20412117Sralph if (++nitems > arraysz) { 20512117Sralph queue = (struct queue **)realloc((char *)queue, 20612117Sralph (stbuf.st_size/12) * sizeof(struct queue *)); 20712117Sralph if (queue == NULL) 20812874Sralph goto errdone; 20912117Sralph } 21012117Sralph queue[nitems-1] = q; 21112117Sralph } 21212117Sralph closedir(dirp); 21312117Sralph if (nitems) 21412117Sralph qsort(queue, nitems, sizeof(struct queue *), compar); 21512117Sralph *namelist = queue; 21612117Sralph return(nitems); 21712874Sralph 21812874Sralph errdone: 21912874Sralph closedir(dirp); 22012874Sralph return(-1); 22112117Sralph } 22212117Sralph 22312117Sralph /* 22412117Sralph * Compare modification times. 22512117Sralph */ 22612117Sralph static 22712117Sralph compar(p1, p2) 22812117Sralph register struct queue **p1, **p2; 22912117Sralph { 23012117Sralph if ((*p1)->q_time < (*p2)->q_time) 23112117Sralph return(-1); 23212117Sralph if ((*p1)->q_time > (*p2)->q_time) 23312117Sralph return(1); 23412117Sralph return(0); 23512117Sralph } 23612117Sralph 237*38736Stef /* 238*38736Stef * Figure out whether the local machine is the same 239*38736Stef * as the remote machine (RM) entry (if it exists). 240*38736Stef */ 241*38736Stef char * 242*38736Stef checkremote() 243*38736Stef { 244*38736Stef char name[MAXHOSTNAMELEN]; 245*38736Stef register struct hostent *hp; 246*38736Stef static char errbuf[128]; 247*38736Stef 248*38736Stef sendtorem = 0; /* assume printer is local */ 249*38736Stef if (RM != (char *)NULL) { 250*38736Stef /* get the official name of the local host */ 251*38736Stef gethostname(name, sizeof(name)); 252*38736Stef name[sizeof(name)-1] = '\0'; 253*38736Stef hp = gethostbyname(name); 254*38736Stef if (hp == (struct hostent *) NULL) { 255*38736Stef (void) sprintf(errbuf, 256*38736Stef "unable to get official name for local machine %s", 257*38736Stef name); 258*38736Stef return errbuf; 259*38736Stef } else (void) strcpy(name, hp->h_name); 260*38736Stef 261*38736Stef /* get the official name of RM */ 262*38736Stef hp = gethostbyname(RM); 263*38736Stef if (hp == (struct hostent *) NULL) { 264*38736Stef (void) sprintf(errbuf, 265*38736Stef "unable to get official name for remote machine %s", 266*38736Stef RM); 267*38736Stef return errbuf; 268*38736Stef } 269*38736Stef 270*38736Stef /* 271*38736Stef * if the two hosts are not the same, 272*38736Stef * then the printer must be remote. 273*38736Stef */ 274*38736Stef if (strcmp(name, hp->h_name) != 0) 275*38736Stef sendtorem = 1; 276*38736Stef } 277*38736Stef return (char *)0; 278*38736Stef } 279*38736Stef 28012117Sralph /*VARARGS1*/ 28112117Sralph fatal(msg, a1, a2, a3) 28212117Sralph char *msg; 28312117Sralph { 28412117Sralph if (from != host) 28512117Sralph printf("%s: ", host); 28612117Sralph printf("%s: ", name); 28712117Sralph if (printer) 28812117Sralph printf("%s: ", printer); 28912117Sralph printf(msg, a1, a2, a3); 29012117Sralph putchar('\n'); 29112117Sralph exit(1); 29212117Sralph } 293