2 Bacula(R) - The Network Backup Solution
4 Copyright (C) 2000-2017 Kern Sibbald
6 The original author of Bacula is Kern Sibbald, with contributions
7 from many 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 This notice must be preserved when any source code is
15 conveyed and/or propagated.
17 Bacula(R) is a registered trademark of Kern Sibbald.
21 * ansi_label.c routines to handle ANSI (and perhaps one day IBM)
27 #include "bacula.h" /* pull in global headers */
28 #include "stored.h" /* pull in Storage Deamon headers */
30 /* Imported functions */
31 void ascii_to_ebcdic(char *dst, char *src, int count);
32 void ebcdic_to_ascii(char *dst, char *src, int count);
34 /* Forward referenced functions */
35 static char *ansi_date(time_t td, char *buf);
36 static bool same_label_names(char *bacula_name, char *ansi_name);
39 * We read an ANSI label and compare the Volume name. We require
40 * a VOL1 record of 80 characters followed by a HDR1 record containing
41 * BACULA.DATA in the filename field. We then read up to 3 more
42 * header records (they are not required) and an EOF, at which
46 * VOL_OK Volume name OK
47 * VOL_NO_LABEL No ANSI label on Volume
48 * VOL_IO_ERROR I/O error on read
49 * VOL_NAME_ERROR Wrong name in VOL1 record
50 * VOL_LABEL_ERROR Probably an ANSI label, but something wrong
53 int read_ansi_ibm_label(DCR *dcr)
55 DEVICE * volatile dev = dcr->dev;
57 char label[80]; /* tape label */
59 char *VolName = dcr->VolumeName;
63 * Read VOL1, HDR1, HDR2 labels, but ignore the data
64 * If tape read the following EOF mark, on disk do
67 Dmsg0(100, "Read ansi label.\n");
68 if (!dev->is_tape()) {
72 dev->label_type = B_BACULA_LABEL; /* assume Bacula label */
74 /* Read a maximum of 5 records VOL1, HDR1, ... HDR4 */
75 for (i=0; i < 6; i++) {
77 stat = dev->read(label, sizeof(label));
78 } while (stat == -1 && errno == EINTR);
82 Dmsg1(100, "Read device got: ERR=%s\n", be.bstrerror());
83 Mmsg2(jcr->errmsg, _("Read error on device %s in ANSI label. ERR=%s\n"),
84 dev->dev_name, be.bstrerror());
85 Jmsg(jcr, M_ERROR, 0, "%s", dev->errmsg);
86 dev->VolCatInfo.VolCatErrors++;
91 dev->set_eot(); /* second eof, set eot bit */
92 Dmsg0(100, "EOM on ANSI label\n");
93 Mmsg0(jcr->errmsg, _("Insane! End of tape while reading ANSI label.\n"));
94 return VOL_LABEL_ERROR; /* at EOM this shouldn't happen */
96 dev->set_ateof(); /* set eof state */
100 case 0: /* Want VOL1 label */
102 if (strncmp("VOL1", label, 4) == 0) {
104 dev->label_type = B_ANSI_LABEL;
105 Dmsg0(100, "Got ANSI VOL1 label\n");
108 ebcdic_to_ascii(label, label, sizeof(label));
109 if (strncmp("VOL1", label, 4) == 0) {
111 dev->label_type = B_IBM_LABEL;
112 Dmsg0(100, "Found IBM label.\n");
113 Dmsg0(100, "Got IBM VOL1 label\n");
118 Dmsg0(100, "No VOL1 label\n");
119 Mmsg0(jcr->errmsg, _("No VOL1 label while reading ANSI/IBM label.\n"));
120 return VOL_NO_LABEL; /* No ANSI label */
124 /* Compare Volume Names allow special wild card */
125 if (VolName && *VolName && *VolName != '*') {
126 if (!same_label_names(VolName, &label[4])) {
131 /* Store new Volume name */
132 q = dev->VolHdr.VolumeName;
133 for (int i=0; *p != ' ' && i < 6; i++) {
137 Dmsg0(100, "Call reserve_volume\n");
138 /* ***FIXME*** why is this reserve_volume() needed???? KES */
139 reserve_volume(dcr, dev->VolHdr.VolumeName);
140 dev = dcr->dev; /* may have changed in reserve_volume */
141 Dmsg2(100, "Wanted ANSI Vol %s got %6s\n", VolName, dev->VolHdr.VolumeName);
142 Mmsg2(jcr->errmsg, _("Wanted ANSI Volume \"%s\" got \"%s\"\n"), VolName, dev->VolHdr.VolumeName);
143 return VOL_NAME_ERROR;
148 if (dev->label_type == B_IBM_LABEL) {
149 ebcdic_to_ascii(label, label, sizeof(label));
151 if (stat != 80 || strncmp("HDR1", label, 4) != 0) {
152 Dmsg0(100, "No HDR1 label\n");
153 Mmsg0(jcr->errmsg, _("No HDR1 label while reading ANSI label.\n"));
154 return VOL_LABEL_ERROR;
156 if (strncmp("BACULA.DATA", &label[4], 11) != 0) {
157 Dmsg1(100, "HD1 not Bacula label. Wanted BACULA.DATA got %11s\n",
159 Mmsg1(jcr->errmsg, _("ANSI/IBM Volume \"%s\" does not belong to Bacula.\n"),
160 dev->VolHdr.VolumeName);
161 return VOL_NAME_ERROR; /* Not a Bacula label */
163 Dmsg0(100, "Got HDR1 label\n");
166 if (dev->label_type == B_IBM_LABEL) {
167 ebcdic_to_ascii(label, label, sizeof(label));
169 if (stat != 80 || strncmp("HDR2", label, 4) != 0) {
170 Dmsg0(100, "No HDR2 label\n");
171 Mmsg0(jcr->errmsg, _("No HDR2 label while reading ANSI/IBM label.\n"));
172 return VOL_LABEL_ERROR;
174 Dmsg0(100, "Got ANSI HDR2 label\n");
178 Dmsg0(100, "ANSI label OK\n");
181 if (dev->label_type == B_IBM_LABEL) {
182 ebcdic_to_ascii(label, label, sizeof(label));
184 if (stat != 80 || strncmp("HDR", label, 3) != 0) {
185 Dmsg0(100, "Unknown or bad ANSI/IBM label record.\n");
186 Mmsg0(jcr->errmsg, _("Unknown or bad ANSI/IBM label record.\n"));
187 return VOL_LABEL_ERROR;
189 Dmsg0(100, "Got HDR label\n");
193 Dmsg0(100, "Too many records in ANSI/IBM label.\n");
194 Mmsg0(jcr->errmsg, _("Too many records in while reading ANSI/IBM label.\n"));
195 return VOL_LABEL_ERROR;
199 * ANSI/IBM VOL1 label
200 * 80 characters blank filled
201 * Pos count Function What Bacula puts
203 * 4-9 6 Volume name Volume name
204 * 10-10 1 Access code
219 * ANSI/IBM HDR1 label
220 * 80 characters blank filled
221 * Pos count Function What Bacula puts
223 * 4-20 17 File name BACULA.DATA
224 * 21-26 6 Volume name Volume name
225 * 27-30 4 Vol seq num 0001
226 * 31-34 4 file num 0001
227 * 35-38 4 Generation 0001
228 * 39-40 2 Gen version 00
229 * 41-46 6 Create date bYYDDD yesterday
230 * 47-52 6 Expire date bYYDDD today
232 * 54-59 6 Block count 000000
233 * 60-72 13 Software name Bacula
236 * ANSI/IBM HDR2 label
237 * 80 characters blank filled
238 * Pos count Function What Bacula puts
240 * 4-4 1 Record format D (V if IBM) => variable
241 * 5-9 5 Block length 32000
242 * 10-14 5 Rec length 32000
249 * 38-38 1 Blocked flag
256 static const char *labels[] = {"HDR", "EOF", "EOV"};
259 * Write an ANSI or IBM 80 character tape label
260 * Type determines whether we are writing HDR, EOF, or EOV labels
261 * Assume we are positioned to write the labels
262 * Returns: true of OK
265 bool write_ansi_ibm_labels(DCR *dcr, int type, const char *VolName)
267 DEVICE *dev = dcr->dev;
269 char ansi_volname[7]; /* 6 char + \0 */
270 char label[80]; /* tape label */
271 char date[20]; /* ansi date buffer */
273 int len, stat, label_type;
276 * If the Device requires a specific label type use it,
277 * otherwise, use the type requested by the Director
279 if (dcr->device->label_type != B_BACULA_LABEL) {
280 label_type = dcr->device->label_type; /* force label type */
282 label_type = dcr->VolCatInfo.LabelType; /* accept Dir type */
285 switch (label_type) {
291 Dmsg1(100, "Write ANSI label type=%d\n", label_type);
292 len = strlen(VolName);
294 Jmsg1(jcr, M_FATAL, 0, _("ANSI Volume label name \"%s\" longer than 6 chars.\n"),
298 /* ANSI labels have 6 characters, and are padded with spaces
299 * 'vol1\0' => 'vol1 \0'
301 strcpy(ansi_volname, VolName);
302 for(int i=len; i < 6; i++) {
305 ansi_volname[6]='\0'; /* only for debug */
307 if (type == ANSI_VOL_LABEL) {
308 ser_begin(label, sizeof(label));
309 ser_bytes("VOL1", 4);
310 ser_bytes(ansi_volname, 6);
311 /* Write VOL1 label */
312 if (label_type == B_IBM_LABEL) {
313 ascii_to_ebcdic(label, label, sizeof(label));
315 label[79] = '3'; /* ANSI label flag */
317 stat = dev->write(label, sizeof(label));
318 if (stat != sizeof(label)) {
320 Jmsg3(jcr, M_FATAL, 0, _("Could not write ANSI VOL1 label. Wanted size=%d got=%d ERR=%s\n"),
321 sizeof(label), stat, be.bstrerror());
326 /* Now construct HDR1 label */
327 memset(label, ' ', sizeof(label));
328 ser_begin(label, sizeof(label));
329 ser_bytes(labels[type], 3);
331 ser_bytes("BACULA.DATA", 11); /* Filename field */
332 ser_begin(&label[21], sizeof(label)-21); /* fileset field */
333 ser_bytes(ansi_volname, 6); /* write Vol Ser No. */
334 ser_begin(&label[27], sizeof(label)-27);
335 ser_bytes("00010001000100", 14); /* File section, File seq no, Generation no */
337 ser_bytes(ansi_date(now, date), 6); /* current date */
338 ser_bytes(ansi_date(now - 24 * 3600, date), 6); /* created yesterday */
339 ser_bytes(" 000000Bacula ", 27);
340 /* Write HDR1 label */
341 if (label_type == B_IBM_LABEL) {
342 ascii_to_ebcdic(label, label, sizeof(label));
346 * This could come at the end of a tape, ignore
349 stat = dev->write(label, sizeof(label));
350 if (stat != sizeof(label)) {
354 if (dev->dev_errno == 0) {
355 dev->dev_errno = ENOSPC; /* out of space */
357 if (dev->dev_errno != ENOSPC) {
358 Jmsg1(jcr, M_FATAL, 0, _("Could not write ANSI HDR1 label. ERR=%s\n"),
363 Jmsg(jcr, M_FATAL, 0, _("Could not write ANSI HDR1 label.\n"));
368 /* Now construct HDR2 label */
369 memset(label, ' ', sizeof(label));
370 ser_begin(label, sizeof(label));
371 ser_bytes(labels[type], 3);
372 ser_bytes("2D3200032000", 12);
373 /* Write HDR2 label */
374 if (label_type == B_IBM_LABEL) {
376 ascii_to_ebcdic(label, label, sizeof(label));
378 stat = dev->write(label, sizeof(label));
379 if (stat != sizeof(label)) {
383 if (dev->dev_errno == 0) {
384 dev->dev_errno = ENOSPC; /* out of space */
386 if (dev->dev_errno != ENOSPC) {
387 Jmsg1(jcr, M_FATAL, 0, _("Could not write ANSI HDR1 label. ERR=%s\n"),
394 Jmsg(jcr, M_FATAL, 0, _("Could not write ANSI HDR1 label.\n"));
398 if (!dev->weof(NULL, 1)) {
399 Jmsg(jcr, M_FATAL, 0, _("Error writing EOF to tape. ERR=%s"), dev->errmsg);
404 Jmsg0(jcr, M_ABORT, 0, _("write_ansi_ibm_label called for non-ANSI/IBM type\n"));
405 return false; /* should not get here */
409 /* Check a Bacula Volume name against an ANSI Volume name */
410 static bool same_label_names(char *bacula_name, char *ansi_name)
413 char *b = bacula_name;
414 /* Six characters max */
415 for (int i=0; i < 6; i++) {
421 /* ANSI labels are blank filled, Bacula's are zero terminated */
422 if (*a == ' ' && *b == 0) {
427 /* Reached 6 characters */
439 static char *ansi_date(time_t td, char *buf)
447 bsnprintf(buf, 10, " %05d ", 1000 * (tm->tm_year + 1900 - 2000) + tm->tm_yday);