Ejemplo n.º 1
0
Archivo: rpc.c Proyecto: aosm/distcc
/**
 * Transmit token name (4 characters) and value (32-bit int, as 8 hex
 * characters).
 **/
int dcc_x_token_int(int ofd, const char *token, unsigned param)
{
    char buf[13];
    int shift;
    char *p;
    const char *hex = "0123456789abcdef";

    if (strlen(token) != 4) {
        rs_log_crit("token \"%s\" seems wrong", token);
        return EXIT_PROTOCOL_ERROR;
    }
    memcpy(buf, token, 4);

    /* Quick and dirty int->hex.  The only standard way is to call snprintf
     * (?), which is undesirably slow for such a frequently-called
     * function. */
    for (shift=28, p = &buf[4];
         shift >= 0;
         shift -= 4, p++) {
        *p = hex[(param >> shift) & 0xf];
    }
    buf[12] = '\0';

    rs_trace("send %s", buf);
    return dcc_writex(ofd, buf, 12);
}
Ejemplo n.º 2
0
static int dcc_write_state(int fd)
{
    int ret;

    /* Write out as one big blob.  fd is positioned at the start of
     * the file. */

    if ((ret = dcc_writex(fd, my_state, sizeof *my_state)))
        return ret;

    return 0;
}
Ejemplo n.º 3
0
/* Write host data to host file */
static int write_hosts(struct daemon_data *d) {
    struct host *h;
    int r = 0;
    assert(d);

    rs_log_info("writing zeroconf data.\n");

    if (generic_lock(d->fd, 1, 1, 1) < 0) {
        rs_log_crit("lock failed: %s\n", strerror(errno));
        return -1;
    }

    if (lseek(d->fd, 0, SEEK_SET) < 0) {
        rs_log_crit("lseek() failed: %s\n", strerror(errno));
        return -1;
    }

    if (ftruncate(d->fd, 0) < 0) {
        rs_log_crit("ftruncate() failed: %s\n", strerror(errno));
        return -1;
    }

    remove_duplicate_services(d);

    for (h = d->hosts; h; h = h->next) {
        char t[256], a[AVAHI_ADDRESS_STR_MAX];

        if (h->resolver)
            /* Not yet fully resolved */
            continue;
	if (h->address.proto == AVAHI_PROTO_INET6)
	    snprintf(t, sizeof(t), "[%s]:%u/%i\n", avahi_address_snprint(a, sizeof(a), &h->address), h->port, d->n_slots * h->n_cpus);
	else
	    snprintf(t, sizeof(t), "%s:%u/%i\n", avahi_address_snprint(a, sizeof(a), &h->address), h->port, d->n_slots * h->n_cpus);

        if (dcc_writex(d->fd, t, strlen(t)) != 0) {
            rs_log_crit("write() failed: %s\n", strerror(errno));
            goto finish;
        }
    }

    r = 0;

finish:

    generic_lock(d->fd, 1, 0, 1);
    return r;

};
Ejemplo n.º 4
0
Archivo: rpc.c Proyecto: aosm/distcc
/**
 * Write a token, and then the string @p buf.
 *
 * The length of buf is determined by its nul delimiter, but the \0 is not sent.
 **/
int dcc_x_token_string(int fd,
                       const char *token,
                       const char *buf)
{
    int ret;
    size_t len;

    len = strlen(buf);
    if ((ret = dcc_x_token_int(fd, token, (unsigned) len)))
        return ret;
    if ((ret = dcc_writex(fd, buf, len)))
        return ret;

    return 0;
}
Ejemplo n.º 5
0
/*
 * Attempt handshake exchange with the server to indicate client's
 * desire to authentciate.
 *
 * @param to_net_sd.	Socket to write to.
 *
 * @param from_net_sd.	Socket to read from.
 *
 * Returns 0 on success, otherwise error.
 */
