/* * Complete an option */ static unsigned char complete_option(char *word, int list) { struct option *o; StringList *words; size_t wordlen; unsigned char rv; words = ftp_sl_init(); wordlen = strlen(word); for (o = optiontab; o->name != NULL; o++) { if (wordlen > strlen(o->name)) continue; if (strncmp(word, o->name, wordlen) == 0) ftp_sl_add(words, ftp_strdup(o->name)); } rv = complete_ambiguous(word, list, words); if (rv == CC_REFRESH) { if (el_insertstr(el, " ") == -1) rv = CC_ERROR; } sl_free(words, 1); return (rv); }
/* * Complete a command */ static unsigned char complete_command(char *word, int list) { struct cmd *c; StringList *words; size_t wordlen; unsigned char rv; words = ftp_sl_init(); wordlen = strlen(word); for (c = cmdtab; c->c_name != NULL; c++) { if (wordlen > strlen(c->c_name)) continue; if (strncmp(word, c->c_name, wordlen) == 0) ftp_sl_add(words, ftp_strdup(c->c_name)); } rv = complete_ambiguous(word, list, words); if (rv == CC_REFRESH) { if (el_insertstr(el, " ") == -1) rv = CC_ERROR; } sl_free(words, 1); return (rv); }
/* * Complete a command */ static unsigned char complete_command(char *word, int list, EditLine *el, char **table, int stlen) { char **c; struct ghs *ghs; StringList *words; size_t wordlen; unsigned char rv; if (table == NULL) return(CC_ERROR); words = sl_init(); wordlen = strlen(word); for (c = table; *c != NULL; c = (char **)((char *)c + stlen)) { ghs = (struct ghs *)c; if (wordlen > strlen(ghs->name)) continue; if (strncmp(word, ghs->name, wordlen) == 0) sl_add(words, ghs->name); } rv = complete_ambiguous(word, list, words, el); sl_free(words, 0); return (rv); }
unsigned char complete_ifname(char *word, int list, EditLine *el) { StringList *words; size_t wordlen; unsigned char rv; words = sl_init(); wordlen = strlen(word); struct if_nameindex *ifn_list, *ifnp; if ((ifn_list = if_nameindex()) == NULL) return 0; for (ifnp = ifn_list; ifnp->if_name != NULL; ifnp++) { if (wordlen > strlen(ifnp->if_name)) continue; if (strncmp(word, ifnp->if_name, wordlen) == 0) sl_add(words, ifnp->if_name); } rv = complete_ambiguous(word, list, words, el); if_freenameindex(ifn_list); sl_free(words, 0); return (rv); }
/* * Complete a mail command. */ static unsigned char complete_command(EditLine *el, char *word, int dolist) { const struct cmd *c; StringList *words; size_t wordlen; unsigned char rv; words = mail_sl_init(); wordlen = strlen(word); for (c = cmdtab; c->c_name != NULL; c++) { if (wordlen > strlen(c->c_name)) continue; if (strncmp(word, c->c_name, wordlen) == 0) mail_sl_add(words, __UNCONST(c->c_name)); } rv = complete_ambiguous(el, word, dolist, words); if (rv == CC_REFRESH) { if (el_insertstr(el, " ") == -1) rv = CC_ERROR; } sl_free(words, 0); return rv; }
/* * Complete a local executable */ static unsigned char complete_executable(EditLine *el, char *word, int dolist) { StringList *words; char dir[ MAXPATHLEN ]; char *fname; unsigned char rv; size_t len; int error; if ((fname = strrchr(word, '/')) == NULL) { dir[0] = '\0'; /* walk the path */ fname = word; } else { if (fname == word) { dir[0] = '/'; dir[1] = '\0'; } else { len = fname - word; (void)strncpy(dir, word, len); dir[fname - word] = '\0'; } fname++; } words = sl_init(); if (*dir == '\0') { /* walk path */ char *env; char *path; env = getenv("PATH"); len = strlen(env); path = salloc(len + 1); (void)strcpy(path, env); error = find_execs(word, path, words); } else { /* check specified dir only */ error = find_execs(word, dir, words); } if (error != 0) return CC_ERROR; rv = complete_ambiguous(el, fname, dolist, words); if (rv == CC_REFRESH) { if (el_insertstr(el, " ") == -1) rv = CC_ERROR; } sl_free(words, 1); return rv; }
/* * Complete a local file */ static unsigned char complete_local(char *word, int list) { StringList *words; char dir[MAXPATHLEN]; char *file; DIR *dd; struct dirent *dp; unsigned char rv; if ((file = strrchr(word, '/')) == NULL) { dir[0] = '.'; dir[1] = '\0'; file = word; } else { if (file == word) { dir[0] = '/'; dir[1] = '\0'; } else { (void)strlcpy(dir, word, (size_t)(file - word) + 1); } file++; } if ((dd = opendir(dir)) == NULL) return (CC_ERROR); words = sl_init(); for (dp = readdir(dd); dp != NULL; dp = readdir(dd)) { if (!strcmp(dp->d_name, ".") || !strcmp(dp->d_name, "..")) continue; if (strlen(file) > dp->d_namlen) continue; if (strncmp(file, dp->d_name, strlen(file)) == 0) { char *tcp; tcp = strdup(dp->d_name); if (tcp == NULL) errx(1, "Can't allocate memory for local dir"); sl_add(words, tcp); } } closedir(dd); rv = complete_ambiguous(file, list, words); sl_free(words, 1); return (rv); }
/* * Complete mime_transfer_encoding type. */ static unsigned char mime_enc_complete(EditLine *el, int ch) { static char word[LINESIZE]; StringList *words; unsigned char rv; const LineInfo *lf; size_t word_len; int dolist; lf = el_line(el); #ifdef EMACS_CTRL_D_BINDING_HACK { int cc_ret; if ((cc_ret = emacs_ctrl_d(el, lf, ch)) != -1) return cc_ret; } #endif /* EMACS_CTRL_D_BINDING_HACK */ word_len = lf->cursor - lf->buffer; if (word_len >= sizeof(word) - 1) return CC_ERROR; words = mail_sl_init(); { const char *ename; const void *cookie; cookie = NULL; for (ename = mime_next_encoding_name(&cookie); ename; ename = mime_next_encoding_name(&cookie)) if (word_len == 0 || strncmp(lf->buffer, ename, word_len) == 0) { char *cp; cp = estrdup(ename); mail_sl_add(words, cp); } } (void)strlcpy(word, lf->buffer, word_len + 1); if ((dolist = get_dolist(lf)) == -1) return CC_ERROR; rv = complete_ambiguous(el, word, dolist, words); sl_free(words, 1); return rv; }
static unsigned char complete_thread_key(EditLine *el, char *word, int dolist) { const char **ap; const char **p; const char *name; size_t len; StringList *words; unsigned char rv; int cnt; const void *cookie; len = strlen(word); words = sl_init(); /* count the entries in the table */ /* XXX - have a function return this rather than counting? */ cnt = 1; /* count the NULL terminator */ cookie = NULL; while (thread_next_key_name(&cookie) != NULL) cnt++; /* allocate sufficient space for the pointers */ ap = salloc(cnt * sizeof(*ap)); /* load the array */ p = ap; cookie = NULL; while ((name = thread_next_key_name(&cookie)) != NULL) *p++ = name; *p = NULL; sort(ap); for (p = ap; *p != NULL; p++) if (len == 0 || strncmp(*p, word, len) == 0) mail_sl_add(words, estrdup(*p)); rv = complete_ambiguous(el, word, dolist, words); sl_free(words, 1); return rv; }
static unsigned char complete_alias(EditLine *el, char *word, int dolist) { struct grouphead *gh; const char **ap; const char **p; int h; int s; size_t len = strlen(word); StringList *words; unsigned char rv; words = sl_init(); /* allocate space for alias table */ s = 1; for (h = 0; h < HSHSIZE; h++) for (gh = groups[h]; gh != NULL; gh = gh->g_link) s++; ap = salloc(s * sizeof(*ap)); /* save pointers */ p = ap; for (h = 0; h < HSHSIZE; h++) for (gh = groups[h]; gh != NULL; gh = gh->g_link) *p++ = gh->g_name; *p = NULL; sort(ap); for (p = ap; *p != NULL; p++) if (len == 0 || strncmp(*p, word, len) == 0) mail_sl_add(words, estrdup(*p)); rv = complete_ambiguous(el, word, dolist, words); if (rv == CC_REFRESH) { if (el_insertstr(el, " ") == -1) rv = CC_ERROR; } sl_free(words, 1); return rv; }
/* * Complete a command */ static unsigned char complete_command(char *word, int list) { const struct cmd *c; StringList *words; size_t wordlen; unsigned char rv; words = sl_init(); wordlen = strlen(word); for (c = cmdtab; c->c_name != NULL; c++) { if (wordlen > strlen(c->c_name)) continue; if (strncmp(word, c->c_name, wordlen) == 0) sl_add(words, c->c_name); } rv = complete_ambiguous(word, list, words); sl_free(words, 0); return (rv); }
static unsigned char complete_set(EditLine *el, char *word, int dolist) { struct var *vp; const char **ap; const char **p; int h; int s; size_t len = strlen(word); StringList *words; unsigned char rv; words = sl_init(); /* allocate space for variables table */ s = 1; for (h = 0; h < HSHSIZE; h++) for (vp = variables[h]; vp != NULL; vp = vp->v_link) s++; ap = salloc(s * sizeof(*ap)); /* save the pointers */ for (h = 0, p = ap; h < HSHSIZE; h++) for (vp = variables[h]; vp != NULL; vp = vp->v_link) *p++ = vp->v_name; *p = NULL; sort(ap); for (p = ap; *p != NULL; p++) if (len == 0 || strncmp(*p, word, len) == 0) mail_sl_add(words, estrdup(*p)); rv = complete_ambiguous(el, word, dolist, words); sl_free(words, 1); return rv; }
/* * Complete a remote file */ static unsigned char complete_remote(char *word, int list) { static StringList *dirlist; static char lastdir[MAXPATHLEN]; StringList *words; char dir[MAXPATHLEN]; char *file, *cp; int i; unsigned char rv; char *dummyargv[] = { "complete", dir, NULL }; if ((file = strrchr(word, '/')) == NULL) { dir[0] = '.'; dir[1] = '\0'; file = word; } else { cp = file; while (*cp == '/' && cp > word) cp--; (void)strlcpy(dir, word, (size_t)(cp - word + 2)); file++; } if (dirchange || strcmp(dir, lastdir) != 0) { /* dir not cached */ char *emesg; sl_free(dirlist, 1); dirlist = sl_init(); mflag = 1; emesg = NULL; #ifndef SMALL if (debug) (void)putc('\n', ttyout); #endif /* !SMALL */ while ((cp = remglob(dummyargv, 0, &emesg)) != NULL) { char *tcp; if (!mflag) continue; if (*cp == '\0') { mflag = 0; continue; } tcp = strrchr(cp, '/'); if (tcp) tcp++; else tcp = cp; tcp = strdup(tcp); if (tcp == NULL) errx(1, "Can't allocate memory for remote dir"); sl_add(dirlist, tcp); } if (emesg != NULL) { fprintf(ttyout, "\n%s\n", emesg); return (CC_REDISPLAY); } (void)strlcpy(lastdir, dir, sizeof lastdir); dirchange = 0; } words = sl_init(); for (i = 0; i < dirlist->sl_cur; i++) { cp = dirlist->sl_str[i]; if (strlen(file) > strlen(cp)) continue; if (strncmp(file, cp, strlen(file)) == 0) sl_add(words, cp); } rv = complete_ambiguous(file, list, words); sl_free(words, 0); return (rv); }
/* * Complete a remote file */ static unsigned char complete_remote(char *word, int list) { static StringList *dirlist; static char lastdir[MAXPATHLEN]; StringList *words; char dir[MAXPATHLEN]; char *file, *cp; size_t i; unsigned char rv; char cmdbuf[MAX_C_NAME]; char *dummyargv[3] = { NULL, NULL, NULL }; (void)strlcpy(cmdbuf, "complete", sizeof(cmdbuf)); dummyargv[0] = cmdbuf; dummyargv[1] = dir; if ((file = strrchr(word, '/')) == NULL) { dir[0] = '\0'; file = word; } else { cp = file; while (*cp == '/' && cp > word) cp--; (void)strlcpy(dir, word, cp - word + 2); file++; } if (dirchange || dirlist == NULL || strcmp(dir, lastdir) != 0) { /* dir not cached */ const char *emesg; if (dirlist != NULL) sl_free(dirlist, 1); dirlist = ftp_sl_init(); mflag = 1; emesg = NULL; while ((cp = remglob(dummyargv, 0, &emesg)) != NULL) { char *tcp; if (!mflag) continue; if (*cp == '\0') { mflag = 0; continue; } tcp = strrchr(cp, '/'); if (tcp) tcp++; else tcp = cp; tcp = ftp_strdup(tcp); ftp_sl_add(dirlist, tcp); } if (emesg != NULL) { fprintf(ttyout, "\n%s\n", emesg); return (CC_REDISPLAY); } (void)strlcpy(lastdir, dir, sizeof(lastdir)); dirchange = 0; } words = ftp_sl_init(); for (i = 0; i < dirlist->sl_cur; i++) { cp = dirlist->sl_str[i]; if (strlen(file) > strlen(cp)) continue; if (strncmp(file, cp, strlen(file)) == 0) ftp_sl_add(words, cp); } rv = complete_ambiguous(file, list, words); sl_free(words, 0); return (rv); }
/* * Complete a local file */ static unsigned char complete_local(char *word, int list) { StringList *words; char dir[MAXPATHLEN]; char *file; DIR *dd; struct dirent *dp; unsigned char rv; size_t len; if ((file = strrchr(word, '/')) == NULL) { dir[0] = '.'; dir[1] = '\0'; file = word; } else { if (file == word) { dir[0] = '/'; dir[1] = '\0'; } else (void)strlcpy(dir, word, file - word + 1); file++; } if (dir[0] == '~') { char *p; if ((p = globulize(dir)) == NULL) return (CC_ERROR); (void)strlcpy(dir, p, sizeof(dir)); free(p); } if ((dd = opendir(dir)) == NULL) return (CC_ERROR); words = ftp_sl_init(); len = strlen(file); for (dp = readdir(dd); dp != NULL; dp = readdir(dd)) { if (!strcmp(dp->d_name, ".") || !strcmp(dp->d_name, "..")) continue; #if defined(DIRENT_MISSING_D_NAMLEN) if (len > strlen(dp->d_name)) continue; #else if (len > dp->d_namlen) continue; #endif if (strncmp(file, dp->d_name, len) == 0) { char *tcp; tcp = ftp_strdup(dp->d_name); ftp_sl_add(words, tcp); } } closedir(dd); rv = complete_ambiguous(file, list, words); if (rv == CC_REFRESH) { struct stat sb; char path[MAXPATHLEN]; (void)strlcpy(path, dir, sizeof(path)); (void)strlcat(path, "/", sizeof(path)); (void)strlcat(path, words->sl_str[0], sizeof(path)); if (stat(path, &sb) >= 0) { char suffix[2] = " "; if (S_ISDIR(sb.st_mode)) suffix[0] = '/'; if (el_insertstr(el, suffix) == -1) rv = CC_ERROR; } } sl_free(words, 1); return (rv); }
static unsigned char complete_smopts(EditLine *el, char *word, int dolist) { struct grouphead *gh; struct smopts_s *sp; const char **ap; const char **p; int h; int s1; int s2; size_t len; StringList *words; unsigned char rv; len = strlen(word); words = sl_init(); /* count the entries in the smoptstbl and groups (alias) tables */ s1 = 1; s2 = 1; for (h = 0; h < HSHSIZE; h++) { for (sp = smoptstbl[h]; sp != NULL; sp = sp->s_link) s1++; for (gh = groups[h]; gh != NULL; gh = gh->g_link) s2++; } /* allocate sufficient space for the pointers */ ap = salloc(MAX(s1, s2) * sizeof(*ap)); /* * First do the smoptstbl pointers. (case _insensitive_) */ p = ap; for (h = 0; h < HSHSIZE; h++) for (sp = smoptstbl[h]; sp != NULL; sp = sp->s_link) *p++ = sp->s_name; *p = NULL; sort(ap); for (p = ap; *p != NULL; p++) if (len == 0 || strncasecmp(*p, word, len) == 0) mail_sl_add(words, estrdup(*p)); /* * Now do the groups (alias) pointers. (case sensitive) */ p = ap; for (h = 0; h < HSHSIZE; h++) for (gh = groups[h]; gh != NULL; gh = gh->g_link) *p++ = gh->g_name; *p = NULL; sort(ap); for (p = ap; *p != NULL; p++) if (len == 0 || strncmp(*p, word, len) == 0) mail_sl_add(words, estrdup(*p)); rv = complete_ambiguous(el, word, dolist, words); sl_free(words, 1); return rv; }