/* IMAP.cc 25 July 2001 Modified by Robin Whittle to call get the real date from the Date header of the message, rather than from the MESSAGECACHE date and time stuff (AKA "elt") which, in the case of Courier IMAP at least, returns the date of the message file in the MailDir. Constructor changed so newly opened mailboxes are sorted on SORTDATE, rather than nothing. Change the Date sort (from the user's point of view) to do a SORTDATE rather than a SORTARRIVAL. SORTDATE works by the "Date: " header in the email and has nothing to so with file dates in Maildir mailboxes. Changes tagged with "RW". */ #include "IMAP.h" IMAP *theimap; extern Language *L; IMAP::IMAP () { theimap = this; TheDEBUG = true; MAILBOXSIZE = 0; TOTALMSGS = 0; msgsmarkeddeleted = 0; imapstream = NIL; timeout = 20; maxlogintrials = 1; TheERROR = false; imapport = DEFIMAPPORT; initStr (imaphost); initStr (username); initStr (password); initStr (mailbox); initStr (fullmailbox); initStr (ERRORSTRING); MAXMSGSFORPAGE = DEFOPT_MSGSPERINDEXPAGE; SortType = SORTDATE; SortReversed = false; // RW Was NO_SORT SLMailboxes = new StringList (); SLSearch = new StringList (); ILSort = new ULongList (); /*EN VEZ DE LAS LINEAS DE ABAJO SE PUEDE PONER #include "linkage.c" EN EL MAIN */ mail_link (&mboxdriver); /* link in the mbox driver */ mail_link (&imapdriver); /* link in the imap driver */ mail_link (&nntpdriver); /* link in the nntp driver */ mail_link (&pop3driver); /* link in the pop3 driver */ mail_link (&mhdriver); /* link in the mh driver */ mail_link (&mxdriver); /* link in the mx driver */ mail_link (&mbxdriver); /* link in the mbx driver */ mail_link (&tenexdriver); /* link in the tenex driver */ mail_link (&mtxdriver); /* link in the mtx driver */ mail_link (&mmdfdriver); /* link in the mmdf driver */ mail_link (&unixdriver); /* link in the unix driver */ mail_link (&newsdriver); /* link in the news driver */ mail_link (&philedriver); /* link in the phile driver */ mail_link (&dummydriver); /* link in the dummy driver */ auth_link (&auth_md5); /* link in the md5 authenticator */ auth_link (&auth_pla); /* link in the pla authenticator */ auth_link (&auth_log); /* link in the log authenticator */ setPathToRemoteFolder (""); setMailboxPrefix (""); setDelimiter (47); setTimeout (timeout); disableRSH(); hideDotFiles(); setMaxLoginTrials (maxlogintrials); } IMAP::~IMAP() { CloseMailbox (); delete SLSearch; delete SLMailboxes; delete ILSort; } xulong IMAP::getNumMsgFromPosList (xulong pos) { return ILSort->elementAt((int)(pos - 1)); } xulong IMAP::getPosListFromNumMsg (xulong nummsg) { return ILSort->indexOf(nummsg); } bool IMAP::isLastMsgFromList (xulong nummsg) { if (ILSort->indexOf(nummsg) >= ILSort->Count () - 1) return true; else return false; } char *IMAP::getFullMailbox (char *amailbox) { //{idolo.ci.uv.es:143/imap/user="noprotes"}INBOX //{idolo.ci.uv.es:143/imap/user="noprotes"}~/mail/ TBuffer mailbox, abuf; setError (false); strncpy (mailbox, amailbox, CMAXFILENAME); if (strcmp (amailbox, "INBOX") == 0) sprintf (abuf, "{%s/imap/user=\"%s\"}%s", imaphost, username, mailbox); else sprintf (abuf, "{%s/imap/user=\"%s\"}%s%s", imaphost, username, getPathToRemoteFolder(), mailbox); //LOG ("abuf=%s", abuf); return xstrdup(abuf); } MAILSTREAM *IMAP::getStream (void) { return imapstream; } void IMAP::setDelimiter (char adelim) { delimiter = adelim; } char IMAP::getDelimiter (void) { return delimiter; } void IMAP::setPathToRemoteFolder (char *aPathToRemoteFolder) { strncpy (PathToRemoteFolder, aPathToRemoteFolder, CMAXBUFFER); } char *IMAP::getPathToRemoteFolder (void) { return PathToRemoteFolder; } void IMAP::setMailboxPrefix (char *aMailboxPrefix) { strncpy (MailboxPrefix, aMailboxPrefix, CMAXBUFFER); } char *IMAP::getMailboxPrefix (void) { return MailboxPrefix; } void IMAP::setMAXMSGSFORPAGE (long maxmsgs) { MAXMSGSFORPAGE = maxmsgs; } bool IMAP::getError (void) { return TheERROR; } void IMAP::setError (bool value) { TheERROR = value; } char *IMAP::getErrorString (void) { if ((strcasecmp (ERRORSTRING, "Can not authenticate to IMAP server: Authentication failure") == 0) || (strcasecmp (ERRORSTRING, "Too many login failures")) == 0) { strncpy (ERRORSTRING, L->get(ERR_INV_USER_PW), CSMALLBUFFER); } //[ALERT] Mailbox is at 99% of quota else if (strstr (ERRORSTRING, "[ALERT] Mailbox is at ") != NULL) { TSBuffer c1, c2, c3, c4, c5, c6; sscanf (ERRORSTRING, "%s %s %s %s %s %s", c1, c2, c3, c4, c5, c6); strncpy (c1, L->get(ERR_QUOTA_USAGE), CSMALLBUFFER); sprintf (ERRORSTRING, c1, c5); } //Do not show the next message //[ALERT] Mailbox vulnerable else if (strstr (ERRORSTRING, "[ALERT] Mailbox vulnerable ") != NULL) { strcpy (ERRORSTRING, ""); } return xstrdup (ERRORSTRING); } void IMAP::setErrorString (char *sterr) { strncpy (ERRORSTRING, sterr, CSMALLBUFFER); } char *IMAP::getBriefMailbox (char *amailbox) { //INBOX //~/mail/ TBuffer mailbox, abuf; setError (false); strncpy (mailbox, amailbox, CMAXFILENAME); if (strcmp (amailbox, "INBOX") == 0) sprintf (abuf, "%s", mailbox); else sprintf (abuf, "%s%s", getPathToRemoteFolder(), mailbox); return xstrdup(abuf); } char *IMAP::getUsername (void) {return (username);} char *IMAP::getPassword (void) {return (password);} bool IMAP::isDebug (void) {return false;} /*{return (TheDEBUG);}*/ void IMAP::Expunge (void) { setError (false); if (imapstream != NIL) mail_expunge (imapstream);} void IMAP::setTimeout (int atimeout) { setError (false); timeout = atimeout; mail_parameters (NIL, SET_TIMEOUT, (void *) timeout); } //To avoid c-client try to connect using rsh at the beginning before IMAP validation // we must set the rshtimeout to 0 void IMAP::disableRSH(void) { setError (false); mail_parameters (NIL, SET_RSHTIMEOUT, 0); } //To avoid c-client show files beginning with dot in mail_list results void IMAP::hideDotFiles(void) { setError (false); mail_parameters (NIL, SET_HIDEDOTFILES, (void *)T); } void IMAP::setMaxLoginTrials (int amaxlogintrials) { setError (false); maxlogintrials = amaxlogintrials; mail_parameters (NIL, SET_MAXLOGINTRIALS, (void *) maxlogintrials); } bool IMAP::OpenMailbox (const char *aimaphost, int aimapport, char *amailbox, char *ausername, char *apassword) { long flag; setError (false); flag = OP_HALFOPEN; if (TheDEBUG == true) {flag = flag || OP_DEBUG;} imapport = aimapport; mail_parameters (NIL, SET_IMAPPORT, (void *)(imapport)); strncpy (username, ausername, CMAXFILENAME); strncpy (password, apassword, CMAXFILENAME); strncpy (mailbox, amailbox, CMAXFILENAME); strncpy (imaphost, aimaphost, CMAXFILENAME); strncpy (fullmailbox, getFullMailbox (mailbox), CMAXFILENAME); imapstream = mail_open (imapstream, fullmailbox, flag); if (imapstream == NIL) {return false;} Sort (); return true; } bool IMAP::Reconnect (void) { long flag; setError (false); flag = OP_HALFOPEN; if (TheDEBUG == true) {flag = flag || OP_DEBUG;} mail_parameters (NIL, SET_IMAPPORT, (void *)(imapport)); imapstream = mail_open (imapstream, fullmailbox, flag); if (imapstream == NIL) {return false;} Sort (); return true; } bool IMAP::ChangeMailbox (char *newmailbox) { long flag; setError (false); flag = OP_HALFOPEN; if (TheDEBUG == true) {flag = flag || OP_DEBUG;} strncpy (mailbox, newmailbox, CMAXFILENAME); strncpy (fullmailbox, getFullMailbox (mailbox), CMAXFILENAME); imapstream = mail_open (imapstream, fullmailbox, flag); if (imapstream == NIL) {return false;} Sort (); msgsmarkeddeleted = 0; return true; } void IMAP::CloseMailbox (void) { setError (false); if (imapstream != NIL) imapstream = mail_close (imapstream); imapstream = NIL; } void IMAP::addMailbox (char *name) { SLMailboxes->Add(name); } char *IMAP::getMailboxName (void) { if (imapstream != NIL) {return (mailbox);} return ""; }; char *IMAP::getFullMailboxName (void) { if (imapstream != NIL) {return (imapstream->mailbox);} return ""; }; long IMAP::getTotalMsgs (void) { TOTALMSGS = -1; if (imapstream != NIL) {TOTALMSGS = (xulong)imapstream->nmsgs;} return TOTALMSGS; }; int IMAP::getMsgsMarkedDeleted (void) { return msgsmarkeddeleted; }; long IMAP::getRecentMsgs (void) { if (imapstream != NIL) {return ((xulong)imapstream->recent);} return (long)-1; }; bool IMAP::Ping (void) { setError (false); if (imapstream != NIL) { long L; L = mail_ping (imapstream); if (L == 0) return false; else return true; } return false; } char *IMAP::getAttIdFromCID (xulong nummsg, char *cid) { int i, j, p; TBuffer connid, basura; StringList *SLAttachs, *SLAttHeader; SLAttachs = new StringList (); SLAttHeader= new StringList (); SLAttachs->Clear(); SLAttHeader->Clear(); getBodyStructure (nummsg, SLAttachs); setError (false); for (i = 0; i < SLAttachs->Count(); ++i) { sscanf (SLAttachs->getString(i).cstr(), "%s %[^]]s", connid, basura); getAttHeaderSL (nummsg, connid, SLAttHeader); for (j=0; j < SLAttHeader->Count(); ++j) { p = NCstrstr ((char *)SLAttHeader->getString(j).cstr(), "Content-Id: "); if (p > 0) { XString XS = XString (cid).substring (4); p = NCstrstr ((char *)SLAttHeader->getString(j).cstr(), (char *)XS.cstr()); if (p > 0) { delete SLAttachs; delete SLAttHeader; return xstrdup(connid); } } } } delete SLAttachs; delete SLAttHeader; return ""; } char *IMAP::getTo (xulong nummsg) { char *pc, *c; setError (false); if (imapstream != NIL) { if (nummsg && (nummsg <= imapstream->nmsgs)) { STRINGLIST *lines = mail_newstringlist (); STRINGLIST *cur = lines; cur->text.size = strlen ((char *) (cur->text.data = (xuchar *)xstrdup ("To"))); c = mail_fetchheader_full (imapstream, nummsg, lines, NIL, NIL); QuitaRetornoCarroDeLinea (c); if (strcmp (c, "") == 0) return ""; pc = xstrdup (c); mail_free_stringlist (&lines); QuitaRetornoCarroDeLinea (pc); return DecodificaHeader(pc + strlen ("To: ")); } } return ""; } char *IMAP::getReplyTo (xulong nummsg) { char *pc, *c; setError (false); if (imapstream != NIL) { if (nummsg && (nummsg <= imapstream->nmsgs)) { STRINGLIST *lines = mail_newstringlist (); STRINGLIST *cur = lines; cur->text.size = strlen ((char *) (cur->text.data = (xuchar *)xstrdup ("Reply-to"))); c = mail_fetchheader_full (imapstream, nummsg, lines, NIL, NIL); QuitaRetornoCarroDeLinea (c); if (strcmp (c, "") == 0) return ""; pc = xstrdup (c); mail_free_stringlist (&lines); QuitaRetornoCarroDeLinea (pc); return DecodificaHeader(pc + strlen ("Reply-to: ")); } } return ""; } char *IMAP::getFrom (xulong nummsg) { char *pc, *c; setError (false); if (imapstream != NIL) { if (nummsg && (nummsg <= imapstream->nmsgs)) { STRINGLIST *lines = mail_newstringlist (); STRINGLIST *cur = lines; cur->text.size = strlen ((char *) (cur->text.data = (xuchar *)xstrdup ("From"))); c = mail_fetchheader_full (imapstream, nummsg, lines, NIL, NIL); QuitaRetornoCarroDeLinea (c); if (strcmp (c, "") == 0) return ""; pc = xstrdup (c); mail_free_stringlist (&lines); QuitaRetornoCarroDeLinea (pc); return DecodificaHeader(pc + strlen("From: ")); } } return ""; } char *IMAP::getCC (xulong nummsg) { char *pc, *c; setError (false); if (imapstream != NIL) { if (nummsg && (nummsg <= imapstream->nmsgs)) { STRINGLIST *lines = mail_newstringlist (); STRINGLIST *cur = lines; cur->text.size = strlen ((char *) (cur->text.data = (xuchar *)xstrdup ("Cc"))); c = mail_fetchheader_full (imapstream, nummsg, lines, NIL, NIL); QuitaRetornoCarroDeLinea (c); if (strcmp (c, "") == 0) return ""; pc = xstrdup (c); mail_free_stringlist (&lines); QuitaRetornoCarroDeLinea (pc); return DecodificaHeader(pc + strlen("Cc: ")); } } return ""; } char *IMAP::getContentType (xulong nummsg) { char *pc, *c; int p; setError (false); if (imapstream != NIL) { if (nummsg && (nummsg <= imapstream->nmsgs)) { STRINGLIST *lines = mail_newstringlist (); STRINGLIST *cur = lines; cur->text.size = strlen ((char *) (cur->text.data = (xuchar *)xstrdup ("Content-Type"))); c = mail_fetchheader_full (imapstream, nummsg, lines, NIL, NIL); QuitaRetornoCarroDeLinea (c); if (strcmp (c, "") == 0) return ""; pc = xstrdup (c); mail_free_stringlist (&lines); QuitaRetornoCarroDeLinea (pc); p = NCstrstr (pc, ";"); if (p > 0) {pc[p - 1] = '\0';} return pc + strlen ("Content-Type: "); } } return ""; } char *IMAP::getSubject (xulong nummsg) { char *pc, *c; setError (false); if (imapstream != NIL) { if (nummsg && (nummsg <= imapstream->nmsgs)) { STRINGLIST *lines = mail_newstringlist (); STRINGLIST *cur = lines; cur->text.size = strlen ((char *) (cur->text.data = (xuchar *)xstrdup ("Subject"))); c = mail_fetchheader_full (imapstream, nummsg, lines, NIL, NIL); QuitaRetornoCarroDeLinea (c); if (strcmp (c, "") == 0) return ""; pc = xstrdup (c); mail_free_stringlist (&lines); QuitaRetornoCarroDeLinea (pc); return DecodificaHeader(pc + strlen ("Subject: ")); } } return ""; } char *IMAP::getDate (xulong nummsg) { char *pc, *c; setError (false); if (imapstream != NIL) { if (nummsg && (nummsg <= imapstream->nmsgs)) { STRINGLIST *lines = mail_newstringlist (); STRINGLIST *cur = lines; cur->text.size = strlen ((char *) (cur->text.data = (xuchar *)xstrdup ("Date"))); c = mail_fetchheader_full (imapstream, nummsg, lines, NIL, NIL); QuitaRetornoCarroDeLinea (c); if (strcmp (c, "") == 0) return ""; pc = xstrdup (c); mail_free_stringlist (&lines); QuitaRetornoCarroDeLinea (pc); return pc + strlen("Date: "); } } return ""; } xulong IMAP::getSize (xulong nummsg) { setError (false); if (imapstream != NIL) { if (nummsg && (nummsg <= imapstream->nmsgs)) { MESSAGECACHE *cache; cache = mail_elt (imapstream, nummsg); return cache->rfc822_size; } } return 0; } char *IMAP::getFormattedSize (xulong nummsg) { setError (false); if (imapstream != NIL) { if (nummsg && (nummsg <= imapstream->nmsgs)) { MESSAGECACHE *cache; cache = mail_elt (imapstream, nummsg); return xstrdup (FormatCountBytes (cache->rfc822_size)); } } return ""; } void IMAP::dumpFullHeader (xulong nummsg, StringList *SL) { setError (false); SL->Clear(); if (imapstream != NIL) { if (nummsg && (nummsg <= imapstream->nmsgs)) { SeparaTokensEnStringList (mail_fetchheader_full (imapstream, nummsg, NIL, NIL, NIL), '\n', SL); } } } void IMAP::dumpFullBody (xulong nummsg, StringList *SL) { setError (false); SL->Clear(); if (imapstream != NIL) { if (nummsg && (nummsg <= imapstream->nmsgs)) { SL->Add (mail_fetchtext (imapstream, nummsg)); } } } char *IMAP::dumpFullMsg (xulong nummsg) { setError (false); if (imapstream != NIL) { if (nummsg && (nummsg <= imapstream->nmsgs)) { return (mail_fetch_message (imapstream, nummsg, NIL, NIL)); } } return NULL; } void IMAP::dumpMsg (xulong nummsg, StringList *SL) { setError (false); SL->Clear(); if (imapstream != NIL) { if (nummsg && (nummsg <= imapstream->nmsgs)) { STRINGLIST *lines = mail_newstringlist (); STRINGLIST *cur = lines; cur->text.size = strlen ((char *) (cur->text.data = (xuchar *) xstrdup ("Date"))); cur = cur->next = mail_newstringlist (); cur->text.size = strlen ((char *) (cur->text.data = (xuchar *) xstrdup ("From"))); cur = cur->next = mail_newstringlist (); cur->text.size = strlen ((char *) (cur->text.data = (xuchar *) xstrdup (">From"))); cur = cur->next = mail_newstringlist (); cur->text.size = strlen ((char *) (cur->text.data = (xuchar *) xstrdup ("Subject"))); cur = cur->next = mail_newstringlist (); cur->text.size = strlen ((char *) (cur->text.data = (xuchar *) xstrdup ("To"))); cur = cur->next = mail_newstringlist (); cur->text.size = strlen ((char *) (cur->text.data = (xuchar *) xstrdup ("cc"))); cur = cur->next = mail_newstringlist (); cur->text.size = strlen ((char *) (cur->text.data = (xuchar *) xstrdup ("Newsgroups"))); SL->Add (mail_fetchheader_full (imapstream, nummsg, lines, NIL, NIL)); SL->Add (mail_fetchtext (imapstream, nummsg)); mail_free_stringlist (&lines); } } } char *IMAP::getFlags (xulong nummsg) { setError (false); if (imapstream != NIL) { if (nummsg && (nummsg <= imapstream->nmsgs)) { TBuffer tmp; MESSAGECACHE *cache; cache = mail_elt (imapstream, nummsg); mail_fetchstructure (imapstream, nummsg, NIL); sprintf (tmp, "%c%c%c%c%c", FEMPTY, FEMPTY, FEMPTY, FEMPTY, FEMPTY); tmp[POS_FLAG_DELETED] = cache->deleted ? FDELETED : FEMPTY; tmp[POS_FLAG_ANSWERED] = cache->answered ? FANSWERED : FEMPTY; if (!cache->seen) {tmp[POS_FLAG_NEW] = FUNSEEN;} tmp[POS_FLAG_IMPORTANT] = cache->flagged ? FFLAGGED : FEMPTY; if (IsSearched (nummsg) == true) {tmp[POS_FLAG_SEARCHED] = FSEARCHED;} else {tmp[POS_FLAG_SEARCHED] = FEMPTY;} tmp[5] = '\0'; return xstrdup (tmp); } } return ""; } void IMAP::getHeaderList (xulong abeginmsg, StringList *SL, char *user, char *maildomain, char *tolabel) { xulong j, t, oldtotal, beginmsg, endmsg, aMAXMSGSFORPAGE, themsgnum; TBuffer tmp, xtmp; TSBuffer abuf; char *inter, *inter2; // RW added this for code below. char *datebuff; MESSAGECACHE *cache; setError (false); if (CALCULATEMAILBOXSIZE == 1) { doMailboxSize(); } SL->Clear(); if (imapstream != NIL) { oldtotal = ILSort->Count(); t = getTotalMsgs(); if (t != oldtotal) {Sort();} aMAXMSGSFORPAGE = MAXMSGSFORPAGE; if (aMAXMSGSFORPAGE <= 0) aMAXMSGSFORPAGE = t; beginmsg=abeginmsg; if (beginmsg <= 0) beginmsg = 1; if (aMAXMSGSFORPAGE > 0) { endmsg = abeginmsg + aMAXMSGSFORPAGE - 1; if (endmsg > t) endmsg = t; } else endmsg = t; for (j=beginmsg; j<=endmsg; ++j) { //themsgnum = j; themsgnum = ILSort->elementAt((int)(j - 1)); cache = mail_elt (imapstream, themsgnum); //1. POSITION inter = xltoa(cache->msgno); SL->Add (inter); delete [] inter; //2. FLAGS mail_fetchstructure (imapstream, themsgnum, NIL); sprintf (tmp, "%c%c%c%c%c", FEMPTY, FEMPTY, FEMPTY, FEMPTY, FEMPTY); tmp[POS_FLAG_DELETED] = cache->deleted ? FDELETED : FEMPTY; tmp[POS_FLAG_ANSWERED] = cache->answered ? FANSWERED : FEMPTY; if (!cache->seen) {tmp[POS_FLAG_NEW] = FUNSEEN;} tmp[POS_FLAG_IMPORTANT] = cache->flagged ? FFLAGGED : FEMPTY; if (IsSearched (themsgnum) == true) {tmp[POS_FLAG_SEARCHED] = FSEARCHED;} else {tmp[POS_FLAG_SEARCHED] = FEMPTY;} tmp[5] = '\0'; SL->Add (tmp); //3. DATE // RW // // Original code: // // Call a function from the UW IMAP c-client code, line // 2305 of mail.c. The date string is returned in tmp. // mail_date (tmp, cache); // ProcesaDate() is at line 1376 of Utils.cc. After 15 // minutes scrutinising the code (why don't people have // more comments???) I think it takes an input such as // // " 8-Sep-2000 08:51:13 +0100" // // and returns: // // "8-Sep-2000" // or "8-Sep" if this is the current year. // inter = ProcesaDate (tmp); // End of original code. // // Start of changes. // // Get a pointer to the date section of the // message's headers. getDate() is a method // of class IMAP, and we are currently in // another method of class IMAP, so we can // use it directly, on the current IMAP object. // // Feed this to mail_parse_date which will // parse the date and write the values // into the "elt" variables in "cache". // // getDate() points to the character after: // "Date: ". Any normal RFC2822 compliant // message will start with the date on that // byte, but I have found some Microsoft // Security bulletin emails which have 8 // extra spaces. Since mail_parse_date() // can only gobble the day of the week if // it starts at byte 0 of the string, then // we need to skip past any spaces we // find to start with. datebuff = (getDate(themsgnum)); // Debug: the offending MS Date: // datebuff = " Thu, 5 Jul 2001 18:08:16 -0700"; while (datebuff[0] == ' ') datebuff++; mail_parse_date (cache, datebuff); // Now create a date string from these values. mail_date (tmp, cache); // Process it to remove bits we don't want. // Note - I have changed ProcesaDate() a lot. // // The only way of doing timezone correction // of time-dates is with the numeric values // in cache, which would be a complete rewrite. inter = ProcesaDate (tmp); // End of changes - RW. SL->Add (inter); delete [] inter; //4. FROM (If the FROM field is the same that user@maildomain then use TO field) strncpy (abuf, user, CSMALLBUFFER); strcat (abuf, "@"); strcat (abuf, maildomain); mail_fetchfrom_mod (tmp, imapstream, themsgnum, CMAXBUFFER - 1, 2); if (strstr (tmp, abuf) == NULL) { mail_fetchfrom_mod (tmp, imapstream, themsgnum, CMAXBUFFER - 1, 1); inter = DecodificaHeader (tmp); strncpy (xtmp, inter, CMAXBUFFER); delete [] inter; } else { mail_fetchto_mod (tmp, imapstream, themsgnum, CMAXBUFFER - 1, 1); strncpy (xtmp, tolabel, CMAXBUFFER); inter = DecodificaHeader (tmp); strcat (xtmp, inter); delete [] inter; } inter = Cut(xtmp, LONGDISPLAYFROM); SL->Add (inter); delete [] inter; //5. SUBJECT mail_fetchsubject (tmp, imapstream, themsgnum, CMAXBUFFER - 1); inter2 = DecodificaHeader (tmp); strncpy (xtmp, inter2, CMAXBUFFER); delete [] inter2; inter = Cut(xtmp, LONGDISPLAYSUBJECT); SL->Add (inter); delete [] inter; //6. SIZE inter = FormatCountBytes (cache->rfc822_size); SL->Add (inter); delete [] inter; //7. UID inter = xltoa(cache->cclientPrivate.uid); SL->Add (inter); delete [] inter; } } } //Internal return the mailbox size. Carga??? void IMAP::doMailboxSize (void) { xulong j, t; MESSAGECACHE *cache; MAILBOXSIZE = 0; setError (false); if (imapstream != NIL) { t = getTotalMsgs(); msgsmarkeddeleted = 0; for (j=1; j<=t; ++j) { cache = mail_elt (imapstream, j); mail_fetchstructure (imapstream, j, NIL); MAILBOXSIZE = MAILBOXSIZE + cache->rfc822_size; if (cache->deleted) ++msgsmarkeddeleted; } } } long IMAP::getMailboxSize (void) { return MAILBOXSIZE; } /* Display body * Accepts: BODY structure pointer * prefix string * index */ void IMAP::display_body (BODY *body, char *pfx, long i, StringList *SLAttach) { char tmp[MAILTMPLEN]; char *s = tmp; PARAMETER *par; PART *part; /* multipart doesn't have a row to itself */ setError (false); if (body->type == TYPEMULTIPART) { /* if not first time, extend prefix */ if (pfx) sprintf (tmp, "%s%ld.", pfx, ++i); else tmp[0] = '\0'; for (i = 0,part = body->nested.part; part; part = part->next) { display_body (&part->body, tmp, i++, SLAttach); } } else { /* non-multipart, output oneline descriptor */ if (!pfx) pfx = ""; /* dummy prefix if top level */ sprintf (s," %s%ld %s", pfx, ++i, body_types[body->type]); if (body->subtype) sprintf (s += strlen (s),"/%s",body->subtype); //if (body->id) sprintf (s += strlen (s),", id = %s",body->id); switch (body->type) { /* bytes or lines depending upon body type */ case TYPEMESSAGE: /* encapsulated message */ case TYPETEXT: /* plain text */ sprintf (s += strlen (s), " %lu bytes", body->size.bytes); break; default: sprintf (s += strlen (s), " %lu bytes", body->size.bytes); break; } if (body->description) sprintf (s += strlen (s),", \"%s\"",body->description); par = body->parameter; if (par) { do { if ((strcmp ("NAME", par->attribute) == 0) || (strcmp ("FILENAME", par->attribute) == 0)) sprintf (s += strlen (s), ", \"%s\"", par->value); par = par->next; } while (par); } SLAttach->Add(tmp); /* encapsulated message? */ if ((body->type == TYPEMESSAGE) && !strcmp (body->subtype,"RFC822") && (body = body->nested.msg->body)) { if (body->type == TYPEMULTIPART) display_body (body, pfx, i-1, SLAttach); else {/* build encapsulation prefix */ sprintf (tmp,"%s%ld.", pfx, i); display_body (body, tmp, (long) 0, SLAttach); } } } } void IMAP::getBodyStructure (xulong nummsg, StringList *SLAttachs) { BODY *body; SLAttachs->Clear(); setError (false); if (imapstream != NIL) { if (nummsg && (nummsg <= imapstream->nmsgs)) { mail_fetchstructure (imapstream, nummsg, &body); if (body) display_body (body, NIL, (long) 0, SLAttachs); } } } void IMAP::getAttachInfo (BODY *body, char *oripfx, char *pfx, long i, StringList *SLAttach, StringList *SLFullHeader) { TBuffer theprefix, name, filename; char tmp[MAILTMPLEN]; char *s = tmp; PARAMETER *par; PART *part; /* multipart doesn't have a row to itself */ setError (false); if (body->type == TYPEMULTIPART) { /* if not first time, extend prefix */ if (pfx) sprintf (tmp, "%s%ld.", pfx, ++i); else tmp[0] = '\0'; for (i = 0,part = body->nested.part; part; part = part->next) { getAttachInfo (&part->body, oripfx, tmp, i++, SLAttach, SLFullHeader); } } else { /* non-multipart, output oneline descriptor */ if (!pfx) pfx = ""; /* dummy prefix if top level */ sprintf (s," %s%ld %s", pfx, ++i, body_types[body->type]); sprintf (theprefix, "%s%ld", pfx, i); if (body->subtype) sprintf (s += strlen (s),"/%s",body->subtype); switch (body->type) { case TYPEMESSAGE: /* encapsulated message */ case TYPETEXT: /* plain text */ sprintf (s += strlen (s), " (%lu lines)", body->size.lines); break; default: sprintf (s += strlen (s), " (%lu bytes)", body->size.bytes); break; } //1 theprefix //2 tmp info //3 codec //4 type //5 subtype //6 description //7 name //8 filename //9 size.bytes if (strcmp (oripfx, theprefix) == 0) { SLAttach->Add (theprefix); SLAttach->Add (tmp); SLAttach->Add (xltoa(body->encoding)); SLAttach->Add (body_types[body->type]); if (body->subtype) SLAttach->Add (body->subtype); else SLAttach->Add (""); if (body->description) SLAttach->Add (body->description); else SLAttach->Add (""); name[0] = '\0'; filename[0] = '\0'; par = body->parameter; if (par) { do { if (strcmp ("NAME", par->attribute) == 0) strncpy (name, par->value, CMAXBUFFER); if (strcmp ("FILENAME", par->attribute) == 0) strncpy (filename, par->value, CMAXBUFFER); par = par->next; } while (par); } if (name) SLAttach->Add (name); else SLAttach->Add (""); if (filename) SLAttach->Add (filename); else SLAttach->Add (""); SLAttach->Add (xltoa(body->size.bytes)); } /* encapsulated message? */ if ((body->type == TYPEMESSAGE) && !strcmp (body->subtype,"RFC822") && (body = body->nested.msg->body)) { if (body->type == TYPEMULTIPART) getAttachInfo (body, oripfx, pfx, i-1, SLAttach, SLFullHeader); else {/* build encapsulation prefix */ sprintf (tmp,"%s%ld.", pfx, i); getAttachInfo (body, oripfx, tmp, (long) 0, SLAttach, SLFullHeader); } } } } char *IMAP::getAttHeaderPC (xulong nummsg, char *attid) { xulong lensource; char *pc = NULL; setError (false); if (imapstream != NIL) { pc = mail_fetch_mime (imapstream, nummsg, attid, &lensource, 0); } return pc; } void IMAP::getAttHeaderSL (xulong nummsg, char *attid, StringList *SL) { xulong lensource; char *pc = NULL; setError (false); if (imapstream != NIL) { pc = mail_fetch_mime (imapstream, nummsg, attid, &lensource, 0); PChar2SL (pc, SL); } } char *IMAP::getAttBody (xulong nummsg, char *attid, StringList *SLAttachInfo, xulong *len, bool decodificar) { xulong lensource; char *pc, *pc2; setError (false); SLAttachInfo->Clear(); if (imapstream != NIL) { if (nummsg && (nummsg <= imapstream->nmsgs)) { BODY *body; mail_fetchstructure (imapstream, nummsg, &body); if (body) { StringList *SLFullHeader; SLFullHeader = new StringList (); getAttachInfo (body, attid, NIL, (long) 0, SLAttachInfo, SLFullHeader); if (SLAttachInfo->Count() <= 0) return NULL; int codec; codec = xatoidef((char *)SLAttachInfo->getString(2).cstr(), 0); switch (codec) { case ENCBASE64: pc = mail_fetchbody (imapstream, nummsg, attid, &lensource); if (decodificar == true) { pc2 = (char *) rfc822_base64 ((xuchar *)pc, lensource, len); return pc2; } else return pc; //break; case ENCQUOTEDPRINTABLE: pc = mail_fetchbody (imapstream, nummsg, attid, &lensource); if (decodificar == true) { pc2 = (char *) rfc822_qprint ((xuchar *)pc, lensource, len); return pc2; } else return pc; //break; default: pc = mail_fetchbody (imapstream, nummsg, attid, len); return pc; //break; } } } } return NULL; } xulong IMAP::getAttSize (xulong nummsg, char *attid, StringList *SLAttachInfo) { xulong lensource; setError (false); SLAttachInfo->Clear(); lensource = 0; if (imapstream != NIL) { if (nummsg && (nummsg <= imapstream->nmsgs)) { BODY *body; mail_fetchstructure (imapstream, nummsg, &body); if (body) { StringList *SLFullHeader; SLFullHeader = new StringList (); getAttachInfo (body, attid, NIL, (long) 0, SLAttachInfo, SLFullHeader); if (SLAttachInfo->Count() <= 0) {return 0;} lensource = xatoidef((char *)SLAttachInfo->getString(8).cstr(), 0); } } } return lensource; } bool IMAP::getAttBodyToFile (xulong nummsg, char *attid, StringList *SLAttachInfo, xulong *len, char *fname, bool decodificar) { xulong lensource; char *pc, *pc2; setError (false); SLAttachInfo->Clear(); if (imapstream != NIL) { if (nummsg && (nummsg <= imapstream->nmsgs)) { BODY *body; int codec; mail_fetchstructure (imapstream, nummsg, &body); if (body) { int fd; StringList *SLFullHeader; SLFullHeader = new StringList (); getAttachInfo (body, attid, NIL, (long) 0, SLAttachInfo, SLFullHeader); if (SLAttachInfo->Count() <= 0) return false; fd = open (fname, O_WRONLY | O_CREAT, 0600); if (fd == -1) {return false;} codec = xatoidef((char *)SLAttachInfo->getString(2).cstr(), 0); switch (codec) { case ENCBASE64: pc = mail_fetchbody (imapstream, nummsg, attid, &lensource); if (decodificar == true) { pc2 = (char *) rfc822_base64 ((xuchar *)pc, lensource, len); write (fd, pc2, (xuint)*len); } else write (fd, pc, (xuint)lensource); break; case ENCQUOTEDPRINTABLE: pc = mail_fetchbody (imapstream, nummsg, attid, &lensource); if (decodificar == true) { pc2 = (char *) rfc822_qprint ((xuchar *)pc, lensource, len); write (fd, pc2, (xuint)*len); } else write (fd, pc, (xuint)lensource); break; default: pc = mail_fetchbody (imapstream, nummsg, attid, len); write (fd, pc, (xuint)*len); break; } close (fd); } } return true; } else return false; } int IMAP::setFlags (char *flags, char *pcmessages) { setError (false); if (imapstream != NIL) { if (pcmessages == NULL) return 0; mail_setflag (imapstream, pcmessages, flags); return CountChar (pcmessages, ',') + 1; } return 0; } int IMAP::clearFlags (char *flags, char *pcmessages) { setError (false); if (imapstream != NIL) { if (pcmessages == NULL) return 0; mail_clearflag (imapstream, pcmessages, flags); return CountChar (pcmessages, ',') + 1; } return 0; } int IMAP::copyMessages (char *mailboxname, char *pcmessages) { long options; TBuffer abuf; setError (false); if (imapstream != NIL) { if ((pcmessages == NULL) || (mailboxname == NULL)) return 0; /* initStr(abuf, "\'"); strcat (abuf, getBriefMailbox(mailboxname)); strcat (abuf, "\'"); */ strncpy (abuf, getBriefMailbox(mailboxname), CMAXBUFFER); options = 0; if (mail_copy_full (imapstream, pcmessages, abuf, options) == NIL) return 0; else return CountChar (pcmessages, ',') + 1; } else return 0; } int IMAP::moveMessages (char *mailboxname, char *pcmessages) { long options; TBuffer abuf; setError (false); if (imapstream != NIL) { if ((pcmessages == NULL) || (mailboxname == NULL)) return 0; strncpy (abuf, getBriefMailbox(mailboxname), CMAXBUFFER); options = CP_MOVE; if (mail_copy_full (imapstream, pcmessages, abuf, options) == NIL) return 0; else return CountChar (pcmessages, ',') + 1; } else return 0; } void IMAP::getMailboxes (StringList *SL, bool refresh) { char *pc, *pc1, *pc2; TBuffer abuf, abuf2, mbinbox; setError (false); if (refresh == true) { delete SLMailboxes; SLMailboxes = new StringList(); mail_list (NIL, "", getFullMailbox("*")); } strncpy (mbinbox, getFullMailbox("INBOX"), CMAXBUFFER); if (SLMailboxes->indexOf (mbinbox) < 0) {SLMailboxes->Add(mbinbox);} for (int i=0; iCount(); ++i) { //LOG ("mailbox %d='%s'", i, SLMailboxes->getString(i).cstr()); pc1 = strstr (SLMailboxes->getString(i).cstr(), "}"); if (pc1 != NULL) {strncpy (abuf, pc1 + 1, CMAXBUFFER);} else {strncpy (abuf, SLMailboxes->getString(i).cstr(), CMAXBUFFER);} pc = strstr (abuf, getPathToRemoteFolder()); if (pc != NULL) { pc2 = pc + strlen(getPathToRemoteFolder()); strcpy (abuf2, HTML_DCOMILLAS); strcat (abuf2, pc2); strcat (abuf2, HTML_DCOMILLAS); SL->Add (abuf2); } else { strcpy (abuf2, HTML_DCOMILLAS); strcat (abuf2, pc1 + 1); strcat (abuf2, HTML_DCOMILLAS); SL->Add (abuf2); } } sortMailboxes (SL); } bool IMAP::createMailbox (char *mailboxname) { TBuffer abuf; setError (false); if (imapstream != NIL) { strncpy (abuf, getFullMailbox(mailboxname), CMAXBUFFER); if (mail_create (imapstream, abuf) == NIL) return false; else return true; } return false; } bool IMAP::deleteMailbox (char *mailboxname) { TBuffer abuf; setError (false); if (imapstream != NIL) { if (strcmp (mailboxname, getMailboxName()) == 0) {return false;} strncpy (abuf, getFullMailbox(mailboxname), CMAXBUFFER); if (mail_delete (imapstream, abuf) == NIL) return false; else return true; } return false; } bool IMAP::renameMailbox (char *oldmailboxname, char *newmailboxname) { TBuffer abufold, abufnew; setError (false); if (imapstream != NIL) { if (strcmp (oldmailboxname, getMailboxName()) == 0) {return false;} strncpy (abufold, getFullMailbox(oldmailboxname), CMAXBUFFER); strncpy (abufnew, getFullMailbox(newmailboxname), CMAXBUFFER); if (mail_rename (imapstream, abufold, abufnew) == NIL) return false; else return true; } return false; } bool IMAP::appendMsg (char *mailbox, STRING *msg) { long L; setError (false); //LOG ("mailbox=%s", mailbox); //LOG ("getFullMailbox=%s", getFullMailbox(mailbox)); L = mail_append (imapstream, getFullMailbox(mailbox), msg); if (L == 0) return false; else return true; } //***************** MODIFIED FUNCTIONS OF IMAP LIBRARY ************************ //Options: 1 Only Personal Name, Address if Personal name not exists // 2 Only Address // 3 All void mail_fetchfrom_mod (char *s,MAILSTREAM *stream,unsigned long msgno, long length, int option) { char *t = NULL, tmp[MAILTMPLEN]; ENVELOPE *env = mail_fetchenvelope (stream,msgno); ADDRESS *adr = env ? env->from : NIL; memset (s,' ',(size_t)length); /* fill it with spaces */ s[length] = '\0'; /* tie off with null */ while (adr && !adr->host) adr = adr->next; /* get first from address from envelope */ if (adr) { switch (option) { case 1: if (!(t = adr->personal)) sprintf (t = tmp,"%.256s@%.256s",adr->mailbox, adr->host); break; case 2: sprintf (t = tmp,"%.256s@%.256s",adr->mailbox,adr->host); break; case 3: sprintf (t = tmp,"%.256s%.256s@%.256s", adr->personal, adr->mailbox, adr->host); break; } memcpy (s,t,(size_t) min (length,(long) strlen (t))); } } //Options: 1 Only Personal Name, Address if Personal name not exists // 2 Only Address // 3 All void mail_fetchto_mod (char *s,MAILSTREAM *stream,unsigned long msgno, long length, int option) { char *t = NULL, tmp[MAILTMPLEN]; ENVELOPE *env = mail_fetchenvelope (stream,msgno); ADDRESS *adr = env ? env->to : NIL; memset (s,' ',(size_t)length); /* fill it with spaces */ s[length] = '\0'; /* tie off with null */ while (adr && !adr->host) adr = adr->next; /* get first to address from envelope */ if (adr) { switch (option) { case 1: if (!(t = adr->personal)) sprintf (t = tmp,"%.256s@%.256s",adr->mailbox, adr->host); break; case 2: sprintf (t = tmp,"%.256s@%.256s",adr->mailbox,adr->host); break; case 3: sprintf (t = tmp,"%.256s%.256s@%.256s", adr->personal, adr->mailbox, adr->host); break; } memcpy (s,t,(size_t) min (length,(long) strlen (t))); } } //BUSCA EN EL BUZON ABIERTO CON CRITERIO IMAP2 //Return the number of hints in the search //Examples of criterion: // ALL SUBJECT "pepe is here" // DELETED FROM "SMITH" SINCE 1-OCT-87 // // range: ALL, ANSWERED, DELETED, FLAGGED, NEW, OLD, RECENT, SEEN, UNANSWERED, UNDELETED, UNFLAGGED, UNSEEN // imaptoken: BCC, BODY, CC, KEYWORD, SUBJECT, TEXT, TO, UNKEYWORD // from: BEFORE, FROM, ON, SINCE int IMAP::searchIMAP2 (char *range, int imaptoken, char *whatsearch, char *from, char *fecha) { TBuffer criterion; setError (false); SLSearch->Clear(); XSearch = XString (" "); if (imapstream != NIL) { initStr(criterion); if (range == NULL) {strcpy (criterion, "ALL");} else {strncpy(criterion, range, 50);} strcat (criterion, " "); switch (imaptoken) { case 1: strcat (criterion, "SUBJECT"); break; case 2: strcat (criterion, "FROM"); break; case 3: strcat (criterion, "BODY"); break; default: strcat (criterion, "TEXT"); break; } strcat (criterion, " "); if (whatsearch == NULL) {strcat (criterion, "\"NOTHING TO SEARCH\"");} else {strcat(criterion, "\""); strncat(criterion, whatsearch, 500); strcat(criterion, "\"");} if (from != NULL) { strcat (criterion, " "); strncat (criterion, from, 100); if (fecha != NULL) { strcat (criterion, " "); strncat (criterion, fecha, 100); } } mail_search (imapstream, criterion); /***** DEBUG *****/ /* DEBUG ("--%d--", imaptoken); DEBUG ("--%s--", criterion); DEBUG ("--%s--", (char *)XSearch.cstr()); DEBUG ("--%ld--", SLSearch->Count()); for (int i = 0; i < SLSearch->Count(); ++i) {DEBUG ("-%s--", (char *)SLSearch->getString(i).cstr());} */ return SLSearch->Count(); } return 0; } void IMAP::addResultToSearch (xulong msgnum) { SLSearch->Add(xltoa(msgnum)); XSearch += xltoa((int)msgnum); XSearch += " "; } bool IMAP::delMsgInSearchList (xulong msgnum) { xulong au; for (int i=0; i < SLSearch->Count(); ++i) { au = atoi((char *)SLSearch->elementAt(i).cstr()); if (au == msgnum) { SLSearch->removeElementAt (i); XSearch = XString (" "); for (int j=0; j < SLSearch->Count(); ++j) { XSearch += (char *)SLSearch->elementAt(j).cstr(); XSearch += " "; } return true; } } return false; } void IMAP::addMsgInSearchList (xulong msgnum) { SLSearch->Add(xltoa(msgnum)); XSearch = XString (" "); for (int i=0; i < SLSearch->Count(); ++i) { XSearch += (char *)SLSearch->elementAt(i).cstr(); XSearch += " "; } } xulong IMAP::getNumFirstMsgInSearch (void) { if (SLSearch->Count() <= 0) return 0; return xatoidef ((char *)SLSearch->getString(0).cstr(), 1); } bool IMAP::IsSearched (xulong nummsg) { TSBuffer stnum; strcpy (stnum, " "); strcat (stnum, xltoa (nummsg)); strcat (stnum, " "); if (strstr ((char *)XSearch.cstr(), stnum) != NULL) {return true;} else {return false;} } void IMAP::getMsgIndex (ULongList *IL) { IL->Clear(); for (int i = 0; i < ILSort->Count(); ++i) {IL->Add (ILSort->elementAt(i));} } void IMAP::setSortType (int aSortType) { if (aSortType == SortType) { if (SortReversed == true) SortReversed = false; else SortReversed = true; } SortType = aSortType; } //SORT int IMAP::Sort (void) { SEARCHPGM *spg = NULL; SORTPGM *pgm = NULL, *pgm2 = NULL; xulong i, *slst, *sl; ILSort->Clear(); if (imapstream != NIL) { if (SortType == NO_SORT) { if (SortReversed == false) {for (i = 1; i <= (unsigned long)getTotalMsgs(); ++i) {ILSort->Add (i);}} else {for (i = (unsigned long)getTotalMsgs(); i >= 1; --i) {ILSort->Add (i);}} return 0; } spg = mail_newsearchpgm (); pgm = mail_newsortpgm (); pgm2 = mail_newsortpgm (); if (SortReversed == true) {pgm->reverse = 1; pgm2->reverse = 1;} else {pgm->reverse = 0; pgm2->reverse = 0;} pgm->function = SortType; pgm->next = pgm2; if (SortType == SORTSUBJECT) SortType2 = SORTDATE; else SortType2 = SORTSUBJECT; pgm2->function = SortType2; pgm2->next = NIL; slst = mail_sort (imapstream, THECHARSET, spg, pgm, NIL); if (slst != NULL) { for (sl = slst; *sl; sl++) { if (*sl) { ILSort->Add (*sl); //DEBUG ("--Added--%d--", *sl); } } fs_give ((void **) &slst); } if (pgm != NULL) {mail_free_sortpgm (&pgm);} if (spg != NULL) {mail_free_searchpgm (&spg);} } return 0; } //Only to put INBOX in the first position of the StringList // not a true sort. void IMAP::sortMailboxes (StringList *SL) { int p; XString XS; if (SL->Count() <= 0) {return;} p = SL->indexOf (HTML_DCOMILLAS"INBOX"HTML_DCOMILLAS); if (p <= 0) {return;} XS = XString (SL->getString(0)); SL->setElementAt(XString(HTML_DCOMILLAS"INBOX"HTML_DCOMILLAS), 0); SL->setElementAt(XS, p); } void IMAP::PathTool (const char *mailbox, int *numseps, int *poslastsep) { char c; *numseps = 0; *poslastsep = -1; for (unsigned int i=0; i < strlen(mailbox); ++i) { c = (unsigned char)mailbox[i]; if (c == getDelimiter ()) {++(*numseps); *poslastsep = i;} } } char *IMAP::expandMailboxName (const char *mailbox) { XString SentMailBox; SentMailBox = XString (""); if (mailbox[0] == '/') { SentMailBox += XString (mailbox).substring(1); } else { SentMailBox += getMailboxPrefix(); SentMailBox += mailbox; } return xstrdup ((char *)SentMailBox.cstr()); } //******************************************************** //***************** CALLBACKS ************************* //******************************************************** void mm_login (NETMBX *mb, char *user, char *pwd, long trial) { strncpy (user, theimap->getUsername(), 50); strncpy (pwd, theimap->getPassword(), 50); } void mm_log (char *string, long errflg) { //DEBUG ("mm_log--%ld--%s--", errflg, string); #ifdef AVOID_IMAP_MSG_MAILBOXVULNERABLE if (strstr (string, "Mailbox vulnerable") != NULL) {return;} #endif if ((errflg == (long)2) || (errflg == (long)1)) {theimap->setError (true); theimap->setErrorString (string);} if (theimap->isDebug() == true) {printf ("mm_log=%ld %s\n", errflg, string); fflush(stdout);} } void mm_dlog (char *string) { //DEBUG ("mm_dlog--%s--", string); if (theimap->isDebug() == true) {printf ("mm_dlog=%s\n", string); fflush(stdout);} } void mm_fatal (char *string) { theimap->setError (true); theimap->setErrorString (string); if (theimap->isDebug() == true) {printf ("mm_fatal=%s\n", string); fflush(stdout);} } void mm_status (MAILSTREAM *imapstream, char *mailbox, MAILSTATUS *status) { if (theimap->isDebug() == true) { printf ("Mailbox %s",mailbox); if (status->flags & SA_MESSAGES) printf (", %lu messages",status->messages); if (status->flags & SA_RECENT) printf (", %lu recent",status->recent); if (status->flags & SA_UNSEEN) printf (", %lu unseen",status->unseen); if (status->flags & SA_UIDVALIDITY) printf (", %lu UID validity", status->uidvalidity); if (status->flags & SA_UIDNEXT) printf (", %lu next UID",status->uidnext); printf ("\n"); } } void mm_list (MAILSTREAM *imapstream, int delim, char *name, long attrib) { //LOG ("mm_list name=%s,delim=%d,attrib=%ld", name, delim, attrib); if (delim > 0) {theimap->setDelimiter(delim);} if (theimap->isDebug() == true) { printf ("MAILBOX=%d %s %ld\n", delim, name, attrib); if (attrib & LATT_NOSELECT) printf (" no select\n"); if (attrib & LATT_NOINFERIORS) printf (" no inferiors\n"); if (attrib & LATT_MARKED) printf (" marked\n"); if (attrib & LATT_UNMARKED) printf (" unmarked\n"); } if (attrib & LATT_NOSELECT) {} else { if (name != NULL) { theimap->addMailbox (name); } } } void mm_notify (MAILSTREAM *imapstream, char *string, long errflg) { //LOG ("notify='%s',errflg=%ld", string, errflg); #ifdef AVOID_IMAP_MSG_MAILBOXVULNERABLE if (strstr (string, "Mailbox vulnerable") != NULL) {return;} #endif if ((errflg == (long)2) || (errflg == (long)1)) {theimap->setError (true); theimap->setErrorString (string);} mm_log (string, errflg); } long mm_diskerror (MAILSTREAM *imapstream, long errcode, long serious) { theimap->setError (true); theimap->setErrorString ("Disk Error"); kill (getpid (), SIGSTOP); return NIL; } void mm_searched (MAILSTREAM *imapstream, xulong number) { theimap->addResultToSearch (number); } //NO USED CALLBACKS void mm_critical (MAILSTREAM *imapstream) {} void mm_nocritical (MAILSTREAM *imapstream) {} void mm_exists (MAILSTREAM *imapstream, xulong number) {} void mm_expunged (MAILSTREAM *imapstream, xulong number) {} void mm_lsub (MAILSTREAM *imapstream, int delim, char *name, long attrib) {} void mm_flags (MAILSTREAM *imapstream, xulong number) {}