예제 #1
0
파일: cli_if.c 프로젝트: Koushien/btpd
static void
cli_read_cb(int sd, short type, void *arg)
{
    struct cli *cli = arg;
    uint32_t cmdlen;
    uint8_t *msg = NULL;

    if (read_fully(sd, &cmdlen, sizeof(cmdlen)) != 0)
        goto error;

    msg = btpd_malloc(cmdlen);
    if (read_fully(sd, msg, cmdlen) != 0)
        goto error;

    if (!(benc_validate(msg, cmdlen) == 0 && benc_islst(msg) &&
            benc_first(msg) != NULL && benc_isstr(benc_first(msg))))
        goto error;

    if (cmd_dispatch(cli, msg) != 0)
        goto error;

    free(msg);
    return;

error:
    btpd_ev_del(&cli->read);
    close(cli->sd);
    free(cli);
    if (msg != NULL)
        free(msg);
}
예제 #2
0
파일: entropy.c 프로젝트: David-B55/ovs
/* Initializes 'buffer' with 'n' bytes of high-quality random numbers.  Returns
 * 0 if successful, otherwise a positive errno value or EOF on error. */
int
get_entropy(void *buffer, size_t n)
{
#ifndef _WIN32
    size_t bytes_read;
    int error;
    int fd;

    fd = open(urandom, O_RDONLY);
    if (fd < 0) {
        VLOG_ERR("%s: open failed (%s)", urandom, ovs_strerror(errno));
        return errno ? errno : EINVAL;
    }

    error = read_fully(fd, buffer, n, &bytes_read);
    close(fd);

    if (error) {
        VLOG_ERR("%s: read error (%s)", urandom, ovs_retval_to_string(error));
    }
#else
    int error = 0;
    HCRYPTPROV   crypt_prov = 0;

    CryptAcquireContext(&crypt_prov, NULL, NULL,
                        PROV_RSA_FULL, CRYPT_VERIFYCONTEXT);
    if (!CryptGenRandom(crypt_prov, n, buffer)) {
        VLOG_ERR("CryptGenRandom: read error (%s)", ovs_lasterror_to_string());
        error = EINVAL;
    }

    CryptReleaseContext(crypt_prov, 0);
#endif
    return error;
}
예제 #3
0
파일: process.c 프로젝트: InCNTRE/OFTT
static void
stream_read(struct stream *s)
{
    if (s->fds[0] < 0) {
        return;
    }

    for (;;) {
        char buffer[512];
        int error;
        size_t n;

        error = read_fully(s->fds[0], buffer, sizeof buffer, &n);
        ds_put_buffer(&s->log, buffer, n);
        if (error) {
            if (error == EAGAIN || error == EWOULDBLOCK) {
                return;
            } else {
                if (error != EOF) {
                    VLOG_WARN("error reading subprocess pipe: %s",
                              strerror(error));
                }
                break;
            }
        } else if (s->log.length > PROCESS_MAX_CAPTURE) {
            VLOG_WARN("subprocess output overflowed %d-byte buffer",
                      PROCESS_MAX_CAPTURE);
            break;
        }
    }
    close(s->fds[0]);
    s->fds[0] = -1;
}
예제 #4
0
static void
read_and_push(
    XferElementGlue *self)
{
    XferElement *elt = XFER_ELEMENT(self);
    int fd = get_read_fd(self);
    XMsg *msg;

    crc32_init(&elt->crc);

    while (!elt->cancelled) {
	char *buf = g_malloc(GLUE_BUFFER_SIZE);
	gsize len;
	int read_error;

	/* read a buffer from upstream */
	len = read_fully(fd, buf, GLUE_BUFFER_SIZE, &read_error);
	if (len < GLUE_BUFFER_SIZE) {
	    if (read_error) {
		if (!elt->cancelled) {
		    xfer_cancel_with_error(elt,
			_("Error reading from fd %d: %s"), fd, strerror(read_error));
		    g_debug("element-glue: error reading from fd %d: %s",
                         fd, strerror(read_error));
		    wait_until_xfer_cancelled(elt->xfer);
		}
                amfree(buf);
		break;
	    } else if (len == 0) { /* we only count a zero-length read as EOF */
		amfree(buf);
		break;
	    }
	}
	crc32_add((uint8_t *)buf, len, &elt->crc);

	xfer_element_push_buffer(elt->downstream, buf, len);
    }

    if (elt->cancelled && elt->expect_eof)
	xfer_element_drain_fd(fd);

    /* send an EOF indication downstream */
    xfer_element_push_buffer(elt->downstream, NULL, 0);

    /* close the read fd, since it's at EOF */
    close_read_fd(self);

    g_debug("sending XMSG_CRC message");
    g_debug("read_and_push CRC: %08x      size %lld",
	    crc32_finish(&elt->crc), (long long)elt->crc.size);
    msg = xmsg_new(elt->upstream, XMSG_CRC, 0);
    msg->crc = crc32_finish(&elt->crc);
    msg->size = elt->crc.size;
    xfer_queue_message(elt->xfer, msg);
}
예제 #5
0
/* Forks, then:
 *
 *   - In the parent, waits for the child to signal that it has completed its
 *     startup sequence.  Then stores -1 in '*fdp' and returns the child's
 *     pid in '*child_pid' argument.
 *
 *   - In the child, stores a fd in '*fdp' and returns 0 through '*child_pid'
 *     argument.  The caller should pass the fd to fork_notify_startup() after
 *     it finishes its startup sequence.
 *
 * Returns 0 on success.  If something goes wrong and child process was not
 * able to signal its readiness by calling fork_notify_startup(), then this
 * function returns -1. However, even in case of failure it still sets child
 * process id in '*child_pid'. */
