Diff

Differences From Artifact [16b07e2510]:

To Artifact [70718fd2dc]:


    39     39   
    40     40   /*
    41     41    * Global variables, needed for all threads but only initialized before any
    42     42    * FUSE threads are created
    43     43    */
    44     44   const char *appfs_cachedir;
    45     45   time_t appfs_boottime;
           46  +int appfs_fuse_started = 0;
    46     47   
    47     48   /*
    48     49    * AppFS Path Type:  Describes the type of path a given file is
    49     50    */
    50     51   typedef enum {
    51     52   	APPFS_PATHTYPE_INVALID,
    52     53   	APPFS_PATHTYPE_FILE,
    53     54   	APPFS_PATHTYPE_DIRECTORY,
    54     55   	APPFS_PATHTYPE_SYMLINK
    55     56   } appfs_pathtype_t;
    56     57   
    57         -/*
    58         - * AppFS Children Files linked-list
    59         - */
    60         -struct appfs_children {
    61         -	struct appfs_children *_next;
    62         -	char name[256];
    63         -};
    64         -
    65     58   /*
    66     59    * AppFS Path Information:
    67     60    *         Completely describes a specific path, how it should be returned to
    68     61    *         to the kernel
    69     62    */
    70     63   struct appfs_pathinfo {
    71     64   	appfs_pathtype_t type;
................................................................................
   260    253   /*
   261    254    * Determine the UID for the user making the current FUSE filesystem request.
   262    255    * This will be used to lookup the user's home directory so we can search for
   263    256    * locally modified files.
   264    257    */
   265    258   static uid_t appfs_get_fsuid(void) {
   266    259   	struct fuse_context *ctx;
          260  +
          261  +	if (!appfs_fuse_started) {
          262  +		return(getuid());
          263  +	}
   267    264   
   268    265   	ctx = fuse_get_context();
   269    266   	if (ctx == NULL) {
   270    267   		/* Unable to lookup user for some reason */
   271    268   		/* Return an unprivileged user ID */
   272    269   		return(1);
   273    270   	}
................................................................................
   373    370   	retval += 10;
   374    371   	retval %= 4294967296ULL;
   375    372   
   376    373   	return(retval);
   377    374   }
   378    375   
   379    376   /* Get information about a path, and optionally list children */
   380         -static int appfs_get_path_info(const char *_path, struct appfs_pathinfo *pathinfo, struct appfs_children **children) {
          377  +static int appfs_get_path_info(const char *path, struct appfs_pathinfo *pathinfo) {
          378  +	Tcl_Interp *interp;
          379  +	Tcl_Obj *attrs_dict, *attr_value;
          380  +	const char *attr_value_str;
          381  +	Tcl_WideInt attr_value_wide;
          382  +	int attr_value_int;
          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  +	int tcl_ret;
          385  +
          386  +	interp = appfs_TclInterp();
          387  +	if (interp == NULL) {
          388  +		return(1);
          389  +	}
          390  +
          391  +	tcl_ret = appfs_Tcl_Eval(interp, 2, "::appfs::getattr", path);
          392  +	if (tcl_ret != TCL_OK) {
          393  +		APPFS_DEBUG("::appfs::getattr(%s) failed.", path);
          394  +		APPFS_DEBUG("Tcl Error is: %s", Tcl_GetStringResult(interp));
          395  +
          396  +		return(1);
          397  +	}
          398  +
          399  +	if (attr_key_type == NULL) {
          400  +		attr_key_type       = Tcl_NewStringObj("type", -1);
          401  +		attr_key_perms      = Tcl_NewStringObj("perms", -1);
          402  +		attr_key_size       = Tcl_NewStringObj("size", -1);
          403  +		attr_key_time       = Tcl_NewStringObj("time", -1);
          404  +		attr_key_source     = Tcl_NewStringObj("source", -1);
          405  +		attr_key_childcount = Tcl_NewStringObj("childcount", -1);
          406  +	}
          407  +
          408  +	attrs_dict = Tcl_GetObjResult(interp);
          409  +	tcl_ret = Tcl_DictObjGet(interp, attrs_dict, attr_key_type, &attr_value);
          410  +	if (tcl_ret != TCL_OK) {
          411  +		APPFS_DEBUG("[dict get \"type\"] failed");
          412  +		APPFS_DEBUG("Tcl Error is: %s", Tcl_GetStringResult(interp));
          413  +
          414  +		return(1);
          415  +	}
          416  +
          417  +	if (attr_value == NULL) {
          418  +		return(1);
          419  +	}
          420  +
          421  +	pathinfo->packaged = 0;
          422  +
          423  +	attr_value_str = Tcl_GetString(attr_value);
          424  +	switch (attr_value_str[0]) {
          425  +		case 'd': /* directory */
          426  +			pathinfo->type = APPFS_PATHTYPE_DIRECTORY;
          427  +			pathinfo->typeinfo.dir.childcount = 0;
          428  +
          429  +			Tcl_DictObjGet(interp, attrs_dict, attr_key_childcount, &attr_value);
          430  +			if (attr_value != NULL) {
          431  +				tcl_ret = Tcl_GetWideIntFromObj(NULL, attr_value, &attr_value_wide);
          432  +				if (tcl_ret == TCL_OK) {
          433  +					pathinfo->typeinfo.dir.childcount = attr_value_wide;
          434  +				}
          435  +			}
          436  +
          437  +			break;
          438  +		case 'f': /* file */
          439  +			pathinfo->type = APPFS_PATHTYPE_FILE;
          440  +			pathinfo->typeinfo.file.size = 0;
          441  +			pathinfo->typeinfo.file.executable = 0;
          442  +
          443  +			Tcl_DictObjGet(interp, attrs_dict, attr_key_size, &attr_value);
          444  +			if (attr_value != NULL) {
          445  +				tcl_ret = Tcl_GetWideIntFromObj(NULL, attr_value, &attr_value_wide);
          446  +				if (tcl_ret == TCL_OK) {
          447  +					pathinfo->typeinfo.file.size = attr_value_wide;
          448  +				}
          449  +			}
          450  +
          451  +			Tcl_DictObjGet(interp, attrs_dict, attr_key_perms, &attr_value);
          452  +			if (attr_value != NULL) {
          453  +				attr_value_str = Tcl_GetString(attr_value);
          454  +				if (attr_value_str[0] == 'x') {
          455  +					pathinfo->typeinfo.file.executable = 1;
          456  +				}
          457  +			}
          458  +			break;
          459  +		case 's': /* symlink */
          460  +			pathinfo->type = APPFS_PATHTYPE_SYMLINK;
          461  +			pathinfo->typeinfo.symlink.size = 0;
          462  +			pathinfo->typeinfo.symlink.source[0] = '\0';
          463  +
          464  +			Tcl_DictObjGet(interp, attrs_dict, attr_key_source, &attr_value);
          465  +			if (attr_value != NULL) {
          466  +				attr_value_str = Tcl_GetStringFromObj(attr_value, &attr_value_int); 
          467  +
          468  +				if ((attr_value_int + 1) <= sizeof(pathinfo->typeinfo.symlink.source)) {
          469  +					pathinfo->typeinfo.symlink.size = attr_value_int;
          470  +					pathinfo->typeinfo.symlink.source[attr_value_int] = '\0';
          471  +
          472  +					memcpy(pathinfo->typeinfo.symlink.source, attr_value_str, attr_value_int);
          473  +				}
          474  +			}
          475  +			break;
          476  +		default:
          477  +			return(1);
          478  +	}
          479  +
          480  +	Tcl_DictObjGet(interp, attrs_dict, attr_key_time, &attr_value);
          481  +	if (attr_value != NULL) {
          482  +		tcl_ret = Tcl_GetWideIntFromObj(NULL, attr_value, &attr_value_wide);
          483  +		if (tcl_ret == TCL_OK) {
          484  +			pathinfo->time = attr_value_wide;
          485  +		}
          486  +	} else {
          487  +		pathinfo->time = 0;
          488  +	}
          489  +
          490  +	return(0);
   381    491   }
   382    492   
   383    493   static int appfs_fuse_readlink(const char *path, char *buf, size_t size) {
   384    494   	struct appfs_pathinfo pathinfo;
   385         -	int res = 0;
          495  +	int retval = 0;
   386    496   
   387    497   	APPFS_DEBUG("Enter (path = %s, ...)", path);
   388    498   
   389    499   	pathinfo.type = APPFS_PATHTYPE_INVALID;
   390    500   
   391         -	res = appfs_get_path_info(path, &pathinfo, NULL);
   392         -	if (res != 0) {
   393         -		return(res);
          501  +	retval = appfs_get_path_info(path, &pathinfo);
          502  +	if (retval != 0) {
          503  +		return(retval);
   394    504   	}
   395    505   
   396    506   	if (pathinfo.type != APPFS_PATHTYPE_SYMLINK) {
   397    507   		return(-EINVAL);
   398    508   	}
   399    509   
   400    510   	if ((strlen(pathinfo.typeinfo.symlink.source) + 1) > size) {
................................................................................
   404    514   	memcpy(buf, pathinfo.typeinfo.symlink.source, strlen(pathinfo.typeinfo.symlink.source) + 1);
   405    515   
   406    516   	return(0);
   407    517   }
   408    518   
   409    519   static int appfs_fuse_getattr(const char *path, struct stat *stbuf) {
   410    520   	struct appfs_pathinfo pathinfo;
   411         -	int res = 0;
          521  +	int retval;
          522  +
          523  +	retval = 0;
   412    524   
   413    525   	APPFS_DEBUG("Enter (path = %s, ...)", path);
   414    526   
   415         -	pathinfo.type = APPFS_PATHTYPE_DIRECTORY;
   416         -	pathinfo.typeinfo.dir.childcount = 0;
          527  +	pathinfo.type = APPFS_PATHTYPE_INVALID;
          528  +
          529  +	retval = appfs_get_path_info(path, &pathinfo);
          530  +	if (retval != 0) {
          531  +		return(retval);
          532  +	}
   417    533   
   418    534   	memset(stbuf, 0, sizeof(struct stat));
   419    535   
   420    536   	stbuf->st_mtime = pathinfo.time;
   421    537   	stbuf->st_ctime = pathinfo.time;
   422    538   	stbuf->st_atime = pathinfo.time;
   423    539   	stbuf->st_ino   = pathinfo.inode;
................................................................................
   440    556   			break;
   441    557   		case APPFS_PATHTYPE_SYMLINK:
   442    558   			stbuf->st_mode = S_IFLNK | 0555;
   443    559   			stbuf->st_nlink = 1;
   444    560   			stbuf->st_size = pathinfo.typeinfo.symlink.size;
   445    561   			break;
   446    562   		case APPFS_PATHTYPE_INVALID:
   447         -			res = -EIO;
          563  +			retval = -EIO;
   448    564   
   449    565   			break;
   450    566   	}
   451    567   
   452    568   	if (pathinfo.packaged) {
   453    569   		if (0) {
   454    570   			stbuf->st_mode |= 0222;
   455    571   		}
   456    572   	}
   457    573   
   458         -	return res;
          574  +	return(retval);
   459    575   }
   460    576   
   461    577   static int appfs_fuse_readdir(const char *path, void *buf, fuse_fill_dir_t filler, off_t offset, struct fuse_file_info *fi) {
   462    578   	Tcl_Interp *interp;
   463    579   	Tcl_Obj **children;
   464    580   	int children_count, idx;
   465    581   	int tcl_ret;
................................................................................
   470    586   	interp = appfs_TclInterp();
   471    587   	if (interp == NULL) {
   472    588   		return(0);
   473    589   	}
   474    590   
   475    591   	filler(buf, ".", NULL, 0);
   476    592   	filler(buf, "..", NULL, 0);
   477         -
   478    593   
   479    594   	tcl_ret = appfs_Tcl_Eval(interp, 2, "::appfs::getchildren", path);
   480    595   	if (tcl_ret != TCL_OK) {
   481    596   		APPFS_DEBUG("::appfs::getchildren(%s) failed.", path);
   482    597   		APPFS_DEBUG("Tcl Error is: %s", Tcl_GetStringResult(interp));
   483    598   		
   484    599   		return(0);
................................................................................
   763    878   		fuse_opt_add_arg(&args, "-oallow_other");
   764    879   	}
   765    880   
   766    881   	/*
   767    882   	 * Enter the FUSE main loop -- this will process any arguments
   768    883   	 * and start servicing requests.
   769    884   	 */
          885  +	appfs_fuse_started = 1;
   770    886   	return(fuse_main(args.argc, args.argv, &appfs_operations, NULL));
   771    887   }
   772    888