+void imap_scan_tree(Folder *folder)
+{
+ IMAPFolder *imapfolder = IMAP_FOLDER(folder);
+ FolderItem *item, *inbox;
+ IMAPSession *session;
+ IMAPNameSpace *namespace = NULL;
+ gchar *imap_dir = "";
+ gchar *root_folder = NULL;
+
+ g_return_if_fail(folder != NULL);
+ g_return_if_fail(folder->account != NULL);
+
+ session = imap_session_get(folder);
+ if (!session) return;
+
+ if (imapfolder->namespace && imapfolder->namespace->data)
+ namespace = (IMAPNameSpace *)imapfolder->namespace->data;
+
+ if (folder->account->imap_dir && *folder->account->imap_dir) {
+ gchar *tmpdir;
+ Xstrdup_a(tmpdir, folder->account->imap_dir, return);
+ strtailchomp(tmpdir, '/');
+ Xalloca(imap_dir, strlen(tmpdir) + 2, return);
+ root_folder = g_strconcat
+ (namespace && namespace->name ? namespace->name : "",
+ imap_dir, NULL);
+ if (namespace && namespace->separator)
+ subst_char(root_folder, namespace->separator, '/');
+ }
+
+ folder_tree_destroy(folder);
+ item = folder_item_new(folder->name, root_folder);
+ item->folder = folder;
+ folder->node = g_node_new(item);
+ g_free(root_folder);
+
+ inbox = folder_item_new("INBOX", "INBOX");
+ inbox->stype = F_INBOX;
+ folder_item_append(item, inbox);
+ folder->inbox = inbox;
+
+ imap_scan_tree_recursive(session, item, namespace);
+}
+
+static void imap_scan_tree_recursive(IMAPSession *session,
+ FolderItem *item,
+ IMAPNameSpace *namespace)
+{
+ IMAPFolder *imapfolder;
+ FolderItem *new_item;
+ GSList *item_list, *cur;
+ gchar *real_path;
+
+ g_return_if_fail(item != NULL);
+ g_return_if_fail(item->folder != NULL);
+ g_return_if_fail(item->no_sub == FALSE);
+
+ imapfolder = IMAP_FOLDER(item->folder);
+
+ if (item->folder->ui_func)
+ item->folder->ui_func(item->folder, item,
+ item->folder->ui_func_data);
+
+ if (item->path) {
+ real_path = imap_get_real_path(imapfolder, item->path);
+ imap_cmd_gen_send(SESSION(session)->sock, "LIST \"\" %s%c%%",
+ real_path,
+ namespace && namespace->separator
+ ? namespace->separator : '/');
+ } else {
+ real_path = g_strdup(namespace && namespace->name
+ ? namespace->name : "");
+ imap_cmd_gen_send(SESSION(session)->sock, "LIST \"\" %s%%",
+ real_path);
+ }
+
+ strtailchomp(real_path, namespace && namespace->separator
+ ? namespace->separator : '/');
+
+ item_list = imap_parse_list(session, real_path);
+ for (cur = item_list; cur != NULL; cur = cur->next) {
+ new_item = cur->data;
+ folder_item_append(item, new_item);
+ if (new_item->no_sub == FALSE)
+ imap_scan_tree_recursive(session, new_item, namespace);
+ }
+}
+
+static GSList *imap_parse_list(IMAPSession *session, const gchar *path)
+{
+ gchar buf[IMAPBUFSIZE];
+ gchar flags[256];
+ gchar separator[16];
+ gchar *p;
+ gchar *name;
+ GSList *item_list = NULL;
+ GString *str;
+ FolderItem *new_item;
+
+ debug_print("getting list of %s ...\n", *path ? path : "\"\"");
+
+ str = g_string_new(NULL);
+
+ for (;;) {
+ if (sock_gets(SESSION(session)->sock, buf, sizeof(buf)) <= 0) {
+ log_warning(_("error occured while getting LIST.\n"));
+ break;
+ }
+ strretchomp(buf);
+ if (buf[0] != '*' || buf[1] != ' ') {
+ log_print("IMAP4< %s\n", buf);
+ break;
+ }
+ debug_print("IMAP4< %s\n", buf);
+
+ g_string_assign(str, buf);
+ p = str->str + 2;
+ if (strncmp(p, "LIST ", 5) != 0) continue;
+ p += 5;
+
+ if (*p != '(') continue;
+ p++;
+ p = strchr_cpy(p, ')', flags, sizeof(flags));
+ if (!p) continue;
+ while (*p == ' ') p++;
+
+ p = strchr_cpy(p, ' ', separator, sizeof(separator));
+ if (!p) continue;
+ extract_quote(separator, '"');
+ if (!strcmp(separator, "NIL"))
+ separator[0] = '\0';
+
+ buf[0] = '\0';
+ while (*p == ' ') p++;
+ if (*p == '{' || *p == '"')
+ p = imap_parse_atom(SESSION(session)->sock, p,
+ buf, sizeof(buf), str);
+ else
+ strncpy2(buf, p, sizeof(buf));
+ strtailchomp(buf, separator[0]);
+ if (buf[0] == '\0') continue;
+ if (!strcmp(buf, path)) continue;
+ if (!strcmp(buf, "INBOX")) continue;
+
+ if (separator[0] != '\0')
+ subst_char(buf, separator[0], '/');
+ name = g_basename(buf);
+ if (name[0] == '.') continue;
+
+ new_item = folder_item_new(name, buf);
+ if (strcasestr(flags, "\\Noinferiors") != NULL)
+ new_item->no_sub = TRUE;
+ if (strcasestr(flags, "\\Noselect") != NULL)
+ new_item->no_select = TRUE;
+
+ item_list = g_slist_append(item_list, new_item);
+
+ debug_print("folder %s has been added.\n", buf);
+ }
+
+ g_string_free(str, TRUE);
+ statusbar_pop_all();
+
+ return item_list;
+}
+