/**
   TASKPRI - lets the user change task priorities by specifying the
   task NAME.

   Author:  Steve Anderson

   Date:  August 3, 1991

   This program and the accompanying source is freeware and can be used,
   altered and ripped however you like.  Enjoy!
**/

#include <stdio.h>
#include <string.h>
#include <exec/types.h>
#include <exec/execbase.h>
#include <exec/tasks.h>

#ifdef LATTICE
#include <proto/exec.h>
int CXBRK(void) { return(0); }      /*  Disable Lattice CTRL/C handling  */
int chkabort(void) { return(0); }   /*  really  */
#endif

#define NAME_LIMIT 30
#define LIMIT 60

extern struct ExecBase *SysBase;
short main( int argc, char *argv[] );

short main( int argc, char *argv[] )
   {
      struct Task *task;
      char *name;
      char taskname[LIMIT][NAME_LIMIT];
      short taskpri[LIMIT];
      short pri;
      short acount = 1;
      short tcount;
      short tlimit;
      short nlimit = 0;
      short t;
      short DEFAULT = 0;  /*  0 = standard, 1 = no args, list tasks  */
      short LIST = 0;     /*  0 = TaskWait list, 1 = TaskReady list  */

      if ( argc == 1 )
         {
            DEFAULT = 1;    /*  no argument case  */
            --acount;       /*  set acount equal to zero  */
         }
      else if ( ((argc == 2) && (strcmp( argv[1], "?") == 0)) || (argc%2 != 1) )
         {
            puts("\n Usage:  TaskPri NAME PRIORITY [ [NAME PRIORITY] ... ]\n");
            exit(1);
         }

      while (acount < argc)                /*  while there are still arguments to process  */
         {
           /*  normal execution  */
            if (DEFAULT == 0)              /*  standard  */
               {
                 /*  set name string  */
                  name = argv[acount];

                 /*  convert pri argument to an integer  */
                  pri = (short)strtol( argv[acount+1], NULL, 10 );

                 /*  find task # in task list  */
                  tcount = acount/2 + 1;
                  tlimit = tcount - 1;

                 /*  find # of previous tasks with same name  */
                  for( t = tlimit; t > 0; t-- )
                     if ( strcmp(argv[tcount],argv[t]) )
                        --tcount;

               }  /*  end if  */

               Forbid();  /*  shut off task switching  */

              /*  search TaskWait/ThisTask lists for task names  */
               task = (struct Task *)SysBase->TaskWait.lh_Head;

               while ( task->tc_Node.ln_Succ )
                  {
                     if (DEFAULT == 1)                  /*  if there are no command line arguments */
                        {
                           if(strlen(task->tc_Node.ln_Name) > (NAME_LIMIT-1))
                              strncpy((char *)&taskname[nlimit][0],task->tc_Node.ln_Name,(NAME_LIMIT-1));
                           else
                              strcpy((char *)&taskname[nlimit][0],task->tc_Node.ln_Name);
                           taskpri[nlimit] = task->tc_Node.ln_Pri;
                           nlimit++;
                        }
                     else if ( !strcmp(name,task->tc_Node.ln_Name) )  /*  GOOD  */
                        {
                           if ( tcount > 1 )
                              {
                                 --tcount;
                              }
                           else
                              {
                                 SetTaskPri( task, pri );  /*  set new priority  */
                                 Permit();                 /*  re-activate task switching  */
                                 printf(" Name:  [33m%-30s[31m     Priority:  [33m%3d[31m\n", name, pri );
                                 Forbid();                 /* shut off task switching  */
                                 break;
                              }

                        }  /*  end else if  */

                    /*  increment to next item in list  */
                     task = (struct Task *)task->tc_Node.ln_Succ;

                    /*  check to see if TaskWait list is done  */
                     if ( !task->tc_Node.ln_Succ )
                        switch ( LIST )
                           {
                              case 0:
                                 LIST++;
                                 task = (struct Task *)SysBase->ThisTask;
                                 break;
                              case 1:
                                 LIST++;
                                 task = (struct Task *)SysBase->TaskReady.lh_Head;
                                 break;

                           }  /*  end if-switch  */

                  }  /*  end while loop  */

            Permit();           /*  re-activate task switching  */
            acount += 2;        /*  increment to next task  */

         }  /*  end while loop  */

      while ( (DEFAULT==1) && (nlimit>0) )      /*  PRINT tasks if no args  */
         {
            nlimit--;
            printf(" Name:  [33m%-30s[31m     Priority:  [33m%3d[31m\n", &taskname[nlimit][0], taskpri[nlimit] );

         }  /*  end while loop  */

   }  /*  end main loop  */

  /****************************  EOF  *********************************/
