Bool
CodeSet_CurrentToUtf8(const char *bufIn,  // IN
                      size_t sizeIn,      // IN
                      char **bufOut,      // OUT
                      size_t *sizeOut)    // OUT
{
#if !defined(CURRENT_IS_UTF8)
   DynBuf db;
   Bool ok;
#endif

   /*
    * Fallback if necessary.
    */
   if (dontUseIcu) {
      return CodeSetOld_CurrentToUtf8(bufIn, sizeIn, bufOut, sizeOut);
   }

#if defined(CURRENT_IS_UTF8)
   return CodeSetDuplicateUtf8Str(bufIn, sizeIn, bufOut, sizeOut);
#else
   DynBuf_Init(&db);
   ok = CodeSet_GenericToGenericDb(CodeSet_GetCurrentCodeSet(), bufIn, sizeIn,
                                   "UTF-8", 0, &db);
   return CodeSetDynBufFinalize(ok, &db, bufOut, sizeOut);
#endif
}
Bool
CodeSet_Utf8FormCToUtf8FormD(const char *bufIn,     // IN
                             size_t sizeIn,         // IN
                             char **bufOut,         // OUT
                             size_t *sizeOut)       // OUT
{
   /*
    * Fallback if necessary.
    */
   if (dontUseIcu) {
      return CodeSetOld_Utf8FormCToUtf8FormD(bufIn, sizeIn, bufOut, sizeOut);
   }

#if defined(__APPLE__)
   {
      DynBuf db;
      Bool ok;
      DynBuf_Init(&db);
      ok = CodeSet_Utf8Normalize(bufIn, sizeIn, FALSE, &db);
      return CodeSetDynBufFinalize(ok, &db, bufOut, sizeOut);
   }
#else
   NOT_IMPLEMENTED();
#endif
}
Exemple #3
0
void
DynBuf_Destroy(DynBuf *b)  // IN/OUT:
{
    ASSERT(b);

    free(b->data);
    DynBuf_Init(b);
}
Exemple #4
0
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;
}
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;
}
Exemple #6
0
Bool
DynArray_Init(DynArray *a,          // IN/OUT
              unsigned int count,   // IN
              size_t width)         // IN
{
   ASSERT(a);

   DynBuf_Init(&a->buf);
   a->width = width;
   return DynArray_SetCount(a, count);
}
Exemple #7
0
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
CodeSet_GenericToGeneric(const char *codeIn,  // IN
                         const char *bufIn,   // IN
                         size_t sizeIn,       // IN
                         const char *codeOut, // IN
                         unsigned int flags,  // IN
                         char **bufOut,       // OUT
                         size_t *sizeOut)     // OUT
{
   DynBuf db;
   Bool ok;

   DynBuf_Init(&db);
   ok = CodeSet_GenericToGenericDb(codeIn, bufIn, sizeIn, codeOut, flags, &db);
   return CodeSetDynBufFinalize(ok, &db, bufOut, sizeOut);
}
Exemple #10
0
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;
}
Bool
CodeSet_Utf8ToUtf16le(const char *bufIn,  // IN
                      size_t sizeIn,      // IN
                      char **bufOut,      // OUT
                      size_t *sizeOut)    // OUT
{
   DynBuf db;
   Bool ok;

   /*
    * Fallback if necessary.
    */
   if (dontUseIcu) {
      return CodeSetOld_Utf8ToUtf16le(bufIn, sizeIn, bufOut, sizeOut);
   }

   DynBuf_Init(&db);
   ok = CodeSetUtf8ToUtf16le(bufIn, sizeIn, &db);
   return CodeSetDynBufFinalize(ok, &db, bufOut, sizeOut);
}
Exemple #12
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;
}
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;
}
Exemple #14
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);
}
Bool
CodeSet_Utf16beToCurrent(const char *bufIn,  // IN
                         size_t sizeIn,      // IN
                         char **bufOut,      // OUT
                         size_t *sizeOut)    // OUT
{
   DynBuf db;
   Bool ok;

   /*
    * Fallback if necessary.
    */
   if (dontUseIcu) {
      return CodeSetOld_Utf16beToCurrent(bufIn, sizeIn, bufOut, sizeOut);
   }

   DynBuf_Init(&db);
   ok = CodeSet_GenericToGenericDb("UTF-16BE", bufIn, sizeIn,
                                   CodeSet_GetCurrentCodeSet(), 0, &db);
   return CodeSetDynBufFinalize(ok, &db, bufOut, sizeOut);
}
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;
}
Exemple #17
0
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;
}
Exemple #18
0
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;
}
Exemple #19
0
XDR *
DynXdr_Create(XDR *in)  // IN
{
   static struct xdr_ops dynXdrOps = {
      /*
       * Yes, these macros are a little redundant, but I figure it helps with
       * readability to group the sun/_KERNEL bits together.
       */
#if !defined(sun) || (defined(sun) && !defined(_KERNEL))
      NULL,             /* x_getlong */
      DynXdrPutLong,    /* x_putlong */
#endif
      NULL,             /* x_getbytes */
      DynXdrPutBytes,   /* x_putbytes */
      DynXdrGetPos,     /* x_getpostn */
      DynXdrSetPos,     /* x_setpostn */
      DynXdrInline,     /* x_inline */
      NULL,             /* x_destroy */
#if defined(__GLIBC__)
      NULL,             /* x_getint32 */
      DynXdrPutInt32,   /* x_putint32 */
#elif defined(__APPLE__)
      NULL,             /* x_control */
#elif defined(sun) && (defined(_LP64) || defined(_KERNEL))
      NULL,             /* x_control */
      NULL,             /* x_getint32 */
      DynXdrPutInt32,   /* x_putint32 */
#endif
   };

   XDR *ret;
   DynXdrData *priv;

   if (in == NULL) {
      ret = malloc(sizeof *ret);
      if (ret == NULL) {
         goto error;
      }
   } else {
      ret = in;
   }

   priv = malloc(sizeof *priv);
   if (priv == NULL) {
      goto error;
   }

   priv->freeMe = (in == NULL);
   DynBuf_Init(&priv->data);

   ret->x_op = XDR_ENCODE;
   ret->x_public = NULL;
   ret->x_private = (char *) priv;
   ret->x_base = 0;
   ret->x_ops = &dynXdrOps;

   return ret;

error:
   if (in == NULL) {
      free(ret);
   }
   return NULL;
}
Exemple #20
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;
}
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;
}
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;
}
Exemple #23
0
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;
}
Exemple #24
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;
}