diff --git a/examples/example_1.php b/examples/example_1.php new file mode 100644 index 0000000..5b0ce18 --- /dev/null +++ b/examples/example_1.php @@ -0,0 +1,7 @@ +mount("/tmp/phpfusemount", "allow_other"); +?> diff --git a/examples/example_2.php b/examples/example_2.php new file mode 100644 index 0000000..c657146 --- /dev/null +++ b/examples/example_2.php @@ -0,0 +1,56 @@ + FUSE_DT_DIR); + $retval[".."] = array('type' => FUSE_DT_DIR); + $retval["test.txt"] = array('type' => FUSE_DT_REG); + return 0; + } + + public function getattr($path, &$st) { + $st['dev'] = 0; + $st['ino'] = 0; + $st['mode'] = 0; + $st['nlink'] = 0; + $st['uid'] = 0; + $st['gid'] = 0; + $st['rdev'] = 0; + $st['size'] = 0; + $st['atime'] = 0; + $st['mtime'] = 0; + $st['ctime'] = 0; + $st['blksize'] = 0; + $st['blocks'] = 0; + + if ($path == "/") { + $st['mode'] = FUSE_S_IFDIR | 0775; + $st['nlink'] = 3; + $st['size'] = 0; + } else if ($path == "/test.txt") { + $st['mode'] = FUSE_S_IFREG | 0664; + $st['nlink'] = 1; + $st['size'] = 12; + } + + return 0; + } + public function open($path, $mode) { + return 1; + } + + public function read($path, $fh, $offset, $buf_len, &$buf) { + $buf = "hello world\n"; + return strlen($buf); + } + + public function release($path, $fh) { + return 0; + } +} + +$fuse = new Sample2Fuse(); +$fuse->mount("/tmp/phpfusemount", array("allow_other","debug","uid"=>"20000")); +?> diff --git a/fuse.c b/fuse.c index 91fa53d..4e22e75 100644 --- a/fuse.c +++ b/fuse.c @@ -1556,30 +1556,65 @@ static PHP_METHOD(Fuse, mount) { const char *path = NULL; int path_len = 0; - const char *option = NULL; - int option_len = 0; + zval* optarray; //array of Fuse options + HashTable* opthash; //HashTable of the array + HashPosition optptr; //Pointer to the position in the array + int optsize; //Size of the options array - if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|s", &path, &path_len, &option, &option_len) == FAILURE) { + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|a", &path, &path_len, &optarray) == FAILURE) { return; } FUSEG(active_object) = object; - // currently no mount options are supported:( - int argc = 2; - if (option && option_len > 0) { - argc += 2; - } - char **argv = emalloc(sizeof(char*)*argc); + opthash=Z_ARRVAL_P(optarray); + optsize=zend_hash_num_elements(opthash); + + int argc = 2+(2*optsize); //2 fixed elements (php_fuse,mountpoint), and optsize additional args and a "-o" per arg + char **argv = safe_emalloc(sizeof(char*),argc,0); + char **elements=safe_emalloc(sizeof(char*),optsize,0); //to store the converted $options entries char *p = estrdup(path); - char *q = estrdup(option); int i = 0; *(argv + i++) = "php_fuse"; - if (option && option_len > 0) { - *(argv + i++) = "-o"; - *(argv + i++) = q; + + //Now join argv with the user-supplied arguments + int j=-1; + zval** data; + for(zend_hash_internal_pointer_reset_ex(opthash, &optptr); zend_hash_get_current_data_ex(opthash, (void**) &data, &optptr) == SUCCESS; zend_hash_move_forward_ex(opthash, &optptr)) { + j++; + char* key; + int key_len; + long index; + + //resulting element + char* element; + int elsize; + + int valtype=Z_TYPE_PP(data); + + if (Z_TYPE_PP(data) != IS_STRING) { //element is not a string, convert instead + zend_error(E_WARNING,"Fuse.mount: Option %d is not a string, but type %d instead. Converting silently.",j,Z_TYPE_PP(data)); + convert_to_string_ex(data); + } + if (zend_hash_get_current_key_ex(opthash, &key, &key_len, &index, 0, &optptr) == HASH_KEY_IS_STRING) { //string=>string + //string key => the end value must be key=value + elsize=key_len+1+Z_STRLEN_PP(data); //key_len+'='+data_len, for unknown reasons one of them includes a nullbyte?! + element=safe_emalloc(elsize,sizeof(char),0); + memset(element,0,elsize); + strncat(element,key,key_len); + strncat(element,"=",1); + strncat(element,Z_STRVAL_PP(data),Z_STRLEN_PP(data)); + + } else { //int (or resource, or whatever)=>string, only use the value + elsize=Z_STRLEN_PP(data); + element=estrdup(Z_STRVAL_PP(data)); + } + *(argv + i++)="-o"; + *(argv + i++)=element; + *(elements + j)=element; } + *(argv + i++) = p; struct fuse_operations op; @@ -1655,9 +1690,12 @@ static PHP_METHOD(Fuse, mount) { fuse_main(argc, argv, &op); - efree(q); efree(p); efree(argv); + + for(i=0;i