Bool CPClipboard_Serialize(const CPClipboard *clip, // IN DynBuf *buf) // OUT: the output buffer { DND_CPFORMAT fmt; uint32 maxFmt = CPFORMAT_MAX; ASSERT(clip); ASSERT(buf); /* First append number of formats in clip. */ if (!DynBuf_Append(buf, &maxFmt, sizeof maxFmt)) { return FALSE; } /* Append format data one by one. */ for (fmt = CPFORMAT_MIN; fmt < CPFORMAT_MAX; ++fmt) { CPClipItem *item = (CPClipItem *)&(clip->items[CPFormatToIndex(fmt)]); if (!DynBuf_Append(buf, &item->exists, sizeof item->exists) || !DynBuf_Append(buf, &item->size, sizeof item->size)) { return FALSE; } if (item->exists && (item->size > 0) && !DynBuf_Append(buf, item->buf, item->size)) { return FALSE; } } if (!DynBuf_Append(buf, &clip->changed, sizeof clip->changed)) { return FALSE; } return TRUE; }
static void HostInfoGetCpuidStrSection(const uint32 args[], // IN: input eax arguments const size_t args_size, // IN: size of the argument array DynBuf *buf) // IN/OUT: result string in DynBuf { static const char format[] = "%08X:%08X%08X%08X%08X-"; CPUIDRegs reg; uint32 max_arg; char temp[64]; int i; __GET_CPUID(args[0], ®); max_arg = reg.eax; if (max_arg < args[0]) { Warning(LGPFX" No CPUID information available. Based = %08X.\n", args[0]); return; } DynBuf_Append(buf, temp, Str_Sprintf(temp, sizeof temp, format, args[0], reg.eax, reg.ebx, reg.ecx, reg.edx)); for (i = 1; i < args_size && args[i] <= max_arg; i++) { ASSERT(args[i] > args[i - 1]); // Ascending order. __GET_CPUID(args[i], ®); DynBuf_Append(buf, temp, Str_Sprintf(temp, sizeof temp, format, args[i], reg.eax, reg.ebx, reg.ecx, reg.edx)); } }
static char * ExtractCommandLineFromAddressSpaceFile(psinfo_t *procInfo) //IN: psinfo struct { int argc; int i; char tempPath[MAXPATHLEN]; char *buf; FileIODescriptor asFd; FileIOResult res; DynBuf cmdLine; DynBufArray args; pid_t pid; FileIO_Invalidate(&asFd); pid = procInfo->pr_pid; if (Str_Snprintf(tempPath, sizeof tempPath, "/proc/%"FMT64"d/as", (int64_t)pid) == -1) { /* This should not happen. MAXPATHLEN should be large enough. */ ASSERT(FALSE); } res = FileIO_Open(&asFd, tempPath, FILEIO_OPEN_ACCESS_READ, FILEIO_OPEN); if (res != FILEIO_SUCCESS) { Warning("Could not open address space file for pid %"FMT64"d, %s\n", (int64_t)pid, FileIO_MsgError(res)); return NULL; } buf = NULL; if (ReadArgsFromAddressSpaceFile(asFd, procInfo, &args)) { /* Concatenate the strings in args into cmdLine. */ DynBuf_Init(&cmdLine); argc = DynBufArray_Count(&args); for (i = 0; i < argc; i++) { buf = DynBuf_Get(DynBufArray_AddressOf(&args, i)); DynBuf_Append(&cmdLine, buf, strlen(buf)); if (i + 1 < argc) { DynBuf_Append(&cmdLine, " ", 1); } DynBuf_Destroy(DynBufArray_AddressOf(&args, i)); } DynBuf_AppendString(&cmdLine,""); DynBufArray_Destroy(&args); DynBuf_Trim(&cmdLine); buf = DynBuf_Detach(&cmdLine); DynBuf_Destroy(&cmdLine); } FileIO_Close(&asFd); return buf; }
VixError VixToolsEnvironToEnvBlock(char const * const *environ, // IN: UTF-8 wchar_t **envBlock) // OUT { VixError err; DynBuf buf; Bool res; static const wchar_t nullTerm[] = { L'\0', L'\0' }; DynBuf_Init(&buf); if ((NULL == environ) || (NULL == envBlock)) { err = VIX_E_FAIL; goto abort; } *envBlock = NULL; while (NULL != *environ) { wchar_t *envVar = Unicode_GetAllocUTF16(*environ); res = DynBuf_Append(&buf, envVar, (wcslen(envVar) + 1) * sizeof(*envVar)); free(envVar); if (!res) { err = VIX_E_OUT_OF_MEMORY; goto abort; } environ++; } /* * Append two null characters at the end. This adds an extra (third) null * if there was at least one environment variable (since there already * is one after the last string) but we need both if there were no * environment variables in the input array. I'll waste two bytes to * keep the code a little simpler. */ res = DynBuf_Append(&buf, nullTerm, sizeof nullTerm); if (!res) { err = VIX_E_OUT_OF_MEMORY; goto abort; } *envBlock = DynBuf_Detach(&buf); err = VIX_OK; abort: DynBuf_Destroy(&buf); return err; }
static char * SyncDriverListMounts(void) { char *paths = NULL; DynBuf buf; MNTHANDLE mounts; DECLARE_MNTINFO(mntinfo); if ((mounts = OPEN_MNTFILE("r")) == NULL) { return NULL; } DynBuf_Init(&buf); while (GETNEXT_MNTINFO(mounts, mntinfo)) { /* * Skip remote mounts because they are not freezable and opening them * could lead to hangs. See PR 1196785. */ if (SyncDriverIsRemoteFSType(MNTINFO_FSTYPE(mntinfo))) { Debug(LGPFX "Skipping remote filesystem, name=%s, mntpt=%s.\n", MNTINFO_NAME(mntinfo), MNTINFO_MNTPT(mntinfo)); continue; } /* * Add a separator if it's not the first path, and add the path to the * tail of the list. */ if ((DynBuf_GetSize(&buf) != 0 && !DynBuf_Append(&buf, ":", 1)) || !DynBuf_Append(&buf, MNTINFO_MNTPT(mntinfo), strlen(MNTINFO_MNTPT(mntinfo)))) { goto exit; } } if (!DynBuf_Append(&buf, "\0", 1)) { goto exit; } paths = DynBuf_AllocGet(&buf); if (paths == NULL) { Debug(LGPFX "Failed to allocate path list.\n"); } exit: DynBuf_Destroy(&buf); (void) CLOSE_MNTFILE(mounts); return paths; }
Bool DynXdr_AppendRaw(XDR *xdrs, // IN const void *buf, // IN size_t len) // IN { DynBuf *intbuf = &((DynXdrData *) xdrs->x_private)->data; return DynBuf_Append(intbuf, buf, len); }
static bool_t DynXdrPutInt32(XDR *xdrs, // IN/OUT DYNXDR_CONST int32_t *ip) // IN { int32_t out = htonl(*ip); DynXdrData *priv = (DynXdrData *) xdrs->x_private; return DynBuf_Append(&priv->data, &out, sizeof out); }
static bool_t DynXdrPutBytes(XDR *xdrs, // IN/OUT DYNXDR_CONST char *data, // IN DYNXDR_SIZE_T len) // IN { DynXdrData *priv = (DynXdrData *) xdrs->x_private; return DynBuf_Append(&priv->data, data, len); }
static char * SyncDriverListMounts(void) { char *paths = NULL; DynBuf buf; MNTHANDLE mounts; DECLARE_MNTINFO(mntinfo); if ((mounts = OPEN_MNTFILE("r")) == NULL) { return NULL; } DynBuf_Init(&buf); while (GETNEXT_MNTINFO(mounts, mntinfo)) { /* * Add a separator if it's not the first path, and add the path to the * tail of the list. */ if ((DynBuf_GetSize(&buf) != 0 && !DynBuf_Append(&buf, ":", 1)) || !DynBuf_Append(&buf, MNTINFO_MNTPT(mntinfo), strlen(MNTINFO_MNTPT(mntinfo)))) { goto exit; } } if (!DynBuf_Append(&buf, "\0", 1)) { goto exit; } paths = DynBuf_AllocGet(&buf); if (paths == NULL) { Debug(LGPFX "Failed to allocate path list.\n"); } exit: DynBuf_Destroy(&buf); (void) CLOSE_MNTFILE(mounts); return paths; }
void DynBuf_SafeInternalAppend(DynBuf *b, // IN/OUT: void const *data, // IN: size_t size, // IN: char const *file, // IN: unsigned int lineno) // IN: { if (!DynBuf_Append(b, data, size)) { Panic("Unrecoverable memory allocation failure at %s:%u\n", file, lineno); } }
static bool_t DynXdrPutLong(XDR *xdrs, // IN/OUT DYNXDR_CONST DYNXDR_LONG *lp) // IN { int32 out; DynXdrData *priv = (DynXdrData *) xdrs->x_private; #ifdef __APPLE__ ASSERT_ON_COMPILE(sizeof *lp <= sizeof (int32)); #endif out = htonl((int32)*lp); return DynBuf_Append(&priv->data, &out, sizeof out); }
void * Escape_Sh(void const *bufIn, // IN size_t sizeIn, // IN size_t *sizeOut) // OUT { static const char be[] = { '\'', }; static const char escSeq[] = { '\'', '"', '\'', '"', }; char const *buf; DynBuf b; size_t startUnescaped; size_t index; buf = (char const *)bufIn; ASSERT(buf); DynBuf_Init(&b); if (DynBuf_Append(&b, be, sizeof(be)) == FALSE) { goto nem; } startUnescaped = 0; for (index = 0; index < sizeIn; index++) { if (buf[index] == '\'') { /* We must escape that byte --hpreg */ if ( DynBuf_Append(&b, &buf[startUnescaped], index - startUnescaped) == FALSE || DynBuf_Append(&b, escSeq, sizeof(escSeq)) == FALSE) { goto nem; } startUnescaped = index; } } if ( /* Last unescaped chunk (if any) --hpreg */ DynBuf_Append(&b, &buf[startUnescaped], index - startUnescaped) == FALSE || DynBuf_Append(&b, be, sizeof(be)) == FALSE /* NUL terminator --hpreg */ || DynBuf_Append(&b, "", 1) == FALSE || DynBuf_Trim(&b) == FALSE) { goto nem; } if (sizeOut) { *sizeOut = DynBuf_GetSize(&b) - 1; } return DynBuf_Get(&b); nem: DynBuf_Destroy(&b); return NULL; }
Bool DnD_CPNameListToDynBufArray(char *fileList, // IN: CPName format size_t listSize, // IN DynBufArray *dynBufArray) // OUT { DynBuf buf; BufRead r; int32 pathLen; size_t count; size_t i; ASSERT(fileList); r.pos = fileList; r.unreadLen = listSize; DynBufArray_Init(dynBufArray, 0); while (r.unreadLen > 0) { DynBuf_Init(&buf); if (!DnDReadBuffer(&r, &pathLen, sizeof pathLen) || (pathLen > r.unreadLen) || !DynBuf_Append(&buf, r.pos, pathLen)) { goto error; } if (!DnDSlideBuffer(&r, pathLen)) { goto error; } if (!DynBufArray_Push(dynBufArray, buf)) { goto error; } } return TRUE; error: DynBuf_Destroy(&buf); count = DynBufArray_Count(dynBufArray); for (i = 0; i < count; i++) { DynBuf *b = DynArray_AddressOf(dynBufArray, i); DynBuf_Destroy(b); } DynBufArray_SetCount(dynBufArray, 0); DynBufArray_Destroy(dynBufArray); return FALSE; }
static void GuestInfoEncodeStats(GuestInfoCollector *current, // IN: current collection GuestInfoCollector *previous, // IN: previous collection DynBuf *statBuf) // IN/OUT: stats data { uint32 i; GuestMemInfo legacy; Bool emitNameSpace = TRUE; /* Provide legacy data for backwards compatibility */ GuestInfoLegacy(current, &legacy); DynBuf_Append(statBuf, &legacy, sizeof legacy); /* Provide data in the new, extensible format. */ for (i = 0; i < current->numStats; i++) { GuestInfoStat *stat = ¤t->stats[i]; if (!stat->query->publish) { continue; } if (GuestInfoIsRate(stat->query->units)) { ASSERT(stat->query->dataType == GuestTypeDouble); GuestInfoAppendRate(emitNameSpace, stat->query->reportID, current, previous, statBuf); } else { ASSERT(stat->query->dataType == GuestTypeUint64); GuestInfoAppendStat(stat->err, emitNameSpace, stat->query->reportID, stat->query->units, stat->query->dataType, &stat->value, GuestInfoBytesNeededUIntDatum(stat->value), statBuf); } emitNameSpace = FALSE; // use the smallest representation } GuestInfoAppendMemNeeded(current, emitNameSpace, statBuf); }
static Bool CodeSetDynBufFinalize(Bool ok, // IN: Earlier steps succeeded DynBuf *db, // IN: Buffer with converted string char **bufOut, // OUT: Converted string size_t *sizeOut) // OUT: Length of string in bytes { /* * NUL can be as long as 4 bytes if UTF-32, make no assumptions. */ if (!ok || !DynBuf_Append(db, "\0\0\0\0", 4) || !DynBuf_Trim(db)) { DynBuf_Destroy(db); return FALSE; } *bufOut = DynBuf_Get(db); if (sizeOut) { *sizeOut = DynBuf_GetSize(db) - 4; } return TRUE; }
static int SNEForEachCallback(const char *key, // IN: environment variable void *value, // IN: environment value void *clientData) // IN/OUT: DynBuf container (SNEBufs) { DynBuf *nativeEnvironStrings = ((SNEBufs *)clientData)->nativeEnvironStrings; DynBuf *nativeEnvironOffsets = ((SNEBufs *)clientData)->nativeEnvironOffsets; size_t itemSize; char *itemBuf; off_t itemOffset; /* * A NULL value indicates that this variable is not to be set. */ if (value == NULL) { return 0; } /* Determine the length of the new string inc. '=' delimiter and NUL. */ itemSize = strlen(key) + strlen(value) + sizeof "="; itemBuf = Util_SafeMalloc(itemSize); /* Create new "key=value" string. */ snprintf(itemBuf, itemSize, "%s=%s", key, (char *)value); ASSERT_MEM_ALLOC(DynBuf_AppendString(nativeEnvironStrings, itemBuf)); /* * Get the relative offset of our newly added string (relative to the DynBuf's base * address), and then append that to nativeEnvironOffsets. */ itemOffset = DynBuf_GetSize(nativeEnvironStrings) - itemSize; ASSERT_MEM_ALLOC(DynBuf_Append(nativeEnvironOffsets, &itemOffset, sizeof itemOffset)); free(itemBuf); return 0; }
static void GuestInfoAppendStat(int errnoValue, // IN: Bool emitNameSpace, // IN: GuestStatToolsID reportID, // IN: GuestValueUnits units, // IN: GuestValueType valueType, // IN: void *value, // IN: size_t valueSize, // IN: DynBuf *stats) // IN/OUT: { const char *NameSpace = GUEST_TOOLS_NAMESPACE; uint64 value64; GuestStatHeader header; GuestDatumHeader datum; header.datumFlags = GUEST_DATUM_ID | GUEST_DATUM_VALUE_TYPE_ENUM | GUEST_DATUM_VALUE_UNIT_ENUM; if (emitNameSpace) { header.datumFlags |= GUEST_DATUM_NAMESPACE; } if (errnoValue == 0) { header.datumFlags |= GUEST_DATUM_VALUE; } DynBuf_Append(stats, &header, sizeof header); if (header.datumFlags & GUEST_DATUM_NAMESPACE) { size_t nameSpaceLen = strlen(NameSpace) + 1; datum.dataSize = nameSpaceLen; DynBuf_Append(stats, &datum, sizeof datum); DynBuf_Append(stats, NameSpace, nameSpaceLen); } if (header.datumFlags & GUEST_DATUM_ID) { value64 = reportID; datum.dataSize = GuestInfoBytesNeededUIntDatum(value64); DynBuf_Append(stats, &datum, sizeof datum); DynBuf_Append(stats, &value64, datum.dataSize); } if (header.datumFlags & GUEST_DATUM_VALUE_TYPE_ENUM) { value64 = valueType; datum.dataSize = GuestInfoBytesNeededUIntDatum(value64); DynBuf_Append(stats, &datum, sizeof datum); DynBuf_Append(stats, &value64, datum.dataSize); } if (header.datumFlags & GUEST_DATUM_VALUE_UNIT_ENUM) { value64 = units; datum.dataSize = GuestInfoBytesNeededUIntDatum(value64); DynBuf_Append(stats, &datum, sizeof datum); DynBuf_Append(stats, &value64, datum.dataSize); } if (header.datumFlags & GUEST_DATUM_VALUE) { datum.dataSize = valueSize; DynBuf_Append(stats, &datum, sizeof datum); DynBuf_Append(stats, value, valueSize); } }
Bool DictLL_MarshalLine(DynBuf *output, // IN/OUT: output buffer char const *name, // IN/OPT: name to marshal char const *value) // IN: value to marshal { size_t size; if (name) { /* * Double quote, pipe, 0x7F, and all control characters but * tab --hpreg * 0x80 to 0xff are unescaped so characters in encodings * like UTF-8 will be displayed normally. */ static int const toEscape[] = { 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, }; char *evalue; /* Write a well-formed line --hpreg */ evalue = Escape_Do('|', toEscape, value, (uint32)strlen(value), &size); if ( !DynBuf_Append(output, name, (uint32)strlen(name)) || !DynBuf_Append(output, " = \"", 4) || (size && !DynBuf_Append(output, evalue, size)) || !DynBuf_Append(output, "\"", 1)) { free(evalue); return FALSE; } free(evalue); } else { /* Write the line as passed from the upper layers --hpreg */ size = (uint32)strlen(value); if (size && !DynBuf_Append(output, value, size)) { return FALSE; } } /* * Win32 takes care of adding the \r (XXX this assumes that the stream * is opened in ascii mode) --hpreg */ if (!DynBuf_Append(output, "\n", 1)) { return FALSE; } return TRUE; }
void * Escape_Undo(char escByte, // IN void const *bufIn, // IN size_t sizeIn, // IN size_t *sizeOut) // OUT { char const *buf; DynBuf b; unsigned int state; size_t startUnescaped; size_t index; int h = 0; /* Compiler warning --hpreg */ int l; buf = (char const *)bufIn; ASSERT(buf); DynBuf_Init(&b); startUnescaped = 0; state = 0; for (index = 0; index < sizeIn; index++) { /* Unsigned does matter --hpreg */ unsigned char ubyte; ubyte = buf[index]; switch (state) { case 0: /* Found <byte> --hpreg */ if (ubyte == escByte) { state = 1; } break; case 1: /* Found <escByte><byte> --hpreg */ h = Hex2Dec[ubyte]; state = h >= 0 ? 2 : 0; break; case 2: /* Found <escByte><hexa digit><byte> --hpreg */ l = Hex2Dec[ubyte]; if (l >= 0) { char escaped; escaped = h << 4 | l; if ( DynBuf_Append(&b, &buf[startUnescaped], index - 2 - startUnescaped) == FALSE || DynBuf_Append(&b, &escaped, 1) == FALSE) { goto nem; } startUnescaped = index + 1; } state = 0; break; default: NOT_IMPLEMENTED(); break; } } if ( /* Last unescaped chunk (if any) --hpreg */ DynBuf_Append(&b, &buf[startUnescaped], index - startUnescaped) == FALSE /* NUL terminator --hpreg */ || DynBuf_Append(&b, "", 1) == FALSE || DynBuf_Trim(&b) == FALSE) { goto nem; } if (sizeOut) { *sizeOut = DynBuf_GetSize(&b) - 1; } return DynBuf_Get(&b); nem: DynBuf_Destroy(&b); return NULL; }
Bool CodeSet_Init(const char *icuDataDir) // IN: ICU data file location in Current code page. // Default is used if NULL. { DynBuf dbpath; #ifdef _WIN32 DWORD attribs; utf16_t *modPath = NULL; utf16_t *lastSlash; utf16_t *wpath; HANDLE hFile = INVALID_HANDLE_VALUE; HANDLE hMapping = NULL; void *memMappedData = NULL; #else struct stat finfo; #endif char *path = NULL; Bool ret = FALSE; DynBuf_Init(&dbpath); #ifdef USE_ICU /* * We're using system ICU, which finds its own data. So nothing to * do here. */ dontUseIcu = FALSE; ret = TRUE; goto exit; #endif /* * ********************* WARNING * Must avoid recursive calls into the codeset library here, hence * the idiotic hoop-jumping. DO NOT change any of these calls to * wrapper equivalents or call any other functions that may perform * string conversion. * ********************* WARNING */ #ifdef _WIN32 // { #if vmx86_devel /* * Devel builds use toolchain directory first. */ { WCHAR icuFilePath[MAX_PATH] = { 0 }; DWORD n = ExpandEnvironmentStringsW(ICU_DATA_FILE_PATH, icuFilePath, ARRAYSIZE(icuFilePath)); if (n > 0 && n < ARRAYSIZE(icuFilePath)) { attribs = GetFileAttributesW(icuFilePath); if ((INVALID_FILE_ATTRIBUTES != attribs) || (attribs & FILE_ATTRIBUTE_DIRECTORY) == 0) { if (!CodeSetOld_Utf16leToCurrent((const char *) icuFilePath, n * sizeof *icuFilePath, &path, NULL)) { goto exit; } goto found; } } } #endif if (icuDataDir) { /* * Data file must be in the specified directory. */ size_t length = strlen(icuDataDir); if (!DynBuf_Append(&dbpath, icuDataDir, length)) { goto exit; } if (length && icuDataDir[length - 1] != DIRSEPC) { if (!DynBuf_Append(&dbpath, DIRSEPS, strlen(DIRSEPS))) { goto exit; } } if (!DynBuf_Append(&dbpath, ICU_DATA_FILE, strlen(ICU_DATA_FILE)) || !DynBuf_Append(&dbpath, "\0", 1)) { goto exit; } /* * Check for file existence. */ attribs = GetFileAttributesA(DynBuf_Get(&dbpath)); if ((INVALID_FILE_ATTRIBUTES == attribs) || (attribs & FILE_ATTRIBUTE_DIRECTORY)) { goto exit; } path = (char *) DynBuf_Detach(&dbpath); } else { /* * Data file must be in the directory of the current module * (i.e. the module that contains CodeSet_Init()). */ HMODULE hModule = W32Util_GetModuleByAddress((void *) CodeSet_Init); if (!hModule) { goto exit; } modPath = CodeSetGetModulePath(hModule); if (!modPath) { goto exit; } lastSlash = wcsrchr(modPath, DIRSEPC_W); if (!lastSlash) { goto exit; } *lastSlash = L'\0'; if (!DynBuf_Append(&dbpath, modPath, wcslen(modPath) * sizeof(utf16_t)) || !DynBuf_Append(&dbpath, DIRSEPS_W, wcslen(DIRSEPS_W) * sizeof(utf16_t)) || !DynBuf_Append(&dbpath, ICU_DATA_FILE_W, wcslen(ICU_DATA_FILE_W) * sizeof(utf16_t)) || !DynBuf_Append(&dbpath, L"\0", 2)) { goto exit; } /* * Since u_setDataDirectory can't handle UTF-16, we would have to * now convert this path to local encoding. But that fails when * the module is in a path containing characters not in the * local encoding (see 282524). So we'll memory-map the file * instead and call udata_setCommonData() below. */ wpath = (utf16_t *) DynBuf_Get(&dbpath); hFile = CreateFileW(wpath, GENERIC_READ, 0, NULL, OPEN_EXISTING, 0, NULL); if (INVALID_HANDLE_VALUE == hFile) { goto exit; } hMapping = CreateFileMapping(hFile, NULL, PAGE_READONLY, 0, 0, NULL); if (NULL == hMapping) { goto exit; } memMappedData = MapViewOfFile(hMapping, FILE_MAP_READ, 0, 0, 0); if (NULL == memMappedData) { goto exit; } } #else // } _WIN32 { #if vmx86_devel { char *modPath; char *lastSlash; /* * Devel builds use toolchain directory first. */ if (stat(ICU_DATA_FILE_PATH, &finfo) >= 0 && !S_ISDIR(finfo.st_mode)) { if ((path = strdup(ICU_DATA_FILE_PATH)) == NULL) { goto exit; } goto found; } /* * Then we try module directory, if we can get it. */ modPath = CodeSetGetModulePath(HGMP_PRIVILEGE); if (modPath) { lastSlash = strrchr(modPath, DIRSEPC); if (lastSlash) { *lastSlash = '\0'; if (DynBuf_Append(&dbpath, modPath, strlen(modPath)) && DynBuf_Append(&dbpath, DIRSEPS, strlen(DIRSEPS)) && DynBuf_Append(&dbpath, ICU_DATA_FILE, strlen(ICU_DATA_FILE)) && DynBuf_Append(&dbpath, "\0", 1)) { if ((stat((const char *) DynBuf_Get(&dbpath), &finfo) >= 0) && !S_ISDIR(finfo.st_mode)) { free(modPath); path = DynBuf_Detach(&dbpath); goto found; } else { DynBuf_SetSize(&dbpath, 0); } } } free(modPath); } } #endif // vmx86_devel /* * Data file is either in POSIX_ICU_DIR or user specified dir. */ if (!icuDataDir) { icuDataDir = POSIX_ICU_DIR; } if (!DynBuf_Append(&dbpath, icuDataDir, strlen(icuDataDir)) || !DynBuf_Append(&dbpath, DIRSEPS, strlen(DIRSEPS)) || !DynBuf_Append(&dbpath, ICU_DATA_FILE, strlen(ICU_DATA_FILE)) || !DynBuf_Append(&dbpath, "\0", 1)) { goto exit; } /* * Check for file existence. (DO NOT CHANGE TO 'stat' WRAPPER). */ path = (char *) DynBuf_Detach(&dbpath); if (stat(path, &finfo) < 0 || S_ISDIR(finfo.st_mode)) { goto exit; } #endif // } _WIN32 #if vmx86_devel found: #endif #ifdef _WIN32 if (memMappedData) { /* * Tell ICU to use this mapped data. */ UErrorCode uerr = U_ZERO_ERROR; ASSERT(memMappedData); udata_setCommonData(memMappedData, &uerr); if (uerr != U_ZERO_ERROR) { UnmapViewOfFile(memMappedData); goto exit; } } else { #endif /* * Tell ICU to use this directory. */ u_setDataDirectory(path); #ifdef _WIN32 } #endif dontUseIcu = FALSE; ret = TRUE; exit: if (!ret) { /* * There was an error initing ICU, but if we can fall back on * non-ICU (old CodeSet) then things are OK. */ if (CODESET_CAN_FALLBACK_ON_NON_ICU) { ret = TRUE; dontUseIcu = TRUE; #ifdef _WIN32 OutputDebugStringW(L"CodeSet_Init: no ICU\n"); #endif } } #ifdef _WIN32 free(modPath); if (hMapping) { CloseHandle(hMapping); } if (hFile != INVALID_HANDLE_VALUE) { CloseHandle(hFile); } #endif free(path); DynBuf_Destroy(&dbpath); return ret; }
StdIO_Status StdIO_ReadNextLine(FILE *stream, // IN: char **buf, // OUT: size_t maxBufLength, // IN: size_t *count) // OUT: { DynBuf b; ASSERT(stream); ASSERT(buf); DynBuf_Init(&b); for (;;) { char *data; size_t size; size_t max; size_t nr; /* * The dynamic buffer must be at least 2 bytes large, so that at least * 1 stream byte and fgets()'s NUL byte can fit --hpreg */ if (DynBuf_Enlarge(&b, 2) == FALSE) { errno = ENOMEM; goto error; } /* Read the next chunk of line directly in the dynamic buffer --hpreg */ data = DynBuf_Get(&b); size = DynBuf_GetSize(&b); if (maxBufLength != 0 && size > maxBufLength) { errno = E2BIG; goto error; } max = DynBuf_GetAllocatedSize(&b); nr = max - size; if (SuperFgets(stream, &nr, data + size) == NULL) { goto error; } size += nr; DynBuf_SetSize(&b, size); if (size < max) { /* SuperFgets() found end-of-line */ if (size == 0 && feof(stream)) { /* Reached end-of-file before reading anything */ DynBuf_Destroy(&b); return StdIO_EOF; } break; } /* * No line terminator found yet, we need a larger buffer to do the next * SuperFgets() --hpreg */ } /* There is a line in the buffer --hpreg */ /* NUL terminator --hpreg */ if (DynBuf_Append(&b, "", 1) == FALSE) { errno = ENOMEM; goto error; } *buf = DynBuf_Get(&b); if (count) { *count = DynBuf_GetSize(&b) - 1; } return StdIO_Success; error: DynBuf_Destroy(&b); return StdIO_Error; }
void * Escape_AnsiToUnix(void const *bufIn, // IN size_t sizeIn, // IN size_t *sizeOut) // OUT { char const *buf; DynBuf b; unsigned int state; size_t startUnescaped; size_t index; buf = (char const *)bufIn; ASSERT(buf); DynBuf_Init(&b); startUnescaped = 0; state = 0; /* * Identify all chunks in buf (\r\n being the chunk separator), and copy * them into b --hpreg */ for (index = 0; index < sizeIn; index++) { char byte; byte = buf[index]; switch (state) { case 1: /* Found \r<byte> --hpreg */ state = 0; if (byte == '\n') { if (DynBuf_Append(&b, &buf[startUnescaped], index - 1 - startUnescaped) == FALSE) { goto nem; } startUnescaped = index; break; } /* Fall through --hpreg */ case 0: /* Found <byte> --hpreg */ if (byte == '\r') { state = 1; } break; default: NOT_IMPLEMENTED(); break; } } if ( /* Last unescaped chunk (if any) --hpreg */ DynBuf_Append(&b, &buf[startUnescaped], index - startUnescaped) == FALSE /* NUL terminator --hpreg */ || DynBuf_Append(&b, "", 1) == FALSE || DynBuf_Trim(&b) == FALSE) { goto nem; } if (sizeOut) { *sizeOut = DynBuf_GetSize(&b) - 1; } return DynBuf_Get(&b); nem: DynBuf_Destroy(&b); return NULL; }
static Bool ReadArgsFromAddressSpaceFile(FileIODescriptor asFd, //IN psinfo_t *psInfo, //IN DynBufArray *cmdLineArr) //OUT { uintptr_t *argOffs; uintptr_t argOff; uintptr_t nextArgOff; int argc; int i; char *argBuf; char *argBufPtr; DynBuf *arg; argc = psInfo->pr_argc; DynBufArray_Init(cmdLineArr, argc); for (i = 0; i < argc; i++) { DynBuf_Init(DynBufArray_AddressOf(cmdLineArr, i)); } if (argc == 0) { return TRUE; } argOffs = Util_SafeCalloc(argc, sizeof *argOffs); if (argOffs == NULL) { return FALSE; } if (!ReadOffsetsFromAddressSpaceFile(asFd, psInfo, argOffs)) { goto fail; } /* Read the command line arguments into the cmdLineArr array. */ nextArgOff = argc > 0 ? argOffs[0] : 0; i = 0; while (i < argc) { argOff = argOffs[i]; /* * The argument strings are contiguous in the address space file. So * argOff[i] + strlen(arg[i]) + 1 should be equal to argOff[i + 1]. */ if ((argOff == 0) || (argOff != nextArgOff)) { goto fail; } argBuf = ExtractArgStringFromAddressSpaceFile(asFd, argOff); if (argBuf == NULL) { goto fail; } nextArgOff = argOff + strlen(argBuf) + 1; argBufPtr = argBuf + strlen(argBuf); while ((argBufPtr > argBuf) && isspace(*(argBufPtr - 1))) { argBufPtr--; } *argBufPtr = '\0'; arg = DynBufArray_AddressOf(cmdLineArr, i); if (!DynBuf_Append(arg, argBuf, strlen(argBuf) + 1)) { free(argBuf); goto fail; } free(argBuf); i++; } return TRUE; fail: Warning("Failed to read command line arguments\n"); argc = DynBufArray_Count(cmdLineArr); for (i = 0; i < argc; i++) { arg = DynArray_AddressOf(cmdLineArr, i); DynBuf_Destroy(arg); } DynBufArray_SetCount(cmdLineArr, 0); DynBufArray_Destroy(cmdLineArr); free(argOffs); return FALSE; }
void * Escape_DoString(const char *escStr, // IN int const *bytesToEsc, // IN void const *bufIn, // IN size_t sizeIn, // IN size_t *sizeOut) // OUT { char const *buf; DynBuf b; size_t startUnescaped; size_t index; size_t escStrLen; ASSERT(escStr); escStrLen = strlen(escStr); ASSERT(escStrLen > 0); ASSERT(bytesToEsc); /* Unsigned does matter --hpreg */ ASSERT(bytesToEsc[(unsigned char)escStr[0]]); buf = (char const *)bufIn; ASSERT(buf); DynBuf_Init(&b); startUnescaped = 0; for (index = 0; index < sizeIn; index++) { /* Unsigned does matter --hpreg */ unsigned char ubyte; char escSeq[2]; ubyte = buf[index]; if (bytesToEsc[ubyte]) { /* We must escape that byte --hpreg */ escSeq[0] = Dec2Hex[ubyte >> 4]; escSeq[1] = Dec2Hex[ubyte & 0xF]; if ( DynBuf_Append(&b, &buf[startUnescaped], index - startUnescaped) == FALSE || DynBuf_Append(&b, escStr, escStrLen) == FALSE || DynBuf_Append(&b, escSeq, sizeof escSeq) == FALSE) { goto nem; } startUnescaped = index + 1; } } if ( /* Last unescaped chunk (if any) --hpreg */ DynBuf_Append(&b, &buf[startUnescaped], index - startUnescaped) == FALSE /* NUL terminator --hpreg */ || DynBuf_Append(&b, "", 1) == FALSE || DynBuf_Trim(&b) == FALSE) { goto nem; } if (sizeOut) { *sizeOut = DynBuf_GetSize(&b) - 1; } return DynBuf_Get(&b); nem: DynBuf_Destroy(&b); return NULL; }
static char * ExtractCommandLineFromAddressSpaceFile(psinfo_t *procInfo, //IN: psinfo struct char **procCmdName) //OUT: command name { int argc; int i; char tempPath[MAXPATHLEN]; char *buf; FileIODescriptor asFd; FileIOResult res; DynBuf cmdLine; DynBufArray args; pid_t pid; char *cmdNameBegin; if (NULL != procCmdName) { *procCmdName = NULL; } FileIO_Invalidate(&asFd); pid = procInfo->pr_pid; if (Str_Snprintf(tempPath, sizeof tempPath, "/proc/%"FMT64"d/as", (int64_t)pid) == -1) { /* This should not happen. MAXPATHLEN should be large enough. */ ASSERT(FALSE); } res = FileIO_Open(&asFd, tempPath, FILEIO_OPEN_ACCESS_READ, FILEIO_OPEN); if (res != FILEIO_SUCCESS) { Warning("Could not open address space file for pid %"FMT64"d, %s\n", (int64_t)pid, FileIO_MsgError(res)); return NULL; } buf = NULL; if (ReadArgsFromAddressSpaceFile(asFd, procInfo, &args)) { /* Concatenate the strings in args into cmdLine. */ DynBuf_Init(&cmdLine); argc = DynBufArray_Count(&args); for (i = 0; i < argc; i++) { buf = DynBuf_Get(DynBufArray_AddressOf(&args, i)); DynBuf_Append(&cmdLine, buf, strlen(buf)); if (i + 1 < argc) { DynBuf_Append(&cmdLine, " ", 1); } if (NULL != procCmdName && 0 == i) { /* * Store the command name of the process. * Find the last path separator, to get the cmd name. * If no separator is found, then use the whole name. */ cmdNameBegin = strrchr(buf, '/'); if (NULL == cmdNameBegin) { cmdNameBegin = buf; } else { /* * Skip over the last separator. */ cmdNameBegin++; } *procCmdName = Unicode_Alloc(cmdNameBegin, STRING_ENCODING_DEFAULT); } DynBuf_Destroy(DynBufArray_AddressOf(&args, i)); } DynBuf_AppendString(&cmdLine,""); DynBufArray_Destroy(&args); DynBuf_Trim(&cmdLine); buf = DynBuf_Detach(&cmdLine); DynBuf_Destroy(&cmdLine); } FileIO_Close(&asFd); return buf; }