Changes On Branch packages

Changes In Branch packages Excluding Merge-Ins

This is equivalent to a diff from 17bbfdc417 to 4a0ff085ab

2018-11-16
21:38
Many build script updates Leaf check-in: 4a0ff085ab user: rkeene tags: packages
21:38
Upgraded to latest Tcl check-in: 3f2cfe4d81 user: rkeene tags: packages
2014-09-18
05:14
Added support for a "platform" symlink pointing to the current platform check-in: 7ef423f980 user: rkeene tags: trunk
04:43
Added package building branch check-in: 07e806db4e user: rkeene tags: packages
2014-09-16
18:21
Removed blank line check-in: 17bbfdc417 user: rkeene tags: trunk
2014-09-14
04:36
Updated to normalize CPU/OS check-in: ee1a499a2e user: rkeene tags: trunk

Modified .fossil-settings/ignore-glob from [5155de6731] to [171004757d].

     1         -appfsd
     2         -appfsd.o
     3         -appfsd.tcl.h
            1  +workdir-*
            2  +ARCHIVE

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         -}

Added build version [970bc0b0dc].

            1  +#! /usr/bin/env bash
            2  +
            3  +# Set timezone to default
            4  +TZ=UTC
            5  +export TZ
            6  +
            7  +targetmode='install'
            8  +if [ "$1" == '--cpio' ]; then
            9  +	targetmode='archive'
           10  +
           11  +	shift
           12  +fi
           13  +
           14  +pkg="$(echo "$1" | sed 's@/*$@@;s@^\.*/*@@')"
           15  +
           16  +if [ -z "${pkg}" ]; then
           17  +	echo "Usage: build [--cpio] <package>" 2>&1
           18  +
           19  +	exit 1
           20  +fi
           21  +
           22  +function predownload() {
           23  +	:
           24  +}
           25  +
           26  +function download() {
           27  +	if [ ! -e "${pkgarchive}" ]; then
           28  +		# Download
           29  +		## Cleanup
           30  +		rm -f src.new
           31  +
           32  +		## Fetch file
           33  +		wget --no-check-certificate -O src.new "${url}" || exit 1
           34  +
           35  +		## Verify signature
           36  +		src_sha256="$(openssl sha256 'src.new' | sed 's@^.*= @@')"
           37  +		if [ "${src_sha256}" != "${sha256}" ]; then
           38  +			echo "SHA256 mismatch:  Downloaded: ${src_sha256} != Expected: ${sha256}" >&2
           39  +
           40  +			exit 1
           41  +		fi
           42  +
           43  +		## Move file into place
           44  +		mv src.new "${pkgarchive}"
           45  +	fi
           46  +}
           47  +
           48  +function extract() {
           49  +	local decompress
           50  +
           51  +	# Decompress archive
           52  +	## Determine type of archive
           53  +	case "${url}" in
           54  +		*.tar.xz|*.tar.xz'?'*|*.txz)
           55  +			decompress='xz'
           56  +			;;
           57  +		*.tar.gz|*.tar.gz'?'*|*.tgz)
           58  +			decompress='gzip'
           59  +			;;
           60  +		*.tar.bz2|*.tar.bz2'?'*|*.tbz2)
           61  +			decompress='bzip2'
           62  +			;;
           63  +		*.zip|*.zip'?'*)
           64  +			decompress='unzip'
           65  +			;;
           66  +		*)
           67  +			echo "Unknown compression method: ${url}" >&2
           68  +
           69  +			exit 1
           70  +			;;
           71  +	esac
           72  +
           73  +	## Do decompression
           74  +	case "${decompress}" in
           75  +		unzip)
           76  +			unzip "${pkgarchive}" || die 'Unable to uncompress archive'
           77  +			;;
           78  +		*)
           79  +			"${decompress}" -dc "${pkgarchive}" | tar -xf - || die 'Unable to uncompress archive'
           80  +			;;
           81  +	esac
           82  +}
           83  +
           84  +function apply_patches() {
           85  +	local patch
           86  +
           87  +	for patch in "${pkgdir}/patches"/*; do
           88  +		if [ ! -e "${patch}" ]; then
           89  +			continue
           90  +		fi
           91  +
           92  +		case "${patch}" in
           93  +			*.diff|*.patch)
           94  +				;;
           95  +			*)
           96  +				continue
           97  +				;;
           98  +		esac
           99  +
          100  +		if [ -e "${patch}.sh" ]; then
          101  +			if ! sh "${patch}.sh"; then
          102  +				continue
          103  +			fi
          104  +		fi
          105  +
          106  +		patch -p1 < "${patch}"
          107  +	done
          108  +}
          109  +
          110  +function verifyRequiredPackages() {
          111  +	local pkg pkgdomain pkgversion
          112  +	local pkgdir pkgconfigdir pkgfound
          113  +	local use_native_platform
          114  +	local add_headers_str
          115  +
          116  +	SAVE_PKG_CONFIG_PATH="${PKG_CONFIG_PATH}"
          117  +	PKG_CONFIG_PATH=''
          118  +	export PKG_CONFIG_PATH
          119  +
          120  +	use_native_platform='0'
          121  +	for pkg in "${require[@]}"; do
          122  +		case "${pkg}" in
          123  +			@native-os)
          124  +				use_native_platform='1'
          125  +				;;
          126  +		esac
          127  +	done
          128  +
          129  +	if [ "${use_native_platform}" = '1' ]; then
          130  +		add_headers_str='-I'
          131  +	else
          132  +		add_headers_str='-isystem '
          133  +	fi
          134  +
          135  +	for pkg in "${require[@]}"; do
          136  +		pkgdomain=''
          137  +		pkgversion=''
          138  +		pkgchanges=(CFLAGS LDFLAGS PATH PKG_CONFIG_PATH)
          139  +
          140  +		case "${pkg}" in
          141  +			*:*)
          142  +				pkgchanges=($(echo "${pkg}" | cut -f 2 -d ':'))
          143  +				pkg="$(echo "${pkg}" | cut -f 1 -d ':')"
          144  +				;;
          145  +		esac
          146  +
          147  +		case "${pkg}" in
          148  +			@native-os)
          149  +				PKG_CONFIG_PATH="${PKG_CONFIG_PATH}:${SAVE_PKG_CONFIG_PATH}"
          150  +
          151  +				continue
          152  +				;;
          153  +			@*)
          154  +				# Fake package
          155  +				continue
          156  +				;;
          157  +			*/*@*)
          158  +				pkgdomain="$(echo "${pkg}" | cut -f 2 -d '@')"
          159  +				pkgversion="$(echo "${pkg}" | cut -f 2 -d '/' | cut -f 1 -d '@')"
          160  +				pkg="$(echo "${pkg}" | cut -f 1 -d '/')"
          161  +				;;
          162  +			*/*)
          163  +				pkgversion="$(echo "${pkg}" | cut -f 2 -d '/')"
          164  +				pkg="$(echo "${pkg}" | cut -f 1 -d '/')"
          165  +				;;
          166  +			*@*)
          167  +				pkgdomain="$(echo "${pkg}" | cut -f 2 -d '@')"
          168  +				pkg="$(echo "${pkg}" | cut -f 1 -d '@')"
          169  +				;;
          170  +		esac
          171  +
          172  +		if [ -z "${pkgdomain}" ]; then
          173  +			pkgdomain="${domain}"
          174  +		fi
          175  +
          176  +		pkgfound='0'
          177  +		ADD_PATH=''
          178  +		for pkgdir in "/opt/appfs/${pkgdomain}/${pkg}/${os}-${arch}"/${pkgversion:-latest} "/opt/appfs/${pkgdomain}/${pkg}/${os}-${arch}"/${pkgversion:-*}; do
          179  +			pkgconfigdir="${pkgdir}/lib/pkgconfig"
          180  +
          181  +			if [ ! -d "${pkgdir}" ]; then
          182  +				continue
          183  +			fi
          184  +
          185  +			# If the package version was unspecified, fully resolve
          186  +			# the directory that we found
          187  +			if [ -z "${pkgversion}" ]; then
          188  +				pkgdir="$(readlink -f "${pkgdir}")"
          189  +			fi
          190  +
          191  +			pkgfound='1'
          192  +
          193  +			for pkgchange in "${pkgchanges[@]}"; do
          194  +				case "${pkgchange}" in
          195  +					CFLAGS)
          196  +						CFLAGS="${CFLAGS} ${add_headers_str}${pkgdir}/include"
          197  +						CXXFLAGS="${CFLAGS} ${add_headers_str}${pkgdir}/include"
          198  +						CPPFLAGS="${CPPFLAGS} ${add_headers_str}${pkgdir}/include"
          199  +						export CFLAGS CXXFLAGS CPPFLAGS
          200  +						;;
          201  +					LDFLAGS)
          202  +						LDFLAGS="${LDFLAGS} -L${pkgdir}/lib -Wl,-rpath,${pkgdir}/lib"
          203  +						export LDFLAGS
          204  +						;;
          205  +					PATH)
          206  +						ADD_PATH="${ADD_PATH}:${pkgdir}/bin"
          207  +						;;
          208  +					PERL5LIB)
          209  +						PERL5LIB="${pkgdir}/lib/perl5:${PERL5LIB}"
          210  +						PERL5LIB="${pkgdir}/lib/site_perl:${PERL5LIB}"
          211  +						export PERL5LIB
          212  +						;;
          213  +					PKG_CONFIG_PATH)
          214  +						if [ -d "${pkgconfigdir}" ]; then
          215  +							PKG_CONFIG_PATH="${PKG_CONFIG_PATH}:${pkgconfigdir}"
          216  +							export PKG_CONFIG_PATH
          217  +						fi
          218  +						;;
          219  +				esac
          220  +			done
          221  +
          222  +			break
          223  +		done
          224  +
          225  +		if [ "${pkgfound}" = '0' ]; then
          226  +			die "Package ${pkg}/${pkgversion:-*}@${pkgdomain} not found."
          227  +		fi
          228  +
          229  +		ADD_PATH="$(echo "${ADD_PATH}" | sed 's@^:*@@')"
          230  +
          231  +		PATH="${ADD_PATH}:${PATH}"
          232  +	done
          233  +}
          234  +
          235  +function verifyPrerequisites() {
          236  +	:
          237  +}
          238  +
          239  +function determineOsArch() {
          240  +	if [ -z "${APPFS_BUILD_OS}" ]; then
          241  +		os="$(uname -s | dd conv=lcase 2>/dev/null)"
          242  +	else
          243  +		os="${APPFS_BUILD_OS}"
          244  +	fi
          245  +
          246  +	if [ -z "${APPFS_BUILD_ARCH}" ]; then
          247  +		arch="$(uname -m | dd conv=lcase 2>/dev/null)"
          248  +
          249  +		case "${arch}" in
          250  +			i?86)
          251  +				arch='ix86'
          252  +				;;
          253  +		esac
          254  +	else
          255  +		arch="${APPFS_BUILD_ARCH}"
          256  +	fi
          257  +}
          258  +
          259  +function determinePrefix() {
          260  +	determineOsArch
          261  +
          262  +	prefixsuffix="${pkg}/${os}-${arch}/${version}"
          263  +	prefix="/opt/appfs/${domain}/${prefixsuffix}"
          264  +	destdir="$(pwd)/INST"
          265  +
          266  +	mkdir "${destdir}" || die
          267  +}
          268  +
          269  +function preconfigure() {
          270  +	:
          271  +}
          272  +
          273  +function postconfigure() {
          274  +	:
          275  +}
          276  +
          277  +function configure_gcc() {
          278  +	local glibcdir linuxheadersdir
          279  +	local dynlinker
          280  +	local gcc_default_headers_c gcc_default_headers_cxx
          281  +	local pkg use_native_platform
          282  +
          283  +	glibcdir="/opt/appfs/core.appfs.rkeene.org/glibc/${os}-${arch}/latest"
          284  +	glibcdir="$(readlink -f "${glibcdir}")"
          285  +
          286  +	linuxheadersdir="/opt/appfs/core.appfs.rkeene.org/linux-headers/${os}-${arch}/latest"
          287  +	linuxheadersdir="$(readlink -f "${linuxheadersdir}")"
          288  +
          289  +	dynlinker="$(ls "${glibcdir}"/lib/ld-linux*.so.* | tail -n 1)"
          290  +
          291  +	if [ ! -f "${dynlinker}" ]; then
          292  +		die 'glibc directory is not available (appfs running/working?)'
          293  +	fi
          294  +
          295  +	use_native_platform='0'
          296  +	for pkg in "${require[@]}"; do
          297  +		case "${pkg}" in
          298  +			@native-os)
          299  +				use_native_platform='1'
          300  +				;;
          301  +		esac
          302  +	done
          303  +
          304  +	if [ "${use_native_platform}" = '0' ]; then
          305  +		gcc_default_headers_c="$(echo '' | ${CPP:-cpp} -v 2>&1 | sed '/^End of search list/,$ d;0,/search starts here:$/ d' | grep '/gcc/' | sed 's@^ *@-isystem @' | tr $'\n' ' ')"
          306  +		gcc_default_headers_cxx="$(echo '' | ${CPP:-cpp} -x c++ -v 2>&1 | sed '/^End of search list/,$ d;0,/search starts here:$/ d' | grep '/gcc/' | sed 's@^ *@-isystem @' | tr $'\n' ' ')"
          307  +
          308  +		CC="${CC:-gcc} -nostdinc ${gcc_default_headers_c} -isystem ${glibcdir}/include"
          309  +		CXX="${CXX:-g++} -nostdinc ${gcc_default_headers_cxx} -isystem ${glibcdir}/include"
          310  +
          311  +		if ! echo " ${require[*]} " | grep ' linux-headers[/@: ]' >/dev/null; then
          312  +			CC="${CC} -isystem ${linuxheadersdir}/include"
          313  +			CXX="${CXX} -isystem ${linuxheadersdir}/include"
          314  +		fi
          315  +	else
          316  +		CC="${CC:-gcc}"
          317  +		CXX="${CXX:-g++}"
          318  +	fi
          319  +
          320  +	BUILD_CC="${CC}"
          321  +	HOST_CC="${CC}"
          322  +	BUILD_CXX="${CXX}"
          323  +	HOST_CXX="${CXX}"
          324  +
          325  +	if [ "${use_native_platform}" = '0' ]; then
          326  +		LDFLAGS="${LDFLAGS} -L${glibcdir}/lib -Wl,-rpath,${glibcdir}/lib -Wl,--dynamic-linker,${dynlinker}"
          327  +	fi
          328  +
          329  +	if [ -z "${appfs_build_no_default_symver}" ]; then
          330  +		LDFLAGS="${LDFLAGS} -Wl,--default-symver"
          331  +	fi
          332  +
          333  +	PKG_CONFIG_LIBDIR="${glibcdir}/lib/pkgconfig"
          334  +
          335  +	export CC CXX BUILD_CC HOST_CC BUILD_CXX HOST_CXX LDFLAGS PKG_CONFIG_LIBDIR
          336  +}
          337  +
          338  +function configure() {
          339  +	configure_gcc
          340  +	./configure --prefix="${prefix}" --sysconfdir="${prefix}/etc" --libdir="${prefix}/lib" --localstatedir=/var "${configure_extra[@]}"
          341  +}
          342  +
          343  +function prebuild() {
          344  +	:
          345  +}
          346  +
          347  +function postbuild() {
          348  +	:
          349  +}
          350  +
          351  +function build() {
          352  +	grep "DESTDIR" Makefile >/dev/null || die "Don't know how to build this software"
          353  +
          354  +	make "${make_extra[@]}"
          355  +}
          356  +
          357  +function preinstall() {
          358  +	:
          359  +}
          360  +
          361  +function postinstall() {
          362  +	:
          363  +}
          364  +
          365  +function install() {
          366  +	make "${make_extra[@]}" install DESTDIR="${destdir}"
          367  +}
          368  +
          369  +function cleanup() {
          370  +	cd "${workdir}" || exit 1
          371  +	cd .. || exit 1
          372  +	rm -rf "${workdir}"
          373  +}
          374  +
          375  +function die() {
          376  +	local message
          377  +
          378  +	message="$1"
          379  +
          380  +	if [ -n "${message}" ]; then
          381  +		echo "error: ${message}" >&2
          382  +	fi
          383  +
          384  +	exit 1
          385  +}
          386  +
          387  +scriptdir="$(cd "$(dirname "$(which "$0")")" && pwd)"
          388  +if [ -z "${scriptdir}" ]; then
          389  +	echo "Unable to locate script directory" >&2
          390  +
          391  +	exit 1
          392  +fi
          393  +
          394  +cd "${scriptdir}" || exit 1
          395  +
          396  +if [ -f 'build.conf' ]; then
          397  +	. 'build.conf'
          398  +fi
          399  +
          400  +if [ -d "pkgs/${pkg}" ]; then
          401  +	pkgdir="$(pwd)/pkgs/${pkg}"
          402  +	pkgfile="${pkgdir}/info"
          403  +else
          404  +	pkgfile="$(pwd)/pkgs/${pkg}"
          405  +	pkgdir="${pkgfile}"
          406  +fi
          407  +
          408  +if [ ! -e "${pkgfile}" ]; then
          409  +	echo "Invalid package." >&2
          410  +
          411  +	exit 1
          412  +fi
          413  +
          414  +pkgdate="$(for artifact in $(find "${pkgdir}" -type f -print0 | xargs -n 1 -0 fossil finfo --limit 1 --width 0 2>/dev/null | grep '^[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9] ' | sed 's@^[^ ]* \[@@;s@\].*@@' | sort -u); do fossil info "${artifact}" | awk '/^uuid:/{ print $3 $4 }' | sed 's@[-:]@@g;s@..$@\.&@'; done | sort -n | tail -n 1)"
          415  +if [ -z "${pkgdate}" ]; then
          416  +	pkgdate="$(find "${pkgdir}" -type f -printf '%TY%Tm%Td%TH%TM.%TS\n' 2>/dev/null | cut -f 1-2 -d '.' | sort -n | tail -n 1)"
          417  +fi
          418  +
          419  +. "${pkgfile}"
          420  +
          421  +archivedir="$(pwd)/ARCHIVE"
          422  +workdir="workdir-$$${RANDOM}${RANDOM}${RANDOM}"
          423  +pkgarchive="${archivedir}/${pkg}-${version}.archive"
          424  +mkdir "${archivedir}" >/dev/null 2>/dev/null
          425  +mkdir "${workdir}" || exit 1
          426  +cd "${workdir}" || exit 1
          427  +workdir="$(pwd)"
          428  +
          429  +# Download
          430  +predownload
          431  +download
          432  +
          433  +# Extract
          434  +extract
          435  +
          436  +# If we just have one directory, use that directory
          437  +dir="$(echo *)"
          438  +if [ -e "${dir}" ]; then
          439  +	(
          440  +		shopt -s dotglob
          441  +		mv "${dir}"/* .
          442  +	)
          443  +fi
          444  +
          445  +# Determine properties
          446  +determinePrefix
          447  +
          448  +# Start logging
          449  +set -x
          450  +
          451  +# Verify pre-requisites are met
          452  +verifyRequiredPackages || die 'Required packages missing'
          453  +verifyPrerequisites || die 'Prerequisities failed'
          454  +
          455  +# Apply patches
          456  +apply_patches
          457  +
          458  +# Start the build
          459  +preconfigure || die 'preconfigure failed'
          460  +configure || die 'configure failed'
          461  +postconfigure || die 'postconfigure failed'
          462  +
          463  +prebuild || die 'prebuild failed'
          464  +build || die 'build failed'
          465  +postbuild || die 'postbuild failed'
          466  +
          467  +preinstall || die 'preinstall failed'
          468  +install || die 'install failed'
          469  +postinstall || die 'postinstall failed'
          470  +
          471  +(
          472  +	case "${targetmode}" in
          473  +		install)
          474  +			appdir="$(appfsinstalldir)/${prefixsuffix}"
          475  +			mkdir -p "${appdir}"
          476  +
          477  +			cd "${destdir}/${prefix}" || exit 1
          478  +
          479  +			cp -rp * "${appdir}"
          480  +			find "${appdir}" -print0 | xargs -0 touch -t "${pkgdate}"
          481  +			find "${appdir}" -print0 | xargs -0 touch -m -t "${pkgdate}"
          482  +			find "${appdir}" -print0 | xargs -0 touch -a -t "${pkgdate}"
          483  +			;;
          484  +		archive)
          485  +			archivefile="${scriptdir}/${pkg}-${version}-$(echo "${pkgdate}" | sed 's@\.@@g')-${os}-${arch}-${domain}.cpio"
          486  +			cd "${destdir}/${prefix}/../../.." || exit 1
          487  +			find "${prefixsuffix}" -print0 | xargs -0 touch -t "${pkgdate}"
          488  +			find "${prefixsuffix}" -print0 | xargs -0 touch -m -t "${pkgdate}"
          489  +			find "${prefixsuffix}" -print0 | xargs -0 touch -a -t "${pkgdate}"
          490  +			find "${prefixsuffix}" | sort | cpio --owner 0:0 -H newc -o > "${archivefile}"
          491  +			;;
          492  +	esac
          493  +) || die 'final installation failed'
          494  +
          495  +cleanup
          496  +
          497  +exit 0

Added build.conf version [501534cf12].

            1  +domain=rkeene.org
            2  +function appfsinstalldir() {
            3  +	case "${domain}" in
            4  +		rkeene.org)
            5  +			echo "/web/rkeene/appfs/applications"
            6  +			;;
            7  +		appfs.rkeene.org)
            8  +			echo "/web/customers/appfs.rkeene.org/appfs/applications"
            9  +			;;
           10  +		core.appfs.rkeene.org)
           11  +			echo "/web/static/core.appfs.rkeene.org/appfs/applications"
           12  +			;;
           13  +	esac
           14  +}

Added pkgs/acl version [b995987669].

            1  +#! /usr/bin/env bash
            2  +
            3  +version='2.2.52'
            4  +url="http://download.savannah.gnu.org/releases/acl/acl-${version}.src.tar.gz"
            5  +domain=core.appfs.rkeene.org
            6  +sha256='179074bb0580c06c4b4137be4c5a92a701583277967acdb5546043c7874e0d23'
            7  +require=(attr)
            8  +
            9  +function prebuild() {
           10  +	echo "# Ignore: DESTDIR" >> Makefile
           11  +}
           12  +
           13  +function install() {
           14  +	make install install-dev install-lib DESTDIR="${destdir}"
           15  +}
           16  +
           17  +function postinstall() {
           18  +	rm -f "${destdir}/${prefix}/libexec/libacl.so"
           19  +	mv "${destdir}/${prefix}"/libexec/* "${destdir}/${prefix}/lib/"
           20  +	rm -rf "${destdir}/${prefix}/libexec"
           21  +}

Added pkgs/attr/info version [59cddfa940].

            1  +#! /usr/bin/env bash
            2  +
            3  +version='2.4.47'
            4  +url="http://download.savannah.gnu.org/releases/attr/attr-${version}.src.tar.gz"
            5  +domain=core.appfs.rkeene.org
            6  +sha256='25772f653ac5b2e3ceeb89df50e4688891e21f723c460636548971652af0a859'
            7  +
            8  +function prebuild() {
            9  +	echo "# Ignore: DESTDIR" >> Makefile
           10  +}
           11  +
           12  +function install() {
           13  +	make install install-dev install-lib DESTDIR="${destdir}"
           14  +}

Added pkgs/attr/patches/attr.destdir.diff version [a05356e164].

            1  +--- ./include/builddefs.in.orig	2011-04-08 11:56:59.000000000 -0500
            2  ++++ ./include/builddefs.in	2011-04-18 13:27:35.000000000 -0500
            3  +@@ -40,14 +40,14 @@
            4  + PKG_VERSION	= @pkg_version@
            5  + PKG_PLATFORM	= @pkg_platform@
            6  + PKG_DISTRIBUTION= @pkg_distribution@
            7  +-PKG_BIN_DIR	= @bindir@
            8  +-PKG_SBIN_DIR	= @sbindir@
            9  +-PKG_LIB_DIR	= @libdir@@libdirsuffix@
           10  +-PKG_DEVLIB_DIR	= @libexecdir@@libdirsuffix@
           11  +-PKG_INC_DIR	= @includedir@/attr
           12  +-PKG_MAN_DIR	= @mandir@
           13  +-PKG_DOC_DIR	= @datadir@/doc/@pkg_name@
           14  +-PKG_LOCALE_DIR	= @datadir@/locale
           15  ++PKG_BIN_DIR	= $(DESTDIR)@bindir@
           16  ++PKG_SBIN_DIR	= $(DESTDIR)@sbindir@
           17  ++PKG_LIB_DIR	= $(DESTDIR)@libdir@@libdirsuffix@
           18  ++PKG_DEVLIB_DIR	= $(DESTDIR)@libexecdir@@libdirsuffix@
           19  ++PKG_INC_DIR	= $(DESTDIR)@includedir@/attr
           20  ++PKG_MAN_DIR	= $(DESTDIR)@mandir@
           21  ++PKG_DOC_DIR	= $(DESTDIR)@datadir@/doc/@pkg_name@
           22  ++PKG_LOCALE_DIR	= $(DESTDIR)@datadir@/locale
           23  + 
           24  + CC		= @cc@
           25  + AWK		= @awk@
           26  +--- ./include/buildmacros.orig	2011-04-08 11:56:59.000000000 -0500
           27  ++++ ./include/buildmacros	2011-04-18 13:28:23.000000000 -0500
           28  +@@ -40,7 +40,7 @@
           29  + 	  $(LFILES:.l=.o) \
           30  + 	  $(YFILES:%.y=%.tab.o)
           31  + 
           32  +-INSTALL	= $(TOPDIR)/include/install-sh -o $(PKG_USER) -g $(PKG_GROUP)
           33  ++INSTALL	= $(TOPDIR)/include/install-sh
           34  + 
           35  + SHELL = /bin/sh
           36  + IMAGES_DIR = $(TOPDIR)/all-images

Added pkgs/bash version [22239c774b].

            1  +#! /usr/bin/env bash
            2  +
            3  +version='4.3.30'
            4  +url="http://ftp.gnu.org/gnu/bash/bash-${version}.tar.gz"
            5  +domain=core.appfs.rkeene.org
            6  +sha256='317881019bbf2262fb814b7dd8e40632d13c3608d2f237800a8828fbb8a640dd'
            7  +require=(zlib readline ncurses)

Added pkgs/binutils version [c2b1e3701b].

            1  +#! /usr/bin/env bash
            2  +
            3  +version=2.24
            4  +url="http://ftp.gnu.org/gnu/binutils/binutils-2.24.tar.gz"
            5  +domain=core.appfs.rkeene.org
            6  +sha256='4930b2886309112c00a279483eaef2f0f8e1b1b62010e0239c16b22af7c346d4'
            7  +require=(zlib)

Added pkgs/bzip2 version [99cab0ae8a].

            1  +#! /usr/bin/env bash
            2  +
            3  +version=1.0.6
            4  +url="http://www.bzip.org/${version}/bzip2-${version}.tar.gz"
            5  +sha256="a2848f34fcd5d6cf47def00461fcb528a0484d8edef8208d6d2e2909dc61d9cd"
            6  +domain='core.appfs.rkeene.org'
            7  +require=()
            8  +
            9  +function configure() {
           10  +	configure_gcc
           11  +	cat Makefile-libbz2_so | sed "s|CC=gcc|CC=${CC} ${CFLAGS} ${LDFLAGS}|g" > Makefile-libbz2_so.new
           12  +	cat Makefile | sed "s|LDFLAGS=|LDFLAGS=${LDFLAGS}|g" | sed "s|CFLAGS=|CFLAGS=${CFLAGS} |g" > Makefile.new
           13  +	mv -f Makefile-libbz2_so.new Makefile-libbz2_so
           14  +	mv -f Makefile.new Makefile
           15  +}
           16  +
           17  +function build() {
           18  +	make -f Makefile-libbz2_so PREFIX="${prefix}"
           19  +}
           20  +
           21  +function install() {
           22  +	make install PREFIX="${destdir}/${prefix}"
           23  +	mv libbz2*.so* ${destdir}/${prefix}/lib
           24  +	(
           25  +		cd "${destdir}/${prefix}/bin" || exit 1
           26  +		rm -f bzcmp bzegrep bzfgrep bzless
           27  +		ln -s bzdiff bzcmp
           28  +		ln -s bzgrep bzegrep
           29  +		ln -s bzgrep bzfgrep
           30  +		ln -s bzmore bzless
           31  +	) || return 1
           32  +
           33  +	(
           34  +		cd "${destdir}/${prefix}/lib" || exit 1
           35  +		rm -f bzcmp bzegrep bzfgrep bzless
           36  +		ln -s libbz2.so.1.0 libbz2.so.1
           37  +		ln -s libbz2.so.1 libbz2.so
           38  +	) || return 1
           39  +}

Added pkgs/coreutils version [a1c739d508].

            1  +#! /usr/bin/env bash
            2  +
            3  +version='8.23'
            4  +url="http://ftp.gnu.org/gnu/coreutils/coreutils-${version}.tar.xz"
            5  +domain=core.appfs.rkeene.org
            6  +sha256='ec43ca5bcfc62242accb46b7f121f6b684ee21ecd7d075059bf650ff9e37b82d'
            7  +require=(attr acl libcap)
            8  +configure_extra=(--without-gmp)
            9  +
           10  +function preconfigure() {
           11  +	DEFAULT_POSIX2_VERSION=199209
           12  +	export DEFAULT_POSIX2_VERSION
           13  +}

Added pkgs/dact version [3cfe3783a4].

            1  +#! /usr/bin/env bash
            2  +
            3  +version='0.8.42'
            4  +url="http://www.rkeene.org/devel/dact-${version}.tar.gz"
            5  +sha256='08c91d36b2de30c4f2e9e13a7b044c137c096db2ba8d868d1962e209dd6b2ed8'
            6  +domain='rkeene.org'
            7  +require=(zlib@core.appfs.rkeene.org bzip2@core.appfs.rkeene.org)
            8  +
            9  +function preconfigure() {
           10  +	sed -i -r 's/^(prefix|libdir|sysconfdir) *= */&$(DESTDIR)/g' Makefile.in
           11  +	sed -i '/^ALGO *=/ a \
           12  +MODS = $(ALGO:.c=.so)' Makefile.in
           13  +}
           14  +
           15  +function postinstall() {
           16  +	# Delete incomplete "libdact"
           17  +	rm -f "${destdir}/${prefix}"/lib/libdact*
           18  +	rmdir "${destdir}/${prefix}/lib" >/dev/null 2>/dev/null
           19  +
           20  +	return 0
           21  +}

