File:  [ELWIX - Embedded LightWeight unIX -] / embedaddon / istgt / src / istgt_misc.c
Revision 1.1.1.2 (vendor branch): download - view: text, annotated - select for diffs - revision graph
Tue Oct 9 09:13:23 2012 UTC (11 years, 9 months ago) by misho
Branches: istgt, MAIN
CVS tags: v20121028, v20120901, HEAD
dhcp 4.1 r7

    1: /*
    2:  * Copyright (C) 2008-2012 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: #if !defined(__GNUC__)
   55: #undef __attribute__
   56: #define __attribute__(x)
   57: #endif
   58: 
   59: static void fatal(const char *format, ...) __attribute__((__noreturn__, __format__(__printf__, 1, 2)));
   60: 
   61: static void
   62: fatal(const char *format, ...)
   63: {
   64: 	char buf[MAX_TMPBUF];
   65: 	va_list ap;
   66: 
   67: 	va_start(ap, format);
   68: 	vsnprintf(buf, sizeof buf, format, ap);
   69: 	fprintf(stderr, "%s", buf);
   70: 	syslog(LOG_ERR, "%s", buf);
   71: 	va_end(ap);
   72: 	exit(EXIT_FAILURE);
   73: }
   74: 
   75: void *
   76: xmalloc(size_t size)
   77: {
   78: 	void *p;
   79: 
   80: 	if (size < 1)
   81: 		size = 1;
   82: 	p = malloc(size);
   83: 	if (p == NULL)
   84: 		fatal("no memory\n");
   85: 	return p;
   86: }
   87: 
   88: void *
   89: xrealloc(void *p, size_t size)
   90: {
   91: 	if (size < 1)
   92: 		size = 1;
   93: 	if (p == NULL) {
   94: 		p = malloc(size);
   95: 	} else {
   96: 		p = realloc(p, size);
   97: 	}
   98: 	if (p == NULL)
   99: 		fatal("no memory\n");
  100: 	return p;
  101: }
  102: 
  103: void
  104: xfree(void *p)
  105: {
  106: 	if (p == NULL)
  107: 		return;
  108: 	free(p);
  109: }
  110: 
  111: char *
  112: xstrdup(const char *s)
  113: {
  114: 	char *p;
  115: 	size_t size;
  116: 
  117: 	if (s == NULL)
  118: 		return NULL;
  119: 	size = strlen(s) + 1;
  120: 	p = xmalloc(size);
  121: 	memcpy(p, s, size - 1);
  122: 	p[size - 1] = '\0';
  123: 	return p;
  124: }
  125: 
  126: char *
  127: strlwr(char *s)
  128: {
  129: 	char *p;
  130: 
  131: 	if (s == NULL)
  132: 		return NULL;
  133: 
  134: 	p = s;
  135: 	while (*p != '\0') {
  136: 		*p = tolower((int) *p);
  137: 		p++;
  138: 	}
  139: 	return s;
  140: }
  141: 
  142: char *
  143: strupr(char *s)
  144: {
  145: 	char *p;
  146: 
  147: 	if (s == NULL)
  148: 		return NULL;
  149: 
  150: 	p = s;
  151: 	while (*p != '\0') {
  152: 		*p = toupper((int) *p);
  153: 		p++;
  154: 	}
  155: 	return s;
  156: }
  157: 
  158: char *
  159: strsepq(char **stringp, const char *delim)
  160: {
  161: 	char *p, *q, *r;
  162: 	int quoted = 0, bslash = 0;
  163: 
  164: 	p = *stringp;
  165: 	if (p == NULL)
  166: 		return NULL;
  167: 
  168: 	r = q = p;
  169: 	while (*q != '\0' && *q != '\n') {
  170: 		/* eat quoted characters */
  171: 		if (bslash) {
  172: 			bslash = 0;
  173: 			*r++ = *q++;
  174: 			continue;
  175: 		} else if (quoted) {
  176: 			if (quoted == '"' && *q == '\\') {
  177: 				bslash = 1;
  178: 				q++;
  179: 				continue;
  180: 			} else if (*q == quoted) {
  181: 				quoted = 0;
  182: 				q++;
  183: 				continue;
  184: 			}
  185: 			*r++ = *q++;
  186: 			continue;
  187: 		} else if (*q == '\\') {
  188: 			bslash = 1;
  189: 			q++;
  190: 			continue;
  191: 		} else if (*q == '"' || *q == '\'') {
  192: 			quoted = *q;
  193: 			q++;
  194: 			continue;
  195: 		}
  196: 
  197: 		/* separator? */
  198: 		if (strchr(delim, (int) *q) == NULL) {
  199: 			*r++ = *q++;
  200: 			continue;
  201: 		}
  202: 
  203: 		/* new string */
  204: 		q++;
  205: 		break;
  206: 	}
  207: 	*r = '\0';
  208: 
  209: 	/* skip tailer */
  210: 	while (*q != '\0' && strchr(delim, (int) *q) != NULL) {
  211:         q++;
  212: 	}
  213: 	if (*q != '\0') {
  214: 		*stringp = q;
  215: 	} else {
  216: 		*stringp = NULL;
  217: 	}
  218: 
  219: 	return p;
  220: }
  221: 
  222: char *
  223: trim_string(char *s)
  224: {
  225: 	char *p, *q;
  226: 
  227: 	if (s == NULL)
  228: 		return NULL;
  229: 
  230: 	/* remove header */
  231: 	p = s;
  232: 	while (*p != '\0' && isspace((int) *p)) {
  233: 		p++;
  234: 	}
  235: 	/* remove tailer */
  236: 	q = p + strlen(p);
  237: 	while (q - 1 >= p && isspace((int) *(q - 1))) {
  238: 		q--;
  239: 		*q = '\0';
  240: 	}
  241: 	/* if remove header, move */
  242: 	if (p != s) {
  243: 		q = s;
  244: 		while (*p != '\0') {
  245: 			*q++ = *p++;
  246: 		}
  247: 	}
  248: 	return s;
  249: }
  250: 
  251: char *
  252: escape_string(const char *s)
  253: {
  254: 	const char *p;
  255: 	char *q, *r;
  256: 	size_t size;
  257: 
  258: 	if (s == NULL)
  259: 		return NULL;
  260: 
  261: 	p = s;
  262: 	size = 0;
  263: 	while (*p != '\0') {
  264: 		if (*p == '"' || *p == '\\' || *p == '\'') {
  265: 			size += 2;
  266: 		} else {
  267: 			size++;
  268: 		}
  269: 		p++;
  270: 	}
  271: 
  272: 	p = s;
  273: 	r = q = xmalloc(size + 1);
  274: 	while (*p != '\0') {
  275: 		if (*p == '"' || *p == '\\' || *p == '\'') {
  276: 			*q++ = '\\';
  277: 			*q++ = *p++;
  278: 		} else {
  279: 			*q++ = *p++;
  280: 		}
  281: 	}
  282: 	*q++ = '\0';
  283: 	return r;
  284: }
  285: 
  286: /* LBA = (M * 60 + S) * 75 + F - 150 */
  287: uint32_t
  288: istgt_msf2lba(uint32_t msf)
  289: {
  290: 	uint32_t lba;
  291: 
  292: 	lba = ((msf >> 16) & 0xff) * 60 * 75;
  293: 	lba += ((msf >> 8) & 0xff) * 75;
  294: 	lba += msf & 0xff;
  295: 	lba -= 150;
  296: 	return lba;
  297: }
  298: 
  299: uint32_t
  300: istgt_lba2msf(uint32_t lba)
  301: {
  302: 	uint32_t m, s, f;
  303: 
  304: 	lba += 150;
  305: 	m = (lba / 75) / 60;
  306: 	s = (lba / 75) % 60;
  307: 	f = lba % 75;
  308: 
  309: 	return ((m << 16) | (s << 8) | f);
  310: }
  311: 
  312: uint8_t
  313: istgt_dget8(const uint8_t *data)
  314: {
  315: 	uint8_t value;
  316: 
  317: 	value  = (data[0] & 0xffU) << 0;
  318: 	return value;
  319: }
  320: 
  321: void
  322: istgt_dset8(uint8_t *data, uint32_t value)
  323: {
  324: 	data[0] = (value >> 0) & 0xffU;
  325: }
  326: 
  327: uint16_t
  328: istgt_dget16(const uint8_t *data)
  329: {
  330: 	uint16_t value;
  331: 
  332: 	value  = (data[0] & 0xffU) << 8;
  333: 	value |= (data[1] & 0xffU) << 0;
  334: 	return value;
  335: }
  336: 
  337: void
  338: istgt_dset16(uint8_t *data, uint32_t value)
  339: {
  340: 	data[0] = (value >> 8) & 0xffU;
  341: 	data[1] = (value >> 0) & 0xffU;
  342: }
  343: 
  344: uint32_t
  345: istgt_dget24(const uint8_t *data)
  346: {
  347: 	uint32_t value;
  348: 
  349: 	value  = (data[0] & 0xffU) << 16;
  350: 	value |= (data[1] & 0xffU) << 8;
  351: 	value |= (data[2] & 0xffU) << 0;
  352: 	return value;
  353: }
  354: 
  355: void
  356: istgt_dset24(uint8_t *data, uint32_t value)
  357: {
  358: 	data[0] = (value >> 16) & 0xffU;
  359: 	data[1] = (value >> 8)  & 0xffU;
  360: 	data[2] = (value >> 0)  & 0xffU;
  361: }
  362: 
  363: uint32_t
  364: istgt_dget32(const uint8_t *data)
  365: {
  366: 	uint32_t value;
  367: 
  368: 	value  = (data[0] & 0xffU) << 24;
  369: 	value |= (data[1] & 0xffU) << 16;
  370: 	value |= (data[2] & 0xffU) << 8;
  371: 	value |= (data[3] & 0xffU) << 0;
  372: 	return value;
  373: }
  374: 
  375: void
  376: istgt_dset32(uint8_t *data, uint32_t value)
  377: {
  378: 	data[0] = (value >> 24) & 0xffU;
  379: 	data[1] = (value >> 16) & 0xffU;
  380: 	data[2] = (value >> 8)  & 0xffU;
  381: 	data[3] = (value >> 0)  & 0xffU;
  382: }
  383: 
  384: uint64_t
  385: istgt_dget48(const uint8_t *data)
  386: {
  387: 	uint64_t value;
  388: 
  389: 	value  = (data[0] & 0xffULL) << 40;
  390: 	value |= (data[1] & 0xffULL) << 32;
  391: 	value |= (data[2] & 0xffULL) << 24;
  392: 	value |= (data[3] & 0xffULL) << 16;
  393: 	value |= (data[4] & 0xffULL) << 8;
  394: 	value |= (data[5] & 0xffULL) << 0;
  395: 	return value;
  396: }
  397: 
  398: void
  399: istgt_dset48(uint8_t *data, uint64_t value)
  400: {
  401: 	data[0] = (value >> 40) & 0xffULL;
  402: 	data[1] = (value >> 32) & 0xffULL;
  403: 	data[2] = (value >> 24) & 0xffULL;
  404: 	data[3] = (value >> 16) & 0xffULL;
  405: 	data[4] = (value >> 8)  & 0xffULL;
  406: 	data[5] = (value >> 0)  & 0xffULL;
  407: }
  408: 
  409: uint64_t
  410: istgt_dget64(const uint8_t *data)
  411: {
  412: 	uint64_t value;
  413: 
  414: 	value  = (data[0] & 0xffULL) << 56;
  415: 	value |= (data[1] & 0xffULL) << 48;
  416: 	value |= (data[2] & 0xffULL) << 40;
  417: 	value |= (data[3] & 0xffULL) << 32;
  418: 	value |= (data[4] & 0xffULL) << 24;
  419: 	value |= (data[5] & 0xffULL) << 16;
  420: 	value |= (data[6] & 0xffULL) << 8;
  421: 	value |= (data[7] & 0xffULL) << 0;
  422: 	return value;
  423: }
  424: 
  425: void
  426: istgt_dset64(uint8_t *data, uint64_t value)
  427: {
  428: 	data[0] = (value >> 56) & 0xffULL;
  429: 	data[1] = (value >> 48) & 0xffULL;
  430: 	data[2] = (value >> 40) & 0xffULL;
  431: 	data[3] = (value >> 32) & 0xffULL;
  432: 	data[4] = (value >> 24) & 0xffULL;
  433: 	data[5] = (value >> 16) & 0xffULL;
  434: 	data[6] = (value >> 8)  & 0xffULL;
  435: 	data[7] = (value >> 0)  & 0xffULL;
  436: }
  437: 
  438: void
  439: istgt_dump(const char *label, const uint8_t *buf, size_t len)
  440: {
  441: 	istgt_fdump(stdout, label, buf, len);
  442: }
  443: 
  444: void
  445: istgt_fdump(FILE *fp, const char *label, const uint8_t *buf, size_t len)
  446: {
  447: 	char tmpbuf[MAX_TMPBUF];
  448: 	char buf8[8+1];
  449: 	size_t total;
  450: 	size_t idx;
  451: 
  452: 	fprintf(fp, "%s\n", label);
  453: 
  454: 	memset(buf8, 0, sizeof buf8);
  455: 	total = 0;
  456: 	for (idx = 0; idx < len; idx++) {
  457: 		if (idx != 0 && idx % 8 == 0) {
  458: 			total += snprintf(tmpbuf + total, sizeof tmpbuf - total,
  459: 			    "%s", buf8);
  460: 			fprintf(fp, "%s\n", tmpbuf);
  461: 			total = 0;
  462: 		}
  463: 		total += snprintf(tmpbuf + total, sizeof tmpbuf - total,
  464: 		    "%2.2x ", buf[idx] & 0xff);
  465: 		buf8[idx % 8] = isprint(buf[idx]) ? buf[idx] : '.';
  466: 	}
  467: 	for ( ; idx % 8 != 0; idx++) {
  468: 		total += snprintf(tmpbuf + total, sizeof tmpbuf - total, "   ");
  469: 		buf8[idx % 8] = ' ';
  470: 	}
  471: 	total += snprintf(tmpbuf + total, sizeof tmpbuf - total, "%s", buf8);
  472: 	fprintf(fp, "%s\n", tmpbuf);
  473: 	fflush(fp);
  474: }
  475: 
  476: #ifndef HAVE_SRANDOMDEV
  477: #include <time.h>
  478: void
  479: srandomdev(void)
  480: {
  481: 	unsigned long seed;
  482: 	time_t now;
  483: 	pid_t pid;
  484: 
  485: 	pid = getpid();
  486: 	now = time(NULL);
  487: 	seed = pid ^ now;
  488: 	srandom(seed);
  489: }
  490: #endif /* HAVE_SRANDOMDEV */
  491: 
  492: #ifndef HAVE_ARC4RANDOM
  493: static int istgt_arc4random_initialized = 0;
  494: 
  495: uint32_t
  496: arc4random(void)
  497: {
  498: 	uint32_t r;
  499: 	uint32_t r1, r2;
  500: 
  501: 	if (!istgt_arc4random_initialized) {
  502: 		srandomdev();
  503: 		istgt_arc4random_initialized = 1;
  504: 	}
  505: 	r1 = (uint32_t) (random() & 0xffff);
  506: 	r2 = (uint32_t) (random() & 0xffff);
  507: 	r = (r1 << 16) | r2;
  508: 	return r;
  509: }
  510: #endif /* HAVE_ARC4RANDOM */
  511: 
  512: void
  513: istgt_gen_random(uint8_t *buf, size_t len)
  514: {
  515: #ifdef USE_RANDOM
  516: 	long l;
  517: 	size_t idx;
  518: 
  519: 	srandomdev();
  520: 	for (idx = 0; idx < len; idx++) {
  521: 		l = random();
  522: 		buf[idx] = (uint8_t) l;
  523: 	}
  524: #else
  525: 	uint32_t r;
  526: 	size_t idx;
  527: 
  528: 	for (idx = 0; idx < len; idx++) {
  529: 		r = arc4random();
  530: 		buf[idx] = (uint8_t) r;
  531: 	}
  532: #endif /* USE_RANDOM */
  533: }
  534: 
  535: int
  536: istgt_bin2hex(char *buf, size_t len, const uint8_t *data, size_t data_len)
  537: {
  538: 	const char *digits = "0123456789ABCDEF";
  539: 	size_t total = 0;
  540: 	size_t idx;
  541: 
  542: 	if (len < 3)
  543: 		return -1;
  544: 	buf[total] = '0';
  545: 	total++;
  546: 	buf[total] = 'x';
  547: 	total++;
  548: 	buf[total] = '\0';
  549: 
  550: 	for (idx = 0; idx < data_len; idx++) {
  551: 		if (total + 3 > len) {
  552: 			buf[total] = '\0';
  553: 			return - 1;
  554: 		}
  555: 		buf[total] = digits[(data[idx] >> 4) & 0x0fU];
  556: 		total++;
  557: 		buf[total] = digits[data[idx] & 0x0fU];
  558: 		total++;
  559: 	}
  560: 	buf[total] = '\0';
  561: 	return total;
  562: }
  563: 
  564: int
  565: istgt_hex2bin(uint8_t *data, size_t data_len, const char *str)
  566: {
  567: 	const char *digits = "0123456789ABCDEF";
  568: 	const char *dp;
  569: 	const char *p;
  570: 	size_t total = 0;
  571: 	int n0, n1;
  572: 
  573: 	p = str;
  574: 	if (p[0] != '0' && (p[1] != 'x' && p[1] != 'X'))
  575: 		return -1;
  576: 	p += 2;
  577: 
  578: 	while (p[0] != '\0' && p[1] != '\0') {
  579: 		if (total >= data_len) {
  580: 			return -1;
  581: 		}
  582: 		dp = strchr(digits, toupper((int) p[0]));
  583: 		if (dp == NULL) {
  584: 			return -1;
  585: 		}
  586: 		n0 = (int) (dp - digits);
  587: 		dp = strchr(digits, toupper((int) p[1]));
  588: 		if (dp == NULL) {
  589: 			return -1;
  590: 		}
  591: 		n1 = (int) (dp - digits);
  592: 
  593: 		data[total] = (uint8_t) (((n0 & 0x0fU) << 4) | (n1 & 0x0fU));
  594: 		total++;
  595: 		p += 2;
  596: 	}
  597: 	return total;
  598: }
  599: 
  600: void
  601: istgt_yield(void)
  602: {
  603: #if defined (HAVE_PTHREAD_YIELD)
  604: 	pthread_yield();
  605: #elif defined (HAVE_SCHED_YIELD)
  606: 	sched_yield();
  607: #else
  608: 	usleep(0);
  609: #endif
  610: }
  611: 
  612: #ifndef HAVE_STRLCPY
  613: size_t
  614: strlcpy(char *dst, const char *src, size_t size)
  615: {
  616: 	size_t len;
  617: 
  618: 	if (dst == NULL)
  619: 		return 0;
  620: 	if (size < 1) {
  621: 		return 0;
  622: 	}
  623: 	len = strlen(src);
  624: 	if (len > size - 1) {
  625: 		len = size - 1;
  626: 	}
  627: 	memcpy(dst, src, len);
  628: 	dst[len] = '\0';
  629: 	return len;
  630: }
  631: #endif /* HAVE_STRLCPY */

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