9efb3b3a2eda67cb9951eff07e03c2f887c0315c
[olsrd.git] / src / socket_parser.c
1 /*
2  * OLSR ad-hoc routing table management protocol
3  * Copyright (C) 2004 Andreas T√łnnesen (andreto@ifi.uio.no)
4  *
5  * This file is part of the olsr.org OLSR daemon.
6  *
7  * olsr.org is free software; you can redistribute it and/or modify
8  * it under the terms of the GNU General Public License as published by
9  * the Free Software Foundation; either version 2 of the License, or
10  * (at your option) any later version.
11  *
12  * olsr.org is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15  * GNU General Public License for more details.
16  *
17  * You should have received a copy of the GNU General Public License
18  * along with olsr.org; if not, write to the Free Software
19  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
20  * 
21  * 
22  * $Id: socket_parser.c,v 1.14 2004/11/12 21:20:23 kattemat Exp $
23  *
24  */
25
26 #include <unistd.h>
27 #include "socket_parser.h"
28 #include "olsr.h"
29 #include "defs.h"
30
31 #ifdef WIN32
32 #undef EINTR
33 #define EINTR WSAEINTR
34 #undef errno
35 #define errno WSAGetLastError()
36 #undef strerror
37 #define strerror(x) StrError(x)
38 #endif
39
40
41 static int hfd = 0;
42
43 static struct timeval tvp = {0, 0};
44 static fd_set ibits;
45
46 #warning highest FD for select is now set in socket add/remove functions
47
48 /**
49  * Add a socket and handler to the socketset
50  * beeing used in the main select(2) loop
51  * in listen_loop
52  *
53  *@param fd the socket
54  *@param pf the processing function
55  */
56 void
57 add_olsr_socket(int fd, void(*pf)(int))
58 {
59   struct olsr_socket_entry *new_entry;
60
61   if((fd == 0) || (pf == NULL))
62     {
63       fprintf(stderr, "Bogus socket entry - not registering...\n");
64       return;
65     }
66   olsr_printf(1, "Adding OLSR socket entry %d\n", fd);
67
68   new_entry = olsr_malloc(sizeof(struct olsr_socket_entry), "Socket entry");
69
70   new_entry->fd = fd;
71   new_entry->process_function = pf;
72
73   /* Queue */
74   new_entry->next = olsr_socket_entries;
75   olsr_socket_entries = new_entry;
76
77   if(fd + 1 > hfd)
78     hfd = fd + 1;
79 }
80
81 /**
82  * Remove a socket and handler to the socketset
83  * beeing used in the main select(2) loop
84  * in listen_loop
85  *
86  *@param fd the socket
87  *@param pf the processing function
88  */
89 int
90 remove_olsr_socket(int fd, void(*pf)(int))
91 {
92   struct olsr_socket_entry *entry, *prev_entry;
93
94   if((fd == 0) || (pf == NULL))
95     {
96       olsr_syslog(OLSR_LOG_ERR, "Bogus socket entry - not processing...\n");
97       return 0;
98     }
99   olsr_printf(1, "Removing OLSR socket entry %d\n", fd);
100
101   entry = olsr_socket_entries;
102   prev_entry = NULL;
103
104   while(entry)
105     {
106       if((entry->fd == fd) && (entry->process_function == pf))
107         {
108           if(prev_entry == NULL)
109             {
110               olsr_socket_entries = entry->next;
111               free(entry);
112             }
113           else
114             {
115               prev_entry->next = entry->next;
116               free(entry);
117             }
118
119           if(hfd == fd + 1)
120             {
121               /* Re-calculate highest FD */
122               entry = olsr_socket_entries;
123               hfd = 0;
124               while(entry)
125                 {
126                   if(entry->fd + 1 > hfd)
127                     hfd = entry->fd + 1;
128                   entry = entry->next;
129                 }
130             }
131           return 1;
132         }
133       prev_entry = entry;
134       entry = entry->next;
135     }
136
137   return 0;
138 }
139
140
141 void
142 poll_sockets()
143 {
144   int n;
145   struct olsr_socket_entry *olsr_sockets;
146
147
148   /* If there are no registered sockets we
149    * do not call select(2)
150    */
151   if(hfd == 0)
152     return;
153   
154   FD_ZERO(&ibits);
155   
156   /* Adding file-descriptors to FD set */
157   olsr_sockets = olsr_socket_entries;
158   while(olsr_sockets)
159     {
160       FD_SET(olsr_sockets->fd, &ibits);
161       olsr_sockets = olsr_sockets->next;
162     }
163       
164   /* Runnig select on the FD set */
165   n = select(hfd, &ibits, 0, 0, &tvp);
166   
167   if(n == 0)
168     return;
169   /* Did somethig go wrong? */
170   if ((n < 0) && errno != EINTR) 
171     {
172       olsr_syslog(OLSR_LOG_ERR, "select: %m");
173       olsr_printf(1, "Error select: %s", strerror(errno));
174       return;
175     }
176
177   /* Update time since this is much used by the parsing functions */
178   gettimeofday(&now, NULL);      
179   
180   olsr_sockets = olsr_socket_entries;
181   while(olsr_sockets)
182     {
183       if(FD_ISSET(olsr_sockets->fd, &ibits))
184         {
185           olsr_sockets->process_function(olsr_sockets->fd);
186         }
187       olsr_sockets = olsr_sockets->next;
188     }
189         
190 }
191