File powerd-2.0.2.dif of Package sysvinit

--- COPYING
+++ COPYING	2014-01-14 10:28:52.282236069 +0000
@@ -2,7 +2,7 @@
 		       Version 2, June 1991
 
  Copyright (C) 1989, 1991 Free Software Foundation, Inc.
-                       59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+                       51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
  Everyone is permitted to copy and distribute verbatim copies
  of this license document, but changing it is not allowed.
 
@@ -305,7 +305,7 @@ the "copyright" line and a pointer to wh
 
     You should have received a copy of the GNU General Public License
     along with this program; if not, write to the Free Software
-    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+    Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 
 
 Also add information on how to contact you by electronic and paper mail.
--- Makefile.in
+++ Makefile.in	2006-02-07 16:29:20.000000000 +0100
@@ -28,7 +28,7 @@ distclean: clean
 	
 
 detectups: detectups.c
-	$(CC) $(LFLAGS) $(LIBS) detectups.c -o detectups
+	$(CC) $(LFLAGS) $(CFLAGS) $(LIBS) detectups.c -o detectups
 
 powerd: powerd.h config.h $(OBJS)
 	$(CC) $(LFLAGS) $(LIBS) $(OBJS) -o $@
--- config.h
+++ config.h	2006-02-07 16:31:03.000000000 +0100
@@ -8,7 +8,12 @@
 /* You shouldnt (and it wont work unless you have modified init) change
  * this file - this is what init uses to know the power status.
  */
-#define PWRSTAT         "/etc/powerstatus"
+#define PWRSTAT		"/var/run/powerstatus"
+#if WITH_SYSVINIT
+# include <initreq.h>
+# define NEWINIT
+# define INIT_REQ_SLEEP 5
+#endif
 
 
 /* Define this if you want to develop on powerd. This will cause powerd to 
--- powerd.8
+++ powerd.8	2014-01-14 10:59:42.198735732 +0000
@@ -104,13 +104,10 @@ for more information
 .br
 /etc/powerd.conf	powerd configuration file
 .br
-/etc/powerstatus	indicates line power status
-.br
-/etc/inittab		init is what actually issues the 
-				shutdown
+/var/run/powerstatus	indicates line power status
 .br
 .SH SEE ALSO
-powerd(8), shutdown(8), wall(1), init(8), inittab(5).
+powerd(8), shutdown(8), wall(1), init(8).
 .SH AUTHOR
 James Brents <James@nistix.com>
 (with parts of this man page borrowed from all over the Linux community)
--- powerd.c
+++ powerd.c	2008-01-10 10:48:25.967567115 +0100
@@ -27,7 +27,6 @@
 
 #include "powerd.h" 
 
-
 static Client *clients;
 static Listen *listens;
 
@@ -73,7 +72,10 @@ int main(int argc, char **argv)
     int i;
 #endif
     char *me=argv[0];
+    char *base = basename(me);
+    char *pidf = NULL;
     int delay = 16;
+    int n;
 
     if (argc<1 || (argc >1 && (!strcmp(argv[1], "--help") || !strcmp(argv[1], "-h")))) {
 	printf("powerd %s by: James Brents <james@nistix.com> (DaSyonic)\n\n", ver);
@@ -88,14 +90,42 @@ int main(int argc, char **argv)
 #ifndef DEBUG
     switch(i=fork()) {
     case 0: /* Child */
-	chdir("/");
+	if (chdir("/") < 0)
+		fprintf(stderr, "%s: %s\n", me, strerror(errno));
 	setsid();
 
 	if ((root = getuid())) {
-		fprintf(stderr, "%s: need to have root privlidges.", me);
+		fprintf(stderr, "%s: need to have root privileges\n", me);
 	} else if (touser != NULL) {
 		if (seteuid(user = uname2id(touser)) == -1)
-			fprintf(stderr, "%s is not a valid username.", touser);
+			fprintf(stderr, "%s is not a valid username: %s\n", touser, strerror(errno));
+	}
+
+	if ((pidf = (char*)malloc(strlen(_PATH_VARRUN)+strlen(base)+1+3+1)) == NULL) {
+		fprintf(stderr, "%s: can create pid file: %s\n", me, strerror(errno));
+	} else {
+		pidf = strcpy(pidf, _PATH_VARRUN);
+		pidf = strcat(pidf, base);
+		pidf = strcat(pidf, ".pid");
+
+		if ((n = open(pidf, O_WRONLY|O_CREAT|O_TRUNC, S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH)) == -1) {
+			fprintf(stderr, "%s: can create pid file: %s\n", me, strerror(errno));
+		} else {
+			snprintf(logbuffer, sizeof(logbuffer)-1, "%d", (int)getpid());
+			if (write(n, logbuffer, strlen(logbuffer)) < 0)
+				fprintf(stderr, "%s: %s\n", me, strerror(errno));
+			close(n);
+		}
+	}
+
+	if ((n = open("/dev/null", O_RDWR)) == -1) {
+		fprintf(stderr, "%s: can not open /dev/null.", me);
+	} else {
+		(void)dup2(n, 0);
+		(void)dup2(n, 1);
+		(void)dup2(n, 2);
+		(void)close(n);
+		errno=0;
 	}
 
 	break;
