remove OSF1 support
[oweals/cde.git] / cde / programs / dtmail / include / DtMail / DtMail.hh
1 /*
2  * CDE - Common Desktop Environment
3  *
4  * Copyright (c) 1993-2012, The Open Group. All rights reserved.
5  *
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)
10  * any later version.
11  *
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
16  * details.
17  *
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
22  */
23 /*
24  *+SNOTICE
25  *
26  *
27  *      $TOG: DtMail.hh /main/18 1998/11/10 17:02:07 mgreess $
28  *
29  *      RESTRICTED CONFIDENTIAL INFORMATION:
30  *      
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
37  *      Sun's request.
38  *
39  *      Copyright 1993 Sun Microsystems, Inc.  All rights reserved.
40  *
41  *+ENOTICE
42  */
43 #ifndef I_HAVE_NO_IDENT
44 #endif
45
46 #ifndef _DTMAIL_HH
47 #define _DTMAIL_HH
48
49 #include <stdio.h>
50 #include <stdarg.h>
51 #if defined(sun) || defined(__FreeBSD__)
52 #include <iconv.h>
53 #endif
54 #include <sys/stat.h>
55 /*#include <nl_types.h>*/
56 #include <DtMail/DtMailError.hh>
57 #include <DtMail/DtMailProps.h>
58 #include <DtMail/DtMailTypes.h>
59 #include <DtMail/DtVirtArray.hh>
60 #include <DtMail/DtLanguages.hh>
61 #include <Tt/tttk.h>
62 #include <fcntl.h>
63
64 // Define a type for the handler used in RFCTransport::launchSendmail
65 typedef void SubProcessFinishedProc (int pid, int status, void *data);
66
67 //
68 // Gorp to get mailrc to work
69 //
70 #define HSHSIZE 40
71 #define MAILRC_NOFILE          20      /* this define is here for      */
72                                 /* compatibility purposes only  */
73                                 /* and will be removed in a     */
74                                 /* later release                */
75
76 // enums cannot be declared inside of classes because the enum scope rules
77 // changed from V2 to V3 compilers causing incompatibilities
78 //
79 enum DtmFileLocality {
80   Dtm_FL_UNKNOWN,               // cannot determine file locality
81   Dtm_FL_LOCAL,                 // file is local to this system (eg ufs)
82   Dtm_FL_LOCAL_AND_REMOTE,      // file is remote with local copy (eg cachefs)
83   Dtm_FL_REMOTE                 // file is remote (e.g. nfs)
84 };
85
86 class DtMail {
87   public:
88     
89     // Returns the minor code set by a DtMail routine. This method
90     // should only be called if error._major is not NO_EXCEPTION.
91     //
92     //  Parameters:
93     //    error - The environment returned from any DtMail method.
94     //
95     //  Returns - The error code as defined in DtMailError.h
96     //
97     static DTMailError_t getMinorCode(DtMailEnv & error);
98     
99     // Returns the internationalized error text for an error. This
100     // method should only be called if error._major is not NO_EXCEPTION.
101     //
102     // Parameters:
103     //  error - The environment returned from any DtMail method.
104     //
105     // Returns - The error text string. This string is valid until
106     //    error.clear() is called on the error.
107     //
108     static const char * getErrorString(DtMailEnv & error);
109
110     // Determine locality of referenced path object
111     // This is not part of the public interface, do not call
112     // as a client of this class.
113     static enum DtmFileLocality DetermineFileLocality(const char * path);
114
115     class MailBox;
116     class Message;
117     class Transport;
118
119     class MailRc;
120
121     class Session : public DtCPlusPlusAllocator {
122       public:
123             Session(DtMailEnv &, const char * app_name);
124             ~Session(void);
125             
126             const char ** enumerateImpls(DtMailEnv & error);
127             void setDefaultImpl(DtMailEnv & error, const char * impl);
128             const char * getDefaultImpl(DtMailEnv & error);
129             void queryImpl(DtMailEnv & error,
130                            const char * impl,
131                            const char * capability,
132                            ...);
133             void queryImplV(DtMailEnv & error,
134                             const char * impl,
135                             const char * capability,
136                             va_list args);
137
138             // Create a mail box object, after selecting an implementation.
139             MailBox * mailBoxConstruct(DtMailEnv & error,
140                                        DtMailObjectSpace space,
141                                        void * arg,
142                                        DtMailCallback open_callback,
143                                        void * client_data,
144                                        const char * impl = NULL);
145
146             Message * messageConstruct(DtMailEnv & error,
147                                        DtMailObjectSpace space,
148                                        void * arg,
149                                        DtMailCallback open_callback,
150                                        void * client_data,
151                                        const char * impl = NULL);
152
153             // Create a transport object after selecting an implementation.
154             Transport * transportConstruct(DtMailEnv & error,
155                                            const char * impl,
156                                            DtMailStatusCallback call_back,
157                                            void * client_data);
158
159             // Retrieve a copy of the MailRc handle.
160             MailRc * mailRc(DtMailEnv & error);
161
162             // The following methods set up the polling requirements for
163             // the DtMail library.
164             //
165             DtMailBoolean pollRequired(DtMailEnv & error);
166
167             int eventFileDesc(DtMailEnv & error);
168
169             void poll(DtMailEnv & error);
170
171             // The expandPath method will turn a relative path, with
172             // variable's into an absolute path, relative to the current
173             // network node.
174             //
175             char * expandPath(DtMailEnv & error, const char * path);
176             char * getRelativePath(DtMailEnv & error, const char * path);
177
178             // Accessors to session data.
179             const char * appName(void) const { return _app_name; }
180             char * ttChannel(void) const { return _tt_channel; }
181             int ttFile(void) const { return _tt_fd; }
182
183             // Meta factory type. This method gives access to the
184             // factory and the implementations specific query
185             // mechanisms.
186             typedef void * (*MetaImplFactory)(const char * operation);
187
188             // The setError method needs to be here so it can be accessed
189             // by the drivers.
190             //
191             void setError(DtMailEnv & error, const DTMailError_t);
192
193             // Add an event routine.
194             void addEventRoutine(DtMailEnv &,
195                                  DtMailEventFunc,
196                                  void * client_data,
197                                  time_t interval);
198
199             // Remove an event routine.
200             void removeEventRoutine(DtMailEnv &,
201                                     DtMailEventFunc,
202                                     void * client_data);
203
204             // Push some data into the event queue.
205             //
206             void writeEventData(DtMailEnv & error,
207                                 const void * buf,
208                                 const unsigned long size);
209
210             // These routines check the list to make sure the created
211             // object is still valid. This is used by the event handlers
212             // to make sure events don't appear for deleted objects.
213             //
214             DtMailBoolean validObjectKey(DtMailObjectKey);
215             DtMailObjectKey newObjectKey(void);
216             void removeObjectKey(DtMailObjectKey);
217
218             // This method allows the client to register a busy callback.
219             // Any time the library is going to be busy for a while, it will
220             // call this handler to set the app state to busy, and unbusy
221             // the app when it is done. This is an optional interface.
222             //
223             typedef void (*BusyApplicationCallback)(DtMailEnv &error,
224                                                     DtMailBusyState busy_state,
225                                                     void * client_data);
226             void registerBusyCallback(DtMailEnv &,
227                                       BusyApplicationCallback,
228                                       void * client_data);
229
230 #ifdef DEAD_WOOD
231             void unregisterBusyCallback(DtMailEnv &);
232 #endif /* DEAD_WOOD */
233
234             void setBusyState(DtMailEnv &, DtMailBusyState busy_state);
235
236             void setAutoSaveFlag(DtMailBoolean flag);
237             DtMailBoolean getAutoSaveFlag();
238
239             // These methods allow disabling and enabling of group privileges
240             //
241             typedef void (*DisableGroupPrivilegesCallback)(void * client_data);
242             typedef void (*EnableGroupPrivilegesCallback)(void * client_data);
243       
244             void registerDisableGroupPrivilegesCallback(
245                                         DisableGroupPrivilegesCallback,
246                                         void * client_data);
247             void registerEnableGroupPrivilegesCallback(
248                                         EnableGroupPrivilegesCallback,
249                                         void * client_data);
250       
251             void disableGroupPrivileges(void);
252             void enableGroupPrivileges(void);
253         
254             // This method allows the client to register a callback that
255             // can be called to return the last time() an interactive X
256             // event was processed.
257             // Any time the library is about to be busy for a while, it
258             // may call this handler to get the time() that the last
259             // interactive X event was processed. It was very recent, the
260             // library may wish to delay the busy event for a while.
261             //
262             typedef long (*LastInteractiveEventTimeCallback)(void * client_data);
263       
264             void registerLastInteractiveEventTimeCallback(
265                                         LastInteractiveEventTimeCallback,
266                                         void * client_data);
267       
268             long lastInteractiveEventTime(void);
269       
270                 // For CHARSET
271         int OpenLcxDb(void);
272         void DtXlateStdToOpLocale(char *op, char *std, char *dflt,
273                      char **ret);
274         void DtXlateOpToStdLocale(char *op, char *opLoc, char **retLoc,
275                      char **ret_retLang, char **retSet);
276         void DtXlateStdToOpCodeset(char *op, char *std, char *dflt,
277                      char **ret);
278         void DtXlateMimeToIconv(const char *, const char *, const char *,
279                      char **, char **);
280         void DtXlateLocaleToMime(const char *, const char *,
281                      const char *, char **);
282
283         char *csToConvName(char *);
284         char *locToConvName();
285         char *targetConvName();
286         char *targetTagName();
287         char *targetTagName(char *);
288                 int csConvert(char **, unsigned long &, int, char *, char *);
289         // End of For CHARSET
290
291           private:
292             unsigned long       _object_signature;
293             void                *_obj_mutex;
294             char *              _tt_channel;
295             int                 _tt_fd;
296             int                 _event_fd[2];
297             char                *_app_name;
298             MailRc *            _mail_rc;
299             DtMailBoolean       _canAutoSave;
300             
301             /* Implementation structure. */
302             struct Impls {
303               char              *impl_name;
304               MetaImplFactory   impl_meta_factory;
305               void              *impl_lib;
306             };
307             
308             Impls               *_impls;
309             const char  **_impl_names; // Used to return names from enumerate.
310             int         _num_impls;
311             int         _default_impl;
312             
313             struct EventRoutine : public DtCPlusPlusAllocator {
314               DtMailEventFunc   routine;
315               void *            client_data;
316               time_t            interval;
317               time_t            last_ran;
318             };
319
320             DtVirtArray<EventRoutine *>         _events;
321             DtVirtArray<DtMailObjectKey>        _valid_keys;
322             DtMailObjectKey                     _cur_key;
323
324             void buildImplTable(DtMailEnv & error);
325             void buildTypeTable(DtMailEnv & error);
326             int lookupImpl(const char * impl);
327
328             BusyApplicationCallback     _busy_cb;
329             void *                      _busy_cb_data;
330
331             DisableGroupPrivilegesCallback      _disableGroupPrivileges_cb;
332             void *                              _disableGroupPrivileges_cb_data;
333
334             EnableGroupPrivilegesCallback       _enableGroupPrivileges_cb;
335             void *                              _enableGroupPrivileges_cb_data;
336
337             LastInteractiveEventTimeCallback    _interactive_time_cb;
338             void *                              _interactive_time_cb_data;
339         };
340
341 //==================NEW MAILRC CLASS
342     class MailRc {
343         
344       public:
345             
346             MailRc(DtMailEnv &, Session *);
347             
348             ~MailRc();
349             
350             int  encryptedLength(int length);
351             void encryptValue(char *to, char *from, int length);
352             int  decryptValue(char *to, char *from, int length);
353
354             void getValue(
355                         DtMailEnv &,
356                         const char * var, const char ** value,
357                         DtMailBoolean decrypt = DTM_FALSE);
358             void setValue(
359                         DtMailEnv &,
360                         const char * var, const char * value,
361                         DtMailBoolean encrypt = DTM_FALSE);
362             void removeValue(DtMailEnv &, const char * var);
363
364             const char * getAlias(DtMailEnv &, const char * name);
365             typedef void (*hm_callback)(char * key, void * value,
366                                         void * client_data);
367             void getAliasList(hm_callback stuffing_func, void *client_data);
368             void setAlias(DtMailEnv &, const char * name, const char * value);
369             void removeAlias(DtMailEnv &, const char * name);
370             DtVirtArray<char *> *getAliasList();
371
372             DtMailBoolean ignore(DtMailEnv &, const char *name);
373             void addIgnore(DtMailEnv &, const char * name);
374             void removeIgnore(DtMailEnv &, const char * name);
375             DtVirtArray<char *> *getIgnoreList();
376
377             const char * getAlternates(DtMailEnv &);
378             void setAlternate(DtMailEnv &, const char * alt);
379             void removeAlternate(DtMailEnv &, const char * alt);
380
381             void update(DtMailEnv &);
382             
383             
384             // Methods below this line are not part of the public interface.
385             // They must be declared public due to implementation restrictions.
386             // DO NOT CALL THESE AS A CLIENT OF THIS CLASS.
387             //
388             int load(char *filename, char* line);
389             void init_globals();
390             static void add_alias(char *name, char *value);
391             static void mt_assign(char *name,char * val);
392             static int mt_deassign(char *s);
393             static void mt_puthash(
394                                 char *name,
395                                 char * val,
396                                 struct var **hasharray);
397             static void mt_scan(FILE * outf);
398             static char *vcopy(char *str);
399             static int group(char **argv, DtMail::MailRc *);
400             static void wgroup(const char *, char **, FILE *);
401             static void ngroup(char * key, void * value, void * client_data);
402             static void nalias(char * key, void * data, void * client_data);
403             static void nignorelist(char *key, void *data, void *client_data);
404             static int unset(char **arglist, DtMail::MailRc *);
405             static void wunset(
406                                 const char * verbatim,
407                                 char ** arglist,
408                                 FILE * outf);
409             static int set(char **arglist, DtMail::MailRc *);
410             static void wset(const char *, char **, FILE *);
411             static int source(char **arglist, DtMail::MailRc *);
412             static void wsource(const char *, char **, FILE *);
413             static int ifcmd(char **arglist, DtMail::MailRc *);
414             static void wifcmd(const char *, char **, FILE *);
415             static int elsecmd(char **arglist, DtMail::MailRc *);
416             static void welsecmd(const char *, char **, FILE *);
417             static int endifcmd(char **arglist, DtMail::MailRc *);
418             static void wendifcmd(const char *, char **, FILE *);
419             static int igfield(char **list, DtMail::MailRc *);
420             static void wigfield(const char *, char **, FILE *);
421             static void nigfield(char * key, void * value, void * client_data);
422             static int clearaliases(char **list, DtMail::MailRc *);
423             static void wclearaliases(const char *, char **, FILE *);
424
425             static void *hm_alloc();
426             static void *hm_test(struct hash **table, char *key);
427             static void hm_delete(struct hash **table, char *key);
428             static void hm_add(struct hash **table, 
429                                char *key, 
430                                void *value, 
431                                int size);
432             static void hm_mark(struct hash **table, char * key);
433             static int hm_ismarked(struct hash **table, char * key);
434             static void hm_scan(
435                                 struct hash **table,
436                                 hm_callback,
437                                 void * client_data);
438             static void free_hash(struct hash *h);
439             static int hash_index(char *key);
440             static void add_ignore(char *name);
441             static void add_alternates(char *name);
442             static int alternates(char **namelist, DtMail::MailRc *);
443             static void walternates(const char *, char **, FILE *);
444             static void nalternates(
445                                 char * key,
446                                 void * value,
447                                 void * client_data);
448             
449             static char *nullfield;
450             static Boolean clearAliases;
451             
452             struct globals {
453             char *g_myname;
454             void *g_ignore;             /* hash list of ignored fields */
455             void *g_retain;             /* hash list of retained fields */
456             void *g_alias;              /* hash list of alias names */
457             void *g_alternates; /* hash list of alternate names */
458             int g_nretained;    /* the number of retained fields */
459             };  
460             
461             static struct globals glob;
462             
463             /* Pointer to active var list */
464             static struct   var *variables[HSHSIZE]; 
465
466             DTMailError_t getParseError(void) { return _parseError; }
467
468           protected:
469             void updateByLine(FILE * in, FILE * out);
470             void outputLine(
471                         const char * verbatim,
472                         const char * parseable,
473                         FILE * out);
474             int commands(char* line);
475             int execute(char linebuf[]);
476             int readline(FILE *ibuf, char *linebuf);
477             void unstack();
478             int isprefix(char *as1, char *as2);
479             void *lex(char word[]);
480             int getrawlist(char line[], char ** argv, int argc);
481             void freerawlist(char **argv);
482             char *mt_value(char name[]);
483             char *expand(char *);
484             int getfolderdir(char *, size_t);
485             static int hash(char *name);
486             static void vfree(char *cp);
487             
488           private:
489             
490             DTMailError_t                       _parseError;
491             FILE *input;
492             int sourcing;
493             int cond;
494             int  ssp;               /* Top of file stack */
495             char *alternate_list;
496             char *_mailrc_name;
497             
498             static struct var *lookup(char *name, struct var **hasharray);
499             
500             
501             struct sstack {
502             FILE    *s_file;                /* File we were in. */
503             int     s_cond;                 /* Saved state of conditionals */
504             };
505             
506             struct sstack sstack[MAILRC_NOFILE];
507         
508         
509     };
510
511     
512     class Envelope;
513     class BodyPart;
514
515     class Message : public DtCPlusPlusAllocator {
516       public:
517             virtual ~Message(void);
518             
519             virtual Envelope * getEnvelope(DtMailEnv &) = 0;
520             
521             // This should only be used when you REALLY need to know
522             // how many body parts are present before actually traversing
523             // the body parts (i.e. like when writing a MIME format message).
524             virtual int getBodyCount(DtMailEnv &) = 0;
525             
526             virtual BodyPart * getFirstBodyPart(DtMailEnv &) = 0;
527             virtual BodyPart * getNextBodyPart(DtMailEnv &,
528                                                BodyPart * last) = 0;
529             
530             virtual BodyPart * newBodyPart(DtMailEnv &,
531                                            BodyPart * after) = 0;
532             
533 #ifdef DEAD_WOOD
534             virtual void newBodyPartOrder(DtMailEnv &,
535                                           BodyPart * new_order,
536                                           const int bodypart_count) = 0;
537 #endif /* DEAD_WOOD */
538
539             virtual void setFlag(DtMailEnv &,
540                                  const DtMailMessageState) = 0;
541
542             virtual void resetFlag(DtMailEnv &,
543                                    const DtMailMessageState) = 0;
544
545             virtual DtMailBoolean flagIsSet(DtMailEnv &,
546                                             const DtMailMessageState) = 0;
547
548             virtual time_t getDeleteTime(DtMailEnv &) = 0;
549
550             virtual void toBuffer(DtMailEnv & error, DtMailBuffer &) = 0;
551
552             virtual const char * impl(DtMailEnv & error) = 0;
553
554             // The mail box method is used by the components of
555             // the message object to determine which mail box the
556             // belong to, and in turn which session.
557             //
558             MailBox * mailBox(void);
559             Session * session(void);
560
561             
562           protected:
563             Message(DtMailEnv &,
564                     MailBox * parent);
565             
566             MailBox *           _parent;
567             Session *           _session;
568             Envelope *          _envelope;
569             void *              _obj_mutex;
570         };
571
572     class Envelope : public DtCPlusPlusAllocator {
573       public:
574             virtual DtMailHeaderHandle getFirstHeader(
575                                                 DtMailEnv &,
576                                                 char ** name,
577                                                 DtMailValueSeq & value) = 0;
578
579             virtual DtMailHeaderHandle getNextHeader(
580                                                  DtMailEnv &,
581                                                  DtMailHeaderHandle last,
582                                                  char ** name,
583                                                  DtMailValueSeq & value) = 0;
584
585             virtual void getHeader(DtMailEnv &,
586                                    const char * name,
587                                    const DtMailBoolean abstract,
588                                    DtMailValueSeq & value) = 0;
589
590             virtual void setHeaderSeq(DtMailEnv &, 
591                                       const char * header_name, 
592                                       const DtMailValueSeq & val) = 0;
593
594             // The last parameter is left to the client to provide
595             // because it can not be done in a type safe manner.
596             //
597             virtual void setHeader(DtMailEnv &, 
598                                    const char * header_name, 
599                                    const DtMailBoolean replace,
600                                    const char *) = 0;
601
602             virtual void removeHeader(DtMailEnv &,
603                                       const char * header_name) = 0;
604     //
605     // fix for the defect 177527
606     // when a reply-to field is in a message headers, the reply-to is
607     // going to be displayed as the send in RMW's msg list scrolled window
608     // instead of the real sender. The following three public methods are
609     // going to access _use_reply_to.
610     //
611     virtual void setUseReplyTo(void)  = 0;
612     virtual void unsetUseReplyTo(void) = 0;
613     virtual DtMailBoolean getUseReplyTo(void) = 0;
614
615
616           protected:
617             Envelope(DtMailEnv & error, Message * parent);
618
619         friend Message::~Message(void);
620             virtual ~Envelope(void); // Only called from Message destructor.
621
622             void *      _obj_mutex;
623             Message *   _parent;
624         };
625     
626     class BodyPart : public DtCPlusPlusAllocator {
627       public:
628
629             virtual void lockContents(DtMailEnv &, const DtMailLock) = 0;
630             virtual void unlockContents(DtMailEnv &) = 0;
631
632             virtual void getContents(DtMailEnv &,
633                                      const void ** contents,
634                                      unsigned long * length,
635                                      char ** type,
636                                      char ** name,
637                                      int * mode,
638                                      char ** description) = 0;
639             
640             virtual void getContentType(DtMailEnv &,
641                                      char ** content_type) = 0;
642             
643             virtual void setContents(DtMailEnv &,
644                                      const void * contents,
645                                      const unsigned long length,
646                                      const char * type,
647                                      const char * name,
648                                      const int mode,
649                                      const char * description) = 0;
650
651             virtual void setFlag(DtMailEnv &,
652                                  DtMailBodyPartState) = 0;
653
654             virtual void resetFlag(DtMailEnv &,
655                                    DtMailBodyPartState) = 0;
656             
657             virtual DtMailBoolean flagIsSet(DtMailEnv &,
658                                             DtMailBodyPartState) = 0;
659
660             virtual time_t getDeleteTime(DtMailEnv &) = 0;
661
662                 virtual void getHeader(DtMailEnv &,
663                 const char * name,
664                 const DtMailBoolean abstract,
665                 DtMailValueSeq & value) = 0;
666
667         // For CHARSET
668         //-------------------------------------------
669         // These methods are duplicated in class BodyPart
670         // (also being implemented in class Session) because
671         // RFCFormat and RFCBodyPart need to access them. 
672         // Duplicating routines like what is being done here is a workaround
673         // for an implementation bug/hole because there is no class where global
674         // routines can be defined (and be accessed by any class).
675         // class Session is not a proper place to put (global) methods because
676         // not every class can get at Session.
677         // RFCFormat accesses these routines through its private Session handle.
678         // RFCBodyPart does not have a Session handle. 
679         // Hence the need to duplicate the following routines.
680
681         virtual int OpenLcxDb(void) = 0;
682         virtual void DtXlateStdToOpLocale(char *op, char *std, char *dflt,
683                      char **ret) = 0;
684         virtual void DtXlateOpToStdLocale(char *op, char *opLoc, char **retLoc,
685                      char **ret_retLang, char **retSet) = 0;
686         virtual void DtXlateMimeToIconv(const char *, const char *,
687                      const char *, char **, char **) = 0;
688         virtual void DtXlateLocaleToMime(const char *, const char *,
689                      const char *, char **) = 0;
690  
691         virtual char *csToConvName(char *) = 0;
692         virtual char *locToConvName() = 0;
693         virtual char *targetConvName() = 0;
694         virtual char *targetTagName() = 0;
695         virtual int csConvert(char **, unsigned long &, int,
696                     char *, char *) = 0;
697         //-------------------------------------------
698
699                 virtual char *csFromContentType(DtMailValueSeq & value) = 0;
700         // End of For CHARSET
701
702 #ifdef DEAD_WOOD
703             virtual DtMailChecksumState checksum(DtMailEnv &) = 0;
704 #endif /* DEAD_WOOD */
705
706           protected:
707             BodyPart(DtMailEnv &, Message * parent);
708
709         friend Message::~Message(void);
710             virtual ~BodyPart(void); // Only called from Message destructor.
711
712             void *      _obj_mutex;
713             Message *   _parent;
714         };
715
716     
717     // The MailBox encapsulates the concept of a mail box as a container.
718     // This class should be used for manipulating mail containers.
719     
720     class MailBox : public DtCPlusPlusAllocator {
721       public:
722             
723             // Create a MailBox. The constructor simply initializes the
724             // instance and sets the appropriate meta handlers for mail
725             // containers.
726             //
727             // Errors:
728             //   None.
729             //
730             MailBox(DtMailEnv &,
731                     Session * session,
732                     DtMailObjectSpace space,
733                     void * arg,
734                     DtMailCallback cb,
735                     void * clientData);
736             
737             // Returns DTM_TRUE if the is mail box is writable and DTM_FALSE
738             // if the mail box is read only.
739             //
740             DtMailBoolean       mailBoxWritable(DtMailEnv &);
741
742             // Destroy a MailBox. The destructor will close the open mail
743             // container, and any embedded containers.
744             //
745             virtual ~MailBox(void);
746             
747             static void appendCB(DtMailEnv&, char*, int, void *clientData);
748             virtual void append(DtMailEnv &error, char *buf, int len) = 0;
749
750             // Create a named mail container in the file system. The
751             // container will be truncated if it already exists, otherwise
752             // it will be created. The mode in this case will be set to
753             // DTMAIL_DEFAULT_CREATE_MODE, the default for mail.
754             //
755             // Errors:
756             //  DTME_ObjectInvalid - The instance was not proprerly initialized.
757             //  DTME_BadArg - The file_name parameter was invalid.
758             //  DTME_ObjectInUse - This object already has an open container.
759             //  DTME_ObjectCreationFailed - A required object could not
760             //       be created.
761             //
762             virtual void create(DtMailEnv &,
763                                 mode_t mode = DTMAIL_DEFAULT_CREATE_MODE) = 0;
764             
765             // Open a named mail container in the file system. The container
766             // must exist, and be readable (at least) by the user.
767             // If the container is writable by the user it will be opened
768             // for update.
769             //
770             // Parameters:
771             //  auto_create - Create the container if it doesn't exist, using
772             //        MailBox::create.
773             //
774             // Errors:
775             //  DTME_ObjectInvalid - The instance was not proprerly initialized.
776             //  DTME_BadArg - The file_name parameter was invalid.
777             //  DTME_ObjectInUse - This object already has an open container.
778             //  DTME_ObjectCreationFailed - A required object could not
779             //       be created.
780             //  DTME_NoSuchFile - The file doesn't exist & auto_create is false.
781             //  DTME_NotMailBox - The object is a container, but not a mail box.
782             //  DTME_NoMemory - A memory allocation failed.
783             //
784             virtual void open(DtMailEnv & error,
785                               DtMailBoolean auto_create = DTM_TRUE,
786                               int open_mode = DTMAIL_DEFAULT_OPEN_MODE,
787                               mode_t create_mode = DTMAIL_DEFAULT_CREATE_MODE,
788                               DtMailBoolean lock_flag = DTM_TRUE,
789                               DtMailBoolean auto_parse = DTM_TRUE) = 0;
790
791             // (Un)locks an open mailbox.
792             virtual void lock() = 0;
793             virtual void unlock() = 0;
794             virtual void save() = 0;
795
796 #ifdef DEAD_WOOD
797             virtual int messageCount(DtMailEnv & error) = 0;
798 #endif /* DEAD_WOOD */
799
800             virtual DtMailMessageHandle getFirstMessageSummary(
801                                         DtMailEnv & error,
802                                         const DtMailHeaderRequest & header_list,
803                                         DtMailHeaderLine & header_line) = 0;
804             
805             virtual DtMailMessageHandle getNextMessageSummary(
806                                         DtMailEnv & error,
807                                         DtMailMessageHandle last,
808                                         const DtMailHeaderRequest & header_list,
809                                         DtMailHeaderLine & header_line) = 0;
810
811             virtual void getMessageSummary(
812                                         DtMailEnv & error,
813                                         DtMailMessageHandle handle,
814                                         const DtMailHeaderRequest &,
815                                         DtMailHeaderLine &) = 0;
816
817             virtual void clearMessageSummary(
818                                         DtMailHeaderLine &) = 0;
819
820             virtual Message * getMessage(
821                                         DtMailEnv & error,
822                                         DtMailMessageHandle message_handle) = 0;
823             
824             virtual Message * getFirstMessage(DtMailEnv &) = 0;
825             
826             virtual Message * getNextMessage(DtMailEnv &, Message * last) = 0;
827             
828             virtual Message * newMessage(DtMailEnv &) = 0;
829
830             virtual void copyMessage(DtMailEnv &, Message *) = 0;
831
832             virtual void copyMailBox(DtMailEnv &, MailBox *) = 0;
833
834             virtual void disableMailRetrieval() = 0;
835             virtual void enableMailRetrieval() = 0;
836             virtual void checkForMail(
837                         DtMailEnv &,
838                         const DtMailBoolean already_locked = DTM_FALSE) = 0;
839
840             virtual void createMailRetrievalAgent(char *password = NULL) = 0;
841             virtual void deleteMailRetrievalAgent() = 0;
842             virtual void updateMailRetrievalPassword(char *password = NULL) = 0;
843
844             virtual void expunge(DtMailEnv &) = 0;
845
846             virtual const char * impl(DtMailEnv & error) = 0;
847
848             // This method is typically used to propagate the session
849             // to embedded objects, such as Messages which may need to
850             // acquire the session to which it belongs.
851             //
852             virtual Session * session(void);
853             
854             virtual void callCallback(DtMailCallbackOp, void *) = 0;
855             virtual void startAutoSave(
856                                 DtMailEnv & error,
857                                 DtMailBoolean start=DTM_TRUE) = 0;
858             typedef void (*err_func)(char *,Boolean,void *);
859             void registerErrMsgFunc(err_func,void * client_data);
860             void unregisterErrMsgFunc(DtMailEnv &);
861             void showError(char *);
862
863             void hideAccessEvents(DtMailBoolean onoff)
864                         {_hide_access_events = onoff;}
865              
866             DtMailObjectKey getObjectKey(void)
867                         {return _key;}
868
869           private:
870             err_func                    _errmsg_func;
871             void *                      _err_data;
872
873
874           protected:
875             DtMailBoolean       _hide_access_events;
876
877             DtMailObjectKey     _key;
878             Session             *_session;
879             void                *_arg;
880             DtMailObjectSpace   _space;
881             DtMailCallback      _callback;
882             void                *_cb_data;
883             void                *_obj_mutex;
884             DtMailBoolean       _mail_box_writable;
885             mode_t              _default_mode;  // Default mode for file.
886         };
887     
888     class Transport : public DtCPlusPlusAllocator {
889       public:
890             virtual DtMailOperationId submit(
891                                         DtMailEnv &,
892                                         Message * msg,
893                                         DtMailBoolean log_msg = DTM_FALSE) = 0;
894
895             // SendMsgDialog initiates a send.  It needs to set information
896             // needed to exec sendmail by calling these init functions.
897             // getSendmailReturnProc returns a handler so that SendMsgDialog
898             // can use it in XtAppAddInput.
899             virtual void initTransportData(int fds[2],
900                 SubProcessFinishedProc proc, void *ptr) = 0;
901             virtual void *getSendmailReturnProc(void) = 0;
902
903
904             virtual void callCallback(DtMailOperationId, void * arg);
905
906           protected:
907             Transport(DtMailEnv &, Session *, DtMailStatusCallback, void *);
908             virtual ~Transport(void);
909
910             DtMailObjectKey             _key;
911             Session *                   _session;
912             DtMailStatusCallback        _callback;
913             void *                      _cb_data;
914             void *                      _obj_mutex;
915         };
916
917   private:
918     
919 friend class MailBox;
920 friend class Message;
921 friend class Envelope;
922 friend class BodyPart;
923 friend class Transport;
924 friend class EmbeddedMessage;
925 friend class FileMessage;
926 friend class FileShare;
927 friend class Session;
928     static void setError(
929                         Session &,
930                         DtMailEnv & error,
931                         DTMailError_t minor_code);
932 };
933
934 #if defined(sun) || defined(__FreeBSD__)
935 template <typename T>
936 size_t iconv (iconv_t i, const T inbuf, size_t* inleft,
937                char** outbuf, size_t* outleft)
938 {
939     return iconv(i, const_cast<T>(inbuf), inleft, outbuf, outleft);
940 };
941 #endif
942
943 #endif