Store tixinfo and manifest on tix install.

This commit is contained in:
Jonas 'Sortie' Termansen 2015-09-09 19:26:50 +02:00
parent 8174ab7b30
commit beaa824076
4 changed files with 133 additions and 10 deletions

View File

@ -135,7 +135,7 @@ mkdir -p "$SORTIX_REPOSITORY_DIR"
# Initialize Tix package management in the system root if absent.
[ -e "$SYSROOT/tix/collection.conf" ] ||
tix-collection "$SYSROOT" create --platform=$HOST --prefix= --disable-multiarch --generation=1
tix-collection "$SYSROOT" create --platform=$HOST --prefix= --disable-multiarch --generation=2
# Build all the packages (if needed) and otherwise install them.
for PACKAGE in $PACKAGES; do
@ -149,7 +149,7 @@ for PACKAGE in $PACKAGES; do
--prefix= \
--exec-prefix= \
--destination="$SORTIX_REPOSITORY_DIR" \
--generation=1 \
--generation=2 \
"$SORTIX_PORTS_DIR/$PACKAGE"
tix-install \
--collection="$SYSROOT" \

View File

@ -161,6 +161,20 @@ int main(int argc, char* argv[])
tixdb_path = strdup(tix_path);
}
// TODO: After releasing Sortix 1.0, do this unconditionally.
if ( 2 <= generation )
{
char* tixinfo_path = join_paths(tixdb_path, "tixinfo");
if ( mkdir_p(tixinfo_path, 0755) != 0 )
error(1, errno, "mkdir: `%s'", tixinfo_path);
free(tixinfo_path);
char* manifest_path = join_paths(tixdb_path, "manifest");
if ( mkdir_p(manifest_path, 0755) != 0 )
error(1, errno, "mkdir: `%s'", manifest_path);
free(manifest_path);
}
char* collection_conf_path = join_paths(tixdb_path, "collection.conf");
FILE* conf_fp = fopen(collection_conf_path, "wx");
if ( !conf_fp && errno == EEXIST )
@ -169,6 +183,9 @@ int main(int argc, char* argv[])
collection);
fprintf(conf_fp, "tix.version=1\n");
fprintf(conf_fp, "tix.class=collection\n");
// TODO: After releasing Sortix 1.0, do this unconditionally.
if ( 2 <= generation )
fprintf(conf_fp, "collection.generation=%i\n", generation);
fprintf(conf_fp, "collection.prefix=%s\n", !strcmp(prefix, "/") ? "" :
prefix);
fprintf(conf_fp, "collection.platform=%s\n", platform);

View File

