home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Gold Fish 2
/
goldfish_vol2_cd1.bin
/
files
/
util
/
misc
/
multiuser
/
src
/
support
/
tasks.c
< prev
next >
Wrap
C/C++ Source or Header
|
1994-03-04
|
7KB
|
256 lines
/************************************************************
* MultiUser - MultiUser Task/File Support System *
* --------------------------------------------------------- *
* Get Information about Tasks *
* --------------------------------------------------------- *
* © Copyright 1993-1994 Geert Uytterhoeven *
* All Rights Reserved. *
************************************************************/
#include <exec/memory.h>
#include <exec/execbase.h>
#include <proto/exec.h>
#include <proto/dos.h>
#include <string.h>
#include <libraries/multiuser.h>
#include <proto/multiuser.h>
#include <clib/alib_stdio_protos.h>
#include "Tasks_rev.h"
#include "Locale.h"
char __VersTag__[] = VERSTAG;
struct TaskInfo {
struct Task *Task;
char Name[32];
ULONG TaskNum;
UBYTE Type;
BYTE Priority;
UWORD uid;
};
static ULONG CountTasks(struct ExecBase *SysBase);
static BOOL FillTaskInfo(struct TaskInfo *tasks, ULONG maxtasks,
ULONG *numtasks, UWORD currentuid, BOOL all,
struct ExecBase *SysBase, struct muBase *muBase);
static BOOL FillIt(struct Task *task, struct TaskInfo *info, UWORD currentuid,
BOOL all, struct muBase *muBase);
static ULONG DumpTaskInfo(struct TaskInfo *tasks, ULONG numtasks,
struct DosLibrary *DOSBase, struct muBase *muBase,
struct LocaleInfo *li);
int __saveds Start(char *arg)
{
struct ExecBase *SysBase;
struct DosLibrary *DOSBase;
struct muBase *muBase = NULL;
struct RDArgs *args;
LONG argarray[] = {
NULL, NULL
};
UWORD currentuid;
struct TaskInfo *tasks;
ULONG maxtasks, numtasks;
struct muUserInfo *info;
LONG error = NULL;
int rc;
struct LocaleInfo li;
SysBase = *(struct ExecBase **)4;
if ((!(DOSBase = (struct DosLibrary *)OpenLibrary("dos.library", 37))) ||
(!(muBase = (struct muBase *)OpenLibrary("multiuser.library", 39)))) {
rc = ERROR_INVALID_RESIDENT_LIBRARY;
goto Exit;
}
OpenLoc(&li);
args = ReadArgs("USERID,ALL/S", argarray, NULL);
if (!args)
error = IoErr();
else {
if (!argarray[0])
currentuid = muGetTaskOwner(NULL)>>16;
else if (info = muAllocUserInfo()) {
strncpy(info->UserID, (char *)argarray[0], muUSERIDSIZE-1);
info->UserID[muUSERIDSIZE-1] = '\0';
if (muGetUserInfo(info, muKeyType_UserID))
currentuid = info->uid;
else {
VPrintf(GetLocS(&li,MSG_UNKNOWN_USER), &argarray[0]);
goto Fail;
}
muFreeUserInfo(info);
} else {
error = IoErr();
goto Fail;
}
do {
maxtasks = CountTasks(SysBase)+5;
if (tasks = AllocVec(maxtasks*sizeof(struct TaskInfo), MEMF_CLEAR)) {
if (FillTaskInfo(tasks, maxtasks, &numtasks, currentuid,
(BOOL)argarray[1], SysBase, muBase)) {
error = DumpTaskInfo(tasks, numtasks, DOSBase, muBase, &li);
rc = RETURN_OK;
} else
rc = RETURN_ERROR;
FreeVec(tasks);
} else
error = IoErr();
} while (!error && (rc != RETURN_OK));
}
FreeArgs(args);
Fail:
if (error) {
PrintFault(error, NULL);
rc = RETURN_ERROR;
}
CloseLoc(&li);
Exit:
CloseLibrary((struct Library *)muBase);
CloseLibrary((struct Library *)DOSBase);
return(rc);
}
/*
* Count the number of tasks in the system
*/
static ULONG CountTasks(struct ExecBase *SysBase)
{
ULONG i = 1;
struct Task *task;
Disable();
for (task = (struct Task *)SysBase->TaskReady.lh_Head;
task->tc_Node.ln_Succ; task = (struct Task *)task->tc_Node.ln_Succ)
i++;
for (task = (struct Task *)SysBase->TaskWait.lh_Head;
task->tc_Node.ln_Succ; task = (struct Task *)task->tc_Node.ln_Succ)
i++;
Enable();
return(i);
}
/*
* Fill in information about the tasks
*/
static BOOL FillTaskInfo(struct TaskInfo *tasks, ULONG maxtasks,
ULONG *numtasks, UWORD currentuid, BOOL all,
struct ExecBase *SysBase, struct muBase *muBase)
{
BOOL rc = TRUE;
struct Task *task;
*numtasks = 0;
Disable();
if (FillIt(SysBase->ThisTask, &tasks[*numtasks], currentuid, all, muBase))
(*numtasks)++;
for (task = (struct Task *)SysBase->TaskReady.lh_Head;
(task->tc_Node.ln_Succ) && (*numtasks < maxtasks);
task = (struct Task *)task->tc_Node.ln_Succ)
if (FillIt(task, &tasks[*numtasks], currentuid, all, muBase))
(*numtasks)++;
if (task->tc_Node.ln_Succ)
rc = FALSE;
else {
for (task = (struct Task *)SysBase->TaskWait.lh_Head;
(task->tc_Node.ln_Succ) && (*numtasks < maxtasks);
task = (struct Task *)task->tc_Node.ln_Succ)
if (FillIt(task, &tasks[*numtasks], currentuid, all, muBase))
(*numtasks)++;
if (task->tc_Node.ln_Succ)
rc = FALSE;
}
Enable();
return(rc);
}
static BOOL FillIt(struct Task *task, struct TaskInfo *info, UWORD currentuid,
BOOL all, struct muBase *muBase)
{
UWORD uid;
struct CommandLineInterface *cli;
char *name;
ULONG i;
uid = muGetTaskOwner(task)>>16;
if (all || (uid == currentuid)) {
info->Task = task;
if (((info->Type = task->tc_Node.ln_Type) == NT_PROCESS) &&
(info->TaskNum = ((struct Process *)task)->pr_TaskNum) &&
(cli = (struct CommandLineInterface *)BADDR(((struct Process *)task)->pr_CLI)) &&
(name = BADDR(cli->cli_CommandName)) && name[0]) {
for (i = 0; (i < name[0]) && (i < 31); i++)
info->Name[i] = name[i+1];
info->Name[i] = '\0';
} else {
strncpy(info->Name, task->tc_Node.ln_Name, 31);
info->Name[31] = '\0';
}
info->Priority = task->tc_Node.ln_Pri;
info->uid = uid;
return(TRUE);
} else
return(FALSE);
}
/*
* Dump the information
*/
static ULONG DumpTaskInfo(struct TaskInfo *tasks, ULONG numtasks,
struct DosLibrary *DOSBase, struct muBase *muBase,
struct LocaleInfo *li)
{
struct muUserInfo *info;
ULONG error = NULL;
ULONG i;
LONG stream[5];
UBYTE typebuff[40]; /* should be enough ! */
if (info = muAllocUserInfo()) {
PutStr(GetLocS(li,MSG_TFORMAT_HEAD1));
PutStr(GetLocS(li,MSG_TFORMAT_HEAD2));
for (i= 0; (i < numtasks) && !CheckSignal(SIGBREAKF_CTRL_C); i++) {
if (tasks[i].Type == NT_PROCESS)
if (tasks[i].TaskNum) {
sprintf(typebuff,GetLocS(li,MSG_CLI), tasks[i].TaskNum);
stream[0] = (LONG)typebuff;
}
else
stream[0] = (LONG)GetLocS(li,MSG_PROC);
else
stream[0] = (LONG)GetLocS(li,MSG_TASK);
stream[1] = (LONG)tasks[i].Task;
stream[2] = (LONG)tasks[i].Priority;
stream[3] = (LONG)tasks[i].Name;
if ((info->uid = tasks[i].uid) == muOWNER_NOBODY)
stream[4] = (LONG)"";
else if (muGetUserInfo(info, muKeyType_uid))
stream[4] = (LONG)info->UserID;
else
stream[4] = (LONG)"???";
VPrintf(GetLocS(li,MSG_TFORMAT_LINE), stream);
}
muFreeUserInfo(info);
} else
error = IoErr();
return(error);
}