home *** CD-ROM | disk | FTP | other *** search
- /*
- o_chan.c
- */
- /* Copyright (c) 1994 Christian F. Tschudin. All rights reserved.
-
- Distributed under the terms of the GNU General Public License
- version 2 of june 1991 as published by the Free Software
- Foundation, Inc.
-
- This file is part of M0.
-
- M0 is distributed in the hope that it will be useful, but WITHOUT ANY
- WARRANTY. No author or distributor accepts responsibility to anyone for
- the consequences of using it or for whether it serves any particular
- purpose or works at all, unless he says so in writing. Refer to the GNU
- General Public License for full details.
-
- Everyone is granted permission to copy, modify and redistribute M0, but
- only under the conditions described in the GNU General Public License.
- A copy of this license is supposed to have been given to you along with
- M0 so you can know your rights and responsibilities. It should be in a
- file named LICENSE. Among other things, the copyright notice and this
- notice must be preserved on all copies. */
-
- #include <stdlib.h>
-
- #include "c_proto.h"
- #include "l_proto.h"
- #include "o_proto.h"
-
-
- #ifdef CHANNEL_CONSOLE
- static retcode
- o_console()
- {
- eindex key;
-
- if (current->osp < 3)
- return ERR_STACK_UNDERFLOW;
-
- decref(current, current->os[current->osp-1]);
- decref(current, current->os[current->osp-2]);
- decref(current, current->os[current->osp-3]);
-
- key = add_console_channel();
- return_ok_result(3, key);
- }
- #endif
-
-
- #ifdef CHANNEL_NIT
- static retcode
- o_nit()
- {
- eindex key;
- byte desthost[6];
-
- load_3_args(addr, srcchan, chk, ap, sp, cp);
-
- if (eptype(ap) != T_STRING || eplen(ap) != 6 || eptype(sp) != T_INT)
- return ERR_TYPE_CHECK;
- if (!(epattr(ap) & A_READ))
- return ERR_ACCESS_CHECK;
-
- str_export(current, desthost, addr, 0, 6);
-
- if (sp->V.i < 0 || sp->V.i > eplen(gaddr(nit_addr)))
- return ERR_RANGE_CHECK;
-
- key = add_nit_channel(sp->V.i, desthost);
-
- decrefp(current,addr,ap);
- decrefp(current,srcchan,sp);
- decrefp(current,chk,cp);
-
- return_ok_result(3, key);
- }
- #endif
-
-
- #ifdef CHANNEL_UDP
- static retcode
- o_udp()
- {
- eindex desthost, port, key;
-
- load_3_args(addr, srcchan, chk, ap, sp, cp);
-
- if (eptype(ap) != T_ARRAY || eplen(ap) != 2 || eptype(sp) != T_INT)
- return ERR_TYPE_CHECK;
- if (!(epattr(ap) & A_READ))
- return ERR_ACCESS_CHECK;
-
- desthost = array_get(current, addr, 0);
- port = array_get(current, addr, 1);
- if (etype(current,desthost) != T_INT || etype(current,port) != T_INT)
- return ERR_TYPE_CHECK;
-
- if (sp->V.i < 0 || sp->V.i > eplen(gaddr(udp_addr)))
- return ERR_RANGE_CHECK;
-
- key = add_udp_channel( sp->V.i,
- eaddr(current, desthost)->V.i,
- eaddr(current, port)->V.i);
-
- decrefp(current,addr,ap);
- decrefp(current,srcchan,sp);
- decrefp(current,chk,cp);
-
- return_ok_result(3, key);
- }
- #endif
-
-
- enum {no_check, car_check};
- enum {asc_target, mzr_target};
-
- struct ch_s {
- eindex *name;
- int type, check, target;
- uint mtu;
- eindex* addr_array;
- retcode (*create_key)();
- byteptr descr;
- };
-
- static struct ch_s ch[] = {
- #ifdef CHANNEL_CONSOLE
- {&console_name, 1, no_check, asc_target, 0, &console_addr, o_console,
- (byteptr)"M0 console (stdout)"},
- #endif
- #ifdef CHANNEL_NIT
- {&nit_name, 1, no_check, mzr_target, 1400, &nit_addr, o_nit,
- (byteptr)"intel/dec/xerox ethernet"},
- #endif
- #ifdef CHANNEL_UDP
- {&udp_name, 1, no_check, mzr_target, 7500, &udp_addr, o_udp,
- (byteptr)"DoD user datagram protocol over IP"},
- #endif
- };
-
- retcode
- channel_defs()
- {
- eindex n_cha, n_adr;
- eindex n_aut, n_des, n_key, n_mtu, n_tar, n_typ;
- eindex check[2], target[2];
- eindex cdict, adict;
- int i, nofch = sizeof(ch)/sizeof(struct ch_s);
-
- n_cha = name_add((byteptr)"_cha", 4, A_EXECUTABLE);
- n_adr = name_add((byteptr)"_adr", 4, A_EXECUTABLE);
-
- n_aut = name_add((byteptr)"_aut", 4, A_EXECUTABLE);
- n_des = name_add((byteptr)"_des", 4, A_EXECUTABLE);
- n_key = name_add((byteptr)"_key", 4, A_EXECUTABLE);
- n_mtu = name_add((byteptr)"_mtu", 4, A_EXECUTABLE);
- n_tar = name_add((byteptr)"_tar", 4, A_EXECUTABLE);
- n_typ = name_add((byteptr)"_typ", 4, A_EXECUTABLE);
- check[0] = name_add((byteptr)"_nch", 4, 0);
- check[1] = name_add((byteptr)"_car", 4, 0);
- target[0] = name_add((byteptr)"_asc", 4, 0);
- target[1] = name_add((byteptr)"_mzr", 4, 0);
-
- cdict = new_dict(0);
- dict_def(0, systemdict, n_cha, cdict);
- decref(0, n_cha); decref(0, cdict);
- adict = new_dict(0);
- dict_def(0, systemdict, n_adr, adict);
- decref(0, n_adr); decref(0, adict);
-
- for (i = 0; i < nofch; i++) {
- eindex e, val, d;
-
- if (!*(ch[i].name))
- continue;
-
- val = *(ch[i].name);
- if (ch[i].addr_array && *(ch[i].addr_array)) {
- dict_def(0, adict, val, *(ch[i].addr_array));
- decref(0, val);
- decref(0, *(ch[i].addr_array));
- }
-
- d = new_dict(0);
- dict_def(0, cdict, val, d);
- decref(0, val);
- decref(0, d);
-
- #define add_entry(k,v) e = (v); dict_def(0,d,k,e);
- add_entry(n_aut, check[ch[i].check]);
- add_entry(n_tar, target[ch[i].target]);
- val = new_element(0, T_INT);
- gaddr(val)->V.i = ch[i].type;
- add_entry(n_typ, val);
- decref(0, val);
- val = str_import(0, ch[i].descr, strlen((char*)(ch[i].descr)), 0);
- add_entry(n_des, val);
- decref(0, val);
- val = new_element(0, T_PROC);
- gaddr(val)->V.pro.fct = ch[i].create_key;
- epattr(gaddr(val)) |= A_EXECUTABLE;
- add_entry(n_key, val);
- decref(0, val);
- val = new_element(0, T_INT);
- gaddr(val)->V.i = ch[i].mtu;
- add_entry(n_mtu, val);
- decref(0, val);
- }
-
- decref(0, n_aut); decref(0, n_des);
- decref(0, n_key); decref(0, n_mtu);
- decref(0, n_tar); decref(0, n_typ);
- decref(0, check[0]); decref(0, check[1]);
- decref(0, target[0]); decref(0, target[1]);
-
- return OK;
- }
-