Category : Utilities for DOS and Windows Machines
Archive   : COPPY36.ZIP
Filename : COPPY.C

 
Output of file : COPPY.C contained in archive : COPPY36.ZIP
/*
** COPPY -- Copies files from a DIRLIST to floppy disks
** fitting as many files by size as it can.
**
** Thomas A. Lundin
** Graphics Unlimited Inc.
** 3000 Second Street North
** Minneapolis, MN 55411
** (612) 588-7571
**
** Version 1.0 -- Turbo C
** 11/05/87 version 3.0
** 12/30/87 version 3.1 clean up some of the path calls
** 1/06/88 version 3.2 infinite loop bug fixed
** 1/07/88 version 3.3 added -w switch
** 3/08/88 version 3.4 couple of glitches fixed
** 12/18/88 version 3.5 more precise requirement calculations
** 12/19/88 version 3.6 -m option: MOVEs files by deleting after copy
**
*/

#define TRUE 1
#define FALSE 0

#include
#include
#include
#include
#include
#include
#include
#include

char output_file[64]; /* output file name */
char input_file[64]; /* input file name */
char fname_buffer[128]; /* line buffer for gang files */
char *fname_ptr; /* ptr for above */

char *strings; /* where the file names are stored */
char *sptr; /* pointer to that area */

char *data; /* where the file data are stored */
char *dptr; /* pointer to that area */

int driveno; /* dest. drive number */
int fh,fi,fo; /* file handles */
int ctrlc(); /* where CTRL-BREAK goes */

FILE *fl;

char *names[1200];

char s_path[80]; /* source path */
char s_drv[3];
char s_dir[66];
char s_file[9];
char s_ext[5];

char t_path[80]; /* target path */
char t_drv[3];
char t_dir[66];
char t_file[9];
char t_ext[5];

char cur_dir[66];
char s_chdir[66];
char t_chdir[66];

struct dfree freespace;
struct ftime ftod;
struct ffblk fcb;

