ftp.nice.ch/pub/next/tools/ups/upsdeamon.N.bs.tar.gz#/upsd/ups_folder/funcs.c

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

/*
**	f u n c s . c
**
**	functions for UPS monitor daemon
**
**	Arthur W. Neilson III
**	art@pilikia.pegasus.com
**	Sat Mar 30 1991
*/

#include <sys/ioctl.h>
#include "common.h"

/*
**	g e t v a r s
**
**	retrieve environment variables
*/
void
getvars()
{
	char   *s, *getenv();

	if ((s = getenv(UPSPORT)) != NULL)
		ups_port = s;
	if ((s = getenv(UPSSHUT)) != NULL)
		ups_shut = s;
	if ((s = getenv(UPSLOG)) != NULL)
		ups_log = s;
	if ((s = getenv(UPSFAIL)) != NULL)
		ups_fail = s;
	if ((s = getenv(UPSREST)) != NULL)
		ups_rest = s;
	if ((s = getenv(UPSTIME)) != NULL)
		ups_time = atoi(s);
}

/*
**	g e t o p t i o n s
**
**	retrieve and process command line options
*/
void
getoptions(ac, av)
int     ac;
char   *av[];
{
	int     c;

	void    version();
	void    usage();

	extern char *optarg;
	extern int optind, opterr;

	/* display program version */
	version(av[0]);

	/* parse the command line */
	while ((c = getopt(ac, av, "d:c:l:f:r:t:")) != EOF)
		switch (c) {
		case 'd':	/* device option */
			ups_port = optarg;
			break;
		case 'c':	/* command option */
			ups_shut = optarg;
			break;
		case 'l':	/* logfile option */
			ups_log = optarg;
			break;
		case 'f':	/* failure option */
			ups_fail = optarg;
			break;
		case 'r':	/* restore option */
			ups_rest = optarg;
			break;
		case 't':	/* time option */
			ups_time = atoi(optarg);
			break;
		case '\?':	/* illegal option */
			usage(av[0]);
			exit(1);
		}
}

/*
**	c h k o p t i o n s
**
**	check runtime options
**	with various sanity tests
*/
void
chkoptions()
{
	struct stat st;
	char   *p, buf[64];

	/* UPS port must exist */
	if (stat(ups_port, &st) == ERR) {
		perror(ups_port);
		exit(1);
	}
	/* and must be character special */
	if ((st.st_mode & S_IFMT) != S_IFCHR) {
		fprintf(stderr, "%s not character special\n", ups_port);
		exit(1);
	}
	/* get command name out of shutdown command */
	strcpy(buf, ups_shut);
	if ((p = strtok(buf, " ")) == NULL)
		p = buf;

	/* shutdown command must exist */
	if (stat(p, &st) == ERR) {
		perror(ups_shut);
		exit(1);
	}
	/* and must be a regular file */
	if ((st.st_mode & S_IFMT) != S_IFREG) {
		fprintf(stderr, "%s not regular\n", ups_port);
		exit(1);
	}
	/* delay time must be > 0 and <= MAX_TIME */
	if (ups_time < 1 || ups_time > MAX_TIME) {
		fprintf(stderr, "time must be between 1 and %d\n", MAX_TIME);
		exit(1);
	}
}

/*
**	m k d a e m o n
**
**	create daemon process
*/
void
mkdaemon()
{
	char    c;
	int	stat;
	unsigned int	modembits;
	unsigned int 	oldbits;

	void    sigcatch();
	void    writelog();
	void    writeall();
	void    shutdown();

	writelog(START_MSG);



	if (!fork()) {

		/* close standard files */

		close(0);	/* stdin */
		close(1);	/* stdout */
		close(2);	/* stderr */


		setpgrp();	/* disassociate from terminal */

		/* ignore interrupts */
		signal(SIGHUP, SIG_IGN);
		signal(SIGINT, SIG_IGN);
		signal(SIGQUIT, SIG_IGN);

		/* catch termination signal */
		signal(SIGTERM, sigcatch);

		/* and shutdown on alarm */
		signal(SIGALRM, shutdown);

		/* open log file for append */
		if ((log_fd = open(ups_log, LOG_FLAGS, LOG_PERMS)) == ERR) {
			perror("could not open log file");
			exit(1);
		}


		/* and advisory lock it */
/*
		if (lockf(log_fd, F_TLOCK, 0L) == ERR) {
			perror("could not open lock file");
			exit(1);
		}
*/

		writelog(START_MSG);

		ups_fd = open(ups_port,O_RDONLY,0);
		if (stat<0) {
			perror("cant open port");
			exit(1);
		}
		/* get old bits first time */
		stat = ioctl(ups_fd,TIOCMGET,&oldbits);
		while (1) {

			stat = ioctl(ups_fd,TIOCMGET,&modembits);
			if (modembits!=oldbits) {
				
				if (state==UPS_LINE) {
					state = UPS_BATTERY;
				} else {
					state = UPS_LINE;
				}

				switch(state) {

				case UPS_LINE :
					writelog(ONLINE_MSG);
					writeall(ups_rest);
					alarm(0);

					break;

				case UPS_BATTERY :
					writelog(BATTERY_MSG);
					writeall(ups_fail);
					alarm(ups_time * SECS_PER_MIN/4);
					break;

				}
				oldbits = modembits;
			}

			sleep(interval);
		}
		


		close(log_fd);
		close(ups_fd);

	} else {

		printf("process forked\n");
	}
}

