122426Sdist /* 222426Sdist * Copyright (c) 1983 Regents of the University of California. 334203Sbostic * All rights reserved. 434203Sbostic * 542801Sbostic * %sccs.include.redist.c% 622426Sdist */ 722426Sdist 813952Ssam #ifndef lint 9*46910Sbostic static char sccsid[] = "@(#)common.c 5.7 (Berkeley) 03/02/91"; 1034203Sbostic #endif /* not lint */ 1113952Ssam 1212117Sralph /* 1312117Sralph * Routines and data common to all the line printer functions. 1412117Sralph */ 1512117Sralph 1612117Sralph #include "lp.h" 1712117Sralph 1812117Sralph int DU; /* daeomon user-id */ 1912117Sralph int MX; /* maximum number of blocks to copy */ 2013170Sralph int MC; /* maximum number of copies allowed */ 2112117Sralph char *LP; /* line printer device name */ 2212117Sralph char *RM; /* remote machine name */ 2312117Sralph char *RP; /* remote printer name */ 2412117Sralph char *LO; /* lock file name */ 2512117Sralph char *ST; /* status file name */ 2612117Sralph char *SD; /* spool directory */ 2712117Sralph char *AF; /* accounting file */ 2812117Sralph char *LF; /* log file for error messages */ 2912117Sralph char *OF; /* name of output filter (created once) */ 3012117Sralph char *IF; /* name of input filter (created per job) */ 3112433Sralph char *RF; /* name of fortran text filter (per job) */ 3212117Sralph char *TF; /* name of troff filter (per job) */ 3313235Sralph char *NF; /* name of ditroff filter (per job) */ 3412117Sralph char *DF; /* name of tex filter (per job) */ 3512117Sralph char *GF; /* name of graph(1G) filter (per job) */ 3612117Sralph char *VF; /* name of vplot filter (per job) */ 3712117Sralph char *CF; /* name of cifplot filter (per job) */ 3812117Sralph char *PF; /* name of vrast filter (per job) */ 3912117Sralph char *FF; /* form feed string */ 4012117Sralph char *TR; /* trailer string to be output when Q empties */ 4113170Sralph short SC; /* suppress multiple copies */ 4212117Sralph short SF; /* suppress FF on each print job */ 4312117Sralph short SH; /* suppress header page */ 4412117Sralph short SB; /* short banner instead of normal header */ 4518128Sralph short HL; /* print header last */ 4612117Sralph short RW; /* open LP for reading and writing */ 4712117Sralph short PW; /* page width */ 4812117Sralph short PL; /* page length */ 4912433Sralph short PX; /* page width in pixels */ 5012433Sralph short PY; /* page length in pixels */ 5112117Sralph short BR; /* baud rate if lp is a tty */ 5213170Sralph int FC; /* flags to clear if lp is a tty */ 5313170Sralph int FS; /* flags to set if lp is a tty */ 5413170Sralph int XC; /* flags to clear for local mode */ 5513170Sralph int XS; /* flags to set for local mode */ 5612433Sralph short RS; /* restricted to those with local accounts */ 5712117Sralph 5812117Sralph char line[BUFSIZ]; 5912117Sralph char pbuf[BUFSIZ/2]; /* buffer for printcap strings */ 6012117Sralph char *bp = pbuf; /* pointer into pbuf for pgetent() */ 6112117Sralph char *name; /* program name */ 6212117Sralph char *printer; /* printer name */ 6312117Sralph char host[32]; /* host machine name */ 6412117Sralph char *from = host; /* client's machine name */ 6538736Stef int sendtorem; /* are we sending to a remote? */ 6612117Sralph 6712117Sralph /* 6812117Sralph * Create a connection to the remote printer server. 6912117Sralph * Most of this code comes from rcmd.c. 7012117Sralph */ 7112528Sralph getport(rhost) 7212528Sralph char *rhost; 7312117Sralph { 7412117Sralph struct hostent *hp; 7512117Sralph struct servent *sp; 7612117Sralph struct sockaddr_in sin; 7712117Sralph int s, timo = 1, lport = IPPORT_RESERVED - 1; 7812874Sralph int err; 7912117Sralph 8012117Sralph /* 8112117Sralph * Get the host address and port number to connect to. 8212117Sralph */ 8312528Sralph if (rhost == NULL) 8412117Sralph fatal("no remote host to connect to"); 8512528Sralph hp = gethostbyname(rhost); 8612117Sralph if (hp == NULL) 8712528Sralph fatal("unknown host %s", rhost); 8812117Sralph sp = getservbyname("printer", "tcp"); 8912117Sralph if (sp == NULL) 9012117Sralph fatal("printer/tcp: unknown service"); 9112117Sralph bzero((char *)&sin, sizeof(sin)); 9212117Sralph bcopy(hp->h_addr, (caddr_t)&sin.sin_addr, hp->h_length); 9312117Sralph sin.sin_family = hp->h_addrtype; 9412117Sralph sin.sin_port = sp->s_port; 9512117Sralph 9612117Sralph /* 9712117Sralph * Try connecting to the server. 9812117Sralph */ 9912117Sralph retry: 10012117Sralph s = rresvport(&lport); 10112117Sralph if (s < 0) 10212117Sralph return(-1); 103*46910Sbostic if (connect(s, (struct sockaddr *)&sin, sizeof(sin)) < 0) { 10412874Sralph err = errno; 10512874Sralph (void) close(s); 10612874Sralph errno = err; 10712117Sralph if (errno == EADDRINUSE) { 10812117Sralph lport--; 10912117Sralph goto retry; 11012117Sralph } 11112117Sralph if (errno == ECONNREFUSED && timo <= 16) { 11212117Sralph sleep(timo); 11312117Sralph timo *= 2; 11412117Sralph goto retry; 11512117Sralph } 11612117Sralph return(-1); 11712117Sralph } 11812117Sralph return(s); 11912117Sralph } 12012117Sralph 12112117Sralph /* 12212117Sralph * Getline reads a line from the control file cfp, removes tabs, converts 12312117Sralph * new-line to null and leaves it in line. 12412117Sralph * Returns 0 at EOF or the number of characters read. 12512117Sralph */ 12612117Sralph getline(cfp) 12712117Sralph FILE *cfp; 12812117Sralph { 12912117Sralph register int linel = 0; 13012117Sralph register char *lp = line; 13112117Sralph register c; 13212117Sralph 13312117Sralph while ((c = getc(cfp)) != '\n') { 13412117Sralph if (c == EOF) 13512117Sralph return(0); 13612117Sralph if (c == '\t') { 13712117Sralph do { 13812117Sralph *lp++ = ' '; 13912117Sralph linel++; 14012117Sralph } while ((linel & 07) != 0); 14112117Sralph continue; 14212117Sralph } 14312117Sralph *lp++ = c; 14412117Sralph linel++; 14512117Sralph } 14612117Sralph *lp++ = '\0'; 14712117Sralph return(linel); 14812117Sralph } 14912117Sralph 15012117Sralph /* 15112117Sralph * Scan the current directory and make a list of daemon files sorted by 15212117Sralph * creation time. 15312117Sralph * Return the number of entries and a pointer to the list. 15412117Sralph */ 15512117Sralph getq(namelist) 15612117Sralph struct queue *(*namelist[]); 15712117Sralph { 15812117Sralph register struct direct *d; 15912117Sralph register struct queue *q, **queue; 16012117Sralph register int nitems; 16112117Sralph struct stat stbuf; 16212117Sralph DIR *dirp; 163*46910Sbostic int arraysz; 164*46910Sbostic static int compar(); 16512117Sralph 16613170Sralph if ((dirp = opendir(SD)) == NULL) 16712117Sralph return(-1); 16812117Sralph if (fstat(dirp->dd_fd, &stbuf) < 0) 16912874Sralph goto errdone; 17012117Sralph 17112117Sralph /* 17212117Sralph * Estimate the array size by taking the size of the directory file 17312117Sralph * and dividing it by a multiple of the minimum size entry. 17412117Sralph */ 17512117Sralph arraysz = (stbuf.st_size / 24); 17612117Sralph queue = (struct queue **)malloc(arraysz * sizeof(struct queue *)); 17712117Sralph if (queue == NULL) 17812874Sralph goto errdone; 17912117Sralph 18012117Sralph nitems = 0; 18112117Sralph while ((d = readdir(dirp)) != NULL) { 18212117Sralph if (d->d_name[0] != 'c' || d->d_name[1] != 'f') 18312117Sralph continue; /* daemon control files only */ 18412117Sralph if (stat(d->d_name, &stbuf) < 0) 18512117Sralph continue; /* Doesn't exist */ 18612117Sralph q = (struct queue *)malloc(sizeof(time_t)+strlen(d->d_name)+1); 18712117Sralph if (q == NULL) 18812874Sralph goto errdone; 18912117Sralph q->q_time = stbuf.st_mtime; 19012117Sralph strcpy(q->q_name, d->d_name); 19112117Sralph /* 19212117Sralph * Check to make sure the array has space left and 19312117Sralph * realloc the maximum size. 19412117Sralph */ 19512117Sralph if (++nitems > arraysz) { 19612117Sralph queue = (struct queue **)realloc((char *)queue, 19712117Sralph (stbuf.st_size/12) * sizeof(struct queue *)); 19812117Sralph if (queue == NULL) 19912874Sralph goto errdone; 20012117Sralph } 20112117Sralph queue[nitems-1] = q; 20212117Sralph } 20312117Sralph closedir(dirp); 20412117Sralph if (nitems) 20512117Sralph qsort(queue, nitems, sizeof(struct queue *), compar); 20612117Sralph *namelist = queue; 20712117Sralph return(nitems); 20812874Sralph 20912874Sralph errdone: 21012874Sralph closedir(dirp); 21112874Sralph return(-1); 21212117Sralph } 21312117Sralph 21412117Sralph /* 21512117Sralph * Compare modification times. 21612117Sralph */ 21712117Sralph static 21812117Sralph compar(p1, p2) 21912117Sralph register struct queue **p1, **p2; 22012117Sralph { 22112117Sralph if ((*p1)->q_time < (*p2)->q_time) 22212117Sralph return(-1); 22312117Sralph if ((*p1)->q_time > (*p2)->q_time) 22412117Sralph return(1); 22512117Sralph return(0); 22612117Sralph } 22712117Sralph 22838736Stef /* 22938736Stef * Figure out whether the local machine is the same 23038736Stef * as the remote machine (RM) entry (if it exists). 23138736Stef */ 23238736Stef char * 23338736Stef checkremote() 23438736Stef { 23538736Stef char name[MAXHOSTNAMELEN]; 23638736Stef register struct hostent *hp; 23738736Stef static char errbuf[128]; 23838736Stef 23938736Stef sendtorem = 0; /* assume printer is local */ 24038736Stef if (RM != (char *)NULL) { 24138736Stef /* get the official name of the local host */ 24238736Stef gethostname(name, sizeof(name)); 24338736Stef name[sizeof(name)-1] = '\0'; 24438736Stef hp = gethostbyname(name); 24538736Stef if (hp == (struct hostent *) NULL) { 24638736Stef (void) sprintf(errbuf, 24738736Stef "unable to get official name for local machine %s", 24838736Stef name); 24938736Stef return errbuf; 25038736Stef } else (void) strcpy(name, hp->h_name); 25138736Stef 25238736Stef /* get the official name of RM */ 25338736Stef hp = gethostbyname(RM); 25438736Stef if (hp == (struct hostent *) NULL) { 25538736Stef (void) sprintf(errbuf, 25638736Stef "unable to get official name for remote machine %s", 25738736Stef RM); 25838736Stef return errbuf; 25938736Stef } 26038736Stef 26138736Stef /* 26238736Stef * if the two hosts are not the same, 26338736Stef * then the printer must be remote. 26438736Stef */ 26538736Stef if (strcmp(name, hp->h_name) != 0) 26638736Stef sendtorem = 1; 26738736Stef } 26838736Stef return (char *)0; 26938736Stef } 27038736Stef 27112117Sralph /*VARARGS1*/ 27212117Sralph fatal(msg, a1, a2, a3) 27312117Sralph char *msg; 27412117Sralph { 27512117Sralph if (from != host) 27612117Sralph printf("%s: ", host); 27712117Sralph printf("%s: ", name); 27812117Sralph if (printer) 27912117Sralph printf("%s: ", printer); 28012117Sralph printf(msg, a1, a2, a3); 28112117Sralph putchar('\n'); 28212117Sralph exit(1); 28312117Sralph } 284