Newsgroups: comp.sources.unix From: tschudin@cui.unige.ch (Christian Tschudin) Subject: v28i052: m0 - a messenger execution environment, Part02/12 References: <1.770917478.19277@gw.home.vix.com> Sender: unix-sources-moderator@gw.home.vix.com Approved: vixie@gw.home.vix.com Submitted-By: tschudin@cui.unige.ch (Christian Tschudin) Posting-Number: Volume 28, Issue 52 Archive-Name: m0/part02 #! /bin/sh # This is a shell archive. Remove anything before this line, then unpack # it by saving it into a file and typing "sh file". To overwrite existing # files, type "sh file -c". You can also feed this as standard input via # unshar, or by typing "sh 'FILES.doc' <<'END_OF_FILE' X# FILES.doc X# christian tschudin, may 1994 X X Xmain C source files: X m0.c standalone M0 platform (server with UDP and NIT channel) X m0c.c a M0 server with a local console X m0uc.c a remote console contacting the M0 server via UDP X m0strip.c a preprocessor that removes comments and blanks from X M0 sources (used by m0.c, m0uc.c and m0c.c) X Xheader files: X c_proto.h function prototypes and data declarations for channels X chksum.h function prototype for CCITT-16 checksumming X copyrght.h my copyright string X element.h data structures for M0 data types X error.h definition of error numbers X hdr.h the header format of a messenger packet X l_proto.h low-level function prototypes and data declarations X o_proto.h function prototypes and data declarations for M0 operators X proc.h data structures of a messenger process X std.h machine dependend declarations (data types, channels) X strbuf.h a (very simple) self extending char string buffer package X X Xlow-level C code: X l_array.c X l_chksum.c X l_compat.c X l_dict.c X l_dump.c X l_elemnt.c X l_format.c X l_incom.c X l_init.c X l_misc.c X l_name.c X l_proc.c X l_str.c X l_strbuf.c X l_time.c X X XC code for submission channels: X c_con.c local console (stdio) channel X c_file.c local channel into files X c_nit.c routines for SUN's (ethernet) network interface tap X c_udp.c routines for the submission and reception of UDP packets X X XC code for M0 operators and the interpreter: X interp.c X o_arith.c X o_array.c X o_attr.c X o_chan.c X o_ctrl.c X o_dict.c X o_init.c X o_misc.c X o_msgr.c X o_stack.c X o_string.c X o_type.c X X XM0 source files: X cons_ini.m0 M0 code for the console programs (m0c and m0uc) X longdict.m0 definitions of long commands (included by startup.m0) X fragment.m0 M0 sources for a fragmentation (+testing) procedure X frag_0.m0 auxiliary file for fragment.m0 X neighbor.m0 complete M0 sources of an exploration messenger X neigh_ex.m0 auxiliary file for neighbor.m0 X startup.m0 M0 startup code for platforms (m0 and m0c) X X Xman pages: X m0.1 nroff format X m0c.1 nroff format X m0c.man formatted ASCII X m0strip.1 nroff format X m0strip.man formatted ASCII X m0uc.1 nroff format X X Xmiscellaneous files: X FILES.doc this file X LICENSE the GNU General Public License X M0.ps introduction to and complete description of M0 (in PostScript) X MANUAL.doc an ASCII file explaining most of the M0 instructions X Makefile main makefile X README a brief welcome message and installation guide X TODO.doc wish list, improvements, known bugs etc X X makefile.all makefile common to all compilation platforms X makefile.dos MS/DOS specific definitions X makefile.osf DEC/OSF specific definitions X makefile.so4 SUN OS 4.x.y specific definitions X makefile.so5 SUN OS 5.x.y specific definitions X makefile.ult DEC/Ultrix specific definitions X makefile.unx definitions common to all UNIX platforms X X# eof END_OF_FILE if test 2890 -ne `wc -c <'FILES.doc'`; then echo shar: \"'FILES.doc'\" unpacked with wrong size! fi # end of 'FILES.doc' fi if test -f 'l_array.c' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'l_array.c'\" else echo shar: Extracting \"'l_array.c'\" \(3274 characters\) sed "s/^X//" >'l_array.c' <<'END_OF_FILE' X/* X array.c X*/ X/* Copyright (c) 1994 Christian F. Tschudin. All rights reserved. X X Distributed under the terms of the GNU General Public License X version 2 of june 1991 as published by the Free Software X Foundation, Inc. X X This file is part of M0. X XM0 is distributed in the hope that it will be useful, but WITHOUT ANY XWARRANTY. No author or distributor accepts responsibility to anyone for Xthe consequences of using it or for whether it serves any particular Xpurpose or works at all, unless he says so in writing. Refer to the GNU XGeneral Public License for full details. X XEveryone is granted permission to copy, modify and redistribute M0, but Xonly under the conditions described in the GNU General Public License. XA copy of this license is supposed to have been given to you along with XM0 so you can know your rights and responsibilities. It should be in a Xfile named LICENSE. Among other things, the copyright notice and this Xnotice must be preserved on all copies. */ X X#include "l_proto.h" X X Xeindex Xnew_array(mproc p, uint len) X{ X eindex ei = new_element(p, T_ARRAY), *ip; X eptr ep; X X if (!ei ) X return 0; X X ep = eaddr(p,ei); X if (len) { X ep->V.arr.a = (eindex*) malloc(len * sizeof(eindex)); X if (!ep->V.arr.a) { X free_element(p,ei); X return 0; X } X } X eplen(ep) = len; X ep->V.arr.alen = len; X for (ip = ep->V.arr.a; len > 0; len--, ip++) X *ip = null_val; X gaddr(null_val)->R += eplen(ep); X return ei; X} X X Xeindex Xarray_get(mproc p, eindex a, uint offs) X{ X eptr ep = eaddr(p,a); X X if (offs<0 || offs >= eplen(ep)) X return 0; X X if (epattr(ep)&A_SUB) X return array_get(p, ep->V.sub.e, ep->V.sub.offset + offs); X X return ep->V.arr.a[offs]; X} X X Xretcode Xarray_put(mproc p, eindex a, uint offs, eindex e) X{ X eptr ap = eaddr(p,a); X X if (offs<0 || offs >= eplen(ap)) X return ERR_RANGE_CHECK; X X if (epattr(ap)&A_SUB) X return array_put(p, ap->V.sub.e, ap->V.sub.offset + offs, e); X X if (a < 0) { X eindex e2 = make_global(p, e); X decref(p, e); X e = e2; X } X decref(p, ap->V.arr.a[offs]); X ap->V.arr.a[offs] = e; X return OK; X} X X/* make_array does NOT increment the refcount of the included members */ Xeindex Xmake_array(mproc p, eindex *ip, uint len) X{ X eindex ei = new_element(p, T_ARRAY), *ip2; X eptr ep; X X if (!ei ) X return 0; X X ep = eaddr(p,ei); X if (len) { X int i; X ep->V.arr.a = (eindex*) malloc(len * sizeof(eindex)); X if (!ep->V.arr.a) { X free_element(p,ei); X return 0; X } X for (i=len, ip2 = ep->V.arr.a; i > 0; i--) X *ip2++ = *ip++; X eplen(ep) = ep->V.arr.alen = len; X } X return ei; X} X X X/* should be called by free_element() only! */ Xvoid Xarray_free(mproc p, eindex ei) X{ X eindex *ea; X eptr ep = eaddr(p, ei); X int i; X X eptype(ep) = T_EMPTY; X for (i=eplen(ep), ea = ep->V.arr.a; i>0; i--, ea++) X if (*ea) { X eindex e = *ea; X *ea = 0; X decref(p, e); X } X free(ep->V.arr.a); X} X X Xretcode Xarray_copy(mproc p, eindex e, eptr from, eptr to) X{ X int i = eplen(from); X eindex *ip = to->V.arr.a = (eindex*) malloc(i * sizeof(eindex)); X int offs = 0; X X if (!ip) X return ERR_MALLOC_FAILED; X X while (epattr(from) & A_SUB) { X offs += from->V.sub.offset; X from = eaddr(p, from->V.sub.e); X } X X memcpy(ip, from->V.arr.a + offs, i * sizeof(eindex)); X X for (; i > 0; i--, ip++) X incref(p,*ip); X X epattr(to) = A_ALL; X return OK; X} X END_OF_FILE if test 3274 -ne `wc -c <'l_array.c'`; then echo shar: \"'l_array.c'\" unpacked with wrong size! fi # end of 'l_array.c' fi if test -f 'l_chksum.c' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'l_chksum.c'\" else echo shar: Extracting \"'l_chksum.c'\" \(3500 characters\) sed "s/^X//" >'l_chksum.c' <<'END_OF_FILE' X/* X chksum.c X*/ X/* Copyright (c) 1994 Christian F. Tschudin. All rights reserved. X X Distributed under the terms of the GNU General Public License X version 2 of june 1991 as published by the Free Software X Foundation, Inc. X X This file is part of M0. X XM0 is distributed in the hope that it will be useful, but WITHOUT ANY XWARRANTY. No author or distributor accepts responsibility to anyone for Xthe consequences of using it or for whether it serves any particular Xpurpose or works at all, unless he says so in writing. Refer to the GNU XGeneral Public License for full details. X XEveryone is granted permission to copy, modify and redistribute M0, but Xonly under the conditions described in the GNU General Public License. XA copy of this license is supposed to have been given to you along with XM0 so you can know your rights and responsibilities. It should be in a Xfile named LICENSE. Among other things, the copyright notice and this Xnotice must be preserved on all copies. */ X X#include "chksum.h" X X Xushort Xcrc_ccitt(byteptr s, uint len) X{ X#define CRC_POLYNOMIAL 010041 /* CRC_CCITT */ X Xstatic ushort crc_table[256] = { X 0x0000, 0x1021, 0x2042, 0x3063, 0x4084, 0x50A5, 0x60C6, 0x70E7, X 0x8108, 0x9129, 0xA14A, 0xB16B, 0xC18C, 0xD1AD, 0xE1CE, 0xF1EF, X 0x1231, 0x0210, 0x3273, 0x2252, 0x52B5, 0x4294, 0x72F7, 0x62D6, X 0x9339, 0x8318, 0xB37B, 0xA35A, 0xD3BD, 0xC39C, 0xF3FF, 0xE3DE, X 0x2462, 0x3443, 0x0420, 0x1401, 0x64E6, 0x74C7, 0x44A4, 0x5485, X 0xA56A, 0xB54B, 0x8528, 0x9509, 0xE5EE, 0xF5CF, 0xC5AC, 0xD58D, X 0x3653, 0x2672, 0x1611, 0x0630, 0x76D7, 0x66F6, 0x5695, 0x46B4, X 0xB75B, 0xA77A, 0x9719, 0x8738, 0xF7DF, 0xE7FE, 0xD79D, 0xC7BC, X 0x48C4, 0x58E5, 0x6886, 0x78A7, 0x0840, 0x1861, 0x2802, 0x3823, X 0xC9CC, 0xD9ED, 0xE98E, 0xF9AF, 0x8948, 0x9969, 0xA90A, 0xB92B, X 0x5AF5, 0x4AD4, 0x7AB7, 0x6A96, 0x1A71, 0x0A50, 0x3A33, 0x2A12, X 0xDBFD, 0xCBDC, 0xFBBF, 0xEB9E, 0x9B79, 0x8B58, 0xBB3B, 0xAB1A, X 0x6CA6, 0x7C87, 0x4CE4, 0x5CC5, 0x2C22, 0x3C03, 0x0C60, 0x1C41, X 0xEDAE, 0xFD8F, 0xCDEC, 0xDDCD, 0xAD2A, 0xBD0B, 0x8D68, 0x9D49, X 0x7E97, 0x6EB6, 0x5ED5, 0x4EF4, 0x3E13, 0x2E32, 0x1E51, 0x0E70, X 0xFF9F, 0xEFBE, 0xDFDD, 0xCFFC, 0xBF1B, 0xAF3A, 0x9F59, 0x8F78, X 0x9188, 0x81A9, 0xB1CA, 0xA1EB, 0xD10C, 0xC12D, 0xF14E, 0xE16F, X 0x1080, 0x00A1, 0x30C2, 0x20E3, 0x5004, 0x4025, 0x7046, 0x6067, X 0x83B9, 0x9398, 0xA3FB, 0xB3DA, 0xC33D, 0xD31C, 0xE37F, 0xF35E, X 0x02B1, 0x1290, 0x22F3, 0x32D2, 0x4235, 0x5214, 0x6277, 0x7256, X 0xB5EA, 0xA5CB, 0x95A8, 0x8589, 0xF56E, 0xE54F, 0xD52C, 0xC50D, X 0x34E2, 0x24C3, 0x14A0, 0x0481, 0x7466, 0x6447, 0x5424, 0x4405, X 0xA7DB, 0xB7FA, 0x8799, 0x97B8, 0xE75F, 0xF77E, 0xC71D, 0xD73C, X 0x26D3, 0x36F2, 0x0691, 0x16B0, 0x6657, 0x7676, 0x4615, 0x5634, X 0xD94C, 0xC96D, 0xF90E, 0xE92F, 0x99C8, 0x89E9, 0xB98A, 0xA9AB, X 0x5844, 0x4865, 0x7806, 0x6827, 0x18C0, 0x08E1, 0x3882, 0x28A3, X 0xCB7D, 0xDB5C, 0xEB3F, 0xFB1E, 0x8BF9, 0x9BD8, 0xABBB, 0xBB9A, X 0x4A75, 0x5A54, 0x6A37, 0x7A16, 0x0AF1, 0x1AD0, 0x2AB3, 0x3A92, X 0xFD2E, 0xED0F, 0xDD6C, 0xCD4D, 0xBDAA, 0xAD8B, 0x9DE8, 0x8DC9, X 0x7C26, 0x6C07, 0x5C64, 0x4C45, 0x3CA2, 0x2C83, 0x1CE0, 0x0CC1, X 0xEF1F, 0xFF3E, 0xCF5D, 0xDF7C, 0xAF9B, 0xBFBA, 0x8FD9, 0x9FF8, X 0x6E17, 0x7E36, 0x4E55, 0x5E74, 0x2E93, 0x3EB2, 0x0ED1, 0x1EF0 X}; X register ushort crc = 0; X X while( len-- > 0 ) X crc = crc_table[(crc>>8 ^ *s++) & 0xff] ^ (crc<<8); X return crc; X} END_OF_FILE if test 3500 -ne `wc -c <'l_chksum.c'`; then echo shar: \"'l_chksum.c'\" unpacked with wrong size! fi # end of 'l_chksum.c' fi if test -f 'l_format.c' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'l_format.c'\" else echo shar: Extracting \"'l_format.c'\" \(3835 characters\) sed "s/^X//" >'l_format.c' <<'END_OF_FILE' X/* X l_format.c X*/ X/* Copyright (c) 1994 Christian F. Tschudin. All rights reserved. X X Distributed under the terms of the GNU General Public License X version 2 of june 1991 as published by the Free Software X Foundation, Inc. X X This file is part of M0. X XM0 is distributed in the hope that it will be useful, but WITHOUT ANY XWARRANTY. No author or distributor accepts responsibility to anyone for Xthe consequences of using it or for whether it serves any particular Xpurpose or works at all, unless he says so in writing. Refer to the GNU XGeneral Public License for full details. X XEveryone is granted permission to copy, modify and redistribute M0, but Xonly under the conditions described in the GNU General Public License. XA copy of this license is supposed to have been given to you along with XM0 so you can know your rights and responsibilities. It should be in a Xfile named LICENSE. Among other things, the copyright notice and this Xnotice must be preserved on all copies. */ X X#include "l_proto.h" X#include "hdr.h" X#include "chksum.h" X Xstatic void Xmake_header(byteptr p, byteptr q, uint clen, uint dlen) X{ X struct header_s *hdr = (struct header_s *) p; X uint len = 16 + clen; X X hdr->version = 0; X hdr->flags = 0; X memcpy(hdr->queue, (char*)q, 8); X hdr->codelen = clen; X#ifdef LITTLE_ENDIAN X swap_int(&(hdr->codelen)); X#endif X if (dlen) { X hdr->flags |= 0x80; X hdr->datalen = dlen; X#ifdef LITTLE_ENDIAN X swap_int(&(hdr->datalen)); X#endif X len += 4; X } X hdr->crc = crc_ccitt(p+2, len - 2); X#ifdef LITTLE_ENDIAN X swap_short(&(hdr->crc)); X#endif X} X X Xbyteptr Xmake_msgr(byteptr q, byteptr c, uint clen, byteptr d, uint dlen, uint *len) X{ X uint doffs; X byteptr m; X X if (d) { X doffs = 20 + 4 * ((clen+3)/4); X *len = doffs + dlen; X } else X *len = 16 + clen; X m = malloc(*len); X if (!m) X return 0; X if (d) { X memcpy((char*)(m+20), (char*)c, clen); X memcpy((char*)(m+doffs), (char*)d, dlen); X make_header(m, q, clen, dlen); X } else { X memcpy((char*)(m+16), (char*)c, clen); X make_header(m, q, clen, 0); X } X return m; X} X X Xeindex Xmake_msgr_str(mproc p, eindex q, eindex c, eindex d) X{ X uint len, clen, dlen, doffs; X byteptr m, key; X X q = desub(p,q); X key = eaddr(p,q)->V.nam.u.s; X clen = elen(p,c); X X if (d) { X dlen = elen(p,d); X doffs = 20 + 4 * ((clen+3)/4); X len = doffs + dlen; X } else X len = 16 + clen; X m = malloc(len); X if (!m) X return 0; X if (d) { X str_export(p, m+20, c, 0, clen); X str_export(p, m+doffs, d, 0, dlen); X make_header(m, key, clen, dlen); X } else { X str_export(p, m+16, c, 0, clen); X make_header(m, key, clen, 0); X } X return str_import(p, m, len, len); X} X X X/* msgr string m must not be shared, but contigious (no subtype) */ X Xretcode Xdecomp_msgr(mproc p, eindex m, eindex *q, eindex *c, eindex *d) X{ X eptr mp = eaddr(p,m); X struct header_s hdr; X uint hlen = sizeof(hdr), coffs, doffs; X byteptr s; X X if (eplen(mp) < 16) X return ERR_SHORT_MSGR; X s = mp->V.str.s; X X if (eplen(mp) < sizeof(hdr)) X hlen = eplen(mp); X memcpy((char*)&hdr, (char*)s, hlen); X X if (hdr.version != 0 ) X return ERR_MSGR_WRONG_VERSION; X X#ifdef LITTLE_ENDIAN X swap_short(&(hdr.crc)); X swap_int(&(hdr.codelen)); X#endif X coffs = 16; X if (hdr.flags & 0x80) { X#ifdef LITTLE_ENDIAN X swap_int(&(hdr.datalen)); X#endif X coffs += 4; X doffs = coffs + 4*((hdr.codelen+3)/4); X } else X hdr.datalen = 0; X X if (coffs + hdr.codelen > eplen(mp)) X return ERR_MSGR_CRC; X X if (crc_ccitt(s+2, coffs + hdr.codelen - 2) != hdr.crc ) X return ERR_MSGR_CRC; X X epattr(mp) &= ~(A_EXECUTABLE | A_WRITE); X *q = key_add(hdr.queue); X *c = make_sub(p, m, coffs); X elen(p,*c) = hdr.codelen; X eattr(p,*c) &= ~A_WRITE; X if (hdr.datalen) { X *d = make_sub(p, m, doffs); X if (doffs+hdr.datalen <= eplen(mp)) X elen(p,*d) = hdr.datalen; X else X elen(p,*d) = eplen(mp) - doffs; X eattr(p,*d) &= ~A_WRITE; X } else X *d = 0; X X return OK; X} END_OF_FILE if test 3835 -ne `wc -c <'l_format.c'`; then echo shar: \"'l_format.c'\" unpacked with wrong size! fi # end of 'l_format.c' fi if test -f 'l_incom.c' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'l_incom.c'\" else echo shar: Extracting \"'l_incom.c'\" \(3412 characters\) sed "s/^X//" >'l_incom.c' <<'END_OF_FILE' X/* X l_incom.c X*/ X/* Copyright (c) 1994 Christian F. Tschudin. All rights reserved. X X Distributed under the terms of the GNU General Public License X version 2 of june 1991 as published by the Free Software X Foundation, Inc. X X This file is part of M0. X XM0 is distributed in the hope that it will be useful, but WITHOUT ANY XWARRANTY. No author or distributor accepts responsibility to anyone for Xthe consequences of using it or for whether it serves any particular Xpurpose or works at all, unless he says so in writing. Refer to the GNU XGeneral Public License for full details. X XEveryone is granted permission to copy, modify and redistribute M0, but Xonly under the conditions described in the GNU General Public License. XA copy of this license is supposed to have been given to you along with XM0 so you can know your rights and responsibilities. It should be in a Xfile named LICENSE. Among other things, the copyright notice and this Xnotice must be preserved on all copies. */ X X#ifdef unix X X#include X#include X X#include "l_proto.h" X X Xstatic receivefct rcv[FD_SETSIZE]; Xstatic eindex chan_name[FD_SETSIZE]; Xstatic sint chan_no[FD_SETSIZE]; X Xstatic void set_fdset(fd_set *sp) X{ X int i; X X FD_ZERO(sp); X for (i = 0; i < FD_SETSIZE; i++) X if (rcv[i]) X FD_SET(i, sp); X} X X Xvoid Xadd_incoming(int fd, receivefct fct, eindex name, sint no) X{ X rcv[fd] = fct; X chan_name[fd] = name; X chan_no[fd] = no; X} X X Xint Xincoming_wouldblock() X{ Xstatic struct timeval NODELAY = {0,0}; X fd_set r; X X set_fdset(&r); X return select(FD_SETSIZE, &r, 0, 0, &NODELAY) <= 0; X} X X Xint Xserve_incoming(long usec) X{ X fd_set r; X int cnt, i; X X set_fdset(&r); X X if (usec > 0) { X struct timeval delay; X delay.tv_sec = usec / 1000000; X delay.tv_usec = usec % 1000000; X cnt = select(FD_SETSIZE, &r, 0, 0, &delay); X } else X cnt = select(FD_SETSIZE, &r, 0, 0, 0); X if (cnt <= 0) X return 0; X X for (i = 0; i < FD_SETSIZE; i++) X if (FD_ISSET(i, &r)) { X eindex msgr, orig_addr; X retcode rc; X X rcv[i](i, &msgr, &orig_addr); X if (msgr) { X eindex o = new_array(0, 3); X eindex n = new_element(0, T_INT); X X array_put(0, o, 0, chan_name[i]); X increfp(gaddr(chan_name[i])); X gaddr(n)->V.i = chan_no[i]; X array_put(0, o, 1, n); X array_put(0, o, 2, orig_addr); X epattr(gaddr(o)) &= ~A_WRITE; X X rc = new_proc(msgr, o); X decref(0, msgr); X decref(0, o); X TRACE(3, if (rc != OK && rc != YIELD_CPU) X printf("error %d creating a process\n", rc)) X } X } X X return cnt; X} X X#else /* __MSDOS__ */ X X#include X#include "l_proto.h" X Xstatic receivefct read0; Xstatic c_name; X Xvoid Xadd_incoming(int fd, receivefct fct, eindex name, sint dummy) X{ X if (fd == 0) { X read0 = fct; X c_name = name; X } X} X X Xint Xincoming_wouldblock() X{ X return !kbhit(); X} X Xint Xserve_incoming(long msec) X{ X if (msec > 0) { X eindex now = time_now(0), then = time_addint(0, now, msec); X eptr tp = gaddr(then); X for (;;) { X decref(0, now); X now = time_now(0); X if (!time_gt(&(tp->V.tim),&(gaddr(now)->V.tim))) X break; X } X decref(0, now); X decref(0, then); X if (!kbhit()) X return 0; X } X X if (read0) { X eindex msgr, orig; X retcode rc; X X read0(0, &msgr, &orig); X if (msgr) { X rc = new_proc(msgr, 0); X decref(0, msgr); X decref(0, orig); X TRACE(3, if (rc != OK && rc != YIELD_CPU) X printf("error %d creating a process\n", rc)) X } X return 1; X } X return 0; X} X X#endif END_OF_FILE if test 3412 -ne `wc -c <'l_incom.c'`; then echo shar: \"'l_incom.c'\" unpacked with wrong size! fi # end of 'l_incom.c' fi if test -f 'l_init.c' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'l_init.c'\" else echo shar: Extracting \"'l_init.c'\" \(3745 characters\) sed "s/^X//" >'l_init.c' <<'END_OF_FILE' X/* X l_init.c X*/ X/* Copyright (c) 1994 Christian F. Tschudin. All rights reserved. X X Distributed under the terms of the GNU General Public License X version 2 of june 1991 as published by the Free Software X Foundation, Inc. X X This file is part of M0. X XM0 is distributed in the hope that it will be useful, but WITHOUT ANY XWARRANTY. No author or distributor accepts responsibility to anyone for Xthe consequences of using it or for whether it serves any particular Xpurpose or works at all, unless he says so in writing. Refer to the GNU XGeneral Public License for full details. X XEveryone is granted permission to copy, modify and redistribute M0, but Xonly under the conditions described in the GNU General Public License. XA copy of this license is supposed to have been given to you along with XM0 so you can know your rights and responsibilities. It should be in a Xfile named LICENSE. Among other things, the copyright notice and this Xnotice must be preserved on all copies. */ X X#include "l_proto.h" X X#define ERRORNAMES (byteptr)"_ena" X#define ERRORHANDLER_NAME (byteptr)"_err" X#define TYPENAMES (byteptr)"_tna" X Xeptr global; X Xstatic byteptr msgr_start_s = (byteptr) ".'_loc.:_cod!"; X Xeindex systemdict; Xeindex queuedict; Xeindex channeldict; X Xeindex errorhandler_name; X Xeindex null_val; Xeindex null_key; Xeindex null_name; Xeindex msgr_name; Xeindex code_name; Xeindex data_name; Xeindex orig_name; Xeindex msgr_start; Xeindex host_id; X Xeindex mark; X Xeindex err_name_array; Xeindex type_name_array; X X X/* msgr must be global! */ X Xstatic void Xlocal_submit(mproc p, void *data, eindex m) X{ X eindex *ip = (eindex *)data; X TRACE(4, printf("local submit (length %d)\n", elen(p, m))) X X new_proc(m, ip ? *ip : 0); X} X X Xretcode low_level_init(void) X{ X eindex ei, *ip; X eptr ep; X retcode rc; X int i; X byte hid[8]; X X global = (eptr) calloc(MAXGLOBALS, sizeof(struct element_s)); X if (!global) X return ERR_IN_INIT; X X randomize(); X X null_val = new_element(0, T_NULL); X null_key = key_add((byteptr)"\0\0\0\0\0\0\0\0"); X null_name = name_add((byteptr)"null", 4, A_EXECUTABLE); X X systemdict = new_dict(0); X if (!systemdict) X return ERR_IN_INIT; X queuedict = new_dict(0); X channeldict = new_dict(0); X X dict_def(0, systemdict, null_name, null_val); X decref(0, null_name); X decref(0, null_val); X X msgr_name = name_add((byteptr)"_mgr", 4, A_EXECUTABLE); X code_name = name_add((byteptr)"_cod", 4, A_EXECUTABLE); X data_name = name_add((byteptr)"_dat", 4, A_EXECUTABLE); X orig_name = name_add((byteptr)"_ori", 4, A_EXECUTABLE); X X mark = new_element(0, T_MARK); X msgr_start = str_import(0, msgr_start_s, X strlen((char*)msgr_start_s), 0); X ep = gaddr(msgr_start); X epattr(ep) |= A_EXECUTABLE; X epattr(ep) &= ~A_WRITE; X X fillin_hostid(hid); X host_id = key_add(hid); X X err_name_array = new_array(0, LAST_ERROR); X ip = gaddr(err_name_array)->V.arr.a; X for (i=0; iR -= LAST_ERROR; X ei = name_add(ERRORNAMES, strlen((char*)ERRORNAMES), A_EXECUTABLE); X dict_def(0, systemdict, ei, err_name_array); X decref(0, ei); X decref(0, err_name_array); X X type_name_array = new_array(0, LAST_TYPE); X ip = gaddr(type_name_array)->V.arr.a; X for (i=0; iR -= LAST_TYPE; X ei = name_add(TYPENAMES, strlen((char*)TYPENAMES), A_EXECUTABLE); X dict_def(0, systemdict, ei, type_name_array); X decref(0, ei); X decref(0, type_name_array); X X errorhandler_name = name_add(ERRORHANDLER_NAME, X strlen((char*)ERRORHANDLER_NAME), A_EXECUTABLE); X X new_channel(null_key, 0, local_submit); X/* X decref(0, null_key); X*/ X X return OK; X} END_OF_FILE if test 3745 -ne `wc -c <'l_init.c'`; then echo shar: \"'l_init.c'\" unpacked with wrong size! fi # end of 'l_init.c' fi if test -f 'l_misc.c' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'l_misc.c'\" else echo shar: Extracting \"'l_misc.c'\" \(3311 characters\) sed "s/^X//" >'l_misc.c' <<'END_OF_FILE' X/* X l_misc.c X*/ X/* Copyright (c) 1994 Christian F. Tschudin. All rights reserved. X X Distributed under the terms of the GNU General Public License X version 2 of june 1991 as published by the Free Software X Foundation, Inc. X X This file is part of M0. X XM0 is distributed in the hope that it will be useful, but WITHOUT ANY XWARRANTY. No author or distributor accepts responsibility to anyone for Xthe consequences of using it or for whether it serves any particular Xpurpose or works at all, unless he says so in writing. Refer to the GNU XGeneral Public License for full details. X XEveryone is granted permission to copy, modify and redistribute M0, but Xonly under the conditions described in the GNU General Public License. XA copy of this license is supposed to have been given to you along with XM0 so you can know your rights and responsibilities. It should be in a Xfile named LICENSE. Among other things, the copyright notice and this Xnotice must be preserved on all copies. */ X X X#include "l_proto.h" X Xchar *error_names[] = { X "stack_underflow", X "oper_stack_overflow", X "dict_stack_overflow", X "exec_stack_overflow", X "type_check", X "range_check", X "access_check", X "division_by_zero", X "no_matching_loop", X "no_matching_halted", X "no_matching_mark", X "dict_full", X "invalid_channel", X "undefined", X "syntax", X "not_implemented", X "implementation_limit", X "circular_data", X X "__the_last_error__", X "ok", X "init_failure", X "invalid_file_name", X "cannot_read_file", X "malloc_failed", X "no_more_locals", X "short_msgr", X "invalid_crc", X "invalid_msgr_version", X "no_process", X "yield_cpu", X "abort", X "idle" X}; X X Xchar * Xunique_filename(char *pref) X{ Xstatic char fn[128]; X X strcpy(fn, pref); X strcat(fn, "_XXXXXX"); X mktemp(fn); X X return fn; X} X X X/* returns 64 random bits, and guarantees that they are not all 0 */ X Xvoid Xrandom64(byte *b) X{ X#ifdef __MSDOS__ X sint *ip; X do { X /* rand returns a short, i.e. 2 bytes */ X ip = (sint*)b; X *ip++ = ((sint)rand() << 16) ^ (sint)rand(); X *ip = ((sint)rand() << 16) ^ (sint)rand(); X } while( !*ip); X#else X sint r[2]; X X do { X /* random returns an int, i.e. 4 bytes, but only 31 bits */ X r[0] = (random() << 16) ^ random(); X r[1] = (random() << 16) ^ random(); X } while( !r[0]); X memcpy(b, r, 8); X#endif X} X X X Xbyteptr Xload_m0(char *binpath, char *libpath, char *filename) X{ X char *outfile, cmd[512], *content; X int cnt; X long len; X FILE *f; X X outfile = unique_filename("stup"); X if (!access(filename, 4)) X sprintf(cmd, "%s%cm0strip -I%s <%s >%s", X binpath, DIRDELIMIT, X libpath, filename, X outfile); X else X sprintf(cmd, "%s%cm0strip -I%s <%s%c%s >%s", X binpath, DIRDELIMIT, X libpath, X libpath, DIRDELIMIT, filename, X outfile); X X TRACE(1, printf("Executing \"%s\"\n", cmd)) X X if (system(cmd)) X return 0; X if (!(f = fopen(outfile, "r"))) X return 0; X fseek(f, 0L, 2); X len = ftell(f); X fseek(f, 0L, 0); X content = malloc(len+1); X if (content) { X cnt = fread(content, 1, len, f); X content[cnt] = '\0'; X } X fclose(f); X unlink(outfile); X return (byteptr)content; X} X X Xretcode Xnew_channel(eindex key, void *data, submitfct fct) X{ X eindex ch; X eptr chp; X X ch = new_element(0, T_CHANNEL); X chp = gaddr(ch); X chp->V.cha.data = data; X chp->V.cha.submit = fct; X dict_def(0, channeldict, key, ch); X decref(0, key); X decref(0, ch); X X return OK; X} END_OF_FILE if test 3311 -ne `wc -c <'l_misc.c'`; then echo shar: \"'l_misc.c'\" unpacked with wrong size! fi # end of 'l_misc.c' fi if test -f 'longdict.m0' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'longdict.m0'\" else echo shar: Extracting \"'longdict.m0'\" \(2915 characters\) sed "s/^X//" >'longdict.m0' <<'END_OF_FILE' X# longdict.m0 X X# Copyright (c) 1994 Christian F. Tschudin. All rights reserved. X# X# Distributed under the terms of the GNU General Public License X# version 2 of june 1991 as published by the Free Software X# Foundation, Inc. X# X# This file is part of M0. X# X# M0 is distributed in the hope that it will be useful, but WITHOUT ANY X# WARRANTY. No author or distributor accepts responsibility to anyone for X# the consequences of using it or for whether it serves any particular X# purpose or works at all, unless he says so in writing. Refer to the GNU X# General Public License for full details. X# X# Everyone is granted permission to copy, modify and redistribute M0, but X# only under the conditions described in the GNU General Public License. X# A copy of this license is supposed to have been given to you along with X# M0 so you can know your rights and responsibilities. It should be in a X# file named LICENSE. Among other things, the copyright notice and this X# notice must be preserved on all copies. X X# longword commands for the M0 interpreter X X X.'add {+} B : X.'and {&} B : X.'array {A} B : X.'begin {(} B : X.'bind {B} B : X.'count {O} B : X.'currentdict {.} B : X.'currentqueue {,} B : X.'dict {D} B : X.'div {/} B : X.'end {)} B : X.'enter {E} B : X.'eq {=} B : X.'exec {!} B : X.'exch {X} B : X.'exit {J} B : X.'false {0} B : X.'find {F} B : X.'get {G} B : X.'getattribute {T} B : X.'gt {>} B : X.'ifelse {?} B : X.'index {I} B : X.'known {K} B : X.'length {`} B : X.'loop {L} B : X.'lt {<} B : X.'mark {[} B : X.'mod {%} B : X.'mul {*} B : X.'neg {N} B : X.'not {~} B : X.'or {|} B : X.'pop {P} B : X.'put {:} B : X.'queuestate {Q} B : X.'randomkey {;} B : X.'roll {R} B : X.'setattribute {W} B : X.'stop {Z} B : X.'stopped {H} B : X.'string {S} B : X.'sub {-} B : X.'submit {$} B : X.'true {1} B : X.'type {Y} B : X.'undefine {U} B : X.'utc {@} B : X.'xor {^} B : X X.'toarray {_cta} B : X.'toextern {_cte} B : X.'toexec {_ctx} B : X.'toint {_cti} B : X.'tokey {_ctk} B : X.'toliteral {_ctl} B : X.'tomsgr {_ctm} B : X.'toname {_ctn} B : X.'tostring {_cts} B : X.'totime {_ctt} B : X X.'addrdict _sys'_adrG : X.'channeldict _sys'_chaG : X.'code {_loc'_codG} : X.'data {_loc'_datG} : X.'errors _sys'_enaG : X.'globaldict _sys'_G : X.'hostid {_hid} B : X.'localdict {_loc} : X.'msgr {_loc'_mgrG} : X.'origin {_loc'_oriG} : X.'platformid {_pid} B : X.'systemdict _sys : X.'types _sys'_tnaG : X.'version _sys'_verG : X X X# utilities: X X.'abs {0I0<{N}{}?} B : X.'clear {1O{PP}L} B : X.'def {.3 1R:} B : X.'dictstack {2_stk} B : X.'dup {0I} B : X.'execstack {3_stk} B : X.'ge {<1X-} B : X.'if {{}?} B : X.'land {0=X0=|0=} B : X.'le {>1X-} B : X.'lnot {0=} B : X.'lor {0=X0=&0=} B : X.'lxor {0=X0=^} B : X.'makechannel {_sys'_chaG 3IG '_keyG 4 3RP !} B : X.'ne {=1X-} B : X.'operstack {2_stk} B : X.'repeat {{P.!}CX1IX1X:L} B : X.'sleep {;0I1QX1IXEP0Q} B : X X.'inet_to_int {0X{X256*|}L} B : # use: [a b c d] inet_to_int int X X# eof END_OF_FILE if test 2915 -ne `wc -c <'longdict.m0'`; then echo shar: \"'longdict.m0'\" unpacked with wrong size! fi # end of 'longdict.m0' fi if test -f 'm0.1' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'m0.1'\" else echo shar: Extracting \"'m0.1'\" \(3504 characters\) sed "s/^X//" >'m0.1' <<'END_OF_FILE' X.TH M0 1 X.SH NAME Xm0 \- a messenger language interpreter and execution environment X.SH SYNOPSIS X.B m0 X[ X.B -h X] [ X.B -s X] [ X.B -t X] [ X.B -u X] [ X.B -v X] X.SH DESCRIPTION X.I M0 Xis a standalone interpreter for the M0 messenger language and Xprovides an execution platform for concurrent M0 processes. Messengers, Xthat is autonomous programs, are received via ethernet or UDP Xdatagrams: after reception and some version checking each messenger is Xturned into an independend process and unconditionally executed. The Xmost important instruction of the M0 language is the submit operator, Xallowing a messenger process to send new messengers to neighboring X.I M0 Xinterpreters. X XThe X.I M0 Xinterpreter listens on UDP port 0x4d30 and filters out ethernet Xframes with protocol type 0x4d30 for the reception of messengers X(whether both interfaces are supported or not depends on the UNIX platform Xon which the X.I M0 Xinterpreter was compiled). For a description of the Xmessenger format accepted and a list of the M0 instructions see the M0 Xmanual. X.PP XOptions: X.IP -h XPrint a brief usage indication to stdout. X.IP -s XContinously print a status line (terminated with \\r) to stdout showing Xthe number of existing, blocked and running processes. X.IP -t XSet the tracing level (for debugging reasons). This only works if the XM0 interpreter was compiled with the -DDEBUG flag. Default is 0. A Xvalue of 1 forces a dump of all aborted messenger processes to files of Xthe form X.I abrt_*. XIf an error occurs in the initialisation (startup) phase of M0, a file X.I stup_* Xis created. Still with the option X.I -t1 Xor higher, a file X.I exit_* Xis created when the interpreter is interrupted (^C). Higher levels of Xtracing print subsequently more information, level 5 currently being Xthe highest level. X.IP -u XChoose another UDP port (default is 0x43). X.IP -v XPrint the version to stdout. X.PP XParts of the initialisation code is found in the X.I startup.m0 Xand X.I longdict.m0 Xfiles. These ASCII files are first treated with the X.I m0strip Xprogram before being read in by the M0 interpreter. X.SH FILES X.IP startup.m0 XStartup code (in M0) for the M0 execution platform. X.IP longdict.m0 XStandard definitions of long command words, included by X.I startup.m0. X.IP abrt_* XDump (ASCII) of aborted messengers (only if tracing level >0). X.IP exit_* XDump (ASCII) of all messenger processes and global memory of the M0 Xplatform (only when tracing level >0 and INT signal (^C) received). X.IP stup_* XDump (ASCII) of an aborted initialisation messenger process that Xexecutes the code found in X.I startup.m0. X.IP M0.ps XPostScript document describing the messenger approach and containing a Xcomplete M0 language manual with examples. X.SH ENVIRONMENT X.IP M0BIN XOverrides the default path where auxiliary programs X.I (m0strip) Xcan be found. X.IP M0LIB XOverrides the default path where the startup files X.I (startup.m0 Xand X.I longdict.m0) Xcan be found. X.SH SEE ALSO Xm0strip(1), m0c(1), m0uc(1) X.SH BUGS XThe interfaces where M0 should listen for incoming messengers cannot be Xspecified: currently all available interfaces (IP and ethernet) are Xtried and served. X.PP XServing messengers which are encapsulated in ethernet frames requires Xthis program to be installed with root as owner and with the SETUID bit Xset (due to the access protections of the ethernet devices). XInsufficient privileges to open the ethernet device simply deactivates Xthe ethernet interface. X.SH AUTHOR XChristian F. Tschudin, , May 1994 END_OF_FILE if test 3504 -ne `wc -c <'m0.1'`; then echo shar: \"'m0.1'\" unpacked with wrong size! fi # end of 'm0.1' fi if test -f 'm0strip.man' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'m0strip.man'\" else echo shar: Extracting \"'m0strip.man'\" \(3143 characters\) sed "s/^X//" >'m0strip.man' <<'END_OF_FILE' X X X XM0STRIP(1) USER COMMANDS M0STRIP(1) X X X XNAME X m0strip - remove white spaces and comments from M0 source X code X XSYNOPSIS X m0strip [ -_o <_f_i_l_e> ] [ -_I <_i_n_c_l_u_d_e_p_a_t_h> ] X XDESCRIPTION X M0strip is a preprocessor that compacts ASCII-based M0 code X by removing white spaces and comments. It also handles some X simple inclusion directives. The output is an arbitrary long X sequence of ASCII characters not containing any control X characters (e.g. newline) and having only the minimal number X of space characters. _M_0_s_t_r_i_p also does some limited syntax X checking: mainly quote and backslash characters must be used X in a balanced way (ASCII strings as well as hex-strings must X be terminated on the same line). X X Comments are introduced by the number sign (#) and extend to X the end of the line. A number sign starting a comment may X not be immediately followed by an integer. Best is to use a X number sign followed by a space or newline character in X order to introduce a comment line. X X There are two directives which enable the inclusion of other X files. These directives are also introduced by a number sign X which MUST be in the first column of a line. Any data fol- X lowing the argument on the same line is discarded. The X directives are: X X #include X The given file is inserted into the stream of M0 com- X mands. The included file is also stripped. X X #includestring X This directive behaves like the previous #_i_n_c_l_u_d_e with X the exception that the file's content is included as an X M0 string: critical characters (like double quote and X backslash) are correctly escaped. The #_i_n_c_l_u_d_e_s_t_r_i_n_g X directive is useful for parts of M0 programs that have X to be available as strings, but that one would like to X write down in the ordinary way (with comments etc). X X Both directives can be nested arbitrarily. X X The -_I option is used by _m_0_s_t_r_i_p for finding files refer- X enced by the two #_i_n_c_l_u_d_e directives. Default is the current X directory. X X Default is to write the resulting M0 code to the standard X output. The -_o option permits to name an output file. X X X X XSun Release 4.1 Last change: 1 X X X X X X XM0STRIP(1) USER COMMANDS M0STRIP(1) X X X XFILES X M0.ps X PostScript document describing the messenger approach X and containing the complete M0 language manual with X examples. X XSEE ALSO X m0(1), m0c(1), m0uc(1) X XBUGS X It would be nice to differentiate the location of include X files with the _c_p_p -like "abc" and notation. X X Only one -_I option is remembered. X XAUTHOR X Christian F. Tschudin, , May 1994 X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X XSun Release 4.1 Last change: 2 X X X END_OF_FILE echo shar: 64 control characters may be missing from \"'m0strip.man'\" if test 3143 -ne `wc -c <'m0strip.man'`; then echo shar: \"'m0strip.man'\" unpacked with wrong size! fi # end of 'm0strip.man' fi if test -f 'm0uc.1' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'m0uc.1'\" else echo shar: Extracting \"'m0uc.1'\" \(3054 characters\) sed "s/^X//" >'m0uc.1' <<'END_OF_FILE' X.TH M0UC 1 X.SH NAME Xm0uc \- an interactive console using UDP to remotely access an M0 interpreter X.SH SYNOPSIS X.B m0uc X[ X.B -h X] [ X.B -m X] [ X.B -p X] [ X.B -v X] [ X.B file X] X.SH DESCRIPTION X.IM0uc is a small ``relay'' or ``front-end'' program that sends command Xlines via UDP to an M0 interpreter and displays received UDP datagrams Xon the console. X.I M0uc does not understand the M0 language but relies on Xthe remote X.I m0 Xor X.I m0c execution platform Xfor executing M0 commands. X.PP XThe X.I m0uc Xprogram downloads to the M0 interpreter an M0 messenger X.I (cons_ini.m0) Xthat installs itself as a command server process. Then, the X.I m0uc Xprogram waits for the user to type command lines which are packed Xinto special messengers that deliver them to the server process. The Xserver process executes the command line and eventually returns, also Xin a messenger, data to be displayed. The X.I m0uc Xdoes not interpret the received messenger but simply writes it to stdout. X.PP XOptions: X.IP -h XPrint a brief usage indication to stdout. X.IP -m XSet the IP address of the machine where the M0 interpreter is running. If Xthis option is not given, the X.I m0uc Xconsole tries the local host. X.IP -p XSet the UDP port where the M0 interpreter is listening. Default is X0x4d30. X.IP -v XPrint the version to stdout. X.IP file XRead the given file and send it to the console server process after it Xhas installed itself. This allows a user to download M0 code into a Xplatform in order to interactively test it via the console. X.PP XThe code for the server process is found in the file X.I cons_ini.m0. XThis file is treated by the X.I m0strip Xfilter before being sent to the M0 interpreter. A file to be downloaded Xis also treated by the X.I m0strip Xprogram. X.PP XThe console messenger offers five additional commands which are not Xpart of a standard M0 execution environment: X.IP print XSend to the front-end program a string to display. X.IP input XWait for a line from the console and return the string (or null if Xempty). X.IP ptop XPrint (non-destructively) the top-most operand. X.IP stack XPrint (non-destructively) the content of the operand stack. X.IP quit XTerminate the console server process. The console program X.I m0uc Xis also alerted and exits. X.PP XThe exchange between the console front-end and the M0 interpreter Xis not reliable because messengers are encapsulated in UDP datagrams: Xdatagrams with commands can be lost, the same as parts of the results Xcan be lost and are never displayed. X.SH FILES X.IP cons_ini.m0 XM0 code for the console server process. X.IP M0.ps XPostScript document describing the messenger approach and containing the Xcomplete M0 language manual with examples. X.SH ENVIRONMENT X.IP M0BIN XOverrides the default path where auxiliary programs X.I (m0strip) Xcan be found. X.IP M0LIB XOverrides the default path where the server code X.I (cons_ini.m0) Xcan be found. X.SH SEE ALSO Xm0strip(1), m0(1), m0c(1) X.SH BUGS XOnly one file can be downloaded. X.SH AUTHOR XChristian F. Tschudin, , May 1994 END_OF_FILE if test 3054 -ne `wc -c <'m0uc.1'`; then echo shar: \"'m0uc.1'\" unpacked with wrong size! fi # end of 'm0uc.1' fi if test -f 'o_dict.c' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'o_dict.c'\" else echo shar: Extracting \"'o_dict.c'\" \(3649 characters\) sed "s/^X//" >'o_dict.c' <<'END_OF_FILE' X/* X o_dict.c X*/ X/* Copyright (c) 1994 Christian F. Tschudin. All rights reserved. X X Distributed under the terms of the GNU General Public License X version 2 of june 1991 as published by the Free Software X Foundation, Inc. X X This file is part of M0. X XM0 is distributed in the hope that it will be useful, but WITHOUT ANY XWARRANTY. No author or distributor accepts responsibility to anyone for Xthe consequences of using it or for whether it serves any particular Xpurpose or works at all, unless he says so in writing. Refer to the GNU XGeneral Public License for full details. X XEveryone is granted permission to copy, modify and redistribute M0, but Xonly under the conditions described in the GNU General Public License. XA copy of this license is supposed to have been given to you along with XM0 so you can know your rights and responsibilities. It should be in a Xfile named LICENSE. Among other things, the copyright notice and this Xnotice must be preserved on all copies. */ X X#include "l_proto.h" X#include "o_proto.h" X X Xretcode Xo_begin() X{ X load_1_arg(ei, ep); X if (eptype(ep) != T_DICT) X return ERR_TYPE_CHECK; X if (current->dsp >= MAXDSTACK) X return ERR_DSTACK_OVERFLOW; X current->ds[current->dsp++] = ei; X current->osp--; X return OK; X} X Xretcode Xo_currentdict() X{ X eindex ei; X X if (current->osp >= MAXOSTACK) X return ERR_OSTACK_OVERFLOW; X if (current->dsp <= 0) X return ERR_STACK_UNDERFLOW; X X ei = current->ds[current->dsp-1]; X current->os[current->osp++] = ei; X incref(current, ei); X X return OK; X} X X Xretcode Xo_dict() X{ X eindex ei; X X if (current->osp >= MAXOSTACK) X return ERR_OSTACK_OVERFLOW; X ei = new_dict(current); X if (!ei) X return ERR_IMPLEMENTATION_LIMIT; X current->os[current->osp++] = ei; X return OK; X} X X Xretcode Xo_end() X{ X if (current->dsp <= 1) X return ERR_STACK_UNDERFLOW; X X current->dsp--; X decref(current, current->ds[current->dsp]); X return OK; X} X X Xretcode Xo_find() X{ X eindex k, d, b; X retcode r; X X if (current->osp < 1) X return ERR_STACK_UNDERFLOW; X X k = current->os[current->osp-1]; X if (dict_find(current, k, &d) == OK) { X if (current->osp >= MAXOSTACK) X return ERR_OSTACK_OVERFLOW; X current->os[current->osp-1] = d; X incref(current, d); X current->osp++; X } else X d = 0; X decref(current, k); X b = new_element(current, T_INT); X eaddr(current,b)->V.i = d ? 1 : 0; X current->os[current->osp-1] = b; X return OK; X} X X Xretcode Xo_known() X{ X eindex v, i; X X load_2_args(d, k, dp, kp); X X if (eptype(dp) != T_DICT) X return ERR_TYPE_CHECK; X if (!(epattr(dp) & A_READ)) X return ERR_ACCESS_CHECK; X v = dict_get(current, d, k); X decrefp(current, d, dp); X decrefp(current, k, kp); X i = new_element(current, T_INT); X eaddr(current,i)->V.i = v ? 1 : 0; X X return_ok_result(2, i); X} X X Xretcode Xo_undef() X{ X retcode rc; X X load_2_args(d, k, dp, kp); X X if (eptype(dp) != T_DICT) X return ERR_TYPE_CHECK; X if (!(epattr(dp) & A_WRITE)) X return ERR_ACCESS_CHECK; X X rc = dict_undef(current, d, k); X if (rc != OK) X return rc; X decrefp(current, d, dp); X decrefp(current, k, kp); X current->osp -= 2; X X return OK; X} X X Xretcode Xdict_find(mproc p, eindex key, eindex *dict) X{ X short len = p->dsp; X eindex *ds = p->ds+len-1; X X while (len-- > 0) { X eptr dp = eaddr(p, *ds); X if (epattr(dp) & A_READ) { X if (dict_get(p, *ds, key)) { X *dict = *ds; X return OK; X } X } X ds--; X } X return ERR_UNDEFINED; X} X X Xretcode Xdict_load(mproc p, eindex key, eindex *val) X{ X short len = p->dsp; X eindex *ds = p->ds+len-1; X eindex ei; X X while (len-- > 0) { X eptr dp = eaddr(p, *ds); X if (epattr(dp) & A_READ) { X ei = dict_get(p, *ds, key); X if (ei) { X *val = ei; X return OK; X } X } X ds--; X } X return ERR_UNDEFINED; X} END_OF_FILE if test 3649 -ne `wc -c <'o_dict.c'`; then echo shar: \"'o_dict.c'\" unpacked with wrong size! fi # end of 'o_dict.c' fi if test -f 'o_init.c' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'o_init.c'\" else echo shar: Extracting \"'o_init.c'\" \(3356 characters\) sed "s/^X//" >'o_init.c' <<'END_OF_FILE' X/* X o_init.c X*/ X/* Copyright (c) 1994 Christian F. Tschudin. All rights reserved. X X Distributed under the terms of the GNU General Public License X version 2 of june 1991 as published by the Free Software X Foundation, Inc. X X This file is part of M0. X XM0 is distributed in the hope that it will be useful, but WITHOUT ANY XWARRANTY. No author or distributor accepts responsibility to anyone for Xthe consequences of using it or for whether it serves any particular Xpurpose or works at all, unless he says so in writing. Refer to the GNU XGeneral Public License for full details. X XEveryone is granted permission to copy, modify and redistribute M0, but Xonly under the conditions described in the GNU General Public License. XA copy of this license is supposed to have been given to you along with XM0 so you can know your rights and responsibilities. It should be in a Xfile named LICENSE. Among other things, the copyright notice and this Xnotice must be preserved on all copies. */ X X#include X X#include "l_proto.h" X#include "o_proto.h" X X Xstatic struct built_in_s { X char *n; X retcode (*fct)(); X} b[] = { X {"!", o_exec}, X {"$", o_submit}, X {"%", o_mod}, X {"&", o_and}, X {"`", o_length}, X {"(", o_begin}, X {")", o_end}, X {"*", o_mul}, X {"+", o_add}, X {",", o_currentqueue}, X {"-", o_sub}, X {".", o_currentdict}, X {"/", o_div}, X {":", o_put}, X {";", o_random}, X {"<", o_lt}, X {"=", o_eq}, X {">", o_gt}, X {"?", o_ifelse}, X {"@", o_gmt}, X X {"A", o_array}, X {"B", o_bind}, X {"C", o_copy}, X {"D", o_dict}, X {"E", o_enter}, X {"F", o_find}, X {"G", o_get}, X {"H", o_halted}, X {"I", o_index}, X {"J", o_exit}, X {"K", o_known}, X {"L", o_loop}, X/* M checksum */ X {"N", o_neg}, X {"O", o_count}, X {"P", o_pop}, X {"Q", o_qstate}, X {"R", o_roll}, X {"S", o_string}, X {"T", o_getattr}, X {"U", o_undef}, X {"V", o_leave}, X {"W", o_setattr}, X {"X", o_exch}, X {"Y", o_type}, X {"Z", o_halt}, X {"[", o_mark}, X {"]", o_makearray}, X {"^", o_xor}, X X {"|", o_or}, X X {"~", o_not}, X X {"_cta", o_toarray}, X {"_cte", o_toextern}, X {"_cti", o_toint}, X {"_ctk", o_tokey}, X {"_ctl", o_toliteral}, X {"_ctm", o_tomsgr}, X {"_ctn", o_toname}, X {"_cts", o_tostring}, X {"_ctt", o_totime}, X {"_ctx", o_toexecutable}, X X {"_hid", o_hostid}, X {"_stk", o_stack}, X X {0, 0} X}; X X Xeindex loop_mark; Xeindex loop_iproc; Xeindex loop_aproc; Xeindex loop_dproc; Xeindex loop_sproc; Xeindex halt_mark; Xeindex halted_proc; X Xstatic struct loops_s { X eindex *e; X retcode (*fct)(); X} loops[] = { X {&loop_iproc, the_loop_iproc}, X {&loop_aproc, the_loop_aproc}, X {&loop_dproc, the_loop_dproc}, X {&loop_sproc, the_loop_sproc}, X {&halted_proc, the_halted_proc} X}; X Xretcode Xoperator_init() X{ X struct built_in_s *bp; X eindex ei, ce, fe; X eptr ep; X retcode rc; X int i; X X for (bp = b; bp->n; bp++) { X ce = name_add((byteptr)(bp->n), strlen(bp->n), A_EXECUTABLE); X fe = new_element(0, T_PROC); X if (!ce || !fe) X return ERR_IN_INIT; X ep = gaddr(fe); X epattr(ep) |= A_EXECUTABLE; X ep->V.pro.fct = bp->fct; X rc = dict_def(0, systemdict, ce, fe); X if (rc!=OK) X return rc; X decref(0, ce); X decref(0, fe); X } X X halt_mark = new_element(0, T_MARK); X loop_mark = new_element(0, T_MARK); X X for (i=0; i < sizeof(loops)/sizeof(struct loops_s); i++) { X ei = new_element(0, T_PROC); X ep = gaddr(ei); X X epattr(ep) |= A_EXECUTABLE; X ep->V.pro.fct = loops[i].fct; X *(loops[i].e) = ei; X } X X return OK; X} END_OF_FILE if test 3356 -ne `wc -c <'o_init.c'`; then echo shar: \"'o_init.c'\" unpacked with wrong size! fi # end of 'o_init.c' fi if test -f 'o_msgr.c' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'o_msgr.c'\" else echo shar: Extracting \"'o_msgr.c'\" \(3305 characters\) sed "s/^X//" >'o_msgr.c' <<'END_OF_FILE' X/* X o_msgr.c X*/ X/* Copyright (c) 1994 Christian F. Tschudin. All rights reserved. X X Distributed under the terms of the GNU General Public License X version 2 of june 1991 as published by the Free Software X Foundation, Inc. X X This file is part of M0. X XM0 is distributed in the hope that it will be useful, but WITHOUT ANY XWARRANTY. No author or distributor accepts responsibility to anyone for Xthe consequences of using it or for whether it serves any particular Xpurpose or works at all, unless he says so in writing. Refer to the GNU XGeneral Public License for full details. X XEveryone is granted permission to copy, modify and redistribute M0, but Xonly under the conditions described in the GNU General Public License. XA copy of this license is supposed to have been given to you along with XM0 so you can know your rights and responsibilities. It should be in a Xfile named LICENSE. Among other things, the copyright notice and this Xnotice must be preserved on all copies. */ X X#include "l_proto.h" X#include "o_proto.h" X X Xretcode Xo_currentqueue() X{ X eindex ei; X X if (current->osp >= MAXOSTACK) X return ERR_OSTACK_OVERFLOW; X ei = current->qkey ? current->qkey : null_val; X incref(current, ei); X current->os[current->osp++] = ei; X X return OK; X} X X Xretcode Xo_enter() X{ X/* possible usages: X q-key E - X q-key int E int (no timeout=0, timeout=1) X q-key time E int X*/ X eindex qk, t=0; X eptr qp, tp; X retcode rc; X X if (current->osp < 1) X return ERR_STACK_UNDERFLOW; X qk = current->os[current->osp-1]; X qp = eaddr(current, qk); X if (eptype(qp) != T_KEY) { X if (eptype(qp)!= T_INT && eptype(qp)!=T_TIME) X return ERR_TYPE_CHECK; X t = qk; X tp = qp; X if (current->osp < 2) X return ERR_STACK_UNDERFLOW; X qk = current->os[current->osp-2]; X qp = eaddr(current,qk); X if (eptype(qp) != T_KEY) X return ERR_TYPE_CHECK; X current->osp -= 2; X } else X current->osp -= 1; X X if (t && eptype(tp) == T_INT) { X eindex now = time_now(current), then; X then = time_addint(current, now, tp->V.i); X decrefp(current, t, tp); X decref(current, now); X t = then; X } X X rc = enqueue(current, qk, t); X if (t) X decref(current, t); X decrefp(current, qk, qp); X X if (t && rc == OK) X current->os[current->osp++] = new_element(current, T_INT); X X return rc; X} X X Xretcode Xo_leave() X{ X if (current->qkey) X dequeue(current); X X return OK; X} X X Xretcode Xo_qstate() X{ X load_2_args(qk, i, qkp, ip); X X if (eptype(qkp)!= T_KEY || eptype(ip)!=T_INT) X return ERR_TYPE_CHECK; X X queue_state(qk, ip->V.i); X X decrefp(current, qk, qkp); X decrefp(current, i, ip); X current->osp -= 2; X X return OK; X} X X Xretcode Xo_submit() X{ X eindex c; X X load_2_args(k, m, kp, mp); X X if (eptype(mp) != T_STRING) X return ERR_TYPE_CHECK; X if (!(epattr(mp) & A_READ)) X return ERR_ACCESS_CHECK; X X if (eptype(kp) == T_KEY) { X c = dict_get(current, channeldict, k); X if (c) { X eindex m2 = make_global(current, m); X eptr cp = eaddr(current, c); X (cp->V.cha.submit)(current, cp->V.cha.data, m2); X decref(0, m2); X } X } else { X eindex m2 = make_global(current, m); X eindex k2 = make_global(current, k); X c = dict_get(current, channeldict, null_key); X (eaddr(current, c)->V.cha.submit)(current, &k2, m2); X decref(0, m2); X decref(0, k2); X } X X X decrefp(current, k, kp); X decrefp(current, m, mp); X current->osp -= 2; X X return OK; X} END_OF_FILE if test 3305 -ne `wc -c <'o_msgr.c'`; then echo shar: \"'o_msgr.c'\" unpacked with wrong size! fi # end of 'o_msgr.c' fi if test -f 'std.h' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'std.h'\" else echo shar: Extracting \"'std.h'\" \(2869 characters\) sed "s/^X//" >'std.h' <<'END_OF_FILE' X/* X std.h X*/ X/* Copyright (c) 1994 Christian F. Tschudin. All rights reserved. X X Distributed under the terms of the GNU General Public License X version 2 of june 1991 as published by the Free Software X Foundation, Inc. X X This file is part of M0. X XM0 is distributed in the hope that it will be useful, but WITHOUT ANY XWARRANTY. No author or distributor accepts responsibility to anyone for Xthe consequences of using it or for whether it serves any particular Xpurpose or works at all, unless he says so in writing. Refer to the GNU XGeneral Public License for full details. X XEveryone is granted permission to copy, modify and redistribute M0, but Xonly under the conditions described in the GNU General Public License. XA copy of this license is supposed to have been given to you along with XM0 so you can know your rights and responsibilities. It should be in a Xfile named LICENSE. Among other things, the copyright notice and this Xnotice must be preserved on all copies. */ X X#ifndef STD_H X#define STD_H X X/* include files: ----------------------------------------------------------- */ X X#include X#include X#include X#include X X#ifdef __MSDOS__ X# include X# include X#else X# include X# include X#endif X X X/* data types: ------------------------------------------------------------- */ X Xtypedef unsigned char byte; X X#ifdef __MSDOS__ X typedef byte huge *byteptr; X #define malloc(n) farmalloc(n) X #define realloc(s,n) farrealloc(s,n) X #define calloc(n,s) farcalloc(n,s) X #define free(p) farfree(p) X#else X typedef byte *byteptr; X#endif X Xtypedef short sshort; X X/* we want signed and unsigned integers to be (at least) 32 bit wide: */ X X#ifdef __MSDOS__ X typedef unsigned short ushort; X typedef unsigned long uint; X typedef long sint; X typedef unsigned long uint32; X#else X typedef int sint; X typedef unsigned int uint32; X#endif X X#define swap_short(s) *(s) = (*(s)>>8) | (*(s)<<8) X#define swap_int(l) *(l) = (*(l)<<24) | ((*(l)&0x0ff00L)<<8) | \ X ((*(l)&0x0ff0000L)>>8) | (0x0ffL&(*(l)>>24)); X X/* compatibility issues: --------------------------------------------------- */ X X#ifdef __MSDOS__ X# define LITTLE_ENDIAN X# define DIRDELIMIT '\\' X extern long gethostid(); /* in l_compat.c */ X#endif X X#ifdef unix X# define DIRDELIMIT '/' X# define randomize() srandom((long)time(NULL)) X#endif X X#ifdef __ultrix X# define LITTLE_ENDIAN X extern byteptr strdup(byteptr s); /* in l_compat.c */ X#endif X X#ifdef __alpha__ X# define LITTLE_ENDIAN X#endif X X/* available channels: ---------------------------------------------------- */ X X#define CHANNEL_CONSOLE /* for all environments */ X X#ifdef SUNOS4 X# define CHANNEL_NIT X# define CHANNEL_UDP X#endif X X#ifdef SUNOS5 X#endif X X#ifdef __ultrix X# define CHANNEL_UDP X#endif X X#ifdef __osf__ X# define CHANNEL_UDP X#endif X X X#endif END_OF_FILE if test 2869 -ne `wc -c <'std.h'`; then echo shar: \"'std.h'\" unpacked with wrong size! fi # end of 'std.h' fi echo shar: End of archive 2 \(of 12\). cp /dev/null ark2isdone MISSING="" for I in 1 2 3 4 5 6 7 8 9 10 11 12 ; do if test ! -f ark${I}isdone ; then MISSING="${MISSING} ${I}" fi done if test "${MISSING}" = "" ; then echo You have unpacked all 12 archives. rm -f ark[1-9]isdone ark[1-9][0-9]isdone else echo You still need to unpack the following archives: echo " " ${MISSING} fi ## End of shell archive. exit 0