ftp.nice.ch/pub/next/unix/printing/npoffd.1.0.N.bs.tar.gz#/npoffd.1.0.N.bs/npoffd.c

This is npoffd.c in view mode; [Download] [Up]

/*
** This program turns off an idle NeXT printer after some given time,
** written by Yunliang Yu <yu@math.duke.edu>, 11/5/94
**
** Modified by Art Isbell (art@cubicsol.com) to take idleLimit as an optional
** argument with 180 seconds the default idleLimit if no argument is
** specified.  npoffd checks the printer idle time every checkPeriod (60 by
** default) seconds, so the actual idle limit can vary from idleLimit to
** idleLimit + checkPeriod seconds.  If this behavior isn't ideal, modify
** checkPeriod.
**
** npoffd fails to turn off the printer if a print job is aborted before any
** printing has occurred because npoffd depends on the modification time of the
** printer device which isn't updated until a page is printed.  A fix for this
** situation is left as an exercise for the reader :-)
**
** To build, as root:
**
** cc -O2 -object -s -arch m68k npoffd.c -o /usr/local/etc/npoffd
**
** To use, add the following to the /etc/rc.local file (assumes 180-second idle
** limit):
**
** if [ -x /usr/local/etc/npoffd ]; then
**     (sleep 5; /usr/local/etc/npoffd 180) &
** fi
**
** Use at your own risk, if any.
*/

#import <libc.h>
#import <time.h>
#import <syslog.h>
#import <sys/types.h>
#import <sys/stat.h>
#import <sys/file.h>
#import <sys/ioctl.h>
#import <mach/m68k/boolean.h>
#import <dev/m68k/npio.h>

static const char *printerPort = "/dev/np0";
static const char *syslogOpenMsg = "npoffd";
static const char *syslogOffMsg = "printer off";
static const char *syslogNoStatMsg = "can't stat %s, exit";

/* minimal idle limit before turning off */
static const int idleLimitDefault = 180;

/* frequency the printer's idle time is checked */
static const int checkPeriod = 60;

int main(int argc, char *argv[])
{
	char *chPtr;

	/* time printer port was last written.  Used to determine whether printing
	** has occurred within the past checkPeriod seconds. */
	time_t previousPrinterPortModifyTime = 0;
	int idleLimit;
	struct stat statBuffer;

	/* Get argument, if any. */
	if (argc != 2 || (idleLimit = (int)strtol(argv[1], &chPtr, 10)) <= 0)
	{
		idleLimit = idleLimitDefault;
	}
	/* Set up syslog. */
	openlog(syslogOpenMsg, LOG_PID, LOG_DAEMON);
	setlogmask(LOG_UPTO(LOG_ERR));

	/* Loop while printer port is accessible. */
	while (stat(printerPort, &statBuffer) != -1)
	{
		/* last time printer port was written */
		time_t printerPortModifyTime = statBuffer.st_mtime;
		int fileDescriptor;

		/* If printing has occurred and printer has been idle for more than
		** idleLimit seconds, power off printer. */
		if (printerPortModifyTime != previousPrinterPortModifyTime &&
			time(0) - printerPortModifyTime > idleLimit &&
			(fileDescriptor = open(printerPort, O_WRONLY | O_NDELAY, 0)) > 0)
		{
			/* structure for NPIOCPOP - printer op command */
			struct npop printerOpStruct;

			printerOpStruct.np_op = NPSETPOWER;
			printerOpStruct.np_power = 0;
			ioctl(fileDescriptor, NPIOCPOP, &printerOpStruct);
			close(fileDescriptor);
			syslog(LOG_ERR, syslogOffMsg);
			previousPrinterPortModifyTime = printerPortModifyTime;
		}
		sleep(checkPeriod);
	}
	syslog(LOG_ERR, syslogNoStatMsg, printerPort);
	closelog();
	exit(1);
}

These are the contents of the former NiCE NeXT User Group NeXTSTEP/OpenStep software archive, currently hosted by Netfuture.ch.