#include <exec/types.h>
#include <exec/tasks.h>
#include <exec/interrupts.h>
#include <libraries/dos.h>
#include <sys/types.h>
#include <sys/param.h>
#include <sys/time.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>

#include <user.h>

void dump_proc (char *);
extern struct ixemul_base *ixemulbase;

struct death_msg {
  struct MinNode	dm_node;
  struct Process	*dm_child;
  int			dm_pgrp;
  int			dm_status;
  struct rusage		dm_rusage;
};

#define PIPE_SIZE	5120

struct tmp_pipe {
  u_short	tp_flags;		/* see below */
  u_char	tp_buffer[PIPE_SIZE];
  u_char	*tp_reader, *tp_writer;	/* buffer pointers.
					   when tp_reader==tp_writer, no data
					   is available */
};

int
main (int argc, char *argv[])
{
  while (*++argv)
    dump_proc (*argv);

  return 0;
}

void
dump_proc (char *pid_str)
{
  pid_t pid = atoi (pid_str);
  struct Task *t;
  
  if ((t=(struct Task *)pid) && !(pid & 1) && 
      (t->tc_Node.ln_Type == NT_TASK || 
       t->tc_Node.ln_Type == NT_PROCESS))
    {
      struct user *p = (struct user *) t->tc_TrapData;
      struct death_msg *dm, *ndm;

      if (!p || ixemulbase != p->u_ixbase)
        fprintf (stderr, "process $%lx does not use ixemul.library.\n", t);
      else
	{
	  printf ("Process $%lx:\n", t);
	  printf ("  p_flag    = %d\n", p->p_flag);
	  printf ("  p_stat    = %d\n", p->p_stat);
	  printf ("  p_sig     = $%lx\n", p->p_sig);
	  printf ("  p_sigmask = $%lx\n", p->p_sigmask);
	  printf ("  p_sigign  = $%lx\n", p->p_sigignore);
	  printf ("  p_sigcat  = $%lx\n", p->p_sigcatch);
	  printf ("  p_wchan   = $%lx\n", p->p_wchan);
	  printf ("  p_wmesg   = %s\n", p->p_wmesg);
	  if (p->p_wmesg && (!strcmp (p->p_wmesg, "pread") || !strcmp (p->p_wmesg, "pwrite")))
	    {
	      struct tmp_pipe *tp = (struct tmp_pipe *) p->p_wchan;
	      printf ("    tmp_pipe:\n");
	      printf ("    tp_flags = $%lx, tp_reader = @%ld, tp_writer = @%ld\n",
		      tp->tp_flags, 
		      tp->tp_reader - tp->tp_buffer,
		      tp->tp_writer - tp->tp_buffer);
	    }
	  printf ("  p_zombies:\n");
	  for (dm  = (struct death_msg *) p->p_zombies.mlh_Head;
	       ndm = (struct death_msg *) dm->dm_node.mln_Succ;
	       dm  = ndm)
	    printf ("    pid=$%lx, pgrp=$%lx, status=$%lx\n",
	    	    dm->dm_child, dm->dm_pgrp, dm->dm_status);
	  printf ("  p_cptr    = $%lx\n", p->p_cptr);
	  printf ("\n");
	}
    }
}
