Exemple #1
0
/*--------------------------------------------------------------------*/
static INLINE size_t
strbuf_grow (strbuf_t *buf, size_t len)

/* Extend the stringbuffer <buf> to hold at least <len> more
 * bytes (ie. enough for a string of length <len>-1).
 *
 * Return <len> if all memory could be allocated, or a lower number
 * of only part of the required memory is available.
 *
 * N.B.: be careful with overflows when doing the checks.
 */

{
    size_t new_len;

    /* Catch some simple situations. */
    if (buf->alloc_len >= MAX_STRBUF_LEN)
        return 0;  /* Truncated */

    if (buf->alloc_len - buf->length > len)
        return len;

    /* Allocate more than we need in anticipation of further adds,
     * but not more than we can manage
     */
    if (MAX_STRBUF_LEN - buf->length < len * 3)
    {
        new_len = MAX_STRBUF_LEN;
        if (new_len - buf->length < len)
            len = new_len - buf->length;
    }
    else
        new_len = buf->length + len * 3;


    /* Is this the first allocation? */
    if (!buf->buf)
    {
        memsafe(buf->buf = xalloc(new_len), new_len, "new strbuf");
        buf->alloc_len = (u_long)new_len;
        buf->length = 0;
        *(buf->buf) = '\0';
        return len;
    }

    /* Extension of the existing buffer */

    memsafe(buf->buf = rexalloc(buf->buf, new_len), new_len, "larger strbuf");
    buf->alloc_len = (u_long)new_len;
    return len;
} /* strbuf_grow() */
Exemple #2
0
/*-------------------------------------------------------------------------*/
svalue_t *
f_tls_error(svalue_t *sp)

/* EFUN tls_error()
 *
 *     string tls_error(int errorno)
 *
 * tls_error() returns a string describing the error behind the
 * error number <errorno>.
 */

{
    string_t *s;
    const char *text;
    int err = sp->u.number;

    text = tls_error(err);

    if (text)
    {
        memsafe(s = new_mstring(text), strlen(text), "tls_error()");
        free_svalue(sp);
        put_string(sp, s);
    }
    else
    {
        free_svalue(sp);
        put_number(sp, 0);
    }

    return sp;
} /* f_tls_error() */
Exemple #3
0
/*-------------------------------------------------------------------------*/
svalue_t *
enhance_arraylist (svalue_t * list)

/* Add an element to the arraylist to <list>.
 * It is the responsibility of the caller to ensure
 * that <list> is in fact an arraylist.
 */
{
    arraylist_t * data = (arraylist_t *) list->u.lvalue;
    arraylist_element_t * element;

    memsafe(element = xalloc(sizeof(*element)), sizeof(*element), "arraylist element");
    element->next = NULL;
    put_number(&(element->value), 0);

    if (data->last == NULL)
    {
        data->first = element;
        data->last = element;
    }
    else
    {
        data->last->next = element;
        data->last = element;
    }
    data->num++;

    return &(element->value);

} /* enhance_arraylist() */
Exemple #4
0
/*-------------------------------------------------------------------------*/
string_t *
trim_all_spaces (const string_t * txt)

/* Trim the input string <txt> by removing all leading and trailing
 * space, and by folding embedded space runs into just one each.
 * Return the new string with one ref; the refcount of <txt> is not changed.
 *
 * Throw an error when out of memory.
 */

{
    char * dest;
    const char * src;
    size_t dest_ix, src_ix, srclen;
    string_t * rc;

    dest = alloca(mstrsize(txt));
    if (dest == NULL)
        errorf("Stack overflow (%zu bytes)\n", mstrsize(txt));

    src = get_txt((string_t *const)txt);
    srclen = mstrsize(txt);
    src_ix = 0;
    dest_ix = 0;

    /* Blank out trailing spaces */
    while (srclen > 0 && src[srclen-1] == ' ')
        srclen--;

    /* Skip leading spaces */
    while (src_ix < srclen && *src == ' ')
        src_ix++, src++;

    /* Copy characters, but fold embedded spaces. */
    for ( ; src_ix < srclen; src_ix++, src++, dest_ix++)
    {
        dest[dest_ix] = *src;

        /* If this and the next character is a space, forward
         * src until the last space in this run.
         */
        if (' ' == *src)
        {
            while (src_ix+1 < srclen && ' ' == src[1])
                src_ix++, src++;
        }
    }

    memsafe(rc = new_n_mstring(dest, dest_ix), dest_ix, "trimmed result");
    return rc;
} /* trim_all_spaces() */
Exemple #5
0
/*-------------------------------------------------------------------------*/
void
put_arraylist (svalue_t * list)

