1
0
mirror of https://github.com/postgrespro/pg_probackup.git synced 2025-01-24 11:46:31 +02:00

Use optind to parse subcommand name

This commit is contained in:
Arthur Zakirov 2018-06-09 18:05:18 +03:00
parent 1304c88ce7
commit 0afc00439c
3 changed files with 128 additions and 130 deletions

View File

@ -64,7 +64,7 @@ static char *target_inclusive;
static TimeLineID target_tli; static TimeLineID target_tli;
static bool target_immediate; static bool target_immediate;
static char *target_name = NULL; static char *target_name = NULL;
static char *target_action = NULL;; static char *target_action = NULL;
static pgRecoveryTarget *recovery_target_options = NULL; static pgRecoveryTarget *recovery_target_options = NULL;
@ -99,9 +99,10 @@ ShowFormat show_format = SHOW_PLAIN;
/* current settings */ /* current settings */
pgBackup current; pgBackup current;
ProbackupSubcmd backup_subcmd; ProbackupSubcmd backup_subcmd = NO_CMD;
bool help = false; static bool help_opt = false;
static bool version_opt = false;
static void opt_backup_mode(pgut_option *opt, const char *arg); static void opt_backup_mode(pgut_option *opt, const char *arg);
static void opt_log_level_console(pgut_option *opt, const char *arg); static void opt_log_level_console(pgut_option *opt, const char *arg);
@ -114,7 +115,8 @@ static void compress_init(void);
static pgut_option options[] = static pgut_option options[] =
{ {
/* directory options */ /* directory options */
{ 'b', 1, "help", &help, SOURCE_CMDLINE }, { 'b', 1, "help", &help_opt, SOURCE_CMDLINE },
{ 'b', 'V', "version", &version_opt, SOURCE_CMDLINE },
{ 's', 'D', "pgdata", &pgdata, SOURCE_CMDLINE }, { 's', 'D', "pgdata", &pgdata, SOURCE_CMDLINE },
{ 's', 'B', "backup-path", &backup_path, SOURCE_CMDLINE }, { 's', 'B', "backup-path", &backup_path, SOURCE_CMDLINE },
/* common options */ /* common options */
@ -152,7 +154,7 @@ static pgut_option options[] =
{ 'b', 131, "expired", &delete_expired, SOURCE_CMDLINE }, { 'b', 131, "expired", &delete_expired, SOURCE_CMDLINE },
{ 'b', 132, "all", &apply_to_all, SOURCE_CMDLINE }, { 'b', 132, "all", &apply_to_all, SOURCE_CMDLINE },
/* TODO not implemented yet */ /* TODO not implemented yet */
{ 'b', 133, "force", &force_delete, SOURCE_CMDLINE }, { 'b', 133, "force", &force_delete, SOURCE_CMDLINE },
/* retention options */ /* retention options */
{ 'u', 134, "retention-redundancy", &retention_redundancy, SOURCE_CMDLINE }, { 'u', 134, "retention-redundancy", &retention_redundancy, SOURCE_CMDLINE },
{ 'u', 135, "retention-window", &retention_window, SOURCE_CMDLINE }, { 'u', 135, "retention-window", &retention_window, SOURCE_CMDLINE },
@ -198,6 +200,9 @@ main(int argc, char *argv[])
/* Check if backup_path is directory. */ /* Check if backup_path is directory. */
struct stat stat_buf; struct stat stat_buf;
int rc; int rc;
int i,
len = 0,
allocated = 0;
/* initialize configuration */ /* initialize configuration */
pgBackup_init(&current); pgBackup_init(&current);
@ -210,106 +215,94 @@ main(int argc, char *argv[])
*/ */
main_tid = pthread_self(); main_tid = pthread_self();
/* Parse subcommands and non-subcommand options */
if (argc > 1)
{
if (strcmp(argv[1], "archive-push") == 0)
backup_subcmd = ARCHIVE_PUSH;
else if (strcmp(argv[1], "archive-get") == 0)
backup_subcmd = ARCHIVE_GET;
else if (strcmp(argv[1], "add-instance") == 0)
backup_subcmd = ADD_INSTANCE;
else if (strcmp(argv[1], "del-instance") == 0)
backup_subcmd = DELETE_INSTANCE;
else if (strcmp(argv[1], "init") == 0)
backup_subcmd = INIT;
else if (strcmp(argv[1], "backup") == 0)
backup_subcmd = BACKUP;
else if (strcmp(argv[1], "restore") == 0)
backup_subcmd = RESTORE;
else if (strcmp(argv[1], "validate") == 0)
backup_subcmd = VALIDATE;
else if (strcmp(argv[1], "show") == 0)
backup_subcmd = SHOW;
else if (strcmp(argv[1], "delete") == 0)
backup_subcmd = DELETE_SUBCMD;
else if (strcmp(argv[1], "set-config") == 0)
backup_subcmd = SET_CONFIG;
else if (strcmp(argv[1], "show-config") == 0)
backup_subcmd = SHOW_CONFIG;
else if (strcmp(argv[1], "--help") == 0
|| strcmp(argv[1], "help") == 0
|| strcmp(argv[1], "-?") == 0)
{
if (argc > 2)
help_command(argv[2]);
else
help_pg_probackup();
}
else if (strcmp(argv[1], "--version") == 0
|| strcmp(argv[1], "version") == 0
|| strcmp(argv[1], "-V") == 0)
{
if (argc == 2)
{
#ifdef PGPRO_VERSION
fprintf(stderr, "%s %s (Postgres Pro %s %s)\n",
PROGRAM_NAME, PROGRAM_VERSION,
PGPRO_VERSION, PGPRO_EDITION);
#else
fprintf(stderr, "%s %s (PostgreSQL %s)\n",
PROGRAM_NAME, PROGRAM_VERSION, PG_VERSION);
#endif
exit(0);
}
else if (strcmp(argv[2], "--help") == 0)
help_command(argv[1]);
else
elog(ERROR, "Invalid arguments for \"%s\" subcommand", argv[1]);
}
else
elog(ERROR, "Unknown subcommand");
}
/* /*
* Make command string before getopt_long() will call. It permutes the * Make command string before getopt_long() will call. It permutes the
* content of argv. * content of argv.
*/ */
if (backup_subcmd == BACKUP || allocated = sizeof(char) * MAXPGPATH;
backup_subcmd == RESTORE || command = (char *) palloc(allocated);
backup_subcmd == VALIDATE ||
backup_subcmd == DELETE_SUBCMD) for (i = 0; i < argc; i++)
{ {
int i, int arglen = strlen(argv[i]);
len = 0,
allocated = 0;
allocated = sizeof(char) * MAXPGPATH; if (arglen + len > allocated)
command = (char *) palloc(allocated);
for (i = 0; i < argc; i++)
{ {
int arglen = strlen(argv[i]); allocated *= 2;
command = repalloc(command, allocated);
if (arglen + len > allocated)
{
allocated *= 2;
command = repalloc(command, allocated);
}
strncpy(command + len, argv[i], arglen);
len += arglen;
command[len++] = ' ';
} }
command[len] = '\0'; strncpy(command + len, argv[i], arglen);
len += arglen;
command[len++] = ' ';
} }
command[len] = '\0';
/* Parse command line arguments */ /* Parse command line arguments */
pgut_getopt(argc, argv, options); pgut_getopt(argc, argv, options);
if (help) /* Process a command */
help_command(argv[2]); if (optind < argc)
{
if (strcmp(argv[optind], "archive-push") == 0)
backup_subcmd = ARCHIVE_PUSH_CMD;
else if (strcmp(argv[optind], "archive-get") == 0)
backup_subcmd = ARCHIVE_GET_CMD;
else if (strcmp(argv[optind], "add-instance") == 0)
backup_subcmd = ADD_INSTANCE_CMD;
else if (strcmp(argv[optind], "del-instance") == 0)
backup_subcmd = DELETE_INSTANCE_CMD;
else if (strcmp(argv[optind], "init") == 0)
backup_subcmd = INIT_CMD;
else if (strcmp(argv[optind], "backup") == 0)
backup_subcmd = BACKUP_CMD;
else if (strcmp(argv[optind], "restore") == 0)
backup_subcmd = RESTORE_CMD;
else if (strcmp(argv[optind], "validate") == 0)
backup_subcmd = VALIDATE_CMD;
else if (strcmp(argv[optind], "show") == 0)
backup_subcmd = SHOW_CMD;
else if (strcmp(argv[optind], "delete") == 0)
backup_subcmd = DELETE_CMD;
else if (strcmp(argv[optind], "set-config") == 0)
backup_subcmd = SET_CONFIG_CMD;
else if (strcmp(argv[optind], "show-config") == 0)
backup_subcmd = SHOW_CONFIG_CMD;
else if (strcmp(argv[optind], "help") == 0)
{
if (argc - optind < 2)
help_pg_probackup();
else
help_command(argv[optind + 1]);
}
else if (strcmp(argv[optind], "version") == 0)
version_opt = true;
else
elog(ERROR, "Unknown subcommand \"%s\"", argv[optind]);
}
if (help_opt)
{
if (backup_subcmd == NO_CMD || argc - optind < 1)
help_pg_probackup();
else
help_command(argv[optind]);
}
else if (version_opt)
{
#ifdef PGPRO_VERSION
fprintf(stderr, "%s %s (Postgres Pro %s %s)\n",
PROGRAM_NAME, PROGRAM_VERSION,
PGPRO_VERSION, PGPRO_EDITION);
#else
fprintf(stderr, "%s %s (PostgreSQL %s)\n",
PROGRAM_NAME, PROGRAM_VERSION, PG_VERSION);
#endif
return 0;
}
else if (backup_subcmd == NO_CMD)
elog(ERROR, "No subcommand specified");
/* backup_path is required for all pg_probackup commands except help */ /* backup_path is required for all pg_probackup commands except help */
if (backup_path == NULL) if (backup_path == NULL)
@ -343,7 +336,7 @@ main(int argc, char *argv[])
} }
/* Option --instance is required for all commands except init and show */ /* Option --instance is required for all commands except init and show */
if (backup_subcmd != INIT && backup_subcmd != SHOW && backup_subcmd != VALIDATE) if (backup_subcmd != INIT_CMD && backup_subcmd != SHOW_CMD && backup_subcmd != VALIDATE_CMD)
{ {
if (instance_name == NULL) if (instance_name == NULL)
elog(ERROR, "required parameter not specified: --instance"); elog(ERROR, "required parameter not specified: --instance");
@ -363,7 +356,7 @@ main(int argc, char *argv[])
* for all commands except init, which doesn't take this parameter * for all commands except init, which doesn't take this parameter
* and add-instance which creates new instance. * and add-instance which creates new instance.
*/ */
if (backup_subcmd != INIT && backup_subcmd != ADD_INSTANCE) if (backup_subcmd != INIT_CMD && backup_subcmd != ADD_INSTANCE_CMD)
{ {
if (access(backup_instance_path, F_OK) != 0) if (access(backup_instance_path, F_OK) != 0)
elog(ERROR, "Instance '%s' does not exist in this backup catalog", elog(ERROR, "Instance '%s' does not exist in this backup catalog",
@ -375,7 +368,7 @@ main(int argc, char *argv[])
* Read options from env variables or from config file, * Read options from env variables or from config file,
* unless we're going to set them via set-config. * unless we're going to set them via set-config.
*/ */
if (instance_name && backup_subcmd != SET_CONFIG) if (instance_name && backup_subcmd != SET_CONFIG_CMD)
{ {
/* Read environment variables */ /* Read environment variables */
pgut_getopt_env(options); pgut_getopt_env(options);
@ -398,10 +391,10 @@ main(int argc, char *argv[])
/* Sanity check of --backup-id option */ /* Sanity check of --backup-id option */
if (backup_id_string_param != NULL) if (backup_id_string_param != NULL)
{ {
if (backup_subcmd != RESTORE if (backup_subcmd != RESTORE_CMD
&& backup_subcmd != VALIDATE && backup_subcmd != VALIDATE_CMD
&& backup_subcmd != DELETE_SUBCMD && backup_subcmd != DELETE_CMD
&& backup_subcmd != SHOW) && backup_subcmd != SHOW_CMD)
elog(ERROR, "Cannot use -i (--backup-id) option together with the '%s' command", elog(ERROR, "Cannot use -i (--backup-id) option together with the '%s' command",
argv[1]); argv[1]);
@ -429,7 +422,7 @@ main(int argc, char *argv[])
pgdata_exclude_dir[i] = "pg_log"; pgdata_exclude_dir[i] = "pg_log";
} }
if (backup_subcmd == VALIDATE || backup_subcmd == RESTORE) if (backup_subcmd == VALIDATE_CMD || backup_subcmd == RESTORE_CMD)
{ {
/* parse all recovery target options into recovery_target_options structure */ /* parse all recovery target options into recovery_target_options structure */
recovery_target_options = parseRecoveryTargetOptions(target_time, target_xid, recovery_target_options = parseRecoveryTargetOptions(target_time, target_xid,
@ -445,17 +438,17 @@ main(int argc, char *argv[])
/* do actual operation */ /* do actual operation */
switch (backup_subcmd) switch (backup_subcmd)
{ {
case ARCHIVE_PUSH: case ARCHIVE_PUSH_CMD:
return do_archive_push(wal_file_path, wal_file_name, file_overwrite); return do_archive_push(wal_file_path, wal_file_name, file_overwrite);
case ARCHIVE_GET: case ARCHIVE_GET_CMD:
return do_archive_get(wal_file_path, wal_file_name); return do_archive_get(wal_file_path, wal_file_name);
case ADD_INSTANCE: case ADD_INSTANCE_CMD:
return do_add_instance(); return do_add_instance();
case DELETE_INSTANCE: case DELETE_INSTANCE_CMD:
return do_delete_instance(); return do_delete_instance();
case INIT: case INIT_CMD:
return do_init(); return do_init();
case BACKUP: case BACKUP_CMD:
{ {
const char *backup_mode; const char *backup_mode;
time_t start_time; time_t start_time;
@ -470,20 +463,20 @@ main(int argc, char *argv[])
return do_backup(start_time); return do_backup(start_time);
} }
case RESTORE: case RESTORE_CMD:
return do_restore_or_validate(current.backup_id, return do_restore_or_validate(current.backup_id,
recovery_target_options, recovery_target_options,
true); true);
case VALIDATE: case VALIDATE_CMD:
if (current.backup_id == 0 && target_time == 0 && target_xid == 0) if (current.backup_id == 0 && target_time == 0 && target_xid == 0)
return do_validate_all(); return do_validate_all();
else else
return do_restore_or_validate(current.backup_id, return do_restore_or_validate(current.backup_id,
recovery_target_options, recovery_target_options,
false); false);
case SHOW: case SHOW_CMD:
return do_show(current.backup_id); return do_show(current.backup_id);
case DELETE_SUBCMD: case DELETE_CMD:
if (delete_expired && backup_id_string_param) if (delete_expired && backup_id_string_param)
elog(ERROR, "You cannot specify --delete-expired and --backup-id options together"); elog(ERROR, "You cannot specify --delete-expired and --backup-id options together");
if (!delete_expired && !delete_wal && !backup_id_string_param) if (!delete_expired && !delete_wal && !backup_id_string_param)
@ -494,10 +487,13 @@ main(int argc, char *argv[])
return do_retention_purge(); return do_retention_purge();
else else
return do_delete(current.backup_id); return do_delete(current.backup_id);
case SHOW_CONFIG: case SHOW_CONFIG_CMD:
return do_configure(true); return do_configure(true);
case SET_CONFIG: case SET_CONFIG_CMD:
return do_configure(false); return do_configure(false);
case NO_CMD:
/* Should not happen */
elog(ERROR, "Unknown subcommand");
} }
return 0; return 0;
@ -561,7 +557,7 @@ compress_init(void)
if (compress_shortcut) if (compress_shortcut)
compress_alg = ZLIB_COMPRESS; compress_alg = ZLIB_COMPRESS;
if (backup_subcmd != SET_CONFIG) if (backup_subcmd != SET_CONFIG_CMD)
{ {
if (compress_level != DEFAULT_COMPRESS_LEVEL if (compress_level != DEFAULT_COMPRESS_LEVEL
&& compress_alg == NOT_DEFINED_COMPRESS) && compress_alg == NOT_DEFINED_COMPRESS)
@ -574,7 +570,7 @@ compress_init(void)
if (compress_level == 0) if (compress_level == 0)
compress_alg = NOT_DEFINED_COMPRESS; compress_alg = NOT_DEFINED_COMPRESS;
if (backup_subcmd == BACKUP || backup_subcmd == ARCHIVE_PUSH) if (backup_subcmd == BACKUP_CMD || backup_subcmd == ARCHIVE_PUSH_CMD)
{ {
#ifndef HAVE_LIBZ #ifndef HAVE_LIBZ
if (compress_alg == ZLIB_COMPRESS) if (compress_alg == ZLIB_COMPRESS)

View File

@ -139,18 +139,19 @@ typedef enum BackupMode
typedef enum ProbackupSubcmd typedef enum ProbackupSubcmd
{ {
INIT = 0, NO_CMD = 0,
ARCHIVE_PUSH, INIT_CMD,
ARCHIVE_GET, ARCHIVE_PUSH_CMD,
ADD_INSTANCE, ARCHIVE_GET_CMD,
DELETE_INSTANCE, ADD_INSTANCE_CMD,
BACKUP, DELETE_INSTANCE_CMD,
RESTORE, BACKUP_CMD,
VALIDATE, RESTORE_CMD,
SHOW, VALIDATE_CMD,
DELETE_SUBCMD, SHOW_CMD,
SET_CONFIG, DELETE_CMD,
SHOW_CONFIG SET_CONFIG_CMD,
SHOW_CONFIG_CMD
} ProbackupSubcmd; } ProbackupSubcmd;
typedef enum ShowFormat typedef enum ShowFormat
@ -367,7 +368,7 @@ extern ShowFormat show_format;
/* current settings */ /* current settings */
extern pgBackup current; extern pgBackup current;
extern ProbackupSubcmd backup_subcmd; extern ProbackupSubcmd backup_subcmd;
/* in dir.c */ /* in dir.c */
/* exclude directory list for $PGDATA file listing */ /* exclude directory list for $PGDATA file listing */

View File

@ -135,8 +135,10 @@ static const unit_conversion time_unit_conversion_table[] =
static size_t static size_t
option_length(const pgut_option opts[]) option_length(const pgut_option opts[])
{ {
size_t len; size_t len;
for (len = 0; opts && opts[len].type; len++) { } for (len = 0; opts && opts[len].type; len++) { }
return len; return len;
} }
@ -156,7 +158,7 @@ option_has_arg(char type)
static void static void
option_copy(struct option dst[], const pgut_option opts[], size_t len) option_copy(struct option dst[], const pgut_option opts[], size_t len)
{ {
size_t i; size_t i;
for (i = 0; i < len; i++) for (i = 0; i < len; i++)
{ {
@ -1047,13 +1049,12 @@ pgut_getopt(int argc, char **argv, pgut_option options[])
size_t len; size_t len;
len = option_length(options); len = option_length(options);
longopts = pgut_newarray(struct option, len + 1); longopts = pgut_newarray(struct option, len + 1 /* zero/end option */);
option_copy(longopts, options, len); option_copy(longopts, options, len);
optstring = longopts_to_optstring(longopts, len); optstring = longopts_to_optstring(longopts, len);
/* Assign named options */ /* Assign named options */
optind = 2;
while ((c = getopt_long(argc, argv, optstring, longopts, &optindex)) != -1) while ((c = getopt_long(argc, argv, optstring, longopts, &optindex)) != -1)
{ {
opt = option_find(c, options); opt = option_find(c, options);