1 |
commit: aeadc86f00479f0b842c8f3f0905d21b35565c13 |
2 |
Author: Fabian Groffen <grobian <AT> gentoo <DOT> org> |
3 |
AuthorDate: Sun Nov 17 12:46:22 2019 +0000 |
4 |
Commit: Fabian Groffen <grobian <AT> gentoo <DOT> org> |
5 |
CommitDate: Sun Nov 17 12:46:22 2019 +0000 |
6 |
URL: https://gitweb.gentoo.org/proj/portage-utils.git/commit/?id=aeadc86f |
7 |
|
8 |
libq/xpak: try to seek to XPAKSTART in _xpak_open |
9 |
|
10 |
To make it easier to deal with assembled files (like binpkgs) just embed |
11 |
the offset logic in _xpak_open. This makes qxpak operate directly on |
12 |
tbz2 files, removing the need to split out using qtbz2 first. |
13 |
|
14 |
Signed-off-by: Fabian Groffen <grobian <AT> gentoo.org> |
15 |
|
16 |
libq/xpak.c | 39 +++++++++++++++++++++++++++++++++------ |
17 |
1 file changed, 33 insertions(+), 6 deletions(-) |
18 |
|
19 |
diff --git a/libq/xpak.c b/libq/xpak.c |
20 |
index 9692eab..82667b0 100644 |
21 |
--- a/libq/xpak.c |
22 |
+++ b/libq/xpak.c |
23 |
@@ -4,6 +4,7 @@ |
24 |
* |
25 |
* Copyright 2005-2010 Ned Ludd - <solar@g.o> |
26 |
* Copyright 2005-2014 Mike Frysinger - <vapier@g.o> |
27 |
+ * Copyright 2019- Fabian Groffen - <grobian@g.o> |
28 |
*/ |
29 |
|
30 |
#include "main.h" |
31 |
@@ -37,6 +38,10 @@ |
32 |
#define XPAK_START_LEN (8 + 4 + 4) |
33 |
#define XPAK_END_MSG "XPAKSTOP" |
34 |
#define XPAK_END_MSG_LEN 8 |
35 |
+#define TBZ2_END_MSG "STOP" |
36 |
+#define TBZ2_END_MSG_LEN 4 |
37 |
+#define TBZ2_END_SIZE_LEN 4 |
38 |
+#define TBZ2_FOOTER_LEN (TBZ2_END_MSG_LEN + TBZ2_END_SIZE_LEN) |
39 |
|
40 |
typedef struct { |
41 |
void *ctx; |
42 |
@@ -87,14 +92,36 @@ static _xpak_archive *_xpak_open(const int fd) |
43 |
if ((ret.fp = fdopen(fd, "r")) == NULL) |
44 |
return NULL; |
45 |
|
46 |
- /* verify this xpak doesnt suck */ |
47 |
+ /* verify this xpak doesn't suck */ |
48 |
if (fread(buf, 1, XPAK_START_LEN, ret.fp) != XPAK_START_LEN) |
49 |
goto close_and_ret; |
50 |
- if (memcmp(buf, XPAK_START_MSG, XPAK_START_MSG_LEN)) { |
51 |
+ if (memcmp(buf, XPAK_START_MSG, XPAK_START_MSG_LEN) != 0) { |
52 |
+ /* stream not positioned at XPAKSTART, let's see if we can |
53 |
+ * reposition the stream */ |
54 |
+ if (fseek(ret.fp, -TBZ2_FOOTER_LEN, SEEK_END) == 0) |
55 |
+ { |
56 |
+ if (fread(buf, 1, TBZ2_FOOTER_LEN, ret.fp) != TBZ2_FOOTER_LEN) |
57 |
+ goto close_and_ret; |
58 |
+ |
59 |
+ if (memcmp(buf + TBZ2_END_SIZE_LEN, |
60 |
+ TBZ2_END_MSG, TBZ2_END_MSG_LEN) == 0) |
61 |
+ { |
62 |
+ int xpaklen = READ_BE_INT32(buf); |
63 |
+ |
64 |
+ if (fseek(ret.fp, -(xpaklen + TBZ2_FOOTER_LEN), SEEK_END) == 0) |
65 |
+ { |
66 |
+ if (fread(buf, 1, XPAK_START_LEN, ret.fp) != XPAK_START_LEN) |
67 |
+ goto close_and_ret; |
68 |
+ if (memcmp(buf, XPAK_START_MSG, XPAK_START_MSG_LEN) == 0) |
69 |
+ goto setup_lens; |
70 |
+ } |
71 |
+ } |
72 |
+ } |
73 |
warn("Not an xpak file"); |
74 |
goto close_and_ret; |
75 |
} |
76 |
|
77 |
+setup_lens: |
78 |
/* calc index and data sizes */ |
79 |
ret.index_len = READ_BE_INT32((unsigned char*)buf+XPAK_START_MSG_LEN); |
80 |
ret.data_len = READ_BE_INT32((unsigned char*)buf+XPAK_START_MSG_LEN+4); |
81 |
@@ -124,7 +151,7 @@ xpak_process_fd( |
82 |
xpak_callback_t func) |
83 |
{ |
84 |
_xpak_archive *x; |
85 |
- char buf[BUFSIZE], ext[BUFSIZE*32]; |
86 |
+ char buf[BUFSIZE]; |
87 |
size_t in; |
88 |
|
89 |
x = _xpak_open(fd); |
90 |
@@ -142,8 +169,8 @@ xpak_process_fd( |
91 |
|
92 |
if (get_data) { |
93 |
/* the xpak may be large (like when it has CONTENTS) #300744 */ |
94 |
- x->data = (size_t)x->data_len < sizeof(ext) ? |
95 |
- ext : xmalloc(x->data_len); |
96 |
+ x->data = xmalloc(x->data_len); |
97 |
+ |
98 |
in = fread(x->data, 1, x->data_len, x->fp); |
99 |
if (in != (size_t)x->data_len) |
100 |
err("insufficient data read, got %zd, requested %d", |
101 |
@@ -157,7 +184,7 @@ xpak_process_fd( |
102 |
|
103 |
_xpak_close(x); |
104 |
|
105 |
- if (get_data && x->data != ext) |
106 |
+ if (get_data) |
107 |
free(x->data); |
108 |
|
109 |
return 0; |