2 Bacula® - The Network Backup Solution
4 Copyright (C) 2005-2009 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 Kern Sibbald.
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 /* ***FIXME*** why is this reserve_volume() needed???? KES */
152 reserve_volume(dcr, dev->VolHdr.VolumeName);
153 dev = dcr->dev; /* may have changed in reserve_volume */
154 Dmsg2(100, "Wanted ANSI Vol %s got %6s\n", VolName, dev->VolHdr.VolumeName);
155 Mmsg2(jcr->errmsg, _("Wanted ANSI Volume \"%s\" got \"%s\"\n"), VolName, dev->VolHdr.VolumeName);
156 return VOL_NAME_ERROR;
161 if (dev->label_type == B_IBM_LABEL) {
162 ebcdic_to_ascii(label, label, sizeof(label));
164 if (stat != 80 || strncmp("HDR1", label, 4) != 0) {
165 Dmsg0(100, "No HDR1 label\n");
166 Mmsg0(jcr->errmsg, _("No HDR1 label while reading ANSI label.\n"));
167 return VOL_LABEL_ERROR;
169 if (strncmp("BACULA.DATA", &label[4], 11) != 0) {
170 Dmsg1(100, "HD1 not Bacula label. Wanted BACULA.DATA got %11s\n",
172 Mmsg1(jcr->errmsg, _("ANSI/IBM Volume \"%s\" does not belong to Bacula.\n"),
173 dev->VolHdr.VolumeName);
174 return VOL_NAME_ERROR; /* Not a Bacula label */
176 Dmsg0(100, "Got HDR1 label\n");
179 if (dev->label_type == B_IBM_LABEL) {
180 ebcdic_to_ascii(label, label, sizeof(label));
182 if (stat != 80 || strncmp("HDR2", label, 4) != 0) {
183 Dmsg0(100, "No HDR2 label\n");
184 Mmsg0(jcr->errmsg, _("No HDR2 label while reading ANSI/IBM label.\n"));
185 return VOL_LABEL_ERROR;
187 Dmsg0(100, "Got ANSI HDR2 label\n");
191 Dmsg0(100, "ANSI label OK\n");
194 if (dev->label_type == B_IBM_LABEL) {
195 ebcdic_to_ascii(label, label, sizeof(label));
197 if (stat != 80 || strncmp("HDR", label, 3) != 0) {
198 Dmsg0(100, "Unknown or bad ANSI/IBM label record.\n");
199 Mmsg0(jcr->errmsg, _("Unknown or bad ANSI/IBM label record.\n"));
200 return VOL_LABEL_ERROR;
202 Dmsg0(100, "Got HDR label\n");
206 Dmsg0(100, "Too many records in ANSI/IBM label.\n");
207 Mmsg0(jcr->errmsg, _("Too many records in while reading ANSI/IBM label.\n"));
208 return VOL_LABEL_ERROR;
212 * ANSI/IBM VOL1 label
213 * 80 characters blank filled
214 * Pos count Function What Bacula puts
216 * 4-9 6 Volume name Volume name
217 * 10-10 1 Access code
232 * ANSI/IBM HDR1 label
233 * 80 characters blank filled
234 * Pos count Function What Bacula puts
236 * 4-20 17 File name BACULA.DATA
237 * 21-26 6 Volume name Volume name
238 * 27-30 4 Vol seq num 0001
239 * 31-34 4 file num 0001
240 * 35-38 4 Generation 0001
241 * 39-40 2 Gen version 00
242 * 41-46 6 Create date bYYDDD yesterday
243 * 47-52 6 Expire date bYYDDD today
245 * 54-59 6 Block count 000000
246 * 60-72 13 Software name Bacula
249 * ANSI/IBM HDR2 label
250 * 80 characters blank filled
251 * Pos count Function What Bacula puts
253 * 4-4 1 Record format D (V if IBM) => variable
254 * 5-9 5 Block length 32000
255 * 10-14 5 Rec length 32000
262 * 38-38 1 Blocked flag
269 static const char *labels[] = {"HDR", "EOF", "EOV"};
272 * Write an ANSI or IBM 80 character tape label
273 * Type determines whether we are writing HDR, EOF, or EOV labels
274 * Assume we are positioned to write the labels
275 * Returns: true of OK
278 bool write_ansi_ibm_labels(DCR *dcr, int type, const char *VolName)
280 DEVICE *dev = dcr->dev;
282 char ansi_volname[7]; /* 6 char + \0 */
283 char label[80]; /* tape label */
284 char date[20]; /* ansi date buffer */
286 int len, stat, label_type;
289 * If the Device requires a specific label type use it,
290 * otherwise, use the type requested by the Director
292 if (dcr->device->label_type != B_BACULA_LABEL) {
293 label_type = dcr->device->label_type; /* force label type */
295 label_type = dcr->VolCatInfo.LabelType; /* accept Dir type */
298 switch (label_type) {
304 Dmsg1(100, "Write ANSI label type=%d\n", label_type);
305 len = strlen(VolName);
307 Jmsg1(jcr, M_FATAL, 0, _("ANSI Volume label name \"%s\" longer than 6 chars.\n"),
311 /* ANSI labels have 6 characters, and are padded with spaces
312 * 'vol1\0' => 'vol1 \0'
314 strcpy(ansi_volname, VolName);
315 for(int i=len; i < 6; i++) {
318 ansi_volname[6]='\0'; /* only for debug */
320 if (type == ANSI_VOL_LABEL) {
321 ser_begin(label, sizeof(label));
322 ser_bytes("VOL1", 4);
323 ser_bytes(ansi_volname, 6);
324 /* Write VOL1 label */
325 if (label_type == B_IBM_LABEL) {
326 ascii_to_ebcdic(label, label, sizeof(label));
328 label[79] = '3'; /* ANSI label flag */
330 stat = dev->write(label, sizeof(label));
331 if (stat != sizeof(label)) {
333 Jmsg1(jcr, M_FATAL, 0, _("Could not write ANSI VOL1 label. ERR=%s\n"),
339 /* Now construct HDR1 label */
340 memset(label, ' ', sizeof(label));
341 ser_begin(label, sizeof(label));
342 ser_bytes(labels[type], 3);
344 ser_bytes("BACULA.DATA", 11); /* Filename field */
345 ser_begin(&label[21], sizeof(label)-21); /* fileset field */
346 ser_bytes(ansi_volname, 6); /* write Vol Ser No. */
347 ser_begin(&label[27], sizeof(label)-27);
348 ser_bytes("00010001000100", 14); /* File section, File seq no, Generation no */
350 ser_bytes(ansi_date(now, date), 6); /* current date */
351 ser_bytes(ansi_date(now - 24 * 3600, date), 6); /* created yesterday */
352 ser_bytes(" 000000Bacula ", 27);
353 /* Write HDR1 label */
354 if (label_type == B_IBM_LABEL) {
355 ascii_to_ebcdic(label, label, sizeof(label));
359 * This could come at the end of a tape, ignore
362 stat = dev->write(label, sizeof(label));
363 if (stat != sizeof(label)) {
367 if (dev->dev_errno == 0) {
368 dev->dev_errno = ENOSPC; /* out of space */
370 if (dev->dev_errno != ENOSPC) {
371 Jmsg1(jcr, M_FATAL, 0, _("Could not write ANSI HDR1 label. ERR=%s\n"),
376 Jmsg(jcr, M_FATAL, 0, _("Could not write ANSI HDR1 label.\n"));
381 /* Now construct HDR2 label */
382 memset(label, ' ', sizeof(label));
383 ser_begin(label, sizeof(label));
384 ser_bytes(labels[type], 3);
385 ser_bytes("2D3200032000", 12);
386 /* Write HDR2 label */
387 if (label_type == B_IBM_LABEL) {
389 ascii_to_ebcdic(label, label, sizeof(label));
391 stat = dev->write(label, sizeof(label));
392 if (stat != sizeof(label)) {
396 if (dev->dev_errno == 0) {
397 dev->dev_errno = ENOSPC; /* out of space */
399 if (dev->dev_errno != ENOSPC) {
400 Jmsg1(jcr, M_FATAL, 0, _("Could not write ANSI HDR1 label. ERR=%s\n"),
407 Jmsg(jcr, M_FATAL, 0, _("Could not write ANSI HDR1 label.\n"));
412 Jmsg(jcr, M_FATAL, 0, _("Error writing EOF to tape. ERR=%s"), dev->errmsg);
417 Jmsg0(jcr, M_ABORT, 0, _("write_ansi_ibm_label called for non-ANSI/IBM type\n"));
418 return false; /* should not get here */
422 /* Check a Bacula Volume name against an ANSI Volume name */
423 static bool same_label_names(char *bacula_name, char *ansi_name)
426 char *b = bacula_name;
427 /* Six characters max */
428 for (int i=0; i < 6; i++) {
434 /* ANSI labels are blank filled, Bacula's are zero terminated */
435 if (*a == ' ' && *b == 0) {
440 /* Reached 6 characters */
452 static char *ansi_date(time_t td, char *buf)
460 bsnprintf(buf, 10, " %05d ", 1000 * (tm->tm_year + 1900 - 2000) + tm->tm_yday);