void my_mysql_free_result(B_DB *mdb)
 {
+   db_lock(mdb);
    if (mdb->result) {
       mysql_free_result(mdb->result);
       mdb->result = NULL;
    }
+   db_unlock(mdb);
 }
 
 char *my_mysql_batch_lock_path_query = "LOCK TABLES Path write,     " 
 
 
 void my_postgresql_free_result(B_DB *mdb)
 {
+   
+   db_lock(mdb);
    if (mdb->result) {
       PQclear(mdb->result);
       mdb->result = NULL;
       free(mdb->fields);
       mdb->fields = NULL;
    }
+   db_unlock(mdb);
 }
 
 int my_postgresql_currval(B_DB *mdb, char *table_name)
 
  */
 bool my_batch_start(JCR *jcr, B_DB *mdb)
 {
-   return db_sql_query(mdb,
+   bool ok;
+
+   db_lock(mdb);
+   ok =  db_sql_query(mdb,
              " CREATE TEMPORARY TABLE batch "
              "        (fileindex integer,   "
              "        jobid integer,        "
              "        name blob,            "
              "        lstat tinyblob,       "
              "        md5 tinyblob)         ",NULL, NULL);
+   db_unlock(mdb);
+   return ok;
 }
 
 /* 
 
       if (!complete_jcr_for_job(jcr, job, run->pool)) {
          return false;
       }
+      if (!jcr->jr.PoolId) {
+         ua->error_msg(_("Could not Pool Job %s\n"), job->name());
+         continue;
+      }
       memset(&pr, 0, sizeof(pr));
       pr.PoolId = jcr->jr.PoolId;
       if (!db_get_pool_record(ua->jcr, ua->db, &pr)) {
       get_job_storage(&store, job, run);
       mr.StorageId = store.store->StorageId;
       if (!find_next_volume_for_append(jcr, &mr, 1, fnv_no_create_vol, fnv_prune)) {
-         ua->error_msg(_("Could not find next Volume for Job %s (%s, %s).\n"),
-            job->hdr.name, pr.Name, level_to_str(run->level));
+         ua->error_msg(_("Could not find next Volume for Job %s (Pool=%s, Level=%s).\n"),
+            job->name(), pr.Name, level_to_str(run->level));
       } else {
          ua->send_msg(
-            _("The next Volume to be used by Job \"%s\" (%s, %s) will be %s\n"),
-            job->hdr.name, pr.Name, level_to_str(run->level), mr.VolumeName);
+            _("The next Volume to be used by Job \"%s\" (Pool=%s, Level=%s) will be %s\n"),
+            job->name(), pr.Name, level_to_str(run->level), mr.VolumeName);
          found = true;
       }
       if (jcr->db && jcr->db != ua->db) {
 
       rctx.store = store;
       
       /*
-       * Note, if search_for_device() succeeds, we get a new_dcr,
+       * Note, if search_for_device() succeeds, we get a new dcr,
        *  which we do not use except for the dev info.
        */
       stat = search_res_for_device(rctx);
       release_msgs(jcr);              /* release queued messages */
       unlock_reservations();
       if (stat == 1) {
-         DCR *new_dcr = jcr->read_dcr;
+         DCR *ndcr = jcr->read_dcr;
          dev->unblock(dev_unlocked);
          detach_dcr_from_dev(dcr);    /* release old device */
          /* Copy important info from the new dcr */
-         dev = dcr->dev = new_dcr->dev; 
+         dev = dcr->dev = ndcr->dev; 
          jcr->read_dcr = dcr; 
-         dcr->device = new_dcr->device;
+         dcr->device = ndcr->device;
          dcr->max_job_spool_size = dcr->device->max_job_spool_size;
          attach_dcr_to_dev(dcr);
-         new_dcr->VolumeName[0] = 0;
-         free_dcr(new_dcr);
+         ndcr->VolumeName[0] = 0;
+         free_dcr(ndcr);
          dev->block(BST_DOING_ACQUIRE); 
          Jmsg(jcr, M_INFO, 0, _("Media Type change.  New device %s chosen.\n"),
             dev->print_name());
 /*
  * Create a new Device Control Record and attach
  *   it to the device (if this is a real job).
+ * Note, this has been updated so that it can be called first 
+ *   without a DEVICE, then a second or third time with a DEVICE,
+ *   and each time, it should cleanup and point to the new device.
+ *   This should facilitate switching devices.
+ * Note, each dcr must point to the controlling job (jcr).  However,
+ *   a job can have multiple dcrs, so we must not store in the jcr's
+ *   structure as previously. The higher level routine must store
+ *   this dcr in the right place
+ *
  */
-DCR *new_dcr(JCR *jcr, DEVICE *dev)
+DCR *new_dcr(JCR *jcr, DCR *dcr, DEVICE *dev)
 {
-   if (jcr) Dmsg2(100, "enter new_dcr JobId=%u dev=%p\n", (uint32_t)jcr->JobId, dev);
-   DCR *dcr = (DCR *)malloc(sizeof(DCR));
-   memset(dcr, 0, sizeof(DCR));
-   dcr->jcr = jcr;
-   if (dev) {
+   if (!dcr) {
+      dcr = (DCR *)malloc(sizeof(DCR));
+      memset(dcr, 0, sizeof(DCR));
       dcr->tid = pthread_self();
-      dcr->dev = dev;
-      dcr->device = dev->device;
+      dcr->spool_fd = -1;
+   }
+   dcr->jcr = jcr;                 /* point back to jcr */
+   /* Set device information, possibly change device */
+   if (dev) {
+      if (dcr->block) {
+         free_block(dcr->block);
+      }
       dcr->block = new_block(dev);
+      if (dcr->rec) {
+         free_record(dcr->rec);
+      }
       dcr->rec = new_record();
+      if (dcr->attached_to_dev) {
+         detach_dcr_from_dev(dcr);
+      }
       dcr->max_job_spool_size = dev->device->max_job_spool_size;
+      dcr->device = dev->device;
+      dcr->dev = dev;
       attach_dcr_to_dev(dcr);
    }
-   dcr->spool_fd = -1;
    return dcr;
 }
 
 void detach_dcr_from_dev(DCR *dcr)
 {
    Dmsg1(500, "JobId=%u enter detach_dcr_from_dev\n", (uint32_t)dcr->jcr->JobId);
-   unreserve_device(dcr);
 
    /* Detach this dcr only if attached */
-   if (dcr->attached_to_dev) {
+   if (dcr->attached_to_dev && dcr->dev) {
+      unreserve_device(dcr);
       dcr->dev->attached_dcrs->remove(dcr);  /* detach dcr from device */
       dcr->attached_to_dev = false;
 //    remove_dcr_from_dcrs(dcr);      /* remove dcr from jcr list */
 {
    JCR *jcr = dcr->jcr;
 
-   if (dcr->dev) {
-      detach_dcr_from_dev(dcr);
-   }
+   detach_dcr_from_dev(dcr);
 
    if (dcr->block) {
       free_block(dcr->block);
 
       return dev->Slot;
    }
    /* Virtual disk autochanger */
-   if (dcr->device->changer_command[0] ==0) {
+   if (dcr->device->changer_command[0] == 0) {
       return 1;
    }
 
 
-/*
- *
- *  Program to scan a Bacula Volume and compare it with
- *    the catalog and optionally synchronize the catalog
- *    with the tape.
- *
- *   Kern E. Sibbald, December 2001
- *
- *
- *   Version $Id$
- */
 /*
    Bacula® - The Network Backup Solution
 
-   Copyright (C) 2001-2006 Free Software Foundation Europe e.V.
+   Copyright (C) 2001-2007 Free Software Foundation Europe e.V.
 
    The main author of Bacula is Kern Sibbald, with contributions from
    many others, a complete list can be found in the file AUTHORS.
    (FSFE), Fiduciary Program, Sumatrastrasse 25, 8006 Zürich,
    Switzerland, email:ftf@fsfeurope.org.
 */
+/*
+ *
+ *  Program to scan a Bacula Volume and compare it with
+ *    the catalog and optionally synchronize the catalog
+ *    with the tape.
+ *
+ *   Kern E. Sibbald, December 2001
+ *
+ *
+ *   Version $Id$
+ */
 
 #include "bacula.h"
 #include "stored.h"
    Dmsg1(100, "Walk attached jcrs. Volume=%s\n", dev->VolCatInfo.VolCatName);
    foreach_dlist(mdcr, dev->attached_dcrs) {
       JCR *mjcr = mdcr->jcr;
+      Dmsg1(000, "========== JobId=%u ========\n", mjcr->JobId);
       if (mjcr->JobId == 0) {
          continue;
       }
       if (verbose) {
          Pmsg1(000, _("Create JobMedia for Job %s\n"), mjcr->Job);
       }
-      if (dev->is_tape()) {
-         mdcr->EndBlock = dcr->EndBlock;
-         mdcr->EndFile = dcr->EndFile;
-//    } else {
-//       mdcr->EndBlock = (uint32_t)dcr->file_addr;
-//       mdcr->EndFile = (uint32_t)(dcr->file_addr >> 32);
-      }
+      mdcr->StartBlock = dcr->StartBlock;
+      mdcr->StartFile = dcr->StartFile;
+      mdcr->EndBlock = dcr->EndBlock;
+      mdcr->EndFile = dcr->EndFile;
       mjcr->read_dcr->VolLastIndex = dcr->VolLastIndex;
       if (!create_jobmedia_record(db, mjcr)) {
          Pmsg2(000, _("Could not create JobMedia record for Volume=%s Job=%s\n"),
             dev->VolCatInfo.VolCatName, mjcr->Job);
       }
    }
+
+   update_media_record(db, &mr);
+
    /* Now let common read routine get up next tape. Note,
     * we call mount_next... with bscan's jcr because that is where we
     * have the Volume list, but we get attached.
       mr->LabelDate = mktime(&tm);
    }
    lasttime = mr->LabelDate;
+   if (mr->VolJobs == 0) {
+      mr->VolJobs = 1;
+   }
+   if (mr->VolMounts == 0) {
+      mr->VolMounts = 1;
+   }
 
    if (!update_db) {
       return 1;
    JOBMEDIA_DBR jmr;
    DCR *dcr = mjcr->read_dcr;
 
-   if (dev->is_tape()) {
-      dcr->EndBlock = dev->EndBlock;
-      dcr->EndFile  = dev->EndFile;
-#ifdef needed
-   } else {
-      dcr->EndBlock = (uint32_t)dev->file_addr;
-      dcr->EndFile = (uint32_t)(dev->file_addr >> 32);
-#endif
-   } 
+   dcr->EndBlock = dev->EndBlock;
+   dcr->EndFile  = dev->EndFile;
 
    memset(&jmr, 0, sizeof(jmr));
    jmr.JobId = mjcr->JobId;
    jobjcr->VolSessionId = rec->VolSessionId;
    jobjcr->VolSessionTime = rec->VolSessionTime;
    jobjcr->ClientId = jr->ClientId;
-   jobjcr->read_dcr = new_dcr(jobjcr, dev);
+   jobjcr->dcr = jobjcr->read_dcr = new_dcr(jobjcr, NULL, dev);
 
    return jobjcr;
 }
 
-/*
- *
- *  Utility routines for "tool" programs such as bscan, bls,
- *    bextract, ...  Some routines also used by Bacula.
- *
- *    Kern Sibbald, MM
- *
- *  Normally nothing in this file is called by the Storage
- *    daemon because we interact more directly with the user
- *    i.e. printf, ...
- *
- *   Version $Id$
- */
 /*
    Bacula® - The Network Backup Solution
 
-   Copyright (C) 2000-2006 Free Software Foundation Europe e.V.
+   Copyright (C) 2000-2007 Free Software Foundation Europe e.V.
 
    The main author of Bacula is Kern Sibbald, with contributions from
    many others, a complete list can be found in the file AUTHORS.
    (FSFE), Fiduciary Program, Sumatrastrasse 25, 8006 Zürich,
    Switzerland, email:ftf@fsfeurope.org.
 */
+/*
+ *
+ *  Utility routines for "tool" programs such as bscan, bls,
+ *    bextract, ...  Some routines also used by Bacula.
+ *
+ *    Kern Sibbald, MM
+ *
+ *  Normally nothing in this file is called by the Storage
+ *    daemon because we interact more directly with the user
+ *    i.e. printf, ...
+ *
+ *   Version $Id$
+ */
 
 #include "bacula.h"
 #include "stored.h"
       return NULL;
    }
    device->dev = dev;
-   dcr = new_dcr(jcr, dev);
-   jcr->dcr = dcr;
+   jcr->dcr = dcr = new_dcr(jcr, NULL, dev);
    if (VolName[0]) {
       bstrncpy(dcr->VolumeName, VolName, sizeof(dcr->VolumeName));
    }
 
 static bool changer_cmd(JCR *sjcr);
 static bool do_label(JCR *jcr, int relabel);
 static DCR *find_device(JCR *jcr, POOL_MEM &dev_name, int drive);
-static void read_volume_label(JCR *jcr, DEVICE *dev, int Slot);
+static void read_volume_label(JCR *jcr, DCR *dcr, DEVICE *dev, int Slot);
 static void label_volume_if_ok(DCR *dcr, char *oldname,
                                char *newname, char *poolname,
                                int Slot, int relabel);
-static bool try_autoload_device(JCR *jcr, int slot, const char *VolName);
+static bool try_autoload_device(JCR *jcr, DCR *dcr, int slot, const char *VolName);
 static void send_dir_busy_message(BSOCK *dir, DEVICE *dev);
 
 struct s_cmds {
          }
          dev->dunlock();
          free_dcr(dcr);
-         jcr->dcr = NULL;
       } else {
          bnet_fsend(dir, _("3999 Device \"%s\" not found or could not be opened.\n"), dev_name.c_str());
       }
 
 
    Dmsg0(90, "try_autoload_device - looking for volume_info\n");
-   if (!try_autoload_device(dcr->jcr, slot, volname)) {
+   if (!try_autoload_device(dcr->jcr, dcr, slot, volname)) {
       goto bail_out;                  /* error */
    }
 
 
    if (found) {
       Dmsg1(100, "Found device %s\n", device->hdr.name);
-      dcr = new_dcr(jcr, device->dev);
+      dcr = new_dcr(jcr, NULL, device->dev);
       dcr->device = device;
-      jcr->dcr = dcr;
    }
    return dcr;
 }
          case BST_UNMOUNTED_WAITING_FOR_SYSOP:
          case BST_UNMOUNTED:
             if (dev->is_autochanger() && slot > 0) {
-               try_autoload_device(jcr, slot, "");
+               try_autoload_device(jcr, dcr, slot, "");
             }
             /* We freed the device, so reopen it and wake any waiting threads */
             if (dev->open(dcr, OPEN_READ_ONLY) < 0) {
 
          case BST_NOT_BLOCKED:
             if (dev->is_autochanger() && slot > 0) {
-               try_autoload_device(jcr, slot, "");
+               try_autoload_device(jcr, dcr, slot, "");
             }
             if (dev->is_open()) {
                if (dev->is_labeled()) {
          }
          dev->dunlock();
          free_dcr(dcr);
-         jcr->dcr = NULL;
       } else {
          bnet_fsend(dir, _("3999 Device \"%s\" not found or could not be opened.\n"), devname.c_str());
       }
          }
          dev->dunlock();
          free_dcr(dcr);
-         jcr->dcr = NULL;
       } else {
          bnet_fsend(dir, _("3999 Device \"%s\" not found or could not be opened.\n"), devname.c_str());
       }
          }
          dev->dunlock();
          free_dcr(dcr);
-         jcr->dcr = NULL;
       } else {
          bnet_fsend(dir, _("3999 Device \"%s\" not found or could not be opened.\n"), devname.c_str());
       }
          }
          dev->dunlock();
          free_dcr(dcr);
-         jcr->dcr = NULL;
       } else {
          bnet_fsend(dir, _("3999 Device \"%s\" not found or could not be opened.\n"), devname.c_str());
       }
          dev = dcr->dev;
          dev->dlock();                 /* Use P to avoid indefinite block */
          if (!dev->is_open()) {
-            read_volume_label(jcr, dev, Slot);
+            read_volume_label(jcr, dcr, dev, Slot);
             dev->close();
          /* Under certain "safe" conditions, we can steal the lock */
          } else if (dev->can_steal_lock()) {
-            read_volume_label(jcr, dev, Slot);
+            read_volume_label(jcr, dcr, dev, Slot);
          } else if (dev->is_busy() || dev->is_blocked()) {
             send_dir_busy_message(dir, dev);
          } else {                     /* device not being used */
-            read_volume_label(jcr, dev, Slot);
+            read_volume_label(jcr, dcr, dev, Slot);
          }
          dev->dunlock();
          free_dcr(dcr);
-         jcr->dcr = NULL;
       } else {
          bnet_fsend(dir, _("3999 Device \"%s\" not found or could not be opened.\n"), devname.c_str());
       }
  *
  *  Enter with the mutex set
  */
