butc: convert butc/dump.c to safer string handling
[openafs.git] / src / butc / dump.c
index 5f5b95f..1f4eb9b 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 <roken.h>
 
-#include <sys/types.h>
-#ifdef AFS_NT40_ENV
-#include <winsock2.h>
-#else
-#include <sys/time.h>
-#include <sys/file.h>
-#include <netinet/in.h>
-#include <sys/socket.h>
-#include <netdb.h>
-#endif
-#include <stdlib.h>
 #include <rx/xdr.h>
 #include <rx/rx.h>
 #include <lwp.h>
 #include <lock.h>
-#include <errno.h>
 #include <afs/tcdata.h>
 #include <afs/bubasics.h>
 #include <afs/budb_client.h>
+#include <afs/butm_prototypes.h>
 #include <afs/vldbint.h>
 #include <afs/ktime.h>
 #include <afs/vlserver.h>
+#include <afs/afsint.h>
 #include <afs/volser.h>
+#include <afs/volser_prototypes.h>
 #include <afs/volint.h>
 #include <afs/cellconfig.h>
+#include <afs/bucoord_prototypes.h>
 
+#include "butc_internal.h"
 #include "error_macros.h"
 #include "butc_xbsa.h"
 #include "afs/butx.h"
 
-
 /* GLOBAL CONFIGURATION PARAMETERS */
 extern int dump_namecheck;
 extern int queryoperator;
@@ -54,11 +45,6 @@ extern struct ubik_client *cstruct;
 dlqlinkT savedEntries;
 dlqlinkT entries_to_flush;
 
-afs_int32 flushSavedEntries(), finishDump(), finishTape(), useTape(),
-addVolume();
-
-extern struct rx_connection *UV_Bind();
-
 extern afs_int32 groupId;
 extern afs_int32 BufferSize;
 extern afs_int32 statusSize;
@@ -89,27 +75,12 @@ afs_int32 tapeblocks;               /* Number of 16K tape datablocks in buffer (!CONF_XBSA) *
  * 6) Ensure bucoord status calls work
  *
  * notes
- * pass 3: 
+ * pass 3:
  *     keep token timeout. If no user reponse (idle time > some period)
  *     and tokens about to time out, terminate dump. This provides at
  *     least something usable.
  */
 
