Annotation of libaitio/src/tools.c, revision 1.8
1.2 misho 1: /*************************************************************************
1.4 misho 2: * (C) 2008 AITNET ltd - Sofia/Bulgaria - <misho@aitnet.org>
3: * by Michael Pounov <misho@elwix.org>
1.2 misho 4: *
5: * $Author: misho $
1.8 ! misho 6: * $Id: tools.c,v 1.7.2.3 2011/12/14 13:12:58 misho Exp $
1.2 misho 7: *
1.4 misho 8: **************************************************************************
9: The ELWIX and AITNET software is distributed under the following
10: terms:
11:
12: All of the documentation and software included in the ELWIX and AITNET
13: Releases is copyrighted by ELWIX - Sofia/Bulgaria <info@elwix.org>
14:
15: Copyright 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011
16: by Michael Pounov <misho@elwix.org>. All rights reserved.
17:
18: Redistribution and use in source and binary forms, with or without
19: modification, are permitted provided that the following conditions
20: are met:
21: 1. Redistributions of source code must retain the above copyright
22: notice, this list of conditions and the following disclaimer.
23: 2. Redistributions in binary form must reproduce the above copyright
24: notice, this list of conditions and the following disclaimer in the
25: documentation and/or other materials provided with the distribution.
26: 3. All advertising materials mentioning features or use of this software
27: must display the following acknowledgement:
28: This product includes software developed by Michael Pounov <misho@elwix.org>
29: ELWIX - Embedded LightWeight unIX and its contributors.
30: 4. Neither the name of AITNET nor the names of its contributors
31: may be used to endorse or promote products derived from this software
32: without specific prior written permission.
33:
34: THIS SOFTWARE IS PROVIDED BY AITNET AND CONTRIBUTORS ``AS IS'' AND
35: ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
36: IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
37: ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
38: FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
39: DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
40: OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
41: HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
42: LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
43: OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
44: SUCH DAMAGE.
45: */
1.2 misho 46: #include "global.h"
47: #include "aitio.h"
48:
49:
50: /*
51: * io_LTrimStr() Remove left whitespaces from text string
52: * @psLine = Text string
53: * return: 0 nothing to do; !=0 Removed bytes
54: */
1.5 misho 55: inline int
56: io_LTrimStr(u_char * __restrict psLine)
1.2 misho 57: {
58: int pos = 0;
59: u_char *s;
60:
61: if (!psLine || !*psLine)
62: return 0;
63:
64: for (s = psLine; isspace(*s); s++);
65: pos = s - psLine;
66:
67: memmove(psLine, s, (strlen((char*) psLine) - pos) + 1);
68: return pos;
69: }
70:
71: /*
72: * io_RTrimStr() Remove right whitespaces from text string
73: * @psLine = Text string
74: * return: 0 nothing to do; !=0 Removed bytes
75: */
1.5 misho 76: inline int
77: io_RTrimStr(u_char * __restrict psLine)
1.2 misho 78: {
79: u_char *t, *pos;
80:
81: if (!psLine || !*psLine)
82: return 0;
83:
84: pos = psLine + strlen((char*) psLine);
85: for (t = pos - 1; t > psLine && isspace(*t); t--);
86: *++t = 0;
87:
88: return pos - t;
89: }
90:
91: /*
92: * io_TrimStr() Remove left and right whitespaces from text string
93: * @psLine = Text string
94: * return: 0 nothing to do; !=0 Removed bytes
95: */
1.5 misho 96: inline int
97: io_TrimStr(u_char * __restrict psLine)
1.2 misho 98: {
99: int ret = 0;
100:
101: ret = io_LTrimStr(psLine);
102: ret += io_RTrimStr(psLine);
103:
104: return ret;
105: }
106:
107: /*
108: * io_UnquotStr() Remove quots from input text string
109: * @psLine = Text string
110: * return: 0 nothing to do; 1 successful unquoted string
111: */
1.5 misho 112: inline int
113: io_UnquotStr(u_char * __restrict psLine)
1.2 misho 114: {
115: char *pos, *str = NULL;
116: int flg;
117:
118: if (!psLine)
119: return 0;
120:
121: switch (*psLine) {
122: case '`':
123: case '"':
124: case '\'':
125: str = strdup((char*) psLine + 1);
126: for (pos = str, flg = 0; *pos; flg = ('\\' == *pos), pos++) {
127: if (!flg && *pos == *psLine) {
128: *pos = 0;
129: strlcpy((char*) psLine, str, strlen((char*) psLine) + 1);
130: break;
131: }
132: }
133: free(str);
134: return 1;
135: }
136:
137: return 0;
138: }
139:
140: /*
1.3 misho 141: * io_Ch2Hex() Convert from Char string to Hex string
1.2 misho 142: * @psLine = Text string
143: * @lineLen = Length of Text string
1.3 misho 144: * return: NULL nothing to do or error; !=0 Allocated new converted data without term\0 (must be free)
1.2 misho 145: */
1.5 misho 146: inline u_char *
147: io_Ch2Hex(u_char *psLine, int lineLen)
1.2 misho 148: {
149: register int i;
1.3 misho 150: char szWork[3];
151: u_char *str;
1.2 misho 152:
153: if (!psLine || !*psLine || !lineLen)
154: return NULL;
155:
1.3 misho 156: str = malloc(lineLen / 2);
1.2 misho 157: if (!str) {
158: LOGERR;
159: return NULL;
160: } else
1.3 misho 161: memset(str, 0, lineLen / 2);
1.2 misho 162:
1.3 misho 163: for (i = 0; i < lineLen && psLine[i * 2]; i++) {
164: strlcpy(szWork, (char*) &psLine[i * 2], 3);
165: str[i] = (u_char) strtol(szWork, NULL, 16);
1.2 misho 166: }
167:
168: return str;
169: }
170:
171:
172: /*
1.3 misho 173: * io_Hex2Ch() Convert from Hex string to Char string
1.2 misho 174: * @psLine = Text string
175: * @lineLen = Length of Text string
176: * return: NULL nothing to do or error; !=0 Allocated new converted string(must be free)
177: */
1.5 misho 178: inline char *
179: io_Hex2Ch(u_char *psLine, int lineLen)
1.2 misho 180: {
181: register int i;
182: char szWork[3], *str;
183:
184: if (!psLine || !*psLine || !lineLen)
185: return NULL;
186:
1.3 misho 187: str = malloc(lineLen * 2 + 1);
1.2 misho 188: if (!str) {
189: LOGERR;
190: return NULL;
191: } else
1.3 misho 192: memset(str, 0, lineLen * 2 + 1);
1.2 misho 193:
1.3 misho 194: for (i = 0; i <= lineLen; i++) {
195: memset(szWork, 0, 3);
196: snprintf(szWork, 3, "%02X", (u_char) psLine[i]);
197: strncat(str, szWork, 2);
1.2 misho 198: }
199:
200: return str;
201: }
1.5 misho 202:
203: /*
204: * io_CopyEnv() Copy environment to new environment array;
205: * @oldenv = Environment array
206: * return: NULL error; !=NULL Allocated new environment array(must be free)
207: */
208: char **
209: io_CopyEnv(const char **oldenv)
210: {
211: char **newenv, **el;
212: register int i, num;
213:
214: if (!oldenv)
215: return NULL;
216: else
217: newenv = el = NULL;
218:
219: /* count items environment */
220: for (i = num = 0; oldenv[i]; i++)
221: if (*strchr(oldenv[i], '='))
222: num++;
223:
224: /* create and copy new environment */
225: newenv = calloc(num + 1, sizeof(char*));
226: if (!newenv) {
227: LOGERR;
228: return NULL;
229: } else
230: el = newenv;
231:
232: for (i = 0; oldenv[i]; i++)
233: if (*strchr(oldenv[i], '=')) {
234: *el = strdup(oldenv[i]);
235: el++;
236: }
237: *el = NULL;
238:
239: return newenv;
240: }
241:
242: /*
243: * io_ExecArgs() Build exec arguments from other array
244: * @psProg = Program name for execute
245: * @oldarg = Arguments array
246: * return: NULL error; !=NULL Allocated execution array(must be free)
247: */
248: char **
249: io_ExecArgs(const char *psProg, const char **oldarg)
250: {
251: char **newarg, **el;
252: register int i, num;
253:
254: if (!psProg || !oldarg)
255: return NULL;
256: else
257: newarg = el = NULL;
258:
259: /* count items arguments */
260: for (num = 0; oldarg[num]; num++);
261:
262: /* create and copy new arguments */
263: newarg = calloc(num + 2, sizeof(char*));
264: if (!newarg) {
265: LOGERR;
266: return NULL;
267: } else
268: el = newarg;
269:
270: *el = strdup(psProg);
271: el++;
272:
273: for (i = 0; oldarg[i]; i++, el++)
274: *el = strdup(oldarg[i]);
275: *el = NULL;
276:
277: return newarg;
278: }
279:
280: /*
281: * io_FreeNullTerm() Free dynamic allocated null terminated array with strings
282: * @arr = Pointer to array for free
283: * return: none
284: */
285: inline void
286: io_FreeNullTerm(char *** __restrict arr)
287: {
288: char **a;
289:
290: if (arr && *arr) {
291: a = *arr;
292: while (a && *a)
293: free(*a++);
294: free(*arr);
295: *arr = NULL;
296: }
297: }
1.6 misho 298:
299: /*
300: * io_ether_ntoa() Convert ethernet address to string
301: * @n = ethernet address structure, like struct ether_addr
302: * @a = string
303: * @len = string length
304: * return: NULL error or !=NULL string a
305: */
306: inline char *
307: io_ether_ntoa(const struct io_ether_addr *n, char * __restrict a, int len)
308: {
309: if (!n || !a)
310: return NULL;
311:
312: memset(a, 0, len);
313: if (snprintf(a, len, "%02x:%02x:%02x:%02x:%02x:%02x",
314: n->ether_addr_octet[0], n->ether_addr_octet[1],
315: n->ether_addr_octet[2], n->ether_addr_octet[3],
316: n->ether_addr_octet[4], n->ether_addr_octet[5]) < 17)
317: return NULL;
318:
319: return a;
320: }
321:
322: /*
323: * io_ether_aton() Convert string to ethernet address
324: * @a = string
325: * @e = ethernet address structure, like struct ether_addr
326: * return: NULL error or !=NULL ethernet address structure
327: */
328: inline struct io_ether_addr *
329: io_ether_aton(const char *a, struct io_ether_addr *e)
330: {
331: int i;
332: u_int o0, o1, o2, o3, o4, o5;
333:
334: if (!a || !e)
335: return NULL;
336:
337: i = sscanf(a, "%x:%x:%x:%x:%x:%x", &o0, &o1, &o2, &o3, &o4, &o5);
338: if (i != 6)
339: return NULL;
340:
341: e->ether_addr_octet[0] = o0;
342: e->ether_addr_octet[1] = o1;
343: e->ether_addr_octet[2] = o2;
344: e->ether_addr_octet[3] = o3;
345: e->ether_addr_octet[4] = o4;
346: e->ether_addr_octet[5] = o5;
347:
348: return e;
349: }
1.7 misho 350:
351: /*
352: * io_n2port() Extract port from network structure
353: * @addr = Address
354: * return: 0 not supported family type or port number
355: */
356: inline u_short
357: io_n2port(io_sockaddr_t * __restrict addr)
358: {
359: u_short port = 0;
360:
361: if (!addr)
362: return port;
363:
364: switch (addr->sa.sa_family) {
365: case AF_INET:
366: return ntohs(addr->sin.sin_port);
367: case AF_INET6:
368: return ntohs(addr->sin6.sin6_port);
369: default:
370: io_SetErr(ESOCKTNOSUPPORT, "Unsuported address family %d",
371: addr->sa.sa_family);
372: break;
373: }
374:
375: return port;
376: }
377:
378: /*
379: * io_n2addr() Extract address from network structure
380: * @addr = Address
381: * @val = Value for store string address
382: * return: NULL error or !=NULL string address from val
383: */
384: const char *
385: io_n2addr(io_sockaddr_t * __restrict addr, ait_val_t * __restrict val)
386: {
387: char str[INET6_ADDRSTRLEN] = { 0 };
388: const char *ret = NULL;
389:
390: if (!addr || !val)
391: return ret;
392:
393: switch (addr->sa.sa_family) {
394: case AF_INET:
395: if (!inet_ntop(AF_INET, &addr->sin.sin_addr, str, INET_ADDRSTRLEN)) {
396: LOGERR;
397: return ret;
398: } else
399: ret = str;
400: break;
401: case AF_INET6:
402: if (!inet_ntop(AF_INET6, &addr->sin6.sin6_addr, str, INET6_ADDRSTRLEN)) {
403: LOGERR;
404: return ret;
405: } else
406: ret = str;
407: break;
408: default:
409: io_SetErr(EPROTONOSUPPORT, "Unsuported address family %d",
410: addr->sa.sa_family);
411: return ret;
412: }
413:
1.8 ! misho 414: if (!AIT_ISEMPTY(val))
! 415: AIT_FREE_VAL(val);
1.7 misho 416: AIT_SET_STR(val, ret);
1.8 ! misho 417: return (const char*) AIT_GET_STR(val);
1.7 misho 418: }
419:
420: /*
421: * io_gethostbyname() Get host and port and make network structure
422: * @psHost = Hostname
423: * @port = Port
424: * @addr = Network address structure
425: * return: NULL error or !=NULL network structure
426: */
427: io_sockaddr_t *
428: io_gethostbyname(const char *psHost, u_short port, io_sockaddr_t * __restrict addr)
429: {
430: struct hostent *host;
431:
432: if (!psHost || !addr)
433: return NULL;
434:
435: /* resolver */
436: if (!addr->sa.sa_family)
437: host = gethostbyname(psHost);
438: else
439: host = gethostbyname2(psHost, addr->sa.sa_family);
440: if (!host) {
441: io_SetErr(EINVAL, "Resolver #%d - %s", h_errno, hstrerror(h_errno));
442: return NULL;
443: }
444:
445: memset(addr, 0, sizeof(io_sockaddr_t));
446: switch (host->h_addrtype) {
447: case AF_INET:
448: addr->sin.sin_len = sizeof(struct sockaddr_in);
449: addr->sin.sin_family = AF_INET;
450: addr->sin.sin_port = htons(port);
451: memcpy(&addr->sin.sin_addr, host->h_addr, sizeof addr->sin.sin_addr);
452: return addr;
453: case AF_INET6:
454: addr->sin6.sin6_len = sizeof(struct sockaddr_in6);
455: addr->sin6.sin6_family = AF_INET6;
456: addr->sin6.sin6_port = htons(port);
457: memcpy(&addr->sin6.sin6_addr, host->h_addr, sizeof addr->sin6.sin6_addr);
458: return addr;
459: default:
460: io_SetErr(EPROTONOSUPPORT, "Unsuported address family %d",
461: host->h_addrtype);
462: break;
463: }
464:
465: return NULL;
466: }
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>