📄 os2.c
字号:
} /* create directory (could add loop here to scan pathcomp * and create more than one level, but really necessary?) */ if (MKDIR(pathcomp, 0777) == -1) { Info(slide, 1, ((char *)slide, LoadFarString(CantCreateExtractDir), pathcomp)); G.os2.rootlen = 0; /* path didn't exist, tried to create, */ return 3; /* failed: file exists, or need 2+ levels */ } } } if ((G.os2.rootpath = (char *)malloc(G.os2.rootlen+xtra)) == (char *)NULL) { G.os2.rootlen = 0; return 10; } strcpy(G.os2.rootpath, pathcomp); if (xtra == 3) /* had just "x:", make "x:." */ G.os2.rootpath[G.os2.rootlen++] = '.'; G.os2.rootpath[G.os2.rootlen++] = '/'; G.os2.rootpath[G.os2.rootlen] = '\0'; Trace((stderr, "rootpath now = [%s]\n", G.os2.rootpath)); } return 0; }#endif /* !SFX || SFX_EXDIR *//*--------------------------------------------------------------------------- END: free rootpath, immediately prior to program exit. ---------------------------------------------------------------------------*/ if (FUNCTION == END) { Trace((stderr, "freeing rootpath\n")); if (G.os2.rootlen > 0) { free(G.os2.rootpath); G.os2.rootlen = 0; } return 0; } return 99; /* should never reach */} /* end function checkdir() *//***********************//* Function isfloppy() */ /* more precisely, is it removable? *//***********************/static int isfloppy(nDrive) int nDrive; /* 1 == A:, 2 == B:, etc. */{ uch ParmList[1] = {0}; uch DataArea[1] = {0}; char Name[3]; HFILE handle;#ifdef __32BIT__ ULONG rc; ULONG action;#else USHORT rc; USHORT action;#endif Name[0] = (char) (nDrive + 'A' - 1); Name[1] = ':'; Name[2] = 0; rc = DosOpen(Name, &handle, &action, 0L, FILE_NORMAL, FILE_OPEN, OPEN_FLAGS_DASD | OPEN_FLAGS_FAIL_ON_ERROR | OPEN_ACCESS_READONLY | OPEN_SHARE_DENYNONE, 0L); if (rc == ERROR_NOT_READY) /* must be removable */ return TRUE; else if (rc) { /* other error: do default a/b heuristic instead */ Trace((stderr, "error in DosOpen(DASD): guessing...\n", rc)); return (nDrive == 1 || nDrive == 2)? TRUE : FALSE; } rc = DosDevIOCtl(DataArea, sizeof(DataArea), ParmList, sizeof(ParmList), DSK_BLOCKREMOVABLE, IOCTL_DISK, handle); DosClose(handle); if (rc) { /* again, just check for a/b */ Trace((stderr, "error in DosDevIOCtl category IOCTL_DISK, function " "DSK_BLOCKREMOVABLE\n (rc = 0x%04x): guessing...\n", rc)); return (nDrive == 1 || nDrive == 2)? TRUE : FALSE; } else { return DataArea[0] ? FALSE : TRUE; }} /* end function isfloppy() */static int IsFileNameValid(const char *name){ HFILE hf;#ifdef __32BIT__ ULONG uAction;#else USHORT uAction;#endif switch( DosOpen((PSZ) name, &hf, &uAction, 0, 0, FILE_OPEN, OPEN_ACCESS_READONLY | OPEN_SHARE_DENYNONE, 0) ) { case ERROR_INVALID_NAME: case ERROR_FILENAME_EXCED_RANGE: return FALSE; case NO_ERROR: DosClose(hf); default: return TRUE; }}/**********************//* Function map2fat() *//**********************/static void map2fat(pathcomp, pEndFAT) char *pathcomp, **pEndFAT;{ char *ppc = pathcomp; /* variable pointer to pathcomp */ char *pEnd = *pEndFAT; /* variable pointer to buildpathFAT */ char *pBegin = *pEndFAT; /* constant pointer to start of this comp. */ char *last_dot = (char *)NULL; /* last dot not converted to underscore */ int dotname = FALSE; /* flag: path component begins with dot */ /* ("." and ".." don't count) */ register unsigned workch; /* hold the character being tested */ /* Only need check those characters which are legal in HPFS but not * in FAT: to get here, must already have passed through mapname. * (GRR: oops, small bug--if char was quoted, no longer have any * knowledge of that.) Also must truncate path component to ensure * 8.3 compliance... */ while ((workch = (uch)*ppc++) != 0) { switch (workch) { case '[': /* add '"' '+' ',' '=' ?? */ case ']': *pEnd++ = '_'; /* convert brackets to underscores */ break; case '.': if (pEnd == *pEndFAT) { /* nothing appended yet... */ if (*ppc == '\0') /* don't bother appending a */ break; /* "./" component to the path */ else if (*ppc == '.' && ppc[1] == '\0') { /* "../" */ *pEnd++ = '.'; /* add first dot, unchanged... */ ++ppc; /* skip second dot, since it will */ } else { /* be "added" at end of if-block */ *pEnd++ = '_'; /* 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: */ *pEnd = '\0'; /* remove it by shifting chars */ pEnd = *pEndFAT + 1; /* left one space (e.g., .p1.p2: */ while (pEnd[1]) { /* __p1 -> _p1_p2 -> _p1.p2 when */ *pEnd = pEnd[1]; /* finished) [opt.: since first */ ++pEnd; /* two chars are same, can start */ } /* shifting at second position] */ } last_dot = pEnd; /* point at last dot so far... */ *pEnd++ = '_'; /* convert dot to underscore for now */ break; default: *pEnd++ = (char)workch; } /* end switch */ } /* end while loop */ *pEnd = '\0'; /* terminate buildpathFAT */ /* NOTE: keep in mind that pEnd points to the end of the path * component, and *pEndFAT still points to the *beginning* of it... * Also 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 underscore is converted to a dot * (only if more characters are saved that way). In no case is * a dot inserted between existing characters. */ if (last_dot == (char *)NULL) { /* no dots: check for underscores... */ char *plu = strrchr(pBegin, '_'); /* pointer to last underscore */ if (plu == (char *)NULL) { /* no dots, no underscores: truncate at 8 */ *pEndFAT += 8; /* chars (could insert '.' and keep 11...) */ if (*pEndFAT > pEnd) *pEndFAT = pEnd; /* oops...didn't have 8 chars to truncate */ else **pEndFAT = '\0'; } else if (MIN(plu - pBegin, 8) + MIN(pEnd - plu - 1, 3) > 8) { last_dot = plu; /* be lazy: drop through to next if-block */ } else if ((pEnd - *pEndFAT) > 8) { *pEndFAT += 8; /* more fits into just basename than if */ **pEndFAT = '\0'; /* convert last underscore to dot */ } else *pEndFAT = pEnd; /* whole thing fits into 8 chars or less */ } if (last_dot != (char *)NULL) { /* one dot (or two, in the case of */ *last_dot = '.'; /* "..") is OK: put it back in */ if ((last_dot - pBegin) > 8) { char *p, *q; int i; p = last_dot; q = last_dot = pBegin + 8; for (i = 0; (i < 4) && *p; ++i) /* too many chars in basename: */ *q++ = *p++; /* shift ".ext" left and */ *q = '\0'; /* truncate/terminate it */ *pEndFAT = q; } else if ((pEnd - last_dot) > 4) { /* too many chars in extension */ *pEndFAT = last_dot + 4; **pEndFAT = '\0'; } else *pEndFAT = pEnd; /* filename is fine; point at terminating zero */ if ((last_dot - pBegin) > 0 && last_dot[-1] == ' ') last_dot[-1] = '_'; /* NO blank in front of '.'! */ }} /* end function map2fat() */static int SetLongNameEA(char *name, char *longname){ EAOP eaop; FEALST fealst; eaop.fpFEAList = (PFEALIST) &fealst; eaop.fpGEAList = NULL; eaop.oError = 0; strcpy((char *) fealst.szName, ".LONGNAME"); strcpy((char *) fealst.szValue, longname); fealst.cbList = sizeof(fealst) - CCHMAXPATH + strlen((char *) fealst.szValue); fealst.cbName = (BYTE) strlen((char *) fealst.szName); fealst.cbValue = sizeof(USHORT) * 2 + strlen((char *) fealst.szValue);#ifdef __32BIT__ fealst.oNext = 0;#endif fealst.fEA = 0; fealst.eaType = 0xFFFD; fealst.eaSize = strlen((char *) fealst.szValue); return DosSetPathInfo(name, FIL_QUERYEASIZE, (PBYTE) &eaop, sizeof(eaop), 0);}/****************************//* Function close_outfile() *//****************************/ /* GRR: need to return error level!! */void close_outfile(__G) /* only for extracted files, not directories */ __GDEF{ fclose(G.outfile); /* set extra fields, both stored-in-zipfile and .LONGNAME flavors */ if (G.extra_field) { /* zipfile extra field may have extended attribs */ int err = EvalExtraFields(__G__ G.filename, G.extra_field, G.lrec.extra_field_length); if (err == IZ_EF_TRUNC) { if (uO.qflag) Info(slide, 1, ((char *)slide, "%-22s ", G.filename)); Info(slide, 1, ((char *)slide, LoadFarString(TruncEAs), makeword(G.extra_field+2)-10, uO.qflag? "\n" : "")); } } if (G.os2.longnameEA) {#ifdef DEBUG int e =#endif SetLongNameEA(G.filename, G.os2.lastpathcomp); Trace((stderr, "close_outfile: SetLongNameEA() returns %d\n", e)); free(G.os2.lastpathcomp); } /* set date/time and permissions */ SetPathAttrTimes(__G__ G.pInfo->file_attr, 0);} /* end function close_outfile() *//******************************//* Function check_for_newer() *//******************************/int check_for_newer(__G__ filename) /* return 1 if existing file newer or equal; */ __GDEF char *filename; /* 0 if older; -1 if doesn't exist yet */{ ulg existing, archive;#ifdef USE_EF_UT_TIME iztimes z_utime;#endif if ((existing = (ulg)GetFileTime(filename)) == (ulg)-1) return DOES_NOT_EXIST;#ifdef USE_EF_UT_TIME if (G.extra_field &&#ifdef IZ_CHECK_TZ G.tz_is_valid &&#endif (ef_scan_for_izux(G.extra_field, G.lrec.extra_field_length, 0, G.lrec.last_mod_dos_datetime, &z_utime, NULL) & EB_UT_FL_MTIME)) { TTrace((stderr, "check_for_newer: using Unix extra field mtime\n")); archive = Utime2DosDateTime(z_utime.mtime); } else { archive = G.lrec.last_mod_dos_datetime; }#else /* !USE_EF_UT_TIME */ archive = G.lrec.last_mod_dos_datetime;#endif /* ?USE_EF_UT_TIME */ return (existing >= archive);} /* end function check_for_newer() */#ifndef SFX/*************************//* Function dateformat() *//*************************/int dateformat(){/*----------------------------------------------------------------------------- For those operating systems which support it, this function returns a value which tells how national convention says that numeric dates are displayed. Return values are DF_YMD, DF_DMY and DF_MDY. -----------------------------------------------------------------------------*/ switch (GetCountryInfo()) { case 0: return DF_MDY; case 1: return DF_DMY; case 2: return DF_YMD; } return DF_MDY; /* default if error */} /* end function dateformat() *//************************//* Function version() *//************************/void version(__G) __GDEF{ int len;#if defined(__IBMC__) || defined(__WATCOMC__) || defined(_MSC_VER) char buf[80];#endif len = sprintf((char *)slide, Loa
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -