--sd.conf password does not match dir.conf storage password
=======
+- Apparently Description records are not freed. Storage daemon
+ Device reported orphaned buffer 45 bytes probably for a Description.
- Write updated bootstrap after every Job.
- Correct Warning: Volume name mismatch. Wanted test2 got test1
when reading a tape and want the next one.
-- Create all pools when Director starts
- Implement autochanger for restore. ARRRGGG! I forgot!
- Make BSR accept count (total files to be restored).
- Make BSR return next_block when it knows record is not
optimizations. I.e. add a state word.
- After unmount, if restore job started, ask to mount.
- Fix db_get_fileset in cats/sql_get.c for multiple records.
-- Fix start/end blocks for File
+- Fix start/end blocks for File devices
- Add new code to scheduler.c and run_conf.c
- Volume Bytes shows bytes on last volume written in Job summary.
- Fix catalog filename truncation in sql_get and sql_create. Use
- Pass "Catalog Files = no" to storage daemon to eliminate network traffic.
- When we are at EOM, we must ask each job to write JobMedia
record (update_volume_info).
+- Create all pools when Director starts
+
char * job_level_to_str (int level);
-/*
- *void print_ls_output (char *fname, char *lname, int type, struct stat *statp);
- */
/* watchdog.c */
int start_watchdog(void);
return cp;
}
-#ifdef WORKING
-extern char *getuser(uid_t uid);
-extern char *getgroup(gid_t gid);
-
-void print_ls_output(char *fname, char *lname, int type, struct stat *statp)
-{
- char buf[1000];
- char *p, *f;
- int n;
-
- p = encode_mode(statp->st_mode, buf);
- n = sprintf(p, " %2d ", (uint32_t)statp->st_nlink);
- p += n;
- n = sprintf(p, "%-8.8s %-8.8s", getuser(statp->st_uid), getgroup(statp->st_gid));
- p += n;
- n = sprintf(p, "%8ld ", statp->st_size);
- p += n;
- p = encode_time(statp->st_ctime, p);
- *p++ = ' ';
- *p++ = ' ';
- for (f=fname; *f; )
- *p++ = *f++;
- if (type == FT_LNK) {
- *p++ = ' ';
- *p++ = '-';
- *p++ = '>';
- *p++ = ' ';
- /* Copy link name */
- for (f=lname; *f; )
- *p++ = *f++;
- }
- *p++ = '\n';
- *p = 0;
- fputs(buf, stdout);
-}
-#endif
int do_shell_expansion(char *name)
{
acquire.o mount.o record.o stored_conf.o
BLSOBJS = bls.o block.o device.o dev.o label.o match_bsr.o \
- acquire.o mount.o parse_bsr.o record.o
+ acquire.o mount.o parse_bsr.o record.o butil.o
BEXTOBJS = bextract.o block.o device.o dev.o label.o record.o \
- acquire.o mount.o match_bsr.o parse_bsr.o
+ acquire.o mount.o match_bsr.o parse_bsr.o butil.o
-SCNOBJS = bscan.o block.o device.o dev.o askdir.o label.o \
- acquire.o mount.o record.o match_bsr.o parse_bsr.o
+SCNOBJS = bscan.o block.o device.o dev.o label.o \
+ acquire.o mount.o record.o match_bsr.o parse_bsr.o \
+ butil.o
-# it was ``be kind to gmake week''. Now it's ``autoconf week''
-#OBJS = $(SRCS:S,.c,.o,)
# these are the objects that are changed by the .configure process
EXTRAOBJS = @OBJLIST@
static void do_extract(char *fname, char *prefix);
-static void print_ls_output(char *fname, char *link, int type, struct stat *statp);
static void get_session_record(DEVICE *dev, DEV_RECORD *rec, SESSION_LABEL *sessrec);
static DEVICE *dev = NULL;
exit(1);
}
-static void my_free_jcr(JCR *jcr)
-{
- return;
-}
-
int main (int argc, char *argv[])
{
add_fname_to_include_list(ff, 0, "/"); /* include everything */
}
- jcr = new_jcr(sizeof(JCR), my_free_jcr);
- jcr->VolSessionId = 1;
- jcr->VolSessionTime = (uint32_t)time(NULL);
- jcr->bsr = bsr;
- strcpy(jcr->Job, "bextract");
- jcr->dev_name = get_pool_memory(PM_FNAME);
- strcpy(jcr->dev_name, argv[0]);
do_extract(argv[0], argv[1]);
- free_jcr(jcr);
if (bsr) {
free_bsr(bsr);
}
static void do_extract(char *devname, char *where)
{
- char VolName[100];
- char *p;
struct stat statp;
int extract = FALSE;
int type;
SESSION_LABEL sessrec;
uint32_t num_files = 0;
- VolName[0] = 0;
- if (strncmp(devname, "/dev/", 5) != 0) {
- /* Try stripping file part */
- p = devname + strlen(devname);
- while (p >= devname && *p != '/') {
- p--;
- }
- if (*p == '/') {
- strcpy(VolName, p+1);
- *p = 0;
- }
+ jcr = setup_jcr("bextract", devname, bsr);
+ dev = setup_to_read_device(jcr);
+ if (!dev) {
+ exit(1);
}
- strcpy(jcr->VolumeName, VolName);
-
- dev = init_dev(NULL, devname);
- if (!dev || !open_device(dev)) {
- Emsg1(M_ERROR_TERM, 0, "Cannot open %s\n", devname);
- }
- Dmsg0(90, "Device opened for read.\n");
+ /* Make sure where directory exists and that it is a directory */
if (stat(where, &statp) < 0) {
Emsg2(M_ERROR_TERM, 0, "Cannot stat %s. It must exist. ERR=%s\n",
where, strerror(errno));
block = new_block(dev);
- create_vol_list(jcr);
-
- Dmsg1(20, "Found %d volumes names to restore.\n", jcr->NumVolumes);
-
- /*
- * Ready device for reading, and read records
- */
- if (!acquire_device_for_read(jcr, dev, block)) {
- free_block(block);
- free_vol_list(jcr);
- return;
- }
-
rec = new_record();
free_pool_memory(rec->data);
- rec->data = get_memory(70000);
+ rec->data = get_memory(70000); /* get a big block for reading */
uint32_t compress_buf_size = 70000;
POOLMEM *compress_buf = get_memory(compress_buf_size);
term_dev(dev);
free_block(block);
free_record(rec);
+ free_jcr(jcr);
printf("%u files restored.\n", num_files);
return;
}
-extern char *getuser(uid_t uid);
-extern char *getgroup(gid_t gid);
-
-static void print_ls_output(char *fname, char *link, int type, struct stat *statp)
-{
- char buf[1000];
- char ec1[30];
- char *p, *f;
- int n;
-
- p = encode_mode(statp->st_mode, buf);
- n = sprintf(p, " %2d ", (uint32_t)statp->st_nlink);
- p += n;
- n = sprintf(p, "%-8.8s %-8.8s", getuser(statp->st_uid), getgroup(statp->st_gid));
- p += n;
- n = sprintf(p, "%8.8s ", edit_uint64(statp->st_size, ec1));
- p += n;
- p = encode_time(statp->st_ctime, p);
- *p++ = ' ';
- *p++ = ' ';
- /* Copy file name */
- for (f=fname; *f && (p-buf) < (int)sizeof(buf); )
- *p++ = *f++;
- if (type == FT_LNK) {
- *p++ = ' ';
- *p++ = '-';
- *p++ = '>';
- *p++ = ' ';
- /* Copy link name */
- for (f=link; *f && (p-buf) < (int)sizeof(buf); )
- *p++ = *f++;
- }
- *p++ = '\n';
- *p = 0;
- fputs(buf, stdout);
-}
-
static void get_session_record(DEVICE *dev, DEV_RECORD *rec, SESSION_LABEL *sessrec)
{
char *rtype;
static void do_blocks(char *infname);
static void do_jobs(char *infname);
static void do_ls(char *fname);
-static void print_ls_output(char *fname, char *link, int type, struct stat *statp);
-static void do_setup(char *infname);
static void do_close();
static void get_session_record(DEVICE *dev, DEV_RECORD *rec, SESSION_LABEL *sessrec);
static int list_blocks = FALSE;
static int list_jobs = FALSE;
static int verbose = 0;
-static char Vol[2000];
-static char *VolName;
-static char *p;
static DEV_RECORD *rec;
static DEV_BLOCK *block;
-static int NumVolumes, CurVolume;
static JCR *jcr;
+static SESSION_LABEL sessrec;
extern char BaculaId[];
}
for (i=0; i < argc; i++) {
- do_setup(argv[i]);
+ jcr = setup_jcr("bls", argv[i], bsr);
+ dev = setup_to_read_device(jcr);
+ if (!dev) {
+ exit(1);
+ }
+ rec = new_record();
+ block = new_block(dev);
if (list_blocks) {
do_blocks(argv[i]);
} else if (list_jobs) {
return 0;
}
-static void my_free_jcr(JCR *jcr)
-{
- return;
-}
-
-/*
- * Setup device, jcr, and prepare to read
- */
-static void do_setup(char *infname)
-{
- jcr = new_jcr(sizeof(JCR), my_free_jcr);
- jcr->VolSessionId = 1;
- jcr->VolSessionTime = (uint32_t)time(NULL);
- jcr->bsr = bsr;
- strcpy(jcr->Job, "bls");
- jcr->dev_name = get_pool_memory(PM_FNAME);
- strcpy(jcr->dev_name, infname);
-
- VolName = Vol;
- VolName[0] = 0;
- if (strncmp(infname, "/dev/", 5) != 0) {
- /* Try stripping file part */
- p = infname + strlen(infname);
- while (p >= infname && *p != '/')
- p--;
- if (*p == '/') {
- strcpy(VolName, p+1);
- *p = 0;
- }
- }
- Dmsg2(100, "Device=%s, Vol=%s.\n", infname, VolName);
- dev = init_dev(NULL, infname);
- if (!dev) {
- Emsg1(M_FATAL, 0, "Cannot open %s\n", infname);
- exit(1);
- }
- /* ***FIXME**** init capabilities */
- if (!open_device(dev)) {
- Emsg1(M_FATAL, 0, "Cannot open %s\n", infname);
- exit(1);
- }
- Dmsg0(90, "Device opened for read.\n");
-
- rec = new_record();
- block = new_block(dev);
-
- NumVolumes = 0;
- CurVolume = 1;
- for (p = VolName; p && *p; ) {
- p = strchr(p, '|');
- if (p) {
- *p++ = 0;
- }
- NumVolumes++;
- }
-
- pm_strcpy(&jcr->VolumeName, VolName);
- Dmsg1(100, "Volume=%s\n", jcr->VolumeName);
- if (!acquire_device_for_read(jcr, dev, block)) {
- Emsg0(M_ERROR, 0, dev->errmsg);
- exit(1);
- }
-}
static void do_close()
{
free_jcr(jcr);
}
-static int mount_next_volume(char *infname)
-{
- if (rec->remainder) {
- Dmsg0(20, "Not end of record. Next volume has more data for current record.\n");
- }
- Dmsg2(20, "NumVolumes=%d CurVolume=%d\n", NumVolumes, CurVolume);
- if (NumVolumes > 1 && CurVolume < NumVolumes) {
- p = VolName;
- while (*p++)
- { }
- CurVolume++;
- Dmsg1(20, "There is another volume %s.\n", p);
- VolName = p;
- pm_strcpy(&jcr->VolumeName, VolName);
-
- close_dev(dev);
- dev->state &= ~ST_READ;
- if (!acquire_device_for_read(jcr, dev, block)) {
- Emsg2(M_FATAL, 0, "Cannot open Dev=%s, Vol=%s\n", infname, VolName);
- exit(1);
- }
- return 1; /* Next volume mounted */
- }
- printf("End of Device reached.\n");
- return 0; /* EOT */
-}
/*
* Device got an error, attempt to analyse it
if (!read_block_from_device(dev, block)) {
Dmsg0(20, "!read_block()\n");
if (dev->state & ST_EOT) {
- if (!mount_next_volume(infname)) {
+ if (!mount_next_read_volume(jcr, dev, block)) {
+ printf("End of File on device\n");
break;
}
+ DEV_RECORD *record;
+ record = new_record();
+ read_block_from_device(dev, block);
+ read_record_from_block(block, record);
+ get_session_record(dev, record, &sessrec);
+ free_record(record);
+ printf("Volume %s mounted.\n", jcr->VolumeName);
continue;
}
if (dev->state & ST_EOF) {
if (!read_block_from_device(dev, block)) {
Dmsg0(20, "!read_block()\n");
if (dev->state & ST_EOT) {
- if (!mount_next_volume(infname)) {
+ DEV_RECORD *record;
+ if (!mount_next_read_volume(jcr, dev, block)) {
+ printf("Got EOF on device %s\n", dev_name(dev));
break;
}
+ record = new_record();
+ read_block_from_device(dev, block);
+ read_record_from_block(block, record);
+ get_session_record(dev, record, &sessrec);
+ free_record(record);
+ printf("Volume %s mounted.\n", jcr->VolumeName);
continue;
}
if (dev->state & ST_EOF) {
}
for ( ;; ) {
- SESSION_LABEL sessrec;
if (!read_block_from_device(dev, block)) {
Dmsg0(20, "!read_record()\n");
DEV_RECORD *record;
Dmsg3(100, "EOT. stat=%s blk=%d rem=%d\n", rec_state_to_str(rec),
block->BlockNumber, rec->remainder);
- if (!mount_next_volume(infname)) {
+ if (!mount_next_read_volume(jcr, dev, block)) {
Dmsg3(100, "After mount next vol. stat=%s blk=%d rem=%d\n", rec_state_to_str(rec),
block->BlockNumber, rec->remainder);
break;
/* Skip to link name */
while (*ap++ != 0)
;
- print_ls_output(fname, ap, type, &statp);
- num_files++;
+ if (file_is_included(&ff, fname) && !file_is_excluded(&ff, fname)) {
+ print_ls_output(fname, ap, type, &statp);
+ num_files++;
+ }
}
}
}
return;
}
-extern char *getuser(uid_t uid);
-extern char *getgroup(gid_t gid);
-
-static void print_ls_output(char *fname, char *link, int type, struct stat *statp)
-{
- char buf[1000];
- char ec1[30];
- char *p, *f;
- int n;
-
- if (!file_is_included(&ff, fname) || file_is_excluded(&ff, fname)) {
- return;
- }
- p = encode_mode(statp->st_mode, buf);
- n = sprintf(p, " %2d ", (uint32_t)statp->st_nlink);
- p += n;
- n = sprintf(p, "%-8.8s %-8.8s", getuser(statp->st_uid), getgroup(statp->st_gid));
- p += n;
- n = sprintf(p, "%8.8s ", edit_uint64(statp->st_size, ec1));
- p += n;
- p = encode_time(statp->st_ctime, p);
- *p++ = ' ';
- *p++ = ' ';
- /* Copy file name */
- for (f=fname; *f && (p-buf) < (int)sizeof(buf); )
- *p++ = *f++;
- if (type == FT_LNK) {
- *p++ = ' ';
- *p++ = '-';
- *p++ = '>';
- *p++ = ' ';
- /* Copy link name */
- for (f=link; *f && (p-buf) < (int)sizeof(buf); )
- *p++ = *f++;
- }
- *p++ = '\n';
- *p = 0;
- fputs(buf, stdout);
-}
static void get_session_record(DEVICE *dev, DEV_RECORD *rec, SESSION_LABEL *sessrec)
{
#include "cats/cats.h"
static void do_scan(char *fname);
-static void print_ls_output(char *fname, struct stat *statp);
static DEVICE *dev = NULL;
exit(1);
}
-static void my_free_jcr(JCR *jcr)
-{
- return;
-}
-
int main (int argc, char *argv[])
{
int ch;
usage();
}
- jcr = new_jcr(sizeof(JCR), my_free_jcr);
- jcr->VolSessionId = 1;
- jcr->VolSessionTime = (uint32_t)time(NULL);
- jcr->NumVolumes = 1;
- jcr->bsr = bsr;
- strcpy(jcr->Job, "bscan");
- jcr->dev_name = get_pool_memory(PM_FNAME);
- strcpy(jcr->dev_name, argv[0]);
+ jcr = setup_jcr("bscan", argv[0], bsr);
/* *** FIXME **** need to put in corect db, user, and password */
if ((db=db_init_database(NULL, "bacula", "bacula", "")) == NULL) {
static void do_scan(char *devname)
{
- char VolName[100];
- char *p;
struct stat statp;
int type;
long record_file_index;
POOL_DBR pr;
JOB_DBR jr;
- if (strncmp(devname, "/dev/", 5) != 0) {
- /* Try stripping file part */
- p = devname + strlen(devname);
- while (p >= devname && *p != '/') {
- p--;
- }
- if (*p == '/') {
- strcpy(VolName, p+1);
- *p = 0;
- }
+ dev = setup_to_read_device(jcr);
+ if (!dev) {
+ exit(1);
}
- strcpy(jcr->VolumeName, VolName);
-
- dev = init_dev(NULL, devname);
- if (!dev || !open_device(dev)) {
- Emsg1(M_ABORT, 0, "Cannot open %s\n", devname);
- }
- Dmsg0(90, "Device opened for read.\n");
fname = get_pool_memory(PM_FNAME);
ofile = get_pool_memory(PM_FNAME);
block = new_block(dev);
- create_vol_list(jcr);
-
- if (!acquire_device_for_read(jcr, dev, block)) {
- Emsg1(M_ABORT, 0, "Cannot open %s\n", devname);
- }
-
rec = new_record();
free_pool_memory(rec->data);
rec->data = get_memory(70000);
decode_stat(ap, &statp);
if (debug_level > 1) {
- print_ls_output(fname, &statp);
+ print_ls_output(fname, lname, type, &statp);
}
/* Data stream and extracting */
return;
}
-extern char *getuser(uid_t uid);
-extern char *getgroup(gid_t gid);
-static void print_ls_output(char *fname, struct stat *statp)
+/* Dummies to replace askdir.c */
+int dir_get_volume_info(JCR *jcr) { return 1;}
+int dir_find_next_appendable_volume(JCR *jcr) { return 1;}
+int dir_update_volume_info(JCR *jcr, VOLUME_CAT_INFO *vol, int relabel) { return 1; }
+int dir_create_jobmedia_record(JCR *jcr) { return 1; }
+int dir_ask_sysop_to_mount_next_volume(JCR *jcr, DEVICE *dev) { return 1; }
+int dir_update_file_attributes(JCR *jcr, DEV_RECORD *rec) { return 1;}
+int dir_send_job_status(JCR *jcr) {return 1;}
+
+
+int dir_ask_sysop_to_mount_volume(JCR *jcr, DEVICE *dev)
{
- char buf[1000];
- char *p, *f;
- int n;
-
- p = encode_mode(statp->st_mode, buf);
- n = sprintf(p, " %2d ", (uint32_t)statp->st_nlink);
- p += n;
- n = sprintf(p, "%-8.8s %-8.8s", getuser(statp->st_uid), getgroup(statp->st_gid));
- p += n;
- n = sprintf(p, "%8lld ", (uint64_t)statp->st_size);
- p += n;
- p = encode_time(statp->st_ctime, p);
- *p++ = ' ';
- *p++ = ' ';
- for (f=fname; *f; )
- *p++ = *f++;
- *p++ = '\n';
- *p = 0;
- fputs(buf, stdout);
+ fprintf(stderr, "Mount Volume %s on device %s and press return when ready: ",
+ jcr->VolumeName, dev_name(dev));
+ getchar();
+ return 1;
}
--- /dev/null
+/*
+ *
+ * Utility routines for "tool" programs such as bscan, bls,
+ * bextract, ...
+ *
+ * Normally nothing in this file is called by the Storage
+ * daemon because we interact more directly with the user
+ * i.e. printf, ...
+ *
+ * Version $Id$
+ */
+/*
+ Copyright (C) 2000, 2001, 2002 Kern Sibbald and John Walker
+
+ This program is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License as
+ published by the Free Software Foundation; either version 2 of
+ the License, or (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public
+ License along with this program; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
+ MA 02111-1307, USA.
+
+ */
+
+#include "bacula.h"
+#include "stored.h"
+
+
+#ifdef DEBUG
+char *rec_state_to_str(DEV_RECORD *rec)
+{
+ static char buf[200];
+ buf[0] = 0;
+ if (rec->state & REC_NO_HEADER) {
+ strcat(buf, "Nohdr,");
+ }
+ if (is_partial_record(rec)) {
+ strcat(buf, "partial,");
+ }
+ if (rec->state & REC_BLOCK_EMPTY) {
+ strcat(buf, "empty,");
+ }
+ if (rec->state & REC_NO_MATCH) {
+ strcat(buf, "Nomatch,");
+ }
+ if (rec->state & REC_CONTINUATION) {
+ strcat(buf, "cont,");
+ }
+ if (buf[0]) {
+ buf[strlen(buf)-1] = 0;
+ }
+ return buf;
+}
+#endif
+
+
+/*
+ * Setup device, jcr, and prepare to read
+ */
+DEVICE *setup_to_read_device(JCR *jcr)
+{
+ DEVICE *dev;
+ DEV_BLOCK *block;
+ char *p;
+
+ jcr->VolumeName[0] = 0;
+ if (strncmp(jcr->dev_name, "/dev/", 5) != 0) {
+ /* Try stripping file part */
+ p = jcr->dev_name + strlen(jcr->dev_name);
+ while (p >= jcr->dev_name && *p != '/')
+ p--;
+ if (*p == '/') {
+ strcpy(jcr->VolumeName, p+1);
+ *p = 0;
+ }
+ }
+
+ dev = init_dev(NULL, jcr->dev_name);
+ if (!dev) {
+ Emsg1(M_FATAL, 0, "Cannot open %s\n", jcr->dev_name);
+ return NULL;
+ }
+ /* ***FIXME**** init capabilities */
+ if (!open_device(dev)) {
+ Emsg1(M_FATAL, 0, "Cannot open %s\n", jcr->dev_name);
+ return NULL;
+ }
+ Dmsg0(90, "Device opened for read.\n");
+
+ block = new_block(dev);
+
+ create_vol_list(jcr);
+
+ Dmsg1(100, "Volume=%s\n", jcr->VolumeName);
+ if (!acquire_device_for_read(jcr, dev, block)) {
+ Emsg0(M_ERROR, 0, dev->errmsg);
+ return NULL;
+ }
+ free_block(block);
+ return dev;
+}
+
+
+static void my_free_jcr(JCR *jcr)
+{
+ return;
+}
+
+JCR *setup_jcr(char *name, char *device, BSR *bsr)
+{
+ JCR *jcr = new_jcr(sizeof(JCR), my_free_jcr);
+ jcr->VolSessionId = 1;
+ jcr->VolSessionTime = (uint32_t)time(NULL);
+ jcr->bsr = bsr;
+ strcpy(jcr->Job, name);
+ jcr->dev_name = get_pool_memory(PM_FNAME);
+ strcpy(jcr->dev_name, device);
+ return jcr;
+}
+
+
+/*
+ * Device got an error, attempt to analyse it
+ */
+void display_error_status(DEVICE *dev)
+{
+ uint32_t status;
+
+ Emsg0(M_ERROR, 0, dev->errmsg);
+ status_dev(dev, &status);
+ Dmsg1(20, "Device status: %x\n", status);
+ if (status & MT_EOD)
+ Emsg0(M_ERROR_TERM, 0, "Unexpected End of Data\n");
+ else if (status & MT_EOT)
+ Emsg0(M_ERROR_TERM, 0, "Unexpected End of Tape\n");
+ else if (status & MT_EOF)
+ Emsg0(M_ERROR_TERM, 0, "Unexpected End of File\n");
+ else if (status & MT_DR_OPEN)
+ Emsg0(M_ERROR_TERM, 0, "Tape Door is Open\n");
+ else if (!(status & MT_ONLINE))
+ Emsg0(M_ERROR_TERM, 0, "Unexpected Tape is Off-line\n");
+ else
+ Emsg2(M_ERROR_TERM, 0, "Read error on Record Header %s: %s\n", dev_name(dev), strerror(errno));
+}
+
+
+extern char *getuser(uid_t uid);
+extern char *getgroup(gid_t gid);
+
+void print_ls_output(char *fname, char *link, int type, struct stat *statp)
+{
+ char buf[1000];
+ char ec1[30];
+ char *p, *f;
+ int n;
+
+ p = encode_mode(statp->st_mode, buf);
+ n = sprintf(p, " %2d ", (uint32_t)statp->st_nlink);
+ p += n;
+ n = sprintf(p, "%-8.8s %-8.8s", getuser(statp->st_uid), getgroup(statp->st_gid));
+ p += n;
+ n = sprintf(p, "%8.8s ", edit_uint64(statp->st_size, ec1));
+ p += n;
+ p = encode_time(statp->st_ctime, p);
+ *p++ = ' ';
+ *p++ = ' ';
+ /* Copy file name */
+ for (f=fname; *f && (p-buf) < (int)sizeof(buf); )
+ *p++ = *f++;
+ if (type == FT_LNK) {
+ *p++ = ' ';
+ *p++ = '-';
+ *p++ = '>';
+ *p++ = ' ';
+ /* Copy link name */
+ for (f=link; *f && (p-buf) < (int)sizeof(buf); )
+ *p++ = *f++;
+ }
+ *p++ = '\n';
+ *p = 0;
+ fputs(buf, stdout);
+}
uint32_t new_VolSessionId();
/* From acquire.c */
-int acquire_device_for_append(JCR *jcr, DEVICE *dev, DEV_BLOCK *block);
-int acquire_device_for_read(JCR *jcr, DEVICE *dev, DEV_BLOCK *block);
-int ready_dev_for_read(JCR *jcr, DEVICE *dev, DEV_BLOCK *block);
-int release_device(JCR *jcr, DEVICE *dev, DEV_BLOCK *block);
+int acquire_device_for_append(JCR *jcr, DEVICE *dev, DEV_BLOCK *block);
+int acquire_device_for_read(JCR *jcr, DEVICE *dev, DEV_BLOCK *block);
+int ready_dev_for_read(JCR *jcr, DEVICE *dev, DEV_BLOCK *block);
+int release_device(JCR *jcr, DEVICE *dev, DEV_BLOCK *block);
/* From askdir.c */
-int dir_get_volume_info(JCR *jcr);
-int dir_find_next_appendable_volume(JCR *jcr);
-int dir_update_volume_info(JCR *jcr, VOLUME_CAT_INFO *vol, int relabel);
-int dir_ask_sysop_to_mount_next_volume(JCR *jcr, DEVICE *dev);
-int dir_ask_sysop_to_mount_volume(JCR *jcr, DEVICE *dev);
-int dir_update_file_attributes(JCR *jcr, DEV_RECORD *rec);
-int dir_send_job_status(JCR *jcr);
-int dir_create_jobmedia_record(JCR *jcr);
+int dir_get_volume_info(JCR *jcr);
+int dir_find_next_appendable_volume(JCR *jcr);
+int dir_update_volume_info(JCR *jcr, VOLUME_CAT_INFO *vol, int relabel);
+int dir_ask_sysop_to_mount_next_volume(JCR *jcr, DEVICE *dev);
+int dir_ask_sysop_to_mount_volume(JCR *jcr, DEVICE *dev);
+int dir_update_file_attributes(JCR *jcr, DEV_RECORD *rec);
+int dir_send_job_status(JCR *jcr);
+int dir_create_jobmedia_record(JCR *jcr);
/* authenticate.c */
-int authenticate_director(JCR *jcr);
-int authenticate_filed(JCR *jcr);
+int authenticate_director(JCR *jcr);
+int authenticate_filed(JCR *jcr);
/* From block.c */
-void dump_block(DEV_BLOCK *b, char *msg);
+void dump_block(DEV_BLOCK *b, char *msg);
DEV_BLOCK *new_block(DEVICE *dev);
-void init_block_write(DEV_BLOCK *block);
-void empty_block(DEV_BLOCK *block);
-void free_block(DEV_BLOCK *block);
-int write_block_to_device(JCR *jcr, DEVICE *dev, DEV_BLOCK *block);
-int write_block_to_dev(DEVICE *dev, DEV_BLOCK *block);
-int read_block_from_device(DEVICE *dev, DEV_BLOCK *block);
-int read_block_from_dev(DEVICE *dev, DEV_BLOCK *block);
+void init_block_write(DEV_BLOCK *block);
+void empty_block(DEV_BLOCK *block);
+void free_block(DEV_BLOCK *block);
+int write_block_to_device(JCR *jcr, DEVICE *dev, DEV_BLOCK *block);
+int write_block_to_dev(DEVICE *dev, DEV_BLOCK *block);
+int read_block_from_device(DEVICE *dev, DEV_BLOCK *block);
+int read_block_from_dev(DEVICE *dev, DEV_BLOCK *block);
+
+/* From butil.c */
+void print_ls_output(char *fname, char *link, int type, struct stat *statp);
+JCR *setup_jcr(char *name, char *device, BSR *bsr);
+DEVICE *setup_to_read_device(JCR *jcr);
/* From dev.c */
-DEVICE *init_dev(DEVICE *dev, char *device);
-int open_dev(DEVICE *dev, char *VolName, int mode);
-void close_dev(DEVICE *dev);
-void force_close_dev(DEVICE *dev);
-int truncate_dev(DEVICE *dev);
-void term_dev(DEVICE *dev);
-char * strerror_dev(DEVICE *dev);
-void clrerror_dev(DEVICE *dev, int func);
-int update_pos_dev(DEVICE *dev);
-int rewind_dev(DEVICE *dev);
-int load_dev(DEVICE *dev);
-int offline_dev(DEVICE *dev);
-int flush_dev(DEVICE *dev);
-int weof_dev(DEVICE *dev, int num);
-int write_block(DEVICE *dev);
-int write_dev(DEVICE *dev, char *buf, size_t len);
-int read_dev(DEVICE *dev, char *buf, size_t len);
-int status_dev(DEVICE *dev, uint32_t *status);
-int eod_dev(DEVICE *dev);
-int fsf_dev(DEVICE *dev, int num);
-int fsr_dev(DEVICE *dev, int num);
-int bsf_dev(DEVICE *dev, int num);
-int bsr_dev(DEVICE *dev, int num);
-void attach_jcr_to_device(DEVICE *dev, JCR *jcr);
-void detach_jcr_from_device(DEVICE *dev, JCR *jcr);
-JCR *next_attached_jcr(DEVICE *dev, JCR *jcr);
+DEVICE *init_dev(DEVICE *dev, char *device);
+int open_dev(DEVICE *dev, char *VolName, int mode);
+void close_dev(DEVICE *dev);
+void force_close_dev(DEVICE *dev);
+int truncate_dev(DEVICE *dev);
+void term_dev(DEVICE *dev);
+char * strerror_dev(DEVICE *dev);
+void clrerror_dev(DEVICE *dev, int func);
+int update_pos_dev(DEVICE *dev);
+int rewind_dev(DEVICE *dev);
+int load_dev(DEVICE *dev);
+int offline_dev(DEVICE *dev);
+int flush_dev(DEVICE *dev);
+int weof_dev(DEVICE *dev, int num);
+int write_block(DEVICE *dev);
+int write_dev(DEVICE *dev, char *buf, size_t len);
+int read_dev(DEVICE *dev, char *buf, size_t len);
+int status_dev(DEVICE *dev, uint32_t *status);
+int eod_dev(DEVICE *dev);
+int fsf_dev(DEVICE *dev, int num);
+int fsr_dev(DEVICE *dev, int num);
+int bsf_dev(DEVICE *dev, int num);
+int bsr_dev(DEVICE *dev, int num);
+void attach_jcr_to_device(DEVICE *dev, JCR *jcr);
+void detach_jcr_from_device(DEVICE *dev, JCR *jcr);
+JCR *next_attached_jcr(DEVICE *dev, JCR *jcr);
/* Get info about device */
-char * dev_name(DEVICE *dev);
-char * dev_vol_name(DEVICE *dev);
+char * dev_name(DEVICE *dev);
+char * dev_vol_name(DEVICE *dev);
uint32_t dev_block(DEVICE *dev);
uint32_t dev_file(DEVICE *dev);
-int dev_is_tape(DEVICE *dev);
+int dev_is_tape(DEVICE *dev);
/* From device.c */
-int open_device(DEVICE *dev);
-int fixup_device_block_write_error(JCR *jcr, DEVICE *dev, DEV_BLOCK *block);
+int open_device(DEVICE *dev);
+int fixup_device_block_write_error(JCR *jcr, DEVICE *dev, DEV_BLOCK *block);
void _lock_device(char *file, int line, DEVICE *dev);
void _unlock_device(char *file, int line, DEVICE *dev);
void _block_device(char *file, int line, DEVICE *dev, int state);
void new_return_device_lock(DEVICE *dev, brwsteal_t *hold);
/* From dircmd.c */
-void connection_request(void *arg);
+void connection_request(void *arg);
/* From fd_cmds.c */
-void run_job(JCR *jcr);
+void run_job(JCR *jcr);
/* From fdmsg.c */
-int bget_msg(BSOCK *sock);
+int bget_msg(BSOCK *sock);
/* From job.c */
-void stored_free_jcr(JCR *jcr);
-void connection_from_filed(void *arg);
-void handle_filed_connection(BSOCK *fd, char *job_name);
+void stored_free_jcr(JCR *jcr);
+void connection_from_filed(void *arg);
+void handle_filed_connection(BSOCK *fd, char *job_name);
/* From label.c */
-int read_dev_volume_label(JCR *jcr, DEVICE *dev, DEV_BLOCK *block);
-void create_session_label(JCR *jcr, DEV_RECORD *rec, int label);
-int write_volume_label_to_dev(JCR *jcr, DEVRES *device, char *VolName, char *PoolName);
-int write_session_label(JCR *jcr, DEV_BLOCK *block, int label);
-int write_volume_label_to_block(JCR *jcr, DEVICE *dev, DEV_BLOCK *block);
-void dump_volume_label(DEVICE *dev);
-void dump_label_record(DEVICE *dev, DEV_RECORD *rec, int verbose);
-int unser_volume_label(DEVICE *dev, DEV_RECORD *rec);
-int unser_session_label(SESSION_LABEL *label, DEV_RECORD *rec);
+int read_dev_volume_label(JCR *jcr, DEVICE *dev, DEV_BLOCK *block);
+void create_session_label(JCR *jcr, DEV_RECORD *rec, int label);
+int write_volume_label_to_dev(JCR *jcr, DEVRES *device, char *VolName, char *PoolName);
+int write_session_label(JCR *jcr, DEV_BLOCK *block, int label);
+int write_volume_label_to_block(JCR *jcr, DEVICE *dev, DEV_BLOCK *block);
+void dump_volume_label(DEVICE *dev);
+void dump_label_record(DEVICE *dev, DEV_RECORD *rec, int verbose);
+int unser_volume_label(DEVICE *dev, DEV_RECORD *rec);
+int unser_session_label(SESSION_LABEL *label, DEV_RECORD *rec);
/* From match_bsr.c */
int match_bsr(BSR *bsr, DEV_RECORD *rec, VOLUME_LABEL *volrec,
- SESSION_LABEL *sesrec);
+ SESSION_LABEL *sesrec);
/* From mount.c */
-int mount_next_write_volume(JCR *jcr, DEVICE *dev, DEV_BLOCK *block, int release);
-int mount_next_read_volume(JCR *jcr, DEVICE *dev, DEV_BLOCK *block);
+int mount_next_write_volume(JCR *jcr, DEVICE *dev, DEV_BLOCK *block, int release);
+int mount_next_read_volume(JCR *jcr, DEVICE *dev, DEV_BLOCK *block);
/* From parse_bsr.c */
/* From record.c */
char *FI_to_ascii(int fi);
char *stream_to_ascii(int stream);
-int write_record_to_block(DEV_BLOCK *block, DEV_RECORD *rec);
-int can_write_record_to_block(DEV_BLOCK *block, DEV_RECORD *rec);
-int read_record_from_block(DEV_BLOCK *block, DEV_RECORD *rec);
+int write_record_to_block(DEV_BLOCK *block, DEV_RECORD *rec);
+int can_write_record_to_block(DEV_BLOCK *block, DEV_RECORD *rec);
+int read_record_from_block(DEV_BLOCK *block, DEV_RECORD *rec);
DEV_RECORD *new_record();
-void free_record(DEV_RECORD *rec);
+void free_record(DEV_RECORD *rec);
/* */
-#define VERSION "1.25a"
+#define VERSION "1.26"
#define VSTRING "1"
#define DATE "05 September 2002"
#define LSMDATE "05Sep02"