static int
fork_and_wait_for_startup(int *fdp, pid_t *child_pid)
{
    int fds[2];
    pid_t pid;
    int ret = 0;

    xpipe(fds);

    pid = fork_and_clean_up();
    if (pid > 0) {
        /* Running in parent process. */
        size_t bytes_read;
        char c;

        close(fds[1]);
        if (read_fully(fds[0], &c, 1, &bytes_read) != 0) {
            int retval;
            int status;

            do {
                retval = waitpid(pid, &status, 0);
            } while (retval == -1 && errno == EINTR);

            if (retval == pid) {
                if (WIFEXITED(status) && WEXITSTATUS(status)) {
                    /* Child exited with an error.  Convey the same error
                     * to our parent process as a courtesy. */
                    exit(WEXITSTATUS(status));
                } else {
                    char *status_msg = process_status_msg(status);
                    //VLOG_ERR("fork child died before signaling startup (%s)",
                    //         status_msg);
                    printf("fork child died before signaling startup (%s)",
                             status_msg);
                    ret = -1;
                }
            } else if (retval < 0) {
                //VLOG_FATAL("waitpid failed (%s)", ovs_strerror(errno));
                printf("waitpid failed (%d)", errno);
            } else {
                abort();
            }
        }
        close(fds[0]);
        *fdp = -1;
    } else if (!pid) {
        /* Running in child process. */
        close(fds[0]);
        *fdp = fds[1];
    }
    *child_pid = pid;
    return ret;
}
예제 #6
0
static pid_t
fork_and_wait_for_startup(int *fdp)
{
    int fds[2];
    pid_t pid;

    xpipe(fds);

    pid = fork();
    if (pid > 0) {
        /* Running in parent process. */
        size_t bytes_read;
        char c;

        close(fds[1]);
        fatal_signal_fork();
        if (read_fully(fds[0], &c, 1, &bytes_read) != 0) {
            int retval;
            int status;

            do {
                retval = waitpid(pid, &status, 0);
            } while (retval == -1 && errno == EINTR);

            if (retval == pid
                && WIFEXITED(status)
                && WEXITSTATUS(status)) {
                /* Child exited with an error.  Convey the same error to
                 * our parent process as a courtesy. */
                exit(WEXITSTATUS(status));
            }

            VLOG_FATAL("fork child failed to signal startup (%s)",
                       strerror(errno));
        }
        close(fds[0]);
        *fdp = -1;
    } else if (!pid) {
        /* Running in child process. */
        close(fds[0]);
        time_postfork();
        lockfile_postfork();
        *fdp = fds[1];
    } else {
        VLOG_FATAL("fork failed (%s)", strerror(errno));
    }

    return pid;
}
예제 #7
0
/* Initializes 'buffer' with 'n' bytes of high-quality random numbers.  Returns
 * 0 if successful, otherwise a positive errno value or EOF on error. */
