2 Bacula® - The Network Backup Solution
4 Copyright (C) 2000-2014 Free Software Foundation Europe e.V.
6 The main author of Bacula is Kern Sibbald, with contributions from many
7 others, a complete list can be found in the file AUTHORS.
9 You may use this file and others of this release according to the
10 license defined in the LICENSE file, which includes the Affero General
11 Public License, v3.0 ("AGPLv3") and some additional permissions and
12 terms pursuant to its AGPLv3 Section 7.
14 Bacula® is a registered trademark of Kern Sibbald.
18 * Utility routines for "tool" programs such as bscan, bls,
19 * bextract, ... Some routines also used by Bacula.
23 * Normally nothing in this file is called by the Storage
24 * daemon because we interact more directly with the user
32 /* Forward referenced functions */
33 static DCR *setup_to_access_device(JCR *jcr, char *dev_name, const char *VolumeName, bool writing);
34 static DEVRES *find_device_res(char *device_name, bool writing);
35 static void my_free_jcr(JCR *jcr);
37 /* Imported variables -- eliminate some day */
38 extern char *configfile;
41 char *rec_state_bits_to_str(DEV_RECORD *rec)
45 if (rec->state_bits & REC_NO_HEADER) {
46 strcat(buf, _("Nohdr,"));
48 if (is_partial_record(rec)) {
49 strcat(buf, _("partial,"));
51 if (rec->state_bits & REC_BLOCK_EMPTY) {
52 strcat(buf, _("empty,"));
54 if (rec->state_bits & REC_NO_MATCH) {
55 strcat(buf, _("Nomatch,"));
57 if (rec->state_bits & REC_CONTINUATION) {
58 strcat(buf, _("cont,"));
61 buf[strlen(buf)-1] = 0;
68 * Setup a pointer to my resource me
73 me = (STORES *)GetNextRes(R_STORAGE, NULL);
76 Emsg1(M_ERROR_TERM, 0, _("No Storage resource defined in %s. Cannot continue.\n"),
83 * Setup a "daemon" JCR for the various standalone
84 * tools (e.g. bls, bextract, bscan, ...)
86 JCR *setup_jcr(const char *name, char *dev_name, BSR *bsr,
87 const char *VolumeName, bool writing)
90 JCR *jcr = new_jcr(sizeof(JCR), my_free_jcr);
92 jcr->VolSessionId = 1;
93 jcr->VolSessionTime = (uint32_t)time(NULL);
94 jcr->NumReadVolumes = 0;
95 jcr->NumWriteVolumes = 0;
97 jcr->setJobType(JT_CONSOLE);
98 jcr->setJobLevel(L_FULL);
99 jcr->JobStatus = JS_Terminated;
100 jcr->where = bstrdup("");
101 jcr->job_name = get_pool_memory(PM_FNAME);
102 pm_strcpy(jcr->job_name, "Dummy.Job.Name");
103 jcr->client_name = get_pool_memory(PM_FNAME);
104 pm_strcpy(jcr->client_name, "Dummy.Client.Name");
105 bstrncpy(jcr->Job, name, sizeof(jcr->Job));
106 jcr->fileset_name = get_pool_memory(PM_FNAME);
107 pm_strcpy(jcr->fileset_name, "Dummy.fileset.name");
108 jcr->fileset_md5 = get_pool_memory(PM_FNAME);
109 pm_strcpy(jcr->fileset_md5, "Dummy.fileset.md5");
111 create_volume_lists();
113 dcr = setup_to_access_device(jcr, dev_name, VolumeName, writing);
117 if (!bsr && VolumeName) {
118 bstrncpy(dcr->VolumeName, VolumeName, sizeof(dcr->VolumeName));
120 bstrncpy(dcr->pool_name, "Default", sizeof(dcr->pool_name));
121 bstrncpy(dcr->pool_type, "Backup", sizeof(dcr->pool_type));
126 * Setup device, jcr, and prepare to access device.
127 * If the caller wants read access, acquire the device, otherwise,
128 * the caller will do it.
130 static DCR *setup_to_access_device(JCR *jcr, char *dev_name,
131 const char *VolumeName, bool writing)
137 char VolName[MAX_NAME_LENGTH];
139 init_reservations_lock();
142 * If no volume name already given and no bsr, and it is a file,
143 * try getting name from Filename
146 bstrncpy(VolName, VolumeName, sizeof(VolName));
147 if (strlen(VolumeName) >= MAX_NAME_LENGTH) {
148 Jmsg0(jcr, M_ERROR, 0, _("Volume name or names is too long. Please use a .bsr file.\n"));
153 if (!jcr->bsr && VolName[0] == 0) {
154 if (strncmp(dev_name, "/dev/", 5) != 0) {
155 /* Try stripping file part */
156 p = dev_name + strlen(dev_name);
158 while (p >= dev_name && !IsPathSeparator(*p))
160 if (IsPathSeparator(*p)) {
161 bstrncpy(VolName, p+1, sizeof(VolName));
167 if ((device=find_device_res(dev_name, writing)) == NULL) {
168 Jmsg2(jcr, M_FATAL, 0, _("Cannot find device \"%s\" in config file %s.\n"),
169 dev_name, configfile);
173 dev = init_dev(jcr, device);
175 Jmsg1(jcr, M_FATAL, 0, _("Cannot init device %s\n"), dev_name);
179 jcr->dcr = dcr = new_dcr(jcr, NULL, dev, writing);
181 bstrncpy(dcr->VolumeName, VolName, sizeof(dcr->VolumeName));
183 bstrncpy(dcr->dev_name, device->device_name, sizeof(dcr->dev_name));
185 create_restore_volume_list(jcr);
187 if (!writing) { /* read only access? */
188 Dmsg0(100, "Acquire device for read\n");
189 if (!acquire_device_for_read(dcr)) {
194 if (!first_open_device(dcr)) {
195 Jmsg1(jcr, M_FATAL, 0, _("Cannot open %s\n"), dev->print_name());
198 jcr->dcr = dcr; /* write dcr */
205 * Called here when freeing JCR so that we can get rid
206 * of "daemon" specific memory allocated.
208 static void my_free_jcr(JCR *jcr)
211 free_pool_memory(jcr->job_name);
212 jcr->job_name = NULL;
214 if (jcr->client_name) {
215 free_pool_memory(jcr->client_name);
216 jcr->client_name = NULL;
218 if (jcr->fileset_name) {
219 free_pool_memory(jcr->fileset_name);
220 jcr->fileset_name = NULL;
222 if (jcr->fileset_md5) {
223 free_pool_memory(jcr->fileset_md5);
224 jcr->fileset_md5 = NULL;
227 free_pool_memory(jcr->comment);
231 free_restore_volume_list(jcr);
242 * Search for device resource that corresponds to
243 * device name on command line (or default).
245 * Returns: NULL on failure
246 * Device resource pointer on success
248 static DEVRES *find_device_res(char *device_name, bool write_access)
253 Dmsg0(900, "Enter find_device_res\n");
255 foreach_res(device, R_DEVICE) {
256 Dmsg2(900, "Compare %s and %s\n", device->device_name, device_name);
257 if (strcmp(device->device_name, device_name) == 0) {
263 /* Search for name of Device resource rather than archive name */
264 if (device_name[0] == '"') {
265 int len = strlen(device_name);
266 bstrncpy(device_name, device_name+1, len+1);
269 device_name[len-1] = 0; /* zap trailing " */
272 foreach_res(device, R_DEVICE) {
273 Dmsg2(900, "Compare %s and %s\n", device->hdr.name, device_name);
274 if (strcmp(device->hdr.name, device_name) == 0) {
282 Pmsg2(0, _("Could not find device \"%s\" in config file %s.\n"), device_name,
287 Pmsg1(0, _("Using device: \"%s\" for writing.\n"), device_name);
289 Pmsg1(0, _("Using device: \"%s\" for reading.\n"), device_name);
296 * Device got an error, attempt to analyse it
298 void display_tape_error_status(JCR *jcr, DEVICE *dev)
302 status = status_dev(dev);
303 Dmsg1(20, "Device status: %x\n", status);
304 if (status & BMT_EOD)
305 Jmsg(jcr, M_ERROR, 0, _("Unexpected End of Data\n"));
306 else if (status & BMT_EOT)
307 Jmsg(jcr, M_ERROR, 0, _("Unexpected End of Tape\n"));
308 else if (status & BMT_EOF)
309 Jmsg(jcr, M_ERROR, 0, _("Unexpected End of File\n"));
310 else if (status & BMT_DR_OPEN)
311 Jmsg(jcr, M_ERROR, 0, _("Tape Door is Open\n"));
312 else if (!(status & BMT_ONLINE))
313 Jmsg(jcr, M_ERROR, 0, _("Unexpected Tape is Off-line\n"));