/* Create an arraylist and put it into <list>.
 */
{
    arraylist_t * data;

    memsafe(data = xalloc(sizeof(*data)), sizeof(*data), "arraylist");

    data->head.fun = cleanup_arraylist;
    data->num = 0;
    data->first = NULL;
    data->last = NULL;

    list->type = T_ERROR_HANDLER;
    list->u.error_handler = &(data->head);
} /* put_arraylist() */
Exemple #6
0
/*-------------------------------------------------------------------------*/
svalue_t *
v_tls_init_connection (svalue_t *sp, int num_arg)

/* EFUN tls_init_connection()
 *
 *   int tls_init_connection(object ob)
 *   int tls_init_connection(object ob, string fun, string|object fob, mixed extra...)
 *   int tls_init_connection(object ob, closure fun, mixed extra...)
 *
 * tls_init_connection() tries to start a TLS secured connection to the
 * interactive object <ob> (or this_object() if <ob> is not given).
 * Result:
 *   errorcode < 0: unsuccessful, use tls_error() to get an useful
 *                  description of the error
 *      number > 0: the secure connection is still being set up in the
 *                   background
 *     number == 0: the secure connection is active.
 *
 * If the callback <fun>/<fun>:<fob> is specified, it will be called once
 * the fate of the secure connection has been determined. The first argument
 * will be the return code from the handshake (errorcode < 0 on failure,
 * or 0 on success), followed by the interactive object <ob> and any <extra>
 * arguments.
 */

{
    svalue_t * argp = sp - num_arg + 1;
    long ret;
    object_t * obj;
    interactive_t *ip;

    if (!tls_available())
        errorf("tls_init_connection(): TLS layer hasn't been initialized.\n");

    if (num_arg > 0)
    {
        obj = argp->u.ob;
        put_number(argp, 0); /* remove obj reference from the stack */
    }
    else
    {
        obj = ref_object(current_object, "tls_init_connection");
    }

    if (!O_SET_INTERACTIVE(ip, obj))
    {
        free_object(obj, "tls_init_connection");
        errorf("Bad arg 1 to tls_init_connection(): "
              "object not interactive.\n");
    }

    free_object(obj, "tls_init_connection");
      /* ip has another reference to obj, so this is safe to do */

    if (ip->tls_status != TLS_INACTIVE)
        errorf("tls_init_connection(): Interactive already has a secure "
              "connection.\n");

    /* Extract the callback information from the stack */
    if (num_arg > 1)
    {
        /* Extract the callback information from the stack */
        int error_index;
        callback_t * cb;

        inter_sp = sp;

        memsafe(cb = xalloc(sizeof *cb) , sizeof *cb , "callback structure");

        assign_eval_cost();

        error_index = setup_efun_callback(cb, argp+1, num_arg-1);

        if (error_index >= 0)
        {
            /* The callback values have already been removed. */
            
            xfree(cb);
            inter_sp = sp = argp;
            vefun_bad_arg(error_index+2, argp);
            /* NOTREACHED */
            return argp;
        }

        /* Callback creation successful */
        ip->tls_cb = cb;

    }

    inter_sp = sp = argp - 1;

    /* Flush the connection */

    {
        object_t * save_c_g = command_giver;
        command_giver = obj;
        add_message(message_flush);
        command_giver = save_c_g;
    }

    ret = tls_init_connection(ip);
    if (ret >= 0)
    {
        ip->tls_status = TLS_HANDSHAKING;
        ret = tls_continue_handshake(ip);

        /* Adjust the return value of tls_continue_handshake() */
        if (ret >= 0)
            ret = !ret;
    }

    push_number(sp, ret);
    return sp;
} /* f_tls_init_connection() */
Exemple #7
0
/*--------------------------------------------------------------------*/
string_t *
intersect_strings (const string_t * p_left, const string_t * p_right, Bool bSubtract)

/* !bSubtract: Intersect string <left> with string <right> and return
 *   a newly allocated string with all those characters which are in
 *   both strings.
 * bSubtract:  Subtract string <right> from string <left> and return
 *   a newly allocated string with all those characters which are in
 *   <left> but not in <right>.
 * The order of the characters returned is their order of appearance
 * in <left>.
 */

