📄 os2zip.c
字号:
/* .LONGNAME EA code */typedef struct{ ULONG cbList; /* length of value + 22 */#ifdef __32BIT__ ULONG oNext;#endif BYTE fEA; /* 0 */ BYTE cbName; /* length of ".LONGNAME" = 9 */ USHORT cbValue; /* length of value + 4 */ BYTE szName[10]; /* ".LONGNAME" */ USHORT eaType; /* 0xFFFD for length-preceded ASCII */ USHORT eaSize; /* length of value */ BYTE szValue[CCHMAXPATH];}FEALST;typedef struct{ ULONG cbList;#ifdef __32BIT__ ULONG oNext;#endif BYTE cbName; BYTE szName[10]; /* ".LONGNAME" */}GEALST;char *GetLongNameEA(char *name){ EAOP eaop; GEALST gealst; static FEALST fealst; if ( _osmode == DOS_MODE ) return NULL; eaop.fpGEAList = (PGEALIST) &gealst; eaop.fpFEAList = (PFEALIST) &fealst; eaop.oError = 0; strcpy(gealst.szName, ".LONGNAME"); gealst.cbName = (BYTE) strlen(gealst.szName);#ifdef __32BIT__ gealst.oNext = 0;#endif gealst.cbList = sizeof(gealst); fealst.cbList = sizeof(fealst); if ( DosQueryPathInfo(name, FIL_QUERYEASFROMLIST, (PBYTE) &eaop, sizeof(eaop)) ) return NULL; if ( fealst.cbValue > 4 && fealst.eaType == 0xFFFD ) { fealst.szValue[fealst.eaSize] = 0; return fealst.szValue; } return NULL;}char *GetLongPathEA(char *name){ static char nbuf[CCHMAXPATH + 1]; char *comp, *next, *ea, sep; BOOL bFound = FALSE; nbuf[0] = 0; next = name; while ( *next ) { comp = next; while ( *next != '\\' && *next != '/' && *next != 0 ) next++; sep = *next; *next = 0; ea = GetLongNameEA(name); strcat(nbuf, ea ? ea : comp); bFound = bFound || (ea != NULL); *next = sep; if ( *next ) { strcat(nbuf, "\\"); next++; } } return (nbuf[0] != 0) && bFound ? nbuf : NULL;}/* general EA code */typedef struct{ USHORT nID; USHORT nSize; ULONG lSize;}EAHEADER, *PEAHEADER;#ifdef __32BIT__/* Perhaps due to bugs in the current OS/2 2.0 kernel, the success or failure of the DosEnumAttribute() and DosQueryPathInfo() system calls depends on the area where the return buffers are allocated. This differs for the various compilers, for some alloca() works, for some malloc() works, for some, both work. We'll have to live with that. *//* The use of malloc() is not very convenient, because it requires backtracking (i.e. free()) at error returns. We do that for system calls that may fail, but not for malloc() calls, because they are VERY unlikely to fail. If ever, we just leave some memory allocated over the usually short lifetime of a zip process ... */#ifdef __GNUC__#define alloc(x) alloca(x)#define unalloc(x)#else#define alloc(x) malloc(x)#define unalloc(x) free(x)#endifvoid GetEAs(char *path, char **bufptr, size_t *size, char **cbufptr, size_t *csize){ FILESTATUS4 fs; PDENA2 pDENA, pFound; EAOP2 eaop; PGEA2 pGEA; PGEA2LIST pGEAlist; PFEA2LIST pFEAlist; PEAHEADER pEAblock; ULONG ulAttributes, ulMemoryBlock; ULONG nLength; ULONG nBlock; char szName[CCHMAXPATH]; *size = *csize = 0; if ( _osmode == DOS_MODE ) return; strcpy(szName, path); nLength = strlen(szName); if ( szName[nLength - 1] == '/' ) szName[nLength - 1] = 0; if ( DosQueryPathInfo(szName, FIL_QUERYEASIZE, (PBYTE) &fs, sizeof(fs)) ) return; nBlock = max(fs.cbList, 65535); if ( (pDENA = alloc((size_t) nBlock)) == NULL ) return; ulAttributes = -1; if ( DosEnumAttribute(ENUMEA_REFTYPE_PATH, szName, 1, pDENA, nBlock, &ulAttributes, ENUMEA_LEVEL_NO_VALUE) || ulAttributes == 0 || (pGEAlist = alloc((size_t) nBlock)) == NULL ) { unalloc(pDENA); return; } pGEA = pGEAlist -> list; pFound = pDENA; while ( ulAttributes-- ) { if ( !(strcmp(pFound -> szName, ".LONGNAME") == 0 && use_longname_ea) ) { pGEA -> cbName = pFound -> cbName; strcpy(pGEA -> szName, pFound -> szName); nLength = sizeof(GEA2) + strlen(pGEA -> szName); nLength = ((nLength - 1) / sizeof(ULONG) + 1) * sizeof(ULONG); pGEA -> oNextEntryOffset = ulAttributes ? nLength : 0; pGEA = (PGEA2) ((PCH) pGEA + nLength); } pFound = (PDENA2) ((PCH) pFound + pFound -> oNextEntryOffset); } if ( pGEA == pGEAlist -> list ) /* no attributes to save */ { unalloc(pDENA); unalloc(pGEAlist); return; } pGEAlist -> cbList = (PCH) pGEA - (PCH) pGEAlist; pFEAlist = (PVOID) pDENA; /* reuse buffer */ pFEAlist -> cbList = nBlock; eaop.fpGEA2List = pGEAlist; eaop.fpFEA2List = pFEAlist; eaop.oError = 0; if ( DosQueryPathInfo(szName, FIL_QUERYEASFROMLIST, (PBYTE) &eaop, sizeof(eaop)) ) { unalloc(pDENA); unalloc(pGEAlist); return; } /* The maximum compressed size is (in case of STORE type) the uncompressed size plus the size of the compression type field plus the size of the CRC field. */ ulAttributes = pFEAlist -> cbList; ulMemoryBlock = ulAttributes + sizeof(USHORT) + sizeof(ULONG); pEAblock = (PEAHEADER) malloc(sizeof(EAHEADER) + ulMemoryBlock); if ( pEAblock == NULL ) { unalloc(pDENA); unalloc(pGEAlist); return; } *bufptr = (char *) pEAblock; *size = sizeof(EAHEADER); pEAblock -> nID = EAID; pEAblock -> nSize = sizeof(pEAblock -> lSize); pEAblock -> lSize = ulAttributes; /* uncompressed size */ nLength = memcompress((char *) (pEAblock + 1), ulMemoryBlock, (char *) pFEAlist, ulAttributes); *size += nLength; pEAblock -> nSize += nLength; if ( (pEAblock = (PEAHEADER) malloc(sizeof(EAHEADER))) == NULL ) { unalloc(pDENA); unalloc(pGEAlist); return; } *cbufptr = (char *) pEAblock; *csize = sizeof(EAHEADER); pEAblock -> nID = EAID; pEAblock -> nSize = sizeof(pEAblock -> lSize); pEAblock -> lSize = ulAttributes; if ( noisy ) printf(" (%ld bytes EA's)", ulAttributes); unalloc(pDENA); unalloc(pGEAlist);}#else /* !__32BIT__ */typedef struct{ ULONG oNextEntryOffset; BYTE fEA; BYTE cbName; USHORT cbValue; CHAR szName[1];}FEA2, *PFEA2;typedef struct{ ULONG cbList; FEA2 list[1];}FEA2LIST, *PFEA2LIST;void GetEAs(char *path, char **bufptr, size_t *size, char **cbufptr, size_t *csize){ FILESTATUS2 fs; PDENA1 pDENA, pFound; EAOP eaop; PGEALIST pGEAlist; PGEA pGEA; PFEALIST pFEAlist; PFEA pFEA; PFEA2LIST pFEA2list; PFEA2 pFEA2; EAHEADER *pEAblock; ULONG ulAttributes; USHORT nLength, nMaxSize; char szName[CCHMAXPATH]; *size = *csize = 0; if ( _osmode == DOS_MODE ) return; strcpy(szName, path); nLength = strlen(szName); if ( szName[nLength - 1] == '/' ) szName[nLength - 1] = 0; if ( DosQueryPathInfo(szName, FIL_QUERYEASIZE, (PBYTE) &fs, sizeof(fs)) || fs.cbList <= 2 * sizeof(ULONG) ) return; ulAttributes = -1; nMaxSize = (USHORT) min(fs.cbList * 2, 65520L); if ( (pDENA = malloc((size_t) nMaxSize)) == NULL ) return; if ( DosEnumAttribute(ENUMEA_REFTYPE_PATH, szName, 1, pDENA, fs.cbList, &ulAttributes, ENUMEA_LEVEL_NO_VALUE) || ulAttributes == 0 || (pGEAlist = malloc(nMaxSize)) == NULL ) { free(pDENA); return; } pGEA = pGEAlist -> list; pFound = pDENA; while ( ulAttributes-- ) { nLength = strlen(pFound -> szName); if ( !(strcmp(pFound -> szName, ".LONGNAME") == 0 && use_longname_ea) ) { pGEA -> cbName = pFound -> cbName; strcpy(pGEA -> szName, pFound -> szName); pGEA = (PGEA) ((PCH) (pGEA++) + nLength); } pFound = (PDENA1) ((PCH) (pFound++) + nLength); } if ( pGEA == pGEAlist -> list ) { free(pDENA); free(pGEAlist); return; } pGEAlist -> cbList = (PCH) pGEA - (PCH) pGEAlist; pFEAlist = (PFEALIST) pDENA; /* reuse buffer */ pFEAlist -> cbList = fs.cbList; pFEA = pFEAlist -> list; eaop.fpGEAList = pGEAlist; eaop.fpFEAList = pFEAlist; eaop.oError = 0; if ( DosQueryPathInfo(szName, FIL_QUERYEASFROMLIST, (PBYTE) &eaop, sizeof(eaop)) ) { free(pDENA); free(pGEAlist); return; } /* now convert into new OS/2 2.0 32-bit format */ pFEA2list = (PFEA2LIST) pGEAlist; /* reuse buffer */ pFEA2 = pFEA2list -> list; while ( (PCH) pFEA - (PCH) pFEAlist < pFEAlist -> cbList ) { nLength = sizeof(FEA) + pFEA -> cbName + 1 + pFEA -> cbValue; memcpy((PCH) pFEA2 + sizeof(pFEA2 -> oNextEntryOffset), pFEA, nLength); memset((PCH) pFEA2 + sizeof(pFEA2 -> oNextEntryOffset) + nLength, 0, 3); pFEA = (PFEA) ((PCH) pFEA + nLength); nLength = sizeof(FEA2) + pFEA2 -> cbName + 1 + pFEA2 -> cbValue; nLength = ((nLength - 1) / sizeof(ULONG) + 1) * sizeof(ULONG); /* rounded up to 4-byte boundary */ pFEA2 -> oNextEntryOffset = ((PCH) pFEA - (PCH) pFEAlist < pFEAlist -> cbList) ? nLength : 0; pFEA2 = (PFEA2) ((PCH) pFEA2 + nLength); } pFEA2list -> cbList = (PCH) pFEA2 - (PCH) pFEA2list; ulAttributes = pFEA2list -> cbList; pEAblock = (PEAHEADER) pDENA; /* reuse buffer */ *bufptr = (char *) pEAblock; *size = sizeof(EAHEADER); pEAblock -> nID = EAID; pEAblock -> nSize = sizeof(pEAblock -> lSize); pEAblock -> lSize = ulAttributes; /* uncompressed size */ nLength = (USHORT) memcompress((char *) (pEAblock + 1), nMaxSize - sizeof(EAHEADER), (char *) pFEA2list, ulAttributes); *size += nLength; pEAblock -> nSize += nLength; pEAblock = (PEAHEADER) pGEAlist; *cbufptr = (char *) pEAblock; *csize = sizeof(EAHEADER); pEAblock -> nID = EAID; pEAblock -> nSize = sizeof(pEAblock -> lSize); pEAblock -> lSize = ulAttributes; if ( noisy ) printf(" (%ld bytes EA's)", ulAttributes);}#endif /* __32BIT__ */int set_extra_field(struct zlist *z){ GetEAs(z->name, &z->extra, &z->ext, &z->cextra, &z->cext); /* store data in local header, and size only in central headers */ return 0;}#endif /* UTIL *//* Initialize the table of uppercase characters including handling of country dependent characters. */void init_upper(){ COUNTRYCODE cc; unsigned nCnt, nU; for ( nCnt = 0; nCnt < sizeof(upper); nCnt++ ) upper[nCnt] = lower[nCnt] = (unsigned char) nCnt; cc.country = cc.codepage = 0; DosMapCase(sizeof(upper), &cc, (PCHAR) upper); for ( nCnt = 0; nCnt < 256; nCnt++ ) { nU = upper[nCnt]; if (nU != nCnt && lower[nU] == (unsigned char) nU) lower[nU] = (unsigned char) nCnt; } for ( nCnt = 'A'; nCnt <= 'Z'; nCnt++ ) lower[nCnt] = (unsigned char) (nCnt - 'A' + 'a');}char *StringLower(char *szArg){ unsigned char *szPtr; for ( szPtr = szArg; *szPtr; szPtr++ ) *szPtr = lower[*szPtr]; return szArg;}#if defined(__IBMC__) && defined(__DEBUG_ALLOC__)void DebugMalloc(void){ _dump_allocated(0); /* print out debug malloc memory statistics */}#endif#endif /* OS2 */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -