#define __USE_SYSBASE   1

#include <exec/types.h>
#include <exec/nodes.h>
#include <exec/tasks.h>
#include <exec/execbase.h>
#include <proto/exec.h>
#include <dos/dosextens.h>
#include <dos.h>
#include <proto/dos.h>
#include <string.h>

struct Process *FindProc(char *name);


#define FORLIST(list,p) for ((p) = (void *)(list)->lh_Head;   \
                             ((struct Node *)(p))->ln_Succ;   \
                             (p) = (void *)((struct Node *)(p))->ln_Succ)

const char * VERSTAG = "$VER: SetPri 1.7 (9.7.94) © Richard Waspe 1994 ";


BOOL IsATask;
BYTE orgpri;

int main (void)
{
	LONG pri=0, oldpri=0;
	struct Task *TaskPtr = NULL;
   LONG Quiet = 0;
   struct RDArgs *rda;
   LONG vec[3];
   char * TaskName = NULL;
	vec[0] = 0;
	vec[1] = 0;
	vec[2] = 0;

	if (rda = ReadArgs("NAME/A,PRIORITY/A/N,Q=QUIET/S", vec, NULL) )
	{
   	TaskName = (char *)(vec[0]);
   	pri = *(LONG *)(vec[1]);
   	Quiet = vec[2];

   	if (pri <-50 || pri >19)
   	{
   		if (!Quiet)
   			PutStr("Requested priority out of range\n");
   		FreeArgs(rda);
   		return 10;
   	}

      Forbid();
		TaskPtr = (struct Task *)(FindProc(TaskName));

		if (TaskPtr == NULL)
		{
			Permit();
			if (!Quiet)
				Printf("%s not found\n", TaskName);
			FreeArgs(rda);
			return 20;
		}
		else
		{
   		if (orgpri != pri)
   			oldpri = SetTaskPri(TaskPtr, pri);
   		Permit();
   		if (!Quiet)
   		{
   			if (IsATask)
   				Printf("Task ");
   			else
   				Printf("Process ");
   			if (orgpri == pri)
   				Printf("%s was already at requested priority\n", TaskName);
   			else
   				Printf("%s priority changed from %ld to %ld\n", TaskName, oldpri, pri);
   		}
   		FreeArgs(rda);
   		return 0;
   	}
   }
   else
   	PrintFault(IoErr(), "ReadArgs() error");

   return 5;
}

struct Process *FindProc(char *name)
{
   struct Process *proc;
   struct List *tasklist[3];
   struct List **plist;
   int len = strlen(name);

   tasklist[0] = &SysBase->TaskWait;
   tasklist[1] = &SysBase->TaskReady;
   tasklist[2] = NULL;

   Disable();
   for (plist = tasklist; *plist != NULL; plist++)
   {
      FORLIST(*plist, proc)
      {
         if (proc->pr_Task.tc_Node.ln_Type != NT_PROCESS || proc->pr_CLI == 0)
         {
            if (stricmp(proc->pr_Task.tc_Node.ln_Name, name) == 0)
            {
               Enable();
               IsATask = (proc->pr_Task.tc_Node.ln_Type != NT_PROCESS);
               orgpri = proc->pr_Task.tc_Node.ln_Pri;
               return (proc);
            }
         }
         else
         {
            struct CommandLineInterface *cli = (void *)BADDR(proc->pr_CLI);
            unsigned char *cmdname = (void *)BADDR(cli->cli_CommandName);

            if (cmdname)
            {
               if (len <= *cmdname && strnicmp(cmdname + *cmdname + 1 - len,
                                              name, len) == 0)
					{
                  Enable();
                  orgpri = proc->pr_Task.tc_Node.ln_Pri;
                  IsATask = FALSE;
                  return (proc);
               }
            }
         }
      }
   }
   Enable();
   return (NULL);
}

