/**********************************************************************
 
        Copyright (C) 2003 Hirohisa MORI <joshua@nichibun.ac.jp>
 
        This program is free software; you can redistribute it 
        and/or modify it under the terms of the GLOBALBASE 
        Library General Public License (G-LGPL) as published by 

        http://www.globalbase.org/
 
        This program is distributed in the hope that it will be 
        useful, but WITHOUT ANY WARRANTY; without even the 
        implied warranty of MERCHANTABILITY or FITNESS FOR A 
        PARTICULAR PURPOSE.

**********************************************************************/

#include        <stdlib.h>
#include        "memory_debug.h"
#include        "ex_matrix.h"


EX_MATRIX *
new_ex_matrix(int v,int h)
{
EX_MATRIX * ret;
EX_MATRIX m;
int size,i;
        m.h_size = h;
        m.v_size = v;
        ret = d_alloc(size=((int)(&XD(&m,v,0)))-((int)&m));
        for ( i = 0 ; i < h*v ; i ++ )
                ret->d[i] = 0;
        ret->h_size = h;
        ret->v_size = v;

        return ret;
}

void
free_ex_matrix(EX_MATRIX * m)
{
        d_f_ree(m);
}

EX_MATRIX *
add_ex(EX_MATRIX * m1,EX_MATRIX * m2)
{
int i;
EX_MATRIX * ret;
int h,v;
        if ( m1->h_size != m2->h_size )
                return 0;
        if ( m1->v_size != m2->v_size )
                return 0;
        h = m1->h_size;
        v = m1->v_size;
        ret = new_ex_matrix(v,h);
        for ( i = 0 ; i < m1->h_size * m1->v_size ; i ++ )
                ret->d[i] = m1->d[i] + m2->d[i];
        return ret;
}

EX_MATRIX *
sub_ex(EX_MATRIX * m1,EX_MATRIX * m2)
{
_Matrix.c___________________________________________________________________________1

int i;
EX_MATRIX * ret;
int h,v;

        if ( m2 ) {
                if ( m1->h_size != m2->h_size )
                        return 0;
                if ( m1->v_size != m2->v_size )
                        return 0;
                h = m1->h_size;
                v = m1->v_size;
                ret = new_ex_matrix(v,h);
                for ( i = 0 ; i < m1->h_size * m1->v_size ; i ++ )
                        ret->d[i] = m1->d[i] - m2->d[i];
                return ret;
        }
        else {
                h = m1->h_size;
                v = m1->v_size;
                ret = new_ex_matrix(v,h);
                for ( i = 0 ; i < m1->h_size * m1->v_size ; i ++ )
                        ret->d[i] =  - m1->d[i];
                return ret;
        }
}

EX_MATRIX * 
mul_ex(EX_MATRIX * m1,EX_MATRIX * m2)
{
EX_MATRIX * ret;
int x,y,i,len;
int h,v;
double acc;
        if ( m1->h_size != m2->v_size )
                return 0;
        len = m1->h_size;
        ret = new_ex_matrix(v = m1->v_size,h = m2->h_size);
        for ( x = 0 ; x < h ; x ++ )
                for ( y = 0 ; y < v ; y ++ ) {
                        acc = 0;
                        for ( i= 0 ; i < len ; i ++ )
                                acc += XD(m1,y,i)*XD(m2,i,x);
                        XD(ret,y,x) = acc;
                }
        return ret;
}

double
inner_ex(int * er,EX_MATRIX * m1,EX_MATRIX * m2)
{
double ret;
int i,size;
        *er = -1;

        if ( m1->h_size != m2->h_size )
                return 0;
        if ( m1->v_size != m2->v_size )
                return 0;
        if ( m1->h_size != 1 && m1->v_size != 1 )
                return 0;
        size = m1->h_size* m1->v_size;
        ret = 0;
        for ( i = 0 ; i < size ; i ++ )
                ret += m1->d[i] * m2->d[i];
        *er = 0;
        return ret;
_Matrix.c___________________________________________________________________________2

}


EX_MATRIX *
get_ex_from_sexp(XL_SEXP * s)
{
XL_SEXP * sym;
L_CHAR * h, * v;
int _h,_v;
EX_MATRIX * ret;
int i;
XL_SEXP * d;

        if ( get_type(s) != XLT_PAIR )
                return 0;
        sym = car(s);
        if ( get_type(sym) != XLT_SYMBOL )
                return 0;
        h = get_sf_attribute(sym->symbol.field,l_string(std_cm,"h"));
        v = get_sf_attribute(sym->symbol.field,l_string(std_cm,"v"));
        if ( h )
                _h = atoi(n_string(std_cm,h));
        else    _h = 1;
        if ( _h == 0 )
                _h = 1;
        if ( v )
                _v = atoi(n_string(std_cm,v));
        else    _v = 1;
        if ( _v == 0 )
                _v = 1;
        ret = new_ex_matrix(_v,_h);
        s = cdr(s);
        for ( i = 0 ; i < _v*_h ; i ++ , s = cdr(s) ) {
                if ( get_type(s) != XLT_PAIR )
                        goto err;
                d = car(s);
                switch ( get_type(d) ) {
                case XLT_INTEGER:
                        ret->d[i] = d->integer.data;
                        break;
                case XLT_FLOAT:
                        ret->d[i] = d->floating.data;
                        break;
                default:
                        goto err;
                }
        }
        return ret;
err:
        free_ex_matrix(ret);
        return 0;
}

XL_SEXP *
get_sexp_from_ex(EX_MATRIX * m)
{
XL_SEXP * ret;
XL_SEXP * sym;
char buf[10];
int total,i;

        sym = n_get_symbol("matrix");
        sprintf(buf,"%i",m->v_size);
        set_attribute(sym,
                l_string(std_cm,"v"),
                l_string(std_cm,buf));
_Matrix.c___________________________________________________________________________3

        sprintf(buf,"%i",m->h_size);
        set_attribute(sym,
                l_string(std_cm,"h"),
                l_string(std_cm,buf));
        ret = cons(sym,0);
        total = m->v_size*m->h_size;
        for ( i = 0 ; i < total ; i ++ )
                ret = cons(get_floating(m->d[i],0),ret);
        return reverse(ret);
}
























































_Matrix.c___________________________________________________________________________4

/**********************************************************************
 
        Copyright (C) 2003 Hirohisa MORI <joshua@nichibun.ac.jp>
 
        This program is free software; you can redistribute it 
        and/or modify it under the terms of the GLOBALBASE 
        Library General Public License (G-LGPL) as published by 

        http://www.globalbase.org/
 
        This program is distributed in the hope that it will be 
        useful, but WITHOUT ANY WARRANTY; without even the 
        implied warranty of MERCHANTABILITY or FITNESS FOR A 
        PARTICULAR PURPOSE.

**********************************************************************/



#include        "machine/include.h"
#include        "memory_debug.h"
#include        "task.h"
#include        "utils.h"
#include        "server.h"


extern SEM netutils_lock;

void
init_access_permission(ACCESS_PERMISSION * ap)
{
        ap->head = ap->tail = 0;
}

void
free_access_list(ACCESS_PERMISSION * ap)
{
ACCESS_LIST * al;
        for ( ; ap->head ; ) {
                al = ap->head;
                ap->head = al->next;

                if ( al->domain )
                        d_f_ree(al->domain);
                d_f_ree(al);
        }
}

void
insert_access_list(
        ACCESS_PERMISSION * ap,
        int     ip,
        int     mask,
        char *  domain,
        int     auth_type,
        int     auth_flags,
        int     type)
{
ACCESS_LIST * al;
        al = d_alloc(sizeof(*al));
        memset(al,0,sizeof(*al));
        al->ip = ip;
        al->mask = mask;
        if ( ip )
                al->domain = 0;
        else if ( domain == 0 ) {
access.c____________________________________________________________________________1

                al->ip = 0;
                al->mask = 0;
                al->domain = 0;
        }
        else {
                al->domain = copy_str(domain);
        }
        al->type = type;

        al->next = 0;
        if ( ap->head ) {
                ap->tail->next = al;
                ap->tail = al;
        }
        else {
                ap->head = ap->tail = al;
        }
}

extern int accept_test;

int
check_permission(ACCESS_PERMISSION * ap,int ip,L_CHAR* user)
{
HOST_ENTRY * hp;
char ** q;
ACCESS_LIST * al;
int len1,len2;
int ip_addr;

        ip_addr = ip;
        hp = r_gethostbyaddr(getHA_v4(ip_addr));
        
        for ( al = ap->head ; al ; al = al->next ) {
                if ( al->ip ) {
                        if ( (ip&al->mask) == al->ip ) {
                                return al->type;
                        }
                        continue;
                }
                if ( al->domain == 0 ) {
                        return al->type;
                }
                if ( hp == 0 )
                        continue;
                len1 = strlen(al->domain);
                q = hp->names;
                for ( ; *q ; q ++ ) {
                        len2 = strlen(*q);
                        if ( len2 < len1 )
                                continue;
                        if ( strcmp(&(*q)[len2-len1],al->domain)
                                        == 0 ) {
                                if ( len2 == len1 ) {
                                        return al->type;
                                }
                                if ( (*q)[len2-len1-1] == '.' ) {
                                        return al->type;
                                }
                        }
                }
        }
        return AP_DENY;
}


access.c____________________________________________________________________________2

/**********************************************************************
 
        Copyright (C) 2003 Hirohisa MORI <joshua@nichibun.ac.jp>
 
        This program is free software; you can redistribute it 
        and/or modify it under the terms of the GLOBALBASE 
        Library General Public License (G-LGPL) as published by 

        http://www.globalbase.org/
 
        This program is distributed in the hope that it will be 
        useful, but WITHOUT ANY WARRANTY; without even the 
        implied warranty of MERCHANTABILITY or FITNESS FOR A 
        PARTICULAR PURPOSE.

**********************************************************************/



#include        "memory_debug.h"
#include        "blacklist.h"
#include        "utils.h"
#include        "client.h"
#include        "machine/err.h"

typedef struct new_connection_cmd {
        BL_CMD          c;
        int *           cerr;
        char *          hostname;
        int             ip;
        short           port;
        int             (*func)();
        void *          work;

        STREAM *        ret;
} NEW_CONNECTION_CMD;

int _new_connect_retry(BLACKLIST * bl);
int _new_connect_proc(BLACKLIST * bl,NEW_CONNECTION_CMD * c);

int
_new_connect_retry(BLACKLIST * bl)
{
int ret;
STREAM * _ret;
int ip;
char * hostname;
int *ipp;
int cerr;
        if ( ((char*)bl->name)[0] == 0 ) {
                hostname = 0;
                ipp = (int*)bl->name;
                ip = ipp[1];
        }
        else {
                hostname = bl->name;
                ip = 0;
        }
        cerr = 0;
        _ret = new_connection(
                        &cerr,
                        hostname,
                        ip,
                        bl->port,
                        0,0);
        if ( _ret )
bl_new_connection.c_________________________________________________________________1

                s_close(_ret);
        if ( cerr == ESYS_CTIMEOUT )
                ret = BLS_ERROR;
        else    ret = BLS_OK;
        return ret;
}

int
_new_connect_proc(BLACKLIST * bl,NEW_CONNECTION_CMD * c)
{
int ret;
        bl->port = c->port;
        if ( bl->state[BLT_RESOLVE].state == BLS_ERROR )
                return BLS_ERROR;
        *c->cerr = 0;
        c->ret = new_connection(
                        c->cerr,
                        c->hostname,
                        c->ip,
                        c->port,
                        c->func,
                        c->work);
        if ( *c->cerr == ESYS_CTIMEOUT )
                ret = BLS_ERROR;
        else    ret = BLS_OK;
        bl->polling_interval = 0;
        return ret;
}

STREAM *
bl_new_connection(
        int * cerr,
        char * hostname,
        int ip,
        short port,
        int (*func)(),
        void * work)
{
NEW_CONNECTION_CMD      c;
int * ipp;

        c.cerr = cerr;
        c.hostname = hostname;
        c.ip = ip;
        c.port = port;
        c.func = func;
        c.work = work;
        c.ret = 0;
        if ( hostname ) {
                c.c.name = copy_str(hostname);
                c.c.name_len = strlen(c.c.name)+1;
        }
        else {
                ipp = d_alloc(sizeof(int)*2);
                ipp[0] = 0;
                ipp[1] = ip;
                c.c.name = (char*)ipp;
                c.c.name_len = 2*sizeof(int);
        }
        c.c.retry = _new_connect_retry;
        c.c.proc = _new_connect_proc;
        c.c.type = BLT_CONNECT;

        bl_do(&c);

        d_f_ree(c.c.name);
bl_new_connection.c_________________________________________________________________2

        return c.ret;
}
































































bl_new_connection.c_________________________________________________________________3

/**********************************************************************
 
        Copyright (C) 2003 Hirohisa MORI <joshua@nichibun.ac.jp>
 
        This program is free software; you can redistribute it 
        and/or modify it under the terms of the GLOBALBASE 
        Library General Public License (G-LGPL) as published by 

        http://www.globalbase.org/
 
        This program is distributed in the hope that it will be 
        useful, but WITHOUT ANY WARRANTY; without even the 
        implied warranty of MERCHANTABILITY or FITNESS FOR A 
        PARTICULAR PURPOSE.

**********************************************************************/



#include        "memory_debug.h"
#include        "task.h"
#include        "utils.h"
#include        "lock_level.h"
#include        "blacklist.h"
#include        "pri_level.h"

SEM blacklist_lock;
BLACKLIST *     blacklist_head;

void bl_task();
int bl_flag = 0;

void
init_blacklist()
{
if ( bl_flag )
er_panic("init_blacklist");
bl_flag = 1;
        blacklist_lock = new_lock(LL_BL);
        create_task(bl_task,0,PRI_BL);
}


int
name_cmp(void * n1,int len1,void * n2,int len2)
{
        if ( len1 != len2 )
                return -1;
        if ( memcmp(n1,n2,len1) == 0 )
                return 0;
        return -1;
}

BLACKLIST *
_search_bl(void * name,int name_len)
{
BLACKLIST *ret;
int i;
        for ( ret = blacklist_head ; ret ; ret = ret->next )
                if ( name_cmp(name,name_len,ret->name,ret->name_len) == 0 )
                        return ret;
        ret = d_alloc(sizeof(*ret));
        ret->name = d_alloc(name_len);
        memcpy(ret->name,name,name_len);
        ret->name_len = name_len;
        for ( i = 0 ; i < BLT_MAX ; i ++ ) {
blacklist.c_________________________________________________________________________1

                ret->state[i].state = BLS_OK;
                ret->state[i].func = 0;
        }
        ret->polling_time = get_xltime();
        ret->polling_interval = 0;
        ret->polling_initial = 0;

        ret->next = blacklist_head;
        blacklist_head = ret;
        return ret;
}

#define BLT_SIZE        4
int bl_trace[BLT_SIZE];
int bl_trace_ptr;

void
set_bl_trace(int a)
{
        bl_trace[bl_trace_ptr] = a;
        bl_trace_ptr = (bl_trace_ptr + 1) % 4;
}


BLACKLIST **
scan_bl(BLACKLIST ** blp)
{
BLACKLIST * bl;
int i;
int f;
int ret;


        bl = *blp;
        f = 0;
        for ( i = 0 ; i < BLT_MAX ; i ++ )
                if ( bl->state[i].state != BLS_OK )
                        f = 1;
        if ( f == 0 ) {
                *blp = bl->next;
                d_f_ree(bl->name);
                d_f_ree(bl);
set_bl_trace(1);
                return blp;
        }
        for ( i = 0 ; i < BLT_MAX ; i ++ ) {
                if ( bl->state[i].state == BLS_ERROR )
                        break;
        }
        if ( i == BLT_MAX )
{set_bl_trace(2);
                return &bl->next;
}
        if ( bl->polling_time > get_xltime() )
{set_bl_trace(3);
                return &bl->next;
}

        unlock_task(blacklist_lock,"scan_bl");
        ret = (*bl->state[i].func)(bl,(void*)0);

        lock_task(blacklist_lock);
        bl->state[i].state = ret;
        bl->polling_time = get_xltime() + bl->polling_interval;
        if ( bl->polling_interval == 0 )
                bl->polling_interval = 1;
blacklist.c_________________________________________________________________________2

        else    bl->polling_interval *= 2;
        if ( bl->polling_interval > BL_INTERVAL_MAX ) {
                bl->state[i].state = BLS_OK;
set_bl_trace(4);
                return &bl->next;
        }
set_bl_trace(5);
        return &bl->next;
}

void
bl_task()
{
BLACKLIST ** blp;
        for ( ; ; ) {
                lock_task(blacklist_lock);
set_bl_trace(0);
                blp = &blacklist_head;
                for ( ; ; ) {
                        if ( *blp == 0 )
                                break;

                        blp = scan_bl(blp);

                }
                unlock_task(blacklist_lock,"bl_task");
                sleep_sec(1);
        }
}




int
bl_do(void * cmd)
{
BLACKLIST * bl;
int ret;
BL_STATE * s;
BL_CMD * _cmd;
unsigned int t;

        _cmd = (BL_CMD*)cmd;
retry:

        lock_task(blacklist_lock);

        bl = _search_bl(_cmd->name,_cmd->name_len);

        s = &bl->state[_cmd->type];

        s->func = _cmd->retry;
        switch ( s->state ) {
        case BLS_OK:
                s->state = BLS_PROCESSING;
                unlock_task(blacklist_lock,"bl_do");

                ret = (*_cmd->proc)(bl,cmd);

                lock_task(blacklist_lock);
                s->state = ret;
                if ( ret == BLS_ERROR ) {
                        bl->polling_interval = bl->polling_initial;
                        bl->polling_time = get_xltime() + bl->polling_initial;
                }
                wakeup_task((int)s);
blacklist.c_________________________________________________________________________3

                break;
        case BLS_PROCESSING:
                sleep_task((int)s,blacklist_lock);
                goto retry;
        case BLS_ERROR:
/*
ss_printf("BLS_ERROR %i\n",get_tid());
*/
                ret = BLS_ERROR;
                bl->polling_interval = bl->polling_initial;
                t = get_xltime() + bl->polling_interval;
                if ( bl->polling_time > t )
                        bl->polling_time = t;
                break;
        default:
                er_panic("bl_do(1)");
        }

        unlock_task(blacklist_lock,"bl_do");
        return ret;
}













































blacklist.c_________________________________________________________________________4

/**********************************************************************
 
        Copyright (C) 2003 Hirohisa MORI <joshua@nichibun.ac.jp>
 
        This program is free software; you can redistribute it 
        and/or modify it under the terms of the GLOBALBASE 
        Library General Public License (G-LGPL) as published by 

        http://www.globalbase.org/
 
        This program is distributed in the hope that it will be 
        useful, but WITHOUT ANY WARRANTY; without even the 
        implied warranty of MERCHANTABILITY or FITNESS FOR A 
        PARTICULAR PURPOSE.

**********************************************************************/

#include        "memory_debug.h"
#include        "utils.h"

void
clean_empty_dir(L_CHAR * dir,int base_len)
{
DIR * dd;
struct dirent * d;
L_CHAR * dir_path;
int i;

        if ( l_strlen(dir) <= base_len )
                return; 
        dd = u_opendir(n_string(std_cm,dir));
        if ( dd == 0 )
                return;
        for ( ; ; ) {
                d = u_readdir(dd);
                if ( d == 0 )
                        break;
                if ( d->d_name[0] == '.' )
                        continue;
                closedir(dd);
                return;
        }
        closedir(dd);
        u_unlink(n_string(std_cm,dir));
        dir_path = ll_copy_str(dir);
        for ( i = l_strlen(dir)-1 ; i >= 0 && dir_path[i] != '/' ; i -- );
        if (  i > 0 ) {
                dir_path[i] = 0;
                clean_empty_dir(dir_path,base_len);
        }
        d_f_ree(dir_path);
        return;
}













clean_empty_dir.c___________________________________________________________________1

/**********************************************************************
 
        Copyright (C) 2003 Hirohisa MORI <joshua@nichibun.ac.jp>
 
        This program is free software; you can redistribute it 
        and/or modify it under the terms of the GLOBALBASE 
        Library General Public License (G-LGPL) as published by 

        http://www.globalbase.org/
 
        This program is distributed in the hope that it will be 
        useful, but WITHOUT ANY WARRANTY; without even the 
        implied warranty of MERCHANTABILITY or FITNESS FOR A 
        PARTICULAR PURPOSE.

**********************************************************************/



#include        "utils.h"


int
cmp_part(L_CHAR * target,L_CHAR * data)
{
int len_target,len_data;
int ofs;

        len_target = l_strlen(target);
        len_data = l_strlen(data);
        for ( ofs = 0 ; ofs <= len_target - len_data ; ofs ++ ) {
                if ( memcmp(&target[ofs],data,len_data*sizeof(L_CHAR)) == 0 )
                        return 1;
        }
        return 0;
}






























cmp_part.c__________________________________________________________________________1

/**********************************************************************
 
        Copyright (C) 2003 Hirohisa MORI <joshua@nichibun.ac.jp>
 
        This program is free software; you can redistribute it 
        and/or modify it under the terms of the GLOBALBASE 
        Library General Public License (G-LGPL) as published by 

        http://www.globalbase.org/
 
        This program is distributed in the hope that it will be 
        useful, but WITHOUT ANY WARRANTY; without even the 
        implied warranty of MERCHANTABILITY or FITNESS FOR A 
        PARTICULAR PURPOSE.

**********************************************************************/


#include "memory_debug.h"
#include "utils.h"


L_CHAR *
compose_path(L_CHAR * d1,L_CHAR * d2)
{
L_CHAR * buf;
int p1;
L_CHAR * ret;
        if ( d2 == 0 || d1 == 0 )
                return 0;
        if ( d2[0] == '/' ) {
                ret = ll_copy_str(d2);
                return ret;
        }
        buf = d_alloc((l_strlen(d1)+l_strlen(d2)+1)*sizeof(L_CHAR));
        l_strcpy(buf,d1);
        p1 = l_strlen(buf);
        if ( p1 > 0 && buf[p1-1] != '/' ) {
                p1 --;
                for ( ; p1 >= 0 && buf[p1] != '/' ; p1 -- );
                if ( p1 < 0 ) {
                        d_f_ree(buf);
                        ret = ll_copy_str(d2);
                        return ret;
                }
                p1 ++;
        }
        for ( ; ; ) {
                if ( *d2 == 0 )
                        break;
                if ( *d2 != '.' )
                        break;
                d2 ++;
                if ( *d2 == '.' ) {
                        d2 ++;
                        if ( *d2 != '/' )
                                return 0;
                        d2 ++;

                        p1 --;
                        if ( buf[p1] == '/' )
                                p1 --;
                        for ( ; p1 >= 0 && buf[p1] != '/' ; p1 -- );
                        p1 ++;
                        if ( p1 <= 0 )
                                return 0;
compose_url.c_______________________________________________________________________1

                }
                else {
                        return 0;
                }
        }
        l_strcpy(&buf[p1],d2);
        buf = d_re_alloc(buf,(l_strlen(buf)+1)*sizeof(L_CHAR));
        return buf;
}


