📄 amiga.c
字号:
#ifndef OLD_AMIGA_RENAMED G.renamed_fullpath = (renamed && (*G.filename == '/' || *G.filename == ':'));#else /* supress G.rootpath even when user gave a relative pathname */# if 1 G.renamed_fullpath = (renamed && strpbrk(G.filename, ":/");# else G.renamed_fullpath = (renamed && (strchr(G.filename, ':') || strchr(G.filename, '/')));# endif#endif if (checkdir(__G__ (char *)NULL, INIT) == 10) return 10; /* initialize path buffer, unless no memory */ *pathcomp = '\0'; /* initialize translation buffer */ pp = pathcomp; /* point to translation buffer */ if (uO.jflag) /* junking directories */ cp = (char *)strrchr(G.filename, '/'); if (cp == NULL) /* no '/' or not junking dirs */ cp = G.filename; /* point to internal zipfile-member pathname */ else ++cp; /* point to start of last component of path *//*--------------------------------------------------------------------------- Begin main loop through characters in filename. ---------------------------------------------------------------------------*/ while ((workch = (uch)*cp++) != 0) { switch (workch) { case '/': /* can assume -j flag not given */ *pp = '\0'; if ((error = checkdir(__G__ pathcomp, APPEND_DIR)) > 1) return error; pp = pathcomp; /* reset conversion buffer for next piece */ lastsemi = NULL; /* leave directory semi-colons alone */ break; case ';': /* VMS version (or DEC-20 attrib?) */ lastsemi = pp; /* keep for now; remove VMS ";##" */ *pp++ = (char)workch; /* later, if requested */ break; default: /* allow ISO European characters in filenames: */ if (isprint(workch) || (160 <= workch && workch <= 255)) *pp++ = (char)workch; } /* end switch */ } /* end while loop */ *pp = '\0'; /* done with pathcomp: terminate it */ /* if not saving them, remove with VMS version numbers (appended ";###") */ if (!uO.V_flag && lastsemi) { pp = lastsemi + 1; while (isdigit((uch)(*pp))) ++pp; if (*pp == '\0') /* only digits between ';' and end: nuke */ *lastsemi = '\0'; }/*--------------------------------------------------------------------------- Report if directory was created (and no file to create: filename ended in '/'), check name to be sure it exists, and combine path and name be- fore exiting. ---------------------------------------------------------------------------*/ if (G.filename[strlen(G.filename) - 1] == '/') { checkdir(__G__ G.filename, GETPATH); if (G.created_dir) { if (QCOND2) { Info(slide, 0, ((char *)slide, " creating: %s\n", G.filename)); } return IZ_CREATED_DIR; /* set dir time (note trailing '/') */ } return 2; /* dir existed already; don't look for data to extract */ } if (*pathcomp == '\0') { Info(slide, 1, ((char *)slide, "mapname: conversion of %s failed\n", G.filename)); return 3; } if ((error = checkdir(__G__ pathcomp, APPEND_NAME)) == 1) { /* GRR: OK if truncated here: warn and continue */ /* (warn in checkdir?) */ } checkdir(__G__ G.filename, GETPATH); return error;} /* end function mapname() *//***********************//* Function checkdir() *//***********************/int checkdir(__G__ pathcomp, flag) __GDEF char *pathcomp; int flag;/* * returns: 1 - (on APPEND_xxx) truncated path component * 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 */{/* these statics are now declared in SYSTEM_SPECIFIC_GLOBALS in amiga.h: *//* 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. ---------------------------------------------------------------------------*//* GRR: check path length after each segment: warn about truncation */ if (FUNCTION == APPEND_DIR) { int too_long = FALSE; Trace((stderr, "appending dir segment [%s]\n", pathcomp)); while ((*G.build_end = *pathcomp++)) ++G.build_end; /* Truncate components over 30 chars? Nah, the filesystem handles it. */ if ((G.build_end-G.buildpath) > FILNAMSIZ-3) /* room for "/a\0" */ too_long = TRUE; /* check if extracting directory? */ if (stat(G.buildpath, &G.statbuf)) { /* path doesn't exist */ if (!G.create_dirs) { /* told not to create (freshening) */ free(G.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", G.buildpath)); free(G.buildpath); return 4; /* no room for filenames: fatal */ } if (MKDIR(G.buildpath, 0777) == -1) { /* create the directory */ Info(slide, 1, ((char *)slide, "checkdir error: cannot create %s\n\ unable to process %s.\n", G.buildpath, G.filename)); free(G.buildpath); return 3; /* path didn't exist, tried to create, failed */ } G.created_dir = TRUE; } else if (!S_ISDIR(G.statbuf.st_mode)) { Info(slide, 1, ((char *)slide, "checkdir error: %s exists but is not a directory\n\ unable to process %s.\n", G.buildpath, G.filename)); free(G.buildpath); return 3; /* path existed but wasn't dir */ } if (too_long) { Info(slide, 1, ((char *)slide, "checkdir error: path too long: %s\n", G.buildpath)); free(G.buildpath); return 4; /* no room for filenames: fatal */ } *G.build_end++ = '/'; *G.build_end = '\0'; Trace((stderr, "buildpath now = [%s]\n", G.buildpath)); return 0; } /* end if (FUNCTION == APPEND_DIR) *//*--------------------------------------------------------------------------- GETPATH: copy full path to the string pointed at by pathcomp, and free G.buildpath. Not our responsibility to worry whether pathcomp has room. ---------------------------------------------------------------------------*/ if (FUNCTION == GETPATH) { strcpy(pathcomp, G.buildpath); Trace((stderr, "getting and freeing path [%s]\n", pathcomp)); free(G.buildpath); G.buildpath = G.build_end = NULL; return 0; }/*--------------------------------------------------------------------------- APPEND_NAME: assume the path component is the filename; append it and return without checking for existence. ---------------------------------------------------------------------------*/ if (FUNCTION == APPEND_NAME) { Trace((stderr, "appending filename [%s]\n", pathcomp)); while ((*G.build_end = *pathcomp++)) { ++G.build_end; if ((G.build_end-G.buildpath) >= FILNAMSIZ) { *--G.build_end = '\0'; Info(slide, 1, ((char *)slide, "checkdir warning: path too long; truncating\n\ %s\n -> %s\n", G.filename, G.buildpath)); return 1; /* filename truncated */ } } Trace((stderr, "buildpath static now = [%s]\n", G.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 static to ")); if ((G.buildpath = (char *)malloc(strlen(G.filename)+G.rootlen+1)) == NULL) return 10; if ((G.rootlen > 0) && !G.renamed_fullpath) { strcpy(G.buildpath, G.rootpath); G.build_end = G.buildpath + G.rootlen; } else { *G.buildpath = '\0'; G.build_end = G.buildpath; } Trace((stderr, "[%s]\n", G.buildpath)); return 0; }/*--------------------------------------------------------------------------- ROOT: if appropriate, store the path in G.rootpath and create it if necessary; 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 == NULL) { G.rootlen = 0; return 0; } if ((G.rootlen = strlen(pathcomp)) > 0) { if (stat(pathcomp, &G.statbuf) || !S_ISDIR(G.statbuf.st_mode)) { /* path does not exist */ if (!G.create_dirs) { G.rootlen = 0; return 2; /* 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, 0777) == -1) { Info(slide, 1, ((char *)slide, "checkdir: cannot create extraction directory: %s\n", pathcomp)); G.rootlen = 0; /* path didn't exist, tried to create, and */ return 3; /* failed: file exists, or 2+ levels required */ } } if ((G.rootpath = (char *)malloc(G.rootlen+2)) == NULL) { G.rootlen = 0; return 10; } strcpy(G.rootpath, pathcomp); if (G.rootpath[G.rootlen-1] != ':' && G.rootpath[G.rootlen-1] != '/') G.rootpath[G.rootlen++] = '/'; G.rootpath[G.rootlen] = '\0'; Trace((stderr, "rootpath now = [%s]\n", G.rootpath)); } return 0; }#endif /* !SFX || SFX_EXDIR *//*--------------------------------------------------------------------------- END: free G.rootpath, immediately prior to program exit. ---------------------------------------------------------------------------*/ if (FUNCTION == END) { Trace((stderr, "freeing rootpath\n")); if (G.rootlen > 0) { free(G.rootpath); G.rootlen = 0; } return 0; } return 99; /* should never reach */} /* end function checkdir() *//**************************************//* Function close_outfile() *//**************************************//* this part differs slightly with Zip *//*-------------------------------------*/void close_outfile(__G) __GDEF{ time_t m_time;#ifdef USE_EF_UT_TIME iztimes z_utime;#endif LONG FileDate(); if (uO.cflag) /* can't set time or filenote on stdout */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -