Exemplo n.º 1
0
static ret_t
digest_HA2 (cherokee_validator_t *validator, cherokee_buffer_t *buf, cherokee_connection_t *conn)
{
	ret_t       ret;
	const char *method;
	cuint_t     method_len;

	/* Sanity check
	 */
	if (cherokee_buffer_is_empty (&validator->uri))
		return ret_deny;

	ret = cherokee_http_method_to_string (conn->header.method, &method, &method_len);
	if (unlikely (ret != ret_ok))
		return ret;

	cherokee_buffer_ensure_size (buf, method_len + 1 + validator->uri.len);

	cherokee_buffer_add        (buf, method, method_len);
	cherokee_buffer_add_str    (buf, ":");
	cherokee_buffer_add_buffer (buf, &validator->uri);

	cherokee_buffer_encode_md5_digest (buf);

	return ret_ok;
}
ret_t
cherokee_handler_proxy_conn_new (cherokee_handler_proxy_conn_t **pconn)
{
	CHEROKEE_NEW_STRUCT (n, handler_proxy_conn);

	/* Socket stuff
	 */
	cherokee_socket_init (&n->socket);

	n->post.sent        = 0;
	n->post.do_buf_sent = true;
	cherokee_buffer_init (&n->post.buf_temp);

	cherokee_buffer_init (&n->header_in_raw);
	cherokee_buffer_ensure_size (&n->header_in_raw, 512);

	n->poll_ref      = NULL;
	n->keepalive_in  = false;
	n->size_in       = 0;
	n->sent_out      = 0;
	n->enc           = pconn_enc_none;

	*pconn = n;
	return ret_ok;
}
Exemplo n.º 3
0
ret_t
cherokee_buffer_add_fsize (cherokee_buffer_t *buf, CST_OFFSET size)
{
	ret_t       ret;
	int         remain;
	const char  ord[]  = "KMGTPE";
	const char *o      = ord;

	ret = cherokee_buffer_ensure_size (buf, buf->len + 8);
	if (unlikely (ret != ret_ok))
		return ret;

	if (size < 973)
		return cherokee_buffer_add_ulong10 (buf, (culong_t)size);

	do {
		remain = (int)(size & 1023);
		size >>= 10;
		if (size >= 973) {
			++o;
			continue;
		}
		if (size < 9 || (size == 9 && remain < 973)) {
			if ((remain = ((remain * 5) + 256) / 512) >= 10)
				++size, remain = 0;
			return cherokee_buffer_add_va_fixed (buf, "%d.%d%c", (int) size, remain, *o);
		}
		if (remain >= 512)
			++size;
		return cherokee_buffer_add_va_fixed (buf, "%3d%c", (int) size, *o);
	} while (1);

	return ret_ok;
}
Exemplo n.º 4
0
ret_t
cherokee_logger_writer_new (cherokee_logger_writer_t **writer)
{
	CHEROKEE_NEW_STRUCT(n,logger_writer);

	INIT_LIST_HEAD (&n->listed);

	n->type        = cherokee_logger_writer_syslog;
	n->fd          = -1;
	n->max_bufsize = DEFAULT_LOGGER_MAX_BUFSIZE;

	cherokee_buffer_init (&n->command);
	cherokee_buffer_init (&n->filename);
	cherokee_buffer_init (&n->buffer);

	cherokee_buffer_ensure_size (&n->buffer, n->max_bufsize);

	n->priv = malloc (sizeof(priv_t));
	if (n->priv == NULL) {
		cherokee_buffer_mrproper (&n->buffer);
		free(n);
		return ret_nomem;
	}

	CHEROKEE_MUTEX_INIT (&PRIV(n)->mutex, NULL);
	n->initialized = false;

	*writer = n;
	return ret_ok;
}
Exemplo n.º 5
0
ret_t
cherokee_handler_zeromq_new (cherokee_handler_t	 **hdl, void *cnt, cherokee_module_props_t *props)
{
	CHEROKEE_NEW_STRUCT (n, handler_zeromq);
	
	/* Init the base class object
	 */
	cherokee_handler_init_base (HANDLER(n), cnt, HANDLER_PROPS(props), PLUGIN_INFO_HANDLER_PTR(zeromq));

	MODULE(n)->init			= (handler_func_init_t) cherokee_handler_zeromq_init;
	MODULE(n)->free			= (module_func_free_t) zeromq_free;
	HANDLER(n)->read_post   = (handler_func_read_post_t) cherokee_handler_zeromq_read_post;
	HANDLER(n)->add_headers = (handler_func_add_headers_t) cherokee_handler_zeromq_add_headers;
	HANDLER(n)->step		= (handler_func_step_t) cherokee_handler_zeromq_step;

	/* Supported features
	 */
	HANDLER(n)->support	 = hsupport_nothing;
	 
	cherokee_buffer_init (&n->output);
	cherokee_buffer_ensure_size (&n->output, 2097152);
	n->encoder = NULL;

	*hdl = HANDLER(n);
	return ret_ok;
}
Exemplo n.º 6
0
/* WARNING: all parameters MUST be valid,
 *          NULL pointers lead to a crash.
 */
