summaryrefslogtreecommitdiffstats
path: root/mdk-stage1/mar/mar-extract-only.c
diff options
context:
space:
mode:
authorGuillaume Cottenceau <gc@mandriva.com>2000-11-09 23:09:17 +0000
committerGuillaume Cottenceau <gc@mandriva.com>2000-11-09 23:09:17 +0000
commitb695b4bd2408c4ad06a1dcdd95b2a95a3bf63fa5 (patch)
tree7f890201f7b16e38103141b0f47a47a30fe8d403 /mdk-stage1/mar/mar-extract-only.c
parent9166c569774a7580df1b39ccebc8cc5abd46b1d9 (diff)
downloaddrakx-backup-do-not-use-b695b4bd2408c4ad06a1dcdd95b2a95a3bf63fa5.tar
drakx-backup-do-not-use-b695b4bd2408c4ad06a1dcdd95b2a95a3bf63fa5.tar.gz
drakx-backup-do-not-use-b695b4bd2408c4ad06a1dcdd95b2a95a3bf63fa5.tar.bz2
drakx-backup-do-not-use-b695b4bd2408c4ad06a1dcdd95b2a95a3bf63fa5.tar.xz
drakx-backup-do-not-use-b695b4bd2408c4ad06a1dcdd95b2a95a3bf63fa5.zip
add `mar' archiving program
Diffstat (limited to 'mdk-stage1/mar/mar-extract-only.c')
-rw-r--r--mdk-stage1/mar/mar-extract-only.c196
1 files changed, 196 insertions, 0 deletions
diff --git a/mdk-stage1/mar/mar-extract-only.c b/mdk-stage1/mar/mar-extract-only.c
new file mode 100644
index 000000000..013631ce2
--- /dev/null
+++ b/mdk-stage1/mar/mar-extract-only.c
@@ -0,0 +1,196 @@
+/*
+ * Guillaume Cottenceau (gc@mandrakesoft.com)
+ *
+ * Copyright 2000 MandrakeSoft
+ *
+ * This software may be freely redistributed under the terms of the GNU
+ * public license.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ */
+
+/*
+ * mar - The Mandrake Archiver
+ *
+ * An archiver that supports compression (through zlib).
+ *
+ */
+
+/*
+ * This code should suffice for stage1 on-the-fly uncompression of kernel modules.
+ * (and it DOES perform tests and return values, blaaaah..)
+ */
+
+#include "mar.h"
+
+
+void gzerr(gzFile f) /* decrease code size */
+{
+ fprintf(stderr, gzerror(f, &gz_errnum));
+}
+
+int calc_integrity(mar_stream *s)
+{
+ char buf[4096];
+ int current_crc = 0;
+ if (gzseek(s->mar_gzfile, sizeof(int), SEEK_SET) != sizeof(int))
+ {
+ gzerr(s->mar_gzfile);
+ return -1;
+ }
+ while (!gzeof(s->mar_gzfile))
+ {
+ int bytes = gzread(s->mar_gzfile, buf, sizeof(buf));
+ if (bytes == -1)
+ {
+ gzerr(s->mar_gzfile);
+ return -1;
+ }
+ DEBUG_MAR(printf("D: mar::calc_integrity more-bytes-to-handle-for-crc %d\n", bytes););
+ while (bytes > 0)
+ {
+ bytes--;
+ current_crc += buf[bytes];
+ }
+ }
+ DEBUG_MAR(printf("D: mar::calc_integrity computed-crc %d\n", current_crc););
+ return current_crc;
+}
+
+
+int extract_file(mar_stream *s, char *filename, char *dest_dir)
+{
+ mar_element * elem = s->first_element;
+ while (elem != NULL)
+ {
+ if (strcmp(elem->filename, filename) == 0)
+ {
+ char *buf;
+ char *dest_file;
+ int fd;
+ dest_file = (char *) malloc(strlen(dest_dir) + strlen(filename) + 1);
+ strcpy(dest_file, dest_dir);
+ strcat(dest_file, filename);
+ fd = creat(dest_file, 00660);
+ if (fd == -1)
+ {
+ perror(dest_file);
+ return -1;
+ }
+ buf = (char *) malloc(elem->file_length);
+ if (buf == NULL)
+ {
+ perror(dest_file);
+ return -1;
+ }
+ if (gzseek(s->mar_gzfile, elem->data_offset, SEEK_SET) != elem->data_offset)
+ {
+ gzerr(s->mar_gzfile);
+ return -1;
+ }
+ if (gzread(s->mar_gzfile, buf, elem->file_length) != elem->file_length)
+ {
+ gzerr(s->mar_gzfile);
+ return -1;
+ }
+ if (write(fd, buf, elem->file_length) != elem->file_length)
+ {
+ perror(dest_file);
+ return -1;
+ }
+ close(fd); /* do not check return value for code size */
+ return 0;
+ }
+ elem = elem->next_element;
+ }
+ return 1; /* 1 for file_not_found_in_archive */
+}
+
+
+mar_stream * open_marfile(char *filename)
+{
+ int end_filetable = 0;
+ mar_stream * s = (mar_stream *) malloc(sizeof(mar_stream));
+ mar_element * previous_element = NULL;
+
+ /* mar_gzfile */
+ s->mar_gzfile = gzopen(filename, "rb");
+ if (s->mar_gzfile == NULL)
+ {
+ perror(filename);
+ return NULL;
+ }
+
+ /* crc32 */
+ if (gzread(s->mar_gzfile, &(s->crc32), sizeof(int)) != sizeof(int))
+ {
+ gzerr(s->mar_gzfile);
+ return NULL;
+ }
+
+ DEBUG_MAR(printf("D: mar::open_marfile crc-in-marfile %d\n", s->crc32););
+ /* verify integrity */
+ if (s->crc32 != calc_integrity(s))
+ {
+ fprintf(stderr, "E: mar::open_marfile CRC check failed\n");
+ return NULL;
+ }
+ else
+ if (gzseek(s->mar_gzfile, sizeof(int), SEEK_SET) != sizeof(int))
+ {
+ gzerr(s->mar_gzfile);
+ return NULL;
+ }
+
+ while (end_filetable == 0)
+ {
+ char buf[512];
+ int ptr = 0;
+ /* read filename */
+ do
+ {
+ if (gzread(s->mar_gzfile, &(buf[ptr]), sizeof(char)) != sizeof(char))
+ {
+ gzerr(s->mar_gzfile);
+ return NULL;
+ }
+ ptr++;
+ } while ((buf[ptr-1] != 0) && (ptr < 512));
+ /* ptr == 1 when we arrive on the "char 0" of the end of the filetable */
+ if (ptr > 1)
+ {
+ mar_element * e = (mar_element *) malloc(sizeof(mar_element));
+ e->filename = strdup(buf);
+ DEBUG_MAR(printf("D: mar::open_marfile processing-file %s\n", e->filename););
+ /* read file_length */
+ if (gzread(s->mar_gzfile, &(e->file_length), sizeof(int)) != sizeof(int))
+ {
+ gzerr(s->mar_gzfile);
+ return NULL;
+ }
+ /* read data_offset */
+ if (gzread(s->mar_gzfile, &(e->data_offset), sizeof(int)) != sizeof(int))
+ {
+ gzerr(s->mar_gzfile);
+ return NULL;
+ }
+ /* write down chaining */
+ if (previous_element == NULL)
+ s->first_element = e;
+ else
+ previous_element->next_element = e;
+ previous_element = e;
+ }
+ else
+ end_filetable = 1;
+
+ }
+ /* chaining for last element */
+ previous_element->next_element = NULL;
+
+ return s;
+}
+