[comp.binaries.ibm.pc] v03i001: move_c, improved file mover

timphus@stltar.stl.informatik.uni-dortmund.de (Stefan Timphus) (05/26/89)

Checksum: 2029852122  (Verify with "brik -cv")
Posting-number: Volume 03, Issue 001
Submitted-by: Stefan Timphus <timphus@stltar.stl.informatik.uni-dortmund.de>
Archive-name: move_c/move_c.txt

[
This actually arrived with a From: line of:

Wilfried Rupflin --- Simula Test
<unido!trillian.irb.informatik.uni-dortmund.de!simula@uunet.UU.NET>

But that line is too big to fit in any of the headers.

This program was originally posted in this newsgroup as:

|Subject: v01i229: move, a file moving utility, C source
|
|MOVE allows DOS users the ability to MOVE files from one directory to
|another with a minimum of effort.
|
|  1)   MOVE is extremely FAST (because it uses the rename() function)
|  2)   The * and ? are fully supported.
|  3)   If a file in the destination directory exists under the same name, MOVE
|       will prompt the user if he/she wants to overwrite it.
|  4)   Files with special attributes are handled accordingly.

This is a revised version -- see near the end of the source file.  --
R.D.]

Stefan Timphus
timphus@stltar.stl.informatik.uni-dortmund.de
simula@trillian.irb.informatik.uni-dortmund.de

BEGIN--cut here--cut here
#include <stdio.h>
#include <dir.h>
#include <string.h>

char    newpath[MAXPATH], pathname[MAXPATH],newname[MAXPATH], oldname[MAXPATH];
char    drive[MAXDRIVE], subdir[MAXDIR], file[MAXFILE], ext[MAXEXT];
char    helpname[MAXPATH], sourcename[MAXPATH];

struct ffblk dta;

int main(int argc,char *argv[])
{
    int len, done, count=0, wassubdir=1, loop, gavename=0, star=0;

    if(argc != 3){      /* Test for proper number of command line arguments */
	printf("\nUsage:   move [path]file(s).ext path[file.ext]|file.ext");
	printf("\n         The * and ? wild cards are permitted for moving.\n");
	return(1);
    }
    strcpy(sourcename,argv[1]);
    strcpy(newpath,argv[2]);    /* Save a copy of the destination path */
    strcpy(subdir,argv[2]);     /* In this place too ! */
    strcpy(helpname,argv[2]);   /* In this place too ! */
    len = strlen(newpath);      /* Get destination path length */
    if(newpath[len-1] == 92)    /* Did user supply a '\' on destination path */
      {
       wassubdir=0;             /* Destination was meant to be a directory */
       if (len>1)               /* Make sure whether you move to root-directory */
				/* Was bug in previous release; */
				/* move to root was not possible */
       subdir[len-1] = 0;       /* If '\' on destination path, */
				/* remove '\' from the secondary copy */
      }
      else                      /* If no, add one to primary copy */
       {
	newpath[len] = 92;      /* Add the '\' */
	newpath[len+1] = 0;     /* Don't forget to terminate it */
       }
    getcwd(newname,MAXPATH);    /* Save the directory we were called from */

    /* The following block supposes that user wants to rename a file */
    if(chdir(subdir) * wassubdir)   /* This block enables renaming across
					directories for single files.
					added by Stefan Timphus */
	   {
		fnsplit(helpname,drive,subdir,file,ext); /* Break up the dest file name */
		gavename=1; 		/* Name for renaming was given */
		newpath[len]=0;         /* Remove the '\' */
		strcat(file,ext);
		len=strlen(subdir);
		subdir[len-1]=0;        /* here too */
		wassubdir=0;            /* really wasn't but is asked later */
		for (loop=0;sourcename[loop]!=0;loop++)
		{
		    if ((sourcename[loop]=='*') || (sourcename[loop]=='?'))
		    star++;              /* check if you want to rename */
		}			/* several files, which is impossible */
		for (loop=0;file[loop]!=0;loop++)
		{
		    if ((file[loop]=='*') || (file[loop]=='?'))
		    star++;              /* you want to rename a single */
		}			/* file, so don't give '*' or '?' */
					/* in the destination name */
		if (star)
		{
			printf("? or * not allowed if file is to be renamed\n");
			return 11;
		}
    }   /* End additional block*/
   
    /* This line is new for the second modification */
    chdir(newname);

    if(chdir(subdir) * wassubdir)          /* See if the destination directory exists */
      {
       printf("Cannot change directory to %s ... quitting.",subdir);
       return 1;
      }
    chdir(newname);                         /* Go back to home directory */
    fnsplit(argv[1],drive,subdir,file,ext); /* Break up the source file name */
    sprintf(pathname,"%s%s",drive,subdir);  /* Save path of source file(s) */
    done = findfirst(argv[1],&dta,47);      /* Go look for first file */
while(!done){
    strcpy(oldname,pathname);      /* Start "creating" the old filename */
    strcat(oldname,dta.ff_name);
    strupr(oldname);               /* Make it all upper case for DOS */
    strcpy(newname,newpath);   /* Start "creating" destination filename */
    if (!gavename)             /* Real moving without rename */
    {
	strcat(newname,dta.ff_name);
    }
    strupr(newname);              /* Make it upper case too */
    if(rename(oldname,newname)==0)    /* Try to rename the file */
      {                              /* If successful, ... */
	count++;                     /* Increment total files moved */
	printf("%-15s moved to %s\n",oldname,newname);   /* Notify user */
	done=findnext(&dta);         /* Look for next one */
	continue;
      }
/* If we can't rename it, A) File already exists, or B) File has permissions */
   printf("The file %s exists, do you want to overwite it (y/n) ",newname);
   len = getche();      /* Get their keypress */
   putchar('\n');
   if(len=='y' || len=='Y')
     {
      if(_chmod(newname,1,0))        /* Set file permissions to r/w */
         printf("Error changing mode of %s. %s not moved.\n",newname,oldname);
        else
          if(remove(newname))
             printf("Error removing %s. %s not moved.\n",newname,oldname);
            else
             continue;           /* After removing file, re-attempt rename */
/* If we can't change the mode or delete the file, forget it! */
     }
   done=findnext(&dta);           /* Find next file matching argv[1] */
}                                  /* End of while */
   if(count>0)                        /* Tell user how much work we did */
      printf("\nNumber of files moved: %3d\n",count);
    else
      printf("No files match.\n");
}
/*  Program compiled using TURBO C VER-2.0
    Written by Shawn Antol
    AT&T Bell Labs
    312-979-5622
    att!ihlpb!santol
    My employer and I are not accountable for any damages
    resulting from the use of this program. It has been tested on
    PC Compatibles using DOS 3.1 and DOS 3.2 and found to have no
    no known bugs (I found one and removed it; Stefan Timphus).

    1989-04-11
    Modified by Stefan Timphus, University Dortmund
    +49 231 755-4663
    To make it more UNIX-like.
    Now can also be used for simple renaming and renaming
    across directories, but only for single files.
    Version for renaming multiple files should be possible.
    Compiled using Turbo-C 2.0.
    timphus@stltar.stl.informatik.uni-dortmund.de
    simula@trillian.irb.informatik.uni-dortmund.de
*/
END--cut here--cut here