/* * misc.c * Copyright (C) 1998-2005 A.J. van Os; Released under GNU GPL * * Description: * Miscellaneous functions */ #include #include #include #include #include #if defined(__riscos) #include "DeskLib:SWI.h" #else #include #include #include #endif /* __riscos */ #if !defined(S_ISREG) #define S_ISREG(x) (((x) & S_IFMT) == S_IFREG) #endif /* !S_ISREG */ #include "antiword.h" #if defined(__vms) #include #endif #if !defined(__riscos) /* * szGetHomeDirectory - get the name of the home directory */ const char * szGetHomeDirectory(void) { const char *szHome; #if defined(__vms) szHome = decc$translate_vms(getenv("HOME")); #elif defined(__Plan9__) szHome = getenv("home"); #else szHome = getenv("HOME"); #endif /* __vms */ if (szHome == NULL || szHome[0] == '\0') { #if defined(N_PLAT_NLM) szHome = "SYS:"; #elif defined(__dos) szHome = "C:"; #else werr(0, "I can't find the name of your HOME directory"); szHome = ""; #endif /* __dos */ } return szHome; } /* end of szGetHomeDirectory */ /* * szGetAntiwordDirectory - get the name of the Antiword directory */ const char * szGetAntiwordDirectory(void) { #if defined(__vms) return decc$translate_vms(getenv("ANTIWORDHOME")); #else return getenv("ANTIWORDHOME"); #endif /* __vms */ } /* end of szGetAntiwordDirectory */ #endif /* !__riscos */ /* * Get the size of the specified file. * Returns -1 if the file does not exist or is not a proper file. */ long lGetFilesize(const char *szFilename) { #if defined(__riscos) os_error *e; int iType, iSize; e = SWI(2, 5, SWI_OS_File | XOS_Bit, 17, szFilename, &iType, NULL, NULL, NULL, &iSize); if (e != NULL) { werr(0, "Get Filesize error %d: %s", e->errnum, e->errmess); return -1; } if (iType != 1) { /* It's not a proper file or the file does not exist */ return -1; } return (long)iSize; #else struct stat tBuffer; errno = 0; if (stat(szFilename, &tBuffer) != 0) { werr(0, "Get Filesize error %d", errno); return -1; } if (!S_ISREG(tBuffer.st_mode)) { /* It's not a regular file */ return -1; } return (long)tBuffer.st_size; #endif /* __riscos */ } /* end of lGetFilesize */ #if defined(DEBUG) void vPrintBlock(const char *szFile, int iLine, const UCHAR *aucBlock, size_t tLength) { int i, j; fail(szFile == NULL || iLine < 0 || aucBlock == NULL); fprintf(stderr, "%s[%3d]:\n", szFile, iLine); for (i = 0; i < 32; i++) { if (16 * i >= (int)tLength) { return; } fprintf(stderr, "%03x: ", (unsigned int)(16 * i)); for (j = 0; j < 16; j++) { if (16 * i + j < (int)tLength) { fprintf(stderr, "%02x ", (unsigned int)aucBlock[16 * i + j]); } } fprintf(stderr, "\n"); } } /* end of vPrintBlock */ void vPrintUnicode(const char *szFile, int iLine, const UCHAR *aucUni, size_t tLen) { char *szASCII; fail(tLen % 2 != 0); tLen /= 2; /* Length in bytes to length in characters */ szASCII = xmalloc(tLen + 1); (void)unincpy(szASCII, aucUni, tLen); szASCII[tLen] = '\0'; (void)fprintf(stderr, "%s[%3d]: %.*s\n", szFile, iLine, (int)tLen, szASCII); szASCII = xfree(szASCII); } /* end of vPrintUnicode */ BOOL bCheckDoubleLinkedList(output_type *pAnchor) { output_type *pCurr, *pLast; int iInList; pLast = pAnchor; iInList = 0; for (pCurr = pAnchor; pCurr != NULL; pCurr = pCurr->pNext) { pLast = pCurr; iInList++; } NO_DBG_DEC(iInList); for (pCurr = pLast; pCurr != NULL; pCurr = pCurr->pPrev) { pLast = pCurr; iInList--; } DBG_DEC_C(iInList != 0, iInList); return pAnchor == pLast && iInList == 0; } /* end of bCheckDoubleLinkedList */ #endif /* DEBUG */ /* * bReadBytes * This function reads the specified number of bytes from the specified file, * starting from the specified offset. * Returns TRUE when successfull, otherwise FALSE */ BOOL bReadBytes(UCHAR *aucBytes, size_t tMemb, ULONG ulOffset, FILE *pFile) { fail(aucBytes == NULL || pFile == NULL || ulOffset > (ULONG)LONG_MAX); if (ulOffset > (ULONG)LONG_MAX) { return FALSE; } if (fseek(pFile, (long)ulOffset, SEEK_SET) != 0) { return FALSE; } if (fread(aucBytes, sizeof(UCHAR), tMemb, pFile) != tMemb) { return FALSE; } return TRUE; } /* end of bReadBytes */ /* * bReadBuffer * This function fills the specified buffer with the specified number of bytes, * starting at the specified offset within the Big/Small Block Depot. * * Returns TRUE when successful, otherwise FALSE */ BOOL bReadBuffer(FILE *pFile, ULONG ulStartBlock, const ULONG *aulBlockDepot, size_t tBlockDepotLen, size_t tBlockSize, UCHAR *aucBuffer, ULONG ulOffset, size_t tToRead) { ULONG ulBegin, ulIndex; size_t tLen; fail(pFile == NULL); fail(ulStartBlock > MAX_BLOCKNUMBER && ulStartBlock != END_OF_CHAIN); fail(aulBlockDepot == NULL); fail(tBlockSize != BIG_BLOCK_SIZE && tBlockSize != SMALL_BLOCK_SIZE); fail(aucBuffer == NULL); fail(tToRead == 0); for (ulIndex = ulStartBlock; ulIndex != END_OF_CHAIN && tToRead != 0; ulIndex = aulBlockDepot[ulIndex]) { if (ulIndex >= (ULONG)tBlockDepotLen) { DBG_DEC(ulIndex); DBG_DEC(tBlockDepotLen); if (tBlockSize >= BIG_BLOCK_SIZE) { werr(1, "The Big Block Depot is damaged"); } else { werr(1, "The Small Block Depot is damaged"); } } if (ulOffset >= (ULONG)tBlockSize) { ulOffset -= tBlockSize; continue; } ulBegin = ulDepotOffset(ulIndex, tBlockSize) + ulOffset; tLen = min(tBlockSize - (size_t)ulOffset, tToRead); ulOffset = 0; if (!bReadBytes(aucBuffer, tLen, ulBegin, pFile)) { werr(0, "Read big block 0x%lx not possible", ulBegin); return FALSE; } aucBuffer += tLen; tToRead -= tLen; } DBG_DEC_C(tToRead != 0, tToRead); return tToRead == 0; } /* end of bReadBuffer */ /* * Convert a Word colornumber into a true color for use in a drawfile * * Returns the true color */ ULONG ulColor2Color(UCHAR ucFontColor) { static const ULONG aulColorTable[] = { /* 0 */ 0x00000000UL, /* Automatic */ /* 1 */ 0x00000000UL, /* Black */ /* 2 */ 0xff000000UL, /* Blue */ /* 3 */ 0xffff0000UL, /* Turquoise */ /* 4 */ 0x00ff0000UL, /* Bright Green */ /* 5 */ 0xff00ff00UL, /* Pink */ /* 6 */ 0x0000ff00UL, /* Red */ /* 7 */ 0x00ffff00UL, /* Yellow */ /* 8 */ 0xffffff00UL, /* White */ /* 9 */ 0x80000000UL, /* Dark Blue */ /* 10 */ 0x80800000UL, /* Teal */ /* 11 */ 0x00800000UL, /* Green */ /* 12 */ 0x80008000UL, /* Violet */ /* 13 */ 0x00008000UL, /* Dark Red */ /* 14 */ 0x00808000UL, /* Dark Yellow */ /* 15 */ 0x80808000UL, /* Gray 50% */ /* 16 */ 0xc0c0c000UL, /* Gray 25% */ }; if ((size_t)ucFontColor >= elementsof(aulColorTable)) { return aulColorTable[0]; } return aulColorTable[(int)ucFontColor]; } /* end of ulColor2Color */ /* * iFindSplit - find a place to split the string * * returns the index of the split character or -1 if no split found. */ static int iFindSplit(const char *szString, size_t tStringLen) { size_t tSplit; if (tStringLen == 0) { return -1; } tSplit = tStringLen - 1; while (tSplit >= 1) { if (szString[tSplit] == ' ' || (szString[tSplit] == '-' && szString[tSplit - 1] != ' ')) { return (int)tSplit; } tSplit--; } return -1; } /* end of iFindSplit */ /* * pSplitList - split the specified list in a printable part and a leftover part * * returns the pointer to the leftover part */ output_type * pSplitList(output_type *pAnchor) { output_type *pCurr, *pLeftOver; int iIndex; fail(pAnchor == NULL); for (pCurr = pAnchor; pCurr->pNext != NULL; pCurr = pCurr->pNext) ; /* EMPTY */ iIndex = -1; for (; pCurr != NULL; pCurr = pCurr->pPrev) { iIndex = iFindSplit(pCurr->szStorage, pCurr->tNextFree); if (iIndex >= 0) { break; } } if (pCurr == NULL || iIndex < 0) { /* No split, no leftover */ return NULL; } /* Split over the iIndex-th character */ NO_DBG_MSG("pLeftOver"); pLeftOver = xmalloc(sizeof(*pLeftOver)); fail(pCurr->tNextFree < (size_t)iIndex); pLeftOver->tStorageSize = pCurr->tNextFree - (size_t)iIndex; pLeftOver->szStorage = xmalloc(pLeftOver->tStorageSize); pLeftOver->tNextFree = pCurr->tNextFree - (size_t)iIndex - 1; (void)strncpy(pLeftOver->szStorage, pCurr->szStorage + iIndex + 1, pLeftOver->tNextFree); pLeftOver->szStorage[pLeftOver->tNextFree] = '\0'; NO_DBG_MSG(pLeftOver->szStorage); pLeftOver->ucFontColor = pCurr->ucFontColor; pLeftOver->usFontStyle = pCurr->usFontStyle; pLeftOver->tFontRef = pCurr->tFontRef; pLeftOver->usFontSize = pCurr->usFontSize; pLeftOver->lStringWidth = lComputeStringWidth( pLeftOver->szStorage, pLeftOver->tNextFree, pLeftOver->tFontRef, pLeftOver->usFontSize); pLeftOver->pPrev = NULL; pLeftOver->pNext = pCurr->pNext; if (pLeftOver->pNext != NULL) { pLeftOver->pNext->pPrev = pLeftOver; } fail(!bCheckDoubleLinkedList(pLeftOver)); NO_DBG_MSG("pAnchor"); NO_DBG_HEX(pCurr->szStorage[iIndex]); while (iIndex >= 0 && isspace((int)(UCHAR)pCurr->szStorage[iIndex])) { iIndex--; } pCurr->tNextFree = (size_t)iIndex + 1; pCurr->szStorage[pCurr->tNextFree] = '\0'; NO_DBG_MSG(pCurr->szStorage); pCurr->lStringWidth = lComputeStringWidth( pCurr->szStorage, pCurr->tNextFree, pCurr->tFontRef, pCurr->usFontSize); pCurr->pNext = NULL; fail(!bCheckDoubleLinkedList(pAnchor)); return pLeftOver; } /* end of pSplitList */ /* * tNumber2Roman - convert a number to Roman Numerals * * returns the number of characters written */ size_t tNumber2Roman(UINT uiNumber, BOOL bUpperCase, char *szOutput) { char *outp, *p, *q; UINT uiNextVal, uiValue; fail(szOutput == NULL); uiNumber %= 4000; /* Very high numbers can't be represented */ if (uiNumber == 0) { szOutput[0] = '\0'; return 0; } outp = szOutput; p = bUpperCase ? "M\2D\5C\2L\5X\2V\5I" : "m\2d\5c\2l\5x\2v\5i"; uiValue = 1000; for (;;) { while (uiNumber >= uiValue) { *outp++ = *p; uiNumber -= uiValue; } if (uiNumber == 0) { *outp = '\0'; fail(outp < szOutput); return (size_t)(outp - szOutput); } q = p + 1; uiNextVal = uiValue / (UINT)(UCHAR)*q; if ((int)*q == 2) { /* magic */ uiNextVal /= (UINT)(UCHAR)*(q += 2); } if (uiNumber + uiNextVal >= uiValue) { *outp++ = *++q; uiNumber += uiNextVal; } else { p++; uiValue /= (UINT)(UCHAR)(*p++); } } } /* end of tNumber2Roman */ /* * iNumber2Alpha - convert a number to alphabetic "numbers" * * returns the number of characters written */ size_t tNumber2Alpha(UINT uiNumber, BOOL bUpperCase, char *szOutput) { char *outp; UINT uiTmp; fail(szOutput == NULL); if (uiNumber == 0) { szOutput[0] = '\0'; return 0; } outp = szOutput; uiTmp = (UINT)(bUpperCase ? 'A': 'a'); if (uiNumber <= 26) { uiNumber -= 1; *outp++ = (char)(uiTmp + uiNumber); } else if (uiNumber <= 26U + 26U*26U) { uiNumber -= 26 + 1; *outp++ = (char)(uiTmp + uiNumber / 26); *outp++ = (char)(uiTmp + uiNumber % 26); } else if (uiNumber <= 26U + 26U*26U + 26U*26U*26U) { uiNumber -= 26 + 26*26 + 1; *outp++ = (char)(uiTmp + uiNumber / (26*26)); *outp++ = (char)(uiTmp + uiNumber / 26 % 26); *outp++ = (char)(uiTmp + uiNumber % 26); } *outp = '\0'; fail(outp < szOutput); return (size_t)(outp - szOutput); } /* end of tNumber2Alpha */ /* * unincpy - copy a counted Unicode string to an single-byte string */ char * unincpy(char *s1, const UCHAR *s2, size_t n) { char *pcDest; ULONG ulChar; size_t tLen; USHORT usUni; for (pcDest = s1, tLen = 0; tLen < n; pcDest++, tLen++) { usUni = usGetWord(tLen * 2, s2); if (usUni == 0) { break; } ulChar = ulTranslateCharacters(usUni, 0, 8, conversion_unknown, encoding_neutral, FALSE); if (ulChar == IGNORE_CHARACTER) { ulChar = (ULONG)'?'; } *pcDest = (char)ulChar; } for (; tLen < n; tLen++) { *pcDest++ = '\0'; } return s1; } /* end of unincpy */ /* * unilen - calculate the length of a Unicode string * * returns the length in bytes */ size_t unilen(const UCHAR *s) { size_t tLen; USHORT usUni; tLen = 0; for (;;) { usUni = usGetWord(tLen, s); if (usUni == 0) { return tLen; } tLen += 2; } } /* end of unilen */ /* * szBaseName - get the basename of the specified filename */ const char * szBasename(const char *szFilename) { const char *szTmp; fail(szFilename == NULL); if (szFilename == NULL || szFilename[0] == '\0') { return "null"; } szTmp = strrchr(szFilename, FILE_SEPARATOR[0]); if (szTmp == NULL) { return szFilename; } return ++szTmp; } /* end of szBasename */ /* * lComputeLeading - compute the leading * * NOTE: the fontsize is specified in half points * * Returns the leading in drawunits */ long lComputeLeading(USHORT usFontSize) { long lLeading; lLeading = (long)usFontSize * 500L; if (usFontSize < 18) { /* Small text: 112% */ lLeading *= 112; } else if (usFontSize < 28) { /* Normal text: 124% */ lLeading *= 124; } else if (usFontSize < 48) { /* Small headlines: 104% */ lLeading *= 104; } else { /* Large headlines: 100% */ lLeading *= 100; } lLeading = lMilliPoints2DrawUnits(lLeading); lLeading += 50; lLeading /= 100; return lLeading; } /* end of lComputeLeading */ /* * Convert a UCS character to an UTF-8 string * * Returns the string length of the result */ size_t tUcs2Utf8(ULONG ulChar, char *szResult, size_t tMaxResultLen) { if (szResult == NULL || tMaxResultLen == 0) { return 0; } if (ulChar < 0x80 && tMaxResultLen >= 2) { szResult[0] = (char)ulChar; szResult[1] = '\0'; return 1; } if (ulChar < 0x800 && tMaxResultLen >= 3) { szResult[0] = (char)(0xc0 | ulChar >> 6); szResult[1] = (char)(0x80 | (ulChar & 0x3f)); szResult[2] = '\0'; return 2; } if (ulChar < 0x10000 && tMaxResultLen >= 4) { szResult[0] = (char)(0xe0 | ulChar >> 12); szResult[1] = (char)(0x80 | (ulChar >> 6 & 0x3f)); szResult[2] = (char)(0x80 | (ulChar & 0x3f)); szResult[3] = '\0'; return 3; } if (ulChar < 0x200000 && tMaxResultLen >= 5) { szResult[0] = (char)(0xf0 | ulChar >> 18); szResult[1] = (char)(0x80 | (ulChar >> 12 & 0x3f)); szResult[2] = (char)(0x80 | (ulChar >> 6 & 0x3f)); szResult[3] = (char)(0x80 | (ulChar & 0x3f)); szResult[4] = '\0'; return 4; } szResult[0] = '\0'; return 0; } /* end of tUcs2Utf8 */ /* * vGetBulletValue - get the bullet value for the conversing type and encoding */ void vGetBulletValue(conversion_type eConversionType, encoding_type eEncoding, char *szResult, size_t tMaxResultLen) { fail(szResult == NULL); fail(tMaxResultLen < 2); if (eEncoding == encoding_utf_8) { (void)tUcs2Utf8(UNICODE_BULLET, szResult, tMaxResultLen); } else { szResult[0] = (char)ucGetBulletCharacter(eConversionType, eEncoding); szResult[1] = '\0'; } } /* end of vGetBulletValue */ /* * bAllZero - are all bytes zero? */ BOOL bAllZero(const UCHAR *aucBytes, size_t tLength) { size_t tIndex; if (aucBytes == NULL || tLength == 0) { return TRUE; } for (tIndex = 0; tIndex < tLength; tIndex++) { if (aucBytes[tIndex] != 0) { return FALSE; } } return TRUE; } /* end of bAllZero */ #if !defined(__riscos) /* * GetCodesetFromLocale - get the codeset from the current locale * * Original version: Copyright (C) 1999 Bruno Haible * Syntax: * language[_territory][.codeset][@modifier][+special][,[sponsor][_revision]] * * Returns TRUE when sucessful, otherwise FALSE */ static BOOL bGetCodesetFromLocale(char *szCodeset, size_t tMaxCodesetLength, BOOL *pbEuro) { #if !defined(__dos) const char *szLocale; const char *pcTmp; size_t tIndex; char szModifier[6]; #endif /* __dos */ if (pbEuro != NULL) { *pbEuro = FALSE; /* Until proven otherwise */ } if (szCodeset == NULL || tMaxCodesetLength == 0) { return FALSE; } #if defined(__dos) if (tMaxCodesetLength < 2 + sizeof(int) * 3 + 1) { DBG_DEC(tMaxCodesetLength); DBG_DEC(2 + sizeof(int) * 3 + 1); return FALSE; } /* Get the active codepage from DOS */ sprintf(szCodeset, "cp%d", iGetCodepage()); DBG_MSG(szCodeset); #else /* Get the locale from the environment */ szLocale = getenv("LC_ALL"); if (szLocale == NULL || szLocale[0] == '\0') { szLocale = getenv("LC_CTYPE"); if (szLocale == NULL || szLocale[0] == '\0') { szLocale = getenv("LANG"); } } if (szLocale == NULL || szLocale[0] == '\0') { /* No locale, so no codeset name and no modifier */ return FALSE; } DBG_MSG(szLocale); pcTmp = strchr(szLocale, '.'); if (pcTmp == NULL) { /* No codeset name */ szCodeset[0] = '\0'; } else { /* Copy the codeset name */ pcTmp++; for (tIndex = 0; tIndex < tMaxCodesetLength; tIndex++) { if (*pcTmp == '@' || *pcTmp == '+' || *pcTmp == ',' || *pcTmp == '_' || *pcTmp == '\0') { szCodeset[tIndex] = '\0'; break; } szCodeset[tIndex] = *pcTmp; pcTmp++; } szCodeset[tMaxCodesetLength - 1] = '\0'; } if (pbEuro == NULL) { /* No need to get the modifier */ return TRUE; } pcTmp = strchr(szLocale, '@'); if (pcTmp != NULL) { /* Copy the modifier */ pcTmp++; for (tIndex = 0; tIndex < sizeof(szModifier); tIndex++) { if (*pcTmp == '+' || *pcTmp == ',' || *pcTmp == '_' || *pcTmp == '\0') { szModifier[tIndex] = '\0'; break; } szModifier[tIndex] = *pcTmp; pcTmp++; } szModifier[sizeof(szModifier) - 1] = '\0'; *pbEuro = STRCEQ(szModifier, "Euro"); } #endif /* __dos */ return TRUE; } /* end of bGetCodesetFromLocale */ /* * GetNormalizedCodeset - get the normalized codeset from the current locale * * Returns TRUE when sucessful, otherwise FALSE */ BOOL bGetNormalizedCodeset(char *szCodeset, size_t tMaxCodesetLength, BOOL *pbEuro) { BOOL bOnlyDigits; const char *pcSrc; char *pcDest; char *szTmp, *szCodesetNorm; if (pbEuro != NULL) { *pbEuro = FALSE; /* Until proven otherwise */ } if (szCodeset == NULL || tMaxCodesetLength < 4) { return FALSE; } /* Get the codeset name */ szTmp = xmalloc(tMaxCodesetLength - 3); if (!bGetCodesetFromLocale(szTmp, tMaxCodesetLength - 3, pbEuro)) { szTmp = xfree(szTmp); return FALSE; } /* Normalize the codeset name */ szCodesetNorm = xmalloc(tMaxCodesetLength - 3); bOnlyDigits = TRUE; pcDest = szCodesetNorm; for (pcSrc = szTmp; *pcSrc != '\0'; pcSrc++) { if (isalnum(*pcSrc)) { *pcDest = tolower(*pcSrc); if (!isdigit(*pcDest)) { bOnlyDigits = FALSE; } pcDest++; } } *pcDest = '\0'; DBG_MSG(szCodesetNorm); /* Add "iso" when szCodesetNorm contains all digits */ if (bOnlyDigits && szCodesetNorm[0] != '\0') { fail(strlen(szCodesetNorm) + 3 >= tMaxCodesetLength); sprintf(szCodeset, "iso%s", szCodesetNorm); } else { fail(strlen(szCodesetNorm) >= tMaxCodesetLength); strncpy(szCodeset, szCodesetNorm, pcDest - szCodesetNorm + 1); szCodeset[tMaxCodesetLength - 1] = '\0'; } DBG_MSG(szCodeset); /* Clean up and leave */ szCodesetNorm = xfree(szCodesetNorm); szTmp = xfree(szTmp); return TRUE; } /* end of bGetNormalizedCodeset */ /* * szGetDefaultMappingFile - get the default mapping file * * Returns the basename of the default mapping file */ const char * szGetDefaultMappingFile(void) { static const struct { const char *szCodeset; const char *szMappingFile; } atMappingFile[] = { { "iso88591", MAPPING_FILE_8859_1 }, { "iso88592", MAPPING_FILE_8859_2 }, { "iso88593", "8859-3.txt" }, { "iso88594", "8859-4.txt" }, { "iso88595", "8859-5.txt" }, { "iso88596", MAPPING_FILE_8859_5 }, { "iso88597", "8859-7.txt" }, { "iso88598", "8859-8.txt" }, { "iso88599", "8859-9.txt" }, { "iso885910", "8859-10.txt" }, { "iso885913", "8859-13.txt" }, { "iso885914", "8859-14.txt" }, { "iso885915", MAPPING_FILE_8859_15 }, { "iso885916", "8859-16.txt" }, { "koi8r", MAPPING_FILE_KOI8_R }, { "koi8u", MAPPING_FILE_KOI8_U }, { "utf8", MAPPING_FILE_UTF_8 }, { "cp437", MAPPING_FILE_CP437 }, { "cp850", "cp850.txt" }, { "cp852", MAPPING_FILE_CP852 }, { "cp862", "cp862.txt" }, { "cp864", "cp864.txt" }, { "cp866", MAPPING_FILE_CP866 }, { "cp1250", MAPPING_FILE_CP1250 }, { "cp1251", MAPPING_FILE_CP1251 }, { "cp1252", "cp1252.txt" }, }; size_t tIndex; BOOL bEuro; char szCodeset[20]; szCodeset[0] = '\0'; bEuro = FALSE; /* Get the normalized codeset name */ if (!bGetNormalizedCodeset(szCodeset, sizeof(szCodeset), &bEuro)) { return MAPPING_FILE_8859_1; } if (szCodeset[0] == '\0') { if (bEuro) { /* Default mapping file (with Euro sign) */ return MAPPING_FILE_8859_15; } else { /* Default mapping file (without Euro sign) */ return MAPPING_FILE_8859_1; } } /* Find the name in the table */ for (tIndex = 0; tIndex < elementsof(atMappingFile); tIndex++) { if (STREQ(atMappingFile[tIndex].szCodeset, szCodeset)) { return atMappingFile[tIndex].szMappingFile; } } /* Default default mapping file */ #if defined(__dos) return MAPPING_FILE_CP437; #else return MAPPING_FILE_8859_1; #endif /* __dos */ } /* end of szGetDefaultMappingFile */ #endif /* !__riscos */ /* * tConvertDTTM - convert Windows Date and Time format * * returns Unix time_t or -1 */ time_t tConvertDTTM(ULONG ulDTTM) { struct tm tTime; time_t tResult; if (ulDTTM == 0) { return (time_t)-1; } memset(&tTime, 0, sizeof(tTime)); tTime.tm_min = (int)(ulDTTM & 0x0000003f); tTime.tm_hour = (int)((ulDTTM & 0x000007c0) >> 6); tTime.tm_mday = (int)((ulDTTM & 0x0000f800) >> 11); tTime.tm_mon = (int)((ulDTTM & 0x000f0000) >> 16); tTime.tm_year = (int)((ulDTTM & 0x1ff00000) >> 20); tTime.tm_isdst = -1; tTime.tm_mon--; /* From 01-12 to 00-11 */ tResult = mktime(&tTime); NO_DBG_MSG(ctime(&tResult)); return tResult; } /* end of tConvertDTTM */