-#define DUMPNAME(dumpname, name, dbDumpId) \
-   if (dbDumpId == 0) \
-     sprintf(dumpname, "%s", name); \
-   else \
-     sprintf(dumpname, "%s (DumpId %u)", name, dbDumpId);
-
-#if defined(AFS_NT40_ENV) || (defined(AFS_DARWIN_ENV) && !defined(AFS_DARWIN60_ENV)) || defined(AFS_SUN4_ENV)
-int
-localtime_r(time_t * t, struct tm *tm)
-{
-    memcpy(tm, localtime(t), sizeof(struct tm));
-    return 0;
-}
-#endif
-
 struct dumpRock {
     /* status only */
     int tapeSeq;
@@ -137,6 +108,15 @@ struct dumpRock {
     struct dumpNode *node;
 };
 
+/* Forward declarations */
+
+int makeVolumeHeader(struct volumeHeader *, struct dumpRock *, int);
+int volumeHeader_hton(struct volumeHeader *, struct volumeHeader *);
+char retryPrompt(char *, afs_int32, afs_uint32);
+int getDumpTape(struct dumpRock *, int, afs_int32);
+int getXBSATape(struct dumpRock *);
+afs_int32 createDump(struct dumpRock *);
+
 /* configuration variables */
 #define HITEOT(code) ((code == BUTM_IO) || (code == BUTM_EOT) || (code == BUTM_IOCTL))
 extern int autoQuery;
@@ -151,7 +131,6 @@ afs_int32
 calcExpirationDate(afs_int32 expType, afs_int32 expDate, afs_int32 createTime)
 {
     struct ktime_date kd;
-    afs_int32 Add_RelDate_to_Time();
 
     switch (expType) {
     case BC_REL_EXPDATE:
@@ -160,11 +139,9 @@ calcExpirationDate(afs_int32 expType, afs_int32 expDate, afs_int32 createTime)
         */
        Int32To_ktimeRelDate(expDate, &kd);
        return (Add_RelDate_to_Time(&kd, createTime));
-       break;
 
     case BC_ABS_EXPDATE:
        return (expDate);
-       break;
 
     case BC_NO_EXPDATE:
     default:
@@ -172,11 +149,11 @@ calcExpirationDate(afs_int32 expType, afs_int32 expDate, afs_int32 createTime)
     }
 }
 
-afs_int32 curr_bserver = 0;
+afs_uint32 curr_bserver = 0;
 struct rx_connection *curr_fromconn = (struct rx_connection *)0;
 
 struct rx_connection *
-Bind(afs_int32 server)
+Bind(afs_uint32 server)
 {
     if (curr_fromconn) {
        if (curr_bserver == server)     /* Keep connection if have it */
@@ -199,10 +176,10 @@ Bind(afs_int32 server)
 /* notes
  * 1) save the chunksize or otherwise ensure tape space remaining is
  *     check frequently enough
- * 2) This is called once. For partial dumps, need to 
+ * 2) This is called once. For partial dumps, need to
  *     ensure that the tape device is left in the correct state for
  *     further dumps.
- * 
+ *
  */
 #define BIGCHUNK 102400
 
@@ -277,7 +254,7 @@ dumpVolume(struct tc_dumpDesc * curDump, struct dumpRock * dparamsPtr)
     buffer = bufferBlock + BUTM_HDRSIZE;
 
     /* Dump one volume fragment at a time until we dump the full volume.
-     * A volume with more than 1 fragment means the volume will 'span' 
+     * A volume with more than 1 fragment means the volume will 'span'
      * 2 or more tapes.
      */
     for (fragmentNumber = 1; !endofvolume; fragmentNumber++) { /*frag */
@@ -292,7 +269,7 @@ dumpVolume(struct tc_dumpDesc * curDump, struct dumpRock * dparamsPtr)
        /* Create and Write the volume header */
        makeVolumeHeader(&hostVolumeHeader, dparamsPtr, fragmentNumber);
        hostVolumeHeader.contd = ((fragmentNumber == 1) ? 0 : TC_VOLCONTD);
-       volumeHeader_hton(&hostVolumeHeader, buffer);
+       volumeHeader_hton(&hostVolumeHeader, (struct volumeHeader *)buffer);
 
        rc = butm_WriteFileData(tapeInfoPtr, buffer, 1,
                                sizeof(hostVolumeHeader));
@@ -314,8 +291,6 @@ dumpVolume(struct tc_dumpDesc * curDump, struct dumpRock * dparamsPtr)
        chunkSize = 0;
        fragmentvolume = 0;
        while (!endofvolume && !fragmentvolume) {       /*w */
-           bytesread = 0;
-
            /* Check for abort in the middle of writing data */
            if (volBytesRead >= chunkSize) {
                chunkSize += BIGCHUNK;
@@ -331,11 +306,11 @@ dumpVolume(struct tc_dumpDesc * curDump, struct dumpRock * dparamsPtr)
            /* Determine how much data to read in upcoming RX_Read() call */
            toread = dataSize;
            /* Check if we are close to the EOT. There should at least be some
-            * data on the tape before it is switched. HACK: we have to split a 
-            * volume across tapes because the volume trailer says the dump 
-            * continues on the next tape (and not the filemark). This could 
-            * result in a volume starting on one tape (no volume data dumped) and 
-            * continued on the next tape. It'll work, just requires restore to 
+            * data on the tape before it is switched. HACK: we have to split a
+            * volume across tapes because the volume trailer says the dump
+            * continues on the next tape (and not the filemark). This could
+            * result in a volume starting on one tape (no volume data dumped) and
+            * continued on the next tape. It'll work, just requires restore to
             * switch tapes. This allows many small volumes (<16K) to be dumped.
             */
            kRemaining = butm_remainingKSpace(tapeInfoPtr);
@@ -357,6 +332,13 @@ dumpVolume(struct tc_dumpDesc * curDump, struct dumpRock * dparamsPtr)
                }
            }
 
+#ifdef xbsa
+           /* Set aside space for the trailing volume header when using large buffers. */
+           if (XBSAMAXBUFFER < toread + sizeof(hostVolumeHeader)) {
+               toread = XBSAMAXBUFFER - sizeof(hostVolumeHeader);
+           }
+#endif
+
            /* Read some volume data. */
            if (fragmentvolume) {
                bytesread = 0;
@@ -379,7 +361,7 @@ dumpVolume(struct tc_dumpDesc * curDump, struct dumpRock * dparamsPtr)
                hostVolumeHeader.contd = (endofvolume ? 0 : TC_VOLCONTD);
                hostVolumeHeader.magic = TC_VOLENDMAGIC;
                hostVolumeHeader.endTime = (endofvolume ? time(0) : 0);
-               volumeHeader_hton(&hostVolumeHeader, &buffer[bytesread]);
+               volumeHeader_hton(&hostVolumeHeader, (struct volumeHeader *)&buffer[bytesread]);
                bytesread += sizeof(hostVolumeHeader);
            }
 
@@ -468,7 +450,7 @@ dumpVolume(struct tc_dumpDesc * curDump, struct dumpRock * dparamsPtr)
     dparamsPtr->curVolumeStatus = DUMP_SUCCESS;
 
   error_exit:
-    /* 
+    /*
      * If we hit the end, see if this is the first volume on the tape or not.
      * Also, mark the tape as finished if the tape contains other dumps.
      */
@@ -491,7 +473,7 @@ dumpVolume(struct tc_dumpDesc * curDump, struct dumpRock * dparamsPtr)
        }
     }
 
-    /* 
+    /*
      * This is used when an error occurs part way into a volume dump. Clean
      * the tape state by writing an FileEnd mark. Forgo this action if we hit
      * the end of tape.
@@ -550,7 +532,6 @@ xbsaDumpVolume(struct tc_dumpDesc * curDump, struct dumpRock * dparamsPtr)
     afs_uint32 statuscount = statusSize, tsize = 0, esize;
     afs_hyper_t estSize;
 
-    char dumpIdStr[XBSA_MAX_OSNAME];
     char volumeNameStr[XBSA_MAX_PATHNAME];
     static char *dumpDescription = "AFS volume dump";
     static char *objectDescription = "XBSA - butc";
@@ -610,14 +591,12 @@ xbsaDumpVolume(struct tc_dumpDesc * curDump, struct dumpRock * dparamsPtr)
     dparamsPtr->curVolStartPos = tapeInfoPtr->position;
 
     /* Tell XBSA what the name and size of volume to write */
-    strcpy(dumpIdStr, butcdumpIdStr);  /* "backup_afs_volume_dumps" */
-    sprintf(volumeNameStr, "/%d", dparamsPtr->databaseDumpId);
-    strcat(volumeNameStr, "/");
-    strcat(volumeNameStr, curDump->name);      /* <dumpid>/<volname> */
+    snprintf(volumeNameStr, sizeof(volumeNameStr), "/%d/%s",
+            dparamsPtr->databaseDumpId, curDump->name);
     hset32(estSize, esize);
     hshlft(estSize, 10);       /* Multiply by 1024 so its in KB */
 
-    rc = xbsa_WriteObjectBegin(&butxInfo, dumpIdStr, volumeNameStr,
+    rc = xbsa_WriteObjectBegin(&butxInfo, butcdumpIdStr, volumeNameStr,
                               xbsalGName, estSize, dumpDescription,
                               objectDescription);
     if (rc != XBSA_SUCCESS) {
@@ -630,10 +609,10 @@ xbsaDumpVolume(struct tc_dumpDesc * curDump, struct dumpRock * dparamsPtr)
     /* Create and Write the volume header */
     makeVolumeHeader(&hostVolumeHeader, dparamsPtr, 1);
     hostVolumeHeader.contd = 0;
-    volumeHeader_hton(&hostVolumeHeader, buffer);
+    volumeHeader_hton(&hostVolumeHeader, (struct volumeHeader *)buffer);
 
-    rc = xbsa_WriteObjectData(&butxInfo, buffer, sizeof(struct volumeHeader),
-                             &bytesWritten);
+    rc = xbsa_WriteObjectData(&butxInfo, buffer,
+                             sizeof(struct volumeHeader), &bytesWritten);
     if (rc != XBSA_SUCCESS) {
        ErrorLog(1, taskId, rc, 0,
                 "Unable to write VolumeHeader data to the server\n");
@@ -645,7 +624,7 @@ xbsaDumpVolume(struct tc_dumpDesc * curDump, struct dumpRock * dparamsPtr)
     bytesWritten = sizeof(struct volumeHeader);
     if (bytesWritten != sizeof(struct volumeHeader)) {
        ErrorLog(1, taskId, rc, 0,
-                "The size of VolumeHeader written (%d) does not equal its actual size (%d)\n",
+                "The size of VolumeHeader written (%d) does not equal its actual size (%" AFS_SIZET_FMT ")\n",
                 bytesWritten, sizeof(struct volumeHeader));
        ERROR_EXIT(TC_INTERNALERROR);
     }
@@ -659,8 +638,6 @@ xbsaDumpVolume(struct tc_dumpDesc * curDump, struct dumpRock * dparamsPtr)
     volBytesRead = 0;
     chunkSize = 0;
     while (!endofvolume) {     /*w */
-       bytesread = 0;
-
        /* Check for abort in the middle of writing data */
        if (volBytesRead >= chunkSize) {
            chunkSize += BIGCHUNK;
@@ -694,11 +671,11 @@ xbsaDumpVolume(struct tc_dumpDesc * curDump, struct dumpRock * dparamsPtr)
            hostVolumeHeader.contd = 0;
            hostVolumeHeader.magic = TC_VOLENDMAGIC;
            hostVolumeHeader.endTime = time(0);
-           volumeHeader_hton(&hostVolumeHeader, &buffer[bytesread]);
+           volumeHeader_hton(&hostVolumeHeader, (struct volumeHeader *)&buffer[bytesread]);
            bytesread += sizeof(hostVolumeHeader);
 
            /* End the dump and transaction with the volserver. We end it now, before
-            * we make the XBSA call because if XBSA blocks, we could time out on the 
+            * we make the XBSA call because if XBSA blocks, we could time out on the
             * volserver (After last read, the transaction with the volserver is idle).
             */
            rc = rx_EndCall(fromcall, 0);
@@ -848,7 +825,6 @@ dumpPass(struct dumpRock * dparamsPtr, int passNumber)
     int action, e;
     afs_int32 code = 0, tcode, dvcode;
     char ch;
-    char retryPrompt();
     struct vldbentry vldbEntry;
     struct sockaddr_in server;
     afs_int32 tapepos;
@@ -884,7 +860,7 @@ dumpPass(struct dumpRock * dparamsPtr, int passNumber)
 
            switch (curDump->vtype) {
            case BACKVOL:
-               if (!(vldbEntry.flags & BACK_EXISTS)) {
+               if (!(vldbEntry.flags & VLF_BACKEXISTS)) {
                    ErrorLog(0, taskId, 0, 0,
                             "Volume %s (%u) failed - Backup volume no longer exists\n",
                             curDump->name, curDump->vid);
@@ -896,7 +872,7 @@ dumpPass(struct dumpRock * dparamsPtr, int passNumber)
 
            case RWVOL:
                for (e = 0; e < vldbEntry.nServers; e++) {      /* Find the RW volume */
-                   if (vldbEntry.serverFlags[e] & ITSRWVOL)
+                   if (vldbEntry.serverFlags[e] & VLSF_RWVOL)
                        break;
                }
                break;
@@ -914,7 +890,7 @@ dumpPass(struct dumpRock * dparamsPtr, int passNumber)
 
                if (e >= vldbEntry.nServers) {  /* Didn't find RO volume */
                    for (e = 0; e < vldbEntry.nServers; e++) {  /* Find the first RO volume */
-                       if (vldbEntry.serverFlags[e] & ITSROVOL)
+                       if (vldbEntry.serverFlags[e] & VLSF_ROVOL)
                            break;
                    }
                }
@@ -926,7 +902,6 @@ dumpPass(struct dumpRock * dparamsPtr, int passNumber)
                         curDump->name, curDump->vid);
                curDump->hostAddr = 0;
                continue;
-               break;
            }
 
            if (e >= vldbEntry.nServers) {
@@ -965,8 +940,8 @@ dumpPass(struct dumpRock * dparamsPtr, int passNumber)
        if (checkAbortByTaskId(taskId))
            ERROR_EXIT(TC_ABORTEDBYREQUEST);
 
-       /* Establish connection to volume - UV_ routine expects 
-        * host address in network order 
+       /* Establish connection to volume - UV_ routine expects
+        * host address in network order
         */
        if (CONF_XBSA) {
            dvcode = xbsaDumpVolume(curDump, dparamsPtr);
@@ -1018,7 +993,6 @@ dumpPass(struct dumpRock * dparamsPtr, int passNumber)
                case 'r':       /* retry */
                    dparamsPtr->curVolume--;    /* redump this volume */
                    continue;
-                   break;
                case 'o':       /* omit */
                    ErrorLog(1, taskId, 0, 0, "Volume %s (%u) omitted\n",
                             curDump->name, curDump->vid);
@@ -1050,7 +1024,6 @@ dumpPass(struct dumpRock * dparamsPtr, int passNumber)
 
            dparamsPtr->curVolume--;    /* redump this volume */
            continue;
-           break;
 
        case DUMP_NORETRYEOT:
            ErrorLog(1, taskId, 0, 0,
@@ -1116,9 +1089,10 @@ dumpPass(struct dumpRock * dparamsPtr, int passNumber)
     return (code);
 }
 
-int
-Dumper(struct dumpNode *nodePtr)
+void *
+Dumper(void *param)
 {
+    struct dumpNode *nodePtr = (struct dumpNode *)param;
     struct dumpRock dparams;
     struct butm_tapeInfo tapeInfo;
     int pass;
@@ -1132,17 +1106,17 @@ Dumper(struct dumpNode *nodePtr)
     int dumpedvolumes = 0;
     int nodumpvolumes = 0;
     char strlevel[5];
-    char msg[20];
-    char finishedMsg1[50];
-    char finishedMsg2[50];
+    char msg[128];
+    char finishedMsg1[128];
+    char finishedMsg2[128];
     time_t startTime = 0;
     time_t endTime = 0;
     afs_int32 allocbufferSize;
 
     extern struct deviceSyncNode *deviceLatch;
     extern struct tapeConfig globalTapeConfig;
-    extern afs_int32 createDump();
 
+    afs_pthread_setname_self("dumper");
     taskId = nodePtr->taskID;  /* Get task Id */
     setStatus(taskId, DRIVE_WAIT);
     EnterDeviceQueue(deviceLatch);
@@ -1203,7 +1177,7 @@ Dumper(struct dumpNode *nodePtr)
      * Used when requesting a tape. Done now because once we create the dump, the
      * routine will then find the newly created dump.
      */
-    sprintf(strlevel, "%d", nodePtr->level);
+    snprintf(strlevel, sizeof(strlevel), "%d", nodePtr->level);
     code =
        bcdb_FindLatestDump(nodePtr->volumeSetName, strlevel,
                            &dparams.lastDump);
@@ -1259,14 +1233,14 @@ Dumper(struct dumpNode *nodePtr)
            break;
     }
 
-    /* 
+    /*
      * Log the error but ignore it since the dump is effectively done.
      * Scantape may assume another volume and ask for next tape.
      */
     if (!CONF_XBSA) {
        code = butm_WriteEOT(&tapeInfo);
        if (code)
-           TapeLog(taskId, code, tapeInfo.error,
+           TapeLog(0, taskId, code, tapeInfo.error,
                    "Warning: Can't write end-of-dump on tape\n");
     }
 
@@ -1308,15 +1282,21 @@ Dumper(struct dumpNode *nodePtr)
 
     lastPass = 1;              /* In case we aborted */
 
-    DUMPNAME(finishedMsg1, nodePtr->dumpSetName, dparams.databaseDumpId);
-    sprintf(finishedMsg2, "%d volumes dumped", dumpedvolumes);
+    /* Format and log finished message. */
+    snprintf(finishedMsg1, sizeof(finishedMsg1), "%s", nodePtr->dumpSetName);
+    if (dparams.databaseDumpId != 0) {
+       snprintf(msg, sizeof(msg), " (DumpId %u)", dparams.databaseDumpId);
+       strlcat(finishedMsg1, msg, sizeof(finishedMsg1));
+    }
+    snprintf(finishedMsg2, sizeof(finishedMsg2),
+            "%d volumes dumped", dumpedvolumes);
     if (failedvolumes) {
-       sprintf(msg, ", %d failed", failedvolumes);
-       strcat(finishedMsg2, msg);
+       snprintf(msg, sizeof(msg), ", %d failed", failedvolumes);
+       strlcat(finishedMsg2, msg, sizeof(finishedMsg2));
     }
     if (nodumpvolumes) {
-       sprintf(msg, ", %d unchanged", nodumpvolumes);
-       strcat(finishedMsg2, msg);
+       snprintf(msg, sizeof(msg), ", %d unchanged", nodumpvolumes);
+       strlcat(finishedMsg2, msg, sizeof(finishedMsg2));
     }
 
     if (code == TC_ABORTEDBYREQUEST) {
@@ -1337,7 +1317,7 @@ Dumper(struct dumpNode *nodePtr)
     if (centralLogIO && startTime) {
        long timediff;
        afs_int32 hrs, min, sec, tmp;
-       char line[1024];
+       char *line = NULL;
        struct tm tmstart, tmend;
 
        localtime_r(&startTime, &tmstart);
@@ -1348,27 +1328,31 @@ Dumper(struct dumpNode *nodePtr)
        min = tmp / 60;
        sec = tmp % 60;
 
-       sprintf(line,
+       code = asprintf(&line,
                "%-5d  %02d/%02d/%04d %02d:%02d:%02d  "
                "%02d/%02d/%04d %02d:%02d:%02d  " "%02d:%02d:%02d  "
-               "%s %d of %d volumes dumped (%ld KB)\n", taskId,
+               "%s %d of %d volumes dumped (%lu KB)\n", taskId,
                tmstart.tm_mon + 1, tmstart.tm_mday, tmstart.tm_year + 1900,
                tmstart.tm_hour, tmstart.tm_min, tmstart.tm_sec,
                tmend.tm_mon + 1, tmend.tm_mday, tmend.tm_year + 1900,
                tmend.tm_hour, tmend.tm_min, tmend.tm_sec, hrs, min, sec,
                nodePtr->volumeSetName, dumpedvolumes,
                dumpedvolumes + failedvolumes,
-               dparams.tapeInfoPtr->kBytes + 1);
-
-       fwrite(line, strlen(line), 1, centralLogIO);
-       fflush(centralLogIO);
+               afs_printable_uint32_lu(dparams.tapeInfoPtr->kBytes + 1));
+       if (code < 0)
+           line = NULL;
+       if (line != NULL) {
+           fwrite(line, strlen(line), 1, centralLogIO);
+           fflush(centralLogIO);
+       }
+       free(line);
     }
 
     setStatus(taskId, TASK_DONE);
 
     FreeNode(taskId);          /* free the dump node */
     LeaveDeviceQueue(deviceLatch);
-    return (code);
+    return (void *)(intptr_t)(code);
 }
 
 #define BELLTIME 60            /* 60 seconds before a bell rings */
@@ -1379,7 +1363,7 @@ Dumper(struct dumpNode *nodePtr)
  *     volume parameters describe the volume that failed
  * entry:
  *     volumeName - name of volume
- *     volumeId - volume id 
+ *     volumeId - volume id
  *     taskId - for job contrl
  * fn return:
  *     character typed by user, one of r, o or a
@@ -1403,17 +1387,13 @@ retryPrompt(char *volumeName, afs_int32 volumeId, afs_uint32 taskId)
     printf("a - abort, the entire dump\n");
 
     while (1) {
-       FFlushInput(stdin);
+       FFlushInput();
        putchar(BELLCHAR);
        fflush(stdout);
 
        start = time(0);
        while (1) {
-#ifdef AFS_PTHREAD_ENV
-           code = GetResponseKey(5, &ch);      /* ch stores key pressed */
-#else
            code = LWP_GetResponseKey(5, &ch);  /* ch stores key pressed */
-#endif
            if (code == 1)
                break;          /* input is available */
 
@@ -1526,7 +1506,6 @@ getDumpTape(struct dumpRock *dparamsPtr, int interactiveFlag,
     afs_int32 tapepos, lastpos;
 
     extern struct tapeConfig globalTapeConfig;
-    extern struct udbHandleS udbHandle;
 
     askForTape = interactiveFlag;
     dparamsPtr->wroteLabel = 0;
@@ -1716,7 +1695,7 @@ getDumpTape(struct dumpRock *dparamsPtr, int interactiveFlag,
                        code = bcdb_FindDumpByID(dmp, &de);
                        if (code)
                            break;
-                       sprintf(strlevel, "%d", de.level);
+                       snprintf(strlevel, sizeof(strlevel), "%d", de.level);
                        code =
                            bcdb_FindLatestDump(de.volumeSetName, strlevel,
                                                &de2);
@@ -1742,7 +1721,7 @@ getDumpTape(struct dumpRock *dparamsPtr, int interactiveFlag,
 
        /*
         * Now have the right tape. Create a new label for the tape
-        * Appended labels have the dump's dumpId - labels at beginnings of 
+        * Appended labels have the dump's dumpId - labels at beginnings of
         *     tape have the initial dump's dumpId.
         * Appended labels do not increment the useCount.
         * Labels at beginnings of tape use the most future expiration of the dump set.
@@ -1872,7 +1851,7 @@ makeVolumeHeader(struct volumeHeader *vhptr, struct dumpRock *dparamsPtr,
     strcpy(vhptr->dumpSetName, nodePtr->dumpSetName);
     strcpy(vhptr->preamble, "H++NAME#");
     strcpy(vhptr->postamble, "T--NAME#");
-  
+
     return (code);
 }
 
@@ -1881,6 +1860,8 @@ volumeHeader_hton(struct volumeHeader *hostPtr, struct volumeHeader *netPtr)
 {
     struct volumeHeader volHdr;
 
+    memset(&volHdr, 0, sizeof(volHdr));
+
     strcpy(volHdr.preamble, hostPtr->preamble);
     strcpy(volHdr.postamble, hostPtr->postamble);
     strcpy(volHdr.volumeName, hostPtr->volumeName);
@@ -2029,9 +2010,11 @@ InitToServer(afs_int32 taskId, struct butx_transactionInfo * butxInfoP,
 /* DeleteDump
  *
  */
-int
-DeleteDump(struct deleteDumpIf *ptr)
+void *
+DeleteDump(void *param)
 {
+    struct deleteDumpIf *ptr = (struct deleteDumpIf *)param;
+
     afs_int32 taskId;
     afs_int32 rc, code = 0;
     afs_uint32 dumpid;
@@ -2047,13 +2030,14 @@ DeleteDump(struct deleteDumpIf *ptr)
     extern struct udbHandleS udbHandle;
     extern struct deviceSyncNode *deviceLatch;
 
+    dumpid = ptr->dumpID;
+    taskId = ptr->taskId;      /* Get task Id */
+
+    afs_pthread_setname_self("deletedump");
     setStatus(taskId, DRIVE_WAIT);
     EnterDeviceQueue(deviceLatch);
     clearStatus(taskId, DRIVE_WAIT);
 
-    dumpid = ptr->dumpID;
-    taskId = ptr->taskId;      /* Get task Id */
-
     printf("\n\n");
     TapeLog(2, taskId, 0, 0, "Delete Dump %u\n", dumpid);
 
@@ -2145,15 +2129,14 @@ DeleteDump(struct deleteDumpIf *ptr)
        for (i = 0; i < vl.budb_volumeList_len; i++) {
            if (dumpEntry.flags & BUDB_DUMP_BUTA) {
                /* dump was from buta, use old buta style names */
-               sprintf(dumpIdStr, "/%d", dumpid);
-               strcpy(volumeNameStr, "/");
-               strcat(volumeNameStr, (char *)vl.budb_volumeList_val[i].name);
+               snprintf(dumpIdStr, sizeof(dumpIdStr), "/%d", dumpid);
+               snprintf(volumeNameStr, sizeof(volumeNameStr), "/%s",
+                        (char *)vl.budb_volumeList_val[i].name);
            } else {            /* BUDB_DUMP_ADSM */
                /* dump was from butc to ADSM, use butc names */
-               strcpy(dumpIdStr, butcdumpIdStr);
-               sprintf(volumeNameStr, "/%d", dumpid);
-               strcat(volumeNameStr, "/");
-               strcat(volumeNameStr, (char *)vl.budb_volumeList_val[i].name);
+               snprintf(dumpIdStr, sizeof(dumpIdStr), "%s", butcdumpIdStr);
+               snprintf(volumeNameStr, sizeof(volumeNameStr), "/%d/%s",
+                        dumpid, (char *)vl.budb_volumeList_val[i].name);
            }
 
            rc = xbsa_DeleteObject(&butxInfo, dumpIdStr, volumeNameStr);
@@ -2211,6 +2194,6 @@ DeleteDump(struct deleteDumpIf *ptr)
        code = BUTX_DELETENOVOL;
        setStatus(taskId, TASK_ERROR);
     }
-    return (code);
+    return (void *)(uintptr_t)(code);
 }
 #endif