📄 macos.c
字号:
/***********************//* Function checkdir() *//***********************/int checkdir(__G__ pathcomp, flag) __GDEF char *pathcomp; int flag;/* * returns: 1 - (on APPEND_NAME) truncated filename * 2 - path doesn't exist, not allowed to create * 3 - path doesn't exist, tried to create and failed; or * path exists and is not a directory, but is supposed to be * 4 - path is too long * 10 - can't allocate memory for filename buffers */{ static int rootlen = 0; /* length of rootpath */ static char *rootpath; /* user's "extract-to" directory */ static char *buildpath; /* full path (so far) to extracted file */ static char *end; /* pointer to end of buildpath ('\0') */# define FN_MASK 7# define FUNCTION (flag & FN_MASK)/*--------------------------------------------------------------------------- APPEND_DIR: append the path component to the path being built and check for its existence. If doesn't exist and we are creating directories, do so for this one; else signal success or error as appropriate. ---------------------------------------------------------------------------*/ if (FUNCTION == APPEND_DIR) { int too_long = FALSE;#ifdef SHORT_NAMES char *old_end = end;#endif Trace((stderr, "appending dir segment [%s]\n", pathcomp)); while ((*end = *pathcomp++) != '\0') ++end;#ifdef SHORT_NAMES /* path components restricted to 14 chars, typically */ if ((end-old_end) > FILENAME_MAX) /* GRR: proper constant? */ *(end = old_end + FILENAME_MAX) = '\0';#endif /* GRR: could do better check, see if overrunning buffer as we go: * check end-buildpath after each append, set warning variable if * within 20 of FILNAMSIZ; then if var set, do careful check when * appending. Clear variable when begin new path. */ if ((end-buildpath) > FILNAMSIZ-3) /* need ':', one-char name, '\0' */ too_long = TRUE; /* check if extracting directory? */ if (stat(buildpath, &G.statbuf)) { /* path doesn't exist */ if (!G.create_dirs) { /* told not to create (freshening) */ free(buildpath); return 2; /* path doesn't exist: nothing to do */ } if (too_long) { Info(slide, 1, ((char *)slide, "checkdir error: path too long: %s\n", buildpath)); free(buildpath); return 4; /* no room for filenames: fatal */ } if (MKDIR(buildpath) == -1) { /* create the directory */ Info(slide, 1, ((char *)slide, "checkdir error: cannot create %s\n\ unable to process %s.\n", buildpath, G.filename)); free(buildpath); return 3; /* path didn't exist, tried to create, failed */ } created_dir = TRUE; } else if (!S_ISDIR(G.statbuf.st_mode)) { Info(slide, 1, ((char *)slide, "checkdir error: %s exists but is not directory\n\ unable to process %s.\n", buildpath, G.filename)); free(buildpath); return 3; /* path existed but wasn't dir */ } if (too_long) { Info(slide, 1, ((char *)slide, "checkdir error: path too long: %s\n", buildpath)); free(buildpath); return 4; /* no room for filenames: fatal */ } *end++ = ':'; *end = '\0'; Trace((stderr, "buildpath now = [%s]\n", buildpath)); return 0; } /* end if (FUNCTION == APPEND_DIR) *//*--------------------------------------------------------------------------- GETPATH: copy full path to the string pointed at by pathcomp, and free buildpath. ---------------------------------------------------------------------------*/ if (FUNCTION == GETPATH) { strcpy(pathcomp, buildpath); Trace((stderr, "getting and freeing path [%s]\n", pathcomp)); free(buildpath); buildpath = end = (char *)NULL; return 0; }/*--------------------------------------------------------------------------- APPEND_NAME: assume the path component is the filename; append it and return without checking for existence. ---------------------------------------------------------------------------*/ if (FUNCTION == APPEND_NAME) {#ifdef SHORT_NAMES char *old_end = end;#endif Trace((stderr, "appending filename [%s]\n", pathcomp)); while ((*end = *pathcomp++) != '\0') { ++end;#ifdef SHORT_NAMES /* truncate name at 14 characters, typically */ if ((end-old_end) > FILENAME_MAX) /* GRR: proper constant? */ *(end = old_end + FILENAME_MAX) = '\0';#endif if ((end-buildpath) >= FILNAMSIZ) { *--end = '\0'; Info(slide, 0x201, ((char *)slide, "checkdir warning: path too long; truncating\n\ %s\n -> %s\n", G.filename, buildpath)); return 1; /* filename truncated */ } } Trace((stderr, "buildpath now = [%s]\n", buildpath)); return 0; /* could check for existence here, prompt for new name... */ }/*--------------------------------------------------------------------------- INIT: allocate and initialize buffer space for the file currently being extracted. If file was renamed with an absolute path, don't prepend the extract-to path. ---------------------------------------------------------------------------*/ if (FUNCTION == INIT) { Trace((stderr, "initializing buildpath to ")); if ((buildpath = (char *)malloc(strlen(G.filename)+rootlen+2)) == (char *)NULL) return 10; if ((rootlen > 0) && !renamed_fullpath) { strcpy(buildpath, rootpath); end = buildpath + rootlen; } else { end = buildpath; if (!renamed_fullpath && !uO.jflag) { *end++ = ':'; /* indicate relative path */ } *end = '\0'; } Trace((stderr, "[%s]\n", buildpath)); return 0; }/*--------------------------------------------------------------------------- ROOT: if appropriate, store the path in rootpath and create it if neces- sary; else assume it's a zipfile member and return. This path segment gets used in extracting all members from every zipfile specified on the command line. ---------------------------------------------------------------------------*/#if (!defined(SFX) || defined(SFX_EXDIR)) if (FUNCTION == ROOT) { Trace((stderr, "initializing root path to [%s]\n", pathcomp)); if (pathcomp == (char *)NULL) { rootlen = 0; return 0; } if ((rootlen = strlen(pathcomp)) > 0) { if (pathcomp[rootlen-1] == ':') { pathcomp[--rootlen] = '\0'; /* strip trailing delimiter */ } if (rootlen > 0 && (stat(pathcomp, &G.statbuf) || !S_ISDIR(G.statbuf.st_mode))) /* path does not exist */ { if (!G.create_dirs /* || iswild(pathcomp) */ ) { rootlen = 0; return 2; /* skip (or treat as stored file) */ } /* create the directory (could add loop here to scan pathcomp * and create more than one level, but why really necessary?) */ if (MKDIR(pathcomp) == -1) { Info(slide, 1, ((char *)slide, "checkdir: cannot create extraction directory: %s\n", pathcomp)); rootlen = 0; /* path didn't exist, tried to create, and */ return 3; /* failed: file exists, or 2+ levels required */ } } if ((rootpath = (char *)malloc(rootlen+2)) == (char *)NULL) { rootlen = 0; return 10; } strcpy(rootpath, pathcomp); rootpath[rootlen++] = ':'; rootpath[rootlen] = '\0'; Trace((stderr, "rootpath now = [%s]\n", rootpath)); } return 0; }#endif /* !SFX || SFX_EXDIR *//*--------------------------------------------------------------------------- END: free rootpath, immediately prior to program exit. ---------------------------------------------------------------------------*/ if (FUNCTION == END) { Trace((stderr, "freeing rootpath\n")); if (rootlen > 0) { free(rootpath); rootlen = 0; } return 0; } return 99; /* should never reach */} /* end function checkdir() *//****************************//* Function close_outfile() *//****************************/void close_outfile(__G) /* GRR: change to return PK-style warning level */ __GDEF{#ifdef USE_EF_UT_TIME iztimes z_utime; unsigned eb_izux_flg;#endif HParamBlockRec hpbr; OSErr err; FSSpec spec; char CompletePath[NAME_MAX]; CInfoPBRec fpb; if (fileno(G.outfile) == 1) return; /* don't attempt to close or set time on stdout */ err = (OSErr)fclose(G.outfile); printerr("macclose FSClose ",err, err, __LINE__, __FILE__, G.filename); GetCompletePath(CompletePath, G.filename, &spec, &err); printerr("GetCompletePath", err, err, __LINE__, __FILE__, G.filename); fpb.hFileInfo.ioNamePtr = spec.name; fpb.hFileInfo.ioVRefNum = spec.vRefNum; fpb.hFileInfo.ioDirID = spec.parID; fpb.hFileInfo.ioFDirIndex = 0; hpbr.fileParam.ioNamePtr = spec.name; hpbr.fileParam.ioVRefNum = spec.vRefNum; hpbr.fileParam.ioDirID = spec.parID; hpbr.fileParam.ioFDirIndex = 0; err = PBGetCatInfoSync((CInfoPBPtr)&fpb); printerr("PBGetCatInfoSync", err, err, __LINE__, __FILE__, G.filename); fpb.hFileInfo.ioDirID = spec.parID; if ((MacZipMode == UnKnown_EF) || UseUT_ExtraField ) {#ifdef USE_EF_UT_TIME eb_izux_flg = ef_scan_for_izux(G.extra_field, G.lrec.extra_field_length, 0, G.lrec.last_mod_dos_datetime, &z_utime, NULL); if (G.extra_field &&#ifdef IZ_CHECK_TZ G.tz_is_valid &&#endif (eb_izux_flg & EB_UT_FL_MTIME)) { fpb.hFileInfo.ioFlMdDat = UnixFtime2MacFtime(z_utime.mtime); fpb.hFileInfo.ioFlCrDat = UnixFtime2MacFtime(z_utime.ctime); }#ifdef DEBUG_TIME { struct tm *tp = gmtime(&z_utime.ctime); printf( "close_outfile: Unix e.f. creat. time = %d/%2d/%2d %2d:%2d:%2d -> %lu UTC\n", tp->tm_year, tp->tm_mon+1, tp->tm_mday, tp->tm_hour, tp->tm_min, tp->tm_sec, z_utime.ctime); tp = gmtime(&z_utime.mtime); printf( "close_outfile: Unix e.f. modif. time = %d/%2d/%2d %2d:%2d:%2d -> %lu UTC\n", tp->tm_year, tp->tm_mon+1, tp->tm_mday, tp->tm_hour, tp->tm_min, tp->tm_sec, z_utime.mtime); }#endif /* DEBUG_TIME */#else /* !USE_EF_UT_TIME */ TTrace((stderr, "close_outfile: using DOS-Datetime ! \n", z_utime.mtime)); dtr.year = (((G.lrec.last_mod_dos_datetime >> 25) & 0x7f) + 1980); dtr.month = ((G.lrec.last_mod_dos_datetime >> 21) & 0x0f); dtr.day = ((G.lrec.last_mod_dos_datetime >> 16) & 0x1f); dtr.hour = ((G.lrec.last_mod_dos_datetime >> 11) & 0x1f); dtr.minute = ((G.lrec.last_mod_dos_datetime >> 5) & 0x3f); dtr.second = ((G.lrec.last_mod_dos_datetime << 1) & 0x3e); DateToSeconds(&dtr, (unsigned long *)&fpb.hFileInfo.ioFlMdDat); fpb.hFileInfo.ioFlCrDat = fpb.hFileInfo.ioFlMdDat;#endif /* ?USE_EF_UT_TIME */ if (err == noErr) err = PBSetCatInfoSync((CInfoPBPtr)&fpb); if (err != noErr) printf("error (%d): cannot set the time for %s\n", err, G.filename); } /* set read-only perms if needed */ if ((err == noErr) && G.pInfo->read_only) { err = PBHSetFLockSync(&hpbr); printerr("PBHSetFLockSync",err,err,__LINE__,__FILE__,G.filename); } /* finally set FinderInfo */ if (MacZipMode != UnKnown_EF) { err = SetFinderInfo(&CurrentFile, &newExtraField); printerr("close_outfile SetFinderInfo ", err, err, __LINE__, __FILE__, G.filename); }} /* end function close_outfile() */#ifndef SFX/************************//* Function version() *//************************/void version(__G) __GDEF{#if 0 char buf[40];#endif sprintf((char *)slide, LoadFarString(CompiledWith),#ifdef __GNUC__ "gcc ", __VERSION__,#else# if 0 "cc ", (sprintf(buf, " version %d", _RELEASE), buf),# else# ifdef __MWERKS__ "CodeWarrior C", "",# else# ifdef THINK_C "Think C", "",# else# ifdef MPW "MPW C", "",# else "unknown compiler", "",# endif# endif# endif# endif#endif "MacOS",#if defined(foobar) || defined(FOOBAR) " (Foo BAR)", /* hardware or OS version */#else "",#endif /* Foo BAR */#ifdef __DATE__ " on ", __DATE__#else "", ""#endif ); (*G.message)((zvoid *)&G, slide, (ulg)strlen((char *)slide), 0);} /* end function version() */#endif /* !SFX *//***********************//* Function macmkdir() *//***********************/int macmkdir(char *path){ OSErr err = -1; OSErr err_rc; char CompletePath[NAME_MAX]; FSSpec spec; Boolean isDirectory = false; short CurrentFork; unsigned pathlen; long dirID; GetExtraFieldData(&MacZipMode, &newExtraField); if (MacZipMode != UnKnown_EF) { RfDfFilen2Real(CompletePath, G.filename, MacZipMode, (newExtraField.flags & EB_M3_FL_NOCHANGE), &CurrentFork); if (CurrentFork == ResourceFork) /* don't build a 'XtraStuf.mac:' dir */ return 0; } if (!IgnoreEF_Macfilename) { pathlen = strlen(path); strcpy(path, uO.exdir); strcat(path, ":"); strcat(path, newExtraField.FullPath); path[pathlen] = 0x00; }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -