Subversion Repositories Scribus

Rev

Rev 2702 | Rev 4430 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
1576 tsoots 1
/***************************************************************************
2
 *   Copyright (C) 2004 by Riku Leino                                      *
3
 *   tsoots@gmail.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 "fileunzip.h"
22
 
23
#include <stdlib.h>
24
#include <string.h>
25
#include <errno.h>
26
#include <fcntl.h>
2632 craig 27
 
28
#ifdef HAVE_SYS_TYPES_H
29
#include <sys/types.h>
30
#endif
31
#ifdef HAVE_SYS_STAT_H
1620 tsoots 32
#include <sys/stat.h>
2632 craig 33
#endif
1576 tsoots 34
 
2702 craig 35
#ifdef HAVE_UNISTD_H
1576 tsoots 36
# include <unistd.h>
2702 craig 37
#endif
38
 
2730 cbradney 39
#ifndef _MSC_VER
40
#include <utime.h>
41
#else
42
#include <direct.h>
43
#include <time.h>
44
#include <sys/utime.h>
45
#endif
1576 tsoots 46
 
47
#include <iostream>
48
#include "unzip.h"
49
#include <qdir.h>
50
 
51
#define CASESENSITIVITY (0)
52
#define WRITEBUFFERSIZE (8192)
53
#define MAXFILENAME (256)
54
 
55
int do_extract_currentfile(unzFile uf, const int* popt_extract_without_path, int* popt_overwrite, const char* password);
56
int do_extract_onefile(unzFile uf, const char* filename, int opt_extract_without_path, int opt_overwrite, const char* password);
57
int mymkdir(const char* dirname);
58
int makedir (char *newdir);
59
void change_file_date(const char* filename, uLong dosdate, tm_unz tmu_date);
60
 
61
FileUnzip::FileUnzip(QString zipFilePath)
62
{
63
        zipFile = zipFilePath;
64
}
65
 
66
QString FileUnzip::getFile(QString name)
67
{
68
        QString pwd = QDir::currentDirPath();
69
        QString outDir = zipFile.left(zipFile.findRev("/") + 1);
70
        QFile f(outDir);
71
        QFileInfo fi(f);
72
        if (!fi.isWritable())
73
                outDir = QDir::homeDirPath() + "/.scribus/";
74
        QDir::setCurrent(outDir);
75
        const char *zipfilename = zipFile.ascii();
76
        const char *filename_to_extract = name.ascii();
77
        unzFile uf = unzOpen(zipfilename);;
78
        int ret = do_extract_onefile(uf,filename_to_extract, 0, 1, NULL);
79
        unzCloseCurrentFile(uf);
80
        QDir::setCurrent(pwd);
81
        if (ret != 0)
82
                return NULL;
83
        else
84
                return outDir + name;
85
}
86
 
87
FileUnzip::~FileUnzip()
88
{
89
 
90
}
91
 
92
 
93
int mymkdir(char* dirname)
94
{
95
    int ret=0;
2730 cbradney 96
#ifndef _MSC_VER
1576 tsoots 97
    ret = mkdir (dirname,0775);
2730 cbradney 98
#else
99
        ret = _mkdir(dirname);
100
#endif
1576 tsoots 101
    return ret;
102
}
103
 
104
int makedir (char *newdir)
105
{
106
  char *buffer ;
107
  char *p;
108
  int  len = (int)strlen(newdir);
109
 
110
  if (len <= 0)
111
    return 0;
112
 
113
  buffer = (char*)malloc(len+1);
114
  strcpy(buffer,newdir);
115
 
116
  if (buffer[len-1] == '/') {
117
    buffer[len-1] = '\0';
118
  }
119
  if (mymkdir(buffer) == 0)
120
    {
121
      free(buffer);
122
      return 1;
123
    }
124
 
125
  p = buffer+1;
126
  while (1)
127
    {
128
      char hold;
129
 
130
      while(*p && *p != '\\' && *p != '/')
131
        p++;
132
      hold = *p;
133
      *p = 0;
134
      if ((mymkdir(buffer) == -1) && (errno == ENOENT))
135
        {
136
          free(buffer);
137
          return 0;
138
        }
139
      if (hold == 0)
140
        break;
141
      *p++ = hold;
142
    }
143
  free(buffer);
144
  return 1;
145
}
146
 
147
 
148
 
149
int do_extract_onefile(unzFile uf, const char* filename, int opt_extract_without_path, int opt_overwrite, const char* password)
150
{
151
//    int err = UNZ_OK;
152
    if (unzLocateFile(uf,filename,CASESENSITIVITY)!=UNZ_OK)
153
        return 2;
154
 
155
    if (do_extract_currentfile(uf,&opt_extract_without_path,
156
                                      &opt_overwrite,
157
                                      password) == UNZ_OK)
158
        return 0;
159
    else
160
        return 1;
161
}
162
 
163
int do_extract_currentfile(unzFile uf, const int* popt_extract_without_path, int*, const char* password)
164
{
165
    char filename_inzip[256];
166
    char* filename_withoutpath;
167
    char* p;
168
    int err=UNZ_OK;
169
    FILE *fout=NULL;
170
    void* buf;
171
    uInt size_buf;
172
 
173
    unz_file_info file_info;
174
//    uLong ratio=0;
175
    err = unzGetCurrentFileInfo(uf,&file_info,filename_inzip,sizeof(filename_inzip),NULL,0,NULL,0);
176
 
177
    if (err!=UNZ_OK)
178
        return err;
179
 
180
    size_buf = WRITEBUFFERSIZE;
181
    buf = (void*)malloc(size_buf);
182
    if (buf==NULL)
183
        return UNZ_INTERNALERROR;
184
 
185
    p = filename_withoutpath = filename_inzip;
186
    while ((*p) != '\0')
187
    {
188
        if (((*p)=='/') || ((*p)=='\\'))
189
            filename_withoutpath = p+1;
190
        p++;
191
    }
192
 
193
    if ((*filename_withoutpath)=='\0')
194
    {
195
        if ((*popt_extract_without_path)==0)
196
            mymkdir(filename_inzip);
197
    }
198
    else
199
    {
200
        char* write_filename;
201
        int skip=0;
202
 
203
        if ((*popt_extract_without_path)==0)
204
            write_filename = filename_inzip;
205
        else
206
            write_filename = filename_withoutpath;
207
 
208
        err = unzOpenCurrentFilePassword(uf,password);
209
 
210
        if ((skip==0) && (err==UNZ_OK))
211
        {
212
            fout=fopen(write_filename,"wb");
213
 
214
            /* some zipfile don't contain directory alone before file */
