/*  Memory handling and a few global symbols

    ©1998,1999 Joseph Walton

    This software is distributed under the terms of the GNU General Public
    License; either version 2 of the License, or (at your option) any
    later version.
*/

#include "nfsd.h"
#include "memory.h"
#include "handle_list.h"

#include <string.h>

#include <dos/dos.h>

#include <exec/memory.h>
#include <clib/alib_protos.h>

#include <proto/exec.h>

/* All memory allocated comes from this pool */
static APTR mem_pool = NULL;

BOOL init_memory(struct nfsd_Global *g)
{
    if (mem_pool = CreatePool(MEMF_ANY, POOL_SIZE, (POOL_SIZE / 2))) {
        APTR recv_buffer = AllocVecPooled(RECV_BUFFER_BYTES),
             send_buffer = AllocVecPooled(SEND_BUFFER_BYTES);
        if (recv_buffer && send_buffer) {
            if (init_handle_list()) {
                NewList(&g->config);
                g->recv_buffer = recv_buffer;
                g->send_buffer = send_buffer;
                return TRUE;
            }
        }
    }

    /* Something failed */
    free_memory();
    return FALSE;
}

/* Just free the whole pool in one go - that's what they're for */
void free_memory()
{
    if (mem_pool) {
        DeletePool(mem_pool);
        mem_pool = NULL;
    }
}

/* Oh, I need these, so I might as well write 'em  in C */

#define SUL sizeof(ULONG)

/* Allocate memory and keep track of its size */
APTR AllocVecPooled(ULONG length)
{
    /* SAS is said to have problems with code like this. I hope
        this variant works */
    ULONG *mem = AllocPooled(mem_pool, length += SUL);
    if (mem) {
        *mem = length;
        mem++;
    }
    return mem;
}

/* Free memory allocated by the above method */
void FreeVecPooled(APTR mem)
{
    /* Ditto for here */
    if (mem) {
        ULONG *mem1 = (ULONG *)mem;
        mem1--;
        FreePooled(mem_pool, mem1, *mem1);
    }
}

#undef SUL

/* Utility function to duplicate a string */
STRPTR DupString(STRPTR orig)
{
    STRPTR new_str;

    if (!orig)
        return NULL;

    if (new_str = AllocVecPooled(strlen(orig) + 1)) {
        strcpy(new_str, orig);
    }

    return new_str;
}