L_CHAR * 
compose_url(L_CHAR * path1,L_CHAR * path2)
{
URL u1,u2,u3;
L_CHAR * ret;
        get_url2(&u1,path1);
        get_url2(&u2,path2);
        zero_url(&u3);
        if ( u1.proto == 0 && u1.server == 0 && u1.port == 0 )
                goto err;
        if ( u2.proto == 0 && u2.server == 0 && u2.port == 0 ) {
                u3.proto = ll_copy_str(u1.proto);
                u3.server = ll_copy_str(u1.server);
                u3.port = u1.port;
                if ( u2.agent ) {
                        u3.agent = ll_copy_str(u2.agent);
                }
                if ( u2.db == 0 ) {
                        u3.db = ll_copy_str(u1.db);
                }
                else    u3.db = compose_path(u1.db,u2.db);
                if ( u3.db == 0 ) {
                }
                u3.resource = ll_copy_str(u2.resource);
                u3.query = ll_copy_str(u2.query);
                u3.name = ll_copy_str(u2.name);
                ret = ll_copy_str(get_url_str2(&u3));
                free_url(&u1);
                free_url(&u2);
                free_url(&u3);
                return ret;
        }
        else if ( u2.proto && u2.server && u2.port ) {
                free_url(&u1);
                free_url(&u2);
                free_url(&u3);
                ret = ll_copy_str(path2);
                return ret;
        }
        else    goto err;
err:
        free_url(&u1);
        free_url(&u2);
        free_url(&u3);
        return 0;
}









compose_url.c_______________________________________________________________________2

/**********************************************************************
 
        Copyright (C) 2003 Hirohisa MORI <joshua@nichibun.ac.jp>
 
        This program is free software; you can redistribute it 
        and/or modify it under the terms of the GLOBALBASE 
        Library General Public License (G-LGPL) as published by 

        http://www.globalbase.org/
 
        This program is distributed in the hope that it will be 
        useful, but WITHOUT ANY WARRANTY; without even the 
        implied warranty of MERCHANTABILITY or FITNESS FOR A 
        PARTICULAR PURPOSE.

**********************************************************************/


#include        "mlong_char.h"
#include        "utils.h"

void
copy_url(URL * a,URL * b)
{
        memset(a,0x55,sizeof(*a));
        if ( b->proto ) {
                a->proto = ll_copy_str(b->proto);
        }
        else    a->proto = 0;
        if ( b->server ) {
                a->server = ll_copy_str(b->server);
        }
        else    a->server = 0;
        a->port = b->port;
        if ( b->db ) {
                a->db = ll_copy_str(b->db);
        }
        else    a->db = 0;
        if ( b->user ) {
                a->user = ll_copy_str(b->user);
        }
        else    a->user = 0;
        if ( b->passwd ) {
                a->passwd = ll_copy_str(b->passwd);
        }
        else    a->passwd = 0;
        if ( b->resource ) {
                a->resource = ll_copy_str(b->resource);
        }
        else    a->resource = 0;
        if ( b->name ) {
                a->name = ll_copy_str(b->name);
        }
        else    a->name = 0;
        if ( b->query ) {
                a->query = ll_copy_str(b->query);
        }
        else    a->query = 0;
        if ( b->agent ) {
                a->agent = ll_copy_str(b->agent);
        }
        else    a->agent = 0;
}

void
mcopy_url(URL * a,URL * b)
copy_url.c__________________________________________________________________________1

{
        memset(a,0x55,sizeof(*a));
        if ( b->proto ) {
                a->proto = ll_copy_mstr(b->proto);
        }
        else    a->proto = 0;
        if ( b->server ) {
                a->server = ll_copy_mstr(b->server);
        }
        else    a->server = 0;
        a->port = b->port;
        if ( b->db ) {
                a->db = ll_copy_mstr(b->db);
        }
        else    a->db = 0;
        if ( b->user ) {
                a->user = ll_copy_mstr(b->user);
        }
        else    a->user = 0;
        if ( b->passwd ) {
                a->passwd = ll_copy_mstr(b->passwd);
        }
        else    a->passwd = 0;
        if ( b->resource ) {
                a->resource = ll_copy_mstr(b->resource);
        }
        else    a->resource = 0;
        if ( b->name ) {
                a->name = ll_copy_mstr(b->name);
        }
        else    a->name = 0;
        if ( b->query ) {
                a->query = ll_copy_mstr(b->query);
        }
        else    a->query = 0;
        if ( b->agent ) {
                a->agent = ll_copy_mstr(b->agent);
        }
        else    a->agent = 0;
}


























copy_url.c__________________________________________________________________________2

/**********************************************************************
 
        Copyright (C) 2003 Hirohisa MORI <joshua@nichibun.ac.jp>
 
        This program is free software; you can redistribute it 
        and/or modify it under the terms of the GLOBALBASE 
        Library General Public License (G-LGPL) as published by 

        http://www.globalbase.org/
 
        This program is distributed in the hope that it will be 
        useful, but WITHOUT ANY WARRANTY; without even the 
        implied warranty of MERCHANTABILITY or FITNESS FOR A 
        PARTICULAR PURPOSE.

**********************************************************************/



#include        "memory_debug.h"
#include        "utils.h"

void
print_div_str(DIV_STR * str)
{
int i;
        printf("[");
        for ( i = 0; ; i ++ ) {
                if ( str[i].type == DST_STRING )
                        printf("%s ",n_string(std_cm,str[i].d.str));
                else    print_div_str(str[i].d.ds);
                if ( str[i].term == 0 )
                        break;
        }
        printf("]");
}

void
divide_string_str(DIV_STR * str,L_CHAR * div)
{
DIV_STR * ds;
L_CHAR * ss;
int p1,p2,i;
int ptr;
int len;
        ss = str->d.str;
        ds = d_alloc(sizeof(*ds));
        ptr = 0;
        len = l_strlen(div);
        for ( p1 = 0 ; ss[p1] ; ) {
                for ( p2 = p1 ; ; p2 ++ ) {
                        if ( ss[p2] == 0 )
                                break;
                        for ( i = 0 ; div[i] ; i ++ ) {
                                if ( ss[p2+i] == 0 )
                                        goto err;
                                if ( ss[p2+i] != div[i] )
                                        goto err;
                        }
                        break;
                err:    {}
                }
                ds = d_re_alloc(ds,(ptr+1)*sizeof(*ds));
                ds[ptr].d.str = d_alloc((p2-p1+1)*sizeof(L_CHAR));
                memcpy(ds[ptr].d.str,&ss[p1],(p2-p1)*sizeof(L_CHAR));
                ds[ptr].d.str[p2-p1] = 0;
divide_string.c_____________________________________________________________________1

                ds[ptr].type = DST_STRING;
                ds[ptr].flags = DSF_FREE;
                ptr ++;
                if ( ss[p2] == 0 )
                        break;
                p1 = p2 + len;
        }
        if ( *ss == 0 ) {
                ds[0].d.str = d_alloc(sizeof(L_CHAR));
                ds[0].d.str[0] = 0;
                ds[0].type = DST_STRING;
                ds[0].flags = DSF_FREE;
                ptr = 1;
        }
        for ( i = 0 ; i < ptr ; i ++ )
                ds[i].term = DST_DATA;
        ds[ptr-1].term = DST_TERMINATE;
        if ( str->flags == DSF_FREE )
                d_f_ree(str->d.str);
        str->flags = DSF_FREE;
        str->type = DST_LIST;
        str->d.ds = ds;
}

void
divide_string(DIV_STR * str,L_CHAR * div)
{
int i;
        for ( i = 0 ; ; i ++ ) {
                if ( str[i].type == DST_STRING )
                        divide_string_str(&str[i],div);
                else    divide_string(str[i].d.ds,div);
                if ( str[i].term == DST_TERMINATE )
                        return;
        }
}


void free_div_str(DIV_STR);

void
free_div_str_list(DIV_STR ds)
{
DIV_STR * dsp;
        for ( dsp = ds.d.ds ; ; dsp ++ ) {
                free_div_str(*dsp);
                if ( dsp->term == DST_TERMINATE )
                        break;
        }
}

void
free_div_str(DIV_STR ds)
{
        if ( ds.type == DST_LIST )
                free_div_str_list(ds);
        if ( ds.flags == DSF_FREE )
                d_f_ree(ds.d.str);
}







divide_string.c_____________________________________________________________________2

/**********************************************************************
 
        Copyright (C) 2003 Hirohisa MORI <joshua@nichibun.ac.jp>
 
        This program is free software; you can redistribute it 
        and/or modify it under the terms of the GLOBALBASE 
        Library General Public License (G-LGPL) as published by 

        http://www.globalbase.org/
 
        This program is distributed in the hope that it will be 
        useful, but WITHOUT ANY WARRANTY; without even the 
        implied warranty of MERCHANTABILITY or FITNESS FOR A 
        PARTICULAR PURPOSE.

**********************************************************************/


#include        <stdio.h>
#include        "equation.h"

/* m[tate-index][yoko-index] */


void
print_matrix(double m[E_DIM][E_DIM])
{
int i,j;
        printf("---\n");
        for ( i = 0 ; i < E_DIM ; i ++ ) {
                printf("(");
                for ( j = 0 ; j < E_DIM ; j ++ )
                        printf("%f ",m[i][j]);
                printf(")\n");
        }
        printf("---\n");
}

void
print_vector(double v[E_DIM])
{
int i;
        printf("(");
        for ( i = 0 ; i < E_DIM ; i++ )
                printf("%f ",v[i]);
        printf(")\n");
}

int
_equation_a(
        double m[E_DIM][E_DIM],
        double v[E_DIM],
        int ofs)
{
int i,j;
int max;
double a,b;
        a = 0;
        max = -1;
        for ( i = ofs ; i < E_DIM ; i ++ ) {
                if ( m[i][ofs] < 0 )
                        b = - m[i][ofs];
                else    b = m[i][ofs];
                if ( b > a ) {
                        max = i;
                        a = b;
equation.c__________________________________________________________________________1

                }
        }
        if ( a == 0 )
                return -1;
        if ( max != ofs ) {
                for ( i = 0 ; i < E_DIM ; i ++ ) {
                        a = m[ofs][i];
                        m[ofs][i] = m[max][i];
                        m[max][i] = a;
                }

                a = v[ofs];
                v[ofs] = v[max];
                v[max] = a;

        }
        for ( i = ofs + 1 ; i < E_DIM ; i ++ ) {
                if ( m[i][ofs] == 0 )
                        continue;
                a = m[ofs][ofs]/m[i][ofs];
                for ( j = ofs ; j < E_DIM ; j ++ )
                        m[i][j] = a*m[i][j] - m[ofs][j];
                m[i][ofs] = 0;

                v[i] = a*v[i] - v[ofs];
        }
        return 0;
}

int
equation(
         double result[E_DIM],
         double m[E_DIM][E_DIM],
         double v[E_DIM])
{
int i,j;
double r;

        for ( i = 0 ; i < E_DIM ; i ++ ) {
                if ( _equation_a(m,v,i) < 0 )
                        return -1;
        }
        for ( i = E_DIM-1 ; i >= 0 ; i -- ) {
                r = 0;
                for ( j = i + 1 ; j < E_DIM ; j ++ )
                        r += m[i][j]*result[j];
                result[i] = (v[i] - r)/m[i][i];
        }
        return 0;
}

void
test_equation()
{
double m[E_DIM][E_DIM] = {
{1, 2, 3},
{3, 6, 4},
{4, 6, 2}
};

double res[E_DIM] = { 1, 2, 3 };
double v[E_DIM];
double a;
double result[E_DIM];

int i,j;
equation.c__________________________________________________________________________2

        for ( i = 0 ; i < E_DIM ; i ++ ) {
                a = 0;
                for ( j = 0 ; j < E_DIM ; j ++ ) {
                        a += m[i][j]*res[j];
                }
                v[i] = a;
        }
        printf("v = (%f %f %f)\n",v[0],v[1],v[2]);
        equation(result,m,v);
        printf("result = (%f %f %f)\n",result[0],result[1],result[2]);
}























































equation.c__________________________________________________________________________3

/**********************************************************************
 
        Copyright (C) 2003 Hirohisa MORI <joshua@nichibun.ac.jp>
 
        This program is free software; you can redistribute it 
        and/or modify it under the terms of the GLOBALBASE 
        Library General Public License (G-LGPL) as published by 

        http://www.globalbase.org/
 
        This program is distributed in the hope that it will be 
        useful, but WITHOUT ANY WARRANTY; without even the 
        implied warranty of MERCHANTABILITY or FITNESS FOR A 
        PARTICULAR PURPOSE.

**********************************************************************/



#include        "memory_debug.h"
#include        "utils.h"

void
free_url(URL * u)
{
        if ( u->proto )
                d_f_ree(u->proto);
        if ( u->server )
                d_f_ree(u->server);
        if ( u->db )
                d_f_ree(u->db);
        if ( u->user )
                d_f_ree(u->user);
        if ( u->passwd )
                d_f_ree(u->passwd);
        if ( u->resource )
                d_f_ree(u->resource);
}




























free_url.c__________________________________________________________________________1

/**********************************************************************
 
        Copyright (C) 2003 Hirohisa MORI <joshua@nichibun.ac.jp>
 
        This program is free software; you can redistribute it 
        and/or modify it under the terms of the GLOBALBASE 
        Library General Public License (G-LGPL) as published by 

        http://www.globalbase.org/
 
        This program is distributed in the hope that it will be 
        useful, but WITHOUT ANY WARRANTY; without even the 
        implied warranty of MERCHANTABILITY or FITNESS FOR A 
        PARTICULAR PURPOSE.

**********************************************************************/


#include        "memory_routine.h"
#include        "utils.h"


void
gcv_url(URL * u)
{
        gc_text((char*)u->proto);
        gc_text((char*)u->server);
        gc_text((char*)u->db);
        gc_text((char*)u->resource);
        gc_text((char*)u->user);
        gc_text((char*)u->passwd);
}


































gcv_url.c___________________________________________________________________________1

/**********************************************************************
 
        Copyright (C) 2003 Hirohisa MORI <joshua@nichibun.ac.jp>
 
        This program is free software; you can redistribute it 
        and/or modify it under the terms of the GLOBALBASE 
        Library General Public License (G-LGPL) as published by 

        http://www.globalbase.org/
 
        This program is distributed in the hope that it will be 
        useful, but WITHOUT ANY WARRANTY; without even the 
        implied warranty of MERCHANTABILITY or FITNESS FOR A 
        PARTICULAR PURPOSE.

**********************************************************************/



#include        "netutils.h"


HOST_ADDR
getHA_v4(unsigned int ip)
{
HOST_ADDR ret;
        if ( ip ) {
                ret.type = HAT_V4;
                ret.size = sizeof(ip);
                ret.d.v4 = ip;
                return ret;
        }
        else {
                ret.type = 0;
                ret.size = 0;
                return ret;
        }
}




























getHA.c_____________________________________________________________________________1

/**********************************************************************
 
        Copyright (C) 2003 Hirohisa MORI <joshua@nichibun.ac.jp>
 
        This program is free software; you can redistribute it 
        and/or modify it under the terms of the GLOBALBASE 
        Library General Public License (G-LGPL) as published by 

        http://www.globalbase.org/
 
        This program is distributed in the hope that it will be 
        useful, but WITHOUT ANY WARRANTY; without even the 
        implied warranty of MERCHANTABILITY or FITNESS FOR A 
        PARTICULAR PURPOSE.

**********************************************************************/



#include "utils.h"


int
get_attr_flags(int * er,L_CHAR * attr,ATTR_TABLE * at)
{
L_CHAR * f;
int ret;
int len;
        ret = 0;
        *er = 0;
retry:
        for ( ; at->flag_name ; at ++ ) {
                f = l_string(std_cm,at->flag_name);
                if ( memcmp(attr,f,(len=l_strlen(f))*sizeof(L_CHAR)) == 0 ) {
                        ret |= at->flag;
                        attr += len;
                        switch ( *attr ) {
                        case ':':
                                attr ++;
                                goto retry;
                        case 0:
                                return ret;
                        default:
                                break;
                        }
                }
        }
        if ( er )
                *er = -1;
        return ret;
}















get_attr_flags.c____________________________________________________________________1

/**********************************************************************
 
        Copyright (C) 2003 Hirohisa MORI <joshua@nichibun.ac.jp>
 
        This program is free software; you can redistribute it 
        and/or modify it under the terms of the GLOBALBASE 
        Library General Public License (G-LGPL) as published by 

        http://www.globalbase.org/
 
        This program is distributed in the hope that it will be 
        useful, but WITHOUT ANY WARRANTY; without even the 
        implied warranty of MERCHANTABILITY or FITNESS FOR A 
        PARTICULAR PURPOSE.

**********************************************************************/


#include        <stdio.h>
#include        <stdlib.h>
#include        <string.h>
#ifdef VA2
#include        <varargs.h>
#else
#include        <stdarg.h>
#endif
#include        "xl.h"
#include        "utils.h"

void
gf_conv_ii(XL_SEXP * s,void * d,void * d2)
{
int * pt;
L_CHAR ** u;
        pt = d;
        u = d2;
        *pt = s->integer.data;
        *u = s->integer.unit;
}

void
gf_conv_di(XL_SEXP * s,void * d,void * d2)
{
int * pt;
L_CHAR ** u;
        pt = d;
        u = d2;
        *pt = s->floating.data;
        *u = s->floating.unit;
}

void
gf_conv_if(XL_SEXP * s,void * d,void * d2)
{
float * pt;
L_CHAR ** u;
        pt = d;
        u = d2;
        *pt = s->integer.data;
        *u = s->integer.unit;
}

void
gf_conv_df(XL_SEXP * s,void * d,void * d2)
{
float * pt;
get_field.c_________________________________________________________________________1

L_CHAR ** u;
        pt = d;
        u = d2;
        *pt = s->floating.data;
        *u = s->floating.unit;
}

void
gf_conv_id(XL_SEXP * s,void * d,void * d2)
{
double * pt;
L_CHAR * * u;
        pt = d;
        u = d2;
        *pt = s->integer.data;
        *u = s->integer.unit;
}

void
gf_conv_dd(XL_SEXP * s,void * d,void * d2)
{
double * pt;
L_CHAR ** u;
        pt = d;
        u = d2;
        *pt = s->floating.data;
        *u = s->floating.unit;
}

void
gf_conv_ss(XL_SEXP * s,void * d)
{
L_CHAR ** ptr;
        ptr = d;
        *ptr = s->string.data;
}

void
gf_conv_sexp(XL_SEXP * s,void * d)
{
XL_SEXP ** p;
        p = d;
        *p = s;
}

typedef void (*conv_func)();

conv_func       cf[6][XLT_MAX] = {
        {
                0,
                0,
                0,
                0,
                0, /* string */
                0, /* integer */
                0 /* float */
        },
        { /* integer */
                0,
                0,
                0,
                0,
                0, /* string */
                gf_conv_ii, /* integer */
                gf_conv_di /* float */
        },
get_field.c_________________________________________________________________________2

        { /* float */
                0,
                0,
                0,
                0,
                0, /* string */
                gf_conv_if, /* integer */
                gf_conv_df /* float */
        },
        { /* double */
                0,
                0,
                0,
                0,
                0, /* string */
                gf_conv_id, /* integer */
                gf_conv_dd /* float */
        },
        { /* string */
                0,
                0,
                0,
                0,
                gf_conv_ss, /* string */
                0, /* integer */
                0 /* float */
        },
        { /* sexp */
                gf_conv_sexp,
                gf_conv_sexp,
                gf_conv_sexp,
                gf_conv_sexp,
                gf_conv_sexp,
                gf_conv_sexp,
                gf_conv_sexp
        }
};

int
set_data(XL_SEXP * s,
         L_CHAR * f,int buf_type,void * d,void * d2,int * r)
{
XL_SEXP * field;
XL_SEXP * data;
XL_SEXP * ftype;
int data_type;
        for ( ; get_type(s)  ; s = cdr(s) ) {
                if ( get_type(s) != XLT_PAIR ) {
                        *r = E_DB_FORMAT;
                        return -1;
                }
                field = car(s);
                if ( get_type(field) != XLT_PAIR )
                        continue;
                ftype = get_el(field,0);
                if ( get_type(ftype) != XLT_SYMBOL ) {
                        *r = E_DB_FORMAT;
                        return -1;
                }
                if ( l_strcmp(ftype->symbol.data,f) )
                        continue;
                data = get_el(field,1);
                data_type = get_type(data);
                if ( cf[buf_type][data_type] == 0 ) {
                        *r = E_TYPE_MISSMATCH;
                        return 0;
get_field.c_________________________________________________________________________3

                }
                (*cf[buf_type][data_type])(data,d,d2);
                *r = 0;
                return 0;
        }
        *r = E_NO_DATA;
        return -1;
}

int
get_field(XL_SEXP * s,...)
{
L_CHAR * f;
char * t;
void *d;
int * r;
va_list p;
int buf_type;
void * d2;

#ifdef VA2
        va_start(p);
#else
        va_start(p,s);
#endif
        for ( ; ; ) {
                f = va_arg(p,L_CHAR*);
                if ( f == 0 )
                        break;
                t = va_arg(p,char*);
                if ( strcmp(t,"i") == 0 )
                        buf_type = 1;
                else if ( strcmp(t,"f") == 0 )
                        buf_type = 2;
                else if ( strcmp(t,"lf") == 0 )
                        buf_type = 3;
                else if ( strcmp(t,"s") == 0 )
                        buf_type = 4;
                else if ( strcmp(t,"sexp") == 0 )
                        buf_type = 5;
                else {
                        buf_type = -1;
                }
                d = va_arg(p,void *);
                r = va_arg(p,int *);
                if ( buf_type == -1 ) {
                        *r = -2;
                        return -1;
                }
                if ( buf_type == 1 || buf_type == 2 || buf_type == 3 )
                        d2 = va_arg(p,void*);
                set_data(s,f,buf_type,d,d2,r);
        }
        va_end(p);
        return 0;
}










get_field.c_________________________________________________________________________4

/**********************************************************************
 
        Copyright (C) 2003 Hirohisa MORI <joshua@nichibun.ac.jp>
 
        This program is free software; you can redistribute it 
        and/or modify it under the terms of the GLOBALBASE 
        Library General Public License (G-LGPL) as published by 

        http://www.globalbase.org/
 
        This program is distributed in the hope that it will be 
        useful, but WITHOUT ANY WARRANTY; without even the 
        implied warranty of MERCHANTABILITY or FITNESS FOR A 
        PARTICULAR PURPOSE.

**********************************************************************/


#include <stdlib.h>
#include        <fcntl.h>
#include        <string.h>
#include        "memory_debug.h"
#include        "utils.h"




