- int status = 3; /* Initial status at start of archive */
- int prev_status;
- extern time_t new_time;
- char save_linkflag;
-
- name_gather(); /* Gather all the names */
- open_archive(1); /* Open for reading */
-
- for(;;) {
- prev_status = status;
- status = read_header();
- switch (status) {
-
- case 1: /* Valid header */
- /* We should decode next field (mode) first... */
- /* Ensure incoming names are null terminated. */
- head->header.name[NAMSIZ-1] = '\0';
-
- if ( !name_match(head->header.name)
- || (f_new_files && hstat.st_mtime<new_time)
- || (f_exclude && check_exclude(head->header.name))) {
-
- int isextended = 0;
-
- if( head->header.linkflag==LF_VOLHDR
- || head->header.linkflag==LF_MULTIVOL
- || head->header.linkflag==LF_NAMES) {
- (*do_something)();
- continue;
- }
- if (f_show_omitted_dirs
- && head->header.linkflag == LF_DIR)
- msg ("Omitting %s\n", head->header.name);
- /* Skip past it in the archive */
- if (head->header.isextended)
- isextended = 1;
- save_linkflag = head->header.linkflag;
- userec(head);
- if (isextended) {
-/* register union record *exhdr;
-
- for (;;) {
- exhdr = findrec();
- if (!exhdr->ext_hdr.isextended) {
- userec(exhdr);
- break;
- }
- }
- userec(exhdr);*/
- skip_extended_headers();
- }
- /* Skip to the next header on the archive */
- if(save_linkflag != LF_DIR)
- skip_file((long)hstat.st_size);
- continue;
-
- }
-
- (*do_something)();
- continue;
-
- /*
- * If the previous header was good, tell them
- * that we are skipping bad ones.
- */
- case 0: /* Invalid header */
- userec(head);
- switch (prev_status) {
- case 3: /* Error on first record */
- msg("Hmm, this doesn't look like a tar archive.");
- /* FALL THRU */
- case 2: /* Error after record of zeroes */
- case 1: /* Error after header rec */
- msg("Skipping to next file header...");
- case 0: /* Error after error */
- break;
- }
- continue;
-
- case 2: /* Record of zeroes */
- userec(head);
- status = prev_status; /* If error after 0's */
- if (f_ignorez)
- continue;
- /* FALL THRU */
- case EOF: /* End of archive */
- break;
+ enum read_header status = HEADER_STILL_UNREAD;
+ enum read_header prev_status;
+
+ base64_init ();
+ name_gather ();
+ open_archive (ACCESS_READ);
+
+ while (1)
+ {
+ prev_status = status;
+ status = read_header ();
+ switch (status)
+ {
+ case HEADER_STILL_UNREAD:
+ abort ();
+
+ case HEADER_SUCCESS:
+
+ /* Valid header. We should decode next field (mode) first.
+ Ensure incoming names are null terminated. */
+
+ /* FIXME: This is a quick kludge before 1.12 goes out. */
+ current_stat.st_mtime
+ = TIME_FROM_CHARS (current_header->header.mtime);
+
+ if (!name_match (current_file_name)
+ || current_stat.st_mtime < newer_mtime_option
+ || excluded_name (current_file_name))
+ {
+ char save_typeflag;
+
+ if (current_header->header.typeflag == GNUTYPE_VOLHDR
+ || current_header->header.typeflag == GNUTYPE_MULTIVOL
+ || current_header->header.typeflag == GNUTYPE_NAMES)
+ {
+ (*do_something) ();
+ continue;