Added pkgs/ffmpeg version [dc320025c3].

            1  +#! /usr/bin/env bash
            2  +
            3  +version='2.4.3'
            4  +url="https://www.ffmpeg.org/releases/ffmpeg-${version}.tar.bz2"
            5  +domain=rkeene.org
            6  +sha256='ca5c3e3c0e4f9e43b9dceafceb866acb1ea575cb9f2d94e0d959303e4fc4e602'
            7  +require=(zlib@core.appfs.rkeene.org readline@core.appfs.rkeene.org)
            8  +make_extra=(-j10)
            9  +
           10  +function configure() {
           11  +	configure_gcc
           12  +	CC="$(echo "${CC}" | sed 's@ -nostdinc @ @g')"
           13  +	./configure --prefix="${prefix}" --cc="${CC} ${CPPFLAGS}" --extra-cflags="${CFLAGS}" --host-cppflags="${CPPFLAGS}" --extra-ldflags="${LDFLAGS}" --enable-shared --enable-pic --enable-rpath --enable-x11grab --enable-gpl || return 1
           14  +	echo '# Ignore: DESTDIR' >> Makefile
           15  +}

Added pkgs/filed version [4dd4fb9eb5].

            1  +#! /usr/bin/env bash
            2  +
            3  +version='1.12'
            4  +url="http://filed.rkeene.org/fossil/tarball/filed-${version}.tar.gz?uuid=${version}"
            5  +sha256='807931f6c8ab4c90e26f5221e89558a84b31d4b4ce60c8c2cccb09350e25de85'
            6  +domain='rkeene.org'
            7  +
            8  +function configure() {
            9  +	configure_gcc
           10  +}
           11  +
           12  +function build() {
           13  +	make prefix="${prefix}" CC="${CC} ${CFLAGS}" LDFLAGS="-pthread ${LDFLAGS}"
           14  +}
           15  +
           16  +function install() {
           17  +	make install prefix="${prefix}" DESTDIR="${destdir}"
           18  +}

