- Update ChangeLog (add release date)
- Do a cvs commit
- Do a cvs -q export -D now -d bacula-1.nn bacula
-- Build new bacula-1.nn to ensure everything is committed
+- Run the regression tests on the new bacula
- Write ReleaseNotes
- If everything is good
- cd bacula/k
- Release Notes for Bacula 1.32
+ Release Notes for Bacula 1.33
Bacula code: Total files = 259 Total lines = 77,740 (*.h *.c *.in)
Major Changes this Release:
-- Implemented forward space file/block whenever possible
- during restore. Restoring a small number of files is now
- much faster.
-- There is a new option to restore that allows you
- to restore files based on their Filename. You can
- also specify a file to read which contains the list.
-- Added ClientRunBeforeJob and ClientRunAfterJob.
-- Implemented Include | and < in File daemon.
-- Automatic labeling of tape Volumes should work now.
-- Recycling has been completely restructured and should work.
-- Implemented full length time interval qualifiers (e.g
- "5n is now "5 min" or "5 minutes". A modifier is now required!
-- Fixed gnome-console to compile with RH9 (Gnome 2.0)
-- Implemented "list nextvol job=xxx", which displays the
- next volume to be used by job xxx. The Volume name to
- be used is also added to the "status dir" output.
-- Lots of fixes with variable expansion and counter variables
-- Implemented a new Include/Exclude syntax.
-- While writing a tape, an end of file mark will be written
- every 1Gb. This makes restores faster. If you want to
- change this use "Maximum File Size" in the SD Device
- resource.
Other Changes this Release:
-- A warning message is sent when a job starts that will be
- blocked because the user did an "unmount".
-- Block checksum errors if any are printed in the job report.
-- Implemented a single routine to read_records. It also returns
- a different record packet for each session. This means
- that multiple simultaneous jobs should work.
-- Added SDConnectTimeout to FD.
-- Lots of doc enhancements
-- Fixed a PurgeOldestVolume bug (VolStatus not returned)
-- Don't crash if DB address record not specified.
-- Return VolStatus on find_next_volume.
-- Use alist for incexe name_list.
-- Use bget_dirmsg() everywhere possible when talking to FD.
-- Delete old semaphore job and workq job scheduling code.
-- edit_run_codes in one place (/lib) Add Job name
-- Update query.sql to find current backups correctly.
-- Correct ambiguous SQL statement for pruning.
-- Set heartbeat interval to zero by default.
-- Fix a possible race condition in stopping the
- heartbeat thread.
-- Eliminate gnome2-console directory. Everything is in gnome-console
-- Enhanced "packet too big" message to indicate who sent it.
-- Corrected console prompt problem in non-readline versions.
-- Correct a number of variable expansion problems.
-- Added a number of new regression tests.
-- In an attempt to make configuration a bit less confusing, I've changed
- the name of a number of variables. The old ones still work, but will
- be phased out over time. FDAddress, FDPassword, SDAddress SDPassword,
- SDDeviceName, and DBPassword.
-- A possible fix to the very intermittent SD crashes that Alex gets.
Items to note: !!!!!
-- Modifiers (sec, min, hour, day, ...) are now required on conf file
- time interval specifications.
-- Duplicate names within the same conf resource are prohibited.
-- If you have used a prior BETA version of 1.32, please do
- the following to cleanup any zero length spool files:
-
- cd <working-directory-as-in-Bacula-conf>
- rm -f *.spool.*
-
- Please be sure there are no spaces between the asterisks
- and the periods.
- Test connect timeouts.
For 1.33 Testing/Documentation:
+- suppress "Do not forget to mount the drive!!!" if error
- Document new records in Director. SDAddress SDDeviceName, SDPassword.
FDPassword, FDAddress, DBAddress, DBPort, DBPassword.
- Document new Include/Exclude ...
- Add counter variable test.
For 1.33
+- Make sure a rescheduled job is properly reported by status.
+- Walk through the Pool records rather than the Job records
+ in dird.c to create/update pools.
+- Figure out a way to move Volumes from one pool to another.
+- What to do about "list files job=xxx".
+- Implement delete Job.
+- Document need to put LabelFormat in quotes.
- Implement scan: for every slot it finds, zero the slot of
Volume other volume having that slot.
- When job rescheduled, status gives is waiting for Client Rufus
for ( ; token != T_EOL; (token = lex_get_token(lc, T_ALL))) {
int len, pm = 0;
switch (token) {
- case T_NUMBER:
- state = s_mday;
- code = atoi(lc->str) - 1;
- if (code < 0 || code > 30) {
- scan_err0(lc, _("Day number out of range (1-31)"));
- }
+ case T_NUMBER:
+ state = s_mday;
+ code = atoi(lc->str) - 1;
+ if (code < 0 || code > 30) {
+ scan_err0(lc, _("Day number out of range (1-31)"));
+ }
+ break;
+ case T_NAME: /* this handles drop through from keyword */
+ case T_UNQUOTED_STRING:
+ if (strchr(lc->str, (int)'-')) {
+ state = s_range;
break;
- case T_NAME: /* this handles drop through from keyword */
- case T_UNQUOTED_STRING:
- if (strchr(lc->str, (int)'-')) {
- state = s_range;
- break;
- }
- if (strchr(lc->str, (int)':')) {
- state = s_time;
+ }
+ if (strchr(lc->str, (int)':')) {
+ state = s_time;
+ break;
+ }
+ /* everything else must be a keyword */
+ for (i=0; keyw[i].name; i++) {
+ if (strcasecmp(lc->str, keyw[i].name) == 0) {
+ state = keyw[i].state;
+ code = keyw[i].code;
+ i = 0;
break;
}
- /* everything else must be a keyword */
- for (i=0; keyw[i].name; i++) {
- if (strcasecmp(lc->str, keyw[i].name) == 0) {
- state = keyw[i].state;
- code = keyw[i].code;
- i = 0;
- break;
- }
- }
- if (i != 0) {
- scan_err1(lc, _("Job type field: %s in run record not found"), lc->str);
- /* NOT REACHED */
- }
- break;
- case T_COMMA:
- continue;
- default:
- scan_err2(lc, _("Unexpected token: %d:%s"), token, lc->str);
+ }
+ if (i != 0) {
+ scan_err1(lc, _("Job type field: %s in run record not found"), lc->str);
/* NOT REACHED */
- break;
+ }
+ break;
+ case T_COMMA:
+ continue;
+ default:
+ scan_err2(lc, _("Unexpected token: %d:%s"), token, lc->str);
+ /* NOT REACHED */
+ break;
}
switch (state) {
- case s_none:
- continue;
- case s_mday: /* day of month */
+ case s_none:
+ continue;
+ case s_mday: /* day of month */
+ if (!have_mday) {
+ clear_bits(0, 30, lrun.mday);
+ clear_bits(0, 6, lrun.wday);
+ have_mday = TRUE;
+ }
+ set_bit(code, lrun.mday);
+ break;
+ case s_month: /* month of year */
+ if (!have_month) {
+ clear_bits(0, 11, lrun.month);
+ have_month = TRUE;
+ }
+ set_bit(code, lrun.month);
+ break;
+ case s_wday: /* week day */
+ if (!have_wday) {
+ clear_bits(0, 6, lrun.wday);
+ clear_bits(0, 30, lrun.mday);
+ have_wday = TRUE;
+ }
+ set_bit(code, lrun.wday);
+ break;
+ case s_wpos: /* Week position 1st, ... */
+ if (!have_wpos) {
+ clear_bits(0, 4, lrun.wpos);
+ have_wpos = TRUE;
+ }
+ set_bit(code, lrun.wpos);
+ break;
+ case s_time: /* time */
+ if (!have_at) {
+ scan_err0(lc, _("Time must be preceded by keyword AT."));
+ /* NOT REACHED */
+ }
+ if (!have_hour) {
+ clear_bit(0, lrun.hour);
+ }
+ p = strchr(lc->str, ':');
+ if (!p) {
+ scan_err0(lc, _("Time logic error.\n"));
+ /* NOT REACHED */
+ }
+ *p++ = 0; /* separate two halves */
+ code = atoi(lc->str);
+ len = strlen(p);
+ if (len > 2 && p[len-1] == 'm') {
+ if (p[len-2] == 'a') {
+ pm = 0;
+ } else if (p[len-2] == 'p') {
+ pm = 1;
+ } else {
+ scan_err0(lc, _("Bad time specification."));
+ /* NOT REACHED */
+ }
+ } else {
+ pm = 0;
+ }
+ code2 = atoi(p);
+ if (pm) {
+ code += 12;
+ }
+ if (code < 0 || code > 23 || code2 < 0 || code2 > 59) {
+ scan_err0(lc, _("Bad time specification."));
+ /* NOT REACHED */
+ }
+ set_bit(code, lrun.hour);
+ lrun.minute = code2;
+ have_hour = TRUE;
+ break;
+ case s_at:
+ have_at = TRUE;
+ break;
+ case s_range:
+ p = strchr(lc->str, '-');
+ if (!p) {
+ scan_err0(lc, _("Range logic error.\n"));
+ }
+ *p++ = 0; /* separate two halves */
+
+ /* Check for day range */
+ if (is_num(lc->str) && is_num(p)) {
+ code = atoi(lc->str) - 1;
+ code2 = atoi(p) - 1;
+ if (code < 0 || code > 30 || code2 < 0 || code2 > 30) {
+ scan_err0(lc, _("Bad day range specification."));
+ }
if (!have_mday) {
clear_bits(0, 30, lrun.mday);
clear_bits(0, 6, lrun.wday);
have_mday = TRUE;
}
- set_bit(code, lrun.mday);
- break;
- case s_month: /* month of year */
- if (!have_month) {
- clear_bits(0, 11, lrun.month);
- have_month = TRUE;
+ if (code < code2) {
+ set_bits(code, code2, lrun.mday);
+ } else {
+ set_bits(code, 30, lrun.mday);
+ set_bits(0, code2, lrun.mday);
}
- set_bit(code, lrun.month);
break;
- case s_wday: /* week day */
+ }
+
+ /* lookup first half of keyword range (week days or months) */
+ lcase(lc->str);
+ for (i=0; keyw[i].name; i++) {
+ if (strcmp(lc->str, keyw[i].name) == 0) {
+ state = keyw[i].state;
+ code = keyw[i].code;
+ i = 0;
+ break;
+ }
+ }
+ if (i != 0 || (state != s_month && state != s_wday && state != s_wpos)) {
+ scan_err0(lc, _("Invalid month, week or position day range"));
+ /* NOT REACHED */
+ }
+
+ /* Lookup end of range */
+ lcase(p);
+ for (i=0; keyw[i].name; i++) {
+ if (strcmp(p, keyw[i].name) == 0) {
+ state2 = keyw[i].state;
+ code2 = keyw[i].code;
+ i = 0;
+ break;
+ }
+ }
+ if (i != 0 || state != state2 || code == code2) {
+ scan_err0(lc, _("Invalid month, weekday or position range"));
+ /* NOT REACHED */
+ }
+ if (state == s_wday) {
if (!have_wday) {
clear_bits(0, 6, lrun.wday);
clear_bits(0, 30, lrun.mday);
have_wday = TRUE;
}
- set_bit(code, lrun.wday);
- break;
- case s_wpos: /* Week position 1st, ... */
- if (!have_wpos) {
- clear_bits(0, 4, lrun.wpos);
- have_wpos = TRUE;
- }
- set_bit(code, lrun.wpos);
- break;
- case s_time: /* time */
- if (!have_at) {
- scan_err0(lc, _("Time must be preceded by keyword AT."));
- /* NOT REACHED */
- }
- if (!have_hour) {
- clear_bit(0, lrun.hour);
- }
- p = strchr(lc->str, ':');
- if (!p) {
- scan_err0(lc, _("Time logic error.\n"));
- /* NOT REACHED */
- }
- *p++ = 0; /* separate two halves */
- code = atoi(lc->str);
- len = strlen(p);
- if (len > 2 && p[len-1] == 'm') {
- if (p[len-2] == 'a') {
- pm = 0;
- } else if (p[len-2] == 'p') {
- pm = 1;
- } else {
- scan_err0(lc, _("Bad time specification."));
- /* NOT REACHED */
- }
+ if (code < code2) {
+ set_bits(code, code2, lrun.wday);
} else {
- pm = 0;
- }
- code2 = atoi(p);
- if (pm) {
- code += 12;
- }
- if (code < 0 || code > 23 || code2 < 0 || code2 > 59) {
- scan_err0(lc, _("Bad time specification."));
- /* NOT REACHED */
- }
- set_bit(code, lrun.hour);
- lrun.minute = code2;
- have_hour = TRUE;
- break;
- case s_at:
- have_at = TRUE;
- break;
- case s_range:
- p = strchr(lc->str, '-');
- if (!p) {
- scan_err0(lc, _("Range logic error.\n"));
- }
- *p++ = 0; /* separate two halves */
-
- /* Check for day range */
- if (is_num(lc->str) && is_num(p)) {
- code = atoi(lc->str) - 1;
- code2 = atoi(p) - 1;
- if (code < 0 || code > 30 || code2 < 0 || code2 > 30) {
- scan_err0(lc, _("Bad day range specification."));
- }
- if (!have_mday) {
- clear_bits(0, 30, lrun.mday);
- clear_bits(0, 6, lrun.wday);
- have_mday = TRUE;
- }
- if (code < code2) {
- set_bits(code, code2, lrun.mday);
- } else {
- set_bits(code, 30, lrun.mday);
- set_bits(0, code2, lrun.mday);
- }
- break;
+ set_bits(code, 6, lrun.wday);
+ set_bits(0, code2, lrun.wday);
}
-
- /* lookup first half of keyword range (week days or months) */
- lcase(lc->str);
- for (i=0; keyw[i].name; i++) {
- if (strcmp(lc->str, keyw[i].name) == 0) {
- state = keyw[i].state;
- code = keyw[i].code;
- i = 0;
- break;
- }
- }
- if (i != 0 || (state != s_month && state != s_wday && state != s_wpos)) {
- scan_err0(lc, _("Invalid month, week or position day range"));
- /* NOT REACHED */
+ } else if (state == s_month) {
+ if (!have_month) {
+ clear_bits(0, 30, lrun.month);
+ have_month = TRUE;
}
-
- /* Lookup end of range */
- lcase(p);
- for (i=0; keyw[i].name; i++) {
- if (strcmp(p, keyw[i].name) == 0) {
- state2 = keyw[i].state;
- code2 = keyw[i].code;
- i = 0;
- break;
- }
+ if (code < code2) {
+ set_bits(code, code2, lrun.month);
+ } else {
+ /* this is a bit odd, but we accept it anyway */
+ set_bits(code, 30, lrun.month);
+ set_bits(0, code2, lrun.month);
}
- if (i != 0 || state != state2 || code == code2) {
- scan_err0(lc, _("Invalid month, weekday or position range"));
- /* NOT REACHED */
+ } else {
+ /* Must be position */
+ if (!have_wpos) {
+ clear_bits(0, 4, lrun.wpos);
+ have_wpos = TRUE;
}
- if (state == s_wday) {
- if (!have_wday) {
- clear_bits(0, 6, lrun.wday);
- clear_bits(0, 30, lrun.mday);
- have_wday = TRUE;
- }
- if (code < code2) {
- set_bits(code, code2, lrun.wday);
- } else {
- set_bits(code, 6, lrun.wday);
- set_bits(0, code2, lrun.wday);
- }
- } else if (state == s_month) {
- if (!have_month) {
- clear_bits(0, 30, lrun.month);
- have_month = TRUE;
- }
- if (code < code2) {
- set_bits(code, code2, lrun.month);
- } else {
- /* this is a bit odd, but we accept it anyway */
- set_bits(code, 30, lrun.month);
- set_bits(0, code2, lrun.month);
- }
+ if (code < code2) {
+ set_bits(code, code2, lrun.wpos);
} else {
- /* Must be position */
- if (!have_wpos) {
- clear_bits(0, 4, lrun.wpos);
- have_wpos = TRUE;
- }
- if (code < code2) {
- set_bits(code, code2, lrun.wpos);
- } else {
- set_bits(code, 4, lrun.wpos);
- set_bits(0, code2, lrun.wpos);
- }
- }
- break;
- case s_hourly:
- clear_defaults();
- set_bits(0, 23, lrun.hour);
- set_bits(0, 30, lrun.mday);
- set_bits(0, 11, lrun.month);
- set_bits(0, 4, lrun.wpos);
- break;
- case s_weekly:
- clear_defaults();
- set_bit(0, lrun.wday);
- set_bits(0, 11, lrun.month);
- set_bits(0, 4, lrun.wpos);
- break;
- case s_daily:
- clear_defaults();
- set_bits(0, 30, lrun.mday);
- set_bits(0, 11, lrun.month);
- set_bits(0, 4, lrun.wpos);
- break;
- case s_monthly:
- clear_defaults();
- set_bits(0, 11, lrun.month);
- set_bits(0, 4, lrun.wpos);
- break;
- default:
- scan_err0(lc, _("Unexpected run state\n"));
- /* NOT REACHED */
- break;
+ set_bits(code, 4, lrun.wpos);
+ set_bits(0, code2, lrun.wpos);
+ }
+ }
+ break;
+ case s_hourly:
+ clear_defaults();
+ set_bits(0, 23, lrun.hour);
+ set_bits(0, 30, lrun.mday);
+ set_bits(0, 11, lrun.month);
+ set_bits(0, 4, lrun.wpos);
+ break;
+ case s_weekly:
+ clear_defaults();
+ set_bit(0, lrun.wday);
+ set_bits(0, 11, lrun.month);
+ set_bits(0, 4, lrun.wpos);
+ break;
+ case s_daily:
+ clear_defaults();
+ set_bits(0, 30, lrun.mday);
+ set_bits(0, 11, lrun.month);
+ set_bits(0, 4, lrun.wpos);
+ break;
+ case s_monthly:
+ clear_defaults();
+ set_bits(0, 11, lrun.month);
+ set_bits(0, 4, lrun.wpos);
+ break;
+ default:
+ scan_err0(lc, _("Unexpected run state\n"));
+ /* NOT REACHED */
+ break;
}
}
{
bfd->fid = open(fname, flags, mode);
bfd->berrno = errno;
+ Dmsg1(50, "Open file %d\n", bfd->fid);
return bfd->fid;
}
int bclose(BFILE *bfd)
{
int stat;
+ Dmsg1(50, "Close file %d\n", bfd->fid);
stat = close(bfd->fid);
bfd->berrno = errno;
bfd->fid = -1;
mode |= O_CTG; /* set contiguous bit if needed */
}
Dmsg1(50, "Create file: %s\n", attr->ofname);
+ if (is_bopen(bfd)) {
+ Jmsg1(jcr, M_ERROR, 0, "bpkt already open fid=%d\n", bfd->fid);
+ }
if ((bopen(bfd, attr->ofname, mode, S_IRUSR | S_IWUSR)) < 0) {
Jmsg2(jcr, M_ERROR, 0, _("Could not create %s: ERR=%s\n"),
attr->ofname, berror(bfd));
} else {
tid = NULL;
}
+ if (is_bopen(bfd)) {
+ Jmsg1(jcr, M_ERROR, 0, "bpkt already open fid=%d\n", bfd->fid);
+ }
if ((bopen(bfd, attr->ofname, mode, 0)) < 0) {
Jmsg2(jcr, M_ERROR, 0, _("Could not open %s: ERR=%s\n"),
attr->ofname, berror(bfd));
* and saved.
*/
if (!is_portable_backup(bfd)) {
+ if (is_bopen(bfd)) {
+ Jmsg1(jcr, M_ERROR, 0, "bpkt already open fid=%d\n", bfd->fid);
+ }
if ((bopen(bfd, attr->ofname, O_WRONLY|O_BINARY, 0)) < 0) {
Jmsg2(jcr, M_ERROR, 0, _("Could not open %s: ERR=%s\n"),
attr->ofname, berror(bfd));
Dmsg2(200, "store_msgs pass=%d code=%d\n", pass, item->code);
if (pass == 1) {
switch (item->code) {
- case MD_STDOUT:
- case MD_STDERR:
- case MD_SYSLOG: /* syslog */
- case MD_CONSOLE:
- scan_types(lc, (MSGS *)(item->value), item->code, NULL, NULL);
- break;
- case MD_OPERATOR: /* send to operator */
- case MD_DIRECTOR: /* send to Director */
- case MD_MAIL: /* mail */
- case MD_MAIL_ON_ERROR: /* mail if Job errors */
- if (item->code == MD_OPERATOR) {
- cmd = res_all.res_msgs.operator_cmd;
- } else {
- cmd = res_all.res_msgs.mail_cmd;
- }
- dest = get_pool_memory(PM_MESSAGE);
- dest[0] = 0;
- dest_len = 0;
- /* Pick up comma separated list of destinations */
- for ( ;; ) {
- token = lex_get_token(lc, T_NAME); /* scan destination */
- dest = check_pool_memory_size(dest, dest_len + lc->str_len + 2);
- if (dest[0] != 0) {
- strcat(dest, " "); /* separate multiple destinations with space */
- dest_len++;
- }
- strcat(dest, lc->str);
- dest_len += lc->str_len;
- Dmsg2(100, "store_msgs newdest=%s: dest=%s:\n", lc->str, NPRT(dest));
- token = lex_get_token(lc, T_ALL);
- if (token == T_COMMA) {
- continue; /* get another destination */
- }
- if (token != T_EQUALS) {
- scan_err1(lc, "expected an =, got: %s", lc->str);
- }
- break;
- }
- Dmsg1(200, "mail_cmd=%s\n", NPRT(cmd));
- scan_types(lc, (MSGS *)(item->value), item->code, dest, cmd);
- free_pool_memory(dest);
- Dmsg0(200, "done with dest codes\n");
- break;
- case MD_FILE: /* file */
- case MD_APPEND: /* append */
- dest = get_pool_memory(PM_MESSAGE);
- /* Pick up a single destination */
+ case MD_STDOUT:
+ case MD_STDERR:
+ case MD_SYSLOG: /* syslog */
+ case MD_CONSOLE:
+ scan_types(lc, (MSGS *)(item->value), item->code, NULL, NULL);
+ break;
+ case MD_OPERATOR: /* send to operator */
+ case MD_DIRECTOR: /* send to Director */
+ case MD_MAIL: /* mail */
+ case MD_MAIL_ON_ERROR: /* mail if Job errors */
+ if (item->code == MD_OPERATOR) {
+ cmd = res_all.res_msgs.operator_cmd;
+ } else {
+ cmd = res_all.res_msgs.mail_cmd;
+ }
+ dest = get_pool_memory(PM_MESSAGE);
+ dest[0] = 0;
+ dest_len = 0;
+ /* Pick up comma separated list of destinations */
+ for ( ;; ) {
token = lex_get_token(lc, T_NAME); /* scan destination */
- pm_strcpy(&dest, lc->str);
- dest_len = lc->str_len;
+ dest = check_pool_memory_size(dest, dest_len + lc->str_len + 2);
+ if (dest[0] != 0) {
+ strcat(dest, " "); /* separate multiple destinations with space */
+ dest_len++;
+ }
+ strcat(dest, lc->str);
+ dest_len += lc->str_len;
+ Dmsg2(100, "store_msgs newdest=%s: dest=%s:\n", lc->str, NPRT(dest));
token = lex_get_token(lc, T_ALL);
- Dmsg1(200, "store_msgs dest=%s:\n", NPRT(dest));
+ if (token == T_COMMA) {
+ continue; /* get another destination */
+ }
if (token != T_EQUALS) {
scan_err1(lc, "expected an =, got: %s", lc->str);
}
- scan_types(lc, (MSGS *)(item->value), item->code, dest, NULL);
- free_pool_memory(dest);
- Dmsg0(200, "done with dest codes\n");
break;
+ }
+ Dmsg1(200, "mail_cmd=%s\n", NPRT(cmd));
+ scan_types(lc, (MSGS *)(item->value), item->code, dest, cmd);
+ free_pool_memory(dest);
+ Dmsg0(200, "done with dest codes\n");
+ break;
+ case MD_FILE: /* file */
+ case MD_APPEND: /* append */
+ dest = get_pool_memory(PM_MESSAGE);
+ /* Pick up a single destination */
+ token = lex_get_token(lc, T_NAME); /* scan destination */
+ pm_strcpy(&dest, lc->str);
+ dest_len = lc->str_len;
+ token = lex_get_token(lc, T_ALL);
+ Dmsg1(200, "store_msgs dest=%s:\n", NPRT(dest));
+ if (token != T_EQUALS) {
+ scan_err1(lc, "expected an =, got: %s", lc->str);
+ }
+ scan_types(lc, (MSGS *)(item->value), item->code, dest, NULL);
+ free_pool_memory(dest);
+ Dmsg0(200, "done with dest codes\n");
+ break;
- default:
- scan_err1(lc, "Unknown item code: %d\n", item->code);
- break;
+ default:
+ scan_err1(lc, "Unknown item code: %d\n", item->code);
+ break;
}
}
scan_to_eol(lc);
str = &lc->str[0];
}
for (i=0; msg_types[i].name; i++) {
- if (strcmp(str, msg_types[i].name) == 0) {
+ if (strcasecmp(str, msg_types[i].name) == 0) {
msg_type = msg_types[i].token;
found = TRUE;
break;
release = 1; /* release next time if we "recurse" */
-ask_again:
+// ask_again:
if (ask && !dir_ask_sysop_to_mount_next_volume(jcr, dev)) {
Dmsg0(100, "Error return ask_sysop ...\n");
return 0; /* error return */
Jmsg1(jcr, M_WARNING, 0, "%s", jcr->errmsg);
Dmsg0(100, "Default\n");
ask = true;
- goto ask_again;
+ /* was - goto ask_again; */
+ goto mount_next_vol;
}
break;
}
while ((ch = getopt(argc, argv, "ad:e:i:?")) != -1) {
switch (ch) {
- case 'a': /* print extended attributes *debug* */
- attrs = 1;
- break;
-
- case 'd': /* set debug level */
- debug_level = atoi(optarg);
- if (debug_level <= 0) {
- debug_level = 1;
- }
- break;
+ case 'a': /* print extended attributes *debug* */
+ attrs = 1;
+ break;
+
+ case 'd': /* set debug level */
+ debug_level = atoi(optarg);
+ if (debug_level <= 0) {
+ debug_level = 1;
+ }
+ break;
- case 'e': /* exclude patterns */
- exc = optarg;
- break;
+ case 'e': /* exclude patterns */
+ exc = optarg;
+ break;
- case 'i': /* include patterns */
- inc = optarg;
- break;
+ case 'i': /* include patterns */
+ inc = optarg;
+ break;
- case '?':
- default:
- usage();
+ case '?':
+ default:
+ usage();
}
}
char *p, *f;
int n;
+ if (type == FT_LNK) {
+ statp->st_mtime = 0;
+ statp->st_mode |= 0777;
+ }
p = encode_mode(statp->st_mode, buf);
n = sprintf(p, " %2d ", (uint32_t)statp->st_nlink);
p += n;
n = sprintf(p, " ");
}
p += n;
- if (type != FT_LNK) {
- p = encode_time(statp->st_mtime, p);
- } else {
- p = encode_time(0, p);
- }
+ p = encode_time(statp->st_mtime, p);
*p++ = ' ';
/* Copy file name */
for (f=fname; *f && (p-buf) < (int)sizeof(buf); )