Imported Upstream version 3.1.0
[debian/amanda] / ndmp-src / ndml_media.c
1 /*
2  * Copyright (c) 1998,1999,2000
3  *      Traakan, Inc., Los Altos, CA
4  *      All rights reserved.
5  *
6  * Redistribution and use in source and binary forms, with or without
7  * modification, are permitted provided that the following conditions
8  * are met:
9  * 1. Redistributions of source code must retain the above copyright
10  *    notice unmodified, this list of conditions, and the following
11  *    disclaimer.
12  * 2. Redistributions in binary form must reproduce the above copyright
13  *    notice, this list of conditions and the following disclaimer in the
14  *    documentation and/or other materials provided with the distribution.
15  *
16  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
17  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
20  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
21  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
22  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
23  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
24  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
25  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
26  * SUCH DAMAGE.
27  */
28
29 /*
30  * Project:  NDMJOB
31  * Ident:    $Id: $
32  *
33  * Description:
34  *
35  */
36
37
38 #include "ndmlib.h"
39
40
41 /*
42  * Media Entry (medent)
43  *
44  * [LABEL][+FILEMARKS][/NBYTES][@SLOT]
45  *
46  * LABEL is simple text and must be first.
47  *
48  * +FILEMARKS, /NBYTES, and @SLOT may occur in any order.
49  *
50  * FILEMARKS is a small decimal number and indicates
51  * how many filemarks to skip when using the media.
52  * 0 means begining of tape. If no +FILEMARKS is given,
53  * 1 is used if LABEL is given, 0 otherwise.
54  *
55  * NBYTES indicates the maximum amount of data on the
56  * media. This is a decimal number optionally followed
57  * by a scale character (k, m, g).
58  *
59  * SLOT is the slot address in the tape robot. It is
60  * the element address, not relative to the first
61  * slot in the robot.
62  */
63
64 int
65 ndmmedia_from_str (struct ndmmedia *me, char *str)
66 {
67         char *          p;
68         char *          q;
69         int             c;
70
71         NDMOS_MACRO_ZEROFILL (me);
72
73         p = str;
74         q = me->label;
75
76         for (; *p; p++) {
77                 c = *p;
78                 if (c == '+' || c == '@' || c == '/')
79                         break;
80
81                 if (q < &me->label[NDMMEDIA_LABEL_MAX])
82                         *q++ = c;
83         }
84         *q = 0;
85
86         if (q > me->label)
87                 me->valid_label = 1;
88
89         while (*p) {
90                 c = *p;
91                 switch (c) {
92                 default:
93                         return -1;              /* what is this? */
94
95                 case '@':
96                         if (me->valid_slot)
97                                 return -2;
98
99                         me->slot_addr = strtol (p+1, &p, 0);
100                         me->valid_slot = 1;
101                         break;
102
103                 case '+':
104                         if (me->valid_filemark)
105                                 return -3;
106
107                         me->file_mark_offset = strtol (p+1, &p, 0);
108                         me->valid_filemark = 1;
109                         break;
110
111                 case '/':
112                         if (me->valid_n_bytes)
113                                 return -4;
114
115                         me->n_bytes = ndmmedia_strtoll (p+1, &p, 0);
116                         me->valid_n_bytes = 1;
117                         break;
118                 }
119         }
120
121         return 0;
122 }
123
124 int
125 ndmmedia_to_str (struct ndmmedia *me, char *str)
126 {
127         char *          q = str;
128
129         *q = 0;
130
131         if (me->valid_label) {
132                 strcpy (q, me->label);
133                 while (*q) q++;
134         }
135
136         if (me->valid_filemark) {
137                 sprintf (q, "+%d", me->file_mark_offset);
138                 while (*q) q++;
139         }
140
141         if (me->valid_n_bytes) {
142                 if (me->n_bytes == 0)
143                         sprintf (q, "/0");
144                 else if (me->n_bytes % (1024*1024*1024) == 0)
145                         sprintf (q, "/%lldG", me->n_bytes/(1024*1024*1024));
146                 else if (me->n_bytes % (1024*1024) == 0)
147                         sprintf (q, "/%lldM", me->n_bytes/(1024*1024));
148                 else if (me->n_bytes % (1024) == 0)
149                         sprintf (q, "/%lldK", me->n_bytes/(1024));
150                 else
151                         sprintf (q, "/%lld", me->n_bytes);
152                 while (*q) q++;
153         }
154
155         if (me->valid_slot) {
156                 sprintf (q, "@%d", me->slot_addr);
157                 while (*q) q++;
158         }
159
160         return 0;
161 }
162
163
164 static char *flag_yes_or_no (int f) { return (f) ? "Y" : "N"; }
165
166 int
167 ndmmedia_pp (struct ndmmedia *me, int lineno, char *buf)
168 {
169     switch (lineno) {
170     case 0:
171         ndmmedia_to_str (me, buf);
172         break;
173
174     case 1:
175         sprintf (buf, "valid label=%s filemark=%s n_bytes=%s slot=%s",
176                 flag_yes_or_no (me->valid_label),
177                 flag_yes_or_no (me->valid_filemark),
178                 flag_yes_or_no (me->valid_n_bytes),
179                 flag_yes_or_no (me->valid_slot));
180         break;
181
182     case 2:
183         sprintf (buf, "media used=%s written=%s eof=%s eom=%s io_error=%s",
184                 flag_yes_or_no (me->media_used),
185                 flag_yes_or_no (me->media_written),
186                 flag_yes_or_no (me->media_eof),
187                 flag_yes_or_no (me->media_eom),
188                 flag_yes_or_no (me->media_io_error));
189         break;
190
191     case 3:
192         sprintf (buf, "label read=%s written=%s io_error=%s mismatch=%s",
193                 flag_yes_or_no (me->label_read),
194                 flag_yes_or_no (me->label_written),
195                 flag_yes_or_no (me->label_io_error),
196                 flag_yes_or_no (me->label_mismatch));
197         break;
198
199     case 4:
200         sprintf (buf, "fm_error=%s nb_determined=%s nb_aligned=%s",
201                 flag_yes_or_no (me->fmark_error),
202                 flag_yes_or_no (me->nb_determined),
203                 flag_yes_or_no (me->nb_aligned));
204         break;
205
206     case 5:
207         sprintf (buf, "slot empty=%s bad=%s missing=%s",
208                 flag_yes_or_no (me->slot_empty),
209                 flag_yes_or_no (me->slot_bad),
210                 flag_yes_or_no (me->slot_missing));
211         break;
212
213     default:
214         strcpy (buf, "<<INVALID>>");
215         break;
216     }
217
218     return 6;
219 }
220
221 long long
222 ndmmedia_strtoll (char *str, char **tailp, int defbase)
223 {
224         long long               val = 0;
225         int                     c;
226
227         for (;;) {
228                 c = *str;
229                 if (c < '0' || '9' < c)
230                         break;
231                 val *= 10;
232                 val += c - '0';
233                 str++;
234         }
235
236         switch (c) {
237         default:
238                 break;
239
240         case 'k': case 'K':
241                 val *= 1024LL;
242                 str++;
243                 break;
244
245         case 'm': case 'M':
246                 val *= 1024*1024LL;
247                 str++;
248                 break;
249
250         case 'g': case 'G':
251                 val *= 1024*1024*1024LL;
252                 str++;
253                 break;
254         }
255
256         if (tailp) *tailp = str;
257
258         return val;
259 }