home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
rtsi.com
/
2014.01.www.rtsi.com.tar
/
www.rtsi.com
/
OS9
/
OSK
/
CMDS
/
mtools_3.6.src.lzh
/
MTOOLS_3.6
/
mcopy.c
< prev
next >
Wrap
Text File
|
1997-11-12
|
9KB
|
408 lines
/*
* mcopy.c
* Copy an MSDOS files to and from Unix
*
*/
#define LOWERCASE
#include "sysincludes.h"
#include "msdos.h"
#include "mtools.h"
#include "vfat.h"
#include "mainloop.h"
#include "plain_io.h"
#include "nameclash.h"
#include "file.h"
#include "fs.h"
#ifdef _OSK
#define S_ISDIR(x) (x&S_IFDIR)
#define S_ISREG(x) (!(x&S_IFDIR))
#endif
/*
* Preserve the file modification times after the fclose()
*/
static void set_mtime(const char *target, long mtime)
{
#ifdef HAVE_UTIMES
struct timeval tv[2];
if (mtime != 0L) {
tv[0].tv_sec = mtime;
tv[0].tv_usec = 0;
tv[1].tv_sec = mtime;
tv[1].tv_usec = 0;
utimes(target, tv);
}
#else
#ifdef HAVE_UTIME
struct utimbuf utbuf;
if (mtime != 0L) {
utbuf.actime = mtime;
utbuf.modtime = mtime;
utime(target, &utbuf);
}
#endif
#endif
return;
}
typedef struct Arg_t {
int preserve;
char *target;
int textmode;
int needfilter;
int nowarn;
int single;
int verbose;
int type;
MainParam_t mp;
ClashHandling_t ch;
Stream_t *sourcefile;
Stream_t *targetDir;
} Arg_t;
static int read_file(Stream_t *Dir, MainParam_t *mp, int entry,
int needfilter)
{
Arg_t *arg=(Arg_t *) mp->arg;
long mtime;
Stream_t *File=mp->File;
Stream_t *Target, *Source;
struct stat stbuf;
int ret;
char errmsg[80];
File->Class->get_data(File, &mtime, 0, 0, 0);
if (!arg->preserve)
mtime = 0L;
/* if we are creating a file, check whether it already exists */
if (!arg->nowarn && arg->target && strcmp(arg->target, "-") &&
!access(arg->target, 0)){
if( ask_confirmation("File \"%s\" exists, overwrite (y/n) ? ",
arg->target,0))
return MISSED_ONE;
/* sanity checking */
if (!stat(arg->target, &stbuf) && !S_ISREG(stbuf.st_mode)) {
fprintf(stderr,"\"%s\" is not a regular file\n",
arg->target);
return MISSED_ONE;
}
}
if(!arg->type)
fprintf(stderr,"Copying %s\n", mp->outname);
if(got_signal)
return MISSED_ONE;
if ((Target = SimpleFileOpen(0, 0, arg->target,
O_WRONLY | O_CREAT | O_TRUNC,
errmsg, 0))) {
ret = 0;
if(needfilter && arg->textmode){
Source = open_filter(COPY(File));
if (!Source)
ret = -1;
} else
Source = COPY(File);
if (ret == 0 )
ret = copyfile(Source, Target);
FREE(&Source);
FREE(&Target);
if(ret < -1){
unlink(arg->target);
return MISSED_ONE;
}
if(arg->target && strcmp(arg->target,"-"))
set_mtime(arg->target, mtime);
return GOT_ONE;
} else {
fprintf(stderr,"%s\n", errmsg);
return MISSED_ONE;
}
}
static int dos_read(Stream_t *Dir, MainParam_t *mp, int entry)
{
return read_file(Dir, mp, entry, 1);
}
static int unix_read(char *name, MainParam_t *mp)
{
return read_file(0, mp, -1, 0);
}
/*
* Open the named file for read, create the cluster chain, return the
* directory structure or NULL on error.
*/
static struct directory *writeit(char *dosname,
char *longname,
void *arg0,
struct directory *dir)
{
Stream_t *Target;
time_t now;
int type, fat, ret;
long date;
size_t filesize, newsize;
Arg_t *arg = (Arg_t *) arg0;
if (arg->mp.File->Class->get_data(arg->mp.File,
& date, &filesize, &type, 0) < 0 ){
fprintf(stderr, "Can't stat source file\n");
return NULL;
}
if (type){
if (arg->verbose)
fprintf(stderr, "\"%s\" is a directory\n", longname);
return NULL;
}
if (!arg->single)
fprintf(stderr,"Copying %s\n", longname);
if(got_signal)
return NULL;
/* will it fit? */
if (!getfreeMin(arg->targetDir, filesize)) {
fprintf(stderr,"Disk full\n");
return NULL;
}
/* preserve mod time? */
if (arg->preserve)
now = date;
else
time(&now);
mk_entry(dosname, 0x20, 0, 0, now, dir);
Target = open_file(arg->targetDir, dir);
if(!Target){
fprintf(stderr,"Could not open Target\n");
exit(1);
}
if (arg->needfilter & arg->textmode)
Target = open_filter(Target);
ret = copyfile(arg->mp.File, Target);
GET_DATA(Target, 0, &newsize, 0, &fat);
FREE(&Target);
if(ret < 0 ){
fat_free(arg->targetDir, fat);
return NULL;
} else {
mk_entry(dosname, 0x20, fat, newsize, now, dir);
return dir;
}
}
static int write_file(Stream_t *Dir, MainParam_t *mp, int entry,
int needfilter)
/* write a messy dos file to another messy dos file */
{
int result;
Arg_t * arg = (Arg_t *) (mp->arg);
arg->needfilter = needfilter;
if (arg->targetDir == Dir){
arg->ch.ignore_entry = -1;
arg->ch.source = entry;
} else {
arg->ch.ignore_entry = -1;
arg->ch.source = -2;
}
result = mwrite_one(arg->targetDir, arg->target, 0,
writeit, (void *)arg, &arg->ch);
if(result == 1)
return GOT_ONE;
else
return MISSED_ONE;
}
static int dos_write(Stream_t *Dir, MainParam_t *mp, int entry)
{
return write_file(Dir, mp, entry, 0);
}
static int unix_write(char *name, MainParam_t *mp)
/* write a Unix file to a messy DOS fs */
{
return write_file(0, mp, 0, 1);
}
static void usage(void)
{
fprintf(stderr,
"Mtools version %s, dated %s\n", mversion, mdate);
fprintf(stderr,
"Usage: %s [-tnmvV] sourcefile targetfile\n", progname);
fprintf(stderr,
" %s [-tnmvV] sourcefile [sourcefiles...] targetdirectory\n",
progname);
exit(1);
}
void mcopy(int argc, char **argv, int mtype)
{
Stream_t *SubDir,*Dir;
int have_target;
Arg_t arg;
int c, ret, fastquit;
char filename[VBUFSIZE];
char spareOutname[VBUFSIZE];
struct stat stbuf;
/* get command line options */
init_clash_handling(& arg.ch);
/* get command line options */
arg.preserve = 0;
arg.nowarn = 0;
arg.textmode = 0;
arg.verbose = 0;
arg.type = mtype;
fastquit = 0;
while ((c = getopt(argc, argv, "tnmvorsamQORSAM")) != EOF) {
switch (c) {
case 't':
arg.textmode = 1;
break;
case 'n':
arg.nowarn = 1;
break;
case 'm':
arg.preserve = 1;
break;
case 'v': /* dummy option for mcopy */
arg.verbose = 1;
break;
case 'Q':
fastquit = 1;
break;
case '?':
usage();
default:
if(handle_clash_options(&arg.ch, c))
usage();
break;
}
}
if (argc - optind < 1)
usage();
/* only 1 file to copy... */
arg.single = SINGLE;
init_mp(&arg.mp);
arg.mp.fast_quit = fastquit;
arg.mp.arg = (void *) &arg;
arg.mp.openflags = O_RDONLY;
arg.targetDir = NULL;
if(mtype){
/* Mtype = copying to stdout */
have_target = 0;
arg.target = 0;
arg.mp.outname = filename;
arg.single = 0;
arg.mp.callback = dos_read;
arg.mp.unixcallback = unix_read;
} else if(argc - optind >= 2 &&
argv[argc-1][0] && argv[argc-1][1] == ':'){
/* Copying to Dos */
have_target = 1;
Dir = open_subdir(&arg.mp, argv[argc-1], O_RDWR, 0, 0);
if(!Dir){
fprintf(stderr,"Bad target\n");
exit(1);
}
get_name(argv[argc-1], filename, arg.mp.mcwd);
SubDir = descend(Dir, filename, 0, 0, 0);
if (!SubDir){
/* the last parameter is a file */
if (argc - optind != 2){
fprintf(stderr,
"%s: Too many arguments, or destination directory omitted\n",
argv[0]);
FREE(&Dir);
exit(1);
}
arg.targetDir = Dir;
arg.mp.outname = 0; /* toss away source name */
arg.target = filename; /* store near name given as
* target */
arg.single = 1;
} else {
arg.targetDir = SubDir;
FREE(&Dir);
arg.mp.outname = filename;
arg.target = filename;
arg.single = 0;
}
arg.mp.callback = dos_write;
arg.mp.unixcallback = unix_write;
} else {
/* Copying to Unix */
have_target = 1;
if (argc - optind == 1){
/* one argument: copying to current directory */
arg.single = 0;
have_target = 0;
arg.target = filename;
arg.mp.outname = filename;
} else if (strcmp(argv[argc-1],"-") &&
!stat(argv[argc-1], &stbuf) &&
S_ISDIR(stbuf.st_mode)){
char *tmp;
tmp = (char *) safe_malloc(VBUFSIZE + 1 +
strlen(argv[argc-1]));
strcpy(tmp, argv[argc-1]);
strcat(tmp,"/");
arg.mp.outname = tmp+strlen(tmp);
arg.target = tmp;
} else if (argc - optind != 2) {
/* last argument is not a directory: we should only
* have one source file */
fprintf(stderr,
"%s: Too many arguments or destination directory omitted\n",
argv[0]);
exit(1);
} else {
arg.target = argv[argc-1];
arg.mp.outname = filename;
}
arg.mp.callback = dos_read;
arg.mp.unixcallback = unix_read;
}
if(!arg.mp.outname)
arg.mp.outname = spareOutname;
arg.mp.lookupflags = ACCEPT_PLAIN | DO_OPEN | NO_DOTS | arg.single;
ret=main_loop(&arg.mp, argv + optind, argc - optind - have_target);
FREE(&arg.targetDir);
exit(ret);
}