Added pkgs/fossil version [c83508e264].

            1  +#! /usr/bin/env bash
            2  +
            3  +version='1.32'
            4  +url="https://www.fossil-scm.org/download/fossil-src-${version}.tar.gz"
            5  +sha256='cd79c333eb9e86fbb8c17bf5cdf31c387e4ab768eede623aed21adfdbcad686e'
            6  +require=(zlib@core.appfs.rkeene.org)
            7  +
            8  +function configure() {
            9  +	configure_gcc
           10  +
           11  +	CCACHE=none
           12  +	export CCACHE
           13  +
           14  +	./configure "${configure_extra[@]}"
           15  +}
           16  +
           17  +function build() {
           18  +	make
           19  +}
           20  +
           21  +function install() {
           22  +	mkdir -p "${destdir}/${prefix}/bin"
           23  +	cp fossil "${destdir}/${prefix}/bin/"
           24  +	chmod 755 "${destdir}/${prefix}/bin/fossil"
           25  +}

Added pkgs/gcc version [ef2bd3b72e].

            1  +#! /usr/bin/env bash
            2  +
            3  +version=4.9.2
            4  +url="http://ftp.gnu.org/gnu/gcc/gcc-${version}/gcc-${version}.tar.gz"
            5  +domain=core.appfs.rkeene.org
            6  +sha256='3e573826ec8b0d62d47821408fbc58721cd020df3e594cd492508de487a43b5e'
            7  +require=(zlib binutils:PATH linux-headers/2.6.32.63)
            8  +configure_extra=(--disable-multilib)

