~ubuntu-branches/debian/sid/rlinetd/sid

« back to all changes in this revision

Viewing changes to engine.c

  • Committer: Bazaar Package Importer
  • Author(s): Robert Luberda
  • Date: 2010-03-20 18:03:45 UTC
  • mfrom: (2.3.2 upstream)
  • Revision ID: james.westby@ubuntu.com-20100320180345-x1srfbe2tg00ezsf
Tags: 0.7-1
* New upstream version.
* Recommend rsyslog instead of sysklogd (closes: #526922).
* update-inetd:
  + add support for enabling, disabling and removing entries;
  + use ucf for managing generated files;
  + ignore ucf files in rlinetd.conf;
  + make appropriate changes in  postinst and postrm scripts.
* Set debhelper compat level to 7
* Standards-Version: 3.8.4 (no changes). 

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
#include <dlfcn.h>
2
 
#include <errno.h>
3
 
#include <fcntl.h>
4
 
#include <netinet/in.h>
5
 
#include <signal.h>
6
 
#include <stdarg.h>
7
 
#include <stdio.h>
8
 
#include <stdlib.h>
9
 
#include <string.h>
10
 
#include <sysexits.h>
11
 
#include <syslog.h>
12
 
#include <sys/types.h>
13
 
#include <sys/socket.h>
14
 
#include <time.h>
15
 
#include <unistd.h>
16
 
 
17
 
#include <config.h>
18
 
 
19
 
#ifdef HAVE_MALLOC_H
20
 
#include <malloc.h>
21
 
#endif
22
 
 
23
 
#include "bytecode.h"
24
 
#include "db.h"
25
 
#include "error.h"
26
 
#include "rlinetd.h"
27
 
#include "signals.h"
28
 
 
29
 
struct rl_cleanup *rl_cleanups = NULL;
30
 
int hisock;
31
 
extern char *rl_parser;
32
 
struct pidtab *rl_pending;
33
 
struct rl_instance *inst_new();
34
 
 
35
 
struct fd_ops {
36
 
        rl_opcode_t *op;
37
 
        struct rl_instance *inst;
38
 
};
39
 
 
40
 
fd_set rfds, wfds;
41
 
struct fd_ops *rfd_ops = NULL, *wfd_ops = NULL;
42
 
int rfd_len = 0, wfd_len = 0;
43
 
 
44
 
/* runs the specified function from our parser library */
45
 
static void run_library_func(char* funcname) {
46
 
        int i;                          
47
 
        void *handle;
48
 
  void (*libfunc)();
49
 
        
50
 
  if((handle = dlopen(rl_parser, RTLD_NOW
51
 
#ifdef RTLD_GLOBAL
52
 
                                                                                        | RTLD_GLOBAL
53
 
#endif
54
 
                                                                                        ))) {
55
 
                if((libfunc = dlsym(handle, funcname))) {
56
 
                        int bound;
57
 
                                                
58
 
                        closelog();
59
 
                        i = 0;
60
 
                        if(rl_debug)
61
 
                                i = 3;
62
 
                        bound = FD_SETSIZE;
63
 
                        for(; i < bound; i++)
64
 
                                        close(i);
65
 
                        libfunc();
66
 
                } else {
67
 
                        rl_fatal(EX_SOFTWARE, "ABORT - failed to find function \"%s\" in parser module %s (%s)",
68
 
                                                 funcname, rl_parser, dlerror());
69
 
                }
70
 
        } else {
71
 
                                        rl_fatal(EX_SOFTWARE, "ABORT - failed to load parser module %s (%s)",
72
 
                                                                         rl_parser, dlerror());
73
 
        }
74
 
        dlclose(handle); 
75
 
}                               
76
 
 
77
 
void main_loop() {
78
 
        fd_set srfds, swfds;
79
 
        
80
 
        for(;;) {
81
 
                int i, n;
82
 
#ifdef HAVE_MALLINFO
83
 
                static long oldmem;
84
 
                struct mallinfo m;
85
 
#endif          
86
 
 
87
 
                if (rls_term_recv) { /* received SIGTERM or SIGINT */
88
 
                        run_library_func("services_free");
89
 
                        return;
90
 
                }       
91
 
                                                
92
 
                if(rls_need_parse || rls_reaped) {
93
 
                        rls_block();
94
 
                        if(rls_need_parse) {
95
 
#ifdef HAVE_MALLINFO
96
 
                                m = mallinfo();
97
 
#endif
98
 
                                run_library_func("parse");
99
 
                                rls_need_parse = 0;
100
 
#ifdef HAVE_MALLINFO
101
 
                                m = mallinfo();
102
 
                                rl_warn("rlinetd configuration (re)loaded, %ld bytes used\n",
103
 
                                                                m.uordblks - oldmem);
104
 
                                oldmem = m.uordblks;
105
 
#else
106
 
                                rl_warn("rlinetd configuration (re)loaded");
107
 
#endif
108
 
                        }
109
 
                        if(rls_reaped) {
110
 
                                struct pidtab *p;
111
 
                                
112
 
                                rl_pending = (struct pidtab *)rls_reaped;
113
 
                                rls_reaped = NULL;
114
 
                                p = rl_pending;
115
 
                                do {
116
 
                                        if(p->next)
117
 
                                                p->next->prev = p->prev;
118
 
                                        if(p->prev)
119
 
                                                p->prev->next = p->next;
120
 
                                        p->next = NULL;
121
 
                                        p->prev = NULL;
122
 
                                } while((p = p->next_cleanup));
123
 
                        }
124
 
                        rls_unblock();
125
 
                }
126
 
                        
127
 
                while(rl_pending) {
128
 
                        struct pidtab *p;
129
 
                        
130
 
                        run_bytecode(oplisttab_get(rl_pending->onexit), rl_pending->inst);
131
 
                        if(rl_pending->inst)
132
 
                                inst_free(rl_pending->inst);
133
 
                        p = rl_pending->next_cleanup;
134
 
                        free(rl_pending);
135
 
                        rl_pending = p;
136
 
                }
137
 
                srfds = rfds;
138
 
                swfds = wfds;
139
 
                if((n = select(hisock + 1, &srfds, &swfds, NULL, NULL)) < 0) {
140
 
                        switch(errno) {
141
 
                                case EINTR:
142
 
                                        break;
143
 
                                default:
144
 
                                        rl_warn("select() failed - %s", strerror(errno));
145
 
                                        break;
146
 
                        }
147
 
                        continue;
148
 
                }
149
 
                if(!n)
150
 
                        continue;
151
 
                for(i = 0; i <= hisock; i++) {
152
 
                        if(FD_ISSET(i, &srfds) && FD_ISSET(i, &rfds)) {
153
 
                                struct rl_instance *grr;
154
 
 
155
 
                                grr = rfd_ops[i].inst;
156
 
                                if(!rfd_ops[i].inst) {
157
 
                                        grr = inst_new();
158
 
                                        grr->sock = i;
159
 
                                }
160
 
                                run_bytecode(rfd_ops[i].op, grr);
161
 
                        }
162
 
                        if(FD_ISSET(i, &swfds) && FD_ISSET(i, &wfds))
163
 
                                run_bytecode(wfd_ops[i].op, wfd_ops[i].inst);
164
 
                }
165
 
        }
166
 
}
167
 
 
168
 
void listeners_set(int j) {
169
 
        fd_set *fds;
170
 
        int i, bound;
171
 
 
172
 
        bound = getdtablesize();
173
 
        fds = fdsettab_get(j);
174
 
        for(i = 0; i <= bound; i++)
175
 
                if(FD_ISSET(i, fds))
176
 
                        FD_SET(i, &rfds);
177
 
}
178
 
 
179
 
void listeners_clear(int j) {
180
 
        fd_set *fds;
181
 
        int i, bound;
182
 
 
183
 
        bound = getdtablesize();
184
 
        fds = fdsettab_get(j);
185
 
        for(i = 0; i <= bound; i++)
186
 
                if(FD_ISSET(i, fds))
187
 
                        FD_CLR(i, &rfds);
188
 
}
189
 
 
190
 
 
191
 
static void fdops_grow(struct fd_ops **ops, int *len, int new) {
192
 
        if(new < *len)
193
 
                return;
194
 
        *ops = realloc(*ops, (new + 1) * sizeof(**ops));
195
 
        if (!*ops)
196
 
                rl_fatal(EX_SOFTWARE, "ABORT - Can't allocate memory");
197
 
        *len = new + 1;
198
 
}
199
 
 
200
 
void read_hook(int fd, rl_opcode_t *op, struct rl_instance *inst) {
201
 
        fdops_grow(&rfd_ops, &rfd_len, fd);
202
 
        rfd_ops[fd].op = op;
203
 
        rfd_ops[fd].inst = inst;
204
 
        FD_SET(fd, &rfds);
205
 
        if(fd > hisock)
206
 
                hisock = fd;
207
 
}
208
 
 
209
 
void read_unhook(int fd) {
210
 
        fdops_grow(&rfd_ops, &rfd_len, fd);
211
 
        FD_CLR(fd, &rfds);
212
 
}
213
 
 
214
 
void write_hook(int fd, rl_opcode_t *op, struct rl_instance *inst) {
215
 
        fdops_grow(&wfd_ops, &wfd_len, fd);
216
 
        wfd_ops[fd].op = op;
217
 
        wfd_ops[fd].inst = inst;
218
 
        FD_SET(fd, &wfds);
219
 
        if(fd > hisock)
220
 
                hisock = fd;
221
 
}
222
 
 
223
 
void write_unhook(int fd) {
224
 
        fdops_grow(&wfd_ops, &wfd_len, fd);
225
 
        FD_CLR(fd, &wfds);
226
 
}
227
 
 
228
 
void all_unhook() {
229
 
        if(rfd_ops)
230
 
                free(rfd_ops);
231
 
        rfd_ops = NULL;
232
 
        rfd_len = 0;
233
 
        if(wfd_ops)
234
 
                free(wfd_ops);
235
 
        wfd_ops = NULL;
236
 
        wfd_len = 0;
237
 
        FD_ZERO(&rfds);
238
 
        FD_ZERO(&wfds);
239
 
}
240
 
 
241
 
struct rl_instance *inst_new() {
242
 
        struct rl_instance *i;
243
 
 
244
 
        i = malloc(sizeof(*i));
245
 
        if (!i)
246
 
                rl_fatal(EX_SOFTWARE, "ABORT - Can't allocate memory");
247
 
        memset(i, 0, sizeof(*i));
248
 
        return i;
249
 
}
250
 
 
251
 
void inst_free(struct rl_instance *i) {
252
 
        if(i->sin)
253
 
                free(i->sin);
254
 
        if(i->buf) {
255
 
                if(i->buf->data)
256
 
                        free(i->buf->data);
257
 
                free(i->buf);
258
 
        }
259
 
        free(i);
260
 
}
261
 
 
262
 
/* vim: set ts=2: */