Mercurial > dropbear
comparison listener.c @ 9:7f77962de998
- Reworked non-channel fd handling to listener.c
- More channel cleaning up
author | Matt Johnston <matt@ucc.asn.au> |
---|---|
date | Thu, 03 Jun 2004 16:45:53 +0000 |
parents | |
children | db2c8e6fb284 |
comparison
equal
deleted
inserted
replaced
7:425ed5c20157 | 9:7f77962de998 |
---|---|
1 #include "includes.h" | |
2 #include "listener.h" | |
3 #include "session.h" | |
4 #include "dbutil.h" | |
5 | |
6 void listener_initialise() { | |
7 | |
8 /* just one slot to start with */ | |
9 ses.listeners = (struct Listener**)m_malloc(sizeof(struct Listener*)); | |
10 ses.listensize = 1; | |
11 ses.listeners[0] = NULL; | |
12 | |
13 } | |
14 | |
15 void set_listener_fds(fd_set * readfds) { | |
16 | |
17 unsigned int i; | |
18 struct Listener *listener; | |
19 | |
20 /* check each in turn */ | |
21 for (i = 0; i < ses.listensize; i++) { | |
22 listener = ses.listeners[i]; | |
23 if (listener != NULL) { | |
24 FD_SET(listener->sock, readfds); | |
25 } | |
26 } | |
27 } | |
28 | |
29 | |
30 void handle_listeners(fd_set * readfds) { | |
31 | |
32 unsigned int i; | |
33 struct Listener *listener; | |
34 | |
35 /* check each in turn */ | |
36 for (i = 0; i < ses.listensize; i++) { | |
37 listener = ses.listeners[i]; | |
38 if (listener != NULL) { | |
39 if (FD_ISSET(listener->sock, readfds)) { | |
40 listener->accepter(listener); | |
41 } | |
42 } | |
43 } | |
44 } | |
45 | |
46 | |
47 /* accepter(int fd, void* typedata) is a function to accept connections, | |
48 * cleanup(void* typedata) happens when cleaning up */ | |
49 struct Listener* new_listener(int sock, int type, void* typedata, | |
50 void (*accepter)(struct Listener*), | |
51 void (*cleanup)(struct Listener*)) { | |
52 | |
53 unsigned int i, j; | |
54 struct Listener *newlisten = NULL; | |
55 /* try get a new structure to hold it */ | |
56 for (i = 0; i < ses.listensize; i++) { | |
57 if (ses.listeners[i] == NULL) { | |
58 break; | |
59 } | |
60 } | |
61 | |
62 /* or create a new one */ | |
63 if (i == ses.listensize) { | |
64 if (ses.listensize > MAX_LISTENERS) { | |
65 TRACE(("leave newlistener: too many already")); | |
66 close(sock); | |
67 return NULL; | |
68 } | |
69 | |
70 ses.listeners = (struct Listener**)m_realloc(ses.listeners, | |
71 (ses.listensize+LISTENER_EXTEND_SIZE) | |
72 *sizeof(struct Listener*)); | |
73 | |
74 ses.listensize += LISTENER_EXTEND_SIZE; | |
75 | |
76 for (j = i; j < ses.listensize; j++) { | |
77 ses.listeners[j] = NULL; | |
78 } | |
79 } | |
80 | |
81 ses.maxfd = MAX(ses.maxfd, sock); | |
82 | |
83 newlisten = (struct Listener*)m_malloc(sizeof(struct Listener)); | |
84 newlisten->index = i; | |
85 newlisten->type = type; | |
86 newlisten->typedata = typedata; | |
87 newlisten->sock = sock; | |
88 newlisten->accepter = accepter; | |
89 newlisten->cleanup = cleanup; | |
90 | |
91 ses.listeners[i] = newlisten; | |
92 return newlisten; | |
93 } | |
94 | |
95 /* Return the first listener which matches the type-specific comparison | |
96 * function. Particularly needed for global requests, like tcp */ | |
97 struct Listener * get_listener(int type, void* typedata, | |
98 int (*match)(void*, void*)) { | |
99 | |
100 unsigned int i; | |
101 struct Listener* listener; | |
102 | |
103 for (i = 0, listener = ses.listeners[i]; i < ses.listensize; i++) { | |
104 if (listener->type == type | |
105 && match(typedata, listener->typedata)) { | |
106 return listener; | |
107 } | |
108 } | |
109 | |
110 return NULL; | |
111 } | |
112 | |
113 void remove_listener(struct Listener* listener) { | |
114 | |
115 if (listener->cleanup) { | |
116 listener->cleanup(listener); | |
117 } | |
118 | |
119 close(listener->sock); | |
120 ses.listeners[listener->index] = NULL; | |
121 m_free(listener); | |
122 | |
123 } |