/*
**	s i g c a t c h
**
**	catch termination signal
*/
void
sigcatch()
{
	writelog(TERM_MSG);

	close(log_fd);
	close(ups_fd);


	exit(1);
}

/*
**	w r i t e l o g
**
**	write message to the UPS log file
*/
void
writelog(msg)
char   *msg;
{
	time_t  ticks;
	char   *p, *ct;
	char    msg_buf[80];
	char 	*strrchr();

	time(&ticks);
	ct = ctime(&ticks);

	/* find newline in buffer */
	if ((p = strrchr(ct, '\n')) != NULL)
		*p = NULL;	/* and zap it */

	sprintf(msg_buf, "%s -- %s\n", ct, msg);
	write(log_fd, msg_buf, strlen(msg_buf));
}

/*
**	w r i t e a l l
**
**	write to all users
*/
void
writeall(fn)
char   *fn;
{
	struct stat st;
	void    attach();

	/* message file must exist */
	if (stat(fn, &st) == ERR)
		return;

	/* and must be a regular file */
	if ((st.st_mode & S_IFMT) != S_IFREG)
		return;

	if (!fork()) {

		attach(CONSOLE);

		/* write message file to users */
		execlp(WALL, WALL, fn, NULL);
	}
}

/*
**	s h u t d o w n
**
**	shutdown the system
*/
void
shutdown()
{
	void    attach();

	writelog(SHUTDOWN_MSG);

	close(ups_log);
	close(ups_port);

	if (!fork()) {

		attach(CONSOLE);

		chdir(ROOT);

		/* execute shutdown command */
		execlp(SH, SH, ups_shut, NULL);
	}
}

/*
**	a t t a c h
**
**	attach standard i/o to a device
*/
void
attach(dev)
char   *dev;
{
	int     fd;

	/* close standard files */
	close(0);		/* stdin */
	close(1);		/* stdout */
	close(2);		/* stderr */

	/* attach stdin to named device */
	if ((fd = open(dev, O_RDWR)) == ERR)
		exit(1);
	dup(fd);		/* and stdout */
	dup(fd);		/* and stderr */
}

/*
**	b a s e n a m e
**
**	remove absolute path from filename
**
*/
char   *
basename(s)
char   *s;
{
	register char *p;

	/* point to char after last '/' */
	if ((p = strrchr(s, '/')) != NULL)
		return (++p);

	return (s);
}

/*
**	v e r s i o n
**
**	display program version
*/
void
version(s)
char   *s;
{
	char   *basename();

	/* display version in foreground */
	if (signal(SIGINT, SIG_IGN) != SIG_IGN)
		fprintf(stderr, "%s release %s version %d.%d patchlevel %d\n",
			basename(s), RELEASE_DATE, RELEASE, REVISION,
			PATCHLEVEL);
}

/*
**	u s a g e
**
**	display program usage
*/
void
usage(s)
char   *s;
{
	char   *basename();

	fprintf(stderr, "usage: %s [-d tty][-c cmd][-l file][-f file][-r file][-t min]\n", basename(s));
	fprintf(stderr, "\t-d tty\t\tpathname of UPS device\n");
	fprintf(stderr, "\t-c cmd\t\tpathname of shutdown command\n");
	fprintf(stderr, "\t-l file\t\tpathname of UPS log file\n");
	fprintf(stderr, "\t-f file\t\tpathname of UPS fail message file\n");
	fprintf(stderr, "\t-r file\t\tpathname of UPS restore message file\n");
	fprintf(stderr, "\t-t min\t\tdelay time in minutes\n");
}

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