Diff

Differences From Artifact [70718fd2dc]:

To Artifact [a228e5eaeb]:


   381    381   	Tcl_WideInt attr_value_wide;
   382    382   	int attr_value_int;
   383    383   	static __thread Tcl_Obj *attr_key_type = NULL, *attr_key_perms = NULL, *attr_key_size = NULL, *attr_key_time = NULL, *attr_key_source = NULL, *attr_key_childcount = NULL;
   384    384   	int tcl_ret;
   385    385   
   386    386   	interp = appfs_TclInterp();
   387    387   	if (interp == NULL) {
   388         -		return(1);
          388  +		return(-EIO);
   389    389   	}
   390    390   
   391    391   	tcl_ret = appfs_Tcl_Eval(interp, 2, "::appfs::getattr", path);
   392    392   	if (tcl_ret != TCL_OK) {
   393    393   		APPFS_DEBUG("::appfs::getattr(%s) failed.", path);
   394    394   		APPFS_DEBUG("Tcl Error is: %s", Tcl_GetStringResult(interp));
   395    395   
   396         -		return(1);
          396  +		return(-ENOENT);
   397    397   	}
   398    398   
   399    399   	if (attr_key_type == NULL) {
   400    400   		attr_key_type       = Tcl_NewStringObj("type", -1);
   401    401   		attr_key_perms      = Tcl_NewStringObj("perms", -1);
   402    402   		attr_key_size       = Tcl_NewStringObj("size", -1);
   403    403   		attr_key_time       = Tcl_NewStringObj("time", -1);
................................................................................
   407    407   
   408    408   	attrs_dict = Tcl_GetObjResult(interp);
   409    409   	tcl_ret = Tcl_DictObjGet(interp, attrs_dict, attr_key_type, &attr_value);
   410    410   	if (tcl_ret != TCL_OK) {
   411    411   		APPFS_DEBUG("[dict get \"type\"] failed");
   412    412   		APPFS_DEBUG("Tcl Error is: %s", Tcl_GetStringResult(interp));
   413    413   
   414         -		return(1);
          414  +		return(-EIO);
   415    415   	}
   416    416   
   417    417   	if (attr_value == NULL) {
   418         -		return(1);
          418  +		return(-EIO);
   419    419   	}
   420    420   
   421    421   	pathinfo->packaged = 0;
          422  +	pathinfo->inode = appfs_get_path_inode(path);
   422    423   
   423    424   	attr_value_str = Tcl_GetString(attr_value);
   424    425   	switch (attr_value_str[0]) {
   425    426   		case 'd': /* directory */
   426    427   			pathinfo->type = APPFS_PATHTYPE_DIRECTORY;
   427    428   			pathinfo->typeinfo.dir.childcount = 0;
   428    429   
................................................................................
   470    471   					pathinfo->typeinfo.symlink.source[attr_value_int] = '\0';
   471    472   
   472    473   					memcpy(pathinfo->typeinfo.symlink.source, attr_value_str, attr_value_int);
   473    474   				}
   474    475   			}
   475    476   			break;
   476    477   		default:
   477         -			return(1);
          478  +			return(-EIO);
   478    479   	}
   479    480   
   480    481   	Tcl_DictObjGet(interp, attrs_dict, attr_key_time, &attr_value);
   481    482   	if (attr_value != NULL) {
   482    483   		tcl_ret = Tcl_GetWideIntFromObj(NULL, attr_value, &attr_value_wide);
   483    484   		if (tcl_ret == TCL_OK) {
   484    485   			pathinfo->time = attr_value_wide;
................................................................................
   575    576   }
   576    577   
   577    578   static int appfs_fuse_readdir(const char *path, void *buf, fuse_fill_dir_t filler, off_t offset, struct fuse_file_info *fi) {
   578    579   	Tcl_Interp *interp;
   579    580   	Tcl_Obj **children;
   580    581   	int children_count, idx;
   581    582   	int tcl_ret;
   582         -	int retval;
   583    583   
   584    584   	APPFS_DEBUG("Enter (path = %s, ...)", path);
   585    585   
   586    586   	interp = appfs_TclInterp();
   587    587   	if (interp == NULL) {
   588    588   		return(0);
   589    589   	}
................................................................................
   591    591   	filler(buf, ".", NULL, 0);
   592    592   	filler(buf, "..", NULL, 0);
   593    593   
   594    594   	tcl_ret = appfs_Tcl_Eval(interp, 2, "::appfs::getchildren", path);
   595    595   	if (tcl_ret != TCL_OK) {
   596    596   		APPFS_DEBUG("::appfs::getchildren(%s) failed.", path);
   597    597   		APPFS_DEBUG("Tcl Error is: %s", Tcl_GetStringResult(interp));
   598         -		
          598  +
   599    599   		return(0);
   600    600   	}
   601    601   
   602    602   	tcl_ret = Tcl_ListObjGetElements(interp, Tcl_GetObjResult(interp), &children_count, &children);
   603    603   	if (tcl_ret != TCL_OK) {
   604    604   		APPFS_DEBUG("Parsing list of children on path %s failed.", path);
   605    605   		APPFS_DEBUG("Tcl Error is: %s", Tcl_GetStringResult(interp));
   606         -		
          606  +
   607    607   		return(0);
   608    608   	}
   609    609   
   610    610   	for (idx = 0; idx < children_count; idx++) {
   611    611   		filler(buf, Tcl_GetString(children[idx]), NULL, 0);
   612    612   	}
   613    613   
   614    614   	return(0);
   615    615   }
   616    616   
   617    617   static int appfs_fuse_open(const char *path, struct fuse_file_info *fi) {
          618  +	Tcl_Interp *interp;
   618    619   	struct appfs_pathinfo pathinfo;
   619         -	const char *real_path;
          620  +	const char *real_path, *mode;
          621  +	int gpi_ret, tcl_ret;
   620    622   	int fh;
   621         -	int gpi_ret;
   622    623   
   623    624   	APPFS_DEBUG("Enter (path = %s, ...)", path);
   624    625   
   625         -#if 0
          626  +	gpi_ret = appfs_get_path_info(path, &pathinfo);
   626    627   
   627         -	if ((fi->flags & 3) != O_RDONLY) {
   628         -                return(-EACCES);
   629         -	}
          628  +	if ((fi->flags & (O_WRONLY|O_CREAT)) == (O_CREAT|O_WRONLY)) {
          629  +		/* The file will be created if it does not exist */
          630  +		if (gpi_ret != 0 && gpi_ret != -ENOENT) {
          631  +			return(gpi_ret);
          632  +		}
   630    633   
   631         -	gpi_ret = appfs_get_path_info(path, &pathinfo, NULL);
   632         -	if (gpi_ret != 0) {
   633         -		return(gpi_ret);
          634  +		mode = "create";
          635  +	} else {
          636  +		/* The file must already exist */
          637  +		if (gpi_ret != 0) {
          638  +			return(gpi_ret);
          639  +		}
          640  +
          641  +		mode = "";
   634    642   	}
   635    643   
   636    644   	if (pathinfo.type == APPFS_PATHTYPE_DIRECTORY) {
   637    645   		return(-EISDIR);
   638    646   	}
   639    647   
   640         -	real_path = appfs_getfile(pathinfo.hostname, pathinfo.typeinfo.file.sha1);
          648  +	interp = appfs_TclInterp();
          649  +	if (interp == NULL) {
          650  +		return(-EIO);
          651  +	}
          652  +
          653  +	tcl_ret = appfs_Tcl_Eval(interp, 3, "::appfs::openpath", path, mode);
          654  +	if (tcl_ret != TCL_OK) {
          655  +		APPFS_DEBUG("::appfs::openpath(%s, %s) failed.", path, mode);
          656  +		APPFS_DEBUG("Tcl Error is: %s", Tcl_GetStringResult(interp));
          657  +
          658  +		return(-EIO);
          659  +	}
          660  +
          661  +	real_path = Tcl_GetStringResult(interp);
   641    662   	if (real_path == NULL) {
   642    663   		return(-EIO);
   643    664   	}
   644    665   
   645         -	fh = open(real_path, O_RDONLY);
   646         -	free((void *) real_path);
          666  +	APPFS_DEBUG("Translated request to open %s to opening %s (mode = \"%s\")", path, real_path, mode);
          667  +
          668  +	fh = open(real_path, fi->flags, 0600);
   647    669   	if (fh < 0) {
   648    670   		return(-EIO);
   649    671   	}
   650    672   
   651    673   	fi->fh = fh;
   652         -#endif
   653    674   
   654    675   	return(0);
   655    676   }
   656    677   
   657    678   static int appfs_fuse_close(const char *path, struct fuse_file_info *fi) {
   658    679   	int close_ret;
   659    680   
................................................................................
   774    795   	.read      = appfs_fuse_read
   775    796   };
   776    797   
   777    798   /*
   778    799    * FUSE option parsing callback
   779    800    */
   780    801   static int appfs_fuse_opt_cb(void *data, const char *arg, int key, struct fuse_args *outargs) {
   781         -	static seen_cachedir = 0;
          802  +	static int seen_cachedir = 0;
   782    803   
   783    804   	if (key == FUSE_OPT_KEY_NONOPT && seen_cachedir == 0) {
   784    805   		seen_cachedir = 1;
   785    806   
   786    807   		appfs_cachedir = strdup(arg);
   787    808   
   788    809   		return(0);