diff options
Diffstat (limited to 'source3/client/client.c')
-rw-r--r-- | source3/client/client.c | 187 |
1 files changed, 23 insertions, 164 deletions
diff --git a/source3/client/client.c b/source3/client/client.c index 167f91ae16..b6c4b704a9 100644 --- a/source3/client/client.c +++ b/source3/client/client.c @@ -2215,181 +2215,40 @@ static int process_command_string(char *cmd) return rc; } +/**************************************************************************** +handle completion of commands for readline +****************************************************************************/ +static char **completion_fn(char *text, int start, int end) +{ #define MAX_COMPLETIONS 100 - -typedef struct { - pstring dirmask; char **matches; - int count, samelen; - const char *text; - int len; -} completion_remote_t; + int i, count=0; -static void completion_remote_filter(file_info *f, const char *mask, void *state) -{ - completion_remote_t *info = (completion_remote_t *)state; + /* for words not at the start of the line fallback to filename completion */ + if (start) return NULL; - if ((info->count < MAX_COMPLETIONS - 1) && (strncmp(info->text, f->name, info->len) == 0) && (strcmp(f->name, ".") != 0) && (strcmp(f->name, "..") != 0)) { - if ((info->dirmask[0] == 0) && !(f->mode & aDIR)) - info->matches[info->count] = strdup(f->name); - else { - pstring tmp; + matches = (char **)malloc(sizeof(matches[0])*MAX_COMPLETIONS); + if (!matches) return NULL; - if (info->dirmask[0] != 0) - pstrcpy(tmp, info->dirmask); - else - tmp[0] = 0; - pstrcat(tmp, f->name); - if (f->mode & aDIR) - pstrcat(tmp, "/"); - info->matches[info->count] = strdup(tmp); - } - if (info->matches[info->count] == NULL) - return; - if (f->mode & aDIR) - smb_readline_ca_char(0); + matches[count++] = strdup(text); + if (!matches[0]) return NULL; - if (info->count == 1) - info->samelen = strlen(info->matches[info->count]); - else - while (strncmp(info->matches[info->count], info->matches[info->count-1], info->samelen) != 0) - info->samelen--; - info->count++; + for (i=0;commands[i].fn && count < MAX_COMPLETIONS-1;i++) { + if (strncmp(text, commands[i].name, strlen(text)) == 0) { + matches[count] = strdup(commands[i].name); + if (!matches[count]) return NULL; + count++; + } } -} - -static char **remote_completion(const char *text, int len) -{ - pstring dirmask; - int i; - completion_remote_t info = { "", NULL, 1, len, text, len }; - - if (len >= PATH_MAX) - return(NULL); - - info.matches = (char **)malloc(sizeof(info.matches[0])*MAX_COMPLETIONS); - if (!info.matches) return NULL; - info.matches[0] = NULL; - - for (i = len-1; i >= 0; i--) - if ((text[i] == '/') || (text[i] == '\\')) - break; - info.text = text+i+1; - info.samelen = info.len = len-i-1; - if (i > 0) { - strncpy(info.dirmask, text, i+1); - info.dirmask[i+1] = 0; - snprintf(dirmask, sizeof(dirmask), "%s%*s*", cur_dir, i-1, text); - } else - snprintf(dirmask, sizeof(dirmask), "%s*", cur_dir); - - if (cli_list(cli, dirmask, aDIR | aSYSTEM | aHIDDEN, completion_remote_filter, &info) < 0) - goto cleanup; - - if (info.count == 2) - info.matches[0] = strdup(info.matches[1]); - else { - info.matches[0] = malloc(info.samelen+1); - if (!info.matches[0]) - goto cleanup; - strncpy(info.matches[0], info.matches[1], info.samelen); - info.matches[0][info.samelen] = 0; + if (count == 2) { + SAFE_FREE(matches[0]); + matches[0] = strdup(matches[1]); } - info.matches[info.count] = NULL; - return info.matches; - -cleanup: - for (i = 0; i < info.count; i++) - free(info.matches[i]); - free(info.matches); - return NULL; + matches[count] = NULL; + return matches; } -static char **completion_fn(const char *text, int start, int end) -{ - smb_readline_ca_char(' '); - - if (start) { - const char *buf, *sp; - int i; - char compl_type; - - buf = smb_readline_get_line_buffer(); - if (buf == NULL) - return NULL; - - sp = strchr(buf, ' '); - if (sp == NULL) - return NULL; - - for (i = 0; commands[i].name; i++) - if ((strncmp(commands[i].name, text, sp - buf) == 0) && (commands[i].name[sp - buf] == 0)) - break; - if (commands[i].name == NULL) - return NULL; - - while (*sp == ' ') - sp++; - - if (sp == (buf + start)) - compl_type = commands[i].compl_args[0]; - else - compl_type = commands[i].compl_args[1]; - - if (compl_type == COMPL_REMOTE) - return remote_completion(text, end - start); - else /* fall back to local filename completion */ - return NULL; - } else { - char **matches; - int i, len, samelen, count=1; - - matches = (char **)malloc(sizeof(matches[0])*MAX_COMPLETIONS); - if (!matches) return NULL; - matches[0] = NULL; - - len = strlen(text); - for (i=0;commands[i].fn && count < MAX_COMPLETIONS-1;i++) { - if (strncmp(text, commands[i].name, len) == 0) { - matches[count] = strdup(commands[i].name); - if (!matches[count]) - goto cleanup; - if (count == 1) - samelen = strlen(matches[count]); - else - while (strncmp(matches[count], matches[count-1], samelen) != 0) - samelen--; - count++; - } - } - - switch (count) { - case 0: /* should never happen */ - case 1: - goto cleanup; - case 2: - matches[0] = strdup(matches[1]); - break; - default: - matches[0] = malloc(samelen+1); - if (!matches[0]) - goto cleanup; - strncpy(matches[0], matches[1], samelen); - matches[0][samelen] = 0; - } - matches[count] = NULL; - return matches; - -cleanup: - while (i >= 0) { - free(matches[i]); - i--; - } - free(matches); - return NULL; - } -} /**************************************************************************** make sure we swallow keepalives during idle time |