Subversion Repositories Scribus

Rev

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