+++ /dev/null
-/*
- * Copyright notice from original mutt:
- * Copyright (C) 1996-2000 Michael R. Elkins <me@mutt.org>
- *
- * 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.
- */
-
-#include <lib-lib/lib-lib.h>
-
-#include <dirent.h>
-#include <pwd.h>
-#include <grp.h>
-
-#include <lib-ui/lib-ui.h>
-#include <lib-ui/menu.h>
-#include <lib-mx/mx.h>
-
-#include "mutt.h"
-#include "buffy.h"
-#include "sort.h"
-#include "browser.h"
-#include "attach.h"
-
-#include <imap/imap.h>
-
-typedef struct folder_t {
- struct folder_file *ff;
- int num;
-} FOLDER;
-
-static char LastDir[_POSIX_PATH_MAX] = "";
-static char LastDirBackup[_POSIX_PATH_MAX] = "";
-
-/* Frees up the memory allocated for the local-global variables. */
-static void destroy_state (struct browser_state *state)
-{
- int c;
-
- for (c = 0; c < state->entrylen; c++) {
- p_delete(&state->entry[c].name);
- p_delete(&state->entry[c].desc);
- p_delete(&state->entry[c].st);
- }
- p_delete(&state->folder);
- p_delete(&state->entry);
-}
-
-static int browser_compare_subject (const void *a, const void *b)
-{
- struct folder_file *pa = (struct folder_file *) a;
- struct folder_file *pb = (struct folder_file *) b;
-
- int r = strcoll(NONULL(pa->name), NONULL(pb->name));
-
- return ((BrowserSort & SORT_REVERSE) ? -r : r);
-}
-
-static int browser_compare_date (const void *a, const void *b)
-{
- struct folder_file *pa = (struct folder_file *) a;
- struct folder_file *pb = (struct folder_file *) b;
-
- int r = pa->mtime - pb->mtime;
-
- return ((BrowserSort & SORT_REVERSE) ? -r : r);
-}
-
-static int browser_compare_size (const void *a, const void *b)
-{
- struct folder_file *pa = (struct folder_file *) a;
- struct folder_file *pb = (struct folder_file *) b;
-
- int r = pa->size - pb->size;
-
- return ((BrowserSort & SORT_REVERSE) ? -r : r);
-}
-
-static void browser_sort (struct browser_state *state)
-{
- int (*f) (const void *, const void *);
-
- switch (BrowserSort & SORT_MASK) {
- case SORT_ORDER:
- return;
- case SORT_DATE:
- f = browser_compare_date;
- break;
- case SORT_SIZE:
- f = browser_compare_size;
- break;
- case SORT_SUBJECT:
- default:
- f = browser_compare_subject;
- break;
- }
- qsort (state->entry, state->entrylen, sizeof (struct folder_file), f);
-}
-
-static int link_is_dir (const char *folder, const char *path)
-{
- struct stat st;
- char fullpath[_POSIX_PATH_MAX];
-
- mutt_concat_path(fullpath, sizeof(fullpath), folder, path);
-
- if (stat (fullpath, &st) == 0)
- return (S_ISDIR (st.st_mode));
- else
- return 0;
-}
-
-static const char *
-folder_format_str(char *dest, ssize_t destlen, char op,
- const char *src, const char *fmt,
- const char *ifstr, const char *elstr,
- anytype data, format_flag flags)
-{
- char fn[STRING], tmp[STRING], permission[11], date[16];
- const char *t_fmt;
- time_t tnow;
- FOLDER *folder = data.ptr;
- struct passwd *pw;
- struct group *gr;
- int optional = (flags & M_FORMAT_OPTIONAL);
-
- switch (op) {
- case 'C':
- snprintf (tmp, sizeof (tmp), "%%%sd", fmt);
- snprintf (dest, destlen, tmp, folder->num + 1);
- break;
-
- case 'd':
- if (folder->ff->st != NULL) {
- tnow = time (NULL);
- t_fmt =
- tnow - folder->ff->st->st_mtime <
- 31536000 ? "%b %d %H:%M" : "%b %d %Y";
- strftime (date, sizeof (date), t_fmt,
- localtime (&folder->ff->st->st_mtime));
- mutt_format_s (dest, destlen, fmt, date);
- }
- else
- mutt_format_s (dest, destlen, fmt, "");
- break;
-
- case 'f':
- {
- const char *s;
-
- if (folder->ff->imap)
- s = NONULL(folder->ff->desc);
- else
- s = NONULL(folder->ff->name);
-
- snprintf (fn, sizeof (fn), "%s%s", s,
- folder->ff->st ? (S_ISLNK (folder->ff->st->st_mode) ? "@" :
- (S_ISDIR (folder->ff->st->st_mode) ? "/" :
- ((folder->ff->st->st_mode & S_IXUSR) !=
- 0 ? "*" : ""))) : "");
-
- mutt_format_s (dest, destlen, fmt, fn);
- break;
- }
- case 'F':
- if (folder->ff->st != NULL) {
- snprintf (permission, sizeof (permission), "%c%c%c%c%c%c%c%c%c%c",
- S_ISDIR(folder->ff->st-> st_mode)
- ? 'd' : (S_ISLNK(folder->ff->st-> st_mode) ? 'l' : '-'),
- (folder->ff->st->st_mode & S_IRUSR) != 0 ? 'r' : '-',
- (folder->ff->st->st_mode & S_IWUSR) != 0 ? 'w' : '-',
- (folder->ff->st->st_mode & S_ISUID) !=
- 0 ? 's' : (folder->ff->st->st_mode & S_IXUSR) !=
- 0 ? 'x' : '-',
- (folder->ff->st->st_mode & S_IRGRP) != 0 ? 'r' : '-',
- (folder->ff->st->st_mode & S_IWGRP) != 0 ? 'w' : '-',
- (folder->ff->st->st_mode & S_ISGID) !=
- 0 ? 's' : (folder->ff->st->st_mode & S_IXGRP) !=
- 0 ? 'x' : '-',
- (folder->ff->st->st_mode & S_IROTH) != 0 ? 'r' : '-',
- (folder->ff->st->st_mode & S_IWOTH) != 0 ? 'w' : '-',
- (folder->ff->st->st_mode & S_ISVTX) !=
- 0 ? 't' : (folder->ff->st->st_mode & S_IXOTH) !=
- 0 ? 'x' : '-');
- mutt_format_s (dest, destlen, fmt, permission);
- }
- else if (folder->ff->imap) {
- /* mark folders with subfolders AND mail */
- snprintf (permission, sizeof (permission), "IMAP %c",
- (folder->ff->inferiors
- && folder->ff->selectable) ? '+' : ' ');
- mutt_format_s (dest, destlen, fmt, permission);
- }
- else
- mutt_format_s (dest, destlen, fmt, "");
- break;
-
- case 'g':
- if (folder->ff->st != NULL) {
- if ((gr = getgrgid (folder->ff->st->st_gid)))
- mutt_format_s (dest, destlen, fmt, gr->gr_name);
- else {
- snprintf (tmp, sizeof (tmp), "%%%sld", fmt);
- snprintf (dest, destlen, tmp, folder->ff->st->st_gid);
- }
- }
- else
- mutt_format_s (dest, destlen, fmt, "");
- break;
-
- case 'l':
- if (folder->ff->st != NULL) {
- snprintf (tmp, sizeof (tmp), "%%%sd", fmt);
- snprintf (dest, destlen, tmp, folder->ff->st->st_nlink);
- }
- else
- mutt_format_s (dest, destlen, fmt, "");
- break;
-
- case 'N':
- if (imap_is_magic (folder->ff->desc, NULL) == M_IMAP) {
- if (!optional) {
- snprintf (tmp, sizeof (tmp), "%%%sd", fmt);
- snprintf (dest, destlen, tmp, folder->ff->new);
- }
- else if (!folder->ff->new)
- optional = 0;
- break;
- }
- snprintf (tmp, sizeof (tmp), "%%%sc", fmt);
- snprintf (dest, destlen, tmp, folder->ff->new ? 'N' : ' ');
- break;
-
- case 's':
- if (folder->ff->st != NULL) {
- snprintf (tmp, sizeof (tmp), "%%%sld", fmt);
- snprintf (dest, destlen, tmp, (long) folder->ff->st->st_size);
- }
- else
- mutt_format_s (dest, destlen, fmt, "");
- break;
-
- case 't':
- snprintf (tmp, sizeof (tmp), "%%%sc", fmt);
- snprintf (dest, destlen, tmp, folder->ff->tagged ? '*' : ' ');
- break;
-
- case 'u':
- if (folder->ff->st != NULL) {
- if ((pw = getpwuid (folder->ff->st->st_uid)))
- mutt_format_s (dest, destlen, fmt, pw->pw_name);
- else {
- snprintf (tmp, sizeof (tmp), "%%%sld", fmt);
- snprintf (dest, destlen, tmp, folder->ff->st->st_uid);
- }
- }
- else
- mutt_format_s (dest, destlen, fmt, "");
- break;
-
- default:
- snprintf (tmp, sizeof (tmp), "%%%sc", fmt);
- snprintf (dest, destlen, tmp, op);
- break;
- }
-
-
- if (flags & M_FORMAT_OPTIONAL)
- m_strformat(dest, destlen, 0, optional ? ifstr : elstr,
- folder_format_str, data, 0);
-
- return src;
-}
-
-
-static void add_folder (MUTTMENU * m, struct browser_state *state,
- const char *name, const struct stat *s, int new)
-{
- if (state->entrylen == state->entrymax) {
- /* need to allocate more space */
- p_realloc(&state->entry, state->entrymax += 256);
- p_clear(&state->entry[state->entrylen], 256);
- if (m)
- m->data = state->entry;
- }
-
- if (s != NULL) {
- (state->entry)[state->entrylen].mode = s->st_mode;
- (state->entry)[state->entrylen].mtime = s->st_mtime;
- (state->entry)[state->entrylen].size = s->st_size;
- (state->entry)[state->entrylen].st = p_dup(s, 1);
- }
-
- (state->entry)[state->entrylen].new = new;
- (state->entry)[state->entrylen].name = m_strdup(name);
- (state->entry)[state->entrylen].desc = m_strdup(name);
- (state->entry)[state->entrylen].imap = 0;
- (state->entrylen)++;
-}
-
-static void init_state (struct browser_state *state, MUTTMENU * menu)
-{
- state->entrylen = 0;
- state->entrymax = 256;
- state->entry = p_new(struct folder_file, state->entrymax);
- state->imap_browse = 0;
- if (menu)
- menu->data = state->entry;
-}
-
-/* get list of all files/newsgroups with mask */
-static int examine_directory (MUTTMENU * menu, struct browser_state *state,
- char *d, const char *prefix)
-{
-
- struct stat s;
- DIR *dp;
- struct dirent *de;
- char buffer[_POSIX_PATH_MAX + STRING];
- int i = -1;
-
- while (stat (d, &s) == -1) {
- if (errno == ENOENT) {
- /* The last used directory is deleted, try to use the parent dir. */
- char *c = strrchr (d, '/');
-
- if (c && (c > d)) {
- *c = 0;
- continue;
- }
- }
- mutt_perror (d);
- return (-1);
- }
-
- if (!S_ISDIR (s.st_mode)) {
- mutt_error (_("%s is not a directory."), d);
- return (-1);
- }
-
- buffy_check (0);
-
- if ((dp = opendir (d)) == NULL) {
- mutt_perror (d);
- return (-1);
- }
-
- init_state (state, menu);
-
- while ((de = readdir (dp)) != NULL) {
- if (m_strcmp(de->d_name, ".") == 0)
- continue; /* we don't need . */
-
- if (m_strncmp(prefix, de->d_name, m_strlen(prefix)) != 0)
- continue;
- if (!((regexec (Mask.rx, de->d_name, 0, NULL, 0) == 0) ^ Mask.neg))
- continue;
-
- mutt_concat_path(buffer, sizeof(buffer), d, de->d_name);
- if (lstat (buffer, &s) == -1)
- continue;
-
- if ((!S_ISREG (s.st_mode)) && (!S_ISDIR (s.st_mode)) &&
- (!S_ISLNK (s.st_mode)))
- continue;
-
- i = buffy_lookup (buffer);
- add_folder (menu, state, de->d_name, &s, i >= 0 ? Incoming.arr[i]->new : 0);
- }
- closedir (dp);
- sidebar_draw ();
- browser_sort (state);
- return 0;
-}
-
-/* get list of mailboxes/subscribed newsgroups */
-static int examine_mailboxes (MUTTMENU * menu, struct browser_state *state)
-{
- struct stat s;
- char buffer[LONG_STRING];
- int i = 0;
- BUFFY* tmp;
-
- if (!Incoming.len)
- return (-1);
- buffy_check (0);
-
- init_state (state, menu);
-
- for (i = 0; i < Incoming.len; i++) {
- tmp = Incoming.arr[i];
- tmp->magic = mx_get_magic (tmp->path);
- if (tmp->magic == M_IMAP) {
- add_folder (menu, state, tmp->path, NULL, tmp->new);
- continue;
- }
- if (tmp->magic == M_POP) {
- add_folder (menu, state, tmp->path, NULL, tmp->new);
- continue;
- }
- if (lstat (tmp->path, &s) == -1)
- continue;
-
- if ((!S_ISREG (s.st_mode)) && (!S_ISDIR (s.st_mode)) &&
- (!S_ISLNK (s.st_mode)))
- continue;
-
- m_strcpy(buffer, sizeof(buffer), NONULL(tmp->path));
- mutt_pretty_mailbox (buffer);
- add_folder (menu, state, buffer, &s, tmp->new);
- }
-
- browser_sort (state);
- return 0;
-}
-
-static int select_file_search (MUTTMENU * menu, regex_t * re, int n)
-{
- return (regexec
- (re, ((struct folder_file *) menu->data)[n].name, 0, NULL, 0));
-}
-
-static void folder_entry (char *s, ssize_t slen, MUTTMENU * menu, int num)
-{
- FOLDER folder;
-
- folder.ff = &((struct folder_file *) menu->data)[num];
- folder.num = num;
-
- m_strformat(s, slen, getmaxx(main_w), FolderFormat, folder_format_str,
- &folder, 0);
-}
-
-static void init_menu (struct browser_state *state, MUTTMENU * menu,
- char *title, ssize_t titlelen, int buffy)
-{
- char path[_POSIX_PATH_MAX];
-
- menu->max = state->entrylen;
-
- if (menu->current >= menu->max)
- menu->current = menu->max - 1;
- if (menu->current < 0)
- menu->current = 0;
- if (menu->top > menu->current)
- menu->top = 0;
-
- menu->tagged = 0;
-
- if (buffy)
- snprintf(title, titlelen, _("Mailboxes [%d]"), buffy_check(0));
- else {
- m_strcpy(path, sizeof(path), LastDir);
- mutt_pretty_mailbox (path);
- if (state->imap_browse && option (OPTIMAPLSUB))
- snprintf (title, titlelen, _("Subscribed [%s], File mask: %s"),
- path, NONULL (Mask.pattern));
- else
- snprintf (title, titlelen, _("Directory [%s], File mask: %s"),
- path, NONULL (Mask.pattern));
- }
- menu->redraw = REDRAW_FULL;
-}
-
-static int file_tag (MUTTMENU * menu, int n, int m)
-{
- struct folder_file *ff = &(((struct folder_file *) menu->data)[n]);
- int ot;
-
- if (S_ISDIR (ff->mode)
- || (S_ISLNK (ff->mode) && link_is_dir (LastDir, ff->name))) {
- mutt_error _("Can't attach a directory!");
-
- return 0;
- }
-
- ot = ff->tagged;
- ff->tagged = (m >= 0 ? m : !ff->tagged);
-
- return ff->tagged - ot;
-}
-
-void mutt_select_file (char *f, ssize_t flen, int flags, char ***files,
- int *numfiles)
-{
- char buf[_POSIX_PATH_MAX];
- char prefix[_POSIX_PATH_MAX] = "";
- char title[STRING];
- struct browser_state state;
- MUTTMENU *menu;
- struct stat st;
- int i, killPrefix = 0;
- int multiple = (flags & M_SEL_MULTI) ? 1 : 0;
- int folder = (flags & M_SEL_FOLDER) ? 1 : 0;
- int buffy = (flags & M_SEL_BUFFY) ? 1 : 0;
-
- buffy = buffy && folder;
-
- p_clear(&state, 1);
-
- if (!folder)
- m_strcpy(LastDirBackup, sizeof(LastDirBackup), LastDir);
-
- if (*f) {
- mutt_expand_path (f, flen);
- if (imap_is_magic (f, NULL) == M_IMAP) {
- init_state (&state, NULL);
- state.imap_browse = 1;
- if (!imap_browse (f, &state))
- m_strcpy(LastDir, sizeof(LastDir), state.folder);
- }
- else {
- for (i = m_strlen(f) - 1; i > 0 && f[i] != '/'; i--);
- if (i > 0) {
- if (f[0] == '/') {
- i = MIN(ssizeof(LastDir) - 1, i);
- m_strcpy(LastDir, sizeof(LastDir), f);
- }
- else {
- getcwd(LastDir, sizeof(LastDir));
- m_strcat(LastDir, sizeof(LastDir), "/");
- m_strncat(LastDir, sizeof(LastDir), f, i);
- }
- }
- else {
- if (f[0] == '/')
- m_strcpy(LastDir, sizeof(LastDir), "/");
- else
- getcwd (LastDir, sizeof (LastDir));
- }
-
- if (i <= 0 && f[0] != '/')
- m_strcpy(prefix, sizeof(prefix), f);
- else
- m_strcpy(prefix, sizeof(prefix), f + i + 1);
- killPrefix = 1;
- }
- }
- else {
- if (!folder)
- getcwd (LastDir, sizeof (LastDir));
- else if (!LastDir[0])
- m_strcpy(LastDir, sizeof(LastDir), NONULL(Maildir));
-
- if (!buffy && imap_is_magic (LastDir, NULL) == M_IMAP) {
- init_state (&state, NULL);
- state.imap_browse = 1;
- imap_browse (LastDir, &state);
- browser_sort (&state);
- }
- }
-
- *f = 0;
-
- if (buffy) {
- if (examine_mailboxes (NULL, &state) == -1)
- goto bail;
- }
- else
- if (!state.imap_browse)
- if (examine_directory (NULL, &state, LastDir, prefix) == -1)
- goto bail;
-
- menu = mutt_new_menu ();
- menu->menu = MENU_FOLDER;
- menu->make_entry = folder_entry;
- menu->search = select_file_search;
- menu->title = title;
- menu->data = state.entry;
- if (multiple)
- menu->tag = file_tag;
- init_menu (&state, menu, title, sizeof (title), buffy);
-
- for (;;) {
- switch (i = mutt_menuLoop (menu)) {
- case OP_GENERIC_SELECT_ENTRY:
-
- if (!state.entrylen) {
- mutt_error _("No files match the file mask");
-
- break;
- }
-
- if (S_ISDIR (state.entry[menu->current].mode) ||
- (S_ISLNK (state.entry[menu->current].mode) &&
- link_is_dir (LastDir, state.entry[menu->current].name))
- || state.entry[menu->current].inferiors
- ) {
- /* make sure this isn't a MH or maildir mailbox */
- if (buffy) {
- m_strcpy(buf, sizeof(buf), state.entry[menu->current].name);
- mutt_expand_path (buf, sizeof (buf));
- }
- else if (state.imap_browse) {
- m_strcpy(buf, sizeof(buf), state.entry[menu->current].name);
- }
- else
- mutt_concat_path(buf, sizeof(buf), LastDir,
- state.entry[menu->current].name);
-
- if ((mx_get_magic (buf) <= 0)
- || state.entry[menu->current].inferiors)
- {
- char OldLastDir[_POSIX_PATH_MAX];
-
- /* save the old directory */
- m_strcpy(OldLastDir, sizeof(OldLastDir), LastDir);
-
- if (m_strcmp(state.entry[menu->current].name, "..") == 0) {
- if (m_strcmp("..", LastDir + m_strlen(LastDir) - 2) == 0)
- m_strcat(LastDir, sizeof(LastDir), "/..");
- else {
- char *p = strrchr (LastDir + 1, '/');
-
- if (p)
- *p = 0;
- else {
- if (LastDir[0] == '/')
- LastDir[1] = 0;
- else
- m_strcat(LastDir, sizeof(LastDir), "/..");
- }
- }
- }
- else if (buffy) {
- m_strcpy(LastDir, sizeof(LastDir),
- state.entry[menu->current].name);
- mutt_expand_path (LastDir, sizeof (LastDir));
- }
- else if (state.imap_browse) {
- int n;
- ciss_url_t url;
-
- m_strcpy(LastDir, sizeof(LastDir),
- state.entry[menu->current].name);
- /* tack on delimiter here */
- n = m_strlen(LastDir) + 1;
-
- /* special case "" needs no delimiter */
- url_parse_ciss (&url, state.entry[menu->current].name);
- if (url.path &&
- (state.entry[menu->current].delim != '\0') &&
- (n < ssizeof (LastDir))) {
- LastDir[n] = '\0';
- LastDir[n - 1] = state.entry[menu->current].delim;
- }
- }
- else {
- char tmp[_POSIX_PATH_MAX];
-
- mutt_concat_path(tmp, sizeof(tmp), LastDir,
- state.entry[menu->current].name);
- m_strcpy(LastDir, sizeof(LastDir), tmp);
- }
-
- destroy_state (&state);
- if (killPrefix) {
- prefix[0] = 0;
- killPrefix = 0;
- }
- buffy = 0;
- if (state.imap_browse) {
- init_state (&state, NULL);
- state.imap_browse = 1;
- imap_browse (LastDir, &state);
- browser_sort (&state);
- menu->data = state.entry;
- }
- else
- if (examine_directory (menu, &state, LastDir, prefix) == -1) {
- /* try to restore the old values */
- m_strcpy(LastDir, sizeof(LastDir), OldLastDir);
- if (examine_directory (menu, &state, LastDir, prefix) == -1) {
- m_strcpy(LastDir, sizeof(LastDir), NONULL(mod_core.homedir));
- goto bail;
- }
- }
- menu->current = 0;
- menu->top = 0;
- init_menu (&state, menu, title, sizeof (title), buffy);
- break;
- }
- }
-
- if (buffy) {
- m_strcpy(f, flen, state.entry[menu->current].name);
- mutt_expand_path (f, flen);
- }
- else if (state.imap_browse)
- m_strcpy(f, flen, state.entry[menu->current].name);
- else
- mutt_concat_path(f, flen, LastDir, state.entry[menu->current].name);
-
- /* Fall through to OP_EXIT */
-
- case OP_EXIT:
-
- if (multiple) {
- char **tfiles;
- int j;
- int h;
-
- if (menu->tagged) {
- *numfiles = menu->tagged;
- tfiles = p_new(char *, *numfiles);
- for (h = 0, j = 0; h < state.entrylen; i++) {
- struct folder_file ff = state.entry[i];
- char full[_POSIX_PATH_MAX];
-
- if (ff.tagged) {
- mutt_concat_path(full, sizeof(full), LastDir, ff.name);
- mutt_expand_path (full, sizeof (full));
- tfiles[j++] = m_strdup(full);
- }
- }
- *files = tfiles;
- }
- else if (f[0]) { /* no tagged entries. return selected entry */
- *numfiles = 1;
- tfiles = p_new(char *, *numfiles);
- mutt_expand_path (f, flen);
- tfiles[0] = m_strdup(f);
- *files = tfiles;
- }
- }
-
- destroy_state (&state);
- mutt_menuDestroy (&menu);
- goto bail;
-
- case OP_BROWSER_TELL:
- if (state.entrylen)
- mutt_message ("%s", state.entry[menu->current].name);
- break;
-
- case OP_BROWSER_TOGGLE_LSUB:
- if (option (OPTIMAPLSUB)) {
- unset_option (OPTIMAPLSUB);
- }
- else {
- set_option (OPTIMAPLSUB);
- }
- mutt_ungetch (0, OP_CHECK_NEW);
- break;
-
- case OP_CREATE_MAILBOX:
- if (!state.imap_browse)
- mutt_error (_("Create is only supported for IMAP mailboxes"));
- else {
- imap_mailbox_create (LastDir);
- /* TODO: find a way to detect if the new folder would appear in
- * this window, and insert it without starting over. */
- destroy_state (&state);
- init_state (&state, NULL);
- state.imap_browse = 1;
- imap_browse (LastDir, &state);
- browser_sort (&state);
- menu->data = state.entry;
- menu->current = 0;
- menu->top = 0;
- init_menu (&state, menu, title, sizeof (title), buffy);
- MAYBE_REDRAW (menu->redraw);
- }
- break;
-
- case OP_RENAME_MAILBOX:
- if (!state.entry[menu->current].imap)
- mutt_error (_("Rename is only supported for IMAP mailboxes"));
- else {
- int nentry = menu->current;
-
- if (imap_mailbox_rename (state.entry[nentry].name) >= 0) {
- destroy_state (&state);
- init_state (&state, NULL);
- state.imap_browse = 1;
- imap_browse (LastDir, &state);
- browser_sort (&state);
- menu->data = state.entry;
- menu->current = 0;
- menu->top = 0;
- init_menu (&state, menu, title, sizeof (title), buffy);
- MAYBE_REDRAW (menu->redraw);
- }
- }
- break;
-
- case OP_DELETE_MAILBOX:
- if (!state.entry[menu->current].imap)
- mutt_error (_("Delete is only supported for IMAP mailboxes"));
- else {
- char msg[STRING];
- IMAP_MBOX mx;
- int nentry = menu->current;
-
- imap_parse_path (state.entry[nentry].name, &mx);
- snprintf (msg, sizeof (msg), _("Really delete mailbox \"%s\"?"),
- mx.mbox);
- if (mutt_yesorno (msg, M_NO) == M_YES) {
- if (!imap_delete_mailbox (Context, mx)) {
- /* free the mailbox from the browser */
- p_delete(&((state.entry)[nentry].name));
- p_delete(&((state.entry)[nentry].desc));
- /* and move all other entries up */
- if (nentry + 1 < state.entrylen)
- memmove (state.entry + nentry, state.entry + nentry + 1,
- sizeof (struct folder_file) * (state.entrylen -
- (nentry + 1)));
- state.entrylen--;
- mutt_message _("Mailbox deleted.");
-
- init_menu (&state, menu, title, sizeof (title), buffy);
- MAYBE_REDRAW (menu->redraw);
- }
- }
- else
- mutt_message _("Mailbox not deleted.");
- p_delete(&mx.mbox);
- }
- break;
-
- case OP_CHANGE_DIRECTORY:
- m_strcpy(buf, sizeof(buf), LastDir);
- if (!state.imap_browse)
- {
- /* add '/' at the end of the directory name if not already there */
- ssize_t len = m_strlen(LastDir);
-
- if (len && LastDir[len - 1] != '/' && ssizeof(buf) > len)
- buf[len] = '/';
- }
-
- if (mutt_get_field (_("Chdir to: "), buf, sizeof (buf), M_FILE) == 0 &&
- buf[0]) {
- buffy = 0;
- mutt_expand_path (buf, sizeof (buf));
- if (imap_is_magic (buf, NULL) == M_IMAP) {
- m_strcpy(LastDir, sizeof(LastDir), buf);
- destroy_state (&state);
- init_state (&state, NULL);
- state.imap_browse = 1;
- imap_browse (LastDir, &state);
- browser_sort (&state);
- menu->data = state.entry;
- menu->current = 0;
- menu->top = 0;
- init_menu (&state, menu, title, sizeof (title), buffy);
- }
- else
- if (stat (buf, &st) == 0) {
- if (S_ISDIR (st.st_mode)) {
- destroy_state (&state);
- if (examine_directory (menu, &state, buf, prefix) == 0)
- m_strcpy(LastDir, sizeof(LastDir), buf);
- else {
- mutt_error _("Error scanning directory.");
-
- if (examine_directory (menu, &state, LastDir, prefix) == -1) {
- mutt_menuDestroy (&menu);
- goto bail;
- }
- }
- menu->current = 0;
- menu->top = 0;
- init_menu (&state, menu, title, sizeof (title), buffy);
- }
- else
- mutt_error (_("%s is not a directory."), buf);
- }
- else
- mutt_perror (buf);
- }
- MAYBE_REDRAW (menu->redraw);
- break;
-
- case OP_ENTER_MASK:
-
- m_strcpy(buf, sizeof(buf), NONULL(Mask.pattern));
- if (mutt_get_field (_("File Mask: "), buf, sizeof (buf), 0) == 0) {
- regex_t *rx = p_new(regex_t, 1);
- char *s = buf;
- int neg = 0, err;
-
- buffy = 0;
- /* assume that the user wants to see everything */
- if (!buf[0])
- m_strcpy(buf, sizeof(buf), ".");
- s = vskipspaces(s);
- if (*s == '!') {
- s = vskipspaces(s + 1);
- neg = 1;
- }
-
- if ((err = REGCOMP (rx, s, REG_NOSUB)) != 0) {
- regerror (err, rx, buf, sizeof (buf));
- regfree (rx);
- p_delete(&rx);
- mutt_error ("%s", buf);
- }
- else {
- m_strreplace(&Mask.pattern, buf);
- regfree (Mask.rx);
- p_delete(&Mask.rx);
- Mask.rx = rx;
- Mask.neg = neg;
-
- destroy_state (&state);
- if (state.imap_browse) {
- init_state (&state, NULL);
- state.imap_browse = 1;
- imap_browse (LastDir, &state);
- browser_sort (&state);
- menu->data = state.entry;
- init_menu (&state, menu, title, sizeof (title), buffy);
- }
- else
- if (examine_directory (menu, &state, LastDir, NULL) == 0)
- init_menu (&state, menu, title, sizeof (title), buffy);
- else {
- mutt_error _("Error scanning directory.");
-
- mutt_menuDestroy (&menu);
- goto bail;
- }
- killPrefix = 0;
- if (!state.entrylen) {
- mutt_error _("No files match the file mask");
-
- break;
- }
- }
- }
- MAYBE_REDRAW (menu->redraw);
- break;
-
- case OP_SORT:
- case OP_SORT_REVERSE:
-
- {
- int resort = 1;
- int reverse = (i == OP_SORT_REVERSE);
-
- switch (mutt_multi_choice ((reverse) ?
- _
- ("Reverse sort by (d)ate, (a)lpha, si(z)e or do(n)'t sort? ")
- :
- _
- ("Sort by (d)ate, (a)lpha, si(z)e or do(n)'t sort? "),
- _("dazn"))) {
- case -1: /* abort */
- resort = 0;
- break;
-
- case 1: /* (d)ate */
- BrowserSort = SORT_DATE;
- break;
-
- case 2: /* (a)lpha */
- BrowserSort = SORT_SUBJECT;
- break;
-
- case 3: /* si(z)e */
- BrowserSort = SORT_SIZE;
- break;
-
- case 4: /* do(n)'t sort */
- BrowserSort = SORT_ORDER;
- resort = 0;
- break;
- }
- if (resort) {
- BrowserSort |= reverse ? SORT_REVERSE : 0;
- browser_sort (&state);
- menu->redraw = REDRAW_FULL;
- }
- break;
- }
-
- case OP_TOGGLE_MAILBOXES:
- buffy = 1 - buffy;
-
- case OP_CHECK_NEW:
- destroy_state (&state);
- prefix[0] = 0;
- killPrefix = 0;
-
- if (buffy) {
- if (examine_mailboxes (menu, &state) == -1)
- goto bail;
- }
- else if (imap_is_magic (LastDir, NULL) == M_IMAP) {
- init_state (&state, NULL);
- state.imap_browse = 1;
- imap_browse (LastDir, &state);
- browser_sort (&state);
- menu->data = state.entry;
- }
- else if (examine_directory (menu, &state, LastDir, prefix) == -1)
- goto bail;
- init_menu (&state, menu, title, sizeof (title), buffy);
- break;
-
- case OP_BUFFY_LIST:
- if (option (OPTFORCEBUFFYCHECK))
- buffy_check (1);
- buffy_list ();
- break;
-
- case OP_BROWSER_NEW_FILE:
-
- snprintf (buf, sizeof (buf), "%s/", LastDir);
- if (mutt_get_field (_("New file name: "), buf, sizeof (buf), M_FILE) ==
- 0) {
- m_strcpy(f, flen, buf);
- destroy_state (&state);
- mutt_menuDestroy (&menu);
- goto bail;
- }
- MAYBE_REDRAW (menu->redraw);
- break;
-
- case OP_BROWSER_VIEW_FILE:
- if (!state.entrylen) {
- mutt_error _("No files match the file mask");
-
- break;
- }
-
- if (state.entry[menu->current].selectable) {
- m_strcpy(f, flen, state.entry[menu->current].name);
- destroy_state (&state);
- mutt_menuDestroy (&menu);
- goto bail;
- }
- else
- if (S_ISDIR (state.entry[menu->current].mode) ||
- (S_ISLNK (state.entry[menu->current].mode) &&
- link_is_dir (LastDir, state.entry[menu->current].name))) {
- mutt_error _("Can't view a directory");
-
- break;
- }
- else {
- BODY *b;
- char nbuf[_POSIX_PATH_MAX];
-
- mutt_concat_path(nbuf, sizeof(nbuf), LastDir,
- state.entry[menu->current].name);
- b = mutt_make_file_attach (nbuf);
- if (b != NULL) {
- mutt_view_attachment (NULL, b, M_REGULAR, NULL, NULL, 0);
- body_list_wipe(&b);
- menu->redraw = REDRAW_FULL;
- }
- else
- mutt_error _("Error trying to view file");
- }
- break;
-
- case OP_BROWSER_SUBSCRIBE:
- case OP_BROWSER_UNSUBSCRIBE:
- if (i == OP_BROWSER_SUBSCRIBE)
- imap_subscribe (state.entry[menu->current].name, 1);
- else
- imap_subscribe (state.entry[menu->current].name, 0);
- }
- }
-
-bail:
-
- if (!folder)
- m_strcpy(LastDir, sizeof(LastDir), LastDirBackup);
-
-}