nkiss

WIP
git clone git://git.nihaljere.xyz/nkiss
Log | Files | Refs

commit 520c3a1027335708828e2c249ae51b3363db99f0
parent acd516d2f9716356b7c3c7a9717877ed02ec5549
Author: Nihal Jere <nihal@nihaljere.xyz>
Date:   Mon, 22 Feb 2021 17:55:12 -0600

alt.*: add alt_swap

Diffstat:
Malt.c | 56++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Malt.h | 1+
2 files changed, 57 insertions(+), 0 deletions(-)

diff --git a/alt.c b/alt.c @@ -160,3 +160,59 @@ alt_owner(char owner[PKG_NAME_MAX], char *path) closedir(installed); } + +void +alt_swap(struct alt_t *in) +{ + struct alt_t out; + memset(&out, 0, sizeof(out)); + char choice[PATH_LEN], out_choice_path[PATH_LEN], in_choice_path[PATH_LEN], + out_manifest[PATH_LEN], in_manifest[PATH_LEN]; + int n; + + alt_owner(out.name, in->path); + if (!out.name[0]) + die("%s: %s doesn't belong to a package", __func__, in->path); + + strcpy(out.path, in->path); + + to_choice(&out, choice); + n = snprintf(out_choice_path, PATH_LEN, "%s/%s", KISS_CHOICES, choice); + if (n >= PATH_LEN) + die("%s: full path for %s too long", __func__, choice); + + to_choice(in, choice); + n = snprintf(in_choice_path, PATH_LEN, "%s/%s", KISS_CHOICES, choice); + if (n >= PATH_LEN) + die("%s: full path for %s too long", __func__, choice); + + n = snprintf(out_manifest, PATH_LEN, "%s/%s/manifest", KISS_INSTALLED, out.name); + if (n >= PATH_LEN) + die("%s: full manifest path for %s too long", __func__, out.name); + + n = snprintf(in_manifest, PATH_LEN, "%s/%s/manifest", KISS_INSTALLED, in->name); + if (n >= PATH_LEN) + die("%s: full manifest path for %s too long", __func__, in->name); + + /* TODO use goto for error handling */ + if (mv(out.path, out_choice_path) == -1) + die("%s: failed to swap out %s:", __func__, out.name); + + if (mv(in_choice_path, in->path) == -1) { + mv(out_choice_path, out.path); + die("%s: failed to swap in %s:", __func__, in->name); + } + + if (file_dropadd(out_manifest, out.path, out_choice_path) == -1) { + mv(in->path, in_choice_path); + mv(out_choice_path, out.path); + die("%s: failed to update manifest for %s; it might be screwed up:", __func__, in->name); + } + + if (file_dropadd(in_manifest, in_choice_path, in->path) == -1) { + file_dropadd(out_manifest, out_choice_path, out.path); + mv(in->path, in_choice_path); + mv(out_choice_path, out.path); + die("%s: failed to update manifest for %s; it might be screwed up:", __func__, out.name); + } +} diff --git a/alt.h b/alt.h @@ -9,3 +9,4 @@ struct alt_t { void alt_load(); int alt_exists(struct alt_t *alt); void alt_owner(char owner[PKG_NAME_MAX], char *path); +void alt_swap(struct alt_t *new);