main(argc, argv)
int argc;
char *argv[];
{
int i, j, k;
long bytesleft;
long maxspace;
long minspace;
long filesize;
int disks_needed;
int clust_used;
int cluster_size;
int clus1, clus2;
long filetotal = 0L;
int length;
int ocount;
int more = TRUE;
int mustsort = TRUE;
int bypass = TRUE;
int predelete = FALSE; /* pre-delete */
int postdelete = FALSE; /* postdelete */
int overwrite = FALSE; /* force overwrite */
char name[13];

ctrlbrk(ctrlc);

if(argc < 3)
{
puts("COPPY from HD to FD by largest fit ver.3.6 (c) 1988 Thomas A. Lundin");
puts("usage:\n coppy [d:][\\path\\][filespec] d:[\\path] [-u -w -d -m -o]");
puts("-or-\n coppy @dirlist d:[\\path] [-u -w -d -m -o]");
puts(" 'dirlist' is a file created by redirecting a DIR command");
puts(" -u copies the files in original (unsorted) order");
puts(" -w carries over existing files to another disk");
puts(" -d deletes specified target subdirectory before copying");
puts(" -m Move: deletes source files after copying to target");
puts(" -o overwrites existing files");
exit(1);
}
for (i = 3; (argc-3) > 0; i++, argc--) { /* process options */
if (strnicmp(argv[i],"-U",2) == 0) {
mustsort = FALSE;
printf("Copy will be in unsorted order\n");
}
else if (strnicmp(argv[i],"-W",2) == 0) {
bypass = FALSE;
overwrite = FALSE;
printf("Any existing files will be recopied on new diskettes.\n");
}
else if (strnicmp(argv[i],"-D",2) == 0) {
predelete = TRUE;
printf("Target diskettes will be deleted before copying.\n");
}
else if (strnicmp(argv[i],"-M",2) == 0) {
postdelete = TRUE;
printf("Source files will be deleted after copying.\n");
}
else if (strnicmp(argv[i],"-O",2) == 0) {
overwrite = TRUE;
bypass = TRUE;
printf("Existing target files will be overwritten.\n");
}
else {
printf("\nInvalid option: %s\n",argv[i]);
exit(1);
}
}

getcwd(cur_dir,66); /* get current dir */
fnsplit(argv[1],s_drv,s_dir,s_file,s_ext); /* split the names */
fnsplit(argv[2],t_drv,t_dir,t_file,t_ext);

strcpy(s_path,argv[1]);
strcpy(t_chdir,argv[2]);

driveno = (toupper(*t_drv) - '@'); /* drive number */

if ((strings = malloc(25200)) == NULL) { /* space for file names */
printf("Unable to grab string space\n");
exit(1);
}
if ((data = malloc(24576)) == NULL) { /* space for data */
printf("Unable to grab data space\n");
exit(1);
}

/*
The main caller
*/
sptr = strings;

if (*s_file == '@') {
strcpy(name,s_file+1); /* form a file.name */
strcat(name,s_ext);
if ((fl = fopen(name,"r")) == NULL) {
printf("Can't open up %s\n",name);
errorexit(1);
}
i = 0;
while ((fname_ptr = fgets(fname_buffer,128,fl)) != NULL) {
if ((isalnum(*fname_ptr) || ispunct(*fname_ptr))
&& *fname_ptr != '.' && i < 1200) {
make_fn(input_file,fname_ptr);
fi = open(input_file,O_RDONLY);
filesize = filelength(fi);
filetotal += filesize;
sprintf(sptr,"%8.8ld=%s",filesize,input_file);
names[i] = sptr;
_close(fi);
sptr = sptr+strlen(input_file)+9;
*sptr++ = NULL; /* store terminator, bump pointer */
++i; /* bump array index */
}
}
}
else {
for (i = 0; i < 1200; ++i) {
if (i == 0) {
if (findfirst(s_path,&fcb,0) == EOF) {
printf("No files matching %s\n",s_path);
errorexit(1);
}
}
else {
if (findnext(&fcb) == EOF) {
break;
}
}
strcpy(s_path,s_drv); /* what file to read */
strcat(s_path,s_dir);
strcat(s_path,fcb.ff_name);
fi = open(s_path,O_RDONLY);
filesize = filelength(fi);
filetotal += filesize;
sprintf(sptr,"%8.8ld=%s",filesize,fcb.ff_name);
names[i] = sptr;
_close(fi);
sptr = sptr+strlen(fcb.ff_name)+9;
*sptr++ = NULL; /* store terminator, bump pointer */
}
}
if (i >= 1200)
printf("1200-file maximum. Overrun ignored!\n");

if (mustsort)
sort(names,i); /* sort the names in descending size order */

printf("\nInsert a disk in drive %c: for capacity test\nPress any key when ready or to quit...\n",driveno + '@');
if (getch() == 0x1b) {
ctrlc();
}
printf("\n");

ocount = 0; /* how many files have been copied */
maxspace = 0L; /* disk capacity */
while(more) {
getdfree(driveno,&freespace); /* free space on floppy */
if(freespace.df_sclus == EOF) {
printf("Error in obtaining free space\n");
errorexit(1);
}
bytesleft = (freespace.df_bsec * freespace.df_sclus) * (long )freespace.df_avail;
maxspace = (freespace.df_bsec * freespace.df_sclus) * (long )freespace.df_total;
cluster_size = (freespace.df_bsec * freespace.df_sclus);

if (filetotal > 0) {
disks_needed = 1;
clust_used = 0;
for (k = 0; k < i; k++) { /* how many disks needed */
filesize = atol(names[k]); /* get the size of a file */
clus1 = filesize / (long )cluster_size;
clus2 = filesize % (long )cluster_size;
if (clus2 > 0) {
clus1++;
}
clust_used += clus1;
if (clust_used > freespace.df_total) {
disks_needed++;
clust_used = clus1;
}
}
if (disks_needed == 1) {
strcpy(t_path,".");
}
else {
strcpy(t_path,"s.");
}

printf("\n%d files will fit on %d diskette%s\n",i,disks_needed,t_path);
printf("\nInsert new disk in drive %c:\nPress any key when ready or to quit...\n",driveno + '@');
if (getch() == 0x1b) {
ctrlc();
}
printf("\n");
filetotal = 0L;
if (predelete == TRUE) {
strcpy(t_path,t_drv); /* what file to delete */
strcat(t_path,t_dir);
strcat(t_path,"*.*");
if (findfirst(t_path,&fcb,0) == EOF) {
printf("No files matching %s\n",s_path);
}
else {
do {
strcpy(t_path,t_drv); /* what file to delete */
strcat(t_path,t_dir);
strcat(t_path,fcb.ff_name);
unlink(t_path);
} while (findnext(&fcb) != EOF);
}
}
}

for (k = 0; k < i; ++k) { /* for each file in the list */
if (*(names[k]) == NULL) { /* we've already used this one */
continue;
}
else {
if ((t_chdir[2] & t_chdir[3]) != NULL) { /* output subdir used */
if (access(t_chdir,0) != 0) { /* need to MKDIR on target? */
if (mkdir(t_chdir) == EOF) {
printf("Unable to create subdir %s\n",t_chdir);
errorexit(1);
}
}
}
strcpy(output_file,t_chdir); /* form the output filespec */
strcat(output_file,"\\");
strcat(output_file,names[k]+9);

if ((access(output_file,0) == 0) && overwrite == FALSE) { /* output already exists */
if (bypass == TRUE) {
*(names[k]) = NULL;
++ocount;
printf("%s already exists, and will be bypassed.\n",output_file);
}
else {
printf("%s already exists, but will be copied later.\n",output_file);
}
}
else {
if ((filesize = atol(names[k])) > bytesleft && mustsort) {
continue; /* file too large */
}
else if ((filesize = atol(names[k])) > bytesleft && !mustsort) {
break; /* file too large */
}
else { /* OK to copy */
strcpy(input_file,s_drv); /* what file to read */
strcat(input_file,s_dir);
strcat(input_file,names[k]+9);

if ((fi = open(input_file,O_RDONLY | O_BINARY)) == EOF) {
printf("Unable to open input %s\n",input_file);
errorexit(1);
}
getftime(fi,&ftod); /* read the tod stamp */
if ((fo = open(output_file,O_WRONLY | O_BINARY | O_CREAT, S_IREAD | S_IWRITE)) == EOF) {
printf("Can't open output %s\n",output_file);
errorexit(1);
}
printf("%s -> %s : %ld bytes ",input_file,output_file,filesize);

while ((length = _read(fi,data,24576)) > NULL) {
_write(fo,data,length);
}

_close(fo);
fo = open(output_file, O_RDONLY); /* open */
setftime(fo,&ftod); /* update time */
_close(fo); /* shut */
_close(fi);
*(names[k]) = NULL; /* don't use this file again */
++ocount; /* output count update */
if (postdelete == TRUE) {
unlink(input_file);
printf("-- MOVED");
}
printf("\n");
break;
}
}
}
}
if (ocount >= i) {
more = FALSE;
}
if (filesize > maxspace) { /* file size > disk capacity ? */
printf("\n");
for (k = 0; k < i; ++k) {
if(*(names[k]) != NULL) {
printf("%s must be split up to fit on a disk.\n",names[k]+9);
}
more = FALSE;
}
}
if (filesize > bytesleft || k >= i) { /* file size > free space ? */
printf("\nInsert new disk in drive %c:\nPress any key when ready or to quit...\n",driveno + '@');
if (getch() == 0x1b) {
ctrlc();
}
printf("\n");
if (predelete == TRUE) {
strcpy(t_path,t_drv); /* what file to delete */
strcat(t_path,t_dir);
strcat(t_path,"*.*");
if (findfirst(t_path,&fcb,0) == EOF) {
printf("No files matching %s\n",s_path);
}
else {
do {
strcpy(t_path,t_drv); /* what file to delete */
strcat(t_path,t_dir);
strcat(t_path,fcb.ff_name);
unlink(t_path);
} while (findnext(&fcb) != EOF);
}
}
}
}
chdir(cur_dir);
exit(0);
}

