Check-in [859535511c]
Overview
Comment:Added symlink support
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA1:859535511cd9b30006912b0f5e743b0671c1cf52
User & Date: rkeene on 2014-09-11 19:57:22
Other Links: manifest | tags
Context
2014-09-12
05:34
Updated to deal with files with commas in the name check-in: 90dbb9682c user: rkeene tags: trunk
2014-09-11
19:57
Added symlink support check-in: 859535511c user: rkeene tags: trunk
2014-09-10
09:14
Minor update check-in: aa1acadcb1 user: rkeene tags: trunk
Changes

Modified appfsd.c from [343214a386] to [56848bb56b].

    50     50   			int childcount;
    51     51   		} dir;
    52     52   		struct {
    53     53   			int executable;
    54     54   			off_t size;
    55     55   			char sha1[41];
    56     56   		} file;
           57  +		struct {
           58  +			off_t size;
           59  +			char source[256];
           60  +		} symlink;
    57     61   	} typeinfo;
    58     62   };
    59     63   
    60     64   struct appfs_sqlite3_query_cb_handle {
    61     65   	struct appfs_children *head;
    62     66   	int argc;
    63     67   	const char *fmt;
................................................................................
   205    209   		APPFS_DEBUG("Call to ::appfs::getpkgmanifest failed: %s", Tcl_GetStringResult(interp));
   206    210   
   207    211   		return;
   208    212   	}
   209    213   
   210    214   	return;
   211    215   }
   212         -
   213    216   
   214    217   #define appfs_free_list_type(id, type) static void appfs_free_list_ ## id(type *head) { \
   215    218   	type *obj, *next; \
   216    219   	for (obj = head; obj; obj = next) { \
   217    220   		next = obj->_next; \
   218    221   		ckfree((void *) obj); \
   219    222   	} \
................................................................................
   434    437   		return(0);
   435    438   	}
   436    439   
   437    440   	if (strcmp(type, "directory") == 0) {
   438    441   		pathinfo->type = APPFS_PATHTYPE_DIRECTORY;
   439    442   		pathinfo->typeinfo.dir.childcount = 0;
   440    443   
          444  +		return(0);
          445  +	}
          446  +
          447  +	if (strcmp(type, "symlink") == 0) {
          448  +		pathinfo->type = APPFS_PATHTYPE_SYMLINK;
          449  +		pathinfo->typeinfo.dir.childcount = 0;
          450  +
          451  +		if (!source) {
          452  +			source = ".BADLINK";
          453  +		}
          454  +
          455  +		pathinfo->typeinfo.symlink.size = strlen(source);
          456  +		snprintf(pathinfo->typeinfo.symlink.source, sizeof(pathinfo->typeinfo.symlink.source), "%s", source);
          457  +
   441    458   		return(0);
   442    459   	}
   443    460   
   444    461   	return(0);
   445    462   
   446    463   	/* Until this is used, prevent the compiler from complaining */
   447    464   	source = source;
