it with the catalog database.
- Document Dan's new --with-dir-user, ... options.
-
For 1.33
+- Change "create_media_record in bscan to use Archive instead of Full.
- Implement RestoreJobRetention? Maybe better "JobRetention" in a Job,
which would take precidence over the Catalog "JobRetention".
- Implement Label Format in Add and Label console commands.
-- Possibly up network buffers to 65K.
-- Keep last 5 or 10 completed jobs and show them in a similar list.
-- Make a Running Jobs: output similar to current Scheduled Jobs:
+- Possibly up network buffers to 65K. Put on variable.
+- Put email tape request delays on one or more variables. User wants
+ to cancel the job after a certain time interval. Maximum Mount Wait?
+ Job, Client, Device, Pool, or Volume?
After 1.33:
+- Each DVD-RAM disk would be a volume, just like each tape is
+ a volume. It's a 4.7GB media with random access, but there's nothing about
+ it that I can see that makes it so different than a tape fromĀ bacula's
+ perspective. Why couldn't I back up to a bare floppy as a volume (ignoring
+ the media capacity?)
- Make dev->file and dev->block_num signed integers so that -1 can
- be an invalid value.
+ be an invalid value which happens with BSR.
- Create VolAddr for disk files in place of VolFile and VolBlock. This
is needed to properly specify ranges.
- Print bsmtp output to job report so that problems will be seen.
- Implement autochanger testing in btape "test" command.
- Implement lmark to list everyfile marked.
- Make mark/unmark report how many files marked/unmarked.
+- Keep last 5 or 10 completed jobs and show them in a similar list.
+- Make a Running Jobs: output similar to current Scheduled Jobs:
+
cp rescue/linux/format_floppy $RPM_BUILD_ROOT/etc/bacula/rescue/
cp rescue/linux/getdiskinfo $RPM_BUILD_ROOT/etc/bacula/rescue/
cp rescue/linux/make_rescue_disk $RPM_BUILD_ROOT/etc/bacula/rescue/
-cp rescue/linux/make_static_bacula $RPM_BUILD_ROOT/etc/bacula/rescue/
cp rescue/linux/restore_bacula $RPM_BUILD_ROOT/etc/bacula/rescue/
cp rescue/linux/restore_etc $RPM_BUILD_ROOT/etc/bacula/rescue/
cp rescue/linux/run_grub $RPM_BUILD_ROOT/etc/bacula/rescue/
%attr(0754,root,root) /etc/bacula/rescue/format_floppy
%attr(0754,root,root) /etc/bacula/rescue/getdiskinfo
%attr(0754,root,root) /etc/bacula/rescue/make_rescue_disk
-%attr(0754,root,root) /etc/bacula/rescue/make_static_bacula
%attr(0754,root,root) /etc/bacula/rescue/restore_bacula
%attr(0754,root,root) /etc/bacula/rescue/restore_etc
%attr(0754,root,root) /etc/bacula/rescue/run_grub
rm -rf /etc/bacula/rescue/diskinfo/*
%changelog
+* Tue Nov 25 2003 D. Scott Barninger <barninger at fairfieldcomputers.com>
+- removed make_static_bacula script from rescue package install
* Sun Nov 23 2003 D. Scott Barninger <barninger at fairfieldcomputers.com>
- Added define at top of file for depkgs version
- Added rescue sub-package
textdomain("bacula-dir");
init_msg(NULL, NULL); /* initialize message handler */
daemon_start_time = time(NULL);
- memset(&last_job, 0, sizeof(last_job));
while ((ch = getopt(argc, argv, "c:d:fg:r:stu:v?")) != -1) {
switch (ch) {
return 0;
}
write_bsr_file(ua, rx.bsr);
- bsendmsg(ua, _("\n%u file%s selected to restore.\n\n"), rx.selected_files,
+ bsendmsg(ua, _("\n%u file%s selected to be restored.\n\n"), rx.selected_files,
rx.selected_files==1?"":"s");
} else {
- bsendmsg(ua, _("No files selected to restore.\n"));
+ bsendmsg(ua, _("No files selected to be restored.\n"));
free_rx(&rx);
return 0;
}
extern time_t daemon_start_time;
extern struct s_last_job last_job;
-static void print_jobs_scheduled(UAContext *ua);
+static void list_scheduled_jobs(UAContext *ua);
+static void list_running_jobs(UAContext *ua);
+static void list_terminated_jobs(UAContext *ua);
static void do_storage_status(UAContext *ua, STORE *store);
static void do_client_status(UAContext *ua, CLIENT *client);
static void do_director_status(UAContext *ua, char *cmd);
static void do_director_status(UAContext *ua, char *cmd)
{
- JCR *jcr;
- int njobs = 0;
- char *msg;
- char dt[MAX_TIME_LENGTH], b1[30], b2[30];
- int pool_mem = FALSE;
+ char dt[MAX_TIME_LENGTH];
bsendmsg(ua, "%s Version: " VERSION " (" BDATE ") %s %s %s\n", my_name,
HOST_OS, DISTNAME, DISTVER);
bstrftime(dt, sizeof(dt), daemon_start_time);
bsendmsg(ua, _("Daemon started %s, %d Job%s run.\n"), dt, last_job.NumJobs,
last_job.NumJobs == 1 ? "" : "s");
- if (last_job.NumJobs > 0) {
- char termstat[50];
-
- bstrftime(dt, sizeof(dt), last_job.end_time);
- bsendmsg(ua, _("Last Job %s finished at %s\n"), last_job.Job, dt);
- jobstatus_to_ascii(last_job.JobStatus, termstat, sizeof(termstat));
-
- bsendmsg(ua, _(" Files=%s Bytes=%s Termination Status=%s\n"),
- edit_uint64_with_commas(last_job.JobFiles, b1),
- edit_uint64_with_commas(last_job.JobBytes, b2),
- termstat);
- }
- lock_jcr_chain();
- for (jcr=NULL; (jcr=get_next_jcr(jcr)); njobs++) {
- if (jcr->JobId == 0) { /* this is us */
- bstrftime(dt, sizeof(dt), jcr->start_time);
- bsendmsg(ua, _("Console connected at %s\n"), dt);
- free_locked_jcr(jcr);
- njobs--;
- continue;
- }
- switch (jcr->JobStatus) {
- case JS_Created:
- msg = _("is waiting execution");
- break;
- case JS_Running:
- msg = _("is running");
- break;
- case JS_Blocked:
- msg = _("is blocked");
- break;
- case JS_Terminated:
- msg = _("has terminated");
- break;
- case JS_ErrorTerminated:
- msg = _("has erred");
- break;
- case JS_Error:
- msg = _("has errors");
- break;
- case JS_FatalError:
- msg = _("has a fatal error");
- break;
- case JS_Differences:
- msg = _("has verify differences");
- break;
- case JS_Canceled:
- msg = _("has been canceled");
- break;
- case JS_WaitFD:
- msg = (char *) get_pool_memory(PM_FNAME);
- Mmsg(&msg, _("is waiting on Client %s"), jcr->client->hdr.name);
- pool_mem = TRUE;
- break;
- case JS_WaitSD:
- msg = (char *) get_pool_memory(PM_FNAME);
- Mmsg(&msg, _("is waiting on Storage %s"), jcr->store->hdr.name);
- pool_mem = TRUE;
- break;
- case JS_WaitStoreRes:
- msg = _("is waiting on max Storage jobs");
- break;
- case JS_WaitClientRes:
- msg = _("is waiting on max Client jobs");
- break;
- case JS_WaitJobRes:
- msg = _("is waiting on max Job jobs");
- break;
- case JS_WaitMaxJobs:
- msg = _("is waiting on max total jobs");
- break;
- case JS_WaitStartTime:
- msg = _("is waiting for its start time");
- break;
- case JS_WaitPriority:
- msg = _("is waiting for higher priority jobs to finish");
- break;
-
- default:
- msg = (char *) get_pool_memory(PM_FNAME);
- Mmsg(&msg, _("is in unknown state %c"), jcr->JobStatus);
- pool_mem = TRUE;
- break;
- }
- /*
- * Now report Storage daemon status code
- */
- switch (jcr->SDJobStatus) {
- case JS_WaitMount:
- if (pool_mem) {
- free_pool_memory(msg);
- pool_mem = FALSE;
- }
- msg = _("is waiting for a mount request");
- break;
- case JS_WaitMedia:
- if (pool_mem) {
- free_pool_memory(msg);
- pool_mem = FALSE;
- }
- msg = _("is waiting for an appendable Volume");
- break;
- case JS_WaitFD:
- if (!pool_mem) {
- msg = (char *) get_pool_memory(PM_FNAME);
- pool_mem = TRUE;
- }
- Mmsg(&msg, _("is waiting for Client %s to connect to Storage %s"),
- jcr->client->hdr.name, jcr->store->hdr.name);
- break;
- }
- bsendmsg(ua, _("JobId %d Job %s %s.\n"), jcr->JobId, jcr->Job, msg);
- if (pool_mem) {
- free_pool_memory(msg);
- pool_mem = FALSE;
- }
- free_locked_jcr(jcr);
- }
- unlock_jcr_chain();
-
- if (njobs == 0) {
- bsendmsg(ua, _("No jobs are running.\n"));
- }
- print_jobs_scheduled(ua);
+ /*
+ * List scheduled Jobs
+ */
+ list_scheduled_jobs(ua);
+
+ /*
+ * List running jobs
+ */
+ list_running_jobs(ua);
+
+ /*
+ * List terminated jobs
+ */
+ list_terminated_jobs(ua);
bsendmsg(ua, "====\n");
}
}
/*
- * Find all jobs to be run this hour
- * and the next hour.
+ * Find all jobs to be run in roughly the
+ * next 24 hours.
*/
-static void print_jobs_scheduled(UAContext *ua)
+static void list_scheduled_jobs(UAContext *ua)
{
time_t runtime;
RUN *run;
JOB *job;
+ int level, num_jobs = 0;
bool hdr_printed = false;
- int level;
Dmsg0(200, "enter find_runs()\n");
level = run->level;
}
if (!hdr_printed) {
- hdr_printed = true;
prt_runhdr(ua);
+ hdr_printed = true;
}
prt_runtime(ua, job, level, runtime, run->pool);
+ num_jobs++;
}
} /* end for loop over resources */
UnlockRes();
+ if (num_jobs == 0) {
+ bsendmsg(ua, _("No Scheduled Jobs.\n"));
+ } else {
+ bsendmsg(ua, "\n");
+ }
Dmsg0(200, "Leave find_runs()\n");
}
+
+static void list_running_jobs(UAContext *ua)
+{
+ JCR *jcr;
+ int njobs = 0;
+ char *msg;
+ char dt[MAX_TIME_LENGTH];
+ char level[10];
+ bool pool_mem = false;
+
+ lock_jcr_chain();
+ for (jcr=NULL; (jcr=get_next_jcr(jcr)); njobs++) {
+ if (jcr->JobId == 0) { /* this is us */
+ bstrftime(dt, sizeof(dt), jcr->start_time);
+ bsendmsg(ua, _("Console connected at %s\n"), dt);
+ njobs--;
+ }
+ free_locked_jcr(jcr);
+ }
+ if (njobs == 0) {
+ unlock_jcr_chain();
+ bsendmsg(ua, _("No Running Jobs.\n"));
+ return;
+ }
+ njobs = 0;
+ bsendmsg(ua, _("\nRunning Jobs:\n"));
+ bsendmsg(ua, _("Level JobId Job Status\n"));
+ bsendmsg(ua, _("====================================================================\n"));
+ for (jcr=NULL; (jcr=get_next_jcr(jcr)); njobs++) {
+ if (jcr->JobId == 0) { /* this is us */
+ njobs--;
+ free_locked_jcr(jcr);
+ continue;
+ }
+ switch (jcr->JobStatus) {
+ case JS_Created:
+ msg = _("is waiting execution");
+ break;
+ case JS_Running:
+ msg = _("is running");
+ break;
+ case JS_Blocked:
+ msg = _("is blocked");
+ break;
+ case JS_Terminated:
+ msg = _("has terminated");
+ break;
+ case JS_ErrorTerminated:
+ msg = _("has erred");
+ break;
+ case JS_Error:
+ msg = _("has errors");
+ break;
+ case JS_FatalError:
+ msg = _("has a fatal error");
+ break;
+ case JS_Differences:
+ msg = _("has verify differences");
+ break;
+ case JS_Canceled:
+ msg = _("has been canceled");
+ break;
+ case JS_WaitFD:
+ msg = (char *) get_pool_memory(PM_FNAME);
+ Mmsg(&msg, _("is waiting on Client %s"), jcr->client->hdr.name);
+ pool_mem = true;
+ break;
+ case JS_WaitSD:
+ msg = (char *) get_pool_memory(PM_FNAME);
+ Mmsg(&msg, _("is waiting on Storage %s"), jcr->store->hdr.name);
+ pool_mem = true;
+ break;
+ case JS_WaitStoreRes:
+ msg = _("is waiting on max Storage jobs");
+ break;
+ case JS_WaitClientRes:
+ msg = _("is waiting on max Client jobs");
+ break;
+ case JS_WaitJobRes:
+ msg = _("is waiting on max Job jobs");
+ break;
+ case JS_WaitMaxJobs:
+ msg = _("is waiting on max total jobs");
+ break;
+ case JS_WaitStartTime:
+ msg = _("is waiting for its start time");
+ break;
+ case JS_WaitPriority:
+ msg = _("is waiting for higher priority jobs to finish");
+ break;
+
+ default:
+ msg = (char *) get_pool_memory(PM_FNAME);
+ Mmsg(&msg, _("is in unknown state %c"), jcr->JobStatus);
+ pool_mem = true;
+ break;
+ }
+ /*
+ * Now report Storage daemon status code
+ */
+ switch (jcr->SDJobStatus) {
+ case JS_WaitMount:
+ if (pool_mem) {
+ free_pool_memory(msg);
+ pool_mem = false;
+ }
+ msg = _("is waiting for a mount request");
+ break;
+ case JS_WaitMedia:
+ if (pool_mem) {
+ free_pool_memory(msg);
+ pool_mem = false;
+ }
+ msg = _("is waiting for an appendable Volume");
+ break;
+ case JS_WaitFD:
+ if (!pool_mem) {
+ msg = (char *) get_pool_memory(PM_FNAME);
+ pool_mem = true;
+ }
+ Mmsg(&msg, _("is waiting for Client %s to connect to Storage %s"),
+ jcr->client->hdr.name, jcr->store->hdr.name);
+ break;
+ }
+ switch (jcr->JobType) {
+ case JT_ADMIN:
+ case JT_RESTORE:
+ bstrncpy(level, " ", sizeof(level));
+ break;
+ default:
+ bstrncpy(level, level_to_str(jcr->JobLevel), sizeof(level));
+ level[4] = 0;
+ break;
+ }
+
+ bsendmsg(ua, _("%-4s %6d %-20s %s\n"),
+ level,
+ jcr->JobId,
+ jcr->Job,
+ msg);
+
+ if (pool_mem) {
+ free_pool_memory(msg);
+ pool_mem = false;
+ }
+ free_locked_jcr(jcr);
+ }
+ unlock_jcr_chain();
+
+ bsendmsg(ua, "\n");
+}
+
+static void list_terminated_jobs(UAContext *ua)
+{
+ char dt[MAX_TIME_LENGTH], b1[30], b2[30];
+ char level[10];
+
+ if (last_job.NumJobs == 0) {
+ bsendmsg(ua, _("No Terminated Jobs.\n"));
+ return;
+ }
+ lock_last_jobs_list();
+ struct s_last_job *je;
+ bsendmsg(ua, _("\nTerminated Jobs:\n"));
+ bsendmsg(ua, _("Level Files Bytes Status Finished Name \n"));
+ bsendmsg(ua, _("====================================================================\n"));
+ for (je=NULL; (je=(s_last_job *)last_jobs->next(je)); ) {
+ char JobName[MAX_NAME_LENGTH];
+ char *termstat;
+
+ bstrftime(dt, sizeof(dt), je->end_time);
+ strcpy(dt+7, dt+9); /* cut century */
+ switch (je->JobType) {
+ case JT_ADMIN:
+ case JT_RESTORE:
+ bstrncpy(level, " ", sizeof(level));
+ break;
+ default:
+ bstrncpy(level, level_to_str(je->JobLevel), sizeof(level));
+ level[4] = 0;
+ break;
+ }
+ switch (je->JobStatus) {
+ case JS_Created:
+ termstat = "Created";
+ break;
+ case JS_FatalError:
+ case JS_ErrorTerminated:
+ termstat = "Error";
+ break;
+ case JS_Differences:
+ termstat = "Diffs";
+ break;
+ case JS_Canceled:
+ termstat = "Cancel";
+ break;
+ case JS_Terminated:
+ termstat = "OK";
+ break;
+ default:
+ termstat = "Other";
+ break;
+ }
+ bstrncpy(JobName, je->Job, sizeof(JobName));
+ /* There are three periods after the Job name */
+ char *p;
+ for (int i=0; i<3; i++) {
+ if ((p=strrchr(JobName, '.')) != NULL) {
+ *p = 0;
+ }
+ }
+ bsendmsg(ua, _("%-4s %8s %12s %-7s %-8s %s\n"),
+ level,
+ edit_uint64_with_commas(je->JobFiles, b1),
+ edit_uint64_with_commas(je->JobBytes, b2),
+ termstat,
+ dt, JobName);
+ }
+ bsendmsg(ua, "\n");
+ unlock_last_jobs_list();
+}
{ N_("help"), helpcmd, _("print help")},
{ N_("lsmark"), lsmark, _("list the marked files")},
{ N_("ls"), lscmd, _("list current directory")},
- { N_("mark"), markcmd, _("mark file for restoration")},
+ { N_("mark"), markcmd, _("mark file to be restored")},
{ N_("pwd"), pwdcmd, _("print current working directory")},
- { N_("unmark"), unmarkcmd, _("unmark file for restoration")},
+ { N_("unmark"), unmarkcmd, _("unmark file to be restored")},
{ N_("?"), helpcmd, _("print help")},
};
#define comsize (sizeof(commands)/sizeof(struct cmdstruct))
decode_stat(fdbr.LStat, &statp, &LinkFI); /* decode stat pkt */
/*
* If we point to a hard linked file, traverse the tree to
- * find that file, and mark it for restoration as well. It
+ * find that file, and mark it to be restored as well. It
* must have the Link we just obtained and the same JobId.
*/
if (LinkFI) {
}
}
}
- bsendmsg(ua, "%d total files. %d marked for restoration.\n", total, num_extract);
+ bsendmsg(ua, "%d total files. %d marked to be restored.\n", total, num_extract);
return 1;
}
}
}
}
- bsendmsg(ua, "%d total files; %d marked for restoration; %s bytes.\n",
+ bsendmsg(ua, "%d total files; %d marked to be restored; %s bytes.\n",
total, num_extract, edit_uint64_with_commas(total_bytes, ec1));
return 1;
}
init_msg(NULL, NULL);
daemon_start_time = time(NULL);
- memset(&last_job, 0, sizeof(last_job));
-
while ((ch = getopt(argc, argv, "c:d:fg:istu:v?")) != -1) {
switch (ch) {
case 'c': /* configuration file */
extern struct s_last_job last_job;
extern time_t daemon_start_time;
+/* Forward referenced functions */
+static void list_terminated_jobs(void *arg);
+static void sendit(char *msg, int len, void *arg);
+static char *level_to_str(int level);
+
+
#ifdef HAVE_CYGWIN
static int privs = 0;
#endif
last_job.NumJobs == 1 ? "" : "s");
sendit(msg, len, arg);
#ifdef HAVE_CYGWIN
- if (!privs) {
- privs = enable_backup_privileges(NULL, 1);
+ if (debug_level > 0) {
+ if (!privs) {
+ privs = enable_backup_privileges(NULL, 1);
+ }
+ len = Mmsg(&msg,
+ _("Priv 0x%x APIs=%sOPT,%sATP,%sLPV,%sGFAE,%sBR,%sBW,%sSPSP\n"), privs,
+ p_OpenProcessToken?"":"!",
+ p_AdjustTokenPrivileges?"":"!",
+ p_LookupPrivilegeValue?"":"!",
+ p_GetFileAttributesEx?"":"!",
+ p_BackupRead?"":"!",
+ p_BackupWrite?"":"!",
+ p_SetProcessShutdownParameters?"":"!");
+ sendit(msg, len, arg);
}
- len = Mmsg(&msg,
- _("Priv 0x%x APIs=%sOPT,%sATP,%sLPV,%sGFAE,%sBR,%sBW,%sSPSP\n"), privs,
- p_OpenProcessToken?"":"!",
- p_AdjustTokenPrivileges?"":"!",
- p_LookupPrivilegeValue?"":"!",
- p_GetFileAttributesEx?"":"!",
- p_BackupRead?"":"!",
- p_BackupWrite?"":"!",
- p_SetProcessShutdownParameters?"":"!");
- sendit(msg, len, arg);
#endif
- if (last_job.NumJobs > 0) {
+ list_terminated_jobs(arg);
+
+#ifdef xxx
char termstat[30];
+ struct s_last_job *je;
+ lock_last_jobs_list();
+ for (je=NULL; (je=(s_last_job *)last_jobs->next(je)); ) {
+ bstrftime(dt, sizeof(dt), je->end_time);
+ len = Mmsg(&msg, _("Last Job %s finished at %s\n"), je->Job, dt);
+ sendit(msg, len, arg);
- bstrftime(dt, sizeof(dt), last_job.end_time);
- len = Mmsg(&msg, _("Last Job %s finished at %s\n"), last_job.Job, dt);
- sendit(msg, len, arg);
+ jobstatus_to_ascii(je->JobStatus, termstat, sizeof(termstat));
+ len = Mmsg(&msg, _(" Files=%s Bytes=%s Termination Status=%s\n"),
+ edit_uint64_with_commas(je->JobFiles, b1),
+ edit_uint64_with_commas(je->JobBytes, b2),
+ termstat);
+ sendit(msg, len, arg);
+ }
+ unlock_last_jobs_list();
+#endif
- jobstatus_to_ascii(last_job.JobStatus, termstat, sizeof(termstat));
- len = Mmsg(&msg, _(" Files=%s Bytes=%s Termination Status=%s\n"),
- edit_uint64_with_commas(last_job.JobFiles, b1),
- edit_uint64_with_commas(last_job.JobBytes, b2),
- termstat);
- sendit(msg, len, arg);
- }
+ /*
+ * List running jobs
+ */
Dmsg0(200, "Begin status jcr loop.\n");
lock_jcr_chain();
for (njcr=NULL; (njcr=get_next_jcr(njcr)); ) {
free_pool_memory(msg);
}
+static void list_terminated_jobs(void *arg)
+{
+ char dt[MAX_TIME_LENGTH], b1[30], b2[30];
+ char level[10];
+ struct s_last_job *je;
+ char *msg;
+
+ if (last_job.NumJobs == 0) {
+ msg = _("No Terminated Jobs.\n");
+ sendit(msg, strlen(msg), arg);
+ return;
+ }
+ lock_last_jobs_list();
+ msg = _("\nTerminated Jobs:\n");
+ sendit(msg, strlen(msg), arg);
+ msg = _("Level Files Bytes Status Finished Name \n");
+ sendit(msg, strlen(msg), arg);
+ msg = _("====================================================================\n");
+ sendit(msg, strlen(msg), arg);
+ for (je=NULL; (je=(s_last_job *)last_jobs->next(je)); ) {
+ char JobName[MAX_NAME_LENGTH];
+ char *termstat;
+ char buf[1000];
+
+ bstrftime(dt, sizeof(dt), je->end_time);
+ strcpy(dt+7, dt+9); /* cut century */
+ switch (je->JobType) {
+ case JT_ADMIN:
+ case JT_RESTORE:
+ bstrncpy(level, " ", sizeof(level));
+ break;
+ default:
+ bstrncpy(level, level_to_str(je->JobLevel), sizeof(level));
+ level[4] = 0;
+ break;
+ }
+ switch (je->JobStatus) {
+ case JS_Created:
+ termstat = "Created";
+ break;
+ case JS_FatalError:
+ case JS_ErrorTerminated:
+ termstat = "Error";
+ break;
+ case JS_Differences:
+ termstat = "Diffs";
+ break;
+ case JS_Canceled:
+ termstat = "Cancel";
+ break;
+ case JS_Terminated:
+ termstat = "OK";
+ break;
+ default:
+ termstat = "Other";
+ break;
+ }
+ bstrncpy(JobName, je->Job, sizeof(JobName));
+ /* There are three periods after the Job name */
+ char *p;
+ for (int i=0; i<3; i++) {
+ if ((p=strrchr(JobName, '.')) != NULL) {
+ *p = 0;
+ }
+ }
+ bsnprintf(buf, sizeof(buf), _("%-4s %8s %12s %-7s %-8s %s\n"),
+ level,
+ edit_uint64_with_commas(je->JobFiles, b1),
+ edit_uint64_with_commas(je->JobBytes, b2),
+ termstat,
+ dt, JobName);
+ sendit(buf, strlen(buf), arg);
+ }
+ sendit("\n", 1, arg);
+ unlock_last_jobs_list();
+}
+
+
/*
* Send to Director
*/
}
+/*
+ * Convert Job Level into a string
+ */
+static char *level_to_str(int level)
+{
+ char *str;
+
+ switch (level) {
+ case L_BASE:
+ str = _("Base");
+ case L_FULL:
+ str = _("Full");
+ break;
+ case L_INCREMENTAL:
+ str = _("Incremental");
+ break;
+ case L_DIFFERENTIAL:
+ str = _("Differential");
+ break;
+ case L_SINCE:
+ str = _("Since");
+ break;
+ case L_VERIFY_CATALOG:
+ str = _("Verify Catalog");
+ break;
+ case L_VERIFY_INIT:
+ str = _("Init Catalog");
+ break;
+ case L_VERIFY_VOLUME_TO_CATALOG:
+ str = _("Volume to Catalog");
+ break;
+ case L_VERIFY_DISK_TO_CATALOG:
+ str = _("Disk to Catalog");
+ break;
+ case L_VERIFY_DATA:
+ str = _("Data");
+ break;
+ case L_NONE:
+ str = " ";
+ break;
+ default:
+ str = _("Unknown Job Level");
+ break;
+ }
+ return str;
+}
+
+
#ifdef HAVE_CYGWIN
#include <windows.h>
* info on the last job run.
*/
struct s_last_job {
+ dlink link;
int NumJobs;
int JobType;
int JobStatus;
+ int JobLevel;
uint32_t JobId;
uint32_t VolSessionId;
uint32_t VolSessionTime;
char Job[MAX_NAME_LENGTH];
};
-extern struct s_last_job last_job;
+extern struct s_last_job last_job;
+extern dlist *last_jobs;
/* The following routines are found in lib/jcr.c */
extern void timeout_handler(int sig);
-struct s_last_job last_job; /* last job run by this daemon */
+struct s_last_job last_job; /* last job run by this daemon */
+dlist *last_jobs;
+static int num_last_jobs = 0;
+#define MAX_LAST_JOBS 10
static JCR *jobs = NULL; /* pointer to JCR chain */
static pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
+void init_last_jobs_list()
+{
+ struct s_last_job *job_entry;
+ last_jobs = new dlist(job_entry, &job_entry->link);
+ memset(&last_job, 0, sizeof(last_job));
+}
+
+void term_last_jobs_list()
+{
+ for (void *je=NULL; (je=last_jobs->next(je)); ) {
+ free(je);
+ }
+ delete last_jobs;
+}
+
+void lock_last_jobs_list()
+{
+ P(mutex);
+}
+
+void unlock_last_jobs_list()
+{
+ V(mutex);
+}
+
/*
* Create a Job Control Record and link it into JCR chain
* Returns newly allocated JCR
pthread_mutex_init(&(jcr->mutex), NULL);
jcr->JobStatus = JS_Created; /* ready to run */
jcr->VolumeName = get_pool_memory(PM_FNAME);
- mp_chr(jcr->VolumeName)[0] = 0;
+ jcr->VolumeName[0] = 0;
jcr->errmsg = get_pool_memory(PM_MESSAGE);
- mp_chr(jcr->errmsg)[0] = 0;
+ jcr->errmsg[0] = 0;
strcpy(jcr->Job, "*Console*"); /* default */
sigtimer.sa_flags = 0;
last_job.JobFiles = jcr->JobFiles;
last_job.JobBytes = jcr->JobBytes;
last_job.JobStatus = jcr->JobStatus;
+ last_job.JobLevel = jcr->JobLevel;
last_job.start_time = jcr->start_time;
last_job.end_time = time(NULL);
break;
void free_jcr(JCR *jcr)
{
+
Dmsg1(200, "Enter free_jcr 0x%x\n", jcr);
#endif
+ struct s_last_job *je;
P(mutex);
jcr->use_count--; /* decrement use count */
free_common_jcr(jcr);
P(mutex);
+ /* Keep list of last jobs, but not Console where JobId==0 */
+ if (last_job.JobId > 0) {
+ je = (struct s_last_job *)malloc(sizeof(struct s_last_job));
+ memcpy((char *)je, (char *)&last_job, sizeof(last_job));
+ last_jobs->append(je);
+ if (++num_last_jobs > MAX_LAST_JOBS) {
+ last_jobs->remove(last_jobs->first());
+ num_last_jobs--;
+ }
+ }
close_msg(NULL); /* flush any daemon messages */
V(mutex);
Dmsg0(200, "Exit free_jcr\n");
DEST *d, *dnew, *temp_chain = NULL;
int i, fd;
+ if (jcr == NULL && msg == NULL) {
+ init_last_jobs_list();
+ }
+
/*
* Make sure we have fd's 0, 1, 2 open
* If we don't do this one of our sockets may open
fclose(trace_fd);
trace_fd = NULL;
}
+ term_last_jobs_list();
}
int is_a_number (const char *num);
int is_an_integer (const char *n);
+/* jcr.c (most definitions are in src/jcr.h) */
+void init_last_jobs_list();
+void term_last_jobs_list();
+void lock_last_jobs_list();
+void unlock_last_jobs_list();
+
+
/* lex.c */
LEX * lex_close_file (LEX *lf);
LEX * lex_open_file (LEX *lf, char *fname, LEX_ERROR_HANDLER *scan_error);
int i;
if (device_is_unmounted(dev)) {
- Jmsg(jcr, M_WARNING, 0, _("device is BLOCKED due to user unmount.\n"));
+ Jmsg(jcr, M_WARNING, 0, _("device %s is BLOCKED due to user unmount.\n"),
+ dev_name(dev));
}
lock_device(dev);
block_device(dev, BST_DOING_ACQUIRE);
DEVICE *rtn_dev = NULL;
if (device_is_unmounted(dev)) {
- Jmsg(jcr, M_WARNING, 0, _("device is BLOCKED due to user unmount.\n"));
+ Jmsg(jcr, M_WARNING, 0, _("device %s is BLOCKED due to user unmount.\n"),
+ dev_name(dev));
}
lock_device(dev);
block_device(dev, BST_DOING_ACQUIRE);
/* Forward referenced functions */
static void send_blocked_status(JCR *jcr, DEVICE *dev);
+static void list_terminated_jobs(void *arg);
+static void sendit(char *msg, int len, void *arg);
+static char *level_to_str(int level);
/*
bstrftime(dt, sizeof(dt), daemon_start_time);
bnet_fsend(user, _("Daemon started %s, %d Job%s run.\n"), dt, last_job.NumJobs,
last_job.NumJobs == 1 ? "" : "s");
- if (last_job.NumJobs > 0) {
+
+ /*
+ * List terminated jobs
+ */
+ list_terminated_jobs(user);
+#ifdef xxx
char termstat[30];
bstrftime(dt, sizeof(dt), last_job.end_time);
edit_uint64_with_commas(last_job.JobFiles, b1),
edit_uint64_with_commas(last_job.JobBytes, b2),
termstat);
- }
+#endif
+ /*
+ * List devices
+ */
LockRes();
for (device=NULL; (device=(DEVRES *)GetNextRes(R_DEVICE, (RES *)device)); ) {
for (dev=device->dev; dev; dev=dev->next) {
bnet_fsend(user, _("No jobs running.\n"));
}
-#ifdef full_status
+#ifdef xfull_status
bnet_fsend(user, "\n\n");
dump_resource(R_DEVICE, resources[R_DEVICE-r_first].res_head, sendit, user);
#endif
}
}
+
+static void list_terminated_jobs(void *arg)
+{
+ char dt[MAX_TIME_LENGTH], b1[30], b2[30];
+ char level[10];
+ struct s_last_job *je;
+ char *msg;
+
+ if (last_job.NumJobs == 0) {
+ msg = _("No Terminated Jobs.\n");
+ sendit(msg, strlen(msg), arg);
+ return;
+ }
+ lock_last_jobs_list();
+ msg = _("\nTerminated Jobs:\n");
+ sendit(msg, strlen(msg), arg);
+ msg = _("Level Files Bytes Status Finished Name \n");
+ sendit(msg, strlen(msg), arg);
+ msg = _("====================================================================\n");
+ sendit(msg, strlen(msg), arg);
+ for (je=NULL; (je=(s_last_job *)last_jobs->next(je)); ) {
+ char JobName[MAX_NAME_LENGTH];
+ char *termstat;
+ char buf[1000];
+
+ bstrftime(dt, sizeof(dt), je->end_time);
+ strcpy(dt+7, dt+9); /* cut century */
+ switch (je->JobType) {
+ case JT_ADMIN:
+ case JT_RESTORE:
+ bstrncpy(level, " ", sizeof(level));
+ break;
+ default:
+ bstrncpy(level, level_to_str(je->JobLevel), sizeof(level));
+ level[4] = 0;
+ break;
+ }
+ switch (je->JobStatus) {
+ case JS_Created:
+ termstat = "Created";
+ break;
+ case JS_FatalError:
+ case JS_ErrorTerminated:
+ termstat = "Error";
+ break;
+ case JS_Differences:
+ termstat = "Diffs";
+ break;
+ case JS_Canceled:
+ termstat = "Cancel";
+ break;
+ case JS_Terminated:
+ termstat = "OK";
+ break;
+ default:
+ termstat = "Other";
+ break;
+ }
+ bstrncpy(JobName, je->Job, sizeof(JobName));
+ /* There are three periods after the Job name */
+ char *p;
+ for (int i=0; i<3; i++) {
+ if ((p=strrchr(JobName, '.')) != NULL) {
+ *p = 0;
+ }
+ }
+ bsnprintf(buf, sizeof(buf), _("%-4s %8s %12s %-7s %-8s %s\n"),
+ level,
+ edit_uint64_with_commas(je->JobFiles, b1),
+ edit_uint64_with_commas(je->JobBytes, b2),
+ termstat,
+ dt, JobName);
+ sendit(buf, strlen(buf), arg);
+ }
+ sendit("\n", 1, arg);
+ unlock_last_jobs_list();
+}
+
+/*
+ * Convert Job Level into a string
+ */
+static char *level_to_str(int level)
+{
+ char *str;
+
+ switch (level) {
+ case L_BASE:
+ str = _("Base");
+ case L_FULL:
+ str = _("Full");
+ break;
+ case L_INCREMENTAL:
+ str = _("Incremental");
+ break;
+ case L_DIFFERENTIAL:
+ str = _("Differential");
+ break;
+ case L_SINCE:
+ str = _("Since");
+ break;
+ case L_VERIFY_CATALOG:
+ str = _("Verify Catalog");
+ break;
+ case L_VERIFY_INIT:
+ str = _("Init Catalog");
+ break;
+ case L_VERIFY_VOLUME_TO_CATALOG:
+ str = _("Volume to Catalog");
+ break;
+ case L_VERIFY_DISK_TO_CATALOG:
+ str = _("Disk to Catalog");
+ break;
+ case L_VERIFY_DATA:
+ str = _("Data");
+ break;
+ case L_NONE:
+ str = " ";
+ break;
+ default:
+ str = _("Unknown Job Level");
+ break;
+ }
+ return str;
+}
+
+/*
+ * Send to Director
+ */
+static void sendit(char *msg, int len, void *arg)
+{
+ BSOCK *user = (BSOCK *)arg;
+
+ memcpy(user->msg, msg, len+1);
+ user->msglen = len+1;
+ bnet_send(user);
+}
textdomain("bacula-sd");
init_msg(NULL, NULL);
daemon_start_time = time(NULL);
- memset(&last_job, 0, sizeof(last_job));
/* Sanity checks */
if (TAPE_BSIZE % DEV_BSIZE != 0 || TAPE_BSIZE / DEV_BSIZE == 0) {
{"storage", store_items, R_STORAGE, NULL},
{"device", dev_items, R_DEVICE, NULL},
{"messages", msgs_items, R_MSGS, NULL},
- {NULL, NULL, 0, NULL}
+ {NULL, NULL, 0, NULL}
};
return;
}
sendit(sock, "dump_resource type=%d\n", type);
- if (type < 0) { /* no recursion */
+ if (type < 0) { /* no recursion */
type = - type;
recurse = 0;
}
switch (type) {
- case R_DIRECTOR:
- sendit(sock, "Director: name=%s\n", res->res_dir.hdr.name);
- break;
- case R_STORAGE:
- sendit(sock, "Storage: name=%s SDaddr=%s SDport=%d SDDport=%d HB=%s\n",
- res->res_store.hdr.name, NPRT(res->res_store.SDaddr),
- res->res_store.SDport, res->res_store.SDDport,
- edit_utime(res->res_store.heartbeat_interval, buf));
- break;
- case R_DEVICE:
- sendit(sock, "Device: name=%s MediaType=%s Device=%s\n",
- res->res_dev.hdr.name,
- res->res_dev.media_type, res->res_dev.device_name);
- sendit(sock, " rew_wait=%d min_bs=%d max_bs=%d\n",
- res->res_dev.max_rewind_wait, res->res_dev.min_block_size,
- res->res_dev.max_block_size);
- sendit(sock, " max_jobs=%d max_files=%" lld " max_size=%" lld "\n",
- res->res_dev.max_volume_jobs, res->res_dev.max_volume_files,
- res->res_dev.max_volume_size);
- sendit(sock, " max_file_size=%" lld " capacity=%" lld "\n",
- res->res_dev.max_file_size, res->res_dev.volume_capacity);
- strcpy(buf, " ");
- if (res->res_dev.cap_bits & CAP_EOF) {
- strcat(buf, "CAP_EOF ");
- }
- if (res->res_dev.cap_bits & CAP_BSR) {
- strcat(buf, "CAP_BSR ");
- }
- if (res->res_dev.cap_bits & CAP_BSF) {
- strcat(buf, "CAP_BSF ");
- }
- if (res->res_dev.cap_bits & CAP_FSR) {
- strcat(buf, "CAP_FSR ");
- }
- if (res->res_dev.cap_bits & CAP_FSF) {
- strcat(buf, "CAP_FSF ");
- }
- if (res->res_dev.cap_bits & CAP_EOM) {
- strcat(buf, "CAP_EOM ");
- }
- if (res->res_dev.cap_bits & CAP_REM) {
- strcat(buf, "CAP_REM ");
- }
- if (res->res_dev.cap_bits & CAP_RACCESS) {
- strcat(buf, "CAP_RACCESS ");
- }
- if (res->res_dev.cap_bits & CAP_AUTOMOUNT) {
- strcat(buf, "CAP_AUTOMOUNT ");
- }
- if (res->res_dev.cap_bits & CAP_LABEL) {
- strcat(buf, "CAP_LABEL ");
- }
- if (res->res_dev.cap_bits & CAP_ANONVOLS) {
- strcat(buf, "CAP_ANONVOLS ");
- }
- if (res->res_dev.cap_bits & CAP_ALWAYSOPEN) {
- strcat(buf, "CAP_ALWAYSOPEN ");
- }
- strcat(buf, "\n");
- sendit(sock, buf);
- break;
- case R_MSGS:
- sendit(sock, "Messages: name=%s\n", res->res_msgs.hdr.name);
- if (res->res_msgs.mail_cmd)
- sendit(sock, " mailcmd=%s\n", res->res_msgs.mail_cmd);
- if (res->res_msgs.operator_cmd)
- sendit(sock, " opcmd=%s\n", res->res_msgs.operator_cmd);
- break;
- default:
- sendit(sock, _("Warning: unknown resource type %d\n"), type);
- break;
+ case R_DIRECTOR:
+ sendit(sock, "Director: name=%s\n", res->res_dir.hdr.name);
+ break;
+ case R_STORAGE:
+ sendit(sock, "Storage: name=%s SDaddr=%s SDport=%d SDDport=%d HB=%s\n",
+ res->res_store.hdr.name, NPRT(res->res_store.SDaddr),
+ res->res_store.SDport, res->res_store.SDDport,
+ edit_utime(res->res_store.heartbeat_interval, buf));
+ break;
+ case R_DEVICE:
+ sendit(sock, "Device: name=%s MediaType=%s Device=%s\n",
+ res->res_dev.hdr.name,
+ res->res_dev.media_type, res->res_dev.device_name);
+ sendit(sock, " rew_wait=%d min_bs=%d max_bs=%d\n",
+ res->res_dev.max_rewind_wait, res->res_dev.min_block_size,
+ res->res_dev.max_block_size);
+ sendit(sock, " max_jobs=%d max_files=%" lld " max_size=%" lld "\n",
+ res->res_dev.max_volume_jobs, res->res_dev.max_volume_files,
+ res->res_dev.max_volume_size);
+ sendit(sock, " max_file_size=%" lld " capacity=%" lld "\n",
+ res->res_dev.max_file_size, res->res_dev.volume_capacity);
+ strcpy(buf, " ");
+ if (res->res_dev.cap_bits & CAP_EOF) {
+ bstrncat(buf, "CAP_EOF ", sizeof(buf));
+ }
+ if (res->res_dev.cap_bits & CAP_BSR) {
+ bstrncat(buf, "CAP_BSR ", sizeof(buf));
+ }
+ if (res->res_dev.cap_bits & CAP_BSF) {
+ bstrncat(buf, "CAP_BSF ", sizeof(buf));
+ }
+ if (res->res_dev.cap_bits & CAP_FSR) {
+ bstrncat(buf, "CAP_FSR ", sizeof(buf));
+ }
+ if (res->res_dev.cap_bits & CAP_FSF) {
+ bstrncat(buf, "CAP_FSF ", sizeof(buf));
+ }
+ if (res->res_dev.cap_bits & CAP_EOM) {
+ bstrncat(buf, "CAP_EOM ", sizeof(buf));
+ }
+ if (res->res_dev.cap_bits & CAP_REM) {
+ bstrncat(buf, "CAP_REM ", sizeof(buf));
+ }
+ if (res->res_dev.cap_bits & CAP_RACCESS) {
+ bstrncat(buf, "CAP_RACCESS ", sizeof(buf));
+ }
+ if (res->res_dev.cap_bits & CAP_AUTOMOUNT) {
+ bstrncat(buf, "CAP_AUTOMOUNT ", sizeof(buf));
+ }
+ if (res->res_dev.cap_bits & CAP_LABEL) {
+ bstrncat(buf, "CAP_LABEL ", sizeof(buf));
+ }
+ if (res->res_dev.cap_bits & CAP_ANONVOLS) {
+ bstrncat(buf, "CAP_ANONVOLS ", sizeof(buf));
+ }
+ if (res->res_dev.cap_bits & CAP_ALWAYSOPEN) {
+ bstrncat(buf, "CAP_ALWAYSOPEN ", sizeof(buf));
+ }
+ bstrncat(buf, "\n", sizeof(buf));
+ sendit(sock, buf);
+ break;
+ case R_MSGS:
+ sendit(sock, "Messages: name=%s\n", res->res_msgs.hdr.name);
+ if (res->res_msgs.mail_cmd)
+ sendit(sock, " mailcmd=%s\n", res->res_msgs.mail_cmd);
+ if (res->res_msgs.operator_cmd)
+ sendit(sock, " opcmd=%s\n", res->res_msgs.operator_cmd);
+ break;
+ default:
+ sendit(sock, _("Warning: unknown resource type %d\n"), type);
+ break;
}
if (recurse && res->res_dir.hdr.next)
dump_resource(type, (RES *)res->res_dir.hdr.next, sendit, sock);
switch (type) {
case R_DIRECTOR:
- if (res->res_dir.password) {
- free(res->res_dir.password);
- }
- if (res->res_dir.address) {
- free(res->res_dir.address);
- }
- break;
+ if (res->res_dir.password) {
+ free(res->res_dir.password);
+ }
+ if (res->res_dir.address) {
+ free(res->res_dir.address);
+ }
+ break;
case R_STORAGE:
- if (res->res_store.address) { /* ***FIXME*** deprecated */
- free(res->res_store.address);
- }
- if (res->res_store.SDaddr) {
- free(res->res_store.SDaddr);
- }
- if (res->res_store.working_directory) {
- free(res->res_store.working_directory);
- }
- if (res->res_store.pid_directory) {
- free(res->res_store.pid_directory);
- }
- if (res->res_store.subsys_directory) {
- free(res->res_store.subsys_directory);
- }
- break;
+ if (res->res_store.address) { /* ***FIXME*** deprecated */
+ free(res->res_store.address);
+ }
+ if (res->res_store.SDaddr) {
+ free(res->res_store.SDaddr);
+ }
+ if (res->res_store.working_directory) {
+ free(res->res_store.working_directory);
+ }
+ if (res->res_store.pid_directory) {
+ free(res->res_store.pid_directory);
+ }
+ if (res->res_store.subsys_directory) {
+ free(res->res_store.subsys_directory);
+ }
+ break;
case R_DEVICE:
- if (res->res_dev.media_type) {
- free(res->res_dev.media_type);
- }
- if (res->res_dev.device_name) {
- free(res->res_dev.device_name);
- }
- if (res->res_dev.changer_name) {
- free(res->res_dev.changer_name);
- }
- if (res->res_dev.changer_command) {
- free(res->res_dev.changer_command);
- }
- break;
+ if (res->res_dev.media_type) {
+ free(res->res_dev.media_type);
+ }
+ if (res->res_dev.device_name) {
+ free(res->res_dev.device_name);
+ }
+ if (res->res_dev.changer_name) {
+ free(res->res_dev.changer_name);
+ }
+ if (res->res_dev.changer_command) {
+ free(res->res_dev.changer_command);
+ }
+ break;
case R_MSGS:
- if (res->res_msgs.mail_cmd) {
- free(res->res_msgs.mail_cmd);
- }
- if (res->res_msgs.operator_cmd) {
- free(res->res_msgs.operator_cmd);
- }
- free_msgs_res((MSGS *)res); /* free message resource */
- res = NULL;
- break;
+ if (res->res_msgs.mail_cmd) {
+ free(res->res_msgs.mail_cmd);
+ }
+ if (res->res_msgs.operator_cmd) {
+ free(res->res_msgs.operator_cmd);
+ }
+ free_msgs_res((MSGS *)res); /* free message resource */
+ res = NULL;
+ break;
default:
Dmsg1(0, "Unknown resource type %d\n", type);
- break;
+ break;
}
/* Common stuff again -- free the resource, recurse to next one */
if (res) {
*/
for (i=0; items[i].name; i++) {
if (items[i].flags & ITEM_REQUIRED) {
- if (!bit_is_set(i, res_all.res_dir.hdr.item_present)) {
+ if (!bit_is_set(i, res_all.res_dir.hdr.item_present)) {
Emsg2(M_ABORT, 0, _("%s item is required in %s resource, but not found.\n"),
- items[i].name, resources[rindex]);
- }
+ items[i].name, resources[rindex]);
+ }
}
/* If this triggers, take a look at lib/parse_conf.h */
if (i >= MAX_RES_ITEMS) {
*/
if (pass == 2) {
switch (type) {
- /* Resources not containing a resource */
- case R_DIRECTOR:
- case R_DEVICE:
- case R_MSGS:
- break;
-
- /* Resources containing a resource */
- case R_STORAGE:
- if ((res = (URES *)GetResWithName(R_STORAGE, res_all.res_dir.hdr.name)) == NULL) {
+ /* Resources not containing a resource */
+ case R_DIRECTOR:
+ case R_DEVICE:
+ case R_MSGS:
+ break;
+
+ /* Resources containing a resource */
+ case R_STORAGE:
+ if ((res = (URES *)GetResWithName(R_STORAGE, res_all.res_dir.hdr.name)) == NULL) {
Emsg1(M_ABORT, 0, "Cannot find Storage resource %s\n", res_all.res_dir.hdr.name);
- }
- res->res_store.messages = res_all.res_store.messages;
- break;
- default:
+ }
+ res->res_store.messages = res_all.res_store.messages;
+ break;
+ default:
printf("Unknown resource type %d\n", type);
- error = 1;
- break;
+ error = 1;
+ break;
}
if (res_all.res_dir.hdr.name) {
- free(res_all.res_dir.hdr.name);
- res_all.res_dir.hdr.name = NULL;
+ free(res_all.res_dir.hdr.name);
+ res_all.res_dir.hdr.name = NULL;
}
if (res_all.res_dir.hdr.desc) {
- free(res_all.res_dir.hdr.desc);
- res_all.res_dir.hdr.desc = NULL;
+ free(res_all.res_dir.hdr.desc);
+ res_all.res_dir.hdr.desc = NULL;
}
return;
}
/* The following code is only executed on pass 1 */
switch (type) {
case R_DIRECTOR:
- size = sizeof(DIRRES);
- break;
+ size = sizeof(DIRRES);
+ break;
case R_STORAGE:
- size = sizeof(STORES);
- break;
+ size = sizeof(STORES);
+ break;
case R_DEVICE:
- size = sizeof(DEVRES);
- break;
+ size = sizeof(DEVRES);
+ break;
case R_MSGS:
- size = sizeof(MSGS);
- break;
+ size = sizeof(MSGS);
+ break;
default:
printf("Unknown resource type %d\n", type);
- error = 1;
- size = 1;
- break;
+ error = 1;
+ size = 1;
+ break;
}
/* Common */
if (!error) {
res = (URES *)malloc(size);
memcpy(res, &res_all, size);
if (!resources[rindex].res_head) {
- resources[rindex].res_head = (RES *)res; /* store first entry */
+ resources[rindex].res_head = (RES *)res; /* store first entry */
} else {
- RES *next;
- /* Add new res to end of chain */
- for (next=resources[rindex].res_head; next->next; next=next->next) {
- if (strcmp(next->name, res->res_dir.hdr.name) == 0) {
- Emsg2(M_ERROR_TERM, 0,
+ RES *next;
+ /* Add new res to end of chain */
+ for (next=resources[rindex].res_head; next->next; next=next->next) {
+ if (strcmp(next->name, res->res_dir.hdr.name) == 0) {
+ Emsg2(M_ERROR_TERM, 0,
_("Attempt to define second %s resource named \"%s\" is not permitted.\n"),
- resources[rindex].name, res->res_dir.hdr.name);
- }
- }
- next->next = (RES *)res;
+ resources[rindex].name, res->res_dir.hdr.name);
+ }
+ }
+ next->next = (RES *)res;
Dmsg2(90, "Inserting %s res: %s\n", res_to_str(type),
- res->res_dir.hdr.name);
+ res->res_dir.hdr.name);
}
}
}
#undef VERSION
#define VERSION "1.33"
#define VSTRING "1"
-#define BDATE "24 Nov 2003"
-#define LSMDATE "24Nov03"
+#define BDATE "28 Nov 2003"
+#define LSMDATE "28Nov03"
/* Debug flags */
#undef DEBUG