Facebook
From Vlad, 3 Years ago, written in Plain Text.
Embed
Download Paste or View Raw
Hits: 125
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <string.h>
  4.  
  5. #include <unistd.h>
  6. #include <sys/mman.h>
  7. #include <sys/types.h>
  8. #include <sys/stat.h>
  9. #include <fcntl.h>
  10. #include <limits.h> // necesar pentru PATH_MAX
  11.  
  12. int copie_opts_i_u(char *nume_sursa, char *nume_dest, int flag_opt_i, int flag_opt_u);
  13.  
  14. int main(int argc, char *argv[])
  15. {
  16.     int i, flag_opt_i = 0, flag_opt_u = 0;
  17.     char *nume_sursa = NULL;
  18.     char *nume_dest = NULL;
  19.  
  20.     if (argc < 3)
  21.     {
  22.         fprintf(stderr, "Usage: %s [-i] [-u] fisier-sursa fisier-destinatie\n", argv[0]);
  23.         exit(1);
  24.     }
  25.  
  26.     for (i = 1; i < argc; i++)
  27.     {
  28.         if (strcmp(argv[i], "-i") == 0)
  29.         {
  30.             flag_opt_i = 1;
  31.             continue;
  32.         }
  33.         if (strcmp(argv[i], "-u") == 0)
  34.         {
  35.             flag_opt_u = 1;
  36.             continue;
  37.         }
  38.  
  39.         if (nume_sursa == NULL)
  40.         {
  41.             nume_sursa = argv[i];
  42.             continue;
  43.         }
  44.         if (nume_dest == NULL)
  45.         {
  46.             nume_dest = argv[i];
  47.             continue;
  48.         }
  49.  
  50.         fprintf(stderr, "Eroare: nu ati respectat formatul impus pentru argumentele din linia de comanda.\n");
  51.         exit(2);
  52.     }
  53.  
  54.     if (nume_sursa == NULL)
  55.     {
  56.         fprintf(stderr, "Eroare: nu ati specificat fisierul sursa.\n");
  57.         exit(3);
  58.     }
  59.  
  60.     if (nume_dest == NULL)
  61.     {
  62.         fprintf(stderr, "Eroare: nu ati specificat fisierul destinatie.\n");
  63.         exit(4);
  64.     }
  65.  
  66.     return copie_opts_i_u(nume_sursa, nume_dest, flag_opt_i, flag_opt_u);
  67. }
  68.  
  69. int copie_simpla(char *nume_sursa, char *nume_dest);
  70.  
  71. int copie_opts_i_u(char *nume_sursa, char *nume_dest, int flag_opt_i, int flag_opt_u)
  72. {
  73.     if (access(nume_sursa, R_OK) != 0)
  74.     {
  75.         fprintf(stderr, "Eroare: fisierul sursa %s nu este accesibil (i.e. nu exista, sau nu am drept de citire, sau ce?)\t", nume_sursa);
  76.         perror("Cauza exacta este");
  77.         return 10;
  78.     }
  79.  
  80.     int flag_dest_exista = access(nume_dest, F_OK) == 0 ? 1 : 0;
  81.  
  82.     int flag_abort_copiere = 0;
  83.  
  84.     if (flag_dest_exista)
  85.     {
  86.  
  87.         if (flag_opt_u)
  88.         {
  89.             struct stat st_sursa, st_dest;
  90.  
  91.             if (0 != stat(nume_sursa, &st_sursa))
  92.             {
  93.                 fprintf(stderr, "Eroare la stat pentru fisierul sursa %s .\t", nume_sursa);
  94.                 perror("Cauza este");
  95.                 return 11;
  96.             }
  97.             if (0 != stat(nume_dest, &st_dest))
  98.             {
  99.                 fprintf(stderr, "Eroare la stat pentru fisierul destinatie %s .\t", nume_dest);
  100.                 perror("Cauza este");
  101.                 return 12;
  102.             }
  103.  
  104.             if (st_sursa.st_mtime > st_dest.st_mtime)
  105.             {
  106.                 printf("\tSursa %s are 'last modified time': %s", nume_sursa, ctime(&st_sursa.st_mtime));
  107.                 printf("\tDestinatia %s are 'last modified time': %s", nume_dest, ctime(&st_dest.st_mtime));
  108.                 printf("Notify message: copierea se va face cu suprascrierea destinatiei (deoarece sursa este mai recenta decat destinatia).\n");
  109.             }
  110.             else
  111.             {
  112.                 flag_abort_copiere = 1;
  113.                 printf("Sursa %s nu este mai recenta decat destinatia %s. Deci NU suprascriu destinatia cu sursa!\n", nume_sursa, nume_dest);
  114.             }
  115.         }
  116.  
  117.         if (!flag_abort_copiere && flag_opt_i)
  118.         {
  119.             char raspuns;
  120.  
  121.             printf("Fisierul destinatie %s exista deja (dar este mai vechi decat sursa). Vreti sa-l suprascrieti? (D/N)\n", nume_dest);
  122.             do
  123.             {
  124.                 scanf("%c", &raspuns);
  125.             } while ((raspuns != 'D') && (raspuns != 'N'));
  126.  
  127.             if (raspuns == 'N')
  128.                 flag_abort_copiere = 1;
  129.             else
  130.                 printf("Notify message: copierea se va face cu suprascrierea destinatiei (cu acceptul utilizatorului).\n");
  131.         }
  132.         else
  133.         {
  134.             /* Vom da prioritate opțiunii -u : dacă destinația este mai recentă decât sursa, nu mai întrebăm utilizatorul, ci anulăm copierea. */
  135.         }
  136.     }
  137.  
  138.     if (!flag_abort_copiere)
  139.     {
  140.         return copie_simpla(nume_sursa, nume_dest);
  141.     }
  142.     else
  143.     {
  144.         fprintf(stderr, "Copierea lui %s in %s nu s-a mai efectuat.\n", nume_sursa, nume_dest);
  145.         return 13;
  146.     }
  147. }
  148.  
  149. int copie_simpla(char *nume_sursa, char *nume_dest)
  150. {
  151.     int f1, f2;
  152.     struct stat sb;
  153.  
  154.     if (-1 == (f1 = open(nume_sursa, O_RDONLY)))
  155.     {
  156.         fprintf(stderr, "Eroare la deschiderea fisierului sursa %s\n", nume_sursa);
  157.         perror("Cauza este");
  158.         return 20;
  159.     }
  160.  
  161.     if (-1 == (f2 = open(nume_dest, O_RDWR | O_CREAT)))
  162.     {
  163.         fprintf(stderr, "Eroare la deschiderea fisierului destinatie %s\n", nume_dest);
  164.         perror("Cauza este");
  165.         return 21;
  166.     }
  167.  
  168.     if (fstat(f1, &sb) == -1)
  169.         perror("Eroare la fstat.");
  170.  
  171.     int offset = 0;
  172.     int length = sb.st_size;
  173.  
  174.     if (ftruncate(f2, length) == -1)
  175.         perror("Eroare la trunchiere");
  176.  
  177.     chmod(nume_dest, S_IRUSR | S_IWUSR);
  178.  
  179.     char *map_addr1 = mmap(NULL, length, PROT_READ, MAP_PRIVATE, f1, offset);
  180.     char *map_addr2 = mmap(NULL, length, PROT_WRITE, MAP_SHARED, f2, offset);
  181.  
  182.     if (map_addr1 == MAP_FAILED || map_addr2 == MAP_FAILED)
  183.         perror("Eroare la mmap.");
  184.  
  185.     for (int i = 0; i < length; i++)
  186.         *(map_addr2 + i) = *(map_addr1 + i);
  187.  
  188.     if (-1 == msync(map_addr2, length, MS_SYNC))
  189.         perror("Erroar la msync");
  190.  
  191.     if (close(f1) == -1 || close(f2) == -1)
  192.         perror("Eroare la inchiderea fisierelor.");
  193.  
  194.     if (munmap(map_addr1, length) == -1 || munmap(map_addr2, length) == -1)
  195.         perror("Erroare la munmap.");
  196.  
  197.     printf("Am copiat cu succes fisierul sursa %s in destinatia %s\n", nume_sursa, nume_dest);
  198.     return 0;
  199. }