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>