/* This file is part of ssp https://lila.oss/ssp
* Copyright (C) 2023 Olivier Brunel jjk@jjacky.com */
/* SPDX-License-Identifier: GPL-2.0-only */
#include <errno.h>
#include <limb/command.h>
#include <limb/exitcode.h>
#include <limb/loadopt.h>
#include <limb/output.h>
#include <limb/stralloc.h>
#include "ssp.h"
struct rename {
stralloc sa;
size_t entoff;
size_t newoff;
};
enum {
ARGID_ENTRY = OPTID_FIRST,
ARGID_NEWNAME,
};
COMMAND(rename, "Rename an entry", "<entry> <newname>", NULL);
static int
parse_cmdline(int argc, const char *argv[], const char usage[], struct rename *ctx)
{
const struct option options[] = {
LOADOPT_ARGUMENTS,
ARGUMENT_REQ( "entry", OPT_PATH, ARGID_ENTRY),
ARGUMENT_REQ( "newname", OPT_PATH, ARGID_NEWNAME),
LOADOPT_DONE
};
struct loadopt lo = LOADOPT_ZERO;
int c;
while ((c = loadopt(&ctx->sa, argc, argv, options, 0, NULL, 0, &lo))) switch (c) {
case ARGID_ENTRY:
ctx->entoff = LO_OFF(&lo);
break;
case ARGID_NEWNAME:
ctx->newoff = LO_OFF(&lo);
break;
case -1:
diecmdusage(EX_USAGE, usage, &command_rename);
default:
die(EX_SOFTWARE, "unexpected return value ", PMINT(c), " from loadopt");
};
return LO_CUR(&lo);
}
int
rename_main(int argc, const char *argv[], const char *env[], const char usage[], void *ssp_)
{
struct ssp *ssp = ssp_;
struct rename ctx = { .sa = STRALLOC_ZERO };
(void) env;
parse_cmdline(argc, argv, usage, &ctx);
const char *entry = ctx.sa.s + ctx.entoff;
const char *newname = ctx.sa.s + ctx.newoff;
if (!strcmp(entry, newname))
diefu(EX_DATA_ERR, "rename entry ", ESC, entry, ESC, ": new name is the same");
int r = open_db(ssp, 1);
if (r < 0)
diefu(exitcode_from_errno(errno), "open database");
r = db_find(entry, ssp);
if (r < 0)
diefu(EX_DATA_ERR, "find entry ", ESC, entry, ESC);
if (!r)
dief(EX_DATA_ERR, "no entry ", ESC, entry, ESC, " in database");
quiet("Renaming ", ESC, entry, ESC, " to ", ESC, newname, ESC, "...");
rebuild_db(entry, newname, db_otp(ssp), ssp);
dbg("showing renamed entry");
close_db(ssp);
const char *av[] = { NULL, newname };
run_command("show", sizeof(av) / sizeof(*av), av, env, ssp);
stralloc_free(&ctx.sa);
return 0;
}