Check-in [6136db979d]
Overview
Comment:Updated packages branch to be a completely isolated branch
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | packages
Files: files | file ages | folders
SHA1:6136db979d902bb4dc4185d46ff0de0964ad8959
User & Date: rkeene on 2014-11-03 23:19:04
Other Links: manifest | tags
Context
2014-11-03
23:20
Emptied old ignore glob check-in: 286b0eb815 user: rkeene tags: packages
23:19
Updated packages branch to be a completely isolated branch check-in: 6136db979d user: rkeene tags: packages
2014-09-18
05:31
Added start of setting dynamic linker check-in: f2ef882677 user: rkeene tags: packages
Changes

Deleted Makefile version [be705a2fe3].

     1         -CC = gcc
     2         -PKG_CONFIG = pkg-config
     3         -CFLAGS = -Wall $(shell $(PKG_CONFIG) --cflags fuse) $(shell $(PKG_CONFIG) --cflags sqlite3) $(TCL_CFLAGS)
     4         -LDFLAGS = $(TCL_LDFLAGS)
     5         -LIBS = $(shell $(PKG_CONFIG) --libs fuse) $(shell $(PKG_CONFIG) --libs sqlite3) $(TCL_LIBS)
     6         -PREFIX = /usr/local
     7         -prefix = $(PREFIX)
     8         -bindir = $(prefix)/bin
     9         -sbindir = $(prefix)/sbin
    10         -
    11         -ifneq ($(TCLKIT_SDK_DIR),)
    12         -TCLCONFIG_SH_PATH = $(TCLKIT_SDK_DIR)/lib/tclConfig.sh
    13         -TCL_LDFLAGS = -Wl,-R,$(TCLKIT_SDK_DIR)/lib
    14         -export TCLKIT_SDK_DIR
    15         -else
    16         -TCLCONFIG_SH_PATH = $(shell echo 'puts [::tcl::pkgconfig get libdir,install]' | tclsh)/tclConfig.sh
    17         -endif
    18         -TCL_CFLAGS = $(shell . $(TCLCONFIG_SH_PATH); echo "$${TCL_INCLUDE_SPEC}")
    19         -TCL_LIBS = $(shell . $(TCLCONFIG_SH_PATH); echo "$${TCL_LIB_SPEC}")
    20         -
    21         -all: appfsd
    22         -
    23         -appfsd: appfsd.o
    24         -	$(CC) $(CPPFLAGS) $(CFLAGS) $(LDFLAGS) -o appfsd appfsd.o $(LIBS)
    25         -
    26         -appfsd.o: appfsd.c appfsd.tcl.h
    27         -	$(CC) $(CPPFLAGS) $(CFLAGS) -o appfsd.o -c appfsd.c
    28         -
    29         -appfsd.tcl.h: appfsd.tcl
    30         -	sed 's@[\\"]@\\&@g;s@^@   "@;s@$$@\\n"@' appfsd.tcl > appfsd.tcl.h.new
    31         -	mv appfsd.tcl.h.new appfsd.tcl.h
    32         -
    33         -install: appfsd
    34         -	if [ ! -d '$(DESTDIR)$(sbindir)' ]; then mkdir -p '$(DESTDIR)$(sbindir)'; chmod 755 '$(DESTDIR)$(sbindir)'; fi
    35         -	cp appfsd '$(DESTDIR)$(sbindir)/'
    36         -
    37         -clean:
    38         -	rm -f appfsd appfsd.o
    39         -	rm -f appfsd.tcl.h
    40         -
    41         -distclean: clean
    42         -
    43         -.PHONY: all test clean distclean install

Deleted README.md version [209ceb6ce4].

     1         -AppFS
     2         -=====
     3         -It's sort of like LazyFS.
     4         -
     5         -Usage
     6         ------
     7         -Run:
     8         -	1. # mkdir /tmp/appfs-cache /opt/appfs
     9         -	2. # appfsd /opt/appfs
    10         -
    11         -
    12         -Paths
    13         ------
    14         -    AppFS should normally be mounted on "/opt/appfs".
    15         -
    16         -    /opt/appfs/hostname
    17         -    	Fetches: http://hostname/appfs/index
    18         -    	Contains CSV file: hash,extraData
    19         -    	Fetches: http://hostname/appfs/sha1/<hash>
    20         -    	Contains CSV file: package,version,os,cpuArch,sha1,isLatest
    21         -
    22         -    /opt/appfs/hostname/package/os-cpuArch/version
    23         -    /opt/appfs/hostname/sha1/
    24         -    	Fetches: http://hostname/appfs/sha1/<sha1>
    25         -    	Contains CSV file:
    26         -    		type,time,extraData,name
    27         -    		type == directory; extraData = (null)
    28         -    		type == symlink; extraData = source
    29         -    		type == file; extraData = size,perms,sha1
    30         -
    31         -    /opt/appfs/hostname/{sha1,package/os-cpuArch/version}/file
    32         -    	Fetches: http://hostname/appfs/sha1/<sha1>
    33         -
    34         -Database
    35         ---------
    36         -    packages(hostname, sha1, package, version, os, cpuArch, isLatest, haveManifest)
    37         -    files(package_sha1, type, time, source, size, perms, file_sha1, file_name, file_directory)
    38         -
    39         -Resources
    40         ----------
    41         -http://appfs.rkeene.org/

