]> git.sur5r.net Git - bacula/bacula/blob - bacula/src/stored/ansi_label.c
48d52bd35ef0b609588ccae9ebe6145082a323ad
[bacula/bacula] / bacula / src / stored / ansi_label.c
1 /*
2    Bacula® - The Network Backup Solution
3
4    Copyright (C) 2005-2009 Free Software Foundation Europe e.V.
5
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 three of the GNU Affero General Public
10    License as published by the Free Software Foundation and included
11    in the file LICENSE.
12
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.
17
18    You should have received a copy of the GNU Affero 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
21    02110-1301, USA.
22
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.
27 */
28 /*
29  *
30  *  ansi_label.c routines to handle ANSI (and perhaps one day IBM)
31  *   tape labels.
32  *
33  *   Kern Sibbald, MMV
34  *
35  *
36  *
37  *   Version $Id$
38  */
39
40 #include "bacula.h"                   /* pull in global headers */
41 #include "stored.h"                   /* pull in Storage Deamon headers */
42
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);
46
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);
50
51 /*
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
56  * point, all is good.
57  *
58  * Returns:
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
64  *      
65  */ 
66 int read_ansi_ibm_label(DCR *dcr) 
67 {
68    DEVICE * volatile dev = dcr->dev;
69    JCR *jcr = dcr->jcr;
70    char label[80];                    /* tape label */
71    int stat, i;
72    char *VolName = dcr->VolumeName;
73    bool ok = false;
74
75    /*
76     * Read VOL1, HDR1, HDR2 labels, but ignore the data
77     *  If tape read the following EOF mark, on disk do
78     *  not read.
79     */
80    Dmsg0(100, "Read ansi label.\n");
81    if (!dev->is_tape()) {
82       return VOL_OK;
83    }
84
85    dev->label_type = B_BACULA_LABEL;  /* assume Bacula label */
86
87    /* Read a maximum of 5 records VOL1, HDR1, ... HDR4 */
88    for (i=0; i < 6; i++) {
89       do {
90          stat = dev->read(label, sizeof(label));
91       } while (stat == -1 && errno == EINTR);
92       if (stat < 0) {
93          berrno be;
94          dev->clrerror(-1);
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++;
100          return VOL_IO_ERROR;
101       }
102       if (stat == 0) {
103          if (dev->at_eof()) {
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 */
108          } else {
109             dev->set_ateof();        /* set eof state */
110          }
111       }
112       switch (i) {
113       case 0:                         /* Want VOL1 label */
114          if (stat == 80) {
115             if (strncmp("VOL1", label, 4) == 0) {
116                ok = true;
117                dev->label_type = B_ANSI_LABEL;
118                Dmsg0(100, "Got ANSI VOL1 label\n");
119             } else {
120                /* Try EBCDIC */
121                ebcdic_to_ascii(label, label, sizeof(label));
122                if (strncmp("VOL1", label, 4) == 0) {
123                   ok = true;;
124                   dev->label_type = B_IBM_LABEL;
125                   Dmsg0(100, "Found IBM label.\n");
126                   Dmsg0(100, "Got IBM VOL1 label\n");
127                }
128             }       
129          }
130          if (!ok) {
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 */
134          }
135
136
137          /* Compare Volume Names allow special wild card */
138          if (VolName && *VolName && *VolName != '*') { 
139             if (!same_label_names(VolName, &label[4])) {
140                char *p = &label[4];
141                char *q;  
142
143                free_volume(dev);
144                /* Store new Volume name */
145                q = dev->VolHdr.VolumeName;
146                for (int i=0; *p != ' ' && i < 6; i++) {
147                   *q++ = *p++;
148                }
149                *q = 0;
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;
157             }
158          }
159          break;
160       case 1:
161          if (dev->label_type == B_IBM_LABEL) {
162             ebcdic_to_ascii(label, label, sizeof(label));
163          }
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;
168          }
169          if (strncmp("BACULA.DATA", &label[4], 11) != 0) {
170             Dmsg1(100, "HD1 not Bacula label. Wanted  BACULA.DATA got %11s\n",
171                &label[4]);
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 */
175          }
176          Dmsg0(100, "Got HDR1 label\n");
177          break;
178       case 2:
179          if (dev->label_type == B_IBM_LABEL) {
180             ebcdic_to_ascii(label, label, sizeof(label));
181          }
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;
186          }
187          Dmsg0(100, "Got ANSI HDR2 label\n");
188          break;
189       default:
190          if (stat == 0) {
191             Dmsg0(100, "ANSI label OK\n");
192             return VOL_OK;
193          }
194          if (dev->label_type == B_IBM_LABEL) {
195             ebcdic_to_ascii(label, label, sizeof(label));
196          }
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;
201          }
202          Dmsg0(100, "Got HDR label\n");
203          break;
204       }
205    }
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;
209 }  
210
211 /*
212  * ANSI/IBM VOL1 label
213  *  80 characters blank filled
214  * Pos   count   Function      What Bacula puts
215  * 0-3     4     "VOL1"          VOL1
216  * 4-9     6     Volume name     Volume name
217  * 10-10   1     Access code 
218  * 11-36   26    Unused
219  *
220  * ANSI
221  * 37-50   14    Owner
222  * 51-78   28    reserved
223  * 79       1    ANSI level        3
224  *
225  * IBM
226  * 37-40   4     reserved
227  * 41-50   10    Owner
228  * 51-79   29    reserved
229
230  *
231  *
232  * ANSI/IBM HDR1 label
233  *  80 characters blank filled
234  * Pos   count   Function          What Bacula puts
235  * 0-3     4     "HDR1"               HDR1
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
244  * 53-53   1     Access
245  * 54-59   6     Block count           000000
246  * 60-72   13    Software name         Bacula
247  * 73-79   7     Reserved
248
249  * ANSI/IBM HDR2 label
250  *  80 characters blank filled
251  * Pos   count   Function          What Bacula puts
252  * 0-3     4     "HDR2"               HDR2
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
256  * 15-15   1     Density
257  * 16-16   1     Continued 
258  * 17-33   17    Job
259  * 34-35   2     Recording
260  * 36-36   1     cr/lf ctl
261  * 37-37   1     reserved
262  * 38-38   1     Blocked flag
263  * 39-49   11    reserved
264  * 50-51   2     offset
265  * 52-79   28    reserved
266
267  */ 
268
269 static const char *labels[] = {"HDR", "EOF", "EOV"};
270
271 /*
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
276  *             false if error
277  */
278 bool write_ansi_ibm_labels(DCR *dcr, int type, const char *VolName)
279 {
280    DEVICE *dev = dcr->dev;
281    JCR *jcr = dcr->jcr;
282    char ansi_volname[7];              /* 6 char + \0 */
283    char label[80];                    /* tape label */
284    char date[20];                     /* ansi date buffer */
285    time_t now;
286    int len, stat, label_type;
287
288    /*
289     * If the Device requires a specific label type use it,
290     * otherwise, use the type requested by the Director
291     */
292    if (dcr->device->label_type != B_BACULA_LABEL) {
293       label_type = dcr->device->label_type;   /* force label type */
294    } else {
295       label_type = dcr->VolCatInfo.LabelType; /* accept Dir type */
296    }
297
298    switch (label_type) {
299    case B_BACULA_LABEL:
300       return true;
301    case B_ANSI_LABEL:
302    case B_IBM_LABEL:
303       ser_declare;
304       Dmsg1(100, "Write ANSI label type=%d\n", label_type);
305       len = strlen(VolName);
306       if (len > 6) {
307          Jmsg1(jcr, M_FATAL, 0, _("ANSI Volume label name \"%s\" longer than 6 chars.\n"),
308             VolName);
309          return false;
310       }
311       /* ANSI labels have 6 characters, and are padded with spaces
312        * 'vol1\0' => 'vol1   \0'
313        */
314       strcpy(ansi_volname, VolName);
315       for(int i=len; i < 6; i++) {
316          ansi_volname[i]=' ';
317       }
318       ansi_volname[6]='\0';     /* only for debug */
319
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));
327          } else {
328             label[79] = '3';                /* ANSI label flag */
329          }
330          stat = dev->write(label, sizeof(label));
331          if (stat != sizeof(label)) {
332             berrno be;
333             Jmsg1(jcr, M_FATAL, 0,  _("Could not write ANSI VOL1 label. ERR=%s\n"),
334                be.bstrerror());
335             return false;
336          }
337       }
338
339       /* Now construct HDR1 label */
340       memset(label, ' ', sizeof(label));
341       ser_begin(label, sizeof(label));
342       ser_bytes(labels[type], 3);
343       ser_bytes("1", 1);
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 */
349       now = time(NULL);
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));
356       }
357
358       /*
359        * This could come at the end of a tape, ignore
360        *  EOT errors.
361        */
362       stat = dev->write(label, sizeof(label));
363       if (stat != sizeof(label)) {
364          berrno be;
365          if (stat == -1) {
366             dev->clrerror(-1);
367             if (dev->dev_errno == 0) {
368                dev->dev_errno = ENOSPC; /* out of space */
369             }
370             if (dev->dev_errno != ENOSPC) {
371                Jmsg1(jcr, M_FATAL, 0, _("Could not write ANSI HDR1 label. ERR=%s\n"),
372                be.bstrerror());
373                return false;
374             }
375          } else {
376             Jmsg(jcr, M_FATAL, 0, _("Could not write ANSI HDR1 label.\n"));
377             return false;
378          }
379       }
380
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) {
388          label[4] = 'V';
389          ascii_to_ebcdic(label, label, sizeof(label));
390       }
391       stat = dev->write(label, sizeof(label));
392       if (stat != sizeof(label)) {
393          berrno be;
394          if (stat == -1) {
395             dev->clrerror(-1);
396             if (dev->dev_errno == 0) {
397                dev->dev_errno = ENOSPC; /* out of space */
398             }
399             if (dev->dev_errno != ENOSPC) {
400                Jmsg1(jcr, M_FATAL, 0, _("Could not write ANSI HDR1 label. ERR=%s\n"),
401                be.bstrerror());
402                return false;
403             }
404             dev->weof(1);
405             return true;
406          } else {
407             Jmsg(jcr, M_FATAL, 0, _("Could not write ANSI HDR1 label.\n"));
408             return false;
409          }
410       }
411       if (!dev->weof(1)) {
412          Jmsg(jcr, M_FATAL, 0, _("Error writing EOF to tape. ERR=%s"), dev->errmsg);
413          return false;
414       }
415       return true;
416    default:
417       Jmsg0(jcr, M_ABORT, 0, _("write_ansi_ibm_label called for non-ANSI/IBM type\n"));
418       return false; /* should not get here */
419    }
420 }
421
422 /* Check a Bacula Volume name against an ANSI Volume name */
423 static bool same_label_names(char *bacula_name, char *ansi_name)
424 {
425    char *a = ansi_name;
426    char *b = bacula_name;
427    /* Six characters max */
428    for (int i=0; i < 6; i++) {
429       if (*a == *b) {
430          a++;
431          b++;
432          continue;
433       }
434       /* ANSI labels are blank filled, Bacula's are zero terminated */
435       if (*a == ' ' && *b == 0) {
436          return true;
437       }
438       return false;
439    }
440    /* Reached 6 characters */
441    b++;
442    if (*b == 0) {
443       return true;
444    }
445    return false;
446 }
447
448 /*
449  * ANSI date
450  *  ' 'YYDDD
451  */
452 static char *ansi_date(time_t td, char *buf)
453 {
454    struct tm *tm;
455
456    if (td == 0) {
457       td = time(NULL);
458    }
459    tm = gmtime(&td);
460    bsnprintf(buf, 10, " %05d ", 1000 * (tm->tm_year + 1900 - 2000) + tm->tm_yday);
461    return buf;
462 }