static int dcc_gssapi_send_handshake(int to_net_sd, int from_net_sd) {
    char auth = HANDSHAKE;
    fd_set sockets;
    int ret;
    struct timeval timeout;

    rs_log_info("Sending handshake.");

    if ((ret = dcc_writex(to_net_sd, &auth, sizeof(auth))) != 0) {
	return ret;
    }

    rs_log_info("Sent %c.", auth);

    FD_ZERO(&sockets);
    FD_SET(from_net_sd, &sockets);
    timeout.tv_sec = 1;
    timeout.tv_usec = 0;

    ret = select(from_net_sd + 1, &sockets, NULL, NULL, &timeout);

    if (ret < 0) {
        rs_log_error("select failed: %s.", strerror(errno));
        return EXIT_IO_ERROR;
    }

    if (ret == 0) {
        rs_log_error("Timeout - does this server require authentication?");
        return EXIT_TIMEOUT;
    }

    rs_log_info("Receiving handshake.");

    if ((ret = dcc_readx(from_net_sd, &auth, sizeof(auth))) != 0) {
        return ret;
    }

    rs_log_info("Received %c.", auth);

    if (auth != HANDSHAKE) {
        rs_log_crit("No server handshake.");
        return EXIT_GSSAPI_FAILED;
    }

    return 0;
}
Ejemplo n.º 6
0
/**
 * Receive @p in_len compressed bytes from @p in_fd, and write the
 * decompressed form to @p out_fd.
 *
 * There's no way for us to know how big the uncompressed form will be, and
 * there is also no way to grow the decompression buffer if it turns out to
 * initially be too small.  So we assume a ratio of 10x.  If it turns out to
 * be too small, we increase the buffer and try again.  Typical compression of
 * source or object is about 2x to 4x.  On modern Unix we should be able to
 * allocate (and not touch) many megabytes at little cost, since it will just
 * turn into an anonymous map.
 *
 * LZO doesn't have any way to decompress part of the input and then break to
 * get more output space, so our buffer needs to be big enough in the first
 * place or we would waste time repeatedly decompressing it.
 **/
int dcc_r_bulk_lzo1x(int out_fd, int in_fd,
                     unsigned in_len)
{
    int ret, lzo_ret;
    char *in_buf = NULL, *out_buf = NULL;
    size_t out_size = 0;
    lzo_uint out_len;

    /* NOTE: out_size is the buffer size, out_len is the amount of actual
     * data. */

    if (in_len == 0)
        return 0;               /* just check */

    if ((in_buf = malloc(in_len)) == NULL) {
        rs_log_error("failed to allocate decompression input");
        ret = EXIT_OUT_OF_MEMORY;
        goto out;
    }

    if ((ret = dcc_readx(in_fd, in_buf, in_len)) != 0)
        goto out;

#if 0
    /* Initial estimate for output buffer.  This is intentionally quite low to
     * exercise the resizing code -- if it works OK then we can scale this
     * up. */
    out_size = 2 * in_len;
#else
    out_size = 8 * in_len;
#endif

try_again_with_a_bigger_buffer:

    if ((out_buf = malloc(out_size)) == NULL) {
        rs_log_error("failed to allocate decompression buffer");
        ret = EXIT_OUT_OF_MEMORY;
        goto out;
    }

    out_len = out_size;
    lzo_ret = lzo1x_decompress_safe((lzo_byte*)in_buf, in_len,
                                    (lzo_byte*)out_buf, &out_len, work_mem);

    if (lzo_ret == LZO_E_OK) {
        rs_trace("decompressed %ld bytes to %ld bytes: %d%%",
                 (long) in_len, (long) out_len,
                 (int) (out_len ? 100*in_len / out_len : 0));

        ret = dcc_writex(out_fd, out_buf, out_len);

        goto out;
    } else if (lzo_ret == LZO_E_OUTPUT_OVERRUN) {
        free(out_buf);
        out_buf = 0;
        out_size *= 2;
        /* FIXME: Make sure this doesn't overflow memory size? */
        rs_trace("LZO_E_OUTPUT_OVERRUN, trying again with %lu byte buffer",
                 (unsigned long) out_size);
        goto try_again_with_a_bigger_buffer;
    } else {
        rs_log_error("LZO1X1 decompression failed: %d", lzo_ret);
        ret = EXIT_IO_ERROR;
        goto out;
    }

out:
    free(in_buf);
    free(out_buf);

    return ret;
}