L_CHAR * script_path;


L_CHAR *_xlwhich(L_CHAR * path,L_CHAR * app);
L_CHAR*in_xlrc(char * home,char * file,L_CHAR * app);
L_CHAR *get_xlwhich(L_CHAR * app);

L_CHAR *
_xlwhich(L_CHAR * path,L_CHAR * app)
{
L_CHAR * p1, * p2, * p3;
int path_len;
L_CHAR * buf;
int fd;
char * filename,*_filename;
int i;
char * d = XLPATH_DELIM;
        path = ll_copy_str(path);
        buf = d_alloc((l_strlen(path) + l_strlen(app) + 10)*sizeof(L_CHAR));
        buf[0] = 0;
        for ( p1 = path ; p1 ; ) {
                p2 = p1;
                for ( ; *p2 ; p2 ++ ) {
                        for ( i = 0 ; d[i] && d[i] != *p2 ; i ++ );
                        if ( d[i] )
                                break;
                }
                switch ( *p2 ) {
                case 0:
                        p3 = 0;
                        break;
                default:
                        p3 = p2+1;
                        *p2 = 0;
                        break;
                }
                l_strcpy(buf,p1);
                path_len = l_strlen(buf);
                
get_script.c________________________________________________________________________1

                if ( '\\' != buf[path_len-1] && '/' != buf[path_len-1] ) {
                        buf[path_len] = '/';
                        path_len ++;
                }
                l_strcpy(&buf[path_len],app);
                filename = ln_copy_str(std_cm,buf);
                _filename = change_delim_str(filename);
                fd = u_open(_filename,O_RDONLY);
                if ( filename != _filename )
                        d_f_ree(_filename);
                d_f_ree(filename);
        
                if ( fd < 0 ) {
                        p1 = p3;
                        continue;
                }
                u_close(fd);
                buf[path_len] = 0;
                goto end;
        }
        d_f_ree(buf);
        buf = 0;
end:
        d_f_ree(path);
        return buf;
}

XL_SEXP*
get_xlrc(char * home,char * file,L_CHAR * symbol)
{
L_CHAR * _home,*_file;
int len_home,len_file;
L_CHAR * filename;
int len;
STREAM* fd;
XL_SEXP * s, * t, * sym;
XL_SEXP * ret;
        _home = l_string(std_cm,home);
        len_home = l_strlen(_home);

        _file = l_string(std_cm,file);
        len_file = l_strlen(_file);

        filename = d_alloc(sizeof(L_CHAR)*(len_home + len_file + 10));

        l_strcpy(filename,_home);
        len = l_strlen(filename);
        if ( filename[len-1] != '/' ) {
                filename[len] = '/';
                len++;
        }

        l_strcpy(&filename[len],_file);

        fd = s_open_file(n_string(std_cm,filename),O_RDONLY);
        if ( fd == 0 ) {
                d_f_ree(filename);
                return 0;
        }
        ret = 0;
        gc_push(0,0,"get_xlrc");
        s = init_parse(fd,filename,filename);
        for ( ; get_type(s) == XLT_PAIR ; s = cdr(s) ) {
                t = car(s);
                if ( get_type(t) != XLT_PAIR )
                        continue;
get_script.c________________________________________________________________________2

                sym = car(t);
                if ( get_type(sym) != XLT_SYMBOL )
                        continue;
                if ( l_strcmp(sym->symbol.data,symbol) )
                        continue;
                ret = cons(get_el(t,1),ret);
        }
        gc_pop(ret,gc_gb_sexp);
        s_close(fd);
        return ret;
}

L_CHAR*
in_xlrc(char * home,char * file,L_CHAR * app)
{
XL_SEXP * rec, * t;
L_CHAR * ret;
        ret = 0;
        gc_push(0,0,"in_xlrc");
        rec = get_xlrc(home,file,l_string(std_cm,"XLPATH"));
        for ( ; get_type(rec) == XLT_PAIR ; rec = cdr(rec) ) {
                t = car(rec);
                if ( get_type(t) == XLT_STRING )
                        ret = _xlwhich(t->string.data,app);
                if ( ret )
                        break;
        }
        gc_pop(0,0);
        return ret;
}

L_CHAR *
get_xlwhich(L_CHAR * app)
{
L_CHAR * ret;
char * home;
        ret = 0;
        home = u_getenv("XLPATH");
        if ( home )
                ret = _xlwhich(l_string(std_cm,home),app);
        if ( ret )
                return ret;
        home = get_homepath();
        if ( home )
                ret = in_xlrc(home,".xlrc",app);
        if ( ret )
                return ret;
        home = get_preference_path();
        if ( home )
                ret = in_xlrc(home,"xlrc",app);
        ret = in_xlrc("/",".xlrc",app);
        if ( ret )
                return ret;
        home = get_root_preference_path();
        if ( home )
                ret = in_xlrc(home,"xlrc",app);
        return ret;
}

L_CHAR *
get_script(L_CHAR * file,L_CHAR * script)
{
L_CHAR * buf;
int len1,len2,len3;
STREAM * st;
L_CHAR * path;
get_script.c________________________________________________________________________3

int i;

        len2 = l_strlen(script);

        /* if script exist? */

        st = s_open_file(n_string(std_cm,script),O_RDONLY);
        if ( st ) {
                s_close(st);
                return ll_copy_str(script);
        }

        if ( script[0] == '/' )
                return 0;

        /* if XL_FILE is defined? */

        if ( file ) {
                len1 = l_strlen(file);
                buf = d_alloc((len1+len2+1)*sizeof(L_CHAR));
                memcpy(buf,file,len1*sizeof(L_CHAR));
                for ( i = len1-1 ; i >= 0 && buf[i] != '/' ; i -- );
                if ( i >= 0 ) {
                        memcpy(&buf[i+1],script,len2*sizeof(L_CHAR));
                        buf[i+1+len2] = 0;
                }
                else {
                        memcpy(buf,script,len2*sizeof(L_CHAR));
                        buf[len2] = 0;
                }

                st = s_open_file(n_string(std_cm,buf),O_RDONLY);
                if ( st ) {
                        s_close(st);
                        return buf;
                }
        }

        /* if script_path exist? */

        if ( script_path ) {
                len1 = l_strlen(script_path);
                buf = d_alloc((len1+len2+1)*sizeof(L_CHAR));
                memcpy(buf,script_path,len1*sizeof(L_CHAR));
                memcpy(&buf[len1],script,len2*sizeof(L_CHAR));
                buf[len1+len2] = 0;
                st = s_open_file(n_string(std_cm,buf),O_RDONLY);
                if ( st ) {
                        s_close(st);
                        return buf;
                }
        }

        /* if xlpath exist? */


        path = get_xlwhich(script);
        if ( path == 0 )
                return 0;
        buf = ll_copy_str(path);
        len3 = l_strlen(buf);
        buf = d_re_alloc(buf,(len3+len2+1)*sizeof(L_CHAR));
        l_strcpy(&buf[len3],script);
        d_f_ree(path);
        return buf;
}
get_script.c________________________________________________________________________4


void
set_script_path(L_CHAR * script)
{
L_CHAR * path;
int len;
int i;
        if ( script == 0 ) {
                if ( script_path )
                        d_f_ree(script_path);
                script_path = 0;
                return;
        }
        path = ll_copy_str(script);
        len = l_strlen(path);
        for ( i = len-1 ; i >= 0 ; i -- ) {
                if ( path[i] == '/' )
                        break;
        }
        if ( script_path )
                d_f_ree(script_path);
        if ( i == -1 ) {
                script_path = nl_copy_str(std_cm,"./");
                d_f_ree(path);
        }
        else {
                path[i+1] = 0;
                script_path = path;
        }
}


L_CHAR *
get_script_path()
{
        return ll_copy_str(script_path);
}

typedef struct path_stack {
        struct path_stack *     next;
        L_CHAR *                path;
} PATH_STACK;

PATH_STACK * push_path_stack(PATH_STACK * p,L_CHAR * path,int len);
PATH_STACK * pop_path_stack(PATH_STACK * p);
L_CHAR * _optimize_path(PATH_STACK * ps,L_CHAR st);


PATH_STACK *
push_path_stack(PATH_STACK * p,L_CHAR * path,int len)
{
PATH_STACK * n;
        n = d_alloc(sizeof(*n));
        n->next = p;
        n->path = d_alloc((len+1)*sizeof(L_CHAR));
        memcpy(n->path,path,len*sizeof(L_CHAR));
        n->path[len] = 0;
        return n;
}

PATH_STACK *
pop_path_stack(PATH_STACK * p)
{
PATH_STACK * ret;
        ret = p->next;
        d_f_ree(p->path);
get_script.c________________________________________________________________________5

        d_f_ree(p);
        return ret;
}

L_CHAR *
_optimize_path(PATH_STACK * ps,L_CHAR st)
{
L_CHAR * g;
int g_len,ps_len;
        if ( ps == 0 || ps->path[0] == 0 )
                return nl_copy_str(std_cm,"");
        g = _optimize_path(ps->next,st);
        g_len = l_strlen(g);
        ps_len = l_strlen(ps->path);
        g = d_re_alloc(g,(g_len+ps_len+3)*sizeof(L_CHAR));
        if ( g_len || st == '/' ) {
                memcpy(&g[g_len+1],ps->path,ps_len*sizeof(L_CHAR));
                g[g_len] = '/';
                g[g_len+ps_len+1] = 0;
        }
        else {
                memcpy(&g[g_len],ps->path,ps_len*sizeof(L_CHAR));
                g[g_len+ps_len] = 0;
        }
        return g;
}

L_CHAR *
optimize_path(L_CHAR * path)
{
L_CHAR * p, * q;
PATH_STACK * ps;
L_CHAR * ret;

        ps = 0;
        for ( p = path ; *p ; ) {
                if ( memcmp(p,l_string(std_cm,"../"),3*sizeof(L_CHAR))
                                == 0 ) {
                        if ( ps )
                                ps = pop_path_stack(ps);
                        else    ps = push_path_stack(ps,p,2);
                        p += 3;
                        continue;
                }
                if ( memcmp(p,l_string(std_cm,"./"),2*sizeof(L_CHAR)) 
                                == 0 ) {
                        if ( ps == 0 )
                                ps = push_path_stack(ps,p,1);
                        p += 2;
                        continue;
                }
                if ( l_strcmp(p,l_string(std_cm,"..")) == 0 ) {
                        if ( ps )
                                ps = pop_path_stack(ps);
                        else    ps = push_path_stack(ps,p,2);
                        p += 2;
                        continue;
                }
                if ( l_strcmp(p,l_string(std_cm,".")) == 0 ) {
                        if ( ps )
                                ps = push_path_stack(ps,p,1);
                        p += 1;
                        continue;
                }
                for ( q = p ; *q && *q != '/' ; q ++ );
                ps = push_path_stack(ps,p,q - p);
get_script.c________________________________________________________________________6

                if ( *q == 0 )
                        p = q;
                else    p = q + 1;
        }
        ret = _optimize_path(ps,path[0]);
        if ( path[l_strlen(path)-1] == '/' ) {
                ret[l_strlen(ret)] = '/';
                ret[l_strlen(ret)+1] = 0;
        }
        else {
                ret[l_strlen(ret)] = 0;
        }
        for ( ; ps ; )
                ps = pop_path_stack(ps);
        return ret;
}

L_CHAR *
get_absolute_path(L_CHAR * path)
{
L_CHAR * ret,* _ret;
int p_len,s_len;
        p_len = l_strlen(path);
        if ( path[0] == '/' )
                ret = ll_copy_str(path);
        else if ( script_path ) {
                s_len = l_strlen(script_path);
                ret = d_alloc((s_len+p_len+1)*sizeof(L_CHAR));
                memcpy(ret,script_path,s_len*sizeof(L_CHAR));
                memcpy(&ret[s_len],path,p_len*sizeof(L_CHAR));
                ret[s_len+p_len] = 0;
        }
        else    ret = ll_copy_str(path);
        _ret = optimize_path(ret);
        d_f_ree(ret);
        return _ret;
}

L_CHAR *
get_relative_path(L_CHAR * path)
{
int len;
        len = l_strlen(script_path);
        if ( memcmp(script_path,path,len*sizeof(L_CHAR)) )
                return ll_copy_str(path);
        return ll_copy_str(&path[len]);
}



















get_script.c________________________________________________________________________7

/**********************************************************************
 
        Copyright (C) 2003 Hirohisa MORI <joshua@nichibun.ac.jp>
 
        This program is free software; you can redistribute it 
        and/or modify it under the terms of the GLOBALBASE 
        Library General Public License (G-LGPL) as published by 

        http://www.globalbase.org/
 
        This program is distributed in the hope that it will be 
        useful, but WITHOUT ANY WARRANTY; without even the 
        implied warranty of MERCHANTABILITY or FITNESS FOR A 
        PARTICULAR PURPOSE.

**********************************************************************/



#include        <string.h>
#include        <stdlib.h>
#include        "memory_debug.h"
#include        "utils.h"
#include        "gbparam.h"

void
make_regular(L_CHAR ** str)
{
        if ( (*str)[0] )
                *str = d_re_alloc(*str,(l_strlen(*str)+1)*sizeof(L_CHAR));
        else {
                d_f_ree(*str);
                *str = 0;
        }
}

int
get_url(URL *   ret,
        L_CHAR * url)
{
int p1,rp,hp;
L_CHAR * p,* h,* d,* r;
int port_buf;
int len;
int er;
        er = 0;
        p1 = 0;
        len = l_strlen(url)+1;
        p = d_alloc(len*sizeof(L_CHAR));
        h = d_alloc(len*sizeof(L_CHAR));
        d = d_alloc(len*sizeof(L_CHAR));
        r = d_alloc(len*sizeof(L_CHAR));
        p[0] = 0;
        h[0] = 0;
        d[0] = 0;
        r[0] = 0;
        ret->proto = p;
        ret->server = h;
        ret->port = GBP_PORT;
        ret->db = d;
        ret->resource = r;
        ret->user = 0;
        ret->passwd = 0;
        rp = 0;
        switch ( url[p1++] ) {
        case 0:
get_url.c___________________________________________________________________________1

                goto err;
        case '/':
                goto d1;
        }
pr1:
        switch ( url[p1++] ) {
        case 0:
                l_strcpy(ret->resource,url);
                goto end;
        case ':':
                memcpy(ret->proto,url,(p1-1)*sizeof(L_CHAR));
                ret->proto[p1-1] = 0;
                break;
        case '/':
                hp = 0;
                rp = p1;
                goto d2;
        default:
                goto pr1;
        }
        switch ( url[p1++] ) {
        case '/':
                break;
        case 0:
        default:
                goto err;
        }
        switch ( url[p1++]) {
        case '/':
                break;
        case 0:
        default:
                goto err;
        }
        switch ( url[p1++] ) {
        case 0:
                goto err;
        case '/':
                goto err;
        default:
                *h++ = url[p1-1];
        }
h2:
        switch ( url[p1++] ) {
        case '/':
                *h = 0;
                ret->port = GBP_PORT;
                goto d1;
        case ':':
                *h = 0;
                break;
        case 0:
                goto err;
        default:
                *h++ = url[p1-1];
                goto h2;
        }
        port_buf = 0;
port2:
        if ( url[p1] == '/' ) {
                p1 ++;
                ret->port = port_buf;
        }
        else if ( '0' <= url[p1] && url[p1] <= '9' ) {
                port_buf *= 10;
                port_buf += url[p1]-'0';
get_url.c___________________________________________________________________________2

                p1 ++;
                goto port2;
        }
        else    goto err;
d1:
        rp = p1;
        hp = p1;
d2:
        switch ( url[p1++] ) {
        case 0:
                goto err;
        case '/':
                goto err;
        default:
                break;
        }
d3:
        switch ( url[p1++] ) {
        case 0:
                if ( hp < rp ) {
                        memcpy(d,&url[hp],(rp-hp-1)*sizeof(L_CHAR));
                        d[rp-hp-1] = 0;
                }
                l_strcpy(r,&url[rp]);
                goto end;
        case '/':
                rp = p1;
                goto d2;
        default:
                goto d3;
        }
err:
        er = -1;
end:

        make_regular(&ret->server);
        make_regular(&ret->proto);
        make_regular(&ret->db);
        make_regular(&ret->resource);
        return er;
}

























get_url.c___________________________________________________________________________3

/**********************************************************************
 
        Copyright (C) 2003 Hirohisa MORI <joshua@nichibun.ac.jp>
 
        This program is free software; you can redistribute it 
        and/or modify it under the terms of the GLOBALBASE 
        Library General Public License (G-LGPL) as published by 

        http://www.globalbase.org/
 
        This program is distributed in the hope that it will be 
        useful, but WITHOUT ANY WARRANTY; without even the 
        implied warranty of MERCHANTABILITY or FITNESS FOR A 
        PARTICULAR PURPOSE.

**********************************************************************/



#include        <string.h>
#include        <stdlib.h>
#include        "memory_debug.h"
#include        "utils.h"
#include        "gbparam.h"

int
xx_get_url2(
        URL *   ret,
        L_CHAR * url,
        char * __file,int __line)
{
L_CHAR * buf;
L_CHAR * div;
L_CHAR * host;
L_CHAR *dir;
L_CHAR ch;
int p,len;
int er;
L_CHAR nq;
L_CHAR * nq_str;
int i;
L_CHAR * f;

        nq = 0;
        nq_str = 0;
        er = 0;
        zero_url(ret);
        buf = xx_ll_copy_str(url,__file,__line);

        for ( i = 0 ; buf[i] ; i ++ ) {
                switch ( buf[i] ) {
                case '?':
                        nq = '?';
                        buf[i] = 0;
                        nq_str = &buf[i+1];
                        break;
                case '#':
                        nq = '#';
                        buf[i] = 0;
                        nq_str = &buf[i+1];
                        break;
                default:
                        continue;
                }
                break;
        }
get_url2.c__________________________________________________________________________1


        len = l_strlen(buf);
        div = xx_nl_copy_str(std_cm,"://",__file,__line);
        for ( p = 0 ; p < len-3 ; p ++ )
                if ( memcmp(div,&buf[p],3*sizeof(L_CHAR)) == 0 ) {
                        d_f_ree(div);
                        goto match;
                }
        d_f_ree(div);
        ret->proto = 0;
        ret->server = 0;
        ret->port = 0;
        dir = buf;
        goto dir_res;
match:
        buf[p] = 0;
        ret->proto = xx_ll_copy_str(buf,__file,__line);
        p += 3;
        host = &buf[p];
        for ( ; buf[p] && buf[p] != ':' && buf[p] != '/' ; p ++ );
        ch = buf[p];
        if ( (&buf[p]) == host ) {
                ret->server = 0;
                switch ( ch ) {
                case ':':
                        er = -1;
                        goto end;
                case '/':
                        ret->port = 0;
                        buf[p] = '/';
                        dir = &buf[p];
                        goto dir_res;
                case 0:
                        ret->port = 0;
                        ret->db = xx_nl_copy_str(std_cm,"/",__file,__line);
                        ret->resource = 0;
                        goto end;
                }
        }
        buf[p] = 0;
        ret->server = xx_ll_copy_str(host,__file,__line);
        switch ( ch ) {
        case 0:
                ret->port = 0;
                ret->db = xx_nl_copy_str(std_cm,"/",__file,__line);
                ret->resource = 0;
                goto end;
        case ':':
                p ++;
                break;
        case '/':
                ret->port = 0;
                buf[p] = '/';
                dir = &buf[p];
                goto dir_res;
        }
/* port: */
        ret->port = 0;
        for ( ; '0' <= buf[p] && buf[p] <= '9' ; p ++ )
                ret->port = ret->port*10 + buf[p] - '0';
        switch ( buf[p] ) {
        case 0:
                ret->db = xx_nl_copy_str(std_cm,"/",__file,__line);
                ret->resource = 0;
                goto end;
        case '/':
get_url2.c__________________________________________________________________________2

                dir = &buf[p];
                goto dir_res;
        default:
                er = -1;
                goto end;
        }
dir_res:
        p = len = l_strlen(dir)-1;
        for ( ; p >= 0 ; p -- )
                if ( dir[p] == '/' )
                        goto res;
        ret->db = 0;
        ret->resource = xx_ll_copy_str(dir,__file,__line);
        goto end;
res:
        if ( len == p ) {
                ret->resource = 0;
                ret->db = xx_ll_copy_str(dir,__file,__line);
        }
        else {
                ret->resource = xx_ll_copy_str(&dir[p+1],__file,__line);
                dir[p+1] = 0;
                ret->db = xx_ll_copy_str(dir,__file,__line);
        }
end:
        if ( ret->port == 0 && ret->proto ) {
                ret->port = get_wkp(ret->proto);
                if ( ret->port < 0 )
                        ret->port = 0;
        }
        switch ( nq ) {
        case '#':
                ret->name = xx_ll_copy_str(nq_str,__file,__line);
                break;
        case '?':
                ret->query = xx_ll_copy_str(nq_str,__file,__line);
                break;
        }
        if ( ret->db && ret->db[0] == '/' && ret->db[1] == '@' ) {
                ret->agent = xx_ll_copy_str(&ret->db[2],__file,__line);
                for ( i = 0 ; ret->agent[i] && ret->agent[i] != '/' ; i ++ );
                nq = ret->agent[i];
                ret->agent[i] = 0;
                f = ret->db;
                if ( nq == 0 )
                        ret->db = xx_nl_copy_str(std_cm,"/",__file,__line);
                else    ret->db = xx_ll_copy_str(&ret->db[i+2],__file,__line);
                d_f_ree(f);
        }
        d_f_ree(buf);
        return er;
}














get_url2.c__________________________________________________________________________3

/**********************************************************************
 
        Copyright (C) 2003 Hirohisa MORI <joshua@nichibun.ac.jp>
 
        This program is free software; you can redistribute it 
        and/or modify it under the terms of the GLOBALBASE 
        Library General Public License (G-LGPL) as published by 

        http://www.globalbase.org/
 
        This program is distributed in the hope that it will be 
        useful, but WITHOUT ANY WARRANTY; without even the 
        implied warranty of MERCHANTABILITY or FITNESS FOR A 
        PARTICULAR PURPOSE.

**********************************************************************/



#include        <stdlib.h>
#include        "memory_debug.h"
#include        "utils.h"

L_CHAR * seek_ptr();