Deleted appfs-mkfs version [994caae026].

     1         -#! /usr/bin/env bash
     2         -
     3         -pkgsdir="$1"
     4         -appfsdir="$2"
     5         -
     6         -if [ -z  "${pkgsdir}" -o -z "${appfsdir}" ]; then
     7         -	echo 'Usage: appfs-mk <pkgsdir> <appfsdir>' >&2
     8         -
     9         -	exit 1
    10         -fi
    11         -
    12         -appfsdir="$(cd "${appfsdir}" && pwd)"
    13         -if [ -z "${appfsdir}" ]; then
    14         -	echo "Unable to find appfs directory." >&2
    15         -
    16         -	exit 1
    17         -fi
    18         -
    19         -mkdir -p "${appfsdir}/sha1"
    20         -
    21         -function sha1() {
    22         -	local filename
    23         -
    24         -	filename="$1"
    25         -
    26         -	openssl sha1 "${filename}" | sed 's@.*= @@'
    27         -}
    28         -
    29         -function emit_manifest() {
    30         -	find . -print0 | while IFS='' read -r -d $'\0' filename; do
    31         -		if [ "${filename}" = '.' ]; then
    32         -			continue
    33         -		fi
    34         -
    35         -		filename="$(echo "${filename}" | sed 's@^\./@@' | head -n 1)"
    36         -
    37         -		if [ ! -e "${filename}" ]; then
    38         -			continue
    39         -		fi
    40         -
    41         -		if [ -h "${filename}" ]; then
    42         -			type='symlink'
    43         -		elif [ -d "${filename}" ]; then
    44         -			type='directory'
    45         -		elif [ -f "${filename}" ]; then
    46         -			type='file'
    47         -		else
    48         -			continue
    49         -		fi
    50         -
    51         -		case "${type}" in
    52         -			directory)
    53         -				stat_format='%Y'
    54         -				extra_data=''
    55         -				;;
    56         -			symlink)
    57         -				stat_format='%Y'
    58         -				extra_data="$(readlink "${filename}")"
    59         -				;;
    60         -			file)
    61         -				if [ -x "${filename}" ]; then
    62         -					extra_data='x'
    63         -				else
    64         -					extra_data=''
    65         -				fi
    66         -
    67         -				stat_format='%Y,%s'
    68         -				filename_hash="$(sha1 "${filename}")"
    69         -				extra_data="${extra_data},${filename_hash}"
    70         -
    71         -				filename_intree="${appfsdir}/sha1/${filename_hash}"
    72         -
    73         -				if [ ! -e "${filename_intree}" ]; then
    74         -					cat "${filename}" > "${filename_intree}.tmp"
    75         -
    76         -					mv "${filename_intree}.tmp" "${filename_intree}"
    77         -				fi
    78         -				;;
    79         -		esac
    80         -		stat_data="$(stat --format="${stat_format}" "${filename}")"
    81         -
    82         -		if [ -z "${extra_data}" ]; then
    83         -			echo "${type},${stat_data},${filename}"
    84         -		else
    85         -			echo "${type},${stat_data},${extra_data},${filename}"
    86         -		fi
    87         -	done
    88         -}
    89         -
    90         -cd "${pkgsdir}" || exit 1
    91         -
    92         -packagelistfile="${appfsdir}/sha1/${RANDOM}${RANDOM}${RANDOM}${RANDOM}${RANDOM}.tmp"
    93         -for package in *; do
    94         -	(
    95         -		cd "${package}" || exit 1
    96         -
    97         -		for os_cpuArch in *; do
    98         -			os="$(echo "${os_cpuArch}" | cut -f 1 -d '-')"
    99         -			cpuArch="$(echo "${os_cpuArch}" | cut -f 2- -d '-')"
   100         -
   101         -			(
   102         -				cd "${os_cpuArch}" || exit 1
   103         -
   104         -				for version in *; do
   105         -					if [ -h "${version}" ]; then
   106         -						continue
   107         -					fi
   108         -
   109         -					manifestfile="${appfsdir}/sha1/${RANDOM}${RANDOM}${RANDOM}${RANDOM}${RANDOM}.tmp"
   110         -
   111         -					(
   112         -						cd "${version}" || exit 1
   113         -
   114         -						emit_manifest
   115         -					) > "${manifestfile}"
   116         -
   117         -					manifestfile_hash="$(sha1 "${manifestfile}")"
   118         -					mv "${manifestfile}" "${appfsdir}/sha1/${manifestfile_hash}"
   119         -
   120         -					# XXX:TODO: Determine if this is the latest version
   121         -					isLatest='0'
   122         -
   123         -					echo "${package},${version},${os},${cpuArch},${manifestfile_hash},${isLatest}"
   124         -				done
   125         -
   126         -			)
   127         -		done
   128         -	)
   129         -
   130         -done > "${packagelistfile}"
   131         -packagelistfile_hash="$(sha1 "${packagelistfile}")"
   132         -mv "${packagelistfile}" "${appfsdir}/sha1/${packagelistfile_hash}"
   133         -
   134         -echo "${packagelistfile_hash},sha1" > "${appfsdir}/index"