................................................................................
   683    700   		}
   684    701   	}
   685    702   
   686    703   	free(path_s);
   687    704   
   688    705   	return(0);
   689    706   }
          707  +
          708  +static int appfs_fuse_readlink(const char *path, char *buf, size_t size) {
          709  +	struct appfs_pathinfo pathinfo;
          710  +	int res = 0;
          711  +
          712  +	APPFS_DEBUG("Enter (path = %s, ...)", path);
          713  +
          714  +	pathinfo.type = APPFS_PATHTYPE_INVALID;
          715  +
          716  +	res = appfs_get_path_info(path, &pathinfo, NULL);
          717  +	if (res != 0) {
          718  +		return(res);
          719  +	}
          720  +
          721  +	if (pathinfo.type != APPFS_PATHTYPE_SYMLINK) {
          722  +		return(-EINVAL);
          723  +	}
          724  +
          725  +	if ((strlen(pathinfo.typeinfo.symlink.source) + 1) > size) {
          726  +		return(-ENAMETOOLONG);
          727  +	}
          728  +
          729  +	memcpy(buf, pathinfo.typeinfo.symlink.source, strlen(pathinfo.typeinfo.symlink.source) + 1);
          730  +
          731  +	return(0);
          732  +}
   690    733   
   691    734   static int appfs_fuse_getattr(const char *path, struct stat *stbuf) {
   692    735   	struct appfs_pathinfo pathinfo;
   693    736   	int res = 0;
   694    737   
   695    738   	APPFS_DEBUG("Enter (path = %s, ...)", path);
          739  +
          740  +	pathinfo.type = APPFS_PATHTYPE_INVALID;
   696    741   
   697    742   	res = appfs_get_path_info(path, &pathinfo, NULL);
   698    743   	if (res != 0) {
   699    744   		return(res);
   700    745   	}
   701    746   
   702    747   	memset(stbuf, 0, sizeof(struct stat));
   703    748   
   704    749   	stbuf->st_mtime = pathinfo.time;
   705    750   	stbuf->st_ctime = pathinfo.time;
   706    751   	stbuf->st_atime = pathinfo.time;
   707    752   
   708         -	if (pathinfo.type == APPFS_PATHTYPE_DIRECTORY) {
   709         -		stbuf->st_mode = S_IFDIR | 0555;
   710         -		stbuf->st_nlink = 2 + pathinfo.typeinfo.dir.childcount;
   711         -	} else {
   712         -		if (pathinfo.typeinfo.file.executable) {
   713         -			stbuf->st_mode = S_IFREG | 0555;
   714         -		} else {
   715         -			stbuf->st_mode = S_IFREG | 0444;
   716         -		}
          753  +	switch (pathinfo.type) {
          754  +		case APPFS_PATHTYPE_DIRECTORY:
          755  +			stbuf->st_mode = S_IFDIR | 0555;
          756  +			stbuf->st_nlink = 2 + pathinfo.typeinfo.dir.childcount;
          757  +			break;
          758  +		case APPFS_PATHTYPE_FILE:
          759  +			if (pathinfo.typeinfo.file.executable) {
          760  +				stbuf->st_mode = S_IFREG | 0555;
          761  +			} else {
          762  +				stbuf->st_mode = S_IFREG | 0444;
          763  +			}
   717    764   
   718         -		stbuf->st_nlink = 1;
   719         -		stbuf->st_size = pathinfo.typeinfo.file.size;
          765  +			stbuf->st_nlink = 1;
          766  +			stbuf->st_size = pathinfo.typeinfo.file.size;
          767  +			break;
          768  +		case APPFS_PATHTYPE_SYMLINK:
          769  +			stbuf->st_mode = S_IFLNK | 0555;
          770  +			stbuf->st_nlink = 1;
          771  +			stbuf->st_size = pathinfo.typeinfo.symlink.size;
          772  +			break;
          773  +		case APPFS_PATHTYPE_INVALID:
          774  +			res = -EIO;
          775  +
          776  +			break;
   720    777   	}
   721    778   
   722    779   	return res;
   723    780   }
   724    781   
   725    782   static int appfs_fuse_readdir(const char *path, void *buf, fuse_fill_dir_t filler, off_t offset, struct fuse_file_info *fi) {
   726    783   	struct appfs_pathinfo pathinfo;
................................................................................
   809    866   
   810    867   	return(read_ret);
   811    868   }
   812    869   
   813    870   static struct fuse_operations appfs_oper = {
   814    871   	.getattr   = appfs_fuse_getattr,
   815    872   	.readdir   = appfs_fuse_readdir,
          873  +	.readlink  = appfs_fuse_readlink,
   816    874   	.open      = appfs_fuse_open,
   817    875   	.release   = appfs_fuse_close,
   818    876   	.read      = appfs_fuse_read
   819    877   };
   820    878   
   821    879   int main(int argc, char **argv) {
   822    880   	const char *cachedir = APPFS_CACHEDIR;