/*
Make a true file name from a line in the DIRLIST
*/
make_fn(name,line)
char *line, *name;
{
char temp[20];

*name = NULL; /* init name buffer */
stctok(line,temp,20," "); /* get the name */
strcat(name,temp);
strcat(name,".");
stctok(line+9,temp,20," "); /* get the extension */
strcat(name,temp);
return;
}
/*
Copy a string up to a terminator character or length
*/
stctok(from,to,length,term)
char *from,*to,*term;
int length;
{
char c;

/* The following statement will generate a Turbo C WARNING; pay no attention. */
while((c = *from++) && (c != *term) && length--) {
*to++ = c;
}
*to = NULL;
return;
}

ctrlc()
{
chdir(cur_dir);
printf("\nCancelled\n");
exit(1);
}

errorexit(n)
int n;
{
chdir(cur_dir);
exit(n);
}


  3 Responses to “Category : Utilities for DOS and Windows Machines
Archive   : COPPY36.ZIP
Filename : COPPY.C

  1. Very nice! Thank you for this wonderful archive. I wonder why I found it only now. Long live the BBS file archives!

  2. This is so awesome! 😀 I’d be cool if you could download an entire archive of this at once, though.

  3. But one thing that puzzles me is the “mtswslnkmcjklsdlsbdmMICROSOFT” string. There is an article about it here. It is definitely worth a read: http://www.os2museum.com/wp/mtswslnk/