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

« back to all changes in this revision

Viewing changes to src/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 = 3;
 
60
                        bound = FD_SETSIZE;
 
61
                        for(; i < bound; i++)
 
62
                                        close(i);
 
63
                        libfunc();
 
64
                } else {
 
65
                        rl_fatal(EX_SOFTWARE, _("ABORT - failed to find function \"%s\" in parser module %s (%s)"),
 
66
                                                 funcname, rl_parser, dlerror());
 
67
                }
 
68
        } else {
 
69
                                        rl_fatal(EX_SOFTWARE, _("ABORT - failed to load parser module %s (%s)"),
 
70
                                                                         rl_parser, dlerror());
 
71
        }
 
72
        dlclose(handle); 
 
73
}                               
 
74
 
 
75
void main_loop() {
 
76
        fd_set srfds, swfds;
 
77
        
 
78
        for(;;) {
 
79
                int i, n;
 
80
#ifdef HAVE_MALLINFO
 
81
                static long oldmem;
 
82
                struct mallinfo m;
 
83
#endif          
 
84
 
 
85
                if (rls_term_recv) { /* received SIGTERM or SIGINT */
 
86
                        run_library_func("services_free");
 
87
                        return;
 
88
                }       
 
89
                                                
 
90
                if(rls_need_parse || rls_reaped) {
 
91
                        rls_block();
 
92
                        if(rls_need_parse) {
 
93
#ifdef HAVE_MALLINFO
 
94
                                m = mallinfo();
 
95
#endif
 
96
                                run_library_func("parse");
 
97
                                rls_need_parse = 0;
 
98
#ifdef HAVE_MALLINFO
 
99
                                m = mallinfo();
 
100
                                rl_warn(_("rlinetd configuration (re)loaded, %ld bytes used\n"),
 
101
                                                                m.uordblks - oldmem);
 
102
                                oldmem = m.uordblks;
 
103
#else
 
104
                                rl_warn(_("rlinetd configuration (re)loaded"));
 
105
#endif
 
106
                        }
 
107
                        if(rls_reaped) {
 
108
                                struct pidtab *p;
 
109
                                
 
110
                                rl_pending = (struct pidtab *)rls_reaped;
 
111
                                rls_reaped = NULL;
 
112
                                p = rl_pending;
 
113
                                do {
 
114
                                        if(p->next)
 
115
                                                p->next->prev = p->prev;
 
116
                                        if(p->prev)
 
117
                                                p->prev->next = p->next;
 
118
                                        p->next = NULL;
 
119
                                        p->prev = NULL;
 
120
                                } while((p = p->next_cleanup));
 
121
                        }
 
122
                        rls_unblock();
 
123
                }
 
124
                        
 
125
                while(rl_pending) {
 
126
                        struct pidtab *p;
 
127
                        
 
128
                        run_bytecode(oplisttab_get(rl_pending->onexit), rl_pending->inst);
 
129
                        if(rl_pending->inst)
 
130
                                inst_free(rl_pending->inst);
 
131
                        p = rl_pending->next_cleanup;
 
132
                        free(rl_pending);
 
133
                        rl_pending = p;
 
134
                }
 
135
                srfds = rfds;
 
136
                swfds = wfds;
 
137
                if((n = select(hisock + 1, &srfds, &swfds, NULL, NULL)) < 0) {
 
138
                        switch(errno) {
 
139
                                case EINTR:
 
140
                                        break;
 
141
                                default:
 
142
                                        rl_warn(_("select() failed - %s"), strerror(errno));
 
143
                                        break;
 
144
                        }
 
145
                        continue;
 
146
                }
 
147
                if(!n)
 
148
                        continue;
 
149
                for(i = 0; i <= hisock; i++) {
 
150
                        if(FD_ISSET(i, &srfds) && FD_ISSET(i, &rfds)) {
 
151
                                struct rl_instance *grr;
 
152
 
 
153
                                grr = rfd_ops[i].inst;
 
154
                                if(!rfd_ops[i].inst) {
 
155
                                        grr = inst_new();
 
156
                                        grr->sock = i;
 
157
                                }
 
158
                                run_bytecode(rfd_ops[i].op, grr);
 
159
                        }
 
160
                        if(FD_ISSET(i, &swfds) && FD_ISSET(i, &wfds))
 
161
                                run_bytecode(wfd_ops[i].op, wfd_ops[i].inst);
 
162
                }
 
163
        }
 
164
}
 
