-fpermissive to allow GCC to compile old C++
[oweals/cde.git] / cde / programs / dtmail / dtmail / MailSession.C
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 librararies 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  *      $TOG: MailSession.C /main/9 1999/03/26 16:51:51 mgreess $
27  *
28  *      RESTRICTED CONFIDENTIAL INFORMATION:
29  *      
30  *      The information in this document is subject to special
31  *      restrictions in a confidential disclosure agreement between
32  *      HP, IBM, Sun, USL, SCO and Univel.  Do not distribute this
33  *      document outside HP, IBM, Sun, USL, SCO, or Univel without
34  *      Sun's specific written approval.  This document and all copies
35  *      and derivative works thereof must be returned or destroyed at
36  *      Sun's request.
37  *
38  *      Copyright 1993 Sun Microsystems, Inc.  All rights reserved.
39  *
40  *+ENOTICE
41  */
42
43 #include <unistd.h>
44 #include <sys/stat.h>
45 #include <sys/types.h>
46
47 #include <X11/Intrinsic.h>
48 #include <DtMail/DtMail.hh>
49 #include <DtMail/DtMailError.hh>
50 #include <DtMail/DtMailXtProc.h>
51 #include <DtMail/IO.hh>
52
53 #include "MailSession.hh"
54 #include "MemUtils.hh"
55 #include "RoamMenuWindow.h"
56
57 DtMail::Session * MailSession::_app_session = NULL;
58 int MailSession::_num_deactivated = 0;
59
60 MailSession::MailSession(DtMailEnv & error, XtAppContext context)
61 : _open_mailboxes(128)
62 {
63     error.clear();
64
65     if (_app_session) {
66         error.setError(DTME_ObjectInUse);
67         return;
68     }
69
70     _app_session = new DtMail::Session(error, "dtmail");
71     if (error.isSet())
72     {
73         // Benign error
74         if ((DTMailError_t)error == DTME_NoMsgCat) error.clear();
75
76         // Else need to translate the error into an DTME_* error
77         // defined in DtMailError.hh
78     }
79
80     XtAppAddInput(context,
81                   _app_session->eventFileDesc(error),
82                   (XtPointer)XtInputReadMask,
83                   DtMailXtInputProc,
84                   _app_session);
85
86 #if 0
87     //
88     // Used to be both XtInputReadMask and XtInputExceptMask
89     // went to the same procedure.  Resulted in problems in
90     // when using R6 polling instead of R5 select.  Now
91     // use separate input handlers.
92     //
93     XtAppAddInput(context,
94                   _app_session->eventFileDesc(error),
95                   (XtPointer)XtInputExceptMask,
96                   DtMailXtExceptProc,
97                   _app_session);
98 #endif
99
100     DtMailDamageContext = context;
101 }
102
103 MailSession::~MailSession(void)
104 {
105     for (int mb = 0; mb < _open_mailboxes.length(); mb++)
106     {
107         delete _open_mailboxes[mb]->handle;
108         delete _open_mailboxes[mb]->path;
109     }
110
111     delete _app_session;
112 }
113
114 Boolean
115 MailSession::isMboxOpen(const char *path)
116 {
117     int pos = locate(path);
118     if (pos >= 0) return (TRUE);
119     return (FALSE);
120 }
121
122 RoamMenuWindow *
123 MailSession::getRMW(const char *path)
124 {
125     int slot = locate(path);
126     if (slot >= 0)
127       return(_open_mailboxes[slot]->rmw);
128     return NULL;
129 }
130
131 RoamMenuWindow *
132 MailSession::getRMW(DtMail::MailBox *mbox)
133 {
134     int slot = locate(mbox);
135     return(_open_mailboxes[slot]->rmw);
136 }
137
138 DtMail::MailBox *
139 MailSession::open(
140     DtMailEnv & error, 
141     const char * path,
142     DtMailCallback cb_func, 
143     void * client_data,
144     DtMailBoolean auto_create, 
145     DtMailBoolean request_lock,
146     DtMailBoolean auto_parse)
147 {
148     // First, see if we have this open in this process.
149     int slot = locate(path);
150
151     // We do not allow open an already opened mailbox
152     // because this may cause memory fault when a message is
153     // deleted from one RMW and the other RMW would like to
154     // read the already deleted message.
155     // (1) set error to DTME_AlreadyOpened
156     // (2) Return a NULL
157     if (slot >= 0)
158     {
159         error.setError(DTME_AlreadyOpened);
160         if (client_data == NULL)
161         {
162             _open_mailboxes[slot]->open_ref_count += 1;
163             return _open_mailboxes[slot]->handle;
164         } else return NULL;
165     }
166
167     // Create a handle for determining what to do next. This will
168     // add us to the file session so we will start getting call
169     // back requests on this file.
170     DtMail::MailBox * mailbox = _app_session->mailBoxConstruct(
171                                                 error, DtMailFileObject,
172                                                 (void *)path,
173                                                 cb_func, client_data);
174     if (error.isSet())
175     {
176         error.setError(DTME_ObjectCreationFailed);
177         delete mailbox;
178         return NULL;
179     }
180     
181     // Does this file exist? If it doesn't and create is
182     // on then make one. If create is off, then raise an
183     // error.
184     mailbox->open(error, 
185               auto_create, 
186               DTMAIL_DEFAULT_OPEN_MODE, 
187               DTMAIL_DEFAULT_CREATE_MODE,
188               request_lock,
189               auto_parse);
190  
191     // Need to translate from BE error to a FE error that the
192     // user can understand.  Opening a mail container can result
193     // in a variety of errors.  Translate those that are considered
194     // to be relevant (for now) - the set can always be extended.
195     // Toss others into an UnknownFormat error.
196     if (error.isSet())
197     {
198         delete mailbox;
199         return(NULL);
200     }
201
202     addToList(mailbox, path, (RoamMenuWindow *) client_data);
203     return mailbox;
204 }
205
206 void
207 MailSession::close(DtMailEnv & error, const DtMail::MailBox * mb)
208 {
209     // Find the mail box slot.
210     int slot = locate(mb);
211     if (slot < 0)
212     {
213         error.setError(DTME_ObjectInvalid);
214         return;
215     }
216
217     MailBoxItem * mbi = _open_mailboxes[slot];
218     mbi->open_ref_count -= 1;
219     if (mbi->open_ref_count <= 0)
220     {
221         if (! _open_mailboxes[slot]->is_active) _num_deactivated--;
222
223         delete mbi->handle;
224         delete mbi->path;
225
226         _open_mailboxes.remove(slot);
227         delete mbi;
228     }
229 }
230
231 void 
232 MailSession::convert(
233     DtMailEnv & error, 
234     const char *,               // old_path
235     const char *,               // new_path
236     DtMailStatusCallback,       // cb_func
237     void *)                     // client_data
238 {
239     error.clear();
240 }
241
242 void
243 MailSession::copy(
244     DtMailEnv & error, 
245     DtMail::Message &,          // msg
246     const char *)               // path
247 {
248     error.clear();
249 }
250
251 int
252 MailSession::locate(const char *path)
253 {
254     int slot;
255     struct stat pathbuf;
256
257     SafeStat(path, &pathbuf);
258     for (slot = 0; slot < _open_mailboxes.length(); slot++)
259     {
260         if (strcmp(_open_mailboxes[slot]->path, path) == 0)
261           return slot;
262
263         if (! _open_mailboxes[slot]->stated)
264         {
265             _open_mailboxes[slot]->stated = TRUE;
266             SafeStat(
267                 _open_mailboxes[slot]->path,
268                 &_open_mailboxes[slot]->statbuf);
269         }
270         
271         if (pathbuf.st_ino == _open_mailboxes[slot]->statbuf.st_ino &&
272             pathbuf.st_dev == _open_mailboxes[slot]->statbuf.st_dev)
273           return slot;
274     }
275
276     return -1;
277 }
278
279 int
280 MailSession::locate(const DtMail::MailBox *mb)
281 {
282     for (int slot = 0; slot < _open_mailboxes.length(); slot++)
283       if (mb == _open_mailboxes[slot]->handle)
284         return slot;
285
286     return -1;
287 }
288
289 int
290 MailSession::locate(const RoamMenuWindow *rmw)
291 {
292     for (int slot = 0; slot < _open_mailboxes.length(); slot++)
293       if (rmw == _open_mailboxes[slot]->rmw)
294         return slot;
295
296     return -1;
297 }
298
299 int
300 MailSession::isActiveRMW(RoamMenuWindow *rmw)
301 {
302     int slot = locate((const RoamMenuWindow *) rmw);
303     if (slot < 0) return 0;
304     
305     return _open_mailboxes[slot]->is_active;
306 }
307
308 void
309 MailSession::activateRMW(RoamMenuWindow *rmw)
310 {
311     int slot = locate((const RoamMenuWindow *) rmw);
312     if (slot < 0) return;
313     
314     if (! _open_mailboxes[slot]->is_active)
315     {
316         DtMail::MailBox *mailbox = rmw->mailbox();
317         mailbox->enableMailRetrieval();
318
319         DtMailEnv mail_error;
320         mail_error.clear();
321         rmw->checkForMail(mail_error);
322
323         _open_mailboxes[slot]->is_active = TRUE;
324         _num_deactivated--;
325     }
326 }
327
328 void
329 MailSession::deactivateRMW(RoamMenuWindow *rmw)
330 {
331     int slot = locate((const RoamMenuWindow *) rmw);
332     if (slot < 0) return;
333     
334     if (_open_mailboxes[slot]->is_active)
335     {
336         DtMail::MailBox *mailbox = rmw->mailbox();
337         mailbox->disableMailRetrieval();
338
339         _open_mailboxes[slot]->is_active = FALSE;
340         _num_deactivated++;
341     }
342 }
343
344 void
345 MailSession::addToList(
346                 DtMail::MailBox *mb,
347                 const char *path,
348                 RoamMenuWindow *rmw)
349 {
350     MailBoxItem * mbi = new MailBoxItem;
351
352     mbi->handle = mb;
353     mbi->is_active = TRUE;
354     mbi->stated = FALSE;
355     mbi->open_ref_count = 1;
356     mbi->path = strdup_n(path);
357     mbi->rmw = rmw;
358     
359     _open_mailboxes.append(mbi);
360 }
361
362 Tt_status 
363 MailSession::lockCB(Tt_message, Tttk_op, const char*, uid_t, int, void*)
364 {
365     // We never give up the lock during a copy!
366     return TT_ERR_INVALID;
367 }