4 * Utility functions for the IMAP module.
14 #include "sysdep_decls.h"
17 #include "internet_addressing.h"
18 #include "imap_tools.h"
22 * Output a string to the IMAP client, either as a literal or quoted.
23 * (We do a literal if it has any double-quotes or backslashes.)
25 void imap_strout(char *buf) {
29 if (buf == NULL) { /* yeah, we handle this */
34 for (i=0; i<strlen(buf); ++i) {
35 if ( (buf[i]=='\"') || (buf[i]=='\\') ) is_literal = 1;
39 cprintf("{%d}\r\n%s", strlen(buf), buf);
43 cprintf("\"%s\"", buf);
52 * Break a command down into tokens, taking into consideration the
53 * possibility of escaping spaces using quoted tokens
55 int imap_parameterize(char **args, char *buf) {
64 original_len = strlen(buf);
66 for (i=0; i<original_len; ++i) {
68 if ( (isspace(buf[i])) && (!in_quote) ) {
70 args[num] = &buf[start];
72 if (args[num][0] == '\"') {
74 args[num][strlen(args[num])-1] = 0;
79 else if ( (buf[i] == '\"') && (!in_quote) ) {
83 else if ( (buf[i] == '\"') && (in_quote) ) {
93 * Convert a struct quickroom to an IMAP-compatible mailbox name.
95 void imap_mailboxname(char *buf, int bufsize, struct quickroom *qrbuf) {
99 * For mailboxes, just do it straight...
101 if (qrbuf->QRflags & QR_MAILBOX) {
102 safestrncpy(buf, qrbuf->QRname, bufsize);
103 strcpy(buf, &buf[11]);
104 if (!strcasecmp(buf, MAILROOM)) strcpy(buf, "INBOX");
108 * Otherwise, prefix the floor name as a "public folders" moniker
111 fl = cgetfloor(qrbuf->QRfloor);
112 lprintf(9, "Floor %d: \n", qrbuf->QRfloor);
113 lprintf(9, " %s\n", fl->f_name); /* FIXME take out */
114 snprintf(buf, bufsize, "%s|%s",
122 * Convert an inputted folder name to our best guess as to what an equivalent
123 * room name should be.
125 * If an error occurs, it returns -1. Otherwise...
127 * The lower eight bits of the return value are the floor number on which the
128 * room most likely resides. The upper eight bits may contain flags,
129 * including IR_MAILBOX if we're dealing with a personal room.
132 int imap_roomname(char *rbuf, int bufsize, char *foldername) {
138 if (foldername == NULL) return(-1);
139 levels = num_parms(foldername);
141 /* When we can support hierarchial mailboxes, take this out. */
142 if (levels > 2) return(-1);
145 * Convert the crispy idiot's reserved names to our reserved names.
147 if (!strcasecmp(foldername, "INBOX")) {
148 safestrncpy(rbuf, MAILROOM, bufsize);
149 return(0 | IR_MAILBOX);
153 extract(buf, foldername, 0);
154 for (i=0; i<MAXFLOORS; ++i) {
156 lprintf(9, "floor %d: %s\n", i, fl->f_name); /* FIXME take out */
157 if (fl->f_flags & F_INUSE) {
158 if (!strcasecmp(buf, fl->f_name)) {
159 extract(rbuf, foldername, 1);
165 /* since we don't allow multi-level yet, fail.
166 extract(rbuf, buf, 1);
172 safestrncpy(rbuf, foldername, bufsize);
173 return(0 | IR_MAILBOX);
181 * Output a struct internet_address_list in the form an IMAP client wants
183 void imap_ial_out(struct internet_address_list *ialist) {
184 struct internet_address_list *iptr;
186 if (ialist == NULL) {
193 for (iptr = ialist; iptr != NULL; iptr = iptr->next) {
195 imap_strout(iptr->ial_name);
197 imap_strout(iptr->ial_user);
199 imap_strout(iptr->ial_node);
209 * Determine whether the supplied string is a valid message set.
210 * If the string contains only numbers, colons, commas, and asterisks,
211 * return 1 for a valid message set. If any other character is found,
214 int imap_is_message_set(char *buf) {
217 if (buf == NULL) return(0); /* stupidity checks */
218 if (strlen(buf) == 0) return(0);
220 if (!strcasecmp(buf, "ALL")) return(1); /* macro? why? */
222 for (i=0; i<strlen(buf); ++i) { /* now start the scan */
231 return(1); /* looks like we're good */