Subversion Repositories Scribus

Rev

Rev 415 | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
411 Franz 1
/***************************************************************************
2
 *   Copyright (C) 2004 by Riku Leino                                      *
3
 *   tsoots@welho.com                                                      *
4
 *                                                                         *
5
 *   This program is free software; you can redistribute it and/or modify  *
6
 *   it under the terms of the GNU General Public License as published by  *
7
 *   the Free Software Foundation; either version 2 of the License, or     *
8
 *   (at your option) any later version.                                   *
9
 *                                                                         *
10
 *   This program is distributed in the hope that it will be useful,       *
11
 *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
12
 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
13
 *   GNU General Public License for more details.                          *
14
 *                                                                         *
15
 *   You should have received a copy of the GNU General Public License     *
16
 *   along with this program; if not, write to the                         *
17
 *   Free Software Foundation, Inc.,                                       *
18
 *   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
19
 ***************************************************************************/
20
 
21
#include "sxwunzip.h"
22
 
23
#ifdef HAVE_XML
24
 
25
#include <stdlib.h>
26
#include <string.h>
27
#include <errno.h>
28
#include <fcntl.h>
29
 
438 tsoots 30
#include <utime.h>
411 Franz 31
 
32
#include <iostream>
33
#include "unzip.h"
34
#include <qdir.h>
35
 
36
#define CASESENSITIVITY (0)
37
#define WRITEBUFFERSIZE (8192)
38
#define MAXFILENAME (256)
39
 
40
int do_extract_currentfile(unzFile uf, const int* popt_extract_without_path, int* popt_overwrite, const char* password);
41
int do_extract_onefile(unzFile uf, const char* filename, int opt_extract_without_path, int opt_overwrite, const char* password);
42
int mymkdir(const char* dirname);
43
int makedir (char *newdir);
44
void change_file_date(const char* filename, uLong dosdate, tm_unz tmu_date);
45
 
46
SxwUnzip::SxwUnzip(QString zipFilePath)
47
{
48
        zipFile = zipFilePath;
49
}
50
 
51
QString SxwUnzip::getFile(QString name)
52
{
53
        QString pwd = QDir::currentDirPath();
54
        QString outDir = zipFile.left(zipFile.findRev("/") + 1);
55
        QFile f(outDir);
56
        QFileInfo fi(f);
57
        if (!fi.isWritable())
58
                outDir = QDir::homeDirPath() + "/.scribus/";
59
        QDir::setCurrent(outDir);
60
        const char *zipfilename = zipFile.ascii();
61
        const char *filename_to_extract = name.ascii();
62
        unzFile uf = unzOpen(zipfilename);;
63
        int ret = do_extract_onefile(uf,filename_to_extract, 0, 1, NULL);
64
        unzCloseCurrentFile(uf);
65
        QDir::setCurrent(pwd);
66
        if (ret != 0)
67
                return NULL;
68
        else
69
                return outDir + name;
70
}
71
 
72
SxwUnzip::~SxwUnzip()
73
{
74
 
75
}
76
 
77
 
78
int do_extract_onefile(unzFile uf, const char* filename, int opt_extract_without_path, int opt_overwrite, const char* password)
79
{
415 Franz 80
//    int err = UNZ_OK;
411 Franz 81
    if (unzLocateFile(uf,filename,CASESENSITIVITY)!=UNZ_OK)
82
        return 2;
83
 
84
    if (do_extract_currentfile(uf,&opt_extract_without_path,
85
                                      &opt_overwrite,
86
                                      password) == UNZ_OK)
87
        return 0;
88
    else
89
        return 1;
90
}
91
 
