コード例 #1
0
ファイル: flatfile.c プロジェクト: Doap/php-src
/* {{{ flatfile_delete
 */
int flatfile_delete(flatfile *dba, datum key_datum TSRMLS_DC) {
	char *key = key_datum.dptr;
	size_t size = key_datum.dsize;
	size_t buf_size = FLATFILE_BLOCK_SIZE;
	char *buf = emalloc(buf_size);
	size_t num;
	size_t pos;

	php_stream_rewind(dba->fp);
	while(!php_stream_eof(dba->fp)) {
		/* read in the length of the key name */
		if (!php_stream_gets(dba->fp, buf, 15)) {
			break;
		}
		num = atoi(buf);
		if (num >= buf_size) {
			buf_size = num + FLATFILE_BLOCK_SIZE;
			buf = erealloc(buf, buf_size);
		}
		pos = php_stream_tell(dba->fp);

		/* read in the key name */
		num = php_stream_read(dba->fp, buf, num);
		if (num < 0)  {
			break;
		}

		if (size == num && !memcmp(buf, key, size)) {
			php_stream_seek(dba->fp, pos, SEEK_SET);
			php_stream_putc(dba->fp, 0);
			php_stream_flush(dba->fp);
			php_stream_seek(dba->fp, 0L, SEEK_END);
			efree(buf);
			return SUCCESS;
		}	

		/* read in the length of the value */
		if (!php_stream_gets(dba->fp, buf, 15)) {
			break;
		}
		num = atoi(buf);
		if (num >= buf_size) {
			buf_size = num + FLATFILE_BLOCK_SIZE;
			buf = erealloc(buf, buf_size);
		}
		/* read in the value */
		num = php_stream_read(dba->fp, buf, num);
		if (num < 0) {
			break;
		}
	}
	efree(buf);
	return FAILURE;
}	
コード例 #2
0
ファイル: mysqlnd_vio.c プロジェクト: MajorDeng/php-src
/* {{{ mysqlnd_vio::network_read */
static enum_func_status
MYSQLND_METHOD(mysqlnd_vio, network_read)(MYSQLND_VIO * const vio, zend_uchar * const buffer, const size_t count,
											 MYSQLND_STATS * const stats, MYSQLND_ERROR_INFO * const error_info)
{
	enum_func_status return_value = PASS;
	php_stream * net_stream = vio->data->m.get_stream(vio);
	size_t old_chunk_size = net_stream->chunk_size;
	size_t to_read = count, ret;
	zend_uchar * p = buffer;

	DBG_ENTER("mysqlnd_vio::network_read");
	DBG_INF_FMT("count="MYSQLND_SZ_T_SPEC, count);

	net_stream->chunk_size = MIN(to_read, vio->data->options.net_read_buffer_size);
	while (to_read) {
		if (!(ret = php_stream_read(net_stream, (char *) p, to_read))) {
			DBG_ERR_FMT("Error while reading header from socket");
			return_value = FAIL;
			break;
		}
		p += ret;
		to_read -= ret;
	}
	MYSQLND_INC_CONN_STATISTIC_W_VALUE(stats, STAT_BYTES_RECEIVED, count - to_read);
	net_stream->chunk_size = old_chunk_size;
	DBG_RETURN(return_value);
}
コード例 #3
0
static inline long
hs_response_recv(php_stream *stream, char *recv, size_t size TSRMLS_DC)
{
    long ret;
#ifdef HS_DEBUG
    long i;
    smart_str debug = {0};
#endif

    ret  = php_stream_read(stream, recv, size);
    if (ret <= 0) {
        return -1;
    }
    recv[size] = '\0';

#ifdef HS_DEBUG
    for (i = 0; i < ret; i++) {
        if ((unsigned char)recv[i] == HS_CODE_NULL) {
            smart_str_appendl_ex(&debug, "\\0", strlen("\\0"), 1);
        } else {
            smart_str_appendc(&debug, recv[i]);
        }
    }
    smart_str_0(&debug);
    php_printf("[handlersocket] (recv) %ld : \"%s\"", ret, debug.c);
    smart_str_free(&debug);
#endif

    return ret;
}
コード例 #4
0
ファイル: hash.c プロジェクト: 31H0B1eV/php-src
static void php_hash_do_hash(INTERNAL_FUNCTION_PARAMETERS, int isfilename, zend_bool raw_output_default) /* {{{ */
{
	char *algo, *data, *digest;
	int algo_len, data_len;
	zend_bool raw_output = raw_output_default;
	const php_hash_ops *ops;
	void *context;
	php_stream *stream = NULL;

	if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "ss|b", &algo, &algo_len, &data, &data_len, &raw_output) == FAILURE) {
		return;
	}

	ops = php_hash_fetch_ops(algo, algo_len);
	if (!ops) {
		php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unknown hashing algorithm: %s", algo);
		RETURN_FALSE;
	}
	if (isfilename) {
		if (CHECK_NULL_PATH(data, data_len)) {
			RETURN_FALSE;
		}
		stream = php_stream_open_wrapper_ex(data, "rb", REPORT_ERRORS, NULL, DEFAULT_CONTEXT);
		if (!stream) {
			/* Stream will report errors opening file */
			RETURN_FALSE;
		}
	}

	context = emalloc(ops->context_size);
	ops->hash_init(context);

	if (isfilename) {
		char buf[1024];
		int n;

		while ((n = php_stream_read(stream, buf, sizeof(buf))) > 0) {
			ops->hash_update(context, (unsigned char *) buf, n);
		}
		php_stream_close(stream);
	} else {
		ops->hash_update(context, (unsigned char *) data, data_len);
	}

	digest = emalloc(ops->digest_size + 1);
	ops->hash_final((unsigned char *) digest, context);
	efree(context);

	if (raw_output) {
		digest[ops->digest_size] = 0;
		RETURN_STRINGL(digest, ops->digest_size, 0);
	} else {
		char *hex_digest = safe_emalloc(ops->digest_size, 2, 1);

		php_hash_bin2hex(hex_digest, (unsigned char *) digest, ops->digest_size);
		hex_digest[2 * ops->digest_size] = 0;
		efree(digest);
		RETURN_STRINGL(hex_digest, 2 * ops->digest_size, 0);
	}
}
コード例 #5
0
ファイル: php_fopen_wrapper.c プロジェクト: PeeHaa/php-src
static size_t php_stream_input_read(php_stream *stream, char *buf, size_t count) /* {{{ */
{
	php_stream_input_t *input = stream->abstract;
	size_t read;

	if (!SG(post_read) && SG(read_post_bytes) < (int64_t)(input->position + count)) {
		/* read requested data from SAPI */
		size_t read_bytes = sapi_read_post_block(buf, count);

		if (read_bytes > 0) {
			php_stream_seek(input->body, 0, SEEK_END);
			php_stream_write(input->body, buf, read_bytes);
		}
	}

	if (!input->body->readfilters.head) {
		/* If the input stream contains filters, it's not really seekable. The
			input->position is likely to be wrong for unfiltered data. */
		php_stream_seek(input->body, input->position, SEEK_SET);
	}
	read = php_stream_read(input->body, buf, count);

	if (!read || read == (size_t) -1) {
		stream->eof = 1;
	} else {
		input->position += read;
	}

	return read;
}
コード例 #6
0
int php_mongo_io_stream_read(mongo_connection *con, mongo_server_options *options, void *data, int size, char **error_message)
{
	int num = 1, received = 0;
	TSRMLS_FETCH();

	/* this can return FAILED if there is just no more data from db */
	while (received < size && num > 0) {
		int len = 4096 < (size - received) ? 4096 : size - received;

		num = php_stream_read(con->socket, (char *) data, len);

		if (num < 0) {
			return -1;
		}

		data = (char*)data + num;
		received += num;
	}

	if (options && options->ctx) {
		php_stream_notify_progress_increment((php_stream_context *)options->ctx, received, size);
	}

	return received;
}
コード例 #7
0
ファイル: cast.c プロジェクト: AxiosCros/php-src
/* use our fopencookie emulation */
static int stream_cookie_reader(void *cookie, char *buffer, int size)
{
	int ret;

	ret = php_stream_read((php_stream*)cookie, buffer, size);
	return ret;
}
コード例 #8
0
ファイル: php_variables.c プロジェクト: Crell/php-src
SAPI_API SAPI_POST_HANDLER_FUNC(php_std_post_handler)
{
	zval *arr = (zval *) arg;
	php_stream *s = SG(request_info).request_body;
	post_var_data_t post_data;

	if (s && SUCCESS == php_stream_rewind(s)) {
		memset(&post_data, 0, sizeof(post_data));

		while (!php_stream_eof(s)) {
			char buf[BUFSIZ] = {0};
			size_t len = php_stream_read(s, buf, BUFSIZ);

			if (len && len != (size_t) -1) {
				smart_str_appendl(&post_data.str, buf, len);

				if (SUCCESS != add_post_vars(arr, &post_data, 0)) {
					smart_str_free(&post_data.str);
					return;
				}
			}

			if (len != BUFSIZ){
				break;
			}
		}

		if (post_data.str.s) {
			add_post_vars(arr, &post_data, 1);
			smart_str_free(&post_data.str);
		}
	}
}
コード例 #9
0
ファイル: cast.c プロジェクト: AxiosCros/php-src
static ssize_t stream_cookie_reader(void *cookie, char *buffer, size_t size)
{
	ssize_t ret;

	ret = php_stream_read(((php_stream *)cookie), buffer, size);
	return ret;
}
コード例 #10
0
ファイル: php_fopen_wrapper.c プロジェクト: mdesign83/php-src
static size_t php_stream_input_read(php_stream *stream, char *buf, size_t count) /* {{{ */
{
	php_stream_input_t *input = stream->abstract;
	size_t read;

	if (!SG(post_read) && SG(read_post_bytes) < (int64_t)(input->position + count)) {
		/* read requested data from SAPI */
		int read_bytes = sapi_read_post_block(buf, count);

		if (read_bytes > 0) {
			php_stream_seek(input->body, 0, SEEK_END);
			php_stream_write(input->body, buf, read_bytes);
		}
	}

	php_stream_seek(input->body, input->position, SEEK_SET);
	read = php_stream_read(input->body, buf, count);

	if (!read || read == (size_t) -1) {
		stream->eof = 1;
	} else {
		input->position += read;
	}

	return read;
}
コード例 #11
0
ファイル: streams.c プロジェクト: Calado/php-src
static size_t php_curl_stream_read(php_stream *stream, char *buf, size_t count TSRMLS_DC)
{
	php_curl_stream *curlstream = (php_curl_stream *) stream->abstract;
	size_t didread = 0;
	
	if (curlstream->readbuffer.readpos >= curlstream->readbuffer.writepos && curlstream->pending) {
		/* we need to read some more data */
		struct timeval tv;

		/* fire up the connection */
		if (curlstream->readbuffer.writepos == 0) {
			while (CURLM_CALL_MULTI_PERFORM == curl_multi_perform(curlstream->multi, &curlstream->pending));
		}
		
		do {
			FD_ZERO(&curlstream->readfds);
			FD_ZERO(&curlstream->writefds);
			FD_ZERO(&curlstream->excfds);

			/* get the descriptors from curl */
			curl_multi_fdset(curlstream->multi, &curlstream->readfds, &curlstream->writefds, &curlstream->excfds, &curlstream->maxfd);

			/* if we are in blocking mode, set a timeout */
			tv.tv_usec = 0;
			tv.tv_sec = 15; /* TODO: allow this to be configured from the script */

			/* wait for data */
			switch ((curlstream->maxfd < 0) ? 1 : 
					select(curlstream->maxfd + 1, &curlstream->readfds, &curlstream->writefds, &curlstream->excfds, &tv)) {
				case -1:
					/* error */
					return 0;
				case 0:
					/* no data yet: timed-out */
					return 0;
				default:
					/* fetch the data */
					do {
						curlstream->mcode = curl_multi_perform(curlstream->multi, &curlstream->pending);
					} while (curlstream->mcode == CURLM_CALL_MULTI_PERFORM);
			}
		} while (curlstream->maxfd >= 0 &&
				curlstream->readbuffer.readpos >= curlstream->readbuffer.writepos && curlstream->pending > 0);

	}

	/* if there is data in the buffer, try and read it */
	if (curlstream->readbuffer.writepos > 0 && curlstream->readbuffer.readpos < curlstream->readbuffer.writepos) {
		php_stream_seek(curlstream->readbuffer.buf, curlstream->readbuffer.readpos, SEEK_SET);
		didread = php_stream_read(curlstream->readbuffer.buf, buf, count);
		curlstream->readbuffer.readpos = php_stream_tell(curlstream->readbuffer.buf);
	}

	if (didread == 0) {
		stream->eof = 1;
	}
	
	return didread;
}
コード例 #12
0
ファイル: flatfile.c プロジェクト: Doap/php-src
/* {{{ flatfile_findkey
 */