-static void read_volume_label(JCR *jcr, DEVICE *dev, int Slot)
+static void read_volume_label(JCR *jcr, DCR *dcr, DEVICE *dev, int Slot)
 {
    BSOCK *dir = jcr->dir_bsock;
    bsteal_lock_t hold;
-   DCR *dcr = jcr->dcr;
 
    dcr->dev = dev;
    steal_device_lock(dev, &hold, BST_WRITING_LABEL);
 
-   if (!try_autoload_device(jcr, Slot, "")) {
+   if (!try_autoload_device(jcr, dcr, Slot, "")) {
       goto bail_out;                  /* error */
    }
 
    return;
 }
 
-static bool try_autoload_device(JCR *jcr, int slot, const char *VolName)
+static bool try_autoload_device(JCR *jcr, DCR *dcr, int slot, const char *VolName)
 {
-   DCR *dcr = jcr->dcr;
    BSOCK *dir = jcr->dir_bsock;
 
    bstrncpy(dcr->VolumeName, VolName, sizeof(dcr->VolumeName));
 
    }
    jcr->dcrs = NULL;
 
+   /* Avoid a double free */
+   if (jcr->dcr == jcr->read_dcr) {
+      jcr->read_dcr = NULL;
+   }
    if (jcr->dcr) {
       free_dcr(jcr->dcr);
       jcr->dcr = NULL;
 
 DCR     *acquire_device_for_append(DCR *dcr);
 bool     acquire_device_for_read(DCR *dcr);
 bool     release_device(DCR *dcr);
-DCR     *new_dcr(JCR *jcr, DEVICE *dev);
+DCR     *new_dcr(JCR *jcr, DCR *dcr, DEVICE *dev);
 void     free_dcr(DCR *dcr);
 void     detach_dcr_from_dev(DCR *dcr);
 
 
     *  explicitly read in this drive. This allows the SD to remember
     *  where the tapes are or last were.
     */
-   if (dev->is_tape()) {
+   if (dev->is_tape() || dev->is_autochanger()) {
       return true;
    } else {
       return free_volume(dev);
    }
    lock_volumes();
    foreach_dlist(vol, vol_list) {
-      Dmsg3(dbglvl, "jid=%u Unreleased Volume=%s dev=%p\n", jid(), vol->vol_name, vol->dev);
+      if (vol->dev) {
+         Dmsg3(dbglvl, "jid=%u free vol_list Volume=%s dev=%s\n", jid(),
+               vol->vol_name, vol->dev->print_name());
+      } else {
+         Dmsg3(dbglvl, "jid=%u free vol_list Volume=%s dev=%p\n", jid(), 
+               vol->vol_name, vol->dev);
+      }
       free(vol->vol_name);
       vol->vol_name = NULL;
    }
    }
 
    init_jcr_device_wait_timers(jcr);
+   jcr->dcr = new_dcr(jcr, NULL, NULL);         /* get a dcr */
+   if (!jcr->dcr) {
+      BSOCK *dir = jcr->dir_bsock;
+      dir->fsend(_("3939 Could not get dcr\n"));
+      Dmsg1(dbglvl, ">dird: %s", dir->msg);
+      ok = false;
+   }
    /*                    
     * At this point, we have a list of all the Director's Storage
     *  resources indicated for this Job, which include Pool, PoolType,
       int repeat = 0;
       bool fail = false;
       rctx.notify_dir = true;
+
       lock_reservations();
       for ( ; !fail && !job_canceled(jcr); ) {
          while ((msg = (char *)msgs->pop())) {
          rctx.VolumeName[0] = 0;
          rctx.any_drive = false;
          if (!jcr->PreferMountedVols) {
-            /* Look for unused drives in autochangers */
+            /*
+             * Here we try to find a drive that is not used.
+             * This will maximize the use of available drives.
+             *
+             */
             rctx.num_writers = 20000000;   /* start with impossible number */
             rctx.low_use_drive = NULL;
             rctx.PreferMountedVols = false;                
                break;
             }
          }
