3 Part of the swftools installer.
5 Copyright (c) 2004 Matthias Kramm <kramm@quiss.org>
7 This program is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2 of the License, or
10 (at your option) any later version.
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with this program; if not, write to the Free Software
19 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
34 typedef struct _reader
40 static void myread(void*self, void*mem, int len)
42 /*if(readpos+len >= sizeof(crndata)) {
43 len = sizeof(crndata) - readpos;
45 reader_t*r = (reader_t*)self;
46 memcpy(mem, r->mem+r->readpos, len);
51 typedef struct _writer
57 static void mywrite(void*self, void*buf, int len)
59 writer_t*w = (writer_t*)self;
60 memcpy(w->mem+w->memlen, buf, len);
64 static int verbose = 0;
65 static void msg(char*format, ...)
72 va_start(arglist, format);
73 vsprintf(buf, format, arglist);
76 while(l && buf[l-1]=='\n') {
80 printf("(archive) %s\n", buf);
84 static int create_directory(char*path,statusfunc_t f)
86 if(!path || !*path || (*path=='.' && (!path[1] || path[1]=='.')))
87 return 1; //nothing to do
88 while(path[0]=='.' && (path[1]=='/' || path[1]=='\\'))
92 if(PathIsDirectoryA(path))
96 if(stat(path, &st)>=0) {
97 if(S_ISDIR(st.st_mode)) {
98 return 1; /* already exists */
103 if(mkdir(path,0755)<0) {
105 sprintf(buf, "create directory \"%s\" FAILED", path);
111 static int goto_directory(char*path,statusfunc_t f)
115 sprintf(buf, "changing to directory \"%s\" FAILED", path);
121 static char basenamebuf[256];
122 static char*get_directory(char*filename)
124 char*r1 = strrchr(filename, '\\');
125 char*r2 = strrchr(filename, '/');
126 char*r = r1>r2?r1:r2;
129 memcpy(basenamebuf, filename, r-filename);
130 basenamebuf[r-filename] = 0;
131 //msg("directory name of \"%s\" is \"%s\"", filename, basenamebuf);
134 static int write_file(char*filename, void*mem, int len,statusfunc_t f)
136 while(filename[0]=='.' && (filename[1]=='/' || filename[1]=='\\'))
139 filename=strdup(filename);
147 msg("create file \"%s\" (%d bytes)", filename, len);
148 FILE*fo = fopen(filename, "wb");
151 sprintf(buf, "Couldn't create file %s", filename);
156 fwrite(mem, len, 1, fo);
162 int unpack_archive(void*data, char*destdir, statusfunc_t f)
167 r.mem = (unsigned char*)data;
170 f(0, "Reading compressed data");
171 depack_init(&d,&r,myread);
174 w.mem = malloc(d.size);
177 f(0, "Decompressing data");
178 depack_process(&d,&w,mywrite);
181 f(0, "Creating installation directory");
182 if(!create_directory(destdir,f)) return 0;
183 f(0, "Changing to installation directory");
184 if(!goto_directory(destdir,f)) return 0;
186 f(0, "Copying files...");
188 while(pos<w.memlen) {
189 unsigned char*mem = w.mem;
193 memcpy(id, &mem[pos], 3);
197 int len = mem[pos]|mem[pos+1]<<8|mem[pos+2]<<16|mem[pos+3]<<24;
201 char*filename = &mem[pos];
202 int l = strlen(filename);
205 if(verbose) printf("[%s] %s %d\n", id, filename, len);
207 sprintf(buf, "[%s] %s (%d bytes)", id, filename, len);
209 if(*(U32*)id == *(U32*)"DIR") {
210 if(!create_directory(filename,f)) return 0;
212 if(!create_directory(get_directory(filename),f)) return 0;
213 if(!write_file(filename,mem+pos,len,f)) return 0;
218 f(0, "Finishing Installation");