cleaner gcc build process
[nestedvm.git] / src / tests / MSPackHelper.c
1 /*
2 UserInfo:
3     On start:
4         0: Addr of CAB/EXE
5         1: Length of CAB/EXE
6     On Edit:
7         2: Addr of output_table array
8
9 Exit codes:
10     0: Success
11     1: Internal Error
12     2: Invalid CAB
13 */
14
15 #include <stdio.h>
16 #include <stdlib.h>
17 #include <string.h>
18 #include <stdarg.h>
19 #include <sys/fcntl.h>
20
21 #include "mspack.h"
22
23 #define MAX(a,b) (((a)>(b))?(a):(b))
24 #define MIN(a,b) (((a)<(b))?(a):(b))
25 #define MAX_MEMBERS 64
26
27 char *xstrdup(const char *s) {
28     char *ret = strdup(s);
29     if(ret == NULL) exit(1);
30     return ret;
31 }
32
33 typedef struct {
34     char *addr;
35     int pos;
36     int size;
37     int length;
38     int writable;
39 } mem_buf_t;
40
41 static mem_buf_t *cab_mem_buf = NULL;
42
43 static void mem_buf_grow(mem_buf_t *buf,size_t newsize) {
44     size_t new_len;
45     char *p;
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);
51     buf->addr = p;
52     buf->length = new_len;
53 }
54
55 static struct {
56     char *filename;
57     mem_buf_t buf;
58 } write_buf_table[MAX_MEMBERS];
59
60 static struct {
61     char *filename;
62     char *data;
63     int length;
64 } output_table[MAX_MEMBERS+1];
65
66 static struct mspack_file *my_open(struct mspack_system *sys, char *filename, int mode) {
67     mem_buf_t *buf = NULL;
68     int i;
69     if(strcmp(filename,"/dev/cab")==0) {    
70         if(mode != MSPACK_SYS_OPEN_READ) return NULL;
71         buf = cab_mem_buf;
72     } else {
73         if(mode != MSPACK_SYS_OPEN_WRITE) return NULL;
74         
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;
80                 buf->writable = 1;
81                 break;
82             }
83         }
84     }
85     
86     return (struct mspack_file *) buf;
87 }
88
89 static void my_close(struct mspack_file *buf_) {
90     mem_buf_t *buf = (mem_buf_t*) buf_;
91     /* NO OP */
92 }
93
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);
98     buf->pos += count;
99     return count;
100 }
101
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);
107     buf->pos += count;
108     buf->size = MAX(buf->size,buf->pos);
109     return count;
110 }
111
112 static int my_seek(struct mspack_file *buf_, off_t off, int mode) {
113     mem_buf_t *buf = (mem_buf_t*) buf_;
114     int newpos;
115     switch(mode) {
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;
119         default: return -1;
120     }
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);
126     }
127     buf->pos = newpos;
128     return 0;
129 }
130
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;
134 }
135
136 static void my_message(struct mspack_file *file, char *format, ...) {
137   va_list ap;
138   va_start(ap, format);
139   vfprintf(stderr, format, ap);
140   va_end(ap);
141   fputc((int) '\n', stderr);
142   fflush(stderr);
143 }
144
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); }
148
149 static struct mspack_system my_system =  {
150     &my_open,
151     &my_close,
152     &my_read, 
153     &my_write,
154     &my_seek,
155     &my_tell,
156     &my_message,
157     &my_alloc,
158     &my_free,
159     &my_copy,
160     NULL
161 };
162
163 char *user_info[4];
164
165 int main(int argc, char **argv) {
166     struct mscab_decompressor *decomp;
167     struct mscabd_cabinet *cab;
168     struct mscabd_file *file;
169         mem_buf_t mem_buf;
170         size_t size = (size_t)user_info[1];
171         int i;
172         
173         mem_buf.addr = user_info[0];
174         mem_buf.pos = mem_buf.writable = 0;
175         mem_buf.length = -1;
176         mem_buf.size = size;
177         
178         cab_mem_buf = &mem_buf;
179                 
180     decomp = mspack_create_cab_decompressor(&my_system);
181     if(!decomp) exit(1);
182     
183     cab = decomp->search(decomp,"/dev/cab");
184     if(!cab) exit(2);
185     
186         for(file = cab->files;file;file=file->next)
187             decomp->extract(decomp,file,file->filename);
188         
189     decomp->close(decomp,cab);
190     mspack_destroy_cab_decompressor(decomp);
191         
192     printf("Success!\n");
193     
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;
198         }
199         
200         user_info[2] = (char*) output_table;
201         
202         /*
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");
206             if(fp) {
207                 fwrite(output_table[0].data,1,output_table[0].length,fp);
208                 fclose(fp);
209                 printf("Wrote: %s\n",output_table[0].filename);
210             }
211         }
212         */
213         
214     return 0;
215 }