static void _php_finfo_get_type(INTERNAL_FUNCTION_PARAMETERS, int mode, int mimetype_emu) /* {{{ */ { zend_long options = 0; char *ret_val = NULL, *buffer = NULL; size_t buffer_len; php_fileinfo *finfo = NULL; zval *zfinfo, *zcontext = NULL; zval *what; char mime_directory[] = "directory"; struct magic_set *magic = NULL; FILEINFO_DECLARE_INIT_OBJECT(object) if (mimetype_emu) { /* mime_content_type(..) emulation */ if (zend_parse_parameters(ZEND_NUM_ARGS(), "z", &what) == FAILURE) { return; } switch (Z_TYPE_P(what)) { case IS_STRING: buffer = Z_STRVAL_P(what); buffer_len = Z_STRLEN_P(what); mode = FILEINFO_MODE_FILE; break; case IS_RESOURCE: mode = FILEINFO_MODE_STREAM; break; default: php_error_docref(NULL, E_WARNING, "Can only process string or stream arguments"); RETURN_FALSE; } magic = magic_open(MAGIC_MIME_TYPE); if (magic_load(magic, NULL) == -1) { php_error_docref(NULL, E_WARNING, "Failed to load magic database."); goto common; } } else if (object) { if (zend_parse_parameters(ZEND_NUM_ARGS(), "s|lr", &buffer, &buffer_len, &options, &zcontext) == FAILURE) { RETURN_FALSE; } FILEINFO_FROM_OBJECT(finfo, object); magic = finfo->magic; } else { if (zend_parse_parameters(ZEND_NUM_ARGS(), "rs|lr", &zfinfo, &buffer, &buffer_len, &options, &zcontext) == FAILURE) { RETURN_FALSE; } if ((finfo = (php_fileinfo *)zend_fetch_resource(Z_RES_P(zfinfo), "file_info", le_fileinfo)) == NULL) { RETURN_FALSE; } magic = finfo->magic; } /* Set options for the current file/buffer. */ if (options) { FINFO_SET_OPTION(magic, options) } switch (mode) { case FILEINFO_MODE_BUFFER: { ret_val = (char *) magic_buffer(magic, buffer, buffer_len); break; } case FILEINFO_MODE_STREAM: { php_stream *stream; zend_off_t streampos; php_stream_from_zval_no_verify(stream, what); if (!stream) { goto common; } streampos = php_stream_tell(stream); /* remember stream position for restoration */ php_stream_seek(stream, 0, SEEK_SET); ret_val = (char *) magic_stream(magic, stream); php_stream_seek(stream, streampos, SEEK_SET); break; } case FILEINFO_MODE_FILE: { /* determine if the file is a local file or remote URL */ const char *tmp2; php_stream_wrapper *wrap; php_stream_statbuf ssb; if (buffer == NULL || !*buffer) { php_error_docref(NULL, E_WARNING, "Empty filename or path"); RETVAL_FALSE; goto clean; } wrap = php_stream_locate_url_wrapper(buffer, &tmp2, 0); if (wrap) { php_stream *stream; php_stream_context *context = php_stream_context_from_zval(zcontext, 0); #ifdef PHP_WIN32 if (php_stream_stat_path_ex(buffer, 0, &ssb, context) == SUCCESS) { if (ssb.sb.st_mode & S_IFDIR) { ret_val = mime_directory; goto common; } } #endif #if PHP_API_VERSION < 20100412 stream = php_stream_open_wrapper_ex(buffer, "rb", ENFORCE_SAFE_MODE | REPORT_ERRORS, NULL, context); #else stream = php_stream_open_wrapper_ex(buffer, "rb", REPORT_ERRORS, NULL, context); #endif if (!stream) { RETVAL_FALSE; goto clean; } if (php_stream_stat(stream, &ssb) == SUCCESS) { if (ssb.sb.st_mode & S_IFDIR) { ret_val = mime_directory; } else { ret_val = (char *)magic_stream(magic, stream); } } php_stream_close(stream); } break; } default: php_error_docref(NULL, E_WARNING, "Can only process string or stream arguments"); } common: if (ret_val) { RETVAL_STRING(ret_val); } else { php_error_docref(NULL, E_WARNING, "Failed identify data %d:%s", magic_errno(magic), magic_error(magic)); RETVAL_FALSE; } clean: if (mimetype_emu) { magic_close(magic); } /* Restore options */ if (options) { FINFO_SET_OPTION(magic, finfo->options) } return; }
/* {{{ flatfile_store */ int flatfile_store(flatfile *dba, datum key_datum, datum value_datum, int mode TSRMLS_DC) { if (mode == FLATFILE_INSERT) { if (flatfile_findkey(dba, key_datum TSRMLS_CC)) { return 1; } php_stream_seek(dba->fp, 0L, SEEK_END); php_stream_printf(dba->fp TSRMLS_CC, "%zu\n", key_datum.dsize); php_stream_flush(dba->fp); if (php_stream_write(dba->fp, key_datum.dptr, key_datum.dsize) < key_datum.dsize) { return -1; } php_stream_printf(dba->fp TSRMLS_CC, "%zu\n", value_datum.dsize); php_stream_flush(dba->fp); if (php_stream_write(dba->fp, value_datum.dptr, value_datum.dsize) < value_datum.dsize) { return -1; } } else { /* FLATFILE_REPLACE */ flatfile_delete(dba, key_datum TSRMLS_CC); php_stream_printf(dba->fp TSRMLS_CC, "%zu\n", key_datum.dsize); php_stream_flush(dba->fp); if (php_stream_write(dba->fp, key_datum.dptr, key_datum.dsize) < key_datum.dsize) { return -1; } php_stream_printf(dba->fp TSRMLS_CC, "%zu\n", value_datum.dsize); if (php_stream_write(dba->fp, value_datum.dptr, value_datum.dsize) < value_datum.dsize) { return -1; } } php_stream_flush(dba->fp); return 0; }
static zval* _jsr_file_get_contents() { TSRMLS_FETCH(); zval *payload; MAKE_STD_ZVAL(payload); zend_bool use_include_path = 0; php_stream *stream; int len; long offset = -1; long maxlen = PHP_STREAM_COPY_ALL; zval *zcontext = NULL; php_stream_context *context = NULL; char *contents; context = php_stream_context_from_zval(zcontext, 0); stream = php_stream_open_wrapper_ex("php://input", "rb", (use_include_path ? USE_PATH : 0) | ENFORCE_SAFE_MODE | REPORT_ERRORS, NULL, context); if (!stream) { ZVAL_NULL(payload); php_stream_close(stream); return payload; } if (offset > 0 && php_stream_seek(stream, offset, SEEK_SET) < 0) { php_error_docref(NULL TSRMLS_CC, E_WARNING, "Failed to seek to position %ld in the stream", offset); php_stream_close(stream); ZVAL_NULL(payload); return payload; } if ((len = php_stream_copy_to_mem(stream, &contents, maxlen, 0)) > 0) { #if PHP_API_VERSION < 20100412 if (PG(magic_quotes_runtime)) { contents = php_addslashes(contents, len, &len, 1 TSRMLS_CC); } #endif ZVAL_STRINGL(payload, contents, len, 1); php_stream_close(stream); return payload; } else if (len == 0) { ZVAL_STRING(payload, "", 0); php_stream_close(stream); return payload; } else { ZVAL_NULL(payload); php_stream_close(stream); return payload; } }
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; }
/* {{{ inifile_filter * copy from to dba while ignoring key name (group must equal) */ static int inifile_filter(inifile *dba, inifile *from, const key_type *key, zend_bool *found) { size_t pos_start = 0, pos_next = 0, pos_curr; int ret = SUCCESS; line_type ln = {{NULL,NULL},{NULL}}; php_stream_seek(from->fp, 0, SEEK_SET); php_stream_seek(dba->fp, 0, SEEK_END); while(inifile_read(from, &ln)) { switch(inifile_key_cmp(&ln.key, key)) { case 0: if (found) { *found = (zend_bool) 1; } pos_curr = php_stream_tell(from->fp); if (pos_start != pos_next) { php_stream_seek(from->fp, pos_start, SEEK_SET); if (SUCCESS != php_stream_copy_to_stream_ex(from->fp, dba->fp, pos_next - pos_start, NULL)) { php_error_docref(NULL, E_WARNING, "Could not copy [%zu - %zu] from temporary stream", pos_next, pos_start); ret = FAILURE; } php_stream_seek(from->fp, pos_curr, SEEK_SET); } pos_next = pos_start = pos_curr; break; case 1: pos_next = php_stream_tell(from->fp); break; case 2: /* the function is meant to process only entries from same group */ assert(0); break; } } if (pos_start != pos_next) { php_stream_seek(from->fp, pos_start, SEEK_SET); if (SUCCESS != php_stream_copy_to_stream_ex(from->fp, dba->fp, pos_next - pos_start, NULL)) { php_error_docref(NULL, E_WARNING, "Could not copy [%zu - %zu] from temporary stream", pos_next, pos_start); ret = FAILURE; } } inifile_line_free(&ln); return ret; }
static int stream_cookie_seeker(void *cookie, __off64_t *position, int whence) { *position = php_stream_seek((php_stream *)cookie, (zend_off_t)*position, whence); if (*position == -1) { return -1; } return 0; }
static int stream_cookie_seeker(void *cookie, __off64_t *position, int whence) { TSRMLS_FETCH(); *position = php_stream_seek((php_stream *)cookie, (off_t)*position, whence); if (*position == -1) return -1; return 0; }
/* {{{ inifile_truncate */ static int inifile_truncate(inifile *dba, size_t size) { int res; if ((res=php_stream_truncate_set_size(dba->fp, size)) != 0) { php_error_docref(NULL, E_WARNING, "Error in ftruncate: %d", res); return FAILURE; } php_stream_seek(dba->fp, size, SEEK_SET); return SUCCESS; }
/* {{{ inifile_nextkey */ int inifile_nextkey(inifile *dba) { line_type ln = {{NULL,NULL},{NULL}}; /*inifile_line_free(&dba->next); ??? */ php_stream_seek(dba->fp, dba->curr.pos, SEEK_SET); ln.key.group = estrdup(dba->curr.key.group ? dba->curr.key.group : ""); inifile_read(dba, &ln); inifile_line_free(&dba->curr); dba->curr = ln; return ln.key.group || ln.key.name; }
static int php_stream_input_seek(php_stream *stream, zend_off_t offset, int whence, zend_off_t *newoffset) /* {{{ */ { php_stream_input_t *input = stream->abstract; if (input->body) { int sought = php_stream_seek(input->body, offset, whence); *newoffset = (input->body)->position; return sought; } return -1; }
PHPAPI int _php_stream_mmap_unmap_ex(php_stream *stream, zend_off_t readden) { int ret = 1; if (php_stream_seek(stream, readden, SEEK_CUR) != 0) { ret = 0; } if (php_stream_mmap_unmap(stream) == 0) { ret = 0; } return ret; }
/* 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); }
/* {{{ 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; }
/* {{{ inifile_fetch */ val_type inifile_fetch(inifile *dba, const key_type *key, int skip) { line_type ln = {{NULL,NULL},{NULL}}; val_type val; int res, grp_eq = 0; if (skip == -1 && dba->next.key.group && dba->next.key.name && !inifile_key_cmp(&dba->next.key, key)) { /* we got position already from last fetch */ php_stream_seek(dba->fp, dba->next.pos, SEEK_SET); ln.key.group = estrdup(dba->next.key.group); } else { /* specific instance or not same key -> restart search */ /* the slow way: restart and seacrch */ php_stream_rewind(dba->fp); inifile_line_free(&dba->next); } if (skip == -1) { skip = 0; } while(inifile_read(dba, &ln)) { if (!(res=inifile_key_cmp(&ln.key, key))) { if (!skip) { val.value = estrdup(ln.val.value ? ln.val.value : ""); /* allow faster access by updating key read into next */ inifile_line_free(&dba->next); dba->next = ln; dba->next.pos = php_stream_tell(dba->fp); return val; } skip--; } else if (res == 1) { grp_eq = 1; } else if (grp_eq) { /* we are leaving group now: that means we cannot find the key */ break; } } inifile_line_free(&ln); dba->next.pos = php_stream_tell(dba->fp); return ln.val; }
/* {{{ 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; }
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(); } }
static PHP_FPOS_T stream_cookie_seeker(void *cookie, zend_off_t position, int whence) { return (PHP_FPOS_T)php_stream_seek((php_stream *)cookie, position, whence); }
static int stream_cookie_seeker(void *cookie, zend_off_t position, int whence) { return php_stream_seek((php_stream *)cookie, position, whence); }
/* {{{ inifile_delete_replace_append */ static int inifile_delete_replace_append(inifile *dba, const key_type *key, const val_type *value, int append, zend_bool *found) { size_t pos_grp_start=0, pos_grp_next; inifile *ini_tmp = NULL; php_stream *fp_tmp = NULL; int ret; /* 1) Search group start * 2) Search next group * 3) If not append: Copy group to ini_tmp * 4) Open temp_stream and copy remainder * 5) Truncate stream * 6) If not append AND key.name given: Filtered copy back from ini_tmp * to stream. Otherwise the user wanted to delete the group. * 7) Append value if given * 8) Append temporary stream */ assert(!append || (key->name && value)); /* missuse */ /* 1 - 3 */ inifile_find_group(dba, key, &pos_grp_start); inifile_next_group(dba, key, &pos_grp_next); if (append) { ret = SUCCESS; } else { ret = inifile_copy_to(dba, pos_grp_start, pos_grp_next, &ini_tmp); } /* 4 */ if (ret == SUCCESS) { fp_tmp = php_stream_temp_create(0, 64 * 1024); if (!fp_tmp) { php_error_docref(NULL, E_WARNING, "Could not create temporary stream"); ret = FAILURE; } else { php_stream_seek(dba->fp, 0, SEEK_END); if (pos_grp_next != (size_t)php_stream_tell(dba->fp)) { php_stream_seek(dba->fp, pos_grp_next, SEEK_SET); if (SUCCESS != php_stream_copy_to_stream_ex(dba->fp, fp_tmp, PHP_STREAM_COPY_ALL, NULL)) { php_error_docref(NULL, E_WARNING, "Could not copy remainder to temporary stream"); ret = FAILURE; } } } } /* 5 */ if (ret == SUCCESS) { if (!value || (key->name && strlen(key->name))) { ret = inifile_truncate(dba, append ? pos_grp_next : pos_grp_start); /* writes error on fail */ } } if (ret == SUCCESS) { if (key->name && strlen(key->name)) { /* 6 */ if (!append && ini_tmp) { ret = inifile_filter(dba, ini_tmp, key, found); } /* 7 */ /* important: do not query ret==SUCCESS again: inifile_filter might fail but * however next operation must be done. */ if (value) { if (pos_grp_start == pos_grp_next && key->group && strlen(key->group)) { php_stream_printf(dba->fp, "[%s]\n", key->group); } php_stream_printf(dba->fp, "%s=%s\n", key->name, value->value ? value->value : ""); } } /* 8 */ /* important: do not query ret==SUCCESS again: inifile_filter might fail but * however next operation must be done. */ if (fp_tmp && php_stream_tell(fp_tmp)) { php_stream_seek(fp_tmp, 0, SEEK_SET); php_stream_seek(dba->fp, 0, SEEK_END); if (SUCCESS != php_stream_copy_to_stream_ex(fp_tmp, dba->fp, PHP_STREAM_COPY_ALL, NULL)) { zend_throw_error(NULL, "Could not copy from temporary stream - ini file truncated"); ret = FAILURE; } } } if (ini_tmp) { php_stream_close(ini_tmp->fp); inifile_free(ini_tmp, 0); } if (fp_tmp) { php_stream_close(fp_tmp); } php_stream_flush(dba->fp); php_stream_seek(dba->fp, 0, SEEK_SET); return ret; }
zend_off_t cdb_file_lseek(php_stream *fp, zend_off_t offset, int whence) { php_stream_seek(fp, offset, whence); return php_stream_tell(fp); }
int cdb_file_lseek(php_stream *fp, off_t offset, int whence TSRMLS_DC) { php_stream_seek(fp, offset, whence); return php_stream_tell(fp); }
static fpos_t stream_cookie_seeker(void *cookie, off_t position, int whence) { TSRMLS_FETCH(); return (fpos_t)php_stream_seek((php_stream *)cookie, position, whence); }