home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Gold Fish 2
/
goldfish_vol2_cd1.bin
/
files
/
util
/
misc
/
multiuser
/
src
/
library
/
misc.c
< prev
next >
Wrap
C/C++ Source or Header
|
1994-06-29
|
15KB
|
609 lines
/************************************************************
* MultiUser - MultiUser Task/File Support System *
* --------------------------------------------------------- *
* Miscellaneous Routines *
* --------------------------------------------------------- *
* © Copyright 1993-1994 Geert Uytterhoeven *
* All Rights Reserved. *
************************************************************/
#include <exec/execbase.h>
#include <utility/tagitem.h>
/*
* Password encryption
*
* This function must be defined here because its prototype in
* <clib/alib_protos.h> does not contain the __stdargs keyword
*/
extern STRPTR __stdargs ACrypt(STRPTR buffer, STRPTR password, STRPTR username);
#include <proto/exec.h>
#include <proto/dos.h>
#include <proto/intuition.h>
#include <proto/utility.h>
#include <proto/reqtools.h>
#include <proto/locale.h>
#include <libraries/reqtools.h>
#include <string.h>
#include "Memory.h"
#include "Server.h"
#include "Config.h"
#include "Locale.h"
#include "LibHeader.h"
#include "Misc.h"
#include "Task.h"
#include "Segment.h"
#include "Protection.h"
#include "UserInfo.h"
#include "Monitor.h"
/*
* Library Bases
*/
struct ExecBase *SysBase;
struct muBase *muBase;
struct DosLibrary *DOSBase = NULL;
struct IntuitionBase *IntuitionBase = NULL;
struct Library *UtilityBase = NULL;
struct ReqToolsBase *ReqToolsBase = NULL;
/*
* Library Vector Offsets for SetFunction()
*/
extern __far LVOAddTask;
extern __far LVORemTask;
extern __far LVOLoadSeg;
extern __far LVONewLoadSeg;
extern __far LVOUnLoadSeg;
extern __far LVOInternalLoadSeg;
extern __far LVOInternalUnLoadSeg;
extern __far LVOCreateProc;
extern __far LVOCreateNewProc;
extern __far LVORunCommand;
extern __far LVOSetProtection;
/*
* Initialisation
*/
BOOL Init(void)
{
struct Task *task;
/*
* Initialise Memory Management
*/
if (!InitMemory())
return(FALSE);
/*
* Initialise the Semaphores
*/
InitSemaphore(&muBase->TaskOwnerSem);
InitSemaphore(&muBase->SegOwnerSem);
InitSemaphore(&muBase->VolumesSem);
InitSemaphore(&muBase->MonitorSem);
/*
* Open dos.library, intuition.library and utility.library V37+,
* reqtools.library V38+ and create the Server
*/
if (!(DOSBase = (struct DosLibrary *)OpenLibrary("dos.library", 37)) ||
!(IntuitionBase = (struct IntuitionBase *)OpenLibrary("intuition.library", 37)) ||
!(UtilityBase = OpenLibrary("utility.library", 37)) ||
!(ReqToolsBase = (struct ReqToolsBase *)OpenLibrary("reqtools.library", 38)) ||
!CreateServer())
return(FALSE);
/*
* Open locale.library, if possible
*/
muBase->LogInfo.li_LocaleBase = OpenLibrary("locale.library",37);
/*
* Open Catalog for logfile output
*/
if (muBase->LogInfo.li_LocaleBase) {
muBase->LogInfo.li_Catalog = OpenCatalog(0,MULTIUSERCATALOGNAME,
OC_BuiltInLanguage,"english",
OC_Version,MULTIUSERCATALOGVERSION,
TAG_DONE);
}
/*
* Initialise Task Owner, Segment Owner and Monitor Lists
*/
InitTaskList();
InitSegList();
InitMonList();
/*
* Initialise Task Control
*/
NewList((struct List *)&muBase->Frozen);
/*
* Create Task/User list
*
* All tasks have no owner.
*/
Forbid();
CreateOrphanTask(SysBase->ThisTask, DEFPROTECTION);
for (task = (struct Task *)SysBase->TaskReady.lh_Head;
task->tc_Node.ln_Succ; task = (struct Task *)task->tc_Node.ln_Succ)
CreateOrphanTask(task, DEFPROTECTION);
for (task = (struct Task *)SysBase->TaskWait.lh_Head;
task->tc_Node.ln_Succ; task = (struct Task *)task->tc_Node.ln_Succ)
CreateOrphanTask(task, DEFPROTECTION);
/*
* Make sure the Server is owned by the system
*/
PushTask((struct Task *)muBase->Server, &RootExtOwner);
/*
* Patch exec.library functions:
*
* AddTask()
* RemTask()
*
* Patch dos.library functions:
*
* LoadSeg()
* NewLoadSeg()
* UnLoadSeg()
* InternalLoadSeg()
* InternalUnLoadSeg()
* CreateProc()
* CreateNewProc()
* RunCommand()
* SetProtection()
*
* This must be done inside this Forbid()/Permit() pair
* to prevent the birth of orphan-tasks
*/
muBase->OLDAddTask = SetFunction((struct Library *)SysBase,
(LONG)&LVOAddTask,
(ULONG (*)())NEWAddTask);
muBase->OLDRemTask = SetFunction((struct Library *)SysBase,
(LONG)&LVORemTask,
(ULONG (*)())NEWRemTask);
muBase->OLDLoadSeg = SetFunction((struct Library *)DOSBase,
(LONG)&LVOLoadSeg,
(ULONG (*)())NEWLoadSeg);
muBase->OLDNewLoadSeg = SetFunction((struct Library *)DOSBase,
(LONG)&LVONewLoadSeg,
(ULONG (*)())NEWNewLoadSeg);
muBase->OLDUnLoadSeg = SetFunction((struct Library *)DOSBase,
(LONG)&LVOUnLoadSeg,
(ULONG (*)())NEWUnLoadSeg);
muBase->OLDInternalLoadSeg = SetFunction((struct Library *)DOSBase,
(LONG)&LVOInternalLoadSeg,
(ULONG (*)())NEWInternalLoadSeg);
muBase->OLDInternalUnLoadSeg = SetFunction((struct Library *)DOSBase,
(LONG)&LVOInternalUnLoadSeg,
(ULONG (*)())NEWInternalUnLoadSeg);
muBase->OLDCreateProc = SetFunction((struct Library *)DOSBase,
(LONG)&LVOCreateProc,
(ULONG (*)())NEWCreateProc);
muBase->OLDCreateNewProc = SetFunction((struct Library *)DOSBase,
(LONG)&LVOCreateNewProc,
(ULONG (*)())NEWCreateNewProc);
muBase->OLDRunCommand = SetFunction((struct Library *)DOSBase,
(LONG)&LVORunCommand,
(ULONG (*)())NEWRunCommand);
muBase->OLDSetProtection = SetFunction((struct Library *)DOSBase,
(LONG)&LVOSetProtection,
(ULONG (*)())NEWSetProtection);
Permit();
/*
* Activate the Server
*/
if (!StartServer())
return(FALSE);
return(TRUE);
}
/*
* Clean Up
*/
BOOL CleanUp(void)
{
/*
* Kill the Server
*/
if (!KillServer())
return(FALSE);
/*
* Restore exec.library functions:
*
* AddTask()
* RemTask()
*
* Restore dos.library functions:
*
* LoadSeg()
* NewLoadSeg()
* UnLoadSeg()
* InternalLoadSeg()
* InternalUnLoadSeg()
* CreateProc()
* CreateNewProc()
* RunCommand()
* SetProtection()
*
* WARNING: This routine does NOT check for a pending patch
* by someone else!!
*/
if (muBase->OLDAddTask) {
SetFunction((struct Library *)SysBase, (LONG)&LVOAddTask,
(ULONG (*)())muBase->OLDAddTask);
muBase->OLDAddTask = NULL;
}
if (muBase->OLDRemTask) {
SetFunction((struct Library *)SysBase, (LONG)&LVORemTask,
(ULONG (*)())muBase->OLDRemTask);
muBase->OLDRemTask = NULL;
}
if (muBase->OLDLoadSeg) {
SetFunction((struct Library *)DOSBase, (LONG)&LVOLoadSeg,
(ULONG (*)())muBase->OLDLoadSeg);
muBase->OLDLoadSeg = NULL;
}
if (muBase->OLDNewLoadSeg) {
SetFunction((struct Library *)DOSBase, (LONG)&LVONewLoadSeg,
(ULONG (*)())muBase->OLDNewLoadSeg);
muBase->OLDNewLoadSeg = NULL;
}
if (muBase->OLDUnLoadSeg) {
SetFunction((struct Library *)DOSBase, (LONG)&LVOUnLoadSeg,
(ULONG (*)())muBase->OLDUnLoadSeg);
muBase->OLDUnLoadSeg = NULL;
}
if (muBase->OLDInternalLoadSeg) {
SetFunction((struct Library *)DOSBase, (LONG)&LVOInternalLoadSeg,
(ULONG (*)())muBase->OLDInternalLoadSeg);
muBase->OLDInternalLoadSeg = NULL;
}
if (muBase->OLDInternalUnLoadSeg) {
SetFunction((struct Library *)DOSBase, (LONG)&LVOInternalUnLoadSeg,
(ULONG (*)())muBase->OLDInternalUnLoadSeg);
muBase->OLDInternalUnLoadSeg = NULL;
}
if (muBase->OLDCreateProc) {
SetFunction((struct Library *)DOSBase, (LONG)&LVOCreateProc,
(ULONG (*)())muBase->OLDCreateProc);
muBase->OLDCreateProc = NULL;
}
if (muBase->OLDCreateNewProc) {
SetFunction((struct Library *)DOSBase, (LONG)&LVOCreateNewProc,
(ULONG (*)())muBase->OLDCreateNewProc);
muBase->OLDCreateNewProc = NULL;
}
if (muBase->OLDRunCommand) {
SetFunction((struct Library *)DOSBase, (LONG)&LVORunCommand,
(ULONG (*)())muBase->OLDRunCommand);
muBase->OLDRunCommand = NULL;
}
if (muBase->OLDSetProtection) {
SetFunction((struct Library *)DOSBase, (LONG)&LVOSetProtection,
(ULONG (*)())muBase->OLDSetProtection);
muBase->OLDSetProtection = NULL;
}
RemAllTaskNodes();
CleanUpMemory();
if (muBase->LogInfo.li_LocaleBase) {
CloseCatalog(muBase->LogInfo.li_Catalog);
CloseLibrary(muBase->LogInfo.li_LocaleBase);
}
if (ReqToolsBase)
CloseLibrary((struct Library *)ReqToolsBase);
if (UtilityBase)
CloseLibrary(UtilityBase);
if (IntuitionBase)
CloseLibrary((struct Library *)IntuitionBase);
if (DOSBase)
CloseLibrary((struct Library *)DOSBase);
return(TRUE);
}
/*
* Entry for Obsolete Library Functions
*/
ULONG __asm muOBSOLETE(void)
{
return(NULL);
}
/*
* Make a Rendez-Vous with the MultiUserFileSystem
*
* Private Library Function
*/
BOOL __asm __saveds muFSRendezVous(register __a6 struct muBase *muBase)
{
BOOL res = FALSE;
Forbid();
if (muBase->Server && muBase->ConsistencySig) {
Signal(muBase->Server, 1<<muBase->ConsistencySig);
res = TRUE;
}
Permit();
return(res);
}
/*
* Get a Shared Lock on the Directory of the Password File
*
* Public Library Function
*/
BPTR __asm __saveds muGetPasswdDirLock(void)
{
return((BPTR)SendServerPacket(muSAction_PasswdDirLock, NULL, NULL, NULL,
NULL));
}
/*
* Get a Shared Lock on the Directory of the Configuration File
*
* Public Library Function
*/
BPTR __asm __saveds muGetConfigDirLock(void)
{
return((BPTR)SendServerPacket(muSAction_ConfigDirLock, NULL, NULL, NULL,
NULL));
}
/*
* Interprete a Tag List
*/
BOOL InterpreteTagList(struct TagItem *taglist, struct muTags *tags)
{
struct TagItem *tstate = taglist;
struct TagItem *tag;
struct muExtOwner *xuser;
ULONG user;
BOOL res = TRUE;
/*
* Fill in the default values
*/
tags->Input = Input();
tags->Output = Output();
tags->PubScrName = NULL;
tags->Task = NULL;
tags->UserID = NULL;
tags->Password = NULL;
tags->DefProtection = DEFPROTECTION;
tags->Graphical = FALSE;
tags->Own = FALSE;
tags->Global = FALSE;
tags->Quiet = FALSE;
tags->All = FALSE;
tags->NoLog = FALSE;
/*
* Change them according to the tags
*/
if (taglist)
while (tag = NextTagItem(&tstate))
switch (tag->ti_Tag) {
case muT_Input:
tags->Input = (BPTR)tag->ti_Data;
break;
case muT_Output:
tags->Output = (BPTR)tag->ti_Data;
break;
case muT_PubScrName:
tags->PubScrName = (STRPTR)tag->ti_Data;
break;
case muT_Task:
tags->Task = (struct Task *)tag->ti_Data;
break;
case muT_UserID:
tags->UserID = (STRPTR)tag->ti_Data;
break;
case muT_Password:
tags->Password = (STRPTR)tag->ti_Data;
break;
case muT_DefProtection:
tags->DefProtection = (ULONG)tag->ti_Data;
break;
case muT_Graphical:
tags->Graphical = (BOOL)tag->ti_Data;
break;
case muT_Own:
tags->Own = (BOOL)tag->ti_Data;
break;
case muT_Global:
tags->Global = (BOOL)tag->ti_Data;
break;
case muT_Quiet:
tags->Quiet = (BOOL)tag->ti_Data;
break;
case muT_All:
tags->All = (BOOL)tag->ti_Data;
break;
case muT_NoLog:
tags->NoLog = (BOOL)tag->ti_Data;
break;
}
if (!tags->Task)
tags->Task = SysBase->ThisTask;
else if (tags->Task != SysBase->ThisTask) {
xuser = GetTaskExtOwner(SysBase->ThisTask);
user = GetTaskOwner(tags->Task);
if (!(muGetRelationshipA(xuser, user, NULL) & muRelF_UID_MATCH))
res = FALSE;
muFreeExtOwner(xuser);
}
if (tags->NoLog) {
xuser = GetTaskExtOwner(SysBase->ThisTask);
if (!muGetRelationshipA(xuser, NULL, NULL) & muRelF_ROOT_UID)
tags->NoLog = FALSE;
muFreeExtOwner(xuser);
}
if (tags->Graphical &&
(((struct Process *)SysBase->ThisTask)->pr_WindowPtr == (APTR)-1))
tags->Graphical = FALSE;
return(res);
}
/*
* Post a warning
*/
void Warn(STRPTR msg, APTR argarray)
{
struct rtHandlerInfo *hinfo;
ULONG sigs, timersig, ret;
struct MsgPort *timerport;
struct timerequest *timerequest;
struct LocaleInfo li;
if (timerport = CreateMsgPort()) {
if (timerequest = CreateIORequest(timerport,
sizeof(struct timerequest))) {
if (!OpenDevice(TIMERNAME, UNIT_VBLANK,
(struct IORequest *)timerequest, 0)) {
OpenLoc(&li);
if (rtEZRequestTags(msg, GetLocS(&li,MSG_RESUME), NULL, argarray,
RTEZ_ReqTitle, GetLocS(&li,MSG_WARNING_GUI),
RTEZ_Flags, EZREQF_CENTERTEXT,
RT_ReqPos, REQPOS_CENTERSCR,
RT_ReqHandler, &hinfo,
TAG_DONE) == CALL_HANDLER) {
timerequest->tr_node.io_Command = TR_ADDREQUEST;
timerequest->tr_time.tv_secs = 10;
timerequest->tr_time.tv_micro = 0;
SendIO((struct IORequest *)timerequest);
timersig = 1<<timerport->mp_SigBit;
do {
if (!hinfo->DoNotWait)
sigs = Wait(hinfo->WaitMask | timersig);
if (sigs & timersig)
ret = rtReqHandler(hinfo, sigs,
RTRH_EndRequest, TRUE, TAG_END);
else
ret = rtReqHandler(hinfo, sigs, TAG_END);
} while (ret == CALL_HANDLER);
AbortIO((struct IORequest *)timerequest);
WaitIO((struct IORequest *)timerequest);
}
CloseLoc(&li);
CloseDevice((struct IORequest*)timerequest);
}
DeleteIORequest(timerequest);
}
DeleteMsgPort(timerport);
}
}
/*
* Painless dead :-)
*/
void Die(STRPTR msg, ULONG code)
{
if (code)
Alert(code);
else {
static UBYTE string[] = {
0, 236, 19, 'M', 'u', 'l', 't', 'i', 'U', 's', 'e', 'r', ' ',
'F', 'a', 't', 'a', 'l', ' ',
'E', 'r', 'r', 'o', 'r', 0, 1,
0, 0, 35, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
};
int xpos;
xpos = 320-4*strlen(msg);
string[26] = xpos>>8;
string[27] = xpos & 0xff;
strncpy(&string[29], msg, 78);
DisplayBeep(NULL);
Delay(20);
DisplayAlert(RECOVERY_ALERT, string, 51);
}
for (;;)
Wait(NULL);
}
/*
* Encrypt a Password
*/
STRPTR Encrypt(STRPTR buffer, STRPTR pwd, STRPTR userid)
{
if (strlen(pwd))
return(ACrypt(buffer, pwd, userid));
else
return(memset(buffer, '\0', 12));
}