int flatfile_findkey(flatfile *dba, datum key_datum TSRMLS_DC) {
	size_t buf_size = FLATFILE_BLOCK_SIZE;
	char *buf = emalloc(buf_size);
	size_t num;
	int ret=0;
	void *key = key_datum.dptr;
	size_t size = key_datum.dsize;

	php_stream_rewind(dba->fp);
	while (!php_stream_eof(dba->fp)) {
		if (!php_stream_gets(dba->fp, buf, 15)) {
			break;
		}
		num = atoi(buf);
		if (num >= buf_size) {
			buf_size = num + FLATFILE_BLOCK_SIZE;
			buf = erealloc(buf, buf_size);
		}
		num = php_stream_read(dba->fp, buf, num);
		if (num < 0) {
			break;
		}
		if (size == num) {
			if (!memcmp(buf, key, size)) {
				ret = 1;
				break;
			}
		}	
		if (!php_stream_gets(dba->fp, buf, 15)) {
			break;
		}
		num = atoi(buf);
		if (num >= buf_size) {
			buf_size = num + FLATFILE_BLOCK_SIZE;
			buf = erealloc(buf, buf_size);
		}
		num = php_stream_read(dba->fp, buf, num);
		if (num < 0) {
			break;
		}
	}
	efree(buf);
	return ret;
}
コード例 #13
0
ファイル: flatfile.c プロジェクト: AxiosCros/php-src
/* {{{ flatfile_nextkey
 */
