Commit | Line | Data |
---|---|---|
da1346d6 PC |
1 | #ifndef lint |
2 | static char *sccsid = "@(#)dumplabel.c 1.1 (UKC) %G%"; | |
3 | #endif not lint | |
4 | /*** | |
5 | ||
6 | * program name: | |
7 | dumplabel.c | |
8 | * function: | |
9 | prints the label from a header | |
10 | writes a dummy dump header at the start of a tape | |
11 | Doesn't do any checksum | |
12 | * switches: | |
13 | -f <tapename> | |
14 | -r rewind/offline each tape | |
15 | -l label format | |
16 | followed by list of tape labels in the same format at given to the | |
17 | locally modified dump program | |
18 | if no tape labels are given print the details on the start of a tape | |
19 | * libraries used: | |
20 | standard | |
21 | * compile time parameters: | |
22 | cc -o dumplabel dumplabel.c | |
23 | * history: | |
24 | Written August 1987 Peter Collinson UKC | |
25 | ||
26 | ***/ | |
27 | #include "dump.h" | |
28 | #include <sys/ioctl.h> | |
29 | #include <sys/mtio.h> | |
30 | ||
31 | #define LABMAX 100 /* get space for 100 */ | |
32 | ||
33 | char *labarg[LABMAX]; /* vector of map entries */ | |
34 | ||
35 | char *labfmt; /* format for tape label */ | |
36 | ||
37 | int labct; /* number of entries */ | |
38 | /* if zero then no labels used */ | |
39 | ||
40 | char *tape = "/dev/rmt8"; | |
41 | ||
42 | int dorew; /* set if rewind offline on exit */ | |
43 | int tapecount; /* number of tapes dealt with */ | |
44 | ||
45 | ||
46 | main(argc, argv) | |
47 | char **argv; | |
48 | { register i; | |
49 | register char *p; | |
50 | while (--argc) { | |
51 | argv++; | |
52 | if (**argv == '-') { | |
53 | for (p = *argv; *p; p++) | |
54 | switch (*p) { | |
55 | ||
56 | case 'f': | |
57 | if (--argc > 0) { | |
58 | argv++; | |
59 | tape = *argv; | |
60 | } | |
61 | break; | |
62 | case 'r': | |
63 | dorew++; /* no rewind/offline */ | |
64 | break; | |
65 | case 'l': | |
66 | if (--argc > 0) { | |
67 | argv++; | |
68 | labfmt = *argv; | |
69 | } | |
70 | } | |
71 | } else { | |
72 | storelabelmap(arg); | |
73 | for (i = 1; i <= labct; i++) | |
74 | dolabel(i); | |
75 | labct = 0; | |
76 | } | |
77 | } | |
78 | if (tapecount == 0) { | |
79 | if (labfmt) { | |
80 | labct = 0; | |
81 | dolabel(1); /* pretend a volume number of 1 */ | |
82 | } else | |
83 | printlabel() | |
84 | } | |
85 | exit(0); | |
86 | } | |
87 | ||
88 | /* | |
89 | * Store map list | |
90 | * The map list | |
91 | * allows a simple way to specify a range of tapes | |
92 | * This generates a string which is inserted into the label format | |
93 | * by use of an sprint operation | |
94 | * | |
95 | * The basic form here is: | |
96 | * <string> a single string | |
97 | * <string>,<string>,...... a list of strings | |
98 | * <string>-<string> a range of strings | |
99 | * where the string is `incremented' | |
100 | * to generate a list | |
101 | */ | |
102 | storelabelmap(arg) | |
103 | char *arg; | |
104 | { | |
105 | register char *ss, *es; | |
106 | register char *incbase, *incr; | |
107 | register lastc; | |
108 | char *labskip(); | |
109 | char *strstore(); | |
110 | ||
111 | /* | |
112 | * Parse the argument looking for a single string | |
113 | */ | |
114 | for (ss = arg; *ss; ss = es, labct++) { | |
115 | es = labskip(ss); | |
116 | lastc = *es; /* save last character */ | |
117 | *es++ = '\0'; /* make the first label into a string */ | |
118 | if (labct > LABMAX) | |
119 | labfatal("Too many (> %d) tape labels specified\n", LABMAX); | |
120 | labarg[labct++] = strstore(ss); | |
121 | ||
122 | if (lastc == 0) | |
123 | break; /* end of list */ | |
124 | ||
125 | if (lastc == '-') { | |
126 | /* | |
127 | * this gives a tape range | |
128 | * increment the source number until it equals the final | |
129 | * value | |
130 | */ | |
131 | incbase = ss; | |
132 | ss = es; | |
133 | es = labskip(ss); | |
134 | if (*es == '-') | |
135 | labfatal("Range has the format <string>-<string>\n"); | |
136 | lastc = *es; | |
137 | *es = '\0'; | |
138 | /* | |
139 | * basic test the source string length must be equal to the | |
140 | * end string length | |
141 | */ | |
142 | if (strlen(incbase) != strlen(ss)) | |
143 | labfatal("strlen(\"%s\") != strlen(\"%s\")\n", incbase, ss); | |
144 | labelrange(incbase, ss); | |
145 | } | |
146 | } | |
147 | } | |
148 | ||
149 | /* | |
150 | * Expand a label range | |
151 | */ | |
152 | /* static */ | |
153 | labelrange(startrange, endrange) | |
154 | char *startrange, *endrange; | |
155 | { | |
156 | register char *incr; | |
157 | register int carry; | |
158 | ||
159 | ||
160 | for (incr = startrange + strlen(startrange) - 1; | |
161 | strcmp(startrange, endrange) != 0; ) { | |
162 | /* start incrementing */ | |
163 | for (carry = 0; carry; ) { | |
164 | if (isdigit(*incr)) { | |
165 | if (*incr == '9') { | |
166 | *incr = '0'; | |
167 | carry = 1; | |
168 | } else | |
169 | *incr++; | |
170 | } else | |
171 | if (isupper(*incr)) { | |
172 | if (*incr == 'Z') { | |
173 | *incr = 'A'; | |
174 | carry = 1; | |
175 | } else | |
176 | *incr++; | |
177 | } else | |
178 | if (islower(*incr)) { | |
179 | if (*incr == 'z') { | |
180 | *incr = 'a'; | |
181 | carry = 1; | |
182 | } else | |
183 | *incr++; | |
184 | } else | |
185 | labfatal("Problem with label map range spec - can only increment alphanumeric values\n"); | |
186 | if (carry) { | |
187 | incr--; | |
188 | if (incr < startrange) | |
189 | labfatal("Problem with label map range spec - end of range reached\n"); | |
190 | } | |
191 | } | |
192 | if (labct > LABMAX) | |
193 | labfatal("Too many (> %d) tape labels specified\n", LABMAX); | |
194 | labarg[labct++] = strstore(startrange); | |
195 | ||
196 | } | |
197 | } | |
198 | ||
199 | /* | |
200 | * Store a string using malloc | |
201 | */ | |
202 | /* static */ | |
203 | char * | |
204 | strstore(arg) | |
205 | char *arg; | |
206 | { | |
207 | register len = strlen(arg)+1; | |
208 | register char *dest; | |
209 | char *malloc(); | |
210 | ||
211 | dest = malloc(len); | |
212 | if (dest == NULL) | |
213 | labfatal("No memory for string storage\n"); | |
214 | bcopy(arg, dest, len); | |
215 | return(dest); | |
216 | } | |
217 | ||
218 | /* | |
219 | * Create a tape label from a volume number | |
220 | */ | |
221 | char * | |
222 | createlabel(volno) | |
223 | int volno; | |
224 | { | |
225 | static char buf[LBLSIZE+LBLSIZE]; | |
226 | static int lastvol; | |
227 | char volbuf[8]; | |
228 | register char *arg; | |
229 | ||
230 | if (userlabel == 0) | |
231 | return ("none"); /* previous behaviour */ | |
232 | ||
233 | if (volno == lastvol) /* cache */ | |
234 | return(buf); | |
235 | lastvol = volno; | |
236 | ||
237 | if (labfmt == NULL) | |
238 | labfmt = "%s"; | |
239 | ||
240 | if (labct == 0) | |
241 | { (void) sprintf(volbuf, "%d", volno); | |
242 | arg = volbuf; | |
243 | } | |
244 | else | |
245 | arg = labarg[volno-1]; /* volumes run 1-> */ | |
246 | (void) sprintf(buf, labfmt, arg); | |
247 | buf[LBLSIZE-1] = '\0'; /* Truncate to correct size */ | |
248 | return(buf); | |
249 | } | |
250 | ||
251 | /* | |
252 | * skip forward looking for valid end of label characters | |
253 | */ | |
254 | char * | |
255 | labskip(str) | |
256 | register char *str; | |
257 | { while (*str != ',' && *str != '-' && *str) | |
258 | str++; | |
259 | return (str); | |
260 | } | |
261 | ||
262 | /* | |
263 | * do the actual labelling | |
264 | */ | |
265 | dolabel(index) | |
266 | { register fd; | |
267 | ||
268 | if (tapecount++) | |
269 | askformount(index); | |
270 | ||
271 | while ((fd = open(tape, 2)) < 0) | |
272 | { fprintf(stderr, "Tape open error\n"); | |
273 | askformount(index); | |
274 | } | |
275 | strcpy(spcl.c_label, createlabel(index)); | |
276 | if (write(fd, (char *)&u_spcl, sizeof (u_spcl)) != sizeof (u_spcl)) | |
277 | { perror("Tape write error"); | |
278 | exit(1); | |
279 | } | |
280 | rewind(fd); | |
281 | close(fd); | |
282 | } | |
283 | ||
284 | /* | |
285 | * ask for a tape to be mounted | |
286 | */ | |
287 | askformount(index) | |
288 | { | |
289 | while (query("Mount tape `%s'\nReady to go?", createlabel(index)) != 1); | |
290 | } | |
291 | ||
292 | /* | |
293 | * ask yes/no question | |
294 | * return 1 on yes | |
295 | * 0 on no | |
296 | */ | |
297 | query(question, arg) | |
298 | char *question; | |
299 | char *arg; | |
300 | { | |
301 | char replybuffer[64]; | |
302 | int back; | |
303 | ||
304 | for(;;) | |
305 | { | |
306 | fprintf(stdout, question, arg); | |
307 | fflush(stdout); | |
308 | if (fgets(replybuffer, 63, stdin) == NULL) | |
309 | { if(ferror(stdin)) | |
310 | { clearerr(stdin); | |
311 | continue; | |
312 | } | |
313 | } | |
314 | else | |
315 | if ((strcmp(replybuffer, "yes\n") == 0) || | |
316 | (strcmp(replybuffer, "Yes\n") == 0)) | |
317 | { | |
318 | back = 1; | |
319 | goto done; | |
320 | } | |
321 | else | |
322 | if ((strcmp(replybuffer, "no\n") == 0) || | |
323 | (strcmp(replybuffer, "No\n") == 0)) | |
324 | { | |
325 | if (query("Abort? ")) | |
326 | labfatal("Aborting\n"); | |
327 | back = 0; | |
328 | goto done; | |
329 | } | |
330 | else | |
331 | fprintf(stderr, "\"Yes\" or \"No\" ONLY!\n"); | |
332 | } | |
333 | done: | |
334 | return(back); | |
335 | } | |
336 | ||
337 | rewind(fd) | |
338 | { | |
339 | struct mtop mtop; | |
340 | if (dorew) | |
341 | { mtop.mt_op = MTOFFL; | |
342 | mtop.mt_count = 1; | |
343 | ioctl(fd, MTIOCTOP, &mtop); | |
344 | } | |
345 | } | |
346 | ||
347 | /* | |
348 | * fatal error message routine | |
349 | */ | |
350 | labfatal(fmt, a1, a2, a3, a4, a5) | |
351 | char *fmt; | |
352 | int a1, a2, a3, a4, a5; | |
353 | { fprintf(stderr, fmt, a1, a2, a3, a4, a5); | |
354 | exit(1); | |
355 | } | |
356 | ||
357 | /* | |
358 | * print the label from a tape | |
359 | */ | |
360 | printlabel() | |
361 | { | |
362 | register fd; | |
363 | ||
364 | if ((fd = open(tape, 2)) < 0) | |
365 | { perror("Tape open error"); | |
366 | exit(1); | |
367 | } | |
368 | if (read(fd, (char *)&u_spcl, sizeof u_spcl) < 0) | |
369 | { perror("Tape read"); | |
370 | exit(1); | |
371 | } | |
372 | printf("%s\n", spcl.c_label); | |
373 | close(fd); | |
374 | } |