
/*

    XDME seems to be nearly BugFree

    however, if there _is_ a bug left, and that Bug causes
    the XDME Process freeze, this module is a possibility
    to save the typed Data before resetting the machine ...

    We do define a possibility to access the Texts of one
    XDME Process from another.

    Please note, that Function is incompatible to Virtual
    Memory Mechanisms like e.g. VMM, since XDME allocates
    its Texts as !MEMF_GLOBAL Memory.

*/


#include "defs.h"

#define MAGIC_NAME "Access_to_XDME_Texts"

static LIST *sec_dbase[1];


DEFAUTOINIT( sec_init )
{
//puts (__FILE__);
    sec_dbase[0] = &DBase;
    SetVar(MAGIC_NAME, (void *)sec_dbase, sizeof(sec_dbase), LV_VAR | GVF_LOCAL_ONLY | GVF_BINARY_VAR);
}

DEFAUTOEXIT( sec_exit )
{
    DeleteVar(MAGIC_NAME, LV_VAR | GVF_LOCAL_ONLY | GVF_BINARY_VAR);
}

/* 1==port; 2==text; 3==file */
DEFUSERCMD("foreignsave", 3, 0, void, do_foreignsave, (void), )
{
    struct MsgPort  *mp;
    struct Process  *pr, *we;
    struct LocalVar *lv;
    UBYTE tc_state;
    ED *ed;

    pr = we = (struct Process *)FindTask(NULL);

    Forbid();
    mp = FindPort (av[1]);
    if (!mp) {
	Permit();
	error ("%s:\nCan't find foreign Port `%s'!", av[0], av[1]);
	return;
    } /* if */

    if (mp->mp_Flags != PA_SIGNAL) {
	Permit();
	error ("%s:\nForeign Port `%s' \ndoes not signal a Task!", av[0], av[1]);
	return;
    } /* if */

    pr = mp->mp_SigTask;

    if (((struct Node *)pr)->ln_Type != NT_PROCESS) {
	Permit();
	error ("%s:\nForeign Port `%s' \ndoes not signal a DOS Process!", av[0], av[1]);
	return;
    } /* if */

    // ---- let the other process sleep
    if (we != mp->mp_SigTask) {
	tc_state = pr->pr_Task.tc_State;
	pr->pr_Task.tc_State = TS_READY;
    } /* if */

    Permit();

    for (lv = GetHead (&pr->pr_LocalVars); lv; lv = GetSucc(lv)) {
	if ((lv->lv_Node.ln_Type != LV_VAR))
	    continue;
	if (strcmp (lv->lv_Node.ln_Name, MAGIC_NAME) == 0)
	    break;
    } /* for */

    if (!lv) {
	error ("%s:\nForeign Port `%s' \ndoes not signal an accessible XDME Process!", av[0], av[1]);
	goto sec_save_end;
    } /* if */

    for (ed = GetHead ((struct MinList *)lv->lv_Value); ed; ed = GetSucc(ed)) {
	if (stricmp(((struct Node *)ed)->ln_Name, av[2]) == 0) {
	    break;
	} /* if */
    } /* for */

    if (ed) {
	UBYTE *iav[2];
	BPTR our_dl;
	ED *our_ep;

	our_ep = Ep;
	Ep     = ed;

	iav[0] = av[0];
	av[0]  = "writeto";

	iav[1] = av[1];
	av[1]  = av[3];

	our_dl = CurrentDir(Ep->dirlock);

	do_writeto();

	Ep->dirlock = CurrentDir(our_dl);
	av[0]	    = iav[0];
	av[1]	    = iav[1];
	Ep	    = our_ep;
    } /* if */

sec_save_end:
    if (we != pr) {
	Forbid();
	pr->pr_Task.tc_State = tc_state;
	Permit();
    } /* if */
}