L_CHAR *
get_url_filepath(URL * u)
{
L_CHAR * buf;
L_CHAR * ptr;
        buf = d_alloc(
                ((u->db ? l_strlen(u->db) : 0) +
                 (u->name ? l_strlen(u->db) : 0) +
                 (u->query ? l_strlen(u->db) : 0) +
                 (u->resource ? l_strlen(u->resource) : 0) + 100) *
                        sizeof(L_CHAR));
        buf[0] = 0;
        ptr = buf;
/* db: */
        if ( u->db == 0 ) {
                *ptr ++ = '/';
        }
        else {
                if ( u->db[0] != '/' )
                        *ptr ++ = '/';
                l_strcpy(ptr,u->db);
                ptr = seek_ptr(ptr);
        }
        if ( *(ptr-1) != '/' )
                *ptr ++ = '/';
/* resource: */
        *ptr = 0;
        if ( u->resource ) {
                l_strcpy(ptr,u->resource);
                ptr = seek_ptr(ptr);
        }
/* query: */
        if ( u->query ) {
                *ptr ++ = '?';
                l_strcpy(ptr,u->query);
                ptr = seek_ptr(ptr);
        }
        if ( u->name ) {
                *ptr ++ = '#';
                l_strcpy(ptr,u->name);
                ptr = seek_ptr(ptr);
get_url_filepath.c__________________________________________________________________1

        }

        buf = d_re_alloc(buf,(l_strlen(buf)+1)*sizeof(L_CHAR));
        return buf;
/* err: */
        d_f_ree(buf);
        return 0;
}


























































get_url_filepath.c__________________________________________________________________2

/**********************************************************************
 
        Copyright (C) 2003 Hirohisa MORI <joshua@nichibun.ac.jp>
 
        This program is free software; you can redistribute it 
        and/or modify it under the terms of the GLOBALBASE 
        Library General Public License (G-LGPL) as published by 

        http://www.globalbase.org/
 
        This program is distributed in the hope that it will be 
        useful, but WITHOUT ANY WARRANTY; without even the 
        implied warranty of MERCHANTABILITY or FITNESS FOR A 
        PARTICULAR PURPOSE.

**********************************************************************/



#include        "machine/include.h"
#include        "memory_debug.h"
#include        "utils.h"
#include        "task.h"
#include        "gbparam.h"


/*
L_CHAR *
get_url_str(URL * u)
{
char * buf;
int len;
L_CHAR * ret;
        len = 0;
        if ( u->proto )
                len += l_strlen(u->proto);
        if ( u->server )
                len += l_strlen(u->server);
        if ( u->port != GBP_PORT )
                len += 5;
        if ( u->db )
                len += l_strlen(u->db);
        if ( u->resource )
                len += l_strlen(u->resource);
        buf = d_alloc((len + 10)*sizeof(L_CHAR));
        if ( u->proto ) {
                if ( u->server == 0 )
                        goto from_db;
                if ( u->port != GBP_PORT ) {
                        if ( u->db[l_strlen(u->db)-1] == '/' )
                                sprintf(buf,"%s://%s:%i/%s%s",
                                        n_string(std_cm,u->proto),
                                        n_string(std_cm,u->server),
                                        u->port,
                                        n_string(std_cm,u->db),
                                        n_string(std_cm,u->resource));
                        else    sprintf(buf,"%s://%s:%i/%s/%s",
                                        n_string(std_cm,u->proto),
                                        n_string(std_cm,u->server),
                                        u->port,
                                        n_string(std_cm,u->db),
                                        n_string(std_cm,u->resource));
                }
                else {
                        if ( u->db[l_strlen(u->db)-1] == '/' )
                                sprintf(buf,"%s://%s/%s%s",
get_url_str.c_______________________________________________________________________1

                                        n_string(std_cm,u->proto),
                                        n_string(std_cm,u->server),
                                        n_string(std_cm,u->db),
                                        n_string(std_cm,u->resource));
                        else    sprintf(buf,"%s://%s/%s/%s",
                                        n_string(std_cm,u->proto),
                                        n_string(std_cm,u->server),
                                        n_string(std_cm,u->db),
                                        n_string(std_cm,u->resource));
                }
        }
        else if ( u->server ) {
                if ( u->port != GBP_PORT ) {
                        if ( u->db[l_strlen(u->db)-1] == '/' )
                                sprintf(buf,"gbp://%s:%i/%s%s",
                                        n_string(std_cm,u->server),
                                        u->port,
                                        n_string(std_cm,u->db),
                                        n_string(std_cm,u->resource));
                        else    sprintf(buf,"gbp://%s:%i/%s/%s",
                                        n_string(std_cm,u->server),
                                        u->port,
                                        n_string(std_cm,u->db),
                                        n_string(std_cm,u->resource));
                }
                else {
                        if ( u->db[l_strlen(u->db)-1] == '/' )
                                sprintf(buf,"gbp://%s/%s%s",
                                        n_string(std_cm,u->server),
                                        n_string(std_cm,u->db),
                                        n_string(std_cm,u->resource));
                        else    sprintf(buf,"gbp://%s/%s/%s",
                                        n_string(std_cm,u->server),
                                        n_string(std_cm,u->db),
                                        n_string(std_cm,u->resource));
                }
        }
        else {
        from_db:
                if ( u->db ) {
                        if ( u->db[l_strlen(u->db)-1] == '/' )
                                sprintf(buf,"/%s%s",
                                        n_string(std_cm,u->db),
                                        n_string(std_cm,u->resource));
                        else    sprintf(buf,"/%s/%s",
                                        n_string(std_cm,u->db),
                                        n_string(std_cm,u->resource));
                }
                else {
                        sprintf(buf,"%s",n_string(std_cm,u->resource));
                }
        }
        ret = l_string(std_cm,buf);
        d_f_ree(buf);
        return ret;
}
*/









get_url_str.c_______________________________________________________________________2

/**********************************************************************
 
        Copyright (C) 2003 Hirohisa MORI <joshua@nichibun.ac.jp>
 
        This program is free software; you can redistribute it 
        and/or modify it under the terms of the GLOBALBASE 
        Library General Public License (G-LGPL) as published by 

        http://www.globalbase.org/
 
        This program is distributed in the hope that it will be 
        useful, but WITHOUT ANY WARRANTY; without even the 
        implied warranty of MERCHANTABILITY or FITNESS FOR A 
        PARTICULAR PURPOSE.

**********************************************************************/



#include        <stdlib.h>
#include        "memory_debug.h"
#include        "utils.h"

L_CHAR *
seek_ptr(L_CHAR * ptr)
{
        for ( ; *ptr ; ptr ++ );
        return ptr;
}


L_CHAR *
get_url_str2(URL * u)
{
L_CHAR * buf;
L_CHAR * ptr;
char port_buf[20];
        buf = d_alloc(
                ((u->proto ? l_strlen(u->proto) : 0) +
                 (u->server ? l_strlen(u->server) : 0) +
                 (u->db ? l_strlen(u->db) : 0) +
                 (u->agent ? l_strlen(u->agent) : 0) +
                 (u->query ? l_strlen(u->query) : 0) +
                 (u->name ? l_strlen(u->name) : 0) +
                 (u->resource ? l_strlen(u->resource) : 0) + 100) *
                        sizeof(L_CHAR));
        buf[0] = 0;
        ptr = buf;
        if ( u->proto == 0 )
                goto err;
        l_strcpy(ptr,u->proto);
        ptr = seek_ptr(ptr);
        *ptr ++ = ':';
        *ptr ++ = '/';
        *ptr ++ = '/';
        if ( u->server == 0 )
                goto agent;
        l_strcpy(ptr,u->server);
        ptr = seek_ptr(ptr);
/* port: */
        if ( u->port == get_wkp(u->proto) )
                goto agent;
        sprintf(port_buf,":%i",u->port);
        l_strcpy(ptr,l_string(std_cm,port_buf));
        ptr = seek_ptr(ptr);
agent:
get_url_str2.c______________________________________________________________________1

        if ( u->agent == 0 )
                goto db;
        *ptr ++ = '/';
        *ptr ++ = '@';
        l_strcpy(ptr,u->agent);
        ptr = seek_ptr(ptr);
        if ( u->db && u->db[0] != '/' )
                *ptr ++ = '/';
db:
        if ( u->db == 0 ) {
                *ptr ++ = '/';
        }
        else {
                if ( u->db[0] != '/' )
                        *ptr ++ = '/';
                l_strcpy(ptr,u->db);
                ptr = seek_ptr(ptr);
        }
        if ( *(ptr-1) != '/' )
                *ptr ++ = '/';
/* resource: */
        if ( u->resource ) {
                l_strcpy(ptr,u->resource);
                ptr = seek_ptr(ptr);
        }
        if ( u->query ) {
                *ptr ++ = '?';
                l_strcpy(ptr,u->query);
                ptr = seek_ptr(ptr);
        }
        if ( u->name ) {
                *ptr ++ = '#';
                l_strcpy(ptr,u->name);
                ptr = seek_ptr(ptr);
        }

        buf = d_re_alloc(buf,(l_strlen(buf)+1)*sizeof(L_CHAR));
        set_buffer(buf);
        return buf;
err:
        d_f_ree(buf);
        return 0;
}























get_url_str2.c______________________________________________________________________2

/**********************************************************************
 
        Copyright (C) 2003 Hirohisa MORI <joshua@nichibun.ac.jp>
 
        This program is free software; you can redistribute it 
        and/or modify it under the terms of the GLOBALBASE 
        Library General Public License (G-LGPL) as published by 

        http://www.globalbase.org/
 
        This program is distributed in the hope that it will be 
        useful, but WITHOUT ANY WARRANTY; without even the 
        implied warranty of MERCHANTABILITY or FITNESS FOR A 
        PARTICULAR PURPOSE.

**********************************************************************/


#include        "utils.h"


typedef struct well_known_port {
        char    name[10];
        int     port;
} WELL_KNOWN_PORT;

WELL_KNOWN_PORT wkp_tbl[] = {
        {"http",80},
        {"xlp",0},
        {"",0}
};


int
get_wkp(L_CHAR * name)
{
int i;
        for ( i = 0 ; wkp_tbl[i].name[0] ; i ++ ) {
                if ( l_strcmp(l_string(std_cm,wkp_tbl[i].name),name) )
                        continue;
                return wkp_tbl[i].port;
        }
        return -1;
}

char*
get_proto_name(int port)
{
int i;
        for ( i = 0 ; wkp_tbl[i].name[0] ; i ++ )
                if ( wkp_tbl[i].port == port )
                        return wkp_tbl[i].name;
        return 0;
}












get_wkp.c___________________________________________________________________________1

/**********************************************************************
 
        Copyright (C) 2003 Hirohisa MORI <joshua@nichibun.ac.jp>
 
        This program is free software; you can redistribute it 
        and/or modify it under the terms of the GLOBALBASE 
        Library General Public License (G-LGPL) as published by 

        http://www.globalbase.org/
 
        This program is distributed in the hope that it will be 
        useful, but WITHOUT ANY WARRANTY; without even the 
        implied warranty of MERCHANTABILITY or FITNESS FOR A 
        PARTICULAR PURPOSE.

**********************************************************************/


#include        <errno.h>
#include        "memory_debug.h"
#include        "task.h"
#include        "netutils.h"
#include        "utils.h"
#include        "resolve.h"


int
localhostcmp(HOST_ADDR ip,char * h)
{
HOST_ADDR lip;
char * bf;
int ret;
        lip.d.v4 = get_localhostip();
        lip.type = HAT_V4;
        lip.size = 4;
        bf = d_alloc(1000);
        get_localhostname(bf);
        if ( cmp_HA(ip,lip) == 0 && strcmp(bf,h) == 0 )
                ret = 0;
        else    ret = 1;
        d_f_ree(bf);
        return ret;
}

int
hostcmp(char * h1,HOST_ADDR ip1,char * h2,HOST_ADDR ip2)
{
int ret;
int i,j;
HOST_ENTRY * he, * he1, * he2;

        if ( h1 == 0 && h2 == 0 ) {
                if ( cmp_HA(ip1,ip2) == 0 )
                        ret = 0;
                else    ret = 1;
        }
        else if ( h1 == 0 ) {
                ret = localhostcmp(ip1,h2);
                if ( ret == 0 )
                        goto end;
                he = r_gethostbyname(h2);
                if ( he == 0 ) {
                        ret = -1;
                        goto end;
                }
                for ( i = 0 ; i < he->ips_length ; i ++ )
hostcmp.c___________________________________________________________________________1

                        if ( cmp_HA(ip1,he->ips[i]) == 0 ) {
                                ret = 0;
                                goto end;
                        }
                ret = 1;
                goto end;
        }
        else if ( h2 == 0 ) {
                ret = localhostcmp(ip2,h1);
                if ( ret == 0 )
                        goto end;
                he = r_gethostbyname(h1);
                if ( he == 0 ) {
                        ret = -1;
                        goto end;
                }
                for ( i = 0 ; i < he->ips_length ; i ++ )
                        if ( cmp_HA(ip2,he->ips[i]) == 0 ) {
                                ret = 0;
                                goto end;
                        }
                ret = 1;
                goto end;
        }
        else {
                if ( strcmp(h1,h2) == 0 ) {
                        ret = 0;
                        goto end;
                }
                he1 = r_gethostbyname(h1);
                he2 = r_gethostbyname(h2);
                if ( he1 == 0 || he2 == 0 ) {
                        ret = -1;
                        goto end;
                }
                for ( i = 0 ; i < he1->ips_length ; i ++ )
                        for ( j = 0 ; j < he2->ips_length ; j ++ )
                                if ( cmp_HA(he1->ips[i],he2->ips[j])
                                                == 0 ) {
                                        ret = 0;
                                        goto end;
                                }
                ret = 1;
                goto end;
        }
end:
        return ret;
}


















hostcmp.c___________________________________________________________________________2

/**********************************************************************
 
        Copyright (C) 2003 Hirohisa MORI <joshua@nichibun.ac.jp>
 
        This program is free software; you can redistribute it 
        and/or modify it under the terms of the GLOBALBASE 
        Library General Public License (G-LGPL) as published by 

        http://www.globalbase.org/
 
        This program is distributed in the hope that it will be 
        useful, but WITHOUT ANY WARRANTY; without even the 
        implied warranty of MERCHANTABILITY or FITNESS FOR A 
        PARTICULAR PURPOSE.

**********************************************************************/



#include        "gbgraph.h"


int
i_rect_type(XL_SEXP * s)
{
XL_SEXP * tl,* br;
        if ( list_length(s) != 2 )
                return -1;
        tl = get_el(s,0);
        br = get_el(s,1);
        if ( list_length(tl) != 2 )
                return -1;
        if ( list_length(br) != 2 )
                return -1;
        if ( get_type(get_el(tl,0)) != XLT_INTEGER )
                return -1;
        if ( get_type(get_el(tl,1)) != XLT_INTEGER )
                return -1;
        if ( get_type(get_el(br,0)) != XLT_INTEGER )
                return -1;
        if ( get_type(get_el(br,1)) != XLT_INTEGER )
                return -1;
        return 0;
}






















i_rect_type.c_______________________________________________________________________1

/**********************************************************************
 
        Copyright (C) 2003 Hirohisa MORI <joshua@nichibun.ac.jp>
 
        This program is free software; you can redistribute it 
        and/or modify it under the terms of the GLOBALBASE 
        Library General Public License (G-LGPL) as published by 

        http://www.globalbase.org/
 
        This program is distributed in the hope that it will be 
        useful, but WITHOUT ANY WARRANTY; without even the 
        implied warranty of MERCHANTABILITY or FITNESS FOR A 
        PARTICULAR PURPOSE.

**********************************************************************/



#include        "task.h"
#include        "utils.h"
#include        "lock_level.h"
#include        "pri_level.h"
#include        "init.h"
#include        "u_file.h"
#include        "memory_debug.h"

SEM utils_lock;
SEM utils_lock2;
SEM dummy_lock;
void _calc_ctl_pri(PRI_CTL * target);

void (*upper_layer_lock_tracer)(int *);


SEM ____sem_null;

int
lock_up_test(SEM s)
{
        if ( s.so == 0 )
                return 0;
        return 1;
}

SEM
_i_new_lock(int ll,char * f,int ln)
{
SEM ret;
        ret.so = malloc(sizeof(SEM_ORG));
        ret.so->d_sem = xx_new_lock(ll,f,ln);
        ret.so->pri = 0;
        return ret;
}

void
close_lock(SEM s)
{
        xx_close_lock(s.so->d_sem);
        free(s.so);
}


void
_i_lock_task(SEM s,char* f,int ln)
{
init_utils.c________________________________________________________________________1

int pri;
        pri = push_pri(PRI_LOCK);
        _lock_task(s.so->d_sem,f,ln);
        s.so->pri = pri;
}

void
_i_unlock_task(SEM s,char* str,char * f,int ln)
{
int pri;
        pri = s.so->pri;
        s.so->pri = 0;
        _unlock_task(s.so->d_sem,str,f,ln);
        change_pri(0,pri);
}


void 
_i_sleep_task(unsigned int key,SEM s,char *file,int line)
{
        if ( s.so == 0 )
                _sleep_task(key,0,file,line);
        else    _sleep_task(key,s.so->d_sem,file,line);
}


void
init_utils()
{
        utils_lock = new_lock(LL_UTILS);
        utils_lock2 = new_lock(LL_UTILS2);
        dummy_lock = new_lock(LL_DUMMY);
        init_blacklist();
        set_sys_param();
}

void
force_scheduling()
{
int pri;
        pri = get_pri(0);
        change_pri(0,pri);
}


int push_pri(int pri)
{
int prev;
        prev = get_pri(0);
        if ( prev < pri )
                change_pri(0,pri);
        return prev;
}

int push_pri_pctl(PRI_CTL * target)
{
        if ( target->ctl_pri < target->base_pri )
                target->ctl_pri = target->base_pri;
        return push_pri(target->ctl_pri);
}



void
_calc_ctl_pri(PRI_CTL * target)
{
init_utils.c________________________________________________________________________2

int c_pri;
PRI_CTL_THREAD * t;
        c_pri = target->base_pri+1;
        for ( t = target->threads ; t ; t = t->next )
                if ( c_pri < t->pri )
                        c_pri = t->pri;
        if ( c_pri == 0 )
                target->ctl_pri = 0;
        else    target->ctl_pri = c_pri-1;
}

void
enter_pri_ctl(PRI_CTL * target,PRI_CTL_THREAD * t)
{
        lock_task(utils_lock2);
        t->pri = get_pri(0);
        t->tid = get_tid();
        t->next = target->threads;
        target->threads = t;
        _calc_ctl_pri(target);
        unlock_task(utils_lock2,"push_pri_ctl");
}

void
exit_pri_ctl(PRI_CTL * target)
{
int tid;
PRI_CTL_THREAD ** tp,* t;
        tid = get_tid();
        lock_task(utils_lock2);
        for ( tp = &target->threads ; *tp ; tp = &(*tp)->next ) {
                t = *tp;
                if ( t->tid != tid )
                        continue;
                *tp = t->next;
                break;
        }
        _calc_ctl_pri(target);
        unlock_task(utils_lock2,"push_pri_ctl");
}


























init_utils.c________________________________________________________________________3

/**********************************************************************
 
        Copyright (C) 2003 Hirohisa MORI <joshua@nichibun.ac.jp>
 
        This program is free software; you can redistribute it 
        and/or modify it under the terms of the GLOBALBASE 
        Library General Public License (G-LGPL) as published by 

        http://www.globalbase.org/
 
        This program is distributed in the hope that it will be 
        useful, but WITHOUT ANY WARRANTY; without even the 
        implied warranty of MERCHANTABILITY or FITNESS FOR A 
        PARTICULAR PURPOSE.

**********************************************************************/

#include        "graph.h"


void
insert_rect_i(I_RECT * r,I_POINT p)
{
        if ( r->tl.x > r->br.x ||
                        r->tl.y > r->br.y ) {
                r->tl = r->br = p;
                return;
        }
        if ( r->tl.x > p.x )
                r->tl.x = p.x;
        if ( r->tl.y > p.y )
                r->tl.y = p.y;
        if ( r->br.x < p.x )
                r->br.x = p.x;
        if ( r->br.y < p.y )
                r->br.y = p.y;
}





























insert_rect_i.c_____________________________________________________________________1

#include "utils.h"

int is_safe_as_filename(char* name){
        while(*name){
                if(
                        *name == ';' || 
                        *name == ',' ||
                        *name == '|' ||
                        *name == '>' ||
                        *name == '<' 
                        ){
                        return 0;
                }
                ++name;
        }
        return 1;
}

















































is_safe_as_filename.c_______________________________________________________________1

/**********************************************************************
 
        Copyright (C) 2003 Hirohisa MORI <joshua@nichibun.ac.jp>
 
        This program is free software; you can redistribute it 
        and/or modify it under the terms of the GLOBALBASE 
        Library General Public License (G-LGPL) as published by 

        http://www.globalbase.org/
 
        This program is distributed in the hope that it will be 
        useful, but WITHOUT ANY WARRANTY; without even the 
        implied warranty of MERCHANTABILITY or FITNESS FOR A 
        PARTICULAR PURPOSE.

**********************************************************************/


#include        <stdlib.h>
#include        "mlong_char.h"
#include        "memory_routine.h"

void gc_text();

L_CHAR *
ll_copy_mstr(L_CHAR * str)
{
L_CHAR * ret;

        ret = mmalloc((l_strlen(str)+1)*sizeof(L_CHAR),gc_text);
        l_strcpy(ret,str);
        return ret;
}

































ll_copy_mstr.c______________________________________________________________________1

/**********************************************************************
 
        Copyright (C) 2003 Hirohisa MORI <joshua@nichibun.ac.jp>
 
        This program is free software; you can redistribute it 
        and/or modify it under the terms of the GLOBALBASE 
        Library General Public License (G-LGPL) as published by 

        http://www.globalbase.org/
 
        This program is distributed in the hope that it will be 
        useful, but WITHOUT ANY WARRANTY; without even the 
        implied warranty of MERCHANTABILITY or FITNESS FOR A 
        PARTICULAR PURPOSE.

**********************************************************************/


#include        <stdlib.h>
#include        "memory_debug.h"
#include        "utils.h"


L_CHAR *
xx_ll_copy_str(L_CHAR * str,char * file,int line)
{
L_CHAR * ret;
int len;
        if ( str == 0 )
                return 0; 
        len = l_strlen(str);
        ret = xx_d_alloc((len+1)*sizeof(L_CHAR),file,line);
        memcpy(ret,str,(len+1)*sizeof(L_CHAR));
        return ret;
}































ll_copy_str.c_______________________________________________________________________1

/**********************************************************************
 
        Copyright (C) 2003 Hirohisa MORI <joshua@nichibun.ac.jp>
 
        This program is free software; you can redistribute it 
        and/or modify it under the terms of the GLOBALBASE 
        Library General Public License (G-LGPL) as published by 

        http://www.globalbase.org/
 
        This program is distributed in the hope that it will be 
        useful, but WITHOUT ANY WARRANTY; without even the 
        implied warranty of MERCHANTABILITY or FITNESS FOR A 
        PARTICULAR PURPOSE.

**********************************************************************/



#include        "utils.h"


char *
ln_copy_str(CODE_METHOD * cm,L_CHAR * str)
{
        return copy_str(n_string(cm,str));
}







































ln_copy_str.c_______________________________________________________________________1