-         /* Look for an exact match all drives */
+         /*
+          * Now we look for a drive that may or may not be in
+          *  use.
+          */
+         /* Look for an exact Volume match all drives */
          rctx.PreferMountedVols = true;
          rctx.exact_match = true;
          rctx.autochanger_only = false;
    unlock_reservations();
 }
 
+/*
+ * Walk through the autochanger resources and check if
+ *  the volume is in one of them.
+ * 
+ * Returns:  true  if volume is in device
+ *           false otherwise
+ */
+static bool is_vol_in_autochanger(RCTX &rctx, VOLRES *vol)
+{
+   AUTOCHANGER *changer;
+   Dmsg2(dbglvl, "jid=%u search changers for %s\n", (int)rctx.jcr->JobId, 
+         rctx.device_name);
+   foreach_res(changer, R_AUTOCHANGER) {
+      Dmsg2(dbglvl, "jid=%u Try match changer res=%s\n", 
+            (int)rctx.jcr->JobId, changer->hdr.name);
+      /* Find resource, and make sure we were able to open it */
+      if (fnmatch(rctx.device_name, changer->hdr.name, 0) == 0) {
+         DEVRES *device;
+         /* Try each device in this AutoChanger */
+         foreach_alist(device, changer->device) {
+            Dmsg2(dbglvl, "jid=%u Try changer device %s\n", 
+                  (int)rctx.jcr->JobId, device->hdr.name);
+            if (device->dev == vol->dev) {
+               Dmsg2(dbglvl, "jid=%u Found changer device %s\n",
+                     (int)rctx.jcr->JobId, device->hdr.name);
+               return true;
+            }
+         }
+      }
+   }
+   return false;
+}
+
 /*
  * Search for a device suitable for this job.
  */
    DIRSTORE *store;
    char *device_name;
    alist *dirstore;
