home *** CD-ROM | disk | FTP | other *** search
- /*
- * Copyright (c) 1990 Regents of the University of California.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms are permitted
- * provided that the above copyright notice and this paragraph are
- * duplicated in all such forms and that any documentation,
- * advertising materials, and other materials related to such
- * distribution and use acknowledge that the software was developed
- * by the University of California, Riverside.
- *
- * NOTE : That's Riverside. Not Berkeley, not Santa Cruz, not even
- * Irvine. Riverside. Ri - ver - side.
- *
- * The name of the University may not be used to endorse or promote
- * products derived from this software without specific prior written
- * permission.
- *
- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
- * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
- *
- * MLPD -- Multiple Line Printer Daemon (Version 1.3)
- * SCCS keywords: @(#)printer.c 1.3 12/1/90
- */
-
- #include "config.h"
-
- /*
- // check_base_printer() -- Check the main printer queue.
- //
- // This function will go through the main printer queue and see
- // whether or not there are any files to print out. If there are,
- // notify the main program the number of files to print out. We
- // mainly want to see that there are files to print, so that all
- // of the other printer queues can be checked.
- */
-
- int check_base_printer()
- {
- #ifdef SUN
- struct dirent *d;
- #else
- struct direct *d;
- #endif
- DIR *dirpointer;
- int nitems;
-
- /*
- // First we open up the spooling directory for the main
- // spooler. Queueing should be allowed on this printer,
- // but printing should be turned off. We open up the
- // directory to read the files in them.
- */
- (void)debug("Checking base printer spooling directory...\n");
- if ((dirpointer = opendir(LP_SPOOL_DIRECTORY)) == NULL)
- {
- debug("Couldn't open directory.\n");
- return -1;
- }
- nitems = 0;
- /*
- // Now, while we have the chance, let's check out the files
- // in the directory and see whether something is printing or
- // not (if nothing is printing, there won't be any files in
- // the directory. lpd will delete them off.)
- */
- while ((d = readdir(dirpointer)) != NULL)
- {
- debug("Checking files in directory.\n");
- /*
- // See if the file has a df* extension.
- // This is the type of file that we want to use to
- // print out.
- */
- if (!strncmp(d->d_name, "cf", 2))
- {
- debug("Incrementing file count.\n");
- ++nitems;
- }
- }
- /*
- // Now close off the directory, and get back to main().
- */
- (void)closedir(dirpointer);
- return (nitems);
- }
-
- /*
- // check_prs() -- Check each printer queue.
- //
- // This function will go through the each printer queue and see
- // whether or not there are any files to print out. If there are,
- // notify the main program the printer is busy, otherwise tell the
- // main program that we would like a print job sent to us. All of
- // the printer queues are checked through this machine.
- */
-
- int check_prs(printers, cnt)
- printerstruct *printers;
- int cnt;
- {
- #ifdef SUN
- struct dirent *d;
- #else
- struct direct *d;
- #endif
- DIR *dirpointer;
- int nitems;
-
- /*
- // Try and create a char[] for the directory where
- // the printer is located.
- */
- /*
- // First we open up the spooling directory for our new
- // spooler. Printing should be allowed on this printer,
- // but queueing should be turned off. We open up the
- // directory to read the files in them.
- */
- if ((dirpointer = opendir(printers->directory[cnt])) == NULL)
- {
- bomb("check_prs:opendir");
- return -1;
- }
- nitems = 0;
- /*
- // Now, while we have the chance, let's check out the files
- // in the directory and see whether something is printing or
- // not. If something is printing, then we don't want to send
- // a job to this printer. If nothing is printing, we want
- // to ship out a job to the printer ASAP.
- */
- while ((d = readdir(dirpointer)) != NULL)
- {
- if (!strncmp(d->d_name, "cf", 2))
- {
- ++nitems;
- }
- }
- /*
- // Close off the directory pointer.
- */
- (void)closedir(dirpointer);
- /*
- // Return the number of files that are printing.
- */
- return(nitems);
- }
-
- /*
- // print_file() -- Print out a file in the spool directory.
- //
- // First, we try to find a file in the directory where we have
- // specified that we are going to print from. If we do, then we
- // take the job from one printer area to another, and "kick-start"
- // the new printer into printing out the jobs (We should have to
- // send a signal to lpd to get this job running.)
- */
-
- int print_file(p, cnt)
- printerstruct *p;
- int cnt;
- {
- #ifdef SUN
- struct dirent *d;
- #else
- struct direct *d;
- #endif
- DIR *dirpointer;
- int nitems;
-
- /*
- // Open up the spooling directory.
- */
- (void)debug("Yes, I can now print out a file!\n");
- if ((dirpointer = opendir(LP_SPOOL_DIRECTORY)) == NULL)
- {
- return -1;
- }
- nitems = 0;
- /*
- // Try to find some number of files to print out on the
- // printer. If we find a file, we send that file to the new
- // directory, and send a signal to the lpd program and
- // return back to the main program. If we do not get any
- // file from the directory, something must be messed up, so
- // we need to return our exit status to the main program.
- // While we are at it, we should pass along the control file
- // that goes with the data file, so that the printer can get
- // the proper information for the banner page, accounting, etc.
- */
- while (((d = readdir(dirpointer)) != NULL) && (nitems == 0))
- {
- /*
- // Check to see that the file we want to print
- // is a data file type in the directory.
- */
- if (!strncmp(d->d_name, "cf", 2))
- {
- /*
- // Move the files.
- */
- (void)debug("I am now attempting to move the files.\n");
- move_files(d->d_name, p, cnt);
- /*
- // Send off the signal to the lpd program.
- // We never use the return value, though.
- */
- (void)debug("Starting up the printer.\n");
- (void)send_lpd_signal(p->name[cnt]);
- ++nitems;
- }
- }
- /*
- // Close off the directory.
- */
- (void)closedir(dirpointer);
- if (nitems == 0)
- {
- bomb("readdir");
- }
- return(0);
- }
-
- /*
- // move_files() -- move the files from one spooling directory to another.
- //
- // This function will move all of the files associated with a print job
- // to a new spooling directory.
- //
- // Arguments: char *cffile -- the name of the control file.
- // printerstruct *p -- the printers structure.
- // int cnt -- the index into printerstruct specifying the printer
- // directory to move the files to.
- */
- move_files(cffile, p, cnt)
- char *cffile;
- printerstruct *p;
- int cnt;
- {
- char tmpbuf1[1024],tmpbuf2[1024],xbuf[1024],data[1024];
- FILE *fp, *fopen();
-
- xbuf[0] = '\0'; data[0] = '\0';
- (void)sprintf(xbuf, "%s/%s", LP_SPOOL_DIRECTORY, cffile);
- (void)debug("Opening and reading control file");
- if ((fp = fopen(xbuf, "r")) == NULL)
- {
- (void)debug("Bombing on fopen().\n");
- bomb("move_files:fopen");
- }
- data[0] = '\0';
- while (fgets(data, 1024, fp) > 0)
- {
- if (data[0] == 'f')
- {
- /*
- // Must be a file that we want...Move it.
- */
- (void)debug("Moving data file.\n");
- tmpbuf1[0] = '\0'; tmpbuf2[0] = '\0';
- data[strlen(data)-1] = '\0';
- (void)sprintf(tmpbuf1,"%s/%s",LP_SPOOL_DIRECTORY,&data[1]);
- (void)sprintf(tmpbuf2,"%s/%s",p->directory[cnt],&data[1]);
- if (rename(tmpbuf1, tmpbuf2) != 0)
- {
- bomb("move_files:fgets:rename");
- }
- }
- data[0] = '\0';
- }
- (void)fclose(fp);
- tmpbuf1[0] = '\0'; tmpbuf2[0] = '\0';
- (void)sprintf(tmpbuf1, "%s/%s", LP_SPOOL_DIRECTORY,cffile);
- (void)sprintf(tmpbuf2, "%s/%s", p->directory[cnt],cffile);
- (void)debug("Moving control file.\n");
- if (rename(tmpbuf1, tmpbuf2) != 0)
- {
- bomb("move_files:rename");
- }
- }
-
- /*
- // restart_all_printers() -- send a signal to restart all printers.
- //
- // We want to restart all printers when we first start up so that we can
- // clear jobs from those queues. This will be run every 30 seconds.
- //
- // Arguments: int nop -- The total number of printers.
- // printerstruct *printers -- the printers structure.
- */
-
- int restart_all_printers(nop, printers)
- int nop;
- printerstruct *printers;
- {
- int clt;
-
- for (clt = 0; clt < nop; ++clt)
- {
- (void)send_lpd_signal(printers->name[clt]);
- }
- }
-
- /*
- // send_lpd_signal() -- Send a signal to lpd to start printing from a printer.
- //
- // This function will create a socket, try and connect using that socket to
- // the default socket for the printer, and then if a connection can be made,
- // the printer is sent a control code to print out all files for a specific
- // printer. If this returns a \0, then everything was okay.
- //
- // Arguments : char *printer; (Name of the printer to use)
- */
-
- int send_lpd_signal(printer)
- char *printer;
- {
- struct sockaddr_un server;
- register int s, n;
- char buf[1024];
-
- s = socket(AF_UNIX, SOCK_STREAM, 0);
- if (s < 0)
- {
- if (errno == EMFILE)
- {
- bomb("send_lpd_signal:socket:EMFILE");
- }
- else if (errno == ENFILE)
- {
- bomb("send_lpd_signal:socket:ENFILE");
- }
- else if (errno == ENOBUFS)
- {
- bomb("send_lpd_signal:socket:ENOBUFS");
- }
- bomb("send_lpd_signal:socket:dont_know");
- }
- server.sun_family = AF_UNIX;
- #ifndef lint
- (void)strcpy((char *)server.sun_path, (char *)"/dev/printer");
- #endif
- if ((int)connect(s, (struct sockaddr *)&server, (int)strlen(server.sun_path) + 2) < 0)
- {
- bomb("connect");
- (void) close(s);
- return(0);
- }
- (void) sprintf(buf, "\1%s\n", printer);
- n = strlen(buf);
- if (write(s, buf, n) != n)
- {
- bomb("write");
- (void) close(s);
- return(0);
- }
- if (read(s, buf, 1) == 1)
- {
- if (buf[0] == '\0')
- {
- (void)close(s);
- return(1);
- }
- (void)putchar(buf[0]);
- }
- while ((n = read(s, buf, sizeof(buf))) > 0)
- (void)fwrite(buf, 1, n, stdout);
- (void)close(s);
- (void)debug("Signal has been sent to the printer %s.\n");
- return(0);
- }
-