* ISO8859-* -> UTF_8
[olsrd.git] / src / socket_parser.c
1 /*
2  * The olsr.org Optimized Link-State Routing daemon(olsrd)
3  * Copyright (c) 2004, Andreas T√łnnesen(andreto@olsr.org)
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 
11  *   notice, this list of conditions and the following disclaimer.
12  * * Redistributions in binary form must reproduce the above copyright 
13  *   notice, this list of conditions and the following disclaimer in 
14  *   the documentation and/or other materials provided with the 
15  *   distribution.
16  * * Neither the name of olsr.org, olsrd nor the names of its 
17  *   contributors may be used to endorse or promote products derived 
18  *   from this software without specific prior written permission.
19  *
20  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
21  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
22  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 
23  * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE 
24  * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, 
25  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 
26  * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 
27  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 
28  * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 
29  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN 
30  * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 
31  * POSSIBILITY OF SUCH DAMAGE.
32  *
33  * Visit http://www.olsr.org for more information.
34  *
35  * If you find this software useful feel free to make a donation
36  * to the project. For more information see the website or contact
37  * the copyright holders.
38  *
39  * $Id: socket_parser.c,v 1.29 2007/11/29 18:09:11 bernd67 Exp $
40  */
41
42 #include <unistd.h>
43 #include "socket_parser.h"
44 #include "olsr.h"
45 #include "defs.h"
46 #include "log.h"
47 #include "net_os.h"
48
49 #ifdef WIN32
50 #undef EINTR
51 #define EINTR WSAEINTR
52 #undef errno
53 #define errno WSAGetLastError()
54 #undef strerror
55 #define strerror(x) StrError(x)
56 #endif
57
58
59 struct olsr_socket_entry *olsr_socket_entries;
60
61 static int hfd = 0;
62
63 /**
64  * Add a socket and handler to the socketset
65  * beeing used in the main select(2) loop
66  * in listen_loop
67  *
68  *@param fd the socket
69  *@param pf the processing function
70  */
71 void
72 add_olsr_socket(int fd, void(*pf)(int))
73 {
74   struct olsr_socket_entry *new_entry;
75
76   if((fd == 0) || (pf == NULL))
77     {
78       fprintf(stderr, "Bogus socket entry - not registering...\n");
79       return;
80     }
81   OLSR_PRINTF(2, "Adding OLSR socket entry %d\n", fd);
82
83   new_entry = olsr_malloc(sizeof(struct olsr_socket_entry), "Socket entry");
84
85   new_entry->fd = fd;
86   new_entry->process_function = pf;
87
88   /* Queue */
89   new_entry->next = olsr_socket_entries;
90   olsr_socket_entries = new_entry;
91
92   if(fd + 1 > hfd)
93     hfd = fd + 1;
94 }
95
96 /**
97  * Remove a socket and handler to the socketset
98  * beeing used in the main select(2) loop
99  * in listen_loop
100  *
101  *@param fd the socket
102  *@param pf the processing function
103  */
104 int
105 remove_olsr_socket(int fd, void(*pf)(int))
106 {
107   struct olsr_socket_entry *entry, *prev_entry;
108
109   if((fd == 0) || (pf == NULL))
110     {
111       olsr_syslog(OLSR_LOG_ERR, "Bogus socket entry - not processing...\n");
112       return 0;
113     }
114   OLSR_PRINTF(1, "Removing OLSR socket entry %d\n", fd);
115
116   entry = olsr_socket_entries;
117   prev_entry = NULL;
118
119   while(entry)
120     {
121       if((entry->fd == fd) && (entry->process_function == pf))
122         {
123           if(prev_entry == NULL)
124             {
125               olsr_socket_entries = entry->next;
126               free(entry);
127             }
128           else
129             {
130               prev_entry->next = entry->next;
131               free(entry);
132             }
133
134           if(hfd == fd + 1)
135             {
136               /* Re-calculate highest FD */
137               entry = olsr_socket_entries;
138               hfd = 0;
139               while(entry)
140                 {
141                   if(entry->fd + 1 > hfd)
142                     hfd = entry->fd + 1;
143                   entry = entry->next;
144                 }
145             }
146           return 1;
147         }
148       prev_entry = entry;
149       entry = entry->next;
150     }
151
152   return 0;
153 }
154
155
156 void
157 poll_sockets(void)
158 {
159   int n;
160   struct olsr_socket_entry *olsr_sockets;
161   /* Global buffer for times(2) calls. Do not remopve since at least OpenBSD needs it. */
162   struct tms tms_buf;
163   fd_set ibits;
164   struct timeval tvp = {0, 0};
165
166
167   /* If there are no registered sockets we
168    * do not call select(2)
169    */
170   if(hfd == 0)
171     return;
172   
173   FD_ZERO(&ibits);
174   
175   /* Adding file-descriptors to FD set */
176   
177   for(olsr_sockets = olsr_socket_entries; olsr_sockets; olsr_sockets = olsr_sockets->next)
178     {
179       FD_SET((unsigned int)olsr_sockets->fd, &ibits); /* And we cast here since we get a warning on Win32 */    
180     }
181       
182   /* Runnig select on the FD set */
183   n = olsr_select(hfd, &ibits, NULL, NULL, &tvp);
184   
185   if(n == 0)
186     return;
187   /* Did somethig go wrong? */
188   if (n < 0) 
189     {
190       if(errno != EINTR) {
191         const char * const err_msg = strerror(errno);
192         olsr_syslog(OLSR_LOG_ERR, "select: %s", err_msg);
193         OLSR_PRINTF(1, "Error select: %s", err_msg);
194       }
195       return;
196     }
197
198   /* Update time since this is much used by the parsing functions */
199   gettimeofday(&now, NULL);
200   now_times = times(&tms_buf);
201
202   for(olsr_sockets = olsr_socket_entries;olsr_sockets;olsr_sockets = olsr_sockets->next)
203     {
204       if(FD_ISSET(olsr_sockets->fd, &ibits))
205           olsr_sockets->process_function(olsr_sockets->fd);
206     }   
207 }
208