ret_t
cherokee_socket_bufread (cherokee_socket_t *socket,
                         cherokee_buffer_t *buf,
                         size_t             count,
                         size_t            *pcnt_read)
{
	ret_t    ret;
	char    *starting;

	/* Read
	 */
	ret = cherokee_buffer_ensure_size (buf, buf->len + count + 2);
	if (unlikely(ret < ret_ok))
		return ret;

	starting = buf->buf + buf->len;

	ret = cherokee_socket_read (socket, starting, count, pcnt_read);
	if (*pcnt_read > 0) {
		buf->len += *pcnt_read;
		buf->buf[buf->len] = '\0';
	}

	TRACE (ENTRIES",bufread", "read fd=%d count=%d ret=%d read=%d\n",
	       socket->socket, count, ret, *pcnt_read);

	return ret;
}
Exemplo n.º 7
0
/*
 * Ensure there is enough (addlen) free space left in the buffer.
 */
ret_t
cherokee_buffer_ensure_addlen (cherokee_buffer_t *buf, size_t addlen)
{
	if (buf->len + addlen < buf->size)
		return ret_ok;

	return cherokee_buffer_ensure_size (buf, ((size_t)buf->len + addlen + 1));
}
Exemplo n.º 8
0
static ret_t
escape_string (cherokee_buffer_t      *buffer,
               const char             *s,
               cuint_t                 len,
	       cherokee_dwriter_lang_t lang)
{
	char    c;
	cuint_t i, j;

	cherokee_buffer_ensure_size (buffer, len*2);

	for (i=0,j=0; i<len; i++) {
		c = s[i];
		switch (c) {
		case '\n':
			buffer->buf[j++] = '\\';
			buffer->buf[j++] = 'n';
			break;
		case '\r':
			buffer->buf[j++] = '\\';
			buffer->buf[j++] = 'r';
			break;
		case '\t':
			buffer->buf[j++] = '\\';
			buffer->buf[j++] = 't';
			break;
		case '\b':
			buffer->buf[j++] = '\\';
			buffer->buf[j++] = 'b';
			break;
		case '\f':
			buffer->buf[j++] = '\\';
			buffer->buf[j++] = 'f';
			break;
		case '\\':
			buffer->buf[j++] = '\\';
			buffer->buf[j++] = '\\';
			break;
		case '/':
			if (lang == dwriter_json)
				buffer->buf[j++] = '\\';

			buffer->buf[j++] = '/';
			break;
		case '"':
			buffer->buf[j++] = '\\';
			buffer->buf[j++] = '"';
			break;
		default:
			buffer->buf[j++] = c;
		}
	}

	buffer->buf[j] = '\0';
	buffer->len    = j;
	return ret_ok;
}
Exemplo n.º 9
0
ret_t
cherokee_validator_digest_response (cherokee_validator_t  *validator,
				    char                  *A1,
				    cherokee_buffer_t     *buf,
				    cherokee_connection_t *conn)
{
	ret_t              ret;
	cherokee_buffer_t a2 = CHEROKEE_BUF_INIT;

	/* A1 has to be in string of length 32:
	 * MD5_digest(user":"******":"passwd)
	 */

	/* Sanity checks
	 */
	if (A1 == NULL)
		return ret_deny;

	if (cherokee_buffer_is_empty (&validator->nonce))
		return ret_deny;

	/* Build A2
	 */
	ret = digest_HA2 (validator, &a2, conn);
	if (ret != ret_ok)
		goto error;

	/* Build the final string
	 */
	cherokee_buffer_ensure_size (buf, 32 + a2.len + validator->nonce.len + 4);

	cherokee_buffer_add (buf, A1, 32);
	cherokee_buffer_add_str (buf, ":");
	cherokee_buffer_add_buffer (buf, &validator->nonce);
	cherokee_buffer_add_str (buf, ":");

	if (!cherokee_buffer_is_empty (&validator->qop)) {
		if (!cherokee_buffer_is_empty (&validator->nc))
			cherokee_buffer_add_buffer (buf, &validator->nc);
		cherokee_buffer_add_str (buf, ":");
		if (!cherokee_buffer_is_empty (&validator->cnonce))
			cherokee_buffer_add_buffer (buf, &validator->cnonce);
		cherokee_buffer_add_str (buf, ":");
		cherokee_buffer_add_buffer (buf, &validator->qop);
		cherokee_buffer_add_str (buf, ":");
	}

	cherokee_buffer_add_buffer (buf, &a2);
	cherokee_buffer_encode_md5_digest (buf);
	cherokee_buffer_mrproper (&a2);

	return ret_ok;

error:
	cherokee_buffer_mrproper (&a2);
	return ret;
}
Exemplo n.º 10
0
ret_t
cherokee_buffer_read_file (cherokee_buffer_t *buf, char *filename)
{
	int r, f;
	ret_t ret;
	struct stat info;

	/* Stat() the file
	 */
	r = cherokee_stat (filename, &info);
	if (r != 0)
		return ret_error;

	/* Is a regular file?
	 */
	if (S_ISREG(info.st_mode) == 0)
		return ret_error;

	/* Maybe get memory
	 */
	ret = cherokee_buffer_ensure_size (buf, buf->len + info.st_size + 1);
	if (unlikely (ret != ret_ok))
		return ret;

	/* Open the file
	 */
	f = cherokee_open (filename, O_RDONLY | O_BINARY, 0);
	if (f < 0) {
		LOG_ERRNO(errno, cherokee_err_error, CHEROKEE_ERROR_BUFFER_OPEN_FILE, filename);
		return ret_error;
	}

	cherokee_fd_set_closexec (f);

	/* Read the content
	 */
	r = read (f, buf->buf + buf->len, info.st_size);
	if (r < 0) {
		buf->buf[buf->len] = '\0';

		cherokee_fd_close(f);
		return ret_error;
	}

	/* Close it and exit
	 */
	cherokee_fd_close(f);

	buf->len += r;
	buf->buf[buf->len] = '\0';

	return ret_ok;
}
Exemplo n.º 11
0
ret_t
cherokee_logger_ncsa_init_base (cherokee_logger_ncsa_t    *logger,
				cherokee_virtual_server_t *vsrv,
				cherokee_config_node_t    *config)
{
	ret_t                   ret;
	cherokee_config_node_t *subconf;
	static int              callback_init = 0;

	/* Init the local buffers
	 */
	cherokee_buffer_init (&logger->now_dtm);
	cherokee_buffer_init (&logger->referer);
	cherokee_buffer_init (&logger->useragent);
	cherokee_buffer_ensure_size (&logger->now_dtm,   64);
	cherokee_buffer_ensure_size (&logger->referer, 1024);
	cherokee_buffer_ensure_size (&logger->useragent, 512);

	/* Init the logger writer
	 */
	ret = cherokee_config_node_get (config, "access", &subconf);
	if (ret != ret_ok) {
		LOG_CRITICAL (CHEROKEE_ERROR_LOGGER_NO_KEY, "access");
		return ret_error;
	}

	ret = cherokee_server_get_log_writer (VSERVER_SRV(vsrv), subconf, &logger->writer_access);
	if (ret != ret_ok) {
		return ret_error;
	}

	/* Callback init
	 */
	if (callback_init == 0) {
		cherokee_buffer_init (&now);
		cherokee_bogotime_add_callback (bogotime_callback, logger, 1);
	}

	return ret_ok;
}
Exemplo n.º 12
0
ret_t
cherokee_buffer_multiply (cherokee_buffer_t *buf, int num)
{
	int i, initial_size;

	initial_size = buf->len;
	cherokee_buffer_ensure_size (buf, buf->len * num + 1);

	for (i=0; i<num; i++) {
		cherokee_buffer_add (buf, buf->buf, initial_size);
	}

	return ret_ok;
}
Exemplo n.º 13
0
static int
openssl_sni_servername_cb (SSL *ssl, int *ad, void *arg)
{
	ret_t                      ret;
	int                        re;
	const char                *servername;
	cherokee_connection_t     *conn;
	cherokee_buffer_t          tmp;
	cherokee_server_t         *srv       = SRV(arg);
	cherokee_virtual_server_t *vsrv      = NULL;

	UNUSED(ad);

	/* Get the pointer to the socket
	 */
	conn = SSL_get_app_data (ssl);
	if (unlikely (conn == NULL)) {
		LOG_ERROR (CHEROKEE_ERROR_SSL_SOCKET, ssl);
		return SSL_TLSEXT_ERR_ALERT_FATAL;
	}

	cherokee_buffer_init(&tmp);
	cherokee_buffer_ensure_size(&tmp, 40);

	/* Read the SNI server name
	 */
	servername = SSL_get_servername (ssl, TLSEXT_NAMETYPE_host_name);
	if (servername == NULL) {
		/* Set the server name to the IP address if we couldn't get the host name via SNI
		 */
		cherokee_socket_ntop (&conn->socket, tmp.buf, tmp.size);
		TRACE (ENTRIES, "No SNI: Did not provide a server name, using IP='%s' as servername.\n", tmp.buf);
	} else {
		cherokee_buffer_add (&tmp, servername, strlen(servername));
		TRACE (ENTRIES, "SNI: Switching to servername='%s'\n", servername);
	}

	/* Look up and change the vserver
	 */
	ret = cherokee_cryptor_libssl_find_vserver(ssl, srv, &tmp, conn);
	if (ret != ret_ok) {
		re = SSL_TLSEXT_ERR_NOACK;
	}
	else {
		re = SSL_TLSEXT_ERR_OK;
	}

	cherokee_buffer_mrproper (&tmp);
	return re;
}
Exemplo n.º 14
0
ret_t
cherokee_validator_digest_check (cherokee_validator_t *validator, cherokee_buffer_t *passwd, cherokee_connection_t *conn)
{
	ret_t             ret;
	int               re   = -1;
	cherokee_buffer_t a1   = CHEROKEE_BUF_INIT;
	cherokee_buffer_t buf  = CHEROKEE_BUF_INIT;

	/* Sanity check
	 */
	if (cherokee_buffer_is_empty (&validator->user) ||
	    cherokee_buffer_is_empty (&validator->realm))
		return ret_deny;

	/* Build A1
	 */
	cherokee_buffer_ensure_size (&a1,
				     validator->user.len  + 1 +
				     validator->realm.len + 1 +
				     passwd->len);

	cherokee_buffer_add_buffer (&a1, &validator->user);
	cherokee_buffer_add_str    (&a1, ":");
	cherokee_buffer_add_buffer (&a1, &validator->realm);
	cherokee_buffer_add_str    (&a1, ":");
	cherokee_buffer_add_buffer (&a1, passwd);

	cherokee_buffer_encode_md5_digest (&a1);

	/* Build a possible response
	 */
	ret = cherokee_validator_digest_response (validator, a1.buf, &buf, conn);
	if (unlikely(ret != ret_ok))
		goto go_out;

	/* Compare and return
	 */
	re = cherokee_buffer_cmp_buf (&conn->validator->response, &buf);

go_out:
	cherokee_buffer_mrproper (&a1);
	cherokee_buffer_mrproper (&buf);

	return (re == 0) ? ret_ok : ret_deny;
}
Exemplo n.º 15
0
ret_t
cherokee_buffer_add_va_list (cherokee_buffer_t *buf, const char *format, va_list args)
{
	int len;
	int estimation;
	int size;
	ret_t ret;
	va_list args2;

	va_copy (args2, args);

	/* Estimate resulting formatted string length.
	 */
	estimation = cherokee_estimate_va_length (format, args);
	if (unlikely (estimation) < 0) {
		LOG_ERROR (CHEROKEE_ERROR_BUFFER_NEG_ESTIMATION, format, estimation);
		return ret_error;
	}

	/* Ensure enough size for buffer.
	 */
	ret = cherokee_buffer_ensure_size (buf, buf->len + estimation + 2);
	if (unlikely (ret != ret_ok)) {
		return ret;
	}

	/* Format the string into the buffer.
	 * NOTE: len does NOT include '\0', size includes '\0' (len + 1)
	 */
	size = buf->size - buf->len;
	if (unlikely (size < 1)) {
		LOG_ERROR (CHEROKEE_ERROR_BUFFER_NO_SPACE, format, size, estimation);
		return ret_error;
	}

	len = vsnprintf (buf->buf + buf->len, size, format, args2);
#if 0
	if (unlikely (estimation < len)) {
		LOG_ERROR (CHEROKEE_ERROR_BUFFER_BAD_ESTIMATION,
			   format, buf->buf + buf->len, estimation, len, size);
	}
#endif

	if (unlikely (len < 0))
		return ret_error;

	/* At this point buf-size is always greater than buf-len, thus size > 0.
	 */
	if (len >= size) {
		LOG_ERROR (CHEROKEE_ERROR_BUFFER_AVAIL_SIZE,
			   estimation, len, size, format);

		cherokee_buffer_ensure_size (buf, buf->len + len + 2);
		size = buf->size - buf->len;
		len = vsnprintf (buf->buf + buf->len, size, format, args2);

		if (unlikely (len < 0))
			return ret_error;

		if (unlikely (len >= size))
			return ret_error;
	}

	buf->len += len;
	return ret_ok;
}
Exemplo n.º 16
0
ret_t
cherokee_request_header_build_string (cherokee_request_header_t *request, cherokee_buffer_t *buf, cherokee_buffer_t *tmp1, cherokee_buffer_t *tmp2)
{
	ret_t           ret;
	const char     *ptr;
	cuint_t         len;
	cherokee_url_t *url = REQUEST_URL(request);

	/* 200 bytes should be enough for a small header
	 */
	cherokee_buffer_ensure_size (buf, 200);

	/* Add main request line:
	 * GET /dir/object HTTP/1.1
	 */
	ret = cherokee_http_method_to_string (request->method, &ptr, &len);
	if (ret != ret_ok) return ret;

	ret = cherokee_buffer_add (buf, ptr, len);
	if (ret != ret_ok) return ret;

	cherokee_buffer_add_str (buf, " ");

	/* Check if the requests goes through a proxy
	 */
	if (request->proxy) {
		cherokee_buffer_add_str (buf, "http://");
		cherokee_buffer_add_buffer (buf, URL_HOST(url));
	}

	cherokee_buffer_add_buffer (buf, URL_REQUEST(url));

	switch (REQUEST_VERSION(request)) {
	case http_version_11:
		cherokee_buffer_add_str (buf, " HTTP/1.1" CRLF);
		break;
	case http_version_10:
		cherokee_buffer_add_str (buf, " HTTP/1.0" CRLF);
		break;
	default:
		SHOULDNT_HAPPEN;
		return ret_error;
	}

	/* Add "Host:" header - in HTTP/1.1
	 */
	if (REQUEST_VERSION(request) == http_version_11) {
		cherokee_buffer_add_str    (buf, "Host: ");
		cherokee_buffer_add_buffer (buf, URL_HOST(url));
		cherokee_buffer_add_str    (buf, CRLF);
	}

	/* Post information
	 */
	if (request->post_len != 0) {
		/* "Content-Length: " FMT_OFFSET CRLF, request->post_len;
		 */
		cherokee_buffer_add_str      (buf, "Content-Length: ");
		cherokee_buffer_add_ullong10 (buf, (cullong_t) request->post_len);
		cherokee_buffer_add_str      (buf, CRLF);
	}

	/* Add "Connection:" header
	 */
	if (REQUEST_KEEPALIVE(request)) {
		cherokee_buffer_add_str (buf, "Connection: Keep-Alive"CRLF);
	} else {
		cherokee_buffer_add_str (buf, "Connection: close"CRLF);
	}

	/* Authentication
	 */
	if (! cherokee_buffer_is_empty (&request->user) ||
	    ! cherokee_buffer_is_empty (&request->password)) {
		cherokee_buffer_clean (tmp1);
		cherokee_buffer_clean (tmp2);

		cherokee_buffer_add_buffer (tmp1, &request->user);
		cherokee_buffer_add_char   (tmp1, ':');
		cherokee_buffer_add_buffer (tmp1, &request->password);

		cherokee_buffer_encode_base64 (tmp1, tmp2);

		cherokee_buffer_add_str    (buf, "Authorization: Basic ");
		cherokee_buffer_add_buffer (buf, tmp2);
		cherokee_buffer_add_str    (buf, CRLF);
	}

	/* Extra headers
	 */
	if (! cherokee_buffer_is_empty (&request->extra_headers)) {
		cherokee_buffer_add_buffer (buf, &request->extra_headers);
	}

	/* Finish the header
	 */
	cherokee_buffer_add_str (buf, CRLF);
	return ret_ok;
}
Exemplo n.º 17
0
ret_t
cherokee_spawner_spawn (cherokee_buffer_t         *binary,
                        cherokee_buffer_t         *user,
                        uid_t                      uid,
                        gid_t                      gid,
                        int                        env_inherited,
                        char                     **envp,
                        cherokee_logger_writer_t  *error_writer,
                        pid_t                     *pid_ret)
{
#ifdef HAVE_SYSV_SEMAPHORES
    char             **n;
    int               *pid_shm;
    int                pid_prev;
    int                k;
    int                phase;
    int                envs     = 0;
    cherokee_buffer_t  tmp      = CHEROKEE_BUF_INIT;

#define ALIGN4(buf)						\
	while (buf.len & 0x3) {					\
		cherokee_buffer_add_char (&buf, '\0');		\
	}


    /* Check it's initialized
     */
    if ((! _active) ||
            (cherokee_spawn_shared.mem == NULL))
    {
        TRACE (ENTRIES, "Spawner is not active. Returning: %s\n", binary->buf);
        return ret_deny;
    }

    /* Lock the monitor mutex
     */
    k = CHEROKEE_MUTEX_TRY_LOCK (&spawning_mutex);
    if (k) {
        return ret_eagain;
    }

    /* Build the string
     * The first character of each block is a mark.
     */
    cherokee_buffer_ensure_size (&tmp, SPAWN_SHARED_LEN);

    /* 1.- Executable */
    phase = 0xF0;
    cherokee_buffer_add        (&tmp, (char *)&phase, sizeof(int));
    cherokee_buffer_add        (&tmp, (char *)&binary->len,   sizeof(int));
    cherokee_buffer_add_buffer (&tmp, binary);
    cherokee_buffer_add_char   (&tmp, '\0');
    ALIGN4 (tmp);

    /* 2.- UID & GID */
    phase = 0xF1;
    cherokee_buffer_add        (&tmp, (char *)&phase, sizeof(int));
    cherokee_buffer_add        (&tmp, (char *)&user->len, sizeof(int));
    cherokee_buffer_add_buffer (&tmp, user);
    cherokee_buffer_add_char   (&tmp, '\0');
    ALIGN4(tmp);

    cherokee_buffer_add (&tmp, (char *)&uid, sizeof(uid_t));
    cherokee_buffer_add (&tmp, (char *)&gid, sizeof(gid_t));

    /* 3.- Environment */
    phase = 0xF2;
    cherokee_buffer_add (&tmp, (char *)&phase, sizeof(int));

    for (n=envp; *n; n++) {
        envs ++;
    }

    cherokee_buffer_add (&tmp, (char *)&env_inherited, sizeof(int));
    cherokee_buffer_add (&tmp, (char *)&envs, sizeof(int));

    for (n=envp; *n; n++) {
        int len = strlen(*n);
        cherokee_buffer_add      (&tmp, (char *)&len, sizeof(int));
        cherokee_buffer_add      (&tmp, *n, len);
        cherokee_buffer_add_char (&tmp, '\0');
        ALIGN4(tmp);
    }

    /* 4.- Error log */
    phase = 0xF3;
    cherokee_buffer_add (&tmp, (char *)&phase, sizeof(int));

    write_logger (&tmp, error_writer);
    ALIGN4 (tmp);

    /* 5.- PID (will be rewritten by the other side) */
    phase = 0xF4;
    cherokee_buffer_add (&tmp, (char *)&phase, sizeof(int));

    pid_shm = (int *) (((char *)cherokee_spawn_shared.mem) + tmp.len);
    k        = *pid_ret;
    pid_prev = *pid_ret;
    cherokee_buffer_add (&tmp, (char *)&k, sizeof(int));

    /* Copy it to the shared memory
     */
    if (unlikely (tmp.len > SPAWN_SHARED_LEN)) {
        goto error;
    }

    memcpy (cherokee_spawn_shared.mem, tmp.buf, tmp.len);
    cherokee_buffer_mrproper (&tmp);

    /* Wake up the spawning thread
     */
    sem_unlock (cherokee_spawn_sem, SEM_LAUNCH_START);

    /* Wait for the PID
     */
    sem_adquire (cherokee_spawn_sem, SEM_LAUNCH_READY);

    if (*pid_shm == -1) {
        TRACE(ENTRIES, "Could not get the PID of: '%s'\n", binary->buf);
        goto error;
    }

    if (*pid_shm == pid_prev) {
        TRACE(ENTRIES, "Could not the new PID, previously it was %d\n", pid_prev);
        goto error;
    }

    TRACE(ENTRIES, "Successfully launched PID=%d\n", *pid_shm);
    *pid_ret = *pid_shm;

    CHEROKEE_MUTEX_UNLOCK (&spawning_mutex);
    return ret_ok;

error:
    CHEROKEE_MUTEX_UNLOCK (&spawning_mutex);
    return ret_error;
#else
    return ret_not_found;

#endif /* HAVE_SYSV_SEMAPHORES */
}
Exemplo n.º 18
0
ret_t
cherokee_logger_writer_configure (cherokee_logger_writer_t *writer, cherokee_config_node_t *config)
{
	ret_t              ret;
	cherokee_buffer_t *tmp = NULL;

	/* Check the type
	 */
	ret = config_read_type (config, &writer->type);
	if (ret != ret_ok) {
		return ret;
	}

	/* Extra properties
	 */
	switch (writer->type) {
	case cherokee_logger_writer_file:
		ret = cherokee_config_node_read (config, "filename", &tmp);
		if (ret != ret_ok) {
			LOG_ERROR (CHEROKEE_ERROR_LOGGER_WRITER_READ, "file");
			return ret_error;
		}
		cherokee_buffer_add_buffer (&writer->filename, tmp);
		break;

	case cherokee_logger_writer_pipe:
		ret = cherokee_config_node_read (config, "command", &tmp);
		if (ret != ret_ok) {
			LOG_ERROR (CHEROKEE_ERROR_LOGGER_WRITER_READ, "exec");
			return ret_error;
		}
		cherokee_buffer_add_buffer (&writer->command, tmp);
		break;
	default:
		break;
	}

	/* Reside the internal buffer if needed
	 */
	ret = cherokee_config_node_read (config, "bufsize", &tmp);
	if (ret == ret_ok) {
		int buf_len;

		ret = cherokee_atoi (tmp->buf, &buf_len);
		if (ret != ret_ok) {
			return ret_error;
		}

		if (buf_len < LOGGER_MIN_BUFSIZE)
			buf_len = LOGGER_MIN_BUFSIZE;
		else if (buf_len > LOGGER_MAX_BUFSIZE)
			buf_len = LOGGER_MAX_BUFSIZE;

		cherokee_buffer_mrproper (&writer->buffer);
		cherokee_buffer_init (&writer->buffer);

		ret = cherokee_buffer_ensure_size (&writer->buffer, buf_len);
		if (ret != ret_ok) {
			LOG_ERROR (CHEROKEE_ERROR_LOGGER_WRITER_ALLOC, writer->max_bufsize);
			return ret_nomem;
		}

		writer->max_bufsize = (size_t)buf_len;
	}

	return ret_ok;
}