OPENAFS-SA-2016-002 VldbListByAttributes information leak
[openafs.git] / src / bucoord / commands.c
index 3b3009b..ec16ca1 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
@@ -9,50 +9,41 @@
 
 #include <afsconfig.h>
 #include <afs/param.h>
+#include <afs/stds.h>
 
+#include <roken.h>
 
-#include <afs/stds.h>
-#if defined(AFS_LINUX24_ENV)
-#define _REGEX_RE_COMP
-#endif
-#include <sys/types.h>
-#if defined(AFS_LINUX24_ENV)
+#ifdef HAVE_POSIX_REGEX                /* use POSIX regexp library */
 #include <regex.h>
 #endif
+
 #include <afs/cmd.h>
-#ifdef AFS_NT40_ENV
-#include <winsock2.h>
-#else
-#include <sys/socket.h>
-#include <netinet/in.h>
-#include <netdb.h>
-#endif
-#include <errno.h>
 #include <afs/com_err.h>
+#include <afs/afsutil.h>
 #include <afs/budb.h>
+#include <afs/budb_prototypes.h>
 #include <afs/butc.h>
 #include <afs/bubasics.h>      /* PA */
+#include <afs/afsint.h>
 #include <afs/volser.h>
 #include <afs/voldefs.h>       /* PA */
 #include <afs/vldbint.h>       /* PA */
 #include <afs/ktime.h>         /* PA */
 #include <ubik.h>
-#include <time.h>
 #include <lock.h>
-#include <afs/butc.h>
 #include <afs/tcdata.h>
 #include <afs/butx.h>
 #include <afs/vsutils_prototypes.h>
+
 #include "bc.h"
 #include "error_macros.h"
+#include "bucoord_internal.h"
 #include "bucoord_prototypes.h"
-#include "regex.h"
 
 extern struct bc_config *bc_globalConfig;
 extern struct bc_dumpTask bc_dumpTasks[BC_MAXSIMDUMPS];
 extern struct ubik_client *cstruct;
 extern char *whoami;
-extern struct ktc_token ttoken;
 
 char *loadFile;
 extern afs_int32 lastTaskCode;
