/***************************************************************************/
/***************************************************************************/
/* */
/* (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 <Xm/SelectioB.h>
#include <Xm/LabelG.h>
#include <Xm/Form.h>
#include "xdir.h"
#include "list.h"
#include "str.h"
static struct {
int recursive; /* Requires initialization */
int level; /* Requires initialization */
struct dirwin_st *dirwin; /* Requires initialization */
struct entry_link *head[MAXLEVELS]; /* Requires initialization */
int error; /* Requires initialization */
int asked_user; /* Requires initialization */
char *rel_path;
char *full_path;
} dc;
static char *del_question = "You are attempting to delete a (possibly nonempty)\ndirectory, but the general preference DELETE MODE\nis set to NONRECURSIVE.\n\nDelete nonempty directories anyway?";
static char *msg1 = "Unable to redisplay directory.\n\nDirectory window might be out of date.";
extern struct st_host_info hinfo[];
extern int beep_when_ops_done;
extern Widget w_toplev;
extern int diagnostics;
extern int inquire_on_delete;
extern XtAppContext app;
extern int rdelete_mode;
char *merge_paths();
char *links_to_path();
int cb_delete_entries();
char **path_to_links();
/*
* cb_delete - Callback that deletes selected file(s).
*/
void
cb_delete(widget, client_data, call_data)
Widget widget;
XtPointer client_data;
XtPointer call_data;
{
struct dirwin_st *dirwin = (struct dirwin_st *)client_data;
struct entry_link *head;
struct entry_link *tail;
int i;
int retval;
/* Start operation */
if (!start_op(True))
return;
/* Clear error flag */
raise_okflag();
/* Ask the user if okay to delete? */
if (inquire_on_delete) {
if (!verify_selection(dirwin, dirwin,
"Do you really want to delete these entries?")) {
end_op();
return;
}
}
/* Make operation interruptable */
show_stop_button(dirwin);
/* This might take some time */
use_busy_cursor();
/* Make sure connection is still good */
if (dirwin->host != LOCAL) {
retval = check_connection(dirwin->host, dirwin);
if (retval < 0) {
restore_prev_cursor();
switch (retval) {
case -6:
record_abort("Delete Entries");
break;
case -1:
record_and_alert("Unable to delete entries.", dirwin->w_shell);
}
hide_stop_button();
end_op();
return;
}
}
/* Form list of selected items to delete */
head = NULL;
tail = NULL;
for (i=0; i<dirwin->nentries; i++)
if (dirwin->entries[i].level == 0)
postorder_selected_items(&dirwin->entries[i], &head, &tail);
/* Set up deletion control block */
dc.recursive = rdelete_mode;
dc.level = 0;
dc.dirwin = dirwin;
dc.head[0] = head;
dc.error = False;
dc.asked_user = False;
/* Perform deletion */
show_mp_monitor(dirwin, "Now Deleting:");
XtAppAddWorkProc(app, (XtWorkProc)cb_delete_entries, NULL);
}
/*
* cb_delete_entries - Work procedure for executing deletion request.
* State information is kept in "dc", the
* deletion control block data structure.
*/
cb_delete_entries()
{
static char *del_error_msg =
"Unable to delete entry(s). Can't get directory list.";
struct entry_link *ptr;
struct sl_struct *list;
int retval;
int len;
int i;
int is_a_directory;
char msg[MAXPATHLEN+40];
int already_handled_dir = False;
char **rel_path_links;
int nlinks;
char **link_ptr;
int indx;
char **first_path_links;
char **p;
char *dir;
dc.full_path = NULL;
dc.rel_path = NULL;
/* Did user push stop button? */
if (stop())
goto abort;
/* Is there more to do? */
if (dc.head[dc.level] == NULL) {
if (dc.level == 0) {
if (dc.error)
record_and_alert("At least one deletion failed.",
dc.dirwin->w_shell);
goto done;
} else {
dc.level--;
already_handled_dir = True;
}
}
/* Build relative path name */
first_path_links = path_to_links(hinfo[dc.dirwin->host].system,
dc.head[0]->entry);
nlinks = 0;
link_ptr = first_path_links;
while (*link_ptr++)
nlinks++;
nlinks += dc.level;
rel_path_links = (char **)XtMalloc(sizeof(char *)*(nlinks+1));
indx = 0;
p = first_path_links;
while (*p) {
rel_path_links[indx++] = XtNewString(*p);
p++;
}
release_path_links(first_path_links);
for (i=1; i<=dc.level; i++)
rel_path_links[indx++] = XtNewString(dc.head[i]->entry);
rel_path_links[nlinks] = NULL;
dc.rel_path = links_to_path(hinfo[dc.dirwin->host].system, rel_path_links,
nlinks);
release_path_links(rel_path_links);
/* Build full path name */
dc.full_path = merge_paths(hinfo[dc.dirwin->host].system,
dc.dirwin->dirname, dc.rel_path);
/* Handle recursion */
if (!already_handled_dir) {
if (dc.recursive || !dc.asked_user) {
/* Test for directory by trying to cd to it */
is_a_directory = False;
if (dc.dirwin->host == LOCAL) {
if (local_cd(dc.full_path, False) == 0)
is_a_directory = True;
} else
switch (remote_cd(dc.dirwin->host, dc.full_path, False)) {
case -6:
goto abort;
case -3:
goto lost;
case 0:
is_a_directory = True;
}
if (is_a_directory) {
if (!dc.recursive) {
beep();
if (question_dialog(del_question, dc.dirwin->w_shell))
dc.recursive = True;
dc.asked_user = True;
}
if (dc.recursive) {
/* Get directory list */
switch (get_dirlist(dc.dirwin->host, dc.full_path, TABULAR,
True, False, False, &list)) {
case -6:
goto abort;
case -3:
goto lost;
case -1:
record_and_alert(del_error_msg, dc.dirwin->w_shell);
goto done;
}
/* Add directory list to new level */
dc.level++;
if (dc.level == MAXLEVELS) {
record_and_alert(
"Deletion(s) aborted. Recursion too deep.",
dc.dirwin->w_shell);
goto done;
}
dc.head[dc.level] = NULL;
for (i=list->nentries-1; i>=0; i--) {
ptr = XtNew(struct entry_link);
ptr->entry = XtNewString(list->entries[i]);
ptr->next = dc.head[dc.level];
dc.head[dc.level] = ptr;
}
release_array_list(list);
XtFree(dc.full_path);
XtFree(dc.rel_path);
return False;
}
}
}
}
/* Delete next directory entry */
update_mp_monitor(dc.rel_path);
if (dc.dirwin->host == LOCAL)
retval = local_delete(dc.full_path);
else {
flush_cache_directory(dc.dirwin->host, dc.full_path);
parse_path(hinfo[dc.dirwin->host].system, dc.full_path, &dir, NULL);
flush_cache_directory(dc.dirwin->host, dir);
XtFree(dir);
len = strlen(dc.full_path);
if ((hinfo[dc.dirwin->host].system == SYS_VMS)
&& (dc.full_path[len-1] == ']'))
retval = remote_rmdir(dc.dirwin->host, dc.full_path);
else if (hinfo[dc.dirwin->host].server == SERVER_MAC_FTPD ||
hinfo[dc.dirwin->host].server == SERVER_WINDOWS_WFTPD ||
hinfo[dc.dirwin->host].server == SERVER_NT)
switch (remote_cd(dc.dirwin->host, dc.full_path, False)) {
case -6:
goto abort;
case -3:
goto lost;
case 0:
retval = remote_rmdir(dc.dirwin->host, dc.full_path);
break;
default:
retval = remote_delete(dc.dirwin->host, dc.full_path);
}
else
retval = remote_delete(dc.dirwin->host, dc.full_path);
}
switch (retval) {
case -6:
goto abort;
case -3:
goto lost;
case -1:
sprintf(msg, "Unable to delete %s.", dc.rel_path);
record_warning(msg);
dc.error = True;
break;
case 0:
if (diagnostics >= NORMAL) {
sprintf(msg, "*** Successfully deleted: %s\n", dc.rel_path);
write_log(msg);
}
}
XtFree(dc.full_path);
XtFree(dc.rel_path);
ptr = dc.head[dc.level];
dc.head[dc.level] = ptr->next;
XtFree(ptr->entry);
XtFree((char *)ptr);
return False;
abort:
hide_mp_monitor();
record_abort("Delete Entries");
write_log("*** Deletion(s) aborted.");
dirwin_out_of_date_alert(dc.dirwin);
goto final;
done:
hide_mp_monitor();
retval = display_dir(dc.dirwin->host, dc.dirwin, dc.dirwin->dirname, True,
False, dc.dirwin->cache_mode, False);
switch (retval) {
case -6:
record_abort("Delete Entries");
write_log("*** Deletion(s) aborted.");
dirwin_out_of_date_alert(dc.dirwin);
break;
case -3:
restore_lost_connection(dc.dirwin->host, dc.dirwin);
break;
case -1:
record_and_alert(msg1, dc.dirwin->w_shell);
}
goto final;
lost:
hide_mp_monitor();
restore_lost_connection(dc.dirwin->host, dc.dirwin);
final:
/* Clean up the deletion control block data structure */
XtFree(dc.rel_path);
dc.rel_path = NULL;
XtFree(dc.full_path);
dc.full_path = NULL;
for(i=0; i<=dc.level; i++)
release_linked_list(&dc.head[i]);
/* Miscellaneous cleanup */
clear_selected_entries();
update_dir_controls();
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