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