home *** CD-ROM | disk | FTP | other *** search
- /*
- o_misc.c
- */
- /* Copyright (c) 1994 Christian F. Tschudin. All rights reserved.
-
- Distributed under the terms of the GNU General Public License
- version 2 of june 1991 as published by the Free Software
- Foundation, Inc.
-
- This file is part of M0.
-
- M0 is distributed in the hope that it will be useful, but WITHOUT ANY
- WARRANTY. No author or distributor accepts responsibility to anyone for
- the consequences of using it or for whether it serves any particular
- purpose or works at all, unless he says so in writing. Refer to the GNU
- General Public License for full details.
-
- Everyone is granted permission to copy, modify and redistribute M0, but
- only under the conditions described in the GNU General Public License.
- A copy of this license is supposed to have been given to you along with
- M0 so you can know your rights and responsibilities. It should be in a
- file named LICENSE. Among other things, the copyright notice and this
- notice must be preserved on all copies. */
-
- #include <stdlib.h>
-
-
- #include "l_proto.h"
- #include "o_proto.h"
-
-
- retcode
- o_get()
- {
- eindex r;
-
- load_2_args(e, i, ep, ip);
-
- if (!(epattr(ep) & A_READ))
- return ERR_ACCESS_CHECK;
- if (eptype(ep) == T_DICT) {
- r = dict_get(current, e, i);
- if (!r)
- return ERR_UNDEFINED;
- incref(current,r);
- } else if (eptype(ep) == T_ARRAY || eptype(ep) == T_STRING) {
- if (eptype(ip) == T_INT) {
- if (ip->V.i < 0 || ip->V.i >= eplen(ep))
- return ERR_RANGE_CHECK;
-
- if (eptype(ep) == T_STRING) {
- r = new_element(current, T_INT);
- eaddr(current,r)->V.i = str_get(current, e, ip->V.i);
- } else {
- r = array_get(current, e, ip->V.i);
- incref(current,r);
- }
- } else if (eptype(ip) == T_ARRAY && eplen(ip) == 2) {
- eindex offs, len;
- sint o, l;
-
- offs = array_get(current, i, 0);
- len = array_get(current, i, 1);
- if (etype(current,offs) != T_INT ||
- etype(current,len) != T_INT)
- return ERR_TYPE_CHECK;
- o = eaddr(current,offs)->V.i;
- l = eaddr(current,len)->V.i;
- if (o < 0 || l < 0 || (o+l) > eplen(ep))
- return ERR_RANGE_CHECK;
- r = make_sub(current, e, o);
- elen(current,r) = l;
- } else
- return ERR_TYPE_CHECK;
- } else
- return ERR_TYPE_CHECK;
- decrefp(current,e, ep);
- decrefp(current,i, ip);
- return_ok_result(2, r);
- }
-
-
- retcode
- o_gmt()
- {
- if (current->osp >= MAXOSTACK)
- return ERR_OSTACK_OVERFLOW;
- current->os[current->osp++] = time_now(current);
- return OK;
- }
-
-
-
- retcode
- o_hostid()
- {
- if (current->osp >= MAXOSTACK)
- return ERR_OSTACK_OVERFLOW;
- current->os[current->osp++] = host_id;
- incref(current, host_id);
-
- return OK;
- }
-
-
- retcode
- o_length()
- {
- uint len;
-
- load_1_arg(ei, ep);
-
- if (eptype(ep) != T_ARRAY && eptype(ep) != T_STRING &&
- eptype(ep) != T_DICT)
- return ERR_TYPE_CHECK;
- if (!(epattr(ep) & A_READ))
- return ERR_ACCESS_CHECK;
- len = eplen(ep);
- decrefp(current, ei, ep);
- ei = new_element(current, T_INT);
- ep = eaddr(current, ei);
- ep->V.i = len;
- current->os[current->osp-1] = ei;
-
- return OK;
- }
-
-
- retcode
- o_put()
- {
- load_3_args(e, i, v, ep, ip, vp);
-
- if (!(epattr(ep) & A_WRITE))
- return ERR_ACCESS_CHECK;
- if (eptype(ep) == T_DICT) {
- retcode rc = dict_def(current, e, i, v);
- if (rc != OK)
- return rc;
- decrefp(current,v, vp);
- } else {
- if (eptype(ip) != T_INT)
- return ERR_TYPE_CHECK;
- if (ip->V.i < 0 || ip->V.i >= eplen(ep))
- return ERR_RANGE_CHECK;
-
- switch (eptype(ep)) {
- case T_STRING:
- if (eptype(vp) != T_INT)
- return ERR_TYPE_CHECK;
- if (vp->V.i < 0 || vp->V.i > 255)
- return ERR_RANGE_CHECK;
- str_put(current, e, ip->V.i, vp->V.i);
- decrefp(current,v,vp);
- break;
- case T_ARRAY:
- /* we should check for circular constructs! */
- array_put(current, e, ip->V.i, v);
- break;
- default:
- return ERR_TYPE_CHECK;
- }
- }
- decrefp(current, i, ip);
- decrefp(current, e, ep);
- current->osp -= 3;
-
- return OK;
- }
-
-
- retcode
- o_random()
- {
- byte k[8];
-
- if (current->osp >= MAXOSTACK)
- return ERR_OSTACK_OVERFLOW;
-
- random64(k);
- current->os[current->osp++] = key_add(k);
-
- return OK;
- }
-