Added pkgs/glibc version [a1708aed89].

            1  +#! /usr/bin/env bash
            2  +
            3  +version=2.20
            4  +url="http://ftp.gnu.org/gnu/glibc/glibc-${version}.tar.xz"
            5  +domain=core.appfs.rkeene.org
            6  +sha256='f84b6d42aecc288d593c397b0a3d02260a33ee686bce0c634eb9b32798f36ba5'
            7  +
            8  +function configure() {
            9  +	mkdir BUILD
           10  +	cd BUILD
           11  +
           12  +	../configure --prefix="${prefix}" --sysconfdir=/etc --localstatedir=/var || return 1
           13  +
           14  +	echo '# Ignore: DESTDIR' >> Makefile
           15  +}

Added pkgs/gmp version [17a262a8c5].

            1  +#! /usr/bin/env bash
            2  +
            3  +version='6.0.0a'
            4  +url="http://ftp.gnu.org/gnu/gmp/gmp-6.0.0a.tar.xz"
            5  +domain=core.appfs.rkeene.org
            6  +sha256='9156d32edac6955bc53b0218f5f3763facb890b73a835d5e1b901dcf8eb8b764'
            7  +
            8  +function postinstall() {
            9  +	rm -f "${destdir}/${prefix}/share/info/dir"
           10  +}

