3 * ansi_label.c routines to handle ANSI (and perhaps one day IBM)
13 Copyright (C) 2005 Kern Sibbald
15 This program is free software; you can redistribute it and/or
16 modify it under the terms of the GNU General Public License as
17 published by the Free Software Foundation; either version 2 of
18 the License, or (at your option) any later version.
20 This program is distributed in the hope that it will be useful,
21 but WITHOUT ANY WARRANTY; without even the implied warranty of
22 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
23 General Public License for more details.
25 You should have received a copy of the GNU General Public
26 License along with this program; if not, write to the Free
27 Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
32 #include "bacula.h" /* pull in global headers */
33 #include "stored.h" /* pull in Storage Deamon headers */
35 /* Forward referenced functions */
36 static char *ansi_date(time_t td, char *buf);
37 static bool same_label_names(char *bacula_name, char *ansi_name);
40 * We read an ANSI label and compare the Volume name. We require
41 * a VOL1 record of 80 characters followed by a HDR1 record containing
42 * BACULA.DATA in the filename field. We then read up to 3 more
43 * header records (they are not required) and an EOF, at which
47 * VOL_OK Volume name OK
48 * VOL_NO_LABEL No ANSI label on Volume
49 * VOL_IO_ERROR I/O error on read
50 * VOL_NAME_ERROR Wrong name in VOL1 record
51 * VOL_LABEL_ERROR Probably an ANSI label, but something wrong
54 int read_ansi_ibm_label(DCR *dcr)
56 DEVICE *dev = dcr->dev;
58 char label[80]; /* tape label */
60 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(000, "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 = read(dev->fd, label, sizeof(label));
78 } while (stat == -1 && errno == EINTR);
81 clrerror_dev(dev, -1);
82 Dmsg1(000, "Read device got: ERR=%s\n", be.strerror());
83 Mmsg2(dev->errmsg, _("Read error on device %s in ANSI/IBM label. ERR=%s\n"),
84 dev->dev_name, be.strerror());
85 Jmsg(jcr, M_ERROR, 0, "%s", dev->errmsg);
86 dev->VolCatInfo.VolCatErrors++;
92 Dmsg0(000, "EOM on ANSI label\n");
93 return VOL_LABEL_ERROR; /* at EOM this shouldn't happen */
99 case 0: /* Want VOL1 label */
100 if (stat != 80 || strncmp("VOL1", label, 4) != 0) {
101 Dmsg0(000, "No VOL1 label\n");
102 return VOL_NO_LABEL; /* No ANSI label */
105 dev->label_type = B_ANSI_LABEL;
107 /* Compare Volume Names allow special wild card */
108 if (VolName && *VolName && *VolName != '*') {
109 if (!same_label_names(VolName, &label[4])) {
111 char *q = dev->VolHdr.VolName;
112 for (int i=0; *p != ' ' && i < 6; i++) {
116 Dmsg2(000, "Wanted ANSI Vol %s got %6s\n", VolName, dev->VolHdr.VolName);
117 return VOL_NAME_ERROR;
122 if (stat != 80 || strncmp("HDR1", label, 4) != 0) {
123 Dmsg0(000, "No HDR1 label\n");
124 return VOL_LABEL_ERROR;
126 if (strncmp("BACULA.DATA", &label[4], 11) != 0) {
127 Dmsg1(000, "HD1 not Bacula label. Wanted BACULA.DATA got %11s\n",
129 return VOL_NAME_ERROR; /* Not a Bacula label */
133 if (stat != 80 || strncmp("HDR2", label, 4) != 0) {
134 Dmsg0(000, "No HDR2 label\n");
135 return VOL_LABEL_ERROR;
140 Dmsg0(000, "ANSI label OK\n");
143 if (stat != 80 || strncmp("HDR", label, 3) != 0) {
144 Dmsg0(000, "Unknown or bad ANSI label record.\n");
145 return VOL_LABEL_ERROR;
150 Dmsg0(000, "Too many records in ANSI label.\n");
151 return VOL_LABEL_ERROR;
155 * Write an ANSI or IBM 80 character tape label
156 * Assume we are positioned at the beginning of the tape.
157 * Returns: true of OK
160 bool write_ansi_ibm_label(DCR *dcr, const char *VolName)
162 DEVICE *dev = dcr->dev;
164 char label[80]; /* tape label */
165 char date[20]; /* ansi date buffer */
167 int len, stat, label_type;
170 * If the Device requires a specific label type use it,
171 * otherwise, use the type requested by the Director
173 if (dcr->device->label_type != B_BACULA_LABEL) {
174 label_type = dcr->device->label_type; /* force label type */
176 label_type = dcr->VolCatInfo.LabelType; /* accept Dir type */
179 switch (label_type) {
185 Dmsg1(000, "Write ANSI label type=%d\n", label_type);
186 len = strlen(VolName);
188 Jmsg1(jcr, M_FATAL, 0, _("ANSI Volume label name \"%s\" longer than 6 chars.\n"),
192 memset(label, ' ', sizeof(label));
193 ser_begin(label, sizeof(label));
194 ser_bytes("VOL1", 4);
195 ser_bytes(VolName, len);
196 label[79] = '3'; /* ANSI label flag */
197 /* Write VOL1 label */
198 stat = write(dev->fd, label, sizeof(label));
199 if (stat != sizeof(label)) {
201 Jmsg1(jcr, M_FATAL, 0, _("Could not write ANSI VOL1 label. ERR=%s\n"),
205 /* Now construct HDR1 label */
206 ser_begin(label, sizeof(label));
207 ser_bytes("HDR1", 4);
208 ser_bytes("BACULA.DATA", 11); /* Filename field */
209 ser_begin(&label[21], sizeof(label)-21); /* fileset field */
210 ser_bytes(VolName, len); /* write Vol Ser No. */
211 ser_begin(&label[27], sizeof(label)-27);
212 ser_bytes("00010001000100", 14); /* File section, File seq no, Generation no */
214 ser_bytes(ansi_date(now, date), 6); /* current date */
215 ser_bytes(ansi_date(now - 24 * 3600, date), 6); /* created yesterday */
216 ser_bytes(" 000000Bacula ", 27);
217 /* Write HDR1 label */
218 stat = write(dev->fd, label, sizeof(label));
219 if (stat != sizeof(label)) {
221 Jmsg1(jcr, M_FATAL, 0, _("Could not write ANSI HDR1 label. ERR=%s\n"),
225 /* Now construct HDR2 label */
226 memset(label, ' ', sizeof(label));
227 ser_begin(label, sizeof(label));
228 ser_bytes("HDR2F3200032000", 15);
229 /* Write HDR1 label */
230 stat = write(dev->fd, label, sizeof(label));
231 if (stat != sizeof(label)) {
233 Jmsg1(jcr, M_FATAL, 0, _("Could not write ANSI HDR1 label. ERR=%s\n"),
237 if (weof_dev(dev, 1) < 0) {
238 Jmsg(jcr, M_FATAL, 0, _("Error writing EOF to tape. ERR=%s"), dev->errmsg);
243 Jmsg0(jcr, M_ABORT, 0, _("write_ansi_ibm_label called for non-ANSI/IBM type\n"));
244 return false; /* should not get here */
248 /* Check a Bacula Volume name against an ANSI Volume name */
249 static bool same_label_names(char *bacula_name, char *ansi_name)
252 char *b = bacula_name;
253 /* Six characters max */
254 for (int i=0; i < 6; i++) {
260 /* ANSI labels are blank filled, Bacula's are zero terminated */
261 if (*a == ' ' && *b == 0) {
266 /* Reached 6 characters */
275 static char *ansi_date(time_t td, char *buf)
283 bsnprintf(buf, 10, " %05d ", 1000 * (tm->tm_year + 1900 - 2000) + tm->tm_yday);