- int found_stuff = 0;
- int status = 3;
- int prev_status;
- struct name *name;
-
- /* int dummy_head; */
- int number_of_records_to_skip = 0;
- int number_of_records_to_keep = 0;
- int number_of_kept_records_in_block;
- int sub_status;
- extern int write_archive_to_stdout;
-
-/* fprintf(stderr,"Junk files\n"); */
- name_gather();
- open_archive(2);
-
- while(!found_stuff) {
- prev_status=status;
- status=read_header();
- switch(status) {
- case EOF:
- found_stuff = 1;
- break;
-
- case 0:
- userec(head);
- switch(prev_status) {
- case 3:
- msg("This doesn't look like a tar archive.");
- /* FALL THROUGH */
- case 2:
- case 1:
- msg("Skipping to next header");
- /* FALL THROUGH */
- case 0:
- break;
- }
- break;
-
- case 1:
- /* head->header.name[NAMSIZ-1] = '\0'; */
- /* fprintf(stderr,"file %s\n",head->header.name); */
- if((name=name_scan(current_file_name))==(struct name *)0) {
- userec(head);
- /* fprintf(stderr,"Skip %ld\n",(long)(hstat.st_size)); */
- if (head->header.isextended)
- skip_extended_headers();
- skip_file((long)(hstat.st_size));
- break;
- }
- name->found = 1;
- found_stuff = 2;
- break;
-
- case 2:
- found_stuff = 1;
- break;
- }
- }
- /* fprintf(stderr,"Out of first loop\n"); */
-
- if(found_stuff!=2) {
- write_eot();
- close_archive();
- names_notfound();
- return;
- }
-
- if(write_archive_to_stdout)
- write_archive_to_stdout = 0;
- new_block = (union record *)malloc(blocksize);
- if(new_block==0) {
- msg("Can't allocate secondary block of %d bytes",blocksize);
- exit(EX_SYSTEM);
- }
-
- /* Save away records before this one in this block */
- number_of_new_records=ar_record-ar_block;
- number_of_records_needed = blocking - number_of_new_records;
- if(number_of_new_records)
- bcopy((void *)ar_block,(void *)new_block,(number_of_new_records)*RECORDSIZE);
-
- /* fprintf(stderr,"Saved %d recs, need %d more\n",number_of_new_records,number_of_records_needed); */
- userec(head);
- if (head->header.isextended)
- skip_extended_headers();
- skip_file((long)(hstat.st_size));
- found_stuff=0;
- /* goto flush_file; */
-
- for(;;) {
- /* Fill in a block */
- /* another_file: */
- if(ar_record==ar_last) {
- /* fprintf(stderr,"New block\n"); */
- flush_archive();
- number_of_blocks_read++;
- }
- sub_status = read_header();
- /* fprintf(stderr,"Header type %d\n",sub_status); */
-
- if(sub_status==2 && f_ignorez) {
- userec(head);
- continue;
- }
- if(sub_status==EOF || sub_status==2) {
- found_stuff = 1;
- bzero(new_block[number_of_new_records].charptr,RECORDSIZE*number_of_records_needed);
- number_of_new_records+=number_of_records_needed;
- number_of_records_needed = 0;
- write_block(0);
- break;
- }
-
- if(sub_status==0) {
- msg("Deleting non-header from archive.");
- userec(head);
- continue;
- }
-
- /* Found another header. Yipee! */
- /* head->header.name[NAMSIZ-1] = '\0'; */
- /* fprintf(stderr,"File %s ",head->header.name); */
- if(name=name_scan(current_file_name)) {
- name->found = 1;
- /* fprintf(stderr,"Flush it\n"); */
- /* flush_file: */
- /* decode_header(head,&hstat,&dummy_head,0); */
- userec(head);
- number_of_records_to_skip=(hstat.st_size+RECORDSIZE-1)/RECORDSIZE;
- /* fprintf(stderr,"Flushing %d recs from %s\n",number_of_records_to_skip,head->header.name); */
-
- while(ar_last-ar_record<=number_of_records_to_skip) {
-
- /* fprintf(stderr,"Block: %d <= %d ",ar_last-ar_record,number_of_records_to_skip); */
- number_of_records_to_skip -= (ar_last - ar_record);
- flush_archive();
- number_of_blocks_read++;
- /* fprintf(stderr,"Block %d left\n",number_of_records_to_skip); */
- }
- ar_record+=number_of_records_to_skip;
- /* fprintf(stderr,"Final %d\n",number_of_records_to_skip); */
- number_of_records_to_skip = 0;
- continue;
- }
-
- /* copy_header: */
- new_block[number_of_new_records]= *head;
- number_of_new_records++;
- number_of_records_needed--;
- number_of_records_to_keep=(hstat.st_size+RECORDSIZE-1)/RECORDSIZE;
- userec(head);
- if(number_of_records_needed==0)
- write_block(1);
- /* copy_data: */
- number_of_kept_records_in_block = ar_last - ar_record;
- if(number_of_kept_records_in_block > number_of_records_to_keep)
- number_of_kept_records_in_block = number_of_records_to_keep;
-
- /* fprintf(stderr,"Need %d kept_in %d keep %d\n",blocking,number_of_kept_records_in_block,number_of_records_to_keep); */
-
- while(number_of_records_to_keep) {
- int n;
-
- if(ar_record==ar_last) {
- /* fprintf(stderr,"Flush. . .\n"); */
- fl_read();
- number_of_blocks_read++;
- ar_record=ar_block;
- number_of_kept_records_in_block = blocking;
- if(number_of_kept_records_in_block > number_of_records_to_keep)
- number_of_kept_records_in_block = number_of_records_to_keep;
- }
- n = number_of_kept_records_in_block;
- if(n>number_of_records_needed)
- n = number_of_records_needed;
-
- /* fprintf(stderr,"Copying %d\n",n); */
- bcopy((void *)ar_record, (void *)(new_block+number_of_new_records), n*RECORDSIZE);
- number_of_new_records += n;
- number_of_records_needed -= n;
- ar_record += n;
- number_of_records_to_keep -= n;
- number_of_kept_records_in_block -= n;
- /* fprintf(stderr,"Now new %d need %d keep %d keep_in %d rec %d/%d\n",
- number_of_new_records,number_of_records_needed,number_of_records_to_keep,
- number_of_kept_records_in_block,ar_record-ar_block,ar_last-ar_block); */
-
- if(number_of_records_needed == 0) {
- write_block(1);
- }
- }
+ enum read_header previous_status = HEADER_STILL_UNREAD;
+ int found_end = 0;
+
+ name_gather ();
+ if (subcommand_option == UPDATE_SUBCOMMAND)
+ name_expand ();
+ open_archive (ACCESS_UPDATE);
+
+ while (!found_end)
+ {
+ enum read_header status = read_header ();
+
+ switch (status)
+ {
+ case HEADER_STILL_UNREAD:
+ abort ();
+
+ case HEADER_SUCCESS:
+ {
+ struct name *name;
+
+ if (subcommand_option == UPDATE_SUBCOMMAND
+ && (name = name_scan (current_file_name), name))
+ {
+ struct stat stat_data;
+ enum archive_format unused;
+
+ decode_header (current_header, ¤t_stat, &unused, 0);
+ if (stat (current_file_name, &stat_data) < 0)
+ ERROR ((0, errno, _("Cannot stat %s"), current_file_name));
+ else if (current_stat.st_mtime >= stat_data.st_mtime)
+ name->found = 1;
+ }
+ set_next_block_after (current_header);
+ if (current_header->oldgnu_header.isextended)
+ skip_extended_headers ();
+ skip_file ((long) current_stat.st_size);
+ break;
+ }
+
+ case HEADER_ZERO_BLOCK:
+ current_block = current_header;
+ found_end = 1;
+ break;
+
+ case HEADER_END_OF_FILE:
+ found_end = 1;
+ break;
+
+ case HEADER_FAILURE:
+ set_next_block_after (current_header);
+ switch (previous_status)
+ {
+ case HEADER_STILL_UNREAD:
+ WARN ((0, 0, _("This does not look like a tar archive")));
+ /* Fall through. */
+
+ case HEADER_SUCCESS:
+ case HEADER_ZERO_BLOCK:
+ ERROR ((0, 0, _("Skipping to next header")));
+ /* Fall through. */
+
+ case HEADER_FAILURE:
+ break;
+
+ case HEADER_END_OF_FILE:
+ abort ();
+ }
+ break;