*/
 int bsnprintf(char *str, int32_t size, const char *fmt,  ...) 
 {
-#ifdef HAVE_VSNPRINTF
-   va_list   arg_ptr;
-   int len;
-
-   va_start(arg_ptr, fmt);
-   len = vsnprintf(str, size, fmt, arg_ptr);
-   va_end(arg_ptr);
-   str[size-1] = 0;
-   return len;
-
-#else
-
    va_list   arg_ptr;
    int len;
-   char *buf;
 
-   buf = get_memory(BIG_BUF);
    va_start(arg_ptr, fmt);
-   len = vsprintf(buf, fmt, arg_ptr);
+   len = bvsnprintf(str, size, fmt, arg_ptr);
    va_end(arg_ptr);
-   if (len >= BIG_BUF) {
-      Emsg0(M_ABORT, 0, _("Buffer overflow.\n"));
-   }
-   memcpy(str, buf, size);
-   str[size-1] = 0;
-   free_memory(buf);
    return len;
-#endif
 }
 
 /*
 
 }
 
 
-
 /*
  * Edit an integer number with commas, the supplied buffer
  * must be at least 27 bytes long.  The incoming number
  */
 char *edit_uint64_with_commas(uint64_t val, char *buf)
 {
-   sprintf(buf, "%" llu, val);
+   /*  
+    * Replacement for sprintf(buf, "%" llu, val)
+    */
+   char mbuf[50];
+   mbuf[sizeof(mbuf)-1] = 0;
+   int i = sizeof(mbuf)-2;                /* edit backward */
+   if (val == 0) {
+      mbuf[i--] = '0';
+   } else {
+      while (val != 0) {
+         mbuf[i--] = "0123456789"[val%10];
+        val /= 10;
+      }
+   }
+   strcpy(buf, &mbuf[i+1]);
    return add_commas(buf, buf);
 }
 
  */
 char *edit_uint64(uint64_t val, char *buf)
 {
-   sprintf(buf, "%" llu, val);
+   /*  
+    * Replacement for sprintf(buf, "%" llu, val)
+    */
+   char mbuf[50];
+   mbuf[sizeof(mbuf)-1] = 0;
+   int i = sizeof(mbuf)-2;                /* edit backward */
+   if (val == 0) {
+      mbuf[i--] = '0';
+   } else {
+      while (val != 0) {
+         mbuf[i--] = "0123456789"[val%10];
+        val /= 10;
+      }
+   }
+   strcpy(buf, &mbuf[i+1]);
    return buf;
 }
 
 
    dcr->rec = new_record();
    dcr->spool_fd = -1;
    dcr->max_spool_size = dev->device->max_spool_size;
-// dev->attached_dcrs->append(dcr);
+   /* Attach this dcr only if dev is initialized */
+   if (dev->fd != 0 && jcr && jcr->JobType != JT_SYSTEM) {
+      dev->attached_dcrs->append(dcr);
+   }
    return dcr;
 }
 
 void free_dcr(DCR *dcr)
 {
-// dcr->dev->attached_dcrs->remove(dcr);
+   JCR *jcr = dcr->jcr;
+   DEVICE *dev = dcr->dev;
+
+   /* Detach this dcr only if the dev is initialized */
+   if (dev->fd != 0 && jcr && jcr->JobType != JT_SYSTEM) {
+      dcr->dev->attached_dcrs->remove(dcr);
+   }
    if (dcr->block) {
       free_block(dcr->block);
    }
 
 
    Pmsg2(000, _("%u Jobs copied. %u records copied.\n"), jobs, records);
 
-   term_dev(in_dev);
-   term_dev(out_dev);
    free_jcr(in_jcr);
    free_jcr(out_jcr);
+
+   term_dev(in_dev);
+   term_dev(out_dev);
    return 0;
 }
   
 
       set_attributes(jcr, attr, &bfd);
    }
    release_device(jcr);
-
    free_attr(attr);
-   term_dev(dev);
    free_jcr(jcr);