Added pkgs/libcap version [832b31b155].

            1  +#! /usr/bin/env bash
            2  +
            3  +version='2.24'
            4  +url="http://www.kernel.org/pub/linux/libs/security/linux-privs/libcap2/libcap-${version}.tar.xz"
            5  +domain=core.appfs.rkeene.org
            6  +sha256='cee4568f78dc851d726fc93f25f4ed91cc223b1fe8259daa4a77158d174e6c65'
            7  +require=(attr)
            8  +
            9  +function configure() {
           10  +	:
           11  +}
           12  +
           13  +function build() {
           14  +	make prefix="${prefix}" lib='lib'
           15  +}
           16  +
           17  +function install() {
           18  +	make prefix="${prefix}" lib='lib' DESTDIR="${destdir}" RAISE_SETFCAP='no' install 
           19  +}

Added pkgs/linux-headers version [9fe679842b].

            1  +#! /usr/bin/env bash
            2  +
            3  +version='3.17.2'
            4  +url="https://www.kernel.org/pub/linux/kernel/v3.x/linux-${version}.tar.xz"
            5  +domain=core.appfs.rkeene.org
            6  +sha256='f9221dc0878955318ab57b8bb5ea1f26cbbaa39359c91d0f6c8de74d68aea796'
            7  +
            8  +function configure() {
            9  +	:
           10  +}
           11  +
           12  +function build() {
           13  +	make defconfig || die
           14  +}
           15  +
           16  +function install() {
           17  +	make INSTALL_HDR_PATH="${destdir}/${prefix}" headers_install || die
           18  +}

