"Fossies" - the Fresh Open Source Software Archive

Member "cryptsetup-2.4.3/tests/differ.c" (13 Jan 2022, 3694 Bytes) of package /linux/misc/cryptsetup-2.4.3.tar.xz:


As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) C and C++ source code syntax highlighting (style: standard) with prefixed line numbers and code folding option. Alternatively you can here view or download the uninterpreted source code file.

    1 /*
    2  * cryptsetup file differ check (rewritten Clemens' fileDiffer in Python)
    3  *
    4  * Copyright (C) 2010-2021 Red Hat, Inc. All rights reserved.
    5  *
    6  * This program is free software; you can redistribute it and/or
    7  * modify it under the terms of the GNU General Public License
    8  * as published by the Free Software Foundation; either version 2
    9  * of the License, or (at your option) any later version.
   10  *
   11  * This program is distributed in the hope that it will be useful,
   12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
   13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   14  * GNU General Public License for more details.
   15  *
   16  * You should have received a copy of the GNU General Public License
   17  * along with this program; if not, write to the Free Software
   18  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
   19  */
   20 
   21 #include <stdio.h>
   22 #include <stdlib.h>
   23 #include <string.h>
   24 #include <fcntl.h>
   25 #include <unistd.h>
   26 #include <ctype.h>
   27 #include <sys/stat.h>
   28 #include <sys/mman.h>
   29 
   30 struct ffile {
   31     char *name;
   32     int fd;
   33     unsigned char *addr;
   34     size_t size;
   35 };
   36 
   37 enum df { OK , FAIL };
   38 
   39 static void print_diff(off_t from, int max,
   40                const unsigned char *o,
   41                const unsigned char *n)
   42 {
   43     int i, len = max;
   44 
   45     if (len > 16)
   46         len = 16;
   47 
   48     printf("OLD:");
   49     for (i = 0; i < len; i++)
   50         printf(" %02x", o[from + i]);
   51     printf("%s\n    ", max != len ? " ..." : "");
   52     for (i = 0; i < len; i++)
   53         printf(" %2c", o[from + i] > ' ' ? o[from + i]: '.');
   54     printf("\nNEW:");
   55     for (i = 0; i < len; i++)
   56         printf(" %02x", n[from + i]);
   57     printf("%s\n    ", max != len ? " ..." : "");
   58     for (i = 0; i < len; i++)
   59         printf(" %2c", n[from + i] > ' ' ? n[from + i]: '.');
   60     printf("\n");
   61 }
   62 
   63 /*
   64  * Xfrom-to (e.g. R10-15)
   65  * A - change allowed
   66  * S - change required, semantic
   67  * R - change required, random
   68  * F - change forbidden
   69  */
   70 static enum df check(const char *range, unsigned char *o, unsigned char *n)
   71 {
   72     char strict;
   73     unsigned long long from, to;
   74     enum df ret;
   75 
   76     if (sscanf(range, "%c%llu-%llu", &strict, &from, &to) != 3) {
   77         printf("Unknown range format %s.\n", range);
   78         return FAIL;
   79     }
   80 
   81     switch (toupper(strict)) {
   82     case 'A':
   83         ret = OK;
   84         break;
   85     case 'S':
   86         ret = memcmp(&o[from], &n[from], to - from + 1) != 0 ? OK : FAIL;
   87         break;
   88     case 'R': /* FIXME - random test */
   89         ret = memcmp(&o[from], &n[from], to - from + 1) != 0 ? OK : FAIL;
   90         break;
   91     case 'F':
   92         ret = memcmp(&o[from], &n[from], to - from + 1) == 0 ? OK : FAIL;
   93         break;
   94     default:
   95         ret = FAIL;
   96         break;
   97     }
   98 
   99     if (ret == FAIL)
  100         print_diff(from,  to - from + 1, o, n);
  101 
  102     return ret;
  103 }
  104 
  105 static int open_mmap(struct ffile *f)
  106 {
  107     struct stat st;
  108 
  109     f->fd = open(f->name, O_RDONLY);
  110     if (f->fd == -1 || fstat(f->fd, &st) == -1)
  111         return 0;
  112 
  113     f->size = st.st_size;
  114     f->addr = mmap(NULL, f->size, PROT_READ, MAP_PRIVATE, f->fd, 0);
  115 
  116     return (f->addr == MAP_FAILED) ? 0 : 1;
  117 }
  118 
  119 static void close_mmap(struct ffile *f)
  120 {
  121     if (f->addr != MAP_FAILED && !munmap(f->addr, f->size))
  122         f->addr = MAP_FAILED;
  123 
  124     if (f->fd != -1 && !close(f->fd))
  125         f->fd = -1;
  126 }
  127 
  128 int main(int argc, char *argv[])
  129 {
  130     int i, r = 1;
  131     struct ffile file_old = {
  132         .fd = -1,
  133         .addr = MAP_FAILED,
  134     };
  135     struct ffile file_new = {
  136         .fd = -1,
  137         .addr = MAP_FAILED,
  138     };
  139 
  140     if (argc < 3) {
  141         printf("Use: differ old_file new_file change_list.\n");
  142         goto bad;
  143     }
  144 
  145     file_old.name = argv[1];
  146     if (!open_mmap(&file_old))
  147         goto bad;
  148 
  149     file_new.name = argv[2];
  150     if (!open_mmap(&file_new))
  151         goto bad;
  152 
  153     for (i = 3; i < argc; i++)
  154         if (check(argv[i], file_old.addr, file_new.addr) == FAIL) {
  155             printf ("FAILED for %s\n", argv[i]);
  156             r = 1;
  157             goto bad;
  158         }
  159 
  160     r = 0;
  161 bad:
  162     close_mmap(&file_new);
  163     close_mmap(&file_old);
  164 
  165     return r;
  166 }