1 /* Update a tar archive.
2 Copyright (C) 1988, 1992 Free Software Foundation
4 This file is part of GNU Tar.
6 GNU Tar is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2, or (at your option)
11 GNU Tar is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with GNU Tar; see the file COPYING. If not, write to
18 the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
20 /* JF implement the 'r' 'u' and 'A' options for tar. */
21 /* The 'A' option is my own invention: It means that the file-names are
22 tar files, and they should simply be appended to the end of the archive.
23 No attempt is made to block the reads from the args; if they're on raw
24 tape or something like that, it'll probably lose. . . */
26 #include <sys/types.h>
33 #ifdef HAVE_SYS_MTIO_H
34 #include <sys/ioctl.h>
58 int time_to_start_writing
= 0; /* We've hit the end of the old stuff,
59 and its time to start writing new stuff
60 to the tape. This involves seeking
61 back one block and re-writing the current
62 block (which has been changed). */
64 char *output_start
; /* Pointer to where we started to write in
65 the first block we write out. This is used
66 if we can't backspace the output and have
67 to null out the first part of the block */
69 extern void skip_file ();
70 extern void skip_extended_headers ();
72 extern union record
*head
;
73 extern struct stat hstat
;
76 void close_archive ();
78 void decode_header ();
81 void flush_archive ();
83 struct name
*name_scan ();
84 char *name_from_list ();
87 void names_notfound ();
94 /* Implement the 'r' (add files to end of archive), and 'u' (add files to
95 end of archive if they arent there, or are more up to date than the
96 version in the archive.) commands.*/
105 extern void dump_file ();
108 if (cmd_mode
== CMD_UPDATE
)
110 open_archive (2); /* Open for updating */
114 prev_status
= status
;
115 status
= read_header ();
122 case 0: /* A bad record */
127 msg ("This doesn't look like a tar archive.");
131 msg ("Skipping to next header");
139 /* printf("File %s\n",head->header.name); */
140 /* head->header.name[NAMSIZ-1]='\0'; */
141 if (cmd_mode
== CMD_UPDATE
&& (name
= name_scan (current_file_name
)))
144 /* struct stat hstat; */
148 decode_header (head
, &hstat
, &head_standard
, 0);
149 if (stat (current_file_name
, &nstat
) < 0)
151 msg_perror ("can't stat %s:", current_file_name
);
155 if (hstat
.st_mtime
>= nstat
.st_mtime
)
160 if (head
->header
.isextended
)
161 skip_extended_headers ();
162 skip_file ((long) hstat
.st_size
);
174 time_to_start_writing
= 1;
175 output_start
= ar_record
->charptr
;
177 while (p
= name_from_list ())
179 if (f_confirm
&& !confirm ("add", p
))
181 if (cmd_mode
== CMD_CAT
)
184 dump_file (p
, -1, 1);
192 /* Catenate file p to the archive without creating a header for it. It had
193 better be a tar file or the archive is screwed */
205 if (0 != stat (p
, &statbuf
) || (fd
= open (p
, O_RDONLY
| O_BINARY
)) < 0)
207 msg_perror ("can't open file %s", p
);
212 bytes_left
= statbuf
.st_size
;
214 while (bytes_left
> 0)
217 bufsiz
= endofrecs ()->charptr
- start
->charptr
;
218 if (bytes_left
< bufsiz
)
221 count
= bufsiz
% RECORDSIZE
;
223 bzero (start
->charptr
+ bytes_left
, (int) (RECORDSIZE
- count
));
225 count
= read (fd
, start
->charptr
, bufsiz
);
228 msg_perror ("read error at byte %ld reading %d bytes in file %s", statbuf
.st_size
- bytes_left
, bufsiz
, p
);
229 exit (EX_ARGSBAD
); /* FOO */
232 userec (start
+ (count
- 1) / RECORDSIZE
);
235 msg ("%s: file shrunk by %d bytes, yark!", p
, bytes_left
);
243 bprint (fp
, buf
, num
)
249 if (num
== 0 || num
== -1)
257 else if (c
>= ' ' && c
<= '~')
272 /* fputs("\\-",fp); */
275 fprintf (fp
, "\\%03o", c
);
284 int number_of_blocks_read
= 0;
286 int number_of_new_records
= 0;
287 int number_of_records_needed
= 0;
289 union record
*new_block
= 0;
290 union record
*save_block
= 0;
300 /* int dummy_head; */
301 int number_of_records_to_skip
= 0;
302 int number_of_records_to_keep
= 0;
303 int number_of_kept_records_in_block
;
305 extern int write_archive_to_stdout
;
307 /* fprintf(stderr,"Junk files\n"); */
313 prev_status
= status
;
314 status
= read_header ();
326 msg ("This doesn't look like a tar archive.");
330 msg ("Skipping to next header");
338 /* head->header.name[NAMSIZ-1] = '\0'; */
339 /* fprintf(stderr,"file %s\n",head->header.name); */
340 if ((name
= name_scan (current_file_name
)) == (struct name
*) 0)
343 /* fprintf(stderr,"Skip %ld\n",(long)(hstat.st_size)); */
344 if (head
->header
.isextended
)
345 skip_extended_headers ();
346 skip_file ((long) (hstat
.st_size
));
358 /* fprintf(stderr,"Out of first loop\n"); */
360 if (found_stuff
!= 2)
368 if (write_archive_to_stdout
)
369 write_archive_to_stdout
= 0;
370 new_block
= (union record
*) malloc (blocksize
);
373 msg ("Can't allocate secondary block of %d bytes", blocksize
);
377 /* Save away records before this one in this block */
378 number_of_new_records
= ar_record
- ar_block
;
379 number_of_records_needed
= blocking
- number_of_new_records
;
380 if (number_of_new_records
)
381 bcopy ((void *) ar_block
, (void *) new_block
, (number_of_new_records
) * RECORDSIZE
);
383 /* fprintf(stderr,"Saved %d recs, need %d more\n",number_of_new_records,number_of_records_needed); */
385 if (head
->header
.isextended
)
386 skip_extended_headers ();
387 skip_file ((long) (hstat
.st_size
));
389 /* goto flush_file; */
393 /* Fill in a block */
395 if (ar_record
== ar_last
)
397 /* fprintf(stderr,"New block\n"); */
399 number_of_blocks_read
++;
401 sub_status
= read_header ();
402 /* fprintf(stderr,"Header type %d\n",sub_status); */
404 if (sub_status
== 2 && f_ignorez
)
409 if (sub_status
== EOF
|| sub_status
== 2)
412 bzero (new_block
[number_of_new_records
].charptr
, RECORDSIZE
* number_of_records_needed
);
413 number_of_new_records
+= number_of_records_needed
;
414 number_of_records_needed
= 0;
421 msg ("Deleting non-header from archive.");
426 /* Found another header. Yipee! */
427 /* head->header.name[NAMSIZ-1] = '\0'; */
428 /* fprintf(stderr,"File %s ",head->header.name); */
429 if (name
= name_scan (current_file_name
))
432 /* fprintf(stderr,"Flush it\n"); */
434 /* decode_header(head,&hstat,&dummy_head,0); */
436 number_of_records_to_skip
= (hstat
.st_size
+ RECORDSIZE
- 1) / RECORDSIZE
;
437 /* fprintf(stderr,"Flushing %d recs from %s\n",number_of_records_to_skip,head->header.name); */
439 while (ar_last
- ar_record
<= number_of_records_to_skip
)
442 /* fprintf(stderr,"Block: %d <= %d ",ar_last-ar_record,number_of_records_to_skip); */
443 number_of_records_to_skip
-= (ar_last
- ar_record
);
445 number_of_blocks_read
++;
446 /* fprintf(stderr,"Block %d left\n",number_of_records_to_skip); */
448 ar_record
+= number_of_records_to_skip
;
449 /* fprintf(stderr,"Final %d\n",number_of_records_to_skip); */
450 number_of_records_to_skip
= 0;
455 new_block
[number_of_new_records
] = *head
;
456 number_of_new_records
++;
457 number_of_records_needed
--;
458 number_of_records_to_keep
= (hstat
.st_size
+ RECORDSIZE
- 1) / RECORDSIZE
;
460 if (number_of_records_needed
== 0)
463 number_of_kept_records_in_block
= ar_last
- ar_record
;
464 if (number_of_kept_records_in_block
> number_of_records_to_keep
)
465 number_of_kept_records_in_block
= number_of_records_to_keep
;
467 /* fprintf(stderr,"Need %d kept_in %d keep %d\n",blocking,number_of_kept_records_in_block,number_of_records_to_keep); */
469 while (number_of_records_to_keep
)
473 if (ar_record
== ar_last
)
475 /* fprintf(stderr,"Flush. . .\n"); */
477 number_of_blocks_read
++;
478 ar_record
= ar_block
;
479 number_of_kept_records_in_block
= blocking
;
480 if (number_of_kept_records_in_block
> number_of_records_to_keep
)
481 number_of_kept_records_in_block
= number_of_records_to_keep
;
483 n
= number_of_kept_records_in_block
;
484 if (n
> number_of_records_needed
)
485 n
= number_of_records_needed
;
487 /* fprintf(stderr,"Copying %d\n",n); */
488 bcopy ((void *) ar_record
, (void *) (new_block
+ number_of_new_records
), n
* RECORDSIZE
);
489 number_of_new_records
+= n
;
490 number_of_records_needed
-= n
;
492 number_of_records_to_keep
-= n
;
493 number_of_kept_records_in_block
-= n
;
494 /* fprintf(stderr,"Now new %d need %d keep %d keep_in %d rec %d/%d\n",
495 number_of_new_records,number_of_records_needed,number_of_records_to_keep,
496 number_of_kept_records_in_block,ar_record-ar_block,ar_last-ar_block); */
498 if (number_of_records_needed
== 0)
514 /* fprintf(stderr,"Write block\n"); */
515 /* We've filled out a block. Write it out. */
517 /* Backspace back to where we started. . . */
518 if (archive
!= STDIN
)
519 (void) move_arch (-(number_of_blocks_read
+ 1));
521 save_block
= ar_block
;
522 ar_block
= new_block
;
524 if (archive
== STDIN
)
528 if (archive
== STDOUT
)
530 ar_block
= save_block
;
534 /* Move the tape head back to where we were */
535 if (archive
!= STDIN
)
536 (void) move_arch (number_of_blocks_read
);
537 number_of_blocks_read
--;
540 number_of_records_needed
= blocking
;
541 number_of_new_records
= 0;
544 /* Move archive descriptor by n blocks worth. If n is positive we move
545 forward, else we move negative. If its a tape, MTIOCTOP had better
546 work. If its something else, we try to seek on it. If we can't
568 if ((er
= rmtioctl (archive
, MTIOCTOP
, &t
)) >= 0)
570 if (errno
== EIO
&& (er
= rmtioctl (archive
, MTIOCTOP
, &t
)) >= 0)
574 cur
= rmtlseek (archive
, 0L, 1);
575 cur
+= blocksize
* n
;
577 /* fprintf(stderr,"Fore to %x\n",cur); */
578 if (rmtlseek (archive
, cur
, 0) != cur
)
580 /* Lseek failed. Try a different method */
581 msg ("Couldn't re-position archive file.");