165
 
 
166
void listeners_set(int j) {
 
167
        fd_set *fds;
 
168
        int i, bound;
 
169
 
 
170
        bound = getdtablesize();
 
171
        fds = fdsettab_get(j);
 
172
        for(i = 0; i <= bound; i++)
 
173
                if(FD_ISSET(i, fds))
 
174
                        FD_SET(i, &rfds);
 
175
}
 
176
 
 
177
void listeners_clear(int j) {
 
178
        fd_set *fds;
 
179
        int i, bound;
 
180
 
 
181
        bound = getdtablesize();
 
182
        fds = fdsettab_get(j);
 
183
        for(i = 0; i <= bound; i++)
 
184
                if(FD_ISSET(i, fds))
 
185
                        FD_CLR(i, &rfds);
 
186
}
 
187
 
 
188
 
 
189
static void fdops_grow(struct fd_ops **ops, int *len, int new) {
 
190
        if(new < *len)
 
191
                return;
 
192
        *ops = realloc(*ops, (new + 1) * sizeof(**ops));
 
193
        if (!*ops)
 
194
                rl_fatal(EX_SOFTWARE, _("ABORT - Can't allocate memory"));
 
195
        *len = new + 1;
 
196
}
 
197
 
 
198
void read_hook(int fd, rl_opcode_t *op, struct rl_instance *inst) {
 
199
        fdops_grow(&rfd_ops, &rfd_len, fd);
 
200
        rfd_ops[fd].op = op;
 
201
        rfd_ops[fd].inst = inst;
 
202
        FD_SET(fd, &rfds);
 
203
        if(fd > hisock)
 
204
                hisock = fd;
 
205
}
 
206
 
 
207
void read_unhook(int fd) {
 
208
        fdops_grow(&rfd_ops, &rfd_len, fd);
 
209
        FD_CLR(fd, &rfds);
 
210
}
 
211
 
 
212
void write_hook(int fd, rl_opcode_t *op, struct rl_instance *inst) {
 
213
        fdops_grow(&wfd_ops, &wfd_len, fd);
 
214
        wfd_ops[fd].op = op;
 
215
        wfd_ops[fd].inst = inst;
 
216
        FD_SET(fd, &wfds);
 
217
        if(fd > hisock)
 
218
                hisock = fd;
 
219
}
 
220
 
 
221
void write_unhook(int fd) {
 
222
        fdops_grow(&wfd_ops, &wfd_len, fd);
 
223
        FD_CLR(fd, &wfds);
 
224
}
 
225
 
 
226
void all_unhook() {
 
227
        if(rfd_ops)
 
228
                free(rfd_ops);
 
229
        rfd_ops = NULL;
 
230
        rfd_len = 0;
 
231
        if(wfd_ops)
 
232
                free(wfd_ops);
 
233
        wfd_ops = NULL;
 
234
        wfd_len = 0;
 
235
        FD_ZERO(&rfds);
 
236
        FD_ZERO(&wfds);
 
237
}
 
238
 
 
239
struct rl_instance *inst_new() {
 
240
        struct rl_instance *i;
 
241
 
 
242
        i = malloc(sizeof(*i));
 
243
        if (!i)
 
244
                rl_fatal(EX_SOFTWARE, _("ABORT - Can't allocate memory"));
 
245
        memset(i, 0, sizeof(*i));
 
246
        return i;
 
247
}
 
248
 
 
249
void inst_free(struct rl_instance *i) {
 
250
        if(i->sin)
 
251
                free(i->sin);
 
252
        if(i->buf) {
 
253
                if(i->buf->data)
 
254
                        free(i->buf->data);
 
255
                free(i->buf);
 
256
        }
 
257
        free(i);
 
258
}
 
259
 
 
260
/* vim: set ts=2: */