+   term_dev(dev);
+
    printf("%u files restored.\n", num_files);
    return;
 }
 
 {
    release_device(jcr);
    free_attr(attr);
-   term_dev(dev);
    free_record(rec);
    free_block(block);
    free_jcr(jcr);
+   term_dev(dev);
 }
 
 
 
       num_media, num_pools, num_jobs, num_files);
 
    free_jcr(bjcr);
+   term_dev(dev);
    return 0;
 }
   
    release_device(bjcr);
 
    free_attr(attr);
-   term_dev(dev);
 }
 
 /*
 
       cmd = NULL;
    }
 
-   if (dev) {
-      term_dev(dev);
+   if (bsr) {
+      free_bsr(bsr);
    }
 
-   if (debug_level > 10)
-      print_memory_pool_stats(); 
-
    free_jcr(jcr);
    jcr = NULL;
 
-   if (bsr) {
-      free_bsr(bsr);
+   if (dev) {
+      term_dev(dev);
    }
 
+   if (debug_level > 10)
+      print_memory_pool_stats(); 
+
    if (this_block) {
       free_block(this_block);
    }
 
       Mmsg1(&dev->errmsg, _("Unable to init mutex: ERR=%s\n"), strerror(errstat));
       Emsg0(M_FATAL, 0, dev->errmsg);
    }
-#ifdef xxx
    if ((errstat = rwl_init(&dev->lock)) != 0) {
       dev->dev_errno = errstat;
       Mmsg1(&dev->errmsg, _("Unable to init mutex: ERR=%s\n"), strerror(errstat));
       Emsg0(M_FATAL, 0, dev->errmsg);
    }
-#endif
 
    dev->fd = -1;
    dev->attached_dcrs = new dlist(dcr, &dcr->dev_link);
    pthread_cond_destroy(&dev->wait);
    pthread_cond_destroy(&dev->wait_next_vol);
    pthread_mutex_destroy(&dev->spool_mutex);
+   rwl_destroy(&dev->lock);
    if (dev->attached_dcrs) {
       delete dev->attached_dcrs;
       dev->attached_dcrs = NULL;
 
    return true;
 }
 
+static const char *spool_name = "*spool*";
+
 static bool despool_data(DCR *dcr, bool commit) 
 {
    DEVICE *rdev;
    lock_device(dcr->dev);
    dcr->dev_locked = true; 
 
-   /* Setup a dev structure to read */
+   /* 
+    * This is really quite kludgy and should be fixed some time.
+    * We create a dev structure to read from the spool file 
+    * in rdev and rdcr.
+    */
    rdev = (DEVICE *)malloc(sizeof(DEVICE));
    memset(rdev, 0, sizeof(DEVICE));
-   rdev->dev_name = get_memory(strlen("spool")+1);
-   strcpy(rdev->dev_name, "spool");
+   rdev->dev_name = get_memory(strlen(spool_name)+1);
+   strcpy(rdev->dev_name, spool_name);
    rdev->errmsg = get_pool_memory(PM_EMSG);
    *rdev->errmsg = 0;
    rdev->max_block_size = dcr->dev->max_block_size;
    rdcr->spool_fd = dcr->spool_fd; 
    rdcr->jcr = jcr;                  /* set a valid jcr */
    block = rdcr->block;
+
    Dmsg1(800, "read/write block size = %d\n", block->buf_len);
    lseek(rdcr->spool_fd, 0, SEEK_SET); /* rewind */
 
    V(dcr->dev->spool_mutex);
    free_memory(rdev->dev_name);
    free_pool_memory(rdev->errmsg);
-   free(rdev);
+   /* Be careful to NULL the jcr and free rdev after free_dcr() */
    rdcr->jcr = NULL;
    free_dcr(rdcr);
+   free(rdev);
    unlock_device(dcr->dev);
    dcr->dev_locked = false;
    dcr->spooling = true;          /* turn on spooling again */
 
 /* */
 #undef  VERSION
 #define VERSION "1.35.1"
-#define VSTRING "1"
-#define BDATE   "17 July 2004"
-#define LSMDATE "17Jul04"
+#define BDATE   "18 July 2004"
+#define LSMDATE "18Jul04"
 
 /* Debug flags */
 #undef  DEBUG