2 * CDE - Common Desktop Environment
4 * Copyright (c) 1993-2012, The Open Group. All rights reserved.
6 * These libraries and programs are free software; you can
7 * redistribute them and/or modify them under the terms of the GNU
8 * Lesser General Public License as published by the Free Software
9 * Foundation; either version 2 of the License, or (at your option)
12 * These libraries and programs are distributed in the hope that
13 * they will be useful, but WITHOUT ANY WARRANTY; without even the
14 * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
15 * PURPOSE. See the GNU Lesser General Public License for more
18 * You should have received a copy of the GNU Lesser General Public
19 * License along with these librararies and programs; if not, write
20 * to the Free Software Foundation, Inc., 51 Franklin Street, Fifth
21 * Floor, Boston, MA 02110-1301 USA
26 * $TOG: RoamCmds.C /main/43 1999/07/13 08:41:44 mgreess $
28 * RESTRICTED CONFIDENTIAL INFORMATION:
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
38 * Copyright 1993, 1994, 1995 Sun Microsystems, Inc. All rights reserved.
43 * Common Desktop Environment
45 * (c) Copyright 1993, 1994, 1995 Hewlett-Packard Company
46 * (c) Copyright 1993, 1994, 1995 International Business Machines Corp.
47 * (c) Copyright 1993, 1994, 1995 Sun Microsystems, Inc.
48 * (c) Copyright 1993, 1994, 1995 Novell, Inc.
49 * (c) Copyright 1995 Digital Equipment Corp.
50 * (c) Copyright 1995 Fujitsu Limited
51 * (c) Copyright 1995 Hitachi, Ltd.
54 * RESTRICTED RIGHTS LEGEND
56 *Use, duplication, or disclosure by the U.S. Government is subject to
57 *restrictions as set forth in subparagraph (c)(1)(ii) of the Rights in
58 *Technical Data and Computer Software clause in DFARS 252.227-7013. Rights
59 *for non-DOD U.S. Government Departments and Agencies are as set forth in
60 *FAR 52.227-19(c)(1,2).
62 *Hewlett-Packard Company, 3000 Hanover Street, Palo Alto, CA 94304 U.S.A.
63 *International Business Machines Corp., Route 100, Somers, NY 10589 U.S.A.
64 *Sun Microsystems, Inc., 2550 Garcia Avenue, Mountain View, CA 94043 U.S.A.
65 *Novell, Inc., 190 River Road, Summit, NJ 07901 U.S.A.
66 *Digital Equipment Corp., 111 Powdermill Road, Maynard, MA 01754, U.S.A.
67 *Fujitsu Limited, 1015, Kamikodanaka Nakahara-Ku, Kawasaki 211, Japan
68 *Hitachi, Ltd., 6, Kanda Surugadai 4-Chome, Chiyoda-ku, Tokyo 101, Japan
75 #include <sys/param.h>
77 #include <sys/types.h>
80 #include <X11/Intrinsic.h>
82 #include <Xm/FileSBP.h>
83 #include <Xm/FileSB.h>
85 #include <Xm/ToggleB.h>
86 #include <Xm/PushBG.h>
87 #include <Xm/PanedW.h>
90 #include <Dt/Action.h>
92 #include <Dt/DtPStrings.h>
94 #include <DtMail/IO.hh>
95 #include <DtMail/DtMailError.hh>
97 #include <DtMail/Buffer.hh>
100 #include <DtMail/Buffer.hh>
102 #include <DtMail/OptCmd.h>
103 #include <EUSCompat.h>
104 #include "EUSDebug.hh"
105 #include "Application.h"
106 #include "AttachArea.h"
107 #include "Attachment.h"
109 #include "DmxPrintJob.h"
110 #include "DtMailEditor.hh"
111 #include "DtMailGenDialog.hh"
112 #include "DtMailHelp.hh"
113 #include "DtMailWDM.hh"
114 #include "FindDialog.h"
117 #include "MemUtils.hh"
118 #include "MsgScrollingList.hh"
119 #include "MsgHndArray.hh"
121 #include "RoamCmds.h"
122 #include "RoamMenuWindow.h"
123 #include "SendMsgDialog.h"
124 #include "Undelete.hh"
126 #if defined(NEED_MMAP_WRAPPER)
129 #include <sys/mman.h>
130 #if defined(NEED_MMAP_WRAPPER)
135 extern XtPointer _XmStringUngenerate (
139 XmTextType output_type);
143 #include <sys/file.h>
146 extern forceUpdate( Widget );
149 (char *name, char *label, int active, RoamMenuWindow *window)
150 : NoUndoCmd (name, label, active)
152 _menuwindow = window;
156 SearchCmd::SearchCmd(
160 RoamMenuWindow *window
161 ) : InterruptibleCmd (name, label, active)
163 _menuwindow = window;
169 TaskDoneCallback callback,
173 InterruptibleCmd::execute( callback, clientData );
180 _menuwindow->list()->clearMsgs();
181 _menuwindow->busyCursor();
184 _criteria=( char * )realloc(_criteria, strlen( this->name()) + 1);
185 strcpy(_criteria, this->name());
188 InterruptibleCmd::execute();
195 DtMailEnv mail_error;
197 // Initialize the mail_error.
200 MsgScrollingList *list=_menuwindow->list();
203 // load_headers will retrieve all of the message headers and
204 // add the handles to the list.
206 count = list->load_headers(mail_error);
208 _menuwindow->normalCursor();
211 _menuwindow->message(GETMSG(DT_catd, 3, 46, "Empty container"));
216 list->scroll_to_bottom();
223 // Just print a message that allows us to trace the execution
225 DebugPrintf(1, "%s: undoit\n", name());
229 SearchCmd::updateMessage (char *msg)
231 InterruptibleCmd::updateMessage(msg);
233 #endif /* DEAD_WOOD */
235 CheckForNewMailCmd::CheckForNewMailCmd(
239 RoamMenuWindow *window
240 ) : NoUndoCmd ( name, label, active )
242 _menuwindow = window;
246 CheckForNewMailCmd::doit()
249 // Initialize the mail_error.
251 _menuwindow->checkForMail(error);
255 OpenInboxCmd::OpenInboxCmd(
260 ) : Cmd (name, label, active)
270 RoamMenuWindow *rmw = theRoamApp.inboxWindow();
274 MailSession *ses = theRoamApp.session();
275 ses->activateRMW(rmw);
280 DtMailEnv mail_error;
281 char *mail_file = NULL;
282 DtMailObjectSpace space;
283 DtMail::Session *d_session = theRoamApp.session()->session();
286 d_session->queryImpl(mail_error,
287 d_session->getDefaultImpl(mail_error),
288 DtMailCapabilityInboxName,
293 if (mail_file) _menuWindow->view_mail_file(mail_file, DTM_FALSE);
298 OpenInboxCmd::undoit()
303 // OpenContainerCmd methods implementation.
304 // For the most part, we treat container->open() as a benign thing.
305 // The magic, as we see it, deals with converting the container
307 // For OpenContainerCmd, if no conversion is necessary bingo! it opens.
308 // If conversion is necessary, it punts the work to ConvertContainerCmd.
312 OpenContainerCmd::OpenContainerCmd (
316 RoamMenuWindow *window
317 ) : RoamInterruptibleCmd (name, label, active)
319 _menuWindow = window;
322 // Parent's execute() ends up calling derived class's doit()
324 OpenContainerCmd::execute()
326 RoamInterruptibleCmd::execute();
330 OpenContainerCmd::execute(
331 RoamTaskDoneCallback rtd_callback,
335 RoamInterruptibleCmd::execute(rtd_callback, clientData);
338 // Tell the RMW to open. The RMW may end up calling its convert()
339 // which depends on ConvertContainerCmd's doit...
340 // By the time RMW->open() returns, the conversion would have
342 // This is the case of a RinterruptibleCmd derived class
343 // getting its work done in its doit() in one call.
347 OpenContainerCmd::doit()
351 assert(_menuWindow != NULL);
353 // Initialize the mail_error.
356 _menuWindow->open(error, _open_create_flag, _open_lock_flag);
358 // Post a dialog indicating error and exit?
359 return; // for now. Should exit instead?
365 OpenContainerCmd::undoit()
367 // Just print a message that allows us to trace the execution
369 DebugPrintf(1, "%s: undoit\n", name());
373 OpenContainerCmd::check_if_done()
375 // Have nothing fancy to do here. Since we do not want a dialog
376 // in any case, set it to true...
384 OpenContainerCmd::post_dialog()
386 // Empty. We don't want a dialog on open...
390 OpenContainerCmd::unpost_dialog()
392 // Empty. We don't post, and we don't unpost.
395 OpenContainerCmd::updateMessage (char *msg)
397 RoamInterruptibleCmd::updateMessage(msg);
401 OpenContainerCmd::set_create_lock_flags(
402 DtMailBoolean create,
406 _open_create_flag = create;
407 _open_lock_flag = lock;
411 // ConvertContainerCmd
414 ConvertContainerCmd::ConvertContainerCmd(
418 RoamMenuWindow *window
419 ) : RoamInterruptibleCmd (name, label, active)
421 _menuWindow = window;
423 _num_to_be_converted = 0;
428 ConvertContainerCmd::execute()
431 _dialog = new DtMailWDM("Convert");
434 RoamInterruptibleCmd::execute();
438 ConvertContainerCmd::execute ( RoamTaskDoneCallback rtd_callback,
442 _dialog = new DtMailWDM("Convert");
445 RoamInterruptibleCmd::execute(rtd_callback, clientData);
448 // Here be bigger dragons!
449 // The doit() calls the session->convert().
450 // And returns right away!
451 // the ses->convert() however ends up calling the conv_cb for every
452 // message that it has converted.
453 // So, we now have two loops working in parallel:
454 // 1) the parent()'s execute() class which called this doit() and is now
455 // calling check_if_done() periodically via its workProc;
456 // 2) the session->convert() which is calling the _conv_cb() for every
457 // message that it converts. In the _conv_cb(), we do the following:
458 // a) force update the dialog and see if it was interrupted;
459 // b) if not interrupted, set_convert_data() where we set _done if
460 // we are really done.
464 ConvertContainerCmd::doit()
466 assert(_menuWindow != NULL);
468 MailSession *ses = theRoamApp.session();
469 DtMailEnv mail_error;
471 // Initialize the mail_error.
474 // ses->convert(mail_error, _src, _dest, _conv_cb, _menuWindow);
476 if (mail_error.isSet()) {
477 _menuWindow->postErrorDialog(mail_error);
482 ConvertContainerCmd::set_convert_data(
487 _num_converted = converted;
488 _num_to_be_converted = to_be_converted;
490 if ((_num_converted == _num_to_be_converted) && !_interrupted) {
496 ConvertContainerCmd::get_num_converted()
498 return(_num_converted);
503 ConvertContainerCmd::check_if_done()
508 else if (_num_converted == _num_to_be_converted) {
514 ConvertContainerCmd::updateDialog(
518 forceUpdate(_dialog->baseWidget());
519 _dialog->updateDialog( msg );
523 ConvertContainerCmd::updateAnimation()
525 forceUpdate(_dialog->baseWidget());
526 _dialog->updateAnimation();
530 ConvertContainerCmd::post_dialog()
532 Dimension x, y, wid, ht;
534 char * buf = new char[25];
536 sprintf(buf, "Converted: %3d%", 0);
538 _dialog->post ("Mailer",
540 _menuWindow->baseWidget(),
543 &RoamInterruptibleCmd::interruptCallback );
545 XtVaGetValues(_dialog->baseWidget(),
555 ConvertContainerCmd::unpost_dialog()
561 ConvertContainerCmd::undoit()
563 // Just print a message that allows us to trace the execution
565 DebugPrintf(1, "%s: undoit\n", name());
569 ConvertContainerCmd::set_data(
572 ConversionStatusCB cb
581 ConvertContainerCmd::get_destination_name()
593 RoamMenuWindow *window
594 ) : RoamCmd ( name, label, active, window )
602 _menuwindow->get_find_dialog();
604 // SearchCmd::doit();
609 ChooseCmd::ChooseCmd(
613 RoamMenuWindow *window
614 ) : NoUndoCmd( name, label, active )
616 _menuwindow = window;
625 SelectAllCmd::SelectAllCmd(
629 RoamMenuWindow *window
630 ) : Cmd ( name, label, active )
632 _menuwindow = window;
638 DtMailEnv mail_error;
640 _menuwindow->list()->select_all_and_display_last(mail_error);
644 SelectAllCmd::undoit()
649 DeleteCmd::DeleteCmd(
653 RoamMenuWindow *window
654 ) : Cmd ( name, label, active )
656 _menuwindow = window;
662 _menuwindow->list()->deleteSelected(FALSE);
672 DestroyCmd::DestroyCmd(
676 RoamMenuWindow *window
677 ) : Cmd(name, label, active)
679 _menuwindow = window;
685 // Call Expunge only if there are deleted messages.
687 if (_menuwindow->list()->get_num_deleted_messages()) {
688 _menuwindow->expunge();
697 // Unified Select File Cmd stuff
698 int UnifiedSelectFileCmd::_is_initialized = 0;
699 char *UnifiedSelectFileCmd::_unified_directory = NULL;
700 char *UnifiedSelectFileCmd::_unified_file = NULL;
701 int UnifiedSelectFileCmd::_unified_hidden = 0;
702 int UnifiedSelectFileCmd::_unify_selection = 1;
704 UnifiedSelectFileCmd::UnifiedSelectFileCmd (
714 :SelectFileCmd (name,
719 unifiedFileSelectedCB,
721 unifiedFileCanceledCB,
725 if (! _is_initialized)
727 FORCE_SEGV_DECL(DtMail::Session, m_session);
729 const char *dirname = NULL;
730 const char *expanded_dirname = NULL;
731 const char *value = NULL;
732 char *full_dirname = NULL;
734 _unified_directory = NULL;
735 _unified_file = NULL;
737 _unify_selection = 1;
740 m_session = theRoamApp.session()->session();
743 m_session->mailRc(error)->getValue(error, "filefolder", &dirname);
745 dirname = strdup("~");
748 expanded_dirname = m_session->expandPath(error, dirname);
749 _unified_directory = XtNewString(expanded_dirname);
752 m_session->mailRc(error)->getValue(
754 "dontunifyfileselection",
757 _unify_selection = 0;
759 free((void*) dirname);
760 free((void*) expanded_dirname);
764 _select_file_callback = select_callback;
765 _select_file_client_data = client_data;
766 _genDialog = new DtMailGenDialog("Dialog", parent);
769 UnifiedSelectFileCmd::~UnifiedSelectFileCmd()
771 if (_genDialog) delete _genDialog;
775 UnifiedSelectFileCmd::doit()
777 if (NULL == _fileBrowser)
779 SelectFileCmd::doit();
780 if (NULL != _unified_directory)
781 setDirectory(_unified_directory);
782 if (NULL != _unified_file)
783 setSelected(_unified_file);
784 setHidden(_unified_hidden);
788 if (_unify_selection)
790 if (NULL != _unified_directory)
791 setDirectory(_unified_directory);
792 if (NULL != _unified_file)
793 setSelected(_unified_file);
794 setHidden(_unified_hidden);
796 SelectFileCmd::doit();
801 UnifiedSelectFileCmd::unifiedFileSelectedCB(void *client_data, char *selection)
803 UnifiedSelectFileCmd *self = (UnifiedSelectFileCmd *) client_data;
807 self->updateUnifiedData();
808 self->unifiedFileSelected(selection);
813 UnifiedSelectFileCmd::unifiedFileSelected(char *selection)
817 SafePathIsAccessible(error, selection);
820 const char *errmsg = NULL;
824 errmsg = (const char*) error;
825 err = strdup(errmsg);
827 _genDialog->setToErrorDialog(GETMSG(DT_catd, 3, 48, "Mailer"), err);
828 answer = _genDialog->post_and_return(DTMAILHELPERROR);
829 if (1 == answer) doit();
834 if (_select_file_callback)
835 _select_file_callback(_select_file_client_data, selection);
839 UnifiedSelectFileCmd::unifiedFileCanceledCB(void *client_data, char *)
841 UnifiedSelectFileCmd *self = (UnifiedSelectFileCmd *) client_data;
844 self->updateUnifiedData();
848 UnifiedSelectFileCmd::updateUnifiedData()
850 if (! _unify_selection)
853 if (NULL != _unified_file)
854 XtFree(_unified_file);
855 _unified_file = getSelected();
858 if (NULL != _unified_directory)
859 XtFree(_unified_directory);
860 _unified_directory = getDirectory();
862 _unified_hidden = getHidden();
865 // Unified Select Mailbox Cmd stuff
866 int UnifiedSelectMailboxCmd::_is_initialized = 0;
867 char *UnifiedSelectMailboxCmd::_unified_directory = NULL;
868 char *UnifiedSelectMailboxCmd::_unified_file = NULL;
869 int UnifiedSelectMailboxCmd::_unified_hidden = 0;
870 int UnifiedSelectMailboxCmd::_unify_selection = 1;
872 UnifiedSelectMailboxCmd::UnifiedSelectMailboxCmd (
882 DtMailBoolean only_show_mailboxes)
883 :SelectFileCmd (name,
888 unifiedMailboxSelectedCB,
890 unifiedMailboxCanceledCB,
894 if (! _is_initialized)
896 FORCE_SEGV_DECL(DtMail::Session, m_session);
898 const char *dirname = NULL;
899 const char *expanded_dirname = NULL;
900 const char *value = NULL;
901 char *full_dirname = NULL;
903 _unified_directory = NULL;
904 _unified_file = NULL;
906 _unify_selection = 1;
908 _only_show_mailboxes = only_show_mailboxes;
910 m_session = theRoamApp.session()->session();
913 m_session->mailRc(error)->getValue(error, "folder", &dirname);
915 dirname = strdup("~");
918 expanded_dirname = m_session->expandPath(error, dirname);
919 _unified_directory = XtNewString(expanded_dirname);
922 m_session->mailRc(error)->getValue(
924 "dontunifyfileselection",
927 _unify_selection = 0;
929 free((void*) dirname);
930 free((void*) expanded_dirname);
934 _select_file_callback = select_callback;
935 _select_file_client_data = client_data;
936 _genDialog = new DtMailGenDialog("Dialog", parent);
939 UnifiedSelectMailboxCmd::~UnifiedSelectMailboxCmd()
941 if (_genDialog) delete _genDialog;
945 UnifiedSelectMailboxCmd::doit()
947 if (NULL == _fileBrowser)
949 SelectFileCmd::doit();
950 if (NULL != _unified_directory)
951 setDirectory(_unified_directory);
952 if (NULL != _unified_file)
953 setSelected(_unified_file);
954 setHidden(_unified_hidden);
960 UnifiedSelectMailboxCmd::unifiedMailboxSearchProc,
965 if (_unify_selection)
967 if (NULL != _unified_directory)
968 setDirectory(_unified_directory);
969 if (NULL != _unified_file)
970 setSelected(_unified_file);
971 setHidden(_unified_hidden);
973 SelectFileCmd::doit();
978 extern void _XmOSBuildFileList(
981 #if NeedWidePrototypes
982 unsigned int typeMask,
984 unsigned char typeMask,
985 #endif /* NeedWidePrototypes */
987 unsigned int *pNumEntries,
988 unsigned int *pNumAlloc);
990 extern int _XmOSFileCompare(const void *sp1, const void *sp2);
991 extern char *_XmStringGetTextConcat(XmString string);
995 UnifiedSelectMailboxCmd::unifiedMailboxSearchProc(
999 XmFileSelectionBoxWidget fs =
1000 (XmFileSelectionBoxWidget) w;
1001 XmFileSelectionBoxCallbackStruct * searchData =
1002 (XmFileSelectionBoxCallbackStruct *) sd;
1008 unsigned int numFiles;
1009 unsigned int numItems = 0;
1010 unsigned int numAlloc;
1011 XmString * XmStringFileList;
1013 XtEnum fileFilterStyle, pathMode;
1014 unsigned char fileTypeMask;
1016 if (!(dir = _XmStringGetTextConcat(searchData->dir)))
1019 if (!(pattern = _XmStringGetTextConcat(searchData->pattern)))
1028 XmNfileTypeMask, &fileTypeMask,
1029 XmNfileFilterStyle, &fileFilterStyle,
1030 XmNpathMode, &pathMode,
1034 dir, pattern, fileTypeMask,
1035 &fileList, &numFiles, &numAlloc);
1037 if (fileList && numFiles)
1039 Boolean showDotFiles = (fileFilterStyle == XmFILTER_NONE);
1042 qsort((void*) fileList, numFiles, sizeof(char*), _XmOSFileCompare);
1044 XmStringFileList = (XmString*) XtMalloc(numFiles*sizeof(XmString));
1047 dirLen = strlen(dir);
1049 while (Index < numFiles)
1051 Boolean isMailBox = 0;
1052 char *dataType = NULL;
1054 dataType = DtDtsFileToDataType(fileList[Index]);
1056 isMailBox = (0 == strcmp(dataType, "DTMAIL_FILE"));
1057 DtDtsFreeDataType(dataType);
1060 (showDotFiles || ((fileList[Index])[dirLen] != '.')) )
1062 if (pathMode == XmPATH_MODE_FULL)
1063 XmStringFileList[numItems++] =
1064 XmStringGenerate(fileList[Index],
1065 XmFONTLIST_DEFAULT_TAG,
1066 XmCHARSET_TEXT, NULL);
1068 XmStringFileList[numItems++] =
1069 XmStringGenerate(&(fileList[Index])[dirLen],
1070 XmFONTLIST_DEFAULT_TAG,
1071 XmCHARSET_TEXT, NULL) ;
1081 XmNfileListItemCount, numItems,
1082 XmNfileListItems, XmStringFileList,
1083 XmNlistUpdated, TRUE,
1088 XtFree( fileList[Index]);
1091 XmStringFree(XmStringFileList[numItems]);
1093 XtFree((char*) XmStringFileList);
1099 XmNfileListItemCount, 0,
1100 XmNfileListItems, NULL,
1101 XmNlistUpdated, TRUE,
1105 XtFree((char *) fileList);
1112 UnifiedSelectMailboxCmd::unifiedMailboxSelectedCB(
1116 UnifiedSelectMailboxCmd *self = (UnifiedSelectMailboxCmd *) client_data;
1120 self->updateUnifiedData();
1121 self->unifiedMailboxSelected(
1122 self->_select_file_callback,
1123 self->_select_file_client_data,
1129 UnifiedSelectMailboxCmd::unifiedMailboxSelected(
1136 SafePathIsAccessible(error, selection);
1139 const char *errmsg = NULL;
1143 errmsg = (const char*) error;
1144 err = strdup(errmsg);
1146 _genDialog->setToErrorDialog(GETMSG(DT_catd, 3, 48, "Mailer"), err);
1147 answer = _genDialog->post_and_return(DTMAILHELPERROR);
1148 if (1 == answer) doit();
1153 updateUnifiedData();
1154 if (cb) cb(client_data, selection);
1158 UnifiedSelectMailboxCmd::unifiedMailboxCanceledCB(void *client_data, char *)
1160 UnifiedSelectMailboxCmd *self = (UnifiedSelectMailboxCmd *) client_data;
1163 self->updateUnifiedData();
1167 UnifiedSelectMailboxCmd::updateUnifiedData()
1169 if (! _unify_selection)
1172 if (NULL != _unified_file)
1173 XtFree(_unified_file);
1174 _unified_file = getSelected();
1177 if (NULL != _unified_directory)
1178 XtFree(_unified_directory);
1179 _unified_directory = getDirectory();
1181 _unified_hidden = getHidden();
1184 ContainerMenuCmd::ContainerMenuCmd(
1188 RoamMenuWindow *window,
1190 ) : RoamCmd ( name, label, active, window )
1192 _menuwindow = window;
1193 _container_name = name;
1198 ContainerMenuCmd::doit()
1200 DtMailEnv mail_error;
1202 // Initialize mail_error.
1205 theRoamApp.busyAllWindows(GETMSG(DT_catd, 3, 15, "Saving..."));
1206 _menuwindow->mailbox()->save();
1207 theRoamApp.unbusyAllWindows();
1214 _menuwindow->view_mail_file(_container_name, DTM_FALSE);
1217 _menuwindow->list()->copySelected(
1221 if (mail_error.isSet())
1223 // We had an error in copying the message to a container!
1227 _menuwindow->list()->copySelected(
1231 if (mail_error.isSet())
1233 // We had an error in moving the message to a container!
1239 ContainerMenuCmd::~ContainerMenuCmd()
1244 // Move the messages that are selected in the RoamMenuWindow to the Inbox.
1245 MoveToInboxCmd::MoveToInboxCmd(
1249 RoamMenuWindow *window
1250 ) : RoamCmd (name, label, active, window)
1252 _menuwindow = window;
1256 MoveToInboxCmd::doit()
1258 DtMailEnv mail_error;
1260 // Initialize mail_error.
1263 // Get a handle to the Inbox.
1264 char * mail_file = NULL;
1265 DtMailObjectSpace space;
1266 DtMail::Session * d_session = theRoamApp.session()->session();
1268 d_session->queryImpl(mail_error,
1269 d_session->getDefaultImpl(mail_error),
1270 DtMailCapabilityInboxName,
1273 _menuwindow->list()->copySelected(mail_error, mail_file, TRUE, FALSE);
1274 if (mail_error.isSet()) {
1275 // We had an error in moving the messages to the Inbox!
1279 MoveToInboxCmd::~MoveToInboxCmd()
1283 // Copy the selected messages to the Inbox.
1284 CopyToInboxCmd::CopyToInboxCmd(
1288 RoamMenuWindow *window
1289 ) : RoamCmd (name, label, active, window)
1291 _menuwindow = window;
1295 CopyToInboxCmd::doit()
1297 DtMailEnv mail_error;
1299 // Initialize mail_error.
1302 // Get a handle to the Inbox.
1303 char * mail_file = NULL;
1304 DtMailObjectSpace space;
1305 DtMail::Session * d_session = theRoamApp.session()->session();
1307 d_session->queryImpl(mail_error,
1308 d_session->getDefaultImpl(mail_error),
1309 DtMailCapabilityInboxName,
1312 _menuwindow->list()->copySelected(mail_error, mail_file, FALSE, FALSE);
1313 if (mail_error.isSet()) {
1314 // We ad an error in copying the messages to the Inbox!
1318 CopyToInboxCmd::~CopyToInboxCmd()
1323 // This is hooked up the Undelete button in the Deleted
1324 // Messages List dialog box.
1326 DoUndeleteCmd::DoUndeleteCmd(
1330 UndelFromListDialog *undelDialog
1331 ) : Cmd ( name, label, active )
1333 _undelDialog = undelDialog;
1337 DoUndeleteCmd::doit()
1339 // Undelete the selected messages.
1340 _undelDialog->undelSelected();
1344 DoUndeleteCmd::undoit()
1349 DoUndeleteCmd::~DoUndeleteCmd()
1353 // This is hooked up to the Close button in the Deleted Messages
1356 CloseUndelCmd::CloseUndelCmd(
1360 UndelFromListDialog *undelDialog
1361 ) : Cmd ( name, label, active )
1363 _undelDialog = undelDialog;
1367 CloseUndelCmd::doit()
1369 // Close the dialog.
1370 _undelDialog->popped_down();
1374 CloseUndelCmd::undoit()
1380 CloseUndelCmd::~CloseUndelCmd()
1384 UndeleteCmd::UndeleteCmd (
1388 RoamMenuWindow *window,
1389 Boolean viaDeleteList
1390 ) : ChooseCmd ( name, label, active, window )
1392 _menuwindow = window;
1393 _undelFromList = NULL;
1394 _fromList = viaDeleteList;
1397 UndeleteCmd::~UndeleteCmd()
1404 FORCE_SEGV_DECL(MsgStruct, tmpMS);
1405 MsgScrollingList *list = _menuwindow->list();
1406 MsgHndArray *deleted_messages;
1407 DtMailEnv mail_error;
1409 // Initialize the mail_error.
1414 // Create the Deleted Messages Dialog
1416 if (_undelFromList) {
1417 // Hack for user testing. If the dialog is up, we destroy it.
1418 XtDestroyWidget(_undelFromList->baseWidget());
1420 // if (!_undelFromList) {
1421 _undelFromList = new UndelFromListDialog(
1422 GETMSG(DT_catd, 1, 227, "Mailer - Deleted Messages"),
1424 _undelFromList->initialize();
1426 // Check for existing list of deleted messages
1427 _num_deleted = list->get_num_deleted_messages();
1429 // If there are deleted messages, put them in the Deleted
1432 if (_num_deleted > 0) {
1433 deleted_messages = list->get_deleted_messages();
1434 _undelFromList->loadMsgs(
1438 if (mail_error.isSet()) {
1439 // Post an exception here!
1440 _menuwindow->postErrorDialog(mail_error);
1444 // Display the dialog
1446 _undelFromList->popped_up();
1448 // Although we don't display the Deleted Message Dialog here, we
1449 // need to make sure that it gets updated for the next time
1451 list->undelete_last_deleted();
1457 SaveCmd::SaveCmd ( char *name,
1460 RoamMenuWindow *window
1461 ) : RoamCmd ( name, label, active, window )
1470 assert(_menuwindow->mailbox() != NULL);
1472 #endif /* DEAD_WOOD */
1476 MoveCopyCmd::MoveCopyCmd( char *name,
1479 FileCallback move_callback,
1480 FileCallback copy_callback,
1481 RoamMenuWindow * menu_window,
1483 DtMailBoolean only_show_mailboxes)
1484 : UnifiedSelectMailboxCmd(name,
1486 GETMSG(DT_catd, 1, 89, "Mailer - Other Mailboxes"),
1492 only_show_mailboxes)
1494 _copy_callback = copy_callback;
1495 _menuwindow = menu_window;
1496 _copy_button = NULL;
1497 _move_button = NULL;
1500 MoveCopyCmd::~MoveCopyCmd()
1505 MoveCopyCmd::setDefault(Widget button)
1509 _default_button = button;
1510 XtSetArg( args[0], XmNdefaultButton, _default_button );
1511 XtSetValues( _fileBrowser, args, 1 );
1518 Widget filter_button;
1519 Widget unused_button;
1523 if (!_fileBrowser) {
1524 UnifiedSelectMailboxCmd::doit();
1525 // Customize buttons for MoveCopy dialog
1526 move = XmStringCreateLocalized(GETMSG(DT_catd, 1, 90, "Move"));
1528 filter_button = XtNameToWidget(_fileBrowser, "*Apply");
1529 _move_button = XtNameToWidget(_fileBrowser, "*OK");
1530 action_area = XtParent(_move_button);
1531 unused_button = XtVaCreateWidget(
1533 xmPushButtonWidgetClass, _fileBrowser,
1535 _copy_button = XtVaCreateManagedWidget(
1536 GETMSG(DT_catd, 1, 237, "Copy"),
1537 /*xmPushButtonWidgetClass, _fileBrowser,*/
1538 xmPushButtonGadgetClass, _fileBrowser,
1540 XmStringCreateLocalized(GETMSG(DT_catd, 1, 43, "Copy")),
1542 printHelpId("Copy", _copy_button);
1544 // add help callback
1545 // XtAddCallback(_copy_button, XmNhelpCallback, HelpCB, helpId);
1551 "dtmailViewmainWindowWork-AreapanedWform2RowColumnMoveCopy");
1554 XmNactivateCallback,
1555 &MoveCopyCmd::fileSelectedCallback2,
1558 if (_menuwindow->mailbox()->mailBoxWritable(error) == DTM_FALSE)
1559 XtUnmanageChild(_move_button);
1561 XtManageChild(_move_button);
1563 // XtVaSetValues(_move_button, XmNsensitive, FALSE);
1565 _file_list = XtNameToWidget(_fileBrowser, "*ItemsList");
1568 XmNbrowseSelectionCallback, &MoveCopyCmd::setDefaultButtonCB,
1572 XmNextendedSelectionCallback, &MoveCopyCmd::setDefaultButtonCB,
1576 XmNmultipleSelectionCallback, &MoveCopyCmd::setDefaultButtonCB,
1580 XmNsingleSelectionCallback, &MoveCopyCmd::setDefaultButtonCB,
1583 _file_text = XtNameToWidget(_fileBrowser, "*Text");
1584 if (NULL != _file_text)
1587 XmNfocusCallback, &MoveCopyCmd::setDefaultButtonCB,
1593 UnifiedSelectMailboxCmd::doit();
1599 MoveCopyCmd::fileSelectedCallback2 (
1601 XtPointer clientData,
1605 MoveCopyCmd *obj = (MoveCopyCmd *) clientData;
1606 XmFileSelectionBoxCallbackStruct *cb =
1607 (XmFileSelectionBoxCallbackStruct *) callData;
1609 char *dir_str = NULL;
1615 static char selected[MAXPATHLEN+1];
1617 // Bring the file selection dialog down.
1618 XtUnmanageChild ( obj->_fileBrowser );
1621 // Get the file name
1623 XtVaGetValues(obj->_fileBrowser, XmNdirectory, &xmstr, NULL);
1625 dname = (char*) _XmStringUngenerate(
1627 XmMULTIBYTE_TEXT, XmMULTIBYTE_TEXT);
1630 // Get the file name
1632 XtVaGetValues(obj->_fileBrowser, XmNdirSpec, &xmstr, NULL);
1635 // Extract the first character string matching the default
1636 // character set from the compound string
1637 fname = (char *) _XmStringUngenerate(
1639 XmMULTIBYTE_TEXT, XmMULTIBYTE_TEXT);
1641 if (NULL == fname || strlen(fname) == 0)
1644 // If a string was successfully extracted, call
1645 // unifiedMailboxSelected to handle the file.
1647 if (NULL != dname) strcat(selected, dname);
1648 strcat(selected, fname);
1649 obj->updateUnifiedData();
1650 obj->unifiedMailboxSelected(
1651 obj->_copy_callback,
1658 MoveCopyCmd::setDefaultButtonCB(
1660 XtPointer clientData,
1663 MoveCopyCmd *thisCmd = (MoveCopyCmd *) clientData;
1664 thisCmd->setDefault(thisCmd->_default_button);
1668 CopyCmd::CopyCmd( char *name,
1671 RoamMenuWindow *window,
1672 MoveCopyCmd *move_copy_cmd
1673 ) : RoamCmd ( name, label, active, window )
1675 _move_copy_cmd = move_copy_cmd;
1685 _move_copy_cmd->doit();
1686 _move_copy_cmd->setDefault(_move_copy_cmd->getCopyButton());
1690 MoveCmd::MoveCmd( char *name,
1693 RoamMenuWindow *window,
1694 MoveCopyCmd *move_copy_cmd
1695 ) : RoamCmd ( name, label, active, window )
1697 _move_copy_cmd = move_copy_cmd;
1707 _move_copy_cmd->doit();
1708 _move_copy_cmd->setDefault(_move_copy_cmd->getMoveButton());
1716 RoamMenuWindow *window
1717 ) : RoamCmd ( name, label, active, window )
1724 _menuwindow->list()->select_next_item();
1732 RoamMenuWindow *window
1733 ) : RoamCmd ( name, label, active, window )
1740 _menuwindow->list()->select_prev_item();
1744 MessagesCmd::MessagesCmd(
1748 RoamMenuWindow *window
1749 ) : RoamCmd ( name, label, active, window )
1757 Boolean old=_menuwindow->fullHeader();
1758 MsgScrollingList *list=_menuwindow->list();
1760 ( !strcmp( this->name(), "Full Header" ) ? _menuwindow->fullHeader( True ) : _menuwindow->fullHeader( False ) );
1762 if ( old!=_menuwindow->fullHeader() && _menuwindow->msgView() ) {
1763 // list->chooseCurrent();
1767 #endif /* DEAD_WOOD */
1769 PrintCmd::PrintCmd (
1774 RoamMenuWindow *window
1775 ) : ChooseCmd ( name, label, active, window ), _tmp_files(5)
1784 // The entire implementation of print was broken. It has
1785 // be removed until a proper implementation can be provided.
1794 DtActionInvocationID id,
1795 XtPointer clientData,
1804 case DtACTION_INVOKED:
1807 data = (PrintCmd *)clientData;
1808 data->_parent->message("");
1809 data->_unregister_tmp_file(id);
1817 PrintCmd::printjobcb( Widget w, XtPointer client_data, XtPointer )
1819 char *filename = (char *) client_data;
1821 XtRemoveCallback(w, XtNdestroyCallback, &PrintCmd::printjobcb, filename);
1828 PrintCmd::printit( int silent )
1831 char *silent_str = "DTPRINTSILENT";
1832 char *tmpdir = new char[MAXPATHLEN+1];
1833 DtMailEnv mail_error;
1834 MsgScrollingList *list;
1836 DebugPrintf(1, "%s: printit\n", name());
1839 sprintf(tmpdir, "%s/%s", getenv("HOME"), DtPERSONAL_TMP_DIRECTORY);
1840 if ((p = tempnam(tmpdir, "dtmail")) == NULL) {
1847 list = _parent->list();
1849 // Copy selected messages to a temp file
1850 int status = list->copySelected(mail_error, p, FALSE, TRUE);
1851 if (mail_error.isSet())
1853 _parent->postErrorDialog(mail_error);
1857 if (0 != status) return;
1860 DmxPrintJob *pjob = new DmxPrintJob(p,
1861 (silent ? DTM_TRUE : DTM_FALSE),
1864 XtAddCallback(pjob->baseWidget(),
1866 &PrintCmd::printjobcb,
1867 (XtPointer) strdup(p));
1875 PrintCmd::_register_tmp_file(
1877 DtActionInvocationID id
1882 // Allocate struct to hold id and temp file
1883 if ((f = (struct tmp_file *)malloc(sizeof(struct tmp_file))) == NULL) {
1887 // Save file name and action id
1888 f->file = strdup(name);
1891 // Add to list of temp files
1892 _tmp_files.append(f);
1898 PrintCmd::_unregister_tmp_file(
1899 DtActionInvocationID id
1905 // Find the temp file that was used by the Action specified by id
1906 for (n = _tmp_files.length() - 1; n >= 0; n--) {
1909 // Found the file. Unlink and free data structs
1913 // Remove entry from list
1914 _tmp_files.remove(n);
1923 PopupCmd::PopupCmd (
1927 PopupWindow * (RoamMenuWindow::* member) (void),
1928 RoamMenuWindow *myparent
1929 ) : NoUndoCmd ( name, label, active )
1938 PopupWindow *popup=(parent->*pmpopup)();
1941 #endif /* DEAD_WOOD */
1943 // OnItemCmd brings up the Help On Item help.
1944 OnItemCmd::OnItemCmd ( char * name,
1947 UIComponent *window )
1948 : NoUndoCmd (name, label, active)
1956 int status = DtHELP_SELECT_ERROR;
1957 Widget widget = _parent->baseWidget();
1958 Widget selWidget = NULL;
1960 // Display the appropriate help information for the selected item.
1962 status = DtHelpReturnSelectedWidgetId(widget, 0, &selWidget);
1964 switch ((int) status) {
1965 case DtHELP_SELECT_ERROR:
1966 printf("Selection Error, cannot continue\n");
1968 case DtHELP_SELECT_VALID:
1969 while (selWidget != NULL) {
1970 if ((XtHasCallbacks(selWidget, XmNhelpCallback)
1971 == XtCallbackHasSome)) {
1972 XtCallCallbacks((Widget) selWidget, XmNhelpCallback, NULL);
1975 selWidget = XtParent(selWidget);
1979 case DtHELP_SELECT_ABORT:
1980 printf("Selection Aborted by user.\n");
1982 case DtHELP_SELECT_INVALID:
1983 printf("You must select a component within your app.\n");
1992 OnAppCmd::OnAppCmd ( char * name,
1995 UIComponent *window )
1996 : NoUndoCmd (name, label, active)
2004 DisplayMain (_parent->baseWidget(), "Mailer", DTMAILWINDOWID);
2007 TasksCmd::TasksCmd ( char * name,
2010 UIComponent *window )
2011 : NoUndoCmd (name, label, active)
2019 DisplayMain (_parent->baseWidget(), "Mailer", HELP_MAILER_TASKS);
2022 ReferenceCmd::ReferenceCmd ( char * name,
2025 UIComponent *window )
2026 : NoUndoCmd (name, label, active)
2032 ReferenceCmd::doit()
2034 DisplayMain (_parent->baseWidget(), "Mailer", HELP_MAILER_REFERENCE);
2037 UsingHelpCmd::UsingHelpCmd ( char * name,
2040 UIComponent *window )
2041 : NoUndoCmd (name, label, active)
2047 UsingHelpCmd::doit()
2049 DisplayMain (_parent->baseWidget(), "Help4Help", "_HOMETOPIC");
2052 RelNoteCmd::RelNoteCmd ( char * name,
2056 ) : NoUndoCmd (name, label, active )
2068 // _genDialog = new DtMailGenDialog("AboutBox", _parent->baseWidget());
2070 // _genDialog->setToAboutDialog();
2071 // answer = _genDialog->post_and_return(GETMSG(DT_catd, 1, 92, "OK"), NULL);
2073 DisplayMain(_parent->baseWidget(), "Mailer", "_copyright");
2076 RelNoteCmd::~RelNoteCmd()
2082 ClearCmd::ClearCmd (
2086 RoamMenuWindow *window
2087 ) : NoUndoCmd (name, label, active )
2095 // ((FindPopup *) parent->find_popup())->clear_text_values();
2098 StartCmd::StartCmd( char *name,
2100 int active ) : Cmd ( name, label, active )
2107 char *forward= ".forward";
2110 GetPasswordEntry(pwd);
2112 char *forward_filename=new char[strlen(pwd.pw_dir)+1+strlen(forward)+1];
2113 sprintf( forward_filename, "%s/%s", pwd.pw_dir, forward );
2123 ChangeCmd::ChangeCmd(
2127 ) : Cmd (name, label, active )
2135 GetPasswordEntry(pwd);
2137 char *user_name=new char[strlen(pwd.pw_name)+1];
2138 strcpy(user_name,pwd.pw_name);
2153 RoamMenuWindow *window
2154 ) : Cmd (name, label, active )
2162 unlink( parent->forwardFilename() );
2163 parent->title( NULL );
2172 #endif /* DEAD_WOOD */
2180 SendMsgDialog *parent,
2182 : NoUndoCmd( name, label, active )
2185 _default_trans = trans_type;
2191 if (!_parent->isMsgValid())
2194 _parent->send_message( this->name(), _default_trans );
2197 // JT - Added methods below
2199 OpenMsgCmd::OpenMsgCmd(
2203 RoamMenuWindow *window)
2204 : RoamCmd (name, label, active, window)
2211 DtMailEnv mail_error;
2213 // Initialize the mail_error.
2216 _menuwindow->list()->viewInSeparateWindow(mail_error);
2217 if (mail_error.isSet()) {
2218 _menuwindow->postErrorDialog(mail_error);
2223 // Attachment Cmds stuff
2225 SaveAttachCmd::SaveAttachCmd ( char *name,
2229 FileCallback save_callback,
2230 RoamMenuWindow *clientData,
2232 :UnifiedSelectFileCmd (name,
2235 GETMSG(DT_catd, 1, 93, "Save"),
2241 _parent = clientData;
2244 SaveAttachCmd::SaveAttachCmd (
2249 FileCallback save_callback,
2250 ViewMsgDialog *clientData,
2253 :UnifiedSelectFileCmd (name,
2256 GETMSG(DT_catd, 1, 93, "Save"),
2262 _parent = clientData;
2265 SaveAttachCmd::SaveAttachCmd (
2270 FileCallback save_callback,
2271 SendMsgDialog *clientData,
2274 :UnifiedSelectFileCmd (name,
2277 GETMSG(DT_catd, 1, 93, "Save"),
2283 _parent = clientData;
2287 SaveAttachCmd::doit()
2289 UnifiedSelectFileCmd::doit();
2291 DtMailEditor *editor = _parent->get_editor();
2292 AttachArea *aa = editor->attachArea();
2293 XmString attachmentName = aa->getSelectedAttachName();
2294 XtVaSetValues(_fileBrowser, XmNtextString, attachmentName, NULL);
2295 XtAddCallback ( _fileBrowser, XmNapplyCallback,
2296 &SaveAttachCmd::updateCallback,
2299 _name = XmStringCopy(attachmentName);
2300 XmStringFree(attachmentName);
2303 // Attachment Cmds stuff
2306 void SaveAttachCmd::updateCallback(Widget, XtPointer clientData, XtPointer )
2308 SaveAttachCmd *obj = (SaveAttachCmd *)clientData;
2310 XtVaSetValues(obj->_fileBrowser, XmNtextString, obj->_name, NULL);
2313 SaveAsTextCmd::SaveAsTextCmd (
2319 RoamMenuWindow *parent_roam_menu_window,
2322 :UnifiedSelectFileCmd (name,
2325 GETMSG(DT_catd, 1, 95, "Save"),
2331 _text_editor = editor;
2332 _roam_menu_window = parent_roam_menu_window;
2335 SaveAsTextCmd::SaveAsTextCmd (
2344 :UnifiedSelectFileCmd (name,
2347 GETMSG(DT_catd, 1, 95, "Save"),
2353 _text_editor = editor;
2354 _roam_menu_window = NULL;
2358 SaveAsTextCmd::fileCB(void * client_data, char * selection)
2360 SaveAsTextCmd * self = (SaveAsTextCmd *)client_data;
2361 self->saveText(selection);
2365 SaveAsTextCmd::saveText(const char * filename)
2368 char *buf = new char[2048];
2371 // Is it already there?
2372 status = SafeAccess(filename, F_OK);
2376 GETMSG(DT_catd, 3, 47, "%s already exists.\nOverwrite?"),
2379 _genDialog->setToQuestionDialog(GETMSG(DT_catd, 3, 48, "Mailer"), buf);
2380 helpId = DTMAILHELPERROR;
2381 answer = _genDialog->post_and_return(helpId);
2387 if (unlink(filename) < 0)
2390 GETMSG(DT_catd, 3, 49, "Unable to overwrite %s.\n\
2391 Check file permissions and retry."),
2393 _genDialog->setToErrorDialog(GETMSG(DT_catd, 3, 50, "Mailer"), buf);
2394 helpId = DTMAILHELPNOOVERWRITE;
2395 _genDialog->post_and_return(helpId);
2401 // Create or truncate, and then write the bits.
2402 int fd = SafeOpen(filename, O_RDWR | O_CREAT | O_TRUNC, 0600);
2405 sprintf(buf, GETMSG(DT_catd, 3, 51, "Unable to create %s."), filename);
2406 _genDialog->setToErrorDialog(GETMSG(DT_catd, 3, 52, "Mailer"), buf);
2407 helpId = DTMAILHELPNOCREATE;
2408 _genDialog->post_and_return(helpId);
2413 if (SafeWrite(fd, "\n", 1) < 1)
2416 GETMSG(DT_catd, 3, 53, "Unable to write to %s."),
2418 _genDialog->setToErrorDialog(GETMSG(DT_catd, 3, 54, "Mailer"), buf);
2419 helpId = DTMAILHELPNOWRITE;
2420 _genDialog->post_and_return(helpId);
2427 if (NULL == _roam_menu_window)
2429 char *text_buf = _text_editor->get_contents();
2430 writeText((XtPointer) fd, text_buf);
2431 XtFree((char*) text_buf);
2434 writeTextFromScrolledList(fd);
2441 SaveAsTextCmd::writeTextFromScrolledList(int fd)
2443 static char buf[2048];
2446 DtMailEnv mail_error;
2447 MsgScrollingList *list;
2448 DmxMailbox *mailbox;
2452 // Create temp file.
2454 char *tmpdir = new char[MAXPATHLEN+1];
2455 sprintf(tmpdir, "%s/%s", getenv("HOME"), DtPERSONAL_TMP_DIRECTORY);
2456 if ((tmppath = tempnam(tmpdir, "dtmail")) == NULL) {
2457 sprintf(buf, GETMSG(DT_catd, 3, 51, "Unable to create %s."), tmpdir);
2458 _genDialog->setToErrorDialog(GETMSG(DT_catd, 3, 52, "Mailer"), buf);
2459 helpId = DTMAILHELPNOCREATE;
2460 _genDialog->post_and_return(helpId);
2467 list = _roam_menu_window->list();
2470 // Copy the selected messages to a temp file.
2472 int status = list->copySelected(mail_error, tmppath, FALSE, TRUE);
2473 if (mail_error.isSet()) {
2474 _roam_menu_window->postErrorDialog(mail_error);
2478 if (0 != status) return;
2480 mailbox = new DmxMailbox(tmppath);
2481 mailbox->loadMessages();
2482 next_msg = mailbox->firstMessage();
2485 DmxPrintHeadersEnum visible_headers;
2487 if (_roam_menu_window->fullHeader())
2488 visible_headers = DMX_PRINT_HEADERS_ALL;
2490 visible_headers = DMX_PRINT_HEADERS_ABBREV;
2494 &SaveAsTextCmd::writeText,
2496 writeText((XtPointer) fd, "\n\n");
2497 } while ((next_msg = mailbox->nextMessage()) != (DmxMsg *) NULL);
2501 // Clean up the temporary file.
2508 SaveAsTextCmd::writeText(XtPointer filedes, char *text_buf)
2510 long fdl = (long) filedes;
2512 int len = strlen(text_buf);
2514 if (SafeWrite(fd, text_buf, len) < len) {
2521 GETMSG(DT_catd, 3, 53, "Unable to write to %s."),
2523 helpId = DTMAILHELPNOWRITE;
2524 _genDialog->setToErrorDialog(GETMSG(DT_catd, 3, 56, "Mailer"), buf);
2525 _genDialog->post_and_return(helpId);
2531 SaveAsTextCmd::doit()
2533 MsgScrollingList *list;
2535 int *pos_list = NULL;
2538 if (_roam_menu_window &&
2539 (list = _roam_menu_window->list()) &&
2540 (listW = list->get_scrolling_list()))
2542 if (!XmListGetSelectedPos(listW, &pos_list, &pos_count))
2547 DtMailGenDialog *dialog = _roam_menu_window->genDialog();
2549 dialog->setToErrorDialog(
2550 GETMSG(DT_catd, 3, 50, "Mailer"),
2551 GETMSG(DT_catd, 2, 16, "No message selected."));
2552 dialog->post_and_return(NULL);
2558 UnifiedSelectFileCmd::doit();
2562 int pos_selected, last_space;
2564 DtMailHeaderLine header;
2565 DtMailMessageHandle msg_handle;
2566 DtMailHeaderRequest request;
2567 DtMail::MailBox *mbox;
2569 pos_selected = list->get_selected_item();
2570 msg_handle = list->msgno(pos_selected);
2572 request.number_of_names = 1;
2573 request.header_name = (char**) malloc(sizeof(char*));
2574 request.header_name[0] = strdup(DtMailMessageSubject);
2576 mbox = _roam_menu_window->mailbox();
2577 mbox->getMessageSummary(error, msg_handle, request, header);
2579 if (0 != header.header_values[0].length())
2581 const char *orig_subject = *((header.header_values[0])[0]);
2583 int orig_len = strlen(orig_subject);
2584 char *subject = (char*) malloc(orig_len + 1);
2587 for (i=0,j=0,last_space=0; i<orig_len; i++)
2589 if (isspace(orig_subject[i]))
2591 if (last_space < i-1)
2596 else if (orig_subject[i] == '/')
2597 subject[j++] = '\\';
2599 subject[j++] = orig_subject[i];
2603 xms = XmStringCreateLocalized(subject);
2604 XtVaSetValues(_fileBrowser, XmNtextString, xms, NULL);
2610 if (NULL != request.header_name)
2612 if (NULL != request.header_name[0])
2613 free(request.header_name[0]);
2614 free(request.header_name);
2617 mbox->clearMessageSummary(header);
2622 DeleteAttachCmd::DeleteAttachCmd(
2628 ) : Cmd ( name, label, active )
2634 DeleteAttachCmd::doit()
2636 _parent->delete_selected_attachments();
2640 DeleteAttachCmd::undoit()
2644 UndeleteAttachCmd::UndeleteAttachCmd(
2650 ) : Cmd ( name, label, active )
2656 UndeleteAttachCmd::doit()
2658 _parent->undelete_last_deleted_attachment();
2663 UndeleteAttachCmd::undoit()
2667 RenameAttachCmd::RenameAttachCmd (
2672 ) : Cmd ( name, label, active )
2674 Widget renameDialog;
2678 renameDialog = XmCreatePromptDialog(
2685 message = XmStringCreateLocalized(GETMSG(DT_catd, 1, 96, "Empty"));
2686 XtVaSetValues(renameDialog, XmNselectionLabelString, message, NULL);
2687 XmStringFree(message);
2688 XmString ok_str = XmStringCreateLocalized(GETMSG(DT_catd, 1, 97, "Rename"));
2689 XtVaSetValues(XtParent(renameDialog),
2690 XmNtitle, GETMSG(DT_catd, 1, 98, "Mailer - Rename"),
2692 XtVaSetValues(renameDialog,
2693 XmNokLabelString, ok_str,
2696 XmStringFree(ok_str);
2697 XtUnmanageChild(XmSelectionBoxGetChild(renameDialog, XmDIALOG_HELP_BUTTON));
2699 _parent->get_editor()->attachArea()->setRenameDialog(renameDialog);
2700 XtAddCallback(renameDialog, XmNcancelCallback,
2701 &RenameAttachCmd::cancelCallback,
2703 XtAddCallback(renameDialog, XmNokCallback,
2704 &RenameAttachCmd::okCallback,
2708 void RenameAttachCmd::doit()
2710 Widget renameDialog;
2711 XmString oldAttachName = NULL;
2716 if (!_parent->renameAttachmentOK()) {
2720 aa = _parent->get_editor()->attachArea();
2722 oldAttachName = aa->getSelectedAttachName();
2724 if (oldAttachName == NULL) return;
2726 renameDialog = aa->getRenameDialog();
2728 sprintf(buf, GETMSG(DT_catd, 3, 57, "Rename attachment as"));
2730 message = XmStringCreateLocalized(buf);
2732 XtVaSetValues(renameDialog,
2733 XmNselectionLabelString, message,
2734 XmNtextString, oldAttachName,
2738 XmStringFree(message);
2739 XmStringFree(oldAttachName);
2741 XtManageChild(renameDialog);
2742 XtPopup(XtParent(renameDialog), XtGrabNone);
2745 void RenameAttachCmd::undoit()
2747 // Just print a message that allows us to trace the execution
2751 void RenameAttachCmd::cancelCallback (
2753 XtPointer clientData,
2757 RenameAttachCmd *obj = (RenameAttachCmd *) clientData;
2759 obj->cancel( callData );
2762 void RenameAttachCmd::cancel( XtPointer )
2766 aa = _parent->get_editor()->attachArea();
2768 Widget renameDialog = aa->getRenameDialog();
2770 XtUnmanageChild(renameDialog);
2773 void RenameAttachCmd::okCallback (
2775 XtPointer clientData,
2779 RenameAttachCmd *obj = (RenameAttachCmd *) clientData;
2780 obj->ok( callData );
2783 void RenameAttachCmd::ok( XtPointer callData )
2785 XmSelectionBoxCallbackStruct *cbs =
2786 (XmSelectionBoxCallbackStruct *)callData;
2789 aa = _parent->get_editor()->attachArea();
2791 Widget renameDialog = aa->getRenameDialog();
2793 XtUnmanageChild(renameDialog);
2795 aa->setSelectedAttachName(cbs->value);
2799 AttachmentActionCmd::AttachmentActionCmd(
2802 RoamMenuWindow *rmw,
2804 ) : Cmd (name, label, TRUE)
2811 AttachmentActionCmd::AttachmentActionCmd(
2816 ) : Cmd (name, label, TRUE)
2823 AttachmentActionCmd::AttachmentActionCmd(
2828 ) : Cmd (name, label, TRUE)
2837 AttachmentActionCmd::doit()
2839 _parent->invokeAttachmentAction(_index);
2843 AttachmentActionCmd::undoit()
2847 SelectAllAttachsCmd::SelectAllAttachsCmd(
2851 ) : Cmd(name, label, TRUE)
2856 SelectAllAttachsCmd::SelectAllAttachsCmd(
2860 ) : Cmd(name, label, TRUE)
2865 SelectAllAttachsCmd::SelectAllAttachsCmd(
2869 ) : Cmd(name, label, FALSE)
2875 SelectAllAttachsCmd::doit()
2877 _parent->selectAllAttachments();
2881 SelectAllAttachsCmd::undoit()
2886 ShowAttachPaneCmd::ShowAttachPaneCmd(
2889 AbstractEditorParent *aep
2890 ) : ToggleButtonCmd(name, label, TRUE)
2896 ShowAttachPaneCmd::doit()
2899 if (!this->getButtonState()) {
2900 _parent->hideAttachArea();
2902 else { // button is ON
2903 _parent->showAttachArea();
2908 ShowAttachPaneCmd::undoit()
2913 AbbrevHeadersCmd::AbbrevHeadersCmd(
2917 ) : ToggleButtonCmd(name, label, TRUE)
2923 AbbrevHeadersCmd::doit()
2926 if (!this->getButtonState()) {
2927 _parent->fullHeader(TRUE);
2929 else { // button is ON
2930 _parent->fullHeader(FALSE);
2935 AbbrevHeadersCmd::undoit()
2946 : NoUndoCmd(name, label, active)
2948 _compose_dialog = s;
2955 // Call the goAway() method on the SMD. Argument TRUE requests it
2956 // to check if the SMD is dirty. Let it handle the
2957 // case where text may be present in the compose window.
2958 if (!_compose_dialog->isMsgValid())
2961 _compose_dialog->goAway(TRUE);
2965 EditUndoCmd::EditUndoCmd(
2969 AbstractEditorParent *w )
2970 : NoUndoCmd( name, label, active )
2972 editor = w->get_editor()->textEditor();
2978 editor->undo_edit();
2981 EditCutCmd::EditCutCmd(
2985 AbstractEditorParent *w
2987 : NoUndoCmd( name, label, active )
2989 editor = w->get_editor()->textEditor();
2991 // className() is a virtual method
2992 if (w->className() == "SendMsgDialog") {
2993 _compose_dialog = (SendMsgDialog *)w;
2996 _compose_dialog = NULL;
3003 editor->cut_selection();
3005 if (_compose_dialog) {
3007 _compose_dialog->activate_edit_paste();
3008 _compose_dialog->activate_edit_paste_indented();
3009 _compose_dialog->activate_edit_paste_bracketed();
3013 EditCopyCmd::EditCopyCmd(
3017 AbstractEditorParent *w )
3018 : NoUndoCmd( name, label, active )
3020 editor = w->get_editor()->textEditor();
3022 // className() is a virtual method
3023 if (w->className() == "SendMsgDialog") {
3024 _compose_dialog = (SendMsgDialog *)w;
3027 _compose_dialog = NULL;
3034 editor->copy_selection();
3035 if (_compose_dialog) {
3037 _compose_dialog->activate_edit_paste();
3038 _compose_dialog->activate_edit_paste_indented();
3039 _compose_dialog->activate_edit_paste_bracketed();
3043 EditPasteCmd::EditPasteCmd(
3047 AbstractEditorParent *w )
3048 : NoUndoCmd( name, label, active )
3050 editor = w->get_editor()->textEditor();
3054 EditPasteCmd::doit()
3056 editor->paste_from_clipboard();
3059 EditPasteSpecialCmd::EditPasteSpecialCmd(
3063 AbstractEditorParent *w,
3064 Editor::InsertFormat format)
3065 : NoUndoCmd( name, label, active )
3067 editor = w->get_editor()->textEditor();
3068 insert_format = format;
3072 EditPasteSpecialCmd::doit()
3074 editor->paste_special_from_clipboard(insert_format);
3078 EditClearCmd::EditClearCmd(
3082 AbstractEditorParent *w )
3083 : NoUndoCmd( name, label, active )
3085 editor = w->get_editor()->textEditor();
3086 // this->deactivate();
3090 EditClearCmd::doit()
3092 editor->clear_selection();
3094 // _edit_paste->activate();
3097 EditDeleteCmd::EditDeleteCmd(
3101 AbstractEditorParent *w )
3102 : NoUndoCmd( name, label, active )
3104 editor = w->get_editor()->textEditor();
3105 // this->deactivate();
3109 EditDeleteCmd::doit()
3111 editor->delete_selection();
3113 // _edit_paste->deactivate();
3116 EditSelectAllCmd::EditSelectAllCmd(
3120 AbstractEditorParent *w )
3121 : NoUndoCmd( name, label, active )
3123 editor = w->get_editor()->textEditor();
3127 EditSelectAllCmd::doit()
3129 editor->select_all();
3134 WordWrapCmd::WordWrapCmd(
3138 AbstractEditorParent *w
3139 ) : ToggleButtonCmd( name, label, active )
3141 editor = w->get_editor()->textEditor();
3143 * allow the app-defaults setting for WordWrap
3146 Widget _w = editor->get_text_widget();
3149 XtSetArg( args[0], XmNwordWrap, &cur_setting );
3150 XtGetValues( _w, args, 1 );
3151 editor->set_word_wrap(cur_setting);
3157 cur_setting = ((ToggleButtonCmd *)this)->getButtonState();
3158 editor->set_word_wrap(cur_setting);
3162 WordWrapCmd::wordWrap()
3164 return(cur_setting);
3167 FindChangeCmd::FindChangeCmd(
3171 AbstractEditorParent *w )
3172 : NoUndoCmd( name, label, active )
3174 editor = w->get_editor()->textEditor();
3178 FindChangeCmd::doit()
3180 editor->find_change();
3187 AbstractEditorParent *w )
3188 : NoUndoCmd( name, label, active )
3190 editor = w->get_editor()->textEditor();
3204 : NoUndoCmd (name, label, active)
3207 _alias = strdup(name);
3215 XtVaGetValues(_header, XmNvalue, &value, NULL);
3219 char *newvalue = (char *) malloc(strlen(value) + strlen(_alias) + 3);
3220 sprintf(newvalue, "%s, %s", value, _alias);
3221 XtVaSetValues(_header, XmNvalue, newvalue, NULL);
3225 XtVaSetValues(_header, XmNvalue, _alias, NULL);
3230 AliasCmd::~AliasCmd()
3232 free((void*) _alias);
3236 OtherAliasesCmd::OtherAliasesCmd(
3240 : NoUndoCmd (name, label, active)
3245 OtherAliasesCmd::doit()
3247 OptCmd *optCmd = (OptCmd *) theRoamApp.mailOptions();
3248 optCmd->displayAliasesOptionsPane();
3251 OtherAliasesCmd::~OtherAliasesCmd()
3256 FormatCmd::FormatCmd(
3260 AbstractEditorParent *w )
3261 : NoUndoCmd( name, label, active )
3263 editor = w->get_editor()->textEditor();
3272 LogMsgCmd::LogMsgCmd(
3276 SendMsgDialog * send
3277 ) : ToggleButtonCmd( name, label, active )
3279 // Go to props and find out the default, ie. to log or not to log.
3280 // But for now, just look in .mailrc to see if "record" is set.
3283 const char *logfile = NULL;
3292 if (!((ToggleButtonCmd *)this)->getButtonState()) {
3293 // turn off logging for this message
3294 _send->setLogState(DTM_FALSE);
3297 // turn on logging for this message
3298 _send->setLogState(DTM_TRUE);
3304 VacationCmd::VacationCmd(
3307 ) : Cmd (name, label, TRUE)
3310 _forwardFile = ".forward";
3311 _backupSuffix = "..BACKUP";
3317 // Check if a .forward file exists.
3319 _priorVacationRunning = this->priorVacationRunning();
3321 // parse the .vacation.msg file and retain the subject
3323 // They need to be retrieved for display in the dialog.
3325 this->parseVacationMessage();
3329 VacationCmd::~VacationCmd()
3331 if (NULL != _subject)
3332 free((void*) _subject);
3343 static unsigned long
3344 writeToFileDesc(const char * buf, int len, va_list args)
3346 int fd = va_arg(args, int);
3347 int cnt = va_arg(args, int);
3351 status = SafeWrite(fd, buf, len);
3352 } while (status < 0 && errno == EAGAIN);
3358 VacationCmd::startVacation(
3363 int i = this->handleMessageFile(subj, text);
3365 i = this->handleForwardFile();
3372 VacationCmd::stopVacation()
3374 char *forwardfile = new char[MAXPATHLEN+1];
3376 sprintf(forwardfile, "%s/%s", getenv("HOME"), _forwardFile);
3378 // Remove the current .forward file (it has vacation in it)
3379 // Recover and replace the original backup forward file, if
3382 unlink(forwardfile);
3384 this->recoverForwardFile(forwardfile);
3385 delete [] forwardfile;
3389 VacationCmd::priorVacationRunning()
3394 Boolean retval = FALSE;
3395 char *forwardfile = new char[MAXPATHLEN+1];
3397 sprintf(forwardfile, "%s/%s", getenv("HOME"), _forwardFile);
3399 if (SafeAccess(forwardfile, F_OK) != 0) {
3400 delete [] forwardfile;
3404 fd = SafeOpen(forwardfile, O_RDONLY);
3406 buf[sizeof buf -1] = '\0';
3408 while ((len = SafeRead(fd, buf, (sizeof buf) - 1)) > 0) {
3410 if ((strstr(buf, "/usr/bin/vacation")) ||
3411 (strstr(buf, "/usr/ucb/vacation"))) {
3419 delete [] forwardfile;
3424 VacationCmd::handleForwardFile()
3434 Boolean forwardExists;
3435 DtMailGenDialog *dialog;
3437 int error_bufLen = 10000;
3438 char *error_buf = new char[error_bufLen];
3439 char *forwardfile = new char[MAXPATHLEN+1];
3440 char *messagefile = new char[256];
3441 char *buf = new char[2048];
3443 // initialize the error_buf
3444 memset(error_buf, 0, error_bufLen);
3445 memset(buf, 0, 2048);
3449 forwardExists = FALSE;
3452 GetPasswordEntry(pw);
3454 sprintf(forwardfile, "%s/%s", pw.pw_dir, _forwardFile);
3456 if (SafeAccess(forwardfile, F_OK) == 0 ) {
3457 forwardExists = TRUE;
3460 forwardExists = FALSE;
3463 if (forwardExists && !_priorVacationRunning) {
3465 /* STRING_EXTRACTION -
3467 * This confirmation window is brought up when the user
3468 * tries to update the vacation status when the user is
3469 * already using a .forward file.
3471 if (NULL != _dialog)
3474 dialog = theRoamApp.genDialog();
3476 sprintf(error_buf, GETMSG(DT_catd, 1, 102, "You are already using the forwarding facility for\nsomething other than Vacation. While Vacation is\nrunning, Vacation will be appended to this other\nforwarding activity. Is it still OK to start Vacation?\0"));
3478 dialog->setToQuestionDialog(GETMSG(DT_catd, 1, 103, "Mailer"),
3481 helpId = DTMAILHELPOKSTARTVACATION;
3482 answer = dialog->post_and_return(helpId);
3484 if (answer == 2) {// Cancel chosen
3486 delete [] messagefile;
3487 delete [] error_buf;
3488 delete [] forwardfile;
3492 if (this->backupFile(forwardfile) < 0) {
3494 delete [] messagefile;
3495 delete [] error_buf;
3496 delete [] forwardfile;
3500 /* A .forward file is currently in use. Merge vacation
3501 * into this file, rather than overwrite it. To do so,
3502 * set the appropriate variable to indicate mode.
3505 _priorVacationRunning = TRUE;
3507 // Turn on the bit to indicate we are currently using a .forward
3510 else if (forwardExists && _priorVacationRunning) {
3512 /* STRING_EXTRACTION -
3514 * This confirmation window is brought up when the user
3515 * tries to update the vacation status when the user is
3516 * already using a .forward file.
3519 if (NULL != _dialog)
3522 dialog = theRoamApp.genDialog();
3524 sprintf(error_buf, GETMSG(DT_catd, 1, 104, "You are already running the vacation program in your .forward file.\nConsult documentation on how to stop it and remove it from your .forward file.\nTry this command after fixing that problem.\0"));
3526 dialog->setToErrorDialog("Error", error_buf);
3527 helpId = DTMAILHELPREMOVEVACATION;
3528 answer = dialog->post_and_return(helpId);
3531 delete [] messagefile;
3532 delete [] error_buf;
3533 delete [] forwardfile;
3538 // Re-initialize the error_buf
3539 memset(error_buf, 0, error_bufLen);
3541 sprintf(messagefile, "%s/.vacation.msg", pw.pw_dir);
3543 if (forwardExists) {
3544 fwd_fd = SafeOpen(forwardfile, O_WRONLY | O_APPEND | O_CREAT);
3547 fwd_fd = SafeOpen(forwardfile, O_WRONLY | O_CREAT);
3550 if (fwd_fd < 0 ) {// If fwdfile is not writable/appendable
3552 // Put up error dialog indicating fwdfile not writable
3553 /* restore the original .forward file */
3555 this->recoverForwardFile(forwardfile);
3557 delete [] messagefile;
3558 delete [] error_buf;
3559 delete [] forwardfile;
3563 SafeFChmod(fwd_fd, 0644);
3565 // Make buf be forwardfile._backupSuffix.
3566 // Then create a backup file of name buf
3568 strcpy(buf, forwardfile);
3569 strcat(buf, _backupSuffix);
3571 // If we are currently using a .forward then we need to append/prepend
3572 // the vacation command
3576 /* CREATE NEW .forward FILE
3578 * The original .forward file has been renamed to the
3579 * backup file name. We need to open the backup .forward
3580 * file so we can copy from it.
3583 if ((bkup_fd = SafeOpen(buf, O_RDONLY)) < 0) {
3584 /* restore the original .forward file */
3586 this->recoverForwardFile(forwardfile);
3588 delete [] messagefile;
3589 delete [] error_buf;
3590 delete [] forwardfile;
3594 /* COPY OLD .forward TO NEW .forward
3596 * Using mmap is quite fast, so rather than do a while
3597 * loop to copy line by line, we'll use mmap followed by
3601 fsize= (int)lseek(bkup_fd, 0, SEEK_END);
3605 (caddr_t) mmap(0, fsize, PROT_READ, MAP_PRIVATE, bkup_fd, 0);
3608 if (fwdptr == (char *)-1) {
3611 delete [] messagefile;
3612 delete [] error_buf;
3613 delete [] forwardfile;
3619 if (SafeWrite(fwd_fd, fwdptr, fsize) < fsize) {
3622 delete [] messagefile;
3623 delete [] error_buf;
3624 delete [] forwardfile;
3629 /* RELEASE .forward FILE
3631 * Un-mmap the new .forward file
3634 lastchar = fwdptr[fsize-1];
3635 munmap(fwdptr, fsize);
3640 /* APPEND VACATION LINE
3642 * The new .forward file is still open, so append the
3643 * new line below as the last line of the .forward file.
3644 * Check to make sure last character in the file is a
3645 * newline. If it's not, add one so our work goes on
3649 if (lastchar != '\n') {
3650 lseek(fwd_fd, 0, SEEK_END);
3652 if (SafeWrite(fwd_fd, txt, strlen(txt)) < strlen(txt)) {
3655 delete [] messagefile;
3656 delete [] error_buf;
3657 delete [] forwardfile;
3664 * Now, add the vacation line to the next line.
3666 char *append_buf1 = new char[1024*2];
3667 sprintf(append_buf1, "|\" /usr/bin/vacation %s\"\n", pw.pw_name);
3669 if (SafeWrite(fwd_fd, append_buf1, strlen(append_buf1)) <
3670 strlen(append_buf1)) {
3673 delete [] messagefile;
3674 delete [] error_buf;
3675 delete [] forwardfile;
3676 delete [] append_buf1;
3680 delete [] append_buf1;
3685 /* Create known backup file. The known backup
3686 * file allows mailtool to differentiate between
3687 * vacation being started from mailtool, and vacation
3688 * being invoked (the Unix program as opposed to the
3689 * MailTool Vacation menu item) via tty session.
3692 if (!forwardExists) {
3694 if ((bkup_fd = SafeOpen(buf, O_WRONLY | O_APPEND | O_CREAT)) < 0) {
3695 /* restore the original .forward file */
3697 this->recoverForwardFile(forwardfile);
3699 delete [] messagefile;
3700 delete [] error_buf;
3701 delete [] forwardfile;
3706 char *end_text = "User not using forward file\n";
3708 if (SafeWrite(bkup_fd, end_text, strlen(end_text)) <
3712 delete [] messagefile;
3713 delete [] error_buf;
3714 delete [] forwardfile;
3720 if (!forwardExists) {
3722 /* WRITE NEW .forward FILE
3724 * There was no .forward file, so no appending
3725 * must be done. Simply write the standard
3726 * vacation line into the new .forward file.
3729 char *append_buf2 = new char[1024*2];
3731 sprintf(append_buf2, "\\%s, |\" /usr/bin/vacation %s\"\n",
3732 pw.pw_name, pw.pw_name);
3733 if (SafeWrite(fwd_fd, append_buf2, strlen(append_buf2)) <
3734 strlen(append_buf2)) {
3738 delete [] messagefile;
3739 delete [] error_buf;
3740 delete [] forwardfile;
3741 delete [] append_buf2;
3744 delete [] append_buf2;
3750 system("/usr/bin/vacation -I");
3753 delete [] messagefile;
3754 delete [] error_buf;
3755 delete [] forwardfile;
3760 VacationCmd::backupFile(
3764 char *buf = new char[MAXPATHLEN+1];
3767 strcat(buf, _backupSuffix);
3769 if (rename(file, buf) < 0) {
3770 /* STRING_EXTRACTION -
3772 * We tried to make a backup copy of your .forward file, but
3773 * it failed. The first %s is the name of the rename
3774 * target; the second %s is the system error string.
3777 // Put up error dialog
3787 VacationCmd::recoverForwardFile(
3791 char *buf = new char[BUFSIZ+1];
3795 strcat(buf, _backupSuffix);
3797 if (rename(buf, file) < 0) {
3799 /* STRING_EXTRACTION -
3801 * We tried to restore your original .forward file, but could
3802 * not. The first %s is the name of the original .forward file,
3803 * the second %s is the the system error string.
3806 // Handle dialog indicating error in recovering .forward file.
3807 // Error usually caused by starting /usr/bin/vacation outside
3814 if ((fd = SafeOpen(file, O_RDONLY)) == 0) {
3819 buf[sizeof file -1] = '\0';
3820 while (SafeRead(fd, buf, BUFSIZ) != 0) {
3821 if (strstr(buf, "User not using forward file")) {
3834 VacationCmd::subject()
3844 return((char *)_body);
3852 VacationCmd::parseVacationMessage()
3857 DtMailGenDialog *dialog;
3860 char dialog_text[1024*4];
3862 DtMail::Session * d_session = theRoamApp.session()->session();
3865 if (NULL != _dialog)
3868 dialog = theRoamApp.genDialog();
3870 GetPasswordEntry(pw);
3872 char *messagefile = new char[MAXPATHLEN+1];
3873 sprintf(messagefile, "%s/.vacation.msg", pw.pw_dir);
3875 // See if the messagefile exists.
3876 // If it doesn't create one and throw in the text found in the
3877 // properties sheet. If no text found, use default template.
3879 char * fullpath = d_session->expandPath(error, messagefile);
3880 delete [] messagefile;
3883 // Map the file and try to parse it as a message. If it is a message,
3884 // then load it with headers. Otherwise, throw everything into the
3888 fd = SafeOpen(fullpath, O_RDONLY);
3891 if (fd < 0) {// File doesn't exist
3899 if (SafeFStat(fd, &buf) < 0) {
3901 sprintf(dialog_text,
3902 GETMSG(DT_catd, 1, 105, "Cannot open .vacation.msg file -- No write permission."));
3903 dialog->setToQuestionDialog("Mailer", dialog_text);
3904 helpId = DTMAILHELPNOWRITEVACATION;
3905 answer = dialog->post_and_return(helpId);
3914 int page_size = (int)sysconf(_SC_PAGESIZE);
3915 size_t map_size = (int) (buf.st_size +
3916 (page_size - (buf.st_size % page_size)));
3918 if (buf.st_size == 0)
3922 mbuf.size = buf.st_size;
3924 mbuf.buffer = (char *)mmap(0, map_size, PROT_READ, MAP_PRIVATE, fd, 0);
3926 mbuf.buffer = mmap(0, map_size, PROT_READ, MAP_PRIVATE, fd, 0);
3928 if (mbuf.buffer == (char *)-1) {
3930 mbuf.buffer = new char[mbuf.size];
3931 if (mbuf.buffer == NULL) {
3932 dialog->setToErrorDialog(GETMSG(DT_catd, 3, 59, "No Memory"),
3933 GETMSG(DT_catd, 3, 60, "There is not enough memory to load the existing .vacation.msg file."));
3934 helpId = DTMAILHELPNOLOADVACATION;
3935 answer = dialog->post_and_return(helpId);
3944 if (SafeRead(fd, mbuf.buffer, (unsigned int)mbuf.size) < mbuf.size) {
3945 dialog->setToErrorDialog(GETMSG(DT_catd, 3, 61, "Mailer"),
3946 GETMSG(DT_catd, 3, 62, "The existing .vacation.msg file appears to be corrupt."));
3947 helpId = DTMAILHELPCORRUPTVACATION;
3948 answer = dialog->post_and_return(helpId);
3950 delete [] mbuf.buffer;
3958 // Now we ask the library to parse it. If this fails for any reason, this
3959 // is not a message, so we give up.
3961 DtMail::Message * msg = d_session->messageConstruct(error,
3969 if (error.isSet()) {
3976 DtMail::Envelope * env = msg->getEnvelope(error);
3977 DtMailHeaderHandle hnd;
3981 DtMailValueSeq value;
3983 for (hnd = env->getFirstHeader(error, &name, value);
3984 error.isNotSet() && hnd;
3985 hnd = env->getNextHeader(error, hnd, &name, value)) {
3987 if (!strcmp(name, "Subject") == 0) {
3993 for (int slen = 0; slen < value.length(); slen++) {
3994 max_len += strlen(*(value[slen]));
3997 char * new_str = new char[max_len + (value.length() * 3)];
3999 strcpy(new_str, "");
4000 for (int copy = 0; copy < value.length(); copy++) {
4002 strcat(new_str, " ");
4005 strcat(new_str, *(value[copy]));
4008 _subject = strdup(new_str);
4016 DtMail::BodyPart * bp = msg->getFirstBodyPart(error);
4017 if (error.isNotSet()) {
4018 unsigned long length;
4020 bp->getContents(error,
4030 // Avoid a memory leak.
4038 VacationCmd::handleMessageFile(
4045 DtMailGenDialog *dialog;
4048 char dialog_text[1024*4];
4049 Boolean text_changed = FALSE;
4050 char *messagefile = new char[256];
4052 BufferMemory buf(4096);
4054 if (NULL != _dialog)
4057 dialog = theRoamApp.genDialog();
4059 // Check if a .forward file exists.
4061 GetPasswordEntry(pw);
4063 sprintf(messagefile, "%s/.vacation.msg", pw.pw_dir);
4065 // See if the messagefile exists.
4066 // If it doesn't create one and throw in the text found in the
4067 // properties sheet. If no text found, use default template.
4071 int msg_file_exists = SafeAccess(messagefile, F_OK);
4073 if (_subject == NULL || strcmp(_subject, subj) != 0)
4074 text_changed = TRUE;
4076 else if (_subject != NULL)
4077 text_changed = TRUE;
4079 if (!text_changed) {
4081 if (_body == NULL || strcmp((char*)_body, text) != 0)
4082 text_changed = TRUE;
4084 else if (_body != NULL)
4085 text_changed = TRUE;
4088 if (msg_file_exists >= 0 && text_changed) {
4089 sprintf(dialog_text,
4090 GETMSG(DT_catd, 1, 106, ".vacation.msg file exists. Replace with new text?"));
4091 dialog->setToQuestionDialog("Mailer", dialog_text);
4092 helpId = DTMAILHELPEXISTSVACATION;
4093 answer = dialog->post_and_return(helpId);
4096 // backup the messageFile
4097 this->backupFile(messagefile);
4101 // If the file doesn't exist or if the user has okayed creation
4103 if ((msg_file_exists < 0) || (answer == 1)) {
4105 fd = SafeOpen(messagefile, O_WRONLY | O_CREAT);
4107 sprintf(dialog_text,
4108 GETMSG(DT_catd, 1, 107, "Cannot open .vacation.msg file -- No write permission."));
4109 dialog->setToQuestionDialog("Mailer", dialog_text);
4110 helpId = DTMAILHELPERROR;
4111 answer = dialog->post_and_return(helpId);
4113 // Handle dialog indicating file not writable
4114 delete [] messagefile;
4117 SafeFChmod (fd, 0644);
4121 * This is the default value of the subject field in the
4122 * message that gets returned to the sender when vacation
4125 subj = GETMSG(DT_catd, 1, 108, "I am on vacation");
4127 buf.appendData("Subject: ", 9);
4128 buf.appendData(subj, strlen(subj));
4129 buf.appendData("\nPrecedence: junk\n\n", 19);
4133 _subject = strdup(subj);
4136 text = GETMSG(DT_catd, 1, 109,
4137 "I'm on vacation.\nYour mail regarding \"$SUBJECT\" will be read when I return.\n");
4139 buf.appendData(text, strlen(text));
4140 if (strlen(text) > 0 && text[strlen(text) - 1] != '\n') {
4141 buf.appendData("\n", 1);
4143 _body = strdup(text);
4145 buf.iterate(writeToFileDesc, fd);
4149 delete [] messagefile;