Use asprintf for string construction
[openafs.git] / src / bozo / bnode.c
index f6facc3..a79558c 100644 (file)
@@ -1,7 +1,7 @@
 /*
  * Copyright 2000, International Business Machines Corporation and others.
  * All Rights Reserved.
- * 
+ *
  * This software has been released under the terms of the IBM Public
  * License.  For details, see the LICENSE file in the top-level source
  * directory or online at http://www.openafs.org/dl/license10.html
 #include <afsconfig.h>
 #include <afs/param.h>
 
-RCSID
-    ("$Header$");
+#include <afs/procmgmt.h>
+#include <roken.h>
 
 #include <stddef.h>
-#include <stdlib.h>
-#include <stdio.h>
-#include <errno.h>
-#include <sys/types.h>
-#ifdef AFS_NT40_ENV
-#include <io.h>
-#else
-#include <sys/file.h>
-#include <sys/time.h>
-#endif
-#ifdef BOZO_SAVE_CORES
-#include <time.h>
-#endif
-#include <sys/stat.h>
-#include <string.h>
 
-#include <afs/procmgmt.h>      /* signal(), kill(), wait(), etc. */
 #include <lwp.h>
+#include <rx/rx.h>
 #include <afs/audit.h>
 #include <afs/afsutil.h>
 #include <afs/fileutil.h>
+
 #include "bnode.h"
+#include "bosprototypes.h"
 
-#if defined(AFS_AIX_ENV) || defined(AFS_SUN4_ENV)
-/* All known versions of AIX lack WCOREDUMP but this works */
-#define WCOREDUMP(x) ((x) & 0x80)
+#ifndef WCOREDUMP
+#define WCOREDUMP(x) ((x) & 0200)
 #endif
 
 #define BNODE_LWP_STACKSIZE    (16 * 1024)
+#define BNODE_ERROR_COUNT_MAX   16   /* maximum number of retries */
 
 int bnode_waiting = 0;
 static PROCESS bproc_pid;      /* pid of waker-upper */
@@ -54,34 +41,41 @@ static struct bnode_stats {
     int weirdPids;
 } bnode_stats;
 
+extern const char *DoCore;
+extern const char *DoPidFiles;
 #ifndef AFS_NT40_ENV
 extern char **environ;         /* env structure */
 #endif
 
+int hdl_notifier(struct bnode_proc *tp);
+
 /* Remember the name of the process, if any, that failed last */
 static void
-RememberProcName(register struct bnode_proc *ap)
+RememberProcName(struct bnode_proc *ap)
 {
-    register struct bnode *tbnodep;
+    struct bnode *tbnodep;
 
     tbnodep = ap->bnode;
     if (tbnodep->lastErrorName) {
        free(tbnodep->lastErrorName);
        tbnodep->lastErrorName = NULL;
     }
-    if (ap->coreName) {
-       tbnodep->lastErrorName = (char *)malloc(strlen(ap->coreName) + 1);
-       strcpy(tbnodep->lastErrorName, ap->coreName);
-    }
+    if (ap->coreName)
+       tbnodep->lastErrorName = strdup(ap->coreName);
 }
 
 /* utility for use by BOP_HASCORE functions to determine where a core file might
  * be stored.
  */
 int
