X-Git-Url: http://git.tuebingen.mpg.de/?p=paraslash.git;a=blobdiff_plain;f=client.c;h=68d8a7efed285891653adfd5d68faaae06d41c1a;hp=34cc9189bb2a1768765be83a5edaf5c0e2be7f5d;hb=a85b3b947174c64ce06b4d6e438677055bf3f1ae;hpb=6aad8ed5fef24cdf2c65cbb193572cb10c2b2c1c diff --git a/client.c b/client.c index 34cc9189..68d8a7ef 100644 --- a/client.c +++ b/client.c @@ -8,12 +8,13 @@ #include #include +#include +#include "client.lsg.h" #include "para.h" #include "list.h" #include "sched.h" #include "crypt.h" -#include "client.cmdline.h" #include "string.h" #include "stdin.h" #include "stdout.h" @@ -22,7 +23,8 @@ #include "error.h" #include "version.h" -INIT_CLIENT_ERRLISTS; +/** Array of error strings. */ +DEFINE_PARA_ERRLIST; static struct sched sched; static struct client_task *ct; @@ -35,8 +37,7 @@ __printf_2_3 void (*para_log)(int, const char*, ...) = stderr_log; #ifdef HAVE_READLINE #include "interactive.h" -#include "server.completion.h" -#include "afs.completion.h" +#include "server_cmd.lsg.h" struct exec_task { struct task *task; @@ -77,17 +78,52 @@ out: return 0; } -static int make_client_argv(const char *line) +/* Called from the line handler and the completers. This overwrites ct->lpr. */ +static int create_merged_lpr(const char *line) { - int ret; + const struct lls_command *cmd = CLIENT_CMD_PTR; + int argc, ret; + char *cmdline, **argv, *errctx; + struct lls_parse_result *argv_lpr; + static struct lls_parse_result *orig_lpr; - free_argv(ct->conf.inputs); - ret = create_argv(line, " ", &ct->conf.inputs); - if (ret >= 0) - ct->conf.inputs_num = ret; + if (!orig_lpr) + orig_lpr = ct->lpr; + ct->lpr = NULL; + cmdline = make_message("-- %s", line); + ret = create_shifted_argv(cmdline, " ", &argv); + free(cmdline); + if (ret < 0) + return ret; + argc = ret; + if (argc == 2) { /* no words (only blanks in line) */ + free_argv(argv); + return 0; + } + argv[0] = para_strdup("--"); + /* + * The original lpr for the interactive session has no non-option + * arguments. We create a fresh lpr from the words in "line" and merge + * it with the orignal lpr. + */ + ret = lls(lls_parse(argc, argv, cmd, &argv_lpr, &errctx)); + free_argv(argv); + if (ret < 0) + goto fail; + ret = lls(lls_merge(orig_lpr, argv_lpr, cmd, &ct->lpr, &errctx)); + lls_free_parse_result(argv_lpr, cmd); + if (ret < 0) + goto fail; + return 1; +fail: + if (errctx) + PARA_ERROR_LOG("%s\n", para_strerror(-ret)); + free(errctx); + assert(ret < 0); return ret; } +/* called from completers */ static int execute_client_command(const char *cmd, char **result) { int ret; @@ -96,9 +132,11 @@ static int execute_client_command(const char *cmd, char **result) .result_buf = para_strdup(""), .result_size = 1, }; + struct lls_parse_result *old_lpr = ct->lpr; + *result = NULL; - ret = make_client_argv(cmd); - if (ret < 0) + ret = create_merged_lpr(cmd); + if (ret <= 0) goto out; exec_task.btrn = btr_new_node(&(struct btr_node_description) EMBRACE(.name = "exec_collect")); @@ -113,6 +151,8 @@ static int execute_client_command(const char *cmd, char **result) goto out; schedule(&command_sched); sched_shutdown(&command_sched); + lls_free_parse_result(ct->lpr, CLIENT_CMD_PTR); + ct->lpr = old_lpr; *result = exec_task.result_buf; btr_remove_node(&exec_task.btrn); ret = 1; @@ -173,7 +213,7 @@ static void complete_lsblob(const char *blob_type, struct i9e_completion_info *ci, struct i9e_completion_result *cr) { - char *opts[] = {"-i", "-l", "-r", NULL}; + char *opts[] = {LSG_SERVER_CMD_LSIMG_OPTS, NULL}; if (ci->word[0] == '-') return i9e_complete_option(opts, ci, cr); @@ -217,18 +257,17 @@ static void help_completer(struct i9e_completion_info *ci, result->matches = i9e_complete_commands(ci->word, completers); } -static void version_completer(struct i9e_completion_info *ci, +static void stat_completer(struct i9e_completion_info *ci, struct i9e_completion_result *cr) { - char *opts[] = {"-v", NULL}; + char *opts[] = {LSG_SERVER_CMD_STAT_OPTS, NULL}; i9e_complete_option(opts, ci, cr); } -static void stat_completer(struct i9e_completion_info *ci, +static void version_completer(struct i9e_completion_info *ci, struct i9e_completion_result *cr) { - char *opts[] = {"-n=", "-p", NULL}; - //PARA_CRIT_LOG("word: %s\n", ci->word); + char *opts[] = {LSG_SERVER_CMD_VERSION_OPTS, NULL}; i9e_complete_option(opts, ci, cr); } @@ -265,7 +304,7 @@ static void sender_completer(struct i9e_completion_info *ci, static void add_completer(struct i9e_completion_info *ci, struct i9e_completion_result *cr) { - char *opts[] = {"-a", "-l", "-f", "-v", "--", NULL}; + char *opts[] = {LSG_SERVER_CMD_ADD_OPTS, NULL}; if (ci->word[0] == '-') i9e_complete_option(opts, ci, cr); @@ -275,11 +314,7 @@ static void add_completer(struct i9e_completion_info *ci, static void ls_completer(struct i9e_completion_info *ci, struct i9e_completion_result *cr) { - char *opts[] = { - "--", "-l", "-l=s", "-l=l", "-l=v", "-l=p", "-l=m", "-l=c", - "-p", "-a", "-r", "-d", "-s=p", "-s=l", "-s=s", "-s=n", "-s=f", - "-s=c", "-s=i", "-s=y", "-s=b", "-s=d", "-s=a", NULL - }; + char *opts[] = {LSG_SERVER_CMD_LS_OPTS, NULL}; if (ci->word[0] == '-') i9e_complete_option(opts, ci, cr); cr->filename_completion_desired = true; @@ -322,12 +357,8 @@ out: static void lsatt_completer(struct i9e_completion_info *ci, struct i9e_completion_result *cr) { - char *opts[] = {"-i", "-l", "-r", NULL}; - - if (ci->word[0] == '-') - i9e_complete_option(opts, ci, cr); - else - complete_attributes(ci->word, &cr->matches); + char *opts[] = {LSG_SERVER_CMD_LSATT_OPTS, NULL}; + i9e_complete_option(opts, ci, cr); } static void mvatt_completer(struct i9e_completion_info *ci, @@ -345,14 +376,14 @@ static void rmatt_completer(struct i9e_completion_info *ci, static void check_completer(struct i9e_completion_info *ci, struct i9e_completion_result *cr) { - char *opts[] = {"-a", "-m", "-p", NULL}; + char *opts[] = {LSG_SERVER_CMD_CHECK_OPTS, NULL}; i9e_complete_option(opts, ci, cr); } static void rm_completer(struct i9e_completion_info *ci, struct i9e_completion_result *cr) { - char *opts[] = {"-v", "-f", "-p", NULL}; + char *opts[] = {LSG_SERVER_CMD_RM_OPTS, NULL}; if (ci->word[0] == '-') { i9e_complete_option(opts, ci, cr); @@ -364,7 +395,7 @@ static void rm_completer(struct i9e_completion_info *ci, static void touch_completer(struct i9e_completion_info *ci, struct i9e_completion_result *cr) { - char *opts[] = {"-n=", "-l=", "-y=", "-i=", "-a=", "-v", "-p", NULL}; + char *opts[] = {LSG_SERVER_CMD_TOUCH_OPTS, NULL}; if (ci->word[0] == '-') i9e_complete_option(opts, ci, cr); @@ -374,7 +405,7 @@ static void touch_completer(struct i9e_completion_info *ci, static void cpsi_completer(struct i9e_completion_info *ci, struct i9e_completion_result *cr) { - char *opts[] = {"-a", "-y", "-i", "-l", "-n", "-v", NULL}; + char *opts[] = {LSG_SERVER_CMD_CPSI_OPTS, NULL}; if (ci->word[0] == '-') i9e_complete_option(opts, ci, cr); @@ -450,9 +481,13 @@ DEFINE_BLOB_COMPLETER(mv, pl) static int client_i9e_line_handler(char *line) { int ret; + static bool first = true; - PARA_DEBUG_LOG("line: %s\n", line); - ret = make_client_argv(line); + if (first) + first = false; + else + lls_free_parse_result(ct->lpr, CLIENT_CMD_PTR); + ret = create_merged_lpr(line); if (ret <= 0) return ret; ret = client_connect(ct, &sched, NULL, NULL); @@ -462,16 +497,18 @@ static int client_i9e_line_handler(char *line) return 1; } +I9E_DUMMY_COMPLETER(SUPERCOMMAND_UNAVAILABLE); static struct i9e_completer completers[] = { - SERVER_COMPLETERS - AFS_COMPLETERS +#define LSG_SERVER_CMD_CMD(_name) {.name = #_name, \ + .completer = _name ## _completer} + LSG_SERVER_CMD_SUBCOMMANDS +#undef LSG_SERVER_CMD_CMD {.name = NULL} }; __noreturn static void interactive_session(void) { int ret; - char *history_file; struct sigaction act; struct i9e_client_info ici = { .fds = {0, 1, 2}, @@ -482,16 +519,15 @@ __noreturn static void interactive_session(void) }; PARA_NOTICE_LOG("\n%s\n", version_text("client")); - if (ct->conf.history_file_given) - history_file = para_strdup(ct->conf.history_file_arg); + if (CLIENT_OPT_GIVEN(HISTORY_FILE, ct->lpr)) + ici.history_file = para_strdup(CLIENT_OPT_STRING_VAL( + HISTORY_FILE, ct->lpr)); else { char *home = para_homedir(); - history_file = make_message("%s/.paraslash/client.history", + ici.history_file = make_message("%s/.paraslash/client.history", home); free(home); } - ici.history_file = history_file; - act.sa_handler = i9e_signal_dispatch; sigemptyset(&act.sa_mask); act.sa_flags = 0; @@ -515,7 +551,9 @@ out: __noreturn static void print_completions(void) { - int ret = i9e_print_completions(completers); + int ret; + + ret = i9e_print_completions(completers); exit(ret <= 0? EXIT_FAILURE : EXIT_SUCCESS); } @@ -590,7 +628,7 @@ int main(int argc, char *argv[]) ret = client_parse_config(argc, argv, &ct, &client_loglevel); if (ret < 0) goto out; - if (ct->conf.complete_given) + if (CLIENT_OPT_GIVEN(COMPLETE, ct->lpr)) print_completions(); if (ret == 0) interactive_session(); /* does not return */