int
get_entropy(void *buffer, size_t n)
{
#ifndef _WIN32
    size_t bytes_read;
    int error;
    int fd;

    fd = open(urandom, O_RDONLY);
    if (fd < 0) {
        VLOG_ERR("%s: open failed (%s)", urandom, ovs_strerror(errno));
        return errno ? errno : EINVAL;
    }

    error = read_fully(fd, buffer, n, &bytes_read);
    close(fd);

    if (error) {
        VLOG_ERR("%s: read error (%s)", urandom, ovs_retval_to_string(error));
    }
#else
    int error = 0;
    HCRYPTPROV   crypt_prov = 0;
    LPVOID msg_buf;

    CryptAcquireContext(&crypt_prov, NULL, NULL,
                        PROV_RSA_FULL, CRYPT_VERIFYCONTEXT);
    if (!CryptGenRandom(crypt_prov, n, buffer)) {
        error = EINVAL;
        FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER
                      | FORMAT_MESSAGE_FROM_SYSTEM
                      | FORMAT_MESSAGE_IGNORE_INSERTS,
                      NULL,
                      GetLastError(),
                      0,
                      (LPTSTR)&msg_buf,
                      0,
                      NULL
            );
        VLOG_ERR("CryptGenRandom: read error (%s)", msg_buf);
        LocalFree(msg_buf);
    }

    CryptReleaseContext(crypt_prov, 0);