/**********************************************************************
 
        Copyright (C) 2003 Hirohisa MORI <joshua@nichibun.ac.jp>
 
        This program is free software; you can redistribute it 
        and/or modify it under the terms of the GLOBALBASE 
        Library General Public License (G-LGPL) as published by 

        http://www.globalbase.org/
 
        This program is distributed in the hope that it will be 
        useful, but WITHOUT ANY WARRANTY; without even the 
        implied warranty of MERCHANTABILITY or FITNESS FOR A 
        PARTICULAR PURPOSE.

**********************************************************************/


#include        "utils.h"
#include        "task.h"
#include        "pri_level.h"


void (*memory_watchdog_func)();
int memory_watchdog_count;

void _memory_watchdog();
void _memory_watchdog_tick();

void
_memory_watchdog()
{
INTEGER64 s,d;
void (*func)();
        for ( ; ; ) {
                func = memory_watchdog_func;
                if ( func ) {
                        s = get_mem_size();
                        d = get_usedmemory_size();
                        if ( s <= d || 512*1024*1024 <= d )
                                (*func)();
                }
                sleep_sec(20);
        }
}


void
_memory_watchdog_tick()
{
        for ( ; memory_watchdog_count < 2 ; ) {
                memory_watchdog_count ++;
                create_task(_memory_watchdog,0,PRI_TICK_CLOSE);
        }
}

void
memory_watchdog(void (*func)())
{
        memory_watchdog_func = func;
        new_tick(_memory_watchdog_tick,0,0);
}




memory_watchdog.c___________________________________________________________________1

/**********************************************************************
 
        Copyright (C) 2003 Hirohisa MORI <joshua@nichibun.ac.jp>
 
        This program is free software; you can redistribute it 
        and/or modify it under the terms of the GLOBALBASE 
        Library General Public License (G-LGPL) as published by 

        http://www.globalbase.org/
 
        This program is distributed in the hope that it will be 
        useful, but WITHOUT ANY WARRANTY; without even the 
        implied warranty of MERCHANTABILITY or FITNESS FOR A 
        PARTICULAR PURPOSE.

**********************************************************************/



#include        "memory_debug.h"
#include        "task.h"
#include        "utils.h"
#include        "lock_level.h"


extern SEM utils_lock;


NESTED_LOCK *
new_nlock()
{
NESTED_LOCK * ret;
        ret = d_alloc(sizeof(*ret));
        ret->tid = 0;
        ret->cnt = 0;
        return ret;
}

void
nlock_task(NESTED_LOCK * n)
{
int tid;
        tid = get_tid();
retry:
        lock_task(utils_lock);
        if ( n->tid == 0 ) {
                n->cnt = 1;
                n->tid = tid;
        }
        else if ( n->tid == tid ) {
                n->cnt ++;
        }
        else {
                sleep_task((int)n,utils_lock);
                goto retry;
        }
        unlock_task(utils_lock,"nlock_task");
}

void
unnlock_task(NESTED_LOCK * n)
{
int tid;
        tid = get_tid();
        lock_task(utils_lock);
        if ( n->tid != tid )
nested_lock.c_______________________________________________________________________1

                er_panic("unnlock_task(1)");
        n->cnt --;
        if ( n->cnt < 0 )
                er_panic("unnlock_task(2)");
        if ( n->cnt == 0 ) {
                n->tid = 0;
                wakeup_task((int)n);
        }
        unlock_task(utils_lock,"unnlock_task");
}

void
destroy_nlock(NESTED_LOCK * n)
{
        d_f_ree(n);
}


















































nested_lock.c_______________________________________________________________________2

/**********************************************************************
 
        Copyright (C) 2003 Hirohisa MORI <joshua@nichibun.ac.jp>
 
        This program is free software; you can redistribute it 
        and/or modify it under the terms of the GLOBALBASE 
        Library General Public License (G-LGPL) as published by 

        http://www.globalbase.org/
 
        This program is distributed in the hope that it will be 
        useful, but WITHOUT ANY WARRANTY; without even the 
        implied warranty of MERCHANTABILITY or FITNESS FOR A 
        PARTICULAR PURPOSE.

**********************************************************************/



#include        "memory_routine.h"
#include        "mlong_char.h"


L_CHAR *
_nl_copy_mstr_1(CODE_METHOD * cm,char * str)
{
L_CHAR * d;
L_CHAR * ret;
        d = _l_string_1(cm,str);
        ret = mmalloc((l_strlen(d)+1)*sizeof(L_CHAR),gc_text);
        l_strcpy(ret,d);
        return ret;
}

L_CHAR *
_nl_copy_mstr_2(CODE_METHOD * cm,char * str)
{
L_CHAR * d;
L_CHAR * ret;
        d = _l_string_2(cm,str);
        ret = mmalloc((l_strlen(d)+1)*sizeof(L_CHAR),gc_text);
        l_strcpy(ret,d);
        return ret;
}






















nl_copy_mstr.c______________________________________________________________________1

/**********************************************************************
 
        Copyright (C) 2003 Hirohisa MORI <joshua@nichibun.ac.jp>
 
        This program is free software; you can redistribute it 
        and/or modify it under the terms of the GLOBALBASE 
        Library General Public License (G-LGPL) as published by 

        http://www.globalbase.org/
 
        This program is distributed in the hope that it will be 
        useful, but WITHOUT ANY WARRANTY; without even the 
        implied warranty of MERCHANTABILITY or FITNESS FOR A 
        PARTICULAR PURPOSE.

**********************************************************************/



#include        "utils.h"
#include        "memory_debug.h"

L_CHAR *
_xx_nl_copy_str_1(CODE_METHOD * cm,char * str,
        char * __file,int __line)
{
L_CHAR * ret;
        ret = xx_ll_copy_str(_l_string_1(cm,str),__file,__line);
        return ret;
}


L_CHAR *
_xx_nl_copy_str_2(CODE_METHOD * cm,char * str,
        char * __file,int __line)
{
L_CHAR * ret;
        ret = xx_ll_copy_str(_l_string_2(cm,str),__file,__line);
        return ret;
}


























nl_copy_str.c_______________________________________________________________________1

/**********************************************************************
 
        Copyright (C) 2003 Hirohisa MORI <joshua@nichibun.ac.jp>
 
        This program is free software; you can redistribute it 
        and/or modify it under the terms of the GLOBALBASE 
        Library General Public License (G-LGPL) as published by 

        http://www.globalbase.org/
 
        This program is distributed in the hope that it will be 
        useful, but WITHOUT ANY WARRANTY; without even the 
        implied warranty of MERCHANTABILITY or FITNESS FOR A 
        PARTICULAR PURPOSE.

**********************************************************************/

#include        "graph.h"


I_POINT
p_addi(I_POINT p1,I_POINT p2)
{
I_POINT ret;
        ret.x = p1.x + p2.x;
        ret.y = p1.y + p2.y;
        return ret;
}






































p_addi.c____________________________________________________________________________1

/**********************************************************************
 
        Copyright (C) 2003 Hirohisa MORI <joshua@nichibun.ac.jp>
 
        This program is free software; you can redistribute it 
        and/or modify it under the terms of the GLOBALBASE 
        Library General Public License (G-LGPL) as published by 

        http://www.globalbase.org/
 
        This program is distributed in the hope that it will be 
        useful, but WITHOUT ANY WARRANTY; without even the 
        implied warranty of MERCHANTABILITY or FITNESS FOR A 
        PARTICULAR PURPOSE.

**********************************************************************/


#include        <string.h>
#include        "task.h"
#include        "memory_debug.h"
#include        "lock_level.h"
#include        "queue.h"
#include        "utils.h"
#include        "pri_level.h"

SEM     queue_lock,queue_lock_for_gc;
SEM     queue_lock_high,queue_lock_for_gc_high;
SYS_QUEUE * q_list;
int queue_lock_for_gc_high_flag;

int _insert_key_list(SYS_QUEUE * q,L_CHAR * key,int wait_flag);
void _delete_key_list(SYS_QUEUE * q,L_CHAR * key);
int _insert_queue(SYS_QUEUE * q,void * _n,int offset,int wait_flag);
void * _delete_queue_simple(SYS_QUEUE * q,int wait_flag);
void dq_tick(SYS_QUEUE * q);
void * _delete_queue_cond(SYS_QUEUE * q,int (*cond)(),void * work,int wait_flag);
int _check_queue(SYS_QUEUE * q,int (*cond)(),void * work);
L_CHAR * _touch_qkey(SYS_QUEUE * q);
void _release_qkey(SYS_QUEUE * q,L_CHAR * key);
int _get_active_que_thread(SYS_QUEUE * q);


PRI_CTL queue_lock_ctl = {PRI_QUEUE,0,0};

void
init_queue()
{
        queue_lock = new_lock(LL_QUEUE);
        queue_lock_for_gc = new_lock(LL_QUEUE_GC);
        queue_lock_high = new_lock(LL_QUEUE_HIGH);
        queue_lock_for_gc_high = new_lock(LL_QUEUE_GC_HIGH);
}


void
gc_queue_lock()
{
        lock_task(queue_lock_for_gc);
        if ( queue_lock_for_gc_high_flag == 0 )
                er_panic("required gc_queue_lock_high");
}

void
gc_queue_lock_high()
{
queue.c_____________________________________________________________________________1

        lock_task(queue_lock_for_gc_high);
        queue_lock_for_gc_high_flag = 1;
}

void
gc_queue_unlock()
{
        queue_lock_for_gc_high_flag = 0;
        unlock_task(queue_lock_for_gc,"qc_queue_unlock");
        unlock_task(queue_lock_for_gc_high,"qc_queue_unlock");
}

void
gc_queue()
{
SYS_QUEUE * q;
Q_HEADER * n;

        for ( q = q_list ; q ; q = q->next ) {
                if ( q->gc_func == 0 )
                        continue;
                for ( n = q->head ; n ; n = n->next )
                        (*q->gc_func)(n);
        }
}

void
setup_queue(SYS_QUEUE * q)
{
int pri;
        pri = push_pri_pctl(&queue_lock_ctl);
        lock_task(queue_lock_for_gc);
        if ( q->flags & QF_HIGH ) {
                if ( q->gc_func )
                        q->target_lock = &queue_lock_for_gc_high;
                else    q->target_lock = &queue_lock_high;
        }
        else {
                if ( q->gc_func )
                        q->target_lock = &queue_lock_for_gc;
                else    q->target_lock = &queue_lock;
        }
        q->next = q_list;
        q_list = q;
        unlock_task(queue_lock_for_gc,"new_queue");
        change_pri(0,pri);
}

int
release_queue(SYS_QUEUE * q)
{
SYS_QUEUE ** qq;
int ret;
int pri;
        pri = push_pri_pctl(&queue_lock_ctl);
        lock_task(queue_lock_for_gc);
        if ( q->head ) {
                ret = -1;
                goto rq;
        }
        for ( qq = &q_list ; *qq ; qq = &(*qq)->next ) {
                if ( *qq == q ) {
                        *qq = q->next;
                        break;
                }
        }
queue.c_____________________________________________________________________________2

        ret = 0;
rq:
        unlock_task(queue_lock_for_gc,"release_queue");
        change_pri(0,pri);
        return ret;
}



int
_insert_key_list(SYS_QUEUE * q,L_CHAR * key,int wait_flag)
{
KEY_LIST * k;
        if ( key == 0 )
                return 0;
        for ( k = q->keylist ; k ; k = k->next )
                if ( l_strcmp(k->key,key) == 0 ) {
                        if ( wait_flag < Q_WAIT_FORCE_INSERT &&
                                        q->key_limit && 
                                        k->cnt >= q->key_limit )
                                return -1;
                        k->cnt ++;
                        return 0;
                }
        k = d_alloc(sizeof(*k));

        k->key = ll_copy_str(key);
        k->cnt = 1;
        k->task_asign = 0;

        k->next = q->keylist;
        q->keylist = k;

        if ( q->key_func )
                create_task(q->key_func,(int)q,q->pri);
        return 0;
}


void
_delete_key_list(SYS_QUEUE * q,L_CHAR * key)
{
KEY_LIST ** kp,* k;
        if ( key == 0 )
                return;
        for ( kp = &q->keylist ; *kp ; kp = &(*kp)->next ) {
                k = *kp;
                if ( l_strcmp(k->key,key) )
                        continue;
                k->cnt --;
        }
}

int
_insert_queue(SYS_QUEUE * q,void * _n,int offset,int wait_flag)
{
Q_HEADER * n,** np;
        n = _n;
retry:
        if ( wait_flag < Q_WAIT_FORCE_INSERT &&
                        q->total_limit && q->total_cnt >= q->total_limit )
                goto sleep;
        if ( _insert_key_list(q,n->key,wait_flag) < 0 )
                goto sleep;
        if ( n->ins )
                er_panic("_insert_queue");
queue.c_____________________________________________________________________________3

        n->ins = q;
        q->total_cnt ++;
        if ( offset < 0 ) {
                switch ( q->flags & QFM_DIRECT ) {
                case QF_STACK:
                        n->next = q->head;
                        q->head = n;
                        break;
                case QF_FIFO:
                        n->next = 0;
                        if ( q->head == 0 )
                                q->head = q->tail = n;
                        else {
                                q->tail->next = n;
                                q->tail = n;
                        }
                        break;
                default:
                        er_panic("insert_queue");
                }
        }
        else {
                np = &q->head;
                for ( ; offset > 0 && *np ; offset -- , np = &(*np)->next );
                n->next = *np;
                *np = n;
                if ( q->tail == 0 )
                        q->tail = n;
                else if ( q->tail->next )
                        q->tail = n;
        }
        wakeup_task((int)q);
        return 0;
sleep:
        if ( wait_flag == 0 )
                return -1;
        sleep_task((int)q,*q->target_lock);
        lock_task(*q->target_lock);
        goto retry;
}

int
insert_queue(SYS_QUEUE * q,void * n,int wait_flag)
{
int ret;
int pri;
        pri = push_pri_pctl(&queue_lock_ctl);
        lock_task(*q->target_lock);
        ret = _insert_queue(q,n,-1,wait_flag);
        unlock_task(*q->target_lock,"insert_queue");
        change_pri(0,pri);
        return ret;
}

int
insert_queue_offset(SYS_QUEUE * q,void * n,int offset,int wait_flag)
{
int ret;
int pri;
        pri = push_pri_pctl(&queue_lock_ctl);
        lock_task(*q->target_lock);
        ret = _insert_queue(q,n,offset,wait_flag);
        unlock_task(*q->target_lock,"insert_queue");
        change_pri(0,pri);
        return ret;
}
queue.c_____________________________________________________________________________4



void *
_delete_queue_simple(SYS_QUEUE * q,int wait_flag)
{
Q_HEADER * ret;
int sleep_tim;

retry:
        if ( q->head == 0 ) {
                if ( wait_flag == 0 )
                        return 0;
                if ( wait_flag < 0 ) {
                        new_timeout((int)q,-wait_flag);
                        sleep_tim = get_xltime();
                }
                sleep_task((int)q,*q->target_lock);
                if ( wait_flag < 0 ) {
                        del_timeout((int)q);
                        wait_flag = wait_flag +
                                get_xltime() - sleep_tim;
                        if ( wait_flag > 0 )
                                wait_flag = 0;
                }
                lock_task(*q->target_lock);
                goto retry;
        }
        ret = q->head;

        if ( ret && q->gc_get )
                (*q->gc_get)(ret);

        q->head = ret->next;
        if ( q->head == 0 )
                q->tail = 0;
        ret->next = 0;
        ret->ins = 0;

        q->total_cnt --;

        _delete_key_list(q,ret->key);

        wakeup_task((int)q);

        return ret;
}

void
dq_tick(SYS_QUEUE * q)
{
        wakeup_task((int)q);
}

void *
_delete_queue_cond(SYS_QUEUE * q,int (*cond)(),void * work,int wait_flag)
{
Q_HEADER * ret, ** retp, * n;
int sleep_tim;

retry:
        for ( retp = &q->head ; *retp ; retp = &(*retp)->next )
                if ( (*cond)(q,*retp,work) == 0 )
                        goto ok;
        if ( wait_flag == 0 )
                return 0;
        if ( q->head )
queue.c_____________________________________________________________________________5

                new_tick((void (*)(int))dq_tick,-1,(int)q);
        if ( wait_flag < 0 ) {
                new_timeout((int)q,-wait_flag);
                sleep_tim = get_xltime();
        }
        sleep_task((int)q,*q->target_lock);
        if ( wait_flag < 0 ) {
                del_timeout((int)q);
                wait_flag = wait_flag + (get_xltime() - sleep_tim);
                if ( wait_flag > 0 )
                        wait_flag = 0;
        }
        lock_task(*q->target_lock);
        del_tick_with_data(dq_tick,(int)q);
        goto retry;

ok:
        ret = *retp;

        if ( ret && q->gc_get )
                (*q->gc_get)(ret);

        *retp = ret->next;
        if ( q->tail == ret ) {
                if ( q->head == 0 )
                        q->tail = 0;
                else {
                        for ( n = q->head ; n->next ; n = n->next );
                        q->tail = n;
                }
        }
        ret->next = 0;
        ret->ins = 0;

        q->total_cnt --;

        _delete_key_list(q,ret->key);

        wakeup_task((int)q);

        return ret;
}

void *
delete_queue(SYS_QUEUE * q,int (*cond)(),void * work,int wait_flag)
{
Q_HEADER * ret;
int pri;
        pri = push_pri_pctl(&queue_lock_ctl);
        lock_task(*q->target_lock);
        if ( cond )
                ret = _delete_queue_cond(q,cond,work,wait_flag);
        else    ret = _delete_queue_simple(q,wait_flag);
        unlock_task(*q->target_lock,"delete_queue");
        change_pri(0,pri);
        return ret;
}


int
_check_queue(SYS_QUEUE * q,int (*cond)(),void * work)
{
Q_HEADER ** retp;
int ret;

        ret = 0;
queue.c_____________________________________________________________________________6

        for ( retp = &q->head ; *retp ; retp = &(*retp)->next ) {
                if ( cond == 0 ) {
                        ret ++;
                        continue;
                }
                switch ( (*cond)(q,*retp,work) ) {
                case 0:
                        ret ++;
                        break;
                case CQ_END:
                        return ret;
                }
        }
        return ret;
}


int
check_queue(SYS_QUEUE * q,int (*cond)(),void * work)
{
int ret;
int pri;
        pri = push_pri_pctl(&queue_lock_ctl);
        lock_task(*q->target_lock);
        ret = _check_queue(q,cond,work);
        unlock_task(*q->target_lock,"check_queue");
        change_pri(0,pri);
        return ret;
}



L_CHAR *
_touch_qkey(SYS_QUEUE * q)
{
KEY_LIST * k;
        for ( k = q->keylist ; k ; k = k->next )
                if ( k->task_asign == 0 ) {
                        k->task_asign = 1;
                        return ll_copy_str(k->key);
                }
        return 0;
}

L_CHAR *
touch_qkey(SYS_QUEUE * q)
{
L_CHAR * ret;
int pri;
        pri = push_pri_pctl(&queue_lock_ctl);
        lock_task(*q->target_lock);
        ret = _touch_qkey(q);
        unlock_task(*q->target_lock,"get_queue_key");
        change_pri(0,pri);
        return ret;
}

void
_release_qkey(SYS_QUEUE * q,L_CHAR * key)
{
KEY_LIST * k, ** kp;
        for ( kp = &q->keylist ; *kp ; kp = &(*kp)->next ) {
                k = *kp;
                if ( l_strcmp(k->key,key) )
                        continue;
                if ( k->cnt ) {
queue.c_____________________________________________________________________________7

                        k->task_asign = 0;
                        create_task(q->key_func,(int)q,q->pri);
                }
                else {
                        *kp = k->next;
                        d_f_ree(k->key);
                        d_f_ree(k);
                }
                return;
        }
        ss_printf("invalid key %ls\n",key);
        er_panic("key");
}

void
release_qkey(SYS_QUEUE * q,L_CHAR * key)
{
int pri;
        pri = push_pri_pctl(&queue_lock_ctl);
        lock_task(*q->target_lock);
        _release_qkey(q,key);
        unlock_task(*q->target_lock,"release_qkey");
        change_pri(0,pri);
}


int
sq_key_cond(SYS_QUEUE * q,void * n,void * work)
{
L_CHAR * key;
Q_HEADER * _n;
        _n = n;
        key = work;
        if ( _n->key == 0 )
                return -1;
        if ( l_strcmp(_n->key,key) == 0 )
                return 0;
        return -1;
}


L_CHAR * 
xx_get_server_key(URL * u,char * __file,int __line)
{
char * key;
L_CHAR * ret;
URL d;
        key = d_alloc(l_strlen(get_url_str2(u))*4 + 20);
        if ( u->server )
                d.server = u->server;
        else    d.server = l_string(std_cm,"server");
        if ( u->proto )
                d.proto = u->proto;
        else    d.proto = l_string(std_cm,"xlp");
        if ( u->agent )
                d.agent = u->agent;
        else    d.agent = l_string(std_cm,"");
        sprintf(key,"%s://%s:%i/@%s",
                n_string(std_cm,d.proto),
                n_string(std_cm,d.server),
                u->port,
                n_string(std_cm,d.agent));
        ret = xx_nl_copy_str(std_cm,key,__file,__line);
        d_f_ree(key);
        return ret;
}
queue.c_____________________________________________________________________________8




void *
xx_new_queue_node(int size,char * __file,int __line)
{
Q_HEADER * h;
        h = xx_d_alloc(size,__file,__line);
        memset(h,0,size);
        return h;
}

int
_get_active_que_thread(SYS_QUEUE * q)
{
KEY_LIST * k;
int ret;
        ret = 0;
        for ( k = q->keylist ; k ; k = k->next )
                if ( k->task_asign )
                        ret ++;
        return ret;
}

int
get_active_que_thread(SYS_QUEUE * q)
{
int ret;
int pri;
        pri = push_pri_pctl(&queue_lock_ctl);
        lock_task(*q->target_lock);
        ret = _get_active_que_thread(q);
        unlock_task(*q->target_lock,"release_qkey");
        change_pri(0,pri);
        return ret;
}






























queue.c_____________________________________________________________________________9

/**********************************************************************
 
        Copyright (C) 2003 Hirohisa MORI <joshua@nichibun.ac.jp>
 
        This program is free software; you can redistribute it 
        and/or modify it under the terms of the GLOBALBASE 
        Library General Public License (G-LGPL) as published by 

        http://www.globalbase.org/
 
        This program is distributed in the hope that it will be 
        useful, but WITHOUT ANY WARRANTY; without even the 
        implied warranty of MERCHANTABILITY or FITNESS FOR A 
        PARTICULAR PURPOSE.

**********************************************************************/



#include        "graph.h"


S_RECT
rect_conv_i2s(I_RECT r)
{
S_RECT ret;
        ret.l = r.tl.x;
        ret.t = r.tl.y;
        ret.r = r.br.x;
        ret.b = r.br.y;
        return ret;
}


































