Subversion Repositories Kolibri OS

Rev

Rev 7802 | Blame | Compare with Previous | Last modification | View Log | Download | RSS feed

  1.  
  2. int cmd_cp(char param[])
  3. {
  4.     char* argv[100];
  5.     int argc;
  6.     char *filename_in = NULL;
  7.     char *filename_out = NULL;
  8.     char *buffer = NULL;
  9.  
  10.     kol_struct70 k70_in;
  11.     kol_struct70 k70_out;
  12.  
  13.     kol_struct_BDVK     bdvk;
  14.  
  15.     unsigned long long filesize;
  16.     unsigned result, buf_size;
  17.  
  18.     argc = parameters_prepare(param, argv);
  19.  
  20.     if (argc != 2)
  21.     {
  22.         printf(CMD_CP_USAGE);
  23.         parameters_free(argc, argv);
  24.         return TRUE;
  25.     }
  26.  
  27.     filename_in  = (char*) malloc(FILENAME_MAX);
  28.     filename_out = (char*) malloc(FILENAME_MAX);
  29.  
  30.     if (argv[0][0] != '/')
  31.     {
  32.         strcpy(filename_in, cur_dir);
  33.         if (filename_in[strlen(filename_in)-1] != '/')
  34.         {
  35.             strcat(filename_in, "/"); // add slash
  36.         }
  37.         strcat(filename_in, argv[0]);
  38.     } else
  39.     {
  40.         strcpy(filename_in, argv[0]);
  41.     }
  42.     // -----
  43.     if (argv[1][0] != '/')
  44.     {
  45.         strcpy(filename_out, cur_dir);
  46.         if (filename_out[strlen(filename_out)-1] != '/')
  47.         {
  48.             strcat(filename_out, "/"); // add slash
  49.         }
  50.         strcat(filename_out, argv[1]);
  51.     } else
  52.     {
  53.         strcpy(filename_out, argv[1]);
  54.     }
  55.        
  56.     // add ability to use directory as destination
  57.     if ( dir_check(filename_out) )
  58.     {
  59.         char *fname = strrchr(filename_in, '/') + 1;  // always exist, as we add curdir
  60.         if (filename_out[strlen(filename_out)-1] != '/')
  61.         {
  62.             strcat(filename_out, "/"); // add slash
  63.         }
  64.         strcat(filename_out, fname);
  65.     }
  66.  
  67.  
  68.     k70_in.p00 = 5;
  69.     k70_in.p04 = 0LL;
  70.     k70_in.p12 = 0;
  71.     k70_in.p16 = (unsigned) &bdvk;
  72.     k70_in.p20 = 0;
  73.     k70_in.p21 = filename_in;
  74.  
  75.     result = kol_file_70(&k70_in); // get information about file
  76.     if ( 0 != result )
  77.         goto lbl_exit;
  78.  
  79.     // count buffer size up to 1Mb, but no more than 1/2 of free memory
  80.     buf_size = 1 << 20; // 1Mb
  81.     while( ((buf_size >> 10) > kol_system_memfree()) && (buf_size > 4096) )
  82.         buf_size /= 2;
  83.  
  84.     filesize = bdvk.p32; // getting file size (restriction - 4 GB only for FAT)
  85.     if (buf_size > filesize)
  86.         buf_size = (unsigned)filesize;  // may be zero!
  87.     if (buf_size == 0) buf_size = 4096; // ...
  88.  
  89.     buffer = (char*) malloc(buf_size);
  90.     if (!buffer)
  91.     {
  92.         result = E_NOMEM;
  93.         goto lbl_exit;
  94.     }
  95.  
  96.     k70_in.p00 = 0;
  97.     //k70_in.p08 = 0;
  98.     k70_in.p12 = buf_size;
  99.     k70_in.p16 = (unsigned) buffer;
  100.     k70_in.p20 = 0;
  101.     k70_in.p21 = filename_in;
  102.  
  103.     k70_out.p00 = 2;
  104.     //k70_out.p08 = 0;
  105.     k70_out.p12 = buf_size;
  106.     k70_out.p16 = (unsigned) buffer;
  107.     k70_out.p20 = 0;
  108.     k70_out.p21 = filename_out;
  109.  
  110.     unsigned long long offset = 0;
  111.     do
  112.     {
  113.         k70_in.p04 = offset;
  114.         if (offset + buf_size > filesize)  // last chunk
  115.         {
  116.             k70_in.p12 = k70_out.p12 = (unsigned)(filesize - offset); // filesize % buf_size;
  117.         }
  118.        
  119.         result = kol_file_70(&k70_in); // read
  120.         if (result != 0)
  121.         {
  122.             goto lbl_exit;
  123.         }
  124.  
  125.         k70_out.p04 = offset;
  126.         result = kol_file_70(&k70_out); // write
  127.         if (result != 0)
  128.         {
  129.            goto lbl_exit;
  130.         }
  131.  
  132.         if (k70_out.p00 == 2)
  133.         {
  134.             k70_out.p00 = 3; // changing function from create (2) to append (3)
  135.         }
  136.         offset += buf_size;
  137.     } while (offset < filesize);
  138.  
  139.     lbl_exit:
  140.  
  141.     parameters_free(argc, argv);
  142.     free(filename_in);
  143.     free(filename_out);
  144.     free(buffer);
  145.  
  146.     return (result == 0);
  147. }
  148.  
  149.