ring_tx: handle EINTR from sendto
[netsniff-ng.git] / str.c
blob9ab94ca517d0b68ea8c7479081b4b8a6519802fb
1 /*
2 * netsniff-ng - the packet sniffing beast
3 * Copyright 2009, 2010 Daniel Borkmann.
4 * Subject to the GPL, version 2.
5 */
7 #include <stdio.h>
8 #include <string.h>
9 #include <stdarg.h>
10 #include <arpa/inet.h>
12 #include "str.h"
13 #include "die.h"
14 #include "xmalloc.h"
16 size_t strlcpy(char *dest, const char *src, size_t size)
18 size_t ret = strlen(src);
20 if (size) {
21 size_t len = (ret >= size) ? size - 1 : ret;
23 memcpy(dest, src, len);
24 dest[len] = '\0';
27 return ret;
30 static inline int vslprintf(char *dst, size_t size, const char *fmt, va_list ap)
32 int ret;
34 ret = vsnprintf(dst, size, fmt, ap);
35 dst[size - 1] = '\0';
37 return ret;
40 int slprintf(char *dst, size_t size, const char *fmt, ...)
42 int ret;
43 va_list ap;
45 va_start(ap, fmt);
46 ret = vslprintf(dst, size, fmt, ap);
47 va_end(ap);
49 return ret;
52 int slprintf_nocheck(char *dst, size_t size, const char *fmt, ...)
54 int ret;
55 va_list ap;
57 va_start(ap, fmt);
58 ret = vslprintf(dst, size, fmt, ap);
59 va_end(ap);
61 return ret;
64 noinline void *xmemset(void *s, int c, size_t n)
66 size_t i;
67 uint8_t *ptr = s;
69 for (i = 0; i < n; ++i)
70 ptr[i] = (uint8_t) c;
72 return ptr;
75 char *strtrim_right(char *p, char c)
77 char *end;
78 size_t len;
80 len = strlen(p);
81 while (*p && len) {
82 end = p + len - 1;
83 if (c == *end)
84 *end = 0;
85 else
86 break;
87 len = strlen(p);
90 return p;
93 char *argv2str(int startind, int argc, char **argv)
95 off_t offset = 0;
96 char *str = NULL;
97 int ret, i;
99 for (i = startind; i < argc; ++i) {
100 size_t tlen = (i < argc - 1) ? 2 : 1;
101 size_t alen = strlen(argv[i]) + tlen;
102 size_t slen = str ? strlen(str) : 0;
104 str = xrealloc(str, slen + alen);
105 ret = slprintf(str + offset, strlen(argv[i]) + tlen, "%s%s",
106 argv[i], tlen == 2 ? " " : "");
107 if (ret < 0)
108 panic("Cannot concatenate string!\n");
109 else
110 offset += ret;
113 return str;
116 char **argv_insert(char **argv, size_t *count, const char *str)
118 argv = xrealloc(argv, (*count + 2) * sizeof(char *));
119 argv[*count] = str ? xstrdup(str) : xstrdup("");
120 argv[*count + 1] = NULL;
122 *count += 1;
123 return argv;
126 void argv_free(char **argv)
128 char **tmp = argv;
130 for (; argv && *argv; argv++)
131 free(*argv);
133 free(tmp);
136 int str2mac(const char *str, uint8_t *mac, size_t len)
138 int i, count;
139 unsigned int tmp[6];
141 if (!str)
142 return -EINVAL;
143 if (len < 6)
144 return -ENOSPC;
146 errno = 0;
147 count = sscanf(str, "%02X:%02X:%02X:%02X:%02X:%02X",
148 &tmp[0], &tmp[1], &tmp[2], &tmp[3], &tmp[4], &tmp[5]);
150 if (errno || count != 6)
151 count = sscanf(str, "%02x:%02x:%02x:%02x:%02x:%02x",
152 &tmp[0], &tmp[1], &tmp[2], &tmp[3], &tmp[4], &tmp[5]);
154 if (count != 6)
155 return -EINVAL;
156 if (errno)
157 return -errno;
159 for (i = 0; i < 6; i++)
160 mac[i] = (uint8_t)tmp[i];
162 return 0;
165 char *str2fqdn(const char *str)
167 size_t slen = strlen(str);
168 size_t flen = 0;
169 char *fqdn;
170 char *tmp;
171 char *dup;
172 int i = 0;
173 int c = 0;
175 dup = xstrdup(str);
176 tmp = dup;
178 fqdn = xzmalloc(slen + 2);
180 while (tmp <= dup + slen && c++ <= slen) {
181 if (tmp[i] == '.' || tmp[i] == '\0') {
182 size_t dlen;
184 tmp[i] = '\0';
185 dlen = strlen(tmp);
186 fqdn[flen] = dlen;
187 memcpy(&fqdn[flen + 1], tmp, dlen);
188 flen += dlen + 1;
189 tmp += dlen + 1;
190 i = 0;
192 continue;
195 i++;
198 xfree(dup);
199 return fqdn;