Initial import of the CDE 2.1.30 sources from the Open Group.
This commit is contained in:
918
cde/programs/dtfile/dtcopy/main_dtcopy.c
Normal file
918
cde/programs/dtfile/dtcopy/main_dtcopy.c
Normal file
@@ -0,0 +1,918 @@
|
||||
/* $TOG: main_dtcopy.c /main/10 1998/10/26 12:42:41 mgreess $ */
|
||||
/************************************<+>*************************************
|
||||
****************************************************************************
|
||||
*
|
||||
* FILE: main_dtcopy.c
|
||||
*
|
||||
* COMPONENT_NAME: dtcopy - Handles move/copy/link operations for 'dtfile'
|
||||
*
|
||||
* DESCRIPTION: Main program for dtfile_copy.
|
||||
*
|
||||
*
|
||||
* FUNCTIONS: AppendErrorMsg
|
||||
* CheckForMap
|
||||
* ConfirmHandler
|
||||
* ErrorHandler
|
||||
* EventCheck
|
||||
* InitNlsMessage
|
||||
* TimeoutHandler
|
||||
* UpdateErrorCount
|
||||
* UpdateStatus
|
||||
* UpdateSummary
|
||||
* get_command_line
|
||||
* main
|
||||
* moveDeleteCallback
|
||||
* moveErrorCallback
|
||||
*
|
||||
* (c) Copyright 1993, 1994, 1995 Hewlett-Packard Company
|
||||
* (c) Copyright 1993, 1994, 1995 International Business Machines Corp.
|
||||
* (c) Copyright 1993, 1994, 1995 Sun Microsystems, Inc.
|
||||
* (c) Copyright 1993, 1994, 1995 Novell, Inc.
|
||||
*
|
||||
****************************************************************************
|
||||
************************************<+>*************************************/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <locale.h>
|
||||
#include <time.h>
|
||||
#include <errno.h>
|
||||
#include <X11/Intrinsic.h>
|
||||
#include <X11/StringDefs.h>
|
||||
#include <Xm/Xm.h>
|
||||
|
||||
/* #Include <X11/Xmu/Editres.h> */ /* for editres debugging tool */
|
||||
|
||||
#include <Dt/Connect.h>
|
||||
#include <Dt/DtNlUtils.h>
|
||||
#include <Dt/EnvControlP.h>
|
||||
|
||||
#include "fsrtns.h"
|
||||
#include "dosync.h"
|
||||
#include "dtcopy.h"
|
||||
#include "sharedFuncs.h"
|
||||
|
||||
|
||||
/*--------------------------------------------------------------------
|
||||
* Global Variables
|
||||
*------------------------------------------------------------------*/
|
||||
|
||||
extern Widget G_toplevel;
|
||||
Widget G_summary_text;
|
||||
Widget G_status_text;
|
||||
/* Widget G_status_text2; */
|
||||
Widget G_error_count;
|
||||
Widget G_error_msgs;
|
||||
Widget G_copy_dialog;
|
||||
Widget G_error_dialog = NULL;
|
||||
Widget G_over_dialog = NULL;
|
||||
Widget G_over_confirm;
|
||||
Widget G_copy_action_area_pbuttons[4];
|
||||
Widget G_help_dialog;
|
||||
Widget G_overwrite_radio;
|
||||
Widget G_rename_text;
|
||||
Widget G_toggle_main;
|
||||
Widget G_toggle_error;
|
||||
|
||||
int G_overwrite_selection = G_OVERWRITE_EXISTING;
|
||||
int G_move = FALSE;
|
||||
int G_do_copy = TRUE;
|
||||
int G_pause_copy = FALSE;
|
||||
int G_user_pause_copy = FALSE;
|
||||
int G_wait_on_error = TRUE;
|
||||
int G_error_status = 0;
|
||||
int G_ignore_errors = FALSE;
|
||||
int G_overwrite_confirm = TRUE;
|
||||
int G_wait_on_input = TRUE;
|
||||
extern int G_dialog_closed;
|
||||
|
||||
char G_rename_oldname[MAX_PATH];
|
||||
char G_source_dir[MAX_PATH];
|
||||
|
||||
/* debugging flag */
|
||||
#ifdef DEBUG
|
||||
int debug = 0;
|
||||
#endif
|
||||
|
||||
static XtAppContext app_context;
|
||||
static Display *display;
|
||||
static Boolean is_mapped = False;
|
||||
static int nfiles = 0;
|
||||
static int ndirs = 0;
|
||||
static int nerr = 0;
|
||||
static char last_dir[MAX_PATH];
|
||||
|
||||
#define FILEOPNUM 14
|
||||
static char *LongFileOpNames[FILEOPNUM];
|
||||
static char *DefaultLongFileOpNames[] = {
|
||||
"processing",
|
||||
"opening",
|
||||
"opening",
|
||||
"opening",
|
||||
"reading link",
|
||||
"deleting",
|
||||
"copying",
|
||||
"creating directory",
|
||||
"copying link",
|
||||
"creating link",
|
||||
"working",
|
||||
"is a copy",
|
||||
"is a link",
|
||||
"renaming"
|
||||
};
|
||||
|
||||
/*--------------------------------------------------------------------
|
||||
* application resource definitions
|
||||
*------------------------------------------------------------------*/
|
||||
|
||||
typedef struct
|
||||
{
|
||||
char *source_name;
|
||||
char *target_name;
|
||||
SyncParams sync;
|
||||
Boolean move;
|
||||
Boolean confirmreplace;
|
||||
Boolean confirmerrors;
|
||||
Boolean popdown;
|
||||
int delay;
|
||||
Boolean use_toggle_buttons;
|
||||
Boolean slow;
|
||||
Boolean checkPerms;
|
||||
} AppArgs, *AppArgsPtr;
|
||||
|
||||
static AppArgs app_args;
|
||||
|
||||
static XtResource resources[] =
|
||||
{
|
||||
/* source and target directories */
|
||||
|
||||
{ "source", "Source", XmRString, sizeof (char *),
|
||||
XtOffset (AppArgsPtr, source_name), XmRImmediate, (XtPointer) NULL, },
|
||||
|
||||
{ "target", "Target", XmRString, sizeof (char *),
|
||||
XtOffset (AppArgsPtr, target_name), XmRImmediate, (XtPointer) NULL, },
|
||||
|
||||
/* SyncParams */
|
||||
|
||||
{ "verbose", "Verbose", XmRBool, sizeof (int),
|
||||
XtOffset (AppArgsPtr, sync.verbose), XmRImmediate, (XtPointer) True, },
|
||||
|
||||
{ "quiet", "Quiet", XmRBool, sizeof (int),
|
||||
XtOffset (AppArgsPtr, sync.quiet), XmRImmediate, (XtPointer) False, },
|
||||
|
||||
{ "dontDoIt", "DontDoIt", XmRBool, sizeof (int),
|
||||
XtOffset (AppArgsPtr, sync.dontdoit), XmRImmediate, (XtPointer) False, },
|
||||
|
||||
|
||||
{ "keepNew", "KeepNew", XmRBool, sizeof (int),
|
||||
XtOffset (AppArgsPtr, sync.keepnew), XmRImmediate, (XtPointer) False, },
|
||||
|
||||
{ "keepOld", "KeepOld", XmRString, sizeof (char *),
|
||||
XtOffset (AppArgsPtr, sync.keepold), XmRImmediate, (XtPointer) NULL, },
|
||||
|
||||
{ "dontDelete", "DontDelete", XmRBool, sizeof (int),
|
||||
XtOffset (AppArgsPtr, sync.dontdelete), XmRImmediate, (XtPointer) False, },
|
||||
|
||||
{ "dontAdd", "DontAdd", XmRBool, sizeof (int),
|
||||
XtOffset (AppArgsPtr, sync.dontadd), XmRImmediate, (XtPointer) False, },
|
||||
|
||||
{ "dontReplace", "DontReplace", XmRBool, sizeof (int),
|
||||
XtOffset (AppArgsPtr, sync.dontreplace),
|
||||
XmRImmediate, (XtPointer) False, },
|
||||
|
||||
{ "dontRecur", "DontRecur", XmRBool, sizeof (int),
|
||||
XtOffset (AppArgsPtr, sync.dontrecur), XmRImmediate, (XtPointer) False, },
|
||||
|
||||
{ "keepLinks", "KeepLinks", XmRBool, sizeof (int),
|
||||
XtOffset (AppArgsPtr, sync.keeplinks), XmRImmediate, (XtPointer) False, },
|
||||
|
||||
{ "keepCopies", "KeepCopies", XmRBool, sizeof (int),
|
||||
XtOffset (AppArgsPtr, sync.keepcopies), XmRImmediate, (XtPointer) False, },
|
||||
|
||||
{ "forceCopies", "ForceCopies", XmRBool, sizeof (int),
|
||||
XtOffset (AppArgsPtr, sync.forcecopies), XmRImmediate, (XtPointer) False, },
|
||||
|
||||
{ "listLinks", "ListLinks", XmRBool, sizeof (int),
|
||||
XtOffset (AppArgsPtr, sync.listlinks), XmRImmediate, (XtPointer) False, },
|
||||
|
||||
{ "listCopies", "ListCopies", XmRBool, sizeof (int),
|
||||
XtOffset (AppArgsPtr, sync.listcopies), XmRImmediate, (XtPointer) False, },
|
||||
|
||||
{ "linkFolders", "LinkFolders", XmRBool, sizeof (int),
|
||||
XtOffset (AppArgsPtr, sync.linkdirs), XmRImmediate, (XtPointer) False, },
|
||||
|
||||
{ "linkFiles", "LinkFiles", XmRBool, sizeof (int),
|
||||
XtOffset (AppArgsPtr, sync.linkfiles), XmRImmediate, (XtPointer) False, },
|
||||
|
||||
{ "copyFolders", "CopyFolders", XmRBool, sizeof (int),
|
||||
XtOffset (AppArgsPtr, sync.copydirs), XmRImmediate, (XtPointer) False, },
|
||||
|
||||
{ "copyFiles", "CopyFiles", XmRBool, sizeof (int),
|
||||
XtOffset (AppArgsPtr, sync.copyfiles), XmRImmediate, (XtPointer) False, },
|
||||
|
||||
{ "copyTop", "CopyTop", XmRBool, sizeof (int),
|
||||
XtOffset (AppArgsPtr, sync.copytop), XmRImmediate, (XtPointer) False, },
|
||||
|
||||
/* other options */
|
||||
|
||||
{ "move", "Move", XmRBoolean, sizeof (Boolean),
|
||||
XtOffset (AppArgsPtr, move), XmRImmediate, (XtPointer) False, },
|
||||
|
||||
{ "confirmReplace", "ConfirmReplace", XmRBoolean, sizeof (Boolean),
|
||||
XtOffset (AppArgsPtr, confirmreplace), XmRImmediate, (XtPointer) False, },
|
||||
|
||||
{ "confirmErrors", "ConfirmErrors", XmRBoolean, sizeof (Boolean),
|
||||
XtOffset (AppArgsPtr, confirmerrors), XmRImmediate, (XtPointer) False, },
|
||||
|
||||
{ "popDown", "PopDown", XmRBoolean, sizeof (Boolean),
|
||||
XtOffset (AppArgsPtr, popdown), XmRImmediate, (XtPointer) False, },
|
||||
|
||||
{ "delay", "Delay", XmRInt, sizeof (int),
|
||||
XtOffset (AppArgsPtr, delay), XmRImmediate, (XtPointer) 5000, }, /* in milliseconds */
|
||||
|
||||
{ "toggle", "Toggle", XmRBoolean, sizeof (Boolean),
|
||||
XtOffset (AppArgsPtr, use_toggle_buttons), XmRImmediate, (XtPointer) True, },
|
||||
{ "slow", "Slow", XmRBoolean, sizeof (Boolean),
|
||||
XtOffset (AppArgsPtr, slow), XmRImmediate, (XtPointer) False, },
|
||||
|
||||
{ "checkPermissions", "CheckPermissions", XmRBoolean, sizeof (Boolean),
|
||||
XtOffset (AppArgsPtr, checkPerms), XmRImmediate, (XtPointer) False, },
|
||||
};
|
||||
|
||||
|
||||
static XrmOptionDescRec option_list[] =
|
||||
{
|
||||
{ "-from", "source", XrmoptionSepArg, NULL },
|
||||
{ "-to", "target", XrmoptionSepArg, NULL },
|
||||
|
||||
{ "-verbose", "verbose", XrmoptionNoArg, "True" },
|
||||
{ "-v", "verbose", XrmoptionNoArg, "True" },
|
||||
{ "-quiet", "quiet", XrmoptionNoArg, "True" },
|
||||
{ "-q", "quiet", XrmoptionNoArg, "True" },
|
||||
{ "-dontDoIt", "dontDoIt", XrmoptionNoArg, "True" },
|
||||
{ "-n", "dontDoIt", XrmoptionNoArg, "True" },
|
||||
|
||||
{ "-keepNew", "keepNew", XrmoptionNoArg, "True" },
|
||||
{ "-kn", "keepNew", XrmoptionNoArg, "True" },
|
||||
{ "-keepOld", "keepOld", XrmoptionSepArg, NULL },
|
||||
{ "-ko", "keepOld", XrmoptionSepArg, NULL },
|
||||
{ "-dontDelete", "dontDelete", XrmoptionNoArg, "True" },
|
||||
{ "-nd", "dontDelete", XrmoptionNoArg, "True" },
|
||||
{ "-dontAdd", "dontAdd", XrmoptionNoArg, "True" },
|
||||
{ "-na", "dontAdd", XrmoptionNoArg, "True" },
|
||||
{ "-dontReplace", "dontReplace", XrmoptionNoArg, "True" },
|
||||
{ "-nr", "dontReplace", XrmoptionNoArg, "True" },
|
||||
{ "-dontRecur", "dontRecur", XrmoptionNoArg, "True" },
|
||||
{ "-nR", "dontRecur", XrmoptionNoArg, "True" },
|
||||
|
||||
{ "-keepLinks", "keepLinks", XrmoptionNoArg, "True" },
|
||||
{ "-kl", "keepLinks", XrmoptionNoArg, "True" },
|
||||
{ "-keepCopies", "keepCopies", XrmoptionNoArg, "True" },
|
||||
{ "-kc", "keepCopies", XrmoptionNoArg, "True" },
|
||||
{ "-forceCopies", "forceCopies", XrmoptionNoArg, "True" },
|
||||
{ "-fc", "forceCopies", XrmoptionNoArg, "True" },
|
||||
{ "-listLinks", "listLinks", XrmoptionNoArg, "True" },
|
||||
{ "-ll", "listLinks", XrmoptionNoArg, "True" },
|
||||
{ "-listCopies", "listCopies", XrmoptionNoArg, "True" },
|
||||
{ "-lc", "listCopies", XrmoptionNoArg, "True" },
|
||||
{ "-linkFolders", "linkFolders", XrmoptionNoArg, "True" },
|
||||
{ "-ld", "linkFolders", XrmoptionNoArg, "True" },
|
||||
{ "-linkFiles", "linkFiles", XrmoptionNoArg, "True" },
|
||||
{ "-lf", "linkFiles", XrmoptionNoArg, "True" },
|
||||
{ "-copyFolders", "copyFolders", XrmoptionNoArg, "True" },
|
||||
{ "-cd", "copyFolders", XrmoptionNoArg, "True" },
|
||||
{ "-copyFiles", "copyFiles", XrmoptionNoArg, "True" },
|
||||
{ "-cf", "copyFiles", XrmoptionNoArg, "True" },
|
||||
{ "-copyTop", "copyTop", XrmoptionNoArg, "True" },
|
||||
{ "-ct", "copyTop", XrmoptionNoArg, "True" },
|
||||
|
||||
{ "-move", "move", XrmoptionNoArg, "True" },
|
||||
{ "-mv", "move", XrmoptionNoArg, "True" },
|
||||
{ "-confirmReplace", "confirmReplace", XrmoptionNoArg, "True" },
|
||||
{ "-cr", "confirmReplace", XrmoptionNoArg, "True" },
|
||||
{ "-confirmErrors", "confirmErrors", XrmoptionNoArg, "True" },
|
||||
{ "-ce", "confirmErrors", XrmoptionNoArg, "True" },
|
||||
{ "-popDown", "popDown", XrmoptionNoArg, "True" },
|
||||
{ "-delay", "delay", XrmoptionSepArg, NULL },
|
||||
{ "-slow", "slow", XrmoptionNoArg, "True" },
|
||||
{ "-toggle", "toggle", XrmoptionNoArg, "True" },
|
||||
{ "-notoggle", "toggle", XrmoptionNoArg, "False" },
|
||||
{ "-checkPerms", "checkPermissions",XrmoptionNoArg, "True" },
|
||||
};
|
||||
|
||||
|
||||
/*--------------------------------------------------------------------
|
||||
* display update functions
|
||||
*------------------------------------------------------------------*/
|
||||
|
||||
static void
|
||||
UpdateSummary(void)
|
||||
{
|
||||
XmString xs;
|
||||
char msg[1024];
|
||||
char files[128];
|
||||
char dirs[128];
|
||||
int new_nfiles = nfiles, new_ndirs = ndirs;
|
||||
|
||||
if (nfiles == 1)
|
||||
strcpy(files, GETMESSAGE(2, 3, "file"));
|
||||
else
|
||||
strcpy(files, GETMESSAGE(2, 4, "files"));
|
||||
|
||||
if (ndirs == 1)
|
||||
strcpy(dirs, GETMESSAGE(2, 5, "subfolder"));
|
||||
else
|
||||
strcpy(dirs, GETMESSAGE(2, 6, "subfolders"));
|
||||
|
||||
if ( nfiles < 0 )
|
||||
new_nfiles = 0;
|
||||
if ( ndirs < 0 )
|
||||
new_ndirs = 0;
|
||||
sprintf(msg, "%4d %s\n%4d %s", new_nfiles, files, new_ndirs, dirs);
|
||||
|
||||
xs = XmStringCreateLocalized(msg);
|
||||
XtVaSetValues (G_summary_text,
|
||||
XmNlabelString, xs,
|
||||
NULL);
|
||||
XmStringFree(xs);
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
UpdateStatus(
|
||||
char *msg1,
|
||||
char *msg2)
|
||||
{
|
||||
|
||||
String msg;
|
||||
String pad;
|
||||
const String ellipsis="...";
|
||||
const int lenEllipsis = 3;
|
||||
int lenSourceDir, lenMsg, lenMsg2, numBlanks;
|
||||
static int maxMsg = -1;
|
||||
|
||||
DPRINTF(("%s %s\n",msg1,msg2));
|
||||
/*
|
||||
XtUnmanageChild(G_status_text2);
|
||||
|
||||
XtVaSetValues (G_status_text,
|
||||
XmNvalue, msg1,
|
||||
XmNcursorPosition, 0,
|
||||
NULL);
|
||||
|
||||
XtVaSetValues (G_status_text2,
|
||||
XmNvalue, msg2,
|
||||
NULL);
|
||||
|
||||
XtManageChild(G_status_text2);
|
||||
|
||||
XtVaSetValues (G_status_text2,
|
||||
XmNcursorPosition, strlen(msg2),
|
||||
NULL);
|
||||
*/
|
||||
|
||||
/* The pathname is truncated, if possible, by replacing */
|
||||
/* the name of the source directory with "...". Thus, */
|
||||
/* when copying /u/joeuser/mydir/myfile, the pathanme */
|
||||
/* is written as .../myfile */
|
||||
|
||||
lenSourceDir = strlen(G_source_dir);
|
||||
lenMsg2 = strlen(msg2);
|
||||
if ( (strncmp(G_source_dir,msg2,lenSourceDir) == 0) &&
|
||||
(lenMsg2 > lenSourceDir) )
|
||||
{
|
||||
msg = XtMalloc(strlen(msg1) + lenEllipsis + (lenMsg2 - lenSourceDir) + 2);
|
||||
sprintf(msg, "%s %s%s", msg1, ellipsis, msg2+lenSourceDir);
|
||||
}
|
||||
else
|
||||
{
|
||||
msg = XtMalloc(strlen(msg1) + lenMsg2 + 2);
|
||||
sprintf(msg, "%s %s", msg1, msg2);
|
||||
}
|
||||
|
||||
/* In order to minimize re-sizing of the dialog, the */
|
||||
/* length of the message is not allowed to decrease. */
|
||||
/* Blanks are added to the end of shorter messages. */
|
||||
|
||||
lenMsg = strlen(msg);
|
||||
maxMsg = (maxMsg > lenMsg) ? maxMsg : lenMsg; /* MAX(maxMsg,lenMsg) */
|
||||
if (lenMsg < maxMsg)
|
||||
{
|
||||
numBlanks = maxMsg - lenMsg;
|
||||
pad = XtMalloc(numBlanks+1);
|
||||
memset(pad,' ',numBlanks);
|
||||
pad[numBlanks] = '\0';
|
||||
msg = XtRealloc(msg,maxMsg+1);
|
||||
strcat(msg,pad);
|
||||
XtFree(pad);
|
||||
}
|
||||
|
||||
|
||||
XmTextFieldSetString(G_status_text, msg);
|
||||
|
||||
XtFree(msg);
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
UpdateErrorCount(void)
|
||||
{
|
||||
char msg[128];
|
||||
|
||||
if (nerr == 0)
|
||||
strcpy(msg, GETMESSAGE(2, 7, "Errors: none"));
|
||||
else
|
||||
sprintf(msg, GETMESSAGE(2, 8, "Errors: %d"), nerr);
|
||||
|
||||
/* for the first error, manage the widgets used to display errors */
|
||||
if (nerr == 1)
|
||||
{
|
||||
XtVaSetValues(G_status_text,
|
||||
XmNbottomAttachment, XmATTACH_NONE,
|
||||
NULL);
|
||||
/*
|
||||
XtVaSetValues(G_status_text2,
|
||||
XmNbottomAttachment, XmATTACH_NONE,
|
||||
NULL);
|
||||
*/
|
||||
XtManageChild(G_error_count);
|
||||
XtManageChild(G_error_msgs);
|
||||
XtManageChild(XtParent(G_error_msgs));
|
||||
}
|
||||
|
||||
XtVaSetValues (G_error_count,
|
||||
XmNvalue, msg,
|
||||
XmNcursorPosition, 0,
|
||||
NULL);
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
AppendErrorMsg(char *msg)
|
||||
{
|
||||
XmTextPosition pos;
|
||||
|
||||
pos = XmTextGetLastPosition (G_error_msgs);
|
||||
XmTextInsert (G_error_msgs, pos, msg);
|
||||
XmTextSetInsertionPosition (G_error_msgs, pos);
|
||||
XmTextShowPosition (G_error_msgs, pos);
|
||||
}
|
||||
|
||||
|
||||
/*--------------------------------------------------------------------
|
||||
* Callback functions
|
||||
*------------------------------------------------------------------*/
|
||||
|
||||
/* ARGSUSED */
|
||||
static void
|
||||
CheckForMap(
|
||||
Widget w,
|
||||
XtPointer client_data,
|
||||
XEvent *event,
|
||||
Boolean *cont)
|
||||
/* set a flag when the main window is mapped */
|
||||
{
|
||||
if (event->type == MapNotify)
|
||||
is_mapped = True;
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
EventCheck(void)
|
||||
/* process X events until there are no more pending events queued */
|
||||
{
|
||||
XEvent event;
|
||||
unsigned long pend_result;
|
||||
|
||||
for (;;) {
|
||||
if (!G_pause_copy) {
|
||||
/* check if there are any X events */
|
||||
if (!(XtAppPending(app_context) & XtIMXEvent)) {
|
||||
/* maybe more events are "in the pipe" */
|
||||
XSync(XtDisplay(G_toplevel), False);
|
||||
if (!(XtAppPending(app_context) & XtIMXEvent))
|
||||
break;
|
||||
}
|
||||
}
|
||||
/* get the next event and process it */
|
||||
XtAppNextEvent(app_context, &event);
|
||||
XtDispatchEvent(&event);
|
||||
}
|
||||
|
||||
/* if the user clicked on the Cancel button and Warning 'yes' btn, abort the copy */
|
||||
if (G_do_copy)
|
||||
return 0;
|
||||
else {
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
ErrorHandler(FileOp op, char *fname, int errnum)
|
||||
{
|
||||
char msg[2048];
|
||||
|
||||
/* increment the error count */
|
||||
nerr++;
|
||||
UpdateErrorCount();
|
||||
|
||||
/* don't count this file as one that has been copied */
|
||||
nfiles--;
|
||||
UpdateSummary();
|
||||
|
||||
/* add error message to error_msgs */
|
||||
sprintf(msg, "%s: %s\n", fname, strerror(errnum));
|
||||
AppendErrorMsg(msg);
|
||||
|
||||
XmUpdateDisplay(G_toplevel);
|
||||
|
||||
/* Initialize the error status variable. It will be set if the user */
|
||||
/* has chosen not to ignore errors */
|
||||
G_error_status = 0;
|
||||
|
||||
if (!G_ignore_errors)
|
||||
{
|
||||
create_error_dialog(G_toplevel, LongFileOpNames[op], fname, errnum);
|
||||
|
||||
G_wait_on_input = TRUE;
|
||||
while (G_wait_on_input)
|
||||
EventCheck();
|
||||
}
|
||||
|
||||
return (G_error_status);
|
||||
}
|
||||
|
||||
|
||||
|
||||
static int
|
||||
ConfirmHandler(
|
||||
FileOp op,
|
||||
char *sname,
|
||||
int stype,
|
||||
char *tname,
|
||||
int ttype,
|
||||
char *link)
|
||||
{
|
||||
char msg[1024];
|
||||
Arg args[5];
|
||||
Boolean is_overwrite = False;
|
||||
Boolean overwrite_dialog = False; /* was overwrite dialog invoked? */
|
||||
char *fname;
|
||||
int rc = 0;
|
||||
SyncParams sync;
|
||||
|
||||
/* update copy counts */
|
||||
if (op == op_sync)
|
||||
{
|
||||
ndirs++;
|
||||
strcpy(last_dir, sname);
|
||||
UpdateSummary();
|
||||
}
|
||||
else if (op == op_copy || op == op_cplink || op == op_mklink)
|
||||
{
|
||||
if (ttype != ft_noent)
|
||||
is_overwrite = True;
|
||||
if (!is_overwrite)
|
||||
{
|
||||
nfiles++;
|
||||
UpdateSummary();
|
||||
}
|
||||
}
|
||||
|
||||
/* display a message that tells the user what we are working on */
|
||||
if (op == op_delete || op == op_mkdir)
|
||||
UpdateStatus(LongFileOpNames[op], tname);
|
||||
else
|
||||
UpdateStatus(LongFileOpNames[op], sname);
|
||||
|
||||
XmUpdateDisplay(G_toplevel);
|
||||
|
||||
|
||||
if (is_overwrite) {
|
||||
|
||||
/* target already exists and would be replaced */
|
||||
|
||||
/* if confirmation is turned on, ask the user */
|
||||
/* set overwrite_dialog so we know if the user was prompted for this file */
|
||||
/* Otherwise, G_overwrite_selection is either the default or was set */
|
||||
/* by the user in a prior invocation of the overwrite dialog */
|
||||
if (G_overwrite_confirm)
|
||||
{
|
||||
overwrite_dialog = TRUE;
|
||||
create_overwrite_dialog (G_toplevel, sname, tname, ttype & ft_isdir);
|
||||
|
||||
G_wait_on_input = TRUE;
|
||||
while (G_wait_on_input)
|
||||
EventCheck();
|
||||
|
||||
}
|
||||
|
||||
if (G_overwrite_selection != G_SKIP)
|
||||
{
|
||||
nfiles++;
|
||||
UpdateSummary();
|
||||
XmUpdateDisplay(G_toplevel);
|
||||
}
|
||||
|
||||
switch (G_overwrite_selection)
|
||||
{
|
||||
case G_OVERWRITE_EXISTING:
|
||||
rc = 0;
|
||||
break;
|
||||
|
||||
case G_RENAME_EXISTING: /* i.e. move clashing target */
|
||||
if (!overwrite_dialog)
|
||||
{
|
||||
if (auto_rename(tname) == 0)
|
||||
{
|
||||
touch(tname); /* SyncDirectory complains if the file is gone */
|
||||
rc = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
ErrorHandler(op_rename, tname, errno);
|
||||
rc = 1; /* do not do the copy */
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
rc = 0;
|
||||
}
|
||||
break;
|
||||
|
||||
case G_SKIP:
|
||||
rc = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (app_args.slow) {
|
||||
XFlush(XtDisplay(G_toplevel));
|
||||
XSync(XtDisplay(G_toplevel), False);
|
||||
sleep(1);
|
||||
}
|
||||
|
||||
return (rc);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* moveDeleteCallback, moveErrorCallback:
|
||||
* called if "-move" option was given, when the
|
||||
* source directory is deleted after a successful copy.
|
||||
*/
|
||||
|
||||
static int
|
||||
moveDeleteCallback(char *fname)
|
||||
{
|
||||
return ConfirmHandler(op_delete, "", ft_noent, fname, 0, "");
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
moveErrorCallback(char *fname, int errnum)
|
||||
{
|
||||
return ErrorHandler(op_delete, fname, errnum);
|
||||
}
|
||||
|
||||
|
||||
/*--------------------------------------------------------------------
|
||||
* Get command line arguments
|
||||
*------------------------------------------------------------------*/
|
||||
|
||||
static int
|
||||
get_command_line(int argc, char *argv[])
|
||||
{
|
||||
int i = 1;
|
||||
|
||||
#define USAGE \
|
||||
"Usage: %s [options ...] source target\n"
|
||||
|
||||
/* get source & target directory, if not yet set */
|
||||
|
||||
if (app_args.source_name == NULL && i < argc)
|
||||
app_args.source_name = argv[i++];
|
||||
|
||||
if (app_args.target_name == NULL && i < argc)
|
||||
app_args.target_name = argv[i++];
|
||||
|
||||
/*
|
||||
* There should be no more arguments left, and
|
||||
* source & target directory should be set
|
||||
*/
|
||||
|
||||
if (i < argc ||
|
||||
app_args.source_name == NULL ||
|
||||
app_args.target_name == NULL)
|
||||
{
|
||||
fprintf(stderr, GETMESSAGE(2, 10, USAGE), argv[0]);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
|
||||
/*--------------------------------------------------------------------
|
||||
* Initialize LongFileOpNames by message catalog.
|
||||
*------------------------------------------------------------------*/
|
||||
|
||||
static void
|
||||
InitNlsMessage(void)
|
||||
{
|
||||
int i;
|
||||
char *msg;
|
||||
|
||||
for (i = 0; i < FILEOPNUM; i++) {
|
||||
msg = GETMESSAGE(2, i + 20, DefaultLongFileOpNames[i]);
|
||||
LongFileOpNames[i] = XtNewString(msg);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*--------------------------------------------------------------------
|
||||
* Main
|
||||
*------------------------------------------------------------------*/
|
||||
|
||||
void
|
||||
main(int argc, char *argv[])
|
||||
{
|
||||
char msg[1024];
|
||||
XEvent event;
|
||||
Arg args[3];
|
||||
int rc, n,perm_status=0;
|
||||
char * tmpStr;
|
||||
|
||||
Boolean copy_status;
|
||||
|
||||
_DtEnvControl(DT_ENV_SET);
|
||||
XtSetLanguageProc(NULL, NULL, NULL);
|
||||
|
||||
/* initialize debugging flag */
|
||||
#ifdef DEBUG
|
||||
if ((tmpStr = getenv("DTFILE_DEBUG")) != NULL)
|
||||
{
|
||||
debug = atoi(tmpStr);
|
||||
if (debug <= 0)
|
||||
debug = 1;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Initialize the toolkit and Open the Display */
|
||||
n=0;
|
||||
XtSetArg (args[n], XmNmappedWhenManaged, FALSE); n++;
|
||||
|
||||
G_toplevel = XtAppInitialize(&app_context,
|
||||
"Dtfile", /* Dtcopy is considered part of Dtfile */
|
||||
option_list, XtNumber(option_list),
|
||||
&argc, argv, NULL, args, n);
|
||||
|
||||
InitNlsMessage();
|
||||
|
||||
XtGetApplicationResources(G_toplevel, &app_args,
|
||||
resources, XtNumber(resources), NULL, 0);
|
||||
|
||||
/* add support for editres debugging tool */
|
||||
/* XtAddEventHandler(G_toplevel, (EventMask) 0, True, _XEditResCheckMessages, NULL); */
|
||||
|
||||
/* Get the source and destination directories */
|
||||
get_command_line(argc,argv);
|
||||
CheckDeleteAccess(app_context,app_args.delay,app_args.checkPerms,
|
||||
app_args.move,app_args.source_name);
|
||||
G_ignore_errors = !app_args.confirmerrors;
|
||||
G_overwrite_confirm = app_args.confirmreplace;
|
||||
G_move = app_args.move;
|
||||
|
||||
/* Set resources for the shell */
|
||||
n = 0;
|
||||
XtSetArg(args[n], XmNallowShellResize, TRUE); n++;
|
||||
if (G_move)
|
||||
{
|
||||
XtSetArg(args[n], XmNtitle, GETMESSAGE(2, 11, "File Manager - Folder Move"));
|
||||
n++;
|
||||
}
|
||||
else
|
||||
{
|
||||
XtSetArg(args[n], XmNtitle, GETMESSAGE(2, 12, "File Manager - Folder Copy"));
|
||||
n++;
|
||||
}
|
||||
|
||||
XtSetValues(G_toplevel, args, n);
|
||||
|
||||
/* Initialize images for error, warning, ... icons */
|
||||
ImageInitialize(XtDisplay(G_toplevel));
|
||||
|
||||
/* Create The Copy Directory Dialog */
|
||||
copy_status = create_copydir_dialog(G_toplevel, app_args.source_name,
|
||||
app_args.target_name);
|
||||
|
||||
if(copy_status == False)
|
||||
{
|
||||
XtRealizeWidget(G_toplevel);
|
||||
XtAppAddTimeOut(app_context, app_args.delay, TimeoutHandler, NULL);
|
||||
|
||||
/* wait for user to close the dialog before exiting */
|
||||
while (!G_dialog_closed)
|
||||
{
|
||||
XtAppNextEvent(app_context, &event);
|
||||
XtDispatchEvent(&event);
|
||||
}
|
||||
exit (-1);
|
||||
}
|
||||
|
||||
/* initialize status, error count, etc ... */
|
||||
sensitize_copy_action_area(G_copy_action_area_pbuttons);
|
||||
nfiles = 0;
|
||||
ndirs = -1; /* -1 so the source folder does not get counted, only subfolders */
|
||||
UpdateSummary();
|
||||
nerr = 0;
|
||||
UpdateErrorCount();
|
||||
|
||||
/* Realize the top level Widget */
|
||||
XtRealizeWidget(G_toplevel);
|
||||
XtMapWidget(G_toplevel);
|
||||
|
||||
/*
|
||||
* Wait for the top level Widget to be mapped.
|
||||
* Reason: The routine for selecting a window position for popup windows
|
||||
* (error and overwrite warning dialogs) won't work until the main window
|
||||
* is mapped. Therefore, we don't want to start the actual copy operation
|
||||
* (which might generate error or warning messages) before the main window
|
||||
* is mapped.
|
||||
*/
|
||||
XtAddEventHandler(G_toplevel, StructureNotifyMask, False, CheckForMap, NULL);
|
||||
while (!is_mapped)
|
||||
EventCheck();
|
||||
XtRemoveEventHandler(G_toplevel, XtAllEvents, True, CheckForMap, NULL);
|
||||
|
||||
/* Set up the Callbacks for the copy operation */
|
||||
periodicCallback = EventCheck;
|
||||
syncConfirmCallback = ConfirmHandler;
|
||||
syncErrorCallback = ErrorHandler;
|
||||
|
||||
/* set up parameters for the copy operation */
|
||||
app_args.sync.source = app_args.source_name; /* source directory */
|
||||
app_args.sync.target = app_args.target_name; /* target directory */
|
||||
app_args.sync.verbose++;
|
||||
strcpy(last_dir, app_args.sync.source);
|
||||
|
||||
/*
|
||||
* Call the Copy Function. This copy function will look at the
|
||||
* even queue and see if there are any pending events. If so,
|
||||
* it will dispatch these events and then resume the copy
|
||||
* operation. The function will return after the copy operation
|
||||
* has completed or when the user aborts the operation by
|
||||
* clicking the "Cancel" button.
|
||||
*/
|
||||
SyncDirectory(&app_args.sync);
|
||||
|
||||
/* if move was requested and the copy was successful, delete the source now */
|
||||
if (G_move)
|
||||
{
|
||||
if (nerr > 0)
|
||||
{
|
||||
sprintf(msg, GETMESSAGE(2, 13, "%s not removed because of errors."),
|
||||
app_args.sync.source);
|
||||
AppendErrorMsg(msg);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* arrange for callback's during recursive directory delete */
|
||||
progressCallback = moveDeleteCallback;
|
||||
errorCallback = moveErrorCallback;
|
||||
|
||||
/* delete the source directory */
|
||||
fsErase(app_args.sync.source, &rc, True);
|
||||
}
|
||||
}
|
||||
|
||||
/* display the result */
|
||||
if (G_do_copy)
|
||||
UpdateStatus(GETMESSAGE(2, 14, "Completed."), "");
|
||||
else
|
||||
UpdateStatus(GETMESSAGE(2, 15, "Cancelled in"), last_dir);
|
||||
|
||||
XtVaSetValues (G_error_msgs,
|
||||
XmNcursorPosition, 0,
|
||||
XmNtopCharacter, 0,
|
||||
NULL);
|
||||
|
||||
/* desensitize the copy area */
|
||||
desensitize_copy_action_area(G_copy_action_area_pbuttons);
|
||||
|
||||
/* if successful popdown the window after a delay */
|
||||
if (app_args.popdown && nerr == 0)
|
||||
XtAppAddTimeOut(app_context, app_args.delay, TimeoutHandler, NULL);
|
||||
|
||||
/* wait for user to close the dialog before exiting */
|
||||
while (!G_dialog_closed)
|
||||
{
|
||||
XtAppNextEvent(app_context, &event);
|
||||
XtDispatchEvent(&event);
|
||||
}
|
||||
|
||||
exit(nerr);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user