#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <proto/exec.h>
#include <dos/dos.h>
#include <dos/dosextens.h>
#include <exec/execbase.h>

char *ver="\0$VER: tasklist Snoopy Support Tool 1.1 (01.01.94)";
extern struct ExecBase *SysBase;

#define TYPE_TASK       0
#define TYPE_PROCESS    1

#define IS_CURRENT      0
#define IS_READY        1
#define IS_WAITING      2

char *GetTaskName( struct Task *t, int *type )
{
    if( t->tc_Node.ln_Type == NT_PROCESS )
    {
        struct Process *p = (struct Process *)t;
        struct CommandLineInterface *cli;
        static char buffer[256];
        char *cp,*dp;
        int i;

        if( p->pr_TaskNum == 0 )
            return t->tc_Node.ln_Name;

        cli = BADDR( p->pr_CLI );
        cp = BADDR( cli->cli_CommandName );
        dp = buffer;

        for( i=*cp++; i; i-- )
        {
            *dp++ = *cp++;
        }
        *dp=0;
        *type = TYPE_PROCESS;
        return buffer;
    }

    *type = TYPE_TASK;
    return t->tc_Node.ln_Name;
}

struct ti
    {
        struct ti *next;
        char *message;
        int type,mode;
        void *addr;
    };

struct ti *anchor = NULL;

void AddTaskInfo( struct Task *t, int mode )
{
    struct ti *n;

    if( ( n = (struct ti *)calloc( 1, sizeof( struct ti ) ) ) != NULL )
    {
        n->next = anchor;
        anchor = n;
        n->mode = mode;
        n->message = strdup( GetTaskName( t, &(n->type) ) );
        n->addr = t;
    }
} 

char *types[] =
    {
        "TASK    ",
        "PROCESS "
    };

char *modes[] =
    {
        "CURRENT ",
        "READY   ",
        "WAITING "
    };

void main( void )
{
    struct Node *np;
    struct ti *ptr;

    Forbid();
    AddTaskInfo( SysBase->ThisTask, IS_CURRENT );
    for( np = SysBase->TaskReady.lh_Head;
         np != (struct Node *)&(SysBase->TaskReady.lh_Tail);
         np = np->ln_Succ )
    {
        AddTaskInfo( (struct Task *)np, IS_READY );
    }
    for( np = SysBase->TaskWait.lh_Head;
         np != (struct Node *)&(SysBase->TaskWait.lh_Tail);
         np = np->ln_Succ )
    {
        AddTaskInfo( (struct Task *)np, IS_WAITING );
    }
    Permit();
    
    for( ptr=anchor; ptr != NULL; ptr = ptr->next )
        printf( "%08lx %s%s\"%s\"\n", ptr->addr, modes[ptr->mode], types[ptr->type], ptr->message );
}
