diff options
-rw-r--r-- | configure.ac | 1 | ||||
-rw-r--r-- | lib/Input.cc | 4 | ||||
-rw-r--r-- | src/paq.cc | 123 |
3 files changed, 128 insertions, 0 deletions
diff --git a/configure.ac b/configure.ac index b4864a2..3ba6acc 100644 --- a/configure.ac +++ b/configure.ac @@ -19,6 +19,7 @@ AC_PROG_MAKE_SET AC_PROG_RANLIB AC_PROG_YACC AM_PROG_LIBTOOL +AC_C_BIGENDIAN # Checks for libraries. AC_CHECK_LIB([c], [printf]) diff --git a/lib/Input.cc b/lib/Input.cc index 6644dd0..4648d91 100644 --- a/lib/Input.cc +++ b/lib/Input.cc @@ -20,7 +20,11 @@ #define S_ISREG(x) 1 #endif +#ifdef WORDS_BIGENDIAN +#define BUILTIN_SIG 0x4e504151 +#else #define BUILTIN_SIG 0x5141504e +#endif /* @@ -1,9 +1,132 @@ #include <dirent.h> +#include <iostream.h> #include <Main.h> #include <Input.h> #include <Output.h> +#include <Regex.h> +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#ifdef WORDS_BIGENDIAN +#define SIGNATURE 0x4e504151 +#else +#define SIGNATURE 0x5141504e +#endif + +String current_dir; + +extern "C" int sortdir(const void * d1, const void * d2) { + struct stat fstats1, fstats2; + String n; + + n = current_dir + "/" + (**((const dirent **)d1)).d_name; + stat(n.to_charp(), &fstats1); + + n = current_dir + "/" + (**((const dirent **)d2)).d_name; + stat(n.to_charp(), &fstats2); + + if (!(S_ISDIR(fstats1.st_mode) ^ S_ISDIR(fstats2.st_mode))) { + return alphasort(d1, d2); + } else { + if (S_ISDIR(fstats1.st_mode)) + return 1; + else + return -1; + } +} CODE_BEGINS +Output * Archive; + +void process_file(const String & filename) { + char t; + int size; + cerr << "Processing file " << filename << endl; + + Input * from = new Input(filename); + Output * to = new Output(filename + ".gz"); + + to->SetZ(); + + copy(from, to); + + delete to; + delete from; + + from = new Input(filename + ".gz"); + size = from->GetSize() + 4; + + Archive->write(&size, 4); + + delete from; + + t = 0; + Archive->write(&t, 1); +} + +void process_directory(const String & dirname) throw (GeneralException) { + struct dirent ** namelist; + int n, i; + char t; + struct stat fstats; + String fname; + + current_dir = dirname; + n = scandir(dirname.to_charp(), &namelist, NULL, sortdir); + cerr << "Processing directory " << dirname << endl; + + if (n < 0) { + throw GeneralException("Unable to open directory " + dirname); + } + + for (i = 0; i < n; i++) { + fname = dirname + "/" + namelist[i]->d_name; + stat(fname.to_charp(), &fstats); + if (S_ISDIR(fstats.st_mode)) { + if (!Regex("^\.{1,2}$").Match(namelist[i]->d_name)) { + t = strlen(namelist[i]->d_name); + Archive->write(&t, 1); + Archive->write(namelist[i]->d_name, t); + t = 0; + Archive->write(&t, 1); + Archive->write(&t, 1); + Archive->write(&t, 1); + Archive->write(&t, 1); + t = 1; + Archive->write(&t, 1); + process_directory(dirname + "/" + namelist[i]->d_name); + } + } else { + if (!Regex("\.gz$").Match(namelist[i]->d_name)) { + t = strlen(namelist[i]->d_name); + Archive->write(&t, 1); + Archive->write(namelist[i]->d_name, t); + process_file(dirname + "/" + namelist[i]->d_name); + } + } + free((void *)namelist[i]); + } + + free((void *)namelist); + + t = 0; + Archive->write(&t, 1); +} + +void build_archive(const String & dirname) { + char buff[4]; + + *((int *) buff) = SIGNATURE; + + Archive->write(buff, 4); + + process_directory(dirname); +} + virtual int startup(void) throw (GeneralException) { + Archive = new Output("/tmp/bleh.paq"); + process_directory("."); + return 0; } CODE_ENDS |