datum flatfile_nextkey(flatfile *dba) {
	datum res;
	size_t num;
	size_t buf_size = FLATFILE_BLOCK_SIZE;
	char *buf = emalloc(buf_size);

	php_stream_seek(dba->fp, dba->CurrentFlatFilePos, SEEK_SET);
	while(!php_stream_eof(dba->fp)) {
		if (!php_stream_gets(dba->fp, buf, 15)) {
			break;
		}
		num = atoi(buf);
		if (num >= buf_size) {
			buf_size = num + FLATFILE_BLOCK_SIZE;
			buf = erealloc(buf, buf_size);
		}
		num = php_stream_read(dba->fp, buf, num);

		if (!php_stream_gets(dba->fp, buf, 15)) {
			break;
		}
		num = atoi(buf);
		if (num >= buf_size) {
			buf_size = num + FLATFILE_BLOCK_SIZE;
			buf = erealloc(buf, buf_size);
		}
		num = php_stream_read(dba->fp, buf, num);

		if (*(buf)!=0) {
			dba->CurrentFlatFilePos = php_stream_tell(dba->fp);
			res.dptr = buf;
			res.dsize = num;
			return res;
		}
	}
	efree(buf);
	res.dptr = NULL;
	res.dsize = 0;
	return res;
}
コード例 #14
0
ファイル: cairo_ft_font.c プロジェクト: gtkforphp/cairo
/* Functions for stream handling */
static unsigned long php_cairo_ft_read_func(FT_Stream stream, unsigned long offset, unsigned char* buffer, unsigned long count) {
	stream_closure *closure;
#ifdef ZTS
	TSRMLS_D;
#endif

	closure = (stream_closure *)stream->descriptor.pointer;
#ifdef ZTS
	TSRMLS_C = closure->TSRMLS_C;
#endif
	php_stream_seek(closure->stream, offset, SEEK_SET);
	return php_stream_read(closure->stream, (char *)buffer, count);
}
コード例 #15
0
ファイル: com_persist.c プロジェクト: AxiosCros/php-src
static HRESULT STDMETHODCALLTYPE stm_read(IStream *This, void *pv, ULONG cb, ULONG *pcbRead)
{
	ULONG nread;
	FETCH_STM();

	nread = (ULONG)php_stream_read(stm->stream, pv, cb);

	if (pcbRead) {
		*pcbRead = nread > 0 ? nread : 0;
	}
	if (nread > 0) {
		return S_OK;
	}
	return S_FALSE;
}
コード例 #16
0
ファイル: flatfile.c プロジェクト: Doap/php-src
/* {{{ flatfile_fetch
 */
datum flatfile_fetch(flatfile *dba, datum key_datum TSRMLS_DC) {
	datum value_datum = {NULL, 0};
	char buf[16];

	if (flatfile_findkey(dba, key_datum TSRMLS_CC)) {
		if (php_stream_gets(dba->fp, buf, sizeof(buf))) {
			value_datum.dsize = atoi(buf);
			value_datum.dptr = safe_emalloc(value_datum.dsize, 1, 1);
			value_datum.dsize = php_stream_read(dba->fp, value_datum.dptr, value_datum.dsize);
		} else {
			value_datum.dptr = NULL;
			value_datum.dsize = 0;
		}
	}
	return value_datum;
}
コード例 #17
0
ファイル: mysqlnd_vio.c プロジェクト: MajorDeng/php-src
/* {{{ mysqlnd_vio::consume_uneaten_data */
size_t
MYSQLND_METHOD(mysqlnd_vio, consume_uneaten_data)(MYSQLND_VIO * const net, enum php_mysqlnd_server_command cmd)
{
#ifdef MYSQLND_DO_WIRE_CHECK_BEFORE_COMMAND
	/*
	  Switch to non-blocking mode and try to consume something from
	  the line, if possible, then continue. This saves us from looking for
	  the actual place where out-of-order packets have been sent.
	  If someone is completely sure that everything is fine, he can switch it
	  off.
	*/
	char tmp_buf[256];
	size_t skipped_bytes = 0;
	int opt = PHP_STREAM_OPTION_BLOCKING;
	php_stream * net_stream = net->data->get_stream(net);
	int was_blocked = net_stream->ops->set_option(net_stream, opt, 0, NULL);

	DBG_ENTER("mysqlnd_vio::consume_uneaten_data");

	if (PHP_STREAM_OPTION_RETURN_ERR != was_blocked) {
		/* Do a read of 1 byte */
		int bytes_consumed;

		do {
			skipped_bytes += (bytes_consumed = php_stream_read(net_stream, tmp_buf, sizeof(tmp_buf)));
		} while (bytes_consumed == sizeof(tmp_buf));

		if (was_blocked) {
			net_stream->ops->set_option(net_stream, opt, 1, NULL);
		}

		if (bytes_consumed) {
			DBG_ERR_FMT("Skipped %u bytes. Last command hasn't consumed all the output from the server",
						bytes_consumed, mysqlnd_command_to_text[net->last_command]);
			php_error_docref(NULL, E_WARNING, "Skipped %u bytes. Last command %s hasn't "
							 "consumed all the output from the server",
							 bytes_consumed, mysqlnd_command_to_text[net->last_command]);
		}
	}
	net->last_command = cmd;

	DBG_RETURN(skipped_bytes);
#else
	return 0;
#endif
}
コード例 #18
0
ファイル: mysqlnd_loaddata.c プロジェクト: Distrotech/php-src
/* {{{ mysqlnd_local_infile_read */
static
int mysqlnd_local_infile_read(void * ptr, zend_uchar * buf, unsigned int buf_len)
{
	MYSQLND_INFILE_INFO	*info = (MYSQLND_INFILE_INFO *)ptr;
	int count;

	DBG_ENTER("mysqlnd_local_infile_read");

	count = (int) php_stream_read(info->fd, (char *) buf, buf_len);

	if (count < 0) {
		strcpy(info->error_msg, "Error reading file");
		info->error_no = CR_UNKNOWN_ERROR;
	}

	DBG_RETURN(count);
}
コード例 #19
0
ファイル: xz_fopen_wrapper.c プロジェクト: chobie/php-xz
static int php_xz_decompress(struct php_xz_stream_data_t *self)
{
  lzma_stream *strm = &self->strm;
  lzma_action action = LZMA_RUN;

  if (strm->avail_in == 0 && !php_stream_eof(self->stream)) {
    strm->next_in = self->in_buf;
    strm->avail_in = php_stream_read(self->stream, self->in_buf, self->in_buf_sz);

  }
  lzma_ret ret = lzma_code(strm, action);

  if (strm->avail_out == 0 && self->out_buf_idx == strm->next_out) {
    //have read all bytes in output buffer in php_xziop_read()
    strm->next_out = self->out_buf_idx = self->out_buf;
    strm->avail_out = self->out_buf_sz;
  }
}
コード例 #20
0
/* {{{ mysqlnd_net::network_read */
static enum_func_status
MYSQLND_METHOD(mysqlnd_net, network_read)(MYSQLND * conn, zend_uchar * buffer, size_t count TSRMLS_DC)
{
	size_t to_read = count, ret;
	size_t old_chunk_size = conn->net->stream->chunk_size;
	DBG_ENTER("mysqlnd_net::network_read");
	DBG_INF_FMT("count=%u", count);
	conn->net->stream->chunk_size = MIN(to_read, conn->net->options.net_read_buffer_size);
	while (to_read) {
		if (!(ret = php_stream_read(conn->net->stream, (char *) buffer, to_read))) {
			DBG_ERR_FMT("Error while reading header from socket");
			DBG_RETURN(FAIL);
		}
		buffer += ret;
		to_read -= ret;
	}
	MYSQLND_INC_CONN_STATISTIC_W_VALUE(conn->stats, STAT_BYTES_RECEIVED, count);
	conn->net->stream->chunk_size = old_chunk_size;
	DBG_RETURN(PASS);
}
コード例 #21
0
ファイル: cdb.c プロジェクト: netroby/php-src
/* {{{ cdb_read */
int cdb_read(struct cdb *c, char *buf, unsigned int len, uint32 pos)
{
    if (php_stream_seek(c->fp, pos, SEEK_SET) == -1) {
        errno = EPROTO;
        return -1;
    }
    while (len > 0) {
        int r;
        do {
            r = php_stream_read(c->fp, buf, len);
        } while ((r == -1) && (errno == EINTR));
        if (r == -1)
            return -1;
        if (r == 0) {
            errno = EPROTO;
            return -1;
        }
        buf += r;
        len -= r;
    }
    return 0;
}
コード例 #22
0
ファイル: http_send_api.c プロジェクト: ngourdeau/pecl-http
static inline void _http_send_response_data_fetch(void **buffer, const void *data, size_t data_len, http_send_mode mode, size_t begin, size_t end TSRMLS_DC)
{
	long bsz, got, len = end - begin;
	
	if (!(bsz = HTTP_G->send.buffer_size)) {
		bsz = HTTP_SENDBUF_SIZE;
	}
	
	switch (mode) {
		case SEND_RSRC: {
			php_stream *s = (php_stream *) data;
			if (SUCCESS == php_stream_seek(s, begin, SEEK_SET)) {
				char *buf = emalloc(bsz);
				
				while (len > 0) {
					got = php_stream_read(s, buf, MIN(len, bsz));
					http_send_response_data_plain(buffer, buf, got);
					len -= got;
				}
				
				efree(buf);
			}
			break;
		}
		case SEND_DATA: {
			const char *buf = ((const char *) data) + begin;
			while (len > 0) {
				got = MIN(len, bsz);
				http_send_response_data_plain(buffer, buf, got);
				len -= got;
				buf += got;
			}
			break;
		}
		EMPTY_SWITCH_DEFAULT_CASE();
	}
}
コード例 #23
0
/* Returns the bytes read on success
 * Returns -31 on unknown failure
 * Returns -80 on timeout
 * Returns -32 when remote server closes the connection
 */
