* it goes to zero, no one is using the associated
  * resource table, so free it.
  */
-static void reload_job_end_cb(JCR *jcr)
+static void reload_job_end_cb(JCR *jcr, void *ctx)
 {
-   if (jcr->reload_id == 0) {
-      return;                        /* nothing to do */
-   }
-   int i = jcr->reload_id - 1;
+   int reload_id = (int)ctx;
    Dmsg3(000, "reload job_end JobId=%d table=%d cnt=%d\n", jcr->JobId,
-      i, reload_table[i].job_count);
+      reload_id, reload_table[reload_id].job_count);
    lock_jcr_chain();
    LockRes();
-   if (--reload_table[i].job_count <= 0) {
-      free_saved_resources(i);
+   if (--reload_table[reload_id].job_count <= 0) {
+      free_saved_resources(reload_id);
    }
    UnlockRes();
    unlock_jcr_chain();
  *    reread our configuration file. 
  *
  * The algorithm used is as follows: we count how many jobs are
- *   running since the last reload and set those jobs to make a
- *   callback. Also, we set each job with the current reload table
- *   id. . The old config is saved with the reload table
+ *   running and mark the running jobs to make a callback on 
+ *   exiting. The old config is saved with the reload table
  *   id in a reload table. The new config file is read. Now, as
  *   each job exits, it calls back to the reload_job_end_cb(), which
  *   decrements the count of open jobs for the given reload table.
    static bool already_here = false;
    sigset_t set;       
    JCR *jcr;
-   int njobs = 0;
+   int njobs = 0;                    /* number of running jobs */
    int table, rtable;
 
    if (already_here) {
       goto bail_out;
    }
 
-   /*
-    * Hook all active jobs that are not already hooked (i.e.
-    *  reload_id == 0
-    */
-   foreach_jcr(jcr) {
-      if (jcr->reload_id == 0 && jcr->JobType != JT_SYSTEM) {
-        reload_table[table].job_count++;
-        jcr->reload_id = table + 1;
-        job_end_push(jcr, reload_job_end_cb);
-        njobs++;
-      }
-      free_locked_jcr(jcr);
-   }
    Dmsg1(000, "Reload_config njobs=%d\n", njobs);
    reload_table[table].res_table = save_config_resources();
    Dmsg1(000, "Saved old config in table %d\n", table);
         res_head[i] = res_tab[i];
       }
       table = rtable;                /* release new, bad, saved table below */
-      if (njobs != 0) {
-        foreach_jcr(jcr) {
-           if (jcr->reload_id == table) {
-              jcr->reload_id = 0;
-           }
-           free_locked_jcr(jcr);
+   } else {
+      /*
+       * Hook all active jobs so that they release this table 
+       */
+      foreach_jcr(jcr) {
+        if (jcr->JobType != JT_SYSTEM) {
+           reload_table[table].job_count++;
+           job_end_push(jcr, reload_job_end_cb, (void *)table);
+           njobs++;
         }
+        free_locked_jcr(jcr);
       }
-      njobs = 0;                     /* force bad tabel to be released below */
    }
 
    /* Reset globals */
 
       Jmsg1(jcr, M_FATAL, 0, _("Unable to init job cond variable: ERR=%s\n"), strerror(errstat));
       goto bail_out;
    }
+   jcr->term_wait_inited = true;
 
    /*
     * Open database
       free_pool_memory(jcr->client_uname);
       jcr->client_uname = NULL;
    }
-   pthread_cond_destroy(&jcr->term_wait);
+   if (jcr->term_wait_inited) {
+      pthread_cond_destroy(&jcr->term_wait);
+   }
+   jcr->job_end_push.destroy();
    Dmsg0(200, "End dird free_jcr\n");
 }
 
 
         jcr->FileIndex = file_index;    /* remember attribute file_index */
         decode_stat(attr, &statf, &LinkFIf);  /* decode file stat packet */
         do_SIG = NO_SIG;