+   DCR *dcr = jcr->dcr;
 
    if (rctx.append) {
       dirstore = jcr->write_store;
       rctx.PreferMountedVols, rctx.exact_match, rctx.suitable_device,
       rctx.autochanger_only);
 
+   /* 
+    * If the appropriate conditions of this if are met, namely that
+    *  we are appending and the user wants mounted drive (or we
+    *  force try a mounted drive because they are all busy), we
+    *  start by looking at all the Volumes in the volume list.
+    */
    if (!vol_list->empty() && rctx.append && rctx.PreferMountedVols) {
       dlist *temp_vol_list, *save_vol_list;
       VOLRES *vol = NULL;
       unlock_volumes();
 
       /* Look through reserved volumes for one we can use */
+      Dmsg1(dbglvl, "jid=%u look for vol in vol list\n", (int)rctx.jcr->JobId);
       foreach_dlist(vol, temp_vol_list) {
          if (!vol->dev) {
+            Dmsg2(dbglvl, "jid=%u vol=%s no dev\n", (int)rctx.jcr->JobId, vol->vol_name);
+            continue;
+         }
+         /* Check with Director if this Volume is OK */
+         bstrncpy(dcr->VolumeName, vol->vol_name, sizeof(dcr->VolumeName));
+         if (!dir_get_volume_info(dcr, GET_VOL_INFO_FOR_WRITE)) {
             continue;
          }
+
+         Dmsg2(dbglvl, "jid=%u vol=%s\n", (int)rctx.jcr->JobId, vol->vol_name);
          foreach_alist(store, dirstore) {
+            int stat;
             rctx.store = store;
             foreach_alist(device_name, store->device) {
-               int stat;
-               if (strcmp(device_name, vol->dev->device->hdr.name) != 0) {
-                  continue;
-               }
+               /* Found a device, try to use it */
                rctx.device_name = device_name;
                rctx.device = vol->dev->device;
+
+               if (!vol->dev->is_autochanger()) {
+                  if (!is_vol_in_autochanger(rctx, vol)) {
+                     continue;
+                  }
+               } else if (strcmp(device_name, vol->dev->device->hdr.name) != 0) {
+                  Dmsg3(dbglvl, "jid=%u device=%s not suitable want %s\n", (int)rctx.jcr->JobId, 
+                        vol->dev->device->hdr.name, device_name);
+                  continue;
+               }
+
                bstrncpy(rctx.VolumeName, vol->vol_name, sizeof(rctx.VolumeName));
                rctx.have_volume = true;
                /* Try reserving this device and volume */
             }
          }
       } /* end for loop over reserved volumes */
+
       lock_volumes();
       save_vol_list = vol_list;
       vol_list = temp_vol_list;
 
    rctx.suitable_device = true;
    Dmsg2(dbglvl, "jid=%u try reserve %s\n", rctx.jcr->JobId, rctx.device->hdr.name);
-   dcr = new_dcr(rctx.jcr, rctx.device->dev);
+   rctx.jcr->dcr = dcr = new_dcr(rctx.jcr, rctx.jcr->dcr, rctx.device->dev);
    if (!dcr) {
       BSOCK *dir = rctx.jcr->dir_bsock;
       dir->fsend(_("3926 Could not get dcr for device: %s\n"), rctx.device_name);
 
 bail_out:
    rctx.have_volume = false;
-   free_dcr(dcr);
+// free_dcr(dcr);
    Dmsg1(dbglvl, "jid=%u Not OK.\n", (int)rctx.jcr->JobId);
    return 0;
 }
 
    rdev->max_block_size = dcr->dev->max_block_size;
    rdev->min_block_size = dcr->dev->min_block_size;
    rdev->device = dcr->dev->device;
-   rdcr = new_dcr(jcr, rdev);
+   rdcr = new_dcr(jcr, NULL, rdev);
    rdcr->spool_fd = dcr->spool_fd;
-   rdcr->jcr = jcr;                   /* set a valid jcr */
    block = dcr->block;                /* save block */
    dcr->block = rdcr->block;          /* make read and write block the same */
 
 
          continue;
       }
 
