diff options
author | Mike Frysinger <vapier@gentoo.org> | 2008-08-29 00:09:56 -0400 |
---|---|---|
committer | Mike Frysinger <vapier@gentoo.org> | 2008-08-29 00:09:56 -0400 |
commit | b93b600b478ed0cbb23a4df16a887c1033e410f1 (patch) | |
tree | 4a798addcc26312b42e1a4663ac2fd0a14061c66 | |
parent | Declare explicit sign for char array (diff) | |
download | rpm2targz-b93b600b478ed0cbb23a4df16a887c1033e410f1.tar.gz rpm2targz-b93b600b478ed0cbb23a4df16a887c1033e410f1.tar.bz2 rpm2targz-b93b600b478ed0cbb23a4df16a887c1033e410f1.zip |
rewrite code again to be faster and fix bug in previous commit (#235290)
Signed-off-by: Mike Frysinger <vapier@gentoo.org>
-rw-r--r-- | rpmoffset.c | 62 |
1 files changed, 44 insertions, 18 deletions
diff --git a/rpmoffset.c b/rpmoffset.c index 10b7f4a..80ed563 100644 --- a/rpmoffset.c +++ b/rpmoffset.c @@ -4,38 +4,64 @@ /* Wouldn't it be a lot more sane if we could just untar these things? */ +#ifndef _GNU_SOURCE +# define _GNU_SOURCE +#endif + +#include <stdint.h> #include <stdio.h> -#include <stdlib.h> -#include <unistd.h> +#include <string.h> + +#ifndef ARRAY_SIZE +# define ARRAY_SIZE(a) (sizeof(a) / sizeof((a)[0])) +#endif +#ifndef BUFSIZ +# define BUFSIZ 8192 +#endif + +#define MAGIC_SIZE 3 int main(int argc, char *argv[]) { - size_t i; - unsigned char p[3]; + size_t i, read_cnt, offset, left; + FILE *fp = stdin; + char p[BUFSIZ]; + + const char magics[][MAGIC_SIZE] = { + { '\037', '\213', '\010' }, /* gzip */ + { 'B', 'Z', 'h' }, /* bzip */ + }; if (argc != 1) { puts("Usage: rpmoffset < rpmfile"); return 1; } + /* fp = fopen(argv[1], "r"); */ - if (read(0,p,3) != 3) - return 2; + offset = left = 0; + while (1) { + read_cnt = fread(p + left, 1, sizeof(p) - left, fp); + if (read_cnt + left < MAGIC_SIZE) + break; - for (i = 0; p[2] != 0 || p[2] != 0xff; ++i) { - if (p[0] == '\037' && p[1] == '\213' && p[2] == '\010') { - printf("%zu\n", i); - return 0; - - } else if (p[0] == 'B' && p[1] == 'Z' && p[2] == 'h') { - printf("%zu\n", i); - return 0; + for (i = 0; i < ARRAY_SIZE(magics); ++i) { + char *needle = memmem(p, sizeof(p), magics[i], MAGIC_SIZE); + if (needle) { + printf("%zu\n", offset + (needle - p)); + return 0; + } } - p[0] = p[1]; - p[1] = p[2]; - if (read(0, p+2, 1) != 1) - return 2; + offset += read_cnt; + if (left == 0) { + offset -= MAGIC_SIZE - 1; + left = MAGIC_SIZE - 1; + } + memmove(p, p + read_cnt - MAGIC_SIZE - 1, MAGIC_SIZE - 1); } + if (ferror(stdin)) + perror(argv[0]); + return 1; } |