215
            if ((fout==NULL) && ((*popt_extract_without_path)==0) &&
216
                                (filename_withoutpath!=(char*)filename_inzip))
217
            {
218
                char c=*(filename_withoutpath-1);
219
                *(filename_withoutpath-1)='\0';
220
                makedir(write_filename);
221
                *(filename_withoutpath-1)=c;
222
                fout=fopen(write_filename,"wb");
223
            }
224
        }
225
 
226
        if (fout!=NULL)
227
        {
228
 
229
            do
230
            {
231
                err = unzReadCurrentFile(uf,buf,size_buf);
232
                if (err<0)
233
                    break;
234
                if (err>0)
235
                    if (fwrite(buf,err,1,fout)!=1)
236
                    {
237
                        err=UNZ_ERRNO;
238
                        break;
239
                    }
240
            }
241
            while (err>0);
242
            if (fout)
243
                    fclose(fout);
244
 
245
            if (err==0)
246
                change_file_date(write_filename,file_info.dosDate,
247
                                 file_info.tmu_date);
248
        }
249
 
250
        if (err==UNZ_OK)
251
            err = unzCloseCurrentFile (uf);
252
        else
253
            unzCloseCurrentFile(uf); /* don't lose the error */
254
    }
255
 
256
    free(buf);
257
    return err;
258
}
259
 
260
/* change_file_date : change the date/time of a file
261
    filename : the filename of the file where date/time must be modified
262
    dosdate : the new date at the MSDos format (4 bytes)
263
    tmu_date : the SAME new date at the tm_unz format */
264
void change_file_date(const char* filename, uLong, tm_unz tmu_date)
265
{
266
  struct utimbuf ut;
267
  struct tm newdate;
268
  newdate.tm_sec = tmu_date.tm_sec;
269
  newdate.tm_min=tmu_date.tm_min;
270
  newdate.tm_hour=tmu_date.tm_hour;
271
  newdate.tm_mday=tmu_date.tm_mday;
272
  newdate.tm_mon=tmu_date.tm_mon;
273
  if (tmu_date.tm_year > 1900)
274
      newdate.tm_year=tmu_date.tm_year - 1900;
275
  else
276
      newdate.tm_year=tmu_date.tm_year ;
277
  newdate.tm_isdst=-1;
278
 
279
  ut.actime=ut.modtime=mktime(&newdate);
280
  utime(filename,&ut);
281
}
282
 
283