Added pkgs/mpc version [9b2be002ec].

            1  +#! /usr/bin/env bash
            2  +
            3  +version='1.0.2'
            4  +url="http://ftp.gnu.org/gnu/mpc/mpc-${version}.tar.gz"
            5  +domain=core.appfs.rkeene.org
            6  +sha256='b561f54d8a479cee3bc891ee52735f18ff86712ba30f036f8b8537bae380c488'
            7  +require=(gmp mpfr)

Added pkgs/mpfr version [8921e1fbd3].

            1  +#! /usr/bin/env bash
            2  +
            3  +version='3.1.2'
            4  +url="http://ftp.gnu.org/gnu/mpfr/mpfr-${version}.tar.xz"
            5  +domain=core.appfs.rkeene.org
            6  +sha256='399d0f47ef6608cc01d29ed1b99c7faff36d9994c45f36f41ba250147100453b'
            7  +require=(gmp)

Added pkgs/ncurses version [7553fdbe53].

            1  +#! /usr/bin/env bash
            2  +
            3  +version='5.9'
            4  +url="http://ftp.gnu.org/gnu/ncurses/ncurses-${version}.tar.gz"
            5  +domain=core.appfs.rkeene.org
            6  +sha256='9046298fb440324c9d4135ecea7879ffed8546dd1b58e59430ea07a4633f563b'
            7  +configure_extra=(--with-termlib --with-ticlib --with-shared)
            8  +
            9  +function postinstall() {
           10  +	# Create libtermcap compatability
           11  +	## Create libtermcap.so shared object
           12  +	cat << \_EOF_ > "${destdir}/${prefix}/lib/libtermcap.so"
           13  +GROUP( libtinfo.so )
           14  +_EOF_
           15  +
           16  +	## Create termcap.h header
           17  +	cat << \_EOF_ > "${destdir}/${prefix}/include/termcap.h"
           18  +#include <ncurses/termcap.h>
           19  +_EOF_
           20  +}

