]> git.meshlink.io Git - catta/blob - libavahi-core/util.c
270a48f23de5000d0f29df2c72ed1b4b005b755b
[catta] / libavahi-core / 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 *avahi_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 avahi_normalize_name(t);
19 }
20
21 gchar *avahi_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 avahi_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 avahi_timeval_diff(const GTimeVal *a, const GTimeVal *b) {
56     g_assert(a);
57     g_assert(b);
58
59     if (avahi_timeval_compare(a, b) < 0)
60         return avahi_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 avahi_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 avahi_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 avahi_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 *avahi_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 avahi_age(const GTimeVal *a) {
127     GTimeVal now;
128     
129     g_assert(a);
130
131     g_get_current_time(&now);
132
133     return avahi_timeval_diff(&now, a);
134 }
135
136 gboolean avahi_domain_cmp(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 0;
152         
153         if (*a == 0 && !escaped_b && *b == '.' && *(b+1) == 0)
154             return 0;
155
156         if (!escaped_a && *a == '.' && *(a+1) == 0 && *b == 0)
157             return 0;
158
159         /* Compare characters */
160         if (escaped_a == escaped_b && *a != *b)
161             return *a < *b ? -1 : 1;
162
163         /* Next characters */
164         a++;
165         b++;
166         
167     }
168 }
169
170 gboolean avahi_domain_equal(const gchar *a, const gchar *b) {
171     return avahi_domain_cmp(a, b) == 0;
172 }
173
174 guint avahi_domain_hash(const gchar *p) {
175     char t[256];
176     strncpy(t, p, sizeof(t)-1);
177     t[sizeof(t)-1] = 0;
178
179     return g_int_hash(t);
180 }
181
182 void avahi_hexdump(gconstpointer p, guint size) {
183     const guint8 *c = p;
184     g_assert(p);
185
186     printf("Dumping %u bytes from %p:\n", size, p);
187     
188     while (size > 0) {
189         guint i;
190
191         for (i = 0; i < 16; i++) { 
192             if (i < size)
193                 printf("%02x ", c[i]);
194             else
195                 printf("   ");
196         }
197
198         for (i = 0; i < 16; i++) {
199             if (i < size)
200                 printf("%c", c[i] >= 32 && c[i] < 127 ? c[i] : '.');
201             else
202                 printf(" ");
203         }
204         
205         printf("\n");
206
207         c += 16;
208
209         if (size <= 16)
210             break;
211         
212         size -= 16;
213     }
214 }