X-Git-Url: http://git.madism.org/?a=blobdiff_plain;f=lib-ui%2Fcomplete.c;fp=lib-ui%2Fcomplete.c;h=2ad60ac4dc1c54b99eaa7bbd18626524d93929bf;hb=96e4b6de291b2195b26289fb03536acd101c6650;hp=0000000000000000000000000000000000000000;hpb=3692b834c97c9933088d7082464fec5ae903920f;p=apps%2Fmadmutt.git diff --git a/lib-ui/complete.c b/lib-ui/complete.c new file mode 100644 index 0000000..2ad60ac --- /dev/null +++ b/lib-ui/complete.c @@ -0,0 +1,222 @@ +/* + * Copyright notice from original mutt: + * Copyright (C) 1996-2000 Michael R. Elkins + * + * This file is part of mutt-ng, see http://www.muttng.org/. + * It's licensed under the GNU General Public License, + * please see the file GPL in the top level source directory. + */ + +#if HAVE_CONFIG_H +# include "config.h" +#endif + +#include +#include +#include +#include +#include + +#include +#include + +#include "mutt.h" +#include "mx.h" +#include +#ifdef USE_NNTP +#include +#endif + +/* given a partial pathname, this routine fills in as much of the rest of the + * path as is unique. + * + * return 0 if ok, -1 if no matches + */ +int mutt_complete (char *s, ssize_t slen) +{ + char *p; + DIR *dirp = NULL; + struct dirent *de; + int i, init = 0; + ssize_t len; + char dirpart[_POSIX_PATH_MAX], exp_dirpart[_POSIX_PATH_MAX]; + char filepart[_POSIX_PATH_MAX]; + + char imap_path[LONG_STRING]; + +#ifdef USE_NNTP + if (option (OPTNEWS)) { + string_list_t *l = CurrentNewsSrv->list; + + m_strcpy(filepart, sizeof(filepart), s); + + /* + * special case to handle when there is no filepart yet. + * find the first subscribed newsgroup + */ + if ((len = m_strlen(filepart)) == 0) { + for (; l; l = l->next) { + NNTP_DATA *data = (NNTP_DATA *) l->data; + + if (data && data->subscribed) { + m_strcpy(filepart, sizeof(filepart), data->group); + init++; + l = l->next; + break; + } + } + } + + for (; l; l = l->next) { + NNTP_DATA *data = (NNTP_DATA *) l->data; + + if (data && data->subscribed && + m_strncmp(data->group, filepart, len) == 0) { + if (init) { + for (i = 0; filepart[i] && data->group[i]; i++) { + if (filepart[i] != data->group[i]) { + filepart[i] = 0; + break; + } + } + filepart[i] = 0; + } + else { + m_strcpy(filepart, sizeof(filepart), data->group); + init = 1; + } + } + } + + strcpy (s, filepart); + + return (init ? 0 : -1); + } +#endif + + /* we can use '/' as a delimiter, imap_complete rewrites it */ + if (*s == '=' || *s == '+' || *s == '!') { + const char *q = NONULL(*s == '!' ? Spoolfile : Maildir); + mutt_concat_path(imap_path, sizeof(imap_path), q, s + 1); + } + else + m_strcpy(imap_path, sizeof(imap_path), s); + + if (mx_get_magic (imap_path) == M_IMAP) + return imap_complete (s, slen, imap_path); + + if (*s == '=' || *s == '+' || *s == '!') { + dirpart[0] = *s; + dirpart[1] = 0; + if (*s == '!') + m_strcpy(exp_dirpart, sizeof(exp_dirpart), NONULL(Spoolfile)); + else + m_strcpy(exp_dirpart, sizeof(exp_dirpart), NONULL(Maildir)); + if ((p = strrchr (s, '/'))) { + char buf[_POSIX_PATH_MAX]; + + *p++ = 0; + mutt_concat_path(buf, sizeof(buf), exp_dirpart, s + 1); + m_strcpy(exp_dirpart, sizeof(exp_dirpart), buf); + snprintf (buf, sizeof (buf), "%s%s/", dirpart, s + 1); + m_strcpy(dirpart, sizeof(dirpart), buf); + m_strcpy(filepart, sizeof(filepart), p); + } + else + m_strcpy(filepart, sizeof(filepart), s + 1); + dirp = opendir (exp_dirpart); + } + else { + if ((p = strrchr (s, '/'))) { + if (p == s) { /* absolute path */ + p = s + 1; + m_strcpy(dirpart, sizeof(dirpart), "/"); + exp_dirpart[0] = 0; + m_strcpy(filepart, sizeof(filepart), p); + dirp = opendir (dirpart); + } + else { + *p = 0; + len = p - s; + memcpy(dirpart, s, len); + dirpart[len] = 0; + p++; + m_strcpy(filepart, sizeof(filepart), p); + m_strcpy(exp_dirpart, sizeof(exp_dirpart), dirpart); + mutt_expand_path (exp_dirpart, sizeof (exp_dirpart)); + dirp = opendir (exp_dirpart); + } + } + else { + /* no directory name, so assume current directory. */ + dirpart[0] = 0; + m_strcpy(filepart, sizeof(filepart), s); + dirp = opendir ("."); + } + } + + if (dirp == NULL) { + return (-1); + } + + /* + * special case to handle when there is no filepart yet. find the first + * file/directory which is not ``.'' or ``..'' + */ + if ((len = m_strlen(filepart)) == 0) { + while ((de = readdir (dirp)) != NULL) { + if (m_strcmp(".", de->d_name) != 0 + && m_strcmp("..", de->d_name) != 0) { + m_strcpy(filepart, sizeof(filepart), de->d_name); + init++; + break; + } + } + } + + while ((de = readdir (dirp)) != NULL) { + if (m_strncmp(de->d_name, filepart, len) == 0) { + if (init) { + for (i = 0; filepart[i] && de->d_name[i]; i++) { + if (filepart[i] != de->d_name[i]) { + filepart[i] = 0; + break; + } + } + filepart[i] = 0; + } + else { + char buf[_POSIX_PATH_MAX]; + struct stat st; + + m_strcpy(filepart, sizeof(filepart), de->d_name); + + /* check to see if it is a directory */ + if (dirpart[0]) { + m_strcpy(buf, sizeof(buf), exp_dirpart); + m_strcpy(buf + m_strlen(buf), sizeof(buf) - m_strlen(buf), "/"); + } + else + buf[0] = 0; + m_strcpy(buf + m_strlen(buf), sizeof(buf) - m_strlen(buf), filepart); + if (stat (buf, &st) != -1 && (st.st_mode & S_IFDIR)) + m_strcpy(filepart + m_strlen(filepart), + sizeof(filepart) - m_strlen(filepart), "/"); + init = 1; + } + } + } + closedir (dirp); + + if (dirpart[0]) { + m_strcpy(s, slen, dirpart); + if (m_strcmp("/", dirpart) != 0 && dirpart[0] != '=' + && dirpart[0] != '+') + m_strcpy(s + m_strlen(s), slen - m_strlen(s), "/"); + m_strcpy(s + m_strlen(s), slen - m_strlen(s), filepart); + } + else + m_strcpy(s, slen, filepart); + + return (init ? 0 : -1); +}