-bnode_CoreName(register struct bnode *abnode, char *acoreName, char *abuffer)
+bnode_CoreName(struct bnode *abnode, char *acoreName, char *abuffer)
 {
-    strcpy(abuffer, AFSDIR_SERVER_CORELOG_FILEPATH);
+    if (DoCore) {
+       strcpy(abuffer, DoCore);
+       strcat(abuffer, "/");
+       strcat(abuffer, AFSDIR_CORE_FILE);
+    } else
+       strcpy(abuffer, AFSDIR_SERVER_CORELOG_FILEPATH);
     if (acoreName) {
        strcat(abuffer, acoreName);
        strcat(abuffer, ".");
@@ -92,62 +86,101 @@ bnode_CoreName(register struct bnode *abnode, char *acoreName, char *abuffer)
 
 /* save core file, if any */
 static void
-SaveCore(register struct bnode *abnode, register struct bnode_proc
+SaveCore(struct bnode *abnode, struct bnode_proc
         *aproc)
 {
     char tbuffer[256];
     struct stat tstat;
-    register afs_int32 code;
+    afs_int32 code = 0;
+    char *corefile = NULL;
 #ifdef BOZO_SAVE_CORES
     struct timeval Start;
     struct tm *TimeFields;
     char FileName[256];
 #endif
 
-    code = stat(AFSDIR_SERVER_CORELOG_FILEPATH, &tstat);
+    /* Linux always appends the PID to core dumps from threaded processes, so
+     * we have to scan the directory to find core files under another name. */
+    if (DoCore) {
+       strcpy(tbuffer, DoCore);
+       strcat(tbuffer, "/");
+       strcat(tbuffer, AFSDIR_CORE_FILE);
+    } else
+       code = stat(AFSDIR_SERVER_CORELOG_FILEPATH, &tstat);
+    if (code) {
+        DIR *logdir;
+        struct dirent *file;
+        unsigned long pid;
+       const char *coredir = AFSDIR_LOGS_DIR;
+
+       if (DoCore)
+         coredir = DoCore;
+
+       logdir = opendir(coredir);
+        if (logdir == NULL)
+            return;
+        while ((file = readdir(logdir)) != NULL) {
+            if (strncmp(file->d_name, "core.", 5) != 0)
+                continue;
+            pid = atol(file->d_name + 5);
+            if (pid == aproc->pid) {
+                asprintf(&corefile, "%s/%s", coredir, file->d_name);
+                if (corefile == NULL) {
+                    closedir(logdir);
+                    return;
+                }
+                code = 0;
+                break;
+            }
+        }
+        closedir(logdir);
+    } else {
+       corefile = strdup(tbuffer);
+    }
     if (code)
        return;
 
     bnode_CoreName(abnode, aproc->coreName, tbuffer);
 #ifdef BOZO_SAVE_CORES
-    TM_GetTimeOfDay(&Start, 0);
+    FT_GetTimeOfDay(&Start, 0);
     TimeFields = localtime(&Start.tv_sec);
     sprintf(FileName, "%s.%d%02d%02d%02d%02d%02d", tbuffer,
-           TimeFields->tm_year, TimeFields->tm_mon + 1, TimeFields->tm_mday,
+           TimeFields->tm_year + 1900, TimeFields->tm_mon + 1, TimeFields->tm_mday,
            TimeFields->tm_hour, TimeFields->tm_min, TimeFields->tm_sec);
     strcpy(tbuffer, FileName);
 #endif
-    code = renamefile(AFSDIR_SERVER_CORELOG_FILEPATH, tbuffer);
+    code = renamefile(corefile, tbuffer);
+    free(corefile);
 }
 
 int
-bnode_GetString(register struct bnode *abnode, register char *abuffer,
-               register afs_int32 alen)
+bnode_GetString(struct bnode *abnode, char *abuffer,
+               afs_int32 alen)
 {
     return BOP_GETSTRING(abnode, abuffer, alen);
 }
 
 int
-bnode_GetParm(register struct bnode *abnode, register afs_int32 aindex,
-             register char *abuffer, afs_int32 alen)
+bnode_GetParm(struct bnode *abnode, afs_int32 aindex,
+             char *abuffer, afs_int32 alen)
 {
     return BOP_GETPARM(abnode, aindex, abuffer, alen);
 }
 
 int
-bnode_GetStat(register struct bnode *abnode, register afs_int32 * astatus)
+bnode_GetStat(struct bnode *abnode, afs_int32 * astatus)
 {
     return BOP_GETSTAT(abnode, astatus);
 }
 
 int
-bnode_RestartP(register struct bnode *abnode)
+bnode_RestartP(struct bnode *abnode)
 {
     return BOP_RESTARTP(abnode);
 }
 
 static int
-bnode_Check(register struct bnode *abnode)
+bnode_Check(struct bnode *abnode)
 {
     if (abnode->flags & BNODE_WAIT) {
        abnode->flags &= ~BNODE_WAIT;
@@ -158,17 +191,17 @@ bnode_Check(register struct bnode *abnode)
 
 /* tell if an instance has a core file */
 int
-bnode_HasCore(register struct bnode *abnode)
+bnode_HasCore(struct bnode *abnode)
 {
     return BOP_HASCORE(abnode);
 }
 
 /* wait for all bnodes to stabilize */
 int
-bnode_WaitAll()
+bnode_WaitAll(void)
 {
-    register struct bnode *tb;
-    register afs_int32 code;
+    struct bnode *tb;
+    afs_int32 code;
     afs_int32 stat;
 
   retry:
@@ -192,9 +225,9 @@ bnode_WaitAll()
 
 /* wait until bnode status is correct */
 int
-bnode_WaitStatus(register struct bnode *abnode, int astatus)
+bnode_WaitStatus(struct bnode *abnode, int astatus)
 {
-    register afs_int32 code;
+    afs_int32 code;
     afs_int32 stat;
 
     bnode_Hold(abnode);
@@ -220,7 +253,15 @@ bnode_WaitStatus(register struct bnode *abnode, int astatus)
 }
 
 int
-bnode_SetStat(register struct bnode *abnode, register int agoal)
+bnode_ResetErrorCount(struct bnode *abnode)
+{
+    abnode->errorStopCount = 0;
+    abnode->errorStopDelay = 0;
+    return 0;
+}
+
+int
+bnode_SetStat(struct bnode *abnode, int agoal)
 {
     abnode->goal = agoal;
     bnode_Check(abnode);
@@ -230,7 +271,7 @@ bnode_SetStat(register struct bnode *abnode, register int agoal)
 }
 
 int
-bnode_SetGoal(register struct bnode *abnode, register int agoal)
+bnode_SetGoal(struct bnode *abnode, int agoal)
 {
     abnode->goal = agoal;
     bnode_Check(abnode);
@@ -238,7 +279,7 @@ bnode_SetGoal(register struct bnode *abnode, register int agoal)
 }
 
 int
-bnode_SetFileGoal(register struct bnode *abnode, register int agoal)
+bnode_SetFileGoal(struct bnode *abnode, int agoal)
 {
     if (abnode->fileGoal == agoal)
        return 0;               /* already done */
@@ -249,10 +290,10 @@ bnode_SetFileGoal(register struct bnode *abnode, register int agoal)
 
 /* apply a function to all bnodes in the system */
 int
-bnode_ApplyInstance(int (*aproc) (), char *arock)
+bnode_ApplyInstance(int (*aproc) (struct bnode *tb, void *), void *arock)
 {
-    register struct bnode *tb, *nb;
-    register afs_int32 code;
+    struct bnode *tb, *nb;
+    afs_int32 code;
 
     for (tb = allBnodes; tb; tb = nb) {
        nb = tb->next;
@@ -264,9 +305,9 @@ bnode_ApplyInstance(int (*aproc) (), char *arock)
 }
 
 struct bnode *
-bnode_FindInstance(register char *aname)
+bnode_FindInstance(char *aname)
 {
-    register struct bnode *tb;
+    struct bnode *tb;
 
     for (tb = allBnodes; tb; tb = tb->next) {
        if (!strcmp(tb->name, aname))
@@ -276,9 +317,9 @@ bnode_FindInstance(register char *aname)
 }
 
 static struct bnode_type *
-FindType(register char *aname)
+FindType(char *aname)
 {
-    register struct bnode_type *tt;
+    struct bnode_type *tt;
 
     for (tt = allTypes; tt; tt = tt->next) {
        if (!strcmp(tt->name, aname))
@@ -290,7 +331,7 @@ FindType(register char *aname)
 int
 bnode_Register(char *atype, struct bnode_ops *aprocs, int anparms)
 {
-    register struct bnode_type *tt;
+    struct bnode_type *tt;
 
     for (tt = allTypes; tt; tt = tt->next) {
        if (!strcmp(tt->name, atype))
@@ -347,7 +388,7 @@ bnode_Create(char *atype, char *ainstance, struct bnode ** abp, char *ap1,
     *abp = tb;
     tb->type = type;
 
-    /* The fs_create above calls bnode_InitBnode() which always sets the 
+    /* The fs_create above calls bnode_InitBnode() which always sets the
      ** fileGoal to BSTAT_NORMAL .... overwrite it with whatever is passed into
      ** this function as a parameter... */
     tb->fileGoal = fileGoal;
@@ -363,7 +404,7 @@ bnode_Create(char *atype, char *ainstance, struct bnode ** abp, char *ap1,
 int
 bnode_DeleteName(char *ainstance)
 {
-    register struct bnode *tb;
+    struct bnode *tb;
 
     tb = bnode_FindInstance(ainstance);
     if (!tb)
@@ -373,14 +414,14 @@ bnode_DeleteName(char *ainstance)
 }
 
 int
-bnode_Hold(register struct bnode *abnode)
+bnode_Hold(struct bnode *abnode)
 {
     abnode->refCount++;
     return 0;
 }
 
 int
-bnode_Release(register struct bnode *abnode)
+bnode_Release(struct bnode *abnode)
 {
     abnode->refCount--;
     if (abnode->refCount == 0 && abnode->flags & BNODE_DELETE) {
@@ -391,10 +432,10 @@ bnode_Release(register struct bnode *abnode)
 }
 
 int
-bnode_Delete(register struct bnode *abnode)
+bnode_Delete(struct bnode *abnode)
 {
-    register afs_int32 code;
-    register struct bnode **lb, *ub;
+    afs_int32 code;
+    struct bnode **lb, *ub;
     afs_int32 temp;
 
     if (abnode->refCount != 0) {
@@ -427,14 +468,14 @@ bnode_Delete(register struct bnode *abnode)
 
 /* function to tell if there's a timeout coming up */
 int
-bnode_PendingTimeout(register struct bnode *abnode)
+bnode_PendingTimeout(struct bnode *abnode)
 {
     return (abnode->flags & BNODE_NEEDTIMEOUT);
 }
 
 /* function called to set / clear periodic bnode wakeup times */
 int
-bnode_SetTimeout(register struct bnode *abnode, afs_int32 atimeout)
+bnode_SetTimeout(struct bnode *abnode, afs_int32 atimeout)
 {
     if (atimeout != 0) {
        abnode->nextTimeout = FT_ApproxTime() + atimeout;
@@ -449,7 +490,7 @@ bnode_SetTimeout(register struct bnode *abnode, afs_int32 atimeout)
 
 /* used by new bnode creation code to format bnode header */
 int
-bnode_InitBnode(register struct bnode *abnode, struct bnode_ops *abnodeops,
+bnode_InitBnode(struct bnode *abnode, struct bnode_ops *abnodeops,
                char *aname)
 {
     struct bnode **lb, *nb;
@@ -457,10 +498,9 @@ bnode_InitBnode(register struct bnode *abnode, struct bnode_ops *abnodeops,
     /* format the bnode properly */
     memset(abnode, 0, sizeof(struct bnode));
     abnode->ops = abnodeops;
-    abnode->name = (char *)malloc(strlen(aname) + 1);
+    abnode->name = strdup(aname);
     if (!abnode->name)
        return ENOMEM;
-    strcpy(abnode->name, aname);
     abnode->flags = BNODE_ACTIVE;
     abnode->fileGoal = BSTAT_NORMAL;
     abnode->goal = BSTAT_SHUTDOWN;
@@ -473,9 +513,9 @@ bnode_InitBnode(register struct bnode *abnode, struct bnode_ops *abnodeops,
 }
 
 static int
-DeleteProc(register struct bnode_proc *abproc)
+DeleteProc(struct bnode_proc *abproc)
 {
-    register struct bnode_proc **pb, *tb;
+    struct bnode_proc **pb, *tb;
     struct bnode_proc *nb;
 
     for (pb = &allProcs, tb = *pb; tb; pb = &tb->next, tb = nb) {
@@ -490,13 +530,13 @@ DeleteProc(register struct bnode_proc *abproc)
 }
 
 /* bnode lwp executes this code repeatedly */
-static int
-bproc()
+static void *
+bproc(void *unused)
 {
-    register afs_int32 code;
-    register struct bnode *tb;
-    register afs_int32 temp;
-    register struct bnode_proc *tp;
+    afs_int32 code;
+    struct bnode *tb;
+    afs_int32 temp;
+    struct bnode_proc *tp;
     struct bnode *nb;
     int options;               /* must not be register */
     struct timeval tv;
@@ -566,13 +606,14 @@ bproc()
                    tb = tp->bnode;
                    bnode_Hold(tb);
 
-                   /* count restarts in last 10 seconds */
+                   /* count restarts in last 30 seconds */
                    if (temp > tb->rsTime + 30) {
-                       /* it's been 10 seconds we've been counting */
+                       /* it's been 30 seconds we've been counting */
                        tb->rsTime = temp;
                        tb->rsCount = 0;
                    }
 
+
                    if (WIFSIGNALED(status) == 0) {
                        /* exited, not signalled */
                        tp->lastExit = WEXITSTATUS(status);
@@ -622,17 +663,27 @@ bproc()
                                 tb->notifier);
                        hdl_notifier(tp);
                    }
-                   BOP_PROCEXIT(tb, tp);
 
-                   bnode_Check(tb);
-                   if (tb->rsCount++ > 10) {
-                       /* 10 in 10 seconds */
+                   if (tb->goal && tb->rsCount++ > 10) {
+                       /* 10 in 30 seconds */
+                       if (tb->errorStopCount >= BNODE_ERROR_COUNT_MAX) {
+                           tb->errorStopDelay = 0;     /* max reached, give up. */
+                       } else {
+                           tb->errorStopCount++;
+                           if (!tb->errorStopDelay) {
+                               tb->errorStopDelay = 1;
+                           } else {
+                               tb->errorStopDelay *= 2;
+                           }
+                       }
                        tb->flags |= BNODE_ERRORSTOP;
                        bnode_SetGoal(tb, BSTAT_SHUTDOWN);
                        bozo_Log
                            ("BNODE '%s' repeatedly failed to start, perhaps missing executable.\n",
                             tb->name);
                    }
+                   BOP_PROCEXIT(tb, tp);
+                   bnode_Check(tb);
                    bnode_Release(tb);  /* bnode delete can happen here */
                    DeleteProc(tp);
                } else
@@ -640,14 +691,15 @@ bproc()
            }
        }
     }
+    return NULL;
 }
 
 static afs_int32
-SendNotifierData(register int fd, register struct bnode_proc *tp)
+SendNotifierData(int fd, struct bnode_proc *tp)
 {
-    register struct bnode *tb = tp->bnode;
+    struct bnode *tb = tp->bnode;
     char buffer[1000], *bufp = buffer, *buf1;
-    register int len;
+    int len;
 
     /*
      * First sent out the bnode_proc struct
@@ -660,15 +712,15 @@ SendNotifierData(register int fd, register struct bnode_proc *tp)
        buf1 = "(null)";
     (void)sprintf(bufp, "coreName: %s\n", buf1);
     bufp += strlen(bufp);
-    (void)sprintf(bufp, "pid: %ld\n", tp->pid);
+    (void)sprintf(bufp, "pid: %ld\n", afs_printable_int32_ld(tp->pid));
     bufp += strlen(bufp);
-    (void)sprintf(bufp, "lastExit: %ld\n", tp->lastExit);
+    (void)sprintf(bufp, "lastExit: %ld\n", afs_printable_int32_ld(tp->lastExit));
     bufp += strlen(bufp);
 #ifdef notdef
-    (void)sprintf(bufp, "lastSignal: %ld\n", tp->lastSignal);
+    (void)sprintf(bufp, "lastSignal: %ld\n", afs_printable_int32_ld(tp->lastSignal));
     bufp += strlen(bufp);
 #endif
-    (void)sprintf(bufp, "flags: %ld\n", tp->flags);
+    (void)sprintf(bufp, "flags: %ld\n", afs_printable_int32_ld(tp->flags));
     bufp += strlen(bufp);
     (void)sprintf(bufp, "END bnode_proc\n");
     bufp += strlen(bufp);
@@ -685,21 +737,21 @@ SendNotifierData(register int fd, register struct bnode_proc *tp)
     bufp += strlen(bufp);
     (void)sprintf(bufp, "name: %s\n", tb->name);
     bufp += strlen(bufp);
-    (void)sprintf(bufp, "rsTime: %ld\n", tb->rsTime);
+    (void)sprintf(bufp, "rsTime: %ld\n", afs_printable_int32_ld(tb->rsTime));
     bufp += strlen(bufp);
-    (void)sprintf(bufp, "rsCount: %ld\n", tb->rsCount);
+    (void)sprintf(bufp, "rsCount: %ld\n", afs_printable_int32_ld(tb->rsCount));
     bufp += strlen(bufp);
-    (void)sprintf(bufp, "procStartTime: %ld\n", tb->procStartTime);
+    (void)sprintf(bufp, "procStartTime: %ld\n", afs_printable_int32_ld(tb->procStartTime));
     bufp += strlen(bufp);
-    (void)sprintf(bufp, "procStarts: %ld\n", tb->procStarts);
+    (void)sprintf(bufp, "procStarts: %ld\n", afs_printable_int32_ld(tb->procStarts));
     bufp += strlen(bufp);
-    (void)sprintf(bufp, "lastAnyExit: %ld\n", tb->lastAnyExit);
+    (void)sprintf(bufp, "lastAnyExit: %ld\n", afs_printable_int32_ld(tb->lastAnyExit));
     bufp += strlen(bufp);
-    (void)sprintf(bufp, "lastErrorExit: %ld\n", tb->lastErrorExit);
+    (void)sprintf(bufp, "lastErrorExit: %ld\n", afs_printable_int32_ld(tb->lastErrorExit));
     bufp += strlen(bufp);
-    (void)sprintf(bufp, "errorCode: %ld\n", tb->errorCode);
+    (void)sprintf(bufp, "errorCode: %ld\n", afs_printable_int32_ld(tb->errorCode));
     bufp += strlen(bufp);
-    (void)sprintf(bufp, "errorSignal: %ld\n", tb->errorSignal);
+    (void)sprintf(bufp, "errorSignal: %ld\n", afs_printable_int32_ld(tb->errorSignal));
     bufp += strlen(bufp);
 /*
     (void) sprintf(bufp, "lastErrorName: %s\n", tb->lastErrorName);
@@ -713,13 +765,14 @@ SendNotifierData(register int fd, register struct bnode_proc *tp)
     if (write(fd, buffer, len) < 0) {
        return -1;
     }
+    return 0;
 }
 
 int
 hdl_notifier(struct bnode_proc *tp)
 {
 #ifndef AFS_NT40_ENV           /* NT notifier callout not yet implemented */
-    int code, pid, status;
+    int pid;
     struct stat tstat;
 
     if (stat(tp->bnode->notifier, &tstat)) {
@@ -730,16 +783,15 @@ hdl_notifier(struct bnode_proc *tp)
     if ((pid = fork()) == 0) {
        FILE *fout;
        struct bnode *tb = tp->bnode;
-       int ec;
 
 #if defined(AFS_HPUX_ENV) || defined(AFS_SUN5_ENV) || defined(AFS_SGI51_ENV)
-       ec = setsid();
+       setsid();
 #elif defined(AFS_DARWIN90_ENV)
-       ec = setpgid(0, 0);
-#elif defined(AFS_LINUX20_ENV) || defined(AFS_AIX_ENV)  
-       ec = setpgrp();
+       setpgid(0, 0);
+#elif defined(AFS_LINUX20_ENV) || defined(AFS_AIX_ENV)
+       setpgrp();
 #else
-       ec = setpgrp(0, 0);
+       setpgrp(0, 0);
 #endif
        fout = popen(tb->notifier, "w");
        if (fout == NULL) {
@@ -748,7 +800,7 @@ hdl_notifier(struct bnode_proc *tp)
            perror(tb->notifier);
            exit(1);
        }
-       code = SendNotifierData(fileno(fout), tp);
+       SendNotifierData(fileno(fout), tp);
        pclose(fout);
        exit(0);
     } else if (pid < 0) {
@@ -762,9 +814,11 @@ hdl_notifier(struct bnode_proc *tp)
 
 /* Called by IOMGR at low priority on IOMGR's stack shortly after a SIGCHLD
  * occurs.  Wakes up bproc do redo things */
-int
-bnode_SoftInt(int asignal)
+void *
+bnode_SoftInt(void *param)
 {
+    /* int asignal = (int) param; */
+
     IOMGR_Cancel(bproc_pid);
     return 0;
 }
@@ -775,24 +829,22 @@ bnode_SoftInt(int asignal)
 void
 bnode_Int(int asignal)
 {
-    extern void bozo_ShutdownAndExit();
-
-    if (asignal == SIGQUIT) {
-       IOMGR_SoftSig(bozo_ShutdownAndExit, (char *)asignal);
+    if (asignal == SIGQUIT || asignal == SIGTERM) {
+       IOMGR_SoftSig(bozo_ShutdownAndExit, (void *)(intptr_t)asignal);
     } else {
-       IOMGR_SoftSig(bnode_SoftInt, (char *)asignal);
+       IOMGR_SoftSig(bnode_SoftInt, (void *)(intptr_t)asignal);
     }
 }
 
 
 /* intialize the whole system */
 int
-bnode_Init()
+bnode_Init(void)
 {
     PROCESS junk;
-    register afs_int32 code;
+    afs_int32 code;
     struct sigaction newaction;
-    static initDone = 0;
+    static int initDone = 0;
 
     if (initDone)
        return 0;
@@ -805,7 +857,7 @@ bnode_Init()
                             "bnode-manager", &bproc_pid);
     if (code)
        return code;
-    memset((char *)&newaction, 0, sizeof(newaction));
+    memset(&newaction, 0, sizeof(newaction));
     newaction.sa_handler = bnode_Int;
     code = sigaction(SIGCHLD, &newaction, NULL);
     if (code)
@@ -813,14 +865,17 @@ bnode_Init()
     code = sigaction(SIGQUIT, &newaction, NULL);
     if (code)
        return errno;
+    code = sigaction(SIGTERM, &newaction, NULL);
+    if (code)
+       return errno;
     return code;
 }
 
 /* free token list returned by parseLine */
 int
-bnode_FreeTokens(register struct bnode_token *alist)
+bnode_FreeTokens(struct bnode_token *alist)
 {
-    register struct bnode_token *nlist;
+    struct bnode_token *nlist;
     for (; alist; alist = nlist) {
        nlist = alist->next;
        free(alist->key);
@@ -842,11 +897,11 @@ int
 bnode_ParseLine(char *aline, struct bnode_token **alist)
 {
     char tbuffer[256];
-    register char *tptr;
+    char *tptr = NULL;
     int inToken;
     struct bnode_token *first, *last;
-    register struct bnode_token *ttok;
-    register int tc;
+    struct bnode_token *ttok;
+    int tc;
 
     inToken = 0;               /* not copying token chars at start */
     first = (struct bnode_token *)0;
@@ -860,8 +915,7 @@ bnode_ParseLine(char *aline, struct bnode_token **alist)
                ttok =
                    (struct bnode_token *)malloc(sizeof(struct bnode_token));
                ttok->next = (struct bnode_token *)0;
-               ttok->key = (char *)malloc(strlen(tbuffer) + 1);
-               strcpy(ttok->key, tbuffer);
+               ttok->key = strdup(tbuffer);
                if (last) {
                    last->next = ttok;
                    last = ttok;
@@ -929,6 +983,7 @@ bnode_NewProc(struct bnode *abnode, char *aexecString, char *coreName,
        free(tp);
        return errno;
     }
+    bozo_Log("%s started pid %ld: %s\n", abnode->name, cpid, aexecString);
 
     bnode_FreeTokens(tlist);
     allProcs = tp;
@@ -936,14 +991,15 @@ bnode_NewProc(struct bnode *abnode, char *aexecString, char *coreName,
     tp->pid = cpid;
     tp->flags = BPROC_STARTED;
     tp->flags &= ~BPROC_EXITED;
+    BOP_PROCSTARTED(abnode, tp);
     bnode_Check(abnode);
     return 0;
 }
 
 int
-bnode_StopProc(register struct bnode_proc *aproc, int asignal)
+bnode_StopProc(struct bnode_proc *aproc, int asignal)
 {
-    register int code;
+    int code;
     if (!(aproc->flags & BPROC_STARTED) || (aproc->flags & BPROC_EXITED))
        return BZNOTACTIVE;
 
@@ -956,9 +1012,9 @@ bnode_StopProc(register struct bnode_proc *aproc, int asignal)
 }
 
 int
-bnode_Deactivate(register struct bnode *abnode)
+bnode_Deactivate(struct bnode *abnode)
 {
-    register struct bnode **pb, *tb;
+    struct bnode **pb, *tb;
     struct bnode *nb;
     if (!(abnode->flags & BNODE_ACTIVE))
        return BZNOTACTIVE;