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 / mmove.c < prev    next >
Text File  |  1997-11-12  |  6KB  |  286 lines

  1. /*
  2.  * mmove.c
  3.  * Renames/moves an MSDOS file
  4.  *
  5.  */
  6.  
  7.  
  8. #define LOWERCASE
  9.  
  10. #include "sysincludes.h"
  11. #include "msdos.h"
  12. #include "mtools.h"
  13. #include "vfat.h"
  14. #include "mainloop.h"
  15. #include "plain_io.h"
  16. #include "nameclash.h"
  17. #include "file.h"
  18. #include "fs.h"
  19.  
  20. /*
  21.  * Preserve the file modification times after the fclose()
  22.  */
  23.  
  24. typedef struct Arg_t {
  25.     char *target;
  26.     char *fromname;
  27.     int nowarn;
  28.     int single;
  29.     int interactive;
  30.     int verbose;
  31.     int oldsyntax;
  32.     MainParam_t mp;
  33.  
  34.     Stream_t *SrcDir;
  35.     int entry;
  36.     ClashHandling_t ch;
  37.     Stream_t *targetDir;
  38. } Arg_t;
  39.  
  40.  
  41. /*
  42.  * Open the named file for read, create the cluster chain, return the
  43.  * directory structure or NULL on error.
  44.  */
  45. static struct directory *renameit(char *dosname,
  46.                   char *longname,
  47.                   void *arg0,
  48.                   struct directory *dir)
  49. {
  50.     int entry;
  51.     struct directory parentdir;
  52.     Stream_t *Dir;
  53.     Arg_t *arg = (Arg_t *) arg0;
  54.     int fat;
  55.  
  56.  
  57.     *dir = arg->mp.dir;
  58.     strncpy(dir->name, dosname, 8);
  59.     strncpy(dir->ext, dosname + 8, 3);
  60.  
  61.     if( (dir->attr & 0x10) && arg->targetDir){
  62.         /* we have a directory here. Change its parent link */
  63.         Dir = open_file(arg->targetDir, & arg->mp.dir);
  64.         if(FileIsLocked(Dir)) {
  65.             fprintf(stderr,
  66.                 "Cannot move directory \'%s%s\' into itself\n",
  67.                 dir->name,dir->ext);
  68.             FREE(&Dir);
  69.             return 0;
  70.         }
  71.         entry = 0;
  72.         if(vfat_lookup(Dir,
  73.                    &parentdir, &entry, 0, "..", ACCEPT_DIR,
  74.                    NULL, NULL, NULL))
  75.             fprintf(stderr," Directory has no parent entry\n");
  76.         else {
  77.             entry--; /* rewind entry */
  78.             GET_DATA(arg->targetDir, 0, 0, 0, &fat);
  79.             parentdir.start[1] = (fat >> 8) & 0xff;
  80.             parentdir.start[0] = fat & 0xff;
  81.             dir_write(Dir, entry, &parentdir);
  82.             if(arg->verbose){
  83.                 fprintf(stderr,
  84.                     "Easy, isn't it? I wonder why DOS can't do this.\n");
  85.             }
  86.         }
  87.         FREE(&Dir);
  88.     }
  89.  
  90.     /* wipe out original entry */
  91.     arg->mp.dir.name[0] = DELMARK;
  92.     dir_write(arg->SrcDir, arg->entry, &arg->mp.dir);
  93.  
  94.     return dir;
  95. }
  96.  
  97.  
  98. static int rename_file(Stream_t *Dir, MainParam_t *mp, int entry)
  99. /* rename a messy DOS file to another messy DOS file */
  100. {
  101.     int result;
  102.     Stream_t *targetDir;
  103.     char *shortname, *longname;
  104.  
  105.     Arg_t * arg = (Arg_t *) (mp->arg);
  106.  
  107.     arg->SrcDir = Dir;
  108.     arg->entry = entry;
  109.     if(arg->oldsyntax)
  110.         targetDir = Dir;
  111.     else
  112.         targetDir = arg->targetDir;
  113.  
  114.     if (targetDir == Dir){
  115.         arg->ch.ignore_entry = -1;
  116.         arg->ch.source = entry;
  117.     } else {
  118.         arg->ch.ignore_entry = -1;
  119.         arg->ch.source = -2;
  120.     }
  121.  
  122.  
  123.     if(arg->oldsyntax && !strcasecmp(mp->shortname, arg->fromname)){
  124.         longname = mp->longname;
  125.         shortname = arg->target;
  126.     } else {
  127.         longname = arg->target;
  128.         shortname = 0;
  129.     }
  130.  
  131.     result = mwrite_one(targetDir, longname, shortname,
  132.                 renameit, (void *)arg, &arg->ch);
  133.     if(result == 1)
  134.         return GOT_ONE;
  135.     else
  136.         return MISSED_ONE;
  137. }
  138.  
  139.  
  140. static void usage(void)
  141. {
  142.     fprintf(stderr,
  143.         "Mtools version %s, dated %s\n", mversion, mdate);
  144.     fprintf(stderr,
  145.         "Usage: %s [-itnmvV] file targetfile\n", progname);
  146.     fprintf(stderr,
  147.         "       %s [-itnmvV] file [files...] target_directory\n", 
  148.         progname);
  149.     exit(1);
  150. }
  151.  
  152. void mmove(int argc, char **argv, int oldsyntax)
  153. {
  154.     Stream_t *SubDir,*Dir;
  155.     Arg_t arg;
  156.     int c, ret;
  157.     char filename[VBUFSIZE];
  158.     char spareOutname[VBUFSIZE];
  159.     char shortname[13];
  160.     char longname[VBUFSIZE];
  161.     char def_drive;
  162.     char *s;
  163.     int i;
  164.     int interactive;
  165.  
  166.     /* get command line options */
  167.  
  168.     init_clash_handling(& arg.ch);
  169.  
  170.     interactive = 0;
  171.  
  172.  
  173.     /* get command line options */
  174.     arg.verbose = 0;
  175.     arg.nowarn = 0;
  176.     arg.interactive = 0;
  177.     while ((c = getopt(argc, argv, "invorsamORSAM")) != EOF) {
  178.         switch (c) {
  179.             case 'i':
  180.                 arg.interactive = 1;
  181.                 break;
  182.             case 'n':
  183.                 arg.nowarn = 1;
  184.                 break;
  185.             case 'v':    /* dummy option for mcopy */
  186.                 arg.verbose = 1;
  187.                 break;
  188.             case '?':
  189.                 usage();
  190.             default:
  191.                 if(handle_clash_options(&arg.ch, c))
  192.                     usage();
  193.                 break;
  194.         }
  195.     }
  196.  
  197.     if (argc - optind < 2)
  198.         usage();
  199.  
  200.  
  201.     /* only 1 file to rename... */
  202.     arg.single = SINGLE;
  203.     
  204.     init_mp(&arg.mp);        
  205.     arg.mp.arg = (void *) &arg;
  206.     arg.mp.openflags = O_RDWR;
  207.  
  208.     /* look for a default drive */
  209.     def_drive = '\0';
  210.     for(i=optind; i<argc; i++)
  211.         if(argv[i][0] && argv[i][1] == ':' ){
  212.             if(!def_drive)
  213.                 def_drive = toupper(argv[i][0]);
  214.             else if(def_drive != toupper(argv[i][0])){
  215.                 fprintf(stderr,
  216.                     "Cannot move files across different drives\n");
  217.                 exit(1);
  218.             }
  219.         }
  220.  
  221.     if(def_drive)
  222.         *(arg.mp.mcwd) = def_drive;
  223.  
  224.     if (oldsyntax && (argc - optind != 2 || strpbrk(":/", argv[argc-1])))
  225.         oldsyntax = 0;
  226.  
  227.     arg.oldsyntax = oldsyntax;
  228.  
  229.     if (!oldsyntax){
  230.         Dir = open_subdir(&arg.mp, argv[argc-1], O_RDWR, 0, 1);
  231.         if(!Dir){
  232.             fprintf(stderr,"Bad target\n");
  233.             exit(1);
  234.         }
  235.         get_name(argv[argc-1], filename, arg.mp.mcwd);
  236.         SubDir = descend(Dir, filename, 0, 0, 1);
  237.         if (!SubDir){
  238.             /* the last parameter is not a directory: take
  239.              * it as the new name */
  240.             if ( argc - optind != 2 ){
  241.                 fprintf(stderr,
  242.                     "%s: Too many arguments, or destination directory omitted\n", 
  243.                     argv[0]);
  244.                 exit(1);
  245.             }
  246.             
  247.             arg.targetDir = Dir;
  248.             arg.mp.outname = 0; /* toss away source name */
  249.             arg.target = filename; /* store near name given as
  250.                         * target */
  251.             arg.single = 1;
  252.         } else {
  253.             arg.targetDir = SubDir;
  254.             FREE(&Dir);
  255.             arg.mp.outname = arg.target = filename;
  256.             arg.single = 0;
  257.         }
  258.     } else {
  259.         arg.fromname = argv[optind];
  260.         if(arg.fromname[0] && arg.fromname[1] == ':')
  261.             arg.fromname += 2;
  262.         s = strrchr(arg.fromname, '/');
  263.         if(s)
  264.             arg.fromname = s+1;
  265.         arg.mp.outname = filename;
  266.         arg.single = 0;
  267.         arg.targetDir = NULL;
  268.         arg.target = argv[argc-1];
  269.     }
  270.  
  271.     arg.mp.callback = rename_file;
  272.  
  273.     arg.mp.lookupflags = 
  274.       ACCEPT_PLAIN | ACCEPT_DIR | DO_OPEN | NO_DOTS | arg.single;
  275.  
  276.     arg.mp.longname = longname;
  277.     arg.mp.shortname = shortname;
  278.     if(!arg.mp.outname)
  279.         arg.mp.outname = spareOutname;
  280.  
  281.     ret=main_loop(&arg.mp, argv + optind, argc - optind - 1);
  282.     FREE(&arg.targetDir);
  283.  
  284.     exit(ret);
  285. }
  286.