Skip to content
Newer
Older
100644 199 lines (182 sloc) 5.04 KB
14c2920 Imported Upstream version 1.5.18
Antonio Radici authored May 24, 2009
1 /*
19304f7 Imported Upstream version 1.5.19
Antonio Radici authored May 24, 2009
2 * Copyright (C) 1996-2000,2007 Michael R. Elkins <me@mutt.org>
14c2920 Imported Upstream version 1.5.18
Antonio Radici authored May 24, 2009
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; either version 2 of the License, or
7 * (at your option) any later version.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
17 */
18
19 #if HAVE_CONFIG_H
20 # include "config.h"
21 #endif
22
23 #include "mutt.h"
24 #ifdef USE_IMAP
25 #include "mailbox.h"
26 #include "imap.h"
27 #endif
28
29 #include <dirent.h>
30 #include <string.h>
31 #include <sys/types.h>
32 #include <sys/stat.h>
33 #include <errno.h>
34
35 /* given a partial pathname, this routine fills in as much of the rest of the
36 * path as is unique.
37 *
38 * return 0 if ok, -1 if no matches
39 */
40 int mutt_complete (char *s, size_t slen)
41 {
42 char *p;
43 DIR *dirp = NULL;
44 struct dirent *de;
45 int i ,init=0;
46 size_t len;
47 char dirpart[_POSIX_PATH_MAX], exp_dirpart[_POSIX_PATH_MAX];
48 char filepart[_POSIX_PATH_MAX];
49 #ifdef USE_IMAP
50 char imap_path[LONG_STRING];
51
52 dprint (2, (debugfile, "mutt_complete: completing %s\n", s));
53
54 /* we can use '/' as a delimiter, imap_complete rewrites it */
55 if (*s == '=' || *s == '+' || *s == '!')
56 {
57 if (*s == '!')
58 p = NONULL (Spoolfile);
59 else
60 p = NONULL (Maildir);
61
62 mutt_concat_path (imap_path, p, s+1, sizeof (imap_path));
63 }
64 else
65 strfcpy (imap_path, s, sizeof(imap_path));
66
67 if (mx_is_imap (imap_path))
68 return imap_complete (s, slen, imap_path);
69 #endif
70
71 if (*s == '=' || *s == '+' || *s == '!')
72 {
73 dirpart[0] = *s;
74 dirpart[1] = 0;
75 if (*s == '!')
76 strfcpy (exp_dirpart, NONULL (Spoolfile), sizeof (exp_dirpart));
77 else
78 strfcpy (exp_dirpart, NONULL (Maildir), sizeof (exp_dirpart));
79 if ((p = strrchr (s, '/')))
80 {
81 char buf[_POSIX_PATH_MAX];
82 if (mutt_concatn_path (buf, sizeof(buf), exp_dirpart, strlen(exp_dirpart), s + 1, (size_t)(p - s - 1)) == NULL) {
83 return -1;
84 }
85 strfcpy (exp_dirpart, buf, sizeof (exp_dirpart));
86 mutt_substrcpy(dirpart, s, p+1, sizeof(dirpart));
87 strfcpy (filepart, p + 1, sizeof (filepart));
88 }
89 else
90 strfcpy (filepart, s + 1, sizeof (filepart));
91 dirp = opendir (exp_dirpart);
92 }
93 else
94 {
95 if ((p = strrchr (s, '/')))
96 {
97 if (p == s) /* absolute path */
98 {
99 p = s + 1;
100 strfcpy (dirpart, "/", sizeof (dirpart));
101 exp_dirpart[0] = 0;
102 strfcpy (filepart, p, sizeof (filepart));
103 dirp = opendir (dirpart);
104 }
105 else
106 {
107 mutt_substrcpy(dirpart, s, p, sizeof(dirpart));
108 strfcpy (filepart, p + 1, sizeof (filepart));
109 strfcpy (exp_dirpart, dirpart, sizeof (exp_dirpart));
110 mutt_expand_path (exp_dirpart, sizeof (exp_dirpart));
111 dirp = opendir (exp_dirpart);
112 }
113 }
114 else
115 {
116 /* no directory name, so assume current directory. */
117 dirpart[0] = 0;
118 strfcpy (filepart, s, sizeof (filepart));
119 dirp = opendir (".");
120 }
121 }
122
123 if (dirp == NULL)
124 {
125 dprint (1, (debugfile, "mutt_complete(): %s: %s (errno %d).\n", exp_dirpart, strerror (errno), errno));
126 return (-1);
127 }
128
129 /*
130 * special case to handle when there is no filepart yet. find the first
131 * file/directory which is not ``.'' or ``..''
132 */
133 if ((len = mutt_strlen (filepart)) == 0)
134 {
135 while ((de = readdir (dirp)) != NULL)
136 {
137 if (mutt_strcmp (".", de->d_name) != 0 && mutt_strcmp ("..", de->d_name) != 0)
138 {
139 strfcpy (filepart, de->d_name, sizeof (filepart));
140 init++;
141 break;
142 }
143 }
144 }
145
146 while ((de = readdir (dirp)) != NULL)
147 {
148 if (mutt_strncmp (de->d_name, filepart, len) == 0)
149 {
150 if (init)
151 {
152 for (i=0; filepart[i] && de->d_name[i]; i++)
153 {
154 if (filepart[i] != de->d_name[i])
155 {
156 filepart[i] = 0;
157 break;
158 }
159 }
160 filepart[i] = 0;
161 }
162 else
163 {
164 char buf[_POSIX_PATH_MAX];
165 struct stat st;
166
167 strfcpy (filepart, de->d_name, sizeof(filepart));
168
169 /* check to see if it is a directory */
170 if (dirpart[0])
171 {
172 strfcpy (buf, exp_dirpart, sizeof (buf));
173 strfcpy (buf + strlen (buf), "/", sizeof (buf) - strlen (buf));
174 }
175 else
176 buf[0] = 0;
177 strfcpy (buf + strlen (buf), filepart, sizeof (buf) - strlen (buf));
178 if (stat (buf, &st) != -1 && (st.st_mode & S_IFDIR))
179 strfcpy (filepart + strlen (filepart), "/",
180 sizeof (filepart) - strlen (filepart));
181 init = 1;
182 }
183 }
184 }
185 closedir (dirp);
186
187 if (dirpart[0])
188 {
189 strfcpy (s, dirpart, slen);
190 if (mutt_strcmp ("/", dirpart) != 0 && dirpart[0] != '=' && dirpart[0] != '+')
191 strfcpy (s + strlen (s), "/", slen - strlen (s));
192 strfcpy (s + strlen (s), filepart, slen - strlen (s));
193 }
194 else
195 strfcpy (s, filepart, slen);
196
197 return (init ? 0 : -1);
198 }
Something went wrong with that request. Please try again.