2 Bacula® - The Network Backup Solution
4 Copyright (C) 2005-2007 Free Software Foundation Europe e.V.
6 The main author of Bacula is Kern Sibbald, with contributions from
7 many others, a complete list can be found in the file AUTHORS.
8 This program is Free Software; you can redistribute it and/or
9 modify it under the terms of version two of the GNU General Public
10 License as published by the Free Software Foundation and included
13 This program is distributed in the hope that it will be useful, but
14 WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 General Public License for more details.
18 You should have received a copy of the GNU General Public License
19 along with this program; if not, write to the Free Software
20 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
23 Bacula® is a registered trademark of John Walker.
24 The licensor of Bacula is the Free Software Foundation Europe
25 (FSFE), Fiduciary Program, Sumatrastrasse 25, 8006 Zürich,
26 Switzerland, email:ftf@fsfeurope.org.
30 * ansi_label.c routines to handle ANSI (and perhaps one day IBM)
40 #include "bacula.h" /* pull in global headers */
41 #include "stored.h" /* pull in Storage Deamon headers */
43 /* Imported functions */
44 void ascii_to_ebcdic(char *dst, char *src, int count);
45 void ebcdic_to_ascii(char *dst, char *src, int count);
47 /* Forward referenced functions */
48 static char *ansi_date(time_t td, char *buf);
49 static bool same_label_names(char *bacula_name, char *ansi_name);
52 * We read an ANSI label and compare the Volume name. We require
53 * a VOL1 record of 80 characters followed by a HDR1 record containing
54 * BACULA.DATA in the filename field. We then read up to 3 more
55 * header records (they are not required) and an EOF, at which
59 * VOL_OK Volume name OK
60 * VOL_NO_LABEL No ANSI label on Volume
61 * VOL_IO_ERROR I/O error on read
62 * VOL_NAME_ERROR Wrong name in VOL1 record
63 * VOL_LABEL_ERROR Probably an ANSI label, but something wrong
66 int read_ansi_ibm_label(DCR *dcr)
68 DEVICE * volatile dev = dcr->dev;
70 char label[80]; /* tape label */
72 char *VolName = dcr->VolumeName;
76 * Read VOL1, HDR1, HDR2 labels, but ignore the data
77 * If tape read the following EOF mark, on disk do
80 Dmsg0(100, "Read ansi label.\n");
81 if (!dev->is_tape()) {
85 dev->label_type = B_BACULA_LABEL; /* assume Bacula label */
87 /* Read a maximum of 5 records VOL1, HDR1, ... HDR4 */
88 for (i=0; i < 6; i++) {
90 stat = dev->read(label, sizeof(label));
91 } while (stat == -1 && errno == EINTR);
95 Dmsg1(100, "Read device got: ERR=%s\n", be.bstrerror());
96 Mmsg2(jcr->errmsg, _("Read error on device %s in ANSI label. ERR=%s\n"),
97 dev->dev_name, be.bstrerror());
98 Jmsg(jcr, M_ERROR, 0, "%s", dev->errmsg);
99 dev->VolCatInfo.VolCatErrors++;
104 dev->set_eot(); /* second eof, set eot bit */
105 Dmsg0(100, "EOM on ANSI label\n");
106 Mmsg0(jcr->errmsg, _("Insane! End of tape while reading ANSI label.\n"));
107 return VOL_LABEL_ERROR; /* at EOM this shouldn't happen */
109 dev->set_ateof(); /* set eof state */
113 case 0: /* Want VOL1 label */
115 if (strncmp("VOL1", label, 4) == 0) {
117 dev->label_type = B_ANSI_LABEL;
118 Dmsg0(100, "Got ANSI VOL1 label\n");
121 ebcdic_to_ascii(label, label, sizeof(label));
122 if (strncmp("VOL1", label, 4) == 0) {
124 dev->label_type = B_IBM_LABEL;
125 Dmsg0(100, "Found IBM label.\n");
126 Dmsg0(100, "Got IBM VOL1 label\n");
131 Dmsg0(100, "No VOL1 label\n");
132 Mmsg0(jcr->errmsg, _("No VOL1 label while reading ANSI/IBM label.\n"));
133 return VOL_NO_LABEL; /* No ANSI label */
137 /* Compare Volume Names allow special wild card */
138 if (VolName && *VolName && *VolName != '*') {
139 if (!same_label_names(VolName, &label[4])) {
144 /* Store new Volume name */
145 q = dev->VolHdr.VolumeName;
146 for (int i=0; *p != ' ' && i < 6; i++) {
150 Dmsg0(100, "Call reserve_volume\n");
151 reserve_volume(dcr, dev->VolHdr.VolumeName);
152 dev = dcr->dev; /* may have changed in reserve_volume */
153 Dmsg2(100, "Wanted ANSI Vol %s got %6s\n", VolName, dev->VolHdr.VolumeName);
154 Mmsg2(jcr->errmsg, _("Wanted ANSI Volume \"%s\" got \"%s\"\n"), VolName, dev->VolHdr.VolumeName);
155 return VOL_NAME_ERROR;
160 if (dev->label_type == B_IBM_LABEL) {
161 ebcdic_to_ascii(label, label, sizeof(label));
163 if (stat != 80 || strncmp("HDR1", label, 4) != 0) {
164 Dmsg0(100, "No HDR1 label\n");
165 Mmsg0(jcr->errmsg, _("No HDR1 label while reading ANSI label.\n"));
166 return VOL_LABEL_ERROR;
168 if (strncmp("BACULA.DATA", &label[4], 11) != 0) {
169 Dmsg1(100, "HD1 not Bacula label. Wanted BACULA.DATA got %11s\n",
171 Mmsg1(jcr->errmsg, _("ANSI/IBM Volume \"%s\" does not belong to Bacula.\n"),
172 dev->VolHdr.VolumeName);
173 return VOL_NAME_ERROR; /* Not a Bacula label */
175 Dmsg0(100, "Got HDR1 label\n");
178 if (dev->label_type == B_IBM_LABEL) {
179 ebcdic_to_ascii(label, label, sizeof(label));
181 if (stat != 80 || strncmp("HDR2", label, 4) != 0) {
182 Dmsg0(100, "No HDR2 label\n");
183 Mmsg0(jcr->errmsg, _("No HDR2 label while reading ANSI/IBM label.\n"));
184 return VOL_LABEL_ERROR;
186 Dmsg0(100, "Got ANSI HDR2 label\n");
190 Dmsg0(100, "ANSI label OK\n");
193 if (dev->label_type == B_IBM_LABEL) {
194 ebcdic_to_ascii(label, label, sizeof(label));
196 if (stat != 80 || strncmp("HDR", label, 3) != 0) {
197 Dmsg0(100, "Unknown or bad ANSI/IBM label record.\n");
198 Mmsg0(jcr->errmsg, _("Unknown or bad ANSI/IBM label record.\n"));
199 return VOL_LABEL_ERROR;
201 Dmsg0(100, "Got HDR label\n");
205 Dmsg0(100, "Too many records in ANSI/IBM label.\n");
206 Mmsg0(jcr->errmsg, _("Too many records in while reading ANSI/IBM label.\n"));
207 return VOL_LABEL_ERROR;
211 * ANSI/IBM VOL1 label
212 * 80 characters blank filled
213 * Pos count Function What Bacula puts
215 * 4-9 6 Volume name Volume name
216 * 10-10 1 Access code
231 * ANSI/IBM HDR1 label
232 * 80 characters blank filled
233 * Pos count Function What Bacula puts
235 * 4-20 17 File name BACULA.DATA
236 * 21-26 6 Volume name Volume name
237 * 27-30 4 Vol seq num 0001
238 * 31-34 4 file num 0001
239 * 35-38 4 Generation 0001
240 * 39-40 2 Gen version 00
241 * 41-46 6 Create date bYYDDD yesterday
242 * 47-52 6 Expire date bYYDDD today
244 * 54-59 6 Block count 000000
245 * 60-72 13 Software name Bacula
248 * ANSI/IBM HDR2 label
249 * 80 characters blank filled
250 * Pos count Function What Bacula puts
252 * 4-4 1 Record format D (V if IBM) => variable
253 * 5-9 5 Block length 32000
254 * 10-14 5 Rec length 32000
261 * 38-38 1 Blocked flag
268 static const char *labels[] = {"HDR", "EOF", "EOV"};
271 * Write an ANSI or IBM 80 character tape label
272 * Type determines whether we are writing HDR, EOF, or EOV labels
273 * Assume we are positioned to write the labels
274 * Returns: true of OK
277 bool write_ansi_ibm_labels(DCR *dcr, int type, const char *VolName)
279 DEVICE *dev = dcr->dev;
281 char label[80]; /* tape label */
282 char date[20]; /* ansi date buffer */
284 int len, stat, label_type;
287 * If the Device requires a specific label type use it,
288 * otherwise, use the type requested by the Director
290 if (dcr->device->label_type != B_BACULA_LABEL) {
291 label_type = dcr->device->label_type; /* force label type */
293 label_type = dcr->VolCatInfo.LabelType; /* accept Dir type */
296 switch (label_type) {
302 Dmsg1(100, "Write ANSI label type=%d\n", label_type);
303 len = strlen(VolName);
305 Jmsg1(jcr, M_FATAL, 0, _("ANSI Volume label name \"%s\" longer than 6 chars.\n"),
309 if (type == ANSI_VOL_LABEL) {
310 ser_begin(label, sizeof(label));
311 ser_bytes("VOL1", 4);
312 ser_bytes(VolName, len);
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 Jmsg1(jcr, M_FATAL, 0, _("Could not write ANSI VOL1 label. ERR=%s\n"),
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(VolName, len); /* 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);