@ -234,6 +234,13 @@ int main(int argc, char* argv[])
return 0;
}
static int strcmp_indirect(const void* a_ptr, const void* b_ptr)
{
const char* a = *(const char* const*) a_ptr;
const char* b = *(const char* const*) b_ptr;
return strcmp(a, b);
}
void InstallPackage(const char* tix_path)
{
if ( !IsFile(tix_path) )
@ -281,7 +288,8 @@ void InstallPackage(const char* tix_path)
if ( !coll_generation )
coll_generation = "1";
assert(coll_generation);
(void) coll_generation;
int generation = atoi(coll_generation);
(void) generation;
const char* coll_prefix = dictionary_get(&coll_conf, "collection.prefix");
assert(coll_prefix);
const char* coll_platform = dictionary_get(&coll_conf, "collection.platform");
@ -314,6 +322,46 @@ void InstallPackage(const char* tix_path)
char* data_and_prefix = package_prefix && package_prefix[0] ?
print_string("data%s", package_prefix) :
strdup("data");
// TODO: After releasing Sortix 1.0, do this unconditionally.
if ( 2 <= generation )
{
char* tixinfo_path = print_string("%s/tixinfo/%s", tixdb_path, package_name);
int tixinfo_fd = open(tixinfo_path, O_WRONLY | O_CREAT | O_TRUNC, 0644);
if ( tixinfo_fd < 0 )
error(1, errno, "%s", tixinfo_path);
TarExtractFileToFD(tix_path, "tix/tixinfo", tixinfo_fd);
close(tixinfo_fd);
FILE* index_fp = TarOpenIndex(tix_path);
string_array_t files = string_array_make();
string_array_append_file(&files, index_fp);
qsort(files.strings, files.length, sizeof(char*), strcmp_indirect);
char* manifest_path = print_string("%s/manifest/%s", tixdb_path, package_name);
FILE* manifest_fp = fopen(manifest_path, "w");
if ( !manifest_fp )
error(1, errno, "%s", manifest_path);
for ( size_t i = 0; i < files.length; i++ )
{
char* str = files.strings[i];
if ( strncmp(str, "data", strlen("data")) != 0 )
continue;
str += strlen("data");
if ( str[0] && str[0] != '/' )
continue;
size_t len = strlen(str);
while ( 2 <= len && str[len-1] == '/' )
str[--len] = '\0';
if ( fprintf(manifest_fp, "%s\n", str) < 0 )
error(1, errno, "%s", manifest_path);
}
if ( ferror(manifest_fp) || fflush(manifest_fp) == EOF )
error(1, errno, "%s", manifest_path);
fclose(manifest_fp);
string_array_reset(&files);
fclose(index_fp);
}
if ( fork_and_wait_or_death() )
{
size_t num_strips = count_tar_components(data_and_prefix);

View File

@ -25,7 +25,13 @@
#ifndef UTIL_H
#define UTIL_H
// TODO: After releasing Sortix 1.0, remove this ifdef and default it to the
// latest generation.
#if defined(__sortix__)
#define DEFAULT_GENERATION "2"
#else
#define DEFAULT_GENERATION "1"
#endif
bool does_path_contain_dotdot(const char* path)
{
@ -573,16 +579,17 @@ bool TarContainsFile(const char* archive, const char* file)
return ret;
}
FILE* TarOpenFile(const char* archive, const char* file)
void TarExtractFileToFD(const char* archive, const char* file, int fd)
{
FILE* fp = tmpfile();
if ( !fp )
error(1, errno, "tmpfile");
pid_t tar_pid = fork_or_death();
if ( !tar_pid )
{
dup2(fileno(fp), 1);
fclose(fp);
if ( dup2(fd, 1) < 0 )
{
error(0, errno, "dup2");
_exit(127);
}
close(fd);
const char* cmd_argv[] =
{
"tar",
@ -593,7 +600,8 @@ FILE* TarOpenFile(const char* archive, const char* file)
NULL
};
execvp(cmd_argv[0], (char* const*) cmd_argv);
error(127, errno, "%s", cmd_argv[0]);
error(0, errno, "%s", cmd_argv[0]);
_exit(127);
}
int tar_exit_status;
waitpid(tar_pid, &tar_exit_status, 0);
@ -602,6 +610,56 @@ FILE* TarOpenFile(const char* archive, const char* file)
error(1, 0, "Unable to extract `%s/%s'", archive, file);
exit(WEXITSTATUS(tar_exit_status));
}
}
FILE* TarOpenFile(const char* archive, const char* file)
{
FILE* fp = tmpfile();
if ( !fp )
error(1, errno, "tmpfile");
TarExtractFileToFD(archive, file, fileno(fp));
if ( fseeko(fp, 0, SEEK_SET) < 0 )
error(1, errno, "fseeko(tmpfile(), 0, SEEK_SET)");
return fp;
}
void TarIndexToFD(const char* archive, int fd)
{
pid_t tar_pid = fork_or_death();
if ( !tar_pid )
{
if ( dup2(fd, 1) < 0 )
{
error(0, errno, "dup2");
_exit(127);
}
close(fd);
const char* cmd_argv[] =
{
"tar",
"--list",
"--file", archive,
NULL
};
execvp(cmd_argv[0], (char* const*) cmd_argv);
error(0, errno, "%s", cmd_argv[0]);
_exit(127);
}
int tar_exit_status;
waitpid(tar_pid, &tar_exit_status, 0);
if ( !WIFEXITED(tar_exit_status) || WEXITSTATUS(tar_exit_status) != 0 )
{
error(1, 0, "Unable to list contents of `%s'", archive);
exit(WEXITSTATUS(tar_exit_status));
}
}
FILE* TarOpenIndex(const char* archive)
{
FILE* fp = tmpfile();
if ( !fp )
error(1, errno, "tmpfile");
TarIndexToFD(archive, fileno(fp));
if ( fseeko(fp, 0, SEEK_SET) < 0 )
error(1, errno, "fseeko(tmpfile(), 0, SEEK_SET)");
return fp;