]> git.meshlink.io Git - catta/blob - util.c
add support for dots and backslashes in domain names (required for DNS-SD)
[catta] / util.c
1 #include <string.h>
2 #include <unistd.h>
3 #include <fcntl.h>
4 #include <errno.h>
5 #include <limits.h>
6 #include <stdio.h>
7
8 #include "util.h"
9
10 gchar *flx_get_host_name(void) {
11 #ifdef HOST_NAME_MAX
12     char t[HOST_NAME_MAX];
13 #else
14     char t[256];
15 #endif
16     gethostname(t, sizeof(t));
17     t[sizeof(t)-1] = 0;
18     return flx_normalize_name(t);
19 }
20
21 gchar *flx_normalize_name(const gchar *s) {
22     size_t l;
23     g_assert(s);
24
25     l = strlen(s);
26
27     if (!l)
28         return g_strdup(".");
29
30     if (s[l-1] == '.')
31         return g_strdup(s);
32     
33     return g_strdup_printf("%s.", s);
34 }
35
36 gint flx_timeval_compare(const GTimeVal *a, const GTimeVal *b) {
37     g_assert(a);
38     g_assert(b);
39
40     if (a->tv_sec < b->tv_sec)
41         return -1;
42
43     if (a->tv_sec > b->tv_sec)
44         return 1;
45
46     if (a->tv_usec < b->tv_usec)
47         return -1;
48
49     if (a->tv_usec > b->tv_usec)
50         return 1;
51
52     return 0;
53 }
54
55 glong flx_timeval_diff(const GTimeVal *a, const GTimeVal *b) {
56     g_assert(a);
57     g_assert(b);
58
59     if (flx_timeval_compare(a, b) < 0)
60         return flx_timeval_diff(b, a);
61
62     return ((glong) a->tv_sec - b->tv_sec)*1000000 + a->tv_usec - b->tv_usec;
63 }
64
65
66 gint flx_set_cloexec(gint fd) {
67     gint n;
68
69     g_assert(fd >= 0);
70     
71     if ((n = fcntl(fd, F_GETFD)) < 0)
72         return -1;
73
74     if (n & FD_CLOEXEC)
75         return 0;
76
77     return fcntl(fd, F_SETFD, n|FD_CLOEXEC);
78 }
79
80 gint flx_set_nonblock(gint fd) {
81     gint n;
82
83     g_assert(fd >= 0);
84
85     if ((n = fcntl(fd, F_GETFL)) < 0)
86         return -1;
87
88     if (n & O_NONBLOCK)
89         return 0;
90
91     return fcntl(fd, F_SETFL, n|O_NONBLOCK);
92 }
93
94 gint flx_wait_for_write(gint fd) {
95     fd_set fds;
96     gint r;
97     
98     FD_ZERO(&fds);
99     FD_SET(fd, &fds);
100     
101     if ((r = select(fd+1, NULL, &fds, NULL, NULL)) < 0) {
102         g_message("select() failed: %s", strerror(errno));
103
104         return -1;
105     }
106     
107     g_assert(r > 0);
108
109     return 0;
110 }
111
112 GTimeVal *flx_elapse_time(GTimeVal *tv, guint msec, guint jitter) {
113     g_assert(tv);
114
115     g_get_current_time(tv);
116
117     if (msec)
118         g_time_val_add(tv, msec*1000);
119
120     if (jitter)
121         g_time_val_add(tv, g_random_int_range(0, jitter) * 1000);
122         
123     return tv;
124 }
125
126 gint flx_age(const GTimeVal *a) {
127     GTimeVal now;
128     
129     g_assert(a);
130
131     g_get_current_time(&now);
132
133     return flx_timeval_diff(&now, a);
134 }
135
136 gboolean flx_domain_equal(const gchar *a, const gchar *b) {
137     int escaped_a = 0, escaped_b = 0;
138     g_assert(a);
139     g_assert(b);
140
141     for (;;) {
142         /* Check for escape characters "\" */
143         if ((escaped_a = *a == '\\'))
144             a ++;
145
146         if ((escaped_b = *b == '\\'))
147             b++;
148
149         /* Check for string end */
150         if (*a == 0 && *b == 0)
151             return TRUE;
152         
153         if (*a == 0 && !escaped_b && *b == '.' && *(b+1) == 0)
154             return TRUE;
155
156         if (!escaped_a && *a == '.' && *(a+1) == 0 && *b == 0)
157             return TRUE;
158
159         /* Compare characters */
160         if (escaped_a == escaped_b && *a != *b)
161             return FALSE;
162
163
164         /* Next characters */
165         a++;
166         b++;
167         
168     }
169 }
170
171 guint flx_domain_hash(const gchar *p) {
172     char t[256];
173     strncpy(t, p, sizeof(t)-1);
174     t[sizeof(t)-1] = 0;
175
176     return g_int_hash(t);
177 }
178
179 void flx_hexdump(gconstpointer p, guint size) {
180     const guint8 *c = p;
181     g_assert(p);
182
183     printf("Dumping %u bytes from %p:\n", size, p);
184     
185     while (size > 0) {
186         guint i;
187
188         for (i = 0; i < 16; i++) { 
189             if (i < size)
190                 printf("%02x ", c[i]);
191             else
192                 printf("   ");
193         }
194
195         for (i = 0; i < 16; i++) {
196             if (i < size)
197                 printf("%c", c[i] >= 32 && c[i] < 127 ? c[i] : '.');
198             else
199                 printf(" ");
200         }
201         
202         printf("\n");
203
204         c += 16;
205
206         if (size <= 16)
207             break;
208         
209         size -= 16;
210     }
211 }