92
int do_extract_currentfile(unzFile uf, const int* popt_extract_without_path, int* popt_overwrite, const char* password)
93
{
94
    char filename_inzip[256];
95
    char* filename_withoutpath;
96
    char* p;
97
    int err=UNZ_OK;
98
    FILE *fout=NULL;
99
    void* buf;
100
    uInt size_buf;
101
 
102
    unz_file_info file_info;
103
//    uLong ratio=0;
104
    err = unzGetCurrentFileInfo(uf,&file_info,filename_inzip,sizeof(filename_inzip),NULL,0,NULL,0);
105
 
106
    if (err!=UNZ_OK)
107
        return err;
108
 
109
    size_buf = WRITEBUFFERSIZE;
110
    buf = (void*)malloc(size_buf);
111
    if (buf==NULL)
112
        return UNZ_INTERNALERROR;
113
 
114
    p = filename_withoutpath = filename_inzip;
115
    while ((*p) != '\0')
116
    {
117
        if (((*p)=='/') || ((*p)=='\\'))
118
            filename_withoutpath = p+1;
119
        p++;
120
    }
121
 
122
    if ((*filename_withoutpath)=='\0')
123
    {
124
        if ((*popt_extract_without_path)==0)
125
            mymkdir(filename_inzip);
126
    }
127
    else
128
    {
129
        char* write_filename;
130
        int skip=0;
131
 
132
        if ((*popt_extract_without_path)==0)
133
            write_filename = filename_inzip;
134
        else
135
            write_filename = filename_withoutpath;
136
 
137
        err = unzOpenCurrentFilePassword(uf,password);
138
 
139
        if ((skip==0) && (err==UNZ_OK))
140
        {
141
            fout=fopen(write_filename,"wb");
142
 
143
            /* some zipfile don't contain directory alone before file */
144
            if ((fout==NULL) && ((*popt_extract_without_path)==0) &&
145
                                (filename_withoutpath!=(char*)filename_inzip))
146
            {
147
                char c=*(filename_withoutpath-1);
148
                *(filename_withoutpath-1)='\0';
149
                makedir(write_filename);
150
                *(filename_withoutpath-1)=c;
151
                fout=fopen(write_filename,"wb");
152
            }
153
        }
154
 
155
        if (fout!=NULL)
156
        {
157
 
158
            do
159
            {
160
                err = unzReadCurrentFile(uf,buf,size_buf);
161
                if (err<0)
162
                    break;
163
                if (err>0)
164
                    if (fwrite(buf,err,1,fout)!=1)
165
                    {
166
                        err=UNZ_ERRNO;
167
                        break;
168
                    }
169
            }
170
            while (err>0);
171
            if (fout)
172
                    fclose(fout);
173
 
174
            if (err==0)
175
                change_file_date(write_filename,file_info.dosDate,
176
                                 file_info.tmu_date);
177
        }
178
 
179
        if (err==UNZ_OK)
180
            err = unzCloseCurrentFile (uf);
181
        else
182
            unzCloseCurrentFile(uf); /* don't lose the error */
183
    }
184
 
185
    free(buf);
186
    return err;
187
}
188
 
189
int mymkdir(char* dirname)
190
{
191
    int ret=0;
192
#ifdef WIN32
193
    ret = mkdir(dirname);
194
#else
195
#ifdef unix
196
    ret = mkdir (dirname,0775);
197
#endif
198
#endif
199
    return ret;
200
}
201
 
202
int makedir (const char *newdir)
203
{
204
  char *buffer ;
205
  char *p;
206
  int  len = (int)strlen(newdir);
207
 
208
  if (len <= 0)
209
    return 0;
210
 
211
  buffer = (char*)malloc(len+1);
212
  strcpy(buffer,newdir);
213
 
214
  if (buffer[len-1] == '/') {
215
    buffer[len-1] = '\0';
216
  }
217
  if (mymkdir(buffer) == 0)
218
    {
219
      free(buffer);
220
      return 1;
221
    }
222
 
223
  p = buffer+1;
224
  while (1)
225
    {
226
      char hold;
227
 
228
      while(*p && *p != '\\' && *p != '/')
229
        p++;
230
      hold = *p;
231
      *p = 0;
232
      if ((mymkdir(buffer) == -1) && (errno == ENOENT))
233
        {
234
          free(buffer);
235
          return 0;
236
        }
237
      if (hold == 0)
238
        break;
239
      *p++ = hold;
240
    }
241
  free(buffer);
242
  return 1;
243
}
244
 
245
/* change_file_date : change the date/time of a file
246
    filename : the filename of the file where date/time must be modified
247
    dosdate : the new date at the MSDos format (4 bytes)
248
    tmu_date : the SAME new date at the tm_unz format */
249
void change_file_date(const char* filename, uLong dosdate, tm_unz tmu_date)
250
{
251
  struct utimbuf ut;
252
  struct tm newdate;
253
  newdate.tm_sec = tmu_date.tm_sec;
254
  newdate.tm_min=tmu_date.tm_min;
255
  newdate.tm_hour=tmu_date.tm_hour;
256
  newdate.tm_mday=tmu_date.tm_mday;
257
  newdate.tm_mon=tmu_date.tm_mon;
258
  if (tmu_date.tm_year > 1900)
259
      newdate.tm_year=tmu_date.tm_year - 1900;
260
  else
261
      newdate.tm_year=tmu_date.tm_year ;
262
  newdate.tm_isdst=-1;
263
 
264
  ut.actime=ut.modtime=mktime(&newdate);
265
  utime(filename,&ut);
266
}
267
 
268
#endif // HAVE_XML
269