{
    size_t   len_left, len_right, len_out;
    size_t   ix_left, ix_right;
    long   * pos;
    CBool  * matches;
    const char * left_txt;
    char * left, * right, * result_txt;
    string_t *result;

    len_left = mstrsize(p_left);
    len_right = mstrsize(p_right);

    xallocate(matches, len_left+1, "intersection matches");
      /* +1 so that smalloc won't complain when given an empty left string */

    for (ix_left = 0; ix_left < len_left; ix_left++)
        matches[ix_left] = bSubtract ? MY_TRUE : MY_FALSE;

    /* Sort the two strings */
    left = sort_string(p_left, len_left, &pos);
    right = sort_string(p_right, len_right, NULL);

    /* Intersect the two strings by mutual comparison.
     * Each non-matched character in left gets is pos[] set to -1.
     */
    len_out = bSubtract ? len_left : 0;
    for ( ix_left = 0, ix_right = 0
        ; ix_left < len_left && ix_right < len_right
        ; )
    {
        if (left[ix_left] < right[ix_right])
            ix_left++;
        else if (left[ix_left] > right[ix_right])
            ix_right++;
        else /* left[ix_left] == right[ix_right]) */
        {
            if (!bSubtract)
            {
                matches[pos[ix_left]] = MY_TRUE;
                len_out++;
            }
            else
            {
                matches[pos[ix_left]] = MY_FALSE;
                len_out--;
            }
            ix_left++;
        }
    }

    /* Create the result: copy all flagged characters */
    memsafe(result = alloc_mstring(len_out), len_out, "intersection result");
    left_txt = get_txt((string_t *const)p_left);
    result_txt = get_txt(result);
    for (ix_left = 0, ix_right = 0; ix_left < len_left; ix_left++)
        if (matches[ix_left])
            result_txt[ix_right++] = left_txt[ix_left];

    /* Free intermediate results */
    xfree(pos);
    xfree(matches);
    xfree(left);
    xfree(right);

    return result;
} /* intersect_strings() */
Exemple #8
0
svalue_t *
f_psyc_render(svalue_t *sp) {
    uint8_t i;
    vector_t *v;
    string_t *out;
    char *meth, *body;
    size_t mlen, blen;
    mapping_t *map;

    psycPacket packet;
    psycHeader headers[2];

    // unless (sp->type == T_POINTER) return sp;
    v = sp->u.vec;
    if (VEC_SIZE(v) == PACKET_BODY + 1) {
	for (i = PACKET_ROUTING; i <= PACKET_ENTITY; i++) {
	    headers[i].lines = 0;
	    if (v->item[i].type == T_MAPPING) {
		map = v->item[i].u.map;
		if (!MAP_SIZE(map)) continue;

		headers[i].modifiers = malloc(sizeof(psycModifier) * MAP_SIZE(v->item[i].u.map));
		if (!headers[i].modifiers) {
		    errorf("Out of memory in psyc_render for modifier table.\n");
		    return sp; // not reached
		}

		walk_mapping(map, &fill_header_from_mapping,
		             &(psyc_modifier_t) {
		                 &headers[i], map->num_values,
		                 i == PACKET_ROUTING ?
		                     PSYC_MODIFIER_ROUTING :
		                     PSYC_MODIFIER_CHECK_LENGTH
		             });
	    }
	    // else ... ignoring possibly invalid args
	}
    } else {
	errorf("Wrong number of elements (%" PRIdMPINT ") "
	       "in array argument to psyc_render()\n", VEC_SIZE(v));
	return sp; // not reached
    }

    if (v->item[PACKET_METHOD].type == T_STRING) {
	meth = get_txt(v->item[PACKET_METHOD].u.str);
	mlen = mstrsize(v->item[PACKET_METHOD].u.str);
    } else {
	meth = NULL;
	mlen = 0;
    }

    if (v->item[PACKET_BODY].type == T_STRING) {
	body = get_txt(v->item[PACKET_BODY].u.str);
	blen = mstrsize(v->item[PACKET_BODY].u.str);
    } else {
	body = NULL;
	blen = 0;
    }

    packet = psyc_newPacket2(headers[PACKET_ROUTING].modifiers,
                             headers[PACKET_ROUTING].lines,
                             headers[PACKET_ENTITY].modifiers,
                             headers[PACKET_ENTITY].lines,
                             meth, mlen, body, blen,
                             PSYC_PACKET_CHECK_LENGTH);

#ifdef DEBUG
    printf("rendering... packet.length = %ld\n", packet.length);
#endif
    // alloc_mstring creates an *untabled* string suitable for tmp data 
    memsafe(out = alloc_mstring(packet.length), packet.length, "f_psyc_render");
    psyc_render(&packet, get_txt(out), packet.length);

    free_svalue(sp);
    put_string(sp, out);
    // stack should take care of freeing the string after use
    return sp;

} /* f_psyc_render */