/***************************************************************************/
/***************************************************************************/
/* */
/* (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 <stdio.h>
#include <errno.h>
#include <Xm/PushBG.h>
#include <Xm/RowColumn.h>
#include <Xm/LabelG.h>
#include <Xm/SeparatoG.h>
#include "xdir.h"
#include "list.h"
#include "str.h"
#define MAXARGV 300
static struct {
struct dirwin_st *dirwin;
struct entry_link *head;
} lc;
struct dirwin_st *launch_dirwin;
extern struct sl_struct *launcher_mappings;
extern XtAppContext app;
extern struct st_host_info hinfo[];
extern int beep_when_ops_done;
extern int child_to_parent_pipe[];
extern struct dirwin_st *dirwin_head;
#if !defined(__FreeBSD__) && !defined(__NetBSD__) && !defined(__GNU_LIBRARY__) && !defined(__GLIBC__) && !defined(__EMX__)
extern char *sys_errlist[];
#endif
char *entry_to_full_path();
struct sl_struct *create_array_list();
int cb_launch_commands();
char *system_name();
char *server_name();
char *decrypt_password();
char *cstring_to_text();
void concat();
void update_launch_menus();
/*
* cb_launch - Callback to launch the command selected in the "Launch"
* menu.
*/
void
cb_launch(widget, client_data, call_data)
Widget widget;
XtPointer client_data;
XtPointer call_data;
{
struct dirwin_st *dirwin = (struct dirwin_st *)client_data;
XmString string;
char *command_name;
char *raw_command_line;
char *command_line;
char *ptr;
int found_percent;
int found_percent_s;
int found_percent_l;
int len;
int i;
int j;
int k;
char ch;
struct entry_link *head_selected_entries = NULL;
struct entry_link *head_command_lines = NULL;
char *full_path;
struct sl_struct *list;
char buf[2];
int nlaunches;
char *passwrd;
/* Start operation */
if (!start_op(True))
return;
/* Clear error flag */
raise_okflag();
XtVaGetValues(widget, XmNlabelString, &string, NULL);
command_name = cstring_to_text(string);
XmStringFree(string); /* Yes, this is necessary */
/* Get command line associated with command name */
for (i=0; i<launcher_mappings->nentries; i++)
if (!compare_command_names(command_name,
launcher_mappings->entries[i]))
break;
if (i == launcher_mappings->nentries)
fatal_error("Bug in cb_launch()");
if ((ptr = strchr(launcher_mappings->entries[i], ':')) == NULL)
fatal_error("Bug in cb_launch()");
XtFree(command_name);
raw_command_line = ptr+2;
/* Create list of full paths of selected entries */
for (i=0; i<dirwin->nentries; i++)
if (dirwin->entries[i].state == SELECTED) {
full_path = entry_to_full_path(&dirwin->entries[i]);
add_to_linked_list(&head_selected_entries, full_path);
XtFree(full_path);
}
list = create_array_list(&head_selected_entries);
/* Are %l and/or %s present in command line? */
found_percent = False;
found_percent_s = False;
found_percent_l = False;
len = strlen(raw_command_line);
for (j=0; j<len; j++) {
ch = raw_command_line[j];
if (found_percent) {
switch (ch) {
case 's':
found_percent_s = True;
break;
case 'l':
found_percent_l = True;
}
found_percent = False;
} else if (ch == '%')
found_percent = True;
}
/* Should the command be launched? */
if ((list->nentries == 0) && (found_percent_s || found_percent_l)) {
warn("Can't launch command -- Requires selected entries.",
dirwin->w_shell);
release_array_list(list);
end_op();
return;
}
/* Interpret command line and create actual command line(s) */
if (found_percent_s)
nlaunches = list->nentries;
else
nlaunches = 1;
for (i=nlaunches-1; i>=0; i--) {
found_percent = False;
len = strlen(raw_command_line);
command_line = XtNewString("");
for (j=0; j<len; j++) {
ch = raw_command_line[j];
if (found_percent) {
switch (ch) {
case 'h':
concat(&command_line, hinfo[dirwin->host].hostname);
break;
case 'u':
concat(&command_line, hinfo[dirwin->host].username);
break;
case 's':
concat(&command_line, list->entries[i]);
break;
case 'l':
for (k=0; k<list->nentries; k++) {
concat(&command_line, list->entries[k]);
if (k != list->nentries-1)
concat(&command_line, " ");
}
break;
case 'y':
concat(&command_line,
system_name(hinfo[dirwin->host].system));
break;
case 'v':
concat(&command_line,
server_name(hinfo[dirwin->host].server));
break;
case 'p':
if (hinfo[dirwin->host].password) {
passwrd =
decrypt_password(hinfo[dirwin->host].password);
concat(&command_line, passwrd);
bzero(passwrd, (int)strlen(passwrd));
XtFree(passwrd);
} else
concat(&command_line, "NO_PASSWORD");
break;
default:
buf[0] = ch;
buf[1] = '\0';
concat(&command_line, buf);
}
found_percent = False;
} else if (ch == '%')
found_percent = True;
else {
buf[0] = ch;
buf[1] = '\0';
concat(&command_line, buf);
}
}
if (found_percent)
concat(&command_line, "%");
add_to_linked_list(&head_command_lines, command_line);
XtFree(command_line);
}
/* Construct control block for launch commands */
lc.dirwin = dirwin;
lc.head = head_command_lines;
release_array_list(list);
/* Pop up launch monitor */
show_mp_monitor(dirwin, "Now Launching:");
/* Make operation interruptable */
show_stop_button(dirwin);
/* Launch commands */
XtAppAddWorkProc(app, (XtWorkProc)cb_launch_commands, NULL);
}
/*
* init_launch_menus - Create the popup launch menu and then initialize the
* popup and pulldown launch menus by creating a bunch
* of placeholder menu items.
*/
void
init_launch_menus(dirwin)
struct dirwin_st *dirwin;
{
XmString string;
int i;
Widget w_pulldown;
/* Get pulldown menu */
XtVaGetValues(dirwin->w_launchMenu, XmNsubMenuId, &w_pulldown, NULL);
/* Create popup menu */
dirwin->w_popupLaunchMenu = XmCreatePopupMenu(dirwin->w_drawingArea,
"popup", NULL, 0);
/* Create header for popup menu */
XtVaCreateManagedWidget("popupLaunchMenuLabel", xmLabelGadgetClass,
dirwin->w_popupLaunchMenu, NULL);
XtVaCreateManagedWidget("separator", xmSeparatorGadgetClass,
dirwin->w_popupLaunchMenu, NULL);
XtVaCreateManagedWidget("separator", xmSeparatorGadgetClass,
dirwin->w_popupLaunchMenu, NULL);
/* Now create the menu items, but leave them unmanaged */
string = XmStringCreateSimple("Dummy");
for (i=0; i<MAXLAUNCH; i++) {
dirwin->w_launchMenuItem[i] = XtVaCreateWidget(
"",
xmPushButtonGadgetClass,
w_pulldown,
XmNlabelString, string,
NULL
);
XtAddCallback(dirwin->w_launchMenuItem[i], XmNactivateCallback,
cb_launch, (XtPointer)dirwin);
dirwin->w_popupLaunchMenuItem[i] = XtVaCreateWidget(
"",
xmPushButtonGadgetClass,
dirwin->w_popupLaunchMenu,
XmNlabelString, string,
NULL
);
XtAddCallback(dirwin->w_popupLaunchMenuItem[i], XmNactivateCallback,
cb_launch, (XtPointer)dirwin);
}
XmStringFree(string);
}
/*
* update_all_launch_menus - Update the "Launch" menu in each directory
* window.
*/
void
update_all_launch_menus()
{
struct dirwin_st *dirwin;
dirwin = dirwin_head;
while (dirwin) {
update_launch_menus(dirwin);
dirwin = dirwin->next;
}
}
/*
* update_launch_menus - Update the popup and pulldown launch menus with
* the latest values from the launch preferences.
*/
void
update_launch_menus(dirwin)
struct dirwin_st *dirwin;
{
int i;
XmString label;
char *temp_buf;
char *command_name;
/* Get rid of current launch menus items */
for (i=0; i<MAXLAUNCH; i++) {
XtUnmanageChild(dirwin->w_launchMenuItem[i]);
XtUnmanageChild(dirwin->w_popupLaunchMenuItem[i]);
}
/* Set sensitivity of launch menu */
if (launcher_mappings->nentries)
XtSetSensitive(dirwin->w_launchMenu, True);
else
XtSetSensitive(dirwin->w_launchMenu, False);
/* Enter launch command names into launch menus */
for (i=0; i<launcher_mappings->nentries; i++) {
temp_buf = XtNewString(launcher_mappings->entries[i]);
command_name = strtok(temp_buf, ":");
label = XmStringCreateSimple(command_name);
XtFree(temp_buf);
XtVaSetValues(dirwin->w_launchMenuItem[i], XmNlabelString, label,
NULL);
XtVaSetValues(dirwin->w_popupLaunchMenuItem[i], XmNlabelString, label,
NULL);
XmStringFree(label);
XtManageChild(dirwin->w_launchMenuItem[i]);
XtManageChild(dirwin->w_popupLaunchMenuItem[i]);
}
}
/*
* concat - Concatenates string "s2" to string "s1". "s1" is actually a
* pointer to a string. The original string pointed to by "s1"
* is freed with XtFree(). Use XtFree() to release the memory
* returned in "s2".
*/
void
concat(s1, s2)
char **s1;
char *s2;
{
char *new_s1 = XtMalloc(strlen(*s1)+strlen(s2)+1);
strcpy(new_s1, *s1);
strcat(new_s1, s2);
XtFree(*s1);
*s1 = new_s1;
}
/*
* cb_launch_commands - Work proc to actually launch commands.
*/
cb_launch_commands()
{
struct entry_link *ptr;
int pid;
char *argv[MAXARGV+1];
int argc;
char *cmd;
char *msg;
int saved_errno;
int len;
/* Did user push stop button? */
if (stop()) {
goto abort;
}
/* Are we done? */
if (lc.head == NULL)
goto done;
/* Let user know where we are */
update_mp_monitor(lc.head->entry);
/* Parse execute line into tokens */
cmd = XtNewString(lc.head->entry);
argc = 0;
if ((argv[argc++] = strtok(cmd, " ")) == NULL)
fatal_error("Trouble in cb_launch_commands()");
while (argc < MAXARGV && (argv[argc] = strtok(NULL, " ")) != NULL)
argc++;
if (argc == MAXARGV) {
warn("Can't launch command -- Bad execute line", lc.dirwin->w_shell);
XtFree(cmd);
goto done;
}
/* Fork and exec */
launch_dirwin = lc.dirwin;
if ((pid = fork()) == 0)
if (execvp(argv[0], argv) == -1) {
saved_errno = errno;
msg = XtMalloc(50+strlen(lc.head->entry)+
strlen(sys_errlist[saved_errno]));
sprintf(msg, "Unable to launch command:\n\n%s\n\n", lc.head->entry);
strcat(msg, sys_errlist[saved_errno]);
strcat(msg, "\n\007");
len = strlen(msg);
if (iwrite(child_to_parent_pipe[1], msg, len) != len)
fatal_error("Trouble in cb_launch_commands()");
exit(-1);
}
/* Finished launching this command */
XtFree(cmd);
ptr = lc.head;
lc.head = lc.head->next;
XtFree(ptr->entry);
XtFree((char *)ptr);
sleep(1);
return False;
abort:
hide_mp_monitor();
record_abort("Launch Command");
goto final;
done:
hide_mp_monitor();
final:
/* Miscellaneous cleanup */
release_linked_list(&lc.head);
if (beep_when_ops_done)
beep();
restore_prev_cursor();
/* Signal end of operation */
hide_stop_button();
end_op();
return True;
}
syntax highlighted by Code2HTML, v. 0.9.1