368 lines
8.6 KiB
C
368 lines
8.6 KiB
C
/*
|
|
* CDE - Common Desktop Environment
|
|
*
|
|
* Copyright (c) 1993-2012, The Open Group. All rights reserved.
|
|
*
|
|
* These libraries and programs are free software; you can
|
|
* redistribute them and/or modify them under the terms of the GNU
|
|
* Lesser General Public License as published by the Free Software
|
|
* Foundation; either version 2 of the License, or (at your option)
|
|
* any later version.
|
|
*
|
|
* These libraries and programs are distributed in the hope that
|
|
* they will be useful, but WITHOUT ANY WARRANTY; without even the
|
|
* implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
|
|
* PURPOSE. See the GNU Lesser General Public License for more
|
|
* details.
|
|
*
|
|
* You should have received a copy of the GNU Lesser General Public
|
|
* License along with these libraries and programs; if not, write
|
|
* to the Free Software Foundation, Inc., 51 Franklin Street, Fifth
|
|
* Floor, Boston, MA 02110-1301 USA
|
|
*/
|
|
/*
|
|
*+SNOTICE
|
|
*
|
|
* $TOG: MailSession.C /main/9 1999/03/26 16:51:51 mgreess $
|
|
*
|
|
* RESTRICTED CONFIDENTIAL INFORMATION:
|
|
*
|
|
* The information in this document is subject to special
|
|
* restrictions in a confidential disclosure agreement between
|
|
* HP, IBM, Sun, USL, SCO and Univel. Do not distribute this
|
|
* document outside HP, IBM, Sun, USL, SCO, or Univel without
|
|
* Sun's specific written approval. This document and all copies
|
|
* and derivative works thereof must be returned or destroyed at
|
|
* Sun's request.
|
|
*
|
|
* Copyright 1993 Sun Microsystems, Inc. All rights reserved.
|
|
*
|
|
*+ENOTICE
|
|
*/
|
|
|
|
#include <unistd.h>
|
|
#include <sys/stat.h>
|
|
#include <sys/types.h>
|
|
|
|
#include <X11/Intrinsic.h>
|
|
#include <DtMail/DtMail.hh>
|
|
#include <DtMail/DtMailError.hh>
|
|
#include <DtMail/DtMailXtProc.h>
|
|
#include <DtMail/IO.hh>
|
|
|
|
#include "MailSession.hh"
|
|
#include "MemUtils.hh"
|
|
#include "RoamMenuWindow.h"
|
|
|
|
DtMail::Session * MailSession::_app_session = NULL;
|
|
int MailSession::_num_deactivated = 0;
|
|
|
|
MailSession::MailSession(DtMailEnv & error, XtAppContext context)
|
|
: _open_mailboxes(128)
|
|
{
|
|
error.clear();
|
|
|
|
if (_app_session) {
|
|
error.setError(DTME_ObjectInUse);
|
|
return;
|
|
}
|
|
|
|
_app_session = new DtMail::Session(error, "dtmail");
|
|
if (error.isSet())
|
|
{
|
|
// Benign error
|
|
if ((DTMailError_t)error == DTME_NoMsgCat) error.clear();
|
|
|
|
// Else need to translate the error into an DTME_* error
|
|
// defined in DtMailError.hh
|
|
}
|
|
|
|
XtAppAddInput(context,
|
|
_app_session->eventFileDesc(error),
|
|
(XtPointer)XtInputReadMask,
|
|
DtMailXtInputProc,
|
|
_app_session);
|
|
|
|
#if 0
|
|
//
|
|
// Used to be both XtInputReadMask and XtInputExceptMask
|
|
// went to the same procedure. Resulted in problems in
|
|
// when using R6 polling instead of R5 select. Now
|
|
// use separate input handlers.
|
|
//
|
|
XtAppAddInput(context,
|
|
_app_session->eventFileDesc(error),
|
|
(XtPointer)XtInputExceptMask,
|
|
DtMailXtExceptProc,
|
|
_app_session);
|
|
#endif
|
|
|
|
DtMailDamageContext = context;
|
|
}
|
|
|
|
MailSession::~MailSession(void)
|
|
{
|
|
for (int mb = 0; mb < _open_mailboxes.length(); mb++)
|
|
{
|
|
delete _open_mailboxes[mb]->handle;
|
|
delete _open_mailboxes[mb]->path;
|
|
}
|
|
|
|
delete _app_session;
|
|
}
|
|
|
|
Boolean
|
|
MailSession::isMboxOpen(const char *path)
|
|
{
|
|
int pos = locate(path);
|
|
if (pos >= 0) return (TRUE);
|
|
return (FALSE);
|
|
}
|
|
|
|
RoamMenuWindow *
|
|
MailSession::getRMW(const char *path)
|
|
{
|
|
int slot = locate(path);
|
|
if (slot >= 0)
|
|
return(_open_mailboxes[slot]->rmw);
|
|
return NULL;
|
|
}
|
|
|
|
RoamMenuWindow *
|
|
MailSession::getRMW(DtMail::MailBox *mbox)
|
|
{
|
|
int slot = locate(mbox);
|
|
return(_open_mailboxes[slot]->rmw);
|
|
}
|
|
|
|
DtMail::MailBox *
|
|
MailSession::open(
|
|
DtMailEnv & error,
|
|
const char * path,
|
|
DtMailCallback cb_func,
|
|
void * client_data,
|
|
DtMailBoolean auto_create,
|
|
DtMailBoolean request_lock,
|
|
DtMailBoolean auto_parse)
|
|
{
|
|
// First, see if we have this open in this process.
|
|
int slot = locate(path);
|
|
|
|
// We do not allow open an already opened mailbox
|
|
// because this may cause memory fault when a message is
|
|
// deleted from one RMW and the other RMW would like to
|
|
// read the already deleted message.
|
|
// (1) set error to DTME_AlreadyOpened
|
|
// (2) Return a NULL
|
|
if (slot >= 0)
|
|
{
|
|
error.setError(DTME_AlreadyOpened);
|
|
if (client_data == NULL)
|
|
{
|
|
_open_mailboxes[slot]->open_ref_count += 1;
|
|
return _open_mailboxes[slot]->handle;
|
|
} else return NULL;
|
|
}
|
|
|
|
// Create a handle for determining what to do next. This will
|
|
// add us to the file session so we will start getting call
|
|
// back requests on this file.
|
|
DtMail::MailBox * mailbox = _app_session->mailBoxConstruct(
|
|
error, DtMailFileObject,
|
|
(void *)path,
|
|
cb_func, client_data);
|
|
if (error.isSet())
|
|
{
|
|
error.setError(DTME_ObjectCreationFailed);
|
|
delete mailbox;
|
|
return NULL;
|
|
}
|
|
|
|
// Does this file exist? If it doesn't and create is
|
|
// on then make one. If create is off, then raise an
|
|
// error.
|
|
mailbox->open(error,
|
|
auto_create,
|
|
DTMAIL_DEFAULT_OPEN_MODE,
|
|
DTMAIL_DEFAULT_CREATE_MODE,
|
|
request_lock,
|
|
auto_parse);
|
|
|
|
// Need to translate from BE error to a FE error that the
|
|
// user can understand. Opening a mail container can result
|
|
// in a variety of errors. Translate those that are considered
|
|
// to be relevant (for now) - the set can always be extended.
|
|
// Toss others into an UnknownFormat error.
|
|
if (error.isSet())
|
|
{
|
|
delete mailbox;
|
|
return(NULL);
|
|
}
|
|
|
|
addToList(mailbox, path, (RoamMenuWindow *) client_data);
|
|
return mailbox;
|
|
}
|
|
|
|
void
|
|
MailSession::close(DtMailEnv & error, const DtMail::MailBox * mb)
|
|
{
|
|
// Find the mail box slot.
|
|
int slot = locate(mb);
|
|
if (slot < 0)
|
|
{
|
|
error.setError(DTME_ObjectInvalid);
|
|
return;
|
|
}
|
|
|
|
MailBoxItem * mbi = _open_mailboxes[slot];
|
|
mbi->open_ref_count -= 1;
|
|
if (mbi->open_ref_count <= 0)
|
|
{
|
|
if (! _open_mailboxes[slot]->is_active) _num_deactivated--;
|
|
|
|
delete mbi->handle;
|
|
delete mbi->path;
|
|
|
|
_open_mailboxes.remove(slot);
|
|
delete mbi;
|
|
}
|
|
}
|
|
|
|
void
|
|
MailSession::convert(
|
|
DtMailEnv & error,
|
|
const char *, // old_path
|
|
const char *, // new_path
|
|
DtMailStatusCallback, // cb_func
|
|
void *) // client_data
|
|
{
|
|
error.clear();
|
|
}
|
|
|
|
void
|
|
MailSession::copy(
|
|
DtMailEnv & error,
|
|
DtMail::Message &, // msg
|
|
const char *) // path
|
|
{
|
|
error.clear();
|
|
}
|
|
|
|
int
|
|
MailSession::locate(const char *path)
|
|
{
|
|
int slot;
|
|
struct stat pathbuf;
|
|
|
|
SafeStat(path, &pathbuf);
|
|
for (slot = 0; slot < _open_mailboxes.length(); slot++)
|
|
{
|
|
if (strcmp(_open_mailboxes[slot]->path, path) == 0)
|
|
return slot;
|
|
|
|
if (! _open_mailboxes[slot]->stated)
|
|
{
|
|
_open_mailboxes[slot]->stated = TRUE;
|
|
SafeStat(
|
|
_open_mailboxes[slot]->path,
|
|
&_open_mailboxes[slot]->statbuf);
|
|
}
|
|
|
|
if (pathbuf.st_ino == _open_mailboxes[slot]->statbuf.st_ino &&
|
|
pathbuf.st_dev == _open_mailboxes[slot]->statbuf.st_dev)
|
|
return slot;
|
|
}
|
|
|
|
return -1;
|
|
}
|
|
|
|
int
|
|
MailSession::locate(const DtMail::MailBox *mb)
|
|
{
|
|
for (int slot = 0; slot < _open_mailboxes.length(); slot++)
|
|
if (mb == _open_mailboxes[slot]->handle)
|
|
return slot;
|
|
|
|
return -1;
|
|
}
|
|
|
|
int
|
|
MailSession::locate(const RoamMenuWindow *rmw)
|
|
{
|
|
for (int slot = 0; slot < _open_mailboxes.length(); slot++)
|
|
if (rmw == _open_mailboxes[slot]->rmw)
|
|
return slot;
|
|
|
|
return -1;
|
|
}
|
|
|
|
int
|
|
MailSession::isActiveRMW(RoamMenuWindow *rmw)
|
|
{
|
|
int slot = locate((const RoamMenuWindow *) rmw);
|
|
if (slot < 0) return 0;
|
|
|
|
return _open_mailboxes[slot]->is_active;
|
|
}
|
|
|
|
void
|
|
MailSession::activateRMW(RoamMenuWindow *rmw)
|
|
{
|
|
int slot = locate((const RoamMenuWindow *) rmw);
|
|
if (slot < 0) return;
|
|
|
|
if (! _open_mailboxes[slot]->is_active)
|
|
{
|
|
DtMail::MailBox *mailbox = rmw->mailbox();
|
|
mailbox->enableMailRetrieval();
|
|
|
|
DtMailEnv mail_error;
|
|
mail_error.clear();
|
|
rmw->checkForMail(mail_error);
|
|
|
|
_open_mailboxes[slot]->is_active = TRUE;
|
|
_num_deactivated--;
|
|
}
|
|
}
|
|
|
|
void
|
|
MailSession::deactivateRMW(RoamMenuWindow *rmw)
|
|
{
|
|
int slot = locate((const RoamMenuWindow *) rmw);
|
|
if (slot < 0) return;
|
|
|
|
if (_open_mailboxes[slot]->is_active)
|
|
{
|
|
DtMail::MailBox *mailbox = rmw->mailbox();
|
|
mailbox->disableMailRetrieval();
|
|
|
|
_open_mailboxes[slot]->is_active = FALSE;
|
|
_num_deactivated++;
|
|
}
|
|
}
|
|
|
|
void
|
|
MailSession::addToList(
|
|
DtMail::MailBox *mb,
|
|
const char *path,
|
|
RoamMenuWindow *rmw)
|
|
{
|
|
MailBoxItem * mbi = new MailBoxItem;
|
|
|
|
mbi->handle = mb;
|
|
mbi->is_active = TRUE;
|
|
mbi->stated = FALSE;
|
|
mbi->open_ref_count = 1;
|
|
mbi->path = strdup_n(path);
|
|
mbi->rmw = rmw;
|
|
|
|
_open_mailboxes.append(mbi);
|
|
}
|
|
|
|
Tt_status
|
|
MailSession::lockCB(Tt_message, Tttk_op, const char*, uid_t, int, void*)
|
|
{
|
|
// We never give up the lock during a copy!
|
|
return TT_ERR_INVALID;
|
|
}
|