*** upstart-0.6.5.orig/util/initctl.c	2012-03-30 08:39:38.941921563 -0700
--- upstart-0.6.5/util/initctl.c	2012-04-02 01:49:46.090692783 -0700
***************
*** 25,35 ****
--- 25,41 ----
  #include <dbus/dbus.h>
  
  #include <sys/types.h>
+ #include <sys/stat.h>
  
  #include <stdio.h>
  #include <stdlib.h>
  #include <unistd.h>
  
+ #include <time.h>
+ 
+ #include <readproc.h>
+ #include <sysinfo.h>
+ 
  #include <nih/macros.h>
  #include <nih/alloc.h>
  #include <nih/string.h>
***************
*** 211,216 ****
--- 217,263 ----
   *
   * Returns: newly allocated string or NULL on raised error..
   **/
+ 
+ /*
+  * this format idea requires some more information (what caused the current state)
+ 
+     PID   EVENT/STATE       TIME    SERVICE          CAUSE
+   24883    stop/waiting   0d 32:22  httpd            runlevel=5
+     690   start/running   0d 00:00  willow-smtpd     usercmd: reload
+ 
+  * so we went with this instead
+ 
+    start/running     44.13d      634 rsyslog
+    start/running     44.13d      675 tty4
+    start/running     44.13d      308 udev
+     stop/waiting                     udevmonitor
+    start/running                     network-interface-security (network-interface/eth0)
+ 
+  *
+  */
+ 
+ 
+ float
+ pid_age(pid_t pid) 
+ {
+ 	proc_t proc_info;
+ 	int seconds_since_boot = uptime(0,0);
+         if (!get_proc_stats(pid, &proc_info)) {
+ 		return 0.0;
+ 	}
+ 
+ 	// readproc.h comment lies about what proc_t.start_time is. It's 
+ 	// actually expressed in Hertz ticks since boot 
+ 
+         int  seconds_since_1970 = time(NULL);
+         int time_of_boot = seconds_since_1970 - seconds_since_boot;
+         long  t = seconds_since_boot - (unsigned long)(proc_info.start_time / Hertz);
+ 
+ 	int delta = t;
+ 	float days = ((float) delta / (float)(60*60*24));
+ 	return days;
+ }
+ 
  char *
  job_status (const void *  parent,
  	    NihDBusProxy *job_class,
***************
*** 243,312 ****
  		}
  	}
  
! 	if (props && *props->name) {
! 		str = nih_sprintf (parent, "%s (%s)",
! 				   job_class_name, props->name);
! 		if (! str)
! 			nih_return_no_memory_error (NULL);
! 	} else {
! 		str = nih_strdup (parent, job_class_name);
! 		if (! str)
! 			nih_return_no_memory_error (NULL);
! 	}
! 
  	if (props) {
! 		if (! nih_strcat_sprintf (&str, parent, " %s/%s",
! 					  props->goal, props->state)) {
  			nih_error_raise_no_memory ();
  			nih_free (str);
  			return NULL;
  		}
  
! 		/* The first process returned is always the main process,
! 		 * which is the process we always want to display alongside
! 		 * the state if there is one.  Prefix if it's not one of
! 		 * the standard processes.
! 		 */
! 		if (props->processes[0]) {
! 			if (strcmp (props->processes[0]->item0, "main")
! 			    && strcmp (props->processes[0]->item0, "pre-start")
! 			    && strcmp (props->processes[0]->item0, "post-stop")) {
! 				if (! nih_strcat_sprintf (&str, parent, ", (%s) process %d",
! 							  props->processes[0]->item0,
! 							  props->processes[0]->item1)) {
! 					nih_error_raise_no_memory ();
! 					nih_free (str);
! 					return NULL;
! 				}
! 			} else {
! 				if (! nih_strcat_sprintf (&str, parent, ", process %d",
! 							  props->processes[0]->item1)) {
! 					nih_error_raise_no_memory ();
! 					nih_free (str);
! 					return NULL;
! 				}
! 			}
  
! 			/* Append a line for each additional process */
! 			for (JobProcessesElement **p = &props->processes[1];
! 			     p && *p; p++) {
! 				if (! nih_strcat_sprintf (&str, parent, "\n\t%s process %d",
! 							  (*p)->item0,
! 							  (*p)->item1)) {
! 					nih_error_raise_no_memory ();
! 					nih_free (str);
! 					return NULL;
! 				}
  			}
  		}
  	} else {
! 		if (! nih_strcat (&str, parent, " stop/waiting")) {
  			nih_error_raise_no_memory ();
  			nih_free (str);
  			return NULL;
  		}
  	}
  
  	return str;
  }
  