-        jcr->fn_printed = FALSE;
+        jcr->fn_printed = false;
         pm_strcpy(&jcr->fname, fname);  /* move filename into JCR */
 
          Dmsg2(040, "dird<filed: stream=%d %s\n", stream, jcr->fname);
    /* Now find all the files that are missing -- i.e. all files in
     *  the database where the MarkedId != current JobId
     */
-   jcr->fn_printed = FALSE;
+   jcr->fn_printed = false;
    sprintf(buf, 
 "SELECT Path.Path,Filename.Name FROM File,Path,Filename "
 "WHERE File.JobId=%d "
    if (!jcr->fn_printed) {
       Jmsg(jcr, M_INFO, 0, "\n");
       Jmsg(jcr, M_INFO, 0, _("The following files are missing:\n"));
-      jcr->fn_printed = TRUE;
+      jcr->fn_printed = true;
    }
    Jmsg(jcr, M_INFO, 0, "      %s%s\n", row[0]?row[0]:"", row[1]?row[1]:"");
    return 0;
 
       return 0;
    }
    Dmsg0(120, "OK Authenticate\n");
-   jcr->authenticated = TRUE;
+   jcr->authenticated = true;
    return 1;
 }
 
 
    sendit("\n", 1, arg);               /* send separately */
    msg =  _("Terminated Jobs:\n"); 
    sendit(msg, strlen(msg), arg);
-   msg =  _(" JobId  Level   Files          Bytes Status   Finished        Name \n");
+   msg =  _(" JobId  Level     Files         Bytes  Status   Finished        Name \n");
    sendit(msg, strlen(msg), arg);
    msg = _("======================================================================\n"); 
    sendit(msg, strlen(msg), arg);
 
    JCR_free_HANDLER *daemon_free_jcr; /* Local free routine */
    dlist *msg_queue;                  /* Queued messages */
    alist job_end_push;                /* Job end pushed calls */
-   int reload_id;                     /* SIGHUP reload table id */
    bool dequeuing;                    /* dequeuing messages */
    POOLMEM *errmsg;                   /* edited error message */
    char Job[MAX_NAME_LENGTH];         /* Unique name of this Job */
    int JobType;                       /* backup, restore, verify ... */
    int JobLevel;                      /* Job level */
    int JobPriority;                   /* Job priority */
-   int authenticated;                 /* set when client authenticated */
    time_t sched_time;                 /* job schedule time, i.e. when it should start */
    time_t start_time;                 /* when job actually started */
    time_t run_time;                   /* used for computing speed */
    MSGS *jcr_msgs;                    /* Copy of message resource -- actually used */
    uint32_t ClientId;                 /* Client associated with Job */
    char *where;                       /* prefix to restore files to */
-   bool prefix_links;                 /* Prefix links with Where path */
-   bool gui;                          /* set if gui using console */
    int cached_pnl;                    /* cached path length */
    POOLMEM *cached_path;              /* cached path */
+   bool prefix_links;                 /* Prefix links with Where path */
+   bool gui;                          /* set if gui using console */
+   bool authenticated;                /* set when client authenticated */
 
    /* Daemon specific part of JCR */
    /* This should be empty in the library */
    FileId_t FileId;                   /* Last file id inserted */
    uint32_t FileIndex;                /* Last FileIndex processed */
    POOLMEM *fname;                    /* name to put into catalog */
-   int fn_printed;                    /* printed filename */
    POOLMEM *stime;                    /* start time for incremental/differential */
    JOB_DBR jr;                        /* Job DB record for current job */
    JOB_DBR *verify_jr;                /* Pointer to target job */
    POOLMEM *client_uname;             /* client uname */ 
    int replace;                       /* Replace option */
    int saveMaxConcurrentJobs;         /* save for restore jobs */
-   bool acquired_resource_locks;      /* set if resource locks acquired */
    int NumVols;                       /* Number of Volume used in pool */
    int reschedule_count;              /* Number of times rescheduled */
    bool spool_data;                   /* Spool data in SD */
