📄 flexos.c
字号:
switch (workch) { case '/': /* can assume -j flag not given */ *pp = '\0'; map2fat(pathcomp, last_dot); /* 8.3 truncation (in place) */ last_dot = (char *)NULL; if ((error = checkdir(__G__ pathcomp, APPEND_DIR)) > 1) return error; pp = pathcomp; /* reset conversion buffer for next piece */ lastsemi = (char *)NULL; /* leave directory semi-colons alone */ break; /* drive names are not stored in zipfile, so no colons allowed; * no brackets or most other punctuation either (all of which * can appear in Unix-created archives; backslash is particularly * bad unless all necessary directories exist) */ case '[': /* these punctuation characters forbidden */ case ']': /* only on plain FAT file systems */ case '+': case ',': case '=': case ':': /* special shell characters of command.com */ case '\\': /* (device and directory limiters, wildcard */ case '"': /* characters, stdin/stdout redirection and */ case '<': /* pipe indicators and the quote sign) are */ case '>': /* never allowed in filenames on (V)FAT */ case '|': case '*': case '?': *pp++ = '_'; break; case '.': if (pp == pathcomp) { /* nothing appended yet... */ if (*cp == '/') { /* don't bother appending a "./" */ ++cp; /* component to the path: skip */ break; /* to next char after the '/' */ } else if (*cp == '.' && cp[1] == '/') { /* "../" */ *pp++ = '.'; /* add first dot, unchanged... */ ++cp; /* skip second dot, since it will */ } else { /* be "added" at end of if-block */ *pp++ = '_'; /* FAT doesn't allow null filename */ dotname = TRUE; /* bodies, so map .exrc -> _.exrc */ } /* (extra '_' now, "dot" below) */ } else if (dotname) { /* found a second dot, but still */ dotname = FALSE; /* have extra leading underscore: */ *pp = '\0'; /* remove it by shifting chars */ pp = pathcomp + 1; /* left one space (e.g., .p1.p2: */ while (pp[1]) { /* __p1 -> _p1_p2 -> _p1.p2 when */ *pp = pp[1]; /* finished) [opt.: since first */ ++pp; /* two chars are same, can start */ } /* shifting at second position] */ } last_dot = pp; /* point at last dot so far... */ *pp++ = '_'; /* convert dot to underscore for now */ break; case ';': /* start of VMS version? */ lastsemi = pp; break; case ' ': /* change spaces to underscores */ if (uO.sflag) /* only if requested */ *pp++ = '_'; else *pp++ = (char)workch; break; default: /* allow ASCII 255 and European characters in filenames: */ if (isprint(workch) || workch >= 127) *pp++ = (char)workch; } /* end switch */ } /* end while loop */ *pp = '\0'; /* done with pathcomp: terminate it */ /* if not saving them, remove VMS version numbers (appended ";###") */ if (!uO.V_flag && lastsemi) { pp = lastsemi; /* semi-colon was omitted: expect all #'s */ while (isdigit((uch)(*pp))) ++pp; if (*pp == '\0') /* only digits between ';' and end: nuke */ *lastsemi = '\0'; } map2fat(pathcomp, last_dot); /* 8.3 truncation (in place) *//*--------------------------------------------------------------------------- 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 (created_dir) { if (QCOND2) { Info(slide, 0, ((char *)slide, LoadFarString(Creating), FnFilter1(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, LoadFarString(ConversionFailed), FnFilter1(G.filename))); return 3; } checkdir(__G__ pathcomp, APPEND_NAME); /* returns 1 if truncated: care? */ checkdir(__G__ G.filename, GETPATH); return error;} /* end function mapname() *//**********************//* Function map2fat() *//**********************/static void map2fat(pathcomp, last_dot) char *pathcomp, *last_dot;{ char *pEnd = pathcomp + strlen(pathcomp);/*--------------------------------------------------------------------------- Case 1: filename has no dot, so figure out if we should add one. Note that the algorithm does not try to get too fancy: if there are no dots already, the name either gets truncated at 8 characters or the last un- derscore is converted to a dot (only if more characters are saved that way). In no case is a dot inserted between existing characters. GRR: have problem if filename is volume label?? ---------------------------------------------------------------------------*/ /* pEnd = pathcomp + strlen(pathcomp); */ if (last_dot == (char *)NULL) { /* no dots: check for underscores... */ char *plu = strrchr(pathcomp, '_'); /* pointer to last underscore */ if (plu == (char *)NULL) { /* no dots, no underscores: truncate at */ if (pEnd > pathcomp+8) /* 8 chars (could insert '.' and keep 11) */ *(pEnd = pathcomp+8) = '\0'; } else if (MIN(plu - pathcomp, 8) + MIN(pEnd - plu - 1, 3) > 8) { last_dot = plu; /* be lazy: drop through to next if-block */ } else if ((pEnd - pathcomp) > 8) /* more fits into just basename */ pathcomp[8] = '\0'; /* than if convert last underscore to dot */ /* else whole thing fits into 8 chars or less: no change */ }/*--------------------------------------------------------------------------- Case 2: filename has dot in it, so truncate first half at 8 chars (shift extension if necessary) and second half at three. ---------------------------------------------------------------------------*/ if (last_dot != (char *)NULL) { /* one dot (or two, in the case of */ *last_dot = '.'; /* "..") is OK: put it back in */ if ((last_dot - pathcomp) > 8) { char *p=last_dot, *q=pathcomp+8; int i; for (i = 0; (i < 4) && *p; ++i) /* too many chars in basename: */ *q++ = *p++; /* shift extension left and */ *q = '\0'; /* truncate/terminate it */ } else if ((pEnd - last_dot) > 4) last_dot[4] = '\0'; /* too many chars in extension */ /* else filename is fine as is: no change */ }} /* end function map2fat() *//***********************//* 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; Trace((stderr, "appending dir segment [%s]\n", pathcomp)); while ((*end = *pathcomp++) != '\0') ++end; /* 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, LoadFarString(PathTooLong), FnFilter1(buildpath))); free(buildpath); return 4; /* no room for filenames: fatal */ } if (mkdir(buildpath, 0777) == -1) { /* create the directory */ Info(slide, 1, ((char *)slide, LoadFarString(CantCreateDir), FnFilter2(buildpath), FnFilter1(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, LoadFarString(DirIsntDirectory), FnFilter2(buildpath), FnFilter1(G.filename))); free(buildpath); return 3; /* path existed but wasn't dir */ } if (too_long) { Info(slide, 1, ((char *)slide, LoadFarString(PathTooLong), FnFilter1(buildpath))); free(buildpath); return 4; /* no room for filenames: fatal */ } *end++ = '/'; *end = '\0'; Trace((stderr, "buildpath now = [%s]\n", FnFilter1(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", FnFilter1(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) { Trace((stderr, "appending filename [%s]\n", FnFilter1(pathcomp))); while ((*end = *pathcomp++) != '\0') { ++end; if ((end-buildpath) >= FILNAMSIZ) { *--end = '\0';
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -