2 * CDE - Common Desktop Environment
4 * Copyright (c) 1993-2012, The Open Group. All rights reserved.
6 * These libraries and programs are free software; you can
7 * redistribute them and/or modify them under the terms of the GNU
8 * Lesser General Public License as published by the Free Software
9 * Foundation; either version 2 of the License, or (at your option)
12 * These libraries and programs are distributed in the hope that
13 * they will be useful, but WITHOUT ANY WARRANTY; without even the
14 * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
15 * PURPOSE. See the GNU Lesser General Public License for more
18 * You should have received a copy of the GNU Lesser General Public
19 * License along with these libraries and programs; if not, write
20 * to the Free Software Foundation, Inc., 51 Franklin Street, Fifth
21 * Floor, Boston, MA 02110-1301 USA
27 * $TOG: RFCImpl.hh /main/22 1998/10/01 17:28:08 mgreess $
29 * RESTRICTED CONFIDENTIAL INFORMATION:
31 * The information in this document is subject to special
32 * restrictions in a confidential disclosure agreement bertween
33 * HP, IBM, Sun, USL, SCO and Univel. Do not distribute this
34 * document outside HP, IBM, Sun, USL, SCO, or Univel wihtout
35 * Sun's specific written approval. This documment and all copies
36 * and derivative works thereof must be returned or destroyed at
39 * Copyright 1993 Sun Microsystems, Inc. All rights reserved.
44 #ifndef I_HAVE_NO_IDENT
50 #include <DtMail/Buffer.hh>
51 #include <DtMail/DtMail.hh>
52 #include <DtMail/DtMailServer.hh>
53 #include <DtMail/FileShare.hh>
54 #include <DtMail/Threads.hh>
56 #include <sys/param.h>
57 #include <sys/types.h>
58 #include <sys/types.h>
62 #if defined(NEED_MMAP_WRAPPER)
66 #if defined(NEED_MMAP_WRAPPER)
71 // Structs needed to exec sendmail
72 typedef struct waitentry {
73 struct waitentry * next;
76 SubProcessFinishedProc * proc;
79 typedef struct pipedata {
85 DTMBX_LONGLOCK_FAILED_CANCEL, // failed to obtain lock, cancel operation
86 DTMBX_LONGLOCK_FAILED_READONLY, // failed to obtain lock, open read only
87 DTMBX_LONGLOCK_FAILED_READWRITE, // failed to obtain lock,
88 // open read write [user locking override]
89 DTMBX_LONGLOCK_SUCCESSFUL // obtained the lock
96 class RFCMessage : public DtMail::Message {
98 RFCMessage(DtMailEnv & error,
99 DtMail::MailBox * parent,
100 const char ** start, // Also returns the end of the message.
101 const char * end_of_file);
103 RFCMessage(DtMailEnv & error,
104 const char * alt_start,
105 const char * alt_end);
107 RFCMessage(DtMailEnv & error,
108 DtMail::Session * session,
109 DtMailObjectSpace space,
114 virtual ~RFCMessage(void);
116 virtual DtMail::Envelope * getEnvelope(DtMailEnv &);
118 // This should only be used when you REALLY need to know
119 // how many body parts are present before actually traversing
120 // the body parts (i.e. like when writing a MIME format message).
121 virtual int getBodyCount(DtMailEnv &);
123 virtual DtMail::BodyPart * getFirstBodyPart(DtMailEnv &);
124 virtual DtMail::BodyPart * getNextBodyPart(DtMailEnv &,
127 virtual DtMail::BodyPart * newBodyPart(DtMailEnv &,
131 virtual void newBodyPartOrder(DtMailEnv &,
134 #endif /* DEAD_WOOD */
136 virtual void setFlag(DtMailEnv &,
137 const DtMailMessageState);
139 virtual void resetFlag(DtMailEnv &,
140 const DtMailMessageState);
142 virtual DtMailBoolean flagIsSet(DtMailEnv &,
143 const DtMailMessageState);
145 virtual time_t getDeleteTime(DtMailEnv &);
147 virtual void toBuffer(DtMailEnv & error, DtMailBuffer &);
149 virtual const char * impl(DtMailEnv &);
151 // Methods following this point are specific to RFCMessage.
153 void markDirty(const int delta);
155 void fixMessageLocation(char ** msgHeaderStart, long & msgHeaderLen,
156 char ** msgBodyStart, long &msgBodyLen,
157 int & msgTemporary, long & msgBodyOffset);
159 void unfixMessageLocation(char *msgStart, int msgTemporary);
161 void adjustMessageLocation(
168 void pinMessageDown(char ** msgHeaderStart, long & msgHeaderLen,
169 char ** msgBodyStart, long &msgBodyLen);
171 RFCMailBox * parent(void) { return (RFCMailBox *)_parent; }
174 unsigned long _object_signature;
175 const char * _msg_start;
176 const char * _msg_end;
177 const char * _body_start;
178 SafeScalar<int> _dirty;
179 DtMailBuffer *_msg_buf;
181 struct BodyPartCache : public DtCPlusPlusAllocator {
183 const char * body_start;
186 DtVirtArray<BodyPartCache *> _bp_cache;
188 // _alternativeMultipart -- does message contain alternative messages?
189 // If DTM_FALSE: this message does not contain alternative messages.
190 // .. can ignore: _alt_msg_cache, _alternativeValid
191 // If DTM_TRUE: this message does contain alternative messages.
192 // The body part cache is allocated; however, the pointers within
193 // the cache are copied from the latest valid alternative message
194 // within the alternative message cache, and so should not be
195 // deleted when a message is destroyed and this is true.
196 // The alternative message cache (_alt_msg_cache) contains one or
197 // more messages that map 1 to 1 with the corresponding alternative
198 // messages contained within the entire message.
200 DtMailBoolean _alternativeMultipart;
202 // _alternativeMessage -- is this message an alternative message?
203 // If DTM_FALSE: this is not an alternative message but rather a real
204 // message -- _msg_start, _msg_end, _body_start, etc. are valid.
205 // If DTM_TRUE: this message is an alternative message; _msg_start,
206 // _msg_end, _body_start, etc. demark the alternative message within
207 // the entire real message. The body part cache is fully allocated and
208 // represents all body parts contained within this alternative message.
210 DtMailBoolean _alternativeMessage;
212 // _alternativeValid -- is this alternative message part valid?
213 // If DTM_FALSE: this alternative cannot be displayed or otherwise
214 // acted upon on this system
215 // If DTM_TRUE: this alternative can be displayed or otherwise
216 // acted upon on this system
218 DtMailBoolean _alternativeValid;
220 // _alt_msg_cache is the "alternative message cache", an array of
221 // MIMEBodyParts an RFCMessages, which have _alternativeMessage
222 // set, and contain only those body parts that are associated with a
223 // single alternative message. There is one entry in the array for
224 // each alternative message within the entire message. Each alternative
225 // message will have _alternativeMessage == DTM_TRUE.
226 // This cache is present only if _alternativeMultipart == DTM_TRUE.
228 struct AlternativeMessageCache : public DtCPlusPlusAllocator {
229 RFCMessage * amc_msg; // -> RFCMessage for alternative
230 RFCBodyPart * amc_body; // -> MIMEBodyPart for alternative
231 const char * amc_body_start; // -> first byte of body
232 const char * amc_body_end; // -> last byte of body
235 DtVirtArray<AlternativeMessageCache *> _alt_msg_cache;
237 DtMail::BodyPart * bodyPart(DtMailEnv & error, const int slot);
239 int lookupByBody(DtMail::BodyPart *);
241 const char * parseMsg(DtMailEnv &, const char * end_of_file);
242 const char * findMsgEnd(DtMailEnv &, const char * end_of_file);
243 void parseBodies(DtMailEnv &);
244 void parseMIMEBodies(DtMailEnv &);
245 void parseMIMETextPlain(DtMailEnv &);
246 void parseMIMEMultipartSubtype(DtMailEnv &, const char * subtype);
247 void parseMIMEMessageSubtype(DtMailEnv &, const char * subtype);
248 void parseMIMEMessageExternalBody(DtMailEnv &);
249 void parseMIMEMultipartMixed(DtMailEnv &, const char * boundary);
250 void parseMIMEMultipartAlternative(DtMailEnv &, const char * boundary);
251 void parseV3Bodies(DtMailEnv &);
253 void writeMsg(char * buffer);
255 int sizeMIMEBodies(DtMailEnv &);
256 int sizeV3Bodies(DtMailEnv &);
258 char * extractBoundary(const char * content_type);
259 DtMailBoolean hasHeaders(const char * buf, const unsigned long size);
261 // This friend declaration is used temporarily by copyMsg to copy
262 // messages from RFC->RFC. A more general solution is needed for
264 friend class RFCMailBox;
267 class RFCEnvelope : public DtMail::Envelope {
269 RFCEnvelope(DtMailEnv & error,
270 DtMail::Message * parent,
274 virtual ~RFCEnvelope(void);
276 virtual DtMailHeaderHandle getFirstHeader(DtMailEnv &,
278 DtMailValueSeq & value);
280 virtual DtMailHeaderHandle getNextHeader(DtMailEnv &,
281 DtMailHeaderHandle last,
283 DtMailValueSeq & value);
285 virtual void getHeader(DtMailEnv &,
287 const DtMailBoolean abstract,
288 DtMailValueSeq & value);
290 virtual void setHeaderSeq(DtMailEnv &,
292 const DtMailValueSeq &) {} ;
294 // The last parameter is left to the client to provide
295 // because it can not be done in a type safe manner.
297 virtual void setHeader(DtMailEnv &,
302 virtual void removeHeader(DtMailEnv &,
305 // Methods below this point are specific to RFCEnvelope.
307 int dirty(void) { return _dirty; }
309 void adjustHeaderLocation(char * headerStart, int headerLength);
311 char *writeHeaders(char *buf);
313 const char * headerLocation(void) { return _header_text; }
315 long headerLength(void) { return _header_len; }
317 const char * unixFrom(DtMailEnv &, int & length);
319 // fix for the defect 177527
320 // when a reply-to field is in a message headers, the reply-to is
321 // going to be displayed as the send in RMW's msg list scrolled window
322 // instead of the real sender. The following three public methods are
323 // going to access _use_reply_to.
325 void setUseReplyTo(void) { _use_reply_to = DTM_TRUE; }
326 void unsetUseReplyTo(void) { _use_reply_to = DTM_FALSE; }
327 DtMailBoolean getUseReplyTo(void) { return _use_reply_to; }
332 DtMailBoolean _use_reply_to;
333 unsigned long _object_signature;
334 SafeScalar<int> _dirty;
336 struct ParsedHeader : public DtCPlusPlusAllocator {
339 const char *name_start;
341 const char *value_start;
343 int alloc_mask; // Tracks updates to value.
347 const char * _header_text;
349 DtVirtArray<ParsedHeader *> _parsed_headers;
352 void getTransportHeader(DtMailEnv & error,
354 DtMailValueSeq & value);
356 DtMailBoolean matchName(const ParsedHeader &, const char *);
358 void parseUnixFrom(DtMailEnv &,
359 const ParsedHeader &,
360 DtMailValueSeq & value);
362 void parseUnixDate(DtMailEnv &,
363 const ParsedHeader &,
364 DtMailValueSeq & value);
366 void makeValue(DtMailEnv &,
367 const ParsedHeader &,
368 DtMailValueSeq & value);
370 void makeReply(DtMailEnv &,
372 DtMailValueSeq & value);
374 DtMailBoolean metooAddr(DtMailValueAddress & addr,
375 DtMailAddressSeq & alts,
376 DtMailBoolean allnet);
378 void parseHeaders(void);
380 int lookupHeader(const char * name, DtMailBoolean real_only = DTM_FALSE);
381 const char * mapName(const char * name);
384 class RFCBodyPart : public DtMail::BodyPart {
386 RFCBodyPart(DtMailEnv &,
387 DtMail::Message * parent,
390 RFCEnvelope * body_env);
392 virtual void lockContents(DtMailEnv &, const DtMailLock);
393 virtual void unlockContents(DtMailEnv &);
395 virtual void getContents(DtMailEnv &,
396 const void ** contents,
397 unsigned long * length,
401 char ** description);
403 virtual void setContents(DtMailEnv &,
404 const void * contents,
405 const unsigned long length,
409 const char * description);
411 virtual void setFlag(DtMailEnv &,
412 DtMailBodyPartState);
414 virtual void resetFlag(DtMailEnv &,
415 DtMailBodyPartState);
417 virtual DtMailBoolean flagIsSet(DtMailEnv &,
418 DtMailBodyPartState);
420 virtual time_t getDeleteTime(DtMailEnv &);
422 virtual void getHeader(DtMailEnv &,
424 const DtMailBoolean abstract,
425 DtMailValueSeq & value);
428 //---------------------------------------------------
429 // These methods are duplicated in class BodyPart (also being implemented
430 // in class Session) because RFCFormat and RFCBodyPart need to access
431 // them. Duplicating routines like what is being done here is a workaround
432 // for an implementation bug/hole because there is no class where global
433 // routines can be defined (and be accessed by any class).
434 // class Session is not a proper place to put (global) methods because
435 // not every class can get at Session.
436 // RFCFormat accesses these routines through its private Session handle.
437 // RFCBodyPart does not have a Session handle. Hence the need to duplicate
438 // the following routines.
440 virtual int OpenLcxDb(void);
441 virtual void DtXlateStdToOpLocale(char *op, char *std, char *dflt,
443 virtual void DtXlateOpToStdLocale(char *op, char *opLoc, char **retLoc,
444 char **ret_retLang, char **retSet);
445 virtual void DtXlateStdToOpCodeset(char *op, char *std, char *dflt,
447 virtual void DtXlateMimeToIconv(const char *, const char *, const char *,
449 virtual void DtXlateLocaleToMime(const char *, const char *,
450 const char *, char **);
452 virtual char *csToConvName(char *);
453 virtual char *locToConvName();
454 virtual char *targetConvName();
455 virtual char *targetTagName();
456 virtual int csConvert(char **, unsigned long &, int, char *, char *);
457 //---------------------------------------------------
459 // Implement in both MIMEBodyPart and V3BodyPart
460 virtual char *csFromContentType(DtMailValueSeq & value) = 0;
461 // End of For CHARSET
464 virtual DtMailChecksumState checksum(DtMailEnv &) = 0;
465 #endif /* DEAD_WOOD */
467 // Methods below this point are specific to RFCBodyPart.
469 virtual char *writeBodyParts(char * buf) = 0;
471 void adjustBodyPartsLocation(char * start);
473 virtual int rfcSize(const char * boundary, DtMailBoolean &) = 0;
477 DtMailBoolean isTerm(const char *); // Determines if we have an eol.
481 // _body_start includes any boundaries.
482 const char * _body_start;
484 // _body_text is where the text of the body begins, after
485 // boundaries, headers, and other uninteresting stuff.
487 const char * _body_text;
489 RFCEnvelope * _body_env;
490 DtMailBoolean _my_env; // True if we made the envelope.
491 SafeScalar<int> _dirty;
493 friend class RFCMessage;
495 // The following entries are a computed cache. They
496 // are built in a lazy fashion, based on the caller's
497 // requests. These entries can be very expensive to
498 // compute so lazy is important.
501 DtMailBoolean _must_free_body;
502 int _body_decoded_len;
505 // The sub classes implement these because they are the major difference
506 // in the get/set contents methods.
508 virtual void getContentType(DtMailEnv &, char**) = 0;
509 virtual void getDtType(DtMailEnv &) = 0;
510 virtual void loadBody(DtMailEnv &) = 0;
511 virtual char * getDescription(DtMailEnv &) = 0;
512 virtual char * getName(DtMailEnv &) = 0;
513 virtual void setName(DtMailEnv &, const char *) = 0;
514 virtual unsigned long getLength(DtMailEnv &) = 0;
515 virtual const void * getBody(DtMailEnv &);
518 class MIMEBodyPart : public RFCBodyPart {
520 MIMEBodyPart(DtMailEnv &,
521 DtMail::Message * parent,
524 RFCEnvelope * body_env);
526 MIMEBodyPart(DtMailEnv &,
527 DtMail::Message * parent,
530 const char * boundary);
533 virtual DtMailChecksumState checksum(DtMailEnv &);
534 #endif /* DEAD_WOOD */
536 char *writeBodyParts(char * buf);
538 int rfcSize(const char * boundary, DtMailBoolean &);
541 virtual char *csFromContentType(DtMailValueSeq & value);
543 char * parameterValue(
544 DtMailValueSeq & value,
545 const char* parameter,
546 DtMailBoolean isCaseSensitive);
549 friend RFCMessage::~RFCMessage(void);
552 void getContentType(DtMailEnv &, char **);
553 void getDtType(DtMailEnv &);
554 void loadBody(DtMailEnv &);
555 char * getDescription(DtMailEnv &);
556 char * getName(DtMailEnv &);
557 void setName(DtMailEnv &, const char *);
558 char * getNameHeaderVal(DtMailEnv &);
559 unsigned long getLength(DtMailEnv &);
560 const void * getBody(DtMailEnv &);
563 class V3BodyPart : public RFCBodyPart {
565 V3BodyPart(DtMailEnv &,
566 DtMail::Message * parent,
569 RFCEnvelope * body_env);
571 V3BodyPart(DtMailEnv &,
572 DtMail::Message * parent,
577 virtual DtMailChecksumState checksum(DtMailEnv &);
578 #endif /* DEAD_WOOD */
580 char *writeBodyParts(char * buf);
582 int rfcSize(const char * boundary, DtMailBoolean &);
585 virtual char *csFromContentType(DtMailValueSeq & value);
588 friend RFCMessage::~RFCMessage(void);
591 void getContentType(DtMailEnv &, char **);
592 void getDtType(DtMailEnv &);
593 void loadBody(DtMailEnv &);
594 char * getDescription(DtMailEnv &);
595 char * getName(DtMailEnv &);
596 void setName(DtMailEnv &, const char *);
597 unsigned long getLength(DtMailEnv &);
600 class RFCMailBox : public DtMail::MailBox
604 RFCMailBox(DtMailEnv &,
605 DtMail::Session * session,
606 DtMailObjectSpace space,
610 const char * impl_name);
612 virtual ~RFCMailBox(void);
614 static void appendCB(DtMailEnv&, char *buf, int len, void *clientData);
615 virtual void append(DtMailEnv &error, char *buf, int len);
616 virtual void create(DtMailEnv & error, mode_t = DTMAIL_DEFAULT_CREATE_MODE);
617 virtual void open(DtMailEnv &,
618 DtMailBoolean auto_create = DTM_TRUE,
619 int open_mode = DTMAIL_DEFAULT_OPEN_MODE,
620 mode_t create_mode = DTMAIL_DEFAULT_CREATE_MODE,
621 DtMailBoolean lock_flag = DTM_TRUE,
622 DtMailBoolean auto_parse = DTM_TRUE);
624 virtual void unlock();
627 virtual void callCallback(DtMailCallbackOp, void *);
628 virtual void disableMailRetrieval()
629 { _mr_allowed = DTM_FALSE; }
630 virtual void enableMailRetrieval()
631 { _mr_allowed = DTM_TRUE; }
632 virtual void checkForMail(
635 already_locked = DTM_FALSE);
636 virtual void clearMessageSummary(DtMailHeaderLine &);
637 virtual void copyMessage(DtMailEnv &, DtMail::Message *);
638 virtual void copyMailBox(DtMailEnv &, DtMail::MailBox *);
639 virtual void createMailRetrievalAgent(char *passwd=NULL);
640 virtual void deleteMailRetrievalAgent();
641 virtual void expunge(DtMailEnv &);
642 virtual DtMail::Message *getFirstMessage(DtMailEnv &);
643 virtual DtMailMessageHandle getFirstMessageSummary(
645 const DtMailHeaderRequest &,
647 virtual DtMail::Message *getNextMessage(DtMailEnv &, DtMail::Message *);
648 virtual DtMailMessageHandle getNextMessageSummary(
651 const DtMailHeaderRequest &,
653 virtual DtMail::Message *getMessage(DtMailEnv &, DtMailMessageHandle);
654 virtual void getMessageSummary(
657 const DtMailHeaderRequest &,
659 virtual const char *impl(DtMailEnv & error);
661 virtual int messageCount(DtMailEnv &);
662 #endif /* DEAD_WOOD */
663 virtual DtMail::Message *newMessage(DtMailEnv &);
664 virtual DtMailCallbackOp retrieveNewMail(DtMailEnv&);
665 virtual void updateMailRetrievalPassword(char *passwd=NULL);
667 // This is not used by any clients!
668 struct MapRegion : public DtCPlusPlusAllocator
671 unsigned long map_size;
672 char * file_region; // Where the parsing begins.
673 unsigned long file_size;
677 struct MessageCache : public DtCPlusPlusAllocator {
679 DtMailBoolean delete_pending;
682 // Methods below this point are specific to RFCMailBox.
683 void markDirty(const int delta);
684 void startAutoSave(DtMailEnv & error, DtMailBoolean start=DTM_TRUE);
688 struct NewMailData : public DtCPlusPlusAllocator
691 Condition * object_valid;
694 // Content-Type: message/partial support.
699 unsigned int total; // 0 == I do not know.
703 // Keep track of how many messages, and whether we've hit the
704 // EOF. The number of messages is a condition variable because
705 // we might have multiple threads trying to read the state
706 // while the parsing thread is reading the state.
710 SafeScalar<int> _dirty; // Write access/dirty state.
711 DtMailBoolean _dot_lock_active;
712 DtMailBoolean _errorLogging; // Extra logging done??
714 SafeScalar<unsigned long> _file_size;
715 const char *_impl_name; // Might be V3 or MIME.
716 int _last_check; // For polling only.
717 time_t _last_poll; // For polling only.
719 DtMailBoolean _lock_flag;
720 FileShare *_lock_obj;
721 DtMailBoolean _lockf_active; // lockf() is being held
722 char * _lockFileName; // lock file name for mailbox
723 DtMailBoolean _long_lock_active;
726 DtVirtArray<MapRegion *> _mappings;
727 unsigned long _object_signature;
728 Condition *_object_valid;
729 DtMailBoolean _parsed;
731 DtMailBoolean _mr_allowed;
733 DtMailServer *_mra_server;
735 DtVirtArray<MessageCache *> _msg_list;
736 _partialData **_partialList;
737 unsigned int _partialListCount;
739 NewMailData *_thread_info;
740 DtMailBoolean _tt_lock;
741 char * _uniqueLockId; // unique id for .lock files
742 int _uniqueLockIdLength;
743 DtMailBoolean _use_dot_lock;
745 // void CheckPointEvent(DtMailEnv & error);
746 void CheckPointEvent();
747 void ExpungeEvent(DtMailBoolean closing = DTM_FALSE);
748 void NewMailEvent(const DtMailBoolean already_locked = DTM_FALSE);
751 static void *ThreadNewMailEntry(void *);
752 static void *ThreadParseEntry(void *);
754 RFCMessage *_assemblePartial(DtMailEnv &error,RFCMessage *Message);
756 _isPartial(DtMailEnv &error, RFCMessage *message);
758 addressIsMapped(void *addressToCheck);
759 #if defined(__linux__)
760 void alterPageMappingAdvice(MapRegion *map, int advice = 0);
762 void alterPageMappingAdvice(
764 int advice = MADV_SEQUENTIAL);
766 int createTemporaryMailboxFile(DtMailEnv &, char *tmp_name);
767 void checkLockFileOwnership(DtMailEnv &);
768 void dotDtmailLockFile(char *, int);
769 void dotDtmailLock(DtMailEnv &);
770 void dotDtmailUnlock(DtMailEnv &);
771 void dumpMaps(const char *);
772 char *generateLockFileName(void);
773 char *generateUniqueLockId(void);
776 const DtMailBoolean already_locked = DTM_FALSE);
777 time_t linkLockFile(DtMailEnv &, char *tempLockFileName);
778 void lockFile(DtMailEnv &);
779 void lockNewMailboxFile(int new_fd);
781 longLock(DtMailEnv &);
782 void longUnlock(DtMailEnv &);
783 int lookupByMsg(RFCMessage * msg);
784 void mailboxAccessHide(char *prefix);
785 void mailboxAccessShow(time_t mtime, char *prefix);
786 void makeHeaderLine(DtMailEnv & error,
788 const DtMailHeaderRequest & request,
790 int mapFile(DtMailEnv & error,
791 const DtMailBoolean already_locked = DTM_FALSE,
792 mode_t create_mode = DTMAIL_DEFAULT_CREATE_MODE);
793 MapRegion *mapNewRegion(DtMailEnv &, int fd, unsigned long bytesWritten);
794 int nextNotDel(const int cur);
795 void openRealFile(DtMailEnv &error, int mode, mode_t create_mode);
796 int prevNotDel(const int cur);
797 void parseFile(DtMailEnv & error, int slot);
798 off_t realFileSize(DtMailEnv &error, struct stat *stat_buffer = NULL);
799 void transferLock(int old_fd, int new_fd);
800 void unlockOldMailboxFile(int old_fd);
801 void unlockFile(DtMailEnv &, int fd);
802 void waitForMsgs(int needed);
803 void writeMailBox(DtMailEnv&, DtMailBoolean);
804 void writeToDumpFile(const char* format, ...);
807 class RFCTransport : public DtMail::Transport {
809 RFCTransport(DtMailEnv &, DtMail::Session *, DtMailStatusCallback, void *,
811 virtual ~RFCTransport(void);
813 virtual DtMailOperationId submit(DtMailEnv &,
815 DtMailBoolean log_msg);
817 static void arpaPhrase(const char * list, DtMailAddressSeq & tokens);
819 // SendMsgDialog initiates a send. It needs to set information
820 // needed to exec sendmail by calling these initialization functions.
821 // getSendmailReturnProc returns a handler so that SendMsgDialog
822 // can use it in XtAppAddInput.
823 virtual void initTransportData(int fds[2],
824 SubProcessFinishedProc proc, void *ptr);
825 virtual void *getSendmailReturnProc(void);
829 Condition * _object_valid;
832 struct ThreadSimpleData : public DtCPlusPlusAllocator {
837 const char * subject;
840 static void * ThreadSimpleEntry(void * arg);
842 void format(DtMailEnv &, DtMail::Message * msg, DtMailBoolean log_msg);
843 void formatSimple(DtMailEnv &,
847 const char * subject,
850 void deliver(DtMailEnv &,
854 DtMailBoolean log_msg,
858 void launchSendmail(DtMailEnv & error,
863 char * concatValue(DtMailValueSeq &);
864 void appendAddrs(DtMailAddressSeq & to, DtMailAddressSeq & from);
865 void skinFiles(DtMailAddressSeq &);
866 char * addrToString(DtMailAddressSeq &);
867 int openLogFile(const char * path);
868 void closeLogFiles(int * files, int file_cnt);
870 // These functions are needed to exec sendmail
871 static void childHandler(void);
872 void signalRegister(void);
873 int startSubprocess(DtMailEnv &error, char * cmd,
874 Buffer & headers, Buffer & bodies, char **argv);
875 static void sendmailReturnProc(void);
877 // Store info from SendMsgDialog
878 // ptr to SendMsgDialog::SendmaliErrorProc
879 SubProcessFinishedProc *_error_proc;
880 // a pointer to SendMsgDialog
882 // get the status from the low and hi bytes returned from wait()
883 inline static int lowByte (int status) { return (status & 0377); }
884 inline static int highByte (int status) { return (lowByte(status >> 8)); }
887 extern const char * RFCDeleteHeader;
889 class RFCValue : public DtMailValue {
891 RFCValue(const char * str, int size, DtMail::Session *s);
892 RFCValue(const char * str, int size);
895 virtual operator const char *(void);
897 virtual const char * operator= (const char *);
899 virtual DtMailValueDate toDate(void);
901 virtual void fromDate(const DtMailValueDate &) { }
902 #endif /* DEAD_WOOD */
904 virtual DtMailAddressSeq * toAddress(void);
906 virtual void fromAddress(const DtMailAddressSeq &) { }
907 #endif /* DEAD_WOOD */
908 virtual const char * raw(void);
911 DtMail::Session *_session;
914 void decodeValue(void);