[Date Prev] [Date Index] [Date Next] [Thread Prev] [Thread Index] [Thread Next]

[PATCH] Power control

Bill Peck bpeck@redhat.com
Fri, 29 Jun 2007 11:44:58 -0700 (PDT)



I have put together a patch that adds power control to conserver. I have to say that I'm not really a C programmer and I'm sure this will need to be cleaned up before its accepted. But I had an itch and wanted to contribute.


I've implemented the following commands for Default and Console:
powerreset, poweroff, and powersubst.

Here is an example from my Default Global section...

       powerreset /usr/sbin/power-reset --system C;
       poweroff /usr/sbin/power-off --system C;
       powersubst C=cs;


a snippit from the help section:


e    change escape sequence            f    force attach read/write
g    group info                        i    information dump
k0   iniate power off                  k1   iniate power reset
L    toggle logging on/off             l?   break sequence list


I'd appreciate any feedback and if anyone else finds this useful.


Obviously this doesn't handle the configuring of the command that does the actual work. But I think thats outside the scope of conserver.
diff -Nur conserver-8.1.14.orig/conserver/client.c conserver-8.1.14.subst/conserver/client.c
--- conserver-8.1.14.orig/conserver/client.c	2006-04-03 09:32:08.000000000 -0400
+++ conserver-8.1.14.subst/conserver/client.c	2007-06-29 13:50:26.000000000 -0400
@@ -394,6 +394,8 @@
     {WHEN_ALWAYS, "f    force attach read/write"},
     {WHEN_ALWAYS, "g    group info"},
     {WHEN_ALWAYS, "i    information dump"},
+    {WHEN_ATTACH, "k0   iniate power off"},
+    {WHEN_ATTACH, "k1   iniate power reset"},
     {WHEN_ATTACH, "L    toggle logging on/off"},
     {WHEN_ATTACH, "l?   break sequence list"},
     {WHEN_ATTACH, "l0   send break per config file"},
diff -Nur conserver-8.1.14.orig/conserver/client.h conserver-8.1.14.subst/conserver/client.h
--- conserver-8.1.14.orig/conserver/client.h	2006-04-03 09:32:08.000000000 -0400
+++ conserver-8.1.14.subst/conserver/client.h	2007-06-29 13:50:26.000000000 -0400
@@ -42,6 +42,7 @@
     S_CATTN,			/* change 1 escape char to next input char */
     S_CESC,			/* change 2 escape char to next input char */
     S_HALT1,			/* we have a halt sequence in progress     */
+    S_POWER,			/* we have a power sequence in progress    */
     S_SUSP,			/* we are suspened, first char wakes us up */
     S_IDENT,			/* probational connection (who is this)    */
     S_PASSWD,			/* still needs a passwd to connect         */
diff -Nur conserver-8.1.14.orig/conserver/consent.h conserver-8.1.14.subst/conserver/consent.h
--- conserver-8.1.14.orig/conserver/consent.h	2006-03-20 11:47:03.000000000 -0500
+++ conserver-8.1.14.subst/conserver/consent.h	2007-06-29 13:31:47.000000000 -0400
@@ -102,6 +102,9 @@
     /* type == EXEC */
     char *exec;			/* exec command                         */
     char *execsubst;		/* exec substitution pattern            */
+    char *poweroff;		/* poweroff command                     */
+    char *powerreset;		/* powerreset command                   */
+    char *powersubst;		/* power substitution pattern           */
     uid_t execuid;		/* user to run exec as                  */
     gid_t execgid;		/* group to run exec as                 */
     /* type == UDS */
diff -Nur conserver-8.1.14.orig/conserver/group.c conserver-8.1.14.subst/conserver/group.c
--- conserver-8.1.14.orig/conserver/group.c	2006-04-07 11:47:20.000000000 -0400
+++ conserver-8.1.14.subst/conserver/group.c	2007-06-29 14:18:24.000000000 -0400
@@ -1832,6 +1832,48 @@
     }
 }
 
+void
+#if PROTOTYPES
+SendPower(CONSCLIENT *pCLServing, CONSENT *pCEServing, short pt)
+#else
+SendPower(pCLServing, pCEServing, pt)
+    CONSCLIENT *pCLServing;
+    CONSENT *pCEServing;
+    short pt;
+#endif
+{
+    FILE *fpipe;
+    char line[256];
+    char *cmd;
+
+    if (pt < 0 || pt > 1) {
+	FileWrite(pCLServing->fd, FLAGFALSE, "aborted]\r\n", -1);
+	return;
+    }
+    if (pt == 0)
+        if ((cmd = StrDup(pCEServing->poweroff)) == (char *)0)
+            OutOfMem();
+
+    if (pt == 1) 
+        if ((cmd = StrDup(pCEServing->powerreset)) == (char *)0)
+            OutOfMem();
+
+    FilePrint(pCLServing->fd, FLAGFALSE, "Command %s\r\n", cmd);
+
+    if ( !(fpipe = (FILE*)popen(cmd,"r")) )
+    {  // If fpipe is NULL
+        FilePrint(pCLServing->fd, FLAGFALSE, "Failed\r\n");
+    }
+
+    while ( fgets( line, sizeof line, fpipe))
+    {
+        FilePrint(pCLServing->fd, FLAGFALSE, "%s", line);
+    }
+    pclose(fpipe);
+
+    FileWrite(pCLServing->fd, FLAGFALSE, "done]\r\n", -1);
+}
+
 #if HAVE_OPENSSL
 int
 #if PROTOTYPES
