示例#1
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() */
示例#2
0
文件: pkg-tls.c 项目: Fuchur/ldmud
/*-------------------------------------------------------------------------*/
int
tls_continue_handshake (interactive_t *ip)

/* Continue the TLS initialisation handshake for interactive <ip>.
 * Return a negative error code if the connection can not be set up.
 * Return 0 if the connection is still begin set up.
 * Return 1 if the connection is now active (or if no secure connection
 * had been requested).
 *
 * If a callback is set for <ip> and connection comes out of the handshaking
 * state, it will be called with the result code.
 */

{
    int ret;

    if (ip->tls_status != TLS_HANDSHAKING)
        return 1;

    ret = tls_do_handshake(ip);
    if (!ret)
	return 0;


    if (ret < 0)
    {
        ip->tls_status = TLS_INACTIVE;
    }
    else
    {
        ip->tls_status = TLS_ACTIVE;
    }

    /* If the connection is no longer in handshake, execute the callback */
    if (ip->tls_cb != NULL)
    {
        tls_cb_handler_t * handler;

        xallocate( handler, sizeof(*handler)
                 , "TLS: Callback handler protector");
        handler->cb = ip->tls_cb;
        ip->tls_cb = NULL;
            /* Protect the callback during its execution. */

        push_error_handler (handle_tls_cb_error, &(handler->head));

        push_number(inter_sp, ret < 0 ? ret : 0);
        push_ref_object(inter_sp, ip->ob, "tls_handshake");

        command_giver = ip->ob;
        current_interactive = ip->ob;
        /* Set current_interactive as it would be for a normal logon() call. */

        (void)apply_callback(handler->cb, 2);

        if (!(ip->ob->flags & O_DESTRUCTED))
            print_prompt();

        command_giver = NULL;

        free_svalue(inter_sp); inter_sp--; /* free the callback */
    }

    return ret;
} /* tls_continue_handshake() */
示例#3
0
svalue_t *
f_convert_charset (svalue_t *sp)

/* EFUN convert_charset()
 *
 *   string convert_charset(string str, string from_cs, string to_cs)
 *
 * Convert the string <str> from charset <from_cs> to charset <to_cs>
 * and return the converted string.
 *
 * The efun is only available on systems with libiconv.
 */