Deleted appfsd.c version [f1b76341ae].

     1         -#define FUSE_USE_VERSION 26
     2         -
     3         -#include <sys/types.h>
     4         -#include <sqlite3.h>
     5         -#include <pthread.h>
     6         -#include <string.h>
     7         -#include <stdarg.h>
     8         -#include <stdlib.h>
     9         -#include <unistd.h>
    10         -#include <errno.h>
    11         -#include <fcntl.h>
    12         -#include <stdio.h>
    13         -#include <fuse.h>
    14         -#include <tcl.h>
    15         -
    16         -#define APPFS_CACHEDIR "/var/cache/appfs"
    17         -
    18         -#define APPFS_DEBUG(x...) { fprintf(stderr, "[debug] %s:%i:%s: ", __FILE__, __LINE__, __func__); fprintf(stderr, x); fprintf(stderr, "\n"); }
    19         -
    20         -static pthread_key_t interpKey;
    21         -
    22         -struct appfs_thread_data {
    23         -	sqlite3 *db;
    24         -	const char *cachedir;
    25         -	time_t boottime;
    26         -};
    27         -
    28         -struct appfs_thread_data globalThread;
    29         -
    30         -typedef enum {
    31         -	APPFS_PATHTYPE_INVALID,
    32         -	APPFS_PATHTYPE_FILE,
    33         -	APPFS_PATHTYPE_DIRECTORY,
    34         -	APPFS_PATHTYPE_SYMLINK
    35         -} appfs_pathtype_t;
    36         -
    37         -struct appfs_children {
    38         -	struct appfs_children *_next;
    39         -	int counter;
    40         -
    41         -	char name[256];
    42         -};
    43         -
    44         -struct appfs_pathinfo {
    45         -	appfs_pathtype_t type;
    46         -	time_t time;
    47         -	char hostname[256];
    48         -	union {
    49         -		struct {
    50         -			int childcount;
    51         -		} dir;
    52         -		struct {
    53         -			int executable;
    54         -			off_t size;
    55         -			char sha1[41];
    56         -		} file;
    57         -		struct {
    58         -			off_t size;
    59         -			char source[256];
    60         -		} symlink;
    61         -	} typeinfo;
    62         -};
    63         -
    64         -struct appfs_sqlite3_query_cb_handle {
    65         -	struct appfs_children *head;
    66         -	int argc;
    67         -	const char *fmt;
    68         -};
    69         -
    70         -static Tcl_Interp *appfs_create_TclInterp(const char *cachedir) {
    71         -	Tcl_Interp *interp;
    72         -	int tcl_ret;
    73         -
    74         -	interp = Tcl_CreateInterp();
    75         -	if (interp == NULL) {
    76         -		fprintf(stderr, "Unable to create Tcl Interpreter.  Aborting.\n");
    77         -
    78         -		return(NULL);
    79         -	}
    80         -
    81         -	tcl_ret = Tcl_Init(interp);
    82         -	if (tcl_ret != TCL_OK) {
    83         -		fprintf(stderr, "Unable to initialize Tcl.  Aborting.\n");
    84         -
    85         -		return(NULL);
    86         -	}
    87         -
    88         -	tcl_ret = Tcl_Eval(interp, ""
    89         -#include "appfsd.tcl.h"
    90         -	"");
    91         -	if (tcl_ret != TCL_OK) {
    92         -		fprintf(stderr, "Unable to initialize Tcl AppFS script.  Aborting.\n");
    93         -		fprintf(stderr, "Tcl Error is: %s\n", Tcl_GetStringResult(interp));
    94         -
    95         -		return(NULL);
    96         -	}
    97         -
    98         -	if (Tcl_SetVar(interp, "::appfs::cachedir", cachedir, TCL_GLOBAL_ONLY) == NULL) {
    99         -		fprintf(stderr, "Unable to set cache directory.  This should never fail.\n");
   100         -
   101         -		return(NULL);
   102         -	}
   103         -
   104         -	tcl_ret = Tcl_Eval(interp, "::appfs::init");
   105         -	if (tcl_ret != TCL_OK) {
   106         -		fprintf(stderr, "Unable to initialize Tcl AppFS script (::appfs::init).  Aborting.\n");
   107         -		fprintf(stderr, "Tcl Error is: %s\n", Tcl_GetStringResult(interp));
   108         -
   109         -		return(NULL);
   110         -	}
   111         -
   112         -	return(interp);
   113         -}
   114         -
   115         -static int appfs_Tcl_Eval(Tcl_Interp *interp, int objc, const char *cmd, ...) {
   116         -	Tcl_Obj **objv;
   117         -	const char *arg;
   118         -	va_list argp;
   119         -	int retval;
   120         -	int i;
   121         -
   122         -	objv = (void *) ckalloc(sizeof(*objv) * objc);
   123         -	objv[0] = Tcl_NewStringObj(cmd, -1);
   124         -	Tcl_IncrRefCount(objv[0]);
   125         -
   126         -	va_start(argp, cmd);
   127         -	for (i = 1; i < objc; i++) {
   128         -		arg = va_arg(argp, const char *);
   129         -		objv[i] = Tcl_NewStringObj(arg, -1);
   130         -		Tcl_IncrRefCount(objv[i]);
   131         -	}
   132         -	va_end(argp);
   133         -
   134         -	retval = Tcl_EvalObjv(interp, objc, objv, 0);
   135         -
   136         -	for (i = 0; i < objc; i++) {
   137         -		Tcl_DecrRefCount(objv[i]);
   138         -	}
   139         -
   140         -	ckfree((void *) objv);
   141         -
   142         -	if (retval != TCL_OK) {
   143         -		APPFS_DEBUG("Tcl command failed, ::errorInfo contains: %s\n", Tcl_GetVar(interp, "::errorInfo", 0));
   144         -	}
   145         -
   146         -	return(retval);
   147         -}
   148         -
   149         -static void appfs_update_index(const char *hostname) {
   150         -	Tcl_Interp *interp;
   151         -	int tcl_ret;
   152         -
   153         -	APPFS_DEBUG("Enter: hostname = %s", hostname);
   154         -
   155         -	interp = pthread_getspecific(interpKey);
   156         -	if (interp == NULL) {
   157         -		interp = appfs_create_TclInterp(globalThread.cachedir);
   158         -
   159         -		pthread_setspecific(interpKey, interp);
   160         -	}
   161         -
   162         -	tcl_ret = appfs_Tcl_Eval(interp, 2, "::appfs::getindex", hostname);
   163         -	if (tcl_ret != TCL_OK) {
   164         -		APPFS_DEBUG("Call to ::appfs::getindex failed: %s", Tcl_GetStringResult(interp));
   165         -
   166         -		return;
   167         -	}
   168         -
   169         -	return;
   170         -}
   171         -
   172         -static const char *appfs_getfile(const char *hostname, const char *sha1) {
   173         -	Tcl_Interp *interp;
   174         -	char *retval;
   175         -	int tcl_ret;
   176         -
   177         -	interp = pthread_getspecific(interpKey);
   178         -	if (interp == NULL) {
   179         -		interp = appfs_create_TclInterp(globalThread.cachedir);
   180         -
   181         -		pthread_setspecific(interpKey, interp);
   182         -	}
   183         -
   184         -	tcl_ret = appfs_Tcl_Eval(interp, 3, "::appfs::download", hostname, sha1);
   185         -	if (tcl_ret != TCL_OK) {
   186         -		APPFS_DEBUG("Call to ::appfs::download failed: %s", Tcl_GetStringResult(interp));
   187         -
   188         -		return(NULL);
   189         -	}
   190         -
   191         -	retval = strdup(Tcl_GetStringResult(interp));
   192         -
   193         -	return(retval);
   194         -}
   195         -
   196         -static void appfs_update_manifest(const char *hostname, const char *sha1) {
   197         -	Tcl_Interp *interp;
   198         -	int tcl_ret;
   199         -
   200         -	interp = pthread_getspecific(interpKey);
   201         -	if (interp == NULL) {
   202         -		interp = appfs_create_TclInterp(globalThread.cachedir);
   203         -
   204         -		pthread_setspecific(interpKey, interp);
   205         -	}
   206         -
   207         -	tcl_ret = appfs_Tcl_Eval(interp, 3, "::appfs::getpkgmanifest", hostname, sha1);
   208         -	if (tcl_ret != TCL_OK) {
   209         -		APPFS_DEBUG("Call to ::appfs::getpkgmanifest failed: %s", Tcl_GetStringResult(interp));
   210         -
   211         -		return;
   212         -	}
   213         -
   214         -	return;
   215         -}
   216         -
   217         -#define appfs_free_list_type(id, type) static void appfs_free_list_ ## id(type *head) { \
   218         -	type *obj, *next; \
   219         -	for (obj = head; obj; obj = next) { \
   220         -		next = obj->_next; \
   221         -		ckfree((void *) obj); \
   222         -	} \
   223         -}
   224         -
   225         -appfs_free_list_type(children, struct appfs_children)
   226         -
   227         -static int appfs_getchildren_cb(void *_head, int columns, char **values, char **names) {
   228         -	struct appfs_children **head_p, *obj;
   229         -
   230         -	head_p = _head;
   231         -
   232         -	obj = (void *) ckalloc(sizeof(*obj));
   233         -
   234         -	snprintf(obj->name, sizeof(obj->name), "%s", values[0]);
   235         -
   236         -	if (*head_p == NULL) {
   237         -		obj->counter = 0;
   238         -	} else {
   239         -		obj->counter = (*head_p)->counter + 1;
   240         -	}
   241         -
   242         -	obj->_next = *head_p;
   243         -	*head_p = obj;
   244         -
   245         -	return(0);
   246         -	
   247         -}
   248         -
   249         -static struct appfs_children *appfs_getchildren(const char *hostname, const char *package_hash, const char *path, int *children_count_p) {
   250         -	struct appfs_children *head = NULL;
   251         -	char *sql;
   252         -	int sqlite_ret;
   253         -
   254         -	if (children_count_p == NULL) {
   255         -		return(NULL);
   256         -	}
   257         -
   258         -	appfs_update_index(hostname);
   259         -	appfs_update_manifest(hostname, package_hash);
   260         -
   261         -	sql = sqlite3_mprintf("SELECT file_name FROM files WHERE package_sha1 = %Q AND file_directory = %Q;", package_hash, path);
   262         -	if (sql == NULL) {
   263         -		APPFS_DEBUG("Call to sqlite3_mprintf failed.");
   264         -
   265         -		return(NULL);
   266         -	}
   267         -
   268         -	APPFS_DEBUG("SQL: %s", sql);
   269         -	sqlite_ret = sqlite3_exec(globalThread.db, sql, appfs_getchildren_cb, &head, NULL);
   270         -	sqlite3_free(sql);
   271         -
   272         -	if (sqlite_ret != SQLITE_OK) {
   273         -		APPFS_DEBUG("Call to sqlite3_exec failed.");
   274         -
   275         -		return(NULL);
   276         -	}
   277         -
   278         -	if (head != NULL) {
   279         -		*children_count_p = head->counter + 1;
   280         -	}
   281         -
   282         -	return(head);
   283         -}
   284         -
   285         -static int appfs_sqlite3_query_cb(void *_cb_handle, int columns, char **values, char **names) {
   286         -	struct appfs_sqlite3_query_cb_handle *cb_handle;
   287         -	struct appfs_children *obj;
   288         -
   289         -	cb_handle = _cb_handle;
   290         -
   291         -	obj = (void *) ckalloc(sizeof(*obj));
   292         -
   293         -	switch (cb_handle->argc) {
   294         -		case 1:
   295         -			snprintf(obj->name, sizeof(obj->name), cb_handle->fmt, values[0]);
   296         -			break;
   297         -		case 2:
   298         -			snprintf(obj->name, sizeof(obj->name), cb_handle->fmt, values[0], values[1]);
   299         -			break;
   300         -		case 3:
   301         -			snprintf(obj->name, sizeof(obj->name), cb_handle->fmt, values[0], values[1], values[2]);
   302         -			break;
   303         -		case 4:
   304         -			snprintf(obj->name, sizeof(obj->name), cb_handle->fmt, values[0], values[1], values[2], values[3]);
   305         -			break;
   306         -	}
   307         -
   308         -	if (cb_handle->head == NULL) {
   309         -		obj->counter = 0;
   310         -	} else {
   311         -		obj->counter = cb_handle->head->counter + 1;
   312         -	}
   313         -
   314         -	obj->_next = cb_handle->head;
   315         -	cb_handle->head = obj;
   316         -
   317         -	return(0);
   318         -}
   319         -
   320         -static struct appfs_children *appfs_sqlite3_query(char *sql, int argc, const char *fmt, int *results_count_p) {
   321         -	struct appfs_sqlite3_query_cb_handle cb_handle;
   322         -	int sqlite_ret;
   323         -
   324         -	if (results_count_p == NULL) {
   325         -		return(NULL);
   326         -	}
   327         -
   328         -	if (sql == NULL) {
   329         -		APPFS_DEBUG("Call to sqlite3_mprintf probably failed.");
   330         -
   331         -		return(NULL);
   332         -	}
   333         -
   334         -	if (fmt == NULL) {
   335         -		fmt = "%s";
   336         -	}
   337         -
   338         -	cb_handle.head = NULL;
   339         -	cb_handle.argc = argc;
   340         -	cb_handle.fmt  = fmt;
   341         -
   342         -	APPFS_DEBUG("SQL: %s", sql);
   343         -	sqlite_ret = sqlite3_exec(globalThread.db, sql, appfs_sqlite3_query_cb, &cb_handle, NULL);
   344         -	sqlite3_free(sql);
   345         -
   346         -	if (sqlite_ret != SQLITE_OK) {
   347         -		APPFS_DEBUG("Call to sqlite3_exec failed.");
   348         -
   349         -		return(NULL);
   350         -	}
   351         -
   352         -	if (cb_handle.head != NULL) {
   353         -		*results_count_p = cb_handle.head->counter + 1;
   354         -	}
   355         -
   356         -	return(cb_handle.head);
   357         -}
   358         -
   359         -static int appfs_lookup_package_hash_cb(void *_retval, int columns, char **values, char **names) {
   360         -	char **retval = _retval;
   361         -
   362         -	*retval = strdup(values[0]);
   363         -
   364         -	return(0);
   365         -}
   366         -
   367         -static char *appfs_lookup_package_hash(const char *hostname, const char *package, const char *os, const char *cpuArch, const char *version) {
   368         -	char *sql;
   369         -	char *retval = NULL;
   370         -	int sqlite_ret;
   371         -
   372         -	appfs_update_index(hostname);
   373         -
   374         -	sql = sqlite3_mprintf("SELECT sha1 FROM packages WHERE hostname = %Q AND package = %Q AND os = %Q AND cpuArch = %Q AND version = %Q;",
   375         -		hostname,
   376         -		package,
   377         -		os,
   378         -		cpuArch,
   379         -		version
   380         -	);
   381         -	if (sql == NULL) {
   382         -		APPFS_DEBUG("Call to sqlite3_mprintf failed.");
   383         -
   384         -		return(NULL);
   385         -	}
   386         -
   387         -	APPFS_DEBUG("SQL: %s", sql);
   388         -	sqlite_ret = sqlite3_exec(globalThread.db, sql, appfs_lookup_package_hash_cb, &retval, NULL);
   389         -	sqlite3_free(sql);
   390         -
   391         -	if (sqlite_ret != SQLITE_OK) {
   392         -		APPFS_DEBUG("Call to sqlite3_exec failed.");
   393         -
   394         -		return(NULL);
   395         -	}
   396         -
   397         -	return(retval);
   398         -}
   399         -
   400         -static int appfs_getfileinfo_cb(void *_pathinfo, int columns, char **values, char **names) {
   401         -	struct appfs_pathinfo *pathinfo = _pathinfo;
   402         -	const char *type, *time, *source, *size, *perms, *sha1;
   403         -
   404         -	type = values[0];
   405         -	time = values[1];
   406         -	source = values[2];
   407         -	size = values[3];
   408         -	perms = values[4];
   409         -	sha1 = values[5];
   410         -
   411         -	pathinfo->time = strtoull(time, NULL, 10);
   412         -
   413         -	if (strcmp(type, "file") == 0) {
   414         -		pathinfo->type = APPFS_PATHTYPE_FILE;
   415         -
   416         -		if (!size) {
   417         -			size = "0";
   418         -		}
   419         -
   420         -		if (!perms) {
   421         -			perms = "";
   422         -		}
   423         -
   424         -		if (!sha1) {
   425         -			sha1 = "";
   426         -		}
   427         -
   428         -		pathinfo->typeinfo.file.size = strtoull(size, NULL, 10);
   429         -		snprintf(pathinfo->typeinfo.file.sha1, sizeof(pathinfo->typeinfo.file.sha1), "%s", sha1);
   430         -
   431         -		if (strcmp(perms, "x") == 0) {
   432         -			pathinfo->typeinfo.file.executable = 1;
   433         -		} else {
   434         -			pathinfo->typeinfo.file.executable = 0;
   435         -		}
   436         -
   437         -		return(0);
   438         -	}
   439         -
   440         -	if (strcmp(type, "directory") == 0) {
   441         -		pathinfo->type = APPFS_PATHTYPE_DIRECTORY;
   442         -		pathinfo->typeinfo.dir.childcount = 0;
   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         -
   458         -		return(0);
   459         -	}
   460         -
   461         -	return(0);
   462         -
   463         -	/* Until this is used, prevent the compiler from complaining */
   464         -	source = source;
   465         -}
   466         -
   467         -static int appfs_getfileinfo(const char *hostname, const char *package_hash, const char *_path, struct appfs_pathinfo *pathinfo) {
   468         -	char *directory, *file, *path;
   469         -	char *sql;
   470         -	int sqlite_ret;
   471         -
   472         -	if (pathinfo == NULL) {
   473         -		return(-EIO);
   474         -	}
   475         -
   476         -	appfs_update_index(hostname);
   477         -	appfs_update_manifest(hostname, package_hash);
   478         -
   479         -	path = strdup(_path);
   480         -	directory = path;
   481         -	file = strrchr(path, '/');
   482         -	if (file == NULL) {
   483         -		file = path;
   484         -		directory = "";
   485         -	} else {
   486         -		*file = '\0';
   487         -		file++;
   488         -	}
   489         -
   490         -	sql = sqlite3_mprintf("SELECT type, time, source, size, perms, file_sha1 FROM files WHERE package_sha1 = %Q AND file_directory = %Q AND file_name = %Q;", package_hash, directory, file);
   491         -	if (sql == NULL) {
   492         -		APPFS_DEBUG("Call to sqlite3_mprintf failed.");
   493         -
   494         -		free(path);
   495         -
   496         -		return(-EIO);
   497         -	}
   498         -
   499         -	free(path);
   500         -
   501         -	pathinfo->type = APPFS_PATHTYPE_INVALID;
   502         -
   503         -	APPFS_DEBUG("SQL: %s", sql);
   504         -	sqlite_ret = sqlite3_exec(globalThread.db, sql, appfs_getfileinfo_cb, pathinfo, NULL);
   505         -	sqlite3_free(sql);
   506         -
   507         -	if (sqlite_ret != SQLITE_OK) {
   508         -		APPFS_DEBUG("Call to sqlite3_exec failed.");
   509         -
   510         -		return(-EIO);
   511         -	}
   512         -
   513         -	if (pathinfo->type == APPFS_PATHTYPE_INVALID) {
   514         -		return(-ENOENT);
   515         -	}
   516         -
   517         -	return(0);
   518         -}
   519         -
   520         -static int appfs_get_path_info_sql(char *sql, int argc, const char *fmt, struct appfs_pathinfo *pathinfo, struct appfs_children **children) {
   521         -	struct appfs_children *node, *dir_children, *dir_child;
   522         -	int dir_children_count = 0;
   523         -
   524         -	dir_children = appfs_sqlite3_query(sql, argc, fmt, &dir_children_count);
   525         -
   526         -	if (dir_children == NULL || dir_children_count == 0) {
   527         -		return(-ENOENT);
   528         -	}
   529         -
   530         -	/* Request for a single hostname */
   531         -	pathinfo->type = APPFS_PATHTYPE_DIRECTORY;
   532         -	pathinfo->typeinfo.dir.childcount = dir_children_count;
   533         -	pathinfo->time = globalThread.boottime;
   534         -
   535         -	if (children) {
   536         -		for (dir_child = dir_children; dir_child; dir_child = dir_child->_next) {
   537         -			node = (void *) ckalloc(sizeof(*node));
   538         -			node->_next = *children;
   539         -			strcpy(node->name, dir_child->name);
   540         -			*children = node;
   541         -		}
   542         -	}
   543         -
   544         -	appfs_free_list_children(dir_children);
   545         -
   546         -	return(0);
   547         -}
   548         -/* Get information about a path, and optionally list children */
   549         -static int appfs_get_path_info(const char *_path, struct appfs_pathinfo *pathinfo, struct appfs_children **children) {
   550         -	struct appfs_children *dir_children;
   551         -	char *hostname, *packagename, *os_cpuArch, *os, *cpuArch, *version;
   552         -	char *path, *path_s;
   553         -	char *package_hash;
   554         -	char *sql;
   555         -	int files_count;
   556         -	int fileinfo_ret, retval;
   557         -
   558         -	if (children) {
   559         -		*children = NULL;
   560         -	}
   561         -
   562         -	if (_path == NULL) {
   563         -		return(-ENOENT);
   564         -	}
   565         -
   566         -	if (_path[0] != '/') {
   567         -		return(-ENOENT);
   568         -	}
   569         -
   570         -	if (_path[1] == '\0') {
   571         -		/* Request for the root directory */
   572         -		pathinfo->hostname[0] = '\0';
   573         -
   574         -		sql = sqlite3_mprintf("SELECT DISTINCT hostname FROM packages;");
   575         -
   576         -		retval = appfs_get_path_info_sql(sql, 1, NULL, pathinfo, children);
   577         -
   578         -		/* The root directory always exists, even if it has no subordinates */
   579         -		if (retval != 0) {
   580         -			pathinfo->type = APPFS_PATHTYPE_DIRECTORY;
   581         -			pathinfo->typeinfo.dir.childcount = 0;
   582         -			pathinfo->time = globalThread.boottime;
   583         -
   584         -			retval = 0;
   585         -		}
   586         -
   587         -		return(retval);
   588         -	}
   589         -
   590         -	path = strdup(_path);
   591         -	path_s = path;
   592         -
   593         -	hostname = path + 1;
   594         -	packagename = strchr(hostname, '/');
   595         -
   596         -	if (packagename != NULL) {
   597         -		*packagename = '\0';
   598         -		packagename++;
   599         -	}
   600         -
   601         -	snprintf(pathinfo->hostname, sizeof(pathinfo->hostname), "%s", hostname);
   602         -
   603         -	if (packagename == NULL) {
   604         -		appfs_update_index(hostname);
   605         -
   606         -		sql = sqlite3_mprintf("SELECT DISTINCT package FROM packages WHERE hostname = %Q;", hostname);
   607         -
   608         -		free(path_s);
   609         -
   610         -		return(appfs_get_path_info_sql(sql, 1, NULL, pathinfo, children));
   611         -	}
   612         -
   613         -	os_cpuArch = strchr(packagename, '/');
   614         -
   615         -	if (os_cpuArch != NULL) {
   616         -		*os_cpuArch = '\0';
   617         -		os_cpuArch++;
   618         -	}
   619         -
   620         -	if (os_cpuArch == NULL) {
   621         -		appfs_update_index(hostname);
   622         -
   623         -		sql = sqlite3_mprintf("SELECT DISTINCT os, cpuArch FROM packages WHERE hostname = %Q AND package = %Q;", hostname, packagename);
   624         -
   625         -		free(path_s);
   626         -
   627         -		return(appfs_get_path_info_sql(sql, 2, "%s-%s", pathinfo, children));
   628         -	}
   629         -
   630         -	version = strchr(os_cpuArch, '/');
   631         -
   632         -	if (version != NULL) {
   633         -		*version = '\0';
   634         -		version++;
   635         -	}
   636         -
   637         -	os = os_cpuArch;
   638         -	cpuArch = strchr(os_cpuArch, '-');
   639         -	if (cpuArch) {
   640         -		*cpuArch = '\0';
   641         -		cpuArch++;
   642         -	}
   643         -
   644         -	if (version == NULL) {
   645         -		/* Request for version list for a package on an OS/CPU */
   646         -		appfs_update_index(hostname);
   647         -
   648         -		sql = sqlite3_mprintf("SELECT DISTINCT version FROM packages WHERE hostname = %Q AND package = %Q AND os = %Q and cpuArch = %Q;", hostname, packagename, os, cpuArch);
   649         -
   650         -		free(path_s);
   651         -
   652         -		return(appfs_get_path_info_sql(sql, 1, NULL, pathinfo, children));
   653         -	}
   654         -
   655         -	path = strchr(version, '/');
   656         -	if (path == NULL) {
   657         -		path = "";
   658         -	} else {
   659         -		*path = '\0';
   660         -		path++;
   661         -	}
   662         -
   663         -	/* Request for a file in a specific package */
   664         -	APPFS_DEBUG("Requesting information for hostname = %s, package = %s, os = %s, cpuArch = %s, version = %s, path = %s", 
   665         -		hostname, packagename, os, cpuArch, version, path
   666         -	);
   667         -
   668         -	package_hash = appfs_lookup_package_hash(hostname, packagename, os, cpuArch, version);
   669         -	if (package_hash == NULL) {
   670         -		free(path_s);
   671         -
   672         -		return(-ENOENT);
   673         -	}
   674         -
   675         -	APPFS_DEBUG("  ... which hash a hash of %s", package_hash);
   676         -
   677         -	appfs_update_manifest(hostname, package_hash);
   678         -
   679         -	if (strcmp(path, "") == 0) {
   680         -		pathinfo->type = APPFS_PATHTYPE_DIRECTORY;
   681         -		pathinfo->time = globalThread.boottime;
   682         -	} else {
   683         -		fileinfo_ret = appfs_getfileinfo(hostname, package_hash, path, pathinfo);
   684         -		if (fileinfo_ret != 0) {
   685         -			free(path_s);
   686         -
   687         -			return(fileinfo_ret);
   688         -		}
   689         -	}
   690         -
   691         -	if (pathinfo->type == APPFS_PATHTYPE_DIRECTORY) {
   692         -		dir_children = appfs_getchildren(hostname, package_hash, path, &files_count);
   693         -
   694         -		if (dir_children != NULL) {
   695         -			pathinfo->typeinfo.dir.childcount = files_count;
   696         -		}
   697         -
   698         -		if (children) {
   699         -			*children = dir_children;
   700         -		}
   701         -	}
   702         -
   703         -	free(path_s);
   704         -
   705         -	return(0);
   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         -}
   733         -
   734         -static int appfs_fuse_getattr(const char *path, struct stat *stbuf) {
   735         -	struct appfs_pathinfo pathinfo;
   736         -	int res = 0;
   737         -
   738         -	APPFS_DEBUG("Enter (path = %s, ...)", path);
   739         -
   740         -	pathinfo.type = APPFS_PATHTYPE_INVALID;
   741         -
   742         -	res = appfs_get_path_info(path, &pathinfo, NULL);
   743         -	if (res != 0) {
   744         -		return(res);
   745         -	}
   746         -
   747         -	memset(stbuf, 0, sizeof(struct stat));
   748         -
   749         -	stbuf->st_mtime = pathinfo.time;
   750         -	stbuf->st_ctime = pathinfo.time;
   751         -	stbuf->st_atime = pathinfo.time;
   752         -
   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         -			}
   764         -
   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;
   777         -	}
   778         -
   779         -	return res;
   780         -}
   781         -
   782         -static int appfs_fuse_readdir(const char *path, void *buf, fuse_fill_dir_t filler, off_t offset, struct fuse_file_info *fi) {
   783         -	struct appfs_pathinfo pathinfo;
   784         -	struct appfs_children *children, *child;
   785         -	int retval;
   786         -
   787         -	APPFS_DEBUG("Enter (path = %s, ...)", path);
   788         -
   789         -	retval = appfs_get_path_info(path, &pathinfo, &children);
   790         -	if (retval != 0) {
   791         -		return(retval);
   792         -	}
   793         -
   794         -	filler(buf, ".", NULL, 0);
   795         -	filler(buf, "..", NULL, 0);
   796         -
   797         -	for (child = children; child; child = child->_next) {
   798         -		filler(buf, child->name, NULL, 0);
   799         -	}
   800         -
   801         -	appfs_free_list_children(children);
   802         -
   803         -	return(0);
   804         -}
   805         -
   806         -static int appfs_fuse_open(const char *path, struct fuse_file_info *fi) {
   807         -	struct appfs_pathinfo pathinfo;
   808         -	const char *real_path;
   809         -	int fh;
   810         -	int gpi_ret;
   811         -
   812         -	APPFS_DEBUG("Enter (path = %s, ...)", path);
   813         -
   814         -	if ((fi->flags & 3) != O_RDONLY) {
   815         -                return(-EACCES);
   816         -	}
   817         -
   818         -	gpi_ret = appfs_get_path_info(path, &pathinfo, NULL);
   819         -	if (gpi_ret != 0) {
   820         -		return(gpi_ret);
   821         -	}
   822         -
   823         -	if (pathinfo.type == APPFS_PATHTYPE_DIRECTORY) {
   824         -		return(-EISDIR);
   825         -	}
   826         -
   827         -	real_path = appfs_getfile(pathinfo.hostname, pathinfo.typeinfo.file.sha1);
   828         -	if (real_path == NULL) {
   829         -		return(-EIO);
   830         -	}
   831         -
   832         -	fh = open(real_path, O_RDONLY);
   833         -	free((void *) real_path);
   834         -	if (fh < 0) {
   835         -		return(-EIO);
   836         -	}
   837         -
   838         -	fi->fh = fh;
   839         -
   840         -	return(0);
   841         -}
   842         -
   843         -static int appfs_fuse_close(const char *path, struct fuse_file_info *fi) {
   844         -	int close_ret;
   845         -
   846         -	close_ret = close(fi->fh);
   847         -	if (close_ret != 0) {
   848         -		return(-EIO);
   849         -	}
   850         -
   851         -	return(0);
   852         -}
   853         -
   854         -static int appfs_fuse_read(const char *path, char *buf, size_t size, off_t offset, struct fuse_file_info *fi) {
   855         -	off_t lseek_ret;
   856         -	ssize_t read_ret;
   857         -
   858         -	APPFS_DEBUG("Enter (path = %s, ...)", path);
   859         -
   860         -	lseek_ret = lseek(fi->fh, offset, SEEK_SET);
   861         -	if (lseek_ret != offset) {
   862         -		return(-EIO);
   863         -	}
   864         -
   865         -	read_ret = read(fi->fh, buf, size);
   866         -
   867         -	return(read_ret);
   868         -}
   869         -
   870         -static struct fuse_operations appfs_oper = {
   871         -	.getattr   = appfs_fuse_getattr,
   872         -	.readdir   = appfs_fuse_readdir,
   873         -	.readlink  = appfs_fuse_readlink,
   874         -	.open      = appfs_fuse_open,
   875         -	.release   = appfs_fuse_close,
   876         -	.read      = appfs_fuse_read
   877         -};
   878         -
   879         -int main(int argc, char **argv) {
   880         -	const char *cachedir = APPFS_CACHEDIR;
   881         -	char dbfilename[1024];
   882         -	int pthread_ret, snprintf_ret, sqlite_ret;
   883         -
   884         -	globalThread.cachedir = cachedir;
   885         -	globalThread.boottime = time(NULL);
   886         -
   887         -	pthread_ret = pthread_key_create(&interpKey, NULL);
   888         -	if (pthread_ret != 0) {
   889         -		fprintf(stderr, "Unable to create TSD key for Tcl.  Aborting.\n");
   890         -
   891         -		return(1);
   892         -	}
   893         -
   894         -	snprintf_ret = snprintf(dbfilename, sizeof(dbfilename), "%s/%s", cachedir, "cache.db");
   895         -	if (snprintf_ret >= sizeof(dbfilename)) {
   896         -		fprintf(stderr, "Unable to set database filename.  Aborting.\n");
   897         -
   898         -		return(1);
   899         -	}
   900         -
   901         -	sqlite_ret = sqlite3_open(dbfilename, &globalThread.db);
   902         -	if (sqlite_ret != SQLITE_OK) {
   903         -		fprintf(stderr, "Unable to open database: %s\n", dbfilename);
   904         -
   905         -		return(1);
   906         -	}
   907         -
   908         -	return(fuse_main(argc, argv, &appfs_oper, NULL));
   909         -}
   910         - 

