122426Sdist /* 222426Sdist * Copyright (c) 1983 Regents of the University of California. 3*34203Sbostic * All rights reserved. 4*34203Sbostic * 5*34203Sbostic * Redistribution and use in source and binary forms are permitted 6*34203Sbostic * provided that this notice is preserved and that due credit is given 7*34203Sbostic * to the University of California at Berkeley. The name of the University 8*34203Sbostic * may not be used to endorse or promote products derived from this 9*34203Sbostic * software without specific prior written permission. This software 10*34203Sbostic * is provided ``as is'' without express or implied warranty. 1122426Sdist */ 1222426Sdist 1313952Ssam #ifndef lint 14*34203Sbostic static char sccsid[] = "@(#)common.c 5.3 (Berkeley) 05/05/88"; 15*34203Sbostic #endif /* not lint */ 1613952Ssam 1712117Sralph /* 1812117Sralph * Routines and data common to all the line printer functions. 1912117Sralph */ 2012117Sralph 2112117Sralph #include "lp.h" 2212117Sralph 2312117Sralph int DU; /* daeomon user-id */ 2412117Sralph int MX; /* maximum number of blocks to copy */ 2513170Sralph int MC; /* maximum number of copies allowed */ 2612117Sralph char *LP; /* line printer device name */ 2712117Sralph char *RM; /* remote machine name */ 2812117Sralph char *RP; /* remote printer name */ 2912117Sralph char *LO; /* lock file name */ 3012117Sralph char *ST; /* status file name */ 3112117Sralph char *SD; /* spool directory */ 3212117Sralph char *AF; /* accounting file */ 3312117Sralph char *LF; /* log file for error messages */ 3412117Sralph char *OF; /* name of output filter (created once) */ 3512117Sralph char *IF; /* name of input filter (created per job) */ 3612433Sralph char *RF; /* name of fortran text filter (per job) */ 3712117Sralph char *TF; /* name of troff filter (per job) */ 3813235Sralph char *NF; /* name of ditroff filter (per job) */ 3912117Sralph char *DF; /* name of tex filter (per job) */ 4012117Sralph char *GF; /* name of graph(1G) filter (per job) */ 4112117Sralph char *VF; /* name of vplot filter (per job) */ 4212117Sralph char *CF; /* name of cifplot filter (per job) */ 4312117Sralph char *PF; /* name of vrast filter (per job) */ 4412117Sralph char *FF; /* form feed string */ 4512117Sralph char *TR; /* trailer string to be output when Q empties */ 4613170Sralph short SC; /* suppress multiple copies */ 4712117Sralph short SF; /* suppress FF on each print job */ 4812117Sralph short SH; /* suppress header page */ 4912117Sralph short SB; /* short banner instead of normal header */ 5018128Sralph short HL; /* print header last */ 5112117Sralph short RW; /* open LP for reading and writing */ 5212117Sralph short PW; /* page width */ 5312117Sralph short PL; /* page length */ 5412433Sralph short PX; /* page width in pixels */ 5512433Sralph short PY; /* page length in pixels */ 5612117Sralph short BR; /* baud rate if lp is a tty */ 5713170Sralph int FC; /* flags to clear if lp is a tty */ 5813170Sralph int FS; /* flags to set if lp is a tty */ 5913170Sralph int XC; /* flags to clear for local mode */ 6013170Sralph int XS; /* flags to set for local mode */ 6112433Sralph short RS; /* restricted to those with local accounts */ 6212117Sralph 6312117Sralph char line[BUFSIZ]; 6412117Sralph char pbuf[BUFSIZ/2]; /* buffer for printcap strings */ 6512117Sralph char *bp = pbuf; /* pointer into pbuf for pgetent() */ 6612117Sralph char *name; /* program name */ 6712117Sralph char *printer; /* printer name */ 6812117Sralph char host[32]; /* host machine name */ 6912117Sralph char *from = host; /* client's machine name */ 7012117Sralph 7112117Sralph /* 7212117Sralph * Create a connection to the remote printer server. 7312117Sralph * Most of this code comes from rcmd.c. 7412117Sralph */ 7512528Sralph getport(rhost) 7612528Sralph char *rhost; 7712117Sralph { 7812117Sralph struct hostent *hp; 7912117Sralph struct servent *sp; 8012117Sralph struct sockaddr_in sin; 8112117Sralph int s, timo = 1, lport = IPPORT_RESERVED - 1; 8212874Sralph int err; 8312117Sralph 8412117Sralph /* 8512117Sralph * Get the host address and port number to connect to. 8612117Sralph */ 8712528Sralph if (rhost == NULL) 8812117Sralph fatal("no remote host to connect to"); 8912528Sralph hp = gethostbyname(rhost); 9012117Sralph if (hp == NULL) 9112528Sralph fatal("unknown host %s", rhost); 9212117Sralph sp = getservbyname("printer", "tcp"); 9312117Sralph if (sp == NULL) 9412117Sralph fatal("printer/tcp: unknown service"); 9512117Sralph bzero((char *)&sin, sizeof(sin)); 9612117Sralph bcopy(hp->h_addr, (caddr_t)&sin.sin_addr, hp->h_length); 9712117Sralph sin.sin_family = hp->h_addrtype; 9812117Sralph sin.sin_port = sp->s_port; 9912117Sralph 10012117Sralph /* 10112117Sralph * Try connecting to the server. 10212117Sralph */ 10312117Sralph retry: 10412117Sralph s = rresvport(&lport); 10512117Sralph if (s < 0) 10612117Sralph return(-1); 10712117Sralph if (connect(s, (caddr_t)&sin, sizeof(sin), 0) < 0) { 10812874Sralph err = errno; 10912874Sralph (void) close(s); 11012874Sralph errno = err; 11112117Sralph if (errno == EADDRINUSE) { 11212117Sralph lport--; 11312117Sralph goto retry; 11412117Sralph } 11512117Sralph if (errno == ECONNREFUSED && timo <= 16) { 11612117Sralph sleep(timo); 11712117Sralph timo *= 2; 11812117Sralph goto retry; 11912117Sralph } 12012117Sralph return(-1); 12112117Sralph } 12212117Sralph return(s); 12312117Sralph } 12412117Sralph 12512117Sralph /* 12612117Sralph * Getline reads a line from the control file cfp, removes tabs, converts 12712117Sralph * new-line to null and leaves it in line. 12812117Sralph * Returns 0 at EOF or the number of characters read. 12912117Sralph */ 13012117Sralph getline(cfp) 13112117Sralph FILE *cfp; 13212117Sralph { 13312117Sralph register int linel = 0; 13412117Sralph register char *lp = line; 13512117Sralph register c; 13612117Sralph 13712117Sralph while ((c = getc(cfp)) != '\n') { 13812117Sralph if (c == EOF) 13912117Sralph return(0); 14012117Sralph if (c == '\t') { 14112117Sralph do { 14212117Sralph *lp++ = ' '; 14312117Sralph linel++; 14412117Sralph } while ((linel & 07) != 0); 14512117Sralph continue; 14612117Sralph } 14712117Sralph *lp++ = c; 14812117Sralph linel++; 14912117Sralph } 15012117Sralph *lp++ = '\0'; 15112117Sralph return(linel); 15212117Sralph } 15312117Sralph 15412117Sralph /* 15512117Sralph * Scan the current directory and make a list of daemon files sorted by 15612117Sralph * creation time. 15712117Sralph * Return the number of entries and a pointer to the list. 15812117Sralph */ 15912117Sralph getq(namelist) 16012117Sralph struct queue *(*namelist[]); 16112117Sralph { 16212117Sralph register struct direct *d; 16312117Sralph register struct queue *q, **queue; 16412117Sralph register int nitems; 16512117Sralph struct stat stbuf; 16612117Sralph int arraysz, compar(); 16712117Sralph DIR *dirp; 16812117Sralph 16913170Sralph if ((dirp = opendir(SD)) == NULL) 17012117Sralph return(-1); 17112117Sralph if (fstat(dirp->dd_fd, &stbuf) < 0) 17212874Sralph goto errdone; 17312117Sralph 17412117Sralph /* 17512117Sralph * Estimate the array size by taking the size of the directory file 17612117Sralph * and dividing it by a multiple of the minimum size entry. 17712117Sralph */ 17812117Sralph arraysz = (stbuf.st_size / 24); 17912117Sralph queue = (struct queue **)malloc(arraysz * sizeof(struct queue *)); 18012117Sralph if (queue == NULL) 18112874Sralph goto errdone; 18212117Sralph 18312117Sralph nitems = 0; 18412117Sralph while ((d = readdir(dirp)) != NULL) { 18512117Sralph if (d->d_name[0] != 'c' || d->d_name[1] != 'f') 18612117Sralph continue; /* daemon control files only */ 18712117Sralph if (stat(d->d_name, &stbuf) < 0) 18812117Sralph continue; /* Doesn't exist */ 18912117Sralph q = (struct queue *)malloc(sizeof(time_t)+strlen(d->d_name)+1); 19012117Sralph if (q == NULL) 19112874Sralph goto errdone; 19212117Sralph q->q_time = stbuf.st_mtime; 19312117Sralph strcpy(q->q_name, d->d_name); 19412117Sralph /* 19512117Sralph * Check to make sure the array has space left and 19612117Sralph * realloc the maximum size. 19712117Sralph */ 19812117Sralph if (++nitems > arraysz) { 19912117Sralph queue = (struct queue **)realloc((char *)queue, 20012117Sralph (stbuf.st_size/12) * sizeof(struct queue *)); 20112117Sralph if (queue == NULL) 20212874Sralph goto errdone; 20312117Sralph } 20412117Sralph queue[nitems-1] = q; 20512117Sralph } 20612117Sralph closedir(dirp); 20712117Sralph if (nitems) 20812117Sralph qsort(queue, nitems, sizeof(struct queue *), compar); 20912117Sralph *namelist = queue; 21012117Sralph return(nitems); 21112874Sralph 21212874Sralph errdone: 21312874Sralph closedir(dirp); 21412874Sralph return(-1); 21512117Sralph } 21612117Sralph 21712117Sralph /* 21812117Sralph * Compare modification times. 21912117Sralph */ 22012117Sralph static 22112117Sralph compar(p1, p2) 22212117Sralph register struct queue **p1, **p2; 22312117Sralph { 22412117Sralph if ((*p1)->q_time < (*p2)->q_time) 22512117Sralph return(-1); 22612117Sralph if ((*p1)->q_time > (*p2)->q_time) 22712117Sralph return(1); 22812117Sralph return(0); 22912117Sralph } 23012117Sralph 23112117Sralph /*VARARGS1*/ 23212117Sralph fatal(msg, a1, a2, a3) 23312117Sralph char *msg; 23412117Sralph { 23512117Sralph if (from != host) 23612117Sralph printf("%s: ", host); 23712117Sralph printf("%s: ", name); 23812117Sralph if (printer) 23912117Sralph printf("%s: ", printer); 24012117Sralph printf(msg, a1, a2, a3); 24112117Sralph putchar('\n'); 24212117Sralph exit(1); 24312117Sralph } 244