#endif
    return error;
}
예제 #8
0
파일: holding.c 프로젝트: code-mx/amanda
void
holding_set_from_driver(
    char    *holding_file,
    off_t    orig_size,
    crc_t    native_crc,
    crc_t    client_crc,
    crc_t    server_crc)
{
    int         fd;
    size_t      buflen;
    char        buffer[DISK_BLOCK_BYTES];
    char       *read_buffer;
    dumpfile_t  file;

    if((fd = robust_open(holding_file, O_RDWR, 0)) == -1) {
	dbprintf(_("holding_set_origsize: open of %s failed: %s\n"),
		 holding_file, strerror(errno));
	return;
    }

    buflen = read_fully(fd, buffer, sizeof(buffer), NULL);
    if (buflen <= 0) {
	dbprintf(_("holding_set_origsize: %s: empty file?\n"), holding_file);
	close(fd);
	return;
    }
    parse_file_header(buffer, &file, (size_t)buflen);
    lseek(fd, (off_t)0, SEEK_SET);
    file.orig_size = orig_size;
    file.native_crc = native_crc;
    file.client_crc = client_crc;
    file.server_crc = server_crc;
    read_buffer = build_header(&file, NULL, DISK_BLOCK_BYTES);
    full_write(fd, read_buffer, DISK_BLOCK_BYTES);
    dumpfile_free_data(&file);
    amfree(read_buffer);
    close(fd);
}
예제 #9
0
파일: holding.c 프로젝트: code-mx/amanda
int
holding_file_get_dumpfile(
    char *	fname,
    dumpfile_t *file)
{
    char buffer[DISK_BLOCK_BYTES];
    int fd;

    memset(buffer, 0, sizeof(buffer));

    fh_init(file);
    file->type = F_UNKNOWN;
    if((fd = robust_open(fname, O_RDONLY, 0)) == -1)
        return 0;

    if(read_fully(fd, buffer, sizeof(buffer), NULL) != sizeof(buffer)) {
        aclose(fd);
        return 0;
    }
    aclose(fd);

    parse_file_header(buffer, file, sizeof(buffer));
    return 1;
}
예제 #10
0
int process_ihexfile(const char *ihexfile, struct record **rec_p)
{
	int fd;
	int rc;
	int i;
	int len;
	uint8_t *ptr;
	uint8_t c;
	uint8_t ih_count;
	uint16_t ih_address;
	uint8_t ih_type;
	uint8_t ih_data[256];
	uint8_t ih_checksum;
	uint32_t ip = 0;
	struct record *rec;

	fd = open(ihexfile, O_RDONLY);
	if (fd < 0) {
		fprintf(stderr, "process_ihexfile: open failed (%s) :%s\n", ihexfile, strerror(errno));
		return -1;
	}

	while (1) {
 		ptr = io_buffer;
		len = read_fully(fd, ptr, 1);
		if (len < 0)
			goto read_error;
		else if (len == 0)
			break;

		c = *(ptr++);
		if (c == '\n')
			continue;
		else if (c == '\r')
			continue;
		if (c != ':')
			goto data_error;

 		ptr = io_buffer;
		len = read_fully(fd, ptr, 8);
		if (len < 0)
			goto read_error;
		else if (len == 0)
			goto data_error;

		if (hex2(&ptr, &ih_count) < 0)
			goto data_error;
		if (hex4(&ptr, &ih_address) < 0)
			goto data_error;
		if (hex2(&ptr, &ih_type) < 0)
			goto data_error;

		if (ih_count > 0) {
			ptr = io_buffer;
			len = read_fully(fd, ptr, (ih_count * 2));
			if (len < 0)
				goto read_error;
			else if (len == 0)
				goto data_error;

			for (i = 0; i < ih_count; i++) {
				if (hex2(&ptr, &ih_data[i]) < 0)
					goto data_error;
			}
		}

 		ptr = io_buffer;
		len = read_fully(fd, ptr, 2);
		if (len < 0)
			goto read_error;
		else if (len == 0)
			goto data_error;

		if (hex2(&ptr, &ih_checksum) < 0)
			goto data_error;

		if (ih_type == 0x00) {
			rec = malloc(sizeof(struct record) + (sizeof(uint8_t) * ih_count));
			if (rec == NULL)
				goto memory_error;
			rec->next = NULL;
			rec->count = ih_count;
			rec->address = ip + ih_address;
			memcpy(rec->data, ih_data, ih_count);
			*(rec_p) = rec;
			rec_p = &rec->next;
		} else if (ih_type == 0x02) {
			ip = (((ih_data[0] << 8) | (ih_data[1] << 0)) << 4);
		} else if (ih_type == 0x04) {
			ip = (((ih_data[0] << 8) | (ih_data[1] << 0)) << 16);
		}
	}
	rc = 0;
	goto close;

memory_error:
	fprintf(stderr, "process_ihexfile: memory error\n");
	rc = -1;
	goto close;
read_error:
	fprintf(stderr, "process_ihexfile: read error\n");
	rc = -1;
	goto close;
data_error:
	fprintf(stderr, "process_ihexfile: data error\n");
	rc = -1;
	goto close;

close:
	if (close(fd) < 0) {
		fprintf(stderr, "process_ihexfile: close failed %s\n", strerror(errno));
		return -1;
	}

	return rc;
}
예제 #11
0
static void
read_and_write(XferElementGlue *self)
{
    XferElement *elt = XFER_ELEMENT(self);
    /* dynamically allocate a buffer, in case this thread has
     * a limited amount of stack allocated */
    char *buf = g_malloc(GLUE_BUFFER_SIZE);
    int rfd = get_read_fd(self);
    int wfd = get_write_fd(self);
    XMsg *msg;
    crc32_init(&elt->crc);

    g_debug("read_and_write: read from %d, write to %d", rfd, wfd);
    while (!elt->cancelled) {
	size_t len;

	/* read from upstream */
	len = read_fully(rfd, buf, GLUE_BUFFER_SIZE, NULL);
	if (len < GLUE_BUFFER_SIZE) {
	    if (errno) {
		if (!elt->cancelled) {
		    xfer_cancel_with_error(elt,
			_("Error reading from fd %d: %s"), rfd, strerror(errno));
		    wait_until_xfer_cancelled(elt->xfer);
		}
		break;
	    } else if (len == 0) { /* we only count a zero-length read as EOF */
		break;
	    }
	}

	/* write the buffer fully */
	if (!elt->downstream->drain_mode && full_write(wfd, buf, len) < len) {
	    if (elt->downstream->must_drain) {
		g_debug("Could not write to fd %d: %s",  wfd, strerror(errno));
	    } else if (elt->downstream->ignore_broken_pipe && errno == EPIPE) {
	    } else {
		if (!elt->cancelled) {
		    xfer_cancel_with_error(elt,
			_("Could not write to fd %d: %s"),
			wfd, strerror(errno));
		    wait_until_xfer_cancelled(elt->xfer);
		}
		break;
	    }
	}
	crc32_add((uint8_t *)buf, len, &elt->crc);
    }

    if (elt->cancelled && elt->expect_eof)
	xfer_element_drain_fd(rfd);

    /* close the read fd.  If it's not at EOF, then upstream will get EPIPE, which will hopefully
     * kill it and complete the cancellation */
    close_read_fd(self);

    /* close the fd we've been writing, as an EOF signal to downstream */
    close_write_fd(self);

    g_debug("read_and_write upstream CRC: %08x      size %lld",
	    crc32_finish(&elt->crc), (long long)elt->crc.size);
    g_debug("sending XMSG_CRC message");
    msg = xmsg_new(elt->upstream, XMSG_CRC, 0);
    msg->crc = crc32_finish(&elt->crc);
    msg->size = elt->crc.size;
    xfer_queue_message(elt->xfer, msg);

    g_debug("read_and_write downstream CRC: %08x      size %lld",
	    crc32_finish(&elt->crc), (long long)elt->crc.size);
    g_debug("sending XMSG_CRC message");
    msg = xmsg_new(elt->downstream, XMSG_CRC, 0);
    msg->crc = crc32_finish(&elt->crc);
    msg->size = elt->crc.size;
    xfer_queue_message(elt->xfer, msg);

    amfree(buf);
}
예제 #12
0
static gpointer
pull_buffer_impl(
    XferElement *elt,
    size_t *size)
{
    XferElementGlue *self = XFER_ELEMENT_GLUE(elt);

    /* accept first, if required */
    if (self->on_pull & PULL_ACCEPT_FIRST) {
	/* don't accept the next time around */
	self->on_pull &= ~PULL_ACCEPT_FIRST;

	if (elt->cancelled) {
	    *size = 0;
	    return NULL;
	}

	if ((self->input_data_socket = do_directtcp_accept(self,
					    &self->input_listen_socket)) == -1) {
	    /* do_directtcp_accept already signalled an error; xfer
	     * is cancelled */
	    *size = 0;
	    return NULL;
	}

	/* read from this new socket */
	self->read_fdp = &self->input_data_socket;
    } else if (self->on_pull & PULL_CONNECT_FIRST) {
	/* or connect first, if required */
	/* don't connect the next time around */
	self->on_pull &= ~PULL_CONNECT_FIRST;

	if (elt->cancelled) {
	    *size = 0;
	    return NULL;
	}

	if ((self->input_data_socket = do_directtcp_connect(self,
				    elt->upstream->output_listen_addrs)) == -1) {
	    /* do_directtcp_connect already signalled an error; xfer
	     * is cancelled */
	    *size = 0;
	    return NULL;
	}

	/* read from this new socket */
	self->read_fdp = &self->input_data_socket;
    }

    switch (self->on_pull) {
	case PULL_FROM_RING_BUFFER: {
	    gpointer buf;

	    if (elt->cancelled) {
		/* the finalize method will empty the ring buffer */
		*size = 0;
		return NULL;
	    }

	    /* make sure there's at least one element available */
	    amsemaphore_down(self->ring_used_sem);

	    /* get it */
	    buf = self->ring[self->ring_tail].buf;
	    *size = self->ring[self->ring_tail].size;
	    self->ring_tail = (self->ring_tail + 1) % GLUE_RING_BUFFER_SIZE;

	    /* and mark this element as free to be overwritten */
	    amsemaphore_up(self->ring_free_sem);

	    return buf;
	}

	case PULL_FROM_FD: {
	    int fd = get_read_fd(self);
	    char *buf;
	    ssize_t len;

	    /* if the fd is already closed, it's possible upstream bailed out
	     * so quickly that we didn't even get a look at the fd */
	    if (elt->cancelled || fd == -1) {
		if (fd != -1) {
		    if (elt->expect_eof)
			xfer_element_drain_fd(fd);

		    close_read_fd(self);
		}

		*size = 0;
		return NULL;
	    }

	    buf = g_malloc(GLUE_BUFFER_SIZE);

	    /* read from upstream */
	    len = read_fully(fd, buf, GLUE_BUFFER_SIZE, NULL);
	    if (len < GLUE_BUFFER_SIZE) {
		if (errno) {
		    if (!elt->cancelled) {
			xfer_cancel_with_error(elt,
			    _("Error reading from fd %d: %s"), fd, strerror(errno));
			wait_until_xfer_cancelled(elt->xfer);
		    }

		    /* return an EOF */
		    amfree(buf);
		    len = 0;

		    /* and finish off the upstream */
		    if (elt->expect_eof) {
			xfer_element_drain_fd(fd);
		    }
		    close_read_fd(self);
		} else if (len == 0) {
		    /* EOF */
		    g_free(buf);
		    buf = NULL;
		    *size = 0;

		    /* signal EOF to downstream */
		    close_read_fd(self);
		}
	    }

	    *size = (size_t)len;

	    return buf;
	}

	default:
	case PULL_INVALID:
	    g_assert_not_reached();
	    return NULL;
    }
}
예제 #13
0
파일: holding.c 프로젝트: code-mx/amanda
int
rename_tmp_holding(
    char *	holding_file,
    int		complete)
{
    int fd;
    size_t buflen;
    char buffer[DISK_BLOCK_BYTES];
    dumpfile_t file;
    char *filename;
    char *filename_tmp = NULL;

    memset(buffer, 0, sizeof(buffer));
    filename = g_strdup(holding_file);
    while(filename != NULL && filename[0] != '\0') {
	g_free(filename_tmp);
	filename_tmp = g_strconcat(filename, ".tmp", NULL);
	if((fd = robust_open(filename_tmp,O_RDONLY, 0)) == -1) {
	    dbprintf(_("rename_tmp_holding: open of %s failed: %s\n"),filename_tmp,strerror(errno));
	    amfree(filename);
	    amfree(filename_tmp);
	    return 0;
	}
	buflen = read_fully(fd, buffer, sizeof(buffer), NULL);
	close(fd);

	if(rename(filename_tmp, filename) != 0) {
	    dbprintf(_("rename_tmp_holding: could not rename \"%s\" to \"%s\": %s"),
		    filename_tmp, filename, strerror(errno));
	}

	if (buflen <= 0) {
	    dbprintf(_("rename_tmp_holding: %s: empty file?\n"), filename);
	    amfree(filename);
	    amfree(filename_tmp);
	    return 0;
	}
	parse_file_header(buffer, &file, (size_t)buflen);
	if(complete == 0 ) {
            char * header;
	    if((fd = robust_open(filename, O_RDWR, 0)) == -1) {
		dbprintf(_("rename_tmp_holdingX: open of %s failed: %s\n"),
			filename, strerror(errno));
		dumpfile_free_data(&file);
		amfree(filename);
		amfree(filename_tmp);
		return 0;

	    }
	    file.is_partial = 1;
	    if (debug_holding > 1)
		dump_dumpfile_t(&file);
            header = build_header(&file, NULL, DISK_BLOCK_BYTES);
	    if (!header) /* this shouldn't happen */
		error(_("header does not fit in %zd bytes"), (size_t)DISK_BLOCK_BYTES);
	    if (full_write(fd, header, DISK_BLOCK_BYTES) != DISK_BLOCK_BYTES) {
		dbprintf(_("rename_tmp_holding: writing new header failed: %s"),
			strerror(errno));
		dumpfile_free_data(&file);
		amfree(filename);
		amfree(filename_tmp);
		free(header);
		close(fd);
		return 0;
	    }
	    free(header);
	    close(fd);
	}
	g_free(filename);
	filename = g_strdup(file.cont_filename);
	dumpfile_free_data(&file);
    }
    amfree(filename);
    amfree(filename_tmp);
    return 1;
}
예제 #14
0
void
read_global_pools()
{
    int total_length, i;
    uchar *poolp;

    // Read the overal length of the five global pools.
    total_length = read_swapped_int();

    // Read the sizes of each of the global pools.
    utf_pool_size = read_swapped_short();
    class_pool_size = read_swapped_short();
    ref_pool_size = read_swapped_short();
    type_pool_size = read_swapped_short();
    value_pool_size = read_swapped_short();

    raw_pool = malloc(total_length);
    if (raw_pool == 0) {
        fprintf(stderr, "Couldn't allocate %d byte for pools\n", total_length);
        fflush(stderr);
        exit(5);
    }
    poolp = raw_pool;

    // printf("UTF pool size = %d\n", utf_pool_size);
    // printf("CLASS pool size = %d\n", class_pool_size);
    // printf("REF pool size = %d\n", ref_pool_size);
    // printf("TYPE pool size = %d\n", type_pool_size);
    // printf("VALUE pool size = %d\n", value_pool_size);

    // printf("Reading %d bytes of pool\n", total_length);
    // fflush(stdout);

    read_fully(raw_pool, total_length);

    // printf("done read\n");
    // fflush(stdout);

    // Allocate the indexes for the four string tables.
    utf_pool = calloc(utf_pool_size, sizeof(uchar *));
    class_pool = calloc(class_pool_size, sizeof(uchar *));
    type_pool = calloc(type_pool_size, sizeof(uchar *));
    value_pool = calloc(value_pool_size, sizeof(uchar *));
    if (utf_pool == 0 || class_pool == 0 || type_pool == 0 || value_pool == 0) {
        fprintf(stderr, "Couldn't allocate space for global pools\n");
        exit(6);
    }

    // Setup the utf pool.
    utf_pool[0] = 0;
    for (i = 1; i < utf_pool_size; i++) {
        ushort len = strlen(poolp);
        utf_pool[i] = poolp;
        poolp += (1 + len);
    }

    // Setup the class pool.
    class_pool[0] = 0;
    for (i = 1; i < class_pool_size; i++) {
        ushort len;
        class_pool[i] = poolp;
        if (*poolp == '%') {
            poolp += 3;
        }
        len = strlen(poolp);
        poolp += (1 + len);
    }

    // The ref_pool simply points at the raw data.
    // We have to offset for the missing entry at zero.
    ref_pool = (poolp - 6);
    poolp = poolp + (6 * (ref_pool_size-1));

    // Setup the type pool.
    type_pool[0] = 0;
    for (i = 1; i < type_pool_size; i++) {
        type_pool[i] = poolp;
        for (;;) {
            char ch = *poolp++;
            if (ch == 0) {
                break;
            }
            if (ch == 'L') {
                poolp += 2;
            }
        }
    }

    // Setup the value pool.
    value_pool[0] = 0;
    for (i = 1; i < value_pool_size; i++) {
        ushort len;
        uchar tag = *poolp;
        value_pool[i] = poolp;
        switch (tag) {
        case CONSTANT_INTEGER:
            poolp += 5;
            break;
        case CONSTANT_FLOAT:
            poolp += 5;
            break;
        case CONSTANT_LONG:
            poolp += 9;
            break;
        case CONSTANT_DOUBLE:
            poolp += 9;
            break;
        case CONSTANT_STRING:
            len = strlen(poolp+1);
            poolp += (len + 2);
            break;
        default:
            fprintf(stderr, "Unexpected tag %d in value pool\n", tag);
            exit(4);
        }
    }

    if (poolp != (raw_pool + total_length)) {
        fprintf(stderr, "Size mismatch when processing global pools\n");
    }
    // printf("Setup global pools OK\n");
}
예제 #15
0
int
file_lock_lock(
    file_lock *lock)
{
    int rv = -2;
    int fd = -1;
    int saved_errno;
    struct flock lock_buf;
    struct stat stat_buf;

    g_assert(!lock->locked);

    /* protect from overlapping lock operations within a process */
    g_static_mutex_lock(&lock_lock);
    if (!locally_locked_files) {
	locally_locked_files = g_hash_table_new(g_str_hash, g_str_equal);
    }

    /* if this filename is in the hash table, then some other thread in this
     * process has locked it */
    if (g_hash_table_lookup(locally_locked_files, lock->filename)) {
	rv = 1;
	errno = EBUSY;
	goto done;
    }

    /* The locks are advisory, so an error here never means the lock is already
     * taken. */
    lock->fd = fd = open(lock->filename, O_CREAT|O_RDWR, 0666);
    if (fd < 0) {
	rv = -1;
	goto done;
    }

    /* now try locking it */
    lock_buf.l_type = F_WRLCK;
    lock_buf.l_start = 0;
    lock_buf.l_whence = SEEK_SET;
    lock_buf.l_len = 0; /* to EOF */
    if (fcntl(fd, F_SETLK, &lock_buf) < 0) {
	if (errno == EACCES || errno == EAGAIN)
	    rv = 1;
	else
	    rv = -1;
	goto done;
    }

    /* and read the file in its entirety */
    if (fstat(fd, &stat_buf) < 0) {
	rv = -1;
	goto done;
    }

    if (!(stat_buf.st_mode & S_IFREG)) {
	rv = -1;
	errno = EINVAL;
	goto done;
    }

    if (stat_buf.st_size) {
	lock->data = g_malloc(stat_buf.st_size+1);
	lock->len = stat_buf.st_size;
	if (read_fully(fd, lock->data, lock->len, NULL) < lock->len) {
	    rv = -1;
	    goto done;
	}
	lock->data[lock->len] = '\0';
    }

    fd = -1; /* we'll keep the file now */
    lock->locked = TRUE;

    /* the lock is acquired; record this in the hash table */
    g_hash_table_insert(locally_locked_files, lock->filename, lock->filename);

    rv = 0;

done:
    saved_errno = errno;
    g_static_mutex_unlock(&lock_lock);
    if (fd >= 0) /* close and unlock if an error occurred */
	close(fd);
    errno = saved_errno;
    return rv;
}
예제 #16
0
void *reader_thread(void *_arg)
{
	orc_t *orc = (orc_t*) _arg;

	setup_thread();

	orc->fd = -1;

	int reconnectcount = 0;

reconnect:
	
	// reconnect, if necessary.
	while (orc->fd < 0) {
		LOG_INFO("Trying to connect to orcboard...(%i)", reconnectcount++);
		orc->fd = orc->impl->connect(orc->impl);
		
		if (orc->fd < 0)
			sleep(1);
	}

	// read for a while
	while (1) {

		// read a packet
		uint8_t buf[3];
		int res = read_fully(orc->fd, buf, 1);
		if (res <= 0)
			goto disconnected;
		if (buf[0] != 0xED) {
			LOG_DEBUG("Recovering sync [%02X]", buf[0]);
			continue;
		}

		res = read_fully(orc->fd, &buf[1], 2);
		if (res <= 0)
			goto disconnected;

		int id = buf[1];
		int datalen = buf[2];

		transaction_t *t = &orc->transactions[id];
		memcpy(t->response, buf, 3);

		res = read_fully(orc->fd, &t->response[PACKET_DATA], datalen + 1);
		if (res <= 0)
			goto disconnected;
		if (!packet_test_checksum(t->response)) {
			LOG_WARN("Bad checksum received from Orc");
			continue;
		}

		if (t->response == garbage && t->response[1]>=orc->idLow && t->response[1]<=orc->idHigh)
			LOG_VERBOSE("Unsolicited ack, id = %02X", t->response[1]);

		// is this a message from orcd, assigning us a client id?
		if (t->response[1] == 0xf7) {
			orc->idLow = t->response[4];
			orc->idHigh = t->response[5];
			orc->idLast = orc->idLow;
			LOG_INFO("Got client transaction range: %02x-%02x", orc->idLow, orc->idHigh);
		}

		if (t->response[1] == 0xfe)
			handle_pad_packet(orc, t->response);

		if (t->response[1] == PACKET_ID_ORCBOARD_BROADCAST &&
		    packet_16u(t->response, 1) == MSG_ASYNC_HEARTBEAT)
			handle_heartbeat_packet(orc, t->response);

		pthread_mutex_lock(&t->mutex);
		pthread_cond_signal(&t->cond);
		pthread_mutex_unlock(&t->mutex);

	}
	
disconnected:
	orc->impl->disconnect(orc->impl, orc->fd);
	orc->fd = -1;
	goto reconnect;

	// silence compiler
	return NULL;
}