1 /*
2  * Copyright (C) 2008-2014 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 #ifndef ISTGT_MISC_H
29 #define ISTGT_MISC_H
30 
31 #include <stdint.h>
32 #include <stddef.h>
33 #include <stdio.h>
34 #include <time.h>
35 
36 #define ISTGT_USE_MACRO_EXPAND
37 
38 #ifdef ISTGT_USE_MACRO_EXPAND
39 #define DSET8(B,D)  (*((uint8_t *)(B)) = (uint8_t)(D))
40 #define DSET16(B,D)													\
41 	(((*((uint8_t *)(B)+0)) = (uint8_t)((uint16_t)(D) >> 8)),		\
42 	 ((*((uint8_t *)(B)+1)) = (uint8_t)((uint16_t)(D) >> 0)))
43 #define DSET24(B,D)													\
44 	(((*((uint8_t *)(B)+0)) = (uint8_t)((uint32_t)(D) >> 16)),		\
45 	 ((*((uint8_t *)(B)+1)) = (uint8_t)((uint32_t)(D) >> 8)),		\
46 	 ((*((uint8_t *)(B)+2)) = (uint8_t)((uint32_t)(D) >> 0)))
47 #define DSET32(B,D)													\
48 	(((*((uint8_t *)(B)+0)) = (uint8_t)((uint32_t)(D) >> 24)),		\
49 	 ((*((uint8_t *)(B)+1)) = (uint8_t)((uint32_t)(D) >> 16)),		\
50 	 ((*((uint8_t *)(B)+2)) = (uint8_t)((uint32_t)(D) >> 8)),		\
51 	 ((*((uint8_t *)(B)+3)) = (uint8_t)((uint32_t)(D) >> 0)))
52 #define DSET48(B,D)													\
53 	(((*((uint8_t *)(B)+0)) = (uint8_t)((uint64_t)(D) >> 40)),		\
54 	 ((*((uint8_t *)(B)+1)) = (uint8_t)((uint64_t)(D) >> 32)),		\
55 	 ((*((uint8_t *)(B)+2)) = (uint8_t)((uint64_t)(D) >> 24)),		\
56 	 ((*((uint8_t *)(B)+3)) = (uint8_t)((uint64_t)(D) >> 16)),		\
57 	 ((*((uint8_t *)(B)+4)) = (uint8_t)((uint64_t)(D) >> 8)),		\
58 	 ((*((uint8_t *)(B)+5)) = (uint8_t)((uint64_t)(D) >> 0)))
59 #define DSET64(B,D)													\
60 	(((*((uint8_t *)(B)+0)) = (uint8_t)((uint64_t)(D) >> 56)),		\
61 	 ((*((uint8_t *)(B)+1)) = (uint8_t)((uint64_t)(D) >> 48)),		\
62 	 ((*((uint8_t *)(B)+2)) = (uint8_t)((uint64_t)(D) >> 40)),		\
63 	 ((*((uint8_t *)(B)+3)) = (uint8_t)((uint64_t)(D) >> 32)),		\
64 	 ((*((uint8_t *)(B)+4)) = (uint8_t)((uint64_t)(D) >> 24)),		\
65 	 ((*((uint8_t *)(B)+5)) = (uint8_t)((uint64_t)(D) >> 16)),		\
66 	 ((*((uint8_t *)(B)+6)) = (uint8_t)((uint64_t)(D) >> 8)),		\
67 	 ((*((uint8_t *)(B)+7)) = (uint8_t)((uint64_t)(D) >> 0)))
68 #define DGET8(B)    (*((uint8_t *)(B)))
69 #define DGET16(B)											\
70 	(((  (uint16_t) *((uint8_t *)(B)+0)) << 8)				\
71 	 | (((uint16_t) *((uint8_t *)(B)+1)) << 0))
72 #define DGET24(B)											\
73 	(((  (uint32_t) *((uint8_t *)(B)+0)) << 16)				\
74 	 | (((uint32_t) *((uint8_t *)(B)+1)) << 8)				\
75 	 | (((uint32_t) *((uint8_t *)(B)+2)) << 0))
76 #define DGET32(B)											\
77 	(((  (uint32_t) *((uint8_t *)(B)+0)) << 24)				\
78 	 | (((uint32_t) *((uint8_t *)(B)+1)) << 16)				\
79 	 | (((uint32_t) *((uint8_t *)(B)+2)) << 8)				\
80 	 | (((uint32_t) *((uint8_t *)(B)+3)) << 0))
81 #define DGET48(B)											\
82 	(((  (uint64_t) *((uint8_t *)(B)+0)) << 40)				\
83 	 | (((uint64_t) *((uint8_t *)(B)+1)) << 32)				\
84 	 | (((uint64_t) *((uint8_t *)(B)+2)) << 24)				\
85 	 | (((uint64_t) *((uint8_t *)(B)+3)) << 16)				\
86 	 | (((uint64_t) *((uint8_t *)(B)+4)) << 8)				\
87 	 | (((uint64_t) *((uint8_t *)(B)+5)) << 0))
88 #define DGET64(B)											\
89 	(((  (uint64_t) *((uint8_t *)(B)+0)) << 56)				\
90 	 | (((uint64_t) *((uint8_t *)(B)+1)) << 48)				\
91 	 | (((uint64_t) *((uint8_t *)(B)+2)) << 40)				\
92 	 | (((uint64_t) *((uint8_t *)(B)+3)) << 32)				\
93 	 | (((uint64_t) *((uint8_t *)(B)+4)) << 24)				\
94 	 | (((uint64_t) *((uint8_t *)(B)+5)) << 16)				\
95 	 | (((uint64_t) *((uint8_t *)(B)+6)) << 8)				\
96 	 | (((uint64_t) *((uint8_t *)(B)+7)) << 0))
97 #else /* ISTGT_USE_MACRO_EXPAND */
98 //#define DSET8(B,D)  (istgt_dset8((B),(D)))
99 #define DSET8(B,D)  (*((uint8_t *)(B)) = (uint8_t)(D))
100 #define DSET16(B,D) (istgt_dset16((B),(D)))
101 #define DSET24(B,D) (istgt_dset24((B),(D)))
102 #define DSET32(B,D) (istgt_dset32((B),(D)))
103 #define DSET48(B,D) (istgt_dset48((B),(D)))
104 #define DSET64(B,D) (istgt_dset64((B),(D)))
105 //#define DGET8(B)    (istgt_dget8((B)))
106 #define DGET8(B)    (*((uint8_t *)(B)))
107 #define DGET16(B)   (istgt_dget16((B)))
108 #define DGET24(B)   (istgt_dget24((B)))
109 #define DGET32(B)   (istgt_dget32((B)))
110 #define DGET48(B)   (istgt_dget48((B)))
111 #define DGET64(B)   (istgt_dget64((B)))
112 #endif /* ISTGT_USE_MACRO_EXPAND */
113 
114 #define DMIN8(A,B)  ((uint8_t)  ((A) > (B) ? (B) : (A)))
115 #define DMIN16(A,B) ((uint16_t) ((A) > (B) ? (B) : (A)))
116 #define DMIN24(A,B) ((uint32_t) ((A) > (B) ? (B) : (A)))
117 #define DMIN32(A,B) ((uint32_t) ((A) > (B) ? (B) : (A)))
118 #define DMIN48(A,B) ((uint64_t) ((A) > (B) ? (B) : (A)))
119 #define DMIN64(A,B) ((uint64_t) ((A) > (B) ? (B) : (A)))
120 #define DMAX8(A,B)  ((uint8_t)  ((A) > (B) ? (A) : (B)))
121 #define DMAX16(A,B) ((uint16_t) ((A) > (B) ? (A) : (B)))
122 #define DMAX24(A,B) ((uint32_t) ((A) > (B) ? (A) : (B)))
123 #define DMAX32(A,B) ((uint32_t) ((A) > (B) ? (A) : (B)))
124 #define DMAX48(A,B) ((uint64_t) ((A) > (B) ? (A) : (B)))
125 #define DMAX64(A,B) ((uint64_t) ((A) > (B) ? (A) : (B)))
126 
127 #define BSHIFTNW(N,W) (((W) > 0) ? (((N) > ((W)-1)) ? ((N) - ((W)-1)) : 0) : 0)
128 #define BMASKW(W) (((W) > 0) ? (~((~0) << (W))) : 0)
129 
130 #define BDSET8W(B,D,N,W) DSET8((B),(((D)&BMASKW((W)))<<BSHIFTNW((N),(W))))
131 #define BDADD8W(B,D,N,W) DSET8((B),((DGET8((B)) & ~(BMASKW((W)) << BSHIFTNW((N),(W)))) | (uint8_t) (((D) & BMASKW((W))) << BSHIFTNW((N),(W)))))
132 #define BSET8W(B,N,W) (*((uint8_t *)(B)) |= (uint8_t) (BMASKW((W))) << BSHIFTNW((N),(W)))
133 #define BCLR8W(B,N,W) (*((uint8_t *)(B)) &= (uint8_t) (~(BMASKW((W))) << BSHIFTNW((N),(W))))
134 #define BGET8W(B,N,W) ((*((uint8_t *)(B)) >> BSHIFTNW((N),(W))) & BMASKW((W)))
135 
136 #define BDSET8(B,D,N) (BDSET8W((B),(D),(N),1))
137 #define BDADD8(B,D,N) (BDADD8W((B),(D),(N),1))
138 #define BSET8(B,N) (BSET8W((B),(N),1))
139 #define BCLR8(B,N) (BCLR8W((B),(N),1))
140 #define BGET8(B,N) (BGET8W((B),(N),1))
141 
142 /* memory allocate */
143 void *xmalloc(size_t size);
144 void *xrealloc(void *p, size_t size);
145 void xfree(void *p);
146 char *xstrdup(const char *s);
147 
148 /* string functions */
149 char *strlwr(char *s);
150 char *strupr(char *s);
151 char *strsepq(char **stringp, const char *delim);
152 char *trim_string(char *s);
153 char *escape_string(const char *s);
154 #ifndef HAVE_STRLCPY
155 size_t strlcpy(char *dst, const char *src, size_t size);
156 #endif /* HAVE_STRLCPY */
157 
158 /* convert from/to LBA/MSF */
159 uint32_t istgt_msf2lba(uint32_t msf);
160 uint32_t istgt_lba2msf(uint32_t lba);
161 
162 /* network byte order operation */
163 uint8_t istgt_dget8(const uint8_t *data);
164 void istgt_dset8(uint8_t *data, uint32_t value);
165 uint16_t istgt_dget16(const uint8_t *data);
166 void istgt_dset16(uint8_t *data, uint32_t value);
167 uint32_t istgt_dget24(const uint8_t *data);
168 void istgt_dset24(uint8_t *data, uint32_t value);
169 uint32_t istgt_dget32(const uint8_t *data);
170 void istgt_dset32(uint8_t *data, uint32_t value);
171 uint64_t istgt_dget48(const uint8_t *data);
172 void istgt_dset48(uint8_t *data, uint64_t value);
173 uint64_t istgt_dget64(const uint8_t *data);
174 void istgt_dset64(uint8_t *data, uint64_t value);
175 
176 /* random value generation */
177 void istgt_gen_random(uint8_t *buf, size_t len);
178 #ifndef HAVE_SRANDOMDEV
179 void srandomdev(void);
180 #endif /* HAVE_SRANDOMDEV */
181 #ifndef HAVE_ARC4RANDOM
182 uint32_t arc4random(void);
183 #endif /* HAVE_ARC4RANDOM */
184 
185 /* convert from/to bin/hex */
186 int istgt_bin2hex(char *buf, size_t len, const uint8_t *data, size_t data_len);
187 int istgt_hex2bin(uint8_t *data, size_t data_len, const char *str);
188 
189 /* other functions */
190 int istgt_difftime(time_t a, time_t b);
191 void istgt_dump(const char *label, const uint8_t *buf, size_t len);
192 void istgt_fdump(FILE *fp, const char *label, const uint8_t *buf, size_t len);
193 void istgt_yield(void);
194 
195 #endif /* ISTGT_MISC_H */
196