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