@@ -116,6 +146,8 @@ int main(int argc, char **argv)
 	monitorups(delay);
     else if (mode == 1)
 	bindport();
+    if (pidf)
+	(void)unlink(pidf);
     exit(0);
 }
 
@@ -194,9 +226,12 @@ void monitorups(int delay) {
 /* log to the syslog */
 void log(int type, int facility, const char *entry, ...)
 {
+    va_list ap;
+    va_start(ap, entry);
     openlog("powerd", LOG_CONS | LOG_PID, facility);
-    syslog(type, entry);
+    vsyslog(type, entry, ap);
     closelog();
+    va_end(ap);
 }
 
 /* Borrowed from Apache
@@ -220,12 +255,39 @@ uid_t uname2id(char *name) {
  */
 void notifyinit(int status) {
 	unsigned int file;
+#ifdef NEWINIT
+	struct init_request req;
+	int success = 0;
+	void (*save_sigalrm)();
+#endif
 
 	errno = 0;
 
 	if (touser != NULL)
 	    seteuid(root);
 
+#ifdef NEWINIT
+	/* Fill out the request struct. */
+	memset(&req, 0, sizeof(req));
+	req.magic = INIT_MAGIC;
+	req.sleeptime = INIT_REQ_SLEEP;
+	req.cmd = (status == FAIL) ? INIT_CMD_POWERFAIL : INIT_CMD_POWEROK;
+
+	/* Open the fifo (with timeout) */
+	save_sigalrm = signal(SIGALRM, alarm_handler);
+	alarm(3);
+	if ((file = open(INIT_FIFO, O_WRONLY, 0644)) >= 0) {
+		if (write(file, &req, sizeof(req)) == sizeof(req))
+			success = 1;
+		close(file);
+	}
+	alarm(0);
+	(void)signal(SIGALRM, save_sigalrm);
+
+	if (!success) {
+		/* The old method ... */
+#endif
+
 	if ((file = open(PWRSTAT, O_CREAT | O_WRONLY, 0644)) == -1) {
 		fprintf(stderr, "Cant open %s: %s\n", PWRSTAT, strerror(errno));
 		exit(-1);
@@ -237,6 +299,10 @@ void notifyinit(int status) {
 #else
 	bsdshutdown(status);
 #endif
+
+#ifdef NEWINIT
+	}
+#endif
 	if (touser != NULL)
 	    seteuid(user);
 
@@ -259,7 +325,8 @@ void notifyinit(int status) {
  * connections
  */
 int bindport() {
-    int len, addr_len, newfd, sin_size, numbytes;
+    socklen_t len, sin_size;
+    int newfd, numbytes;
     struct sockaddr_in serveraddr, remoteaddr;
     struct timeval mytv;
     FileDescriptor *list;    
@@ -289,7 +356,7 @@ int bindport() {
 	exit(-1);
     }
 
-    len = sizeof(serveraddr);
+    len = (socklen_t)sizeof(serveraddr);
 
     if (getsockname(serverfd, (struct sockaddr *)&serveraddr, &len)) {
 	fprintf(stderr, "getsockname()\n"); 
@@ -301,8 +368,6 @@ int bindport() {
     if ((touser != NULL) && (listenport < 1024))
 	seteuid(user);
 
-    addr_len = sizeof(struct sockaddr);
-
 //    printf("Im here\n");
     while (1) {
 	errno = 0;
@@ -321,7 +386,7 @@ int bindport() {
 	
 	if (FD_ISSET(serverfd, &readfds)) {
 	    FileDescriptor *tmp;
-	    sin_size = sizeof(struct sockaddr_in);
+	    sin_size = (socklen_t)sizeof(struct sockaddr_in);
 	    if ((newfd=accept(serverfd, (struct sockaddr *)&remoteaddr, 
 				&sin_size)) == -1) {
 		perror("accept");
@@ -540,6 +605,15 @@ void debughelp(int sig)
     mypower = (mypower == 1) ? 0 : 1;
 }
 
+#ifdef NEWINIT
+/* alarm handler for communication with init */
+/* static */ void alarm_handler (int sig)
+{
+    printf("Writing to init FIFO %s timed out\n", INIT_FIFO);
+    sleep(1);
+}
+#endif
+
 /* Open and parse the configuration file
  */
 void openconfig(int *delay) {
--- powerd.h.in
+++ powerd.h.in	2008-01-10 10:46:28.348626572 +0100
@@ -60,6 +60,7 @@
 /***********           If you do, Please send patches.         **********/
 #include <stdio.h>
 #include <stdlib.h>
+#include <stdarg.h>
 #include <string.h>
 #include <signal.h>
 #include <unistd.h>
@@ -67,6 +68,7 @@
 #include <ctype.h>
 #include <sys/types.h>
 #include <sys/ioctl.h>
+#include <sys/stat.h>
 #include <errno.h>
 #include <syslog.h>
 #include <unistd.h>
@@ -77,6 +79,11 @@
 #include <arpa/inet.h>
 #include <sys/time.h>
 #include <netdb.h>
+#include <libgen.h>
+#include <paths.h>
+#ifndef _PATH_VARRUN
+# define  _PATH_VARRUN	"/var/run/"
+#endif
 
 #define CONNECTED	0x01
 #define SENTNOTICE	0x02
@@ -122,7 +129,8 @@ struct filedescriptor_ {
     Listen *listen;
 };
 
-void log(int type, int facility, const char *entry, ...);
+void mylog(int type, int facility, const char *entry, ...);
+#define	log(args...)	mylog(args)
 uid_t uname2id(char *name);
 void notifyinit(int status);
 void monitorups(int delay);
@@ -139,6 +147,7 @@ int vhost(FileDescriptor *fd, char *para
 void auth(FileDescriptor *fd, char *password);
 void quit_sig(int sig);
 void debughelp(int sig);
+/* static */ void alarm_handler(int sig);
 int notifyclients(int status);
 void getrid(FileDescriptor *fd, int i);
 void bsdshutdown(int status);
--- initreq.h
+++ initreq.h	2013-08-13 20:02:46.132705014 +0000
@@ -0,0 +1,77 @@
+/*
+ * initreq.h	Interface to talk to init through /dev/initctl.
+ *
+ *		Copyright (C) 1995-2004 Miquel van Smoorenburg
+ *
+ *		This library is free software; you can redistribute it and/or
+ *		modify it under the terms of the GNU Lesser General Public
+ *		License as published by the Free Software Foundation; either
+ *		version 2 of the License, or (at your option) any later version.
+ *
+ * Version:     @(#)initreq.h  1.28  31-Mar-2004 MvS
+ *
+ */
+#ifndef _INITREQ_H
+#define _INITREQ_H
+
+#include <sys/param.h>
+
+#if defined(__FreeBSD_kernel__)
+#  define INIT_FIFO  "/etc/.initctl"
+#else
+#  define INIT_FIFO  "/dev/initctl"
+#endif
+
+#define INIT_MAGIC 0x03091969
+#define INIT_CMD_START		0
+#define INIT_CMD_RUNLVL		1
+#define INIT_CMD_POWERFAIL	2
+#define INIT_CMD_POWERFAILNOW	3
+#define INIT_CMD_POWEROK	4
+#define INIT_CMD_BSD		5
+#define INIT_CMD_SETENV		6
+#define INIT_CMD_UNSETENV	7
+
+#define INIT_CMD_CHANGECONS	12345
+
+#ifdef MAXHOSTNAMELEN
+#  define INITRQ_HLEN	MAXHOSTNAMELEN
+#else
+#  define INITRQ_HLEN	64
+#endif
+
+/*
+ *	This is what BSD 4.4 uses when talking to init.
+ *	Linux doesn't use this right now.
+ */
+struct init_request_bsd {
+	char	gen_id[8];		/* Beats me.. telnetd uses "fe" */
+	char	tty_id[16];		/* Tty name minus /dev/tty      */
+	char	host[INITRQ_HLEN];	/* Hostname                     */
+	char	term_type[16];		/* Terminal type                */
+	int	signal;			/* Signal to send               */
+	int	pid;			/* Process to send to           */
+	char	exec_name[128];	        /* Program to execute           */
+	char	reserved[128];		/* For future expansion.        */
+};
+
+
+/*
+ *	Because of legacy interfaces, "runlevel" and "sleeptime"
+ *	aren't in a separate struct in the union.
+ *
+ *	The weird sizes are because init expects the whole
+ *	struct to be 384 bytes.
+ */
+struct init_request {
+	int	magic;			/* Magic number                 */
+	int	cmd;			/* What kind of request         */
+	int	runlevel;		/* Runlevel to change to        */
+	int	sleeptime;		/* Time between TERM and KILL   */
+	union {
+		struct init_request_bsd	bsd;
+		char			data[368];
+	} i;
+};
+
+#endif