Unicode *
Unicode_AllocList(char **srcList,          // IN: list of strings
                  ssize_t length,          // IN: list 
                  StringEncoding encoding) // IN:
{
   Unicode *dstList = NULL;
   ssize_t i;

   ASSERT(srcList != NULL);

   encoding = Unicode_ResolveEncoding(encoding);

   if (length < 0) {
      length = 0;
      while (srcList[length] != NULL) {
         length++;
      }
      
      /* Include the sentinel element. */
      length++;
   }

   dstList = Util_SafeMalloc(length * sizeof *dstList);

   for (i = 0; i < length; i++) {
      dstList[i] = Unicode_Alloc(srcList[i], encoding);
   }

   return dstList;
}
Bool
ProcMgr_GetImpersonatedUserInfo(char **userName,            // OUT
                                char **homeDir)             // OUT
{
   char buffer[BUFSIZ];
   struct passwd pw;
   struct passwd *ppw;

   *userName = NULL;
   *homeDir = NULL;

   ppw = &pw;
   if ((ppw = getpwuid_r(Id_GetEUid(), &pw, buffer, sizeof buffer)) == NULL) {
      return FALSE;
   }

   *userName = Unicode_Alloc(ppw->pw_name, STRING_ENCODING_DEFAULT);
   *homeDir = Unicode_Alloc(ppw->pw_dir, STRING_ENCODING_DEFAULT);

   return TRUE;
}
Example #3
0
Unicode
System_GetTimeAsString(void)
{
   struct timeval tv;
   time_t sec;
   int msec;
   size_t charsWritten;
   size_t bufSize = 8; // Multiplied by 2 for the initial allocation.
   char *buf = NULL;
   Unicode dateTime = NULL;
   Unicode output = NULL;

   if (gettimeofday(&tv, NULL)) {
      goto out;
   }
   sec = tv.tv_sec;
   msec = tv.tv_usec / 1000;

   /*
    * Loop repeatedly trying to format the time into a buffer, doubling the
    * buffer with each failure. This should be safe as the manpage for
    * strftime(3) seems to suggest that it only fails if the buffer isn't large
    * enough.
    *
    * The resultant string is encoded according to the current locale.
    */
   do {
      char *newBuf;
      bufSize *= 2;

      newBuf = realloc(buf, bufSize);
      if (newBuf == NULL) {
         goto out;
      }
      buf = newBuf;
      charsWritten = strftime(buf, bufSize, "%b %d %H:%M:%S", localtime(&sec));
   } while (charsWritten == 0);

   /*
    * Append the milliseconds field, but only after converting the date/time
    * string from encoding specified in the current locale to an opaque type.
    */
   dateTime = Unicode_Alloc(buf, STRING_ENCODING_DEFAULT);
   if (dateTime == NULL) {
      goto out;
   }
   output = Unicode_Format("%s.%03d", dateTime, msec);

  out:
   free(buf);
   Unicode_Free(dateTime);
   return output;
}
Example #4
0
char *
VixToolsGetNextEnvVar(VixToolsEnvIterator *envItr)    // IN
{
   char *envVar;

   if (NULL == envItr) {
      return NULL;
   }

#ifdef _WIN32
   if (VIX_TOOLS_ENV_TYPE_ENV_BLOCK == envItr->envType) {
      if (L'\0' == envItr->data.eb.currEnvVar[0]) {
         envVar = NULL;
      } else {
         envVar = Unicode_AllocWithUTF16(envItr->data.eb.currEnvVar);
         while(*envItr->data.eb.currEnvVar++);
      }
   } else if (VIX_TOOLS_ENV_TYPE_ENVIRON == envItr->envType) {
      if (NULL == *envItr->data.environ) {
         envVar = NULL;
      } else {
         envVar = Unicode_AllocWithUTF16(*envItr->data.environ);
         envItr->data.environ++;
      }
   } else {
      /* Is someone using uninitialized memory? */
      NOT_IMPLEMENTED();
   }
#else
   if (NULL == *envItr->environ) {
      envVar = NULL;
   } else {
      envVar = Unicode_Alloc(*envItr->environ, STRING_ENCODING_DEFAULT);
      envItr->environ++;
   }
#endif
   return envVar;
}
ProcMgrProcInfoArray *
ProcMgr_ListProcesses(void)
{
   ProcMgrProcInfoArray *procList = NULL;
   ProcMgrProcInfo processInfo;
   Bool failed = TRUE;
   DIR *dir;
   struct dirent *ent;

   procList = Util_SafeCalloc(1, sizeof *procList);
   ProcMgrProcInfoArray_Init(procList, 0);
   processInfo.procOwner = NULL;
   processInfo.procCmd = NULL;

   dir = opendir("/proc");
   if (NULL == dir) {
      Warning("ProcMgr_ListProcesses unable to open /proc\n");
      goto exit;
   }

   while (TRUE) {
      struct passwd *pwd;
      char tempPath[MAXPATHLEN];
      psinfo_t procInfo;
      size_t strLen = 0;
      size_t numRead = 0;
      FileIODescriptor psInfoFd;
      FileIOResult res;

      errno = 0;
      FileIO_Invalidate(&psInfoFd);

      ent = readdir(dir);
      if (ent == NULL) {
         if (errno == 0) {
            break;
         } else {
            goto exit;
         }
      }

      if (Str_Snprintf(tempPath,
                       sizeof tempPath,
                       "/proc/%s/psinfo",
                       ent->d_name) == -1) {
         Debug("Process id '%s' too large\n", ent->d_name);
         continue;
      }
      res = FileIO_Open(&psInfoFd,
                        tempPath,
                        FILEIO_OPEN_ACCESS_READ,
                        FILEIO_OPEN);
      if (res != FILEIO_SUCCESS) {
         if ((res == FILEIO_FILE_NOT_FOUND) ||
             (res == FILEIO_NO_PERMISSION)) {
            continue;
         } else {
            goto exit;
         }
      }

      res = FileIO_Read(&psInfoFd, &procInfo, sizeof procInfo, &numRead);
      FileIO_Close(&psInfoFd);
      if (res != FILEIO_SUCCESS) {
         goto exit;
      }

      processInfo.procStartTime = procInfo.pr_start.tv_sec;

      /*
       * Command line strings in procInfo.pr_psargs are truncated to PRARGZ
       * bytes. In this case we extract the arguments from the /proc/<pid>/as
       * file. Since most command line strings are expected to fit within
       * PRARGSZ bytes, we avoid calling
       * ExtractCommandLineFromAddressSpaceFile for every process.
       */
      if (strlen(procInfo.pr_psargs) + 1 == PRARGSZ) {
         char *tmp;

         tmp = ExtractCommandLineFromAddressSpaceFile(&procInfo);
         if (tmp != NULL) {
            processInfo.procCmd = Unicode_Alloc(tmp, STRING_ENCODING_DEFAULT);
            free(tmp);
         } else {
            processInfo.procCmd = Unicode_Alloc(procInfo.pr_psargs,
                                                STRING_ENCODING_DEFAULT);
         }
      } else {
         processInfo.procCmd = Unicode_Alloc(procInfo.pr_psargs,
                                             STRING_ENCODING_DEFAULT);
      }

      /*
       * Store the pid in dynbuf.
       */
      processInfo.procId = procInfo.pr_pid;

      /*
       * Store the owner of the process.
       */
      pwd = getpwuid(procInfo.pr_uid);
      processInfo.procOwner = (NULL == pwd)
                              ? Str_SafeAsprintf(&strLen, "%d", (int) procInfo.pr_uid)
                              : Unicode_Alloc(pwd->pw_name, STRING_ENCODING_DEFAULT);

      /*
       * Store the process info into a list buffer.
       */
      if (!ProcMgrProcInfoArray_Push(procList, processInfo)) {
         Warning("%s: failed to expand DynArray - out of memory\n",
                 __FUNCTION__);
         goto exit;
      }
      processInfo.procCmd = NULL;
      processInfo.procOwner = NULL;
   } // while (TRUE)

   if (0 < ProcMgrProcInfoArray_Count(procList)) {
      failed = FALSE;
   }

exit:
   closedir(dir);

   free(processInfo.procOwner);
   free(processInfo.procCmd);

   if (failed) {
      ProcMgr_FreeProcList(procList);
      procList = NULL;
   }

   return procList;
}
Example #6
0
ProcMgrProcInfoArray *
ProcMgr_ListProcesses(void)
{
   ProcMgrProcInfoArray *procList = NULL;
   ProcMgrProcInfo processInfo;
   Bool failed = TRUE;
   DIR *dir;
   struct dirent *ent;

   procList = Util_SafeCalloc(1, sizeof *procList);
   ProcMgrProcInfoArray_Init(procList, 0);
   processInfo.procOwner = NULL;
   processInfo.procCmdLine = NULL;
   processInfo.procCmdName = NULL;

   dir = opendir("/proc");
   if (NULL == dir) {
      Warning("ProcMgr_ListProcesses unable to open /proc\n");
      goto exit;
   }

   while (TRUE) {
      char *tmp;
      char *cmdNameBegin = NULL;
      char *cmdNameEnd = NULL;
      struct passwd *pwd;
      char tempPath[MAXPATHLEN];
      psinfo_t procInfo;
      size_t strLen = 0;
      size_t numRead = 0;
      FileIODescriptor psInfoFd;
      FileIOResult res;
      Bool cmdNameLookup = TRUE;

      errno = 0;
      FileIO_Invalidate(&psInfoFd);

      ent = readdir(dir);
      if (ent == NULL) {
         if (errno == 0) {
            break;
         } else {
            goto exit;
         }
      }

      if (Str_Snprintf(tempPath,
                       sizeof tempPath,
                       "/proc/%s/psinfo",
                       ent->d_name) == -1) {
         Debug("Process id '%s' too large\n", ent->d_name);
         continue;
      }
      res = FileIO_Open(&psInfoFd,
                        tempPath,
                        FILEIO_OPEN_ACCESS_READ,
                        FILEIO_OPEN);
      if (res != FILEIO_SUCCESS) {
         if ((res == FILEIO_FILE_NOT_FOUND) ||
             (res == FILEIO_NO_PERMISSION)) {
            continue;
         } else {
            goto exit;
         }
      }

      res = FileIO_Read(&psInfoFd, &procInfo, sizeof procInfo, &numRead);
      FileIO_Close(&psInfoFd);
      if (res != FILEIO_SUCCESS) {
         goto exit;
      }

      processInfo.procStartTime = procInfo.pr_start.tv_sec;

      /*
       * If the command name in the ps info struct is strictly less than the
       * maximum allowed size, then we can save it right now. Else we shall
       * need to try and parse it from the entire command line, to avoid
       * saving a truncated command name.
       */
      if (strlen(procInfo.pr_fname) + 1 < sizeof procInfo.pr_fname) {
         processInfo.procCmdName = Unicode_Alloc(procInfo.pr_fname,
                                                 STRING_ENCODING_DEFAULT);
         cmdNameLookup = FALSE;
      }

      /*
       * The logic below is this:
       * 1. If we are looking for the explicit command name, we need to
       *    extract the arguments from the /proc/<pid>/as file and save argv[0].
       * 2. If we are not looking for the explicit command name, but the command
       *    line in the ps info struct is not strictly less than the maximum
       *    allowed size, we still need to extract the arguments from the
       *    /proc/<pid>/as file, to avoid saving truncated comand line.
       * 3. Else we can save the command line directly from the ps info struct.
       */
      if (cmdNameLookup) {
         tmp = ExtractCommandLineFromAddressSpaceFile(&procInfo, &processInfo.procCmdName);
      } else if (strlen(procInfo.pr_psargs) + 1 >= sizeof procInfo.pr_psargs) {
         tmp = ExtractCommandLineFromAddressSpaceFile(&procInfo, NULL);
      } else {
         tmp = NULL;
      }

      if (tmp != NULL) {
         processInfo.procCmdLine = Unicode_Alloc(tmp, STRING_ENCODING_DEFAULT);
         cmdNameLookup = FALSE;
      } else {
         /*
          * We had some issues reading procfs, mostly due to lack of
          * permissions for certain system owned precesses. So let's resort to
          * what the procinfo structure provides as a last resort.
          */
         processInfo.procCmdLine = Unicode_Alloc(procInfo.pr_psargs,
                                                 STRING_ENCODING_DEFAULT);

         if (cmdNameLookup) {
            /*
             * Now let's try and get the best effort command name from the entire
             * command line. The method below does not take care of spaces in folder
             * names and executable file names. This is the best we can do at this
             * point, considering that spaces are not common in either file or
             * folder names in Solaris, specially when owned by the system.
             */
            char *tmp2 = Unicode_Alloc(procInfo.pr_psargs, STRING_ENCODING_DEFAULT);
            cmdNameBegin = tmp2;
            /*
             * Assuming the command name to end at the first blank space.
             */
            cmdNameEnd = cmdNameBegin;
            while ('\0' != *cmdNameEnd) {
               if ('/' == *cmdNameEnd) {
                  cmdNameBegin = cmdNameEnd + 1;
               }
               if (' ' == *cmdNameEnd) {
                  break;
               }
               cmdNameEnd++;
            }
            *cmdNameEnd = '\0';
            processInfo.procCmdName = Str_SafeAsprintf(NULL, "%s", cmdNameBegin);
            free(tmp2);
         }
      }
      free(tmp);
      tmp = NULL;

      /*
       * Store the pid.
       */
      processInfo.procId = procInfo.pr_pid;

      /*
       * Store the owner of the process.
       */
      pwd = getpwuid(procInfo.pr_uid);
      processInfo.procOwner = (NULL == pwd)
                              ? Str_SafeAsprintf(&strLen, "%d", (int) procInfo.pr_uid)
                              : Unicode_Alloc(pwd->pw_name, STRING_ENCODING_DEFAULT);

      /*
       * Store the process info into a list buffer.
       */
      if (!ProcMgrProcInfoArray_Push(procList, processInfo)) {
         Warning("%s: failed to expand DynArray - out of memory\n",
                 __FUNCTION__);
         goto exit;
      }
      processInfo.procCmdName = NULL;
      processInfo.procCmdLine = NULL;
      processInfo.procOwner = NULL;
   } // while (TRUE)

   if (0 < ProcMgrProcInfoArray_Count(procList)) {
      failed = FALSE;
   }

exit:
   closedir(dir);

   free(processInfo.procOwner);
   free(processInfo.procCmdLine);
   free(processInfo.procCmdName);

   if (failed) {
      ProcMgr_FreeProcList(procList);
      procList = NULL;
   }

   return procList;
}
Example #7
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;
}