Guest User

Untitled

a guest
Jan 21st, 2019
103
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 2.55 KB | None | 0 0
  1. #include <stdio.h>
  2. #include <limits.h>
  3. #include <stdlib.h>
  4. #include <fcntl.h>
  5. #include <sys/types.h>
  6. #include <unistd.h>
  7. #include <stdint.h>
  8.  
  9. int
  10. read_f(int fd, void *buf, size_t size)
  11. {
  12.     char *p = buf;
  13.     size_t s = 0;
  14.     while(size && (s = read(fd, p, size))) {
  15.         size -= s;
  16.         p += s;
  17.     }
  18.     return s;
  19. }
  20.  
  21. int
  22. write_f(int fd, void *buf, size_t size)
  23. {
  24.     char *p = buf;
  25.     size_t s = 0;
  26.     while(size && (s = write(fd, p, size))) {
  27.         size -= s;
  28.         p += s;
  29.     }
  30.     return s;
  31. }
  32.  
  33. struct FHeader
  34. {
  35.     char    magic[4];
  36.     int32_t partnum;
  37. };
  38.  
  39. struct FSection
  40. {
  41.     int32_t offset;
  42.     int32_t size;
  43. };
  44.  
  45. void
  46. copy_section(int src, int dst, int32_t offset, int32_t size)
  47. {
  48.     size_t src_off = lseek(src, 0, SEEK_CUR);
  49.     char *buf = calloc(size, sizeof(*buf));
  50.     lseek(src, offset, SEEK_SET);
  51.     read_f(src, buf, size);
  52.     struct FHeader dsth;
  53.     lseek(dst, 0, SEEK_SET);
  54.     read_f(dst, &dsth, sizeof(dsth));
  55.     struct FSection *desc = calloc(dsth.partnum, sizeof(*desc));
  56.     int32_t new_offset = lseek(dst, 0, SEEK_END) - lseek(dst, 0, SEEK_SET) -
  57.         dsth.partnum * sizeof(*desc);
  58.     struct FSection new = { new_offset, size };
  59.     lseek(dst, new_offset, SEEK_SET);
  60.     read_f(dst, desc, dsth.partnum * sizeof(*desc));
  61.     lseek(dst, 0, SEEK_SET);
  62.     ++dsth.partnum;
  63.     write_f(dst, &dsth, sizeof(dsth));
  64.     lseek(dst, new_offset, SEEK_SET);
  65.     write_f(dst, buf, size);
  66.     write_f(dst, desc, (dsth.partnum - 1)* sizeof(*desc));
  67.     write_f(dst, &new, sizeof(new));
  68.     lseek(src, src_off, SEEK_SET);
  69. }
  70.  
  71. int
  72. main(int argc, char *argv[])
  73. {
  74.     enum { BASE = 10 };
  75.     int src = open(argv[1], O_RDONLY, 0);
  76.     struct FHeader h, mask = { {'C', 'M', 'C', '\x7f' }, 0};
  77.     struct FSection sh;
  78.     read_f(src, &h, sizeof(h));
  79.     int filec = strtol(argv[2], NULL, BASE);
  80.     char path[PATH_MAX];
  81.     if(h.partnum < filec) {
  82.         filec = 1;
  83.     }
  84.     int minor = h.partnum / filec, major = minor + 1;
  85.     int c;
  86.     lseek(src, -(h.partnum * sizeof(sh)), SEEK_END);
  87.     for(int i = 0; i < filec; ++i) {
  88.         if(i < h.partnum % filec) {
  89.             c = major;
  90.         } else {
  91.             c = minor;
  92.         }
  93.         sprintf(path, "%s-%d", argv[1], i + 1);
  94.         int dst = open(path, O_RDWR | O_CREAT | O_TRUNC, 0644);
  95.         write_f(dst, &mask, sizeof(mask));
  96.         for(int j = 0; j < c; ++j) {
  97.             read_f(src, &sh, sizeof(sh));
  98.             copy_section(src, dst, sh.offset, sh.size);
  99.         }
  100.         close(dst);
  101.     }
  102.     return 0;
  103. }
Add Comment
Please, Sign In to add comment