Added pkgs/readline version [4f5b78a41f].

            1  +#! /usr/bin/env bash
            2  +
            3  +version=6.3
            4  +url="https://ftp.gnu.org/gnu/readline/readline-${version}.tar.gz"
            5  +domain=core.appfs.rkeene.org
            6  +sha256='56ba6071b9462f980c5a72ab0023893b65ba6debb4eeb475d7a563dc65cafd43'

Added pkgs/tcl version [4e6f6630aa].

            1  +#! /usr/bin/env bash
            2  +
            3  +version='8.6.9'
            4  +url="http://sourceforge.net/projects/tcl/files/Tcl/${version}/tcl${version}-src.tar.gz"
            5  +domain=core.appfs.rkeene.org
            6  +sha256='ad0cd2de2c87b9ba8086b43957a0de3eb2eb565c7159d5f53ccbba3feb915f4e'
            7  +require=(zlib)
            8  +
            9  +function preconfigure() {
           10  +	cd unix
           11  +}
           12  +
           13  +function postinstall() {
           14  +	cd ..
           15  +}

Added pkgs/zlib version [e788328143].

            1  +#! /usr/bin/env bash
            2  +
            3  +version=1.2.8
            4  +url="http://zlib.net/zlib-${version}.tar.gz"
            5  +domain=core.appfs.rkeene.org
            6  +sha256='36658cb768a54c1d4dec43c3116c27ed893e88b02ecfcb44f2166f9c0b7f2a0d'