File:  [ELWIX - Embedded LightWeight unIX -] / embedaddon / istgt / src / istgt_misc.c
Revision 1.1.1.1 (vendor branch): download - view: text, annotated - select for diffs - revision graph
Tue Feb 21 16:42:02 2012 UTC (12 years, 4 months ago) by misho
Branches: istgt, MAIN
CVS tags: v20111008, HEAD
istgt

    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>