int php_mongo_io_stream_read(mongo_connection *con, mongo_server_options *options, int timeout, void *data, int size, char **error_message)
{
	int num = 1, received = 0;
	TSRMLS_FETCH();

	int socketTimeoutMS = options->socketTimeoutMS ? options->socketTimeoutMS : FG(default_socket_timeout) * 1000;

	/* Convert negative values to -1 second, which implies no timeout */
	socketTimeoutMS = socketTimeoutMS < 0 ? -1000 : socketTimeoutMS;
	timeout = timeout < 0 ? -1000 : timeout;

	/* Socket timeout behavior varies based on the following:
	 * - Negative => no timeout (i.e. block indefinitely)
	 * - Zero => not specified (no changes to existing configuration)
	 * - Positive => used specified timeout (revert to previous value later) */
	if (timeout && timeout != socketTimeoutMS) {
		struct timeval rtimeout = {0, 0};

		rtimeout.tv_sec = timeout / 1000;
		rtimeout.tv_usec = (timeout % 1000) * 1000;

		php_stream_set_option(con->socket, PHP_STREAM_OPTION_READ_TIMEOUT, 0, &rtimeout);
		mongo_manager_log(MonGlo(manager), MLOG_CON, MLOG_FINE, "Setting the stream timeout to %d.%06d", rtimeout.tv_sec, rtimeout.tv_usec);
	} else {
		mongo_manager_log(MonGlo(manager), MLOG_CON, MLOG_FINE, "No timeout changes for %s", con->hash);
	}

	php_mongo_stream_notify_io(options, MONGO_STREAM_NOTIFY_IO_READ, 0, size TSRMLS_CC);

	/* this can return FAILED if there is just no more data from db */
	while (received < size && num > 0) {
		int len = 4096 < (size - received) ? 4096 : size - received;
		ERROR_HANDLER_DECLARATION(error_handler)

		ERROR_HANDLER_REPLACE(error_handler, mongo_ce_ConnectionException);
		num = php_stream_read(con->socket, (char *) data, len);
		ERROR_HANDLER_RESTORE(error_handler);

		if (num < 0) {
			/* Doesn't look like this can happen, php_sockop_read overwrites
			 * the failure from recv() to return 0 */
			*error_message = strdup("Read from socket failed");
			return -31;
		}

		/* It *may* have failed. It also may simply have no data */
		if (num == 0) {
			zval *metadata;

			MAKE_STD_ZVAL(metadata);
			array_init(metadata);
			if (php_stream_populate_meta_data(con->socket, metadata)) {
				zval **tmp;

				if (zend_hash_find(Z_ARRVAL_P(metadata), "timed_out", sizeof("timed_out"), (void**)&tmp) == SUCCESS) {
					convert_to_boolean_ex(tmp);
					if (Z_BVAL_PP(tmp)) {
						struct timeval rtimeout = {0, 0};

						if (timeout > 0 && options->socketTimeoutMS != timeout) {
							rtimeout.tv_sec = timeout / 1000;
							rtimeout.tv_usec = (timeout % 1000) * 1000;
						} else {
							/* Convert timeout=-1 to -1second, which PHP interprets as no timeout */
							int socketTimeoutMS = options->socketTimeoutMS == -1 ? -1000 : options->socketTimeoutMS;
							rtimeout.tv_sec = socketTimeoutMS / 1000;
							rtimeout.tv_usec = (socketTimeoutMS % 1000) * 1000;
						}
						*error_message = malloc(256);
						snprintf(*error_message, 256, "Read timed out after reading %d bytes, waited for %d.%06d seconds", num, rtimeout.tv_sec, rtimeout.tv_usec);
						zval_ptr_dtor(&metadata);
						return -80;
					}
				}
				if (zend_hash_find(Z_ARRVAL_P(metadata), "eof", sizeof("eof"), (void**)&tmp) == SUCCESS) {
					convert_to_boolean_ex(tmp);
					if (Z_BVAL_PP(tmp)) {
						*error_message = strdup("Remote server has closed the connection");
						zval_ptr_dtor(&metadata);
						return -32;
					}
				}
			}
			zval_ptr_dtor(&metadata);
		}

		data = (char*)data + num;
		received += num;
	}
	/* PHP may have sent notify-progress of *more then* 'received' in some
	 * cases.
	 * PHP will read 8192 byte chunks at a time, but if we request less data
	 * then that PHP will just buffer the rest, which is fine.  It could
	 * confuse users a little, why their progress update was higher then the
	 * max-bytes-expected though... */
	php_mongo_stream_notify_io(options, MONGO_STREAM_NOTIFY_IO_COMPLETED, received, size TSRMLS_CC);

	/* If the timeout was changed, revert to the previous value now */
	if (timeout && timeout != socketTimeoutMS) {
		struct timeval rtimeout = {0, 0};

		/* If socketTimeoutMS was never specified, revert to default_socket_timeout */
		if (options->socketTimeoutMS == 0) {
			mongo_manager_log(MonGlo(manager), MLOG_CON, MLOG_FINE, "Stream timeout will be reverted to default_socket_timeout (%d)", FG(default_socket_timeout));
		}

		rtimeout.tv_sec = socketTimeoutMS / 1000;
		rtimeout.tv_usec = (socketTimeoutMS % 1000) * 1000;

		php_stream_set_option(con->socket, PHP_STREAM_OPTION_READ_TIMEOUT, 0, &rtimeout);
		mongo_manager_log(MonGlo(manager), MLOG_CON, MLOG_FINE, "Now setting stream timeout back to %d.%06d", rtimeout.tv_sec, rtimeout.tv_usec);
	}

	return received;
}
コード例 #24
0
php_http_message_parser_state_t php_http_message_parser_parse_stream(php_http_message_parser_t *parser, php_http_buffer_t *buf, php_stream *s, unsigned flags, php_http_message_t **message)
{
	php_http_message_parser_state_t state = PHP_HTTP_MESSAGE_PARSER_STATE_START;

	if (!buf->data) {
		php_http_buffer_resize_ex(buf, 0x1000, 1, 0);
	}
	while (1) {
		size_t justread = 0;
#if DBG_PARSER
		fprintf(stderr, "#SP: %s (f:%u)\n", php_http_message_parser_state_name(state), flags);
#endif
		/* resize if needed */
		if (buf->free < 0x1000) {
			php_http_buffer_resize_ex(buf, 0x1000, 1, 0);
		}
		switch (state) {
			case PHP_HTTP_MESSAGE_PARSER_STATE_START:
			case PHP_HTTP_MESSAGE_PARSER_STATE_HEADER:
			case PHP_HTTP_MESSAGE_PARSER_STATE_HEADER_DONE:
				/* read line */
				php_stream_get_line(s, buf->data + buf->used, buf->free, &justread);
				/* if we fail reading a whole line, try a single char */
				if (!justread) {
					int c = php_stream_getc(s);

					if (c != EOF) {
						char s[1] = {c};
						justread = php_http_buffer_append(buf, s, 1);
					}
				}
				php_http_buffer_account(buf, justread);
				break;

			case PHP_HTTP_MESSAGE_PARSER_STATE_BODY_DUMB:
				/* read all */
				justread = php_stream_read(s, buf->data + buf->used, buf->free);
				php_http_buffer_account(buf, justread);
				break;

			case PHP_HTTP_MESSAGE_PARSER_STATE_BODY_LENGTH:
				/* read body_length */
				justread = php_stream_read(s, buf->data + buf->used, MIN(buf->free, parser->body_length));
				php_http_buffer_account(buf, justread);
				break;

			case PHP_HTTP_MESSAGE_PARSER_STATE_BODY_CHUNKED:
				/* duh, this is very naive */
				if (parser->body_length) {
					justread = php_stream_read(s, buf->data + buf->used, MIN(parser->body_length, buf->free));

					php_http_buffer_account(buf, justread);

					parser->body_length -= justread;
				} else {
					php_http_buffer_resize(buf, 24);
					php_stream_get_line(s, buf->data, buf->free, &justread);
					php_http_buffer_account(buf, justread);

					parser->body_length = strtoul(buf->data + buf->used - justread, NULL, 16);
				}
				break;

			case PHP_HTTP_MESSAGE_PARSER_STATE_BODY:
			case PHP_HTTP_MESSAGE_PARSER_STATE_BODY_DONE:
			case PHP_HTTP_MESSAGE_PARSER_STATE_UPDATE_CL:
				/* should not occur */
				abort();
				break;

			case PHP_HTTP_MESSAGE_PARSER_STATE_DONE:
			case PHP_HTTP_MESSAGE_PARSER_STATE_FAILURE:
				return php_http_message_parser_state_is(parser);
		}

		if (justread) {
			state = php_http_message_parser_parse(parser, buf, flags, message);
		} else if (php_stream_eof(s)) {
			return php_http_message_parser_parse(parser, buf, flags | PHP_HTTP_MESSAGE_PARSER_CLEANUP, message);
		} else {
			return state;
		}
	}

	return PHP_HTTP_MESSAGE_PARSER_STATE_DONE;
}
コード例 #25
0
ファイル: odbc_stmt.c プロジェクト: AmesianX/php-src
static int odbc_stmt_execute(pdo_stmt_t *stmt)
{
	RETCODE rc;
	pdo_odbc_stmt *S = (pdo_odbc_stmt*)stmt->driver_data;
	char *buf = NULL;
	SQLLEN row_count = -1;

	if (stmt->executed) {
		SQLCloseCursor(S->stmt);
	}
	
	rc = SQLExecute(S->stmt);	

	while (rc == SQL_NEED_DATA) {
		struct pdo_bound_param_data *param;

		rc = SQLParamData(S->stmt, (SQLPOINTER*)&param);
		if (rc == SQL_NEED_DATA) {
			php_stream *stm;
			int len;
			pdo_odbc_param *P;
			zval *parameter;
	
			P = (pdo_odbc_param*)param->driver_data;
			if (Z_ISREF(param->parameter)) {
				parameter = Z_REFVAL(param->parameter);
			} else {
				parameter = &param->parameter;
			}
			if (Z_TYPE_P(parameter) != IS_RESOURCE) {
				/* they passed in a string */
				zend_ulong ulen;
				convert_to_string(parameter);

				switch (pdo_odbc_utf82ucs2(stmt, P->is_unicode, 
							Z_STRVAL_P(parameter),
							Z_STRLEN_P(parameter),
							&ulen)) {
					case PDO_ODBC_CONV_NOT_REQUIRED:
						SQLPutData(S->stmt, Z_STRVAL_P(parameter),
							Z_STRLEN_P(parameter));
						break;
					case PDO_ODBC_CONV_OK:
						SQLPutData(S->stmt, S->convbuf, ulen);
						break;
					case PDO_ODBC_CONV_FAIL:
						pdo_odbc_stmt_error("error converting input string");
						SQLCloseCursor(S->stmt);
						if (buf) {
							efree(buf);
						}
						return 0;
				}
				continue;
			}

			/* we assume that LOBs are binary and don't need charset
			 * conversion */

			php_stream_from_zval_no_verify(stm, parameter);
			if (!stm) {
				/* shouldn't happen either */
				pdo_odbc_stmt_error("input LOB is no longer a stream");
				SQLCloseCursor(S->stmt);
				if (buf) {
					efree(buf);
				}
				return 0;
			}

			/* now suck data from the stream and stick it into the database */
			if (buf == NULL) {
				buf = emalloc(8192);
			}

			do {
				len = php_stream_read(stm, buf, 8192);
				if (len == 0) {
					break;
				}
				SQLPutData(S->stmt, buf, len);
			} while (1);
		}
	}

	if (buf) {
		efree(buf);
	}

	switch (rc) {
		case SQL_SUCCESS:
			break;
		case SQL_NO_DATA_FOUND:
		case SQL_SUCCESS_WITH_INFO:
			pdo_odbc_stmt_error("SQLExecute");
			break;

		default:
			pdo_odbc_stmt_error("SQLExecute");
			return 0;
	}

	SQLRowCount(S->stmt, &row_count);
	stmt->row_count = row_count;

	if (!stmt->executed) {
		/* do first-time-only definition of bind/mapping stuff */
		SQLSMALLINT colcount;

		/* how many columns do we have ? */
		SQLNumResultCols(S->stmt, &colcount);

		stmt->column_count = (int)colcount;
		S->cols = ecalloc(colcount, sizeof(pdo_odbc_column));
		S->going_long = 0;
	}

	return 1;
}
コード例 #26
0
ファイル: odbc_stmt.c プロジェクト: AmesianX/php-src
static int odbc_stmt_param_hook(pdo_stmt_t *stmt, struct pdo_bound_param_data *param,
		enum pdo_param_event event_type)
{
	pdo_odbc_stmt *S = (pdo_odbc_stmt*)stmt->driver_data;
	RETCODE rc;
	SWORD sqltype = 0, ctype = 0, scale = 0, nullable = 0;
	SQLULEN precision = 0;
	pdo_odbc_param *P;
	zval *parameter;
	