@@ -3428,6 +3470,22 @@
 			}
 			continue;
 
+		    case S_POWER:	/* power sequence? */
+			pCLServing->iState = S_NORMAL;
+			if (acIn[i] < '0' || acIn[i] > '1') {
+			    FileWrite(pCLServing->fd, FLAGFALSE,
+				      "aborted]\r\n", -1);
+			    continue;
+			}
+
+		        if (pCLServing->fwr) {
+			    int pt = acIn[i] - '0';
+			    SendPower(pCLServing, pCEServing, pt);
+		        } else
+			    FileWrite(pCLServing->fd, FLAGFALSE,
+				  "attach to send power]\r\n", -1);
+			continue;
+
 		    case S_HALT1:	/* halt sequence? */
 			pCLServing->iState = S_NORMAL;
 			if (acIn[i] != '?' &&
@@ -3630,6 +3688,18 @@
 					    tyme, (char *)0);
 				break;
 
+			    case 'k':	/* power character 1     */
+				if (pCEServing->fronly) {
+				    FileWrite(pCLServing->fd, FLAGFALSE,
+					      "can't power a read-only console]\r\n",
+					      -1);
+				    continue;
+				}
+				pCLServing->iState = S_POWER;
+				FileWrite(pCLServing->fd, FLAGFALSE,
+					  "power ", -1);
+				break;
+
 			    case 'L':
 				CommandLogging(pGE, pCLServing, pCEServing,
 					       tyme);
diff -Nur conserver-8.1.14.orig/conserver/readcfg.c conserver-8.1.14.subst/conserver/readcfg.c
--- conserver-8.1.14.orig/conserver/readcfg.c	2006-03-20 11:47:03.000000000 -0500
+++ conserver-8.1.14.subst/conserver/readcfg.c	2007-06-29 14:32:06.000000000 -0400
@@ -729,6 +729,18 @@
 	if ((c->exec = StrDup(d->exec)) == (char *)0)
 	    OutOfMem();
     }
+    if (d->poweroff != (char *)0) {
+	if (c->poweroff != (char *)0)
+	    free(c->poweroff);
+	if ((c->poweroff = StrDup(d->poweroff)) == (char *)0)
+	    OutOfMem();
+    }
+    if (d->powerreset != (char *)0) {
+	if (c->powerreset != (char *)0)
+	    free(c->powerreset);
+	if ((c->powerreset = StrDup(d->powerreset)) == (char *)0)
+	    OutOfMem();
+    }
     if (d->device != (char *)0) {
 	if (c->device != (char *)0)
 	    free(c->device);
@@ -747,6 +759,12 @@
 	if ((c->execsubst = StrDup(d->execsubst)) == (char *)0)
 	    OutOfMem();
     }
