예제 #1
0
파일: escape.c 프로젝트: raphaeldias/vmware
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;
}
예제 #2
0
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;
}
예제 #3
0
void
DynArray_QSort(DynArray *a,             // IN/OUT
               DynArrayCmp compare)     // IN
{
   uint8 *arrayBuf;

   ASSERT(a);
   ASSERT(compare);

   arrayBuf = DynBuf_Get(&a->buf);
   qsort(arrayBuf, DynArray_Count(a), a->width, compare);
}
예제 #4
0
void *
DynArray_AddressOf(const DynArray *a,   // IN
                   unsigned int i)      // IN
{
   uint8 *result = NULL;

   ASSERT(a);

   if (i < DynArray_Count(a)) {
      result = ((uint8 *)DynBuf_Get(&a->buf)) + (i * a->width);
   }
   return result;
}
예제 #5
0
Bool
DictLL_WriteLine(FILE *stream,      // IN: stream to write
                 char const *name,  // IN: name to write
                 char const *value) // IN: value to write
{
   DynBuf buf;

   DynBuf_Init(&buf);
   if (!DictLL_MarshalLine(&buf, name, value)) {
      DynBuf_Destroy(&buf);
      errno = ENOMEM;
      return FALSE;
   }
   if (fwrite(DynBuf_Get(&buf), DynBuf_GetSize(&buf), 1, stream) != 1) {
      DynBuf_Destroy(&buf);
      return FALSE;
   }
   DynBuf_Destroy(&buf);
   return TRUE;
}
예제 #6
0
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;
}
예제 #7
0
char *
Hostinfo_GetCpuidStr(void)
{
   static const uint32 basic_args[] = {0x0, 0x1, 0xa};
   static const uint32 extended_args[] = {0x80000000, 0x80000001, 0x80000008};
   DynBuf buf;
   char *result;

   DynBuf_Init(&buf);

   HostInfoGetCpuidStrSection(basic_args, ARRAYSIZE(basic_args), &buf);
   HostInfoGetCpuidStrSection(extended_args, ARRAYSIZE(extended_args), &buf);

   // Trim buffer and set NULL character to replace last '-'.
   DynBuf_Trim(&buf);
   result = (char*)DynBuf_Get(&buf);
   ASSERT(result && result[0]); // We should at least get result from eax = 0x0.
   result[DynBuf_GetSize(&buf) - 1] = '\0';

   return DynBuf_Detach(&buf);
}
예제 #8
0
static gboolean
GuestInfoStatsGather(gpointer data)
{
#if (defined(__linux__) && !defined(USERWORLD)) || defined(_WIN32)
   ToolsAppCtx *ctx = data;
   DynBuf stats;
#endif
#if defined(_WIN32)
   gboolean perfmonLogStats;
#endif

   g_debug("Entered guest info stats gather.\n");

#if defined(_WIN32)
   perfmonLogStats = g_key_file_get_boolean(ctx->config,
                                            CONFGROUPNAME_GUESTINFO,
                                            CONFNAME_GUESTINFO_ENABLESTATLOGGING,
                                            NULL);

   GuestInfo_SetStatLogging(perfmonLogStats);
#endif

#if (defined(__linux__) && !defined(USERWORLD)) || defined(_WIN32)
   /* Send the vmstats to the VMX. */
   DynBuf_Init(&stats);

   if (GuestInfo_PerfMon(&stats)) {
      if (!GuestInfoUpdateVmdb(ctx, INFO_MEMORY, DynBuf_Get(&stats),
                               DynBuf_GetSize(&stats))) {
         g_warning("Failed to send vmstats.\n");
      }
   } else {
      g_warning("Failed to get vmstats.\n");
   }

   DynBuf_Destroy(&stats);
#endif

   return TRUE;
}
예제 #9
0
파일: escape.c 프로젝트: raphaeldias/vmware
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;
}
예제 #10
0
파일: escape.c 프로젝트: raphaeldias/vmware
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;
}
예제 #11
0
void *
DynXdr_Get(XDR *xdrs)  // IN
{
   DynBuf *buf = &((DynXdrData *) xdrs->x_private)->data;
   return DynBuf_Get(buf);
}
예제 #12
0
Bool
StrUtil_VDynBufPrintf(DynBuf *b,        // IN/OUT
                      const char *fmt,  // IN
                      va_list args)     // IN
{
   /*
    * Arbitrary lower-limit on buffer size allocation, to avoid doing
    * many tiny enlarge operations.
    */

   const size_t minAllocSize = 128;

   while (1) {
      int i;
      size_t size = DynBuf_GetSize(b);
      size_t allocSize = DynBuf_GetAllocatedSize(b);

      /* Make sure the buffer isn't still unallocated */
      if (allocSize < minAllocSize) {
         Bool success = DynBuf_Enlarge(b, minAllocSize);
         if (!success) {
            return FALSE;
         }
         continue;
      }

      /*
       * Is there any allocated-but-not-occupied space? If so, try the printf.
       * If there was no space to begin with, or Str_Vsnprintf() ran out of
       * space, this will fail.
       */

      if (allocSize - size > 0) {
         va_list tmpArgs;

         va_copy(tmpArgs, args);
         i = Str_Vsnprintf((char *) DynBuf_Get(b) + size, allocSize - size,
                           fmt, tmpArgs);
         va_end(tmpArgs);
      } else {
         i = -1;
      }

      if (i >= 0) {
         /*
          * Success. Enlarge the buffer.
          *
          * The ASSERT here is to verify that printf() isn't lying
          * about the length of the string it wrote. This actually
          * happens, believe it or not. See bug 253674.
          */

         ASSERT(i + size == allocSize ||
                ((char *)DynBuf_Get(b))[i + size] == '\0');

         DynBuf_SetSize(b, size + i);
         break;

      } else {
         /*
          * Failure. We must grow the buffer first.  Note that this is
          * just a minimum size- dynbuf will probably decide to double
          * the actual reallocated buffer size.
          */

         Bool success = DynBuf_Enlarge(b, size + minAllocSize);

         if (!success) {
            return FALSE;
         }
      }
   }

   return TRUE;
}
예제 #13
0
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;
}
예제 #14
0
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;
}
예제 #15
0
Bool
CodeSet_GenericToGenericDb(const char *codeIn,  // IN
                           const char *bufIn,   // IN
                           size_t sizeIn,       // IN
                           const char *codeOut, // IN
                           unsigned int flags,  // IN
                           DynBuf *db)          // IN/OUT
{
   Bool result = FALSE;
   UErrorCode uerr;
   const char *bufInCur;
   const char *bufInEnd;
   UChar bufPiv[1024];
   UChar *bufPivSource;
   UChar *bufPivTarget;
   UChar *bufPivEnd;
   char *bufOut;
   char *bufOutCur;
   char *bufOutEnd;
   size_t bufOutSize;
   size_t bufOutOffset;
   UConverter *cvin = NULL;
   UConverter *cvout = NULL;
   UConverterToUCallback toUCb;
   UConverterFromUCallback fromUCb;

   ASSERT(codeIn);
   ASSERT(sizeIn == 0 || bufIn);
   ASSERT(codeOut);
   ASSERT(db);
   ASSERT((CSGTG_NORMAL == flags) || (CSGTG_TRANSLIT == flags) ||
          (CSGTG_IGNORE == flags));

   if (dontUseIcu) {
      // fall back
      return CodeSetOld_GenericToGenericDb(codeIn, bufIn, sizeIn, codeOut,
                                           flags, db);
   }

   /*
    * Trivial case.
    */

   if ((0 == sizeIn) || (NULL == bufIn)) {
      result = TRUE;
      goto exit;
   }

   /*
    * Open converters.
    */

   uerr = U_ZERO_ERROR;
   cvin = ucnv_open(codeIn, &uerr);
   if (!cvin) {
      goto exit;
   }

   uerr = U_ZERO_ERROR;
   cvout = ucnv_open(codeOut, &uerr);
   if (!cvout) {
      goto exit;
   }

   /*
    * Set callbacks according to flags.
    */

   switch (flags) {
   case CSGTG_NORMAL:
      toUCb = UCNV_TO_U_CALLBACK_STOP;
      fromUCb = UCNV_FROM_U_CALLBACK_STOP;
      break;

   case CSGTG_TRANSLIT:
      toUCb = UCNV_TO_U_CALLBACK_SUBSTITUTE;
      fromUCb = UCNV_FROM_U_CALLBACK_SUBSTITUTE;
      break;

   case CSGTG_IGNORE:
      toUCb = UCNV_TO_U_CALLBACK_SKIP;
      fromUCb = UCNV_FROM_U_CALLBACK_SKIP;
      break;

   default:
      NOT_IMPLEMENTED();
      break;
   }

   uerr = U_ZERO_ERROR;
   ucnv_setToUCallBack(cvin, toUCb, NULL, NULL, NULL, &uerr);
   if (U_ZERO_ERROR != uerr) {
      goto exit;
   }

   uerr = U_ZERO_ERROR;
   ucnv_setFromUCallBack(cvout, fromUCb, NULL, NULL, NULL, &uerr);
   if (U_ZERO_ERROR != uerr) {
      goto exit;
   }

   /*
    * Convert using ucnv_convertEx().
    * As a starting guess, make the output buffer the same size as
    * the input string (with a fudge constant added in to avoid degen
    * cases).
    */

   bufInCur = bufIn;
   bufInEnd = bufIn + sizeIn;
   bufOutSize = sizeIn + 4;
   bufOutOffset = 0;
   bufPivSource = bufPiv;
   bufPivTarget = bufPiv;
   bufPivEnd = bufPiv + ARRAYSIZE(bufPiv);

   for (;;) {
      if (!DynBuf_Enlarge(db, bufOutSize)) {
         goto exit;
      }
      bufOut = DynBuf_Get(db);
      bufOutCur = bufOut + bufOutOffset;
      bufOutSize = DynBuf_GetAllocatedSize(db);
      bufOutEnd = bufOut + bufOutSize;

      uerr = U_ZERO_ERROR;
      ucnv_convertEx(cvout, cvin, &bufOutCur, bufOutEnd,
		     &bufInCur, bufInEnd,
		     bufPiv, &bufPivSource, &bufPivTarget, bufPivEnd,
		     FALSE, TRUE, &uerr);

      if (!U_FAILURE(uerr)) {
         /*
          * "This was a triumph.
          *  I'm making a note here:
          *  HUGE SUCCESS.
          *  It's hard to overstate
          *  my satisfaction."
          */

         break;
      }

      if (U_BUFFER_OVERFLOW_ERROR != uerr) {
	 // failure
         goto exit;
      }

      /*
       * Our guess at 'bufOutSize' was obviously wrong, just double it.
       * We'll be reallocating bufOut, so will need to recompute bufOutCur
       * based on bufOutOffset.
       */

      bufOutSize *= 2;
      bufOutOffset = bufOutCur - bufOut;
   }

   /*
    * Set final size and return.
    */

   DynBuf_SetSize(db, bufOutCur - bufOut);

   result = TRUE;

  exit:
   if (cvin) {
      ucnv_close(cvin);
   }

   if (cvout) {
      ucnv_close(cvout);
   }

   return result;
}
예제 #16
0
파일: escape.c 프로젝트: raphaeldias/vmware
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;
}
예제 #17
0
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;
}