rect_conv_i2s.c_____________________________________________________________________1

/**********************************************************************
 
        Copyright (C) 2003 Hirohisa MORI <joshua@nichibun.ac.jp>
 
        This program is free software; you can redistribute it 
        and/or modify it under the terms of the GLOBALBASE 
        Library General Public License (G-LGPL) as published by 

        http://www.globalbase.org/
 
        This program is distributed in the hope that it will be 
        useful, but WITHOUT ANY WARRANTY; without even the 
        implied warranty of MERCHANTABILITY or FITNESS FOR A 
        PARTICULAR PURPOSE.

**********************************************************************/



#include        "graph.h"


S_RECT
rect_conv_r2s(R_RECT r)
{
S_RECT ret;
        ret.l = r.tl.x;
        ret.t = r.tl.y;
        ret.r = r.br.x;
        ret.b = r.br.y;
        return ret;
}


































rect_conv_r2s.c_____________________________________________________________________1

/**********************************************************************
 
        Copyright (C) 2003 Hirohisa MORI <joshua@nichibun.ac.jp>
 
        This program is free software; you can redistribute it 
        and/or modify it under the terms of the GLOBALBASE 
        Library General Public License (G-LGPL) as published by 

        http://www.globalbase.org/
 
        This program is distributed in the hope that it will be 
        useful, but WITHOUT ANY WARRANTY; without even the 
        implied warranty of MERCHANTABILITY or FITNESS FOR A 
        PARTICULAR PURPOSE.

**********************************************************************/



#include        "gbgraph.h"


int
rect_type(XL_SEXP * s)
{
XL_SEXP * tl,* br;
        if ( list_length(s) != 2 )
                return -1;
        tl = get_el(s,0);
        br = get_el(s,1);
        if ( list_length(tl) != 2 )
                return -1;
        if ( list_length(br) != 2 )
                return -1;
        if ( get_type(get_el(tl,0)) != XLT_INTEGER &&
                get_type(get_el(tl,0)) != XLT_FLOAT )
                return -1;
        if ( get_type(get_el(tl,1)) != XLT_INTEGER &&
                get_type(get_el(tl,1)) != XLT_FLOAT )
                return -1;
        if ( get_type(get_el(br,0)) != XLT_INTEGER &&
                get_type(get_el(br,0)) != XLT_FLOAT )
                return -1;
        if ( get_type(get_el(br,1)) != XLT_INTEGER &&
                get_type(get_el(br,1)) != XLT_FLOAT )
                return -1;
        return 0;
}


















rect_type.c_________________________________________________________________________1

/**********************************************************************
 
        Copyright (C) 2003 Hirohisa MORI <joshua@nichibun.ac.jp>
 
        This program is free software; you can redistribute it 
        and/or modify it under the terms of the GLOBALBASE 
        Library General Public License (G-LGPL) as published by 

        http://www.globalbase.org/
 
        This program is distributed in the hope that it will be 
        useful, but WITHOUT ANY WARRANTY; without even the 
        implied warranty of MERCHANTABILITY or FITNESS FOR A 
        PARTICULAR PURPOSE.

**********************************************************************/

#define SEQUENCE_RESOLVE        1


#include        <stdio.h>
#include        "task.h"
#include        "lock_level.h"
#include        "netutils.h"
#include        "memory_debug.h"
#include        "utils.h"
#include        "pri_level.h"

typedef struct resolve_queue {
        struct resolve_queue *  next;
        unsigned                pri:1;
        unsigned                status:3;
#define RQ_IDLE                 0
#define RQ_RUN                  1
#define RQ_TIMEOUT              2
#define RQ_ABOAT_CATCH_         3
#define RQ_OK_                  4
        unsigned int            start_time;
        unsigned int            req_time;
} RESOLVE_QUEUE;

typedef struct resolve_queue_header {
        RESOLVE_QUEUE *         head;
        RESOLVE_QUEUE *         tail;
} RESOLVE_QUEUE_HEADER;

typedef struct resolve_request_t {
        struct resolve_request_t *      next;
        HOST_ADDR *                     a;
        char *                          name;
        HOST_ENTRY *                    hp;
        int                             ok;
 } RESOLVE_REQUEST_T;

SEM     resolve_lock,resolve_lock2;
HOST_ENTRY * resolv_cache;
HOST_ENTRY ** prev_cache;

HOST_ENTRY ** del_list;
int del_ptr;
RESOLVE_QUEUE_HEADER resolve_que_header[2];
RESOLVE_QUEUE * resolve_run;
int aboat_resolve_flag;
int resolve_running = 0;

#define DEL_SIZE        100
resolve.c___________________________________________________________________________1

#define RESOLV_TICK     3600
#define RESOLV_TIMEOUT          600
#define RESOLV_QUE_TIMEOUT      120
#define RESOLV_MIN_TIMEOUT      2

#define RHE_NOTHING     0
#define RHE_RETRY       1
#define RHE_OK          2

void resolv_tick();
HOST_ENTRY * _err_host_entry(char * name,HOST_ADDR * ap);
void _insert_resolve_queue(RESOLVE_QUEUE * rq);
RESOLVE_QUEUE * _delete_resolve_queue();
void _wakeup_resolve_thread();
int _entry_resolve_call(RESOLVE_QUEUE * rq);
int _exit_resolve_call(RESOLVE_QUEUE * rq);
void wakeup_resolve_thread();
int _return_host_entry(HOST_ENTRY*,char * name,HOST_ADDR*);
HOST_ENTRY * resolve_request(HOST_ADDR * a,char * name);

void resolve_thread();
int resolve_tid;
int resolve_launch;
RESOLVE_REQUEST_T * resolve_que_head;
RESOLVE_REQUEST_T * resolve_que_tail;


void
init_resolve()
{
int i;
        resolve_lock = new_lock(LL_P_RESOLV);
        resolve_lock2 = new_lock(LL_P_RESOLV2);
        del_list = d_alloc(sizeof(HOST_ENTRY*)*DEL_SIZE);
        for ( i = 0 ; i < DEL_SIZE ; i ++ )
                del_list[i] = 0;
        del_ptr = 0;
        new_tick(resolv_tick,RESOLV_TICK,0);


}


void
_insert_resolve_queue(RESOLVE_QUEUE * rq)
{
RESOLVE_QUEUE_HEADER * h;
        h = &resolve_que_header[rq->pri];
        rq->next = 0;
        if ( h->head == 0 )
                h->head = h->tail = rq;
        else {
                h->tail->next = rq;
                h->tail = rq;
        }
}


RESOLVE_QUEUE *
_delete_resolve_queue()
{
RESOLVE_QUEUE * ret;
int pri;
RESOLVE_QUEUE_HEADER * h;
        for ( pri = 0 ; pri < 2 ; pri ++ ) {
                h = &resolve_que_header[pri];
resolve.c___________________________________________________________________________2

                if ( h->head ) {
                        ret = h->head;
                        h->head = ret->next;
                        if ( h->head == 0 )
                                h->tail = 0;
                        return ret;
                }
        }
        return 0;
}


void
_wakeup_resolve_thread()
{
RESOLVE_QUEUE * rq2;
int t;

retry:
        if ( resolve_run == 0 ) {
                if ( aboat_resolve_flag ) {
                        aboat_resolve_request();
                        new_tick(wakeup_resolve_thread,-1,0);
                        return;
                }
                else {
                        rq2 = _delete_resolve_queue();
                        if ( rq2 == 0 )
                                return;
                        if ( rq2->pri == 1 &&
                                        get_xltime() - rq2->start_time > RESOLV_QUE_T
                                                                           IMEOUT ) {
                                rq2->status = RQ_TIMEOUT;
                                wakeup_task((int)rq2);
                                return;
                        }
                        resolve_run = rq2;
                        rq2->status = RQ_RUN;
                        wakeup_task((int)rq2);
                        if ( rq2->pri == 0 ) {
                                rq2->start_time = get_xltime();
                                new_tick(wakeup_resolve_thread,-RESOLV_MIN_TIMEOUT,0)
                                                                                    ;
                        }
                }
        }
        else if ( resolve_run->status == RQ_OK_ ) {
                resolve_run = 0;
                goto retry;
        }
        else if ( resolve_run->pri ) {
                if ( resolve_que_header[0].head == 0 )
                        return;
                rq2 = resolve_run;
                resolve_run = 0;
                rq2->status = RQ_IDLE;
                _insert_resolve_queue(rq2);
                aboat_resolve_flag = 1;
                aboat_resolve_request();
                new_tick(wakeup_resolve_thread,-1,0);
                goto retry;
        }
        else {
                if ( (t = get_xltime() - resolve_run->start_time) >= RESOLV_MIN_TIMEO
                                                                               UT ) {
                        resolve_run->pri = 1;
resolve.c___________________________________________________________________________3

                        goto retry;
                }
                new_tick(wakeup_resolve_thread,t-RESOLV_MIN_TIMEOUT,0);
                return;
        }
}

void
wakeup_resolve_thread()
{
        lock_task(resolve_lock2);
        _wakeup_resolve_thread();
        unlock_task(resolve_lock2,"wakeup_resolve_thread");
}


int
_entry_resolve_call(RESOLVE_QUEUE * rq)
{

        rq->status = RQ_IDLE;
        rq->start_time = get_xltime();
        _insert_resolve_queue(rq);
        _wakeup_resolve_thread();
        for ( ; rq->status != RQ_RUN ; ) {
                sleep_task((int)rq,resolve_lock2);
                lock_task(resolve_lock2);
        }
        return 0;
}

int
_exit_resolve_call(RESOLVE_QUEUE * rq)
{
        if ( rq->status == RQ_RUN ) {
                rq->status = RQ_OK_;
                _wakeup_resolve_thread();
                return 0;
        }
        aboat_resolve_flag = 0;
        _wakeup_resolve_thread();
        for ( ; rq->status != RQ_RUN ; ) {
                sleep_task((int)rq,resolve_lock2);
                lock_task(resolve_lock2);
        }
        if ( rq->status == RQ_TIMEOUT )
                return 0;
        return -1;
}


HOST_ENTRY *
_search_host_entry_byname(char * name)
{
HOST_ENTRY * ret;
int i;
        if ( name == 0 )
                return 0; 
        prev_cache = &resolv_cache;
        for ( ret = resolv_cache ; ret ; 
                        prev_cache = &ret->next,
                        ret = ret->next ) {
                for ( i = 0 ; ret->names[i] ; i ++ )
                        if ( strcmp(ret->names[i],name) == 0 )
                                return ret;
        }
resolve.c___________________________________________________________________________4

        return 0;
}

HOST_ENTRY *
_search_host_entry_byaddr(HOST_ADDR ip)
{
HOST_ENTRY * ret;
int i;
        prev_cache = &resolv_cache;
        for ( ret = resolv_cache ; ret ;
                        prev_cache = &ret->next,
                        ret = ret->next ) {
                for ( i = 0 ; i < ret->ips_length ; i ++ ) {
                        if ( ret->ips[i].size != ip.size )
                                continue;
                        if ( memcmp(&ret->ips[i].d,&ip.d,ip.size) )
                                continue;
                        return ret;
                }
        }
        return 0;
}

HOST_ENTRY *
new_host_entry(int names_size,int ips_size)
{
HOST_ENTRY * ret;
        ret = d_alloc(sizeof(*ret));
        ret->flags = 0;
        ret->names = d_alloc((names_size+1)*sizeof(char*));
        ret->ips = d_alloc(ips_size*sizeof(HOST_ADDR));
        ret->ips_length = ips_size;
        ret->timer = 0;
        ret->canonical = 0;
        return ret;
}

void
free_host_entry(HOST_ENTRY * he)
{
char ** q;
        for ( q = he->names ; *q ; q ++ )
                d_f_ree(*q);
        d_f_ree(he->names);
        d_f_ree(he->ips);
        d_f_ree(he);
}

void
_delete_host_entry(HOST_ENTRY * he)
{
HOST_ENTRY ** hep;
        if ( prev_cache && *prev_cache == he ) {
                hep = prev_cache;
                goto del;
        }
        for ( hep = &resolv_cache ; *hep ; hep = &(*hep)->next )
                if ( *hep == he )
                        goto del;
        return;
del:
        *hep = he->next;
        prev_cache = 0;

        if ( del_list[del_ptr] )
                free_host_entry(del_list[del_ptr]);
resolve.c___________________________________________________________________________5

        del_list[del_ptr++] = he;
        if ( del_ptr >= DEL_SIZE )
                del_ptr = 0;
        return;
}


void
_insert_host_entry(HOST_ENTRY * he)
{
        he->next = resolv_cache;
        resolv_cache = he;
        prev_cache = 0;
}


int
_cmp_he_name(char * name,HOST_ENTRY * he)
{
char ** q;
        for ( q = he->names ; *q ; q ++ )
                if ( strcmp(*q,name) == 0 )
                        return 0;
        return -1;
}

int
_cmp_he_addr(HOST_ADDR a,HOST_ENTRY * he)
{
int i;
HOST_ADDR * ap;
        for ( i = 0 ; i < he->ips_length ; i ++ ) {
                ap = &he->ips[i];
                if ( a.type != ap->type )
                        continue;
                if ( a.size != ap->size )
                        continue;
                if ( memcmp(&a.d,&ap->d,a.size) )
                        continue;
                return 0;
        }
        return -1;
}

int
_cmp_host_entry(HOST_ENTRY * he1,HOST_ENTRY * he2)
{
char ** q, ** r;
int i;
        if ( he1->ips_length != he2->ips_length )
                return -1;
        for ( q = he1->names, r = he2->names ; *q && *r ; q ++ , r ++ );
        if ( *q != *r )
                return -1;
        for ( q = he1->names ; *q ; q ++ )
                if ( _cmp_he_name(*q,he2) < 0 )
                        return -1;
        for ( i = 0 ; i < he1->ips_length ; i ++ )
                if ( _cmp_he_addr(he1->ips[i],he2) < 0 )
                        return -1;
        return 0;
}

HOST_ENTRY * 
_replace_host_entry(HOST_ENTRY * he)
{
resolve.c___________________________________________________________________________6

int i;
HOST_ENTRY * he1;
        he1 = _search_host_entry_byname(he->names[0]);
        if ( he1 && _cmp_host_entry(he1,he) == 0 )
                return he1;
        for ( i = 0 ; he->names[i] ; i ++ ) {
                he1 = _search_host_entry_byname(he->names[i]);
                if ( he1 == 0 )
                        continue;
                wakeup_task((int)he1);
                _delete_host_entry(he1);
        }
        for ( i = 0 ; i  < he->ips_length ; i ++ ) {
                he1 = _search_host_entry_byaddr(he->ips[i]);
                if ( he1 == 0 )
                        continue;
                wakeup_task((int)he1);
                _delete_host_entry(he1);
        }
        _insert_host_entry(he);
        return he;
}


void
_host_entry_regulation(HOST_ENTRY * he)
{
char * dom;
char ** q;
char * p;
int len1,len_dom;
char * target;
        dom = get_localdomainname();
        if ( dom == 0 )
                return;
        len_dom = strlen(dom);
        for ( q = he->names ; *q ; q ++ ) {
                if ( strcmp(*q,"localhost") == 0 )
                        continue;
                p = *q;
                for ( ; *p && *p != '.' ; p ++ );
                if ( *p == '.' ) {
                        len1 = strlen(&p[1]);
                        if ( memcmp(&p[1],dom,len1) == 0 ) {
                                target = d_alloc(strlen(*q)+len_dom+2);
                                *p = 0;
                                sprintf(target,"%s.%s",*q,dom);
                                d_f_ree(*q);
                                *q = target;
                        }
                }
                else {
                        target = d_alloc(strlen(*q)+len_dom+2);
                        sprintf(target,"%s.%s",*q,dom);
                        d_f_ree(*q);
                        *q = target;
                }
        }
        he->canonical = he->names[0];
}


HOST_ENTRY *
_err_host_entry(char * name,HOST_ADDR * ap)
{
int nsize,ipsize;
resolve.c___________________________________________________________________________7

HOST_ENTRY * ret;
        if ( name )
                nsize = 2;
        else    nsize = 1;
        if ( ap )
                ipsize = 1;
        else    ipsize = 0;
        ret = new_host_entry(nsize,ipsize);
        if ( name ) {
                ret->names[0] = copy_str(name);
                ret->names[1] = 0;
                ret->canonical = ret->names[0];
        }
        else {
                ret->names[0] = 0;
                ret->canonical = 0;
        }
        if ( ap ) {
                ret->ips[0] = *ap;
        }
        ret->flags |= HEF_ERROR;
        return ret;
}

int
_return_host_entry(HOST_ENTRY * he,char * name,HOST_ADDR * ap)
{
        if ( he == 0 ) {
                he = _err_host_entry(name,ap);
                he->flags = HEF_LOADING;
                return RHE_NOTHING;
        }
        if ( he->flags & HEF_LOADING ) {
                for ( ; he->flags & HEF_LOADING ; ) {
                        sleep_task((int)he,resolve_lock2);
                        lock_task(resolve_lock2);
                }
                return RHE_RETRY;
        }
        return RHE_OK;
}



void
resolve_thread()
{
RESOLVE_REQUEST_T * n;

        resolve_tid = get_tid();
        for ( ; ; ) {
                lock_task(resolve_lock2);
                if (  resolve_que_head == 0 ) {
                        resolve_tid = 0;
                        resolve_launch = 0;
                        unlock_task(resolve_lock2,"resolve_thread");
                        break;
                }
                n = resolve_que_head;
                resolve_que_head = n->next;
                if ( resolve_que_head == 0 )
                        resolve_que_tail = 0;
                unlock_task(resolve_lock2,"resolve_thread");

                if ( n->a ) {
                        resolve_running = 1;
resolve.c___________________________________________________________________________8

                        n->hp = intr_gethostbyaddr_rr(*n->a);
                        resolve_running = 0;
                }
                else if ( n->name ) {
                        resolve_running = 1;
                        n->hp = intr_gethostbyname_rr(n->name);
                        resolve_running = 0;
                }
                else    n->hp = 0;


                lock_task(resolve_lock2);
                n->ok = 1;
                wakeup_task((int)n);
                unlock_task(resolve_lock2,"resolve_thread");
        }
}

HOST_ENTRY *
resolve_request(HOST_ADDR * a,char * name)
{
RESOLVE_REQUEST_T n;
        memset(&n,0,sizeof(n));
        n.a = a;
        n.name = name;
        lock_task(resolve_lock2);
        if ( resolve_que_head ) {
                resolve_que_tail->next = &n;
                resolve_que_tail = &n;
        }
        else resolve_que_head = resolve_que_tail = &n;
        wakeup_task((int)&resolve_que_head);
        if ( resolve_launch == 0 ) {
                create_task(resolve_thread,PRI_FETCH,0);
                resolve_launch = 1;
        }
        for ( ; n.ok == 0 ; ) {
                sleep_task((int)&n,resolve_lock2);
                lock_task(resolve_lock2);
        }
        unlock_task(resolve_lock2,"resolve_request");
        return n.hp;
}

HOST_ENTRY *
r_gethostbyaddr(HOST_ADDR a)
{
HOST_ENTRY * ret, *new_ret;
unsigned int t;
RESOLVE_QUEUE rq;

/*
ss_printf("r_get_hostbyaddr :: %x\n",a.d.v4);
*/
        lock_task(resolve_lock2);
retry2:
        ret = _search_host_entry_byaddr(a);
        switch ( _return_host_entry(ret,0,&a) ) {
        case RHE_OK:
                goto ok;
        case RHE_RETRY:
                goto retry2;
        case RHE_NOTHING:
                break;
        default:
                er_panic("RHE");
resolve.c___________________________________________________________________________9

        }
        _entry_resolve_call(&rq);
retry:
        unlock_task(resolve_lock2,"r_get_hostbyaddr");

        if ( SEQUENCE_RESOLVE )
                ret = resolve_request(&a,0);
        else    ret = intr_gethostbyaddr_rr(a);

        lock_task(resolve_lock2);
        if ( _exit_resolve_call(&rq) < 0 )
                goto retry;
        if ( rq.status == RQ_TIMEOUT )
                ret = 0;

        t = get_xltime();
        if ( ret ) {
                _host_entry_regulation(ret);
                new_ret = _replace_host_entry(ret);
                if ( new_ret != ret ) {
                        free_host_entry(ret);
                        ret = new_ret;
                }
                ret->timer = 0;
        }
        else {
                ret = _err_host_entry(0,&a);
                new_ret = _replace_host_entry(ret);
                if ( new_ret != ret ) {
                        free_host_entry(ret);
                        ret = new_ret;
                }
                ret->timer = 0;
/*
                ret = _search_host_entry_byaddr(a);
                if ( ret && !(ret->flags & HEF_LOGHOST) ) {
                        if ( ret->timer == 0 )
                                ret->timer = t;
                        else if ( t - ret->timer > RESOLV_TIMEOUT ) {
                                _delete_host_entry(ret);
                                ret = 0;
                        }
                }
*/
        }
ok:
        if ( ret )
                ret->access = t;
        if ( ret->flags & HEF_ERROR )
                ret = 0;
        unlock_task(resolve_lock2,"r_gethostbyaddr");
        return ret;
}

HOST_ENTRY *
r_gethostbyname(char * name)
{
HOST_ENTRY * ret, * new_ret;
unsigned int t;
RESOLVE_QUEUE rq;
/*
ss_printf("r_get_hostbyname :: %s\n",name);
*/
        lock_task(resolve_lock2);
retry2:
        ret = _search_host_entry_byname(name);
resolve.c__________________________________________________________________________10

        switch ( _return_host_entry(ret,name,0) ) {
        case RHE_OK:
                goto ok;
        case RHE_RETRY:
                goto retry2;
        case RHE_NOTHING:
                break;
        default:
                er_panic("RHE");
        }
        _entry_resolve_call(&rq);
retry:
        unlock_task(resolve_lock2,"r_get_hostbyname");

        if ( SEQUENCE_RESOLVE )
                ret = resolve_request(0,name);
        else    ret = intr_gethostbyname_rr(name);

        lock_task(resolve_lock2);
        if ( _exit_resolve_call(&rq) < 0 )
                goto retry;
        if ( rq.status == RQ_TIMEOUT )
                ret = 0;

        t = get_xltime();
        if ( ret ) {
                _host_entry_regulation(ret);
                new_ret = _replace_host_entry(ret);
                if ( new_ret != ret ) {
                        free_host_entry(ret);
                        ret = new_ret;
                }
                ret->timer = 0;
        }
        else {
                ret = _err_host_entry(name,0);
                new_ret = _replace_host_entry(ret);
                if ( new_ret != ret ) {
                        free_host_entry(ret);
                        ret = new_ret;
                }
                ret->timer = 0;
/*
                ret = _search_host_entry_byname(name);
                if ( ret && !(ret->flags & HEF_LOGHOST) ) {
                        if ( ret->timer == 0 )
                                ret->timer = t;
                        else if ( t - ret->timer > RESOLV_TIMEOUT ) {
                                _delete_host_entry(ret);
                                ret = 0;
                        }
                }
*/
        }
ok:
        if ( ret )
                ret->access = t;
        if ( ret->flags & HEF_ERROR )
                ret = 0;
        unlock_task(resolve_lock2,"r_gethostbyname");
/*
ss_printf("r_get_hostbyname :: %s OK\n",name);
*/
        return ret;
}

