Check-in [dde1c0a38d]
Overview
Comment:Made home directory part user-servicable via config file
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA1:dde1c0a38da539410c69c892aa6a3e005cc24db7
User & Date: rkeene on 2014-11-10 06:47:31
Other Links: manifest | tags
Context
2014-11-10
07:11
Updated ownership/group and disabled all caching so that things are consistent (and slow!) check-in: 6e3b24c68c user: rkeene tags: trunk
06:47
Made home directory part user-servicable via config file check-in: dde1c0a38d user: rkeene tags: trunk
06:19
Updated to deal with having no home directory gracefully and fixed bug introduced with childcount patch check-in: c0f54be8fb user: rkeene tags: trunk
Changes

Modified appfsd.c from [1dcdd9bb28] to [126129663c].

460
461
462
463
464
465
466




















467
468
469
470
471
472
473
...
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
....
1164
1165
1166
1167
1168
1169
1170


1171
1172
1173
1174
1175
1176
1177
}

static int tcl_appfs_simulate_user_fs_leave(ClientData cd, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]) {
	appfs_simulate_user_fs_leave();

	return(TCL_OK);
}





















/*
 * Generate an inode for a given path.  The inode should be computed in such
 * a way that it is unlikely to be duplicated and remains the same for a given
 * file
 */
static long long appfs_get_path_inode(const char *path) {
................................................................................
	memset(stbuf, 0, sizeof(struct stat));

	stbuf->st_mtime = pathinfo.time;
	stbuf->st_ctime = pathinfo.time;
	stbuf->st_atime = pathinfo.time;
	stbuf->st_ino   = pathinfo.inode;
	stbuf->st_mode  = 0;
	stbuf->st_uid   = appfs_get_fsuid();
	stbuf->st_gid   = appfs_get_fsgid();

	switch (pathinfo.type) {
		case APPFS_PATHTYPE_DIRECTORY:
			stbuf->st_mode = S_IFDIR | 0555;
			stbuf->st_nlink = 2 + pathinfo.typeinfo.dir.childcount;
			break;
		case APPFS_PATHTYPE_FILE:
................................................................................
#ifdef USE_TCL_STUBS
	if (Tcl_InitStubs(interp, TCL_VERSION, 0) == 0L) {
		return(TCL_ERROR);
	}
#endif

	Tcl_CreateObjCommand(interp, "appfsd::get_homedir", tcl_appfs_get_homedir, NULL, NULL);


	Tcl_CreateObjCommand(interp, "appfsd::simulate_user_fs_enter", tcl_appfs_simulate_user_fs_enter, NULL, NULL);
	Tcl_CreateObjCommand(interp, "appfsd::simulate_user_fs_leave", tcl_appfs_simulate_user_fs_leave, NULL, NULL);

	Tcl_PkgProvide(interp, "appfsd", "1.0");

	return(TCL_OK);
}







>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>







 







|
|







 







>
>







460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
...
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
....
1184
1185
1186
1187
1188
1189
1190
1191
1192
1193
1194
1195
1196
1197
1198
1199
}

static int tcl_appfs_simulate_user_fs_leave(ClientData cd, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]) {
	appfs_simulate_user_fs_leave();

	return(TCL_OK);
}

static int tcl_appfs_get_fsuid(ClientData cd, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]) {
	uid_t fsuid;

	fsuid = appfs_get_fsuid();

       	Tcl_SetObjResult(interp, Tcl_NewWideIntObj(fsuid));

	return(TCL_OK);
}

static int tcl_appfs_get_fsgid(ClientData cd, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]) {
	gid_t fsgid;

	fsgid = appfs_get_fsgid();

       	Tcl_SetObjResult(interp, Tcl_NewWideIntObj(fsgid));

	return(TCL_OK);
}

/*
 * Generate an inode for a given path.  The inode should be computed in such
 * a way that it is unlikely to be duplicated and remains the same for a given
 * file
 */
