/***************************************************************************/ /***************************************************************************/ /* */ /* (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 #include #include "xdir.h" #ifndef SIGCLD #define SIGCLD SIGCHLD #endif struct st_host_info hinfo[MAXHOSTS]; Widget w_toplev; XtAppContext app; Display *display; int screen; int depth; Visual *visual; Window root_window; int xfer_mode; int child_to_parent_pipe[2]; void cb_msg_from_child_process(); void cb_diag_close(); void fatal_error(); int cb_create_dialogs(); int create_gprefs_window(); int create_vprefs_window(); void reapchild(); char *merge_paths(); static int (*dialog_creation_fns[])() = { create_gprefs_window, create_vprefs_window, NULL }; static void (*saved_sigcld_handler)(); String *get_fallbacks(); extern int initial_xfer_mode; extern struct dirwin_st *launch_dirwin; /* * main - Initialize and run. */ main(argc, argv) int argc; char **argv; { int i; int j; int retval; int use_color = False; String *fallbacks; char *requested_wd; char *current_wd; /* Initialize SOCKS */ #ifdef SOCKS SOCKSinit(argv[0]); #endif /* Verify that environment variable HOME is set */ if (getenv("HOME") == NULL) fatal_error("Environment variable HOME not set"); /* Initialize preferences from .xdirrc */ construct_prefs_filename(); read_prefs_from_file(); /* Initialize the file transfer and recursive copy mode */ xfer_mode = initial_xfer_mode; /* Initialize caches from .xdircache */ construct_history_filename(); read_history_from_file(); /* Should fallback resources contain color information? */ for (i=0; i 4 (int *)&argc, #else (Cardinal *)&argc, #endif argv, fallbacks, XmNmappedWhenManaged, False, NULL ); /* Get application resources */ get_application_resources(); /* Get the display and screen characteristics */ display = XtDisplay(w_toplev); screen = XDefaultScreen(display); depth = XDefaultDepth(display, screen); visual = XDefaultVisual(display, screen); root_window = XRootWindowOfScreen(XtScreen(w_toplev)); /* Create custom Xdir icon for window manager */ create_wm_icon(); /* Add callback for the WM_DELETE_WINDOW protocol */ add_wm_delete_window_cb(w_toplev, cb_diag_close, NULL, True); /* Display startup window */ display_startup_dialog(); /* Create diagnostics window */ create_diagnostics_window(); /* Get rid of startup window */ close_startup_dialog(); /* Remember current working directory */ if (local_pwd(¤t_wd) < 0) fatal_error("Unable to get working directory"); /* Initialize local host */ init_local_host(); /* Make widgets "real" */ XtRealizeWidget(w_toplev); /* Ignore signals from broken pipes (and sockets) */ signal(SIGPIPE, SIG_IGN); /* Connect to local host */ if (argc > 1) { if (argv[argc-1][0] == '/') requested_wd = XtNewString(argv[argc-1]); else requested_wd = merge_paths(SYS_UNIX, current_wd, argv[argc-1]); retval = display_dir(LOCAL, NULL, requested_wd, True, True, False, False); XtFree(requested_wd); if (retval < 0) { if (connect_to_local(NULL) < 0) fatal_error("Unable to connect to local host."); } } else if (connect_to_local(NULL) < 0) fatal_error("Unable to connect to local host."); /* No longer need to remember current working directory */ XtFree(current_wd); /* Create often-used dialogs in background */ XtAppAddWorkProc(app, (XtWorkProc)cb_create_dialogs, NULL); /* Will need to reap children */ signal(SIGCLD, reapchild); /* Create mechanism for receiving messages from child process */ if (pipe(child_to_parent_pipe) == -1) fatal_error("Unable to create child to parent pipe"); XtAppAddInput(app, child_to_parent_pipe[0], (XtPointer)XtInputReadMask, (XtInputCallbackProc)cb_msg_from_child_process, NULL); /* Display copyright notice */ write_copyright(); /* Turn over control */ XtAppMainLoop(app); } /* * fatal_error - Writes string "msg" to standard error and then terminates. */ void fatal_error(msg) char *msg; { fprintf(stderr, "*** FATAL ERROR: %s\n", msg); exit(-1); } /* * cb_create_dialogs - Work procedure to create often-used dialogs in * the background. */ cb_create_dialogs() { static int indx = 0; if (dialog_creation_fns[indx]) { dialog_creation_fns[indx](); indx++; return False; } else return True; } /* * reapchild - Reap the child file viewer process in order to free up the * temporary directory and file(s). */ void reapchild(signo) int signo; { int pid = iwait(NULL); if (pid != -1) mark_viewdir_for_removal(pid); /* Reset signal handler for AIX, IRIX, etc. */ signal(SIGCLD, reapchild); } /* * save_sigcld_handler - Save current signal handler for SIGCLD. */ void save_sigcld_handler() { saved_sigcld_handler = signal(SIGCLD, SIG_DFL); } /* * restore_sigcld_handler - Restore signal handler for SIGCLD that was * saved by save_sigcld_handler(). */ void restore_sigcld_handler() { signal(SIGCLD, saved_sigcld_handler); } /* * cb_msg_from_child_process - Callback to process error message from child * process. Message ends with a bell character. */ void cb_msg_from_child_process(widget, client_data, call_data) Widget widget; XtPointer client_data; XtPointer call_data; { int nbytes; char buf[2]; char *msg = XtNewString(""); char *temp; /* Read entire message from child */ while (1) { nbytes = iread(child_to_parent_pipe[0], buf, 1); if (nbytes < 0) fatal_error("Trouble in cb_msg_from_child_process()"); buf[nbytes] = '\0'; temp = XtMalloc(strlen(msg)+nbytes+1); strcpy(temp, msg); strcat(temp, buf); XtFree(msg); msg = temp; if (msg[strlen(msg)-1] == '\007') { warn(msg, launch_dirwin->w_shell); XtFree(msg); return; } } }