	/* we're only interested in parameters for prepared SQL right now */
	if (param->is_param) {

		switch (event_type) {
			case PDO_PARAM_EVT_FETCH_PRE:
			case PDO_PARAM_EVT_FETCH_POST:
			case PDO_PARAM_EVT_NORMALIZE:
				/* Do nothing */
				break;

			case PDO_PARAM_EVT_FREE:
				P = param->driver_data;
				if (P) {
					efree(P);
				}
				break;

			case PDO_PARAM_EVT_ALLOC:
			{
				/* figure out what we're doing */
				switch (PDO_PARAM_TYPE(param->param_type)) {
					case PDO_PARAM_LOB:
						break;

					case PDO_PARAM_STMT:
						return 0;
					
					default:
						break;
				}

				rc = SQLDescribeParam(S->stmt, (SQLUSMALLINT) param->paramno+1, &sqltype, &precision, &scale, &nullable);
				if (rc != SQL_SUCCESS && rc != SQL_SUCCESS_WITH_INFO) {
					/* MS Access, for instance, doesn't support SQLDescribeParam,
					 * so we need to guess */
					sqltype = PDO_PARAM_TYPE(param->param_type) == PDO_PARAM_LOB ?
									SQL_LONGVARBINARY :
									SQL_LONGVARCHAR;
					precision = 4000;
					scale = 5;
					nullable = 1;

					if (param->max_value_len > 0) {
						precision = param->max_value_len;
					}
				}
				if (sqltype == SQL_BINARY || sqltype == SQL_VARBINARY || sqltype == SQL_LONGVARBINARY) {
					ctype = SQL_C_BINARY;
				} else {
					ctype = SQL_C_CHAR;
				}

				P = emalloc(sizeof(*P));
				param->driver_data = P;

				P->len = 0; /* is re-populated each EXEC_PRE */
				P->outbuf = NULL;

				P->is_unicode = pdo_odbc_sqltype_is_unicode(S, sqltype);
				if (P->is_unicode) {
					/* avoid driver auto-translation: we'll do it ourselves */
					ctype = SQL_C_BINARY;
				}

				if ((param->param_type & PDO_PARAM_INPUT_OUTPUT) == PDO_PARAM_INPUT_OUTPUT) {
					P->paramtype = SQL_PARAM_INPUT_OUTPUT;
				} else if (param->max_value_len <= 0) {
					P->paramtype = SQL_PARAM_INPUT;
				} else {
					P->paramtype = SQL_PARAM_OUTPUT;
				}
				
				if (P->paramtype != SQL_PARAM_INPUT) {
					if (PDO_PARAM_TYPE(param->param_type) != PDO_PARAM_NULL) {
						/* need an explicit buffer to hold result */
						P->len = param->max_value_len > 0 ? param->max_value_len : precision;
						if (P->is_unicode) {
							P->len *= 2;
						}
						P->outbuf = emalloc(P->len + (P->is_unicode ? 2:1));
					}
				}
				
				if (PDO_PARAM_TYPE(param->param_type) == PDO_PARAM_LOB && P->paramtype != SQL_PARAM_INPUT) {
					pdo_odbc_stmt_error("Can't bind a lob for output");
					return 0;
				}

				rc = SQLBindParameter(S->stmt, (SQLUSMALLINT) param->paramno+1,
						P->paramtype, ctype, sqltype, precision, scale,
						P->paramtype == SQL_PARAM_INPUT ? 
							(SQLPOINTER)param :
							P->outbuf,
						P->len,
						&P->len
						);
	
				if (rc == SQL_SUCCESS || rc == SQL_SUCCESS_WITH_INFO) {
					return 1;
				}
				pdo_odbc_stmt_error("SQLBindParameter");
				return 0;
			}

			case PDO_PARAM_EVT_EXEC_PRE:
				P = param->driver_data;
				if (!Z_ISREF(param->parameter)) {
					parameter = &param->parameter;
				} else {
					parameter = Z_REFVAL(param->parameter);
				}

				if (PDO_PARAM_TYPE(param->param_type) == PDO_PARAM_LOB) {
					if (Z_TYPE_P(parameter) == IS_RESOURCE) {
						php_stream *stm;
						php_stream_statbuf sb;

						php_stream_from_zval_no_verify(stm, parameter);

						if (!stm) {
							return 0;
						}

						if (0 == php_stream_stat(stm, &sb)) {
							if (P->outbuf) {
								int len, amount;
								char *ptr = P->outbuf;
								char *end = P->outbuf + P->len;

								P->len = 0;
								do {
									amount = end - ptr;
									if (amount == 0) {
										break;
									}
									if (amount > 8192)
										amount = 8192;
									len = php_stream_read(stm, ptr, amount);
									if (len == 0) {
										break;
									}
									ptr += len;
									P->len += len;
								} while (1);

							} else {
								P->len = SQL_LEN_DATA_AT_EXEC(sb.sb.st_size);
							}
						} else {
							if (P->outbuf) {
								P->len = 0;
							} else {
								P->len = SQL_LEN_DATA_AT_EXEC(0);
							}
						}
					} else {
						convert_to_string(parameter);
						if (P->outbuf) {
							P->len = Z_STRLEN_P(parameter);
							memcpy(P->outbuf, Z_STRVAL_P(parameter), P->len);
						} else {
							P->len = SQL_LEN_DATA_AT_EXEC(Z_STRLEN_P(parameter));
						}
					}
				} else if (Z_TYPE_P(parameter) == IS_NULL || PDO_PARAM_TYPE(param->param_type) == PDO_PARAM_NULL) {
					P->len = SQL_NULL_DATA;
				} else {
					convert_to_string(parameter);
					if (P->outbuf) {
						zend_ulong ulen;
						switch (pdo_odbc_utf82ucs2(stmt, P->is_unicode,
								Z_STRVAL_P(parameter),
								Z_STRLEN_P(parameter),
								&ulen)) {
							case PDO_ODBC_CONV_FAIL:
							case PDO_ODBC_CONV_NOT_REQUIRED:
								P->len = Z_STRLEN_P(parameter);
								memcpy(P->outbuf, Z_STRVAL_P(parameter), P->len);
								break;
							case PDO_ODBC_CONV_OK:
								P->len = ulen;
								memcpy(P->outbuf, S->convbuf, P->len);
								break;
						}
					} else {
						P->len = SQL_LEN_DATA_AT_EXEC(Z_STRLEN_P(parameter));
					}
				}
				return 1;
			
			case PDO_PARAM_EVT_EXEC_POST:
				P = param->driver_data;

				if (P->outbuf) {
					zend_ulong ulen;
					char *srcbuf;
					zend_ulong srclen = 0;

					if (Z_ISREF(param->parameter)) {
						parameter = Z_REFVAL(param->parameter);
					} else {
						parameter = &param->parameter;
					}
					zval_ptr_dtor(parameter);
					ZVAL_NULL(parameter);

					switch (P->len) {
						case SQL_NULL_DATA:
							break;
						default:
							switch (pdo_odbc_ucs22utf8(stmt, P->is_unicode, P->outbuf, P->len, &ulen)) {
								case PDO_ODBC_CONV_FAIL:
									/* something fishy, but allow it to come back as binary */
								case PDO_ODBC_CONV_NOT_REQUIRED:
									srcbuf = P->outbuf;
									srclen = P->len;
									break;
								case PDO_ODBC_CONV_OK:
									srcbuf = S->convbuf;
									srclen = ulen;
									break;
							}
										
							ZVAL_NEW_STR(parameter, zend_string_alloc(srclen, 0));
							memcpy(Z_STRVAL_P(parameter), srcbuf, srclen);
							Z_STRVAL_P(parameter)[Z_STRLEN_P(parameter)] = '\0';
					}
				}
				return 1;
		}
	}
	return 1;
}
コード例 #27
0
ファイル: hash.c プロジェクト: Bharath2796/php-src
static void php_hash_do_hash(INTERNAL_FUNCTION_PARAMETERS, int isfilename, zend_bool raw_output_default) /* {{{ */
{
	zend_string *digest;
	char *algo, *data;
	size_t algo_len, data_len;
	zend_bool raw_output = raw_output_default;
	const php_hash_ops *ops;
	void *context;
	php_stream *stream = NULL;

	if (zend_parse_parameters(ZEND_NUM_ARGS(), "ss|b", &algo, &algo_len, &data, &data_len, &raw_output) == FAILURE) {
		return;
	}

	ops = php_hash_fetch_ops(algo, algo_len);
	if (!ops) {
		php_error_docref(NULL, E_WARNING, "Unknown hashing algorithm: %s", algo);
		RETURN_FALSE;
	}
	if (isfilename) {
		if (CHECK_NULL_PATH(data, data_len)) {
			php_error_docref(NULL, E_WARNING, "Invalid path");
			RETURN_FALSE;
		}
		stream = php_stream_open_wrapper_ex(data, "rb", REPORT_ERRORS, NULL, FG(default_context));
		if (!stream) {
			/* Stream will report errors opening file */
			RETURN_FALSE;
		}
	}

	context = emalloc(ops->context_size);
	ops->hash_init(context);

	if (isfilename) {
		char buf[1024];
		size_t n;

		while ((n = php_stream_read(stream, buf, sizeof(buf))) > 0) {
			ops->hash_update(context, (unsigned char *) buf, n);
		}
		php_stream_close(stream);
	} else {
		ops->hash_update(context, (unsigned char *) data, data_len);
	}

	digest = zend_string_alloc(ops->digest_size, 0);
	ops->hash_final((unsigned char *) ZSTR_VAL(digest), context);
	efree(context);

	if (raw_output) {
		ZSTR_VAL(digest)[ops->digest_size] = 0;
		RETURN_NEW_STR(digest);
	} else {
		zend_string *hex_digest = zend_string_safe_alloc(ops->digest_size, 2, 0, 0);

		php_hash_bin2hex(ZSTR_VAL(hex_digest), (unsigned char *) ZSTR_VAL(digest), ops->digest_size);
		ZSTR_VAL(hex_digest)[2 * ops->digest_size] = 0;
		zend_string_release(digest);
		RETURN_NEW_STR(hex_digest);
	}
}
コード例 #28
0
ファイル: hash.c プロジェクト: 66Ton99/php5.4-ppa
static void php_hash_do_hash_hmac(INTERNAL_FUNCTION_PARAMETERS, int isfilename, zend_bool raw_output_default) /* {{{ */
{
	char *algo, *data, *digest, *key, *K;
	int algo_len, data_len, key_len, i;
	zend_bool raw_output = raw_output_default;
	const php_hash_ops *ops;
	void *context;
	php_stream *stream = NULL;

	if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "sss|b", &algo, &algo_len, &data, &data_len, 
																  &key, &key_len, &raw_output) == FAILURE) {
		return;
	}

	ops = php_hash_fetch_ops(algo, algo_len);
	if (!ops) {
		php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unknown hashing algorithm: %s", algo);
		RETURN_FALSE;
	}
	if (isfilename) {
		stream = php_stream_open_wrapper_ex(data, "rb", REPORT_ERRORS, NULL, DEFAULT_CONTEXT);
		if (!stream) {
			/* Stream will report errors opening file */
			RETURN_FALSE;
		}
	}

	context = emalloc(ops->context_size);
	ops->hash_init(context);

	K = emalloc(ops->block_size);
	memset(K, 0, ops->block_size);

	if (key_len > ops->block_size) {
		/* Reduce the key first */
		ops->hash_update(context, (unsigned char *) key, key_len);
		ops->hash_final((unsigned char *) K, context);
		/* Make the context ready to start over */
		ops->hash_init(context);
	} else {
		memcpy(K, key, key_len);
	}
			
	/* XOR ipad */
	for(i=0; i < ops->block_size; i++) {
		K[i] ^= 0x36;
	}
	ops->hash_update(context, (unsigned char *) K, ops->block_size);

	if (isfilename) {
		char buf[1024];
		int n;

		while ((n = php_stream_read(stream, buf, sizeof(buf))) > 0) {
			ops->hash_update(context, (unsigned char *) buf, n);
		}
		php_stream_close(stream);
	} else {
		ops->hash_update(context, (unsigned char *) data, data_len);
	}

	digest = emalloc(ops->digest_size + 1);
	ops->hash_final((unsigned char *) digest, context);

	/* Convert K to opad -- 0x6A = 0x36 ^ 0x5C */
	for(i=0; i < ops->block_size; i++) {
		K[i] ^= 0x6A;
	}

	/* Feed this result into the outter hash */
	ops->hash_init(context);
	ops->hash_update(context, (unsigned char *) K, ops->block_size);
	ops->hash_update(context, (unsigned char *) digest, ops->digest_size);
	ops->hash_final((unsigned char *) digest, context);

	/* Zero the key */
	memset(K, 0, ops->block_size);
	efree(K);
	efree(context);

	if (raw_output) {
		digest[ops->digest_size] = 0;
		RETURN_STRINGL(digest, ops->digest_size, 0);
	} else {
		char *hex_digest = safe_emalloc(ops->digest_size, 2, 1);

		php_hash_bin2hex(hex_digest, (unsigned char *) digest, ops->digest_size);
		hex_digest[2 * ops->digest_size] = 0;
		efree(digest);
		RETURN_STRINGL(hex_digest, 2 * ops->digest_size, 0);
	}
}
コード例 #29
0
ファイル: exec.c プロジェクト: EvgeniySpinov/php-src
/* {{{ php_exec
 * If type==0, only last line of output is returned (exec)
 * If type==1, all lines will be printed and last lined returned (system)
 * If type==2, all lines will be saved to given array (exec with &$array)
 * If type==3, output will be printed binary, no lines will be saved or returned (passthru)
 *
 */
