unpack.c - dedup - deduplicating backup program
 (HTM) git clone git://bitreich.org/dedup/ git://enlrupgkhuxnvlhsf6lc3fziv5h2hhfrinws65d7roiv6bfj7d652fid.onion/dedup/
 (DIR) Log
 (DIR) Files
 (DIR) Refs
 (DIR) Tags
 (DIR) README
 (DIR) LICENSE
       ---
       unpack.c (2424B)
       ---
            1 /*
            2  * ISC License
            3  *
            4  * (c) 2019 Roberto E. Vargas Caballero <k0ga@shike2.com>
            5  *
            6  * Permission to use, copy, modify, and/or distribute this software for any
            7  * purpose with or without fee is hereby granted, provided that the above
            8  * copyright notice and this permission notice appear in all copies.
            9  *
           10  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
           11  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
           12  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
           13  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
           14  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
           15  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
           16  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
           17  */
           18 
           19 #include <ctype.h>
           20 #include <stdarg.h>
           21 #include <stdio.h>
           22 #include <stdlib.h>
           23 
           24 static int
           25 lunpack(unsigned char *src, char *fmt, va_list va)
           26 {
           27         unsigned char *bp, *cp;
           28         unsigned short *sp;
           29         unsigned s;
           30         unsigned long *lp, l;
           31         unsigned long long *qp, q;
           32         int n;
           33 
           34         bp = src;
           35         while (*fmt) {
           36                 switch (*fmt++) {
           37                 case '\'':
           38                         n = atoi(fmt);
           39                         while (isdigit(*fmt))
           40                                 fmt++;
           41                         cp = va_arg(va, unsigned char *);
           42                         while (n--)
           43                                 *cp++ = *bp++;
           44                         break;
           45                 case 'c':
           46                         cp = va_arg(va, unsigned char *);
           47                         *cp = *bp++;
           48                         break;
           49                 case 's':
           50                         sp = va_arg(va, unsigned short *);
           51                         s =  (unsigned) *bp++;
           52                         s |= (unsigned) *bp++ << 8;
           53                         *sp = s;
           54                         break;
           55                 case 'l':
           56                         lp = va_arg(va, unsigned long *);
           57                         l = (unsigned long) *bp++;
           58                         l |= (unsigned long) *bp++ << 8;
           59                         l |= (unsigned long) *bp++ << 16;
           60                         l |= (unsigned long) *bp++ << 24;
           61                         *lp = l;
           62                         break;
           63                 case 'q':
           64                         qp = va_arg(va, unsigned long long *);
           65                         q = (unsigned long long) *bp++;
           66                         q |= (unsigned long long) *bp++ << 8;
           67                         q |= (unsigned long long) *bp++ << 16;
           68                         q |= (unsigned long long) *bp++ << 24;
           69                         q |= (unsigned long long) *bp++ << 32;
           70                         q |= (unsigned long long) *bp++ << 40;
           71                         q |= (unsigned long long) *bp++ << 48;
           72                         q |= (unsigned long long) *bp++ << 56;
           73                         *qp = q;
           74                         break;
           75                 default:
           76                         va_end(va);
           77                         return -1;
           78                 }
           79         }
           80 
           81         return bp - src;
           82 }
           83 
           84 int
           85 unpack(unsigned char *src, char *fmt, ...)
           86 {
           87         int r;
           88         int (*fn)(unsigned char *dst, char *fmt, va_list va);
           89         va_list va;
           90 
           91         va_start(va, fmt);
           92         fn = lunpack;
           93         r = (*fn)(src, fmt, va);
           94         va_end(va);
           95 
           96         return r;
           97 }