Store tixinfo and manifest on tix install.
This commit is contained in:
parent
8174ab7b30
commit
beaa824076
|
@ -135,7 +135,7 @@ mkdir -p "$SORTIX_REPOSITORY_DIR"
|
||||||
|
|
||||||
# Initialize Tix package management in the system root if absent.
|
# Initialize Tix package management in the system root if absent.
|
||||||
[ -e "$SYSROOT/tix/collection.conf" ] ||
|
[ -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.
|
# Build all the packages (if needed) and otherwise install them.
|
||||||
for PACKAGE in $PACKAGES; do
|
for PACKAGE in $PACKAGES; do
|
||||||
|
@ -149,7 +149,7 @@ for PACKAGE in $PACKAGES; do
|
||||||
--prefix= \
|
--prefix= \
|
||||||
--exec-prefix= \
|
--exec-prefix= \
|
||||||
--destination="$SORTIX_REPOSITORY_DIR" \
|
--destination="$SORTIX_REPOSITORY_DIR" \
|
||||||
--generation=1 \
|
--generation=2 \
|
||||||
"$SORTIX_PORTS_DIR/$PACKAGE"
|
"$SORTIX_PORTS_DIR/$PACKAGE"
|
||||||
tix-install \
|
tix-install \
|
||||||
--collection="$SYSROOT" \
|
--collection="$SYSROOT" \
|
||||||
|
|
|
@ -161,6 +161,20 @@ int main(int argc, char* argv[])
|
||||||
tixdb_path = strdup(tix_path);
|
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");
|
char* collection_conf_path = join_paths(tixdb_path, "collection.conf");
|
||||||
FILE* conf_fp = fopen(collection_conf_path, "wx");
|
FILE* conf_fp = fopen(collection_conf_path, "wx");
|
||||||
if ( !conf_fp && errno == EEXIST )
|
if ( !conf_fp && errno == EEXIST )
|
||||||
|
@ -169,6 +183,9 @@ int main(int argc, char* argv[])
|
||||||
collection);
|
collection);
|
||||||
fprintf(conf_fp, "tix.version=1\n");
|
fprintf(conf_fp, "tix.version=1\n");
|
||||||
fprintf(conf_fp, "tix.class=collection\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, "/") ? "" :
|
fprintf(conf_fp, "collection.prefix=%s\n", !strcmp(prefix, "/") ? "" :
|
||||||
prefix);
|
prefix);
|
||||||
fprintf(conf_fp, "collection.platform=%s\n", platform);
|
fprintf(conf_fp, "collection.platform=%s\n", platform);
|
||||||
|
|
|
@ -234,6 +234,13 @@ int main(int argc, char* argv[])
|
||||||
return 0;
|
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)
|
void InstallPackage(const char* tix_path)
|
||||||
{
|
{
|
||||||
if ( !IsFile(tix_path) )
|
if ( !IsFile(tix_path) )
|
||||||
|
@ -281,7 +288,8 @@ void InstallPackage(const char* tix_path)
|
||||||
if ( !coll_generation )
|
if ( !coll_generation )
|
||||||
coll_generation = "1";
|
coll_generation = "1";
|
||||||
assert(coll_generation);
|
assert(coll_generation);
|
||||||
(void) coll_generation;
|
int generation = atoi(coll_generation);
|
||||||
|
(void) generation;
|
||||||
const char* coll_prefix = dictionary_get(&coll_conf, "collection.prefix");
|
const char* coll_prefix = dictionary_get(&coll_conf, "collection.prefix");
|
||||||
assert(coll_prefix);
|
assert(coll_prefix);
|
||||||
const char* coll_platform = dictionary_get(&coll_conf, "collection.platform");
|
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] ?
|
char* data_and_prefix = package_prefix && package_prefix[0] ?
|
||||||
print_string("data%s", package_prefix) :
|
print_string("data%s", package_prefix) :
|
||||||
strdup("data");
|
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() )
|
if ( fork_and_wait_or_death() )
|
||||||
{
|
{
|
||||||
size_t num_strips = count_tar_components(data_and_prefix);
|
size_t num_strips = count_tar_components(data_and_prefix);
|
||||||
|
|
72
tix/util.h
72
tix/util.h
|
@ -25,7 +25,13 @@
|
||||||
#ifndef UTIL_H
|
#ifndef UTIL_H
|
||||||
#define 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"
|
#define DEFAULT_GENERATION "1"
|
||||||
|
#endif
|
||||||
|
|
||||||
bool does_path_contain_dotdot(const char* path)
|
bool does_path_contain_dotdot(const char* path)
|
||||||
{
|
{
|
||||||
|
@ -573,16 +579,17 @@ bool TarContainsFile(const char* archive, const char* file)
|
||||||
return ret;
|
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();
|
pid_t tar_pid = fork_or_death();
|
||||||
if ( !tar_pid )
|
if ( !tar_pid )
|
||||||
{
|
{
|
||||||
dup2(fileno(fp), 1);
|
if ( dup2(fd, 1) < 0 )
|
||||||
fclose(fp);
|
{
|
||||||
|
error(0, errno, "dup2");
|
||||||
|
_exit(127);
|
||||||
|
}
|
||||||
|
close(fd);
|
||||||
const char* cmd_argv[] =
|
const char* cmd_argv[] =
|
||||||
{
|
{
|
||||||
"tar",
|
"tar",
|
||||||
|
@ -593,7 +600,8 @@ FILE* TarOpenFile(const char* archive, const char* file)
|
||||||
NULL
|
NULL
|
||||||
};
|
};
|
||||||
execvp(cmd_argv[0], (char* const*) cmd_argv);
|
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;
|
int tar_exit_status;
|
||||||
waitpid(tar_pid, &tar_exit_status, 0);
|
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);
|
error(1, 0, "Unable to extract `%s/%s'", archive, file);
|
||||||
exit(WEXITSTATUS(tar_exit_status));
|
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 )
|
if ( fseeko(fp, 0, SEEK_SET) < 0 )
|
||||||
error(1, errno, "fseeko(tmpfile(), 0, SEEK_SET)");
|
error(1, errno, "fseeko(tmpfile(), 0, SEEK_SET)");
|
||||||
return fp;
|
return fp;
|
||||||
|
|
Loading…
Reference in New Issue