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>
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;
323 // Parent's execute() ends up calling derived class's doit()
325 OpenContainerCmd::execute()
327 RoamInterruptibleCmd::execute();
331 OpenContainerCmd::execute(
332 RoamTaskDoneCallback rtd_callback,
336 RoamInterruptibleCmd::execute(rtd_callback, clientData);
339 // Tell the RMW to open. The RMW may end up calling its convert()
340 // which depends on ConvertContainerCmd's doit...
341 // By the time RMW->open() returns, the conversion would have
343 // This is the case of a RinterruptibleCmd derived class
344 // getting its work done in its doit() in one call.
348 OpenContainerCmd::doit()
352 assert(_menuWindow != NULL);
354 // Initialize the mail_error.
357 _menuWindow->open(error, _open_create_flag, _open_lock_flag);
359 // Post a dialog indicating error and exit?
360 return; // for now. Should exit instead?
366 OpenContainerCmd::undoit()
368 // Just print a message that allows us to trace the execution
370 DebugPrintf(1, "%s: undoit\n", name());
374 OpenContainerCmd::check_if_done()
376 // Have nothing fancy to do here. Since we do not want a dialog
377 // in any case, set it to true...
385 OpenContainerCmd::post_dialog()
387 // Empty. We don't want a dialog on open...
391 OpenContainerCmd::unpost_dialog()
393 // Empty. We don't post, and we don't unpost.
396 OpenContainerCmd::updateMessage (char *msg)
398 RoamInterruptibleCmd::updateMessage(msg);
402 OpenContainerCmd::set_create_lock_flags(
403 DtMailBoolean create,
407 _open_create_flag = create;
408 _open_lock_flag = lock;
412 // ConvertContainerCmd
415 ConvertContainerCmd::ConvertContainerCmd(
419 RoamMenuWindow *window
420 ) : RoamInterruptibleCmd (name, label, active)
422 _menuWindow = window;
424 _num_to_be_converted = 0;
429 ConvertContainerCmd::execute()
432 _dialog = new DtMailWDM("Convert");
435 RoamInterruptibleCmd::execute();
439 ConvertContainerCmd::execute ( RoamTaskDoneCallback rtd_callback,
443 _dialog = new DtMailWDM("Convert");
446 RoamInterruptibleCmd::execute(rtd_callback, clientData);
449 // Here be bigger dragons!
450 // The doit() calls the session->convert().
451 // And returns right away!
452 // the ses->convert() however ends up calling the conv_cb for every
453 // message that it has converted.
454 // So, we now have two loops working in parallel:
455 // 1) the parent()'s execute() class which called this doit() and is now
456 // calling check_if_done() periodically via its workProc;
457 // 2) the session->convert() which is calling the _conv_cb() for every
458 // message that it converts. In the _conv_cb(), we do the following:
459 // a) force update the dialog and see if it was interrupted;
460 // b) if not interrupted, set_convert_data() where we set _done if
461 // we are really done.
465 ConvertContainerCmd::doit()
467 assert(_menuWindow != NULL);
469 MailSession *ses = theRoamApp.session();
470 DtMailEnv mail_error;
472 // Initialize the mail_error.
475 // ses->convert(mail_error, _src, _dest, _conv_cb, _menuWindow);
477 if (mail_error.isSet()) {
478 _menuWindow->postErrorDialog(mail_error);
483 ConvertContainerCmd::set_convert_data(
488 _num_converted = converted;
489 _num_to_be_converted = to_be_converted;
491 if ((_num_converted == _num_to_be_converted) && !_interrupted) {
497 ConvertContainerCmd::get_num_converted()
499 return(_num_converted);
504 ConvertContainerCmd::check_if_done()
509 else if (_num_converted == _num_to_be_converted) {
515 ConvertContainerCmd::updateDialog(
519 forceUpdate(_dialog->baseWidget());
520 _dialog->updateDialog( msg );
524 ConvertContainerCmd::updateAnimation()
526 forceUpdate(_dialog->baseWidget());
527 _dialog->updateAnimation();
531 ConvertContainerCmd::post_dialog()
533 Dimension x, y, wid, ht;
535 char * buf = new char[25];
537 sprintf(buf, "Converted: %3d%", 0);
539 _dialog->post ("Mailer",
541 _menuWindow->baseWidget(),
544 &RoamInterruptibleCmd::interruptCallback );
546 XtVaGetValues(_dialog->baseWidget(),
556 ConvertContainerCmd::unpost_dialog()
562 ConvertContainerCmd::undoit()
564 // Just print a message that allows us to trace the execution
566 DebugPrintf(1, "%s: undoit\n", name());
570 ConvertContainerCmd::set_data(
573 ConversionStatusCB cb
582 ConvertContainerCmd::get_destination_name()
594 RoamMenuWindow *window
595 ) : RoamCmd ( name, label, active, window )
603 _menuwindow->get_find_dialog();
605 // SearchCmd::doit();
610 ChooseCmd::ChooseCmd(
614 RoamMenuWindow *window
615 ) : NoUndoCmd( name, label, active )
617 _menuwindow = window;
626 SelectAllCmd::SelectAllCmd(
630 RoamMenuWindow *window
631 ) : Cmd ( name, label, active )
633 _menuwindow = window;
639 DtMailEnv mail_error;
641 _menuwindow->list()->select_all_and_display_last(mail_error);
645 SelectAllCmd::undoit()
650 DeleteCmd::DeleteCmd(
654 RoamMenuWindow *window
655 ) : Cmd ( name, label, active )
657 _menuwindow = window;
663 _menuwindow->list()->deleteSelected(FALSE);
673 DestroyCmd::DestroyCmd(
677 RoamMenuWindow *window
678 ) : Cmd(name, label, active)
680 _menuwindow = window;
686 // Call Expunge only if there are deleted messages.
688 if (_menuwindow->list()->get_num_deleted_messages()) {
689 _menuwindow->expunge();
698 // Unified Select File Cmd stuff
699 int UnifiedSelectFileCmd::_is_initialized = 0;
700 char *UnifiedSelectFileCmd::_unified_directory = NULL;
701 char *UnifiedSelectFileCmd::_unified_file = NULL;
702 int UnifiedSelectFileCmd::_unified_hidden = 0;
703 int UnifiedSelectFileCmd::_unify_selection = 1;
705 UnifiedSelectFileCmd::UnifiedSelectFileCmd (
715 :SelectFileCmd (name,
720 unifiedFileSelectedCB,
722 unifiedFileCanceledCB,
726 if (! _is_initialized)
728 FORCE_SEGV_DECL(DtMail::Session, m_session);
730 const char *dirname = NULL;
731 const char *expanded_dirname = NULL;
732 const char *value = NULL;
733 char *full_dirname = NULL;
735 _unified_directory = NULL;
736 _unified_file = NULL;
738 _unify_selection = 1;
741 m_session = theRoamApp.session()->session();
744 m_session->mailRc(error)->getValue(error, "filefolder", &dirname);
746 dirname = strdup("~");
749 expanded_dirname = m_session->expandPath(error, dirname);
750 _unified_directory = XtNewString(expanded_dirname);
753 m_session->mailRc(error)->getValue(
755 "dontunifyfileselection",
758 _unify_selection = 0;
760 free((void*) dirname);
761 free((void*) expanded_dirname);
765 _select_file_callback = select_callback;
766 _select_file_client_data = client_data;
767 _genDialog = new DtMailGenDialog("Dialog", parent);
770 UnifiedSelectFileCmd::~UnifiedSelectFileCmd()
772 if (_genDialog) delete _genDialog;
776 UnifiedSelectFileCmd::doit()
778 if (NULL == _fileBrowser)
780 SelectFileCmd::doit();
781 if (NULL != _unified_directory)
782 setDirectory(_unified_directory);
783 if (NULL != _unified_file)
784 setSelected(_unified_file);
785 setHidden(_unified_hidden);
789 if (_unify_selection)
791 if (NULL != _unified_directory)
792 setDirectory(_unified_directory);
793 if (NULL != _unified_file)
794 setSelected(_unified_file);
795 setHidden(_unified_hidden);
797 SelectFileCmd::doit();
802 UnifiedSelectFileCmd::unifiedFileSelectedCB(void *client_data, char *selection)
804 UnifiedSelectFileCmd *self = (UnifiedSelectFileCmd *) client_data;
808 self->updateUnifiedData();
809 self->unifiedFileSelected(selection);
814 UnifiedSelectFileCmd::unifiedFileSelected(char *selection)
818 SafePathIsAccessible(error, selection);
821 const char *errmsg = NULL;
825 errmsg = (const char*) error;
826 err = strdup(errmsg);
828 _genDialog->setToErrorDialog(GETMSG(DT_catd, 3, 48, "Mailer"), err);
829 answer = _genDialog->post_and_return(DTMAILHELPERROR);
830 if (1 == answer) doit();
835 if (_select_file_callback)
836 _select_file_callback(_select_file_client_data, selection);
840 UnifiedSelectFileCmd::unifiedFileCanceledCB(void *client_data, char *)
842 UnifiedSelectFileCmd *self = (UnifiedSelectFileCmd *) client_data;
845 self->updateUnifiedData();
849 UnifiedSelectFileCmd::updateUnifiedData()
851 if (! _unify_selection)
854 if (NULL != _unified_file)
855 XtFree(_unified_file);
856 _unified_file = getSelected();
859 if (NULL != _unified_directory)
860 XtFree(_unified_directory);
861 _unified_directory = getDirectory();
863 _unified_hidden = getHidden();
866 // Unified Select Mailbox Cmd stuff
867 int UnifiedSelectMailboxCmd::_is_initialized = 0;
868 char *UnifiedSelectMailboxCmd::_unified_directory = NULL;
869 char *UnifiedSelectMailboxCmd::_unified_file = NULL;
870 int UnifiedSelectMailboxCmd::_unified_hidden = 0;
871 int UnifiedSelectMailboxCmd::_unify_selection = 1;
873 UnifiedSelectMailboxCmd::UnifiedSelectMailboxCmd (
883 DtMailBoolean only_show_mailboxes)
884 :SelectFileCmd (name,
889 unifiedMailboxSelectedCB,
891 unifiedMailboxCanceledCB,
895 if (! _is_initialized)
897 FORCE_SEGV_DECL(DtMail::Session, m_session);
899 const char *dirname = NULL;
900 const char *expanded_dirname = NULL;
901 const char *value = NULL;
902 char *full_dirname = NULL;
904 _unified_directory = NULL;
905 _unified_file = NULL;
907 _unify_selection = 1;
909 _only_show_mailboxes = only_show_mailboxes;
911 m_session = theRoamApp.session()->session();
914 m_session->mailRc(error)->getValue(error, "folder", &dirname);
916 dirname = strdup("~");
919 expanded_dirname = m_session->expandPath(error, dirname);
920 _unified_directory = XtNewString(expanded_dirname);
923 m_session->mailRc(error)->getValue(
925 "dontunifyfileselection",
928 _unify_selection = 0;
930 free((void*) dirname);
931 free((void*) expanded_dirname);
935 _select_file_callback = select_callback;
936 _select_file_client_data = client_data;
937 _genDialog = new DtMailGenDialog("Dialog", parent);
940 UnifiedSelectMailboxCmd::~UnifiedSelectMailboxCmd()
942 if (_genDialog) delete _genDialog;
946 UnifiedSelectMailboxCmd::doit()
948 if (NULL == _fileBrowser)
950 SelectFileCmd::doit();
951 if (NULL != _unified_directory)
952 setDirectory(_unified_directory);
953 if (NULL != _unified_file)
954 setSelected(_unified_file);
955 setHidden(_unified_hidden);
961 UnifiedSelectMailboxCmd::unifiedMailboxSearchProc,
966 if (_unify_selection)
968 if (NULL != _unified_directory)
969 setDirectory(_unified_directory);
970 if (NULL != _unified_file)
971 setSelected(_unified_file);
972 setHidden(_unified_hidden);
974 SelectFileCmd::doit();
979 extern void _XmOSBuildFileList(
982 #if NeedWidePrototypes
983 unsigned int typeMask,
985 unsigned char typeMask,
986 #endif /* NeedWidePrototypes */
988 unsigned int *pNumEntries,
989 unsigned int *pNumAlloc);
991 extern int _XmOSFileCompare(const void *sp1, const void *sp2);
992 extern char *_XmStringGetTextConcat(XmString string);
996 UnifiedSelectMailboxCmd::unifiedMailboxSearchProc(
1000 XmFileSelectionBoxWidget fs =
1001 (XmFileSelectionBoxWidget) w;
1002 XmFileSelectionBoxCallbackStruct * searchData =
1003 (XmFileSelectionBoxCallbackStruct *) sd;
1009 unsigned int numFiles;
1010 unsigned int numItems = 0;
1011 unsigned int numAlloc;
1012 XmString * XmStringFileList;
1014 XtEnum fileFilterStyle, pathMode;
1015 unsigned char fileTypeMask;
1017 if (!(dir = _XmStringGetTextConcat(searchData->dir)))
1020 if (!(pattern = _XmStringGetTextConcat(searchData->pattern)))
1029 XmNfileTypeMask, &fileTypeMask,
1030 XmNfileFilterStyle, &fileFilterStyle,
1031 XmNpathMode, &pathMode,
1035 dir, pattern, fileTypeMask,
1036 &fileList, &numFiles, &numAlloc);
1038 if (fileList && numFiles)
1040 Boolean showDotFiles = (fileFilterStyle == XmFILTER_NONE);
1043 qsort((void*) fileList, numFiles, sizeof(char*), _XmOSFileCompare);
1045 XmStringFileList = (XmString*) XtMalloc(numFiles*sizeof(XmString));
1048 dirLen = strlen(dir);
1050 while (Index < numFiles)
1052 Boolean isMailBox = 0;
1053 char *dataType = NULL;
1055 dataType = DtDtsFileToDataType(fileList[Index]);
1057 isMailBox = (0 == strcmp(dataType, "DTMAIL_FILE"));
1058 DtDtsFreeDataType(dataType);
1061 (showDotFiles || ((fileList[Index])[dirLen] != '.')) )
1063 if (pathMode == XmPATH_MODE_FULL)
1064 XmStringFileList[numItems++] =
1065 XmStringGenerate(fileList[Index],
1066 XmFONTLIST_DEFAULT_TAG,
1067 XmCHARSET_TEXT, NULL);
1069 XmStringFileList[numItems++] =
1070 XmStringGenerate(&(fileList[Index])[dirLen],
1071 XmFONTLIST_DEFAULT_TAG,
1072 XmCHARSET_TEXT, NULL) ;
1082 XmNfileListItemCount, numItems,
1083 XmNfileListItems, XmStringFileList,
1084 XmNlistUpdated, TRUE,
1089 XtFree( fileList[Index]);
1092 XmStringFree(XmStringFileList[numItems]);
1094 XtFree((char*) XmStringFileList);
1100 XmNfileListItemCount, 0,
1101 XmNfileListItems, NULL,
1102 XmNlistUpdated, TRUE,
1106 XtFree((char *) fileList);
1113 UnifiedSelectMailboxCmd::unifiedMailboxSelectedCB(
1117 UnifiedSelectMailboxCmd *self = (UnifiedSelectMailboxCmd *) client_data;
1121 self->updateUnifiedData();
1122 self->unifiedMailboxSelected(
1123 self->_select_file_callback,
1124 self->_select_file_client_data,
1130 UnifiedSelectMailboxCmd::unifiedMailboxSelected(
1137 SafePathIsAccessible(error, selection);
1140 const char *errmsg = NULL;
1144 errmsg = (const char*) error;
1145 err = strdup(errmsg);
1147 _genDialog->setToErrorDialog(GETMSG(DT_catd, 3, 48, "Mailer"), err);
1148 answer = _genDialog->post_and_return(DTMAILHELPERROR);
1149 if (1 == answer) doit();
1154 updateUnifiedData();
1155 if (cb) cb(client_data, selection);
1159 UnifiedSelectMailboxCmd::unifiedMailboxCanceledCB(void *client_data, char *)
1161 UnifiedSelectMailboxCmd *self = (UnifiedSelectMailboxCmd *) client_data;
1164 self->updateUnifiedData();
1168 UnifiedSelectMailboxCmd::updateUnifiedData()
1170 if (! _unify_selection)
1173 if (NULL != _unified_file)
1174 XtFree(_unified_file);
1175 _unified_file = getSelected();
1178 if (NULL != _unified_directory)
1179 XtFree(_unified_directory);
1180 _unified_directory = getDirectory();
1182 _unified_hidden = getHidden();
1185 ContainerMenuCmd::ContainerMenuCmd(
1189 RoamMenuWindow *window,
1191 ) : RoamCmd ( name, label, active, window )
1193 _menuwindow = window;
1194 _container_name = name;
1199 ContainerMenuCmd::doit()
1201 DtMailEnv mail_error;
1203 // Initialize mail_error.
1206 theRoamApp.busyAllWindows(GETMSG(DT_catd, 3, 15, "Saving..."));
1207 _menuwindow->mailbox()->save();
1208 theRoamApp.unbusyAllWindows();
1215 _menuwindow->view_mail_file(_container_name, DTM_FALSE);
1218 _menuwindow->list()->copySelected(
1222 if (mail_error.isSet())
1224 // We had an error in copying the message to a container!
1228 _menuwindow->list()->copySelected(
1232 if (mail_error.isSet())
1234 // We had an error in moving the message to a container!
1240 ContainerMenuCmd::~ContainerMenuCmd()
1245 // Move the messages that are selected in the RoamMenuWindow to the Inbox.
1246 MoveToInboxCmd::MoveToInboxCmd(
1250 RoamMenuWindow *window
1251 ) : RoamCmd (name, label, active, window)
1253 _menuwindow = window;
1257 MoveToInboxCmd::doit()
1259 DtMailEnv mail_error;
1261 // Initialize mail_error.
1264 // Get a handle to the Inbox.
1265 char * mail_file = NULL;
1266 DtMailObjectSpace space;
1267 DtMail::Session * d_session = theRoamApp.session()->session();
1269 d_session->queryImpl(mail_error,
1270 d_session->getDefaultImpl(mail_error),
1271 DtMailCapabilityInboxName,
1274 _menuwindow->list()->copySelected(mail_error, mail_file, TRUE, FALSE);
1275 if (mail_error.isSet()) {
1276 // We had an error in moving the messages to the Inbox!
1280 MoveToInboxCmd::~MoveToInboxCmd()
1284 // Copy the selected messages to the Inbox.
1285 CopyToInboxCmd::CopyToInboxCmd(
1289 RoamMenuWindow *window
1290 ) : RoamCmd (name, label, active, window)
1292 _menuwindow = window;
1296 CopyToInboxCmd::doit()
1298 DtMailEnv mail_error;
1300 // Initialize mail_error.
1303 // Get a handle to the Inbox.
1304 char * mail_file = NULL;
1305 DtMailObjectSpace space;
1306 DtMail::Session * d_session = theRoamApp.session()->session();
1308 d_session->queryImpl(mail_error,
1309 d_session->getDefaultImpl(mail_error),
1310 DtMailCapabilityInboxName,
1313 _menuwindow->list()->copySelected(mail_error, mail_file, FALSE, FALSE);
1314 if (mail_error.isSet()) {
1315 // We ad an error in copying the messages to the Inbox!
1319 CopyToInboxCmd::~CopyToInboxCmd()
1324 // This is hooked up the Undelete button in the Deleted
1325 // Messages List dialog box.
1327 DoUndeleteCmd::DoUndeleteCmd(
1331 UndelFromListDialog *undelDialog
1332 ) : Cmd ( name, label, active )
1334 _undelDialog = undelDialog;
1338 DoUndeleteCmd::doit()
1340 // Undelete the selected messages.
1341 _undelDialog->undelSelected();
1345 DoUndeleteCmd::undoit()
1350 DoUndeleteCmd::~DoUndeleteCmd()
1354 // This is hooked up to the Close button in the Deleted Messages
1357 CloseUndelCmd::CloseUndelCmd(
1361 UndelFromListDialog *undelDialog
1362 ) : Cmd ( name, label, active )
1364 _undelDialog = undelDialog;
1368 CloseUndelCmd::doit()
1370 // Close the dialog.
1371 _undelDialog->popped_down();
1375 CloseUndelCmd::undoit()
1381 CloseUndelCmd::~CloseUndelCmd()
1385 UndeleteCmd::UndeleteCmd (
1389 RoamMenuWindow *window,
1390 Boolean viaDeleteList
1391 ) : ChooseCmd ( name, label, active, window )
1393 _menuwindow = window;
1394 _undelFromList = NULL;
1395 _fromList = viaDeleteList;
1398 UndeleteCmd::~UndeleteCmd()
1405 FORCE_SEGV_DECL(MsgStruct, tmpMS);
1406 MsgScrollingList *list = _menuwindow->list();
1407 MsgHndArray *deleted_messages;
1408 DtMailEnv mail_error;
1410 // Initialize the mail_error.
1415 // Create the Deleted Messages Dialog
1417 if (_undelFromList) {
1418 // Hack for user testing. If the dialog is up, we destroy it.
1419 XtDestroyWidget(_undelFromList->baseWidget());
1421 // if (!_undelFromList) {
1422 _undelFromList = new UndelFromListDialog(
1423 GETMSG(DT_catd, 1, 227, "Mailer - Deleted Messages"),
1425 _undelFromList->initialize();
1427 // Check for existing list of deleted messages
1428 _num_deleted = list->get_num_deleted_messages();
1430 // If there are deleted messages, put them in the Deleted
1433 if (_num_deleted > 0) {
1434 deleted_messages = list->get_deleted_messages();
1435 _undelFromList->loadMsgs(
1439 if (mail_error.isSet()) {
1440 // Post an exception here!
1441 _menuwindow->postErrorDialog(mail_error);
1445 // Display the dialog
1447 _undelFromList->popped_up();
1449 // Although we don't display the Deleted Message Dialog here, we
1450 // need to make sure that it gets updated for the next time
1452 list->undelete_last_deleted();
1458 SaveCmd::SaveCmd ( char *name,
1461 RoamMenuWindow *window
1462 ) : RoamCmd ( name, label, active, window )
1471 assert(_menuwindow->mailbox() != NULL);
1473 #endif /* DEAD_WOOD */
1477 MoveCopyCmd::MoveCopyCmd( char *name,
1480 FileCallback move_callback,
1481 FileCallback copy_callback,
1482 RoamMenuWindow * menu_window,
1484 DtMailBoolean only_show_mailboxes)
1485 : UnifiedSelectMailboxCmd(name,
1487 GETMSG(DT_catd, 1, 89, "Mailer - Other Mailboxes"),
1493 only_show_mailboxes)
1495 _copy_callback = copy_callback;
1496 _menuwindow = menu_window;
1497 _copy_button = NULL;
1498 _move_button = NULL;
1501 MoveCopyCmd::~MoveCopyCmd()
1506 MoveCopyCmd::setDefault(Widget button)
1510 _default_button = button;
1511 XtSetArg( args[0], XmNdefaultButton, _default_button );
1512 XtSetValues( _fileBrowser, args, 1 );
1519 Widget filter_button;
1520 Widget unused_button;
1524 if (!_fileBrowser) {
1525 UnifiedSelectMailboxCmd::doit();
1526 // Customize buttons for MoveCopy dialog
1527 move = XmStringCreateLocalized(GETMSG(DT_catd, 1, 90, "Move"));
1529 filter_button = XtNameToWidget(_fileBrowser, "*Apply");
1530 _move_button = XtNameToWidget(_fileBrowser, "*OK");
1531 action_area = XtParent(_move_button);
1532 unused_button = XtVaCreateWidget(
1534 xmPushButtonWidgetClass, _fileBrowser,
1536 _copy_button = XtVaCreateManagedWidget(
1537 GETMSG(DT_catd, 1, 237, "Copy"),
1538 /*xmPushButtonWidgetClass, _fileBrowser,*/
1539 xmPushButtonGadgetClass, _fileBrowser,
1541 XmStringCreateLocalized(GETMSG(DT_catd, 1, 43, "Copy")),
1543 printHelpId("Copy", _copy_button);
1545 // add help callback
1546 // XtAddCallback(_copy_button, XmNhelpCallback, HelpCB, helpId);
1552 (void *)"dtmailViewmainWindowWork-AreapanedWform2RowColumnMoveCopy");
1555 XmNactivateCallback,
1556 &MoveCopyCmd::fileSelectedCallback2,
1559 if (_menuwindow->mailbox()->mailBoxWritable(error) == DTM_FALSE)
1560 XtUnmanageChild(_move_button);
1562 XtManageChild(_move_button);
1564 // XtVaSetValues(_move_button, XmNsensitive, FALSE);
1566 _file_list = XtNameToWidget(_fileBrowser, "*ItemsList");
1569 XmNbrowseSelectionCallback, &MoveCopyCmd::setDefaultButtonCB,
1573 XmNextendedSelectionCallback, &MoveCopyCmd::setDefaultButtonCB,
1577 XmNmultipleSelectionCallback, &MoveCopyCmd::setDefaultButtonCB,
1581 XmNsingleSelectionCallback, &MoveCopyCmd::setDefaultButtonCB,
1584 _file_text = XtNameToWidget(_fileBrowser, "*Text");
1585 if (NULL != _file_text)
1588 XmNfocusCallback, &MoveCopyCmd::setDefaultButtonCB,
1594 UnifiedSelectMailboxCmd::doit();
1600 MoveCopyCmd::fileSelectedCallback2 (
1602 XtPointer clientData,
1606 MoveCopyCmd *obj = (MoveCopyCmd *) clientData;
1607 XmFileSelectionBoxCallbackStruct *cb =
1608 (XmFileSelectionBoxCallbackStruct *) callData;
1610 char *dir_str = NULL;
1616 static char selected[MAXPATHLEN+1];
1618 // Bring the file selection dialog down.
1619 XtUnmanageChild ( obj->_fileBrowser );
1622 // Get the file name
1624 XtVaGetValues(obj->_fileBrowser, XmNdirectory, &xmstr, NULL);
1626 dname = (char*) _XmStringUngenerate(
1628 XmMULTIBYTE_TEXT, XmMULTIBYTE_TEXT);
1631 // Get the file name
1633 XtVaGetValues(obj->_fileBrowser, XmNdirSpec, &xmstr, NULL);
1636 // Extract the first character string matching the default
1637 // character set from the compound string
1638 fname = (char *) _XmStringUngenerate(
1640 XmMULTIBYTE_TEXT, XmMULTIBYTE_TEXT);
1642 if (NULL == fname || strlen(fname) == 0)
1645 // If a string was successfully extracted, call
1646 // unifiedMailboxSelected to handle the file.
1648 if (NULL != dname) strcat(selected, dname);
1649 strcat(selected, fname);
1650 obj->updateUnifiedData();
1651 obj->unifiedMailboxSelected(
1652 obj->_copy_callback,
1659 MoveCopyCmd::setDefaultButtonCB(
1661 XtPointer clientData,
1664 MoveCopyCmd *thisCmd = (MoveCopyCmd *) clientData;
1665 thisCmd->setDefault(thisCmd->_default_button);
1669 CopyCmd::CopyCmd( char *name,
1672 RoamMenuWindow *window,
1673 MoveCopyCmd *move_copy_cmd
1674 ) : RoamCmd ( name, label, active, window )
1676 _move_copy_cmd = move_copy_cmd;
1686 _move_copy_cmd->doit();
1687 _move_copy_cmd->setDefault(_move_copy_cmd->getCopyButton());
1691 MoveCmd::MoveCmd( char *name,
1694 RoamMenuWindow *window,
1695 MoveCopyCmd *move_copy_cmd
1696 ) : RoamCmd ( name, label, active, window )
1698 _move_copy_cmd = move_copy_cmd;
1708 _move_copy_cmd->doit();
1709 _move_copy_cmd->setDefault(_move_copy_cmd->getMoveButton());
1717 RoamMenuWindow *window
1718 ) : RoamCmd ( name, label, active, window )
1725 _menuwindow->list()->select_next_item();
1733 RoamMenuWindow *window
1734 ) : RoamCmd ( name, label, active, window )
1741 _menuwindow->list()->select_prev_item();
1745 MessagesCmd::MessagesCmd(
1749 RoamMenuWindow *window
1750 ) : RoamCmd ( name, label, active, window )
1758 Boolean old=_menuwindow->fullHeader();
1759 MsgScrollingList *list=_menuwindow->list();
1761 ( !strcmp( this->name(), "Full Header" ) ? _menuwindow->fullHeader( True ) : _menuwindow->fullHeader( False ) );
1763 if ( old!=_menuwindow->fullHeader() && _menuwindow->msgView() ) {
1764 // list->chooseCurrent();
1768 #endif /* DEAD_WOOD */
1770 PrintCmd::PrintCmd (
1775 RoamMenuWindow *window
1776 ) : ChooseCmd ( name, label, active, window ), _tmp_files(5)
1785 // The entire implementation of print was broken. It has
1786 // be removed until a proper implementation can be provided.
1795 DtActionInvocationID id,
1796 XtPointer clientData,
1805 case DtACTION_INVOKED:
1808 data = (PrintCmd *)clientData;
1809 data->_parent->message("");
1810 data->_unregister_tmp_file(id);
1818 PrintCmd::printjobcb( Widget w, XtPointer client_data, XtPointer )
1820 char *filename = (char *) client_data;
1822 XtRemoveCallback(w, XtNdestroyCallback, &PrintCmd::printjobcb, filename);
1829 PrintCmd::printit( int silent )
1832 char *silent_str = "DTPRINTSILENT";
1833 char *tmpdir = new char[MAXPATHLEN+1];
1834 DtMailEnv mail_error;
1835 MsgScrollingList *list;
1837 DebugPrintf(1, "%s: printit\n", name());
1840 sprintf(tmpdir, "%s/%s", getenv("HOME"), DtPERSONAL_TMP_DIRECTORY);
1841 if ((p = tempnam(tmpdir, "dtmail")) == NULL) {
1848 list = _parent->list();
1850 // Copy selected messages to a temp file
1851 int status = list->copySelected(mail_error, p, FALSE, TRUE);
1852 if (mail_error.isSet())
1854 _parent->postErrorDialog(mail_error);
1858 if (0 != status) return;
1861 DmxPrintJob *pjob = new DmxPrintJob(p,
1862 (silent ? DTM_TRUE : DTM_FALSE),
1865 XtAddCallback(pjob->baseWidget(),
1867 &PrintCmd::printjobcb,
1868 (XtPointer) strdup(p));
1876 PrintCmd::_register_tmp_file(
1878 DtActionInvocationID id
1883 // Allocate struct to hold id and temp file
1884 if ((f = (struct tmp_file *)malloc(sizeof(struct tmp_file))) == NULL) {
1888 // Save file name and action id
1889 f->file = strdup(name);
1892 // Add to list of temp files
1893 _tmp_files.append(f);
1899 PrintCmd::_unregister_tmp_file(
1900 DtActionInvocationID id
1906 // Find the temp file that was used by the Action specified by id
1907 for (n = _tmp_files.length() - 1; n >= 0; n--) {
1910 // Found the file. Unlink and free data structs
1914 // Remove entry from list
1915 _tmp_files.remove(n);
1924 PopupCmd::PopupCmd (
1928 PopupWindow * (RoamMenuWindow::* member) (void),
1929 RoamMenuWindow *myparent
1930 ) : NoUndoCmd ( name, label, active )
1939 PopupWindow *popup=(parent->*pmpopup)();
1942 #endif /* DEAD_WOOD */
1944 // OnItemCmd brings up the Help On Item help.
1945 OnItemCmd::OnItemCmd ( char * name,
1948 UIComponent *window )
1949 : NoUndoCmd (name, label, active)
1957 int status = DtHELP_SELECT_ERROR;
1958 Widget widget = _parent->baseWidget();
1959 Widget selWidget = NULL;
1961 // Display the appropriate help information for the selected item.
1963 status = DtHelpReturnSelectedWidgetId(widget, 0, &selWidget);
1965 switch ((int) status) {
1966 case DtHELP_SELECT_ERROR:
1967 printf("Selection Error, cannot continue\n");
1969 case DtHELP_SELECT_VALID:
1970 while (selWidget != NULL) {
1971 if ((XtHasCallbacks(selWidget, XmNhelpCallback)
1972 == XtCallbackHasSome)) {
1973 XtCallCallbacks((Widget) selWidget, XmNhelpCallback, NULL);
1976 selWidget = XtParent(selWidget);
1980 case DtHELP_SELECT_ABORT:
1981 printf("Selection Aborted by user.\n");
1983 case DtHELP_SELECT_INVALID:
1984 printf("You must select a component within your app.\n");
1993 OnAppCmd::OnAppCmd ( char * name,
1996 UIComponent *window )
1997 : NoUndoCmd (name, label, active)
2005 DisplayMain (_parent->baseWidget(), "Mailer", DTMAILWINDOWID);
2008 TasksCmd::TasksCmd ( char * name,
2011 UIComponent *window )
2012 : NoUndoCmd (name, label, active)
2020 DisplayMain (_parent->baseWidget(), "Mailer", HELP_MAILER_TASKS);
2023 ReferenceCmd::ReferenceCmd ( char * name,
2026 UIComponent *window )
2027 : NoUndoCmd (name, label, active)
2033 ReferenceCmd::doit()
2035 DisplayMain (_parent->baseWidget(), "Mailer", HELP_MAILER_REFERENCE);
2038 UsingHelpCmd::UsingHelpCmd ( char * name,
2041 UIComponent *window )
2042 : NoUndoCmd (name, label, active)
2048 UsingHelpCmd::doit()
2050 DisplayMain (_parent->baseWidget(), "Help4Help", "_HOMETOPIC");
2053 RelNoteCmd::RelNoteCmd ( char * name,
2057 ) : NoUndoCmd (name, label, active )
2069 // _genDialog = new DtMailGenDialog("AboutBox", _parent->baseWidget());
2071 // _genDialog->setToAboutDialog();
2072 // answer = _genDialog->post_and_return(GETMSG(DT_catd, 1, 92, "OK"), NULL);
2074 DisplayMain(_parent->baseWidget(), "Mailer", "_copyright");
2077 RelNoteCmd::~RelNoteCmd()
2083 ClearCmd::ClearCmd (
2087 RoamMenuWindow *window
2088 ) : NoUndoCmd (name, label, active )
2096 // ((FindPopup *) parent->find_popup())->clear_text_values();
2099 StartCmd::StartCmd( char *name,
2101 int active ) : Cmd ( name, label, active )
2108 char *forward= ".forward";
2111 GetPasswordEntry(pwd);
2113 char *forward_filename=new char[strlen(pwd.pw_dir)+1+strlen(forward)+1];
2114 sprintf( forward_filename, "%s/%s", pwd.pw_dir, forward );
2124 ChangeCmd::ChangeCmd(
2128 ) : Cmd (name, label, active )
2136 GetPasswordEntry(pwd);
2138 char *user_name=new char[strlen(pwd.pw_name)+1];
2139 strcpy(user_name,pwd.pw_name);
2154 RoamMenuWindow *window
2155 ) : Cmd (name, label, active )
2163 unlink( parent->forwardFilename() );
2164 parent->title( NULL );
2173 #endif /* DEAD_WOOD */
2181 SendMsgDialog *parent,
2183 : NoUndoCmd( name, label, active )
2186 _default_trans = trans_type;
2192 if (!_parent->isMsgValid())
2195 _parent->send_message( this->name(), _default_trans );
2198 // JT - Added methods below
2200 OpenMsgCmd::OpenMsgCmd(
2204 RoamMenuWindow *window)
2205 : RoamCmd (name, label, active, window)
2212 DtMailEnv mail_error;
2214 // Initialize the mail_error.
2217 _menuwindow->list()->viewInSeparateWindow(mail_error);
2218 if (mail_error.isSet()) {
2219 _menuwindow->postErrorDialog(mail_error);
2224 // Attachment Cmds stuff
2226 SaveAttachCmd::SaveAttachCmd ( char *name,
2230 FileCallback save_callback,
2231 RoamMenuWindow *clientData,
2233 :UnifiedSelectFileCmd (name,
2236 GETMSG(DT_catd, 1, 93, "Save"),
2242 _parent = clientData;
2245 SaveAttachCmd::SaveAttachCmd (
2250 FileCallback save_callback,
2251 ViewMsgDialog *clientData,
2254 :UnifiedSelectFileCmd (name,
2257 GETMSG(DT_catd, 1, 93, "Save"),
2263 _parent = clientData;
2266 SaveAttachCmd::SaveAttachCmd (
2271 FileCallback save_callback,
2272 SendMsgDialog *clientData,
2275 :UnifiedSelectFileCmd (name,
2278 GETMSG(DT_catd, 1, 93, "Save"),
2284 _parent = clientData;
2288 SaveAttachCmd::doit()
2290 UnifiedSelectFileCmd::doit();
2292 DtMailEditor *editor = _parent->get_editor();
2293 AttachArea *aa = editor->attachArea();
2294 XmString attachmentName = aa->getSelectedAttachName();
2295 XtVaSetValues(_fileBrowser, XmNtextString, attachmentName, NULL);
2296 XtAddCallback ( _fileBrowser, XmNapplyCallback,
2297 &SaveAttachCmd::updateCallback,
2300 _name = XmStringCopy(attachmentName);
2301 XmStringFree(attachmentName);
2304 // Attachment Cmds stuff
2307 void SaveAttachCmd::updateCallback(Widget, XtPointer clientData, XtPointer )
2309 SaveAttachCmd *obj = (SaveAttachCmd *)clientData;
2311 XtVaSetValues(obj->_fileBrowser, XmNtextString, obj->_name, NULL);
2314 SaveAsTextCmd::SaveAsTextCmd (
2320 RoamMenuWindow *parent_roam_menu_window,
2323 :UnifiedSelectFileCmd (name,
2326 GETMSG(DT_catd, 1, 95, "Save"),
2332 _text_editor = editor;
2333 _roam_menu_window = parent_roam_menu_window;
2336 SaveAsTextCmd::SaveAsTextCmd (
2345 :UnifiedSelectFileCmd (name,
2348 GETMSG(DT_catd, 1, 95, "Save"),
2354 _text_editor = editor;
2355 _roam_menu_window = NULL;
2359 SaveAsTextCmd::fileCB(void * client_data, char * selection)
2361 SaveAsTextCmd * self = (SaveAsTextCmd *)client_data;
2362 self->saveText(selection);
2366 SaveAsTextCmd::saveText(const char * filename)
2369 char *buf = new char[2048];
2372 // Is it already there?
2373 status = SafeAccess(filename, F_OK);
2377 GETMSG(DT_catd, 3, 47, "%s already exists.\nOverwrite?"),
2380 _genDialog->setToQuestionDialog(GETMSG(DT_catd, 3, 48, "Mailer"), buf);
2381 helpId = DTMAILHELPERROR;
2382 answer = _genDialog->post_and_return(helpId);
2388 if (unlink(filename) < 0)
2391 GETMSG(DT_catd, 3, 49, "Unable to overwrite %s.\n\
2392 Check file permissions and retry."),
2394 _genDialog->setToErrorDialog(GETMSG(DT_catd, 3, 50, "Mailer"), buf);
2395 helpId = DTMAILHELPNOOVERWRITE;
2396 _genDialog->post_and_return(helpId);
2402 // Create or truncate, and then write the bits.
2403 int fd = SafeOpen(filename, O_RDWR | O_CREAT | O_TRUNC, 0600);
2406 sprintf(buf, GETMSG(DT_catd, 3, 51, "Unable to create %s."), filename);
2407 _genDialog->setToErrorDialog(GETMSG(DT_catd, 3, 52, "Mailer"), buf);
2408 helpId = DTMAILHELPNOCREATE;
2409 _genDialog->post_and_return(helpId);
2414 if (SafeWrite(fd, "\n", 1) < 1)
2417 GETMSG(DT_catd, 3, 53, "Unable to write to %s."),
2419 _genDialog->setToErrorDialog(GETMSG(DT_catd, 3, 54, "Mailer"), buf);
2420 helpId = DTMAILHELPNOWRITE;
2421 _genDialog->post_and_return(helpId);
2428 if (NULL == _roam_menu_window)
2430 char *text_buf = _text_editor->get_contents();
2431 writeText((XtPointer) (intptr_t) fd, text_buf);
2432 XtFree((char*) text_buf);
2435 writeTextFromScrolledList(fd);
2442 SaveAsTextCmd::writeTextFromScrolledList(int fd)
2444 static char buf[2048];
2447 DtMailEnv mail_error;
2448 MsgScrollingList *list;
2449 DmxMailbox *mailbox;
2453 // Create temp file.
2455 char *tmpdir = new char[MAXPATHLEN+1];
2456 sprintf(tmpdir, "%s/%s", getenv("HOME"), DtPERSONAL_TMP_DIRECTORY);
2457 if ((tmppath = tempnam(tmpdir, "dtmail")) == NULL) {
2458 sprintf(buf, GETMSG(DT_catd, 3, 51, "Unable to create %s."), tmpdir);
2459 _genDialog->setToErrorDialog(GETMSG(DT_catd, 3, 52, "Mailer"), buf);
2460 helpId = DTMAILHELPNOCREATE;
2461 _genDialog->post_and_return(helpId);
2468 list = _roam_menu_window->list();
2471 // Copy the selected messages to a temp file.
2473 int status = list->copySelected(mail_error, tmppath, FALSE, TRUE);
2474 if (mail_error.isSet()) {
2475 _roam_menu_window->postErrorDialog(mail_error);
2479 if (0 != status) return;
2481 mailbox = new DmxMailbox(tmppath);
2482 mailbox->loadMessages();
2483 next_msg = mailbox->firstMessage();
2486 DmxPrintHeadersEnum visible_headers;
2488 if (_roam_menu_window->fullHeader())
2489 visible_headers = DMX_PRINT_HEADERS_ALL;
2491 visible_headers = DMX_PRINT_HEADERS_ABBREV;
2495 &SaveAsTextCmd::writeText,
2496 (XtPointer) (intptr_t) fd);
2497 writeText((XtPointer) (intptr_t) fd, "\n\n");
2498 } while ((next_msg = mailbox->nextMessage()) != (DmxMsg *) NULL);
2502 // Clean up the temporary file.
2509 SaveAsTextCmd::writeText(XtPointer filedes, char *text_buf)
2511 long fdl = (long) filedes;
2513 int len = strlen(text_buf);
2515 if (SafeWrite(fd, text_buf, len) < len) {
2522 GETMSG(DT_catd, 3, 53, "Unable to write to %s."),
2524 helpId = DTMAILHELPNOWRITE;
2525 _genDialog->setToErrorDialog(GETMSG(DT_catd, 3, 56, "Mailer"), buf);
2526 _genDialog->post_and_return(helpId);
2532 SaveAsTextCmd::doit()
2534 MsgScrollingList *list;
2536 int *pos_list = NULL;
2539 if (_roam_menu_window &&
2540 (list = _roam_menu_window->list()) &&
2541 (listW = list->get_scrolling_list()))
2543 if (!XmListGetSelectedPos(listW, &pos_list, &pos_count))
2548 DtMailGenDialog *dialog = _roam_menu_window->genDialog();
2550 dialog->setToErrorDialog(
2551 GETMSG(DT_catd, 3, 50, "Mailer"),
2552 GETMSG(DT_catd, 2, 16, "No message selected."));
2553 dialog->post_and_return(NULL);
2559 UnifiedSelectFileCmd::doit();
2563 int pos_selected, last_space;
2565 DtMailHeaderLine header;
2566 DtMailMessageHandle msg_handle;
2567 DtMailHeaderRequest request;
2568 DtMail::MailBox *mbox;
2570 pos_selected = list->get_selected_item();
2571 msg_handle = list->msgno(pos_selected);
2573 request.number_of_names = 1;
2574 request.header_name = (char**) malloc(sizeof(char*));
2575 request.header_name[0] = strdup(DtMailMessageSubject);
2577 mbox = _roam_menu_window->mailbox();
2578 mbox->getMessageSummary(error, msg_handle, request, header);
2580 if (0 != header.header_values[0].length())
2582 const char *orig_subject = *((header.header_values[0])[0]);
2584 int orig_len = strlen(orig_subject);
2585 char *subject = (char*) malloc(orig_len + 1);
2588 for (i=0,j=0,last_space=0; i<orig_len; i++)
2590 if (isspace(orig_subject[i]))
2592 if (last_space < i-1)
2597 else if (orig_subject[i] == '/')
2598 subject[j++] = '\\';
2600 subject[j++] = orig_subject[i];
2604 xms = XmStringCreateLocalized(subject);
2605 XtVaSetValues(_fileBrowser, XmNtextString, xms, NULL);
2611 if (NULL != request.header_name)
2613 if (NULL != request.header_name[0])
2614 free(request.header_name[0]);
2615 free(request.header_name);
2618 mbox->clearMessageSummary(header);
2623 DeleteAttachCmd::DeleteAttachCmd(
2629 ) : Cmd ( name, label, active )
2635 DeleteAttachCmd::doit()
2637 _parent->delete_selected_attachments();
2641 DeleteAttachCmd::undoit()
2645 UndeleteAttachCmd::UndeleteAttachCmd(
2651 ) : Cmd ( name, label, active )
2657 UndeleteAttachCmd::doit()
2659 _parent->undelete_last_deleted_attachment();
2664 UndeleteAttachCmd::undoit()
2668 RenameAttachCmd::RenameAttachCmd (
2673 ) : Cmd ( name, label, active )
2675 Widget renameDialog;
2679 renameDialog = XmCreatePromptDialog(
2686 message = XmStringCreateLocalized(GETMSG(DT_catd, 1, 96, "Empty"));
2687 XtVaSetValues(renameDialog, XmNselectionLabelString, message, NULL);
2688 XmStringFree(message);
2689 XmString ok_str = XmStringCreateLocalized(GETMSG(DT_catd, 1, 97, "Rename"));
2690 XtVaSetValues(XtParent(renameDialog),
2691 XmNtitle, GETMSG(DT_catd, 1, 98, "Mailer - Rename"),
2693 XtVaSetValues(renameDialog,
2694 XmNokLabelString, ok_str,
2697 XmStringFree(ok_str);
2698 XtUnmanageChild(XmSelectionBoxGetChild(renameDialog, XmDIALOG_HELP_BUTTON));
2700 _parent->get_editor()->attachArea()->setRenameDialog(renameDialog);
2701 XtAddCallback(renameDialog, XmNcancelCallback,
2702 &RenameAttachCmd::cancelCallback,
2704 XtAddCallback(renameDialog, XmNokCallback,
2705 &RenameAttachCmd::okCallback,
2709 void RenameAttachCmd::doit()
2711 Widget renameDialog;
2712 XmString oldAttachName = NULL;
2717 if (!_parent->renameAttachmentOK()) {
2721 aa = _parent->get_editor()->attachArea();
2723 oldAttachName = aa->getSelectedAttachName();
2725 if (oldAttachName == NULL) return;
2727 renameDialog = aa->getRenameDialog();
2729 sprintf(buf, "%s", GETMSG(DT_catd, 3, 57, "Rename attachment as"));
2731 message = XmStringCreateLocalized(buf);
2733 XtVaSetValues(renameDialog,
2734 XmNselectionLabelString, message,
2735 XmNtextString, oldAttachName,
2739 XmStringFree(message);
2740 XmStringFree(oldAttachName);
2742 XtManageChild(renameDialog);
2743 XtPopup(XtParent(renameDialog), XtGrabNone);
2746 void RenameAttachCmd::undoit()
2748 // Just print a message that allows us to trace the execution
2752 void RenameAttachCmd::cancelCallback (
2754 XtPointer clientData,
2758 RenameAttachCmd *obj = (RenameAttachCmd *) clientData;
2760 obj->cancel( callData );
2763 void RenameAttachCmd::cancel( XtPointer )
2767 aa = _parent->get_editor()->attachArea();
2769 Widget renameDialog = aa->getRenameDialog();
2771 XtUnmanageChild(renameDialog);
2774 void RenameAttachCmd::okCallback (
2776 XtPointer clientData,
2780 RenameAttachCmd *obj = (RenameAttachCmd *) clientData;
2781 obj->ok( callData );
2784 void RenameAttachCmd::ok( XtPointer callData )
2786 XmSelectionBoxCallbackStruct *cbs =
2787 (XmSelectionBoxCallbackStruct *)callData;
2790 aa = _parent->get_editor()->attachArea();
2792 Widget renameDialog = aa->getRenameDialog();
2794 XtUnmanageChild(renameDialog);
2796 aa->setSelectedAttachName(cbs->value);
2800 AttachmentActionCmd::AttachmentActionCmd(
2803 RoamMenuWindow *rmw,
2805 ) : Cmd (name, label, TRUE)
2812 AttachmentActionCmd::AttachmentActionCmd(
2817 ) : Cmd (name, label, TRUE)
2824 AttachmentActionCmd::AttachmentActionCmd(
2829 ) : Cmd (name, label, TRUE)
2838 AttachmentActionCmd::doit()
2840 _parent->invokeAttachmentAction(_index);
2844 AttachmentActionCmd::undoit()
2848 SelectAllAttachsCmd::SelectAllAttachsCmd(
2852 ) : Cmd(name, label, TRUE)
2857 SelectAllAttachsCmd::SelectAllAttachsCmd(
2861 ) : Cmd(name, label, TRUE)
2866 SelectAllAttachsCmd::SelectAllAttachsCmd(
2870 ) : Cmd(name, label, FALSE)
2876 SelectAllAttachsCmd::doit()
2878 _parent->selectAllAttachments();
2882 SelectAllAttachsCmd::undoit()
2887 ShowAttachPaneCmd::ShowAttachPaneCmd(
2890 AbstractEditorParent *aep
2891 ) : ToggleButtonCmd(name, label, TRUE)
2897 ShowAttachPaneCmd::doit()
2900 if (!this->getButtonState()) {
2901 _parent->hideAttachArea();
2903 else { // button is ON
2904 _parent->showAttachArea();
2909 ShowAttachPaneCmd::undoit()
2914 AbbrevHeadersCmd::AbbrevHeadersCmd(
2918 ) : ToggleButtonCmd(name, label, TRUE)
2924 AbbrevHeadersCmd::doit()
2927 if (!this->getButtonState()) {
2928 _parent->fullHeader(TRUE);
2930 else { // button is ON
2931 _parent->fullHeader(FALSE);
2936 AbbrevHeadersCmd::undoit()
2947 : NoUndoCmd(name, label, active)
2949 _compose_dialog = s;
2956 // Call the goAway() method on the SMD. Argument TRUE requests it
2957 // to check if the SMD is dirty. Let it handle the
2958 // case where text may be present in the compose window.
2959 if (!_compose_dialog->isMsgValid())
2962 _compose_dialog->goAway(TRUE);
2966 EditUndoCmd::EditUndoCmd(
2970 AbstractEditorParent *w )
2971 : NoUndoCmd( name, label, active )
2973 editor = w->get_editor()->textEditor();
2979 editor->undo_edit();
2982 EditCutCmd::EditCutCmd(
2986 AbstractEditorParent *w
2988 : NoUndoCmd( name, label, active )
2990 editor = w->get_editor()->textEditor();
2992 // className() is a virtual method
2993 if (w->className() == "SendMsgDialog") {
2994 _compose_dialog = (SendMsgDialog *)w;
2997 _compose_dialog = NULL;
3004 editor->cut_selection();
3006 if (_compose_dialog) {
3008 _compose_dialog->activate_edit_paste();
3009 _compose_dialog->activate_edit_paste_indented();
3010 _compose_dialog->activate_edit_paste_bracketed();
3014 EditCopyCmd::EditCopyCmd(
3018 AbstractEditorParent *w )
3019 : NoUndoCmd( name, label, active )
3021 editor = w->get_editor()->textEditor();
3023 // className() is a virtual method
3024 if (w->className() == "SendMsgDialog") {
3025 _compose_dialog = (SendMsgDialog *)w;
3028 _compose_dialog = NULL;
3035 editor->copy_selection();
3036 if (_compose_dialog) {
3038 _compose_dialog->activate_edit_paste();
3039 _compose_dialog->activate_edit_paste_indented();
3040 _compose_dialog->activate_edit_paste_bracketed();
3044 EditPasteCmd::EditPasteCmd(
3048 AbstractEditorParent *w )
3049 : NoUndoCmd( name, label, active )
3051 editor = w->get_editor()->textEditor();
3055 EditPasteCmd::doit()
3057 editor->paste_from_clipboard();
3060 EditPasteSpecialCmd::EditPasteSpecialCmd(
3064 AbstractEditorParent *w,
3065 Editor::InsertFormat format)
3066 : NoUndoCmd( name, label, active )
3068 editor = w->get_editor()->textEditor();
3069 insert_format = format;
3073 EditPasteSpecialCmd::doit()
3075 editor->paste_special_from_clipboard(insert_format);
3079 EditClearCmd::EditClearCmd(
3083 AbstractEditorParent *w )
3084 : NoUndoCmd( name, label, active )
3086 editor = w->get_editor()->textEditor();
3087 // this->deactivate();
3091 EditClearCmd::doit()
3093 editor->clear_selection();
3095 // _edit_paste->activate();
3098 EditDeleteCmd::EditDeleteCmd(
3102 AbstractEditorParent *w )
3103 : NoUndoCmd( name, label, active )
3105 editor = w->get_editor()->textEditor();
3106 // this->deactivate();
3110 EditDeleteCmd::doit()
3112 editor->delete_selection();
3114 // _edit_paste->deactivate();
3117 EditSelectAllCmd::EditSelectAllCmd(
3121 AbstractEditorParent *w )
3122 : NoUndoCmd( name, label, active )
3124 editor = w->get_editor()->textEditor();
3128 EditSelectAllCmd::doit()
3130 editor->select_all();
3135 WordWrapCmd::WordWrapCmd(
3139 AbstractEditorParent *w
3140 ) : ToggleButtonCmd( name, label, active )
3142 editor = w->get_editor()->textEditor();
3144 * allow the app-defaults setting for WordWrap
3147 Widget _w = editor->get_text_widget();
3150 XtSetArg( args[0], XmNwordWrap, &cur_setting );
3151 XtGetValues( _w, args, 1 );
3152 editor->set_word_wrap(cur_setting);
3158 cur_setting = ((ToggleButtonCmd *)this)->getButtonState();
3159 editor->set_word_wrap(cur_setting);
3163 WordWrapCmd::wordWrap()
3165 return(cur_setting);
3168 FindChangeCmd::FindChangeCmd(
3172 AbstractEditorParent *w )
3173 : NoUndoCmd( name, label, active )
3175 editor = w->get_editor()->textEditor();
3179 FindChangeCmd::doit()
3181 editor->find_change();
3188 AbstractEditorParent *w )
3189 : NoUndoCmd( name, label, active )
3191 editor = w->get_editor()->textEditor();
3205 : NoUndoCmd (name, label, active)
3208 _alias = strdup(name);
3216 XtVaGetValues(_header, XmNvalue, &value, NULL);
3220 char *newvalue = (char *) malloc(strlen(value) + strlen(_alias) + 3);
3221 sprintf(newvalue, "%s, %s", value, _alias);
3222 XtVaSetValues(_header, XmNvalue, newvalue, NULL);
3226 XtVaSetValues(_header, XmNvalue, _alias, NULL);
3231 AliasCmd::~AliasCmd()
3233 free((void*) _alias);
3237 OtherAliasesCmd::OtherAliasesCmd(
3241 : NoUndoCmd (name, label, active)
3246 OtherAliasesCmd::doit()
3248 OptCmd *optCmd = (OptCmd *) theRoamApp.mailOptions();
3249 optCmd->displayAliasesOptionsPane();
3252 OtherAliasesCmd::~OtherAliasesCmd()
3257 FormatCmd::FormatCmd(
3261 AbstractEditorParent *w )
3262 : NoUndoCmd( name, label, active )
3264 editor = w->get_editor()->textEditor();
3273 LogMsgCmd::LogMsgCmd(
3277 SendMsgDialog * send
3278 ) : ToggleButtonCmd( name, label, active )
3280 // Go to props and find out the default, ie. to log or not to log.
3281 // But for now, just look in .mailrc to see if "record" is set.
3284 const char *logfile = NULL;
3293 if (!((ToggleButtonCmd *)this)->getButtonState()) {
3294 // turn off logging for this message
3295 _send->setLogState(DTM_FALSE);
3298 // turn on logging for this message
3299 _send->setLogState(DTM_TRUE);
3305 VacationCmd::VacationCmd(
3308 ) : Cmd (name, label, TRUE)
3311 _forwardFile = ".forward";
3312 _backupSuffix = "..BACKUP";
3318 // Check if a .forward file exists.
3320 _priorVacationRunning = this->priorVacationRunning();
3322 // parse the .vacation.msg file and retain the subject
3324 // They need to be retrieved for display in the dialog.
3326 this->parseVacationMessage();
3330 VacationCmd::~VacationCmd()
3332 if (NULL != _subject)
3333 free((void*) _subject);
3344 static unsigned long
3345 writeToFileDesc(const char * buf, int len, va_list args)
3347 int fd = va_arg(args, int);
3348 int cnt = va_arg(args, int);
3352 status = SafeWrite(fd, buf, len);
3353 } while (status < 0 && errno == EAGAIN);
3359 VacationCmd::startVacation(
3364 int i = this->handleMessageFile(subj, text);
3366 i = this->handleForwardFile();
3373 VacationCmd::stopVacation()
3375 char *forwardfile = new char[MAXPATHLEN+1];
3377 sprintf(forwardfile, "%s/%s", getenv("HOME"), _forwardFile);
3379 // Remove the current .forward file (it has vacation in it)
3380 // Recover and replace the original backup forward file, if
3383 unlink(forwardfile);
3385 this->recoverForwardFile(forwardfile);
3386 delete [] forwardfile;
3390 VacationCmd::priorVacationRunning()
3395 Boolean retval = FALSE;
3396 char *forwardfile = new char[MAXPATHLEN+1];
3398 sprintf(forwardfile, "%s/%s", getenv("HOME"), _forwardFile);
3400 if (SafeAccess(forwardfile, F_OK) != 0) {
3401 delete [] forwardfile;
3405 fd = SafeOpen(forwardfile, O_RDONLY);
3407 buf[sizeof buf -1] = '\0';
3409 while ((len = SafeRead(fd, buf, (sizeof buf) - 1)) > 0) {
3411 if ((strstr(buf, "/usr/bin/vacation")) ||
3412 (strstr(buf, "/usr/ucb/vacation"))) {
3420 delete [] forwardfile;
3425 VacationCmd::handleForwardFile()
3435 Boolean forwardExists;
3436 DtMailGenDialog *dialog;
3438 int error_bufLen = 10000;
3439 char *error_buf = new char[error_bufLen];
3440 char *forwardfile = new char[MAXPATHLEN+1];
3441 char *messagefile = new char[256];
3442 char *buf = new char[2048];
3444 // initialize the error_buf
3445 memset(error_buf, 0, error_bufLen);
3446 memset(buf, 0, 2048);
3450 forwardExists = FALSE;
3453 GetPasswordEntry(pw);
3455 sprintf(forwardfile, "%s/%s", pw.pw_dir, _forwardFile);
3457 if (SafeAccess(forwardfile, F_OK) == 0 ) {
3458 forwardExists = TRUE;
3461 forwardExists = FALSE;
3464 if (forwardExists && !_priorVacationRunning) {
3466 /* STRING_EXTRACTION -
3468 * This confirmation window is brought up when the user
3469 * tries to update the vacation status when the user is
3470 * already using a .forward file.
3472 if (NULL != _dialog)
3475 dialog = theRoamApp.genDialog();
3477 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"));
3479 dialog->setToQuestionDialog(GETMSG(DT_catd, 1, 103, "Mailer"),
3482 helpId = DTMAILHELPOKSTARTVACATION;
3483 answer = dialog->post_and_return(helpId);
3485 if (answer == 2) {// Cancel chosen
3487 delete [] messagefile;
3488 delete [] error_buf;
3489 delete [] forwardfile;
3493 if (this->backupFile(forwardfile) < 0) {
3495 delete [] messagefile;
3496 delete [] error_buf;
3497 delete [] forwardfile;
3501 /* A .forward file is currently in use. Merge vacation
3502 * into this file, rather than overwrite it. To do so,
3503 * set the appropriate variable to indicate mode.
3506 _priorVacationRunning = TRUE;
3508 // Turn on the bit to indicate we are currently using a .forward
3511 else if (forwardExists && _priorVacationRunning) {
3513 /* STRING_EXTRACTION -
3515 * This confirmation window is brought up when the user
3516 * tries to update the vacation status when the user is
3517 * already using a .forward file.
3520 if (NULL != _dialog)
3523 dialog = theRoamApp.genDialog();
3525 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"));
3527 dialog->setToErrorDialog("Error", error_buf);
3528 helpId = DTMAILHELPREMOVEVACATION;
3529 answer = dialog->post_and_return(helpId);
3532 delete [] messagefile;
3533 delete [] error_buf;
3534 delete [] forwardfile;
3539 // Re-initialize the error_buf
3540 memset(error_buf, 0, error_bufLen);
3542 sprintf(messagefile, "%s/.vacation.msg", pw.pw_dir);
3544 if (forwardExists) {
3545 fwd_fd = SafeOpen(forwardfile, O_WRONLY | O_APPEND | O_CREAT);
3548 fwd_fd = SafeOpen(forwardfile, O_WRONLY | O_CREAT);
3551 if (fwd_fd < 0 ) {// If fwdfile is not writable/appendable
3553 // Put up error dialog indicating fwdfile not writable
3554 /* restore the original .forward file */
3556 this->recoverForwardFile(forwardfile);
3558 delete [] messagefile;
3559 delete [] error_buf;
3560 delete [] forwardfile;
3564 SafeFChmod(fwd_fd, 0644);
3566 // Make buf be forwardfile._backupSuffix.
3567 // Then create a backup file of name buf
3569 strcpy(buf, forwardfile);
3570 strcat(buf, _backupSuffix);
3572 // If we are currently using a .forward then we need to append/prepend
3573 // the vacation command
3577 /* CREATE NEW .forward FILE
3579 * The original .forward file has been renamed to the
3580 * backup file name. We need to open the backup .forward
3581 * file so we can copy from it.
3584 if ((bkup_fd = SafeOpen(buf, O_RDONLY)) < 0) {
3585 /* restore the original .forward file */
3587 this->recoverForwardFile(forwardfile);
3589 delete [] messagefile;
3590 delete [] error_buf;
3591 delete [] forwardfile;
3595 /* COPY OLD .forward TO NEW .forward
3597 * Using mmap is quite fast, so rather than do a while
3598 * loop to copy line by line, we'll use mmap followed by
3602 fsize= (int)lseek(bkup_fd, 0, SEEK_END);
3606 (caddr_t) mmap(0, fsize, PROT_READ, MAP_PRIVATE, bkup_fd, 0);
3609 if (fwdptr == (char *)-1) {
3612 delete [] messagefile;
3613 delete [] error_buf;
3614 delete [] forwardfile;
3620 if (SafeWrite(fwd_fd, fwdptr, fsize) < fsize) {
3623 delete [] messagefile;
3624 delete [] error_buf;
3625 delete [] forwardfile;
3630 /* RELEASE .forward FILE
3632 * Un-mmap the new .forward file
3635 lastchar = fwdptr[fsize-1];
3636 munmap(fwdptr, fsize);
3641 /* APPEND VACATION LINE
3643 * The new .forward file is still open, so append the
3644 * new line below as the last line of the .forward file.
3645 * Check to make sure last character in the file is a
3646 * newline. If it's not, add one so our work goes on
3650 if (lastchar != '\n') {
3651 lseek(fwd_fd, 0, SEEK_END);
3653 if (SafeWrite(fwd_fd, txt, strlen(txt)) < strlen(txt)) {
3656 delete [] messagefile;
3657 delete [] error_buf;
3658 delete [] forwardfile;
3665 * Now, add the vacation line to the next line.
3667 char *append_buf1 = new char[1024*2];
3668 sprintf(append_buf1, "|\" /usr/bin/vacation %s\"\n", pw.pw_name);
3670 if (SafeWrite(fwd_fd, append_buf1, strlen(append_buf1)) <
3671 strlen(append_buf1)) {
3674 delete [] messagefile;
3675 delete [] error_buf;
3676 delete [] forwardfile;
3677 delete [] append_buf1;
3681 delete [] append_buf1;
3686 /* Create known backup file. The known backup
3687 * file allows mailtool to differentiate between
3688 * vacation being started from mailtool, and vacation
3689 * being invoked (the Unix program as opposed to the
3690 * MailTool Vacation menu item) via tty session.
3693 if (!forwardExists) {
3695 if ((bkup_fd = SafeOpen(buf, O_WRONLY | O_APPEND | O_CREAT)) < 0) {
3696 /* restore the original .forward file */
3698 this->recoverForwardFile(forwardfile);
3700 delete [] messagefile;
3701 delete [] error_buf;
3702 delete [] forwardfile;
3707 char *end_text = "User not using forward file\n";
3709 if (SafeWrite(bkup_fd, end_text, strlen(end_text)) <
3713 delete [] messagefile;
3714 delete [] error_buf;
3715 delete [] forwardfile;
3721 if (!forwardExists) {
3723 /* WRITE NEW .forward FILE
3725 * There was no .forward file, so no appending
3726 * must be done. Simply write the standard
3727 * vacation line into the new .forward file.
3730 char *append_buf2 = new char[1024*2];
3732 sprintf(append_buf2, "\\%s, |\" /usr/bin/vacation %s\"\n",
3733 pw.pw_name, pw.pw_name);
3734 if (SafeWrite(fwd_fd, append_buf2, strlen(append_buf2)) <
3735 strlen(append_buf2)) {
3739 delete [] messagefile;
3740 delete [] error_buf;
3741 delete [] forwardfile;
3742 delete [] append_buf2;
3745 delete [] append_buf2;
3751 system("/usr/bin/vacation -I");
3754 delete [] messagefile;
3755 delete [] error_buf;
3756 delete [] forwardfile;
3761 VacationCmd::backupFile(
3765 char *buf = new char[MAXPATHLEN+1];
3768 strcat(buf, _backupSuffix);
3770 if (rename(file, buf) < 0) {
3771 /* STRING_EXTRACTION -
3773 * We tried to make a backup copy of your .forward file, but
3774 * it failed. The first %s is the name of the rename
3775 * target; the second %s is the system error string.
3778 // Put up error dialog
3788 VacationCmd::recoverForwardFile(
3792 char *buf = new char[BUFSIZ+1];
3795 sprintf(buf, "%s", file);
3796 strcat(buf, _backupSuffix);
3798 if (rename(buf, file) < 0) {
3800 /* STRING_EXTRACTION -
3802 * We tried to restore your original .forward file, but could
3803 * not. The first %s is the name of the original .forward file,
3804 * the second %s is the the system error string.
3807 // Handle dialog indicating error in recovering .forward file.
3808 // Error usually caused by starting /usr/bin/vacation outside
3815 if ((fd = SafeOpen(file, O_RDONLY)) == 0) {
3820 buf[sizeof file -1] = '\0';
3821 while (SafeRead(fd, buf, BUFSIZ) != 0) {
3822 if (strstr(buf, "User not using forward file")) {
3835 VacationCmd::subject()
3845 return((char *)_body);
3853 VacationCmd::parseVacationMessage()
3858 DtMailGenDialog *dialog;
3861 char dialog_text[1024*4];
3863 DtMail::Session * d_session = theRoamApp.session()->session();
3866 if (NULL != _dialog)
3869 dialog = theRoamApp.genDialog();
3871 GetPasswordEntry(pw);
3873 char *messagefile = new char[MAXPATHLEN+1];
3874 sprintf(messagefile, "%s/.vacation.msg", pw.pw_dir);
3876 // See if the messagefile exists.
3877 // If it doesn't create one and throw in the text found in the
3878 // properties sheet. If no text found, use default template.
3880 char * fullpath = d_session->expandPath(error, messagefile);
3881 delete [] messagefile;
3884 // Map the file and try to parse it as a message. If it is a message,
3885 // then load it with headers. Otherwise, throw everything into the
3889 fd = SafeOpen(fullpath, O_RDONLY);
3892 if (fd < 0) {// File doesn't exist
3900 if (SafeFStat(fd, &buf) < 0) {
3902 sprintf(dialog_text, "%s",
3903 GETMSG(DT_catd, 1, 105, "Cannot open .vacation.msg file -- No write permission."));
3904 dialog->setToQuestionDialog("Mailer", dialog_text);
3905 helpId = DTMAILHELPNOWRITEVACATION;
3906 answer = dialog->post_and_return(helpId);
3915 int page_size = (int)sysconf(_SC_PAGESIZE);
3916 size_t map_size = (int) (buf.st_size +
3917 (page_size - (buf.st_size % page_size)));
3919 if (buf.st_size == 0)
3923 mbuf.size = buf.st_size;
3925 mbuf.buffer = (char *)mmap(0, map_size, PROT_READ, MAP_PRIVATE, fd, 0);
3927 mbuf.buffer = mmap(0, map_size, PROT_READ, MAP_PRIVATE, fd, 0);
3929 if (mbuf.buffer == (char *)-1) {
3931 mbuf.buffer = new char[mbuf.size];
3932 if (mbuf.buffer == NULL) {
3933 dialog->setToErrorDialog(GETMSG(DT_catd, 3, 59, "No Memory"),
3934 GETMSG(DT_catd, 3, 60, "There is not enough memory to load the existing .vacation.msg file."));
3935 helpId = DTMAILHELPNOLOADVACATION;
3936 answer = dialog->post_and_return(helpId);
3945 if (SafeRead(fd, mbuf.buffer, (unsigned int)mbuf.size) < mbuf.size) {
3946 dialog->setToErrorDialog(GETMSG(DT_catd, 3, 61, "Mailer"),
3947 GETMSG(DT_catd, 3, 62, "The existing .vacation.msg file appears to be corrupt."));
3948 helpId = DTMAILHELPCORRUPTVACATION;
3949 answer = dialog->post_and_return(helpId);
3951 delete [] mbuf.buffer;
3959 // Now we ask the library to parse it. If this fails for any reason, this
3960 // is not a message, so we give up.
3962 DtMail::Message * msg = d_session->messageConstruct(error,
3970 if (error.isSet()) {
3977 DtMail::Envelope * env = msg->getEnvelope(error);
3978 DtMailHeaderHandle hnd;
3982 DtMailValueSeq value;
3984 for (hnd = env->getFirstHeader(error, &name, value);
3985 error.isNotSet() && hnd;
3986 hnd = env->getNextHeader(error, hnd, &name, value)) {
3988 if (!strcmp(name, "Subject") == 0) {
3994 for (int slen = 0; slen < value.length(); slen++) {
3995 max_len += strlen(*(value[slen]));
3998 char * new_str = new char[max_len + (value.length() * 3)];
4000 strcpy(new_str, "");
4001 for (int copy = 0; copy < value.length(); copy++) {
4003 strcat(new_str, " ");
4006 strcat(new_str, *(value[copy]));
4009 _subject = strdup(new_str);
4017 DtMail::BodyPart * bp = msg->getFirstBodyPart(error);
4018 if (error.isNotSet()) {
4019 unsigned long length;
4021 bp->getContents(error,
4031 // Avoid a memory leak.
4039 VacationCmd::handleMessageFile(
4046 DtMailGenDialog *dialog;
4049 char dialog_text[1024*4];
4050 Boolean text_changed = FALSE;
4051 char *messagefile = new char[256];
4053 BufferMemory buf(4096);
4055 if (NULL != _dialog)
4058 dialog = theRoamApp.genDialog();
4060 // Check if a .forward file exists.
4062 GetPasswordEntry(pw);
4064 sprintf(messagefile, "%s/.vacation.msg", pw.pw_dir);
4066 // See if the messagefile exists.
4067 // If it doesn't create one and throw in the text found in the
4068 // properties sheet. If no text found, use default template.
4072 int msg_file_exists = SafeAccess(messagefile, F_OK);
4074 if (_subject == NULL || strcmp(_subject, subj) != 0)
4075 text_changed = TRUE;
4077 else if (_subject != NULL)
4078 text_changed = TRUE;
4080 if (!text_changed) {
4082 if (_body == NULL || strcmp((char*)_body, text) != 0)
4083 text_changed = TRUE;
4085 else if (_body != NULL)
4086 text_changed = TRUE;
4089 if (msg_file_exists >= 0 && text_changed) {
4090 sprintf(dialog_text, "%s",
4091 GETMSG(DT_catd, 1, 106, ".vacation.msg file exists. Replace with new text?"));
4092 dialog->setToQuestionDialog("Mailer", dialog_text);
4093 helpId = DTMAILHELPEXISTSVACATION;
4094 answer = dialog->post_and_return(helpId);
4097 // backup the messageFile
4098 this->backupFile(messagefile);
4102 // If the file doesn't exist or if the user has okayed creation
4104 if ((msg_file_exists < 0) || (answer == 1)) {
4106 fd = SafeOpen(messagefile, O_WRONLY | O_CREAT);
4108 sprintf(dialog_text, "%s",
4109 GETMSG(DT_catd, 1, 107, "Cannot open .vacation.msg file -- No write permission."));
4110 dialog->setToQuestionDialog("Mailer", dialog_text);
4111 helpId = DTMAILHELPERROR;
4112 answer = dialog->post_and_return(helpId);
4114 // Handle dialog indicating file not writable
4115 delete [] messagefile;
4118 SafeFChmod (fd, 0644);
4122 * This is the default value of the subject field in the
4123 * message that gets returned to the sender when vacation
4126 subj = GETMSG(DT_catd, 1, 108, "I am on vacation");
4128 buf.appendData("Subject: ", 9);
4129 buf.appendData(subj, strlen(subj));
4130 buf.appendData("\nPrecedence: junk\n\n", 19);
4134 _subject = strdup(subj);
4137 text = GETMSG(DT_catd, 1, 109,
4138 "I'm on vacation.\nYour mail regarding \"$SUBJECT\" will be read when I return.\n");
4140 buf.appendData(text, strlen(text));
4141 if (strlen(text) > 0 && text[strlen(text) - 1] != '\n') {
4142 buf.appendData("\n", 1);
4144 _body = strdup(text);
4146 buf.iterate(writeToFileDesc, fd);
4150 delete [] messagefile;