--- 290,404 ----
  		}
  	}
  
!         /*   EVENT / STATE  */  
  	if (props) {
!               	/*    EVENT / STATE  */
!                 if (!nih_strcat_sprintf(&str, parent, " %7s/%-9s",
!                      props->goal,  // event
!                      props->state  // state
!                      )) {
! 			nih_error_raise_no_memory ();
! 			nih_free (str);
! 			return NULL;
!                 }
!         } else {
!              /* simplified line, because there are no process properties */
!              if (!nih_strcat_sprintf(&str, parent, " %7s/%-9s",
!                      "stop","waiting"
!                      )) {
!         		nih_error_raise_no_memory ();
! 			nih_free (str);
! 			return NULL;
! 	    }
!         }
! 
!  	/* The first process returned is always the main process,
! 	 * which is the process we always want to display on the main
!          # line if there is one...
! 	 */
! 
! 	/*   TIME / PID    */
! 	if (props && props->processes[0]) {
! 
! 		int pid = props->processes[0]->item1;
!       		float proc_age = pid_age(pid);
! 
! 	       /* TIME */
! 		if (!nih_strcat_sprintf(&str, parent, " %8.2fd",proc_age)) {
  			nih_error_raise_no_memory ();
  			nih_free (str);
  			return NULL;
  		}
  
! 		if (!nih_strcat_sprintf(&str, parent, " %8d", pid)) {
! 			nih_error_raise_no_memory ();
! 			nih_free (str);
! 			return NULL;
! 		}
  
! 		 /* Prefix the service name with process if it's not one of the standard processes */
! 		if (strcmp (props->processes[0]->item0, "main")
! 			 && strcmp (props->processes[0]->item0, "pre-start")
! 			 && strcmp (props->processes[0]->item0, "post-stop")) {
! 			if (!nih_strcat_sprintf(&str, parent, "(%s) ", props->processes[0]->item0)) {
! 				nih_error_raise_no_memory ();
! 				nih_free (str);
! 				return NULL;
  			}
  		}
  	} else {
! 		/* there is no PID / process running */
! 
!  	       /* TIME - empty */
! 		if (!nih_strcat_sprintf(&str, parent, " %9s", "")) {
! 			nih_error_raise_no_memory ();
! 			nih_free (str);
! 			return NULL;
! 		}
! 
! 		/* PID - empty */
! 		if (!nih_strcat_sprintf(&str, parent, " %8s", "")) {
  			nih_error_raise_no_memory ();
  			nih_free (str);
  			return NULL;
  		}
  	}
  
+ 	/* Append the job name */
+ 	if (!nih_strcat_sprintf(&str, parent, " %s", 
+                       job_class_name)) {
+        		nih_error_raise_no_memory ();
+ 		nih_free (str);
+ 		return NULL;
+         }
+ 	/* Append the prop name if there is one */
+ 	if (props && *props->name) {
+ 		if (!nih_strcat_sprintf(&str, parent, " (%s)",
+ 			props->name)) {
+ 			nih_error_raise_no_memory ();
+ 			nih_free (str);
+ 			return NULL;
+ 		}
+ 	}
+ 
+         // nih_strcat_sprintf (&str, parent, "\n %26s %8d (%s)", "", 44, "test");
+ 	
+ 	/* Append each additional process */
+         if (props && props->processes[0]) {
+ 		for (JobProcessesElement **p = &props->processes[1];
+ 		     p && *p; p++) {
+ 			if (! nih_strcat_sprintf (&str, parent, "\n %26s %8d + (%s)",
+ 						  "",
+ 						  (*p)->item1,
+ 						  (*p)->item0)) {
+ 					nih_error_raise_no_memory ();
+ 					nih_free (str);
+ 					return NULL;
+ 			}
+ 		}
+ 	}
+ 
+ 
  	return str;
  }
  
