📄 macos.c
字号:
/* Copyright (c) 1990-2005 Info-ZIP. All rights reserved. See the accompanying file LICENSE, version 2004-May-22 or later (the contents of which are also included in zip.h) for terms of use. If, for some reason, both of these files are missing, the Info-ZIP license also may be found at: ftp://ftp.info-zip.org/pub/infozip/license.html*//*--------------------------------------------------------------------------- macos.c Macintosh-specific routines for use with Info-ZIP's Zip 2.3 and later. ---------------------------------------------------------------------------*//*****************************************************************************//* Includes *//*****************************************************************************/#include "zip.h"#include "revision.h"#include "crypt.h"#include <signal.h>#include <stdio.h>#include <stdlib.h>#include <sound.h>#include <unistd.h>#include <Strings.h>#include <setjmp.h>/* #include "charmap.h" */#include "helpers.h"#include "macstuff.h"#include "pathname.h"#include "recurse.h"/*****************************************************************************//* Macros, typedefs *//*****************************************************************************/#define PATH_END MacPathEnd/*****************************************************************************//* Global Vars *//*****************************************************************************/int error_level; /* used only in ziperr() *//* Note: sizeof() returns the size of this allusion 13 is current length of "XtraStuf.mac:" */extern const char ResourceMark[13]; /* var is initialized in file pathname.c */extern jmp_buf EnvForExit;MacZipGlobals MacZip;unsigned long count_of_Zippedfiles = 0;/*****************************************************************************//* Module level Vars *//*****************************************************************************/static const char MacPathEnd = ':'; /* the Macintosh dir separator *//* Inform Progress vars */long estTicksToFinish;long createTime;long updateTicks;static char *Time_Est_strings[] = { "Zipping Files; Items done:", "More than 24 hours", "More than %s hours", "About %s hours, %s minutes", "About an hour", "Less than an hour", "About %s minutes, %s seconds", "About a minute", "Less than a minute", "About %s seconds", "About a second", "About 1 minute, %s seconds"};/*****************************************************************************//* Prototypes *//*****************************************************************************/int DoCurrentDir(void);void DoAboutBox(void);void DoQuit(void);void DoEventLoop(void);void ZipInitAllVars(void);void UserStop(void);Boolean IsZipFile(char *name);static long EstimateCompletionTime(const long progressMax, const long progressSoFar, unsigned char percent);static void UpdateTimeToComplete(void);#ifdef USE_SIOUX#include <sioux.h>void DoWarnUserDupVol( char *FullPath );/*****************************************************************************//* Functions *//*****************************************************************************//*** Standalone Unzip with Metrowerks SIOUX starts here***/int main(int argc, char **argv){ int return_code; SIOUXSettings.asktosaveonclose = FALSE; SIOUXSettings.showstatusline = TRUE; SIOUXSettings.columns = 100; SIOUXSettings.rows = 40; /* 30 = MacZip Johnny Lee's; 40 = new (my) MacZip */ MacZip.MacZipMode = NewZipMode_EF; argc = ccommand(&argv); if (verbose) PrintArguments(argc, argv); ZipInitAllVars(); return_code = zipmain(argc, argv); if (verbose) printf("\n\n Finish"); return return_code;}/*** SIOUX needs no extra event handling***/void UserStop(void){};/*** Password enter function '*' printed for each char***/int macgetch(void){ WindowPtr whichWindow; EventRecord theEvent; char c; /* one-byte buffer for read() to use */ do { SystemTask(); if (!GetNextEvent(everyEvent, &theEvent)) theEvent.what = nullEvent; else { switch (theEvent.what) { case keyDown: c = theEvent.message & charCodeMask; break; case mouseDown: if (FindWindow(theEvent.where, &whichWindow) == inSysWindow) SystemClick(&theEvent, whichWindow); break; case updateEvt: break; } } } while (theEvent.what != keyDown); printf("*"); fflush(stdout); return (int)c;}#endif/******************************//* Function version_local() *//******************************//*** Print Compilers version and compile time/date***/void version_local(){/* prints e.g:Compiled with Metrowerks CodeWarrior version 2000 for PowerPC Processor compile time: Feb 4 1998 17:49:49.*/static ZCONST char CompiledWith[] = "\n\nCompiled with %s %x for %s \n %s %s %s.\n\n"; printf(CompiledWith,#ifdef __MWERKS__ " Metrowerks CodeWarrior version", __MWERKS__,#endif#ifdef __MC68K__ " MC68K Processor",#else " PowerPC Processor",#endif#ifdef __DATE__ "compile time: ", __DATE__, __TIME__#else "", "", ""#endif );} /* end function version_local() *//*** Deletes a dir if the switch '-m' is used***/int deletedir(char *path){static char Num = 0;static FSSpec trashfolder;static Boolean FirstCall = true;static Boolean Immediate_File_Deletion = false;OSErr err;FSSpec dirToDelete;char currpath[NAME_MAX], *envptr;CInfoPBRec fpb;/* init this function */if ((path == NULL) || (strlen(path) == 0)) { Num = 0; FirstCall = true; return -1; }UserStop();GetCompletePath(currpath,path,&dirToDelete, &err);if (FirstCall == true) { FirstCall = false; envptr = getenv("Immediate_File_Deletion"); if (!(envptr == (char *)NULL || *envptr == '\0')) { if (stricmp(envptr,"yes") == 0) Immediate_File_Deletion = true; else Immediate_File_Deletion = false; } err = FSpFindFolder(dirToDelete.vRefNum, kTrashFolderType, kDontCreateFolder,&trashfolder); printerr("FSpFindFolder:",err,err,__LINE__,__FILE__,path); } fpb.dirInfo.ioNamePtr = dirToDelete.name; fpb.dirInfo.ioVRefNum = dirToDelete.vRefNum; fpb.dirInfo.ioDrDirID = dirToDelete.parID; fpb.dirInfo.ioFDirIndex = 0; err = PBGetCatInfoSync(&fpb); printerr("PBGetCatInfo deletedir ", err, err, __LINE__, __FILE__, "");if (fpb.dirInfo.ioDrNmFls > 0) { return 0; /* do not move / delete folders which are not empty */ }if (Immediate_File_Deletion) { err = FSpDelete(&dirToDelete); return err; }err = CatMove (dirToDelete.vRefNum, dirToDelete.parID, dirToDelete.name, trashfolder.parID, trashfolder.name);/* -48 = file is already existing so we have to rename it before moving the file */if (err == -48) { Num++; if (dirToDelete.name[0] >= 28) /* cut foldername if to long */ dirToDelete.name[0] = 28; P2CStr(dirToDelete.name); sprintf(currpath,"%s~%d",(char *)dirToDelete.name,Num); C2PStr(currpath); C2PStr((char *)dirToDelete.name); err = HRename (dirToDelete.vRefNum, dirToDelete.parID, dirToDelete.name, (unsigned char *) currpath); err = CatMove (dirToDelete.vRefNum, dirToDelete.parID, (unsigned char *) currpath, trashfolder.parID, trashfolder.name); }return err;}/*** Set the file-type so the archive will get the correct icon, type** and creator code.*/void setfiletype(char *new_f, unsigned long Creator, unsigned long Type){OSErr err;if (strcmp(zipfile, new_f) == 0) err = FSpChangeCreatorType(&MacZip.ZipFileSpec, Creator, Type);printerr("FSpChangeCreatorType:", err, err, __LINE__, __FILE__, new_f);return;}/*** Convert the external (native) filename into Zip's internal Unix compatible** name space.*/char *ex2in(char *externalFilen, int isdir, int *pdosflag)/* char *externalFilen external file name *//* int isdir input: externalFilen is a directory *//* int *pdosflag output: force MSDOS file attributes? *//* Convert the external file name to a zip file name, returning the malloc'ed string or NULL if not enough memory. */{ char *internalFilen; /* internal file name (malloc'ed) */ char *t; /* shortened name */ char *Pathname; char buffer[NAME_MAX]; int dosflag; AssertStr(externalFilen, externalFilen) AssertBool(isdir,"") dosflag = dosify; /* default for non-DOS and non-OS/2 */ /* Find starting point in name before doing malloc */ for (t = externalFilen; *t == PATH_END; t++) ; if (!MacZip.StoreFullPath) { Pathname = StripPartialDir(buffer, MacZip.SearchDir,t); } else { Pathname = t; } /* Make changes, if any, to the copied name (leave original intact) */ if (!pathput) { t = last(Pathname, PATH_END); } else t = Pathname; /* Malloc space for internal name and copy it */ if ((internalFilen = malloc(strlen(t) + 10 + strlen(ResourceMark) )) == NULL) return NULL; sstrcpy(internalFilen, t); /* we have to eliminate illegal chars: * The name space for Mac filenames and Zip filenames (unix style names) * do both include all printable extended-ASCII characters. The only * difference we have to take care of is the single special character * used as path delimiter: * ':' on MacOS and '/' on Unix and '\' on Dos. * So, to convert between Mac filenames and Unix filenames without any * loss of information, we simply interchange ':' and '/'. Additionally, * we try to convert the coding of the extended-ASCII characters into * InfoZip's standard ISO 8859-1 codepage table. */ MakeCompatibleString(internalFilen, ':', '/', '/', ':', MacZip.CurrTextEncodingBase); /* Returned malloc'ed name */ if (pdosflag) *pdosflag = dosflag; if (isdir) { return internalFilen; /* avoid warning on unused variable */ } if (dosify) { msname(internalFilen); printf("\n ex2in: %s",internalFilen); } return internalFilen;}/*** Collect all filenames. Go through all directories***/int wild(char *Pathpat) /* path/pattern to match *//* If not in exclude mode, expand the pattern based on the contents of the file system. Return an error code in the ZE_ class. */{FSSpec Spec;char fullpath[NAME_MAX];OSErr err;AssertStr(Pathpat, Pathpat);if (noisy) printf("%s \n\n",GetZipVersionsInfo());if (extra_fields == 0) { MacZip.DataForkOnly = true; }/* for switch '-R' -> '.' means current dir */if (strcmp(Pathpat,".") == 0) sstrcpy(Pathpat,"*");sstrcpy(MacZip.Pattern,Pathpat);if (recurse) { MacZip.StoreFoldersAlso = true; MacZip.SearchLevels = 0; /* if 0 we aren't checking levels */ }else { MacZip.StoreFoldersAlso = false; MacZip.SearchLevels = 1; }/* make complete path */GetCompletePath(fullpath, MacZip.Pattern, &Spec,&err);err = PrintUserHFSerr((err != -43) && (err != 0), err, MacZip.Pattern);printerr("GetCompletePath:", err, err, __LINE__, __FILE__, fullpath);/* extract the filepattern */GetFilename(MacZip.Pattern, fullpath);/* extract Path and get FSSpec of search-path *//* get FSSpec of search-path ; we need a dir to start searching for filenames */TruncFilename(MacZip.SearchDir, fullpath);GetCompletePath(MacZip.SearchDir, MacZip.SearchDir, &Spec,&err);if (noisy) { if (MacZip.SearchLevels == 0) { printf("\nSearch Pattern: [%s] Levels: all", MacZip.Pattern); } else { printf("\nSearch Pattern: [%s] Levels: %d", MacZip.Pattern, MacZip.SearchLevels); } printf("\nSearch Path: [%s]", MacZip.SearchDir); printf("\nZip-File: [%s] \n",MacZip.ZipFullPath);}/* we are working only with pathnames; * this can cause big problems on a mac ... */if (CheckMountedVolumes(MacZip.SearchDir) > 1) DoWarnUserDupVol(MacZip.SearchDir);/* start getting all filenames */err = FSpRecurseDirectory(&Spec, MacZip.SearchLevels);printerr("FSpRecurseDirectory:", err, err, __LINE__, __FILE__, "");return ZE_OK;}/*** Convert the internal filename into a external (native).** The user will see this modified filename.** For more performance:** I do not completly switch back to the native macos filename.** The user will still see directory separator '/' and the converted** charset.*/
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -