コード例 #1
0
ファイル: unixsock.c プロジェクト: androdev4u/sysdb
int
sdb_unixsock_client_connect(sdb_unixsock_client_t *client)
{
    struct sockaddr_un sa;
    int fd;

    if ((! client) || (! client->path))
        return -1;

    memset(&sa, 0, sizeof(sa));

    if (client->fh)
        fclose(client->fh);

    fd = socket(AF_UNIX, SOCK_STREAM, /* protocol = */ 0);
    if (fd < 0) {
        char errbuf[1024];
        sdb_log(SDB_LOG_ERR, "unixsock: Failed to open socket: %s",
                sdb_strerror(errno, errbuf, sizeof(errbuf)));
        return -1;
    }

    sa.sun_family = AF_UNIX;
    strncpy(sa.sun_path, client->path, sizeof(sa.sun_path));
    sa.sun_path[sizeof(sa.sun_path) - 1] = '\0';

    if (connect(fd, (struct sockaddr *)&sa, sizeof(sa))) {
        char errbuf[1024];
        sdb_log(SDB_LOG_ERR, "unixsock: Failed to connect to %s: %s",
                sa.sun_path, sdb_strerror(errno, errbuf, sizeof(errbuf)));
        close(fd);
        return -1;
    }

    client->fh = fdopen(fd, "r+");
    if (! client->fh) {
        char errbuf[1024];
        sdb_log(SDB_LOG_ERR, "unixsock: Failed to open I/O "
                "stream for %s: %s", sa.sun_path,
                sdb_strerror(errno, errbuf, sizeof(errbuf)));
        close(fd);
        return -1;
    }

    /* enable line-buffering */
    setvbuf(client->fh, NULL, _IOLBF, 0);

    client->shutdown = 0;
    return 0;
} /* sdb_unixsock_client_connect */
コード例 #2
0
ファイル: unixsock.c プロジェクト: androdev4u/sysdb
int
sdb_unixsock_client_send(sdb_unixsock_client_t *client,
                         const char *msg)
{
    int status;

    if ((! client) || (! client->fh))
        return -1;

    if (client->shutdown & SDB_SHUT_WR) /* reconnect */
        sdb_unixsock_client_connect(client);

    status = fprintf(client->fh, "%s\r\n", msg);
    if (status < 0) {
        char errbuf[1024];
        sdb_log(SDB_LOG_ERR, "unixsock: Failed to write to "
                "socket (%s): %s", client->path,
                sdb_strerror(errno, errbuf, sizeof(errbuf)));
        return status;
    }
    return status;
} /* sdb_unixsock_client_send */
コード例 #3
0
ファイル: unixsock.c プロジェクト: androdev4u/sysdb
char *
sdb_unixsock_client_recv(sdb_unixsock_client_t *client,
                         char *buffer, size_t buflen)
{
    char *tmp;

    if ((! client) || (! client->fh) || (! buffer))
        return NULL;

    if (client->shutdown & SDB_SHUT_RD) /* reconnect */
        sdb_unixsock_client_connect(client);

    tmp = NULL;
    while (tmp == NULL) {
        errno = 0;
        tmp = fgets(buffer, (int)buflen - 1, client->fh);
        if (! tmp) {
            if ((errno == EAGAIN) || (errno == EINTR))
                continue;

            if (! feof(client->fh)) {
                char errbuf[1024];
                sdb_log(SDB_LOG_ERR, "unixsock: Failed to read "
                        "from socket (%s): %s", client->path,
                        sdb_strerror(errno, errbuf, sizeof(errbuf)));
            }
            return NULL;
        }
    }
    buffer[buflen - 1] = '\0';

    buflen = strlen(buffer);
    while (buflen && ((buffer[buflen - 1] == '\n') || (buffer[buflen - 1] == '\r'))) {
        buffer[buflen - 1] = '\0';
        --buflen;
    }
    return buffer;
} /* sdb_unixsock_client_recv */
コード例 #4
0
ファイル: main.c プロジェクト: androdev4u/sysdb
int
main(int argc, char **argv)
{
	const char *host = NULL;

	char *homedir;
	char hist_file[1024] = "";

	sdb_input_t input = SDB_INPUT_INIT;
	sdb_llist_t *commands = NULL;

	while (42) {
		int opt = getopt(argc, argv, "H:U:c:C:K:A:hV");

		if (-1 == opt)
			break;

		switch (opt) {
			case 'H':
				host = optarg;
				break;
			case 'U':
				input.user = optarg;
				break;

			case 'c':
				{
					sdb_object_t *obj;

					if (! commands)
						commands = sdb_llist_create();
					if (! commands) {
						sdb_log(SDB_LOG_ERR, "Failed to create list object");
						exit(1);
					}

					if (! (obj = sdb_object_create_T(optarg, sdb_object_t))) {
						sdb_log(SDB_LOG_ERR, "Failed to create object");
						exit(1);
					}
					if (sdb_llist_append(commands, obj)) {
						sdb_log(SDB_LOG_ERR, "Failed to append command to list");
						sdb_object_deref(obj);
						exit(1);
					}
					sdb_object_deref(obj);
				}
				break;

			case 'C':
				ssl_options.cert_file = optarg;
				break;
			case 'K':
				ssl_options.key_file = optarg;
				break;
			case 'A':
				ssl_options.ca_file = optarg;
				break;

			case 'h':
				exit_usage(argv[0], 0);
				break;
			case 'V':
				exit_version();
				break;
			default:
				exit_usage(argv[0], 1);
		}
	}

	if (optind < argc)
		exit_usage(argv[0], 1);

	if (! host)
		host = DEFAULT_SOCKET;
	if (! input.user)
		input.user = sdb_get_current_user();
	else
		input.user = strdup(input.user);
	if (! input.user)
		exit(1);

	if (sdb_ssl_init())
		exit(1);

	input.client = sdb_client_create(host);
	if (! input.client) {
		sdb_log(SDB_LOG_ERR, "Failed to create client object");
		sdb_input_reset(&input);
		exit(1);
	}
	canonicalize_ssl_options();
	if (sdb_client_set_ssl_options(input.client, &ssl_options)) {
		sdb_log(SDB_LOG_ERR, "Failed to apply SSL options");
		sdb_input_reset(&input);
		sdb_ssl_free_options(&ssl_options);
		exit(1);
	}
	sdb_ssl_free_options(&ssl_options);
	if (sdb_client_connect(input.client, input.user)) {
		sdb_log(SDB_LOG_ERR, "Failed to connect to SysDBd");
		sdb_input_reset(&input);
		exit(1);
	}

	if (commands) {
		int status = execute_commands(input.client, commands);
		sdb_llist_destroy(commands);
		sdb_input_reset(&input);
		if ((status != SDB_CONNECTION_OK) && (status != SDB_CONNECTION_DATA))
			exit(1);
		exit(0);
	}

	sdb_log(SDB_LOG_INFO, "SysDB client "SDB_CLIENT_VERSION_STRING
			SDB_CLIENT_VERSION_EXTRA" (libsysdbclient %s%s)",
			sdb_client_version_string(), sdb_client_version_extra());
	sdb_command_print_server_version(&input);
	printf("\n");

	using_history();

	if ((homedir = sdb_get_homedir())) {
		snprintf(hist_file, sizeof(hist_file) - 1,
				"%s/.sysdb_history", homedir);
		hist_file[sizeof(hist_file) - 1] = '\0';
		free(homedir);
		homedir = NULL;

		errno = 0;
		if (read_history(hist_file) && (errno != ENOENT)) {
			char errbuf[1024];
			sdb_log(SDB_LOG_WARNING, "Failed to load history (%s): %s",
					hist_file, sdb_strerror(errno, errbuf, sizeof(errbuf)));
		}
	}

	input.input = sdb_strbuf_create(2048);
	sdb_input_init(&input);
	sdb_input_mainloop();

	sdb_client_shutdown(input.client, SHUT_WR);
	while (! sdb_client_eof(input.client)) {
		/* wait for remaining data to arrive */
		sdb_command_print_reply(input.client);
	}

	if (hist_file[0] != '\0') {
		errno = 0;
		if (write_history(hist_file)) {
			char errbuf[1024];
			sdb_log(SDB_LOG_WARNING, "Failed to store history (%s): %s",
					hist_file, sdb_strerror(errno, errbuf, sizeof(errbuf)));
		}
	}

	sdb_input_reset(&input);
	sdb_ssl_shutdown();
	return 0;
} /* main */
コード例 #5
0
ファイル: rrdtool.c プロジェクト: tokkee/sysdb
static sdb_timeseries_t *
sdb_rrd_fetch(const char *id, sdb_timeseries_opts_t *opts,
		sdb_object_t *user_data)
{
	sdb_timeseries_t *ts;

	time_t start = (time_t)SDB_TIME_TO_SECS(opts->start);
	time_t end = (time_t)SDB_TIME_TO_SECS(opts->end);

	unsigned long step = 0;
	unsigned long ds_cnt = 0;
	unsigned long val_cnt = 0;
	char **ds_namv = NULL;
	rrd_value_t *data = NULL;

	if (user_data) {
		/* -> use RRDCacheD */
		char *addr = SDB_OBJ_WRAPPER(user_data)->data;

		if (! rrdcached_connect(addr))
			return NULL;

#ifdef HAVE_RRD_CLIENT_H
		if (rrdc_flush(id)) {
			sdb_log(SDB_LOG_ERR, "Failed to flush '%s' through RRDCacheD: %s",
					id, rrd_get_error());
			return NULL;
		}
#endif
	}

#define FREE_RRD_DATA() \
	do { \
		size_t i; \
		for (i = 0; i < ds_cnt; ++i) \
			rrd_freemem(ds_namv[i]); \
		rrd_freemem(ds_namv); \
		rrd_freemem(data); \
	} while (0)

	/* limit to about 1000 data-points for now
	 * TODO: make this configurable */
	step = (end - start) / 1000;

	if (rrd_fetch_r(id, "AVERAGE", &start, &end, &step,
				&ds_cnt, &ds_namv, &data)) {
		char errbuf[1024];
		sdb_strerror(errno, errbuf, sizeof(errbuf));
		sdb_log(SDB_LOG_ERR, "Failed to fetch data from %s: %s", id, errbuf);
		return NULL;
	}

	val_cnt = (unsigned long)(end - start) / step;

	/* RRDtool does not support fetching specific data-sources, so we'll have
	 * to filter the requested ones after fetching them all */
	if (opts->data_names && opts->data_names_len)
		ts = sdb_timeseries_create(opts->data_names_len,
				(const char * const *)opts->data_names, val_cnt);
	else
		ts = sdb_timeseries_create(ds_cnt, (const char * const *)ds_namv, val_cnt);
	if (! ts) {
		char errbuf[1024];
		sdb_strerror(errno, errbuf, sizeof(errbuf));
		sdb_log(SDB_LOG_ERR, "Failed to allocate time-series object: %s", errbuf);
		FREE_RRD_DATA();
		return NULL;
	}

	ts->start = SECS_TO_SDB_TIME(start + (time_t)step);
	ts->end = SECS_TO_SDB_TIME(end);

	if (copy_data(ts, data, (time_t)step, (size_t)ds_cnt, ds_namv) < 0) {
		FREE_RRD_DATA();
		sdb_timeseries_destroy(ts);
		return NULL;
	}

	FREE_RRD_DATA();
	return ts;
} /* sdb_rrd_fetch */
コード例 #6
0
ファイル: connection.c プロジェクト: androdev4u/sysdb
static int
connection_init(sdb_object_t *obj, va_list ap)
{
	sdb_conn_t *conn;
	int sock_fd;
	int sock_fl;

	assert(obj);
	conn = CONN(obj);

	sock_fd = va_arg(ap, int);

	conn->buf = sdb_strbuf_create(/* size = */ 128);
	if (! conn->buf) {
		sdb_log(SDB_LOG_ERR, "frontend: Failed to allocate a read buffer "
				"for a new connection");
		return -1;
	}
	conn->errbuf = sdb_strbuf_create(0);
	if (! conn->errbuf) {
		sdb_log(SDB_LOG_ERR, "frontend: Failed to allocate an error buffer "
				"for a new connection");
		return -1;
	}

	conn->client_addr_len = sizeof(conn->client_addr);
	conn->fd = accept(sock_fd, (struct sockaddr *)&conn->client_addr,
			&conn->client_addr_len);

	if (conn->fd < 0) {
		char buf[1024];
		sdb_log(SDB_LOG_ERR, "frontend: Failed to accept remote "
				"connection: %s", sdb_strerror(errno,
					buf, sizeof(buf)));
		return -1;
	}

	/* update the object name */
	snprintf(obj->name + strlen(CONN_FD_PREFIX),
			strlen(CONN_FD_PLACEHOLDER), "%i", conn->fd);

	/* defaults */
	conn->read = conn_read;
	conn->write = conn_write;
	conn->finish = NULL;
	conn->ssl_session = NULL;

	sock_fl = fcntl(conn->fd, F_GETFL);
	if (fcntl(conn->fd, F_SETFL, sock_fl | O_NONBLOCK)) {
		char buf[1024];
		sdb_log(SDB_LOG_ERR, "frontend: Failed to switch connection conn#%i "
				"to non-blocking mode: %s", conn->fd,
				sdb_strerror(errno, buf, sizeof(buf)));
		return -1;
	}

	conn->username = NULL;
	conn->ready = 0;

	sdb_log(SDB_LOG_DEBUG, "frontend: Accepted connection on fd=%i",
			conn->fd);

	conn->cmd = SDB_CONNECTION_IDLE;
	conn->cmd_len = 0;
	conn->skip_len = 0;
	return 0;
} /* connection_init */