1/*
2  Copyright (c) 1990-1999 Info-ZIP.  All rights reserved.
3
4  See the accompanying file LICENSE, version 1999-Oct-05 or later
5  (the contents of which are also included in zip.h) for terms of use.
6  If, for some reason, both of these files are missing, the Info-ZIP license
7  also may be found at:  ftp://ftp.cdrom.com/pub/infozip/license.html
8*/
9/*** macopen.c; stuff only required for the Mac port ***/
10
11#include "zip.h"
12
13#include <string.h>
14#include <fcntl.h>
15#include <unix.h>
16#include <sound.h>
17
18#include "helpers.h"
19#include "pathname.h"
20#include "macopen.h"
21#include "macstuff.h"
22
23#ifdef MACZIP
24#include "macglob.h"
25
26extern char *zipfile;   /* filename of the Zipfile */
27extern char *tempzip;   /* Temporary zip file name */
28
29extern MacZipGlobals    MacZip;
30
31
32/* don't include "osdep.h" otherwise we will trap into endless loop */
33#undef open
34#undef fopen
35
36
37
38FILE *MacFopen(const char *path, const char *mode)
39{
40static char TruncPath[NAME_MAX];
41OSErr   err = 0;
42
43AssertStr(path,path)
44
45            /* open zipfile or tempzip */
46if (strcmp(zipfile,path) == 0)
47    {
48    GetCompletePath(MacZip.ZipFullPath,path,&MacZip.ZipFileSpec,&err);
49    err = PrintUserHFSerr((err != -43) && (err != 0), err, path);
50    printerr("GetCompletePath:",err,err,__LINE__,__FILE__,path);
51    if (CheckMountedVolumes(MacZip.ZipFullPath) > 1)
52        DoWarnUserDupVol(MacZip.ZipFullPath);
53
54    /* tempfile should appear in the same directory of the zipfile
55       -> save path of zipfile */
56    TruncFilename(TruncPath, MacZip.ZipFullPath);
57    return fopen(MacZip.ZipFullPath, mode);
58    }
59
60if (strcmp(tempzip,path) == 0)
61    {  /* add path of zipfile */
62    sstrcat(TruncPath,tempzip);
63    GetCompletePath(MacZip.TempZipFullPath,TruncPath,&MacZip.TempZipFileSpec,&err);
64    err = PrintUserHFSerr((err != -43) && (err != 0), err, path);
65    printerr("GetCompletePath:",err,err,__LINE__,__FILE__,path);
66
67    return fopen(MacZip.TempZipFullPath, mode);
68    }
69
70printerr("MacFopen:",err,err,__LINE__,__FILE__,path);
71return NULL;
72}
73
74
75
76
77int MacOpen(const char *path,int oflag, ...)
78{
79char RealFname[NAME_MAX];
80
81AssertStr(path,path)
82
83RfDfFilen2Real(RealFname,path, MacZip.MacZipMode, MacZip.DataForkOnly, &MacZip.CurrentFork);
84/* convert to real fname and init global var  MacZip.CurrentFork  !!  */
85
86switch (MacZip.CurrentFork)
87    {
88    case DataFork:
89        {
90        return my_open(RealFname, oflag);
91        break;
92        }
93    case ResourceFork:
94        {
95        return my_open( RealFname, oflag | O_RSRC);
96        break;
97        }
98    default:  /* for now (Zip ver 2.3b) MacOpen should never reach this point */
99        {     /* however, this may change in the future ... */
100        printerr("open: no resource / datafork ",-1,-1,__LINE__,__FILE__,path);
101        return -1;
102        }
103    }
104}
105
106
107#ifdef muell
108 /* file to delete */
109int destroy(char *path)
110{
111static char lastpath[NAME_MAX];
112char    currpath[NAME_MAX];
113static Boolean FirstCall = true;
114long rc;
115
116AssertStr(path,path)
117
118RfDfFilen2Real(currpath, path, MacZip.MacZipMode, MacZip.DataForkOnly, &MacZip.CurrentFork);
119
120if (FirstCall == true)
121    {
122    FirstCall = false;
123    rc = remove(currpath);
124    }
125else if (strcmp(currpath,lastpath) == 0) return 0; /* ignore, file is already deleted */
126        else rc = remove(currpath); /* we are removeing all the files only by their
127        pathname this is dangerous on a mac but there is no other way without
128         a complete rewrite of the port  */
129
130strcpy(lastpath,currpath);
131
132return rc;
133}
134#endif
135
136
137
138
139/* this function replaces the function "replace()" defined in fileio.c */
140int replace(char *new_f, char *temp_f)  /* destination and source file names */
141{
142OSErr   err = 0;
143char    newfname[NAME_MAX];
144
145AssertStr(new_f,new_f)
146AssertStr(temp_f,temp_f)
147
148UserStop();
149
150GetFilename(newfname, new_f);
151
152/* check zipfile name and tempfile name */
153/* we are using this function only for replacing the tempfile with the zipfile */
154if ((strcmp(zipfile,new_f) == 0) || (strcmp(tempzip,temp_f) == 0))
155    {
156    remove(MacZip.ZipFullPath);
157
158    /* rename the temp file to the zip file */
159    err = rename(MacZip.TempZipFullPath,MacZip.ZipFullPath);
160    printerr("rename:",err,err,__LINE__,__FILE__,MacZip.TempZipFullPath);
161if (err != 0) return ZE_CREAT;
162    else return ZE_OK;
163    }
164else return ZE_CREAT;
165}
166
167
168
169 /* file to delete */
170 /* we are removeing all the files only by their
171    pathname this is dangerous on a mac but there is no
172    other way without a complete rewrite of the port  */
173
174int destroy(char *path)
175{
176static char lastpath[NAME_MAX];
177static FSSpec  trashfolder;
178static Boolean FirstCall = true;
179static char Num = 0;
180static Boolean  Immediate_File_Deletion = false;
181char    currpath[NAME_MAX], *envptr;
182FSSpec  fileToDelete;
183OSErr   err;
184
185/* init this function */
186if ((path == NULL) ||
187    (strlen(path) == 0))
188    {
189    FirstCall = true;
190    Num = 0;
191    return -1;
192    }
193
194UserStop();
195
196RfDfFilen2Real(currpath, path, MacZip.MacZipMode,
197                MacZip.DataForkOnly, &MacZip.CurrentFork);
198GetCompletePath(currpath,currpath,&fileToDelete, &err);
199
200if (FirstCall == true)
201    {
202    FirstCall = false;
203    sstrcpy(lastpath,currpath);
204    err = FSpFindFolder(fileToDelete.vRefNum, kTrashFolderType,
205                      kDontCreateFolder,&trashfolder);
206    printerr("FSpFindFolder:",err,err,__LINE__,__FILE__,path);
207
208    envptr = getenv("Immediate_File_Deletion");
209    if (!(envptr == (char *)NULL || *envptr == '\0'))
210        {
211        if (stricmp(envptr,"yes") == 0)
212            Immediate_File_Deletion = true;
213        else
214            Immediate_File_Deletion = false;
215        }
216
217    if (Immediate_File_Deletion)
218        {
219        err = FSpDelete(&fileToDelete);
220        return err;
221        }
222
223    err = CatMove (fileToDelete.vRefNum, fileToDelete.parID,
224                   fileToDelete.name, trashfolder.parID, trashfolder.name);
225    return err;
226    }
227
228if (strcmp(currpath,lastpath) == 0)
229    {
230    return 0; /* ignore, file is already deleted */
231    }
232else
233    {
234
235    if (Immediate_File_Deletion)
236        {
237        err = FSpDelete(&fileToDelete);
238        sstrcpy(lastpath,path);
239        return err;
240        }
241
242    err = CatMove (fileToDelete.vRefNum, fileToDelete.parID,
243                   fileToDelete.name, trashfolder.parID, trashfolder.name);
244
245    /* -48 = file is already existing so we have to rename it before
246       moving the file */
247    if (err == -48)
248        {
249        Num++;
250        if (fileToDelete.name[0] >= 28) /* cut filename if to long */
251            fileToDelete.name[0] = 28;
252        P2CStr(fileToDelete.name);
253        sprintf(currpath,"%s~%d",(char *)fileToDelete.name,Num);
254        C2PStr(currpath);
255        C2PStr((char *)fileToDelete.name);
256        err = HRename (fileToDelete.vRefNum, fileToDelete.parID,
257                       fileToDelete.name, (unsigned char *) currpath);
258        err = CatMove (fileToDelete.vRefNum, fileToDelete.parID,
259                       (unsigned char *) currpath, trashfolder.parID,
260                       trashfolder.name);
261        }
262    }
263
264sstrcpy(lastpath,currpath);
265return err;
266}
267
268
269
270#endif  /* #ifdef MACZIP */
271
272
273
274
275/*
276 *  int open(const char *path, int oflag)
277 *
278 *      Opens a file stream.
279 */
280int my_open(char *path, int oflag)
281{
282    FSSpec          spec;
283    char            permission;
284    HParamBlockRec  hpb;
285    OSErr           err, errno;
286    Boolean targetIsFolder, wasAliased;
287
288    AssertStr(path,path)
289
290    /* Setup permission */
291    if ((oflag & 0x03) == O_RDWR)
292        permission = fsRdWrPerm;
293    else
294        permission = (oflag & O_RDONLY) ? fsRdPerm : 0 + (oflag & O_WRONLY) ? fsWrPerm : 0;
295
296        FSpLocationFromFullPath(strlen(path),path, &spec);
297        if ((oflag & (O_ALIAS | O_NRESOLVE)) == 0)
298            ResolveAliasFile(&spec, true, &targetIsFolder, &wasAliased);
299        hpb.fileParam.ioNamePtr = spec.name;
300        hpb.fileParam.ioVRefNum = spec.vRefNum;
301        hpb.fileParam.ioDirID = spec.parID;
302        hpb.ioParam.ioPermssn = permission;
303
304        if (oflag & O_RSRC)         /* open the resource fork of the file */
305            err = PBHOpenRFSync(&hpb);
306        else                        /* open the data fork of the file */
307            err = PBHOpenDFSync(&hpb);
308
309    if ((err == fnfErr) && (oflag & O_CREAT)) {
310        hpb.fileParam.ioFlVersNum = 0;
311        err = PBHCreateSync(&hpb);
312        if (err == noErr) {
313            /* Set the finder info */
314            unsigned long secs;
315            unsigned long isbinary = oflag & O_BINARY;
316
317            hpb.fileParam.ioFlFndrInfo.fdType = '\?\?\?\?';
318            hpb.fileParam.ioFlFndrInfo.fdCreator = '\?\?\?\?';
319            hpb.fileParam.ioFlFndrInfo.fdFlags = 0;
320            if (oflag & O_ALIAS)        /* set the alias bit */
321                hpb.fileParam.ioFlFndrInfo.fdFlags = kIsAlias;
322            else                                        /* clear all flags */
323                hpb.fileParam.ioFlFndrInfo.fdFlags = 0;
324
325            GetDateTime(&secs);
326            hpb.fileParam.ioFlCrDat = hpb.fileParam.ioFlMdDat = secs;
327            PBHSetFInfoSync(&hpb);
328        }
329
330        if (err && (err != dupFNErr)) {
331            errno = err; return -1;
332        }
333
334            if (oflag & O_RSRC)         /* open the resource fork of the file */
335                err = PBHOpenRFSync(&hpb);
336            else                        /* open the data fork of the file */
337                err = PBHOpenDFSync(&hpb);
338    }
339
340    if (err && (err != dupFNErr) && (err != opWrErr)) {
341        errno = err; return -1;
342    }
343
344    if (oflag & O_TRUNC) {
345        IOParam pb;
346
347        pb.ioRefNum = hpb.ioParam.ioRefNum;
348        pb.ioMisc = 0L;
349        err = PBSetEOFSync((ParmBlkPtr)&pb);
350        if (err != noErr) {
351            errno = err; return -1;
352        }
353    }
354
355    if (oflag & O_APPEND) lseek(hpb.ioParam.ioRefNum,0,SEEK_END);
356
357    return (hpb.ioParam.ioRefNum);
358}
359
360
361
362
363
364