-      jcr->dcr = dcr = new_dcr(jcr, dev);
+      jcr->dcr = dcr = new_dcr(jcr, NULL, dev);
       if (dev->is_autochanger()) {
          /* If autochanger set slot in dev sturcture */
          get_autochanger_loaded_slot(dcr);
 
  */
 
 #undef  VERSION
-#define VERSION "2.1.18"
-#define BDATE   "16 June 2007"
-#define LSMDATE "16Jun07"
+#define VERSION "2.1.19"
+#define BDATE   "18 June 2007"
+#define LSMDATE "18Jun07"
 
 #define PROG_COPYRIGHT "Copyright (C) %d-2007 Free Software Foundation Europe e.V.\n"
 #define BYEAR "2007"       /* year for copyright messages in progs */
 
 In that directory, you should find a make.log, which has the full details
 of the compiles, links, and installs done for that package.
 
+Note, if you are building on a 64 bit machine, please know that
+the build for the depkgs-mingw32/scons puts the python scons libraries
+in depkgs-mingw32/scons/lib64 but when running scons it looks for the
+libs in depkgs-mingw32/scons/lib. So adding symlink from
+depkgs-mingw32/scons/lib64 to depkgs-mingw32/scons/lib will fix the
+problem.
 
 You need the header files from the Microsoft VSS SDK.  Unfortunately the SDK
 can only be downloaded and installed on a Windows system.  You can find it on
 
 process_scons()
 {
         get_source "${URL_SCONS}" "${DIR_SCONS}" "${MKD_SCONS}"
-        echo Installing scons
+        echo "Installing scons"
         if python setup.py install --prefix=${DEPPKG_DIR}/scons > make.log 2>&1
         then
                 :
         else
-                echo Make failed - Check `pwd`/make.log
+                echo "Make failed - Check `pwd`/make.log"
                 exit 1
         fi
 }
         mv nsis-2.17 ../nsis
         if get_source "${URL_NSIS_SRC}" "${DIR_NSIS_SRC}" "${MKD_NSIS_SRC}"
         then
-                echo Patching nsis
+                echo "Patching nsis"
                 >patch.log
                 do_patch nsis.patch
         fi
-        echo Building nsis
+        echo "Building nsis"
         if ../../scons/bin/scons SKIPSTUBS=all SKIPPLUGINS=all SKIPUTILS=all SKIPMISC=all \
                 PREFIX=${DEPPKG_DIR}/nsis PREFIX_BIN=${DEPPKG_DIR}/nsis/Bin \
                 PREFIX_CONF=${DEPPKG_DIR}/nsis PREFIX_DATA=${DEPPKG_DIR}/nsis \
         then
                 :
         else
-                echo Scons failed - Check `pwd`/make.log
+                echo "Scons failed - Check `pwd`/make.log"
                 exit 1
         fi
-        echo Installing nsis
+        echo "Installing nsis"
         cp -p build/release/makensis/makensis ../../nsis
 }
 
 {
         if get_source "${URL_MT}" "${DIR_MT}" "${MKD_MT}"
         then
-                echo Patching mt
+                echo "Patching mt"
                 >patch.log
                 do_patch mt.patch
         fi
-        echo Building mt
+        echo "Building mt"
         do_make Makefile PREFIX=${DEPPKG_DIR} all
         echo Installing mt
         do_make Makefile PREFIX=${DEPPKG_DIR} install
 
               Technical notes on version 2.1
 
 General:
+18Jun08
+kes  Add some additional locking in the cats directory in subroutines
+     that modify packet variables called from batch insert.
+kes  Rework how dcrs are allocated. new_dcr() can now be called
+     with an existing pointer, and it will simply clean it up.
+     This allows the reservation system to test various different
+     devices, and will permit easy device changes.
+kes  A bunch of changes all over to handle new new_dcr() calling
+     sequence.
+kes  Work more on the Volume management in the SD. Remember Volumes
+     for tape drives and for autochangers (even virtual disk changers).
+kes  When looking at the Volume list to reserve a drive, handle 
+     autochanger names correctly by interating through the changer 
+     devices.  Also call the Director to see if a Volume is suitable
+     for the current job.
+kes  Fix some bugs in bscan. Make sure all media records are written.
+     Make sure that valid JobMedia records are written for disk files.
+     Previously they were completely wrong.
+kes  Move source tar files for depkgs-mingw32 to www.bacula.org so
+     that the URLs don't change and so that the developers will all
+     work off the same copy. Rebuild from scrach.
+kes  Upgrade Win32 SQLite3 from 3.3.8 to 3.3.17.
 Release: 2.1.18 beta
 16Jun07
 kes  Fix seg fault in FD from incorrect digest size.