Annotation of embedaddon/istgt/src/istgt_misc.c, revision 1.1.1.1

1.1       misho       1: /*
                      2:  * Copyright (C) 2008-2010 Daisuke Aoyama <aoyama@peach.ne.jp>.
                      3:  * All rights reserved.
                      4:  *
                      5:  * Redistribution and use in source and binary forms, with or without
                      6:  * modification, are permitted provided that the following conditions
                      7:  * are met:
                      8:  * 1. Redistributions of source code must retain the above copyright
                      9:  *    notice, this list of conditions and the following disclaimer.
                     10:  * 2. Redistributions in binary form must reproduce the above copyright
                     11:  *    notice, this list of conditions and the following disclaimer in the
                     12:  *    documentation and/or other materials provided with the distribution.
                     13:  *
                     14:  * THIS SOFTWARE IS PROVIDED BY AUTHOR AND CONTRIBUTORS ``AS IS'' AND
                     15:  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
                     16:  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
                     17:  * ARE DISCLAIMED.  IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE
                     18:  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
                     19:  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
                     20:  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
                     21:  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
                     22:  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
                     23:  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
                     24:  * SUCH DAMAGE.
                     25:  *
                     26:  */
                     27: 
                     28: #ifdef HAVE_CONFIG_H
                     29: #include "config.h"
                     30: #endif
                     31: 
                     32: #include <inttypes.h>
                     33: #include <stdint.h>
                     34: 
                     35: #include <ctype.h>
                     36: #include <stdarg.h>
                     37: #include <stdio.h>
                     38: #include <stdlib.h>
                     39: #include <string.h>
                     40: #include <syslog.h>
                     41: 
                     42: #include <unistd.h>
                     43: 
                     44: #ifdef HAVE_LIBPTHREAD
                     45: #include <pthread.h>
                     46: #endif
                     47: #ifdef HAVE_SCHED
                     48: #include <sched.h>
                     49: #endif
                     50: 
                     51: #include "istgt.h"
                     52: #include "istgt_misc.h"
                     53: 
                     54: static void
                     55: fatal(const char *format, ...)
                     56: {
                     57:        char buf[MAX_TMPBUF];
                     58:        va_list ap;
                     59: 
                     60:        va_start(ap, format);
                     61:        vsnprintf(buf, sizeof buf, format, ap);
                     62:        fprintf(stderr, "%s", buf);
                     63:        syslog(LOG_ERR, "%s", buf);
                     64:        va_end(ap);
                     65:        exit(EXIT_FAILURE);
                     66: }
                     67: 
                     68: void *
                     69: xmalloc(size_t size)
                     70: {
                     71:        void *p;
                     72: 
                     73:        if (size < 1)
                     74:                size = 1;
                     75:        p = malloc(size);
                     76:        if (p == NULL)
                     77:                fatal("no memory\n");
                     78:        return p;
                     79: }
                     80: 
                     81: void *
                     82: xrealloc(void *p, size_t size)
                     83: {
                     84:        if (size < 1)
                     85:                size = 1;
                     86:        if (p == NULL) {
                     87:                p = malloc(size);
                     88:        } else {
                     89:                p = realloc(p, size);
                     90:        }
                     91:        if (p == NULL)
                     92:                fatal("no memory\n");
                     93:        return p;
                     94: }
                     95: 
                     96: void
                     97: xfree(void *p)
                     98: {
                     99:        if (p == NULL)
                    100:                return;
                    101:        free(p);
                    102: }
                    103: 
                    104: char *
                    105: xstrdup(const char *s)
                    106: {
                    107:        char *p;
                    108:        size_t size;
                    109: 
                    110:        if (s == NULL)
                    111:                return NULL;
                    112:        size = strlen(s) + 1;
                    113:        p = xmalloc(size);
                    114:        memcpy(p, s, size - 1);
                    115:        p[size - 1] = '\0';
                    116:        return p;
                    117: }
                    118: 
                    119: char *
                    120: strlwr(char *s)
                    121: {
                    122:        char *p;
                    123: 
                    124:        if (s == NULL)
                    125:                return NULL;
                    126: 
                    127:        p = s;
                    128:        while (*p != '\0') {
                    129:                *p = tolower((int) *p);
                    130:                p++;
                    131:        }
                    132:        return s;
                    133: }
                    134: 
                    135: char *
                    136: strupr(char *s)
                    137: {
                    138:        char *p;
                    139: 
                    140:        if (s == NULL)
                    141:                return NULL;
                    142: 
                    143:        p = s;
                    144:        while (*p != '\0') {
                    145:                *p = toupper((int) *p);
                    146:                p++;
                    147:        }
                    148:        return s;
                    149: }
                    150: 
                    151: char *
                    152: strsepq(char **stringp, const char *delim)
                    153: {
                    154:        char *p, *q, *r;
                    155:        int quoted = 0, bslash = 0;
                    156: 
                    157:        p = *stringp;
                    158:        if (p == NULL)
                    159:                return NULL;
                    160: 
                    161:        r = q = p;
                    162:        while (*q != '\0' && *q != '\n') {
                    163:                /* eat quoted characters */
                    164:                if (bslash) {
                    165:                        bslash = 0;
                    166:                        *r++ = *q++;
                    167:                        continue;
                    168:                } else if (quoted) {
                    169:                        if (quoted == '"' && *q == '\\') {
                    170:                                bslash = 1;
                    171:                                q++;
                    172:                                continue;
                    173:                        } else if (*q == quoted) {
                    174:                                quoted = 0;
                    175:                                q++;
                    176:                                continue;
                    177:                        }
                    178:                        *r++ = *q++;
                    179:                        continue;
                    180:                } else if (*q == '\\') {
                    181:                        bslash = 1;
                    182:                        q++;
                    183:                        continue;
                    184:                } else if (*q == '"' || *q == '\'') {
                    185:                        quoted = *q;
                    186:                        q++;
                    187:                        continue;
                    188:                }
                    189: 
                    190:                /* separator? */
                    191:                if (strchr(delim, (int) *q) == NULL) {
                    192:                        *r++ = *q++;
                    193:                        continue;
                    194:                }
                    195: 
                    196:                /* new string */
                    197:                q++;
                    198:                break;
                    199:        }
                    200:        *r = '\0';
                    201: 
                    202:        /* skip tailer */
                    203:        while (*q != '\0' && strchr(delim, (int) *q) != NULL) {
                    204:         q++;
                    205:        }
                    206:        if (*q != '\0') {
                    207:                *stringp = q;
                    208:        } else {
                    209:                *stringp = NULL;
                    210:        }
                    211: 
                    212:        return p;
                    213: }
                    214: 
                    215: char *
                    216: trim_string(char *s)
                    217: {
                    218:        char *p, *q;
                    219: 
                    220:        if (s == NULL)
                    221:                return NULL;
                    222: 
                    223:        /* remove header */
                    224:        p = s;
                    225:        while (*p != '\0' && isspace((int) *p)) {
                    226:                p++;
                    227:        }
                    228:        /* remove tailer */
                    229:        q = p + strlen(p);
                    230:        while (q - 1 >= p && isspace((int) *(q - 1))) {
                    231:                q--;
                    232:                *q = '\0';
                    233:        }
                    234:        /* if remove header, move */
                    235:        if (p != s) {
                    236:                q = s;
                    237:                while (*p != '\0') {
                    238:                        *q++ = *p++;
                    239:                }
                    240:        }
                    241:        return s;
                    242: }
                    243: 
                    244: char *
                    245: escape_string(const char *s)
                    246: {
                    247:        const char *p;
                    248:        char *q, *r;
                    249:        size_t size;
                    250: 
                    251:        if (s == NULL)
                    252:                return NULL;
                    253: 
                    254:        p = s;
                    255:        size = 0;
                    256:        while (*p != '\0') {
                    257:                if (*p == '"' || *p == '\\' || *p == '\'') {
                    258:                        size += 2;
                    259:                } else {
                    260:                        size++;
                    261:                }
                    262:                p++;
                    263:        }
                    264: 
                    265:        p = s;
                    266:        r = q = xmalloc(size + 1);
                    267:        while (*p != '\0') {
                    268:                if (*p == '"' || *p == '\\' || *p == '\'') {
                    269:                        *q++ = '\\';
                    270:                        *q++ = *p++;
                    271:                } else {
                    272:                        *q++ = *p++;
                    273:                }
                    274:        }
                    275:        *q++ = '\0';
                    276:        return r;
                    277: }
                    278: 
                    279: /* LBA = (M * 60 + S) * 75 + F - 150 */
                    280: uint32_t
                    281: istgt_msf2lba(uint32_t msf)
                    282: {
                    283:        uint32_t lba;
                    284: 
                    285:        lba = ((msf >> 16) & 0xff) * 60 * 75;
                    286:        lba += ((msf >> 8) & 0xff) * 75;
                    287:        lba += msf & 0xff;
                    288:        lba -= 150;
                    289:        return lba;
                    290: }
                    291: 
                    292: uint32_t
                    293: istgt_lba2msf(uint32_t lba)
                    294: {
                    295:        uint32_t m, s, f;
                    296: 
                    297:        lba += 150;
                    298:        m = (lba / 75) / 60;
                    299:        s = (lba / 75) % 60;
                    300:        f = lba % 75;
                    301: 
                    302:        return ((m << 16) | (s << 8) | f);
                    303: }
                    304: 
                    305: uint8_t
                    306: istgt_dget8(const uint8_t *data)
                    307: {
                    308:        uint8_t value;
                    309: 
                    310:        value  = (data[0] & 0xffU) << 0;
                    311:        return value;
                    312: }
                    313: 
                    314: void
                    315: istgt_dset8(uint8_t *data, uint32_t value)
                    316: {
                    317:        data[0] = (value >> 0) & 0xffU;
                    318: }
                    319: 
                    320: uint16_t
                    321: istgt_dget16(const uint8_t *data)
                    322: {
                    323:        uint16_t value;
                    324: 
                    325:        value  = (data[0] & 0xffU) << 8;
                    326:        value |= (data[1] & 0xffU) << 0;
                    327:        return value;
                    328: }
                    329: 
                    330: void
                    331: istgt_dset16(uint8_t *data, uint32_t value)
                    332: {
                    333:        data[0] = (value >> 8) & 0xffU;
                    334:        data[1] = (value >> 0) & 0xffU;
                    335: }
                    336: 
                    337: uint32_t
                    338: istgt_dget24(const uint8_t *data)
                    339: {
                    340:        uint32_t value;
                    341: 
                    342:        value  = (data[0] & 0xffU) << 16;
                    343:        value |= (data[1] & 0xffU) << 8;
                    344:        value |= (data[2] & 0xffU) << 0;
                    345:        return value;
                    346: }
                    347: 
                    348: void
                    349: istgt_dset24(uint8_t *data, uint32_t value)
                    350: {
                    351:        data[0] = (value >> 16) & 0xffU;
                    352:        data[1] = (value >> 8)  & 0xffU;
                    353:        data[2] = (value >> 0)  & 0xffU;
                    354: }
                    355: 
                    356: uint32_t
                    357: istgt_dget32(const uint8_t *data)
                    358: {
                    359:        uint32_t value;
                    360: 
                    361:        value  = (data[0] & 0xffU) << 24;
                    362:        value |= (data[1] & 0xffU) << 16;
                    363:        value |= (data[2] & 0xffU) << 8;
                    364:        value |= (data[3] & 0xffU) << 0;
                    365:        return value;
                    366: }
                    367: 
                    368: void
                    369: istgt_dset32(uint8_t *data, uint32_t value)
                    370: {
                    371:        data[0] = (value >> 24) & 0xffU;
                    372:        data[1] = (value >> 16) & 0xffU;
                    373:        data[2] = (value >> 8)  & 0xffU;
                    374:        data[3] = (value >> 0)  & 0xffU;
                    375: }
                    376: 
                    377: uint64_t
                    378: istgt_dget48(const uint8_t *data)
                    379: {
                    380:        uint64_t value;
                    381: 
                    382:        value  = (data[0] & 0xffULL) << 40;
                    383:        value |= (data[1] & 0xffULL) << 32;
                    384:        value |= (data[2] & 0xffULL) << 24;
                    385:        value |= (data[3] & 0xffULL) << 16;
                    386:        value |= (data[4] & 0xffULL) << 8;
                    387:        value |= (data[5] & 0xffULL) << 0;
                    388:        return value;
                    389: }
                    390: 
                    391: void
                    392: istgt_dset48(uint8_t *data, uint64_t value)
                    393: {
                    394:        data[0] = (value >> 40) & 0xffULL;
                    395:        data[1] = (value >> 32) & 0xffULL;
                    396:        data[2] = (value >> 24) & 0xffULL;
                    397:        data[3] = (value >> 16) & 0xffULL;
                    398:        data[4] = (value >> 8)  & 0xffULL;
                    399:        data[5] = (value >> 0)  & 0xffULL;
                    400: }
                    401: 
                    402: uint64_t
                    403: istgt_dget64(const uint8_t *data)
                    404: {
                    405:        uint64_t value;
                    406: 
                    407:        value  = (data[0] & 0xffULL) << 56;
                    408:        value |= (data[1] & 0xffULL) << 48;
                    409:        value |= (data[2] & 0xffULL) << 40;
                    410:        value |= (data[3] & 0xffULL) << 32;
                    411:        value |= (data[4] & 0xffULL) << 24;
                    412:        value |= (data[5] & 0xffULL) << 16;
                    413:        value |= (data[6] & 0xffULL) << 8;
                    414:        value |= (data[7] & 0xffULL) << 0;
                    415:        return value;
                    416: }
                    417: 
                    418: void
                    419: istgt_dset64(uint8_t *data, uint64_t value)
                    420: {
                    421:        data[0] = (value >> 56) & 0xffULL;
                    422:        data[1] = (value >> 48) & 0xffULL;
                    423:        data[2] = (value >> 40) & 0xffULL;
                    424:        data[3] = (value >> 32) & 0xffULL;
                    425:        data[4] = (value >> 24) & 0xffULL;
                    426:        data[5] = (value >> 16) & 0xffULL;
                    427:        data[6] = (value >> 8)  & 0xffULL;
                    428:        data[7] = (value >> 0)  & 0xffULL;
                    429: }
                    430: 
                    431: void
                    432: istgt_dump(const char *label, const uint8_t *buf, size_t len)
                    433: {
                    434:        istgt_fdump(stdout, label, buf, len);
                    435: }
                    436: 
                    437: void
                    438: istgt_fdump(FILE *fp, const char *label, const uint8_t *buf, size_t len)
                    439: {
                    440:        char tmpbuf[MAX_TMPBUF];
                    441:        char buf8[8+1];
                    442:        int total;
                    443:        int i;
                    444: 
                    445:        fprintf(fp, "%s\n", label);
                    446: 
                    447:        memset(buf8, 0, sizeof buf8);
                    448:        total = 0;
                    449:        for (i = 0; i < len; i++) {
                    450:                if (i != 0 && i % 8 == 0) {
                    451:                        total += snprintf(tmpbuf + total, sizeof tmpbuf - total,
                    452:                                                          "%s", buf8);
                    453:                        fprintf(fp, "%s\n", tmpbuf);
                    454:                        total = 0;
                    455:                }
                    456:                total += snprintf(tmpbuf + total, sizeof tmpbuf - total,
                    457:                                                  "%2.2x ", buf[i] & 0xff);
                    458:                buf8[i % 8] = isprint(buf[i]) ? buf[i] : '.';
                    459:        }
                    460:        for ( ; i % 8 != 0; i++) {
                    461:                total += snprintf(tmpbuf + total, sizeof tmpbuf - total, "   ");
                    462:                buf8[i % 8] = ' ';
                    463:        }
                    464:        total += snprintf(tmpbuf + total, sizeof tmpbuf - total, "%s", buf8);
                    465:        fprintf(fp, "%s\n", tmpbuf);
                    466:        fflush(fp);
                    467: }
                    468: 
                    469: #ifndef HAVE_SRANDOMDEV
                    470: #include <time.h>
                    471: void
                    472: srandomdev(void)
                    473: {
                    474:        unsigned long seed;
                    475:        time_t now;
                    476:        pid_t pid;
                    477: 
                    478:        pid = getpid();
                    479:        now = time(NULL);
                    480:        seed = pid ^ now;
                    481:        srandom(seed);
                    482: }
                    483: #endif /* HAVE_SRANDOMDEV */
                    484: 
                    485: #ifndef HAVE_ARC4RANDOM
                    486: static int istgt_arc4random_initialized = 0;
                    487: 
                    488: uint32_t
                    489: arc4random(void)
                    490: {
                    491:        uint32_t r;
                    492:        uint32_t r1, r2;
                    493: 
                    494:        if (!istgt_arc4random_initialized) {
                    495:                srandomdev();
                    496:                istgt_arc4random_initialized = 1;
                    497:        }
                    498:        r1 = (uint32_t) (random() & 0xffff);
                    499:        r2 = (uint32_t) (random() & 0xffff);
                    500:        r = (r1 << 16) | r2;
                    501:        return r;
                    502: }
                    503: #endif /* HAVE_ARC4RANDOM */
                    504: 
                    505: void
                    506: istgt_gen_random(uint8_t *buf, size_t len)
                    507: {
                    508: #ifdef USE_RANDOM
                    509:        long l;
                    510:        int i;
                    511: 
                    512:        srandomdev();
                    513:        for (i = 0; i < len; i++) {
                    514:                l = random();
                    515:                buf[i] = (uint8_t) l;
                    516:        }
                    517: #else
                    518:        uint32_t r;
                    519:        int i;
                    520: 
                    521:        for (i = 0; i < len; i++) {
                    522:                r = arc4random();
                    523:                buf[i] = (uint8_t) r;
                    524:        }
                    525: #endif /* USE_RANDOM */
                    526: }
                    527: 
                    528: int
                    529: istgt_bin2hex(char *buf, size_t len, const uint8_t *data, size_t data_len)
                    530: {
                    531:        const char *digits = "0123456789ABCDEF";
                    532:        int total = 0;
                    533:        int i;
                    534: 
                    535:        if (len < 3)
                    536:                return -1;
                    537:        buf[total] = '0';
                    538:        total++;
                    539:        buf[total] = 'x';
                    540:        total++;
                    541:        buf[total] = '\0';
                    542: 
                    543:        for (i = 0; i < data_len; i++) {
                    544:                if (total + 3 > len) {
                    545:                        buf[total] = '\0';
                    546:                        return - 1;
                    547:                }
                    548:                buf[total] = digits[(data[i] >> 4) & 0x0fU];
                    549:                total++;
                    550:                buf[total] = digits[data[i] & 0x0fU];
                    551:                total++;
                    552:        }
                    553:        buf[total] = '\0';
                    554:        return total;
                    555: }
                    556: 
                    557: int
                    558: istgt_hex2bin(uint8_t *data, size_t data_len, const char *str)
                    559: {
                    560:        const char *digits = "0123456789ABCDEF";
                    561:        const char *dp;
                    562:        const char *p;
                    563:        int total = 0;
                    564:        int n0, n1;
                    565: 
                    566:        p = str;
                    567:        if (p[0] != '0' && (p[1] != 'x' && p[1] != 'X'))
                    568:                return -1;
                    569:        p += 2;
                    570: 
                    571:        while (p[0] != '\0' && p[1] != '\0') {
                    572:                if (total >= data_len) {
                    573:                        return -1;
                    574:                }
                    575:                dp = strchr(digits, toupper((int) p[0]));
                    576:                if (dp == NULL) {
                    577:                        return -1;
                    578:                }
                    579:                n0 = (int) (dp - digits);
                    580:                dp = strchr(digits, toupper((int) p[1]));
                    581:                if (dp == NULL) {
                    582:                        return -1;
                    583:                }
                    584:                n1 = (int) (dp - digits);
                    585: 
                    586:                data[total] = (uint8_t) (((n0 & 0x0fU) << 4) | (n1 & 0x0fU));
                    587:                total++;
                    588:                p += 2;
                    589:        }
                    590:        return total;
                    591: }
                    592: 
                    593: void
                    594: istgt_yield(void)
                    595: {
                    596: #if defined (HAVE_PTHREAD_YIELD)
                    597:        pthread_yield();
                    598: #elif defined (HAVE_SCHED_YIELD)
                    599:        sched_yield();
                    600: #else
                    601:        usleep(0);
                    602: #endif
                    603: }
                    604: 
                    605: #ifndef HAVE_STRLCPY
                    606: size_t
                    607: strlcpy(char *dst, const char *src, size_t size)
                    608: {
                    609:        size_t len;
                    610: 
                    611:        if (dst == NULL)
                    612:                return 0;
                    613:        if (size < 1) {
                    614:                return 0;
                    615:        }
                    616:        len = strlen(src);
                    617:        if (len > size - 1) {
                    618:                len = size - 1;
                    619:        }
                    620:        memcpy(dst, src, len);
                    621:        dst[len] = '\0';
                    622:        return len;
                    623: }
                    624: #endif /* HAVE_STRLCPY */

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>