Newsgroups: comp.sources.unix From: tschudin@cui.unige.ch (Christian Tschudin) Subject: v28i054: m0 - a messenger execution environment, Part04/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 54 Archive-Name: m0/part04 #! /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 'l_dump.c' <<'END_OF_FILE' X/* X l_dump.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 DEBUG X X#include "l_proto.h" X Xint trace; X X Xstatic void Xdump_e(FILE *f, mproc p, eindex ei, int depth) X{ X eptr ep = eaddr(p,ei); X char fmt[10]; X int i, j; X eindex *ea; X mproc p2; X X for (i=0; iV.sub.e, ep->V.sub.offset); X if (eplen(ep) == 0) X fprintf(f, "[]"); X else { X fprintf(f, "[ "); X for (i=0; iV.sub.e); X ei = desub(p, ei); X ep = eaddr(p,ei); X } X fprintf(f, "\n"); X for (i=ep->V.dic.alen, ea = ep->V.dic.d; i>0; i--, ea+=2) X if (*ea && *ea != DICT_DELETED) { X for (j=0; j %3d\n", *ea, *(ea+1)); X } X return; X case T_INT: X#ifdef __MSDOS__ X fprintf(f, "%ld", ep->V.i); break; X#else X fprintf(f, "%d", ep->V.i); break; X#endif X case T_KEY: X if (epattr(ep)&A_SUB) { X fprintf(f, "(%d) ", ep->V.sub.e); X ei = desub(p, ei); X ep = eaddr(p,ei); X } X fprintf(f, "\\"); X for (i=0; i<8; i++) X fprintf(f, "%02x", ep->V.nam.u.s[i]); X fprintf(f, "\\"); X break; X case T_NAME: X if (epattr(ep)&A_SUB) { X fprintf(f, "(%d) ", ep->V.sub.e); X ei = desub(p, ei); X ep = eaddr(p,ei); X } X sprintf(fmt, "%%.%ds", (int) eplen(ep)); X if (eplen(ep) <= SHORTNAMELEN) X fprintf(f, fmt, ep->V.nam.u.n); X else X fprintf(f, fmt, ep->V.nam.u.s); X break; X case T_QUEUE: X if (!ep->V.que.head) X fprintf(f, "pids: -- /"); X else X fprintf(f, "pids: %d /", ep->V.que.head->pid); X if (!ep->V.que.tail) X fprintf(f, " --"); X else for (p2 = ep->V.que.tail; p2; p2 = p2->qtail) X fprintf(f, " %d", p2->pid); X break; X case T_STRING: X if (epattr(ep)&A_SUB) X fprintf(f, "(%d, offs=%d) ", ep->V.sub.e, ep->V.sub.offset); X if (epattr(ep)&A_FRAG) X fprintf(f, "(%d+%d) ", ep->V.fra.f[0], ep->V.fra.f[1]); X fprintf(f, "\""); X for (i=0;iV.tim.sec, ep->V.tim.usec); X#else X fprintf(f, "%d + %d", ep->V.tim.sec, ep->V.tim.usec); X#endif X break; X default: break; X } X fprintf(f, "\n"); X} X X Xvoid Xdump_element(FILE *f, mproc p, eindex ei) X{ X dump_e(f, p, ei, 0); X} X Xvoid Xdump_elements(FILE *f, mproc p) X{ X eptr ep; X int lim, i; X X if (!p) { X lim = MAXGLOBALS; X ep = global; X fprintf(f, "Global elements:\n"); X } else { X lim = MAXLOCALS; X ep = p->local; X fprintf(f, "Local elements:\n"); X } X for (i=0; i0; i--, s++) X if (*s) X fprintf(f, " %d", *s); X fprintf(f, " ]\n"); X} X Xvoid Xdump_elements_to_file(char *fn, mproc p) X{ X FILE *f = fopen(fn, "w"); X X if (!f) X return; X X dump_elements(f, p); X X fclose(f); X} X X Xvoid Xdump_process(FILE *f, mproc p) X{ X fprintf(f, "*** Dump of process %d\n", p->pid); X fprintf(f, "state: %s\n", X !p->state ? "run" : X p->state==S_BLOCKED ? "block" : "term"); X if (p->last_error == OK) X fprintf(f, "interpretation ok!\n"); X else { X fprintf(f, "last error of this process: %d (%s)\n", X p->last_error, error_names[p->last_error]); X fprintf(f, "error element is %d\n", p->err_element); X } X fprintf(f, "process queue: %d\n", p->qkey); X fprintf(f, "oper stack: "); X dump_stack(f, p->os, p->osp); X fprintf(f, "dict stack: "); X dump_stack(f, p->ds, p->dsp); X fprintf(f, "exec stack: "); X dump_stack(f, p->es, p->esp); X} X X Xvoid Xdump_process_to_file(char *fn, mproc p) X{ X FILE *f = fopen(fn, "w"); X X if (!f) X return; X X dump_process(f, p); X dump_elements(f, p); X dump_elements(f, 0); X fclose(f); X} X X#endif /* DEBUG */ X X Xvoid terminate(int s) X{ X printf("\n"); X X#ifdef DEBUG X if (trace > 0) { X char *fn = unique_filename("exit"); X FILE *f = fopen(fn, "w"); X X if (f) { X mproc p = current; X X printf("## dumping memory to file %s\n", fn); X while (p) { X dump_process(f, p); X dump_elements(f, p); X p = p->next; X if (p == current) X break; X } X fprintf(f, "\n## global memory:\n"); X dump_elements(f, 0); X fclose(f); X } X } X#endif X X printf("## M0 platform ends.\n"); X exit(0); X} END_OF_FILE if test 5896 -ne `wc -c <'l_dump.c'`; then echo shar: \"'l_dump.c'\" unpacked with wrong size! fi # end of 'l_dump.c' fi if test -f 'l_proto.h' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'l_proto.h'\" else echo shar: Extracting \"'l_proto.h'\" \(6091 characters\) sed "s/^X//" >'l_proto.h' <<'END_OF_FILE' X/* X l_proto.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 X#ifndef L_PROTO_H X#define L_PROTO_H X X#include "element.h" X#include "error.h" X#include "proc.h" X X#ifdef DEBUG X# define TRACE(lev,stmt) if (trace > lev) stmt; X#else X# define TRACE(lev,stmt) X#endif X X/* interp.h */ Xextern retcode init_interpreter(char *bin, char *lib); Xextern int runable(void); Xextern retcode run(void); X X X/* l_array.c */ Xextern eindex new_array(mproc p, uint len); Xextern eindex array_get(mproc p, eindex a, uint offs); Xextern retcode array_put(mproc p, eindex a, uint offs, eindex e); Xextern eindex make_array(mproc p, eindex *ip, uint len); Xextern void array_free(mproc p, eindex ei); Xextern retcode array_copy(mproc p, eindex f, eptr from, eptr to); X X X/* l_compat.c */ Xextern void fillin_hostid(byteptr hid); Xextern void get_utc(uint *sec, uint *usec); X X X/* l_dict.c */ Xextern eindex systemdict; Xextern eindex new_dict(mproc p); Xextern retcode dict_def(mproc p, eindex d, eindex key, eindex val); Xextern eindex dict_get(mproc p, eindex d, eindex key); Xextern retcode dict_undef(mproc p, eindex d, eindex key); Xextern void dict_free(mproc p, eindex d); X#define DICT_DELETED (~(1<<(8*sizeof(eindex)-2))) Xextern retcode dict_copy(mproc p, eindex f, eptr from, eptr to); X X X/* l_dump.c */ X#ifdef DEBUG Xextern int trace; Xextern void dump_element(FILE *f, mproc p, eindex ei); Xextern void dump_elements(FILE *f, mproc p); Xextern void dump_stack(FILE *f, eindex *s, ushort lim); Xextern void dump_elements_to_file(char *fn, mproc p); Xextern void dump_process_to_file(char *fn, mproc p); Xextern void dump_process(FILE *f, mproc p); X#endif Xextern void terminate(int s); X X/* l_elemnt.c */ Xextern char* type_names[]; Xextern eindex new_element(mproc p, byte t); Xextern void free_element(mproc p, eindex ei); Xextern void decref(mproc p, eindex ei); Xextern eindex element_copy(mproc p, eindex ei); /* make a local copy */ Xextern eindex make_sub(mproc p, eindex ei, uint offset); Xextern eindex make_global(mproc p, eindex ei); Xextern eindex desub(mproc p, eindex ei); Xextern void remove_refcycles(void); Xextern int element_equal(mproc p, eindex e1, eindex e2); X X X/* l_format.c */ Xextern byteptr make_msgr(byteptr q, byteptr c, uint clen, X byteptr d, uint dlen, uint *len); Xextern eindex make_msgr_str(mproc p, eindex q, eindex c, eindex d); Xextern retcode decomp_msgr(mproc p, eindex m, eindex *q, eindex *c, eindex *d); X X X/* l_incom.c */ Xextern void add_incoming(int fd, receivefct fct, eindex cname, sint cno); Xextern int incoming_wouldblock(void); Xextern int serve_incoming(long usec); X X X/* l_init.h */ Xextern eptr global; Xextern eindex systemdict; Xextern eindex queuedict; Xextern eindex channeldict; Xextern eindex errorhandler_name; Xextern eindex null_val; Xextern eindex null_key; Xextern eindex null_name; Xextern eindex msgr_name; Xextern eindex msgrO_name; Xextern eindex code_name; Xextern eindex data_name; Xextern eindex orig_name; Xextern eindex ext_name; Xextern eindex msgr_start; /* init code (string) of each msgr */ Xextern eindex host_id; /* key */ Xextern eindex mark; /* used on the operand stack */ Xextern eindex err_name_array; /* array with all error names */ Xextern eindex type_name_array; /* array with all type names */ Xextern retcode low_level_init(void); X X X/* interp.c */ Xextern retcode init_interpreter(char *bin, char *lib); Xextern int runable(void); Xextern retcode run(void); X X X/* l_misc.c */ Xextern char* error_names[]; Xextern char* unique_filename(char *pref); Xextern void random64(byte *b); /* fills in 64 random bits */ Xextern byteptr load_m0(char *binpath, char *libpath, char *filename); Xextern retcode new_channel(eindex key, void *data, submitfct fct); X X X/* l_name.c */ Xextern eindex name_add(byteptr n, uint len, byte attr); Xextern int name_eq(eindex n1, eindex n2); Xextern eindex key_add(byteptr k); Xextern int key_eq(eindex k1, eindex k2); Xextern void free_name(eindex ei); X X X/* l_proc.c */ Xextern mproc current, time_queue; Xextern retcode new_proc(eindex msgr, eindex orig); Xextern void remove_proc(mproc p); Xextern retcode enqueue(mproc p, eindex qkey, eindex t); Xextern void dequeue(mproc p); Xextern void timeout(mproc p); Xextern void queue_state(eindex qk, sint i); X X X/* l_str.c */ Xextern retcode import_str_from_file(char *fn, eindex *str); Xextern eindex str_import(mproc p, byteptr s, uint len, uint alen); Xextern retcode str_export(mproc p, byteptr dest, eindex str, uint offs, uint len); Xextern eindex new_string(mproc p, uint len); Xextern int str_get(mproc p, eindex str, uint pos); Xextern void str_put(mproc p, eindex str, uint pos, byte c); Xextern int str_gt(mproc p, eindex s1, eindex s2); Xextern retcode str_gettoken(mproc p, eindex str, uint *lp, eindex *e); Xextern void free_string(mproc p,eindex ei); Xextern retcode str_copy(mproc p, eindex f, eptr from, eptr to); X X X/* l_time.c */ Xextern eindex time_now(mproc p); Xextern eindex time_addint(mproc p, eindex t1, sint usec); Xextern eindex time_diff(mproc p, eindex t1, eindex t2); Xextern int time_eq(struct time_s *t1, struct time_s *t2); Xextern int time_gt(struct time_s *t1, struct time_s *t2); Xextern long next_timeout(void); /* consults the time_queue, result in usecs */ X X#endif END_OF_FILE if test 6091 -ne `wc -c <'l_proto.h'`; then echo shar: \"'l_proto.h'\" unpacked with wrong size! fi # end of 'l_proto.h' fi if test -f 'm0c.c' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'m0c.c'\" else echo shar: Extracting \"'m0c.c'\" \(6238 characters\) sed "s/^X//" >'m0c.c' <<'END_OF_FILE' X/* X m0c.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 X#include X X#ifdef __MSDOS__ X# include X#endif X X#include "l_proto.h" X#include "c_proto.h" X#include "copyrght.h" X X X#define VERSION "0.11" X#define INI_FILE "cons_ini.m0" X X Xbyte server_queue[8]; Xbyte request_queue[8]; Xchar *bin, *lib, *inc; X X X/* The \xxx..x\ key is used to (a) globally deposit the data field X (=request) and (b) to restart the queue associated with that key - X the server already knows how to send back results: */ Xbyte request[]="\\xxxxxxxxxxxxxxxx\\_ctk _1I_dat:0Q"; X Xchar line[2024]; X Xstatic void init(void); Xstatic void usage(FILE *f); X Xmain(argc, argv) Xint argc; Xchar *argv[]; X{ X while (argc > 1 && argv[1][0] == '-') { X argc--, argv++; X switch(argv[0][1]) { X case 'h': usage(stdout); break; X case 'I': inc = argv[0] + 2; break; X#ifdef DEBUG X case 't': trace = atoi(argv[0]+2); break; X#endif X case 'v': X printf("The M0 local console, version %s (compiled %s at %s)\n", X VERSION, __DATE__, __TIME__); X exit(0); X default: X usage(stderr); break; X } X } X X X bin = getenv("M0BIN"); X lib = getenv("M0LIB"); X X init(); X X X /* unfortunately we can not do a while loop yet: X the end of treatement of a requests is not X specially signalled by the server process X (one should reprogram cons_ini.m0 ... */ X if (argc > 1) { X byteptr download, msgr; X uint msgrlen; X eindex m; X X argc--; argv++; X download = load_m0(bin?bin:DEFBINPATH, inc?inc:".", argv[0]); X if (!download) { X fprintf(stderr, "cannot load file %s\n", argv[0]); X exit(1); X /* continue; */ X } X msgr = make_msgr(request_queue, X request, strlen((char*)request), X download, strlen((char*)download), X &msgrlen); X free((char*)download); X m = str_import(0, msgr, msgrlen, msgrlen); X new_proc(m, 0); X decref(0, m); X run(); X } X X for (;;) { X long to; X X for (;;) { X if (runable()) X run(); X to = next_timeout(); X if (to == 0) X timeout(time_queue); X if (!incoming_wouldblock()) { X to = 0; X break; X } X if (to != 0 && !runable()) { X remove_refcycles(); X break; X } X } X if (msgr_was_empty) X break; X serve_incoming(to); X } X printf("## M0 local console terminated\n"); X return 0; X} X X Xvoid usage(FILE *f) X{ X fprintf(f, "The M0 local console, version %s (compiled %s at %s)\n", X VERSION, __DATE__, __TIME__); X fprintf(f, "%s\n", COPYRIGHT); X fprintf(f, "usage: m0c [options] []\n"); X fprintf(f, "options:\n" X "\t-help\n" X "\t-I\n" X#ifdef DEBUG X "\t-t\n" X#endif X/* X "\t-m \n" X "\t-p \n" X*/ X "\t-version\n" X ); X fprintf(f, "environment variables:\n" X "\tM0BIN path for finding the m0strip binary\n" X "\tM0LIB path for finding the %s startup file\n", INI_FILE); X exit(f == stdout ? 0 : 1); X} X X Xvoid Xinit(void) X{ X int i; X uint msgrlen; X byteptr server_ini, msgr; X eindex m; X byte h[8]; X X printf("## Welcome to the M0 local console (v %s, compiled %s at %s)\n", X VERSION, __DATE__, __TIME__); X printf("## %s\n", COPYRIGHT); X X if ( low_level_init() != OK || operator_init() != OK) { X fprintf(stderr, "low level initialization error\n"); X exit(1); X } X X random64(server_queue); X random64(request_queue); X for (i = 0; i < 8; i++) X sprintf((char*)request+1+2*i, "%02x", server_queue[i]); X request[17] = '\\'; X TRACE(4, printf("Request: \"%s\"\n", request)) X X#ifdef CHANNEL_CONSOLE X console_init(request_queue, request); X#endif X#ifdef CHANNEL_NIT X /* all interfaces that can be found */ X nit_init(get_eth_devices(), ETHERNET_TYPE); X#endif X#ifdef CHANNEL_UDP X if (udp_init(get_ip_addresses(), UDP_SERVERPORT) != 0) X fprintf(stderr, "## Cannot find an empty UDP port\n"); X else { X int i; X printf("## Listening on UDP port 0x%04x at IP address(es)",UDP_SERVERPORT); X for (i = 0; i < eplen(gaddr(udp_addr)); i++) { X eindex e = array_get(0, array_get(0, udp_addr, i), 0); X printf(" %s (=%u)", iptoa(gaddr(e)->V.i), gaddr(e)->V.i); X } X printf("\n"); X } X#endif X X if (channel_defs() != OK) { X fprintf(stderr, "channel level initialization error\n"); X exit(1); X } X X#ifdef SUNOS5 X setuid(getuid()); X seteuid(getuid()); X#else X# ifndef __MSDOS__ X setreuid(getuid(), getuid()); X# endif X#endif X X if( init_interpreter(bin?bin:DEFBINPATH, lib?lib:DEFLIBPATH) != OK) { X fprintf(stderr, "error initializing the M0 interpreter\n"); X exit(1); X } X X#ifdef __MSDOS__ X printf("## remaining memory: 0x%lx bytes (%d kbytes)\n", X farcoreleft(), (int)(farcoreleft()/1024)); X#endif X X fillin_hostid(h); X printf("## This is M0 host \\%02x%02x%02x%02x%02x%02x%02x%02x\\\n\n", X h[0], h[1], h[2], h[3], h[4], h[5], h[6], h[7]); X X server_ini = load_m0(bin?bin:DEFBINPATH, lib?lib:DEFLIBPATH, INI_FILE); X if (!server_ini) { X fprintf(stderr, "loading console initialisation file %s failed\n", INI_FILE); X exit(1); X } X TRACE(4, printf("Server_ini: \"%s\"\n", server_ini)) X X strcpy(line, "{null0{}_sys'_chaG'consoleG'_keyG!}"); X msgr = make_msgr(server_queue, X server_ini, strlen((char*)server_ini), X (byteptr)line, strlen(line), X &msgrlen); X free((char*)server_ini); X m = str_import(0, msgr, msgrlen, msgrlen); X new_proc(m, 0); X decref(0, m); X run(); X X signal(SIGINT, terminate); X signal(SIGTERM, terminate); X#ifndef __MSDOS__ X signal(SIGHUP, terminate); X#endif X} END_OF_FILE if test 6238 -ne `wc -c <'m0c.c'`; then echo shar: \"'m0c.c'\" unpacked with wrong size! fi # end of 'm0c.c' fi if test -f 'm0c.man' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'m0c.man'\" else echo shar: Extracting \"'m0c.man'\" \(6021 characters\) sed "s/^X//" >'m0c.man' <<'END_OF_FILE' X X X XM0C(1) USER COMMANDS M0C(1) X X X XNAME X m0c - a messenger language interpreter and execution X environment with built-in console. X XSYNOPSIS X m0c [ -h ] [ -I ] [ -t ] [ -v ] [ X file ] X XDESCRIPTION X _M_0_c is an execution platform for concurrent M0 processes X similar to the _m_0 interpreter. However, it has a built-in X console where M0 commands can be typed in interactively. X X Beside the command line interface, _m_0_c listens on UDP port X 0x4d30 and filters ethernet frames with protocol type 0x4d30 X for the reception of messengers (whether both interfaces are X supported or not depends on the UNIX platform on which the X M0 interpreter was compiled). X X Lines entered by the user are inserted into a messenger X which delivers its content to a previously installed console X messenger process. This server process executes the given X M0 commands. As a side-effect of this execution it is possi- X ble that some results are returned to the user, thus are X printed on stdout. X X Options: X X -h Print a brief usage indication to stdout. X X -I Tell _m_0_s_t_r_i_p where the include files of a file to down- X load can be found. X X -t X Set the tracing level (for debugging reasons). This X only works if the M0 interpreter was compiled with the X -DDEBUG flag. Default is 0. A value of 1 forces a dump X of all aborted messenger processes to files of the form X _a_b_r_t_*. If an error occurs in the initialisation X (startup) phase of M0, a file _s_t_u_p_* is created. Still X with the option -_t_1 or higher, a file _e_x_i_t_* is created X when the interpreter is interrupted (^C). Higher levels X of tracing print subsequently more information, level 5 X currently being the highest level. X X -v Print the version to stdout. X X file Read the given file and send it to the console server X process after it has installed itself. This allows a X user to download M0 code into a platform in order to X interactively test it via the console. X X X X XSun Release 4.1 Last change: 1 X X X X X X XM0C(1) USER COMMANDS M0C(1) X X X X Parts of the initialisation code needed by _m_0_c is found in X the _s_t_a_r_t_u_p._m_0 and _l_o_n_g_d_i_c_t._m_0 files. These ASCII files are X first treated with the _m_0_s_t_r_i_p program before being read in X by the M0 interpreter. As a next step, the file _c_o_n_s__i_n_i._m_0 X is read and turned into a messenger process: it becomes the X console server process which executes the typed-in commands. X X A file to be downloaded is also treated by the _m_0_s_t_r_i_p pro- X gram. If the file contains ``include'' statements, the -_I X option can be used to tell _m_0_s_t_r_i_p in which directory these X files to be included can be found. X X The console messenger offers five additional commands which X are not part of a standard M0 execution environment: X X print X Send to the console a string to display. X X input X Wait for a line from the console and return the string X (or null if empty). X X ptop Print (non-destructively) the top-most operand. X X stack X Print (non-destructively) the content of the operand X stack. X X quit Terminate the console program. X XFILES X startup.m0 X Startup code (in M0) for the M0 execution platform. X X longdict.m0 X Standard definitions of long command words, included by X _s_t_a_r_t_u_p._m_0. X X cons_ini.m0 X M0 code for the console server process. X X abrt_* X Dump (ASCII) of aborted messengers (only of tracing X level >0). X X exit_* X Dump (ASCII) of all messenger processes and global X memory of the M0 platform (only when tracing level >0 X and INT signal (^C) received). X X stup_* X Dump (ASCII) of an aborted initialisation messenger X X X XSun Release 4.1 Last change: 2 X X X X X X XM0C(1) USER COMMANDS M0C(1) X X X X process that executes the code found in _s_t_a_r_t_u_p._m_0. X X M0.ps X PostScript document describing the messenger approach X and containing a complete M0 language manual with exam- X ples. X XENVIRONMENT X M0BIN X Overrides the default path where auxiliary programs X (_m_0_s_t_r_i_p) can be found. X X M0LIB X Overrides the default path where the startup files X (_s_t_a_r_t_u_p._m_0 and _l_o_n_g_d_i_c_t._m_0) and the console code X (_c_o_n_s__i_n_i._m_0) can be found. X XSEE ALSO X m0strip(1), m0(1), m0uc(1) X XBUGS X The interfaces where _m_0_c should listen for incoming X messengers cannot be specified: currently all available X interfaces (IP and ethernet) are tried and served. The UDP X port cannot be set too, leading thus to collisions on the X port number with other M0 platforms or console programs. X X The interception of messengers which are encapsulated in X ethernet frames requires this program to be installed with X root as owner and with the SETUID bit set (due to the access X protections of the ethernet devices). Insufficient X privileges to open the ethernet device simply deactivates in X _m_0_c the ethernet interface. X X Only one file can be donwloaded. 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 XSun Release 4.1 Last change: 3 X X X END_OF_FILE echo shar: 141 control characters may be missing from \"'m0c.man'\" if test 6021 -ne `wc -c <'m0c.man'`; then echo shar: \"'m0c.man'\" unpacked with wrong size! fi # end of 'm0c.man' fi if test -f 'm0strip.c' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'m0strip.c'\" else echo shar: Extracting \"'m0strip.c'\" \(6140 characters\) sed "s/^X//" >'m0strip.c' <<'END_OF_FILE' X/* X m0strip.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#include X#include X X#include "copyrght.h" X X#define VERSION "0.11" X#define MAXLINE 512 X Xenum {PUNCT, LOWER, UPPER, DIGIT, STRG}; /* used in last_char */ X Xchar line[MAXLINE+1], last_char; XFILE *fin, *fout; Xchar infile[256]; Xchar includepath[256]; X Xchar incl[] = "#include"; Xchar inclstr[] = "#includestring"; X Xextern FILE *myfopen(char *); X X Xmain(argc, argv) Xint argc; Xchar *argv[]; X{ X while (argc > 1 && argv[1][0] == '-') { X argc--, argv++; X switch(argv[0][1]) { X case 'o': X if (fout || argc < 2) usage(); X fout = fopen(argv[1], "w"); X if (!fout) { X fprintf(stderr, "cannot open output file %s\n", argv[1]); X exit(1); X } X break; X case 'I': X strcpy(includepath, argv[0]+2); break; X default: X usage(); X } X } X X if (argc > 1) { X fin = fopen(argv[1], "r"); X if (!fin) { X fprintf(stderr, "cannot open input file %s\n", argv[1]); X exit(1); X } X strcpy(infile, argv[1]); X } else { X fin = stdin; X strcpy(infile, "--stdin--"); X } X X if (!fout) X fout = stdout; X X readfile(fin, "stdin", 0); X return 0; X} X X Xprint_error(char *fn, int linecount, char *err) X{ X fprintf(stderr, "%s, line %d: %s\n", fn, linecount, err); X exit(1); X} X X Xreadfile(FILE *f, char *fn, int quote) X{ X int linecount = 0, i; X X for(;;) { X if (!fgets(line, MAXLINE, f)) X break; X X linecount++; X if (strncmp(inclstr, line, strlen(inclstr)) == 0) { X char *cp = strtok(line+strlen(inclstr), " \t\n"); X FILE *f2 = myfopen(cp); X if (!f2) X print_error(fn, linecount, "cannot open input file"); X for (i=1; i < 2*quote; i++) X fputc('\\', fout); X fputc('\"', fout); X last_char = PUNCT; X readfile(f2, cp, quote+1); X for (i=1; i < 2*quote; i++) X fputc('\\', fout); X fputc('\"', fout); X last_char = PUNCT; X fclose(f2); X continue; X } X if (strncmp(incl, line, strlen(incl)) == 0) { X char *cp = strtok(line+strlen(incl), " \t\n"); X FILE *f2 = myfopen(cp); X if (!f2) X print_error(fn, linecount, "cannot open input file"); X readfile(f2, cp, quote); X fclose(f2); X continue; X } X remove_comments(line, fn, linecount, 1); X read_ascii(line, fn, linecount, quote); X } X} X X Xremove_comments(char *l, char *fn, int linecount, int rem_blanks) X{ X char *s = l; X int in_number = 0; X X for (;;) { X switch (*s) { X case '\n': *s = '\0'; goto bot; X case '#': X if (in_number) { s++; in_number--; break; } X if (isdigit(*s)) { s++; in_number = 2; break; } X *s = '\0'; goto bot; X default: s++; break; X } X } Xbot: X if (in_number) X print_error(fn, linecount, "unterminated #base#digits# number"); X if (rem_blanks) { X for (s--; s >= l && isspace(*s); s--); X *(s+1) = '\0'; X for (s = l; isspace(*s); s++); X if (s > l) { X for (; *s; l++, s++) X *l = *s; X *l = '\0'; X } X } X return 0; X} X X Xread_ascii(char *s, char *fn, int linecount, int quote) X{ X char *cp; X int i; X X if (*s == '\0') return; X X for (cp = s; *cp; s = cp) { X if (isspace(*cp)) X cp++; X else if (isdigit(*cp)) { X for (cp++; isdigit(*cp); cp++); X if (last_char == DIGIT) X fputc(' ', fout); X while (cp > s) { X fputc(*s, fout); X s++; X } X last_char = DIGIT; X } else if (isupper(*cp)) { X fputc(*cp, fout); X cp++; X last_char = UPPER; X } else if (islower(*cp) || *cp == '_') { X for (cp++; islower(*cp) || *cp == '_'; cp++); X if (last_char == LOWER) X fputc(' ', fout); X while (cp > s) { X fputc(*s, fout); X s++; X } X last_char = LOWER; X } else if (*cp == '\\') { X for(cp++;;cp++) { X if (*cp == '\0') X print_error(fn, linecount, "unterminated hexstring"); X if (*cp == '\\') X break; X if ( !isxdigit(*cp) ) X print_error(fn, linecount, "invalid char in hexstring"); X } X for (i=0; i <= 2*quote; i++) X fputc('\\', fout); X s++; X while (cp > s) { X fputc(*s, fout); X s++; X } X for (i=0; i <= 2*quote; i++) X fputc('\\', fout); X cp++; X last_char = PUNCT; X } else if (*cp == '\"') { X for(cp++;;cp++) { X if (*cp == '\0') X print_error(fn, linecount, "unterminated string"); X if (*cp == '\"') X break; X if (*cp == '\\' && *(cp+1) == '\"') X cp++; X } X for (i=1; i < 2*quote; i++) X fputc('\\', fout); X fputc('\"', fout); X s++; X while (cp > s) { X if (*s == '\"' || *s == '\\') { X for (i=0; i < 2*quote; i++) X fputc('\\', fout); X } X fputc(*s, fout); X s++; X } X for (i=1; i < 2*quote; i++) X fputc('\\', fout); X fputc('\"', fout); X cp++; X last_char = PUNCT; X } else { X fputc(*cp, fout); X cp++; X last_char = PUNCT; X } X } X} X X Xusage() X{ X fprintf(stderr, "Strip blanks from M0 code, version %s (compiled %s at %s)\n", X VERSION, __DATE__, __TIME__); X fprintf(stderr, "%s\n", COPYRIGHT); X fprintf(stderr, "usage: m0strip [options] []\n"); X fprintf(stderr, "options:\n" X "\t-o \n" X "\t-I\n"); X exit(1); X} X X XFILE* Xmyfopen(char *fn) X{ X char path[512]; X FILE *f; X X f = fopen(fn, "r"); X if (f || includepath[0] == '\0' || strchr(fn, '/')) X return f; X if (includepath[strlen(includepath)-1] == '/') X sprintf(path, "%s%s", includepath, fn); X else X sprintf(path, "%s/%s", includepath, fn); X return fopen(path, "r"); X} END_OF_FILE if test 6140 -ne `wc -c <'m0strip.c'`; then echo shar: \"'m0strip.c'\" unpacked with wrong size! fi # end of 'm0strip.c' fi if test -f 'm0uc.c' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'m0uc.c'\" else echo shar: Extracting \"'m0uc.c'\" \(5955 characters\) sed "s/^X//" >'m0uc.c' <<'END_OF_FILE' X/* X m0uc.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 X#include X X#include "l_proto.h" /* for l_format.c */ X#include "c_proto.h" /* for UDP_SERVERPORT */ X#include "copyrght.h" X X#define VERSION "0.11" X#define INI_FILE "cons_ini.m0" X X Xushort serverport = UDP_SERVERPORT; Xushort myport = UDP_SERVERPORT+1; Xuint host = 0, this_ip_host; Xint udp_sock; X Xbyte request_queue[8]; X X/* The \xxx..x\ key is used to (a) globally deposit the data field X (=request) and (b) to restart the queue associated with that key - X the server already knows how to send back results: */ Xbyte request[]="\\xxxxxxxxxxxxxxxx\\_ctk _1I_dat:0Q"; X Xchar line[8096]; X Xstatic void usage(FILE *f); X Xmain(argc, argv) Xint argc; Xchar *argv[]; X{ X while (argc > 1 && argv[1][0] == '-') { X argc--, argv++; X switch(argv[0][1]) { X case 'h': usage(stdout); break; X case 'm': X if (argc < 2) usage(stderr); X host = ntohl(inet_addr(argv[1])); X argc--, argv++; break; X case 'p': X if (argc < 2) usage(stderr); X serverport = strtol(argv[1], NULL, 0); X argc--, argv++; break; X/* X case 'u': X if (argc < 2) usage(stderr); X myport = strtol(argv[1], NULL, 0); X argc--, argv++; break; X*/ X case 'v': X printf("The M0 remote console, version %s (compiled %s at %s)\n", X VERSION, __DATE__, __TIME__); X exit(0); X default: X usage(stderr); break; X } X } X X init(); X X /* unfortunately we can not do a while loop yet: X the end of treatement of a requests is not X specially signalled by the server process X (one should reprogram cons_ini.m0 ... */ X if (argc > 1) { X byte *download, *msgr; X uint msgrlen; X X argc--; argv++; X download = load_m0(".", ".", argv[0]); X if (!download) { X fprintf(stderr, "cannot load file %s\n", argv[0]); X exit(1); X /* continue; */ X } X if (strlen((char*)download) > 7000) { X fprintf(stderr, "file %s to download is too large: skipped\n", argv[0]); X free(download); X exit(1); X /* continue; */ X } X msgr = make_msgr(request_queue, X request, strlen((char*)request), X download, strlen((char*)download), X &msgrlen); X if (udp_send(udp_sock, host, UDP_SERVERPORT, msgr, msgrlen) < 0) X perror("client download"); X free(msgr); X free(download); X } X X for (;;) { X int cnt; X uint msgrlen; X byteptr msgr; X fd_set r; X X FD_ZERO(&r); X FD_SET(0, &r); /* stdin */ X FD_SET(udp_sock, &r); /* udp port */ X select(FD_SETSIZE, &r, NULL, NULL, NULL); X if (FD_ISSET(udp_sock, &r)) { X cnt = recv(udp_sock, line, sizeof(line)-1, 0); X if (cnt < 0) X perror("client recv"); X if (cnt == 0) X break; X line[cnt] = '\0'; X printf("%s", line); X fflush(stdout); X continue; X } X cnt = read(0, line, sizeof(line)); X if (cnt <= 0) X break; X msgr = make_msgr(request_queue, X request, strlen((char*)request), X cnt>1 ? (byteptr)line : 0, cnt-1, &msgrlen); X if (udp_send(udp_sock, host, UDP_SERVERPORT, msgr, (int)msgrlen) < 0) X perror("client send"); X free(msgr); X } X printf("## M0 console terminated\n"); X} X X Xvoid Xusage(FILE *f) X{ X fprintf(f, "The M0 remote UDP console, version %s (compiled %s at %s)\n", X VERSION, __DATE__, __TIME__); X fprintf(f, "%s\n", COPYRIGHT); X fprintf(f, "usage: m0uc [options] []\n"); X fprintf(f, "options:\n" X "\t-help\n" X "\t-m \n" X "\t-p \n" X/* X "\t-u \n" X*/ X "\t-version\n"); X fprintf(f, "environment variables:\n" X "\tM0BIN path for finding the m0strip binary\n" X "\tM0LIB path for finding the %s startup file\n", INI_FILE); X exit(1); X} X X Xinit() X{ X char *bin, *lib; X int i; X byte server_queue[8]; X uint msgrlen; X byteptr server_ini, msgr; X X for (i = 10; ;i--) { X udp_sock = udp_listen(0, myport); X if (udp_sock > 0) X break; X if (i < 1) { X fprintf(stderr, "Cannot find an empty UDP-port\n"); X exit(1); X } X myport++; X } X X printf("## Welcome to the M0 remote console (v %s, compiled %s at %s)\n", X VERSION, __DATE__, __TIME__); X printf("## %s\n\n", COPYRIGHT); X X this_ip_host = * get_ip_addresses(); X if (!host) X host = this_ip_host; X X printf( "Local host %s (%u), UDP port is 0x%04x\n", X iptoa(this_ip_host), this_ip_host, myport); X printf( "Contacting the M0 platform at %s (%u), UDP port 0x%04x ...\n\n", X iptoa(host), host, serverport); X X srandom(time(NULL)); X random64(server_queue); X random64(request_queue); X for (i = 0; i < 8; i++) X sprintf((char*)request+1+2*i, "%02x", server_queue[i]); X request[17] = '\\'; X X bin = getenv("M0BIN"); X lib = getenv("M0LIB"); X server_ini = load_m0(bin?bin:DEFBINPATH, lib?lib:DEFLIBPATH, INI_FILE); X if (!server_ini) { X fprintf(stderr, "loading initialisation code from file %s failed\n", INI_FILE); X exit(1); X } X X sprintf(line, "{[%u %u]0{}_cha'udpipG'_keyG!}", this_ip_host, myport); X msgr = make_msgr(server_queue, X server_ini, strlen((char*)server_ini), X (byteptr)line, strlen(line), X &msgrlen); X if (udp_send(udp_sock, host, serverport, msgr, msgrlen) < 0) X perror("client send"); X free(msgr); X free(server_ini); X} X END_OF_FILE if test 5955 -ne `wc -c <'m0uc.c'`; then echo shar: \"'m0uc.c'\" unpacked with wrong size! fi # end of 'm0uc.c' fi if test -f 'makefile.all' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'makefile.all'\" else echo shar: Extracting \"'makefile.all'\" \(6546 characters\) sed "s/^X//" >'makefile.all' <<'END_OF_FILE' X# makefile.all X X# ---------------------------------------------------------------------------- X# common part X XCHANLIBOBJS= c_con.$(O) c_file.$(O) c_nit.$(O) c_udp.$(O) X XLOWLIBOBJS= l_array.$(O) l_chksum.$(O) l_compat.$(O) l_dict.$(O) \ X l_dump.$(O) l_elemnt.$(O) l_format.$(O) l_incom.$(O) \ X l_init.$(O) l_misc.$(O) l_name.$(O) l_proc.$(O) \ X l_str.$(O) l_strbuf.$(O) l_time.$(O) X XOPERLIBOBJS= o_arith.$(O) o_array.$(O) o_attr.$(O) o_chan.$(O) \ X o_ctrl.$(O) o_dict.$(O) o_init.$(O) o_misc.$(O) \ X o_msgr.$(O) o_stack.$(O) o_string.$(O) o_type.$(O) X XLIBOBJS= $(LOWLIBOBJS) $(CHANLIBOBJS) $(OPERLIBOBJS) X XIN_CHKSUM= chksum.h std.h XIN_ELEMENT= element.h std.h XIN_ERROR= error.h std.h XIN_HDR= hdr.h std.h X XIN_PROC= proc.h $(IN_ERROR) $(IN_ELEMENT) XIN_STRBUF= strbuf.h $(IN_ELEMENT) $(IN_ERROR) X XIN_LP= l_proto.h $(IN_ELEMENT) $(IN_ERROR) $(IN_PROC) XIN_CP= c_proto.h $(IN_LP) XIN_OP= o_proto.h $(IN_ERROR) X XLOWLIB= libLOW.$(L) XCHANLIB= libCHAN.$(L) XOPERLIB= libOPER.$(L) X X# ---------------------------------------------------------------------- X X$(CHANLIB): $(CHANLIBOBJS) X $(RANLIBCMD) $(CHANLIB) X X$(LOWLIB): $(LOWLIBOBJS) X $(RANLIBCMD) $(LOWLIB) X X$(OPERLIB): $(OPERLIBOBJS) X $(RANLIBCMD) $(OPERLIB) X X# ---------------------------------------------------------------------- X Xm0$(E): $(LOWLIB) $(CHANLIB) $(OPERLIB) interp.$(O) m0.$(O) X $(CC) $(LFLAGS) \ X m0.$(O) interp.$(O) $(OPERLIB) $(LOWLIB) $(CHANLIB) $(SYSLIBS) X $(MV) a.out $@ X Xm0c$(E): $(LOWLIB) $(CHANLIB) $(OPERLIB) interp.$(O) m0c.$(O) X $(CC) $(LFLAGS) \ X m0c.$(O) interp.$(O) $(OPERLIB) $(LOWLIB) $(CHANLIB) $(SYSLIBS) X $(MV) a.out $@ X Xm0uc: $(LOWLIB) $(CHANLIB) m0uc.$(O) X $(CC) $(LFLAGS) m0uc.$(O) $(CHANLIB) $(LOWLIB) $(SYSLIBS) X $(MV) a.out $@ X Xm0strip$(E): m0strip.$(O) X $(CC) $(LFLAGS) m0strip.$(O) $(SYSLIBS) X $(MV) a.out $@ X X# ---------------------------------------------------------------------- X# lowlevel library X Xl_array.$(O): $(IN_LP) l_array.c X $(CC) $(CFLAGS) -c $*.c X $(LIBCMD) $(LOWLIB) $(LIBFLAGS)$*.$(O) X Xl_compat.$(O): $(IN_LP) l_compat.c X $(CC) $(CFLAGS) -c $*.c X $(LIBCMD) $(LOWLIB) $(LIBFLAGS)$*.$(O) X Xl_chksum.$(O): $(IN_CHKSUM) l_chksum.c X $(CC) $(CFLAGS) -c $*.c X $(LIBCMD) $(LOWLIB) $(LIBFLAGS)$*.$(O) X Xl_dict.$(O): $(IN_LP) l_dict.c X $(CC) $(CFLAGS) -c $*.c X $(LIBCMD) $(LOWLIB) $(LIBFLAGS)$*.$(O) X Xl_dump.$(O): $(IN_LP) l_dump.c X $(CC) $(CFLAGS) -c $*.c X $(LIBCMD) $(LOWLIB) $(LIBFLAGS)$*.$(O) X Xl_elemnt.$(O): $(IN_LP) l_elemnt.c X $(CC) $(CFLAGS) -c $*.c X $(LIBCMD) $(LOWLIB) $(LIBFLAGS)$*.$(O) X Xl_incom.$(O): $(IN_LP) l_incom.c X $(CC) $(CFLAGS) -c $*.c X $(LIBCMD) $(LOWLIB) $(LIBFLAGS)$*.$(O) X Xl_init.$(O): $(IN_LP) l_init.c X $(CC) $(CFLAGS) -c $*.c X $(LIBCMD) $(LOWLIB) $(LIBFLAGS)$*.$(O) X Xl_format.$(O): $(IN_LP) $(IN_HDR) $(IN_CHKSUM) l_format.c X $(CC) $(CFLAGS) -c $*.c X $(LIBCMD) $(LOWLIB) $(LIBFLAGS)$*.$(O) X Xl_misc.$(O): $(IN_LP) l_misc.c X $(CC) $(CFLAGS) -c $*.c X $(LIBCMD) $(LOWLIB) $(LIBFLAGS)$*.$(O) X Xl_name.$(O): $(IN_LP) l_name.c X $(CC) $(CFLAGS) -c $*.c X $(LIBCMD) $(LOWLIB) $(LIBFLAGS)$*.$(O) X Xl_proc.$(O): $(IN_LP) l_proc.c X $(CC) $(CFLAGS) -c $*.c X $(LIBCMD) $(LOWLIB) $(LIBFLAGS)$*.$(O) X Xl_str.$(O): $(IN_LP) $(IN_STRBUF) l_str.c X $(CC) $(CFLAGS) -c $*.c X $(LIBCMD) $(LOWLIB) $(LIBFLAGS)$*.$(O) X Xl_strbuf.$(O): $(IN_STRBUF) l_strbuf.c X $(CC) $(CFLAGS) -c $*.c X $(LIBCMD) $(LOWLIB) $(LIBFLAGS)$*.$(O) X Xl_time.$(O): $(IN_LP) l_time.c X $(CC) $(CFLAGS) -c $*.c X $(LIBCMD) $(LOWLIB) $(LIBFLAGS)$*.$(O) X X# ---------------------------------------------------------------------- X# channel library X Xc_con.$(O): $(IN_CP) c_con.c X $(CC) $(CFLAGS) -c $*.c X $(LIBCMD) $(CHANLIB) $(LIBFLAGS)$*.$(O) X Xc_file.$(O): $(IN_CP) c_file.c X $(CC) $(CFLAGS) -c $*.c X $(LIBCMD) $(CHANLIB) $(LIBFLAGS)$*.$(O) X Xc_nit.$(O): $(IN_CP) c_nit.c X $(CC) $(CFLAGS) -c $*.c X $(LIBCMD) $(CHANLIB) $(LIBFLAGS)$*.$(O) X Xc_udp.$(O): $(IN_CP) c_udp.c X $(CC) $(CFLAGS) -c $*.c X $(LIBCMD) $(CHANLIB) $(LIBFLAGS)$*.$(O) X X# ---------------------------------------------------------------------- X# the interpreter X Xinterp.$(O): $(IN_LP) $(IN_OP) interp.c X $(CC) $(CFLAGS) -c $*.c X X# ---------------------------------------------------------------------- X# operator library X Xo_arith.$(O): $(IN_LP) $(IN_OP) o_arith.c X $(CC) $(CFLAGS) -c $*.c X $(LIBCMD) $(OPERLIB) $(LIBFLAGS)$*.$(O) X Xo_array.$(O): $(IN_LP) $(IN_OP) o_array.c X $(CC) $(CFLAGS) -c $*.c X $(LIBCMD) $(OPERLIB) $(LIBFLAGS)$*.$(O) X Xo_attr.$(O): $(IN_LP) $(IN_OP) o_attr.c X $(CC) $(CFLAGS) -c $*.c X $(LIBCMD) $(OPERLIB) $(LIBFLAGS)$*.$(O) X Xo_chan.$(O): $(IN_CP) $(IN_LP) $(IN_OP) o_chan.c X $(CC) $(CFLAGS) -c $*.c X $(LIBCMD) $(OPERLIB) $(LIBFLAGS)$*.$(O) X Xo_ctrl.$(O): $(IN_LP) $(IN_OP) o_ctrl.c X $(CC) $(CFLAGS) -c $*.c X $(LIBCMD) $(OPERLIB) $(LIBFLAGS)$*.$(O) X Xo_dict.$(O): $(IN_LP) $(IN_OP) o_dict.c X $(CC) $(CFLAGS) -c $*.c X $(LIBCMD) $(OPERLIB) $(LIBFLAGS)$*.$(O) X Xo_init.$(O): $(IN_LP) $(IN_OP) o_init.c X $(CC) $(CFLAGS) -c $*.c X $(LIBCMD) $(OPERLIB) $(LIBFLAGS)$*.$(O) X Xo_misc.$(O): $(IN_LP) $(IN_OP) o_misc.c X $(CC) $(CFLAGS) -c $*.c X $(LIBCMD) $(OPERLIB) $(LIBFLAGS)$*.$(O) X Xo_msgr.$(O): $(IN_LP) $(IN_OP) o_msgr.c X $(CC) $(CFLAGS) -c $*.c X $(LIBCMD) $(OPERLIB) $(LIBFLAGS)$*.$(O) X Xo_stack.$(O): $(IN_LP) $(IN_OP) o_stack.c X $(CC) $(CFLAGS) -c $*.c X $(LIBCMD) $(OPERLIB) $(LIBFLAGS)$*.$(O) X Xo_string.$(O): $(IN_LP) $(IN_OP) o_string.c X $(CC) $(CFLAGS) -c $*.c X $(LIBCMD) $(OPERLIB) $(LIBFLAGS)$*.$(O) X Xo_type.$(O): $(IN_LP) $(IN_STRBUF) $(IN_OP) o_type.c X $(CC) $(CFLAGS) -c $*.c X $(LIBCMD) $(OPERLIB) $(LIBFLAGS)$*.$(O) X X# ---------------------------------------------------------------------- X# the main objects for executables X Xm0.$(O): $(IN_LP) $(IN_CP) copyrght.h m0.c X $(CC) $(CFLAGS) \ X -DDEFLIBPATH=\"$(M0DEFLIBPATH)\" \ X -DDEFBINPATH=\"$(M0DEFBINPATH)\" \ X -c $*.c X Xm0c.$(O): $(IN_LP) copyrght.h m0c.c X $(CC) $(CFLAGS) \ X -DDEFLIBPATH=\"$(M0DEFLIBPATH)\" \ X -DDEFBINPATH=\"$(M0DEFBINPATH)\" \ X -c $*.c X Xm0uc.$(O): $(IN_LP) $(IN_CP) copyrght.h m0uc.c X $(CC) $(CFLAGS) \ X -DDEFLIBPATH=\"$(M0DEFLIBPATH)\" \ X -DDEFBINPATH=\"$(M0DEFBINPATH)\" \ X -c $*.c X Xm0strip.$(O): copyrght.h m0strip.c X $(CC) $(CFLAGS) -c $*.c X X# --------------------------------------------------------------------------- X Xclean: X rm -f core *.$(O) *.$(L) $(EXEFILES) *.BAK X rm -f *~ abrt_* exit_* stup_* X rm -f mon.out gmon.out X Xinstall: $(EXEFILES) X install $(EXEFILES) $(M0DEFBINPATH) X install -d $(M0DEFLIBPATH) X install *.m0 $(M0DEFLIBPATH) X install *.1 $(M0DEFMANPATH) X # we should also change the owner of m0 and m0c to root with setuid X # but currently this is only needed for the SunOS4 platform ... X# eof END_OF_FILE if test 6546 -ne `wc -c <'makefile.all'`; then echo shar: \"'makefile.all'\" unpacked with wrong size! fi # end of 'makefile.all' fi if test -f 'o_chan.c' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'o_chan.c'\" else echo shar: Extracting \"'o_chan.c'\" \(5565 characters\) sed "s/^X//" >'o_chan.c' <<'END_OF_FILE' X/* X o_chan.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 "c_proto.h" X#include "l_proto.h" X#include "o_proto.h" X X X#ifdef CHANNEL_CONSOLE Xstatic retcode Xo_console() X{ X eindex key; X X if (current->osp < 3) X return ERR_STACK_UNDERFLOW; X X decref(current, current->os[current->osp-1]); X decref(current, current->os[current->osp-2]); X decref(current, current->os[current->osp-3]); X X key = add_console_channel(); X return_ok_result(3, key); X} X#endif X X X#ifdef CHANNEL_NIT Xstatic retcode Xo_nit() X{ X eindex key; X byte desthost[6]; X X load_3_args(addr, srcchan, chk, ap, sp, cp); X X if (eptype(ap) != T_STRING || eplen(ap) != 6 || eptype(sp) != T_INT) X return ERR_TYPE_CHECK; X if (!(epattr(ap) & A_READ)) X return ERR_ACCESS_CHECK; X X str_export(current, desthost, addr, 0, 6); X X if (sp->V.i < 0 || sp->V.i > eplen(gaddr(nit_addr))) X return ERR_RANGE_CHECK; X X key = add_nit_channel(sp->V.i, desthost); X X decrefp(current,addr,ap); X decrefp(current,srcchan,sp); X decrefp(current,chk,cp); X X return_ok_result(3, key); X} X#endif X X X#ifdef CHANNEL_UDP Xstatic retcode Xo_udp() X{ X eindex desthost, port, key; X X load_3_args(addr, srcchan, chk, ap, sp, cp); X X if (eptype(ap) != T_ARRAY || eplen(ap) != 2 || eptype(sp) != T_INT) X return ERR_TYPE_CHECK; X if (!(epattr(ap) & A_READ)) X return ERR_ACCESS_CHECK; X X desthost = array_get(current, addr, 0); X port = array_get(current, addr, 1); X if (etype(current,desthost) != T_INT || etype(current,port) != T_INT) X return ERR_TYPE_CHECK; X X if (sp->V.i < 0 || sp->V.i > eplen(gaddr(udp_addr))) X return ERR_RANGE_CHECK; X X key = add_udp_channel( sp->V.i, X eaddr(current, desthost)->V.i, X eaddr(current, port)->V.i); X X decrefp(current,addr,ap); X decrefp(current,srcchan,sp); X decrefp(current,chk,cp); X X return_ok_result(3, key); X} X#endif X X Xenum {no_check, car_check}; Xenum {asc_target, mzr_target}; X Xstruct ch_s { X eindex *name; X int type, check, target; X uint mtu; X eindex* addr_array; X retcode (*create_key)(); X byteptr descr; X}; X Xstatic struct ch_s ch[] = { X#ifdef CHANNEL_CONSOLE X {&console_name, 1, no_check, asc_target, 0, &console_addr, o_console, X (byteptr)"M0 console (stdout)"}, X#endif X#ifdef CHANNEL_NIT X {&nit_name, 1, no_check, mzr_target, 1400, &nit_addr, o_nit, X (byteptr)"intel/dec/xerox ethernet"}, X#endif X#ifdef CHANNEL_UDP X {&udp_name, 1, no_check, mzr_target, 7500, &udp_addr, o_udp, X (byteptr)"DoD user datagram protocol over IP"}, X#endif X}; X Xretcode Xchannel_defs() X{ X eindex n_cha, n_adr; X eindex n_aut, n_des, n_key, n_mtu, n_tar, n_typ; X eindex check[2], target[2]; X eindex cdict, adict; X int i, nofch = sizeof(ch)/sizeof(struct ch_s); X X n_cha = name_add((byteptr)"_cha", 4, A_EXECUTABLE); X n_adr = name_add((byteptr)"_adr", 4, A_EXECUTABLE); X X n_aut = name_add((byteptr)"_aut", 4, A_EXECUTABLE); X n_des = name_add((byteptr)"_des", 4, A_EXECUTABLE); X n_key = name_add((byteptr)"_key", 4, A_EXECUTABLE); X n_mtu = name_add((byteptr)"_mtu", 4, A_EXECUTABLE); X n_tar = name_add((byteptr)"_tar", 4, A_EXECUTABLE); X n_typ = name_add((byteptr)"_typ", 4, A_EXECUTABLE); X check[0] = name_add((byteptr)"_nch", 4, 0); X check[1] = name_add((byteptr)"_car", 4, 0); X target[0] = name_add((byteptr)"_asc", 4, 0); X target[1] = name_add((byteptr)"_mzr", 4, 0); X X cdict = new_dict(0); X dict_def(0, systemdict, n_cha, cdict); X decref(0, n_cha); decref(0, cdict); X adict = new_dict(0); X dict_def(0, systemdict, n_adr, adict); X decref(0, n_adr); decref(0, adict); X X for (i = 0; i < nofch; i++) { X eindex e, val, d; X X if (!*(ch[i].name)) X continue; X X val = *(ch[i].name); X if (ch[i].addr_array && *(ch[i].addr_array)) { X dict_def(0, adict, val, *(ch[i].addr_array)); X decref(0, val); X decref(0, *(ch[i].addr_array)); X } X X d = new_dict(0); X dict_def(0, cdict, val, d); X decref(0, val); X decref(0, d); X X#define add_entry(k,v) e = (v); dict_def(0,d,k,e); X add_entry(n_aut, check[ch[i].check]); X add_entry(n_tar, target[ch[i].target]); X val = new_element(0, T_INT); X gaddr(val)->V.i = ch[i].type; X add_entry(n_typ, val); X decref(0, val); X val = str_import(0, ch[i].descr, strlen((char*)(ch[i].descr)), 0); X add_entry(n_des, val); X decref(0, val); X val = new_element(0, T_PROC); X gaddr(val)->V.pro.fct = ch[i].create_key; X epattr(gaddr(val)) |= A_EXECUTABLE; X add_entry(n_key, val); X decref(0, val); X val = new_element(0, T_INT); X gaddr(val)->V.i = ch[i].mtu; X add_entry(n_mtu, val); X decref(0, val); X } X X decref(0, n_aut); decref(0, n_des); X decref(0, n_key); decref(0, n_mtu); X decref(0, n_tar); decref(0, n_typ); X decref(0, check[0]); decref(0, check[1]); X decref(0, target[0]); decref(0, target[1]); X X return OK; X} END_OF_FILE if test 5565 -ne `wc -c <'o_chan.c'`; then echo shar: \"'o_chan.c'\" unpacked with wrong size! fi # end of 'o_chan.c' fi echo shar: End of archive 4 \(of 12\). cp /dev/null ark4isdone 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