Annotation of embedaddon/istgt/src/istgt_misc.c, revision 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>