use $(LIBENSCVECTOR) instead of libensc_vector.a
[util-vserver.git] / util-vserver / src / vps.c
index aac59f4..a3055a3 100644 (file)
 #endif
 
 #include "util.h"
-#include "wrappers.h"
-#include "wrappers-vserver.h"
 #include "pathconfig.h"
 
 #include <lib/vserver.h>
 #include <lib/fmt.h>
 #include <assert.h>
+#include <fcntl.h>
+#include <signal.h>
+#include <errno.h>
+
+#define ENSC_WRAPPERS_VSERVER  1
+#define ENSC_WRAPPERS_STDLIB   1
+#define ENSC_WRAPPERS_UNISTD   1
+#define ENSC_WRAPPERS_FCNTL    1
+#include <wrappers.h>
 
 #define CTXNR_WIDTH    5
-#define HUNK_SIZE      0x40;
+#define HUNK_SIZE      0x4000
 #define CONTEXT_WIDTH  20
 #define CONTEXT_PLACE  "                    "
 
@@ -44,21 +51,52 @@ struct ContextMapping {
 static struct ContextMapping           *mapping    = 0;
 static size_t                          mapping_len = 0;
 
+
+static void
+showHelp(int fd, char const *cmd, int res)
+{
+  WRITE_MSG(fd, "Usage:  ");
+  WRITE_STR(fd, cmd);
+  WRITE_MSG(fd,
+           " <ps-opts>*\n\n"
+           "Please report bugs to " PACKAGE_BUGREPORT "\n");
+  exit(res);
+}
+
+static void
+showVersion()
+{
+  WRITE_MSG(1,
+           "vps " VERSION " -- shows processes in vserver-contexts\n"
+           "This program is part of " PACKAGE_STRING "\n\n"
+           "Copyright (C) 2004 Enrico Scholz\n"
+           VERSION_COPYRIGHT_DISCLAIMER);
+  exit(0);
+}
+
+
 static size_t
 writeContextInfo(xid_t ctx, char const *name)
 {
-  char         buf[sizeof(ctx)*3+1];
-  size_t       l   = utilvserver_fmt_ulong(buf, ctx);
   size_t       l1  = name==0 ? 0 : strlen(name);
   size_t       res = CTXNR_WIDTH + 1;
+  
+  if (ctx==VC_NOCTX) {
+    if (3<CTXNR_WIDTH) Vwrite(1, CONTEXT_PLACE, CTXNR_WIDTH-3);
+    Vwrite(1, "ERR ", 4);
+  }
+  else {
+    char       buf[sizeof(ctx)*3+1];
+    size_t     l = utilvserver_fmt_ulong(buf, ctx);
 
-  if (l<CTXNR_WIDTH) write(1, CONTEXT_PLACE, CTXNR_WIDTH-l);
-  write(1, buf, l);
-  write(1, " ", 1);
+    if (l<CTXNR_WIDTH) Vwrite(1, CONTEXT_PLACE, CTXNR_WIDTH-l);
+    Vwrite(1, buf, l);
+    Vwrite(1, " ", 1);
+  }
 
   if (l1!=0) {
     assert(name!=0);
-    write(1, name, l1);
+    Vwrite(1, name, l1);
   }
 
   return res+l1;
@@ -72,7 +110,7 @@ extractCtx(char *pid_str)
   while (*pid_str==' ') ++pid_str;
   pid = atoi(pid_str);
 
-  return vc_X_getctx(pid);
+  return vc_get_task_xid(pid);
 }
 
 static char const *
@@ -149,10 +187,10 @@ processOutput(char *data, size_t len)
 
   pid_end = pos-data + 4;
 
-  write(1, data, pid_end);
-  write(1, "CONTEXT" CONTEXT_PLACE, CONTEXT_WIDTH);
-  write(1, data+pid_end, eol_pos-(data+pid_end));
-  write(1, "\n", 1);
+  Vwrite(1, data, pid_end);
+  Vwrite(1, "CONTEXT" CONTEXT_PLACE, CONTEXT_WIDTH);
+  Vwrite(1, data+pid_end, eol_pos-(data+pid_end));
+  Vwrite(1, "\n", 1);
 
   len -= eol_pos-data;
   data = eol_pos+1;
@@ -170,11 +208,12 @@ processOutput(char *data, size_t len)
     ctx          = extractCtx(data + pid_end - 6);
     vserver_name = resolveCtx(ctx);
 
-    write(1, data, pid_end);
+    Vwrite(1, data, pid_end);
     l = writeContextInfo(ctx, vserver_name);
-    if (l<CONTEXT_WIDTH) write(1, CONTEXT_PLACE, CONTEXT_WIDTH-l);
-    write(1, data+pid_end, eol_pos-(data+pid_end));
-    write(1, "\n", 1);
+    if (l<CONTEXT_WIDTH) Vwrite(1, CONTEXT_PLACE, CONTEXT_WIDTH-l);
+    else                 Vwrite(1, " ", 1);
+    Vwrite(1, data+pid_end, eol_pos-(data+pid_end));
+    Vwrite(1, "\n", 1);
     
     len -= eol_pos-data;
     data = eol_pos+1;
@@ -187,9 +226,25 @@ int main(int argc, char *argv[])
   pid_t                pid;
   char *       data;
   size_t       len;
+  char const * errptr;
+
+  if (argc>1) {
+    if (strcmp(argv[1], "--help")   ==0) showHelp(1, argv[0], 0);
+    if (strcmp(argv[1], "--version")==0) showVersion();
+  }
 
-  if (vc_X_getctx(0)!=1)
-    Evc_new_s_context(1, vc_get_securecaps(), 0);
+  signal(SIGCHLD, SIG_DFL);
+
+  if (!switchToWatchXid(&errptr)) {
+    perror(errptr);
+    exit(wrapper_exit_code);
+  }
+
+  if (access("/proc/uptime",R_OK)==-1 && errno==ENOENT)
+    WRITE_MSG(2,
+             "WARNING: can not access /proc/uptime. Usually, this is caused by\n"
+             "         procfs-security. Please read the FAQ for more details\n"
+             "         http://www.linux-vserver.org/index.php?page=Linux-Vserver+FAQ\n");
 
   Epipe(p);
   pid = Efork();
@@ -212,8 +267,5 @@ int main(int argc, char *argv[])
   Eclose(p[0]);
   
   processOutput(data, len);
-
-  exitLikeProcess(pid);
-  perror("exitLikeProcess()");
-  return wrapper_exit_code;
+  exitLikeProcess(pid, "ps", wrapper_exit_code);
 }