7 2: Addr of output_table array
19 #include <sys/fcntl.h>
23 #define MAX(a,b) (((a)>(b))?(a):(b))
24 #define MIN(a,b) (((a)<(b))?(a):(b))
25 #define MAX_MEMBERS 64
27 char *xstrdup(const char *s) {
28 char *ret = strdup(s);
29 if(ret == NULL) exit(1);
41 static mem_buf_t *cab_mem_buf = NULL;
43 static void mem_buf_grow(mem_buf_t *buf,size_t newsize) {
46 if(buf->length < 0) exit(1);
47 if(newsize <= buf->length) return;
48 new_len = MAX(buf->length ? buf->length*2 : 65536,newsize);
49 p = realloc(buf->addr,new_len);
50 if(p == NULL) exit(1);
52 buf->length = new_len;
58 } write_buf_table[MAX_MEMBERS];
64 } output_table[MAX_MEMBERS+1];
66 static struct mspack_file *my_open(struct mspack_system *sys, char *filename, int mode) {
67 mem_buf_t *buf = NULL;
69 if(strcmp(filename,"/dev/cab")==0) {
70 if(mode != MSPACK_SYS_OPEN_READ) return NULL;
73 if(mode != MSPACK_SYS_OPEN_WRITE) return NULL;
75 for(i=0;i<MAX_MEMBERS;i++) {
76 if(write_buf_table[i].filename == NULL) {
77 printf("%s in %d\n",filename,i);
78 write_buf_table[i].filename = xstrdup(filename);
79 buf = &write_buf_table[i].buf;
86 return (struct mspack_file *) buf;
89 static void my_close(struct mspack_file *buf_) {
90 mem_buf_t *buf = (mem_buf_t*) buf_;
94 static int my_read(struct mspack_file *buf_, void *out, int count) {
95 mem_buf_t *buf = (mem_buf_t*) buf_;
96 count = MIN(buf->size - buf->pos, count);
97 memcpy(out,buf->addr + buf->pos,count);
102 static int my_write(struct mspack_file *buf_, void *in, int count) {
103 mem_buf_t *buf = (mem_buf_t*) buf_;
104 if(!buf->writable) return -1;
105 if(buf->length < buf->pos + count) mem_buf_grow(buf,buf->pos + count);
106 memcpy(buf->addr+buf->pos,in,count);
108 buf->size = MAX(buf->size,buf->pos);
112 static int my_seek(struct mspack_file *buf_, off_t off, int mode) {
113 mem_buf_t *buf = (mem_buf_t*) buf_;
116 case MSPACK_SYS_SEEK_START: newpos = off; break;
117 case MSPACK_SYS_SEEK_CUR: newpos = buf->pos + off; break;
118 case MSPACK_SYS_SEEK_END: newpos = buf->size - off; break;
121 if(newpos < 0) return -1;
122 if(newpos > buf->size) {
123 if(!buf->writable) return -1;
124 if(newpos > buf->length)
125 mem_buf_grow(buf,newpos);
131 static off_t my_tell(struct mspack_file *buf_) {
132 mem_buf_t *buf = (mem_buf_t*) buf_;
133 return buf ? buf->pos : 0;
136 static void my_message(struct mspack_file *file, char *format, ...) {
138 va_start(ap, format);
139 vfprintf(stderr, format, ap);
141 fputc((int) '\n', stderr);
145 static void *my_alloc(struct mspack_system *sys, size_t size) { return malloc(size); }
146 static void my_free(void *p) { free(p); }
147 static void my_copy(void *src, void *dest, size_t bytes) { memcpy(dest, src, bytes); }
149 static struct mspack_system my_system = {
165 int main(int argc, char **argv) {
166 struct mscab_decompressor *decomp;
167 struct mscabd_cabinet *cab;
168 struct mscabd_file *file;
170 size_t size = (size_t)user_info[1];
173 mem_buf.addr = user_info[0];
174 mem_buf.pos = mem_buf.writable = 0;
178 cab_mem_buf = &mem_buf;
180 decomp = mspack_create_cab_decompressor(&my_system);
183 cab = decomp->search(decomp,"/dev/cab");
186 for(file = cab->files;file;file=file->next)
187 decomp->extract(decomp,file,file->filename);
189 decomp->close(decomp,cab);
190 mspack_destroy_cab_decompressor(decomp);
192 printf("Success!\n");
194 for(i=0;i<MAX_MEMBERS && write_buf_table[i].filename;i++) {
195 output_table[i].filename = write_buf_table[i].filename;
196 output_table[i].data = write_buf_table[i].buf.addr;
197 output_table[i].length = write_buf_table[i].buf.size;
200 user_info[2] = (char*) output_table;
203 if(output_table[0].filename) {
204 printf("%s in 0\n",write_buf_table[0].filename);
205 fp = fopen(output_table[0].filename,"wb");
207 fwrite(output_table[0].data,1,output_table[0].length,fp);
209 printf("Wrote: %s\n",output_table[0].filename);