Beispiel #1
0
unsigned int
DynArray_Count(const DynArray *a)       // IN
{
   ASSERT(a);

   return (unsigned int) (DynBuf_GetSize(&a->buf) / a->width);
}
Beispiel #2
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 *
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
GuestInfo_PerfMon(DynBuf *statBuf)  // IN/OUT: inited, ready to fill
{
   GuestInfoCollector *temp;
   static GuestInfoCollector *current = NULL;
   static GuestInfoCollector *previous = NULL;

   ASSERT(statBuf && DynBuf_GetSize(statBuf) == 0);

   /* Preallocate space to minimize realloc operations. */
   if (!DynBuf_Enlarge(statBuf, GUEST_INFO_PREALLOC_SIZE)) {
      return FALSE;
   }

   /* First time through, allocate all necessary memory */
   if (previous == NULL) {
      current = GuestInfoConstructCollector(guestInfoQuerySpecTable,
                                            N_QUERIES);

      previous = GuestInfoConstructCollector(guestInfoQuerySpecTable,
                                             N_QUERIES);
   }

   if ((current == NULL) ||
       (previous == NULL)) {
      GuestInfoDestroyCollector(current);
      current = NULL;
      GuestInfoDestroyCollector(previous);
      previous = NULL;
      return FALSE;
   }

   /* Collect the current data */
   GuestInfoCollect(current);

   /* Encode the captured data */
   GuestInfoEncodeStats(current, previous, statBuf);

   /* Switch the collections for next time. */
   temp = current;
   current = previous;
   previous = temp;

   return TRUE;
}
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;
}
Beispiel #6
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;
}
Beispiel #8
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);
}
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;
}
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;
}
Beispiel #11
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;
}
Beispiel #12
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;
}
Beispiel #13
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;
}
Beispiel #14
0
static u_int
DynXdrGetPos(DYNXDR_GETPOS_CONST XDR *xdrs) // IN
{
   DynXdrData *priv = (DynXdrData *) xdrs->x_private;
   return (u_int) DynBuf_GetSize(&priv->data);
}
Beispiel #15
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;
}
Beispiel #16
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;
}