summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorpixel <pixel>2003-01-27 18:07:53 +0000
committerpixel <pixel>2003-01-27 18:07:53 +0000
commit715e5efccac0144c48a2f8ae0c8b959506f74a9f (patch)
treecfbe2de00528d7de42d98cce02ea7c45b6b6e55e
parenta1176b45029cf5c7645627d38dfc96f66ea213f5 (diff)
paq compressor
-rw-r--r--configure.ac1
-rw-r--r--lib/Input.cc4
-rw-r--r--src/paq.cc123
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
/*
diff --git a/src/paq.cc b/src/paq.cc
index fff6569..65c9fc1 100644
--- a/src/paq.cc
+++ b/src/paq.cc
@@ -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