{
    iconv_t context;
    
    string_t *from_cs, *to_cs, *in_str, *out_str;

#if HAS_ICONV_NONCONST_IN
#   define ICONV_IN_CAST (char**)
#else
#   define ICONV_IN_CAST
#endif

    const char *pIn; /* Input string pointer */
    size_t in_len;   /* Input length */
    size_t in_left;  /* Input length left */

    char * out_buf;  /* Output buffer */
    size_t out_size; /* Size of the output buffer */
    size_t out_left; /* Size left in output buffer */
    char  *pOut;     /* Output string pointer */

    in_str = sp[-2].u.str;
    from_cs = sp[-1].u.str;
    to_cs = sp->u.str;

    pIn = get_txt(in_str);
    in_len = mstrsize(in_str);
    in_left = in_len;

    /* If the input string is empty, we can return immediately
     * (and in fact must since the allocator will balk at allocating 0 bytes)
     */
    if (!in_len)
    {
        sp -= 2;
        free_string_svalue(sp);
        free_string_svalue(sp+1);
        put_string(sp, sp[2].u.str);

        return sp;
    }

    /* Allocate a temporary output string */
    out_size = in_len > 65536 ? (in_len + 33) : (2 * in_len);
    out_left = out_size;

    xallocate(out_buf, out_size, "iconv buffer");
    pOut = out_buf;

    /* Open the iconv context */
    context = iconv_open(get_txt(to_cs), get_txt(from_cs));
    if (context == (iconv_t) -1)
    {
        xfree(out_buf);

        if (errno == EINVAL)
            errorf("convert_charset(): Conversion '%s' -> '%s' not supported.\n"
                 , get_txt(from_cs), get_txt(to_cs)
                );
        else
            errorf("convert_charset(): Error %d.\n", errno);
        /* NOTREACHED */
        return sp;
    }

    /* Convert the string, reallocating the output buffer where necessary */
    while (in_left)
    {
        size_t rc;

        rc = iconv(context, ICONV_IN_CAST &pIn, &in_left, &pOut, &out_left);
        if (rc == (size_t)-1)
        {
            if (errno == E2BIG)
            {
                /* Reallocate output buffer */
                size_t newsize;
                char * tmp;

                newsize = out_size + (in_len > 128 ? in_len : 128);
                tmp = rexalloc(out_buf, newsize);
                if (!tmp)
                {
                    iconv_close(context);
                    xfree(out_buf);
                    outofmem(newsize, "iconv buffer");
                    /* NOTREACHED */
                    return sp;
                }
                out_buf = tmp;
                pOut = out_buf + out_size;
                out_left = newsize - out_size;
                out_size = newsize;

                continue;
            }

            /* Other error: clean up */
            iconv_close(context);
            xfree(out_buf);

            if (errno == EILSEQ)
            {
                errorf("convert_charset(): Invalid character sequence at "
                       "index %td\n", 
                       (ptrdiff_t)(pIn - get_txt(in_str)));
                /* NOTREACHED */
                return sp;
            }

            if (errno == EINVAL)
            {
                errorf("convert_charset(): Incomplete character sequence at "
                       "index %td\n", (ptrdiff_t)(pIn - get_txt(in_str)));
                /* NOTREACHED */
                return sp;
            }

            errorf("convert_charset(): Error %d at index %td\n"
                 , errno, (ptrdiff_t)(pIn - get_txt(in_str))
                 );
            /* NOTREACHED */
            return sp;
        } /* if (rc < 0) */
    } /* while (in_left) */

    /* While the actual conversion is complete, the output stream may now
     * be in a non-base state. Add the necessary epilogue to get back
     * to the base state.
     */
    while(1)
    {
        size_t rc;
        rc = iconv(context, NULL, NULL, &pOut, &out_left);
        if (rc == (size_t)-1)
        {
            if (errno == E2BIG)
            {
                /* Reallocate output buffer */
                size_t newsize;
                char * tmp;

                newsize = out_size + (in_len > 128 ? in_len : 128);
                tmp = rexalloc(out_buf, newsize);
                if (!tmp)
                {
                    iconv_close(context);
                    xfree(out_buf);
                    outofmem(newsize, "iconv buffer");
                    /* NOTREACHED */
                    return sp;
                }
                out_buf = tmp;
                pOut = out_buf + out_size;
                out_left = newsize - out_size;
                out_size = newsize;

                continue;
            }

            /* Other error: clean up */
            iconv_close(context);
            xfree(out_buf);

            if (errno == EILSEQ)
            {
                errorf("convert_charset(): Invalid character sequence at "
                       "index %td\n", (ptrdiff_t)(pIn - get_txt(in_str)));
                /* NOTREACHED */
                return sp;
            }

            if (errno == EINVAL)
            {
                errorf("convert_charset(): Incomplete character sequence at "
                       "index %td\n", (ptrdiff_t)(pIn - get_txt(in_str)));
                /* NOTREACHED */
                return sp;
            }

            errorf("convert_charset(): Error %d at index %td\n"
                 , errno, (ptrdiff_t)(pIn - get_txt(in_str))
                 );
            /* NOTREACHED */
            return sp;
        } /* if (rc < 0) */

        /* At this point, the iconv() succeeded: we're done */
        break;
    } /* while(1) */
    
    iconv_close(context);

    /* Get the return string and prepare the return arguments */
    out_str = new_n_mstring(out_buf, out_size - out_left);
    xfree(out_buf);
    if (!out_str)
    {
        outofmem(out_size - out_left, "convert_charset() result");
        /* NOTREACHED */
        return sp;
    }

    free_string_svalue(sp--);
    free_string_svalue(sp--);
    free_string_svalue(sp);
    put_string(sp, out_str);
    
    return sp;
} /* f_convert_charset() */