+    if (d->powersubst != (char *)0) {
+	if (c->powersubst != (char *)0)
+	    free(c->powersubst);
+	if ((c->powersubst = StrDup(d->powersubst)) == (char *)0)
+	    OutOfMem();
+    }
     if (d->initsubst != (char *)0) {
 	if (c->initsubst != (char *)0)
 	    free(c->initsubst);
@@ -925,6 +943,48 @@
 
 void
 #if PROTOTYPES
+ProcessPowerOff(CONSENT *c, char *id)
+#else
+ProcessPowerOff(c, id)
+    CONSENT *c;
+    char *id;
+#endif
+{
+    if (c->poweroff != (char *)0) {
+	free(c->poweroff);
+	c->poweroff = (char *)0;
+    }
+    if (id == (char *)0 || id[0] == '\000') {
+	return;
+    }
+    if ((c->poweroff = StrDup(id))
+	== (char *)0)
+	OutOfMem();
+}
+
+void
+#if PROTOTYPES
+ProcessPowerReset(CONSENT *c, char *id)
+#else
+ProcessPowerReset(c, id)
+    CONSENT *c;
+    char *id;
+#endif
+{
+    if (c->powerreset != (char *)0) {
+	free(c->poweroff);
+	c->powerreset = (char *)0;
+    }
+    if (id == (char *)0 || id[0] == '\000') {
+	return;
+    }
+    if ((c->powerreset = StrDup(id))
+	== (char *)0)
+	OutOfMem();
+}
+
+void
+#if PROTOTYPES
 DefaultItemBreak(char *id)
 #else
 DefaultItemBreak(id)
@@ -1106,6 +1166,19 @@
 
 void
 #if PROTOTYPES
+DefaultItemPowersubst(char *id)
+#else
+DefaultItemPowersubst(id)
+    char *id;
+#endif
+{
+    CONDDEBUG((1, "DefaultItemPowersubst(%s) [%s:%d]", id, file, line));
+    ProcessSubst(substData, (char **)0, &(parserDefaultTemp->powersubst),
+		 "powersubst", id);
+}
+
+void
+#if PROTOTYPES
 DefaultItemUdssubst(char *id)
 #else
 DefaultItemUdssubst(id)
@@ -1575,6 +1648,30 @@
 
 void
 #if PROTOTYPES
+DefaultItemPowerOff(char *id)
+#else
+DefaultItemPowerOff(id)
+    char *id;
+#endif
+{
+    CONDDEBUG((1, "DefaultItemPowerOff(%s) [%s:%d]", id, file, line));
+    ProcessPowerOff(parserDefaultTemp, id);
+}
+
+void
+#if PROTOTYPES
+DefaultItemPowerReset(char *id)
+#else
+DefaultItemPowerReset(id)
+    char *id;
+#endif
+{
+    CONDDEBUG((1, "DefaultItemPowerReset(%s) [%s:%d]", id, file, line));
+    ProcessPowerReset(parserDefaultTemp, id);
+}
+
+void
+#if PROTOTYPES
 DefaultItemMOTD(char *id)
 #else
 DefaultItemMOTD(id)
@@ -3141,6 +3238,14 @@
 	    ProcessSubst(substData, &(c->initcmd), (char **)0, (char *)0,
 			 c->initsubst);
 
+	/* go ahead and do the power subst */
+	if (c->powersubst != (char *)0) {
+	    ProcessSubst(substData, &(c->poweroff), (char **)0, (char *)0,
+			 c->powersubst);
+	    ProcessSubst(substData, &(c->powerreset), (char **)0, (char *)0,
+			 c->powersubst);
+	}
+
 	/* go ahead and do the '&' substitution */
 	if (c->logfile != (char *)0) {
 	    char *lf;
@@ -3490,6 +3595,19 @@
 
 void
 #if PROTOTYPES
+ConsoleItemPowersubst(char *id)
+#else
+ConsoleItemPowersubst(id)
+    char *id;
+#endif
+{
+    CONDDEBUG((1, "ConsoleItemPowersubst(%s) [%s:%d]", id, file, line));
+    ProcessSubst(substData, (char **)0, &(parserConsoleTemp->powersubst),
+		 "powersubst", id);
+}
+
+void
+#if PROTOTYPES
 ConsoleItemUdssubst(char *id)
 #else
 ConsoleItemUdssubst(id)
@@ -3636,6 +3754,30 @@
 
 void
 #if PROTOTYPES
+ConsoleItemPowerOff(char *id)
+#else
+ConsoleItemPowerOff(id)
+    char *id;
+#endif
+{
+    CONDDEBUG((1, "ConsoleItemPowerOff(%s) [%s:%d]", id, file, line));
+    ProcessPowerOff(parserConsoleTemp, id);
+}
+
+void
+#if PROTOTYPES
+ConsoleItemPowerReset(char *id)
+#else
+ConsoleItemPowerReset(id)
+    char *id;
+#endif
+{
+    CONDDEBUG((1, "ConsoleItemPower(%s) [%s:%d]", id, file, line));
+    ProcessPowerReset(parserConsoleTemp, id);
+}
+
+void
+#if PROTOTYPES
 ConsoleItemMOTD(char *id)
 #else
 ConsoleItemMOTD(id)
@@ -4817,6 +4959,9 @@
     {"idletimeout", DefaultItemIdletimeout},
     {"include", DefaultItemInclude},
     {"initcmd", DefaultItemInitcmd},
+    {"poweroff", DefaultItemPowerOff},
+    {"powerreset", DefaultItemPowerReset},
+    {"powersubst", DefaultItemPowersubst},
     {"initrunas", DefaultItemInitrunas},
     {"initspinmax", DefaultItemInitspinmax},
     {"initspintimer", DefaultItemInitspintimer},
@@ -4855,6 +5000,9 @@
     {"idletimeout", ConsoleItemIdletimeout},
     {"include", ConsoleItemInclude},
     {"initcmd", ConsoleItemInitcmd},
+    {"poweroff", ConsoleItemPowerOff},
+    {"powerreset", ConsoleItemPowerReset},
+    {"powersubst", ConsoleItemPowersubst},
     {"initrunas", ConsoleItemInitrunas},
     {"initspinmax", ConsoleItemInitspinmax},
     {"initspintimer", ConsoleItemInitspintimer},