Commit | Line | Data |
---|---|---|
2741ad75 KM |
1 | /*- |
2 | * Copyright (c) 1992 Keith Muller. | |
f547d164 KB |
3 | * Copyright (c) 1992, 1993 |
4 | * The Regents of the University of California. All rights reserved. | |
2741ad75 KM |
5 | * |
6 | * This code is derived from software contributed to Berkeley by | |
7 | * Keith Muller of the University of California, San Diego. | |
8 | * | |
9 | * %sccs.include.redist.c% | |
10 | */ | |
11 | ||
12 | #ifndef lint | |
59d11f9a | 13 | static char sccsid[] = "@(#)ar_io.c 8.1 (Berkeley) %G%"; |
2741ad75 KM |
14 | #endif /* not lint */ |
15 | ||
16 | #include <sys/types.h> | |
17 | #include <sys/time.h> | |
18 | #include <sys/stat.h> | |
19 | #include <sys/ioctl.h> | |
20 | #include <sys/mtio.h> | |
21 | #include <sys/param.h> | |
22 | #include <signal.h> | |
23 | #include <string.h> | |
24 | #include <fcntl.h> | |
25 | #include <unistd.h> | |
26 | #include <stdio.h> | |
27 | #include <ctype.h> | |
28 | #include <errno.h> | |
29 | #include <stdlib.h> | |
30 | #include "pax.h" | |
31 | #include "extern.h" | |
32 | ||
33 | /* | |
bbab641f | 34 | * Routines which deal directly with the archive I/O device/file. |
2741ad75 KM |
35 | */ |
36 | ||
37 | #define DMOD 0666 /* default mode of created archives */ | |
38 | #define EXT_MODE O_RDONLY /* open mode for list/extract */ | |
39 | #define AR_MODE (O_WRONLY | O_CREAT | O_TRUNC) /* mode for archive */ | |
40 | #define APP_MODE O_RDWR /* mode for append */ | |
41 | #define STDO "<STDOUT>" /* psuedo name for stdout */ | |
42 | #define STDN "<STDIN>" /* psuedo name for stdin */ | |
43 | static int arfd = -1; /* archive file descriptor */ | |
ce8aa995 | 44 | static int artyp = ISREG; /* archive type: file/FIFO/tape */ |
2741ad75 KM |
45 | static int arvol = 1; /* archive volume number */ |
46 | static int lstrval = -1; /* return value from last i/o */ | |
47 | static int io_ok; /* i/o worked on volume after resync */ | |
bbab641f | 48 | static int did_io; /* did i/o ever occur on volume? */ |
2741ad75 KM |
49 | static int done; /* set via tty termination */ |
50 | static struct stat arsb; /* stat of archive device at open */ | |
51 | static int invld_rec; /* tape has out of spec record size */ | |
82633d4d | 52 | static int wr_trail = 1; /* trailer was rewritten in append */ |
ce8aa995 | 53 | static int can_unlnk = 0; /* do we unlink null archives? */ |
2741ad75 KM |
54 | char *arcname; /* printable name of archive */ |
55 | ||
56 | static int get_phys __P((void)); | |
57 | extern sigset_t s_mask; | |
58 | ||
59 | /* | |
60 | * ar_open() | |
61 | * Opens the next archive volume. Determines the type of the device and | |
62 | * sets up block sizes as required by the archive device and the format. | |
63 | * Note: we may be called with name == NULL on the first open only. | |
64 | * Return: | |
65 | * -1 on failure, 0 otherwise | |
66 | */ | |
67 | ||
68 | #if __STDC__ | |
69 | int | |
70 | ar_open(char *name) | |
71 | #else | |
72 | int | |
73 | ar_open(name) | |
74 | char *name; | |
75 | #endif | |
76 | { | |
77 | struct mtget mb; | |
78 | ||
79 | if (arfd != -1) | |
80 | (void)close(arfd); | |
81 | arfd = -1; | |
349d8467 | 82 | can_unlnk = did_io = io_ok = invld_rec = 0; |
ce8aa995 | 83 | artyp = ISREG; |
2741ad75 KM |
84 | flcnt = 0; |
85 | ||
86 | /* | |
87 | * open based on overall operation mode | |
88 | */ | |
89 | switch (act) { | |
90 | case LIST: | |
91 | case EXTRACT: | |
92 | if (name == NULL) { | |
93 | arfd = STDIN_FILENO; | |
94 | arcname = STDN; | |
95 | } else if ((arfd = open(name, EXT_MODE, DMOD)) < 0) | |
bbab641f | 96 | syswarn(0, errno, "Failed open to read on %s", name); |
2741ad75 KM |
97 | break; |
98 | case ARCHIVE: | |
99 | if (name == NULL) { | |
100 | arfd = STDOUT_FILENO; | |
101 | arcname = STDO; | |
102 | } else if ((arfd = open(name, AR_MODE, DMOD)) < 0) | |
bbab641f | 103 | syswarn(0, errno, "Failed open to write on %s", name); |
ce8aa995 KM |
104 | else |
105 | can_unlnk = 1; | |
2741ad75 KM |
106 | break; |
107 | case APPND: | |
108 | if (name == NULL) { | |
109 | arfd = STDOUT_FILENO; | |
110 | arcname = STDO; | |
111 | } else if ((arfd = open(name, APP_MODE, DMOD)) < 0) | |
bbab641f | 112 | syswarn(0, errno, "Failed open to read/write on %s", |
2741ad75 KM |
113 | name); |
114 | break; | |
115 | case COPY: | |
116 | /* | |
117 | * arfd not used in COPY mode | |
118 | */ | |
119 | arcname = "<NONE>"; | |
120 | lstrval = 1; | |
121 | return(0); | |
122 | } | |
123 | if (arfd < 0) | |
124 | return(-1); | |
125 | ||
126 | /* | |
127 | * set up is based on device type | |
128 | */ | |
129 | if (fstat(arfd, &arsb) < 0) { | |
bbab641f | 130 | syswarn(0, errno, "Failed stat on %s", arcname); |
ce8aa995 KM |
131 | (void)close(arfd); |
132 | arfd = -1; | |
133 | can_unlnk = 0; | |
2741ad75 KM |
134 | return(-1); |
135 | } | |
136 | if (S_ISDIR(arsb.st_mode)) { | |
bbab641f | 137 | warn(0, "Cannot write an archive on top of a directory %s", |
2741ad75 | 138 | arcname); |
ce8aa995 KM |
139 | (void)close(arfd); |
140 | arfd = -1; | |
141 | can_unlnk = 0; | |
2741ad75 KM |
142 | return(-1); |
143 | } | |
ce8aa995 | 144 | |
2741ad75 KM |
145 | if (S_ISCHR(arsb.st_mode)) |
146 | artyp = ioctl(arfd, MTIOCGET, &mb) ? ISCHR : ISTAPE; | |
147 | else if (S_ISBLK(arsb.st_mode)) | |
148 | artyp = ISBLK; | |
149 | else if ((lseek(arfd, (off_t)0L, SEEK_CUR) == -1) && (errno == ESPIPE)) | |
150 | artyp = ISPIPE; | |
151 | else | |
152 | artyp = ISREG; | |
153 | ||
ce8aa995 KM |
154 | /* |
155 | * make sure we beyond any doubt that we only can unlink regular files | |
156 | * we created | |
157 | */ | |
158 | if (artyp != ISREG) | |
159 | can_unlnk = 0; | |
2741ad75 | 160 | /* |
bbab641f | 161 | * if we are writing, we are done |
2741ad75 KM |
162 | */ |
163 | if (act == ARCHIVE) { | |
164 | blksz = rdblksz = wrblksz; | |
165 | lstrval = 1; | |
166 | return(0); | |
167 | } | |
168 | ||
169 | /* | |
170 | * set default blksz on read. APPNDs writes rdblksz on the last volume | |
171 | * On all new archive volumes, we shift to wrblksz (if the user | |
172 | * specified one, otherwize we will continue to use rdblksz). We | |
173 | * must to set blocksize based on what kind of device the archive is | |
174 | * stored. | |
175 | */ | |
176 | switch(artyp) { | |
177 | case ISTAPE: | |
178 | /* | |
179 | * Tape drives come in at least two flavors. Those that support | |
180 | * variable sized records and those that have fixed sized | |
181 | * records. They must be treated differently. For tape drives | |
182 | * that support variable sized records, we must make large | |
183 | * reads to make sure we get the entire record, otherwise we | |
184 | * will just get the first part of the record (up to size we | |
185 | * asked). Tapes with fixed sized records may or may not return | |
186 | * multiple records in a single read. We really do not care | |
187 | * what the physical record size is UNLESS we are going to | |
188 | * append. (We will need the physical block size to rewrite | |
189 | * the trailer). Only when we are appending do we go to the | |
bbab641f | 190 | * effort to figure out the true PHYSICAL record size. |
2741ad75 KM |
191 | */ |
192 | blksz = rdblksz = MAXBLK; | |
193 | break; | |
194 | case ISPIPE: | |
195 | case ISBLK: | |
196 | case ISCHR: | |
197 | /* | |
198 | * Blocksize is not a major issue with these devices (but must | |
199 | * be kept a multiple of 512). If the user specified a write | |
200 | * block size, we use that to read. Under append, we must | |
201 | * always keep blksz == rdblksz. Otherwise we go ahead and use | |
202 | * the device optimal blocksize as (and if) returned by stat | |
203 | * and if it is within pax specs. | |
204 | */ | |
205 | if ((act == APPND) && wrblksz) { | |
206 | blksz = rdblksz = wrblksz; | |
207 | break; | |
208 | } | |
209 | ||
210 | if ((arsb.st_blksize > 0) && (arsb.st_blksize < MAXBLK) && | |
211 | ((arsb.st_blksize % BLKMULT) == 0)) | |
212 | rdblksz = arsb.st_blksize; | |
213 | else | |
214 | rdblksz = DEVBLK; | |
215 | /* | |
216 | * For performance go for large reads when we can without harm | |
217 | */ | |
218 | if ((act == APPND) || (artyp == ISCHR)) | |
219 | blksz = rdblksz; | |
220 | else | |
221 | blksz = MAXBLK; | |
222 | break; | |
223 | case ISREG: | |
224 | /* | |
225 | * if the user specified wrblksz works, use it. Under appends | |
226 | * we must always keep blksz == rdblksz | |
227 | */ | |
228 | if ((act == APPND) && wrblksz && ((arsb.st_size%wrblksz)==0)){ | |
229 | blksz = rdblksz = wrblksz; | |
230 | break; | |
231 | } | |
232 | /* | |
233 | * See if we can find the blocking factor from the file size | |
234 | */ | |
235 | for (rdblksz = MAXBLK; rdblksz > 0; rdblksz -= BLKMULT) | |
236 | if ((arsb.st_size % rdblksz) == 0) | |
237 | break; | |
238 | /* | |
239 | * When we cannont find a match, we may have a flawed archive. | |
240 | */ | |
241 | if (rdblksz <= 0) | |
242 | rdblksz = FILEBLK; | |
243 | /* | |
244 | * for performance go for large reads when we can | |
245 | */ | |
246 | if (act == APPND) | |
247 | blksz = rdblksz; | |
248 | else | |
249 | blksz = MAXBLK; | |
250 | break; | |
251 | default: | |
252 | /* | |
253 | * should never happen, worse case, slow... | |
254 | */ | |
255 | blksz = rdblksz = BLKMULT; | |
256 | break; | |
257 | } | |
258 | lstrval = 1; | |
259 | return(0); | |
260 | } | |
261 | ||
262 | /* | |
263 | * ar_close() | |
264 | * closes archive device, increments volume number, and prints i/o summary | |
265 | */ | |
266 | #if __STDC__ | |
267 | void | |
268 | ar_close(void) | |
269 | #else | |
270 | void | |
271 | ar_close() | |
272 | #endif | |
273 | { | |
274 | FILE *outf; | |
275 | ||
82633d4d KM |
276 | if (arfd < 0) { |
277 | did_io = io_ok = flcnt = 0; | |
278 | return; | |
279 | } | |
280 | ||
bbab641f KM |
281 | if (act == LIST) |
282 | outf = stdout; | |
283 | else | |
284 | outf = stderr; | |
285 | ||
286 | /* | |
287 | * Close archive file. This may take a LONG while on tapes (we may be | |
288 | * forced to wait for the rewind to complete) so tell the user what is | |
289 | * going on (this avoids the user hitting control-c thinking pax is | |
290 | * broken). | |
291 | */ | |
82633d4d KM |
292 | if (vflag && (artyp == ISTAPE)) { |
293 | if (vfpart) | |
bbab641f | 294 | (void)putc('\n', outf); |
bbab641f KM |
295 | (void)fputs("pax: Waiting for tape drive close to complete...", |
296 | outf); | |
297 | (void)fflush(outf); | |
298 | } | |
299 | ||
ce8aa995 KM |
300 | /* |
301 | * if nothing was written to the archive (and we created it), we remove | |
302 | * it | |
303 | */ | |
304 | if (can_unlnk && (fstat(arfd, &arsb) == 0) && (S_ISREG(arsb.st_mode)) && | |
305 | (arsb.st_size == 0)) { | |
306 | (void)unlink(arcname); | |
307 | can_unlnk = 0; | |
308 | } | |
309 | ||
2741ad75 | 310 | (void)close(arfd); |
bbab641f | 311 | |
82633d4d | 312 | if (vflag && (artyp == ISTAPE)) { |
bbab641f | 313 | (void)fputs("done.\n", outf); |
82633d4d | 314 | vfpart = 0; |
bbab641f KM |
315 | (void)fflush(outf); |
316 | } | |
2741ad75 | 317 | arfd = -1; |
bbab641f | 318 | |
2741ad75 KM |
319 | if (!io_ok && !did_io) { |
320 | flcnt = 0; | |
321 | return; | |
322 | } | |
323 | did_io = io_ok = 0; | |
324 | ||
325 | /* | |
326 | * The volume number is only increased when the last device has data | |
bbab641f | 327 | * and we have already determined the archive format. |
2741ad75 | 328 | */ |
bbab641f KM |
329 | if (frmt != NULL) |
330 | ++arvol; | |
331 | ||
2741ad75 KM |
332 | if (!vflag) { |
333 | flcnt = 0; | |
334 | return; | |
335 | } | |
336 | ||
337 | /* | |
338 | * Print out a summary of I/O for this archive volume. | |
339 | */ | |
2741ad75 KM |
340 | if (vfpart) { |
341 | (void)putc('\n', outf); | |
342 | vfpart = 0; | |
343 | } | |
344 | ||
bbab641f KM |
345 | /* |
346 | * If we have not determined the format yet, we just say how many bytes | |
347 | * we have skipped over looking for a header to id. there is no way we | |
348 | * could have written anything yet. | |
349 | */ | |
350 | if (frmt == NULL) { | |
351 | # ifdef NET2_STAT | |
352 | (void)fprintf(outf, "pax: unknown format, %lu bytes skipped.\n", | |
353 | # else | |
354 | (void)fprintf(outf, "pax: unknown format, %qu bytes skipped.\n", | |
355 | # endif | |
356 | rdcnt); | |
357 | (void)fflush(outf); | |
358 | flcnt = 0; | |
359 | return; | |
360 | } | |
361 | ||
2741ad75 KM |
362 | (void)fprintf(outf, |
363 | # ifdef NET2_STAT | |
bbab641f | 364 | "pax: %s vol %d, %lu files, %lu bytes read, %lu bytes written.\n", |
2741ad75 | 365 | # else |
bbab641f | 366 | "pax: %s vol %d, %lu files, %qu bytes read, %qu bytes written.\n", |
2741ad75 KM |
367 | # endif |
368 | frmt->name, arvol-1, flcnt, rdcnt, wrcnt); | |
369 | (void)fflush(outf); | |
370 | flcnt = 0; | |
371 | } | |
372 | ||
d84693c4 KM |
373 | /* |
374 | * ar_drain() | |
375 | * drain any archive format independent padding from an archive read | |
376 | * from a socket or a pipe. This is to prevent the process on the | |
377 | * other side of the pipe from getting a SIGPIPE (pax will stop | |
378 | * reading an archive once a format dependent trailer is detected). | |
379 | */ | |
380 | #if __STDC__ | |
381 | void | |
382 | ar_drain(void) | |
383 | #else | |
384 | void | |
385 | ar_drain() | |
386 | #endif | |
387 | { | |
388 | register int res; | |
389 | char drbuf[MAXBLK]; | |
390 | ||
391 | /* | |
392 | * we only drain from a pipe/socket. Other devices can be closed | |
393 | * without reading up to end of file. We sure hope that pipe is closed | |
394 | * on the other side so we will get an EOF. | |
395 | */ | |
396 | if ((artyp != ISPIPE) || (lstrval <= 0)) | |
397 | return; | |
398 | ||
399 | /* | |
400 | * keep reading until pipe is drained | |
401 | */ | |
402 | while ((res = read(arfd, drbuf, sizeof(drbuf))) > 0) | |
403 | ; | |
404 | lstrval = res; | |
405 | } | |
406 | ||
2741ad75 KM |
407 | /* |
408 | * ar_set_wr() | |
82633d4d KM |
409 | * Set up device right before switching from read to write in an append. |
410 | * device dependent code (if required) to do this should be added here. | |
411 | * For all archive devices we are already positioned at the place we want | |
412 | * to start writing when this routine is called. | |
2741ad75 KM |
413 | * Return: |
414 | * 0 if all ready to write, -1 otherwise | |
415 | */ | |
416 | ||
417 | #if __STDC__ | |
418 | int | |
419 | ar_set_wr(void) | |
420 | #else | |
421 | int | |
422 | ar_set_wr() | |
423 | #endif | |
424 | { | |
425 | off_t cpos; | |
426 | ||
82633d4d KM |
427 | /* |
428 | * we must make sure the trailer is rewritten on append, ar_next() | |
429 | * will stop us if the archive containing the trailer was not written | |
430 | */ | |
431 | wr_trail = 0; | |
432 | ||
2741ad75 KM |
433 | /* |
434 | * Add any device dependent code as required here | |
435 | */ | |
436 | if (artyp != ISREG) | |
437 | return(0); | |
438 | /* | |
bbab641f KM |
439 | * Ok we have an archive in a regular file. If we were rewriting a |
440 | * file, we must get rid of all the stuff after the current offset | |
441 | * (it was not written by pax). | |
2741ad75 KM |
442 | */ |
443 | if (((cpos = lseek(arfd, (off_t)0L, SEEK_CUR)) < 0) || | |
82633d4d KM |
444 | (ftruncate(arfd, cpos) < 0)) { |
445 | syswarn(1, errno, "Unable to truncate archive file"); | |
2741ad75 | 446 | return(-1); |
82633d4d | 447 | } |
2741ad75 KM |
448 | return(0); |
449 | } | |
450 | ||
451 | /* | |
452 | * ar_app_ok() | |
453 | * check if the last volume in the archive allows appends. We cannot check | |
454 | * this until we are ready to write since there is no spec that says all | |
455 | * volumes in a single archive have to be of the same type... | |
456 | * Return: | |
457 | * 0 if we can append, -1 otherwise. | |
458 | */ | |
459 | ||
460 | #if __STDC__ | |
461 | int | |
462 | ar_app_ok(void) | |
463 | #else | |
464 | int | |
465 | ar_app_ok() | |
466 | #endif | |
467 | { | |
468 | if (artyp == ISPIPE) { | |
469 | warn(1, "Cannot append to an archive obtained from a pipe."); | |
470 | return(-1); | |
471 | } | |
472 | ||
473 | if (!invld_rec) | |
474 | return(0); | |
2741ad75 KM |
475 | warn(1,"Cannot append, device record size %d does not support pax spec", |
476 | rdblksz); | |
477 | return(-1); | |
478 | } | |
479 | ||
480 | /* | |
481 | * ar_read() | |
482 | * read up to a specified number of bytes from the archive into the | |
483 | * supplied buffer. When dealing with tapes we may not always be able to | |
484 | * read what we want. | |
485 | * Return: | |
486 | * Number of bytes in buffer. 0 for end of file, -1 for a read error. | |
487 | */ | |
488 | ||
489 | #if __STDC__ | |
490 | int | |
491 | ar_read(register char *buf, register int cnt) | |
492 | #else | |
493 | int | |
494 | ar_read(buf, cnt) | |
495 | register char *buf; | |
496 | register int cnt; | |
497 | #endif | |
498 | { | |
499 | register int res = 0; | |
500 | ||
501 | /* | |
502 | * if last i/o was in error, no more reads until reset or new volume | |
503 | */ | |
504 | if (lstrval <= 0) | |
505 | return(lstrval); | |
506 | ||
507 | /* | |
508 | * how we read must be based on device type | |
509 | */ | |
510 | switch (artyp) { | |
511 | case ISTAPE: | |
512 | if ((res = read(arfd, buf, cnt)) > 0) { | |
513 | /* | |
514 | * CAUTION: tape systems may not always return the same | |
515 | * sized records so we leave blksz == MAXBLK. The | |
516 | * physical record size that a tape drive supports is | |
517 | * very hard to determine in a uniform and portable | |
518 | * manner. | |
519 | */ | |
520 | io_ok = 1; | |
521 | if (res != rdblksz) { | |
522 | /* | |
523 | * Record size changed. If this is happens on | |
bbab641f KM |
524 | * any record after the first, we probably have |
525 | * a tape drive which has a fixed record size | |
526 | * we are getting multiple records in a single | |
527 | * read). Watch out for record blocking that | |
528 | * violates pax spec (must be a multiple of | |
529 | * BLKMULT). | |
2741ad75 KM |
530 | */ |
531 | rdblksz = res; | |
532 | if (rdblksz % BLKMULT) | |
533 | invld_rec = 1; | |
534 | } | |
535 | return(res); | |
536 | } | |
537 | break; | |
538 | case ISREG: | |
539 | case ISBLK: | |
540 | case ISCHR: | |
541 | case ISPIPE: | |
542 | default: | |
543 | /* | |
544 | * Files are so easy to deal with. These other things cannot | |
545 | * be trusted at all. So when we are dealing with character | |
546 | * devices and pipes we just take what they have ready for us | |
547 | * and return. Trying to do anything else with them runs the | |
548 | * risk of failure. | |
549 | */ | |
550 | if ((res = read(arfd, buf, cnt)) > 0) { | |
551 | io_ok = 1; | |
552 | return(res); | |
553 | } | |
554 | break; | |
555 | } | |
556 | ||
557 | /* | |
558 | * We are in trouble at this point, something is broken... | |
559 | */ | |
560 | lstrval = res; | |
561 | if (res < 0) | |
562 | syswarn(1, errno, "Failed read on archive volume %d", arvol); | |
563 | else | |
564 | warn(0, "End of archive volume %d reached", arvol); | |
565 | return(res); | |
566 | } | |
567 | ||
568 | /* | |
569 | * ar_write() | |
570 | * Write a specified number of bytes in supplied buffer to the archive | |
571 | * device so it appears as a single "block". Deals with errors and tries | |
572 | * to recover when faced with short writes. | |
573 | * Return: | |
574 | * Number of bytes written. 0 indicates end of volume reached and with no | |
575 | * flaws (as best that can be detected). A -1 indicates an unrecoverable | |
576 | * error in the archive occured. | |
577 | */ | |
578 | ||
579 | #if __STDC__ | |
580 | int | |
581 | ar_write(register char *buf, register int bsz) | |
582 | #else | |
583 | int | |
584 | ar_write(buf, bsz) | |
585 | register char *buf; | |
586 | register int bsz; | |
587 | #endif | |
588 | { | |
589 | register int res; | |
590 | off_t cpos; | |
591 | ||
592 | /* | |
593 | * do not allow pax to create a "bad" archive. Once a write fails on | |
594 | * an archive volume prevent further writes to it. | |
595 | */ | |
596 | if (lstrval <= 0) | |
597 | return(lstrval); | |
598 | ||
599 | if ((res = write(arfd, buf, bsz)) == bsz) { | |
82633d4d | 600 | wr_trail = 1; |
2741ad75 KM |
601 | io_ok = 1; |
602 | return(bsz); | |
603 | } | |
2741ad75 KM |
604 | /* |
605 | * write broke, see what we can do with it. We try to send any partial | |
bbab641f | 606 | * writes that may violate pax spec to the next archive volume. |
2741ad75 KM |
607 | */ |
608 | if (res < 0) | |
609 | lstrval = res; | |
610 | else | |
611 | lstrval = 0; | |
612 | ||
613 | switch (artyp) { | |
614 | case ISREG: | |
615 | if ((res > 0) && (res % BLKMULT)) { | |
616 | /* | |
617 | * try to fix up partial writes which are not BLKMULT | |
618 | * in size by forcing the runt record to next archive | |
619 | * volume | |
620 | */ | |
621 | if ((cpos = lseek(arfd, (off_t)0L, SEEK_CUR)) < 0) | |
622 | break; | |
623 | cpos -= (off_t)res; | |
624 | if (ftruncate(arfd, cpos) < 0) | |
625 | break; | |
626 | res = lstrval = 0; | |
627 | break; | |
628 | } | |
629 | if (res >= 0) | |
630 | break; | |
631 | /* | |
632 | * if file is out of space, handle it like a return of 0 | |
633 | */ | |
634 | if ((errno == ENOSPC) || (errno == EFBIG) || (errno == EDQUOT)) | |
635 | res = lstrval = 0; | |
636 | break; | |
637 | case ISTAPE: | |
638 | case ISCHR: | |
639 | case ISBLK: | |
640 | if (res >= 0) | |
641 | break; | |
642 | if (errno == EACCES) { | |
643 | warn(0, "Write failed, archive is write protected."); | |
644 | res = lstrval = 0; | |
645 | return(0); | |
646 | } | |
647 | /* | |
648 | * see if we reached the end of media, if so force a change to | |
649 | * the next volume | |
650 | */ | |
651 | if ((errno == ENOSPC) || (errno == EIO) || (errno == ENXIO)) | |
652 | res = lstrval = 0; | |
653 | break; | |
654 | case ISPIPE: | |
655 | default: | |
656 | /* | |
657 | * we cannot fix errors to these devices | |
658 | */ | |
659 | break; | |
660 | } | |
661 | ||
662 | /* | |
663 | * Better tell the user the bad news... | |
bbab641f KM |
664 | * if this is a block aligned archive format, we may have a bad archive |
665 | * if the format wants the header to start at a BLKMULT boundry. While | |
2741ad75 KM |
666 | * we can deal with the mis-aligned data, it violates spec and other |
667 | * archive readers will likely fail. if the format is not block | |
bbab641f | 668 | * aligned, the user may be lucky (and the archive is ok). |
2741ad75 | 669 | */ |
82633d4d KM |
670 | if (res >= 0) { |
671 | if (res > 0) | |
672 | wr_trail = 1; | |
2741ad75 | 673 | io_ok = 1; |
82633d4d KM |
674 | } |
675 | ||
676 | /* | |
677 | * If we were trying to rewrite the trailer and it didn't work, we | |
678 | * must quit right away. | |
679 | */ | |
680 | if (!wr_trail && (res <= 0)) { | |
681 | warn(1,"Unable to append, trailer re-write failed. Quitting."); | |
682 | return(res); | |
683 | } | |
684 | ||
685 | if (res == 0) | |
2741ad75 KM |
686 | warn(0, "End of archive volume %d reached", arvol); |
687 | else if (res < 0) | |
688 | syswarn(1, errno, "Failed write to archive volume: %d", arvol); | |
689 | else if (!frmt->blkalgn || ((res % frmt->blkalgn) == 0)) | |
690 | warn(0,"WARNING: partial archive write. Archive MAY BE FLAWED"); | |
691 | else | |
692 | warn(1,"WARNING: partial archive write. Archive IS FLAWED"); | |
693 | return(res); | |
694 | } | |
695 | ||
696 | /* | |
697 | * ar_rdsync() | |
698 | * Try to move past a bad spot on a flawed archive as needed to continue | |
699 | * I/O. Clears error flags to allow I/O to continue. | |
700 | * Return: | |
701 | * 0 when ok to try i/o again, -1 otherwise. | |
702 | */ | |
703 | ||
704 | #if __STDC__ | |
705 | int | |
706 | ar_rdsync(void) | |
707 | #else | |
708 | int | |
709 | ar_rdsync() | |
710 | #endif | |
711 | { | |
712 | long fsbz; | |
713 | off_t cpos; | |
714 | off_t mpos; | |
715 | struct mtop mb; | |
716 | ||
717 | /* | |
718 | * Fail resync attempts at user request (done) or this is going to be | |
719 | * an update/append to a existing archive. if last i/o hit media end, | |
720 | * we need to go to the next volume not try a resync | |
721 | */ | |
722 | if ((done > 0) || (lstrval == 0)) | |
723 | return(-1); | |
724 | ||
725 | if ((act == APPND) || (act == ARCHIVE)) { | |
726 | warn(1, "Cannot allow updates to an archive with flaws."); | |
727 | return(-1); | |
728 | } | |
729 | if (io_ok) | |
730 | did_io = 1; | |
731 | ||
732 | switch(artyp) { | |
733 | case ISTAPE: | |
734 | /* | |
735 | * if the last i/o was a successful data transfer, we assume | |
736 | * the fault is just a bad record on the tape that we are now | |
737 | * past. If we did not get any data since the last resync try | |
738 | * to move the tape foward one PHYSICAL record past any | |
739 | * damaged tape section. Some tape drives are stubborn and need | |
740 | * to be pushed. | |
741 | */ | |
742 | if (io_ok) { | |
743 | io_ok = 0; | |
744 | lstrval = 1; | |
745 | break; | |
746 | } | |
747 | mb.mt_op = MTFSR; | |
748 | mb.mt_count = 1; | |
749 | if (ioctl(arfd, MTIOCTOP, &mb) < 0) | |
750 | break; | |
751 | lstrval = 1; | |
752 | break; | |
753 | case ISREG: | |
754 | case ISCHR: | |
755 | case ISBLK: | |
756 | /* | |
757 | * try to step over the bad part of the device. | |
758 | */ | |
759 | io_ok = 0; | |
760 | if (((fsbz = arsb.st_blksize) <= 0) || (artyp != ISREG)) | |
761 | fsbz = BLKMULT; | |
762 | if ((cpos = lseek(arfd, (off_t)0L, SEEK_CUR)) < 0) | |
763 | break; | |
764 | mpos = fsbz - (cpos % (off_t)fsbz); | |
765 | if (lseek(arfd, mpos, SEEK_CUR) < 0) | |
766 | break; | |
767 | lstrval = 1; | |
768 | break; | |
769 | case ISPIPE: | |
770 | default: | |
771 | /* | |
772 | * cannot recover on these archive device types | |
773 | */ | |
774 | io_ok = 0; | |
775 | break; | |
776 | } | |
777 | if (lstrval <= 0) { | |
bbab641f | 778 | warn(1, "Unable to recover from an archive read failure."); |
2741ad75 KM |
779 | return(-1); |
780 | } | |
781 | warn(0, "Attempting to recover from an archive read failure."); | |
782 | return(0); | |
783 | } | |
784 | ||
785 | /* | |
786 | * ar_fow() | |
787 | * Move the I/O position within the archive foward the specified number of | |
788 | * bytes as supported by the device. If we cannot move the requested | |
789 | * number of bytes, return the actual number of bytes moved in skipped. | |
790 | * Return: | |
791 | * 0 if moved the requested distance, -1 on complete failure, 1 on | |
792 | * partial move (the amount moved is in skipped) | |
793 | */ | |
794 | ||
795 | #if __STDC__ | |
796 | int | |
797 | ar_fow(off_t sksz, off_t *skipped) | |
798 | #else | |
799 | int | |
800 | ar_fow(sksz, skipped) | |
801 | off_t sksz; | |
802 | off_t *skipped; | |
803 | #endif | |
804 | { | |
805 | off_t cpos; | |
806 | off_t mpos; | |
807 | ||
808 | *skipped = 0; | |
809 | if (sksz <= 0) | |
810 | return(0); | |
811 | ||
812 | /* | |
813 | * we cannot move foward at EOF or error | |
814 | */ | |
815 | if (lstrval <= 0) | |
816 | return(lstrval); | |
817 | ||
818 | /* | |
819 | * Safer to read forward on devices where it is hard to find the end of | |
820 | * the media without reading to it. With tapes we cannot be sure of the | |
821 | * number of physical blocks to skip (we do not know physical block | |
822 | * size at this point), so we must only read foward on tapes! | |
823 | */ | |
824 | if (artyp != ISREG) | |
825 | return(0); | |
826 | ||
827 | /* | |
828 | * figure out where we are in the archive | |
829 | */ | |
830 | if ((cpos = lseek(arfd, (off_t)0L, SEEK_CUR)) >= 0) { | |
831 | /* | |
832 | * we can be asked to move farther than there are bytes in this | |
833 | * volume, if so, just go to file end and let normal buf_fill() | |
834 | * deal with the end of file (it will go to next volume by | |
835 | * itself) | |
836 | */ | |
837 | if ((mpos = cpos + sksz) > arsb.st_size) { | |
838 | *skipped = arsb.st_size - cpos; | |
839 | mpos = arsb.st_size; | |
840 | } else | |
841 | *skipped = sksz; | |
842 | if (lseek(arfd, mpos, SEEK_SET) >= 0) | |
843 | return(0); | |
844 | } | |
845 | syswarn(1, errno, "Foward positioning operation on archive failed"); | |
846 | lstrval = -1; | |
847 | return(-1); | |
848 | } | |
849 | ||
850 | /* | |
851 | * ar_rev() | |
852 | * move the i/o position within the archive backwards the specified byte | |
853 | * count as supported by the device. With tapes drives we RESET rdblksz to | |
854 | * the PHYSICAL blocksize. | |
855 | * NOTE: We should only be called to move backwards so we can rewrite the | |
856 | * last records (the trailer) of an archive (APPEND). | |
857 | * Return: | |
858 | * 0 if moved the requested distance, -1 on complete failure | |
859 | */ | |
860 | ||
861 | #if __STDC__ | |
862 | int | |
863 | ar_rev(off_t sksz) | |
864 | #else | |
865 | int | |
866 | ar_rev(sksz) | |
867 | off_t sksz; | |
868 | #endif | |
869 | { | |
870 | off_t cpos; | |
871 | struct mtop mb; | |
349d8467 | 872 | register int phyblk; |
2741ad75 | 873 | |
2741ad75 | 874 | /* |
82633d4d | 875 | * make sure we do not have try to reverse on a flawed archive |
2741ad75 KM |
876 | */ |
877 | if (lstrval < 0) | |
878 | return(lstrval); | |
879 | ||
880 | switch(artyp) { | |
881 | case ISPIPE: | |
82633d4d KM |
882 | if (sksz <= 0) |
883 | break; | |
2741ad75 KM |
884 | /* |
885 | * cannot go backwards on these critters | |
886 | */ | |
82633d4d KM |
887 | warn(1, "Reverse positioning on pipes is not supported."); |
888 | lstrval = -1; | |
889 | return(-1); | |
2741ad75 KM |
890 | case ISREG: |
891 | case ISBLK: | |
892 | case ISCHR: | |
893 | default: | |
82633d4d KM |
894 | if (sksz <= 0) |
895 | break; | |
896 | ||
2741ad75 KM |
897 | /* |
898 | * For things other than files, backwards movement has a very | |
899 | * high probability of failure as we really do not know the | |
900 | * true attributes of the device we are talking to (the device | |
901 | * may not even have the ability to lseek() in any direction). | |
82633d4d | 902 | * First we figure out where we are in the archive. |
2741ad75 | 903 | */ |
82633d4d KM |
904 | if ((cpos = lseek(arfd, (off_t)0L, SEEK_CUR)) < 0) { |
905 | syswarn(1, errno, | |
906 | "Unable to obtain current archive byte offset"); | |
907 | lstrval = -1; | |
908 | return(-1); | |
909 | } | |
2741ad75 KM |
910 | |
911 | /* | |
912 | * we may try to go backwards past the start when the archive | |
913 | * is only a single record. If this hapens and we are on a | |
914 | * multi volume archive, we need to go to the end of the | |
915 | * previous volume and continue our movement backwards from | |
82633d4d | 916 | * there. |
2741ad75 KM |
917 | */ |
918 | if ((cpos -= sksz) < (off_t)0L) { | |
919 | if (arvol > 1) { | |
82633d4d KM |
920 | /* |
921 | * this should never happen | |
922 | */ | |
923 | warn(1,"Reverse position on previous volume."); | |
2741ad75 KM |
924 | lstrval = -1; |
925 | return(-1); | |
926 | } | |
927 | cpos = (off_t)0L; | |
928 | } | |
82633d4d KM |
929 | if (lseek(arfd, cpos, SEEK_SET) < 0) { |
930 | syswarn(1, errno, "Unable to seek archive backwards"); | |
931 | lstrval = -1; | |
932 | return(-1); | |
933 | } | |
934 | break; | |
2741ad75 KM |
935 | case ISTAPE: |
936 | /* | |
937 | * Calculate and move the proper number of PHYSICAL tape | |
82633d4d | 938 | * blocks. If the sksz is not an even multiple of the physical |
2741ad75 KM |
939 | * tape size, we cannot do the move (this should never happen). |
940 | * (We also cannot handler trailers spread over two vols). | |
82633d4d | 941 | * get_phys() also makes sure we are in front of the filemark. |
2741ad75 | 942 | */ |
349d8467 | 943 | if ((phyblk = get_phys()) <= 0) { |
82633d4d KM |
944 | lstrval = -1; |
945 | return(-1); | |
2741ad75 KM |
946 | } |
947 | ||
82633d4d KM |
948 | /* |
949 | * make sure future tape reads only go by physical tape block | |
950 | * size (set rdblksz to the real size). | |
951 | */ | |
952 | rdblksz = phyblk; | |
953 | ||
954 | /* | |
955 | * if no movement is required, just return (we must be after | |
956 | * get_phys() so the physical blocksize is properly set) | |
957 | */ | |
958 | if (sksz <= 0) | |
959 | break; | |
960 | ||
961 | /* | |
962 | * ok we have to move. Make sure the tape drive can do it. | |
963 | */ | |
2741ad75 | 964 | if (sksz % phyblk) { |
82633d4d KM |
965 | warn(1, |
966 | "Tape drive unable to backspace requested amount"); | |
2741ad75 KM |
967 | lstrval = -1; |
968 | return(-1); | |
969 | } | |
970 | ||
2741ad75 | 971 | /* |
82633d4d | 972 | * move backwards the requested number of bytes |
2741ad75 | 973 | */ |
82633d4d KM |
974 | mb.mt_op = MTBSR; |
975 | mb.mt_count = sksz/phyblk; | |
976 | if (ioctl(arfd, MTIOCTOP, &mb) < 0) { | |
977 | syswarn(1,errno, "Unable to backspace tape %d blocks.", | |
978 | mb.mt_count); | |
979 | lstrval = -1; | |
980 | return(-1); | |
981 | } | |
982 | break; | |
2741ad75 | 983 | } |
82633d4d KM |
984 | lstrval = 1; |
985 | return(0); | |
2741ad75 KM |
986 | } |
987 | ||
988 | /* | |
989 | * get_phys() | |
82633d4d KM |
990 | * Determine the physical block size on a tape drive. We need the physical |
991 | * block size so we know how many bytes we skip over when we move with | |
992 | * mtio commands. We also make sure we are BEFORE THE TAPE FILEMARK when | |
993 | * return. | |
994 | * This is one really SLOW routine... | |
2741ad75 | 995 | * Return: |
349d8467 | 996 | * physical block size if ok (ok > 0), -1 otherwise |
2741ad75 KM |
997 | */ |
998 | ||
999 | #if __STDC__ | |
1000 | static int | |
1001 | get_phys(void) | |
1002 | #else | |
1003 | static int | |
1004 | get_phys() | |
1005 | #endif | |
1006 | { | |
82633d4d | 1007 | register int padsz = 0; |
bbab641f | 1008 | register int res; |
349d8467 | 1009 | register int phyblk; |
bbab641f | 1010 | struct mtop mb; |
82633d4d | 1011 | char scbuf[MAXBLK]; |
2741ad75 KM |
1012 | |
1013 | /* | |
82633d4d KM |
1014 | * move to the file mark, and then back up one record and read it. |
1015 | * this should tell us the physical record size the tape is using. | |
1016 | */ | |
1017 | if (lstrval == 1) { | |
1018 | /* | |
1019 | * we know we are at file mark when we get back a 0 from | |
1020 | * read() | |
1021 | */ | |
1022 | while ((res = read(arfd, scbuf, sizeof(scbuf))) > 0) | |
1023 | padsz += res; | |
1024 | if (res < 0) { | |
1025 | syswarn(1, errno, "Unable to locate tape filemark."); | |
1026 | return(-1); | |
1027 | } | |
1028 | } | |
2741ad75 | 1029 | |
82633d4d KM |
1030 | /* |
1031 | * move backwards over the file mark so we are at the end of the | |
1032 | * last record. | |
1033 | */ | |
1034 | mb.mt_op = MTBSF; | |
2741ad75 | 1035 | mb.mt_count = 1; |
82633d4d KM |
1036 | if (ioctl(arfd, MTIOCTOP, &mb) < 0) { |
1037 | syswarn(1, errno, "Unable to backspace over tape filemark."); | |
2741ad75 | 1038 | return(-1); |
bbab641f | 1039 | } |
2741ad75 KM |
1040 | |
1041 | /* | |
82633d4d KM |
1042 | * move backwards so we are in front of the last record and read it to |
1043 | * get physical tape blocksize. | |
2741ad75 | 1044 | */ |
82633d4d KM |
1045 | mb.mt_op = MTBSR; |
1046 | mb.mt_count = 1; | |
1047 | if (ioctl(arfd, MTIOCTOP, &mb) < 0) { | |
1048 | syswarn(1, errno, "Unable to backspace over last tape block."); | |
1049 | return(-1); | |
1050 | } | |
1051 | if ((phyblk = read(arfd, scbuf, sizeof(scbuf))) <= 0) { | |
1052 | syswarn(1, errno, "Cannot determine archive tape blocksize."); | |
bbab641f | 1053 | return(-1); |
82633d4d | 1054 | } |
bbab641f KM |
1055 | |
1056 | /* | |
82633d4d KM |
1057 | * read foward to the file mark, then back up in front of the filemark |
1058 | * (this is a bit paranoid, but should be safe to do). | |
bbab641f | 1059 | */ |
82633d4d KM |
1060 | while ((res = read(arfd, scbuf, sizeof(scbuf))) > 0) |
1061 | ; | |
1062 | if (res < 0) { | |
1063 | syswarn(1, errno, "Unable to locate tape filemark."); | |
bbab641f | 1064 | return(-1); |
82633d4d KM |
1065 | } |
1066 | mb.mt_op = MTBSF; | |
1067 | mb.mt_count = 1; | |
1068 | if (ioctl(arfd, MTIOCTOP, &mb) < 0) { | |
1069 | syswarn(1, errno, "Unable to backspace over tape filemark."); | |
1070 | return(-1); | |
1071 | } | |
bbab641f KM |
1072 | |
1073 | /* | |
82633d4d | 1074 | * set lstrval so we know that the filemark has not been seen |
bbab641f | 1075 | */ |
82633d4d KM |
1076 | lstrval = 1; |
1077 | ||
1078 | /* | |
1079 | * return if there was no padding | |
1080 | */ | |
1081 | if (padsz == 0) | |
349d8467 | 1082 | return(phyblk); |
bbab641f KM |
1083 | |
1084 | /* | |
82633d4d KM |
1085 | * make sure we can move backwards over the padding. (this should |
1086 | * never fail). | |
bbab641f | 1087 | */ |
82633d4d KM |
1088 | if (padsz % phyblk) { |
1089 | warn(1, "Tape drive unable to backspace requested amount"); | |
bbab641f | 1090 | return(-1); |
82633d4d | 1091 | } |
bbab641f KM |
1092 | |
1093 | /* | |
82633d4d KM |
1094 | * move backwards over the padding so the head is where it was when |
1095 | * we were first called (if required). | |
bbab641f | 1096 | */ |
82633d4d KM |
1097 | mb.mt_op = MTBSR; |
1098 | mb.mt_count = padsz/phyblk; | |
1099 | if (ioctl(arfd, MTIOCTOP, &mb) < 0) { | |
1100 | syswarn(1,errno,"Unable to backspace tape over %d pad blocks", | |
1101 | mb.mt_count); | |
2741ad75 | 1102 | return(-1); |
82633d4d | 1103 | } |
349d8467 | 1104 | return(phyblk); |
2741ad75 KM |
1105 | } |
1106 | ||
1107 | /* | |
1108 | * ar_next() | |
bbab641f KM |
1109 | * prompts the user for the next volume in this archive. For some devices |
1110 | * we may allow the media to be changed. Otherwise a new archive is | |
1111 | * prompted for. By pax spec, if there is no controlling tty or an eof is | |
1112 | * read on tty input, we must quit pax. | |
2741ad75 KM |
1113 | * Return: |
1114 | * 0 when ready to continue, -1 when all done | |
1115 | */ | |
1116 | ||
1117 | #if __STDC__ | |
1118 | int | |
1119 | ar_next(void) | |
1120 | #else | |
1121 | int | |
1122 | ar_next() | |
1123 | #endif | |
1124 | { | |
1125 | char buf[PAXPATHLEN+2]; | |
1126 | static int freeit = 0; | |
1127 | sigset_t o_mask; | |
1128 | ||
1129 | /* | |
bbab641f | 1130 | * WE MUST CLOSE THE DEVICE. A lot of devices must see last close, (so |
2741ad75 | 1131 | * things like writing EOF etc will be done) (Watch out ar_close() can |
bbab641f | 1132 | * also be called via a signal handler, so we must prevent a race. |
2741ad75 KM |
1133 | */ |
1134 | if (sigprocmask(SIG_BLOCK, &s_mask, &o_mask) < 0) | |
bbab641f | 1135 | syswarn(0, errno, "Unable to set signal mask"); |
2741ad75 KM |
1136 | ar_close(); |
1137 | if (sigprocmask(SIG_SETMASK, &o_mask, (sigset_t *)NULL) < 0) | |
bbab641f | 1138 | syswarn(0, errno, "Unable to restore signal mask"); |
2741ad75 | 1139 | |
82633d4d | 1140 | if (done || !wr_trail) |
2741ad75 KM |
1141 | return(-1); |
1142 | ||
1143 | tty_prnt("\nATTENTION! Pax archive volume change required.\n"); | |
1144 | ||
1145 | /* | |
1146 | * if i/o is on stdin or stdout, we cannot reopen it (we do not know | |
bbab641f | 1147 | * the name), the user will be forced to type it in. |
2741ad75 KM |
1148 | */ |
1149 | if (strcmp(arcname, STDO) && strcmp(arcname, STDN) && (artyp != ISREG) | |
1150 | && (artyp != ISPIPE)) { | |
1151 | if (artyp == ISTAPE) { | |
1152 | tty_prnt("%s ready for archive tape volume: %d\n", | |
1153 | arcname, arvol); | |
1154 | tty_prnt("Load the NEXT TAPE on the tape drive"); | |
1155 | } else { | |
1156 | tty_prnt("%s ready for archive volume: %d\n", | |
1157 | arcname, arvol); | |
1158 | tty_prnt("Load the NEXT STORAGE MEDIA (if required)"); | |
1159 | } | |
1160 | ||
1161 | if ((act == ARCHIVE) || (act == APPND)) | |
1162 | tty_prnt(" and make sure it is WRITE ENABLED.\n"); | |
1163 | else | |
1164 | tty_prnt("\n"); | |
1165 | ||
1166 | for(;;) { | |
1167 | tty_prnt("Type \"y\" to continue, \".\" to quit pax,"); | |
1168 | tty_prnt(" or \"s\" to switch to new device.\nIf you"); | |
1169 | tty_prnt(" cannot change storage media, type \"s\"\n"); | |
1170 | tty_prnt("Is the device ready and online? > "); | |
1171 | ||
1172 | if ((tty_read(buf,sizeof(buf))<0) || !strcmp(buf,".")){ | |
1173 | done = 1; | |
1174 | lstrval = -1; | |
1175 | tty_prnt("Quitting pax!\n"); | |
1176 | vfpart = 0; | |
1177 | return(-1); | |
1178 | } | |
1179 | ||
1180 | if ((buf[0] == '\0') || (buf[1] != '\0')) { | |
1181 | tty_prnt("%s unknown command, try again\n",buf); | |
1182 | continue; | |
1183 | } | |
1184 | ||
1185 | switch (buf[0]) { | |
1186 | case 'y': | |
1187 | case 'Y': | |
1188 | /* | |
1189 | * we are to continue with the same device | |
1190 | */ | |
1191 | if (ar_open(arcname) >= 0) | |
1192 | return(0); | |
1193 | tty_prnt("Cannot re-open %s, try again\n", | |
1194 | arcname); | |
1195 | continue; | |
1196 | case 's': | |
1197 | case 'S': | |
1198 | /* | |
1199 | * user wants to open a different device | |
1200 | */ | |
1201 | tty_prnt("Switching to a different archive\n"); | |
1202 | break; | |
1203 | default: | |
1204 | tty_prnt("%s unknown command, try again\n",buf); | |
1205 | continue; | |
1206 | } | |
1207 | break; | |
1208 | } | |
1209 | } else | |
1210 | tty_prnt("Ready for archive volume: %d\n", arvol); | |
1211 | ||
1212 | /* | |
1213 | * have to go to a different archive | |
1214 | */ | |
1215 | for (;;) { | |
1216 | tty_prnt("Input archive name or \".\" to quit pax.\n"); | |
1217 | tty_prnt("Archive name > "); | |
1218 | ||
1219 | if ((tty_read(buf, sizeof(buf)) < 0) || !strcmp(buf, ".")) { | |
1220 | done = 1; | |
1221 | lstrval = -1; | |
1222 | tty_prnt("Quitting pax!\n"); | |
1223 | vfpart = 0; | |
1224 | return(-1); | |
1225 | } | |
1226 | if (buf[0] == '\0') { | |
1227 | tty_prnt("Empty file name, try again\n"); | |
1228 | continue; | |
1229 | } | |
1230 | if (!strcmp(buf, "..")) { | |
1231 | tty_prnt("Illegal file name: .. try again\n"); | |
1232 | continue; | |
1233 | } | |
1234 | if (strlen(buf) > PAXPATHLEN) { | |
1235 | tty_prnt("File name too long, try again\n"); | |
1236 | continue; | |
1237 | } | |
1238 | ||
1239 | /* | |
1240 | * try to open new archive | |
1241 | */ | |
1242 | if (ar_open(buf) >= 0) { | |
1243 | if (freeit) { | |
1244 | (void)free(arcname); | |
1245 | freeit = 0; | |
1246 | } | |
1247 | if ((arcname = strdup(buf)) == NULL) { | |
1248 | done = 1; | |
1249 | lstrval = -1; | |
bbab641f | 1250 | warn(0, "Cannot save archive name."); |
2741ad75 KM |
1251 | return(-1); |
1252 | } | |
1253 | freeit = 1; | |
1254 | break; | |
1255 | } | |
1256 | tty_prnt("Cannot open %s, try again\n", buf); | |
1257 | continue; | |
1258 | } | |
1259 | return(0); | |
1260 | } |