resolve.c__________________________________________________________________________11

void
resolv_tick()
{
HOST_ENTRY * he;
unsigned int t;
        t = get_xltime();
        lock_task(resolve_lock2);
retry:
        for ( he = resolv_cache ; he ; he = he->next ) {
                if ( he->flags & HEF_LOGHOST )
                        continue;
                if ( t - he->access > RESOLV_TICK ) {
                        _delete_host_entry(he);
                        goto retry;
                }
        }
        unlock_task(resolve_lock2,"resolv_tick");
}

int
cmp_HA(HOST_ADDR a,HOST_ADDR b)
{
        if ( a.type != b.type )
                return -1;
        if ( a.size != b.size )
                return -1;
        if ( memcmp(&a.d,&b.d,a.size) == 0 )
                return 0;
        return -1;
}




































resolve.c__________________________________________________________________________12

/**********************************************************************
 
        Copyright (C) 2003 Hirohisa MORI <joshua@nichibun.ac.jp>
 
        This program is free software; you can redistribute it 
        and/or modify it under the terms of the GLOBALBASE 
        Library General Public License (G-LGPL) as published by 

        http://www.globalbase.org/
 
        This program is distributed in the hope that it will be 
        useful, but WITHOUT ANY WARRANTY; without even the 
        implied warranty of MERCHANTABILITY or FITNESS FOR A 
        PARTICULAR PURPOSE.

**********************************************************************/



#include        "utils.h"
#include        "memory_debug.h"

typedef struct safety_entity {
        char            ch;
        char *          ent;
} SAFETY_ENTITY;

SAFETY_ENTITY se[] = {
        {'&' , "&amp;"},
        {'<' , "&lt;"},
        {'\\' ,"\\\\"},
        {'\n' ,"\\n"},
        {'\r' ,"\\n"},
        {0,0}
};

L_CHAR *
xx_safety_string(L_CHAR * str,
        char * __file,int __line)
{
L_CHAR * ret;
int i,cnt,len;
L_CHAR ch;
int max;
SAFETY_ENTITY * sep;
L_CHAR * p;
char * q;
        max = 0;
        for ( i = 0 ; se[i].ch ; i ++ ) {
                len = strlen(se[i].ent);
                if ( max < len )
                        max = len;
        }
        cnt = 0;
        for ( i = 0 ; str[i] ; i ++ ) {
                for ( sep = &se[0] ; sep->ch ; sep ++ )
                        if ( sep->ch == str[i] )
                                cnt ++;
        }
        len = i;

        ret = xx_d_alloc((len + max*cnt + 1)*sizeof(L_CHAR),__file,__line);
        p = ret;
        for ( i = 0 ; i < len ; i ++ ) {
                ch = str[i];
                sep = &se[0];
safety_string.c_____________________________________________________________________1

                for ( ; sep->ch ; sep ++ ) {
                        if ( sep->ch == ch )
                                goto next;
                }
                *p ++ = ch;
                continue;
        next:
                for ( q = sep->ent ; *q ; )
                        *p++ = *q++;
        }
        *p = 0;
        return ret;
}





















































safety_string.c_____________________________________________________________________2

/**********************************************************************
 
        Copyright (C) 2003 Hirohisa MORI <joshua@nichibun.ac.jp>
 
        This program is free software; you can redistribute it 
        and/or modify it under the terms of the GLOBALBASE 
        Library General Public License (G-LGPL) as published by 

        http://www.globalbase.org/
 
        This program is distributed in the hope that it will be 
        useful, but WITHOUT ANY WARRANTY; without even the 
        implied warranty of MERCHANTABILITY or FITNESS FOR A 
        PARTICULAR PURPOSE.

**********************************************************************/

#include        "utils.h"
#include        "save_global.h"
#include        "memory_debug.h"


FILE * sg_fd;
int init_sg_flag;

void
init_sg()
{
char filename[100];
char * _filename;

        if ( init_sg_flag )
                return;
        init_sg_flag = 1;
        sprintf(filename,"%sglobal.txt",get_preference_path());
        _filename = change_delim_str(filename);
        u_mkdir(get_preference_path(),0700);
        sg_fd = fopen(_filename,"w+");
        if ( _filename != filename )
                d_f_ree(_filename);
}

void
end_sg()
{
        fclose(sg_fd);
}

void
sg_title(char * title)
{
        if ( sg_fd == 0 )
                return;
        fprintf(sg_fd,"\n%s\n\n",title);
}

void
sg(char * type,char * name,void * ptr)
{
        if ( sg_fd == 0 )
                return;
        fprintf(sg_fd,"%s\t\t*((%s*)0x%x)\n",name,type,(int)ptr);
}



save_global.c_______________________________________________________________________1

/**********************************************************************
 
        Copyright (C) 2003 Hirohisa MORI <joshua@nichibun.ac.jp>
 
        This program is free software; you can redistribute it 
        and/or modify it under the terms of the GLOBALBASE 
        Library General Public License (G-LGPL) as published by 

        http://www.globalbase.org/
 
        This program is distributed in the hope that it will be 
        useful, but WITHOUT ANY WARRANTY; without even the 
        implied warranty of MERCHANTABILITY or FITNESS FOR A 
        PARTICULAR PURPOSE.

**********************************************************************/


#include        <stdlib.h>
#include        "utils.h"
#include        "memory_debug.h"

#define BUFFER_FIFO_SIZE                50
#define BUFFER_THREAD_LEN               11

typedef struct buffer {
        THREAD_AREA_HEADER      h;
        int                     ptr;
        void *                  fifo[BUFFER_FIFO_SIZE];
        char *                  file[BUFFER_FIFO_SIZE];
        int                     line[BUFFER_FIFO_SIZE];
} BUFFER;

void set_buffer_close_gc(BUFFER * bf);

THREAD_AREA     sb_ta;

void
set_buffer_close_gc(BUFFER * bf)
{
int i;
        for ( i = 0 ; i < BUFFER_FIFO_SIZE ; i ++ )
                if ( bf->fifo[i] )
                        d_f_ree(bf->fifo[i]);
}

void
init_set_buffer()
{
THREAD_AREA param;
        param.ent_size = BUFFER_THREAD_LEN;
        param.area_size = sizeof(BUFFER);
        param.close_gc = set_buffer_close_gc;
        init_thread_area(&sb_ta,&param);
}

void
xx_set_buffer(void * buf,char* _file,int _line)
{
BUFFER * bf;
        init_set_buffer();
        bf = get_my_area(&sb_ta);
        if ( bf->fifo[bf->ptr] )
                d_f_ree(bf->fifo[bf->ptr]);
        bf->fifo[bf->ptr] = buf;
        bf->file[bf->ptr] = _file;
set_buffer.c________________________________________________________________________1

        bf->line[bf->ptr] = _line;
        bf->ptr ++;
        if ( bf->ptr >= BUFFER_FIFO_SIZE )
                bf->ptr = 0;
}





























































set_buffer.c________________________________________________________________________2

/**********************************************************************
 
        Copyright (C) 2003 Hirohisa MORI <joshua@nichibun.ac.jp>
 
        This program is free software; you can redistribute it 
        and/or modify it under the terms of the GLOBALBASE 
        Library General Public License (G-LGPL) as published by 

        http://www.globalbase.org/
 
        This program is distributed in the hope that it will be 
        useful, but WITHOUT ANY WARRANTY; without even the 
        implied warranty of MERCHANTABILITY or FITNESS FOR A 
        PARTICULAR PURPOSE.

**********************************************************************/


#include        <stdlib.h>
#include        "utils.h"
#include        "memory_debug.h"
#include        "xl.h"


#define BUFFER_THREAD_LEN       11

typedef struct buffer {
        THREAD_AREA_HEADER      h;
        int                     type;
        int                     pos;
} BUFFER;

void set_cpu_msg(int pos);
void set_cpu_thr_type(int type);
void set_cpu_msg_close_gc(BUFFER * bf);


THREAD_AREA     cpu_ta;

void
set_cpu_msg_close_gc(BUFFER * bf)
{
}

void
init_cpu_msg()
{
THREAD_AREA param;
        param.ent_size = BUFFER_THREAD_LEN;
        param.area_size = sizeof(BUFFER);
        param.close_gc = set_cpu_msg_close_gc;
        init_thread_area(&cpu_ta,&param);
}

void
set_cpu_msg(int pos)
{
BUFFER * bf;
        init_cpu_msg();
        bf = get_my_area(&cpu_ta);
        bf->pos = pos;
}


void
set_cpu_thr_type(int type)
set_cpu_msg.c_______________________________________________________________________1

{
BUFFER * bf;
        init_cpu_msg();
        bf = get_my_area(&cpu_ta);
        bf->pos = 0;
        bf->type = type;
}

typedef struct buf_list {
        BUFFER                  b;
        struct buf_list *       next;
} BUF_LIST;

typedef struct cpu_w {
        BUF_LIST *              ret;
} CPU_W;

int gv_cpu_func(BUFFER * th,CPU_W * w);
int gv_cpu_direct_func(BUFFER * th,CPU_W * w);

XL_SEXP * gv_cpu();

void
init_gv_cpu(XLISP_ENV * e)
{
        set_env(e,l_string(std_cm,"gv-cpu"),
                get_func_prim(gv_cpu,FO_APPLICATIVE,0,1,1));
}

int
gv_cpu_func(BUFFER * th,CPU_W * w)
{
BUF_LIST * b;
        b = d_alloc(sizeof(*b));
        b->b = *th;
        b->next = w->ret;
        w->ret = b;
        return 0;
}

XL_SEXP *
gv_cpu()
{
CPU_W w;
XL_SEXP * ret;
BUF_LIST * bp, * bpp;
        w.ret = 0;
        scan_ta(&cpu_ta,gv_cpu_func,&w);

        ret = 0;
        for ( bp = w.ret ; bp ; bp = bp->next ) {
                ret = cons(
                        List(get_integer(bp->b.h.tid,0),
                                get_integer(bp->b.type,0),
                                get_integer(bp->b.pos,0),
                                -1),
                        ret);
        }
        bp = w.ret;
        for ( ; bp ; ) {
                bpp = bp;
                bp = bp->next;
                d_f_ree(bpp);
        }

        return cons(
set_cpu_msg.c_______________________________________________________________________2

                List(n_get_symbol("fd"),
                        get_integer(s_check_resource2(0),0),
                        -1),
                ret);
}

int
gv_cpu_direct_func(BUFFER * th,CPU_W * w)
{
        printf("(i:%i t:%i p:%i)",
                th->h.tid,
                th->type,
                th->pos);
        return 0;
}

void
gv_cpu_direct()
{
CPU_W w;
        w.ret = 0;
        printf("TH ==> ");
        scan_ta(&cpu_ta,gv_cpu_direct_func,&w);
        printf("END\n");
}









































set_cpu_msg.c_______________________________________________________________________3

/**********************************************************************
 
        Copyright (C) 2003 Hirohisa MORI <joshua@nichibun.ac.jp>
 
        This program is free software; you can redistribute it 
        and/or modify it under the terms of the GLOBALBASE 
        Library General Public License (G-LGPL) as published by 

        http://www.globalbase.org/
 
        This program is distributed in the hope that it will be 
        useful, but WITHOUT ANY WARRANTY; without even the 
        implied warranty of MERCHANTABILITY or FITNESS FOR A 
        PARTICULAR PURPOSE.

**********************************************************************/

#include        "u_file.h"


_SYS_PARAM      sys_param;

void
set_sys_param()
{
        sys_param.max_fd = get_fd_max();
        sys_param.cpu = numofcpu();
        sys_param.init_mem_size = get_mem_size();

}




































set_sys_param.c_____________________________________________________________________1

/**********************************************************************
 
        Copyright (C) 2003 Hirohisa MORI <joshua@nichibun.ac.jp>
 
        This program is free software; you can redistribute it 
        and/or modify it under the terms of the GLOBALBASE 
        Library General Public License (G-LGPL) as published by 

        http://www.globalbase.org/
 
        This program is distributed in the hope that it will be 
        useful, but WITHOUT ANY WARRANTY; without even the 
        implied warranty of MERCHANTABILITY or FITNESS FOR A 
        PARTICULAR PURPOSE.

**********************************************************************/


#include        <stdlib.h>
#include        "memory_debug.h"
#include        "task.h"
#include        "utils.h"
#include        "lock_level.h"

#define TA_HASH_KEY(ta,tid)     ((tid)%(ta)->ent_size)

THREAD_AREA *   ta_head;
int             ta_flag;
SEM             ta_lock;
extern SEM      utils_lock;

void
init_thread_area(THREAD_AREA * ta,THREAD_AREA * ta_param)
{
int i;
        lock_task(utils_lock);
        if ( ta_flag == 0 ) {
                ta_flag = 1;
                ta_lock = new_lock(LL_THREAD_AREA);
        }
        unlock_task(utils_lock,"init_thread_area");
        lock_task(ta_lock);
        if ( ta->ent )
                goto end;
        *ta = *ta_param;
        ta->ent = d_alloc(sizeof(THREAD_AREA_HEADER*)*ta->ent_size);
        for ( i = 0 ; i < ta->ent_size ; i ++ )
                ta->ent[i] = 0;
        ta->next = ta_head;
        ta_head = ta;
end:
        unlock_task(ta_lock,"init_thread_area");
}

void *
get_my_area(THREAD_AREA * ta)
{
unsigned int tid,key;
THREAD_AREA_HEADER * th;
int i;
char * ptr;
        lock_task(ta_lock);
        tid = get_tid();
        key = TA_HASH_KEY(ta,tid);
        for ( th = ta->ent[key] ; th ; th = th->next )
                if ( th->tid == tid ) {
thread_area.c_______________________________________________________________________1

                        unlock_task(ta_lock,"get_my_area");
                        return (void*)th;
                }
        th = d_alloc(ta->area_size);
        for ( ptr = (char*)th, i = ta->area_size ; i ; i -- )
                *ptr++ = 0;
        th->tid = tid;
        th->next = ta->ent[key];
        ta->ent[key] = th;
        unlock_task(ta_lock,"get_my_area");
        return (void*)th;
}

void
close_thread_area()
{
int tid;
THREAD_AREA * ta;
THREAD_AREA_HEADER ** thp,* th;
int key;
        lock_task(ta_lock);
        tid = get_tid();
        for ( ta = ta_head ; ta ; ta = ta->next ) {
                key = TA_HASH_KEY(ta,tid);
                for ( thp = &ta->ent[key] ; *thp ; thp = &(*thp)->next ) {
                        th = *thp;
                        if ( th->tid != tid )
                                continue;
                        *thp = th->next;
                        (*ta->close_gc)(th);
                        d_f_ree(th);
                        break;
                }
        }
        unlock_task(ta_lock,"close_thread_area");
}


int
scan_ta(THREAD_AREA * ta,int (*func)(),void * work)
{
int key;
THREAD_AREA_HEADER * th;
int ret;
        ret = 0;
        lock_task(ta_lock);
        for ( key = 0; key < ta->ent_size ; key ++ )
                for ( th = ta->ent[key] ; th ; th = th->next ) {
                        ret = (*func)(th,work);
                        if ( ret )
                                goto end;
                }
end:
        unlock_task(ta_lock,"scan_ta");
        return ret;
}










thread_area.c_______________________________________________________________________2

/**********************************************************************
 
        Copyright (C) 2003 Hirohisa MORI <joshua@nichibun.ac.jp>
 
        This program is free software; you can redistribute it 
        and/or modify it under the terms of the GLOBALBASE 
        Library General Public License (G-LGPL) as published by 

        http://www.globalbase.org/
 
        This program is distributed in the hope that it will be 
        useful, but WITHOUT ANY WARRANTY; without even the 
        implied warranty of MERCHANTABILITY or FITNESS FOR A 
        PARTICULAR PURPOSE.

**********************************************************************/


#include        "task.h"
#include        "memory_debug.h"
#include        "utils.h"
#include        "lock_level.h"
#include        "pri_level.h"

void tick_thread();
void tick_thread_2();

typedef struct tick_func {
        struct tick_func *      next;
        void                    (*func)();
        int                     data;
        int                     interval;
} TICK_FUNC;

typedef struct tick_wheel {
        struct tick_wheel *     next;
        TICK_FUNC *             list;
        unsigned int            invoke;
} TICK_WHEEL;

void insert_tick(TICK_FUNC * tl,unsigned int time);
void insert_immidiate_tick(TICK_FUNC * tl);

TICK_WHEEL * wheel;
SEM tick_lock;
TICK_FUNC * target_tick;

TICK_FUNC * immidiate_tick;
TICK_FUNC * immidiate_tick_tail;

void
init_tick()
{
        tick_lock = new_lock(LL_TICK);
        create_task(tick_thread,0,PRI_TICK);
        create_task(tick_thread_2,0,PRI_TICK_STRONG);
}

void
insert_immidiate_tick(TICK_FUNC * tl)
{
        lock_task(tick_lock);
        tl->next = 0;
        if ( immidiate_tick ) {
                immidiate_tick_tail->next = tl;
                immidiate_tick_tail = tl;
tick.c______________________________________________________________________________1

        }
        else    immidiate_tick = immidiate_tick_tail = tl;
        wakeup_task((int)&immidiate_tick);
        unlock_task(tick_lock,"insert_immidiate_tick");
}


void
insert_tick(TICK_FUNC * tl,unsigned int time)
{
TICK_WHEEL * w, ** wp;
        tl->next = 0;
        lock_task(tick_lock);
        for ( wp = &wheel ; *wp ; wp = &(*wp)->next ) {
                w = *wp;
                if ( w->invoke > time ) {
                        break;
                }
                else if ( w->invoke == time ) {
                        tl->next = w->list;
                        w->list = tl;
                        goto end;
                }
        }
        w = d_alloc(sizeof(*w));
        w->invoke = time;
        w->list = tl;
        w->next = *wp;
        *wp = w;
end:
        unlock_task(tick_lock,"new_tick(1)");
}

void
new_tick(void (*func)(),int interval,int data)
{
TICK_FUNC * tl;
int _interval;
        tl = d_alloc(sizeof(*tl));
        tl->interval = interval;
        tl->func = func;
        tl->data = data;
        tl->next = 0;
        if ( interval < 0 )
                _interval = -interval;
        else    _interval = interval;
        if ( interval == 0 )
                insert_immidiate_tick(tl);
        else    insert_tick(tl,get_xltime() + _interval);
}

void
change_tick(int interval)
{
        if ( target_tick == 0 )
                return;
        target_tick->interval = interval;
}

void
del_tick(void (*func)())
{
TICK_WHEEL * w, ** wp;
TICK_FUNC * tl, ** tlp;
        lock_task(tick_lock);
        for ( wp = &wheel ; *wp ; ) {
tick.c______________________________________________________________________________2

                w = *wp;
                for ( tlp = &w->list ; *tlp ; ) {
                        tl = *tlp;
                        if ( tl->func != func ) {
                                tlp = &tl->next;
                                continue;
                        }
                        *tlp = tl->next;
                        d_f_ree(tl);
                }
                if ( w->list )
                        wp = &w->next;
                else {
                        *wp = w->next;
                        d_f_ree(w);
                }
        }
        unlock_task(tick_lock,"del_tick");
}

void
del_tick_with_data(void (*func)(),int data)
{
TICK_WHEEL * w, ** wp;
TICK_FUNC * tl, ** tlp;
        lock_task(tick_lock);
        for ( wp = &wheel ; *wp ; ) {
                w = *wp;
                for ( tlp = &w->list ; *tlp ; ) {
                        tl = *tlp;
                        if ( tl->func != func || tl->data != data ) {
                                tlp = &tl->next;
                                continue;
                        }
                        *tlp = tl->next;
                        d_f_ree(tl);
                }
                if ( w->list )
                        wp = &w->next;
                else {
                        *wp = w->next;
                        d_f_ree(w);
                }
        }
        unlock_task(tick_lock,"del_tick");
}

void
tick_thread()
{
int time;
TICK_WHEEL * w;
TICK_FUNC * tf1, * tf2;

        for ( ; ; ) {
                sleep_sec(1);
        more:
                time = get_xltime();
                lock_task(tick_lock);
                if ( wheel == 0 )
                        goto next;
                if ( wheel->invoke > time )
                        goto next;
                w = wheel;
                wheel = w->next;
                unlock_task(tick_lock,"tick_thread");
tick.c______________________________________________________________________________3


                for ( tf1 = w->list ; tf1 ; ) {
                        tf2 = tf1->next;
                        target_tick = tf1;
                        (*tf1->func)(tf1->data);
                        target_tick = 0;
                        if ( tf1->interval <= 0 )
                                d_f_ree(tf1);
                        else {
                                insert_tick(tf1,get_xltime() + tf1->interval);
                        }
                        tf1 = tf2;
                }
                d_f_ree(w);
                goto more;
        next:
                unlock_task(tick_lock,"tick_thread");
        }
}

void
tick_thread_2()
{
TICK_FUNC * f, * f2;
        for ( ; ; ) {
                lock_task(tick_lock);
                for ( ; immidiate_tick == 0  ; ) {
                        sleep_task((int)&immidiate_tick,tick_lock);
                        lock_task(tick_lock);
                }
                f = immidiate_tick;
                immidiate_tick = 0;
                immidiate_tick_tail = 0;
                unlock_task(tick_lock,"tick_thread_2");
                for ( ; f ; )  {
                        f2 = f->next;
                        (*f->func)(f->data);
                        d_f_ree(f);
                        f = f2;
                }
        }
}


void
new_timeout_func(int key)
{
        wakeup_task(key);
}


void
new_timeout(int key,int interval)
{
        new_tick(new_timeout_func,-interval,key);
}

void
del_timeout(int key)
{
        del_tick_with_data(new_timeout_func,key);
}




tick.c______________________________________________________________________________4

/**********************************************************************
 
        Copyright (C) 2003 Hirohisa MORI <joshua@nichibun.ac.jp>
 
        This program is free software; you can redistribute it 
        and/or modify it under the terms of the GLOBALBASE 
        Library General Public License (G-LGPL) as published by 

        http://www.globalbase.org/
 
        This program is distributed in the hope that it will be 
        useful, but WITHOUT ANY WARRANTY; without even the 
        implied warranty of MERCHANTABILITY or FITNESS FOR A 
        PARTICULAR PURPOSE.

**********************************************************************/


#include        "task.h"
#include        "utils.h"
#include        "lock_level.h"
#include        "pri_level.h"




unsigned int _start_time;
int _force_limit;
int _limit;
int (*_sync_func)();
void timeout_exit_task();
void exit_tick();


