Go to most recent revision | Details | Last modification | View Log | RSS feed
Rev | Author | Line No. | Line |
---|---|---|---|
1082 | dev | 1 | #!/usr/bin/perl -w |
2 | |||
3 | # |
||
4 | # Sample backend for HostAdmiral |
||
5 | # (copyleft) Anatoli Klassen |
||
6 | # |
||
7 | |||
8 | # FIXME use transactions |
||
9 | |||
10 | use strict; |
||
11 | use vars; |
||
12 | use subs; |
||
13 | use Socket; |
||
14 | use DBI; |
||
15 | use Time::HiRes qw( gettimeofday tv_interval ); |
||
16 | |||
17 | # == configuration ============================= |
||
18 | |||
19 | my $host = '127.0.0.1'; |
||
20 | my $port = 9097; |
||
21 | my $password = '0123456789ABCDEF'; |
||
22 | my $db_url = 'DBI:mysql:database=mail;host=localhost;port=3306'; |
||
23 | my $db_user = 'root'; |
||
24 | my $db_password = ''; |
||
25 | my $log_level = 9; # 0 - none, 9 - all |
||
26 | |||
27 | # == constants ================================= |
||
28 | |||
29 | my $protocol_ver_maj = "1"; |
||
30 | my $protocol_ver_min = "0"; |
||
31 | my $protocol_header = "HostAdmiral_TcpListener"; |
||
32 | my $password_header = "password="; |
||
33 | my $domain_header = "inetDomain"; |
||
34 | my $user_header = "user"; |
||
35 | my $system_user_header = "systemUser"; |
||
36 | my $mailbox_header = "mailbox"; |
||
37 | my $mail_alias_header = "mailAlias"; |
||
38 | my $create_action = "create"; |
||
39 | my $modify_action = "modify"; |
||
40 | my $delete_action = "delete"; |
||
41 | |||
42 | # response codes |
||
43 | my $code_ok = 200; |
||
44 | my $code_ok_but = 201; |
||
45 | my $code_ignored = 202; |
||
46 | my $code_no_body = 400; |
||
47 | my $code_protocol_header = 401; |
||
48 | my $code_no_end_lines = 402; |
||
49 | my $code_no_password = 403; |
||
50 | my $code_wrong_password = 404; |
||
51 | my $code_no_command = 405; |
||
52 | my $code_wrong_command = 406; |
||
53 | my $code_unknown_command = 407; |
||
54 | my $code_wrong_params = 408; |
||
55 | my $code_db_connect_error = 501; |
||
56 | my $code_db_error = 502; |
||
57 | my $code_db_close_error = 503; |
||
58 | |||
59 | # == internal global variables ================= |
||
60 | |||
61 | my %handlers; |
||
62 | |||
63 | sub connection_loop |
||
64 | { |
||
65 | # listen for connections |
||
66 | socket(SERVER, PF_INET, SOCK_STREAM, getprotobyname('tcp')) or die "$!\n"; |
||
67 | setsockopt(SERVER, SOL_SOCKET, SO_REUSEADDR, 1) or die "$!\n"; |
||
68 | bind(SERVER, sockaddr_in($port, inet_aton($host))) or die "$!\n"; |
||
69 | listen(SERVER, 1); |
||
70 | |||
71 | while(1) { |
||
72 | # get connection |
||
73 | my $rem_addr = accept(CLIENT, SERVER); |
||
74 | my $buf; |
||
75 | my $body = ""; |
||
76 | my %request = (); |
||
77 | #log_debug("Remote: $rem_addr"); |
||
78 | $request{'start_timestamp'} = [gettimeofday]; |
||
79 | |||
80 | # receive request body |
||
81 | while((my $size = sysread CLIENT, $buf, 65536) > 0) { |
||
82 | $body .= $buf; |
||
83 | } |
||
84 | $request{'body'} = $body; |
||
85 | $request{'body_timestamp'} = [gettimeofday]; |
||
86 | |||
87 | # call handler |
||
88 | handle_request(\%request); |
||
89 | $request{'done_timestamp'} = [gettimeofday]; |
||
90 | |||
91 | # print out response |
||
92 | print CLIENT "$protocol_header $protocol_ver_maj.$protocol_ver_min" |
||
93 | . "\n$request{'code'} $request{'response'}\n\n"; |
||
94 | close CLIENT; |
||
95 | $request{'stop_timestamp'} = [gettimeofday]; |
||
96 | log_debug("Duration: " . tv_interval($request{'start_timestamp'}, |
||
97 | $request{'stop_timestamp'}) . " sec"); |
||
98 | } |
||
99 | |||
100 | # close the port |
||
101 | close SERVER; |
||
102 | } |
||
103 | |||
104 | sub handle_request |
||
105 | { |
||
106 | my $request = shift @_; |
||
107 | |||
108 | log_debug("Handle request [\n$request->{'body'}]"); |
||
109 | |||
110 | my @lines = split /\n/, $request->{'body'}, -1; |
||
111 | my $cur = 0; |
||
112 | |||
113 | # check header |
||
114 | if($#lines < $cur) { |
||
115 | set_request_code($request, $code_no_body, "Request without body"); |
||
116 | return; |
||
117 | } |
||
118 | unless($lines[$cur] =~ /^$protocol_header $protocol_ver_maj\.\d+$/) { |
||
119 | set_request_code($request, $code_protocol_header, "Request must start" |
||
120 | . "with [$protocol_header $protocol_ver_maj.minor]," |
||
121 | . " but [$lines[$cur]] found"); |
||
122 | return; |
||
123 | } |
||
124 | $cur++; |
||
125 | |||
126 | # check end lines |
||
127 | if($#lines < $cur+1 || $lines[$#lines-1] ne "" || $lines[$#lines] ne "") { |
||
128 | set_request_code($request, $code_no_end_lines, |
||
129 | "Request doesn't end with \\n\\n"); |
||
130 | return; |
||
131 | } |
||
132 | |||
133 | # check password |
||
134 | if($password) { |
||
135 | if($#lines < $cur || !($lines[$cur] =~ /^$password_header/)) { |
||
136 | set_request_code($request, $code_no_password, |
||
137 | "Password not specified"); |
||
138 | return; |
||
139 | } |
||
140 | |||
141 | unless($lines[$cur] =~ /^$password_header$password$/) { |
||
142 | set_request_code($request, $code_wrong_password, |
||
143 | "Wrong password"); |
||
144 | return; |
||
145 | } |
||
146 | |||
147 | $cur++; |
||
148 | } |
||
149 | |||
150 | # get command handler |
||
151 | if($#lines < $cur) { |
||
152 | set_request_code($request, $code_no_command, "Empty command"); |
||
153 | return; |
||
154 | } |
||
155 | unless($lines[$cur] =~ /^(\S+)\t(\S+)/) { |
||
156 | set_request_code($request, $code_wrong_command, "Can not get command"); |
||
157 | return; |
||
158 | } |
||
159 | |||
160 | $request->{'command'} = $1; |
||
161 | $request->{'subcommand'} = $2; |
||
162 | $request->{'handler'} = $handlers{"$1_$2"}; |
||
163 | |||
164 | unless($request->{'handler'}) { |
||
165 | set_request_code($request, $code_unknown_command, |
||
166 | "Unknown command [$request->{'command'} $request->{'subcommand'}]"); |
||
167 | return; |
||
168 | } |
||
169 | |||
170 | # call |
||
171 | log_debug("call $request->{'command'}_$request->{'subcommand'}"); |
||
172 | my @params = @lines[$cur..$#lines-2]; |
||
173 | &{$request->{'handler'}}($request, @params); |
||
174 | } |
||
175 | |||
176 | sub handle_user_create |
||
177 | { |
||
178 | my $request = shift @_; |
||
179 | |||
180 | set_request_code($request, $code_ignored, "Not interesting in users"); |
||
181 | } |
||
182 | |||
183 | sub handle_user_modify |
||
184 | { |
||
185 | my $request = shift @_; |
||
186 | |||
187 | set_request_code($request, $code_ignored, "Not interesting in users"); |
||
188 | } |
||
189 | |||
190 | sub handle_user_delete |
||
191 | { |
||
192 | my $request = shift @_; |
||
193 | |||
194 | set_request_code($request, $code_ignored, "Not interesting in users"); |
||
195 | } |
||
196 | |||
197 | sub handle_domain_create |
||
198 | { |
||
199 | my $request = shift @_; |
||
200 | my %params = parse_command_params($request, shift @_, ("name")); |
||
201 | return unless(%params); |
||
202 | |||
203 | my $res_action = save_to_db($request, "transport", |
||
204 | { domain => $params{"name"} }, |
||
205 | { domain => $params{"name"}, comment => $params{"comment"}, |
||
206 | transport => 'virtual:' } ); |
||
207 | |||
208 | if($res_action eq 'update') { |
||
209 | return unless(restart_mail_system()); |
||
210 | set_request_code($request, $code_ok_but, "Domain exists, modified"); |
||
211 | } |
||
212 | elsif($res_action eq 'insert') { |
||
213 | return unless(restart_mail_system()); |
||
214 | set_request_code($request, $code_ok, "Domain created"); |
||
215 | } |
||
216 | } |
||
217 | |||
218 | sub handle_domain_modify |
||
219 | { |
||
220 | my $request = shift @_; |
||
221 | my %params = parse_command_params($request, shift @_, ("oldName", "name")); |
||
222 | return unless(%params); |
||
223 | |||
224 | my $res_action = save_to_db($request, "transport", |
||
225 | { domain => $params{"oldName"} }, |
||
226 | { domain => $params{"name"}, comment => $params{"comment"}, |
||
227 | transport => 'virtual:' } ); |
||
228 | |||
229 | if($res_action eq 'update') { |
||
230 | return unless(restart_mail_system()); |
||
231 | set_request_code($request, $code_ok, "Domain modified"); |
||
232 | } |
||
233 | elsif($res_action eq 'insert') { |
||
234 | return unless(restart_mail_system()); |
||
235 | set_request_code($request, $code_ok_but, "Domain not found, created"); |
||
236 | } |
||
237 | } |
||
238 | |||
239 | sub handle_domain_delete |
||
240 | { |
||
241 | my $request = shift @_; |
||
242 | my %params = parse_command_params($request, shift @_, ("name")); |
||
243 | return unless(%params); |
||
244 | |||
245 | my $res_action = delete_from_db($request, "transport", |
||
246 | { domain => $params{"name"} } ); |
||
247 | |||
248 | if($res_action eq 'delete') { |
||
249 | return unless(restart_mail_system()); |
||
250 | set_request_code($request, $code_ok, "Domain deleted"); |
||
251 | } |
||
252 | elsif($res_action eq 'not found') { |
||
253 | set_request_code($request, $code_ok_but, "Domain not found"); |
||
254 | } |
||
255 | } |
||
256 | |||
257 | sub handle_system_user_create |
||
258 | { |
||
259 | } |
||
260 | |||
261 | sub handle_system_user_modify |
||
262 | { |
||
263 | } |
||
264 | |||
265 | sub handle_system_user_delete |
||
266 | { |
||
267 | } |
||
268 | |||
269 | sub handle_mailbox_create |
||
270 | { |
||
271 | my $request = shift @_; |
||
272 | my %params = parse_command_params($request, shift @_, |
||
273 | ("login", "password", "domain")); |
||
274 | return unless(%params); |
||
275 | |||
276 | my $res_action = save_to_db($request, "users", |
||
277 | { login => "$params{'login'}\@$params{'domain'}" }, |
||
278 | { login => "$params{'login'}\@$params{'domain'}", |
||
279 | password => $params{"password"}, |
||
280 | maildir => "$params{'domain'}/$params{'login'}/", |
||
281 | expired => ($params{"enabled"} eq "true" ? 0 : 1), |
||
282 | comment => $params{"comment"}, |
||
283 | uid => ($params{"systemUser"} ? $params{"systemUser"} : undef) } ); |
||
284 | |||
285 | if($res_action eq 'update') { |
||
286 | set_request_code($request, $code_ok_but, "Mailbox exists, modified"); |
||
287 | } |
||
288 | elsif($res_action eq 'insert') { |
||
289 | set_request_code($request, $code_ok, "Mailbox created"); |
||
290 | } |
||
291 | } |
||
292 | |||
293 | sub handle_mailbox_modify |
||
294 | { |
||
295 | my $request = shift @_; |
||
296 | my %params = parse_command_params($request, shift @_, |
||
297 | ("oldLogin", "oldDomain", "login", "domain")); |
||
298 | return unless(%params); |
||
299 | |||
300 | # FIXME move the old maildir |
||
301 | |||
302 | my $res_action = save_to_db($request, "users", |
||
303 | { login => "$params{'oldLogin'}\@$params{'oldDomain'}" }, |
||
304 | { login => "$params{'login'}\@$params{'domain'}", |
||
305 | password => $params{"password"}, |
||
306 | maildir => "$params{'domain'}/$params{'login'}/", |
||
307 | expired => ($params{"enabled"} eq "true" ? "0" : "1"), |
||
308 | comment => $params{"comment"}, |
||
309 | uid => ($params{"systemUser"} ? $params{"systemUser"} : undef) } ); |
||
310 | |||
311 | if($res_action eq 'update') { |
||
312 | set_request_code($request, $code_ok, "Mailbox modified"); |
||
313 | } |
||
314 | elsif($res_action eq 'insert') { |
||
315 | set_request_code($request, $code_ok_but, "Mailbox not found, created"); |
||
316 | } |
||
317 | } |
||
318 | |||
319 | sub handle_mailbox_delete |
||
320 | { |
||
321 | my $request = shift @_; |
||
322 | my %params = parse_command_params($request, shift @_, ("login", "domain")); |
||
323 | return unless(%params); |
||
324 | |||
325 | # FIXME remove the maildir |
||
326 | |||
327 | my $res_action = delete_from_db($request, "users", |
||
328 | { login => "$params{'login'}\@$params{'domain'}" } ); |
||
329 | |||
330 | if($res_action eq 'delete') { |
||
331 | set_request_code($request, $code_ok, "Mailbox deleted"); |
||
332 | } |
||
333 | elsif($res_action eq 'not found') { |
||
334 | set_request_code($request, $code_ok_but, "Mailbox not found"); |
||
335 | } |
||
336 | } |
||
337 | |||
338 | sub handle_mail_alias_create |
||
339 | { |
||
340 | my $request = shift @_; |
||
341 | my %params = parse_command_params($request, shift @_, ("address", "domain")); |
||
342 | return unless(%params); |
||
343 | my @rcpts = parse_command_array($request, @_); |
||
344 | |||
345 | my $del_action = delete_from_db($request, "aliases", |
||
346 | { alias => "$params{'address'}\@$params{'domain'}" } ); |
||
347 | return if($del_action eq "error"); |
||
348 | |||
349 | foreach my $rcpt (@rcpts) { |
||
350 | log_debug("save $rcpt"); |
||
351 | my $res_action = save_to_db($request, "aliases", |
||
352 | undef, |
||
353 | { alias => "$params{'address'}\@$params{'domain'}", |
||
354 | rcpt => $rcpt, comment => $params{"comment"} } ); |
||
355 | return if($res_action eq "error"); |
||
356 | } |
||
357 | |||
358 | if($del_action eq 'delete') { |
||
359 | set_request_code($request, $code_ok_but, "Mail alias exists, modified"); |
||
360 | } |
||
361 | elsif($del_action eq 'not found') { |
||
362 | set_request_code($request, $code_ok, "Mail alias created"); |
||
363 | } |
||
364 | } |
||
365 | |||
366 | sub handle_mail_alias_modify |
||
367 | { |
||
368 | my $request = shift @_; |
||
369 | my %params = parse_command_params($request, shift @_, ("address", "domain")); |
||
370 | return unless(%params); |
||
371 | my @rcpts = parse_command_array($request, @_); |
||
372 | |||
373 | my $del_action = delete_from_db($request, "aliases", |
||
374 | { alias => "$params{'address'}\@$params{'domain'}" } ); |
||
375 | return if($del_action eq "error"); |
||
376 | |||
377 | foreach my $rcpt (@rcpts) { |
||
378 | log_debug("save $rcpt"); |
||
379 | my $res_action = save_to_db($request, "aliases", |
||
380 | undef, |
||
381 | { alias => "$params{'address'}\@$params{'domain'}", |
||
382 | rcpt => $rcpt, comment => $params{"comment"} } ); |
||
383 | return if($res_action eq "error"); |
||
384 | } |
||
385 | |||
386 | if($del_action eq 'delete') { |
||
387 | set_request_code($request, $code_ok, "Mail alias modified"); |
||
388 | } |
||
389 | elsif($del_action eq 'not found') { |
||
390 | set_request_code($request, $code_ok_but, "Mail alias not found, created"); |
||
391 | } |
||
392 | } |
||
393 | |||
394 | sub handle_mail_alias_delete |
||
395 | { |
||
396 | my $request = shift @_; |
||
397 | my %params = parse_command_params($request, shift @_, ("address", "domain")); |
||
398 | return unless(%params); |
||
399 | |||
400 | my $res_action = delete_from_db($request, "aliases", |
||
401 | { alias => "$params{'address'}\@$params{'domain'}" } ); |
||
402 | |||
403 | if($res_action eq 'delete') { |
||
404 | set_request_code($request, $code_ok, "Mail alias deleted"); |
||
405 | } |
||
406 | elsif($res_action eq 'not found') { |
||
407 | set_request_code($request, $code_ok_but, "Mail alias not found"); |
||
408 | } |
||
409 | } |
||
410 | |||
411 | sub decode_param |
||
412 | { |
||
413 | my $value = shift @_; |
||
414 | |||
415 | $value =~ s/\\r/\r/g; |
||
416 | $value =~ s/\\n/\n/g; |
||
417 | $value =~ s/\\t/\t/g; |
||
418 | $value =~ s/\\0/\000/g; |
||
419 | $value =~ s/\\\\/\\/g; |
||
420 | |||
421 | return $value; |
||
422 | } |
||
423 | |||
424 | sub parse_command_array |
||
425 | { |
||
426 | my $request = shift @_; |
||
427 | my @params = (); |
||
428 | |||
429 | map { |
||
430 | if(/^\t(.*)$/) { |
||
431 | push @params, decode_param($1); |
||
432 | } |
||
433 | } @_; |
||
434 | |||
435 | return @params; |
||
436 | } |
||
437 | |||
438 | sub parse_command_params($$@) |
||
439 | { |
||
440 | my $request = shift @_; |
||
441 | my @params = split /\t/, shift @_, -1; |
||
442 | my %required = map { $_ => 1 } @_; # convert array to hash |
||
443 | my %values = (); |
||
444 | |||
445 | @params = @params[2..$#params]; # remove handler and action |
||
446 | map { |
||
447 | my ($key, $value) = split /=/, $_; |
||
448 | $values{$key} = decode_param($value); |
||
449 | delete($required{$key}); |
||
450 | } @params; |
||
451 | |||
452 | if(%required) { |
||
453 | set_request_code($request, $code_wrong_params, |
||
454 | "Params " . join(', ', keys %required) . " expected but not found"); |
||
455 | return (); |
||
456 | } |
||
457 | |||
458 | return %values; |
||
459 | } |
||
460 | |||
461 | sub restart_mail_system |
||
462 | { |
||
463 | my $request = shift @_; |
||
464 | |||
465 | log_debug("Mail system restarted"); |
||
466 | |||
467 | return 1; |
||
468 | } |
||
469 | |||
470 | sub db_connect |
||
471 | { |
||
472 | my $request = shift @_; |
||
473 | my $dbh = undef; |
||
474 | |||
475 | eval { $dbh = DBI->connect($db_url, $db_user, $db_password); }; |
||
476 | if($@) { |
||
477 | set_request_code($request, $code_db_connect_error, $@); |
||
478 | $dbh = undef; |
||
479 | } |
||
480 | |||
481 | return $dbh; |
||
482 | } |
||
483 | |||
484 | sub db_close |
||
485 | { |
||
486 | my $request = shift @_; |
||
487 | my $dbh = shift @_; |
||
488 | my $error = shift @_; |
||
489 | my $no_error = 1; |
||
490 | |||
491 | if($error) { |
||
492 | set_request_code($request, $code_db_error, $error); |
||
493 | $no_error = 0; |
||
494 | } |
||
495 | |||
496 | eval { |
||
497 | $dbh->disconnect() if($dbh); |
||
498 | }; |
||
499 | |||
500 | if($@ && $no_error) { |
||
501 | set_request_code($request, $code_db_close_error, $@); |
||
502 | $no_error = 0; |
||
503 | } |
||
504 | |||
505 | return $no_error; |
||
506 | } |
||
507 | |||
508 | sub delete_from_db |
||
509 | { |
||
510 | my $request = shift @_; |
||
511 | my $table = shift @_; |
||
512 | my $key_columns = shift @_; |
||
513 | |||
514 | my $res_action = 'none'; |
||
515 | my $dbh = db_connect($request); |
||
516 | |||
517 | return 'error' unless($dbh); |
||
518 | |||
519 | eval { |
||
520 | my $sql = ""; |
||
521 | while(my ($key, $value) = each(%$key_columns)) { |
||
522 | next unless(defined $value); |
||
523 | $sql .= " and " if($sql); |
||
524 | $sql .= "$key = ?"; |
||
525 | } |
||
526 | $sql = "delete from $table where $sql"; |
||
527 | |||
528 | my $sth = $dbh->prepare($sql); |
||
529 | my $count = 0; |
||
530 | while(my ($key, $value) = each(%$key_columns)) { |
||
531 | next unless(defined $value); |
||
532 | $sth->bind_param(++$count, $value); |
||
533 | } |
||
534 | |||
535 | my $res = $sth->execute; |
||
536 | |||
537 | if($res < 1) { |
||
538 | $res_action = 'not found'; |
||
539 | } |
||
540 | else { |
||
541 | $res_action = 'delete'; |
||
542 | } |
||
543 | }; |
||
544 | |||
545 | if(db_close($request, $dbh, $@)) { |
||
546 | return $res_action; |
||
547 | } |
||
548 | else { |
||
549 | return 'error'; |
||
550 | } |
||
551 | } |
||
552 | |||
553 | sub save_to_db |
||
554 | { |
||
555 | my $request = shift @_; |
||
556 | my $table = shift @_; |
||
557 | my $key_columns = shift @_; |
||
558 | my $value_columns = shift @_; |
||
559 | |||
560 | my $error_set = 0; |
||
561 | my $res_action = 'none'; |
||
562 | my $dbh = db_connect($request); |
||
563 | |||
564 | return 'error' unless($dbh); |
||
565 | |||
566 | eval { |
||
567 | my $res = 0; |
||
568 | |||
569 | if($key_columns) { |
||
570 | my $update_sql = ""; |
||
571 | my $where = ""; |
||
572 | while(my ($key, $value) = each(%$value_columns)) { |
||
573 | next unless(defined $value); |
||
574 | $update_sql .= ", " if($update_sql); |
||
575 | $update_sql .= "$key = ?"; |
||
576 | } |
||
577 | while(my ($key, $value) = each(%$key_columns)) { |
||
578 | next unless(defined $value); |
||
579 | $where .= " and " if($where); |
||
580 | $where .= "$key = ?"; |
||
581 | } |
||
582 | $update_sql = "update $table set $update_sql where $where"; |
||
583 | |||
584 | my $update_sth = $dbh->prepare($update_sql); |
||
585 | my $count = 0; |
||
586 | while(my ($key, $value) = each(%$value_columns)) { |
||
587 | next unless(defined $value); |
||
588 | $update_sth->bind_param(++$count, $value); |
||
589 | } |
||
590 | while(my ($key, $value) = each(%$key_columns)) { |
||
591 | next unless(defined $value); |
||
592 | $update_sth->bind_param(++$count, $value); |
||
593 | } |
||
594 | |||
595 | $res = $update_sth->execute; |
||
596 | $res_action = 'update'; |
||
597 | } |
||
598 | |||
599 | if($res < 1) { |
||
600 | my $insert_sql = ""; |
||
601 | my $sql_params = ""; |
||
602 | while(my ($key, $value) = each(%$key_columns)) { |
||
603 | next unless(defined $value); |
||
604 | next if($value_columns->{$key}); |
||
605 | if($insert_sql) { |
||
606 | $insert_sql .= ", "; |
||
607 | $sql_params .= ", "; |
||
608 | } |
||
609 | $insert_sql .= "$key"; |
||
610 | $sql_params .= "?"; |
||
611 | } |
||
612 | while(my ($key, $value) = each(%$value_columns)) { |
||
613 | next unless(defined $value); |
||
614 | if($insert_sql) { |
||
615 | $insert_sql .= ", "; |
||
616 | $sql_params .= ", "; |
||
617 | } |
||
618 | $insert_sql .= "$key"; |
||
619 | $sql_params .= "?"; |
||
620 | } |
||
621 | $insert_sql = "insert into $table ($insert_sql)" |
||
622 | . " values ($sql_params)"; |
||
623 | |||
624 | my $insert_sth = $dbh->prepare($insert_sql); |
||
625 | my $count = 0; |
||
626 | while(my ($key, $value) = each(%$key_columns)) { |
||
627 | next unless(defined $value); |
||
628 | next if($value_columns->{$key}); |
||
629 | $insert_sth->bind_param(++$count, $value); |
||
630 | } |
||
631 | while(my ($key, $value) = each(%$value_columns)) { |
||
632 | next unless(defined $value); |
||
633 | $insert_sth->bind_param(++$count, $value); |
||
634 | } |
||
635 | |||
636 | $res = $insert_sth->execute; |
||
637 | $res_action = 'insert'; |
||
638 | } |
||
639 | }; |
||
640 | |||
641 | if(db_close($request, $dbh, $@)) { |
||
642 | return $res_action; |
||
643 | } |
||
644 | else { |
||
645 | return 'error'; |
||
646 | } |
||
647 | } |
||
648 | |||
649 | sub set_request_code |
||
650 | { |
||
651 | my $request = shift @_; |
||
652 | my $code = shift @_; |
||
653 | my $message = shift @_; |
||
654 | |||
655 | $request->{'code'} = $code; |
||
656 | $request->{'response'} = $message; |
||
657 | |||
658 | my $error = "Error $code '$message' in request [\n$request->{'body'}]"; |
||
659 | if($code >= 500 && $code < 600) { |
||
660 | log_error($error); |
||
661 | } |
||
662 | elsif($code >= 400 && $code < 500) { |
||
663 | log_warning($error); |
||
664 | } |
||
665 | elsif($code >= 200 && $code < 300) { |
||
666 | log_info("$code $message"); |
||
667 | } |
||
668 | else { |
||
669 | log_error("unknown code $code"); |
||
670 | } |
||
671 | } |
||
672 | |||
673 | sub log_debug |
||
674 | { |
||
675 | log_message("DEBUG", shift @_) if ($log_level >= 9); |
||
676 | } |
||
677 | |||
678 | sub log_info |
||
679 | { |
||
680 | log_message("INFO", shift @_) if ($log_level >= 5); |
||
681 | } |
||
682 | |||
683 | sub log_warning |
||
684 | { |
||
685 | log_message("WARN", shift @_) if ($log_level >= 3); |
||
686 | } |
||
687 | |||
688 | sub log_error |
||
689 | { |
||
690 | log_message("ERROR", shift @_) if ($log_level >= 1); |
||
691 | } |
||
692 | |||
693 | sub log_message |
||
694 | { |
||
695 | print shift @_, ":\t", shift @_, "\n"; |
||
696 | } |
||
697 | |||
698 | sub init |
||
699 | { |
||
700 | $handlers{"${user_header}_${create_action}"} = \&handle_user_create; |
||
701 | $handlers{"${user_header}_${modify_action}"} = \&handle_user_modify; |
||
702 | $handlers{"${user_header}_${delete_action}"} = \&handle_user_delete; |
||
703 | $handlers{"${domain_header}_${create_action}"} = \&handle_domain_create; |
||
704 | $handlers{"${domain_header}_${modify_action}"} = \&handle_domain_modify; |
||
705 | $handlers{"${domain_header}_${delete_action}"} = \&handle_domain_delete; |
||
706 | $handlers{"${system_user_header}_${create_action}"} = \&handle_system_user_create; |
||
707 | $handlers{"${system_user_header}_${modify_action}"} = \&handle_system_user_modify; |
||
708 | $handlers{"${system_user_header}_${delete_action}"} = \&handle_system_user_delete; |
||
709 | $handlers{"${mailbox_header}_${create_action}"} = \&handle_mailbox_create; |
||
710 | $handlers{"${mailbox_header}_${modify_action}"} = \&handle_mailbox_modify; |
||
711 | $handlers{"${mailbox_header}_${delete_action}"} = \&handle_mailbox_delete; |
||
712 | $handlers{"${mail_alias_header}_${create_action}"} = \&handle_mail_alias_create; |
||
713 | $handlers{"${mail_alias_header}_${modify_action}"} = \&handle_mail_alias_modify; |
||
714 | $handlers{"${mail_alias_header}_${delete_action}"} = \&handle_mail_alias_delete; |
||
715 | } |
||
716 | |||
717 | sub main |
||
718 | { |
||
719 | #my $sth = $dbh->prepare("SELECT * FROM transport"); |
||
720 | #$sth->execute(); |
||
721 | #while(my $ref = $sth->fetchrow_hashref()) { |
||
722 | # print "id = $ref->{'id'}\n"; |
||
723 | #} |
||
724 | #$sth->finish(); |
||
725 | |||
726 | init(); |
||
727 | connection_loop(); |
||
728 | } |
||
729 | |||
730 | main(); |
||
731 |