Deleted appfsd.tcl version [fc1c954390].

     1         -#! /usr/bin/env tclsh
     2         -
     3         -package require http 2.7
     4         -package require sqlite3
     5         -
     6         -namespace eval ::appfs {
     7         -	variable cachedir "/tmp/appfs-cache"
     8         -	variable ttl 3600
     9         -	variable nttl 60
    10         -
    11         -	proc _hash_sep {hash {seps 4}} {
    12         -		for {set idx 0} {$idx < $seps} {incr idx} {
    13         -			append retval "[string range $hash [expr {$idx * 2}] [expr {($idx * 2) + 1}]]/"
    14         -		}
    15         -		append retval "[string range $hash [expr {$idx * 2}] end]"
    16         -
    17         -		return $retval
    18         -	}
    19         -
    20         -	proc _cachefile {url key {keyIsHash 1}} {
    21         -		set filekey $key
    22         -		if {$keyIsHash} {
    23         -			set filekey [_hash_sep $filekey]
    24         -		}
    25         -
    26         -		set file [file join $::appfs::cachedir $filekey]
    27         -
    28         -		file mkdir [file dirname $file]
    29         -
    30         -		if {![file exists $file]} {
    31         -			set tmpfile "${file}.new"
    32         -
    33         -			set fd [open $tmpfile "w"]
    34         -			fconfigure $fd -translation binary
    35         -
    36         -			catch {
    37         -				set token [::http::geturl $url -channel $fd -binary true]
    38         -			}
    39         -
    40         -			if {[info exists token]} {
    41         -				set ncode [::http::ncode $token]
    42         -				::http::reset $token
    43         -			} else {
    44         -				set ncode "900"
    45         -			}
    46         -
    47         -			close $fd
    48         -
    49         -			if {$keyIsHash} {
    50         -				catch {
    51         -					set hash [string tolower [exec openssl sha1 $tmpfile]]
    52         -					regsub {.*= *} $hash {} hash
    53         -				}
    54         -			} else {
    55         -				set hash $key
    56         -			}
    57         -
    58         -			if {$ncode == "200" && $hash == $key} {
    59         -				file rename -force -- $tmpfile $file
    60         -			} else {
    61         -				file delete -force -- $tmpfile
    62         -			}
    63         -		}
    64         -
    65         -		return $file
    66         -	}
    67         -
    68         -
    69         -	proc _isHash {value} {
    70         -		set value [string tolower $value]
    71         -
    72         -		if {[string length $value] != 40} {
    73         -			return false
    74         -		}
    75         -
    76         -		if {![regexp {^[0-9a-f]*$} $value]} {
    77         -			return false
    78         -		}
    79         -
    80         -		return true
    81         -	}
    82         -
    83         -	proc _db {args} {
    84         -		return [uplevel 1 [list ::appfs::db {*}$args]]
    85         -	}
    86         -
    87         -	proc _normalizeOS {os} {
    88         -		set os [string tolower [string trim $os]]
    89         -
    90         -		switch -- $os {
    91         -			"linux" - "freebsd" - "openbsd" - "netbsd" {
    92         -				return $os
    93         -			}
    94         -			"sunos" {
    95         -				return "solaris"
    96         -			}
    97         -		}
    98         -
    99         -		return -code error "Unable to normalize OS: $os"
   100         -	}
   101         -
   102         -	proc _normalizeCPU {cpu} {
   103         -		set cpu [string tolower [string trim $cpu]]
   104         -
   105         -		switch -glob -- $cpu {
   106         -			"i?86" {
   107         -				return "ix86"
   108         -			}
   109         -			"x86_64" {
   110         -				return $cpu
   111         -			}
   112         -		}
   113         -
   114         -		return -code error "Unable to normalize CPU: $cpu"
   115         -	}
   116         -
   117         -	proc init {} {
   118         -		if {[info exists ::appfs::init_called]} {
   119         -			return
   120         -		}
   121         -
   122         -		set ::appfs::init_called 1
   123         -
   124         -		if {![info exists ::appfs::db]} {
   125         -			file mkdir $::appfs::cachedir
   126         -
   127         -			sqlite3 ::appfs::db [file join $::appfs::cachedir cache.db]
   128         -		}
   129         -
   130         -		_db eval {CREATE TABLE IF NOT EXISTS sites(hostname PRIMARY KEY, lastUpdate, ttl);}
   131         -		_db eval {CREATE TABLE IF NOT EXISTS packages(hostname, sha1, package, version, os, cpuArch, isLatest, haveManifest);}
   132         -		_db eval {CREATE TABLE IF NOT EXISTS files(package_sha1, type, time, source, size, perms, file_sha1, file_name, file_directory);}
   133         -	}
   134         -
   135         -	proc download {hostname hash {method sha1}} {
   136         -		set url "http://$hostname/appfs/$method/$hash"
   137         -		set file [_cachefile $url $hash]
   138         -
   139         -		if {![file exists $file]} {
   140         -			return -code error "Unable to fetch"
   141         -		}
   142         -
   143         -		return $file
   144         -	}
   145         -
   146         -	proc getindex {hostname} {
   147         -		set now [clock seconds]
   148         -
   149         -		set lastUpdates [_db eval {SELECT lastUpdate, ttl FROM sites WHERE hostname = $hostname LIMIT 1;}]
   150         -		if {[llength $lastUpdates] == 0} {
   151         -			set lastUpdate 0
   152         -			set ttl 0
   153         -		} else {
   154         -			set lastUpdate [lindex $lastUpdates 0]
   155         -			set ttl [lindex $lastUpdates 1]
   156         -		}
   157         -
   158         -		if {$now < ($lastUpdate + $ttl)} {
   159         -			return COMPLETE
   160         -		}
   161         -
   162         -		if {[string match "*\[/~\]*" $hostname]} {
   163         -			return -code error "Invalid hostname"
   164         -		}
   165         -
   166         -		set url "http://$hostname/appfs/index"
   167         -
   168         -		catch {
   169         -			set token [::http::geturl $url]
   170         -			if {[::http::ncode $token] == "200"} {
   171         -				set indexhash_data [::http::data $token]
   172         -			}
   173         -			::http::reset $token
   174         -			$token cleanup
   175         -		}
   176         -
   177         -		if {![info exists indexhash_data]} {
   178         -			# Cache this result for 60 seconds
   179         -			_db eval {INSERT OR REPLACE INTO sites (hostname, lastUpdate, ttl) VALUES ($hostname, $now, $::appfs::nttl);}
   180         -
   181         -			return -code error "Unable to fetch $url"
   182         -		}
   183         -
   184         -		set indexhash [lindex [split $indexhash_data ","] 0]
   185         -
   186         -		if {![_isHash $indexhash]} {
   187         -			return -code error "Invalid hash: $indexhash"
   188         -		}
   189         -
   190         -		set file [download $hostname $indexhash]
   191         -		set fd [open $file]
   192         -		set data [read $fd]
   193         -		close $fd
   194         -
   195         -		set curr_packages [list]
   196         -		foreach line [split $data "\n"] {
   197         -			set line [string trim $line]
   198         -
   199         -			if {[string match "*/*" $line]} {
   200         -				continue
   201         -			}
   202         -
   203         -			if {$line == ""} {
   204         -				continue
   205         -			}
   206         -
   207         -			set work [split $line ","]
   208         -
   209         -			unset -nocomplain pkgInfo
   210         -			set pkgInfo(package)  [lindex $work 0]
   211         -			set pkgInfo(version)  [lindex $work 1]
   212         -			set pkgInfo(os)       [_normalizeOS [lindex $work 2]]
   213         -			set pkgInfo(cpuArch)  [_normalizeCPU [lindex $work 3]]
   214         -			set pkgInfo(hash)     [string tolower [lindex $work 4]]
   215         -			set pkgInfo(hash_type) "sha1"
   216         -			set pkgInfo(isLatest) [expr {!![lindex $work 5]}]
   217         -
   218         -			if {![_isHash $pkgInfo(hash)]} {
   219         -				continue
   220         -			}
   221         -
   222         -			lappend curr_packages $pkgInfo(hash)
   223         -
   224         -			# Do not do any additional work if we already have this package
   225         -			set existing_packages [_db eval {SELECT package FROM packages WHERE hostname = $hostname AND sha1 = $pkgInfo(hash);}]
   226         -			if {[lsearch -exact $existing_packages $pkgInfo(package)] != -1} {
   227         -				continue
   228         -			}
   229         -
   230         -			if {$pkgInfo(isLatest)} {
   231         -				_db eval {UPDATE packages SET isLatest = 0 WHERE hostname = $hostname AND package = $pkgInfo($package) AND os = $pkgInfo($package) AND cpuArch = $pkgInfo(cpuArch);}
   232         -			}
   233         -
   234         -			_db eval {INSERT INTO packages (hostname, sha1, package, version, os, cpuArch, isLatest, haveManifest) VALUES ($hostname, $pkgInfo(hash), $pkgInfo(package), $pkgInfo(version), $pkgInfo(os), $pkgInfo(cpuArch), $pkgInfo(isLatest), 0);}
   235         -		}
   236         -
   237         -		# Look for packages that have been deleted
   238         -		set found_packages [_db eval {SELECT sha1 FROM packages WHERE hostname = $hostname;}]
   239         -		foreach package $found_packages {
   240         -			set found_packages_arr($package) 1
   241         -		}
   242         -
   243         -		foreach package $curr_packages {
   244         -			unset -nocomplain found_packages_arr($package)
   245         -		}
   246         -
   247         -		foreach package [array names found_packages_arr] {
   248         -			_db eval {DELETE FROM packages WHERE hostname = $hostname AND sha1 = $package;}
   249         -		}
   250         -
   251         -		_db eval {INSERT OR REPLACE INTO sites (hostname, lastUpdate, ttl) VALUES ($hostname, $now, $::appfs::ttl);}
   252         -
   253         -		return COMPLETE
   254         -	}
   255         -
   256         -	proc getpkgmanifest {hostname package_sha1} {
   257         -		set haveManifests [_db eval {SELECT haveManifest FROM packages WHERE sha1 = $package_sha1 LIMIT 1;}]
   258         -		set haveManifest [lindex $haveManifests 0]
   259         -
   260         -		if {$haveManifest} {
   261         -			return COMPLETE
   262         -		}
   263         -
   264         -		if {![_isHash $package_sha1]} {
   265         -			return FAIL
   266         -		}
   267         -
   268         -		set file [download $hostname $package_sha1]
   269         -		set fd [open $file]
   270         -		set pkgdata [read $fd]
   271         -		close $fd
   272         -
   273         -		_db transaction {
   274         -			foreach line [split $pkgdata "\n"] {
   275         -				set line [string trim $line]
   276         -
   277         -				if {$line == ""} {
   278         -					continue
   279         -				}
   280         -
   281         -				set work [split $line ","]
   282         -
   283         -				unset -nocomplain fileInfo
   284         -				set fileInfo(type) [lindex $work 0]
   285         -				set fileInfo(time) [lindex $work 1]
   286         -
   287         -				set work [lrange $work 2 end]
   288         -				switch -- $fileInfo(type) {
   289         -					"file" {
   290         -						set fileInfo(size) [lindex $work 0]
   291         -						set fileInfo(perms) [lindex $work 1]
   292         -						set fileInfo(sha1) [lindex $work 2]
   293         -
   294         -						set work [lrange $work 3 end]
   295         -					}
   296         -					"symlink" {
   297         -						set fileInfo(source) [lindex $work 0]
   298         -						set work [lrange $work 1 end]
   299         -					}
   300         -				}
   301         -
   302         -				set fileInfo(name) [join $work ","]
   303         -				set fileInfo(name) [split [string trim $fileInfo(name) "/"] "/"]
   304         -				set fileInfo(directory) [join [lrange $fileInfo(name) 0 end-1] "/"]
   305         -				set fileInfo(name) [lindex $fileInfo(name) end]
   306         -
   307         -				_db eval {INSERT INTO files (package_sha1, type, time, source, size, perms, file_sha1, file_name, file_directory) VALUES ($package_sha1, $fileInfo(type), $fileInfo(time), $fileInfo(source), $fileInfo(size), $fileInfo(perms), $fileInfo(sha1), $fileInfo(name), $fileInfo(directory) );}
   308         -				_db eval {UPDATE packages SET haveManifest = 1 WHERE sha1 = $package_sha1;}
   309         -			}
   310         -		}
   311         -
   312         -		return COMPLETE
   313         -	}
   314         -}

Name change from packages/build to build.


Name change from packages/build.conf to build.conf.


Name change from packages/pkgs/glibc to pkgs/glibc.


Name change from packages/pkgs/readline to pkgs/readline.