/***********************************************************************
* *
* This software is part of the BSD package *
*Copyright (c) 1978-2012 The Regents of the University of California an*
* *
* Redistribution and use in source and binary forms, with or *
* without modification, are permitted provided that the following *
* conditions are met: *
* *
* 1. Redistributions of source code must retain the above *
* copyright notice, this list of conditions and the *
* following disclaimer. *
* *
* 2. Redistributions in binary form must reproduce the above *
* copyright notice, this list of conditions and the *
* materials provided with the distribution. *
* *
* 3. Neither the name of The Regents of the University of California*
* names of its contributors may be used to endorse or *
* promote products derived from this software without *
* specific prior written permission. *
* *
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND *
* CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, *
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF *
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE *
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS *
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, *
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED *
* TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, *
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON *
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, *
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY *
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE *
* POSSIBILITY OF SUCH DAMAGE. *
* *
* Redistribution and use in source and binary forms, with or without *
* modification, are permitted provided that the following conditions *
* are met: *
* 1. Redistributions of source code must retain the above copyright *
* notice, this list of conditions and the following disclaimer. *
* 2. Redistributions in binary form must reproduce the above copyright *
* notice, this list of conditions and the following disclaimer in *
* distribution. *
* 3. Neither the name of the University nor the names of its *
* contributors may be used to endorse or promote products derived *
* from this software without specific prior written permission. *
* *
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS" *
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED *
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A *
* PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS *
* OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, *
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT *
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF *
* USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND *
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, *
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT *
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF *
* SUCH DAMAGE. *
* *
* Kurt Shoens (UCB) *
* gsf *
* *
***********************************************************************/
#pragma prototyped
/*
* IMAP4rev1 client
*
* Glenn Fowler
* AT&T Research
*/
#include "mailx.h"
#if _PACKAGE_ast
#include <css.h>
#include <tm.h>
#include <vmalloc.h>
typedef struct { /* IMAP_data item */
char* buffer;
} Imapdata_t;
typedef struct { /* IMAP_list item */
} Imaplist_t;
typedef union { /* list item value */
long number;
char* name;
char* string;
} Imapvalue_t;
int type;
};
typedef struct { /* flag table element */
} Imapflag_t;
typedef struct { /* lex table element */
} Imaplex_t;
typedef struct { /* IMAP Msg_t.m_info info */
} Imapmsg_t;
};
typedef struct { /* imap_BODYSTRUCTURE discipline*/
} Imapbody_t;
};
typedef struct { /* response info */
} Imapop_t;
typedef struct
{
struct
{
struct
{
} Imap_t;
/*
* imap dump <item> table
*/
{
"fl[ags]", IMAP_DUMP_FLAGS,
"f[older]", IMAP_DUMP_FOLDER,
"m[essage]", IMAP_DUMP_MESSAGE,
"q[ueue]", IMAP_DUMP_QUEUE,
"s[tate]", IMAP_DUMP_STATE,
};
/*
* operation states
*/
{
"free", IMAP_STATE_free,
"sent", IMAP_STATE_sent,
"more", IMAP_STATE_more,
"done", IMAP_STATE_done,
};
/*
* part content types
*/
{
"attachment", IMAP_CONTENT_attachment,
"data", IMAP_CONTENT_data,
"header", IMAP_CONTENT_header,
"message", IMAP_CONTENT_message,
"multipart", IMAP_CONTENT_multipart,
"text", IMAP_CONTENT_text,
};
/*
* message flags
*/
{
"DELETE", MDELETE,
"INIT", MINIT,
"MARK", MMARK,
"MBOX", MBOX,
"MODIFY", MODIFY,
"NEW", MNEW,
"NONE", MNONE,
"PRESERVE", MPRESERVE,
"READ", MREAD,
"SAVE", MSAVE,
"SCAN", MSCAN,
"SPAM", MSPAM,
"STATUS", MSTATUS,
"TOUCH", MTOUCH,
"USED", MUSED,
"ZOMBIE", MZOMBIE,
};
/*
* the rest define the parts of the protocol used by this implementation
*/
{
"+", IMAP_MORE,
"BAD", IMAP_BAD,
"BYE", IMAP_BYE,
"CAPABILITY", IMAP_CAPABILITY,
"COPY", IMAP_COPY,
"EXISTS", IMAP_EXISTS,
"EXPUNGE", IMAP_EXPUNGE,
"FETCH", IMAP_FETCH,
"FLAGS", IMAP_FLAGS,
"LIST", IMAP_LIST,
"LSUB", IMAP_LSUB,
"NO", IMAP_NO,
"OK", IMAP_OK,
"PREAUTH", IMAP_PREAUTH,
"RECENT", IMAP_RECENT,
"SEARCH", IMAP_SEARCH,
"STORE", IMAP_FETCH,
"UNKNOWN", IMAP_UNKNOWN,
};
{
"ANONYMOUS", IMAP_AUTH_ANONYMOUS,
"KERBEROS_V4", IMAP_AUTH_KERBEROS_V4,
"LOGIN", IMAP_AUTH_LOGIN,
"XFILE", IMAP_AUTH_XFILE,
};
{
"ALERT", IMAP_STATUS_ALERT,
"NEWNAME", IMAP_STATUS_NEWNAME,
"PARSE", IMAP_STATUS_PARSE,
"PERMANENTFLAGS", IMAP_STATUS_PERMANENTFLAGS,
"READ-ONLY", IMAP_STATUS_READ_ONLY,
"READ-WRITE", IMAP_STATUS_READ_WRITE,
"TRYCREATE", IMAP_STATUS_TRYCREATE,
"UIDNEXT", IMAP_STATUS_UIDNEXT,
"UIDVALIDITY", IMAP_STATUS_UIDVALIDITY,
"UNSEEN", IMAP_STATUS_UNSEEN,
};
{
"BODY", IMAP_FETCH_BODY,
"BODYSTRUCTURE", IMAP_FETCH_BODYSTRUCTURE,
"ENVELOPE", IMAP_FETCH_ENVELOPE,
"FLAGS", IMAP_FETCH_FLAGS,
"INTERNALDATE", IMAP_FETCH_INTERNALDATE,
"RFC822.SIZE", IMAP_FETCH_RFC822_SIZE,
"UID", IMAP_FETCH_UID,
};
{
"\\*", IMAP_FLAG_LOCAL, 0,
"\\Answered", IMAP_FLAG_ANSWERED, 0,
"\\Draft", IMAP_FLAG_DRAFT, 0,
"\\Flagged", IMAP_FLAG_FLAGGED, 0,
};
static int imapconnect(Imap_t*);
/*
* return the name for the given code in table tab with n elements
*/
static char*
{
return "[ERROR]";
}
/*
* return the list of flag names set in flags in the string stream sp
*/
static char*
{
register int sep;
sep = 0;
{
if (sep)
else
sep = 1;
}
if (!sep)
}
/*
* list arg value on sfstdout
*/
static void
{
{
case IMAP_data:
sfprintf(sfstdout, " {%d}%.*s", ap->value.data.length, ap->value.data.length, ap->value.data.buffer);
break;
case IMAP_list:
{
do {
}
else
break;
case IMAP_name:
break;
case IMAP_number:
break;
case IMAP_string:
break;
}
if (!level)
}
/*
* set mailbox flag capabilities
*/
static void
{
register int i;
for (i = 0; i < elementsof(imapflags); i++)
if (ap->type == IMAP_name && (fp = (Imapflag_t*)strsearch(imapflags, elementsof(imapflags), sizeof(imapflags[0]), stracmp, ap->value.name, NiL)))
{
for (i = 0; i < elementsof(imapflags); i++)
}
}
/*
* parse a response arg
*/
static char*
{
register int c;
register char* b;
register int eol;
int m;
char* e;
for (;;)
{
for (; isspace(*s); s++);
if (*s)
{
if (*s == eol)
{
*ep = 0;
return s + 1;
}
else
{
return 0;
}
switch (*s)
{
case '{':
goto name;
return e + 1;
case '"':
for (b = ++s; *s && *s != '"'; s++);
if (*s)
*s++ = 0;
return s;
case '[':
m = ']';
goto list;
case '(':
m = ')';
list:
s++;
return s;
case '0':
case '1':
case '2':
case '3':
case '4':
case '5':
case '6':
case '7':
case '8':
case '9':
return e;
case 'N':
{
return s + 3;
}
/*FALLTHROUGH*/
default:
name:
m = 0;
for (b = s; (c = *s); s++)
if (c == '[')
m = c;
else if (c == ']')
m = 0;
else if (m == 0)
{
if (c == eol)
{
*ep = 0;
break;
}
else if (isspace(c))
break;
}
if (c)
*s++ = 0;
return s;
}
}
break;
}
return 0;
}
/*
* output an arg value converting \r\n => \n
*/
static void
{
register char* e;
register char* s;
register char* t;
register int n;
{
case IMAP_data:
while (t = (char*)memchr(t, '\r', e - t))
{
if (++t >= e)
break;
if (*t != '\n')
continue;
*(t - 1) = '\n';
n = t - s;
if ((s = ++t) >= e)
break;
}
if ((n = e - s) > 0)
{
}
break;
case IMAP_string:
break;
}
}
/*
* read and parse an IMAP server response
*/
static Imapop_t*
{
register char* s;
register char* z;
register size_t n;
char* b;
char* e;
/*
* read the first (possibly only) line of the response
*/
return 0;
*--z = 0;
if (TRACING('m'))
/*
* tag or *
*/
for (; isspace(*s); s++);
if (*s == '*')
{
for (; *++s && !isspace(*s););
}
else
{
n = (int)strtol(s, &e, 10);
s = e;
}
/*
*/
/*
* optional count
*/
for (; isspace(*s); s++);
if (isdigit(*s))
{
n = (int)strtol(s, &e, 10);
for (s = e; isspace(*s); s++);
}
else
n = 0;
/*
* response code
*/
for (b = s; *s && !isspace(*s); s++);
if (*s)
for (*s++ = 0; isspace(*s); s++);
op->code = (xp = (Imaplex_t*)strsearch(imapresponse, elementsof(imapresponse), sizeof(Imaplex_t), stracmp, b, NiL)) ? xp->code : IMAP_UNKNOWN;
if (TRACING('r'))
note(ERROR, "imap: recv %d %s %d %s", op - imap->op, imapname(imapresponse, elementsof(imapresponse), op->code), op->count, s);
/*
* if the message has imbedded literals there's
* more input to consume and we have to cache what's
* already been read
*/
bt = 0;
while (z > s && *(z - 1) == '}')
{
n = z - s + 1;
if (bt)
else
for (z -= 2; z > s && *z != '{'; z--);
return 0;
return 0;
*--z = 0;
if (TRACING('m'))
}
if (bt)
{
}
else
bh = 0;
return op;
}
/*
* handle EXPUNGE response
*/
static void
{
}
/*
* consume ENVELOPE response
*/
static void
{
register char* s;
if (!vp)
return;
{
else
}
return;
return;
return;
s = localize(s);
if (s && *s)
{
}
}
/*
* consume BODYSTRUCTURE response
*/
static void
imap_BODYSTRUCTURE(register Imap_t* imap, register Imaparg_t* ap, register Msg_t* mp, register Imapbody_t* bp)
{
register char* s;
int* id;
if (!ap)
return;
else
{
do {
}
else
{
{
s = strlower(s);
if (streq(s, "text"))
else if (streq(s, "message"))
else
}
return;
do {
break;
{
break;
}
return;
return;
return;
{
case IMAP_CONTENT_message:
break;
case IMAP_CONTENT_text:
{
return;
streq(s, "ATTACHMENT") &&
{
if (streq(s, "FILENAME"))
{
break;
}
break;
}
}
break;
case IMAP_CONTENT_data:
{
}
break;
}
{
}
else
}
}
/*
* handle FETCH response
*/
static void
{
char* s;
{
while (ap)
{
xp = 0;
else if (!(xp = (Imaplex_t*)strsearch(imapfetch, elementsof(imapfetch), sizeof(Imaplex_t), stracmp, ap->value.name, NiL)))
{
{
*s = 0;
xp = (Imaplex_t*)strsearch(imapfetch, elementsof(imapfetch), sizeof(Imaplex_t), stracmp, ap->value.name, NiL);
*s = '[';
}
}
{
{
case IMAP_FETCH_BODY:
break;
case IMAP_FETCH_BODYSTRUCTURE:
break;
case IMAP_FETCH_ENVELOPE:
break;
case IMAP_FETCH_FLAGS:
if (vp->type == IMAP_name && (fp = (Imapflag_t*)strsearch(imapflags, elementsof(imapflags), sizeof(imapflags[0]), stracmp, vp->value.name, NiL)))
break;
case IMAP_FETCH_INTERNALDATE:
break;
case IMAP_FETCH_RFC822_SIZE:
break;
}
else if (TRACING('u'))
}
}
}
}
/*
* sync the state.msg.list from the server
*/
static void
{
int dot;
{
}
}
/*
* consume IMAP server info until tag is complete
* tag<0 for any tag completed
*/
static Imapop_t*
{
register int n;
int to;
int i;
char* s;
{
return 0;
break;
}
if (!wp)
to = 0;
{
return wp;
return 0;
}
else
to = -1;
for (;;)
{
{
case 0:
if (wp)
break;
case 1:
{
if (TRACING('a'))
{
}
{
case IMAP_BAD:
case IMAP_NO:
n = 1;
goto status;
case IMAP_BYE:
goto status;
case IMAP_CAPABILITY:
{
/*UNDENT...*/
{
s += 4;
{
for (; *s && !isdigit(*s); s++);
}
}
if (xp = (Imaplex_t*)strsearch(imapauth, elementsof(imapauth), sizeof(Imaplex_t), stracmp, s + 5, NiL))
/*...INDENT*/
}
break;
case IMAP_EXISTS:
else
{
if (n > 0)
else if (n < 0)
{
n = -n;
}
}
break;
case IMAP_EXPUNGE:
break;
case IMAP_FETCH:
break;
case IMAP_FLAGS:
break;
case IMAP_LIST:
break;
case IMAP_OK:
n = 0;
/*
* check for status
*/
{
if (ap->type == IMAP_list && (sp = ap->value.list.head) && sp->type == IMAP_name && (xp = (Imaplex_t*)strsearch(imapstatus, elementsof(imapstatus), sizeof(Imaplex_t), stracmp, sp->value.name, NiL)))
{
/*UNDENT...*/
{
case IMAP_STATUS_ALERT:
case IMAP_STATUS_NEWNAME:
case IMAP_STATUS_PARSE:
n = 1;
break;
break;
case IMAP_STATUS_READ_ONLY:
break;
case IMAP_STATUS_READ_WRITE:
break;
case IMAP_STATUS_TRYCREATE:
break;
case IMAP_STATUS_UIDNEXT:
break;
case IMAP_STATUS_UIDVALIDITY:
break;
case IMAP_STATUS_UNSEEN:
break;
}
/*...INDENT*/
}
}
break;
case IMAP_PREAUTH:
break;
case IMAP_RECENT:
break;
case IMAP_SEARCH:
{
}
break;
}
return op;
}
continue;
default:
break;
}
break;
}
return 0;
}
/*
* va_list version of imapsend
*/
static Imapop_t*
{
register int i;
register int c;
register int q;
register char* s;
/*
* autologout may have dropped the connection
* the autoreconnect is here
*/
return 0;
/*
* grab a free tag
* this might mean waiting for a previous one to finish
*/
i = 1;
c = i;
{
i = 1;
if (i == c)
}
/*
* write the op
*/
q = 0;
for (;;)
{
switch (c = *s++)
{
case 0:
break;
case '"':
case '\'':
if (!q)
q = c;
continue;
case ' ':
case '\n':
case '\r':
case '\t':
if (!q)
{
for (; (c = *s) && (c == ' ' || c == '\n' || c == '\r' || c == '\t'); s++);
if (c && c != ')')
}
else
continue;
case '(':
if (!q)
for (; (c = *s) && (c == ' ' || c == '\n' || c == '\r' || c == '\t'); s++);
continue;
case ')':
if (!q)
{
for (; (c = *s) && (c == ' ' || c == '\n' || c == '\r' || c == '\t'); s++);
if (c && c != ']')
}
continue;
default:
continue;
}
break;
}
if (TRACING('s'))
{
i = 0;
}
if (!i)
return 0;
}
/*
* send a tagged imap op
*/
static Imapop_t*
{
return op;
}
/*
* send and recv a tagged imap op
*/
static int
{
return 0;
}
/*
* connect and authenticate to the IMAP service
*/
static int
{
register char* svc;
int fd;
/*
* imap->connected<0 means we got here from one of
* the imapexec()'s in this function -- not good
*/
{
return -1;
}
/*
* the old connection if any is useless now
*/
{
}
{
}
{
register char* host;
register char* user;
register char* meth;
/*
* get the host and authentication info from the imap file
*
* <host> [ <user> [ <meth> [ <arg> ... ] ] ]
*/
{
{
continue;
if (*user)
*user++ = 0;
{
if (*meth)
*meth++ = 0;
{
goto match;
}
}
}
host = 0;
user = 0;
meth = 0;
}
else
{
}
host = 0;
user = 0;
meth = 0;
{
if (!meth)
{
{
}
else
meth = "AUTHENTICATE XFILE";
}
}
if (fp)
}
/*
* connect to the service
*/
{
return -1;
}
{
{
}
else
return -1;
}
if (imapexec(imap, "CAPABILITY") || imap->version < IMAP_VERSION || imap->version == IMAP_VERSION && imap->revision < IMAP_REVISION)
{
note(ERROR|SYSTEM, "imap: %s: service version %d.%d must be at least %d.%d", svc, imap->version, imap->revision, IMAP_VERSION, IMAP_REVISION);
else
goto drop;
}
if (!imap->authenticated)
{
/*
* do the authentication
* imap->authenticated<0 is a hint to the
* IMAP_MORE response to consult imap->meth
*/
{
goto drop;
}
}
return 0;
drop:
{
}
{
}
return -1;
}
/*
* print message and fail on VM_BADADDR,VM_NOMEM
*/
static int
{
switch (type)
{
case VM_BADADDR:
imap_exit(1);
return -1;
case VM_NOMEM:
note(ERROR, "imap: storage allocator out of space on %lu byte request ( region %lu segments %lu busy %lu:%lu:%lu free %lu:%lu:%lu )", (size_t)obj, st.extent, st.n_seg, st.n_busy, st.s_busy, st.m_busy, st.n_free, st.s_free, st.m_free);
imap_exit(1);
return -1;
}
return 0;
}
/*
* initialize the IMAP service state
*/
static Imap_t*
imapinit(void)
{
{
return 0;
}
if (!(imap->gm = vmopen(&imap->vmdisc, Vmlast, 0)) || !(imap->vm = vmopen(&imap->vmdisc, Vmlast, 0)))
{
return 0;
}
{
return 0;
}
}
/*
* flush IMAP_STATE_sent requests and CLOSE
*/
static int
{
register int n;
{
n = 0;
n++;
if (n)
else
}
}
/*
* IMAP state.msg.list initialization
*/
int
{
register char* s;
register char* t;
return -1;
return -1;
if (!name)
return 0;
/*
* determine the service info
* info from previous folders is cached
* to preserve authentication
* ${IMAP} provides defaults
*/
name = "@inbox";
if (*name == '@')
name++;
{
if (!(t = strchr(s, '/')))
{
return -1;
}
*t++ = 0;
{
}
if (s = strchr(t, '/'))
*s++ = 0;
{
}
if (!s || !*s)
name = "inbox";
else
}
return -1;
return -1;
return 0;
}
/*
* return message pointer given number
*/
static Msg_t*
imap_msg(int m)
{
{
if (TRACING('b'))
{
note(ERROR, "imap: message %d id=%s content=%s type=%s encoding=%s name=%s size=%d/%d", m, pp->id, imapname(imapcontent, elementsof(imapcontent), pp->content), pp->type, pp->encoding, pp->name, pp->lines, pp->size);
}
}
return mp;
}
/*
* IMAP setinput()
*/
{
}
/*
/*
* IMAP command()
*/
int
imap_command(char* s)
{
register int n;
int items;
char* e;
unsigned long trace;
{
for (s += 4; isspace(*s); s++);
if (!*s)
{
list:
for (n = 0; n < elementsof(imapdump); n++)
}
else for (items = 0;;)
{
for (; isspace(*s); s++);
if (!*s)
break;
if (items++)
{
goto list;
}
for (s = e; isspace(*s); s++);
if (isdigit(*s))
{
n = strtol(s, &e, 0);
s = e;
}
else if (*s == '*')
{
s++;
n = -1;
}
else
n = 0;
{
case IMAP_DUMP_FLAGS:
for (n = 0; n < elementsof(imapflags); n++)
sfprintf(sfstdout, "%15s%s%s\n", imapflags[n].name, (imapflags[n].code & IMAP_FLAG_APPLICABLE) ? " APPLICABLE" : "", (imapflags[n].code & IMAP_FLAG_PERMANENT) ? " PERMANENT" : "");
break;
case IMAP_DUMP_FOLDER:
break;
case IMAP_DUMP_MESSAGE:
{
{
break;
}
if (n < 0)
{
}
else if (n > 0)
{
}
else
{
}
{
sfprintf(sfstdout, "message %4d %s\n", mp - state.msg.list + 1, imapflagnames(imap->tp, imapmflags, elementsof(imapmflags), mp->m_flag));
sfprintf(sfstdout, "%12s content=%s type=%s encoding=%s name=%s size=%d/%d\n", pp->id, imapname(imapcontent, elementsof(imapcontent), pp->content), pp->type, pp->encoding, pp->name, pp->lines, pp->size);
}
break;
}
case IMAP_DUMP_QUEUE:
{
sfprintf(sfstdout, " [%d] %s %s %d %s%s\n", op - imap->op, imapname(imapstate, elementsof(imapstate), op->state), imapname(imapresponse, elementsof(imapresponse), op->code), op->count, op->msg, op->retain ? " retain" : "");
break;
}
case IMAP_DUMP_STATE:
sfprintf(sfstdout, " auth %s\n", imapflagnames(imap->tp, imapauth, elementsof(imapauth), imap->auth));
break;
}
}
n = 0;
}
else
{
TRACE('r');
}
return n;
}
/*
* IMAP copy()
*/
int
{
register char* s;
register int i;
/*
* Compute the prefix string, without trailing whitespace
*/
{
}
{
else
{
{
i = RETAIN;
s = "";
}
else
{
i = IGNORE;
s = " ";
}
{
s = " ";
}
}
}
else
sfprintf(op, "\n(attachment %3d %s %18s \"%s\")\n", pp->attachment, counts(1, pp->lines, pp->size), pp->type, pp->name);
return 0;
}
/*
* IMAP mkdir()
*/
int
imap_mkdir(char* s)
{
if (*s == '@')
s++;
}
/*
* IMAP rename()
*/
int
imap_rename(char* f, char* t)
{
if (*f == '@')
f++;
if (*t == '@')
t++;
}
/*
* IMAP rmdir()
*/
int
imap_rmdir(char* s)
{
if (*s == '@')
s++;
}
/*
* IMAP exit()
*/
void
{
imap_quit();
}
/*
* IMAP folders()
*/
int
imap_folders(void)
{
}
/*
* IMAP getatt()
*/
static int
imap_getatt(Msg_t* mp, register Imappart_t* pp, register char* name, unsigned long flags, off_t* lines, off_t* chars)
{
register char* s;
register int n;
char* cmd;
{
{
}
return 1;
}
{
if (cmd)
else
{
}
n = 1;
}
else if (cmd)
{
s = cmd;
n = -1;
}
{
n = -1;
}
else
{
s = name;
n = 0;
}
{
mime(1) &&
return 0;
}
return 1;
}
if (lines)
if (chars)
mime(1) &&
wait_command(n);
return 0;
}
/*
* IMAP get1()
*/
int
{
register int i;
register char* s;
char* name;
char* a;
char* e;
int n;
int r;
{
return 1;
}
{
return 1;
}
if (!*argv)
{
do {
sfprintf(sfstdout, "(attachment %3d %s %18s \"%s\")\n", pp->attachment, counts(1, pp->lines, pp->size), pp->type, pp->name);
return 0;
}
s = *argv++;
r = 0;
for (;;)
{
while (isspace(*s))
s++;
if (!*s)
break;
else if (*s == ',')
{
s++;
r = 0;
}
else if (*s == '*')
{
if (!r)
r = 1;
for (i = r; i <= ip->attachments; i++)
a[i] = 1;
r = 0;
}
else if (*s == '-')
{
s++;
r = 1;
}
else
{
n = strtol(s, &e, 0);
if (n > 0 && n <= ip->attachments)
{
if (r)
{
for (i = r; i <= n; i++)
a[i] = 1;
r = 0;
}
else
a[n] = 1;
}
else
{
while (*e && !isspace(*e))
e++;
}
s = e;
if (*s == '-')
{
s++;
r = n;
}
}
}
r = 0;
if (a[i])
{
while (pp->attachment != i)
{
r = 1;
goto done;
}
{
continue;
}
argv++;
else
r = 1;
}
done:
free(a);
return r;
}
/*
* IMAP printhead()
*/
void
{
char* sizes;
int subjlen;
int current;
int disposition;
return;
disposition = 'M';
disposition = 'P';
disposition = '*';
disposition = 'X';
disposition = 'U';
disposition = 'N';
else
if (who)
{
else
}
else
{
printf("%c%c%3d %-20.20s %16.16s %s %.*s\n",
else
printf("%c%c%3d %-20.20s %16.16s %s\n",
}
}
/*
* imap_msgflags() support
*/
static void
{
register int i;
register int c;
if (TRACING('z'))
c = '(';
for (i = 0; i < elementsof(imapflags); i++)
{
c = ' ';
}
if (c == ' ')
{
}
else
}
/*
* IMAP message flag update
*/
void
{
register int flags;
return;
{
}
{
}
}
/*
* '(' IMAP SEARCH expression ')'
*/
int
imap_msglist(register char* s)
{
register char* t;
for (; isspace(*s); s++);
if (*s != '(')
{
return 0;
}
s++;
t = s + strlen(s);
for (; t > s && isspace(*--t) && *t != ')';);
return 0;
}
/*
* IMAP quit()
*/
void
imap_quit(void)
{
register int i;
}
/*
* IMAP save()
*/
int
{
}
#else
/*
* stubs when IMAP can't fly
*/
int
{
return -1;
}
#endif