void
timeout_exit_task()
{
int t;
        t = get_xltime() - _start_time;
        if ( t < _limit )
                sleep_sec(_limit - t);
        if ( _sync_func ) {
                for ( ; get_xltime() - _start_time
                                < _force_limit; ) {
                        if ( (*_sync_func)() == 0 )
                                break;
                        sleep_sec(1);
                }
        }
        exit_stabilizer('r');
        exit(0);
}

void
exit_tick()
{
        create_task(timeout_exit_task,0,0);
}

void
timeout_exit(int limit,int force_limit,int (*sync_func)())
{
        _start_time = get_xltime();
        _limit = limit;
        _force_limit = force_limit;
        _sync_func = sync_func;
timeout_exit.c______________________________________________________________________1

        new_tick(exit_tick,-limit*0.9,0);
}
































































timeout_exit.c______________________________________________________________________2

/**********************************************************************
 
        Copyright (C) 2003 Hirohisa MORI <joshua@nichibun.ac.jp>
 
        This program is free software; you can redistribute it 
        and/or modify it under the terms of the GLOBALBASE 
        Library General Public License (G-LGPL) as published by 

        http://www.globalbase.org/
 
        This program is distributed in the hope that it will be 
        useful, but WITHOUT ANY WARRANTY; without even the 
        implied warranty of MERCHANTABILITY or FITNESS FOR A 
        PARTICULAR PURPOSE.

**********************************************************************/




#ifdef VA2
#include        <varargs.h>
#else
#include        <stdarg.h>
#endif
#include        <fcntl.h>


#include        "log.h"


int (*__log_vprintf)(int,int,void *,char*,va_list);


int
log_vprintf(int level,int layer,void * opt,char * fmt,va_list p)
{
int (*f)(int,int,void*,char*,va_list);

        f = __log_vprintf;
        if ( f )
                return (*f)(level,layer,opt,fmt,p);
        else    return -1;
}

int
log_printf(
        int level,
        int layer,
        void * opt,
        char * fmt,...)
{
va_list p;
int ret;
int (*f)(int,int,void*,char*,va_list);

        f = __log_vprintf;
        if ( f == 0 )
                return -1;
#ifdef VA2
        va_start(p);
#else
        va_start(p,fmt);
#endif

        ret = (*f)(level,layer,opt,fmt,p);
u_log.c_____________________________________________________________________________1

        va_end(p);


        return ret;
}





























































u_log.c_____________________________________________________________________________2

/**********************************************************************
 
        Copyright (C) 2003 Hirohisa MORI <joshua@nichibun.ac.jp>
 
        This program is free software; you can redistribute it 
        and/or modify it under the terms of the GLOBALBASE 
        Library General Public License (G-LGPL) as published by 

        http://www.globalbase.org/
 
        This program is distributed in the hope that it will be 
        useful, but WITHOUT ANY WARRANTY; without even the 
        implied warranty of MERCHANTABILITY or FITNESS FOR A 
        PARTICULAR PURPOSE.

**********************************************************************/



#include        <sys/types.h>
#include        <sys/stat.h>
#include        "memory_debug.h"
#include        "utils.h"
#include        "machine/include.h"

int
u_mkdir(char * str,int mode)
{
char * s, * _s;
int p;
int ret;
        p = strlen(str)-1;
        if ( p <= 0 )
                return -1;
        s = copy_str(str);
        if ( s[p] == '/' ) {
                s[p] = 0;
        }
        _s = change_delim_str(s);
        ret = m_mkdir(_s,mode);
        if ( _s != s )
                d_f_ree(_s);
        d_f_ree(s);
        return ret;
}

DIR *
u_opendir(char * filename)
{
char* _dir;
DIR * ret;
        _dir = change_delim_str(filename);
        ret = opendir(_dir);
        if ( filename != _dir )
                d_f_ree(_dir);
        return ret;
}









u_mkdir.c___________________________________________________________________________1

/**********************************************************************
 
        Copyright (C) 2003 Hirohisa MORI <joshua@nichibun.ac.jp>
 
        This program is free software; you can redistribute it 
        and/or modify it under the terms of the GLOBALBASE 
        Library General Public License (G-LGPL) as published by 

        http://www.globalbase.org/
 
        This program is distributed in the hope that it will be 
        useful, but WITHOUT ANY WARRANTY; without even the 
        implied warranty of MERCHANTABILITY or FITNESS FOR A 
        PARTICULAR PURPOSE.

**********************************************************************/


#include        <stdlib.h>
#include        <string.h>
#include        "memory_debug.h"
#include        "utils.h"

int
unlink_p(char * path);

int
unlink_p(char * path)
{
int len;
char * _path;
int ret;
        len = strlen(path);
        if ( path[len-1] == '/' ) {
                _path = copy_str(path);
                _path[len-1] = 0;
                ret = u_unlink(_path);
                d_f_ree(path);
        }
        else    ret = u_unlink(path);
        return ret;
}

void
u_rm(char * path,int flags)
{
U_STAT st;
DIR * dd;
struct dirent * d;
char * buf;
int len;

        if ( flags & RMF_REC ) {
                u_stat(path,&st);
                switch (st.us_mode & S_IFMT) {
//              case S_IFREG:
                case S_IFDIR:
                        dd = u_opendir(path);
                        if ( dd == 0 )
                                break;
                        for ( ; ; ) {
                                d = u_readdir(dd);
                                if ( d == 0 )
                                        break;
                                if ( strcmp(d->d_name,".") == 0 )
                                        continue;
u_rm.c______________________________________________________________________________1

                                if ( strcmp(d->d_name,"..") == 0 )
                                        continue;
                                buf = d_alloc(
                                        (len=strlen(path))+
                                        strlen(d->d_name)+10);
                                strcpy(buf,path);
                                if ( buf[len-1] == '/' )
                                        strcpy(&buf[len],d->d_name);
                                else {
                                        buf[len] = '/';
                                        strcpy(&buf[len+1],d->d_name);
                                }
                                u_rm(buf,flags);
                        }
                        closedir(dd);

                        rmdir(path);

                        break;
                default:

                        unlink_p(path);

                        break;
                }
        }
        else {
                if ( flags & RMF_FILE ) {
                        u_stat(path,&st);
                        if ( (st.us_mode & S_IFMT) != S_IFDIR )
                                unlink_p(path);
                }
                if ( flags & RMF_DIR ) {
                        u_stat(path,&st);
                        if ( (st.us_mode & S_IFMT) == S_IFDIR ) {
                                dd = u_opendir(path);
                                if ( dd == 0 ) {
                                        rmdir(path);
                                        goto no_rm;
                                }
                                for ( ; ; ) {
                                        d = u_readdir(dd);
                                        if ( d == 0 )
                                                break;
                                        if ( strcmp(d->d_name,".") == 0 )
                                                continue;
                                        if ( strcmp(d->d_name,"..") == 0 )
                                                continue;
                                        closedir(dd);
                                        goto no_rm;
                                }
                                closedir(dd);
                                rmdir(path);
                        }
                no_rm:
                        ;
                }
        }
}







u_rm.c______________________________________________________________________________2

/**********************************************************************
 
        Copyright (C) 2003 Hirohisa MORI <joshua@nichibun.ac.jp>
 
        This program is free software; you can redistribute it 
        and/or modify it under the terms of the GLOBALBASE 
        Library General Public License (G-LGPL) as published by 

        http://www.globalbase.org/
 
        This program is distributed in the hope that it will be 
        useful, but WITHOUT ANY WARRANTY; without even the 
        implied warranty of MERCHANTABILITY or FITNESS FOR A 
        PARTICULAR PURPOSE.

**********************************************************************/


#include        "utils.h"
#include        "netutils.h"

int
_cmp(L_CHAR * a,L_CHAR *b)
{
        if ( a && b ) {
                if ( l_strcmp(a,b) )
                        return -1;
        }
        else if ( a == 0 && b )
                return -1;
        else if ( a && b == 0 )
                return -1;
        return 0;
}

int
_cmp_server(L_CHAR * s1,L_CHAR * s2)
{
int my_ip;
        if ( s1 && s2 ) {
                return hostcmp(
                        n_string(std_cm,s1),
                        getHA_v4(0),
                        n_string(std_cm,s2),
                        getHA_v4(0));
        }
        my_ip = get_localhostip();
        if ( s1 ) {
                return hostcmp(
                        n_string(std_cm,s1),
                        getHA_v4(0),
                        0,
                        getHA_v4(my_ip));
        }
        else if ( s2 ) {
                return hostcmp(
                        0,
                        getHA_v4(my_ip),
                        n_string(std_cm,s2),
                        getHA_v4(0));
        }
        else    return 0;
}

int
url_cmp(URL * a,URL * b)
url_cmp.c___________________________________________________________________________1

{
        if ( _cmp(a->proto,b->proto) )
                return -1;
        if ( _cmp_server(a->server,b->server) )
                return -1;
        if ( a->port != b->port )
                return -1;
        if ( _cmp(a->db,b->db) )
                return -1;
        if ( _cmp(a->resource,b->resource) )
                return -1;
        return 0;
}

int
url_cmp_str(URL * a,URL * b)
{
        if ( _cmp(a->proto,b->proto) )
                return -1;
        if ( _cmp(a->server,b->server) )
                return -1;
        if ( a->port != b->port )
                return -1;
        if ( _cmp(a->db,b->db) )
                return -1;
        if ( _cmp(a->resource,b->resource) )
                return -1;
        return 0;
}





































url_cmp.c___________________________________________________________________________2

/**********************************************************************
 
        Copyright (C) 2003 Hirohisa MORI <joshua@nichibun.ac.jp>
 
        This program is free software; you can redistribute it 
        and/or modify it under the terms of the GLOBALBASE 
        Library General Public License (G-LGPL) as published by 

        http://www.globalbase.org/
 
        This program is distributed in the hope that it will be 
        useful, but WITHOUT ANY WARRANTY; without even the 
        implied warranty of MERCHANTABILITY or FITNESS FOR A 
        PARTICULAR PURPOSE.

**********************************************************************/



#include        "memory_debug.h"
#include        "long_char.h"
#include        "utils.h"
#include        "netutils.h"

L_CHAR *
url_regulation(L_CHAR * url)
{
URL u;
char * d;
char * _ret;
L_CHAR * ret;
char * ptr;
int len_server,len_d;
char * _server;
        get_url2(&u,url);
        if ( u.server == 0 ) {
                ret = ll_copy_str(url);
                goto end0;
        }
        d = get_localdomainname();
        if ( d == 0 ) {
                ret = ll_copy_str(url);
                goto end0;
        }
        _server = ln_copy_str(std_cm,u.server);
        for ( ptr = _server ; *ptr && *ptr != '.' ; ptr ++ );
        if ( *ptr == 0 ) {
                len_server = strlen(_server);
                len_d = strlen(d);
                _ret = d_alloc(len_server + len_d + 20);
                sprintf(_ret,"%s.%s",_server,d);
                ret = nl_copy_str(std_cm,_ret);
        }
        else {
                *ptr = 0;
                ptr ++;
                len_server = strlen(ptr);
                len_d = strlen(d);
                if ( len_d <= len_server ) {
                        ret = ll_copy_str(url);
                        goto end2;
                }
                if ( d[len_server] != '.' ) {
                        ret = ll_copy_str(url);
                        goto end2;
                }
url_regulation.c____________________________________________________________________1

                if ( memcmp(ptr,d,len_server) ) {
                        ret = ll_copy_str(url);
                        goto end2;
                }
                _ret = d_alloc(strlen(_server) + len_d + 20);
                sprintf(_ret,"%s.%s",_server,d);
                ret = nl_copy_str(std_cm,_ret);
        }
        d_f_ree(_ret);
        if ( u.server )
                d_f_ree(u.server);
        u.server = ret;
        ret = ll_copy_str(get_url_str2(&u));
end2:
        d_f_ree(_server);
end0:
        free_url(&u);
        return ret;
}















































url_regulation.c____________________________________________________________________2

/**********************************************************************
 
        Copyright (C) 2003 Hirohisa MORI <joshua@nichibun.ac.jp>
 
        This program is free software; you can redistribute it 
        and/or modify it under the terms of the GLOBALBASE 
        Library General Public License (G-LGPL) as published by 

        http://www.globalbase.org/
 
        This program is distributed in the hope that it will be 
        useful, but WITHOUT ANY WARRANTY; without even the 
        implied warranty of MERCHANTABILITY or FITNESS FOR A 
        PARTICULAR PURPOSE.

**********************************************************************/


#include        "graph.h"

void
marge_vrect(I_RECT * r1,I_RECT * r2)
{
        if ( r1->tl.x >= r1->br.x ) {
                *r1 = *r2;
                return;
        }
        if ( r1->tl.x > r2->tl.x )
                r1->tl.x = r2->tl.x;
        if ( r1->tl.y > r2->tl.y )
                r1->tl.y = r2->tl.y;
        if ( r1->br.x < r2->br.x )
                r1->br.x = r2->br.x;
        if ( r1->br.y < r2->br.y )
                r1->br.y = r2->br.y;
}






























v_utils.c___________________________________________________________________________1

/**********************************************************************
 
        Copyright (C) 2003 Hirohisa MORI <joshua@nichibun.ac.jp>
 
        This program is free software; you can redistribute it 
        and/or modify it under the terms of the GLOBALBASE 
        Library General Public License (G-LGPL) as published by 

        http://www.globalbase.org/
 
        This program is distributed in the hope that it will be 
        useful, but WITHOUT ANY WARRANTY; without even the 
        implied warranty of MERCHANTABILITY or FITNESS FOR A 
        PARTICULAR PURPOSE.

**********************************************************************/



#include        "machine/include.h"
#include        "memory_debug.h"
#include        "utils.h"
#include        "version.h"


VERSION * version_list;


void
set_version(VERSION * v)
{
        v->next = version_list;
        version_list = v;
}


VERSION * 
get_version(char * layer)
{
VERSION * ret;
        if ( layer == 0 )
                return version_list;
        ret = version_list;
        for ( ; ret ; ret = ret->next ) {
                if ( strcmp(ret->layer,layer) == 0 )
                        return ret;
        }
        return 0;
}

void
free_version_v(VERSION * v)
{
        if ( v->layer )
                d_f_ree(v->layer);
        if ( v->name )
                d_f_ree(v->name);
        if ( v->publisher )
                d_f_ree(v->publisher);
        if ( v->version )
                d_f_ree(v->version);
        if ( v->comment )
                d_f_ree(v->comment);
}

void
version.c___________________________________________________________________________1

free_version(VERSION * v)
{
        free_version_v(v);
        d_f_ree(v);
}

void
copy_version(VERSION * v1,VERSION * v2)
{
        *v1 = *v2;
        if ( v2->layer )
                v1->layer = copy_str(v2->layer);
        if ( v2->name )
                v1->name = copy_str(v2->name);
        if ( v2->publisher )
                v1->publisher = copy_str(v2->publisher);
        if ( v2->version )
                v1->version = copy_str(v2->version);
        if ( v2->comment )
                v1->comment = copy_str(v2->comment);
}













































version.c___________________________________________________________________________2

/**********************************************************************
 
        Copyright (C) 2003 Hirohisa MORI <joshua@nichibun.ac.jp>
 
        This program is free software; you can redistribute it 
        and/or modify it under the terms of the GLOBALBASE 
        Library General Public License (G-LGPL) as published by 

        http://www.globalbase.org/
 
        This program is distributed in the hope that it will be 
        useful, but WITHOUT ANY WARRANTY; without even the 
        implied warranty of MERCHANTABILITY or FITNESS FOR A 
        PARTICULAR PURPOSE.

**********************************************************************/



#include        "memory_debug.h"
#include        "utils.h"
#include        "task.h"

extern SEM utils_lock;

void
_waitsync_ack(WAITSYNC_CLIENT * c,WAITSYNC_SERVER * s,int type)
{
WAITSYNC_NODE * n;
        for ( n = c->list ; n ; n = n->client_next ) {
                if ( n->server == s )
                        return;
        }
        if ( type == WST_FORCE_STOP )
                s->wait_type = type;
        n = d_alloc(sizeof(*n));
        n->server = s;
        n->client = c;
        n->client_next = c->list;
        c->list = n;
        n->server_next = s->list;
        s->list = n;
        c->count ++;
}

void
_waitsync_wakeup(WAITSYNC_SERVER * s)
{
WAITSYNC_NODE * n, * n2, ** np;
WAITSYNC_CLIENT * c;
        for ( n = s->list ; n ; n = n2 ) {
                n2 = n->server_next;
                c = n->client;
                np = &c->list;
                for ( ; *np && *np != n ; np = &(*np)->client_next );
                if ( *np == 0 )
                        er_panic("_waitsync_wakeup");
                *np = n->client_next;
                d_f_ree(n);
                if ( c->list == 0 )
                        wakeup_task((int)c);
        }
        s->list = 0;
        s->wait_type = WST_WAIT;
}

waitsync.c__________________________________________________________________________1

void
_waitsync_clear(WAITSYNC_CLIENT * c)
{
WAITSYNC_NODE * n, * n2, ** np;
WAITSYNC_SERVER * s;
        for ( n = c->list ; n ; n = n2 ) {
                n2 = n->client_next;
                s = n->server;
                np = &s->list;
                for ( ; *np && *np != n ; np = &(*np)->server_next );
                if ( *np == 0 )
                        er_panic("_waitsync_clear");
                *np = n->server_next;
                d_f_ree(n);
        }
        c->list = 0;
        c->count = 0;
}


int
_waitsync_sleep(WAITSYNC_CLIENT * c)
{
int ret;
        ret = 0;
        for ( ; c->list ; ) {
                sleep_task((int)c,utils_lock);
                lock_task(utils_lock);
                ret = 1;
        }
        return ret;
}


void
waitsync_ack(WAITSYNC_CLIENT * c,WAITSYNC_SERVER * s,int type)
{
        lock_task(utils_lock);
if ( s->list && ((unsigned int)s->list) < 0x1000 )
er_panic("1");
        _waitsync_ack(c,s,type);
if ( s->list && ((unsigned int)s->list) < 0x1000 )
er_panic("1-1");
        unlock_task(utils_lock,"waitsync");
}


void
waitsync_wakeup(WAITSYNC_SERVER * s)
{
        lock_task(utils_lock);
if ( s->list && ((unsigned int)s->list) < 0x1000 )
er_panic("2");
        _waitsync_wakeup(s);
        unlock_task(utils_lock,"waitsync");
}

int
waitsync_sleep(WAITSYNC_CLIENT * c)
{
int ret;
        lock_task(utils_lock);
        ret = _waitsync_sleep(c);
        unlock_task(utils_lock,"waitsync");
        return ret;
}
waitsync.c__________________________________________________________________________2



void
waitsync_clear(WAITSYNC_CLIENT * c)
{
        lock_task(utils_lock);
        _waitsync_clear(c);
        unlock_task(utils_lock,"waitsync");
}

























































waitsync.c__________________________________________________________________________3

/**********************************************************************
 
        Copyright (C) 2003 Hirohisa MORI <joshua@nichibun.ac.jp>
 
        This program is free software; you can redistribute it 
        and/or modify it under the terms of the GLOBALBASE 
        Library General Public License (G-LGPL) as published by 

        http://www.globalbase.org/
 
        This program is distributed in the hope that it will be 
        useful, but WITHOUT ANY WARRANTY; without even the 
        implied warranty of MERCHANTABILITY or FITNESS FOR A 
        PARTICULAR PURPOSE.

**********************************************************************/



#include        "gbgraph.h"

int
xl_to_gb_point(GB_POINT *p, XL_SEXP * s)
{
#define SET_REAL(a, s)  \
        if ( get_type(s) == XLT_FLOAT ) a = s->floating.data;           \
        else if ( get_type(s) == XLT_INTEGER ) a = s->integer.data;     \
        else return -1

XL_SEXP * x,* y;
        
        if ( list_length(s) != 2 )
                return -1;
        
        x = get_el(s,0);
        y = get_el(s,1);
        
        SET_REAL(p->x, x);
        SET_REAL(p->y, y);
        return 0;
}

XL_SEXP *
gb_point_to_xl(GB_POINT *p)
{
        return List(get_floating(p->x, 0), get_floating(p->y, 0), -1);
}


int
xl_to_gb_rect(GB_RECT *r, XL_SEXP * s)
{
XL_SEXP * tl,* br;

        if ( list_length(s) != 2 )
                return -1;
        
        tl = get_el(s,0);
        br = get_el(s,1);
        
        if ( xl_to_gb_point(&r->tl, tl) )
                return -1;
        if ( xl_to_gb_point(&r->br, br) )
                return -1;
        return 0;
}
xl_gbgraph.c________________________________________________________________________1


XL_SEXP *
gb_rect_to_xl(GB_RECT *r)
{
        return List(gb_point_to_xl(&r->tl), gb_point_to_xl(&r->br), -1);
}




























































xl_gbgraph.c________________________________________________________________________2

/**********************************************************************
 
        Copyright (C) 2003 Hirohisa MORI <joshua@nichibun.ac.jp>
 
        This program is free software; you can redistribute it 
        and/or modify it under the terms of the GLOBALBASE 
        Library General Public License (G-LGPL) as published by 

        http://www.globalbase.org/
 
        This program is distributed in the hope that it will be 
        useful, but WITHOUT ANY WARRANTY; without even the 
        implied warranty of MERCHANTABILITY or FITNESS FOR A 
        PARTICULAR PURPOSE.

**********************************************************************/



#include        "gbgraph.h"


I_RECT
xl_to_i_rect(XL_SEXP * s)
{
I_RECT r;
XL_SEXP * tl_x,* tl_y;
XL_SEXP * br_x,* br_y;
        tl_x = get_el(get_el(s,0),0);
        tl_y = get_el(get_el(s,0),1);
        br_x = get_el(get_el(s,1),0);
        br_y = get_el(get_el(s,1),1);
        r.tl.x = tl_x->integer.data;
        r.tl.y = tl_y->integer.data;
        r.br.x = br_x->integer.data;
        r.br.y = br_y->integer.data;
        return r;
}




























xl_to_i_rect.c______________________________________________________________________1

/**********************************************************************
 
        Copyright (C) 2003 Hirohisa MORI <joshua@nichibun.ac.jp>
 
        This program is free software; you can redistribute it 
        and/or modify it under the terms of the GLOBALBASE 
        Library General Public License (G-LGPL) as published by 

        http://www.globalbase.org/
 
        This program is distributed in the hope that it will be 
        useful, but WITHOUT ANY WARRANTY; without even the 
        implied warranty of MERCHANTABILITY or FITNESS FOR A 
        PARTICULAR PURPOSE.

**********************************************************************/



#include        "utils.h"



void
zero_url(URL * u)
{
        memset(u,0,sizeof(*u));
        u->proto = 0;
        u->server = 0;
        u->port = 0;
        u->db = 0;
        u->resource = 0;
        u->user = 0;
        u->passwd = 0;
}































zero_url.c__________________________________________________________________________1