PHPAPI int php_exec(int type, char *cmd, zval *array, zval *return_value)
{
	FILE *fp;
	char *buf;
	size_t l = 0;
	int pclose_return;
	char *b, *d=NULL;
	php_stream *stream;
	size_t buflen, bufl = 0;
#if PHP_SIGCHILD
	void (*sig_handler)() = NULL;
#endif

#if PHP_SIGCHILD
	sig_handler = signal (SIGCHLD, SIG_DFL);
#endif

#ifdef PHP_WIN32
	fp = VCWD_POPEN(cmd, "rb");
#else
	fp = VCWD_POPEN(cmd, "r");
#endif
	if (!fp) {
		php_error_docref(NULL, E_WARNING, "Unable to fork [%s]", cmd);
		goto err;
	}

	stream = php_stream_fopen_from_pipe(fp, "rb");

	buf = (char *) emalloc(EXEC_INPUT_BUF);
	buflen = EXEC_INPUT_BUF;

	if (type != 3) {
		b = buf;

		while (php_stream_get_line(stream, b, EXEC_INPUT_BUF, &bufl)) {
			/* no new line found, let's read some more */
			if (b[bufl - 1] != '\n' && !php_stream_eof(stream)) {
				if (buflen < (bufl + (b - buf) + EXEC_INPUT_BUF)) {
					bufl += b - buf;
					buflen = bufl + EXEC_INPUT_BUF;
					buf = erealloc(buf, buflen);
					b = buf + bufl;
				} else {
					b += bufl;
				}
				continue;
			} else if (b != buf) {
				bufl += b - buf;
			}

			if (type == 1) {
				PHPWRITE(buf, bufl);
				if (php_output_get_level() < 1) {
					sapi_flush();
				}
			} else if (type == 2) {
				/* strip trailing whitespaces */
				l = bufl;
				while (l >= 1 && l-- && isspace(((unsigned char *)buf)[l]));
				if (l != (bufl - 1)) {
					bufl = l + 1;
					buf[bufl] = '\0';
				}
				add_next_index_stringl(array, buf, bufl);
			}
			b = buf;
		}
		if (bufl) {
			/* strip trailing whitespaces if we have not done so already */
			if ((type == 2 && buf != b) || type != 2) {
				l = bufl;
				while (l >= 1 && l-- && isspace(((unsigned char *)buf)[l]));
				if (l != (bufl - 1)) {
					bufl = l + 1;
					buf[bufl] = '\0';
				}
				if (type == 2) {
					add_next_index_stringl(array, buf, bufl);
				}
			}

			/* Return last line from the shell command */
			RETVAL_STRINGL(buf, bufl);
		} else { /* should return NULL, but for BC we return "" */
			RETVAL_EMPTY_STRING();
		}
	} else {
		while((bufl = php_stream_read(stream, buf, EXEC_INPUT_BUF)) > 0) {
			PHPWRITE(buf, bufl);
		}
	}

	pclose_return = php_stream_close(stream);
	efree(buf);

done:
#if PHP_SIGCHILD
	if (sig_handler) {
		signal(SIGCHLD, sig_handler);
	}
#endif
	if (d) {
		efree(d);
	}
	return pclose_return;
err:
	pclose_return = -1;
	goto done;
}
コード例 #30
0
/* ArchiveWriter::finish {{{
 *
*/
ZEND_METHOD(ArchiveWriter, finish)
{
	zval *this = getThis();
	int resource_id;
	HashPosition pos;
	archive_file_t *arch;
	archive_entry_t **entry;
	int result, error_num;
	const char *error_string;
	mode_t mode;
	php_stream *stream;
	zend_error_handling error_handling;

	zend_replace_error_handling(EH_THROW, ce_ArchiveException, &error_handling TSRMLS_CC);

	if (!_archive_get_fd(this, &arch TSRMLS_CC)) {
		zend_restore_error_handling(&error_handling TSRMLS_CC);
		return;
	}

	if (zend_hash_sort(arch->entries, zend_qsort, _archive_pathname_compare, 0 TSRMLS_CC) == FAILURE) {
		RETURN_FALSE;
	}

	zend_hash_internal_pointer_reset_ex(arch->entries, &pos);
	while (zend_hash_get_current_data_ex(arch->entries, (void **)&entry, &pos) == SUCCESS) {

		mode = archive_entry_mode((*entry)->entry);

		if (S_ISREG(mode) && archive_entry_size((*entry)->entry) > 0) {
			if ((stream = php_stream_open_wrapper_ex((*entry)->filename, "r", ENFORCE_SAFE_MODE | REPORT_ERRORS, NULL, NULL))) {
				char buf[PHP_ARCHIVE_BUF_LEN];
				int header_written=0;
				int read_bytes;

				while ((read_bytes = php_stream_read(stream, buf, PHP_ARCHIVE_BUF_LEN))) {
					if (!header_written) {
						/* write header only after the first successful read */
						result = archive_write_header(arch->arch, (*entry)->entry);
						if (result == ARCHIVE_FATAL) {
							php_error_docref(NULL TSRMLS_CC, E_WARNING, "Failed to write entry header for file %s: fatal error", (*entry)->filename);
							zend_restore_error_handling(&error_handling TSRMLS_CC);
							return;
						}
						header_written = 1;
					}
					result = archive_write_data(arch->arch, buf, read_bytes);

					if (result <= 0) {
						error_num = archive_errno(arch->arch);
						error_string = archive_error_string(arch->arch);

						if (error_num && error_string) {
							php_error_docref(NULL TSRMLS_CC, E_WARNING, "Failed to write file %s to archive: error #%d, %s", (*entry)->filename, error_num, error_string);
						}
						else {
							php_error_docref(NULL TSRMLS_CC, E_WARNING, "Failed to write file %s: unknown error %d", (*entry)->filename, result);
						}
						php_stream_close(stream);
						zend_restore_error_handling(&error_handling TSRMLS_CC);
						return;
					}
				}
				php_stream_close(stream);
			}
		}
		else {
			result = archive_write_header(arch->arch, (*entry)->entry);
			if (result == ARCHIVE_FATAL) {
				php_error_docref(NULL TSRMLS_CC, E_WARNING, "Failed to write entry header for file %s: fatal error", (*entry)->filename);
				zend_restore_error_handling(&error_handling TSRMLS_CC);
				return;
			}
		}
		zend_hash_move_forward_ex(arch->entries, &pos);
	}

	if ((resource_id = _archive_get_rsrc_id(this TSRMLS_CC))) {
		add_property_resource(this, "fd", 0);
		zend_list_delete(resource_id);
		zend_restore_error_handling(&error_handling TSRMLS_CC);
		RETURN_TRUE;
	}

	php_error_docref(NULL TSRMLS_CC, E_WARNING, "Failed to finish writing of archive file");
	zend_restore_error_handling(&error_handling TSRMLS_CC);
}