                           /* arccomp.c, 29 May 10 */

#include "global.h"

#if HAVE_ARCHIVE_H
#include <archive.h>
#include <archive_entry.h>
#endif
#include <stdio.h>
#include <string.h>
 
#if HAVE_FNMATCH_H
#include <fnmatch.h>
#endif
#include "errors.h"
#include "isprop.h"
#include "usage.h"
#include "utils.h"
#include "singlefile.h"
#include "chkfiles.h"
#include "arccomp.h"


char *cur_arccomp_name;
BOOL started_arccomp_file;

#if HAVE_FNMATCH_H && HAVE_ARCHIVE_H
#define MAX_AC_BUFF_SIZE 5000

int num_ac_patterns;
char ac_patterns[MAX_AC_PATTERN_LEN];
char *cur_arccomp_name;

struct archive *ina;
#endif


BOOL is_arc_comp(char *filename)
{
#if HAVE_FNMATCH_H && HAVE_ARCHIVE_H
int pnum;
char *cur_ac_pattern = ac_patterns;

for (pnum=0; pnum < num_ac_patterns; pnum++)
   {
   if (pnum != 0)
      cur_ac_pattern+=1+strlen(cur_ac_pattern);
// printf("%s %d\n", filename, fnmatch(cur_ac_pattern, filename, 0));
   if (fnmatch(cur_ac_pattern, filename, 0) == 0)
      return TRUE;
   }
return FALSE;

#else
return FALSE;
#endif
}


#if HAVE_ARCHIVE_H
static void arc_warning(char *warn_str, ...)
{
print_warning(warn_str);
}


static char * read_arccomp_buff(void)
{
static char file_buff[MAX_AC_BUFF_SIZE];

file_bytes_read = archive_read_data(ina, file_buff, sizeof(file_buff));

// printf("bytes read %d\n", file_bytes_read);

if (file_bytes_read < 0)
   {
   print_warning(archive_error_string(ina));
   print_warning("\n");
   file_bytes_read=0;
   }

return file_buff;
}
#endif


void handle_arc_comp(char *filename)
{
#if HAVE_ARCHIVE_H
struct archive_entry *arc_entry;

ina = archive_read_new();
if (ina == NULL)
   arc_warning("Could not create archive reader\n", filename);
if (archive_read_support_compression_all(ina) != ARCHIVE_OK)
   {
   arc_warning("Could not enable decompression\n", filename);
   return;
   }
if (archive_read_support_format_all(ina) != ARCHIVE_OK)
   {
   arc_warning("Could not enable archive read formats\n", filename);
   return;
   }
// File descriptor 0 is stdin
if (archive_read_open_fd(ina, 0, 10240) != ARCHIVE_OK)
   {
   arc_warning("Could not open archive\n", filename);
   return;
   }
started_arccomp_file=TRUE;
cur_arccomp_name=filename;
while (archive_read_next_header(ina, &arc_entry) == ARCHIVE_OK)
   {
// printf("%s: ", archive_entry_pathname(arc_entry));

   // Only process regular files having non-zero size
   if (S_ISREG(archive_entry_mode(arc_entry)) &&
       (archive_entry_size(arc_entry) > 0))
      {
      if ((num_arg_patterns == 0) ||
	  match_file_pattern(archive_entry_pathname(arc_entry)))
         analyse_file(read_arccomp_buff, archive_entry_pathname(arc_entry));
      else
	 {
	 if (do_usage_file)
	    cnt_file_not_processed(archive_entry_pathname(arc_entry));
         }
      }
   }
started_arccomp_file=FALSE;

/* Close the archives.  */
if (archive_read_finish(ina) != ARCHIVE_OK)
   arc_warning("Error closing archive\n", filename);

#endif
}


#if HAVE_ARCHIVE_H
static void add_ac_suffix(char *ac_str, int *cur_ac_pattern_len)
{
if (save_arg_info(ac_patterns, cur_ac_pattern_len, MAX_AC_PATTERN_LEN,
		ac_str, "Size of file archive/compression suffixes exceeded at %s\n"))
   num_ac_patterns++;
}
#endif


void init_arccomp(void)
{
#if HAVE_FNMATCH_H && HAVE_ARCHIVE_H
int cur_ac_pattern_len = 0;

add_ac_suffix("*.bz2", &cur_ac_pattern_len);
add_ac_suffix("*.cpio", &cur_ac_pattern_len);
add_ac_suffix("*.cpgz", &cur_ac_pattern_len);
add_ac_suffix("*.gz", &cur_ac_pattern_len);
add_ac_suffix("*.iso", &cur_ac_pattern_len);
add_ac_suffix("*.tar", &cur_ac_pattern_len);
add_ac_suffix("*.tbz2", &cur_ac_pattern_len);
add_ac_suffix("*.tgz", &cur_ac_pattern_len);
add_ac_suffix("*.z", &cur_ac_pattern_len);
add_ac_suffix("*.Z", &cur_ac_pattern_len);
add_ac_suffix("*.zip", &cur_ac_pattern_len);
#endif
}

