2 Bacula(R) - The Network Backup Solution
4 Copyright (C) 2000-2015 Kern Sibbald
5 Copyright (C) 2005-2014 Free Software Foundation Europe e.V.
7 The original author of Bacula is Kern Sibbald, with contributions
8 from many others, a complete list can be found in the file AUTHORS.
10 You may use this file and others of this release according to the
11 license defined in the LICENSE file, which includes the Affero General
12 Public License, v3.0 ("AGPLv3") and some additional permissions and
13 terms pursuant to its AGPLv3 Section 7.
15 This notice must be preserved when any source code is
16 conveyed and/or propagated.
18 Bacula(R) is a registered trademark of Kern Sibbald.
22 * ansi_label.c routines to handle ANSI (and perhaps one day IBM)
29 #include "bacula.h" /* pull in global headers */
30 #include "stored.h" /* pull in Storage Deamon headers */
32 /* Imported functions */
33 void ascii_to_ebcdic(char *dst, char *src, int count);
34 void ebcdic_to_ascii(char *dst, char *src, int count);
36 /* Forward referenced functions */
37 static char *ansi_date(time_t td, char *buf);
38 static bool same_label_names(char *bacula_name, char *ansi_name);
41 * We read an ANSI label and compare the Volume name. We require
42 * a VOL1 record of 80 characters followed by a HDR1 record containing
43 * BACULA.DATA in the filename field. We then read up to 3 more
44 * header records (they are not required) and an EOF, at which
48 * VOL_OK Volume name OK
49 * VOL_NO_LABEL No ANSI label on Volume
50 * VOL_IO_ERROR I/O error on read
51 * VOL_NAME_ERROR Wrong name in VOL1 record
52 * VOL_LABEL_ERROR Probably an ANSI label, but something wrong
55 int read_ansi_ibm_label(DCR *dcr)
57 DEVICE * volatile dev = dcr->dev;
59 char label[80]; /* tape label */
61 char *VolName = dcr->VolumeName;
65 * Read VOL1, HDR1, HDR2 labels, but ignore the data
66 * If tape read the following EOF mark, on disk do
69 Dmsg0(100, "Read ansi label.\n");
70 if (!dev->is_tape()) {
74 dev->label_type = B_BACULA_LABEL; /* assume Bacula label */
76 /* Read a maximum of 5 records VOL1, HDR1, ... HDR4 */
77 for (i=0; i < 6; i++) {
79 stat = dev->read(label, sizeof(label));
80 } while (stat == -1 && errno == EINTR);
84 Dmsg1(100, "Read device got: ERR=%s\n", be.bstrerror());
85 Mmsg2(jcr->errmsg, _("Read error on device %s in ANSI label. ERR=%s\n"),
86 dev->dev_name, be.bstrerror());
87 Jmsg(jcr, M_ERROR, 0, "%s", dev->errmsg);
88 dev->VolCatInfo.VolCatErrors++;
93 dev->set_eot(); /* second eof, set eot bit */
94 Dmsg0(100, "EOM on ANSI label\n");
95 Mmsg0(jcr->errmsg, _("Insane! End of tape while reading ANSI label.\n"));
96 return VOL_LABEL_ERROR; /* at EOM this shouldn't happen */
98 dev->set_ateof(); /* set eof state */
102 case 0: /* Want VOL1 label */
104 if (strncmp("VOL1", label, 4) == 0) {
106 dev->label_type = B_ANSI_LABEL;
107 Dmsg0(100, "Got ANSI VOL1 label\n");
110 ebcdic_to_ascii(label, label, sizeof(label));
111 if (strncmp("VOL1", label, 4) == 0) {
113 dev->label_type = B_IBM_LABEL;
114 Dmsg0(100, "Found IBM label.\n");
115 Dmsg0(100, "Got IBM VOL1 label\n");
120 Dmsg0(100, "No VOL1 label\n");
121 Mmsg0(jcr->errmsg, _("No VOL1 label while reading ANSI/IBM label.\n"));
122 return VOL_NO_LABEL; /* No ANSI label */
126 /* Compare Volume Names allow special wild card */
127 if (VolName && *VolName && *VolName != '*') {
128 if (!same_label_names(VolName, &label[4])) {
133 /* Store new Volume name */
134 q = dev->VolHdr.VolumeName;
135 for (int i=0; *p != ' ' && i < 6; i++) {
139 Dmsg0(100, "Call reserve_volume\n");
140 /* ***FIXME*** why is this reserve_volume() needed???? KES */
141 reserve_volume(dcr, dev->VolHdr.VolumeName);
142 dev = dcr->dev; /* may have changed in reserve_volume */
143 Dmsg2(100, "Wanted ANSI Vol %s got %6s\n", VolName, dev->VolHdr.VolumeName);
144 Mmsg2(jcr->errmsg, _("Wanted ANSI Volume \"%s\" got \"%s\"\n"), VolName, dev->VolHdr.VolumeName);
145 return VOL_NAME_ERROR;
150 if (dev->label_type == B_IBM_LABEL) {
151 ebcdic_to_ascii(label, label, sizeof(label));
153 if (stat != 80 || strncmp("HDR1", label, 4) != 0) {
154 Dmsg0(100, "No HDR1 label\n");
155 Mmsg0(jcr->errmsg, _("No HDR1 label while reading ANSI label.\n"));
156 return VOL_LABEL_ERROR;
158 if (strncmp("BACULA.DATA", &label[4], 11) != 0) {
159 Dmsg1(100, "HD1 not Bacula label. Wanted BACULA.DATA got %11s\n",
161 Mmsg1(jcr->errmsg, _("ANSI/IBM Volume \"%s\" does not belong to Bacula.\n"),
162 dev->VolHdr.VolumeName);
163 return VOL_NAME_ERROR; /* Not a Bacula label */
165 Dmsg0(100, "Got HDR1 label\n");
168 if (dev->label_type == B_IBM_LABEL) {
169 ebcdic_to_ascii(label, label, sizeof(label));
171 if (stat != 80 || strncmp("HDR2", label, 4) != 0) {
172 Dmsg0(100, "No HDR2 label\n");
173 Mmsg0(jcr->errmsg, _("No HDR2 label while reading ANSI/IBM label.\n"));
174 return VOL_LABEL_ERROR;
176 Dmsg0(100, "Got ANSI HDR2 label\n");
180 Dmsg0(100, "ANSI label OK\n");
183 if (dev->label_type == B_IBM_LABEL) {
184 ebcdic_to_ascii(label, label, sizeof(label));
186 if (stat != 80 || strncmp("HDR", label, 3) != 0) {
187 Dmsg0(100, "Unknown or bad ANSI/IBM label record.\n");
188 Mmsg0(jcr->errmsg, _("Unknown or bad ANSI/IBM label record.\n"));
189 return VOL_LABEL_ERROR;
191 Dmsg0(100, "Got HDR label\n");
195 Dmsg0(100, "Too many records in ANSI/IBM label.\n");
196 Mmsg0(jcr->errmsg, _("Too many records in while reading ANSI/IBM label.\n"));
197 return VOL_LABEL_ERROR;
201 * ANSI/IBM VOL1 label
202 * 80 characters blank filled
203 * Pos count Function What Bacula puts
205 * 4-9 6 Volume name Volume name
206 * 10-10 1 Access code
221 * ANSI/IBM HDR1 label
222 * 80 characters blank filled
223 * Pos count Function What Bacula puts
225 * 4-20 17 File name BACULA.DATA
226 * 21-26 6 Volume name Volume name
227 * 27-30 4 Vol seq num 0001
228 * 31-34 4 file num 0001
229 * 35-38 4 Generation 0001
230 * 39-40 2 Gen version 00
231 * 41-46 6 Create date bYYDDD yesterday
232 * 47-52 6 Expire date bYYDDD today
234 * 54-59 6 Block count 000000
235 * 60-72 13 Software name Bacula
238 * ANSI/IBM HDR2 label
239 * 80 characters blank filled
240 * Pos count Function What Bacula puts
242 * 4-4 1 Record format D (V if IBM) => variable
243 * 5-9 5 Block length 32000
244 * 10-14 5 Rec length 32000
251 * 38-38 1 Blocked flag
258 static const char *labels[] = {"HDR", "EOF", "EOV"};
261 * Write an ANSI or IBM 80 character tape label
262 * Type determines whether we are writing HDR, EOF, or EOV labels
263 * Assume we are positioned to write the labels
264 * Returns: true of OK
267 bool write_ansi_ibm_labels(DCR *dcr, int type, const char *VolName)
269 DEVICE *dev = dcr->dev;
271 char ansi_volname[7]; /* 6 char + \0 */
272 char label[80]; /* tape label */
273 char date[20]; /* ansi date buffer */
275 int len, stat, label_type;
278 * If the Device requires a specific label type use it,
279 * otherwise, use the type requested by the Director
281 if (dcr->device->label_type != B_BACULA_LABEL) {
282 label_type = dcr->device->label_type; /* force label type */
284 label_type = dcr->VolCatInfo.LabelType; /* accept Dir type */
287 switch (label_type) {
293 Dmsg1(100, "Write ANSI label type=%d\n", label_type);
294 len = strlen(VolName);
296 Jmsg1(jcr, M_FATAL, 0, _("ANSI Volume label name \"%s\" longer than 6 chars.\n"),
300 /* ANSI labels have 6 characters, and are padded with spaces
301 * 'vol1\0' => 'vol1 \0'
303 strcpy(ansi_volname, VolName);
304 for(int i=len; i < 6; i++) {
307 ansi_volname[6]='\0'; /* only for debug */
309 if (type == ANSI_VOL_LABEL) {
310 ser_begin(label, sizeof(label));
311 ser_bytes("VOL1", 4);
312 ser_bytes(ansi_volname, 6);
313 /* Write VOL1 label */
314 if (label_type == B_IBM_LABEL) {
315 ascii_to_ebcdic(label, label, sizeof(label));
317 label[79] = '3'; /* ANSI label flag */
319 stat = dev->write(label, sizeof(label));
320 if (stat != sizeof(label)) {
322 Jmsg3(jcr, M_FATAL, 0, _("Could not write ANSI VOL1 label. Wanted size=%d got=%d ERR=%s\n"),
323 sizeof(label), stat, be.bstrerror());
328 /* Now construct HDR1 label */
329 memset(label, ' ', sizeof(label));
330 ser_begin(label, sizeof(label));
331 ser_bytes(labels[type], 3);
333 ser_bytes("BACULA.DATA", 11); /* Filename field */
334 ser_begin(&label[21], sizeof(label)-21); /* fileset field */
335 ser_bytes(ansi_volname, 6); /* write Vol Ser No. */
336 ser_begin(&label[27], sizeof(label)-27);
337 ser_bytes("00010001000100", 14); /* File section, File seq no, Generation no */
339 ser_bytes(ansi_date(now, date), 6); /* current date */
340 ser_bytes(ansi_date(now - 24 * 3600, date), 6); /* created yesterday */
341 ser_bytes(" 000000Bacula ", 27);
342 /* Write HDR1 label */
343 if (label_type == B_IBM_LABEL) {
344 ascii_to_ebcdic(label, label, sizeof(label));
348 * This could come at the end of a tape, ignore
351 stat = dev->write(label, sizeof(label));
352 if (stat != sizeof(label)) {
356 if (dev->dev_errno == 0) {
357 dev->dev_errno = ENOSPC; /* out of space */
359 if (dev->dev_errno != ENOSPC) {
360 Jmsg1(jcr, M_FATAL, 0, _("Could not write ANSI HDR1 label. ERR=%s\n"),
365 Jmsg(jcr, M_FATAL, 0, _("Could not write ANSI HDR1 label.\n"));
370 /* Now construct HDR2 label */
371 memset(label, ' ', sizeof(label));
372 ser_begin(label, sizeof(label));
373 ser_bytes(labels[type], 3);
374 ser_bytes("2D3200032000", 12);
375 /* Write HDR2 label */
376 if (label_type == B_IBM_LABEL) {
378 ascii_to_ebcdic(label, label, sizeof(label));
380 stat = dev->write(label, sizeof(label));
381 if (stat != sizeof(label)) {
385 if (dev->dev_errno == 0) {
386 dev->dev_errno = ENOSPC; /* out of space */
388 if (dev->dev_errno != ENOSPC) {
389 Jmsg1(jcr, M_FATAL, 0, _("Could not write ANSI HDR1 label. ERR=%s\n"),
396 Jmsg(jcr, M_FATAL, 0, _("Could not write ANSI HDR1 label.\n"));
401 Jmsg(jcr, M_FATAL, 0, _("Error writing EOF to tape. ERR=%s"), dev->errmsg);
406 Jmsg0(jcr, M_ABORT, 0, _("write_ansi_ibm_label called for non-ANSI/IBM type\n"));
407 return false; /* should not get here */
411 /* Check a Bacula Volume name against an ANSI Volume name */
412 static bool same_label_names(char *bacula_name, char *ansi_name)
415 char *b = bacula_name;
416 /* Six characters max */
417 for (int i=0; i < 6; i++) {
423 /* ANSI labels are blank filled, Bacula's are zero terminated */
424 if (*a == ' ' && *b == 0) {
429 /* Reached 6 characters */
441 static char *ansi_date(time_t td, char *buf)
449 bsnprintf(buf, 10, " %05d ", 1000 * (tm->tm_year + 1900 - 2000) + tm->tm_yday);