+   bool acquired_resource_locks;      /* set if resource locks acquired */
+   bool term_wait_inited;             /* Set when cond var inited */
+   bool fn_printed;                   /* printed filename */
 #endif /* DIRECTOR_DAEMON */
 
 
 
 /*
  * Push a subroutine address into the job end callback stack
  */
-void job_end_push(JCR *jcr, void job_end_cb(JCR *jcr))
+void job_end_push(JCR *jcr, void job_end_cb(JCR *jcr,void *), void *ctx)
 {
-   jcr->job_end_push.prepend((void *)job_end_cb);
+   jcr->job_end_push.append((void *)job_end_cb);
+   jcr->job_end_push.append(ctx);
 }
 
 /* Pop each job_end subroutine and call it */
 static void job_end_pop(JCR *jcr)
 {
-   void (*job_end_cb)(JCR *jcr);
-   for (int i=0; i<jcr->job_end_push.size(); i++) {
-      job_end_cb = (void (*)(JCR *))jcr->job_end_push.get(i);
-      job_end_cb(jcr);
+   void (*job_end_cb)(JCR *jcr, void *ctx);
+   void *ctx;
+   for (int i=jcr->job_end_push.size()-1; i > 0; ) {
+      ctx = jcr->job_end_push.get(i--);
+      job_end_cb = (void (*)(JCR *,void *))jcr->job_end_push.get(i--);
+      job_end_cb(jcr, ctx);
    }
 }
 
 
 void read_last_jobs_list(int fd, uint64_t addr);
 uint64_t write_last_jobs_list(int fd, uint64_t addr);
 void write_state_file(char *dir, const char *progname, int port);
-void job_end_push(JCR *jcr, void job_end_cb(JCR *jcr));
+void job_end_push(JCR *jcr, void job_end_cb(JCR *jcr,void *), void *ctx);
 
 
 /* lex.c */
 
    btimer_t *tid = start_bsock_timer(fd, 60 * 5);
    if (cram_md5_auth(fd, jcr->sd_auth_key, ssl_need) &&
        cram_md5_get_auth(fd, jcr->sd_auth_key, ssl_need)) {
-      jcr->authenticated = TRUE;
+      jcr->authenticated = true;
    }
    stop_bsock_timer(tid);
    if (!jcr->authenticated) {
 
 static void statcmd();
 static void unfillcmd();
 static int flush_block(DEV_BLOCK *block, int dump);
-#ifdef xxx_needed
-static int record_cb(JCR *jcr, DEVICE *dev, DEV_BLOCK *block, DEV_RECORD *rec);
-#endif
 static int quickie_cb(JCR *jcr, DEVICE *dev, DEV_BLOCK *block, DEV_RECORD *rec);
 static bool compare_blocks(DEV_BLOCK *last_block, DEV_BLOCK *block);
 static int my_mount_next_read_volume(JCR *jcr, DEVICE *dev, DEV_BLOCK *block);
       ok = false;
    }
 
-
    Pmsg2(-1, _("\n\nDone filling tape%s. Now beginning re-read of %stape ...\n"),
       simple?"":"s", simple?"":"first ");
 
         force_close_dev(dev);
          get_cmd(_("Mount first tape. Press enter when ready: ")); 
       }
-   
       free_vol_list(jcr);
+      jcr->dcr = new_dcr(jcr, dev);
       set_volume_name("TestVolume1", 1);
       jcr->bsr = NULL;
       create_vol_list(jcr);
 
       Dmsg1(100, "Authentication failed Job %s\n", jcr->Job);
       Jmsg(jcr, M_FATAL, 0, _("Unable to authenticate File daemon\n"));
    } else {
-      jcr->authenticated = TRUE;
+      jcr->authenticated = true;
       Dmsg1(110, "OK Authentication Job %s\n", jcr->Job);
    }