Changeset 5064:1e2d32e1a644 for imap
- Timestamp:
- 2007-04-05 09:26:09 (20 months ago)
- Branch:
- HEAD
- Location:
- imap
- Files:
-
- 2 modified
-
browse.c (modified) (9 diffs)
-
imap_private.h (modified) (1 diff)
Legend:
- Unmodified
- Added
- Removed
-
imap/browse.c
r5052 r5064 1 1 /* 2 2 * Copyright (C) 1996-9 Brandon Long <blong@fiction.net> 3 * Copyright (C) 1999-200 6Brendan Cully <brendan@kublai.com>3 * Copyright (C) 1999-2007 Brendan Cully <brendan@kublai.com> 4 4 * 5 5 * This program is free software; you can redistribute it and/or modify … … 36 36 int noinferiors, struct browser_state *state, short isparent); 37 37 static int compare_names(struct folder_file *a, struct folder_file *b); 38 static int browse_get_namespace (IMAP_DATA *idata, char *nsbuf, int nsblen,39 IMAP_NAMESPACE_INFO *nsi, int nsilen, int *nns);40 static int browse_verify_namespace (IMAP_DATA* idata,41 IMAP_NAMESPACE_INFO* nsi, int nns);42 38 43 39 /* imap_browse: IMAP hook into the folder browser, fills out browser_state, … … 49 45 char buf[LONG_STRING]; 50 46 char buf2[LONG_STRING]; 51 char nsbuf[LONG_STRING];52 47 char mbox[LONG_STRING]; 53 48 char list_cmd[5]; 54 IMAP_NAMESPACE_INFO nsi[16];55 int home_namespace = 0;56 49 int n; 57 int i;58 50 int nsup; 59 51 char ctmp; 60 int nns = 0;61 52 short showparents = 0; 62 53 int save_lsub; … … 75 66 if (!(idata = imap_conn_find (&(mx.account), 0))) 76 67 goto fail; 77 78 if (!mx.mbox)79 {80 home_namespace = 1;81 mbox[0] = '\0'; /* Do not replace "" with "INBOX" here */82 mx.mbox = safe_strdup(ImapHomeNamespace);83 if (mutt_bit_isset(idata->capabilities,NAMESPACE))84 {85 mutt_message _("Getting namespaces...");86 if (browse_get_namespace (idata, nsbuf, sizeof (nsbuf),87 nsi, sizeof (nsi), &nns) != 0)88 goto fail;89 if (browse_verify_namespace (idata, nsi, nns) != 0)90 goto fail;91 }92 }93 68 94 69 mutt_message _("Getting folder list..."); … … 137 112 if (mbox[n-1] == list.delim) 138 113 { 139 /* don't show parents in the home namespace */ 140 if (!home_namespace) 141 showparents = 1; 114 showparents = 1; 142 115 imap_qualify_path (buf, sizeof (buf), &mx, mbox); 143 116 state->folder = safe_strdup (buf); … … 192 165 } 193 166 } 167 else 168 mbox[0] = '\0'; 194 169 195 170 /* no namespace, no folder: set folder to host only */ … … 198 173 imap_qualify_path (buf, sizeof (buf), &mx, NULL); 199 174 state->folder = safe_strdup (buf); 200 }201 202 if (home_namespace && mbox[0] != '\0')203 {204 /* Listing the home namespace, so INBOX should be included. Home205 * namespace is not "", so we have to list it explicitly. We ask the206 * server to see if it has descendants. */207 dprint (3, (debugfile, "imap_browse: adding INBOX\n"));208 if (browse_add_list_result (idata, "LIST \"\" \"INBOX\"", state, 0))209 goto fail;210 175 } 211 176 … … 230 195 qsort(&(state->entry[nsup]),state->entrylen-nsup,sizeof(state->entry[0]), 231 196 (int (*)(const void*,const void*)) compare_names); 232 if (home_namespace)233 { /* List additional namespaces */234 for (i = 0; i < nns; i++)235 if (nsi[i].listable && !nsi[i].home_namespace) {236 imap_add_folder(nsi[i].delim, nsi[i].prefix, nsi[i].noselect,237 nsi[i].noinferiors, state, 0);238 dprint (3, (debugfile, "imap_browse: adding namespace: %s\n",239 nsi[i].prefix));240 }241 }242 197 243 198 if (save_lsub) … … 495 450 return mutt_strcmp(a->name, b->name); 496 451 } 497 498 static int browse_get_namespace (IMAP_DATA* idata, char* nsbuf, int nsblen,499 IMAP_NAMESPACE_INFO* nsi, int nsilen, int* nns)500 {501 char *s;502 int n;503 char ns[LONG_STRING];504 char delim = '/';505 int type;506 int nsbused = 0;507 int rc;508 509 *nns = 0;510 nsbuf[nsblen-1] = '\0';511 512 imap_cmd_start (idata, "NAMESPACE");513 514 do515 {516 if ((rc = imap_cmd_step (idata)) != IMAP_CMD_CONTINUE)517 break;518 519 s = imap_next_word (idata->buf);520 if (ascii_strncasecmp ("NAMESPACE", s, 9) == 0)521 {522 /* There are three sections to the response, User, Other, Shared,523 * and maybe more by extension */524 for (type = IMAP_NS_PERSONAL; *s; type++)525 {526 s = imap_next_word (s);527 if (*s && ascii_strncasecmp (s, "NIL", 3))528 {529 s++;530 while (*s && *s != ')')531 {532 s++; /* skip ( */533 /* copy namespace */534 n = 0;535 delim = '\0';536 537 if (*s == '\"')538 {539 s++;540 while (*s && *s != '\"' && n < sizeof (ns) - 1)541 {542 if (*s == '\\')543 s++;544 ns[n++] = *s;545 s++;546 }547 if (*s)548 s++;549 }550 else551 while (*s && !ISSPACE (*s) && n < sizeof (ns) - 1)552 {553 ns[n++] = *s;554 s++;555 }556 ns[n] = '\0';557 if (n == sizeof (ns) - 1)558 dprint (1, (debugfile, "browse_get_namespace: too long: [%s]\n", ns));559 /* delim? */560 s = imap_next_word (s);561 /* delimiter is meaningless if namespace is "". Why does562 * Cyrus provide one?! */563 if (n && *s && *s == '\"')564 {565 if (s[1] && s[2] == '\"')566 delim = s[1];567 else if (s[1] && s[1] == '\\' && s[2] && s[3] == '\"')568 delim = s[2];569 }570 /* skip "" namespaces, they are already listed at the root */571 if ((ns[0] != '\0') && (nsbused < nsblen) && (*nns < nsilen))572 {573 dprint (3, (debugfile, "browse_get_namespace: adding %s\n", ns));574 nsi->type = type;575 /* Cyrus doesn't append the delimiter to the namespace,576 * but UW-IMAP does. We'll strip it here and add it back577 * as if it were a normal directory, from the browser */578 if (n && (ns[n-1] == delim))579 ns[--n] = '\0';580 strncpy (nsbuf+nsbused,ns,nsblen-nsbused-1);581 nsi->prefix = nsbuf+nsbused;582 nsbused += n+1;583 nsi->delim = delim;584 nsi++;585 (*nns)++;586 }587 while (*s && *s != ')')588 s++;589 if (*s)590 s++;591 }592 }593 }594 }595 }596 while (rc == IMAP_CMD_CONTINUE);597 598 if (rc != IMAP_CMD_OK)599 return -1;600 601 return 0;602 }603 604 /* Check which namespaces have contents */605 static int browse_verify_namespace (IMAP_DATA* idata,606 IMAP_NAMESPACE_INFO *nsi, int nns)607 {608 char buf[LONG_STRING];609 IMAP_LIST list;610 int i = 0;611 int rc;612 613 for (i = 0; i < nns; i++, nsi++)614 {615 /* Cyrus gives back nothing if the % isn't added. This may return lots616 * of data in some cases, I guess, but I currently feel that's better617 * than invisible namespaces */618 if (nsi->delim)619 snprintf (buf, sizeof (buf), "%s \"\" \"%s%c%%\"",620 option (OPTIMAPLSUB) ? "LSUB" : "LIST", nsi->prefix,621 nsi->delim);622 else623 snprintf (buf, sizeof (buf), "%s \"\" \"%s%%\"",624 option (OPTIMAPLSUB) ? "LSUB" : "LIST", nsi->prefix);625 626 imap_cmd_start (idata, buf);627 idata->cmdtype = IMAP_CT_LIST;628 idata->cmddata = &list;629 nsi->listable = 0;630 nsi->home_namespace = 0;631 do632 {633 rc = imap_cmd_step (idata);634 if (rc == IMAP_CMD_CONTINUE && list.name)635 nsi->listable |= (list.name[0] != '\0');636 }637 while (rc == IMAP_CMD_CONTINUE);638 idata->cmddata = NULL;639 640 if (rc != IMAP_CMD_OK)641 return -1;642 }643 644 return 0;645 }646 -
imap/imap_private.h
r5046 r5064 124 124 char* path; 125 125 } IMAP_CACHE; 126 127 typedef struct128 {129 int type;130 int listable;131 char *prefix;132 char delim;133 int home_namespace;134 /* We get these when we check if namespace exists - cache them */135 int noselect;136 int noinferiors;137 } IMAP_NAMESPACE_INFO;138 126 139 127 typedef struct
