Makefile: WARNINGS: add -Wdouble-promotion
[olsrd.git] / lib / nameservice / src / mapwrite.c
1
2 /*
3  * Copyright (c) 2007, Sven-Ola <sven-ola-aet-gmx.de>
4  * All rights reserved.
5  *
6  * Redistribution and use in source and binary forms, with or without
7  * modification, are permitted provided that the following conditions
8  * are met:
9  *
10  * * Redistributions of source code must retain the above copyright notice,
11  *   this list of conditions and the following disclaimer.
12  * * Redistributions in binary form must reproduce the above copyright notice,
13  *   this list of conditions and the following disclaimer in the documentation
14  *   and/or other materials provided with the distribution.
15  * * Neither the name of the UniK olsr daemon nor the names of its contributors
16  *   may be used to endorse or promote products derived from this software
17  *   without specific prior written permission.
18  *
19  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
20  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
21  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
22  * IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
23  * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
24  * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
25  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
26  * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
27  * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
28  * OF THE POSSIBILITY OF SUCH DAMAGE.
29  *
30  */
31
32 #include <stdio.h>
33 #include <string.h>
34 #include <errno.h>
35 #include <unistd.h>
36 #include <fcntl.h>
37 #include <sys/types.h>
38 #include <sys/stat.h>
39
40 #include "defs.h"
41 #include "scheduler.h"
42 #include "nameservice.h"
43 #include "mid_set.h"
44 #include "tc_set.h"
45 #include "ipcalc.h"
46 #include "lq_plugin.h"
47
48 #include "mapwrite.h"
49
50 static char my_latlon_str[48];
51
52 /**
53  * lookup a nodes position
54  */
55 static char *
56 lookup_position_latlon(union olsr_ip_addr *ip)
57 {
58   int hash;
59   struct db_entry *entry;
60   struct list_node *list_head, *list_node;
61
62   if (ipequal(ip, &olsr_cnf->main_addr)) {
63     return my_latlon_str;
64   }
65
66   for (hash = 0; hash < HASHSIZE; hash++) {
67     list_head = &latlon_list[hash];
68     for (list_node = list_head->next; list_node != list_head; list_node = list_node->next) {
69
70       entry = list2db(list_node);
71
72       if (entry->names && ipequal(&entry->originator, ip)) {
73         return entry->names->name;
74       }
75     }
76   }
77   return NULL;
78 }
79
80 /**
81  * write latlon positions to a file
82  */
83 void
84 mapwrite_work(FILE * fmap)
85 {
86   int hash;
87   struct olsr_if *ifs;
88   union olsr_ip_addr ip;
89   struct ipaddr_str strbuf1, strbuf2;
90   struct tc_entry *tc;
91   struct tc_edge_entry *tc_edge;
92
93   if (!my_names || !fmap)
94     return;
95
96   for (ifs = olsr_cnf->interfaces; ifs; ifs = ifs->next) {
97     if (0 != ifs->interf) {
98       if (olsr_cnf->ip_version == AF_INET) {
99         if (!(ip4equal((struct in_addr *)&olsr_cnf->main_addr, &ifs->interf->int_addr.sin_addr))) {
100           if (0 >
101               fprintf(fmap, "Mid('%s','%s');\n", olsr_ip_to_string(&strbuf1, &olsr_cnf->main_addr),
102                       olsr_ip_to_string(&strbuf2, (union olsr_ip_addr *)&ifs->interf->int_addr.sin_addr))) {
103             return;
104           }
105         }
106       } else if (!(ip6equal((struct in6_addr *)&olsr_cnf->main_addr, &ifs->interf->int6_addr.sin6_addr))) {
107         if (0 >
108             fprintf(fmap, "Mid('%s','%s');\n", olsr_ip_to_string(&strbuf1, &olsr_cnf->main_addr),
109                     olsr_ip_to_string(&strbuf2, (union olsr_ip_addr *)&ifs->interf->int6_addr.sin6_addr))) {
110           return;
111         }
112       }
113     }
114   }
115
116   for (hash = 0; hash < HASHSIZE; hash++) {
117     struct mid_entry *entry = mid_set[hash].next;
118     while (entry != &mid_set[hash]) {
119       struct mid_address *alias = entry->aliases;
120       while (alias) {
121         if (0 >
122             fprintf(fmap, "Mid('%s','%s');\n", olsr_ip_to_string(&strbuf1, &entry->main_addr),
123                     olsr_ip_to_string(&strbuf2, &alias->alias))) {
124           return;
125         }
126         alias = alias->next_alias;
127       }
128       entry = entry->next;
129     }
130   }
131   lookup_defhna_latlon(&ip);
132   sprintf(my_latlon_str, "%f,%f,%d", (double)my_lat, (double)my_lon, get_isdefhna_latlon());
133   if (0 >
134       fprintf(fmap, "Self('%s',%s,'%s','%s');\n", olsr_ip_to_string(&strbuf1, &olsr_cnf->main_addr), my_latlon_str,
135               olsr_ip_to_string(&strbuf2, &ip), my_names->name)) {
136     return;
137   }
138   for (hash = 0; hash < HASHSIZE; hash++) {
139     struct db_entry *entry;
140     struct list_node *list_head, *list_node;
141
142     list_head = &latlon_list[hash];
143     for (list_node = list_head->next; list_node != list_head; list_node = list_node->next) {
144
145       entry = list2db(list_node);
146
147       if (NULL != entry->names) {
148         if (0 >
149             fprintf(fmap, "Node('%s',%s,'%s','%s');\n", olsr_ip_to_string(&strbuf1, &entry->originator), entry->names->name,
150                     olsr_ip_to_string(&strbuf2, &entry->names->ip), lookup_name_latlon(&entry->originator))) {
151           return;
152         }
153       }
154     }
155   }
156
157   OLSR_FOR_ALL_TC_ENTRIES(tc) {
158     OLSR_FOR_ALL_TC_EDGE_ENTRIES(tc, tc_edge) {
159       char *lla = lookup_position_latlon(&tc->addr);
160       char *llb = lookup_position_latlon(&tc_edge->T_dest_addr);
161       if (NULL != lla && NULL != llb) {
162         struct lqtextbuffer lqbuffer, lqbuffer2;
163
164         /*
165          * To speed up processing, Links with both positions are named PLink()
166          */
167         if (0 >
168             fprintf(fmap, "PLink('%s','%s',%s,%s,%s,%s);\n", olsr_ip_to_string(&strbuf1, &tc_edge->T_dest_addr),
169                     olsr_ip_to_string(&strbuf2, &tc->addr), get_tc_edge_entry_text(tc_edge, ',', &lqbuffer2),
170                     get_linkcost_text(tc_edge->cost, false, &lqbuffer), lla, llb)) {
171           return;
172         }
173       } else {
174         struct lqtextbuffer lqbuffer, lqbuffer2;
175
176         /*
177          * If one link end pos is unkown, only send Link()
178          */
179         if (0 >
180             fprintf(fmap, "Link('%s','%s',%s,%s);\n", olsr_ip_to_string(&strbuf1, &tc_edge->T_dest_addr),
181                     olsr_ip_to_string(&strbuf2, &tc->addr), get_tc_edge_entry_text(tc_edge, ',', &lqbuffer2),
182                     get_linkcost_text(tc_edge->cost, false, &lqbuffer))) {
183           return;
184         }
185       }
186     }
187     OLSR_FOR_ALL_TC_EDGE_ENTRIES_END(tc, tc_edge);
188   }
189   OLSR_FOR_ALL_TC_ENTRIES_END(tc);
190 }
191
192 #ifndef WIN32
193
194 /*
195  * Windows doesn't know fifo's AFAIK. We better write
196  * to a file (done in nameservice.c, see #ifdef WIN32)
197  */
198
199 static const char *the_fifoname = 0;
200 static int fifopolltime = 0;
201
202 static void
203 mapwrite_poll(void *context __attribute__ ((unused)))
204 {
205   fifopolltime++;
206   if (0 == (fifopolltime & 7) && 0 != the_fifoname) {
207     FILE *fout;
208     /* Non-blocking means: fail open if no pipe reader */
209     int fd = open(the_fifoname, O_WRONLY | O_NONBLOCK);
210     if (0 <= fd) {
211       /*
212        * Change to blocking, otherwhise expect fprintf errors
213        */
214       fcntl(fd, F_SETFL, O_WRONLY);
215       fout = fdopen(fd, "w");
216       if (0 != fout) {
217         mapwrite_work(fout);
218         fclose(fout);
219         /* Give pipe reader cpu slot to detect EOF */
220         usleep(1);
221       } else {
222         close(fd);
223       }
224     }
225   }
226 }
227
228 int
229 mapwrite_init(const char *fifoname)
230 {
231   the_fifoname = fifoname;
232   if (0 != fifoname && 0 != *fifoname) {
233     unlink(fifoname);
234     if (0 > mkfifo(fifoname, S_IWUSR | S_IRUSR | S_IRGRP | S_IROTH)) {
235       OLSR_PRINTF(1, "mkfifo(%s): %s", fifoname, strerror(errno));
236       return false;
237     } else {
238       the_fifoname = fifoname;
239       olsr_start_timer(100, 5, OLSR_TIMER_PERIODIC, &mapwrite_poll, NULL, 0);
240     }
241   }
242   return true;
243 }
244
245 void
246 mapwrite_exit(void)
247 {
248   if (0 != the_fifoname) {
249     unlink(the_fifoname);
250     /* Ignore any Error */
251     the_fifoname = 0;
252   }
253 }
254 #endif
255
256 /*
257  * Local Variables:
258  * mode: c
259  * c-indent-tabs-mode: t
260  * c-basic-offset: 4
261  * tab-width: 4
262  * End:
263  */