static long long appfs_get_path_inode(const char *path) {
................................................................................
	memset(stbuf, 0, sizeof(struct stat));

	stbuf->st_mtime = pathinfo.time;
	stbuf->st_ctime = pathinfo.time;
	stbuf->st_atime = pathinfo.time;
	stbuf->st_ino   = pathinfo.inode;
	stbuf->st_mode  = 0;
	stbuf->st_uid   = 0;
	stbuf->st_gid   = 0;

	switch (pathinfo.type) {
		case APPFS_PATHTYPE_DIRECTORY:
			stbuf->st_mode = S_IFDIR | 0555;
			stbuf->st_nlink = 2 + pathinfo.typeinfo.dir.childcount;
			break;
		case APPFS_PATHTYPE_FILE:
................................................................................
#ifdef USE_TCL_STUBS
	if (Tcl_InitStubs(interp, TCL_VERSION, 0) == 0L) {
		return(TCL_ERROR);
	}
#endif

	Tcl_CreateObjCommand(interp, "appfsd::get_homedir", tcl_appfs_get_homedir, NULL, NULL);
	Tcl_CreateObjCommand(interp, "appfsd::get_fsuid", tcl_appfs_get_fsuid, NULL, NULL);
	Tcl_CreateObjCommand(interp, "appfsd::get_fsgid", tcl_appfs_get_fsgid, NULL, NULL);
	Tcl_CreateObjCommand(interp, "appfsd::simulate_user_fs_enter", tcl_appfs_simulate_user_fs_enter, NULL, NULL);
	Tcl_CreateObjCommand(interp, "appfsd::simulate_user_fs_leave", tcl_appfs_simulate_user_fs_leave, NULL, NULL);

	Tcl_PkgProvide(interp, "appfsd", "1.0");

	return(TCL_OK);
}

Modified appfsd.tcl from [9561940a42] to [2a6db15ed4].

2
3
4
5
6
7
8













9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
...
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
...
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375

package require http 2.7
package require sqlite3
package require sha1
package require appfsd
package require platform
package require pki














namespace eval ::appfs {
	variable cachedir "/tmp/appfs-cache"
	variable ttl 3600
	variable nttl 60

	# User-replacable function to convert a hostname/hash/method to an URL
	proc _construct_url {hostname hash method} {
		return "http://$hostname/appfs/$method/$hash"
	}

	proc _hash_sep {hash {seps 4}} {
		for {set idx 0} {$idx < $seps} {incr idx} {
			append retval "[string range $hash [expr {$idx * 2}] [expr {($idx * 2) + 1}]]/"
		}
		append retval "[string range $hash [expr {$idx * 2}] end]"

................................................................................
		# Create indexes
		db eval {CREATE INDEX IF NOT EXISTS sites_index ON sites (hostname);}
		db eval {CREATE INDEX IF NOT EXISTS packages_index ON packages (hostname, package, version, os, cpuArch);}
		db eval {CREATE INDEX IF NOT EXISTS files_index ON files (package_sha1, file_name, file_directory);}
	}

	proc download {hostname hash {method sha1}} {
		set url [_construct_url $hostname $hash $method]
		set file [_cachefile $url $hash]

		if {![file exists $file]} {
			return -code error "Unable to fetch (file does not exist: $file)"
		}

		return $file
................................................................................

		return COMPLETE
	}

	proc _localpath {package hostname file} {
		set dir ""
		catch {
			set homedir [::appfsd::get_homedir]
			set dir [file join $homedir .appfs "./${package}@${hostname}" "./${file}"]
		}
		return $dir
	}

	proc _whiteoutpath {package hostname file} {
		set dir ""
		catch {
			set homedir [::appfsd::get_homedir]
			set dir [file join $homedir .appfs "./${package}@${hostname}" ".APPFS.WHITEOUT" "./${file}.APPFS.WHITEOUT"]
		}
		return $dir
	}

	proc _parsepath {path} {
		set path [string trim $path "/"]







>
>
>
>
>
>
>
>
>
>
>
>
>






<
<
<
<







 







|







 







|








|







2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27




28
29
30
31
32
33
34
...
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
...
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384

package require http 2.7
package require sqlite3
package require sha1
package require appfsd
package require platform
package require pki

# Functions specifically meant for users to replace as a part of configuration
namespace eval ::appfs::user {
	# User-replacable function to convert a hostname/hash/method to an URL
	proc construct_url {hostname hash method} {
		return "http://$hostname/appfs/$method/$hash"
	}

	# User-replaceable function get the home directory of the current user
	proc get_homedir {} {
		return [::appfsd::get_homedir]
	}
}

namespace eval ::appfs {
	variable cachedir "/tmp/appfs-cache"
	variable ttl 3600
	variable nttl 60






	proc _hash_sep {hash {seps 4}} {
		for {set idx 0} {$idx < $seps} {incr idx} {
			append retval "[string range $hash [expr {$idx * 2}] [expr {($idx * 2) + 1}]]/"
		}
		append retval "[string range $hash [expr {$idx * 2}] end]"

................................................................................
		# Create indexes
		db eval {CREATE INDEX IF NOT EXISTS sites_index ON sites (hostname);}
		db eval {CREATE INDEX IF NOT EXISTS packages_index ON packages (hostname, package, version, os, cpuArch);}
		db eval {CREATE INDEX IF NOT EXISTS files_index ON files (package_sha1, file_name, file_directory);}
	}

	proc download {hostname hash {method sha1}} {
		set url [::appfs::user::construct_url $hostname $hash $method]
		set file [_cachefile $url $hash]

		if {![file exists $file]} {
			return -code error "Unable to fetch (file does not exist: $file)"
		}

		return $file
................................................................................

		return COMPLETE
	}

	proc _localpath {package hostname file} {
		set dir ""
		catch {
			set homedir [::appfs::user::get_homedir]
			set dir [file join $homedir .appfs "./${package}@${hostname}" "./${file}"]
		}
		return $dir
	}

	proc _whiteoutpath {package hostname file} {
		set dir ""
		catch {
			set homedir [::appfs::user::get_homedir]
			set dir [file join $homedir .appfs "./${package}@${hostname}" ".APPFS.WHITEOUT" "./${file}.APPFS.WHITEOUT"]
		}
		return $dir
	}

	proc _parsepath {path} {
		set path [string trim $path "/"]