#include "xsm.h"
#include "save.h"
#include "saveutil.h"
#include "popup.h"
#include "info.h"
#include "lock.h"
#include "choose.h"
#include <X11/Shell.h>
#include <X11/Xaw/Form.h>
#include <X11/Xaw/List.h>
#include <X11/Xaw/Command.h>
#include <X11/Xaw/Toggle.h>
#include <X11/Xaw/AsciiText.h>
Widget savePopup;
Widget saveForm;
Widget saveMessageLabel;
Widget saveName;
Widget saveTypeLabel;
Widget saveTypeGlobal;
Widget saveTypeLocal;
Widget saveTypeBoth;
Widget interactStyleLabel;
Widget interactStyleNone;
Widget interactStyleErrors;
Widget interactStyleAny;
Widget saveOkButton;
Widget helpSaveButton;
Widget saveCancelButton;
Widget helpPopup;
Widget helpForm;
Widget helpSaveText;
Widget helpSaveOkButton;
Widget nameInUsePopup;
Widget nameInUseForm;
Widget nameInUseLabel;
Widget nameInUseOverwriteButton;
Widget nameInUseCancelButton;
Widget badSavePopup;
Widget badSaveForm;
Widget badSaveLabel;
Widget badSaveOkButton;
Widget badSaveCancelButton;
Widget badSaveListWidget;
extern Widget clientInfoPopup;
extern Widget clientPropPopup;
extern Widget nameSessionPopup;
extern int checkpoint_from_signal;
static int saveTypeData[] = {
SmSaveLocal,
SmSaveGlobal,
SmSaveBoth
};
static int interactStyleData[] = {
SmInteractStyleNone,
SmInteractStyleErrors,
SmInteractStyleAny
};
static String *failedNames = NULL;
static int numFailedNames = 0;
static Bool help_visible = False;
static String name_in_use = NULL;
static Bool name_locked = False;
static void
MakeCurrentSession(String new_name, Bool name_changed)
{
char title[256];
List *cl;
if (session_name)
{
for (cl = ListFirst (RunningList); cl; cl = ListNext (cl))
{
ClientRec *client = (ClientRec *) cl->thing;
if (!client->restarted &&
!client->userIssuedCheckpoint &&
client->discardCommand)
{
execute_system_command (client->discardCommand);
XtFree (client->discardCommand);
client->discardCommand = NULL;
}
}
if (!need_to_name_session)
UnlockSession (session_name);
}
if (name_changed)
{
if (session_name)
XtFree (session_name);
session_name = XtNewString (new_name);
}
LockSession (session_name, True);
sprintf (title, "xsm: %s", session_name);
XtVaSetValues (topLevel,
XtNtitle, title,
NULL);
set_session_save_file_name (session_name);
for (cl = ListFirst (RunningList); cl; cl = ListNext (cl))
{
ClientRec *client = (ClientRec *) cl->thing;
client->userIssuedCheckpoint = False;
if (client->discardCommand)
{
XtFree (client->discardCommand);
client->discardCommand = NULL;
}
}
need_to_name_session = False;
}
#define NAME_OK 0
#define NAME_EMPTY 1
#define NAME_EXISTS 2
#define NAME_LOCKED 3
static int
GetSaveName(String *nameRet)
{
String new_name = NULL;
Bool name_changed;
XtVaGetValues (saveName,
XtNstring, &new_name,
NULL);
*nameRet = new_name;
if (!new_name || *new_name == '\0')
return (NAME_EMPTY);
name_changed = !session_name ||
(session_name && strcmp (session_name, new_name) != 0);
if (!need_to_name_session && !name_changed)
return (NAME_OK);
if (GetSessionNames (&sessionNameCount,
&sessionNamesShort, NULL, &sessionsLocked))
{
int i, no_good = 0, locked = 0;
for (i = 0; i < sessionNameCount; i++)
if (strcmp (new_name, sessionNamesShort[i]) == 0)
{
no_good = 1;
locked = sessionsLocked[i];
break;
}
FreeSessionNames (sessionNameCount,
sessionNamesShort, NULL, sessionsLocked);
if (no_good)
return (locked ? NAME_LOCKED : NAME_EXISTS);
}
MakeCurrentSession (new_name, name_changed);
return (NAME_OK);
}
static void
GetSaveOptions(int *saveType, int *interactStyle, Bool *fast)
{
XtPointer ptr;
if (help_visible)
{
XtPopdown (helpPopup);
help_visible = 0;
}
ptr = XawToggleGetCurrent (saveTypeLocal );
*saveType = *((int *) ptr);
ptr = XawToggleGetCurrent (interactStyleNone );
*interactStyle = *((int *) ptr);
*fast = False;
}
void
DoSave(int saveType, int interactStyle, Bool fast)
{
ClientRec *client;
List *cl;
char *_saveType;
char *_shutdown;
char *_interactStyle;
if (saveType == SmSaveLocal)
_saveType = "Local";
else if (saveType == SmSaveGlobal)
_saveType = "Global";
else
_saveType = "Both";
if (wantShutdown)
_shutdown = "True";
else
_shutdown = "False";
if (interactStyle == SmInteractStyleNone)
_interactStyle = "None";
else if (interactStyle == SmInteractStyleErrors)
_interactStyle = "Errors";
else
_interactStyle = "Any";
SetSaveSensitivity (False);
saveInProgress = True;
shutdownCancelled = False;
phase2InProgress = False;
if (ListCount (RunningList) == 0)
FinishUpSave ();
for (cl = ListFirst (RunningList); cl; cl = ListNext (cl))
{
client = (ClientRec *) cl->thing;
SmsSaveYourself (client->smsConn,
saveType, wantShutdown, interactStyle, fast);
ListAddLast (WaitForSaveDoneList, (char *) client);
client->userIssuedCheckpoint = True;
client->receivedDiscardCommand = False;
if (verbose)
{
printf ("Client Id = %s, sent SAVE YOURSELF [", client->clientId);
printf ("Save Type = %s, Shutdown = %s, ", _saveType, _shutdown);
printf ("Interact Style = %s, Fast = False]\n", _interactStyle);
}
}
if (verbose)
{
printf ("\n");
printf ("Sent SAVE YOURSELF to all clients. Waiting for\n");
printf ("SAVE YOURSELF DONE, INTERACT REQUEST, or\n");
printf ("SAVE YOURSELF PHASE 2 REQUEST from each client.\n");
printf ("\n");
}
}
static void
SaveOkAction(Widget w, XEvent *event, String *params, Cardinal *num_params)
{
XtCallCallbacks (saveOkButton, XtNcallback, NULL);
}
static void
DelSaveWinAction(Widget w, XEvent *event, String *params, Cardinal *num_params)
{
XtCallCallbacks (saveCancelButton, XtNcallback, NULL);
}
static void
DelNameInUseWinAction(Widget w, XEvent *event, String *params,
Cardinal *num_params)
{
XtCallCallbacks (nameInUseCancelButton, XtNcallback, NULL);
}
static void
DelBadSaveWinAction(Widget w, XEvent *event, String *params,
Cardinal *num_params)
{
if (XtIsManaged (badSaveCancelButton))
XtCallCallbacks (badSaveCancelButton, XtNcallback, NULL);
else
XtCallCallbacks (badSaveOkButton, XtNcallback, NULL);
}
static void
DelSaveHelpWinAction(Widget w, XEvent *event, String *params,
Cardinal *num_params)
{
XtCallCallbacks (helpSaveOkButton, XtNcallback, NULL);
}
static void
SaveOkXtProc(Widget w, XtPointer client_data, XtPointer callData)
{
String name = NULL;
char label[256];
int status;
static int first_time = 1;
int saveType;
int interactStyle;
Bool fast;
if ((status = GetSaveName (&name)) != NAME_OK)
{
#ifdef XKB
XkbStdBell(XtDisplay(topLevel),XtWindow(topLevel),0,XkbBI_BadValue);
#else
XBell (XtDisplay (topLevel), 0);
#endif
if (status == NAME_EXISTS || status == NAME_LOCKED)
{
name_in_use = name;
if (status == NAME_LOCKED)
{
name_locked = True;
sprintf (label, "Another session by the name '%s' is active.\nChoose another name for the session.", name);
XtUnmanageChild (nameInUseOverwriteButton);
XtVaSetValues (nameInUseCancelButton,
XtNlabel, "OK",
XtNfromHoriz, NULL,
NULL);
}
else
{
name_locked = False;
sprintf (label, "Another session by the name '%s' already exists.\nWould you like to overwrite it?", name);
XtManageChild (nameInUseOverwriteButton);
XtVaSetValues (nameInUseCancelButton,
XtNlabel, "Cancel",
XtNfromHoriz, nameInUseOverwriteButton,
NULL);
}
XtVaSetValues (nameInUseLabel,
XtNlabel, label,
NULL);
XtPopdown (savePopup);
PopupPopup (mainWindow, nameInUsePopup,
True, first_time, 25, 100, "DelNameInUseWinAction()");
if (first_time)
first_time = 0;
}
return;
}
GetSaveOptions (&saveType, &interactStyle, &fast);
DoSave (saveType, interactStyle, fast);
}
void
LetClientInteract(List *cl)
{
ClientRec *client = (ClientRec *) cl->thing;
SmsInteract (client->smsConn);
ListSearchAndFreeOne (WaitForInteractList, (char *) client);
if (verbose)
{
printf ("Client Id = %s, sent INTERACT\n", client->clientId);
}
}
void
StartPhase2(void)
{
List *cl;
if (verbose)
{
printf ("\n");
printf ("Starting PHASE 2 of SAVE YOURSELF\n");
printf ("\n");
}
for (cl = ListFirst (WaitForPhase2List); cl; cl = ListNext (cl))
{
ClientRec *client = (ClientRec *) cl->thing;
SmsSaveYourselfPhase2 (client->smsConn);
if (verbose)
{
printf ("Client Id = %s, sent SAVE YOURSELF PHASE 2",
client->clientId);
}
}
ListFreeAllButHead (WaitForPhase2List);
phase2InProgress = True;
}
void
FinishUpSave(void)
{
ClientRec *client;
List *cl;
if (verbose)
{
printf ("\n");
printf ("All clients issued SAVE YOURSELF DONE\n");
printf ("\n");
}
saveInProgress = False;
phase2InProgress = False;
for (cl = ListFirst (RunningList); cl; cl = ListNext (cl))
{
client = (ClientRec *) cl->thing;
if (!client->receivedDiscardCommand)
continue;
if (client->discardCommand)
{
execute_system_command (client->discardCommand);
XtFree (client->discardCommand);
client->discardCommand = NULL;
}
if (client->saveDiscardCommand)
{
client->discardCommand = client->saveDiscardCommand;
client->saveDiscardCommand = NULL;
}
}
WriteSave (sm_id);
if (wantShutdown && shutdownCancelled)
{
shutdownCancelled = False;
}
else if (wantShutdown)
{
if (ListCount (RunningList) == 0)
EndSession (0);
shutdownInProgress = True;
for (cl = ListFirst (RunningList); cl; cl = ListNext (cl))
{
client = (ClientRec *) cl->thing;
SmsDie (client->smsConn);
if (verbose)
{
printf ("Client Id = %s, sent DIE\n", client->clientId);
}
}
}
else
{
for (cl = ListFirst (RunningList); cl; cl = ListNext (cl))
{
client = (ClientRec *) cl->thing;
SmsSaveComplete (client->smsConn);
if (verbose)
{
printf ("Client Id = %s, sent SAVE COMPLETE\n",
client->clientId);
}
}
}
if (!shutdownInProgress)
{
XtPopdown (savePopup);
SetAllSensitive (1);
if (checkpoint_from_signal)
checkpoint_from_signal = False;
}
}
static void
SaveCancelXtProc(Widget w, XtPointer client_data, XtPointer callData)
{
XtPopdown (savePopup);
if (help_visible)
{
XtPopdown (helpPopup);
help_visible = 0;
}
SetAllSensitive (1);
}
static Widget
AddToggle(char *widgetName, Widget parent, int state, Widget radioGroup,
XtPointer radioData, Widget fromHoriz, Widget fromVert)
{
Widget toggle;
toggle = XtVaCreateManagedWidget (
widgetName, toggleWidgetClass, parent,
XtNstate, state,
XtNradioGroup, radioGroup,
XtNradioData, radioData,
XtNfromHoriz, fromHoriz,
XtNfromVert, fromVert,
NULL);
return (toggle);
}
void
SetSaveSensitivity(Bool on)
{
XtSetSensitive (savePopup, on);
#if 0
XtSetSensitive (saveTypeLabel, on);
XtSetSensitive (saveTypeGlobal, on);
XtSetSensitive (saveTypeLocal, on);
XtSetSensitive (saveTypeBoth, on);
XtSetSensitive (interactStyleLabel, on);
XtSetSensitive (interactStyleNone, on);
XtSetSensitive (interactStyleErrors, on);
XtSetSensitive (interactStyleAny, on);
XtSetSensitive (saveOkButton, on);
#endif
}
void
SavePopupStructureNotifyXtHandler(Widget w, XtPointer closure, XEvent *event,
Boolean *continue_to_dispatch)
{
if (event->type == MapNotify)
{
int saveType;
int interactStyle;
Bool fast;
if (name_locked)
{
}
DeleteSession (name_in_use);
MakeCurrentSession (name_in_use, True);
name_in_use = NULL;
GetSaveOptions (&saveType, &interactStyle, &fast);
DoSave (saveType, interactStyle, fast);
XtRemoveEventHandler (savePopup, StructureNotifyMask, False,
SavePopupStructureNotifyXtHandler, NULL);
}
}
static void
NameInUseOverwriteXtProc(Widget w, XtPointer client_data, XtPointer callData)
{
if (name_locked)
{
return;
}
XtPopdown (nameInUsePopup);
XtAddEventHandler (savePopup, StructureNotifyMask, False,
SavePopupStructureNotifyXtHandler, NULL);
XtPopup (savePopup, XtGrabNone);
}
static void
NameInUseCancelXtProc(Widget w, XtPointer client_data, XtPointer callData)
{
XtPopdown (nameInUsePopup);
XtPopup (savePopup, XtGrabNone);
name_in_use = NULL;
}
static void
BadSaveOkXtProc(Widget w, XtPointer client_data, XtPointer callData)
{
ListFreeAllButHead (FailedSaveList);
XtPopdown (badSavePopup);
FinishUpSave ();
}
static void
BadSaveCancelXtProc(Widget w, XtPointer client_data, XtPointer callData)
{
ListFreeAllButHead (FailedSaveList);
XtPopdown (badSavePopup);
if (wantShutdown)
{
List *cl;
shutdownCancelled = True;
for (cl = ListFirst (RunningList); cl; cl = ListNext (cl))
{
ClientRec *client = (ClientRec *) cl->thing;
SmsShutdownCancelled (client->smsConn);
if (verbose)
{
printf ("Client Id = %s, sent SHUTDOWN CANCELLED\n",
client->clientId);
}
}
}
FinishUpSave ();
}
static void
BadSaveListXtProc(Widget w, XtPointer client_data, XtPointer callData)
{
}
static void
HelpSaveXtProc(Widget w, XtPointer client_data, XtPointer callData)
{
static int first_time = 1;
if (help_visible)
{
XMapRaised (XtDisplay (topLevel), XtWindow (helpPopup));
}
else
{
PopupPopup (savePopup, helpPopup,
True, first_time, 50, 50, "DelSaveHelpWinAction()");
help_visible = 1;
if (first_time)
first_time = 0;
}
}
static void
HelpSaveOkXtProc(Widget w, XtPointer client_data, XtPointer callData)
{
XtPopdown (helpPopup);
help_visible = 0;
}
void
create_save_popup(void)
{
XtTranslations translations;
static XtActionsRec actions[] = {
{"SaveOkAction", SaveOkAction},
{"DelSaveWinAction", DelSaveWinAction},
{"DelNameInUseWinAction", DelNameInUseWinAction},
{"DelBadSaveWinAction", DelBadSaveWinAction},
{"DelSaveHelpWinAction", DelSaveHelpWinAction}
};
savePopup = XtVaCreatePopupShell (
"savePopup", transientShellWidgetClass, topLevel,
XtNallowShellResize, True,
NULL);
saveForm = XtCreateManagedWidget (
"saveForm", formWidgetClass, savePopup, NULL, 0);
saveMessageLabel = XtVaCreateManagedWidget (
"saveMessageLabel", labelWidgetClass, saveForm,
XtNfromHoriz, NULL,
XtNfromVert, NULL,
XtNborderWidth, 0,
NULL);
saveName = XtVaCreateManagedWidget (
"saveName", asciiTextWidgetClass, saveForm,
XtNfromVert, NULL,
XtNeditType, XawtextEdit,
XtNresizable, True,
XtNresize, XawtextResizeWidth,
NULL);
saveTypeLabel = XtVaCreateManagedWidget (
"saveTypeLabel", labelWidgetClass, saveForm,
XtNfromHoriz, NULL,
XtNfromVert, saveMessageLabel,
XtNborderWidth, 0,
XtNvertDistance, 20,
NULL);
saveTypeLocal = AddToggle (
"saveTypeLocal",
saveForm,
0,
NULL,
(XtPointer) &saveTypeData[0],
saveTypeLabel,
saveMessageLabel
);
saveTypeGlobal = AddToggle (
"saveTypeGlobal",
saveForm,
0,
saveTypeLocal,
(XtPointer) &saveTypeData[1],
saveTypeLocal,
saveMessageLabel
);
saveTypeBoth = AddToggle (
"saveTypeBoth",
saveForm,
1,
saveTypeLocal,
(XtPointer) &saveTypeData[2],
saveTypeGlobal,
saveMessageLabel
);
XtVaSetValues (saveName, XtNfromHoriz, saveTypeLabel, NULL);
XtVaSetValues (saveTypeLocal, XtNvertDistance, 20, NULL);
XtVaSetValues (saveTypeGlobal, XtNvertDistance, 20, NULL);
XtVaSetValues (saveTypeBoth, XtNvertDistance, 20, NULL);
interactStyleLabel = XtVaCreateManagedWidget (
"interactStyleLabel", labelWidgetClass, saveForm,
XtNfromHoriz, NULL,
XtNfromVert, saveTypeLabel,
XtNborderWidth, 0,
NULL);
interactStyleNone = AddToggle (
"interactStyleNone",
saveForm,
0,
NULL,
(XtPointer) &interactStyleData[0],
saveTypeLabel,
saveTypeLabel
);
interactStyleErrors = AddToggle (
"interactStyleErrors",
saveForm,
0,
interactStyleNone,
(XtPointer) &interactStyleData[1],
interactStyleNone,
saveTypeLabel
);
interactStyleAny = AddToggle (
"interactStyleAny",
saveForm,
1,
interactStyleNone,
(XtPointer) &interactStyleData[2],
interactStyleErrors,
saveTypeLabel
);
saveOkButton = XtVaCreateManagedWidget (
"saveOkButton", commandWidgetClass, saveForm,
XtNfromHoriz, NULL,
XtNfromVert, interactStyleLabel,
XtNvertDistance, 20,
XtNresizable, True,
NULL);
XtAddCallback (saveOkButton, XtNcallback, SaveOkXtProc, 0);
helpSaveButton = XtVaCreateManagedWidget (
"helpSaveButton", commandWidgetClass, saveForm,
XtNfromHoriz, saveOkButton,
XtNfromVert, interactStyleLabel,
XtNvertDistance, 20,
NULL);
XtAddCallback (helpSaveButton, XtNcallback, HelpSaveXtProc, 0);
saveCancelButton = XtVaCreateManagedWidget (
"saveCancelButton", commandWidgetClass, saveForm,
XtNfromHoriz, helpSaveButton,
XtNfromVert, interactStyleLabel,
XtNvertDistance, 20,
NULL);
XtAddCallback (saveCancelButton, XtNcallback, SaveCancelXtProc, 0);
XtSetKeyboardFocus (saveForm, saveName);
XtAppAddActions (appContext, actions, XtNumber (actions));
translations = XtParseTranslationTable
("<Key>Return: SaveOkAction()\n");
XtOverrideTranslations(saveName, translations);
XtInstallAllAccelerators (saveForm, saveForm);
nameInUsePopup = XtVaCreatePopupShell (
"nameInUsePopup", transientShellWidgetClass, topLevel,
XtNallowShellResize, True,
NULL);
nameInUseForm = XtVaCreateManagedWidget (
"nameInUseForm", formWidgetClass, nameInUsePopup,
NULL);
nameInUseLabel = XtVaCreateManagedWidget (
"nameInUseLabel", labelWidgetClass, nameInUseForm,
XtNresizable, True,
XtNfromHoriz, NULL,
XtNfromVert, NULL,
XtNborderWidth, 0,
XtNtop, XawChainTop,
XtNbottom, XawChainTop,
NULL);
nameInUseOverwriteButton = XtVaCreateManagedWidget (
"nameInUseOverwriteButton", commandWidgetClass, nameInUseForm,
XtNfromHoriz, NULL,
XtNfromVert, nameInUseLabel,
XtNtop, XawChainBottom,
XtNbottom, XawChainBottom,
NULL);
XtAddCallback (nameInUseOverwriteButton, XtNcallback,
NameInUseOverwriteXtProc, 0);
nameInUseCancelButton = XtVaCreateManagedWidget (
"nameInUseCancelButton", commandWidgetClass, nameInUseForm,
XtNresizable, True,
XtNfromHoriz, nameInUseOverwriteButton,
XtNfromVert, nameInUseLabel,
XtNtop, XawChainBottom,
XtNbottom, XawChainBottom,
NULL);
XtAddCallback (nameInUseCancelButton, XtNcallback,
NameInUseCancelXtProc, 0);
helpPopup = XtVaCreatePopupShell (
"helpPopup", transientShellWidgetClass, topLevel,
NULL);
helpForm = XtVaCreateManagedWidget (
"helpForm", formWidgetClass, helpPopup,
NULL);
helpSaveText = XtVaCreateManagedWidget (
"helpSaveText", labelWidgetClass, helpForm,
XtNfromHoriz, NULL,
XtNfromVert, NULL,
XtNtop, XawChainTop,
XtNbottom, XawChainTop,
NULL);
helpSaveOkButton = XtVaCreateManagedWidget (
"helpSaveOkButton", commandWidgetClass, helpForm,
XtNfromHoriz, NULL,
XtNfromVert, helpSaveText,
XtNtop, XawChainBottom,
XtNbottom, XawChainBottom,
XtNvertDistance, 20,
NULL);
XtAddCallback (helpSaveOkButton, XtNcallback,
HelpSaveOkXtProc, 0);
badSavePopup = XtVaCreatePopupShell (
"badSavePopup", transientShellWidgetClass, topLevel,
XtNallowShellResize, True,
NULL);
badSaveForm = XtVaCreateManagedWidget (
"badSaveForm", formWidgetClass, badSavePopup,
NULL);
badSaveLabel = XtVaCreateManagedWidget (
"badSaveLabel", labelWidgetClass, badSaveForm,
XtNfromHoriz, NULL,
XtNfromVert, NULL,
XtNborderWidth, 0,
XtNtop, XawChainTop,
XtNbottom, XawChainTop,
NULL);
badSaveListWidget = XtVaCreateManagedWidget (
"badSaveListWidget", listWidgetClass, badSaveForm,
XtNresizable, True,
XtNdefaultColumns, 1,
XtNforceColumns, True,
XtNfromHoriz, NULL,
XtNfromVert, badSaveLabel,
XtNtop, XawChainTop,
XtNbottom, XawChainBottom,
NULL);
XtAddCallback (badSaveListWidget, XtNcallback, BadSaveListXtProc, 0);
badSaveOkButton = XtVaCreateManagedWidget (
"badSaveOkButton", commandWidgetClass, badSaveForm,
XtNfromHoriz, NULL,
XtNfromVert, badSaveListWidget,
XtNtop, XawChainBottom,
XtNbottom, XawChainBottom,
NULL);
XtAddCallback (badSaveOkButton, XtNcallback, BadSaveOkXtProc, 0);
badSaveCancelButton = XtVaCreateManagedWidget (
"badSaveCancelButton", commandWidgetClass, badSaveForm,
XtNfromHoriz, badSaveOkButton,
XtNfromVert, badSaveListWidget,
XtNtop, XawChainBottom,
XtNbottom, XawChainBottom,
NULL);
XtAddCallback (badSaveCancelButton, XtNcallback, BadSaveCancelXtProc, 0);
XtInstallAllAccelerators (badSaveForm, badSaveForm);
}
void
PopupSaveDialog(void)
{
static int first_time = 1;
XtSetSensitive (mainWindow, 0);
XtSetSensitive (clientInfoPopup, 0);
XtSetSensitive (clientPropPopup, 0);
XawToggleSetCurrent (saveTypeBoth,
(XtPointer) &saveTypeData[2]);
XawToggleSetCurrent (interactStyleAny,
(XtPointer) &interactStyleData[2]);
XtVaSetValues (savePopup,
XtNtitle, wantShutdown ? "Shutdown" : "Checkpoint",
NULL);
XtVaSetValues (saveName,
XtNstring, need_to_name_session ? "" : session_name,
NULL);
XtVaSetValues (saveOkButton,
XtNlabel, wantShutdown ? "Shutdown" : "Checkpoint",
NULL);
PopupPopup (mainWindow, savePopup,
True, first_time, 25, 100, "DelSaveWinAction()");
if (first_time)
first_time = 0;
}
void
CheckPointXtProc(Widget w, XtPointer client_data, XtPointer callData)
{
wantShutdown = False;
PopupSaveDialog ();
}
void
ShutdownSaveXtProc(Widget w, XtPointer client_data, XtPointer callData)
{
wantShutdown = True;
PopupSaveDialog ();
}
void
PopupBadSave(void)
{
ClientRec *client;
char *progName, *hostname, *tmp1, *tmp2;
String clientInfo;
int maxlen1, maxlen2;
char extraBuf1[80], extraBuf2[80];
char *restart_service_prop;
List *cl, *pl;
int i, k;
static int first_time = 1;
if (failedNames)
{
for (i = 0; i < numFailedNames; i++)
XtFree (failedNames[i]);
XtFree ((char *) failedNames);
failedNames = NULL;
}
maxlen1 = maxlen2 = 0;
numFailedNames = 0;
for (cl = ListFirst (FailedSaveList); cl; cl = ListNext (cl))
{
client = (ClientRec *) cl->thing;
progName = NULL;
restart_service_prop = NULL;
for (pl = ListFirst (client->props); pl; pl = ListNext (pl))
{
Prop *pprop = (Prop *) pl->thing;
List *vl = ListFirst (pprop->values);
PropValue *pval = (PropValue *) vl->thing;
if (strcmp (pprop->name, SmProgram) == 0)
{
progName = GetProgramName ((char *) pval->value);
if ((int) strlen (progName) > maxlen1)
maxlen1 = strlen (progName);
}
else if (strcmp (pprop->name, "_XC_RestartService") == 0)
{
restart_service_prop = (char *) pval->value;
}
}
if (!progName)
continue;
if (restart_service_prop)
tmp1 = restart_service_prop;
else if (client->clientHostname)
tmp1 = client->clientHostname;
else
continue;
if ((tmp2 = (char *) strchr (tmp1, '/')) == NULL)
hostname = tmp1;
else
hostname = tmp2 + 1;
if ((int) strlen (hostname) > maxlen2)
maxlen2 = strlen (hostname);
numFailedNames++;
}
failedNames = (String *) XtMalloc (
numFailedNames * sizeof (String));
i = 0;
for (cl = ListFirst (FailedSaveList); cl; cl = ListNext (cl))
{
ClientRec *client = (ClientRec *) cl->thing;
int extra1, extra2;
progName = NULL;
restart_service_prop = NULL;
for (pl = ListFirst (client->props); pl; pl = ListNext (pl))
{
Prop *pprop = (Prop *) pl->thing;
List *vl = ListFirst (pprop->values);
PropValue *pval = (PropValue *) vl->thing;
if (strcmp (pprop->name, SmProgram) == 0)
{
progName = GetProgramName ((char *) pval->value);
}
else if (strcmp (pprop->name, "_XC_RestartService") == 0)
{
restart_service_prop = (char *) pval->value;
}
}
if (!progName)
continue;
if (restart_service_prop)
tmp1 = restart_service_prop;
else if (client->clientHostname)
tmp1 = client->clientHostname;
else
continue;
if ((tmp2 = (char *) strchr (tmp1, '/')) == NULL)
hostname = tmp1;
else
hostname = tmp2 + 1;
extra1 = maxlen1 - strlen (progName) + 5;
extra2 = maxlen2 - strlen (hostname);
clientInfo = (String) XtMalloc (strlen (progName) +
extra1 + extra2 + 3 + strlen (hostname) + 1);
for (k = 0; k < extra1; k++)
extraBuf1[k] = ' ';
extraBuf1[extra1] = '\0';
for (k = 0; k < extra2; k++)
extraBuf2[k] = ' ';
extraBuf2[extra2] = '\0';
sprintf (clientInfo, "%s%s (%s%s)", progName, extraBuf1,
hostname, extraBuf2);
failedNames[i++] = clientInfo;
if (client->freeAfterBadSavePopup)
{
FreeClient (client, True );
}
}
XawListChange (badSaveListWidget,
failedNames, numFailedNames, 0, True);
XtPopdown (savePopup);
if (wantShutdown && !shutdownCancelled)
XtManageChild (badSaveCancelButton);
else
XtUnmanageChild (badSaveCancelButton);
PopupPopup (mainWindow, badSavePopup,
True, first_time, 25, 100, "DelBadSaveWinAction()");
if (first_time)
first_time = 0;
}
void
ShutdownDontSaveXtProc(Widget w, XtPointer client_data, XtPointer callData)
{
List *cl;
ClientRec *client;
if (ListCount (RunningList) == 0)
EndSession (0);
for (cl = ListFirst (RunningList); cl; cl = ListNext (cl))
{
client = (ClientRec *) cl->thing;
if (!client->restarted &&
!client->userIssuedCheckpoint &&
client->discardCommand)
{
execute_system_command (client->discardCommand);
XtFree (client->discardCommand);
client->discardCommand = NULL;
}
}
shutdownInProgress = True;
for (cl = ListFirst (RunningList); cl; cl = ListNext (cl))
{
client = (ClientRec *) cl->thing;
SmsDie (client->smsConn);
if (verbose)
{
printf ("Client Id = %s, sent DIE\n", client->clientId);
}
}
}