@@ -69,9 +60,9 @@ static int EvalVolumeSet2(struct bc_config *aconfig, struct bc_volumeSet *avs,
 static int DBLookupByVolume(char *volumeName);
 
 int
-bc_EvalVolumeSet(struct bc_config *aconfig, 
-                struct bc_volumeSet *avs, 
-                struct bc_volumeDump **avols, 
+bc_EvalVolumeSet(struct bc_config *aconfig,
+                struct bc_volumeSet *avs,
+                struct bc_volumeDump **avols,
                 struct ubik_client *uclient)
 {                              /*bc_EvalVolumeSet */
     int code = -1;
@@ -103,9 +94,9 @@ struct serversort {
 };
 
 afs_int32
-getSPEntries(afs_uint32 server, afs_int32 partition, 
-            struct serversort **serverlist, 
-            struct serversort **ss, 
+getSPEntries(afs_uint32 server, afs_int32 partition,
+            struct serversort **serverlist,
+            struct serversort **ss,
             struct partitionsort **ps)
 {
     if (!(*ss) || ((*ss)->ipaddr != server)) {
@@ -117,13 +108,12 @@ getSPEntries(afs_uint32 server, afs_int32 partition,
     }
     /* No server entry added. Add one */
     if (!(*ss)) {
-       *ss = (struct serversort *)malloc(sizeof(struct serversort));
+       *ss = calloc(1, sizeof(struct serversort));
        if (!(*ss)) {
-           afs_com_err(whoami, BC_NOMEM, "");
+           afs_com_err(whoami, BC_NOMEM, NULL);
            *ss = 0;
            return (BC_NOMEM);
        }
-       memset(*ss, 0, sizeof(struct serversort));
        (*ss)->ipaddr = server;
        (*ss)->next = *serverlist;
        *serverlist = *ss;
@@ -138,15 +128,14 @@ getSPEntries(afs_uint32 server, afs_int32 partition,
     }
     /* No partition entry added. Add one */
     if (!(*ps)) {
-       *ps = (struct partitionsort *)malloc(sizeof(struct partitionsort));
+       *ps = calloc(1, sizeof(struct partitionsort));
        if (!(*ps)) {
-           afs_com_err(whoami, BC_NOMEM, "");
+           afs_com_err(whoami, BC_NOMEM, NULL);
            free(*ss);
            *ps = 0;
            *ss = 0;
            return (BC_NOMEM);
        }
-       memset(*ps, 0, sizeof(struct partitionsort));
        (*ps)->part = partition;
        (*ps)->next = (*ss)->partitions;
        (*ss)->partitions = *ps;
@@ -155,7 +144,7 @@ getSPEntries(afs_uint32 server, afs_int32 partition,
 }
 
 afs_int32
-randSPEntries(struct serversort *serverlist, 
+randSPEntries(struct serversort *serverlist,
              struct bc_volumeDump **avols)
 {
     struct serversort *ss, **pss;
@@ -197,9 +186,9 @@ randSPEntries(struct serversort *serverlist,
 }
 
 static int
-EvalVolumeSet2(struct bc_config *aconfig, 
-              struct bc_volumeSet *avs, 
-              struct bc_volumeDump **avols, 
+EvalVolumeSet2(struct bc_config *aconfig,
+              struct bc_volumeSet *avs,
+              struct bc_volumeDump **avols,
               struct ubik_client *uclient)
 {                              /*EvalVolumeSet2 */
     struct bc_volumeEntry *tve;
@@ -218,10 +207,11 @@ EvalVolumeSet2(struct bc_config *aconfig,
     *avols = (struct bc_volumeDump *)0;
     bulkentries.nbulkentries_len = 0;
     bulkentries.nbulkentries_val = 0;
+    memset(&attributes, 0, sizeof(attributes));
 
     /* For each of the volume set entries - collect the volumes that match it */
     for (tve = avs->ventries; tve; tve = tve->next) {
-       /* Put together a call to the vlserver for this vlentry. The 
+       /* Put together a call to the vlserver for this vlentry. The
         * performance gain is from letting the vlserver expand the
         * volumeset and not this routine.
         */
@@ -242,7 +232,7 @@ EvalVolumeSet2(struct bc_config *aconfig,
            bulkentries.nbulkentries_val = 0;
            nsi = -1;
            tcode =
-               ubik_Call(VL_ListAttributesN2, uclient, 0, &attributes,
+               ubik_VL_ListAttributesN2(uclient, 0, &attributes,
                          tve->name, si, &nentries, &bulkentries, &nsi);
            if (tcode)
                ERROR(tcode);
@@ -257,21 +247,26 @@ EvalVolumeSet2(struct bc_config *aconfig,
            if (nentries == 0)
                ERROR(RXGEN_OPCODE);    /* Use EvalVolumeSet1 */
 
+           if (nentries < 0)
+               nentries = 0;
+           if (nentries > bulkentries.nbulkentries_len)
+               nentries = bulkentries.nbulkentries_len;
+
            /* Step through each entry and add it to the list of volumes */
            entries = bulkentries.nbulkentries_val;
            for (e = 0; e < nentries; e++) {
                ei = entries[e].matchindex & 0xffff;
                et = (entries[e].matchindex >> 16) & 0xffff;
                switch (et) {
-               case ITSRWVOL:{
+               case VLSF_RWVOL:{
                        et = RWVOL;
                        break;
                    }
-               case ITSBACKVOL:{
+               case VLSF_BACKVOL:{
                        et = BACKVOL;
                        break;
                    }
-               case ITSROVOL:{
+               case VLSF_ROVOL:{
                        et = ROVOL;
                        break;
                    }
@@ -285,7 +280,7 @@ EvalVolumeSet2(struct bc_config *aconfig,
                                 entries[e].serverPartition[ei], &servers,
                                 &ss, &ps);
                if (tcode) {
-                   afs_com_err(whoami, tcode, "");
+                   afs_com_err(whoami, tcode, NULL);
                    ERROR(tcode);
                }
 
@@ -314,17 +309,15 @@ EvalVolumeSet2(struct bc_config *aconfig,
 
                if (add) {
                    /* Allocate a volume dump structure and its name */
-                   tvd = (struct bc_volumeDump *)
-                       malloc(sizeof(struct bc_volumeDump));
+                   tvd = calloc(1, sizeof(struct bc_volumeDump));
                    if (!tvd) {
-                       afs_com_err(whoami, BC_NOMEM, "");
+                       afs_com_err(whoami, BC_NOMEM, NULL);
                        ERROR(BC_NOMEM);
                    }
-                   memset(tvd, 0, sizeof(*tvd));
 
-                   tvd->name = (char *)malloc(strlen(entries[e].name) + 10);
+                   tvd->name = malloc(strlen(entries[e].name) + 10);
                    if (!(tvd->name)) {
-                       afs_com_err(whoami, BC_NOMEM, "");
+                       afs_com_err(whoami, BC_NOMEM, NULL);
                        free(tvd);
                        ERROR(BC_NOMEM);
                    }
@@ -358,7 +351,7 @@ EvalVolumeSet2(struct bc_config *aconfig,
 
            /* Free memory allocated during VL call */
            if (bulkentries.nbulkentries_val) {
-               free((char *)bulkentries.nbulkentries_val);
+               free(bulkentries.nbulkentries_val);
                bulkentries.nbulkentries_val = 0;
                entries = 0;
            }
@@ -371,7 +364,7 @@ EvalVolumeSet2(struct bc_config *aconfig,
 
   error_exit:
     if (bulkentries.nbulkentries_val) {
-       free((char *)bulkentries.nbulkentries_val);
+       free(bulkentries.nbulkentries_val);
     }
     return (code);
 }                              /*EvalVolumeSet2 */
@@ -380,29 +373,29 @@ EvalVolumeSet2(struct bc_config *aconfig,
  * EvalVolumeSetOld
  *
  * Description:
- *     Takes the entries in a volumeset and expands them into a list of 
+ *     Takes the entries in a volumeset and expands them into a list of
  *      volumes. Every VLDB volume entry is looked at and compared to the
  *      volumeset entries.
  *
- *      When matching a VLDB volume entry to a volumeset entry, 
+ *      When matching a VLDB volume entry to a volumeset entry,
  *       1. If the RW volume entry matches, that RW volume is used.
  *       2. Otherwise, if the BK volume entry matches, the BK volume is used.
  *       3. Finally, if the RO volume entry matches, the RO volume is used.
- *      For instance: A volumeset entry of ".* .* user.t.*" will match volume 
- *                    "user.troy" and "user.troy.backup". The rules will use 
+ *      For instance: A volumeset entry of ".* .* user.t.*" will match volume
+ *                    "user.troy" and "user.troy.backup". The rules will use
  *                    the RW volume "user.troy".
  *
  *      When a VLDB volume entry matches a volumeset entry (be it RW, BK or RO),
- *      that volume is used and matches against any remaining volumeset entries 
+ *      that volume is used and matches against any remaining volumeset entries
  *      are not even done.
  *      For instance: A 1st volumeset entry ".* .* .*.backup" will match with
- *                    "user.troy.backup". Its 2nd volumeset entry ".* .* .*" 
- *                    would have matched its RW volume "user.troy", but the first 
+ *                    "user.troy.backup". Its 2nd volumeset entry ".* .* .*"
+ *                    would have matched its RW volume "user.troy", but the first
  *                    match is used and the second match isn't even done.
  *
  * Arguments:
  *     aconfig : Global configuration info.
- *     avs     : 
+ *     avs     :
  *     avols   : Ptr to linked list of entries describing volumes to dump.
  *     uclient : Ptr to Ubik client structure.
  *
@@ -418,13 +411,12 @@ EvalVolumeSet2(struct bc_config *aconfig,
  *-----------------------------------------------------------------------------
  */
 static int
-EvalVolumeSet1(struct bc_config *aconfig, 
+EvalVolumeSet1(struct bc_config *aconfig,
               struct bc_volumeSet *avs,
-              struct bc_volumeDump **avols, 
+              struct bc_volumeDump **avols,
               struct ubik_client *uclient)
 {                              /*EvalVolumeSet1 */
     afs_int32 code;            /*Result of various calls */
-    char *errm;
     struct bc_volumeDump *tvd; /*Ptr to new dump instance */
     struct bc_volumeEntry *tve, *ctve; /*Ptr to new volume entry instance */
     char patt[256];            /*Composite regex; also, target string */
@@ -439,6 +431,12 @@ EvalVolumeSet1(struct bc_config *aconfig,
     int foundentry = 0;
     struct serversort *servers = 0, *ss = 0;
     struct partitionsort *ps = 0;
+#ifdef HAVE_POSIX_REGEX
+    regex_t re;
+    int need_regfree = 0;
+#else
+    char *errm;
+#endif
 
     *avols = (struct bc_volumeDump *)0;
     ctve = (struct bc_volumeEntry *)0; /* no compiled entry */
@@ -449,8 +447,7 @@ EvalVolumeSet1(struct bc_config *aconfig,
      */
     for (index = 0; 1; index = next_index) {   /*w */
        memset(&entry, 0, sizeof(entry));
-       code = ubik_Call(VL_ListEntry,  /*Routine to invoke */
-                        uclient,       /*Ubik client structure */
+       code = ubik_VL_ListEntry(uclient,       /*Ubik client structure */
                         0,     /*Ubik flags */
                         index, /*Current index */
                         &count,        /*Ptr to working variable */
@@ -485,6 +482,13 @@ EvalVolumeSet1(struct bc_config *aconfig,
                /* If the volume entry is not compiled, then compile it */
                if (ctve != tve) {
                    sprintf(patt, "^%s$", tve->name);
+#ifdef HAVE_POSIX_REGEX
+                   if (regcomp(&re, patt, REG_NOSUB) != 0) {
+                     afs_com_err(whoami, 0, "Can't compile regular expression '%s'", patt);
+                     return (-1);
+                   }
+                   need_regfree = 1;
+#else
                    errm = (char *)re_comp(patt);
                    if (errm) {
                        afs_com_err(whoami, 0,
@@ -492,17 +496,23 @@ EvalVolumeSet1(struct bc_config *aconfig,
                                patt, errm);
                        return (-1);
                    }
+#endif
                    ctve = tve;
                }
 
                /* If the RW name matches the volume set entry, take
                 * it and exit. First choice is to use the RW volume.
                 */
-               if (entry.serverFlags[srvpartpair] & ITSRWVOL) {
-                   if (entry.flags & RW_EXISTS) {
+               if (entry.serverFlags[srvpartpair] & VLSF_RWVOL) {
+                   if (entry.flags & VLF_RWEXISTS) {
                        sprintf(patt, "%s", entry.name);
+#ifdef HAVE_POSIX_REGEX
+                       code = regexec(&re, patt, 0, NULL, 0);
+                       if (code == 0) {
+#else
                        code = re_exec(patt);
                        if (code == 1) {
+#endif
                            found = 1;
                            foundentry = srvpartpair;
                            volType = RWVOL;
@@ -510,13 +520,18 @@ EvalVolumeSet1(struct bc_config *aconfig,
                        }
                    }
 
-                   /* If the BK name matches the volume set entry, take 
+                   /* If the BK name matches the volume set entry, take
                     * it and exit. Second choice is to use the BK volume.
                     */
-                   if (entry.flags & BACK_EXISTS) {
+                   if (entry.flags & VLF_BACKEXISTS) {
                        sprintf(patt, "%s.backup", entry.name);
+#ifdef HAVE_POSIX_REGEX
+                       code = regexec(&re, patt, 0, NULL, 0);
+                       if (code == 0) {
+#else
                        code = re_exec(patt);
                        if (code == 1) {
+#endif
                            found = 1;
                            foundentry = srvpartpair;
                            volType = BACKVOL;
@@ -529,11 +544,16 @@ EvalVolumeSet1(struct bc_config *aconfig,
                 * it, but continue searching. Further entries may be
                 * RW or backup entries that will match.
                 */
-               else if (!found && (entry.serverFlags[srvpartpair] & ITSROVOL)
-                        && (entry.flags & RO_EXISTS)) {
+               else if (!found && (entry.serverFlags[srvpartpair] & VLSF_ROVOL)
+                        && (entry.flags & VLF_ROEXISTS)) {
                    sprintf(patt, "%s.readonly", entry.name);
+#ifdef HAVE_POSIX_REGEX
+                   code = regexec(&re, patt, 0, NULL, 0);
+                   if (code == 0) {
+#else
                    code = re_exec(patt);
                    if (code == 1) {
+#endif
                        found = 1;
                        foundentry = srvpartpair;
                        volType = ROVOL;
@@ -552,22 +572,20 @@ EvalVolumeSet1(struct bc_config *aconfig,
                                 entry.serverPartition[foundentry], &servers,
                                 &ss, &ps);
                if (code) {
-                   afs_com_err(whoami, code, "");
+                   afs_com_err(whoami, code, NULL);
                    return (code);
                }
 
                total++;
-               tvd = (struct bc_volumeDump *)
-                   malloc(sizeof(struct bc_volumeDump));
+               tvd = calloc(1, sizeof(struct bc_volumeDump));
                if (!tvd) {
-                   afs_com_err(whoami, BC_NOMEM, "");
+                   afs_com_err(whoami, BC_NOMEM, NULL);
                    return (BC_NOMEM);
                }
-               memset(tvd, 0, sizeof(*tvd));
 
-               tvd->name = (char *)malloc(strlen(entry.name) + 10);
+               tvd->name = malloc(strlen(entry.name) + 10);
                if (!(tvd->name)) {
-                   afs_com_err(whoami, BC_NOMEM, "");
+                   afs_com_err(whoami, BC_NOMEM, NULL);
                    free(tvd);
                    return (BC_NOMEM);
                }
@@ -595,6 +613,10 @@ EvalVolumeSet1(struct bc_config *aconfig,
            }                   /*f */
        }                       /*ve */
     }                          /*w */
+#ifdef HAVE_POSIX_REGEX
+    if (need_regfree)
+       regfree(&re);
+#endif
 
     /* Randomly link the volumedump entries together */
     randSPEntries(servers, avols);
@@ -603,33 +625,39 @@ EvalVolumeSet1(struct bc_config *aconfig,
     return (0);
 }                              /*EvalVolumeSet1 */
 
-/* compactDateString
- *     print out a date in compact format, 16 chars, format is
- *     mm/dd/yyyy hh:mm
- * entry:
- *     date_long - ptr to a long containing the time
- * exit:
- *     ptr to a string containing a representation of the date
- */
 char *
-compactDateString(afs_uint32 *date_long, char *string, afs_int32 size)
+compactTimeString(time_t *date, char *string, afs_int32 size)
 {
     struct tm *ltime;
 
     if (!string)
-       return 0;
+       return NULL;
 
-    if (*date_long == NEVERDATE) {
+    if (*date == NEVERDATE) {
        sprintf(string, "NEVER");
     } else {
-        time_t t = *date_long;
-       ltime = localtime(&t);
-       /* prints date in U.S. format of mm/dd/yyyy */
+       ltime = localtime(date);
        strftime(string, size, "%m/%d/%Y %H:%M", ltime);
     }
     return (string);
 }
 
+/* compactDateString
+ *     print out a date in compact format, 16 chars, format is
+ *     mm/dd/yyyy hh:mm
+ * entry:
+ *     date_long - ptr to a long containing the time
+ * exit:
+ *     ptr to a string containing a representation of the date
+ */
+char *
+compactDateString(afs_uint32 *date_long, char *string, afs_int32 size)
+{
+    time_t t = *date_long;
+    return compactTimeString(&t, string, size);
+}
+
+
 afs_int32
 bc_SafeATOI(char *anum)
 {
@@ -697,23 +725,20 @@ bc_FloatATOI(char *anum)
 char *
 bc_CopyString(char *astring)
 {
-    afs_int32 tlen;
     char *tp;
 
     if (!astring)
        return (NULL);          /* propagate null strings easily */
-    tlen = strlen(astring);
-    tp = (char *)malloc(tlen + 1);     /* don't forget the terminating null */
+    tp = strdup(astring);
     if (!tp) {
-       afs_com_err(whoami, BC_NOMEM, "");
+       afs_com_err(whoami, BC_NOMEM, NULL);
        return (tp);
     }
-    strcpy(tp, astring);
     return tp;
 }
 
 /* concatParams
- * 
+ *
  *    Concatenates the parameters of an option and returns the string.
  *
  */
@@ -736,9 +761,9 @@ concatParams(struct cmd_item *itemPtr)
        return (NULL);
     }
 
-    string = (char *)malloc(length);   /* allocate the string */
+    string = malloc(length);   /* allocate the string */
     if (!string) {
-       afs_com_err(whoami, BC_NOMEM, "");
+       afs_com_err(whoami, BC_NOMEM, NULL);
        return (NULL);
     }
     string[0] = 0;
@@ -757,7 +782,7 @@ concatParams(struct cmd_item *itemPtr)
 /* printIfStatus
  *     print out an interface status node as received from butc
  */
+
 void
 printIfStatus(struct tciStatusS *statusPtr)
 {
@@ -882,11 +907,10 @@ bc_WaitForNoJobs(void)
 {
     int i;
     int usefulJobRunning = 1;
+    int printWaiting = 1;
 
     extern dlqlinkT statusHead;
 
-    afs_com_err(whoami, 0, "waiting for job termination");
-
     while (usefulJobRunning) {
        usefulJobRunning = (dlqEmpty(&statusHead) ? 0 : 1);
        if (dispatchLock.excl_locked)
@@ -897,8 +921,13 @@ bc_WaitForNoJobs(void)
        }
 
        /* Wait 5 seconds and check again */
-       if (usefulJobRunning)
+       if (usefulJobRunning) {
+            if (printWaiting) {
+                afs_com_err(whoami, 0, "waiting for job termination");
+                printWaiting = 0;
+            }
            IOMGR_Sleep(5);
+        }
     }
     return (lastTaskCode);
 }
@@ -939,7 +968,7 @@ bc_JobsCmd(struct cmd_syndesc *as, void *arock)
            if (statusPtr->dbDumpId)
                printf(": DumpID %u", statusPtr->dbDumpId);
            if (statusPtr->nKBytes)
-               printf(", %ld Kbytes", afs_cast_int32(statusPtr->nKBytes));
+               printf(", %ld Kbytes", afs_printable_int32_ld(statusPtr->nKBytes));
            if (strlen(statusPtr->volumeName) != 0)
                printf(", volume %s", statusPtr->volumeName);
 
@@ -964,7 +993,7 @@ bc_JobsCmd(struct cmd_syndesc *as, void *arock)
        }
     }
 
-    /* 
+    /*
      * Now print the scheduled dumps.
      */
     if (!dlqEmpty(&statusHead) && as)
@@ -984,11 +1013,11 @@ bc_JobsCmd(struct cmd_syndesc *as, void *arock)
        }
 
        /* Print token expiration time */
-       if ((ttoken.endTime > prevTime)
-           && (ttoken.endTime <= youngest->scheduledDump) && as
-           && (ttoken.endTime != NEVERDATE)) {
-           if (ttoken.endTime > time(0)) {
-               compactDateString(&ttoken.endTime, ds, 50);
+       if ((tokenExpires > prevTime)
+           && (tokenExpires <= youngest->scheduledDump) && as
+           && (tokenExpires != NEVERDATE)) {
+           if (tokenExpires > time(0)) {
+               compactTimeString(&tokenExpires, ds, 50);
                printf("       %16s: TOKEN EXPIRATION\n", ds);
            } else {
                printf("       TOKEN HAS EXPIRED\n");
@@ -1008,11 +1037,11 @@ bc_JobsCmd(struct cmd_syndesc *as, void *arock)
     }
 
     /* Print token expiration time if havn't already */
-    if ((ttoken.endTime == NEVERDATE) && as)
+    if ((tokenExpires == NEVERDATE) && as)
        printf("     : TOKEN NEVER EXPIRES\n");
-    else if ((ttoken.endTime > prevTime) && as) {
-       if (ttoken.endTime > time(0)) {
-           compactDateString(&ttoken.endTime, ds, 50);
+    else if ((tokenExpires > prevTime) && as) {
+       if (tokenExpires > time(0)) {
+           compactTimeString(&tokenExpires, ds, 50);
            printf("       %16s: TOKEN EXPIRATION\n", ds);
        } else {
            printf("     : TOKEN HAS EXPIRED\n");
@@ -1088,7 +1117,6 @@ bc_KillCmd(struct cmd_syndesc *as, void *arock)
        }
        statusPtr->flags |= ABORT_REQUEST;
        unlock_Status();
-       return (0);
     }
     return 0;
 }
@@ -1135,35 +1163,30 @@ bc_VolRestoreCmd(struct cmd_syndesc *as, void *arock)
     }
 
     /* specified other destination host */
-    if (as->parms[0].items) {
-       tp = as->parms[0].items->data;
-       if (bc_ParseHost(tp, &destServ)) {
-           afs_com_err(whoami, 0, "Failed to locate destination host '%s'", tp);
-           return -1;
-       }
+    tp = as->parms[0].items->data;
+    if (bc_ParseHost(tp, &destServ)) {
+       afs_com_err(whoami, 0, "Failed to locate destination host '%s'", tp);
+       return -1;
     }
 
     /* specified other destination partition */
-    if (as->parms[1].items) {
-       tp = as->parms[1].items->data;
-       if (bc_GetPartitionID(tp, &destPartition)) {
-           afs_com_err(whoami, 0, "Can't parse destination partition '%s'", tp);
-           return -1;
-       }
+    tp = as->parms[1].items->data;
+    if (bc_GetPartitionID(tp, &destPartition)) {
+       afs_com_err(whoami, 0, "Can't parse destination partition '%s'", tp);
+       return -1;
     }
 
     for (ti = as->parms[2].items; ti; ti = ti->next) {
        /* build list of volume items */
-       tvol = (struct bc_volumeDump *)malloc(sizeof(struct bc_volumeDump));
+       tvol = calloc(1, sizeof(struct bc_volumeDump));
        if (!tvol) {
-           afs_com_err(whoami, BC_NOMEM, "");
+           afs_com_err(whoami, BC_NOMEM, NULL);
            return BC_NOMEM;
        }
-       memset(tvol, 0, sizeof(struct bc_volumeDump));
 
-       tvol->name = (char *)malloc(VOLSER_MAXVOLNAME + 1);
+       tvol->name = malloc(VOLSER_MAXVOLNAME + 1);
        if (!tvol->name) {
-           afs_com_err(whoami, BC_NOMEM, "");
+           afs_com_err(whoami, BC_NOMEM, NULL);
            return BC_NOMEM;
        }
        strncpy(tvol->name, ti->data, VOLSER_OLDMAXVOLNAME);
@@ -1196,14 +1219,14 @@ bc_VolRestoreCmd(struct cmd_syndesc *as, void *arock)
     oldFlag = 0;
 
     /* Read all the port offsets into the ports array. The first element in the
-     * array is for full restore and the rest are for incremental restores 
+     * array is for full restore and the rest are for incremental restores
      */
     if (as->parms[5].items) {
        for (ti = as->parms[5].items; ti; ti = ti->next)
            portCount++;
-       ports = (afs_int32 *) malloc(portCount * sizeof(afs_int32));
+       ports = malloc(portCount * sizeof(afs_int32));
        if (!ports) {
-           afs_com_err(whoami, BC_NOMEM, "");
+           afs_com_err(whoami, BC_NOMEM, NULL);
            return BC_NOMEM;
        }
 
@@ -1222,7 +1245,7 @@ bc_VolRestoreCmd(struct cmd_syndesc *as, void *arock)
        if (dumpID <= 0)
          dumpID = 0;
       }
-    
+
     /*
      * Perform the call to start the restore.
      */
@@ -1270,7 +1293,7 @@ bc_DiskRestoreCmd(struct cmd_syndesc *as, void *arock)
 
     /* parm 0 is the server to restore
      * parm 1 is the partition to restore
-     
+
      * parm 8 and above as in VolRestoreCmd:
      * parm 8 is the new server to restore to
      * parm 9 is the new partition to restore to
@@ -1331,9 +1354,9 @@ bc_DiskRestoreCmd(struct cmd_syndesc *as, void *arock)
     if (as->parms[2].items) {
        for (ti = as->parms[2].items; ti; ti = ti->next)
            portCount++;
-       ports = (afs_int32 *) malloc(portCount * sizeof(afs_int32));
+       ports = malloc(portCount * sizeof(afs_int32));
        if (!ports) {
-           afs_com_err(whoami, BC_NOMEM, "");
+           afs_com_err(whoami, BC_NOMEM, NULL);
            return BC_NOMEM;
        }
 
@@ -1358,7 +1381,7 @@ bc_DiskRestoreCmd(struct cmd_syndesc *as, void *arock)
        return (-1);
     }
 
-    /* Since we want only RW volumes, remove any 
+    /* Since we want only RW volumes, remove any
      * BK or RO volumes from the list.
      */
     for (prev = 0, tvol = volsToRestore; tvol; tvol = nextvol) {
@@ -1498,13 +1521,11 @@ bc_VolsetRestoreCmd(struct cmd_syndesc *as, void *arock)
            }
 
            /* Allocate a volumeDump structure and link it in */
-           tvol =
-               (struct bc_volumeDump *)malloc(sizeof(struct bc_volumeDump));
-           memset(tvol, 0, sizeof(struct bc_volumeDump));
+           tvol = calloc(1, sizeof(struct bc_volumeDump));
 
-           tvol->name = (char *)malloc(VOLSER_MAXVOLNAME + 1);
+           tvol->name = malloc(VOLSER_MAXVOLNAME + 1);
            if (!tvol->name) {
-               afs_com_err(whoami, BC_NOMEM, "");
+               afs_com_err(whoami, BC_NOMEM, NULL);
                return BC_NOMEM;
            }
            strncpy(tvol->name, volume, VOLSER_OLDMAXVOLNAME);
@@ -1528,9 +1549,9 @@ bc_VolsetRestoreCmd(struct cmd_syndesc *as, void *arock)
     if (as->parms[2].items) {
        for (ti = as->parms[2].items; ti; ti = ti->next)
            portCount++;
-       ports = (afs_int32 *) malloc(portCount * sizeof(afs_int32));
+       ports = malloc(portCount * sizeof(afs_int32));
        if (!ports) {
-           afs_com_err(whoami, BC_NOMEM, "");
+           afs_com_err(whoami, BC_NOMEM, NULL);
            return BC_NOMEM;
        }
 
@@ -1601,7 +1622,6 @@ bc_DumpCmd(struct cmd_syndesc *as, void *arock)
     afs_int32 problemFindingDump;      /* can't find parent(s) */
 
     afs_int32 *portp = NULL;
-    afs_int32 portCount = 0;
     afs_int32 doAt, atTime;    /* Time a timed-dump is to start at */
     afs_int32 length;
     char *timeString;
@@ -1629,10 +1649,10 @@ bc_DumpCmd(struct cmd_syndesc *as, void *arock)
        return (code);
     }
 
-    /* 
+    /*
      * Some parameters cannot be specified together
-     * The "-file" option cannot exist with the "-volume", "-dump", 
-     * "-portoffset", or "-append" option 
+     * The "-file" option cannot exist with the "-volume", "-dump",
+     * "-portoffset", or "-append" option
      */
     if (as->parms[6].items) {
        loadfile = 1;
@@ -1650,7 +1670,7 @@ bc_DumpCmd(struct cmd_syndesc *as, void *arock)
        }
     }
 
-    /* 
+    /*
      * Get the time we are to perform this dump
      */
     if (as->parms[3].items) {
@@ -1675,7 +1695,7 @@ bc_DumpCmd(struct cmd_syndesc *as, void *arock)
 
     dontExecute = (as->parms[5].items ? 1 : 0);        /* -n */
 
-    /* 
+    /*
      * If this dump is not a load file, then check the parameters.
      */
     if (!loadfile) {           /*6 */
@@ -1684,10 +1704,9 @@ bc_DumpCmd(struct cmd_syndesc *as, void *arock)
 
        /* get the port number, if one was specified */
        if (as->parms[2].items) {
-           portCount = 1;
-           portp = (afs_int32 *) malloc(sizeof(afs_int32));
+           portp = malloc(sizeof(afs_int32));
            if (!portp) {
-               afs_com_err(whoami, BC_NOMEM, "");
+               afs_com_err(whoami, BC_NOMEM, NULL);
                return BC_NOMEM;
            }
 
@@ -1719,12 +1738,12 @@ bc_DumpCmd(struct cmd_syndesc *as, void *arock)
 
     /*6 */
     /*
-     * If given the "-at" option, then add this to the jobs list and return 
+     * If given the "-at" option, then add this to the jobs list and return
      * with no error.
      *
      * Create a status node for this timed dump.
      * Fill in the time to dump and the cmd line for the dump leaving off
-     * the -at option.  If the -n option is there, it is scheduled with 
+     * the -at option.  If the -n option is there, it is scheduled with
      * the Timed dump as opposed to not scheduling the time dump at all.
      */
     if (doAt) {
@@ -1766,9 +1785,9 @@ bc_DumpCmd(struct cmd_syndesc *as, void *arock)
            sprintf(statusPtr->taskName, "Scheduled Dump");
            statusPtr->jobNumber = bc_jobNumber();
            statusPtr->scheduledDump = atTime;
-           statusPtr->cmdLine = (char *)malloc(length);
+           statusPtr->cmdLine = malloc(length);
            if (!statusPtr->cmdLine) {
-               afs_com_err(whoami, BC_NOMEM, "");
+               afs_com_err(whoami, BC_NOMEM, NULL);
                return BC_NOMEM;
            }
 
@@ -1801,7 +1820,7 @@ bc_DumpCmd(struct cmd_syndesc *as, void *arock)
                strcat(statusPtr->cmdLine, " -n");
 
            printf("Add scheduled dump as job %d\n", statusPtr->jobNumber);
-           if ((atTime > ttoken.endTime) && (ttoken.endTime != NEVERDATE))
+           if ((atTime > tokenExpires) && (tokenExpires != NEVERDATE))
                afs_com_err(whoami, 0,
                        "Warning: job %d starts after expiration of AFS token",
                        statusPtr->jobNumber);
@@ -1812,22 +1831,21 @@ bc_DumpCmd(struct cmd_syndesc *as, void *arock)
        return (0);
     }
 
-    /* 
+    /*
      * Read and execute the load file if specified.  The work of reading is done
      * in the main routine prior the dispatch call. loadFile and dontExecute are
      * global variables so this can take place in main.
      */
     if (loadfile) {
-       loadFile = (char *)malloc(strlen(as->parms[6].items->data) + 1);
+       loadFile = strdup(as->parms[6].items->data);
        if (!loadFile) {
-           afs_com_err(whoami, BC_NOMEM, "");
+           afs_com_err(whoami, BC_NOMEM, NULL);
            return BC_NOMEM;
        }
-       strcpy(loadFile, as->parms[6].items->data);
        return 0;
     }
 
-    /* 
+    /*
      * We are doing a real dump (no load file or timed dump).
      */
     printf("Starting dump of volume set '%s' (dump level '%s')\n", vsName,
@@ -1850,9 +1868,9 @@ bc_DumpCmd(struct cmd_syndesc *as, void *arock)
        }
 
        /* We found the most recent dump at this level. Now check
-        * if we should use it by seeing if its full dump hierarchy 
+        * if we should use it by seeing if its full dump hierarchy
         * exists. If it doesn't, we don't want to base our incremental
-        * off of this dump. 
+        * off of this dump.
         */
        if (!parent || (dumpEntry.id > parent)) {
            /* Follow the parent dumps to see if they are all there */
@@ -1878,7 +1896,7 @@ bc_DumpCmd(struct cmd_syndesc *as, void *arock)
        }
     }
 
-    /* If the problemflag was raise, it means we are not doing the 
+    /* If the problemflag was raise, it means we are not doing the
      * dump at the level we requested it be done at.
      */
     if (problemFindingDump) {
@@ -2140,7 +2158,7 @@ bc_ScanDumpsCmd(struct cmd_syndesc *as, void *arock)
  */
 
 afs_int32
-bc_ParseExpiration(struct cmd_parmdesc *paramPtr, afs_int32 *expType, 
+bc_ParseExpiration(struct cmd_parmdesc *paramPtr, afs_int32 *expType,
                   afs_int32 *expDate)
 {
     struct cmd_item *itemPtr;
@@ -2241,7 +2259,7 @@ bc_dbVerifyCmd(struct cmd_syndesc *as, void *arock)
     detail = (as->parms[0].items ? 1 : 0);     /* print more details */
 
     code =
-       ubik_Call(BUDB_DbVerify, udbHandle.uh_client, 0, &status, &orphans,
+       ubik_BUDB_DbVerify(udbHandle.uh_client, 0, &status, &orphans,
                  &host);
 
     if (code) {
@@ -2309,7 +2327,7 @@ deleteDump(afs_uint32 dumpid,             /* The dumpid to delete */
 
        /* If dump is to an XBSA server, connect to butc and send it
         * the dump to delete. Butc will contact the XBSA server.
-        * The dump will not be an appended dump because XBSA butc 
+        * The dump will not be an appended dump because XBSA butc
         * does not support the append option.
         */
        if (xbsadump && dumpEntry.nVolumes) {
@@ -2369,7 +2387,7 @@ deleteDump(afs_uint32 dumpid,             /* The dumpid to delete */
        /* Display the dumps that were deleted - includes appended dumps */
        for (i = 0; i < dumps.budb_dumpsList_len; i++)
            printf("     %u%s\n", dumps.budb_dumpsList_val[i],
-                  (i > 0) ? " Appended Dump" : "");
+                  (i > 0) ? " Appended Dump" : NULL);
        if (dumps.budb_dumpsList_val)
            free(dumps.budb_dumpsList_val);
     }
@@ -2390,11 +2408,11 @@ bc_deleteDumpCmd(struct cmd_syndesc *as, void *arock)
     afs_int32 rcode = 0;
     afs_int32 groupId = 0, havegroupid, sflags, noexecute;
     struct cmd_item *ti;
-    afs_uint32 fromTime = 0, toTime = 0, havetime = 0;
+    afs_int32 fromTime = 0, toTime = 0, havetime = 0;
     char *timeString;
     budb_dumpsList dumps, flags;
     int i;
-    afs_int32 port = -1, dbonly = 0, force;
+    afs_int32 port = -1, force;
 
     /* Must specify at least one of -dumpid, -from, or -to */
     if (!as->parms[0].items && !as->parms[1].items && !as->parms[2].items
@@ -2428,7 +2446,7 @@ bc_deleteDumpCmd(struct cmd_syndesc *as, void *arock)
        havetime = 1;
     }
 
-    port = (as->parms[3].items ? getPortOffset(as->parms[3].items->data) : 0); /* -port */
+    port = (as->parms[3].items ? getPortOffset(as->parms[3].items->data) : 0); /* -portoffset */
     if (as->parms[5].items)    /* -dbonly */
        port = -1;
 
@@ -2438,7 +2456,12 @@ bc_deleteDumpCmd(struct cmd_syndesc *as, void *arock)
     if (havegroupid)
        groupId = atoi(as->parms[4].items->data);
 
-    noexecute = (as->parms[7].items ? 1 : 0);
+    if (as->parms[7].items || as->parms[8].items) {
+        /* -noexecute (hidden) or -dryrun used */
+       noexecute = 1;
+    } else {
+       noexecute = 0;
+    }
 
     /* Get the time to delete to */
     if (as->parms[2].items) {  /* -to */
@@ -2652,7 +2675,7 @@ bc_restoreDbCmd(struct cmd_syndesc *as, void *arock)
 }
 
 /* ----------------------------------
- * supporting routines for database examination 
+ * supporting routines for database examination
  * ----------------------------------
  */
 
@@ -2727,12 +2750,10 @@ DBLookupByVolume(char *volumeName)
            for (i = 0; i < numEntries; i++) {  /*f */
                struct dumpedVol *insPtr, **prevPtr;
 
-               tempPtr =
-                   (struct dumpedVol *)malloc(sizeof(struct dumpedVol));
+               tempPtr = calloc(1, sizeof(struct dumpedVol));
                if (!tempPtr)
                    ERROR(BC_NOMEM);
 
-               memset(tempPtr, 0, sizeof(*tempPtr));
                tempPtr->incTime = volumeEntry[i].clone;
                tempPtr->dumpID = volumeEntry[i].dump;
                strncpy(tempPtr->tapeName, volumeEntry[i].tape,
@@ -2799,7 +2820,7 @@ DBLookupByVolume(char *volumeName)
     }
 
     if (code)
-       afs_com_err(whoami, code, "");
+       afs_com_err(whoami, code, NULL);
     return (code);
 }
 
@@ -2885,13 +2906,12 @@ dumpInfo(afs_int32 dumpid, afs_int32 detailFlag)
 
     /* now get the list of tapes */
     for (tapeNumber = dumpEntry.tapes.b; tapeNumber <= dumpEntry.tapes.maxTapes; tapeNumber++) {       /*f */
-       tapeLinkPtr = (struct tapeLink *)malloc(sizeof(struct tapeLink));
+       tapeLinkPtr = calloc(1, sizeof(struct tapeLink));
        if (!tapeLinkPtr) {
-           afs_com_err(whoami, BC_NOMEM, "");
+           afs_com_err(whoami, BC_NOMEM, NULL);
            ERROR(BC_NOMEM);
        }
 
-       memset(tapeLinkPtr, 0, sizeof(*tapeLinkPtr));
        code = bcdb_FindTapeSeq(dumpid, tapeNumber, &tapeLinkPtr->tapeEntry);
        if (code) {
            code = 0;
@@ -2936,13 +2956,11 @@ dumpInfo(afs_int32 dumpid, afs_int32 detailFlag)
            for (i = 0; i < vl.budb_volumeList_len; i++) {
                link = &tapeLinkPtr->firstVolume;
 
-               volumeLinkPtr =
-                   (struct volumeLink *)malloc(sizeof(struct volumeLink));
+               volumeLinkPtr = calloc(1, sizeof(struct volumeLink));
                if (!volumeLinkPtr) {
-                   afs_com_err(whoami, BC_NOMEM, "");
+                   afs_com_err(whoami, BC_NOMEM, NULL);
                    ERROR(BC_NOMEM);
                }
-               memset(volumeLinkPtr, 0, sizeof(*volumeLinkPtr));
 
                memcpy(&volumeLinkPtr->volumeEntry,
                       &vl.budb_volumeList_val[i],
@@ -3056,7 +3074,7 @@ printRecentDumps(int ndumps)
        dl.budb_dumpList_val = 0;
 
        /* outline algorithm */
-       code = ubik_Call(BUDB_GetDumps, udbHandle.uh_client, 0, BUDB_MAJORVERSION, BUDB_OP_NPREVIOUS, "",       /* no name */
+       code = ubik_BUDB_GetDumps(udbHandle.uh_client, 0, BUDB_MAJORVERSION, BUDB_OP_NPREVIOUS, "",     /* no name */
                         0,     /* start */
                         ndumps,        /* end */
                         index, /* index */
@@ -3098,7 +3116,7 @@ printRecentDumps(int ndumps)
     return (code);
 }
 
-/* bc_dumpInfoCmd 
+/* bc_dumpInfoCmd
  *     list the dumps and contens of the dumps.
  * params:
  *     as - name of tape