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 libraries 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>
81 #include <X11/Intrinsic.h>
83 #include <Xm/FileSBP.h>
84 #include <Xm/FileSB.h>
86 #include <Xm/ToggleB.h>
87 #include <Xm/PushBG.h>
88 #include <Xm/PanedW.h>
91 #include <Dt/Action.h>
93 #include <Dt/DtPStrings.h>
95 #include <DtMail/IO.hh>
96 #include <DtMail/DtMailError.hh>
98 #include <DtMail/Buffer.hh>
101 #include <DtMail/Buffer.hh>
103 #include <DtMail/OptCmd.h>
104 #include <EUSCompat.h>
105 #include "EUSDebug.hh"
106 #include "Application.h"
107 #include "AttachArea.h"
108 #include "Attachment.h"
110 #include "DmxPrintJob.h"
111 #include "DtMailEditor.hh"
112 #include "DtMailGenDialog.hh"
113 #include "DtMailHelp.hh"
114 #include "DtMailWDM.hh"
115 #include "FindDialog.h"
118 #include "MemUtils.hh"
119 #include "MsgScrollingList.hh"
120 #include "MsgHndArray.hh"
122 #include "RoamCmds.h"
123 #include "RoamMenuWindow.h"
124 #include "SendMsgDialog.h"
125 #include "Undelete.hh"
127 #if defined(NEED_MMAP_WRAPPER)
130 #include <sys/mman.h>
131 #if defined(NEED_MMAP_WRAPPER)
136 extern XtPointer _XmStringUngenerate (
140 XmTextType output_type);
144 #include <sys/file.h>
147 extern void forceUpdate( Widget );
150 (char *name, char *label, int active, RoamMenuWindow *window)
151 : NoUndoCmd (name, label, active)
153 _menuwindow = window;
157 SearchCmd::SearchCmd(
161 RoamMenuWindow *window
162 ) : InterruptibleCmd (name, label, active)
164 _menuwindow = window;
170 TaskDoneCallback callback,
174 InterruptibleCmd::execute( callback, clientData );
181 _menuwindow->list()->clearMsgs();
182 _menuwindow->busyCursor();
185 _criteria=( char * )realloc(_criteria, strlen( this->name()) + 1);
186 strcpy(_criteria, this->name());
189 InterruptibleCmd::execute();
196 DtMailEnv mail_error;
198 // Initialize the mail_error.
201 MsgScrollingList *list=_menuwindow->list();
204 // load_headers will retrieve all of the message headers and
205 // add the handles to the list.
207 count = list->load_headers(mail_error);
209 _menuwindow->normalCursor();
212 _menuwindow->message(GETMSG(DT_catd, 3, 46, "Empty container"));
217 list->scroll_to_bottom();
224 // Just print a message that allows us to trace the execution
226 DebugPrintf(1, "%s: undoit\n", name());
230 SearchCmd::updateMessage (char *msg)
232 InterruptibleCmd::updateMessage(msg);
234 #endif /* DEAD_WOOD */
236 CheckForNewMailCmd::CheckForNewMailCmd(
240 RoamMenuWindow *window
241 ) : NoUndoCmd ( name, label, active )
243 _menuwindow = window;
247 CheckForNewMailCmd::doit()
250 // Initialize the mail_error.
252 _menuwindow->checkForMail(error);
256 OpenInboxCmd::OpenInboxCmd(
261 ) : Cmd (name, label, active)
271 RoamMenuWindow *rmw = theRoamApp.inboxWindow();
275 MailSession *ses = theRoamApp.session();
276 ses->activateRMW(rmw);
281 DtMailEnv mail_error;
282 char *mail_file = NULL;
283 DtMailObjectSpace space;
284 DtMail::Session *d_session = theRoamApp.session()->session();
287 d_session->queryImpl(mail_error,
288 d_session->getDefaultImpl(mail_error),
289 DtMailCapabilityInboxName,
294 if (mail_file) _menuWindow->view_mail_file(mail_file, DTM_FALSE);
299 OpenInboxCmd::undoit()
304 // OpenContainerCmd methods implementation.
305 // For the most part, we treat container->open() as a benign thing.
306 // The magic, as we see it, deals with converting the container
308 // For OpenContainerCmd, if no conversion is necessary bingo! it opens.
309 // If conversion is necessary, it punts the work to ConvertContainerCmd.
313 OpenContainerCmd::OpenContainerCmd (
317 RoamMenuWindow *window
318 ) : RoamInterruptibleCmd (name, label, active)
320 _menuWindow = window;
321 _open_create_flag = DTM_FALSE;
322 _open_lock_flag = DTM_FALSE;
325 // Parent's execute() ends up calling derived class's doit()
327 OpenContainerCmd::execute()
329 RoamInterruptibleCmd::execute();
333 OpenContainerCmd::execute(
334 RoamTaskDoneCallback rtd_callback,
338 RoamInterruptibleCmd::execute(rtd_callback, clientData);
341 // Tell the RMW to open. The RMW may end up calling its convert()
342 // which depends on ConvertContainerCmd's doit...
343 // By the time RMW->open() returns, the conversion would have
345 // This is the case of a RinterruptibleCmd derived class
346 // getting its work done in its doit() in one call.
350 OpenContainerCmd::doit()
354 assert(_menuWindow != NULL);
356 // Initialize the mail_error.
359 _menuWindow->open(error, _open_create_flag, _open_lock_flag);
361 // Post a dialog indicating error and exit?
362 return; // for now. Should exit instead?
368 OpenContainerCmd::undoit()
370 // Just print a message that allows us to trace the execution
372 DebugPrintf(1, "%s: undoit\n", name());
376 OpenContainerCmd::check_if_done()
378 // Have nothing fancy to do here. Since we do not want a dialog
379 // in any case, set it to true...
387 OpenContainerCmd::post_dialog()
389 // Empty. We don't want a dialog on open...
393 OpenContainerCmd::unpost_dialog()
395 // Empty. We don't post, and we don't unpost.
398 OpenContainerCmd::updateMessage (char *msg)
400 RoamInterruptibleCmd::updateMessage(msg);
404 OpenContainerCmd::set_create_lock_flags(
405 DtMailBoolean create,
409 _open_create_flag = create;
410 _open_lock_flag = lock;
414 // ConvertContainerCmd
417 ConvertContainerCmd::ConvertContainerCmd(
421 RoamMenuWindow *window
422 ) : RoamInterruptibleCmd (name, label, active)
424 _menuWindow = window;
426 _num_to_be_converted = 0;
435 ConvertContainerCmd::execute()
438 _dialog = new DtMailWDM("Convert");
441 RoamInterruptibleCmd::execute();
445 ConvertContainerCmd::execute ( RoamTaskDoneCallback rtd_callback,
449 _dialog = new DtMailWDM("Convert");
452 RoamInterruptibleCmd::execute(rtd_callback, clientData);
455 // Here be bigger dragons!
456 // The doit() calls the session->convert().
457 // And returns right away!
458 // the ses->convert() however ends up calling the conv_cb for every
459 // message that it has converted.
460 // So, we now have two loops working in parallel:
461 // 1) the parent()'s execute() class which called this doit() and is now
462 // calling check_if_done() periodically via its workProc;
463 // 2) the session->convert() which is calling the _conv_cb() for every
464 // message that it converts. In the _conv_cb(), we do the following:
465 // a) force update the dialog and see if it was interrupted;
466 // b) if not interrupted, set_convert_data() where we set _done if
467 // we are really done.
471 ConvertContainerCmd::doit()
473 assert(_menuWindow != NULL);
475 MailSession *ses = theRoamApp.session();
476 DtMailEnv mail_error;
478 // Initialize the mail_error.
481 // ses->convert(mail_error, _src, _dest, _conv_cb, _menuWindow);
483 if (mail_error.isSet()) {
484 _menuWindow->postErrorDialog(mail_error);
489 ConvertContainerCmd::set_convert_data(
494 _num_converted = converted;
495 _num_to_be_converted = to_be_converted;
497 if ((_num_converted == _num_to_be_converted) && !_interrupted) {
503 ConvertContainerCmd::get_num_converted()
505 return(_num_converted);
510 ConvertContainerCmd::check_if_done()
515 else if (_num_converted == _num_to_be_converted) {
521 ConvertContainerCmd::updateDialog(
525 forceUpdate(_dialog->baseWidget());
526 _dialog->updateDialog( msg );
530 ConvertContainerCmd::updateAnimation()
532 forceUpdate(_dialog->baseWidget());
533 _dialog->updateAnimation();
537 ConvertContainerCmd::post_dialog()
539 Dimension x, y, wid, ht;
541 char * buf = new char[25];
543 sprintf(buf, "Converted: %3d%%", 0);
545 _dialog->post ("Mailer",
547 _menuWindow->baseWidget(),
550 &RoamInterruptibleCmd::interruptCallback );
552 XtVaGetValues(_dialog->baseWidget(),
562 ConvertContainerCmd::unpost_dialog()
568 ConvertContainerCmd::undoit()
570 // Just print a message that allows us to trace the execution
572 DebugPrintf(1, "%s: undoit\n", name());
576 ConvertContainerCmd::set_data(
579 ConversionStatusCB cb
588 ConvertContainerCmd::get_destination_name()
600 RoamMenuWindow *window
601 ) : RoamCmd ( name, label, active, window )
609 _menuwindow->get_find_dialog();
611 // SearchCmd::doit();
616 ChooseCmd::ChooseCmd(
620 RoamMenuWindow *window
621 ) : NoUndoCmd( name, label, active )
623 _menuwindow = window;
633 SelectAllCmd::SelectAllCmd(
637 RoamMenuWindow *window
638 ) : Cmd ( name, label, active )
640 _menuwindow = window;
646 DtMailEnv mail_error;
648 _menuwindow->list()->select_all_and_display_last(mail_error);
652 SelectAllCmd::undoit()
657 DeleteCmd::DeleteCmd(
661 RoamMenuWindow *window
662 ) : Cmd ( name, label, active )
664 _menuwindow = window;
671 _menuwindow->list()->deleteSelected(FALSE);
681 DestroyCmd::DestroyCmd(
685 RoamMenuWindow *window
686 ) : Cmd(name, label, active)
688 _menuwindow = window;
694 // Call Expunge only if there are deleted messages.
696 if (_menuwindow->list()->get_num_deleted_messages()) {
697 _menuwindow->expunge();
706 // Unified Select File Cmd stuff
707 int UnifiedSelectFileCmd::_is_initialized = 0;
708 char *UnifiedSelectFileCmd::_unified_directory = NULL;
709 char *UnifiedSelectFileCmd::_unified_file = NULL;
710 int UnifiedSelectFileCmd::_unified_hidden = 0;
711 int UnifiedSelectFileCmd::_unify_selection = 1;
713 UnifiedSelectFileCmd::UnifiedSelectFileCmd (
723 :SelectFileCmd (name,
728 unifiedFileSelectedCB,
730 unifiedFileCanceledCB,
734 if (! _is_initialized)
736 FORCE_SEGV_DECL(DtMail::Session, m_session);
738 const char *dirname = NULL;
739 const char *expanded_dirname = NULL;
740 const char *value = NULL;
741 char *full_dirname = NULL;
743 _unified_directory = NULL;
744 _unified_file = NULL;
746 _unify_selection = 1;
749 m_session = theRoamApp.session()->session();
752 m_session->mailRc(error)->getValue(error, "filefolder", &dirname);
754 dirname = strdup("~");
757 expanded_dirname = m_session->expandPath(error, dirname);
758 _unified_directory = XtNewString(expanded_dirname);
761 m_session->mailRc(error)->getValue(
763 "dontunifyfileselection",
766 _unify_selection = 0;
768 free((void*) dirname);
769 free((void*) expanded_dirname);
773 _select_file_callback = select_callback;
774 _select_file_client_data = client_data;
775 _genDialog = new DtMailGenDialog("Dialog", parent);
778 UnifiedSelectFileCmd::~UnifiedSelectFileCmd()
780 if (_genDialog) delete _genDialog;
784 UnifiedSelectFileCmd::doit()
786 if (NULL == _fileBrowser)
788 SelectFileCmd::doit();
789 if (NULL != _unified_directory)
790 setDirectory(_unified_directory);
791 if (NULL != _unified_file)
792 setSelected(_unified_file);
793 setHidden(_unified_hidden);
797 if (_unify_selection)
799 if (NULL != _unified_directory)
800 setDirectory(_unified_directory);
801 if (NULL != _unified_file)
802 setSelected(_unified_file);
803 setHidden(_unified_hidden);
805 SelectFileCmd::doit();
810 UnifiedSelectFileCmd::unifiedFileSelectedCB(void *client_data, char *selection)
812 UnifiedSelectFileCmd *self = (UnifiedSelectFileCmd *) client_data;
816 self->updateUnifiedData();
817 self->unifiedFileSelected(selection);
822 UnifiedSelectFileCmd::unifiedFileSelected(char *selection)
826 SafePathIsAccessible(error, selection);
829 const char *errmsg = NULL;
833 errmsg = (const char*) error;
834 err = strdup(errmsg);
836 _genDialog->setToErrorDialog(GETMSG(DT_catd, 3, 48, "Mailer"), err);
837 answer = _genDialog->post_and_return(DTMAILHELPERROR);
838 if (1 == answer) doit();
843 if (_select_file_callback)
844 _select_file_callback(_select_file_client_data, selection);
848 UnifiedSelectFileCmd::unifiedFileCanceledCB(void *client_data, char *)
850 UnifiedSelectFileCmd *self = (UnifiedSelectFileCmd *) client_data;
853 self->updateUnifiedData();
857 UnifiedSelectFileCmd::updateUnifiedData()
859 if (! _unify_selection)
862 if (NULL != _unified_file)
863 XtFree(_unified_file);
864 _unified_file = getSelected();
867 if (NULL != _unified_directory)
868 XtFree(_unified_directory);
869 _unified_directory = getDirectory();
871 _unified_hidden = getHidden();
874 // Unified Select Mailbox Cmd stuff
875 int UnifiedSelectMailboxCmd::_is_initialized = 0;
876 char *UnifiedSelectMailboxCmd::_unified_directory = NULL;
877 char *UnifiedSelectMailboxCmd::_unified_file = NULL;
878 int UnifiedSelectMailboxCmd::_unified_hidden = 0;
879 int UnifiedSelectMailboxCmd::_unify_selection = 1;
881 UnifiedSelectMailboxCmd::UnifiedSelectMailboxCmd (
891 DtMailBoolean only_show_mailboxes)
892 :SelectFileCmd (name,
897 unifiedMailboxSelectedCB,
899 unifiedMailboxCanceledCB,
903 _only_show_mailboxes = DTM_FALSE;
905 if (! _is_initialized)
907 FORCE_SEGV_DECL(DtMail::Session, m_session);
909 const char *dirname = NULL;
910 const char *expanded_dirname = NULL;
911 const char *value = NULL;
912 char *full_dirname = NULL;
914 _unified_directory = NULL;
915 _unified_file = NULL;
917 _unify_selection = 1;
919 _only_show_mailboxes = only_show_mailboxes;
921 m_session = theRoamApp.session()->session();
924 m_session->mailRc(error)->getValue(error, "folder", &dirname);
926 dirname = strdup("~");
929 expanded_dirname = m_session->expandPath(error, dirname);
930 _unified_directory = XtNewString(expanded_dirname);
933 m_session->mailRc(error)->getValue(
935 "dontunifyfileselection",
938 _unify_selection = 0;
940 free((void*) dirname);
941 free((void*) expanded_dirname);
945 _select_file_callback = select_callback;
946 _select_file_client_data = client_data;
947 _genDialog = new DtMailGenDialog("Dialog", parent);
950 UnifiedSelectMailboxCmd::~UnifiedSelectMailboxCmd()
952 if (_genDialog) delete _genDialog;
956 UnifiedSelectMailboxCmd::doit()
958 if (NULL == _fileBrowser)
960 SelectFileCmd::doit();
961 if (NULL != _unified_directory)
962 setDirectory(_unified_directory);
963 if (NULL != _unified_file)
964 setSelected(_unified_file);
965 setHidden(_unified_hidden);
971 UnifiedSelectMailboxCmd::unifiedMailboxSearchProc,
976 if (_unify_selection)
978 if (NULL != _unified_directory)
979 setDirectory(_unified_directory);
980 if (NULL != _unified_file)
981 setSelected(_unified_file);
982 setHidden(_unified_hidden);
984 SelectFileCmd::doit();
989 extern void _XmOSBuildFileList(
992 #if NeedWidePrototypes
993 unsigned int typeMask,
995 unsigned char typeMask,
996 #endif /* NeedWidePrototypes */
998 unsigned int *pNumEntries,
999 unsigned int *pNumAlloc);
1001 extern int _XmOSFileCompare(const void *sp1, const void *sp2);
1002 extern char *_XmStringGetTextConcat(XmString string);
1006 UnifiedSelectMailboxCmd::unifiedMailboxSearchProc(
1010 XmFileSelectionBoxWidget fs =
1011 (XmFileSelectionBoxWidget) w;
1012 XmFileSelectionBoxCallbackStruct * searchData =
1013 (XmFileSelectionBoxCallbackStruct *) sd;
1019 unsigned int numFiles;
1020 unsigned int numItems = 0;
1021 unsigned int numAlloc;
1022 XmString * XmStringFileList;
1024 XtEnum fileFilterStyle, pathMode;
1025 unsigned char fileTypeMask;
1027 if (!(dir = _XmStringGetTextConcat(searchData->dir)))
1030 if (!(pattern = _XmStringGetTextConcat(searchData->pattern)))
1039 XmNfileTypeMask, &fileTypeMask,
1040 XmNfileFilterStyle, &fileFilterStyle,
1041 XmNpathMode, &pathMode,
1045 dir, pattern, fileTypeMask,
1046 &fileList, &numFiles, &numAlloc);
1048 if (fileList && numFiles)
1050 Boolean showDotFiles = (fileFilterStyle == XmFILTER_NONE);
1053 qsort((void*) fileList, numFiles, sizeof(char*), _XmOSFileCompare);
1055 XmStringFileList = (XmString*) XtMalloc(numFiles*sizeof(XmString));
1058 dirLen = strlen(dir);
1060 while (Index < numFiles)
1062 Boolean isMailBox = 0;
1063 char *dataType = NULL;
1065 dataType = DtDtsFileToDataType(fileList[Index]);
1067 isMailBox = (0 == strcmp(dataType, "DTMAIL_FILE"));
1068 DtDtsFreeDataType(dataType);
1071 (showDotFiles || ((fileList[Index])[dirLen] != '.')) )
1073 if (pathMode == XmPATH_MODE_FULL)
1074 XmStringFileList[numItems++] =
1075 XmStringGenerate(fileList[Index],
1076 XmFONTLIST_DEFAULT_TAG,
1077 XmCHARSET_TEXT, NULL);
1079 XmStringFileList[numItems++] =
1080 XmStringGenerate(&(fileList[Index])[dirLen],
1081 XmFONTLIST_DEFAULT_TAG,
1082 XmCHARSET_TEXT, NULL) ;
1092 XmNfileListItemCount, numItems,
1093 XmNfileListItems, XmStringFileList,
1094 XmNlistUpdated, TRUE,
1099 XtFree( fileList[Index]);
1102 XmStringFree(XmStringFileList[numItems]);
1104 XtFree((char*) XmStringFileList);
1110 XmNfileListItemCount, 0,
1111 XmNfileListItems, NULL,
1112 XmNlistUpdated, TRUE,
1116 XtFree((char *) fileList);
1123 UnifiedSelectMailboxCmd::unifiedMailboxSelectedCB(
1127 UnifiedSelectMailboxCmd *self = (UnifiedSelectMailboxCmd *) client_data;
1131 self->updateUnifiedData();
1132 self->unifiedMailboxSelected(
1133 self->_select_file_callback,
1134 self->_select_file_client_data,
1140 UnifiedSelectMailboxCmd::unifiedMailboxSelected(
1147 SafePathIsAccessible(error, selection);
1150 const char *errmsg = NULL;
1154 errmsg = (const char*) error;
1155 err = strdup(errmsg);
1157 _genDialog->setToErrorDialog(GETMSG(DT_catd, 3, 48, "Mailer"), err);
1158 answer = _genDialog->post_and_return(DTMAILHELPERROR);
1159 if (1 == answer) doit();
1164 updateUnifiedData();
1165 if (cb) cb(client_data, selection);
1169 UnifiedSelectMailboxCmd::unifiedMailboxCanceledCB(void *client_data, char *)
1171 UnifiedSelectMailboxCmd *self = (UnifiedSelectMailboxCmd *) client_data;
1174 self->updateUnifiedData();
1178 UnifiedSelectMailboxCmd::updateUnifiedData()
1180 if (! _unify_selection)
1183 if (NULL != _unified_file)
1184 XtFree(_unified_file);
1185 _unified_file = getSelected();
1188 if (NULL != _unified_directory)
1189 XtFree(_unified_directory);
1190 _unified_directory = getDirectory();
1192 _unified_hidden = getHidden();
1195 ContainerMenuCmd::ContainerMenuCmd(
1199 RoamMenuWindow *window,
1201 ) : RoamCmd ( name, label, active, window )
1203 _menuwindow = window;
1204 _container_name = name;
1209 ContainerMenuCmd::doit()
1211 DtMailEnv mail_error;
1213 // Initialize mail_error.
1216 theRoamApp.busyAllWindows(GETMSG(DT_catd, 3, 15, "Saving..."));
1217 _menuwindow->mailbox()->save();
1218 theRoamApp.unbusyAllWindows();
1225 _menuwindow->view_mail_file(_container_name, DTM_FALSE);
1228 _menuwindow->list()->copySelected(
1232 if (mail_error.isSet())
1234 // We had an error in copying the message to a container!
1238 _menuwindow->list()->copySelected(
1242 if (mail_error.isSet())
1244 // We had an error in moving the message to a container!
1250 ContainerMenuCmd::~ContainerMenuCmd()
1255 // Move the messages that are selected in the RoamMenuWindow to the Inbox.
1256 MoveToInboxCmd::MoveToInboxCmd(
1260 RoamMenuWindow *window
1261 ) : RoamCmd (name, label, active, window)
1263 _menuwindow = window;
1267 MoveToInboxCmd::doit()
1269 DtMailEnv mail_error;
1271 // Initialize mail_error.
1274 // Get a handle to the Inbox.
1275 char * mail_file = NULL;
1276 DtMailObjectSpace space;
1277 DtMail::Session * d_session = theRoamApp.session()->session();
1279 d_session->queryImpl(mail_error,
1280 d_session->getDefaultImpl(mail_error),
1281 DtMailCapabilityInboxName,
1284 _menuwindow->list()->copySelected(mail_error, mail_file, TRUE, FALSE);
1285 if (mail_error.isSet()) {
1286 // We had an error in moving the messages to the Inbox!
1290 MoveToInboxCmd::~MoveToInboxCmd()
1294 // Copy the selected messages to the Inbox.
1295 CopyToInboxCmd::CopyToInboxCmd(
1299 RoamMenuWindow *window
1300 ) : RoamCmd (name, label, active, window)
1302 _menuwindow = window;
1306 CopyToInboxCmd::doit()
1308 DtMailEnv mail_error;
1310 // Initialize mail_error.
1313 // Get a handle to the Inbox.
1314 char * mail_file = NULL;
1315 DtMailObjectSpace space;
1316 DtMail::Session * d_session = theRoamApp.session()->session();
1318 d_session->queryImpl(mail_error,
1319 d_session->getDefaultImpl(mail_error),
1320 DtMailCapabilityInboxName,
1323 _menuwindow->list()->copySelected(mail_error, mail_file, FALSE, FALSE);
1324 if (mail_error.isSet()) {
1325 // We ad an error in copying the messages to the Inbox!
1329 CopyToInboxCmd::~CopyToInboxCmd()
1334 // This is hooked up the Undelete button in the Deleted
1335 // Messages List dialog box.
1337 DoUndeleteCmd::DoUndeleteCmd(
1341 UndelFromListDialog *undelDialog
1342 ) : Cmd ( name, label, active )
1344 _undelDialog = undelDialog;
1348 DoUndeleteCmd::doit()
1350 // Undelete the selected messages.
1351 _undelDialog->undelSelected();
1355 DoUndeleteCmd::undoit()
1360 DoUndeleteCmd::~DoUndeleteCmd()
1364 // This is hooked up to the Close button in the Deleted Messages
1367 CloseUndelCmd::CloseUndelCmd(
1371 UndelFromListDialog *undelDialog
1372 ) : Cmd ( name, label, active )
1374 _undelDialog = undelDialog;
1378 CloseUndelCmd::doit()
1380 // Close the dialog.
1381 _undelDialog->popped_down();
1385 CloseUndelCmd::undoit()
1391 CloseUndelCmd::~CloseUndelCmd()
1395 UndeleteCmd::UndeleteCmd (
1399 RoamMenuWindow *window,
1400 Boolean viaDeleteList
1401 ) : ChooseCmd ( name, label, active, window )
1403 _menuwindow = window;
1404 _undelFromList = NULL;
1405 _fromList = viaDeleteList;
1410 UndeleteCmd::~UndeleteCmd()
1417 FORCE_SEGV_DECL(MsgStruct, tmpMS);
1418 MsgScrollingList *list = _menuwindow->list();
1419 MsgHndArray *deleted_messages;
1420 DtMailEnv mail_error;
1422 // Initialize the mail_error.
1427 // Create the Deleted Messages Dialog
1429 if (_undelFromList) {
1430 // Hack for user testing. If the dialog is up, we destroy it.
1431 XtDestroyWidget(_undelFromList->baseWidget());
1433 // if (!_undelFromList) {
1434 _undelFromList = new UndelFromListDialog(
1435 GETMSG(DT_catd, 1, 227, "Mailer - Deleted Messages"),
1437 _undelFromList->initialize();
1439 // Check for existing list of deleted messages
1440 _num_deleted = list->get_num_deleted_messages();
1442 // If there are deleted messages, put them in the Deleted
1445 if (_num_deleted > 0) {
1446 deleted_messages = list->get_deleted_messages();
1447 _undelFromList->loadMsgs(
1451 if (mail_error.isSet()) {
1452 // Post an exception here!
1453 _menuwindow->postErrorDialog(mail_error);
1457 // Display the dialog
1459 _undelFromList->popped_up();
1461 // Although we don't display the Deleted Message Dialog here, we
1462 // need to make sure that it gets updated for the next time
1464 list->undelete_last_deleted();
1470 SaveCmd::SaveCmd ( char *name,
1473 RoamMenuWindow *window
1474 ) : RoamCmd ( name, label, active, window )
1483 assert(_menuwindow->mailbox() != NULL);
1485 #endif /* DEAD_WOOD */
1489 MoveCopyCmd::MoveCopyCmd( char *name,
1492 FileCallback move_callback,
1493 FileCallback copy_callback,
1494 RoamMenuWindow * menu_window,
1496 DtMailBoolean only_show_mailboxes)
1497 : UnifiedSelectMailboxCmd(name,
1499 GETMSG(DT_catd, 1, 89, "Mailer - Other Mailboxes"),
1505 only_show_mailboxes)
1507 _copy_callback = copy_callback;
1508 _menuwindow = menu_window;
1509 _copy_button = NULL;
1510 _move_button = NULL;
1513 _default_button = NULL;
1516 MoveCopyCmd::~MoveCopyCmd()
1521 MoveCopyCmd::setDefault(Widget button)
1525 _default_button = button;
1526 XtSetArg( args[0], XmNdefaultButton, _default_button );
1527 XtSetValues( _fileBrowser, args, 1 );
1534 Widget filter_button;
1535 Widget unused_button;
1539 if (!_fileBrowser) {
1540 UnifiedSelectMailboxCmd::doit();
1541 // Customize buttons for MoveCopy dialog
1542 move = XmStringCreateLocalized(GETMSG(DT_catd, 1, 90, "Move"));
1544 filter_button = XtNameToWidget(_fileBrowser, "*Apply");
1545 _move_button = XtNameToWidget(_fileBrowser, "*OK");
1546 action_area = XtParent(_move_button);
1547 unused_button = XtVaCreateWidget(
1549 xmPushButtonWidgetClass, _fileBrowser,
1551 _copy_button = XtVaCreateManagedWidget(
1552 GETMSG(DT_catd, 1, 237, "Copy"),
1553 /*xmPushButtonWidgetClass, _fileBrowser,*/
1554 xmPushButtonGadgetClass, _fileBrowser,
1556 XmStringCreateLocalized(GETMSG(DT_catd, 1, 43, "Copy")),
1558 printHelpId("Copy", _copy_button);
1560 // add help callback
1561 // XtAddCallback(_copy_button, XmNhelpCallback, HelpCB, helpId);
1567 (void *)"dtmailViewmainWindowWork-AreapanedWform2RowColumnMoveCopy");
1570 XmNactivateCallback,
1571 &MoveCopyCmd::fileSelectedCallback2,
1574 if (_menuwindow->mailbox()->mailBoxWritable(error) == DTM_FALSE)
1575 XtUnmanageChild(_move_button);
1577 XtManageChild(_move_button);
1579 // XtVaSetValues(_move_button, XmNsensitive, FALSE);
1581 _file_list = XtNameToWidget(_fileBrowser, "*ItemsList");
1584 XmNbrowseSelectionCallback, &MoveCopyCmd::setDefaultButtonCB,
1588 XmNextendedSelectionCallback, &MoveCopyCmd::setDefaultButtonCB,
1592 XmNmultipleSelectionCallback, &MoveCopyCmd::setDefaultButtonCB,
1596 XmNsingleSelectionCallback, &MoveCopyCmd::setDefaultButtonCB,
1599 _file_text = XtNameToWidget(_fileBrowser, "*Text");
1600 if (NULL != _file_text)
1603 XmNfocusCallback, &MoveCopyCmd::setDefaultButtonCB,
1609 UnifiedSelectMailboxCmd::doit();
1615 MoveCopyCmd::fileSelectedCallback2 (
1617 XtPointer clientData,
1621 MoveCopyCmd *obj = (MoveCopyCmd *) clientData;
1622 XmFileSelectionBoxCallbackStruct *cb =
1623 (XmFileSelectionBoxCallbackStruct *) callData;
1625 char *dir_str = NULL;
1631 static char selected[MAXPATHLEN+1];
1633 // Bring the file selection dialog down.
1634 XtUnmanageChild ( obj->_fileBrowser );
1637 // Get the file name
1639 XtVaGetValues(obj->_fileBrowser, XmNdirectory, &xmstr, NULL);
1641 dname = (char*) _XmStringUngenerate(
1643 XmMULTIBYTE_TEXT, XmMULTIBYTE_TEXT);
1646 // Get the file name
1648 XtVaGetValues(obj->_fileBrowser, XmNdirSpec, &xmstr, NULL);
1651 // Extract the first character string matching the default
1652 // character set from the compound string
1653 fname = (char *) _XmStringUngenerate(
1655 XmMULTIBYTE_TEXT, XmMULTIBYTE_TEXT);
1657 if (NULL == fname || strlen(fname) == 0)
1660 // If a string was successfully extracted, call
1661 // unifiedMailboxSelected to handle the file.
1663 if (NULL != dname) snprintf(selected, sizeof(selected), "%s", dname);
1664 strcat(selected, fname);
1665 obj->updateUnifiedData();
1666 obj->unifiedMailboxSelected(
1667 obj->_copy_callback,
1674 MoveCopyCmd::setDefaultButtonCB(
1676 XtPointer clientData,
1679 MoveCopyCmd *thisCmd = (MoveCopyCmd *) clientData;
1680 thisCmd->setDefault(thisCmd->_default_button);
1684 CopyCmd::CopyCmd( char *name,
1687 RoamMenuWindow *window,
1688 MoveCopyCmd *move_copy_cmd
1689 ) : RoamCmd ( name, label, active, window )
1691 _move_copy_cmd = move_copy_cmd;
1701 _move_copy_cmd->doit();
1702 _move_copy_cmd->setDefault(_move_copy_cmd->getCopyButton());
1706 MoveCmd::MoveCmd( char *name,
1709 RoamMenuWindow *window,
1710 MoveCopyCmd *move_copy_cmd
1711 ) : RoamCmd ( name, label, active, window )
1713 _move_copy_cmd = move_copy_cmd;
1723 _move_copy_cmd->doit();
1724 _move_copy_cmd->setDefault(_move_copy_cmd->getMoveButton());
1732 RoamMenuWindow *window
1733 ) : RoamCmd ( name, label, active, window )
1740 _menuwindow->list()->select_next_item();
1748 RoamMenuWindow *window
1749 ) : RoamCmd ( name, label, active, window )
1756 _menuwindow->list()->select_prev_item();
1760 MessagesCmd::MessagesCmd(
1764 RoamMenuWindow *window
1765 ) : RoamCmd ( name, label, active, window )
1773 Boolean old=_menuwindow->fullHeader();
1774 MsgScrollingList *list=_menuwindow->list();
1776 ( !strcmp( this->name(), "Full Header" ) ? _menuwindow->fullHeader( True ) : _menuwindow->fullHeader( False ) );
1778 if ( old!=_menuwindow->fullHeader() && _menuwindow->msgView() ) {
1779 // list->chooseCurrent();
1783 #endif /* DEAD_WOOD */
1785 PrintCmd::PrintCmd (
1790 RoamMenuWindow *window
1791 ) : ChooseCmd ( name, label, active, window ), _tmp_files(5)
1800 // The entire implementation of print was broken. It has
1801 // be removed until a proper implementation can be provided.
1810 DtActionInvocationID id,
1811 XtPointer clientData,
1820 case DtACTION_INVOKED:
1823 data = (PrintCmd *)clientData;
1824 data->_parent->message("");
1825 data->_unregister_tmp_file(id);
1833 PrintCmd::printjobcb( Widget w, XtPointer client_data, XtPointer )
1835 char *filename = (char *) client_data;
1837 XtRemoveCallback(w, XtNdestroyCallback, &PrintCmd::printjobcb, filename);
1844 PrintCmd::printit( int silent )
1847 char *silent_str = "DTPRINTSILENT";
1848 char *tmpdir = new char[MAXPATHLEN+1];
1849 DtMailEnv mail_error;
1850 MsgScrollingList *list;
1852 DebugPrintf(1, "%s: printit\n", name());
1855 snprintf(tmpdir, MAXPATHLEN+1, "%s/%s", getenv("HOME"), DtPERSONAL_TMP_DIRECTORY);
1856 if ((p = tempnam(tmpdir, "dtmail")) == NULL) {
1863 list = _parent->list();
1865 // Copy selected messages to a temp file
1866 int status = list->copySelected(mail_error, p, FALSE, TRUE);
1867 if (mail_error.isSet())
1869 _parent->postErrorDialog(mail_error);
1873 if (0 != status) return;
1876 DmxPrintJob *pjob = new DmxPrintJob(p,
1877 (silent ? DTM_TRUE : DTM_FALSE),
1880 XtAddCallback(pjob->baseWidget(),
1882 &PrintCmd::printjobcb,
1883 (XtPointer) strdup(p));
1891 PrintCmd::_register_tmp_file(
1893 DtActionInvocationID id
1898 // Allocate struct to hold id and temp file
1899 if ((f = (struct tmp_file *)malloc(sizeof(struct tmp_file))) == NULL) {
1903 // Save file name and action id
1904 f->file = strdup(name);
1907 // Add to list of temp files
1908 _tmp_files.append(f);
1914 PrintCmd::_unregister_tmp_file(
1915 DtActionInvocationID id
1921 // Find the temp file that was used by the Action specified by id
1922 for (n = _tmp_files.length() - 1; n >= 0; n--) {
1925 // Found the file. Unlink and free data structs
1929 // Remove entry from list
1930 _tmp_files.remove(n);
1939 PopupCmd::PopupCmd (
1943 PopupWindow * (RoamMenuWindow::* member) (void),
1944 RoamMenuWindow *myparent
1945 ) : NoUndoCmd ( name, label, active )
1954 PopupWindow *popup=(parent->*pmpopup)();
1957 #endif /* DEAD_WOOD */
1959 // OnItemCmd brings up the Help On Item help.
1960 OnItemCmd::OnItemCmd ( char * name,
1963 UIComponent *window )
1964 : NoUndoCmd (name, label, active)
1972 int status = DtHELP_SELECT_ERROR;
1973 Widget widget = _parent->baseWidget();
1974 Widget selWidget = NULL;
1976 // Display the appropriate help information for the selected item.
1978 status = DtHelpReturnSelectedWidgetId(widget, 0, &selWidget);
1980 switch ((int) status) {
1981 case DtHELP_SELECT_ERROR:
1982 printf("Selection Error, cannot continue\n");
1984 case DtHELP_SELECT_VALID:
1985 while (selWidget != NULL) {
1986 if ((XtHasCallbacks(selWidget, XmNhelpCallback)
1987 == XtCallbackHasSome)) {
1988 XtCallCallbacks((Widget) selWidget, XmNhelpCallback, NULL);
1991 selWidget = XtParent(selWidget);
1995 case DtHELP_SELECT_ABORT:
1996 printf("Selection Aborted by user.\n");
1998 case DtHELP_SELECT_INVALID:
1999 printf("You must select a component within your app.\n");
2008 OnAppCmd::OnAppCmd ( char * name,
2011 UIComponent *window )
2012 : NoUndoCmd (name, label, active)
2020 DisplayMain (_parent->baseWidget(), "Mailer", DTMAILWINDOWID);
2023 TasksCmd::TasksCmd ( char * name,
2026 UIComponent *window )
2027 : NoUndoCmd (name, label, active)
2035 DisplayMain (_parent->baseWidget(), "Mailer", HELP_MAILER_TASKS);
2038 ReferenceCmd::ReferenceCmd ( char * name,
2041 UIComponent *window )
2042 : NoUndoCmd (name, label, active)
2048 ReferenceCmd::doit()
2050 DisplayMain (_parent->baseWidget(), "Mailer", HELP_MAILER_REFERENCE);
2053 UsingHelpCmd::UsingHelpCmd ( char * name,
2056 UIComponent *window )
2057 : NoUndoCmd (name, label, active)
2063 UsingHelpCmd::doit()
2065 DisplayMain (_parent->baseWidget(), "Help4Help", "_HOMETOPIC");
2068 RelNoteCmd::RelNoteCmd ( char * name,
2072 ) : NoUndoCmd (name, label, active )
2084 // _genDialog = new DtMailGenDialog("AboutBox", _parent->baseWidget());
2086 // _genDialog->setToAboutDialog();
2087 // answer = _genDialog->post_and_return(GETMSG(DT_catd, 1, 92, "OK"), NULL);
2089 DisplayMain(_parent->baseWidget(), "Mailer", "_copyright");
2092 RelNoteCmd::~RelNoteCmd()
2098 ClearCmd::ClearCmd (
2102 RoamMenuWindow *window
2103 ) : NoUndoCmd (name, label, active )
2111 // ((FindPopup *) parent->find_popup())->clear_text_values();
2114 StartCmd::StartCmd( char *name,
2116 int active ) : Cmd ( name, label, active )
2123 char *forward= ".forward";
2126 GetPasswordEntry(pwd);
2128 char *forward_filename=new char[strlen(pwd.pw_dir)+1+strlen(forward)+1];
2129 sprintf( forward_filename, "%s/%s", pwd.pw_dir, forward );
2139 ChangeCmd::ChangeCmd(
2143 ) : Cmd (name, label, active )
2151 GetPasswordEntry(pwd);
2153 char *user_name=new char[strlen(pwd.pw_name)+1];
2154 strcpy(user_name,pwd.pw_name);
2169 RoamMenuWindow *window
2170 ) : Cmd (name, label, active )
2178 unlink( parent->forwardFilename() );
2179 parent->title( NULL );
2188 #endif /* DEAD_WOOD */
2196 SendMsgDialog *parent,
2198 : NoUndoCmd( name, label, active )
2201 _default_trans = trans_type;
2207 if (!_parent->isMsgValid())
2210 _parent->send_message( this->name(), _default_trans );
2213 // JT - Added methods below
2215 OpenMsgCmd::OpenMsgCmd(
2219 RoamMenuWindow *window)
2220 : RoamCmd (name, label, active, window)
2227 DtMailEnv mail_error;
2229 // Initialize the mail_error.
2232 _menuwindow->list()->viewInSeparateWindow(mail_error);
2233 if (mail_error.isSet()) {
2234 _menuwindow->postErrorDialog(mail_error);
2239 // Attachment Cmds stuff
2241 SaveAttachCmd::SaveAttachCmd ( char *name,
2245 FileCallback save_callback,
2246 RoamMenuWindow *clientData,
2248 :UnifiedSelectFileCmd (name,
2251 GETMSG(DT_catd, 1, 93, "Save"),
2257 _parent = clientData;
2261 SaveAttachCmd::SaveAttachCmd (
2266 FileCallback save_callback,
2267 ViewMsgDialog *clientData,
2270 :UnifiedSelectFileCmd (name,
2273 GETMSG(DT_catd, 1, 93, "Save"),
2279 _parent = clientData;
2283 SaveAttachCmd::SaveAttachCmd (
2288 FileCallback save_callback,
2289 SendMsgDialog *clientData,
2292 :UnifiedSelectFileCmd (name,
2295 GETMSG(DT_catd, 1, 93, "Save"),
2301 _parent = clientData;
2306 SaveAttachCmd::doit()
2308 UnifiedSelectFileCmd::doit();
2310 DtMailEditor *editor = _parent->get_editor();
2311 AttachArea *aa = editor->attachArea();
2312 XmString attachmentName = aa->getSelectedAttachName();
2313 XtVaSetValues(_fileBrowser, XmNtextString, attachmentName, NULL);
2314 XtAddCallback ( _fileBrowser, XmNapplyCallback,
2315 &SaveAttachCmd::updateCallback,
2318 _name = XmStringCopy(attachmentName);
2319 XmStringFree(attachmentName);
2322 // Attachment Cmds stuff
2325 void SaveAttachCmd::updateCallback(Widget, XtPointer clientData, XtPointer )
2327 SaveAttachCmd *obj = (SaveAttachCmd *)clientData;
2329 XtVaSetValues(obj->_fileBrowser, XmNtextString, obj->_name, NULL);
2332 SaveAsTextCmd::SaveAsTextCmd (
2338 RoamMenuWindow *parent_roam_menu_window,
2341 :UnifiedSelectFileCmd (name,
2344 GETMSG(DT_catd, 1, 95, "Save"),
2350 _text_editor = editor;
2351 _roam_menu_window = parent_roam_menu_window;
2354 SaveAsTextCmd::SaveAsTextCmd (
2363 :UnifiedSelectFileCmd (name,
2366 GETMSG(DT_catd, 1, 95, "Save"),
2372 _text_editor = editor;
2373 _roam_menu_window = NULL;
2377 SaveAsTextCmd::fileCB(void * client_data, char * selection)
2379 SaveAsTextCmd * self = (SaveAsTextCmd *)client_data;
2380 self->saveText(selection);
2384 SaveAsTextCmd::saveText(const char * filename)
2387 char *buf = new char[2048];
2390 // Is it already there?
2391 status = SafeAccess(filename, F_OK);
2395 GETMSG(DT_catd, 3, 47, "%s already exists.\nOverwrite?"),
2398 _genDialog->setToQuestionDialog(GETMSG(DT_catd, 3, 48, "Mailer"), buf);
2399 helpId = DTMAILHELPERROR;
2400 answer = _genDialog->post_and_return(helpId);
2406 if (unlink(filename) < 0)
2409 GETMSG(DT_catd, 3, 49, "Unable to overwrite %s.\n\
2410 Check file permissions and retry."),
2412 _genDialog->setToErrorDialog(GETMSG(DT_catd, 3, 50, "Mailer"), buf);
2413 helpId = DTMAILHELPNOOVERWRITE;
2414 _genDialog->post_and_return(helpId);
2420 // Create or truncate, and then write the bits.
2421 int fd = SafeOpen(filename, O_RDWR | O_CREAT | O_TRUNC, 0600);
2424 sprintf(buf, GETMSG(DT_catd, 3, 51, "Unable to create %s."), filename);
2425 _genDialog->setToErrorDialog(GETMSG(DT_catd, 3, 52, "Mailer"), buf);
2426 helpId = DTMAILHELPNOCREATE;
2427 _genDialog->post_and_return(helpId);
2432 if (SafeWrite(fd, "\n", 1) < 1)
2435 GETMSG(DT_catd, 3, 53, "Unable to write to %s."),
2437 _genDialog->setToErrorDialog(GETMSG(DT_catd, 3, 54, "Mailer"), buf);
2438 helpId = DTMAILHELPNOWRITE;
2439 _genDialog->post_and_return(helpId);
2446 if (NULL == _roam_menu_window)
2448 char *text_buf = _text_editor->get_contents();
2449 writeText((XtPointer) (intptr_t) fd, text_buf);
2450 XtFree((char*) text_buf);
2453 writeTextFromScrolledList(fd);
2460 SaveAsTextCmd::writeTextFromScrolledList(int fd)
2462 static char buf[2048];
2465 DtMailEnv mail_error;
2466 MsgScrollingList *list;
2467 DmxMailbox *mailbox;
2471 // Create temp file.
2473 char *tmpdir = new char[MAXPATHLEN+1];
2474 snprintf(tmpdir, MAXPATHLEN+1, "%s/%s", getenv("HOME"), DtPERSONAL_TMP_DIRECTORY);
2475 if ((tmppath = tempnam(tmpdir, "dtmail")) == NULL) {
2476 snprintf(buf, sizeof(buf), GETMSG(DT_catd, 3, 51, "Unable to create %s."), tmpdir);
2477 _genDialog->setToErrorDialog(GETMSG(DT_catd, 3, 52, "Mailer"), buf);
2478 helpId = DTMAILHELPNOCREATE;
2479 _genDialog->post_and_return(helpId);
2486 list = _roam_menu_window->list();
2489 // Copy the selected messages to a temp file.
2491 int status = list->copySelected(mail_error, tmppath, FALSE, TRUE);
2492 if (mail_error.isSet()) {
2493 _roam_menu_window->postErrorDialog(mail_error);
2497 if (0 != status) return;
2499 mailbox = new DmxMailbox(tmppath);
2500 mailbox->loadMessages();
2501 next_msg = mailbox->firstMessage();
2504 DmxPrintHeadersEnum visible_headers;
2506 if (_roam_menu_window->fullHeader())
2507 visible_headers = DMX_PRINT_HEADERS_ALL;
2509 visible_headers = DMX_PRINT_HEADERS_ABBREV;
2513 &SaveAsTextCmd::writeText,
2514 (XtPointer) (intptr_t) fd);
2515 writeText((XtPointer) (intptr_t) fd, "\n\n");
2516 } while ((next_msg = mailbox->nextMessage()) != (DmxMsg *) NULL);
2520 // Clean up the temporary file.
2527 SaveAsTextCmd::writeText(XtPointer filedes, char *text_buf)
2529 long fdl = (long) filedes;
2531 int len = strlen(text_buf);
2533 if (SafeWrite(fd, text_buf, len) < len) {
2540 GETMSG(DT_catd, 3, 53, "Unable to write to %s."),
2542 helpId = DTMAILHELPNOWRITE;
2543 _genDialog->setToErrorDialog(GETMSG(DT_catd, 3, 56, "Mailer"), buf);
2544 _genDialog->post_and_return(helpId);
2550 SaveAsTextCmd::doit()
2552 MsgScrollingList *list;
2554 int *pos_list = NULL;
2557 if (_roam_menu_window &&
2558 (list = _roam_menu_window->list()) &&
2559 (listW = list->get_scrolling_list()))
2561 if (!XmListGetSelectedPos(listW, &pos_list, &pos_count))
2566 DtMailGenDialog *dialog = _roam_menu_window->genDialog();
2568 dialog->setToErrorDialog(
2569 GETMSG(DT_catd, 3, 50, "Mailer"),
2570 GETMSG(DT_catd, 2, 16, "No message selected."));
2571 dialog->post_and_return(NULL);
2577 UnifiedSelectFileCmd::doit();
2581 int pos_selected, last_space;
2583 DtMailHeaderLine header;
2584 DtMailMessageHandle msg_handle;
2585 DtMailHeaderRequest request;
2586 DtMail::MailBox *mbox;
2588 pos_selected = list->get_selected_item();
2589 msg_handle = list->msgno(pos_selected);
2591 request.number_of_names = 1;
2592 request.header_name = (char**) malloc(sizeof(char*));
2593 request.header_name[0] = strdup(DtMailMessageSubject);
2595 mbox = _roam_menu_window->mailbox();
2596 mbox->getMessageSummary(error, msg_handle, request, header);
2598 if (0 != header.header_values[0].length())
2600 const char *orig_subject = *((header.header_values[0])[0]);
2602 int orig_len = strlen(orig_subject);
2603 char *subject = (char*) malloc(orig_len + 1);
2606 for (i=0,j=0,last_space=0; i<orig_len; i++)
2608 if (isspace(orig_subject[i]))
2610 if (last_space < i-1)
2615 else if (orig_subject[i] == '/')
2616 subject[j++] = '\\';
2618 subject[j++] = orig_subject[i];
2622 xms = XmStringCreateLocalized(subject);
2623 XtVaSetValues(_fileBrowser, XmNtextString, xms, NULL);
2629 if (NULL != request.header_name)
2631 if (NULL != request.header_name[0])
2632 free(request.header_name[0]);
2633 free(request.header_name);
2636 mbox->clearMessageSummary(header);
2641 DeleteAttachCmd::DeleteAttachCmd(
2647 ) : Cmd ( name, label, active )
2653 DeleteAttachCmd::doit()
2655 _parent->delete_selected_attachments();
2659 DeleteAttachCmd::undoit()
2663 UndeleteAttachCmd::UndeleteAttachCmd(
2669 ) : Cmd ( name, label, active )
2675 UndeleteAttachCmd::doit()
2677 _parent->undelete_last_deleted_attachment();
2682 UndeleteAttachCmd::undoit()
2686 RenameAttachCmd::RenameAttachCmd (
2691 ) : Cmd ( name, label, active )
2693 Widget renameDialog;
2697 renameDialog = XmCreatePromptDialog(
2704 message = XmStringCreateLocalized(GETMSG(DT_catd, 1, 96, "Empty"));
2705 XtVaSetValues(renameDialog, XmNselectionLabelString, message, NULL);
2706 XmStringFree(message);
2707 XmString ok_str = XmStringCreateLocalized(GETMSG(DT_catd, 1, 97, "Rename"));
2708 XtVaSetValues(XtParent(renameDialog),
2709 XmNtitle, GETMSG(DT_catd, 1, 98, "Mailer - Rename"),
2711 XtVaSetValues(renameDialog,
2712 XmNokLabelString, ok_str,
2715 XmStringFree(ok_str);
2716 XtUnmanageChild(XmSelectionBoxGetChild(renameDialog, XmDIALOG_HELP_BUTTON));
2718 _parent->get_editor()->attachArea()->setRenameDialog(renameDialog);
2719 XtAddCallback(renameDialog, XmNcancelCallback,
2720 &RenameAttachCmd::cancelCallback,
2722 XtAddCallback(renameDialog, XmNokCallback,
2723 &RenameAttachCmd::okCallback,
2727 void RenameAttachCmd::doit()
2729 Widget renameDialog;
2730 XmString oldAttachName = NULL;
2735 if (!_parent->renameAttachmentOK()) {
2739 aa = _parent->get_editor()->attachArea();
2741 oldAttachName = aa->getSelectedAttachName();
2743 if (oldAttachName == NULL) return;
2745 renameDialog = aa->getRenameDialog();
2747 sprintf(buf, "%s", GETMSG(DT_catd, 3, 57, "Rename attachment as"));
2749 message = XmStringCreateLocalized(buf);
2751 XtVaSetValues(renameDialog,
2752 XmNselectionLabelString, message,
2753 XmNtextString, oldAttachName,
2757 XmStringFree(message);
2758 XmStringFree(oldAttachName);
2760 XtManageChild(renameDialog);
2761 XtPopup(XtParent(renameDialog), XtGrabNone);
2764 void RenameAttachCmd::undoit()
2766 // Just print a message that allows us to trace the execution
2770 void RenameAttachCmd::cancelCallback (
2772 XtPointer clientData,
2776 RenameAttachCmd *obj = (RenameAttachCmd *) clientData;
2778 obj->cancel( callData );
2781 void RenameAttachCmd::cancel( XtPointer )
2785 aa = _parent->get_editor()->attachArea();
2787 Widget renameDialog = aa->getRenameDialog();
2789 XtUnmanageChild(renameDialog);
2792 void RenameAttachCmd::okCallback (
2794 XtPointer clientData,
2798 RenameAttachCmd *obj = (RenameAttachCmd *) clientData;
2799 obj->ok( callData );
2802 void RenameAttachCmd::ok( XtPointer callData )
2804 XmSelectionBoxCallbackStruct *cbs =
2805 (XmSelectionBoxCallbackStruct *)callData;
2808 aa = _parent->get_editor()->attachArea();
2810 Widget renameDialog = aa->getRenameDialog();
2812 XtUnmanageChild(renameDialog);
2814 aa->setSelectedAttachName(cbs->value);
2818 AttachmentActionCmd::AttachmentActionCmd(
2821 RoamMenuWindow *rmw,
2823 ) : Cmd (name, label, TRUE)
2830 AttachmentActionCmd::AttachmentActionCmd(
2835 ) : Cmd (name, label, TRUE)
2842 AttachmentActionCmd::AttachmentActionCmd(
2847 ) : Cmd (name, label, TRUE)
2856 AttachmentActionCmd::doit()
2858 _parent->invokeAttachmentAction(_index);
2862 AttachmentActionCmd::undoit()
2866 SelectAllAttachsCmd::SelectAllAttachsCmd(
2870 ) : Cmd(name, label, TRUE)
2875 SelectAllAttachsCmd::SelectAllAttachsCmd(
2879 ) : Cmd(name, label, TRUE)
2884 SelectAllAttachsCmd::SelectAllAttachsCmd(
2888 ) : Cmd(name, label, FALSE)
2894 SelectAllAttachsCmd::doit()
2896 _parent->selectAllAttachments();
2900 SelectAllAttachsCmd::undoit()
2905 ShowAttachPaneCmd::ShowAttachPaneCmd(
2908 AbstractEditorParent *aep
2909 ) : ToggleButtonCmd(name, label, TRUE)
2915 ShowAttachPaneCmd::doit()
2918 if (!this->getButtonState()) {
2919 _parent->hideAttachArea();
2921 else { // button is ON
2922 _parent->showAttachArea();
2927 ShowAttachPaneCmd::undoit()
2932 AbbrevHeadersCmd::AbbrevHeadersCmd(
2936 ) : ToggleButtonCmd(name, label, TRUE)
2942 AbbrevHeadersCmd::doit()
2945 if (!this->getButtonState()) {
2946 _parent->fullHeader(TRUE);
2948 else { // button is ON
2949 _parent->fullHeader(FALSE);
2954 AbbrevHeadersCmd::undoit()
2965 : NoUndoCmd(name, label, active)
2967 _compose_dialog = s;
2974 // Call the goAway() method on the SMD. Argument TRUE requests it
2975 // to check if the SMD is dirty. Let it handle the
2976 // case where text may be present in the compose window.
2977 if (!_compose_dialog->isMsgValid())
2980 _compose_dialog->goAway(TRUE);
2984 EditUndoCmd::EditUndoCmd(
2988 AbstractEditorParent *w )
2989 : NoUndoCmd( name, label, active )
2991 editor = w->get_editor()->textEditor();
2997 editor->undo_edit();
3000 EditCutCmd::EditCutCmd(
3004 AbstractEditorParent *w
3006 : NoUndoCmd( name, label, active )
3008 editor = w->get_editor()->textEditor();
3010 // className() is a virtual method
3011 if (w->className() == "SendMsgDialog") {
3012 _compose_dialog = (SendMsgDialog *)w;
3015 _compose_dialog = NULL;
3022 editor->cut_selection();
3024 if (_compose_dialog) {
3026 _compose_dialog->activate_edit_paste();
3027 _compose_dialog->activate_edit_paste_indented();
3028 _compose_dialog->activate_edit_paste_bracketed();
3032 EditCopyCmd::EditCopyCmd(
3036 AbstractEditorParent *w )
3037 : NoUndoCmd( name, label, active )
3039 editor = w->get_editor()->textEditor();
3041 // className() is a virtual method
3042 if (w->className() == "SendMsgDialog") {
3043 _compose_dialog = (SendMsgDialog *)w;
3046 _compose_dialog = NULL;
3053 editor->copy_selection();
3054 if (_compose_dialog) {
3056 _compose_dialog->activate_edit_paste();
3057 _compose_dialog->activate_edit_paste_indented();
3058 _compose_dialog->activate_edit_paste_bracketed();
3062 EditPasteCmd::EditPasteCmd(
3066 AbstractEditorParent *w )
3067 : NoUndoCmd( name, label, active )
3069 editor = w->get_editor()->textEditor();
3073 EditPasteCmd::doit()
3075 editor->paste_from_clipboard();
3078 EditPasteSpecialCmd::EditPasteSpecialCmd(
3082 AbstractEditorParent *w,
3083 Editor::InsertFormat format)
3084 : NoUndoCmd( name, label, active )
3086 editor = w->get_editor()->textEditor();
3087 insert_format = format;
3091 EditPasteSpecialCmd::doit()
3093 editor->paste_special_from_clipboard(insert_format);
3097 EditClearCmd::EditClearCmd(
3101 AbstractEditorParent *w )
3102 : NoUndoCmd( name, label, active )
3104 editor = w->get_editor()->textEditor();
3105 // this->deactivate();
3109 EditClearCmd::doit()
3111 editor->clear_selection();
3113 // _edit_paste->activate();
3116 EditDeleteCmd::EditDeleteCmd(
3120 AbstractEditorParent *w )
3121 : NoUndoCmd( name, label, active )
3123 editor = w->get_editor()->textEditor();
3124 // this->deactivate();
3128 EditDeleteCmd::doit()
3130 editor->delete_selection();
3132 // _edit_paste->deactivate();
3135 EditSelectAllCmd::EditSelectAllCmd(
3139 AbstractEditorParent *w )
3140 : NoUndoCmd( name, label, active )
3142 editor = w->get_editor()->textEditor();
3146 EditSelectAllCmd::doit()
3148 editor->select_all();
3153 WordWrapCmd::WordWrapCmd(
3157 AbstractEditorParent *w
3158 ) : ToggleButtonCmd( name, label, active )
3160 editor = w->get_editor()->textEditor();
3162 * allow the app-defaults setting for WordWrap
3165 Widget _w = editor->get_text_widget();
3168 XtSetArg( args[0], XmNwordWrap, &cur_setting );
3169 XtGetValues( _w, args, 1 );
3170 editor->set_word_wrap(cur_setting);
3176 cur_setting = ((ToggleButtonCmd *)this)->getButtonState();
3177 editor->set_word_wrap(cur_setting);
3181 WordWrapCmd::wordWrap()
3183 return(cur_setting);
3186 FindChangeCmd::FindChangeCmd(
3190 AbstractEditorParent *w )
3191 : NoUndoCmd( name, label, active )
3193 editor = w->get_editor()->textEditor();
3197 FindChangeCmd::doit()
3199 editor->find_change();
3206 AbstractEditorParent *w )
3207 : NoUndoCmd( name, label, active )
3209 editor = w->get_editor()->textEditor();
3223 : NoUndoCmd (name, label, active)
3226 _alias = strdup(name);
3234 XtVaGetValues(_header, XmNvalue, &value, NULL);
3238 char *newvalue = (char *) malloc(strlen(value) + strlen(_alias) + 3);
3239 sprintf(newvalue, "%s, %s", value, _alias);
3240 XtVaSetValues(_header, XmNvalue, newvalue, NULL);
3244 XtVaSetValues(_header, XmNvalue, _alias, NULL);
3249 AliasCmd::~AliasCmd()
3251 free((void*) _alias);
3255 OtherAliasesCmd::OtherAliasesCmd(
3259 : NoUndoCmd (name, label, active)
3265 OtherAliasesCmd::doit()
3267 OptCmd *optCmd = (OptCmd *) theRoamApp.mailOptions();
3268 optCmd->displayAliasesOptionsPane();
3271 OtherAliasesCmd::~OtherAliasesCmd()
3276 FormatCmd::FormatCmd(
3280 AbstractEditorParent *w )
3281 : NoUndoCmd( name, label, active )
3283 editor = w->get_editor()->textEditor();
3292 LogMsgCmd::LogMsgCmd(
3296 SendMsgDialog * send
3297 ) : ToggleButtonCmd( name, label, active )
3299 // Go to props and find out the default, ie. to log or not to log.
3300 // But for now, just look in .mailrc to see if "record" is set.
3303 const char *logfile = NULL;
3312 if (!((ToggleButtonCmd *)this)->getButtonState()) {
3313 // turn off logging for this message
3314 _send->setLogState(DTM_FALSE);
3317 // turn on logging for this message
3318 _send->setLogState(DTM_TRUE);
3324 VacationCmd::VacationCmd(
3327 ) : Cmd (name, label, TRUE)
3330 _forwardFile = ".forward";
3331 _backupSuffix = "..BACKUP";
3337 // Check if a .forward file exists.
3339 _priorVacationRunning = this->priorVacationRunning();
3341 // parse the .vacation.msg file and retain the subject
3343 // They need to be retrieved for display in the dialog.
3345 this->parseVacationMessage();
3349 VacationCmd::~VacationCmd()
3351 if (NULL != _subject)
3352 free((void*) _subject);
3363 static unsigned long
3364 writeToFileDesc(const char * buf, int len, va_list args)
3366 int fd = va_arg(args, int);
3367 int cnt = va_arg(args, int);
3371 status = SafeWrite(fd, buf, len);
3372 } while (status < 0 && errno == EAGAIN);
3378 VacationCmd::startVacation(
3383 int i = this->handleMessageFile(subj, text);
3385 i = this->handleForwardFile();
3392 VacationCmd::stopVacation()
3394 char *forwardfile = new char[MAXPATHLEN+1];
3396 snprintf(forwardfile, MAXPATHLEN+1, "%s/%s", getenv("HOME"), _forwardFile);
3398 // Remove the current .forward file (it has vacation in it)
3399 // Recover and replace the original backup forward file, if
3402 unlink(forwardfile);
3404 this->recoverForwardFile(forwardfile);
3405 delete [] forwardfile;
3409 VacationCmd::priorVacationRunning()
3414 Boolean retval = FALSE;
3415 char *forwardfile = new char[MAXPATHLEN+1];
3417 snprintf(forwardfile, MAXPATHLEN+1, "%s/%s", getenv("HOME"), _forwardFile);
3419 if (SafeAccess(forwardfile, F_OK) != 0) {
3420 delete [] forwardfile;
3424 fd = SafeOpen(forwardfile, O_RDONLY);
3426 buf[sizeof buf -1] = '\0';
3428 while ((len = SafeRead(fd, buf, (sizeof buf) - 1)) > 0) {
3430 if ((strstr(buf, "/usr/bin/vacation")) ||
3431 (strstr(buf, "/usr/ucb/vacation"))) {
3439 delete [] forwardfile;
3444 VacationCmd::handleForwardFile()
3454 Boolean forwardExists;
3455 DtMailGenDialog *dialog;
3457 int error_bufLen = 10000;
3458 char *error_buf = new char[error_bufLen];
3459 char *forwardfile = new char[MAXPATHLEN+1];
3460 char *messagefile = new char[256];
3461 char *buf = new char[2048];
3463 // initialize the error_buf
3464 memset(error_buf, 0, error_bufLen);
3465 memset(buf, 0, 2048);
3469 forwardExists = FALSE;
3472 GetPasswordEntry(pw);
3474 sprintf(forwardfile, "%s/%s", pw.pw_dir, _forwardFile);
3476 if (SafeAccess(forwardfile, F_OK) == 0 ) {
3477 forwardExists = TRUE;
3480 forwardExists = FALSE;
3483 if (forwardExists && !_priorVacationRunning) {
3485 /* STRING_EXTRACTION -
3487 * This confirmation window is brought up when the user
3488 * tries to update the vacation status when the user is
3489 * already using a .forward file.
3491 if (NULL != _dialog)
3494 dialog = theRoamApp.genDialog();
3496 sprintf(error_buf, "%s", 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"));
3498 dialog->setToQuestionDialog(GETMSG(DT_catd, 1, 103, "Mailer"),
3501 helpId = DTMAILHELPOKSTARTVACATION;
3502 answer = dialog->post_and_return(helpId);
3504 if (answer == 2) {// Cancel chosen
3506 delete [] messagefile;
3507 delete [] error_buf;
3508 delete [] forwardfile;
3512 if (this->backupFile(forwardfile) < 0) {
3514 delete [] messagefile;
3515 delete [] error_buf;
3516 delete [] forwardfile;
3520 /* A .forward file is currently in use. Merge vacation
3521 * into this file, rather than overwrite it. To do so,
3522 * set the appropriate variable to indicate mode.
3525 _priorVacationRunning = TRUE;
3527 // Turn on the bit to indicate we are currently using a .forward
3530 else if (forwardExists && _priorVacationRunning) {
3532 /* STRING_EXTRACTION -
3534 * This confirmation window is brought up when the user
3535 * tries to update the vacation status when the user is
3536 * already using a .forward file.
3539 if (NULL != _dialog)
3542 dialog = theRoamApp.genDialog();
3544 sprintf(error_buf, "%s", 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"));
3546 dialog->setToErrorDialog("Error", error_buf);
3547 helpId = DTMAILHELPREMOVEVACATION;
3548 answer = dialog->post_and_return(helpId);
3551 delete [] messagefile;
3552 delete [] error_buf;
3553 delete [] forwardfile;
3558 // Re-initialize the error_buf
3559 memset(error_buf, 0, error_bufLen);
3561 sprintf(messagefile, "%s/.vacation.msg", pw.pw_dir);
3563 if (forwardExists) {
3564 fwd_fd = SafeOpen(forwardfile, O_WRONLY | O_APPEND | O_CREAT);
3567 fwd_fd = SafeOpen(forwardfile, O_WRONLY | O_CREAT);
3570 if (fwd_fd < 0 ) {// If fwdfile is not writable/appendable
3572 // Put up error dialog indicating fwdfile not writable
3573 /* restore the original .forward file */
3575 this->recoverForwardFile(forwardfile);
3577 delete [] messagefile;
3578 delete [] error_buf;
3579 delete [] forwardfile;
3583 SafeFChmod(fwd_fd, 0644);
3585 // Make buf be forwardfile._backupSuffix.
3586 // Then create a backup file of name buf
3588 strcpy(buf, forwardfile);
3589 strcat(buf, _backupSuffix);
3591 // If we are currently using a .forward then we need to append/prepend
3592 // the vacation command
3596 /* CREATE NEW .forward FILE
3598 * The original .forward file has been renamed to the
3599 * backup file name. We need to open the backup .forward
3600 * file so we can copy from it.
3603 if ((bkup_fd = SafeOpen(buf, O_RDONLY)) < 0) {
3604 /* restore the original .forward file */
3606 this->recoverForwardFile(forwardfile);
3608 delete [] messagefile;
3609 delete [] error_buf;
3610 delete [] forwardfile;
3614 /* COPY OLD .forward TO NEW .forward
3616 * Using mmap is quite fast, so rather than do a while
3617 * loop to copy line by line, we'll use mmap followed by
3621 fsize= (int)lseek(bkup_fd, 0, SEEK_END);
3625 (caddr_t) mmap(0, fsize, PROT_READ, MAP_PRIVATE, bkup_fd, 0);
3628 if (fwdptr == (char *)-1) {
3631 delete [] messagefile;
3632 delete [] error_buf;
3633 delete [] forwardfile;
3639 if (SafeWrite(fwd_fd, fwdptr, fsize) < fsize) {
3642 delete [] messagefile;
3643 delete [] error_buf;
3644 delete [] forwardfile;
3649 /* RELEASE .forward FILE
3651 * Un-mmap the new .forward file
3654 lastchar = fwdptr[fsize-1];
3655 munmap(fwdptr, fsize);
3660 /* APPEND VACATION LINE
3662 * The new .forward file is still open, so append the
3663 * new line below as the last line of the .forward file.
3664 * Check to make sure last character in the file is a
3665 * newline. If it's not, add one so our work goes on
3669 if (lastchar != '\n') {
3670 lseek(fwd_fd, 0, SEEK_END);
3672 if (SafeWrite(fwd_fd, txt, strlen(txt)) < strlen(txt)) {
3675 delete [] messagefile;
3676 delete [] error_buf;
3677 delete [] forwardfile;
3684 * Now, add the vacation line to the next line.
3686 char *append_buf1 = new char[1024*2];
3687 sprintf(append_buf1, "|\" /usr/bin/vacation %s\"\n", pw.pw_name);
3689 if (SafeWrite(fwd_fd, append_buf1, strlen(append_buf1)) <
3690 strlen(append_buf1)) {
3693 delete [] messagefile;
3694 delete [] error_buf;
3695 delete [] forwardfile;
3696 delete [] append_buf1;
3700 delete [] append_buf1;
3705 /* Create known backup file. The known backup
3706 * file allows mailtool to differentiate between
3707 * vacation being started from mailtool, and vacation
3708 * being invoked (the Unix program as opposed to the
3709 * MailTool Vacation menu item) via tty session.
3712 if (!forwardExists) {
3714 if ((bkup_fd = SafeOpen(buf, O_WRONLY | O_APPEND | O_CREAT)) < 0) {
3715 /* restore the original .forward file */
3717 this->recoverForwardFile(forwardfile);
3719 delete [] messagefile;
3720 delete [] error_buf;
3721 delete [] forwardfile;
3726 char *end_text = "User not using forward file\n";
3728 if (SafeWrite(bkup_fd, end_text, strlen(end_text)) <
3732 delete [] messagefile;
3733 delete [] error_buf;
3734 delete [] forwardfile;
3741 if (!forwardExists) {
3743 /* WRITE NEW .forward FILE
3745 * There was no .forward file, so no appending
3746 * must be done. Simply write the standard
3747 * vacation line into the new .forward file.
3750 char *append_buf2 = new char[1024*2];
3752 sprintf(append_buf2, "\\%s, |\" /usr/bin/vacation %s\"\n",
3753 pw.pw_name, pw.pw_name);
3754 if (SafeWrite(fwd_fd, append_buf2, strlen(append_buf2)) <
3755 strlen(append_buf2)) {
3760 delete [] messagefile;
3761 delete [] error_buf;
3762 delete [] forwardfile;
3763 delete [] append_buf2;
3766 delete [] append_buf2;
3772 system("/usr/bin/vacation -I");
3775 delete [] messagefile;
3776 delete [] error_buf;
3777 delete [] forwardfile;
3782 VacationCmd::backupFile(
3786 char *buf = new char[MAXPATHLEN+1];
3789 strcat(buf, _backupSuffix);
3791 if (rename(file, buf) < 0) {
3792 /* STRING_EXTRACTION -
3794 * We tried to make a backup copy of your .forward file, but
3795 * it failed. The first %s is the name of the rename
3796 * target; the second %s is the system error string.
3799 // Put up error dialog
3809 VacationCmd::recoverForwardFile(
3813 char *buf = new char[BUFSIZ+1];
3816 sprintf(buf, "%s", file);
3817 strcat(buf, _backupSuffix);
3819 if (rename(buf, file) < 0) {
3821 /* STRING_EXTRACTION -
3823 * We tried to restore your original .forward file, but could
3824 * not. The first %s is the name of the original .forward file,
3825 * the second %s is the the system error string.
3828 // Handle dialog indicating error in recovering .forward file.
3829 // Error usually caused by starting /usr/bin/vacation outside
3836 if ((fd = SafeOpen(file, O_RDONLY)) == -1) {
3841 buf[sizeof file -1] = '\0';
3842 while (SafeRead(fd, buf, BUFSIZ) != 0) {
3843 if (strstr(buf, "User not using forward file")) {
3856 VacationCmd::subject()
3866 return((char *)_body);
3874 VacationCmd::parseVacationMessage()
3879 DtMailGenDialog *dialog;
3882 char dialog_text[1024*4];
3884 DtMail::Session * d_session = theRoamApp.session()->session();
3887 if (NULL != _dialog)
3890 dialog = theRoamApp.genDialog();
3892 GetPasswordEntry(pw);
3894 char *messagefile = new char[MAXPATHLEN+1];
3895 sprintf(messagefile, "%s/.vacation.msg", pw.pw_dir);
3897 // See if the messagefile exists.
3898 // If it doesn't create one and throw in the text found in the
3899 // properties sheet. If no text found, use default template.
3901 char * fullpath = d_session->expandPath(error, messagefile);
3902 delete [] messagefile;
3905 // Map the file and try to parse it as a message. If it is a message,
3906 // then load it with headers. Otherwise, throw everything into the
3910 fd = SafeOpen(fullpath, O_RDONLY);
3913 if (fd < 0) {// File doesn't exist
3921 if (SafeFStat(fd, &buf) < 0) {
3923 sprintf(dialog_text, "%s",
3924 GETMSG(DT_catd, 1, 105, "Cannot open .vacation.msg file -- No write permission."));
3925 dialog->setToQuestionDialog("Mailer", dialog_text);
3926 helpId = DTMAILHELPNOWRITEVACATION;
3927 answer = dialog->post_and_return(helpId);
3936 int page_size = (int)sysconf(_SC_PAGESIZE);
3937 size_t map_size = (int) (buf.st_size +
3938 (page_size - (buf.st_size % page_size)));
3940 if (buf.st_size == 0) {
3946 mbuf.size = buf.st_size;
3947 mbuf.buffer = mmap(0, map_size, PROT_READ, MAP_PRIVATE, fd, 0);
3948 if (mbuf.buffer == (char *)-1) {
3950 mbuf.buffer = new char[mbuf.size];
3951 if (mbuf.buffer == NULL) {
3952 dialog->setToErrorDialog(GETMSG(DT_catd, 3, 59, "No Memory"),
3953 GETMSG(DT_catd, 3, 60, "There is not enough memory to load the existing .vacation.msg file."));
3954 helpId = DTMAILHELPNOLOADVACATION;
3955 answer = dialog->post_and_return(helpId);
3964 if (SafeRead(fd, mbuf.buffer, (unsigned int)mbuf.size) < mbuf.size) {
3965 dialog->setToErrorDialog(GETMSG(DT_catd, 3, 61, "Mailer"),
3966 GETMSG(DT_catd, 3, 62, "The existing .vacation.msg file appears to be corrupt."));
3967 helpId = DTMAILHELPCORRUPTVACATION;
3968 answer = dialog->post_and_return(helpId);
3970 delete [] mbuf.buffer;
3978 // Now we ask the library to parse it. If this fails for any reason, this
3979 // is not a message, so we give up.
3981 DtMail::Message * msg = d_session->messageConstruct(error,
3989 if (error.isSet()) {
3996 DtMail::Envelope * env = msg->getEnvelope(error);
3997 DtMailHeaderHandle hnd;
4001 DtMailValueSeq value;
4003 for (hnd = env->getFirstHeader(error, &name, value);
4004 error.isNotSet() && hnd;
4005 hnd = env->getNextHeader(error, hnd, &name, value)) {
4007 if (!strcmp(name, "Subject") == 0) {
4013 for (int slen = 0; slen < value.length(); slen++) {
4014 max_len += strlen(*(value[slen]));
4017 char * new_str = new char[max_len + (value.length() * 3)];
4019 strcpy(new_str, "");
4020 for (int copy = 0; copy < value.length(); copy++) {
4022 strcat(new_str, " ");
4025 strcat(new_str, *(value[copy]));
4028 _subject = strdup(new_str);
4036 DtMail::BodyPart * bp = msg->getFirstBodyPart(error);
4037 if (error.isNotSet()) {
4038 unsigned long length;
4040 bp->getContents(error,
4050 // Avoid a memory leak.
4058 VacationCmd::handleMessageFile(
4065 DtMailGenDialog *dialog;
4068 char dialog_text[1024*4];
4069 Boolean text_changed = FALSE;
4070 char *messagefile = new char[256];
4072 BufferMemory buf(4096);
4074 if (NULL != _dialog)
4077 dialog = theRoamApp.genDialog();
4079 // Check if a .forward file exists.
4081 GetPasswordEntry(pw);
4083 sprintf(messagefile, "%s/.vacation.msg", pw.pw_dir);
4085 // See if the messagefile exists.
4086 // If it doesn't create one and throw in the text found in the
4087 // properties sheet. If no text found, use default template.
4091 int msg_file_exists = SafeAccess(messagefile, F_OK);
4093 if (_subject == NULL || strcmp(_subject, subj) != 0)
4094 text_changed = TRUE;
4096 else if (_subject != NULL)
4097 text_changed = TRUE;
4099 if (!text_changed) {
4101 if (_body == NULL || strcmp((char*)_body, text) != 0)
4102 text_changed = TRUE;
4104 else if (_body != NULL)
4105 text_changed = TRUE;
4108 if (msg_file_exists >= 0 && text_changed) {
4109 sprintf(dialog_text, "%s",
4110 GETMSG(DT_catd, 1, 106, ".vacation.msg file exists. Replace with new text?"));
4111 dialog->setToQuestionDialog("Mailer", dialog_text);
4112 helpId = DTMAILHELPEXISTSVACATION;
4113 answer = dialog->post_and_return(helpId);
4116 // backup the messageFile
4117 this->backupFile(messagefile);
4121 // If the file doesn't exist or if the user has okayed creation
4123 if ((msg_file_exists < 0) || (answer == 1)) {
4125 fd = SafeOpen(messagefile, O_WRONLY | O_CREAT);
4127 sprintf(dialog_text, "%s",
4128 GETMSG(DT_catd, 1, 107, "Cannot open .vacation.msg file -- No write permission."));
4129 dialog->setToQuestionDialog("Mailer", dialog_text);
4130 helpId = DTMAILHELPERROR;
4131 answer = dialog->post_and_return(helpId);
4133 // Handle dialog indicating file not writable
4134 delete [] messagefile;
4137 SafeFChmod (fd, 0644);
4141 * This is the default value of the subject field in the
4142 * message that gets returned to the sender when vacation
4145 subj = GETMSG(DT_catd, 1, 108, "I am on vacation");
4147 buf.appendData("Subject: ", 9);
4148 buf.appendData(subj, strlen(subj));
4149 buf.appendData("\nPrecedence: junk\n\n", 19);
4153 _subject = strdup(subj);
4156 text = GETMSG(DT_catd, 1, 109,
4157 "I'm on vacation.\nYour mail regarding \"$SUBJECT\" will be read when I return.\n");
4159 buf.appendData(text, strlen(text));
4160 if (strlen(text) > 0 && text[strlen(text) - 1] != '\n') {
4161 buf.appendData("\n", 1);
4163 _body = strdup(text);
4165 buf.iterate(writeToFileDesc, fd);
4169 delete [] messagefile;