/***************************************************************************/ /***************************************************************************/ /* */ /* (c) 1995-1999. The Regents of the University of California. All */ /* rights reserved. */ /* */ /* This work was produced at the University of California, Lawrence */ /* Livermore National Laboratory (UC LLNL) under contract no. */ /* W-7405-ENG-48 (Contract 48) between the U.S. Department of Energy */ /* (DOE) and The Regents of the University of California (University) */ /* for the operation of UC LLNL. Copyright is reserved to the */ /* University for purposes of controlled dissemination, */ /* commercialization through formal licensing, or other disposition */ /* under terms of Contract 48; DOE policies, regulations and orders; */ /* and U.S. statutes. The rights of the Federal Government are */ /* reserved under Contract 48 subject to the restrictions agreed upon */ /* by the DOE and University. */ /* */ /* */ /* DISCLAIMER */ /* */ /* This software was prepared as an account of work sponsored by an */ /* agency of the United States Government. Neither the United States */ /* Government nor the University of California nor any of their */ /* employees, makes any warranty, express or implied, or assumes any */ /* liability or responsibility for the accuracy, completeness, or */ /* usefulness of any information, apparatus, product, or process */ /* disclosed, or represents that its specific commercial products, */ /* process, or service by trade name, trademark, manufacturer, or */ /* otherwise, does not necessarily constitute or imply its */ /* endorsement, recommendation, or favoring by the United States */ /* Government or the University of California. The views and opinions */ /* of the authors expressed herein do not necessarily state or reflect */ /* those of the United States Government or the University of */ /* California, and shall not be used for advertising or product */ /* endorsement purposes. */ /* */ /* Permission to use, copy, modify and distribute this software and its */ /* documentation for any non-commercial purpose, without fee, is */ /* hereby granted, provided that the above copyright notice and this */ /* permission notice appear in all copies of the software and */ /* supporting documentation, and that all UC LLNL identification in */ /* the user interface remain unchanged. The title to copyright LLNL */ /* XDIR shall at all times remain with The Regents of the University */ /* of California and users agree to preserve same. Users seeking the */ /* right to make derivative works with LLNL XDIR for commercial */ /* purposes may obtain a license from the Lawrence Livermore National */ /* Laboratory's Technology Transfer Office, P.O. Box 808, L-795, */ /* Livermore, CA 94550. */ /* */ /***************************************************************************/ /***************************************************************************/ #include #include #include "xdir.h" static Widget w_reconnect_dialog; static char *msg1 = "Lost connection to %s."; static char *msg2 = "Lost connection to %s.\n\nWas able to reconnect.\n\nYou might have to reissue your last command\nor refresh one or more directory windows."; static char *msg3 = "Lost connection to %s.\n\nWas not able to reconnect.\n\nWill close all directory windows for this host."; static char *msg4 = "Lost connection to %s.\n\nWas not able to reconnect.\n\nWill close all directory windows for this host\nand open a directory window for the local host."; static char *msg5 = "Lost connection to %s.\n\nUser aborted reconnection attempt.\n\nWill close all directory windows for this host."; static char *msg6 = "Lost connection to %s.\n\nUser aborted reconnection attempt.\n\nWill close all directory windows for this host\nand open a directory window for the local host."; Widget show_in_progress_dialog(); extern struct st_host_info hinfo[]; extern struct dirwin_st *dirwin_head; extern int connection_check_time; void clean_up_lost_connection(); /* * check_connection - Make sure that connection is up. If less than the * time specified by the user preference "Connection * Check Time" has passed since last hearing from the * remote host, then it is assumed that the connection * is up. If more than "Connection Check Time" has * passed then a NOOP is sent to see if the connection * is up; if not an attempt is made to restore the * connection. Returns 0 if connection is good, -3 * for unable to restore lost connection, -6 for stop * button pushed, and -1 for other errors. */ check_connection(host, dirwin) int host; struct dirwin_st *dirwin; { struct timeval current_time; int retval; /* If we've heard from remote host recently, assume connection is good */ gettimeofday(¤t_time, NULL); if (hinfo[host].last_reply_time+connection_check_time*60 > current_time.tv_sec) return 0; /* It's been awhile since last reply. Send noop to remote host. */ retval = remote_noop(host); switch (retval) { case -3: /* Lost connection. Try to reconnect */ case -2: /* No response. Assume lost connection. */ switch (try_to_reconnect(host, dirwin)) { case 0: return 0; case -6: clean_up_lost_connection(host, dirwin, True); return -3; default: clean_up_lost_connection(host, dirwin, False); return -3; } default: return retval; } } /* * restore_lost_connection - This routine is called when a lost control * connection to "host" is detected. The user * is informed, and a reconnection is attempted. * Auxiliary dialogs are centered over directory * window "dirwin". If unable to reconnect, all * directory windows associated with host are * closed, and -1 is returned. If able to * reconnect, 0 is returned. */ restore_lost_connection(host, dirwin) int host; struct dirwin_st *dirwin; { char *msg; int retval; /* Report broken connection */ msg = XtMalloc(strlen(msg1)+strlen(hinfo[host].hostname)+10); sprintf(msg, msg1, hinfo[host].hostname); record_warning(msg); XtFree(msg); /* Try to reconnect */ retval = try_to_reconnect(host, dirwin); /* If able to reconnect, let user know */ if (retval == 0) { msg = XtMalloc(strlen(msg2)+strlen( hinfo[host].hostname)+1); sprintf(msg, msg2, hinfo[host].hostname); warn(msg, dirwin->w_shell); XtFree(msg); return 0; } /* Report failure to reconnect */ clean_up_lost_connection(host, dirwin, (retval == -6)); return -1; } /* * show_reconnect_dialog - Pop up a dialog that displays an "attempting to * reconnect message over directory window "dirwin". */ void show_reconnect_dialog(dirwin) struct dirwin_st *dirwin; { w_reconnect_dialog = show_in_progress_dialog(dirwin, "Reconnect to Remote Host", "LOST CONNECTION TO REMOTE HOST\n\n------------\n\nATTEMPTING TO RECONNECT"); } /* * hide_reconnect_dialog - Pop down dialog that displays an "attempting to * reconnect message. */ void hide_reconnect_dialog() { hide_in_progress_dialog(w_reconnect_dialog); } /* * try_to_reconnect - Try to reestablish connection to remote host. * Returns 0 if successful, -6 if stop button pressed, * else -1. */ try_to_reconnect(host, dirwin) int host; struct dirwin_st *dirwin; { int retval; show_reconnect_dialog(dirwin); retval = do_connect(host, dirwin); hide_reconnect_dialog(); return retval; } /* * clean_up_lost_connection - Report failure to reconnect and close all * directory windows for this host. Set * "stop_button_pushed" to True if unable to * reconnect because user pressed stop button. */ void clean_up_lost_connection(host, dirwin, stop_button_pushed) int host; struct dirwin_st *dirwin; int stop_button_pushed; { struct dirwin_st *dwin; struct dirwin_st *next; char *msg; /* Report lost connection */ dwin = dirwin_head; while (dwin && (dwin->host == dirwin->host)) dwin = dwin->next; if (dwin) { if (stop_button_pushed) { record_abort("Reconnect to Remote Host"); msg = XtMalloc(strlen(msg5)+strlen(hinfo[host].hostname)+1); sprintf(msg, msg5, hinfo[host].hostname); } else { msg = XtMalloc(strlen(msg3)+strlen(hinfo[host].hostname)+1); sprintf(msg, msg3, hinfo[host].hostname); } warn(msg, dirwin->w_shell); } else { if (stop_button_pushed) { record_abort("Reconnect to Remote Host"); msg = XtMalloc(strlen(msg6)+strlen(hinfo[host].hostname)+1); sprintf(msg, msg6, hinfo[host].hostname); } else { msg = XtMalloc(strlen(msg4)+strlen(hinfo[host].hostname)+1); sprintf(msg, msg4, hinfo[host].hostname); } warn(msg, dirwin->w_shell); if (connect_to_local(NULL) < 0) fatal_error("Unable to connect to local host."); } XtFree(msg); /* Close all directory windows for host */ dwin = dirwin_head; while (dwin) { next = dwin->next; if (dwin->host == host) close_directory_window(dwin); dwin = next; } }