Set the tm_isdst flag to -1 before calling mktime(). Otherwise, the current
[oweals/busybox.git] / procps / ps.c
index b8e4cd3a07664c3c0b59660bc444f74cf9559349..9dc45d35d45940caa68b1545d08794241923d77c 100644 (file)
+/* vi: set sw=4 ts=4: */
 /*
- * Mini ps implementation for busybox
+ * Mini ps implementation(s) for busybox
  *
- * Copyright (C) 1998 by Erik Andersen <andersee@debian.org>
+ * Copyright (C) 1999-2003 by Erik Andersen <andersen@codepoet.org>
  *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the Free
+ * Software Foundation; either version 2 of the License, or (at your option)
+ * any later version.
  *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
  *
+ * You should have received a copy of the GNU General Public License along with
+ * this program; if not, write to the Free Software Foundation, Inc., 59 Temple
+ * Place, Suite 330, Boston, MA 02111-1307 USA
  */
 
-#include "internal.h"
+#include <stdio.h>
+#include <stdlib.h>
 #include <unistd.h>
 #include <dirent.h>
-#include <stdio.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <ctype.h>
+#include <string.h>
+#include <termios.h>
+#include <sys/ioctl.h>
+#include "busybox.h"
+#ifdef CONFIG_SELINUX
+#include <fs_secure.h>
+#include <ss.h>
+#include <flask_util.h>          /* for is_flask_enabled() */
+#endif
+
+static const int TERMINAL_WIDTH = 79;      /* not 80 in case terminal has linefold bug */
+
 
 
 extern int ps_main(int argc, char **argv)
 {
-    DIR *dir;
-    FILE *file;
-    struct dirent *entry;
+       procps_status_t * p;
+       int i, len;
+#ifdef CONFIG_FEATURE_AUTOWIDTH
+       struct winsize win = { 0, 0, 0, 0 };
+       int terminal_width = TERMINAL_WIDTH;
+#else
+#define terminal_width  TERMINAL_WIDTH
+#endif
 
-    if ( argc>1 && **(argv+1) == '-' ) {
-       usage ("ps\n");
-    }
-    
-    dir = opendir("/proc");
-    if (!dir) {
-       perror("Can't open /proc");
-       exit(FALSE);
-    }
+#ifdef CONFIG_SELINUX
+       int use_selinux = 0;
+       security_id_t sid;
+       if(is_flask_enabled() && argv[1] && !strcmp(argv[1], "-c") )
+               use_selinux = 1;
+#endif
 
-    fprintf(stdout, "PID\tUid\tGid\tState\tName\n");
-    while ((entry = readdir(dir)) != NULL) {
-       char psStatus[NAME_MAX];
-       char psName[NAME_MAX]="";
-       char psState[NAME_MAX]="";
-       int psPID=0, psPPID=0, psUid=0, psGid=0;
-       //if (match(entry->d_name, "[0-9]") == FALSE)
-       //    continue;
-       sprintf(psStatus, "/proc/%s/status", entry->d_name);
-       file = fopen( psStatus, "r");
-       if (file == NULL) {
-           continue;
-           //perror(psStatus);
-           //exit( FALSE);
-       }
-       fscanf(file, "Name:\t%s\nState:\t%s\nPid:\t%d\nPPid:\t%d\nUid:\t%d\nGid:\t%d", 
-               psName, psState, &psPID, &psPPID, &psUid, &psGid);
-       fclose(file);
 
-       fprintf(stdout, "%d\t%d\t%d\t%s\t%s\n", psPID, psUid, psGid, psState, psName);
-    }
-    closedir(dir);
-    exit(TRUE);
+#ifdef CONFIG_FEATURE_AUTOWIDTH
+               ioctl(fileno(stdout), TIOCGWINSZ, &win);
+               if (win.ws_col > 0)
+                       terminal_width = win.ws_col - 1;
+#endif
+
+#ifdef CONFIG_SELINUX
+       if(use_selinux)
+               printf("  PID Context                          Stat Command\n");
+       else
+#endif
+       printf("  PID  Uid     VmSize Stat Command\n");
+#ifdef CONFIG_SELINUX
+       while ((p = procps_scan(1, use_selinux, &sid)) != 0) {
+#else
+       while ((p = procps_scan(1)) != 0) {
+#endif
+               char *namecmd = p->cmd;
+
+#ifdef CONFIG_SELINUX
+               if(use_selinux)
+               {
+                       char sbuf[128];
+                       len = sizeof(sbuf);
+                       if(security_sid_to_context(sid, (security_context_t)&sbuf, &len))
+                               strcpy(sbuf, "unknown");
+
+                       len = printf("%5d %-32s %s ", p->pid, sbuf, p->state);
+               }
+               else
+#endif
+               if(p->rss == 0)
+                       len = printf("%5d %-8s        %s ", p->pid, p->user, p->state);
+               else
+                       len = printf("%5d %-8s %6ld %s ", p->pid, p->user, p->rss, p->state);
+               i = terminal_width-len;
+
+               if(namecmd != 0 && namecmd[0] != 0) {
+                       if(i < 0)
+               i = 0;
+                       if(strlen(namecmd) > i)
+                               namecmd[i] = 0;
+                       printf("%s\n", namecmd);
+               } else {
+                       namecmd = p->short_cmd;
+                       if(i < 2)
+                               i = 2;
+                       if(strlen(namecmd) > (i-2))
+                               namecmd[i-2] = 0;
+                       printf("[%s]\n", namecmd);
+               }
+               free(p->cmd);
+       }
+       return EXIT_SUCCESS;
 }