root/trunk/engine/ispcp_common_methods.pl

Revision 1412, 46.0 kB (checked in by scitech, 39 minutes ago)

Fixed #1518: Virtual mail problem. Add support for alias subdomain mail (part I)

Line 
1 #!/usr/bin/perl
2
3 # ispCP ω (OMEGA) a Virtual Hosting Control Panel
4 # Copyright (c) 2001-2006 by moleSoftware GmbH
5 # http://www.molesoftware.com
6 # Copyright (c) 2006-2008 by isp Control Panel
7 # http://isp-control.net
8 #
9 #
10 # License:
11 #    This program is free software; you can redistribute it and/or
12 #    modify it under the terms of the MPL Mozilla Public License
13 #    as published by the Free Software Foundation; either version 1.1
14 #    of the License, or (at your option) any later version.
15 #
16 #    This program is distributed in the hope that it will be useful,
17 #    but WITHOUT ANY WARRANTY; without even the implied warranty of
18 #    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
19 #    MPL Mozilla Public License for more details.
20 #
21 #    You may have received a copy of the MPL Mozilla Public License
22 #    along with this program.
23 #
24 #    An on-line copy of the MPL Mozilla Public License can be found
25 #    http://www.mozilla.org/MPL/MPL-1.1.html
26 #
27 #
28 # The ispCP ω Home Page is at:
29 #
30 #    http://isp-control.net
31 #
32
33 BEGIN {
34
35     my @needed = (strict,
36                   warnings,
37                   IO::Socket,
38                   DBI,
39                   DBD::mysql,
40                   MIME::Entity,
41                   MIME::Parser,
42                   Crypt::CBC,
43                   Crypt::Blowfish,
44                   Crypt::PasswdMD5,
45                   MIME::Base64,
46                   Term::ReadPassword,
47                   File::Basename,
48                   File::Path);
49
50     my ($mod, $mod_err, $mod_missing) = ('', '_off_', '');
51
52     for $mod (@needed) {
53
54         if (eval "require $mod") {
55
56             $mod -> import();
57
58         } else {
59
60             print STDERR "\nCRITICAL ERROR: Module [$mod] WAS NOT FOUND !\n" ;
61
62             $mod_err = '_on_';
63
64             if ($mod_missing eq '') {
65
66                 $mod_missing .= $mod;
67
68             } else {
69
70                 $mod_missing .= ", $mod";
71
72             }
73         }
74
75     }
76
77     if ($mod_err eq '_on_') {
78
79         print STDERR "\nModules [$mod_missing] WAS NOT FOUND in your system...\n";
80
81         exit 1;
82
83     } else {
84
85         $| = 1;
86
87     }
88 }
89
90 # Global variables;
91
92 $main::cc_stdout = '/tmp/ispcp-cc.stdout';
93
94 $main::cc_stderr = '/tmp/ispcp-cc.stderr';
95
96 $main::el_sep = "\t#\t";
97
98 @main::el = ();
99
100 %main::domain_id_name = ();
101
102 %main::domain_name_id = ();
103
104 %main::domain_id_ipid = ();
105
106 %main::sub_id_name = ();
107
108 %main::sub_name_id = ();
109
110 %main::sub_id_parentid = ();
111
112 %main::als_id_name = ();
113
114 %main::als_name_id = ();
115
116 %main::als_id_parentid = ();
117
118 %main::ip_id_num = ();
119
120 %main::ip_num_id = ();
121
122 $main::db_host = undef;
123
124 $main::db_user = undef;
125
126 $main::db_pwd = undef;
127
128 $main::db_name = undef;
129
130 @main::db_connect = ();
131
132 $main::db = undef;
133
134 $main::use_crypted_pwd = undef;
135
136 $main::master_name = 'ispcp-rqst-mngr';
137
138 %main::cfg = ();
139
140 %main::cfg_reg = ();
141
142 $main::cfg_re = '^[ \t]*([\_A-Za-z0-9]+) *= *([^\n\r]*)[\n\r]';
143
144 # License request function must not SIGPIPE;
145
146 $SIG{PIPE} = 'IGNORE';
147
148 $SIG{HUP} = 'IGNORE';
149
150 sub push_el {
151
152     my ($el, $sub_name, $msg) = @_;
153
154     push @$el, "$sub_name".$main::el_sep."$msg";
155
156     if (defined($main::engine_debug)) {
157
158         print STDOUT "DEBUG: push_el() sub_name: $sub_name, msg: $msg\n";
159
160     }
161
162 }
163
164 sub pop_el {
165
166     my ($el) = @_;
167
168     my $data = pop @$el;
169
170     if (!defined($data)) {
171
172         if (defined($main::engine_debug)) {
173
174             print STDOUT "DEBUG: pop_el() Empty 'EL' Stack !\n";
175
176         }
177
178         return undef;
179     }
180
181     my ($sub_name, $msg) = split(/$main::el_sep/, $data);
182
183     if (defined($main::engine_debug)) {
184
185         print STDOUT "DEBUG: pop_el() sub_name: $sub_name, msg: $msg\n";
186
187     }
188
189
190     return $data;
191
192 }
193
194
195 sub dump_el {
196
197     my ($el, $fname) = @_;
198
199     my $res;
200
201     if ($fname ne 'stdout' && $fname ne 'stderr') {
202
203         $res = open(FP, ">", $fname);
204
205         if (!defined($res)) {
206
207             return 0;
208
209         }
210
211     }
212
213     my $el_data = undef;
214
215     while (defined($el_data = pop_el(\@main::el))) {
216
217         my ($sub_name, $msg) = split(/$main::el_sep/, $el_data);
218
219         if ($fname eq 'stdout') {
220
221             printf STDOUT "%-30s | %s\n",  $sub_name, $msg;
222
223         } elsif ($fname eq 'stderr') {
224
225             printf STDERR "%-30s | %s\n",  $sub_name, $msg;
226
227         } else {
228
229             printf FP "%-30s | %s\n",  $sub_name, $msg;
230
231         }
232
233     }
234
235     close(FP);
236
237 }
238
239 sub doSQL {
240
241     my ($sql) = @_;
242
243     my $qr = undef;
244
245     push_el(\@main::el, 'doSQL()', 'Starting...');
246
247     if (!defined($sql) || ($sql eq '')) {
248
249         push_el(\@main::el, 'doSQL()', 'ERROR: Undefined SQL query !');
250
251         return (-1, '');
252
253     }
254
255     if (!defined($main::db) || !ref($main::db)) {
256
257         $main::db = DBI->connect(@main::db_connect, {PrintError => 0});
258
259         if ( !defined($main::db) ) {
260
261             push_el(
262                     \@main::el,
263                     'doSQL()',
264                     'ERROR: Unable to connect SQL server !'
265                    );
266
267             return (-1, '');
268
269         } elsif ($main::cfg{'DATABASE_UTF8'} eq 'yes' ) { # DB: use always UTF8
270             $qr = $main::db->do("SET NAMES 'utf8';");
271         }
272     }
273
274     if ($sql =~ /select/i) {
275
276         $qr = $main::db->selectall_arrayref($sql);
277
278     } elsif ($sql =~ /show/i) {
279
280         $qr = $main::db->selectall_arrayref($sql);
281
282     } else {
283
284         $qr = $main::db->do($sql);
285
286     }
287
288     if (defined($qr)) {
289
290         push_el(\@main::el, 'doSQL()', 'Ending...');
291
292         return (0, $qr);
293
294     } else {
295
296         push_el(\@main::el, 'doSQL()', 'ERROR: Incorrect SQL Query -> '.$main::db -> errstr);
297
298         return (-1, '');
299
300     }
301
302 }
303
304 sub doHashSQL {
305
306     my ($sql) = @_;
307
308     my $qr = undef;
309
310     push_el(\@main::el, 'doHashSQL()', 'Starting...');
311
312     if (!defined($sql) || ($sql eq '')) {
313
314         push_el(\@main::el, 'doHashSQL()', 'ERROR: Undefined SQL query !');
315
316         return (-1, '');
317
318     }
319
320     if (!defined($main::db) || !ref($main::db)) {
321
322         $main::db = DBI -> connect(@main::db_connect, {PrintError => 0});
323
324         if ( !defined($main::db) ) {
325
326             push_el(
327                     \@main::el,
328                     'doHashSQL()',
329                     'ERROR: Unable to connect SQL server !'
330                    );
331
332             return (-1, '');
333
334         } elsif ($main::cfg{'DATABASE_UTF8'} eq 'yes' ) { # DB: use always UTF8
335             $qr = $main::db -> do("SET NAMES 'utf8';");
336         }
337     }
338
339     if ($sql =~ /select/i) {
340
341         $qr = $main::db -> selectall_hashref($sql);
342
343     } elsif ($sql =~ /show/i) {
344
345         $qr = $main::db -> selectall_hashref($sql);
346
347     } else {
348
349         $qr = $main::db -> do($sql);
350
351     }
352
353     if (defined($qr)) {
354
355         push_el(\@main::el, 'doHashSQL()', 'Ending...');
356
357         return (0, $qr);
358
359     } else {
360
361         push_el(\@main::el, 'doHashSQL()', 'ERROR: Incorrect SQL Query -> '.$main::db -> errstr);
362
363         return (-1, '');
364
365     }
366
367 }
368
369 ##
370 # setfmode
371 # sets user, group and rights of a file.
372 # If $fgroup set to 'null' this function will get the GID from /etc/passwd.
373 #
374 # @author               VHCS/ispCP Team
375 # @author               Benedikt Heintel
376 # @copyright    2006-2008 by ispCP | http://isp-control.net
377 # @version              1.1
378 #
379 # @access       public
380 # @param        String  $fname  File or Folder Name
381 # @param        Mixed   $fuser  Linux User or UserID
382 # @param        Mixed   $fgroup Linux Group, GroupID or 'null'
383 # @param        int             $fperms Linux Permissions
384 # @return       int                             success (0) or error (-1)
385 sub setfmode {
386
387     my ($fname, $fuser, $fgroup, $fperms) = @_;
388
389     push_el(\@main::el, 'setfmode()', 'Starting...');
390
391     if (!defined($fname) || !defined($fuser) || !defined($fperms) ||
392                 $fname eq '' || $fname eq '' || $fgroup eq '' || $fperms eq '') {
393
394         push_el(\@main::el, 'setfmode()',
395                 "ERROR: Undefined input data, fname: |$fname|, fuid: |$fuser|, fgid: |$fgroup|, fperms: |$fperms| !");
396         return -1;
397     }
398
399     if (! -e $fname) {
400         push_el(\@main::el, 'setfmode()', "ERROR: File '$fname' does not exist !");
401         return -1;
402     }
403
404     my @udata = ();
405     my @gdata = ();
406
407     my ($uid, $gid) = (undef, undef);
408
409         # get UID of user
410         if ($fuser =~ /^\d+$/) {
411                 $uid = $fuser;
412         }
413         elsif ($fuser ne '-1') {
414             @udata = getpwnam($fuser);
415
416             if (scalar(@udata) == 0) {
417                push_el(\@main::el, 'setfmode()', "ERROR: Unknown user '$fuser' !");
418                return -1;
419             }
420             $uid = $udata[2];
421         }
422
423         # get GID of user
424         if ($fgroup =~ /^\d+$/) {
425                 $gid = $fgroup;
426         }
427         elsif ($fgroup eq 'null') {
428                 $gid = $udata[3];
429         }
430         elsif ($fgroup ne '-1') {
431                 @gdata = getgrnam($fgroup);
432
433             if (scalar(@udata) == 0) {
434                push_el(\@main::el, 'setfmode()', "ERROR: Unknown user '$fgroup' !");
435                return -1;
436             }
437             $gid = $gdata[2];
438         }
439
440     my $res = chmod($fperms, $fname);
441
442     if ($res != 1) {
443         push_el(\@main::el, 'setfmode()', "ERROR: cannot change permissions of file '$fname' !");
444         return -1;
445     }
446
447     $res = chown($uid, $gid, $fname);
448
449     if ($res != 1) {
450         push_el(\@main::el, 'setfmode()', "ERROR: cannot change user/group of file '$fname' !");
451         return -1;
452
453     }
454
455     push_el(\@main::el, 'setfmode()', 'Ending...');
456     return 0;
457 }
458
459
460 sub get_file {
461
462     my ($fname) = @_;
463
464     push_el(\@main::el, 'get_file()', 'Starting...');
465
466     if (!defined($fname) || ($fname eq '')) {
467         push_el(\@main::el, 'get_file()', "ERROR: Undefined input data, fname: |$fname| !" );
468         return 1;
469     }
470
471     if (! -e $fname) {
472         push_el(\@main::el, 'get_file()', "ERROR: File '$fname' does not exist !");
473         return 1;
474     }
475
476     my $res = open(F, '<', $fname);
477
478     if (!defined($res)) {
479         push_el(\@main::el, 'get_file()', "ERROR: Can't open '$fname' for reading: $!");
480         return 1;
481     }
482
483     my @fdata = <F>;
484
485     close(F);
486
487     my $line = join('', @fdata);
488
489     push_el(\@main::el, 'get_file()', 'Ending...');
490
491     return (0, $line);
492
493 }
494
495 ##
496 # store_file
497 # Changes the content of a file and sets user, group and rights of that file.
498 # If $fgid set to 'null' this function will get the GID from /etc/passwd.
499 #
500 # @author               VHCS/ispCP Team
501 # @copyright    2006-2008 by ispCP | http://isp-control.net
502 # @version              1.0
503 #
504 # @access       public
505 # @param        String  $fname  File Name
506 # @param        String  $fdata  Data to write to file
507 # @param        Mixed   $fuser  Linux User or UserID
508 # @param        Mixed   $fgroup Linux Group, GroupID or null
509 # @param        int             $fperms Linux Permissions
510 # @return       int                             success (0) or error (-1)
511 sub store_file {
512
513     my ($fname, $fdata, $fuid, $fgid, $fperms) = @_;
514
515     push_el(\@main::el, 'store_file()', 'Starting...');
516
517     if (!defined($fname) || $fname eq '' || $fuid eq '' || $fgid eq '' || $fperms eq '') {
518         push_el(\@main::el, 'store_file()',
519                 "ERROR: Undefined input data, fname: |$fname|, fdata, fuid: '$fuid', fgid: '$fgid', fperms: '$fperms'");
520         return -1;
521     }
522
523     my $res = open(F, '>', $fname);
524
525     if (!defined($res)) {
526         push_el(\@main::el, 'store_file()', "ERROR: Can't open file |$fname| for writing: $!");
527         return -1;
528     }
529
530     print F $fdata;
531     close(F);
532
533         my ($rs, $rdata) = setfmode($fname, $fuid, $fgid, $fperms);
534     return -1 if ($rs != 0);
535
536     push_el(\@main::el, 'store_file()', 'Ending...');
537     return 0;
538 }
539
540 ##
541 # save_file
542 # Changes the content of a file.
543 #
544 # @author               VHCS/ispCP Team
545 # @copyright    2006-2008 by ispCP | http://isp-control.net
546 # @version              1.0
547 #
548 # @access       public
549 # @param        String  $fname  File Name
550 # @param        String  $fdata  Data to write to file
551 # @return       int                             success (0) or error (-1)
552 sub save_file {
553
554     my ($fname, $fdata) = @_;
555
556     push_el(\@main::el, 'save_file()', 'Starting...');
557
558     if (!defined($fname) || $fname eq '' ) {
559         push_el(\@main::el, 'save_file()', "ERROR: Undefined input data, fname: |$fname|");
560         return -1;
561     }
562
563     my $res = open(F, '>', $fname);
564
565     if (!defined($res)) {
566         push_el(\@main::el, 'save_file()', "ERROR: Can't open file |$fname| for writing: $!");
567         return -1;
568
569     }
570
571     print F $fdata;
572     close(F);
573
574     push_el(\@main::el, 'save_file()', 'Ending...');
575     return 0;
576 }
577
578 sub del_file {
579
580     my ($fname) = @_;
581
582     push_el(\@main::el, 'del_file()', 'Starting...');
583
584     if (!defined($fname) || ($fname eq '')) {
585
586         push_el(
587                 \@main::el,
588                 'del_file()',
589                 "ERROR: Undefined input data, fname: |$fname| !"
590                );
591
592         return -1;
593
594     }
595
596     if (! -e $fname) {
597
598         push_el(
599                 \@main::el,
600                 'del_file()',
601                 "ERROR: File '$fname' does not exist !"
602                );
603
604         return -1;
605
606     }
607
608     my $res = unlink ($fname);
609
610     if ($res != 1) {
611
612         push_el(
613                 \@main::el,
614                 'del_file()',
615                 "ERROR: Can't unlink '$fname' !"
616                );
617
618         return -1;
619
620     }
621
622     push_el(\@main::el, 'del_file()', 'Ending...');
623
624     return 0;
625
626 }
627
628 sub set_zone {
629     my ($fdata, $data, $zone, $comment) = @_;
630
631     my @fdata = split("\n", $fdata);
632
633     my $bz = '';
634     my $az = '';
635     my $zs = 0;
636     my $ze = 0;
637     my $ll;
638     my $curline;
639
640     while(length($fdata) > 0) {
641         $ll = index($fdata, "\n");
642         if( $ll < 0 ) {
643             $ll = length( $fdata );
644         } else {
645             $ll++;
646         }
647         $curline = substr( $fdata, 0, $ll );
648         $fdata = substr( $fdata, $ll );
649
650         if( $zs == 0 ) {
651             if( index($curline, $comment."## START ISPCP ".$zone." ###") == 0 ) {
652                 $zs = 1;
653             } else {
654                 $bz .= $curline;
655             }
656         } elsif( $ze == 0 ) {
657             if( index($curline, $comment."## END ISPCP ".$zone." ###") == 0) {
658                 $ze = 1;
659             }
660         } elsif( $ze == 1 ) {
661                 $az .= $curline;
662         }
663     }
664
665     return
666         $bz.($zs == 1 ? "" : "\n").
667         $comment."## START ISPCP ".$zone." ###\n".
668         $data."\n".
669         $comment."## END ISPCP ".$zone." ###\n".
670         $az;
671 }
672
673 sub get_zone {
674     my ($fdata, $zone, $comment) = @_;
675
676     my @fdata = split("\n", $fdata);
677
678     my $zonecontent = '';
679     my $zs = 0;
680     my $ze = 0;
681     my $ll;
682     my $curline;
683
684     while(length($fdata) > 0) {
685         $ll = index($fdata, "\n");
686         if( $ll < 0 ) {
687             $ll = length( $fdata );
688         } else {
689             $ll++;
690         }
691         $curline = substr( $fdata, 0, $ll );
692         $fdata = substr( $fdata, $ll );
693
694         if( $zs == 0 ) {
695             if( index($curline, $comment."## START ISPCP ".$zone." ###") == 0 ) {
696                 $zs = 1;
697             }
698         } elsif( $ze == 0 ) {
699             if( index($curline, $comment."## END ISPCP ".$zone." ###") == 0) {
700                 $ze = 1;
701             } else {
702                 $zonecontent .= $curline;
703             }
704         }
705     }
706
707     return $zonecontent;
708 }
709
710 sub del_zone {
711     my ($fdata, $zone, $comment) = @_;
712
713     my @fdata = split("\n", $fdata);
714
715     my $bz = '';
716     my $az = '';
717     my $zs = 0;
718     my $ze = 0;
719     my $ll;
720     my $curline;
721
722     while(length($fdata) > 0) {
723         $ll = index($fdata, "\n");
724         if( $ll < 0 ) {
725             $ll = length( $fdata );
726         } else {
727             $ll++;
728         }
729         $curline = substr( $fdata, 0, $ll );
730         $fdata = substr( $fdata, $ll );
731
732         if( $zs == 0 ) {
733             if( index($curline, $comment."## START ISPCP ".$zone." ###") == 0 ) {
734                 $zs = 1;
735             } else {
736                 $bz .= $curline;
737             }
738         } elsif( $ze == 0 ) {
739             if( index($curline, $comment."## END ISPCP ".$zone." ###") == 0) {
740                 $ze = 1;
741             }
742         } elsif( $ze == 1 ) {
743                 $az .= $curline;
744         }
745     }
746
747     return $bz.$az;
748 }
749
750 sub sys_command {
751
752     my ($cmd) = @_;
753
754     push_el(\@main::el, 'sys_command()', 'Starting...');
755
756     my $result = system($cmd);
757
758     my $exit_value  = $? >> 8;
759
760     my $signal_num  = $? & 127;
761
762     my $dumped_core = $? & 128;
763
764     if ($exit_value == 0) {
765
766         push_el(\@main::el, "sys_command('$cmd')", 'Ending...');
767
768         return 0;
769
770     } else {
771
772         push_el(\@main::el, 'sys_command()', "ERROR: External command '$cmd' returned '$exit_value' status !");
773
774         return -1;
775
776     }
777
778 }
779
780 sub sys_command_rs {
781
782     my ($cmd) = @_;
783
784     push_el(\@main::el, 'sys_command_rs()', 'Starting...');
785
786     my $result = system($cmd);
787
788     my $exit_value  = $? >> 8;
789
790     my $signal_num  = $? & 127;
791
792     my $dumped_core = $? & 128;
793
794     push_el(\@main::el, 'sys_command_rs()', 'Ending...');
795
796     if ($exit_value == 0) {
797
798         return 0;
799
800     } else {
801
802         return $exit_value;
803
804     }
805
806 }
807
808 sub make_dir {
809
810     my ($dname, $duid, $dgid, $dperms) = @_;
811
812     my ($rs, $rdata) = ('', '');
813
814     push_el(\@main::el, 'make_dir()', 'Starting...');
815
816     if (
817         !defined($dname) || !defined($duid) ||
818         !defined($dgid) || !defined($dperms) ||
819         $dname eq '' || $duid eq '' ||
820         $dgid eq '' || $dperms eq ''
821        )
822     {
823
824         push_el(\@main::el, 'make_dir()', "ERROR: Undefined input data, dname: |$dname|, duid: |$duid|, dgid: |$dgid|, dperms: |$dperms| !");
825
826         return -1;
827
828     }
829
830     if ( -e $dname && -f $dname ) {
831
832         push_el(\@main::el,'make_dir()', "'$dname' exists as file ! removing file first...");
833
834         return -1 if (del_file($dname) != 0);
835
836     }
837
838     if (!(-e $dname && -d $dname)) {
839
840         push_el(\@main::el, 'make_dir()', "'$dname' doesn't exists as directory! creating...");
841
842         $rs =  mkpath($dname);
843
844         if (!$rs) {
845
846             push_el(\@main::el, 'make_dir()', "ERROR: mkdir() returned '$rs' status !");
847
848             return -1;
849
850         }
851
852     } else {
853
854         push_el(\@main::el, 'make_dir()', "'$dname' exists ! Setting its permissions...");
855
856     }
857
858     return -1 if (setfmode($dname, $duid, $dgid, $dperms) != 0);
859
860     push_el(\@main::el, 'make_dir()', 'Ending...');
861
862     return 0;
863 }
864
865 sub del_dir {
866
867     my ($dname) = @_;
868
869     push_el(\@main::el, 'make_dir()', 'Starting...');
870
871     if (!defined($dname) || ($dname eq '')) {
872
873         push_el(\@main::el, 'make_dir()', "ERROR: Undefined input data, dname: |$dname| !");
874
875         return -1;
876
877     }
878
879     push_el(\@main::el, 'make_dir()', "Trying to remove '$dname'...");
880
881     return -1 if (sys_command("rm -rf $dname") != 0);
882
883     push_el(\@main::el, 'make_dir()', 'Ending...');
884
885     return 0;
886
887 }
888
889 sub gen_rand_num {
890
891     my ($len) = @_;
892
893     push_el(\@main::el, 'gen_rand_num()', 'Starting...');
894
895     if (!defined($len) || ($len eq '')) {
896
897         push_el(\@main::el, 'gen_rand_num()', "ERROR: Undefined input data, len: |$len| !");
898
899         return (-1, '');
900
901     }
902
903     if (!(0 < $len && $len < 11)) {
904
905         push_el(\@main::el, 'gen_rand_num()', "ERROR: Input data length '$len' out of limits [1, 10] !");
906
907         return (-1, '');
908
909     }
910
911     my @rand_data = ('A'..'Z', 'a'..'z', '0'..'9', '.', '/');
912
913     my ($i, $rdata) = ('', '');
914
915     for ($i = 0; $i < $len; $i++) {
916
917         $rdata .= $rand_data[ rand() * ($#rand_data + 1) ];
918
919     }
920
921     push_el(\@main::el, 'gen_rand_num()', 'Ending...');
922
923     return (0, $rdata);
924
925 }
926
927 sub gen_sys_rand_num {
928
929     my ($len) = @_;
930
931     push_el(\@main::el, 'gen_sys_rand_num()', 'Starting...');
932
933     if (!defined($len) || ($len eq '')) {
934
935         push_el(\@main::el, 'gen_sys_rand_num()', "ERROR: Undefined input data, len: |$len| !");
936
937         return (-1, '');
938
939     }
940
941     if (0 >= $len ) {
942
943         push_el(\@main::el, 'gen_sys_rand_num()', "ERROR: Input data length '$len' is zero or negative !");
944
945         return (-1, '');
946
947     }
948
949     my $pool_size = 0;
950     my $read_avail = 0;
951
952     if ( -e '/proc/sys/kernel/random/entropy_avail') {
953
954         $read_avail = 1;
955
956         $pool_size = int(get_file('/proc/sys/kernel/random/entropy_avail'));
957
958         if ( $pool_size <= ($len + 10)) {
959             push_el(\@main::el, 'gen_sys_rand_num()', "WARNING: entropy pool is $pool_size, but we require more or less $len");
960         }
961     }
962
963     if ( -e '/dev/urandom') {
964         push_el(\@main::el, 'gen_sys_rand_num()', "NOTICE: seeding the entropy pool (possible current size: $pool_size)");
965
966         my $seed = $len;
967         while ($seed >= 0 ||
968               ($read_avail && int(get_file('/proc/sys/kernel/random/entropy_avail')) <= ($len + 10))) {
969
970             my ($n, $c, $l) = (100, undef, 0);
971
972             do {
973                 $l = int(rand() * 100);
974                 next if ($l < 0 || $l > 255);
975                 $c .= chr($l);
976             } while($n--);
977
978             save_file('/dev/urandom', $c . (rand() * rand() * rand() * rand()));
979             save_file('/dev/urandom', time ^ ($$ + ($$ << 15)) << (1 ^ rand -$$ ));
980             $seed--;
981         }
982     }
983
984     if ($read_avail) {
985
986         $pool_size = int(get_file('/proc/sys/kernel/random/entropy_avail'));
987
988         push_el(\@main::el, 'gen_sys_rand_num()', "NOTICE: new entropy pool size is $pool_size");
989     }
990
991     my $rs = open(F, '<', '/dev/random');
992
993     if (!defined($rs)) {
994
995         $rs = open(F, '<', '/dev/urandom');
996
997         if (!defined($rs)) {
998
999             push_el(\@main::el, 'gen_sys_rand_num()', "ERROR: Couldn't open the pseudo-random characters generator: $!");
1000
1001             return (-1, '');
1002         }
1003
1004     }
1005
1006     my ($i, $rdata, $rc, $rci) = (0, undef, undef, undef);
1007
1008     while ($i <= $len) {
1009
1010         read(F, $rc, 1);
1011
1012         $rci = ord($rc);
1013
1014         # Excludes all chars below Space (incl.) and bove }, the escape char (\) and the '
1015         next if ($rci <= 32 || $rci >= 126 || $rci == 92 || $rci == 39);
1016
1017         $rdata .= $rc;
1018         $rc = undef;
1019         $i++;
1020
1021     }
1022
1023     close(F);
1024
1025     push_el(\@main::el, 'gen_sys_rand_num()', 'Ending...');
1026
1027     return (0, $rdata);
1028
1029 }
1030
1031 sub crypt_md5_data {
1032
1033     my ($data) = @_;
1034
1035     push_el(\@main::el, 'crypt_md5_data()', 'Starting...');
1036
1037     if (!defined($data) || $data eq '') {
1038
1039         push_el(\@main::el, 'crypt_md5_data()', "ERROR: Undefined input data, data: |$data| !");
1040
1041         return (-1, '');
1042
1043     }
1044
1045     my ($rs, $rdata) = gen_rand_num(8);
1046
1047     return (-1, '') if ($rs != 0);
1048
1049     $rdata = unix_md5_crypt($data, $rdata);
1050
1051     push_el(\@main::el, 'crypt_md5_data()', 'Ending...');
1052
1053     return (0, $rdata);
1054
1055 }
1056
1057 sub crypt_data {
1058
1059     my ($data) = @_;
1060
1061     push_el(\@main::el, 'crypt_data()', 'Starting...');
1062
1063     if (!defined($data) || $data eq '') {
1064
1065         push_el(\@main::el, 'crypt_data()', "ERROR: Undefined input data, data: |$data| !");
1066
1067         return (-1, '');
1068
1069     }
1070
1071     my ($rs, $rdata) = gen_rand_num(2);
1072
1073     return (-1, '') if ($rs != 0);
1074
1075     $rdata = crypt($data, $rdata);
1076
1077     push_el(\@main::el, 'crypt_data()', 'Ending...');
1078
1079     return (0, $rdata);
1080
1081 }
1082
1083 sub get_tag {
1084
1085     my ($bt, $et, $src) = @_;
1086
1087     push_el(\@main::el, 'get_tag()', "Starting...");
1088
1089     if (
1090         !defined($bt) || !defined($et) ||
1091         !defined($src) || $bt eq '' ||
1092         $et eq '' || $src eq ''
1093        )
1094     {
1095
1096         push_el(\@main::el, 'get_tag()', "ERROR: Undefined intput data, bt: |$bt|, et: |$et|, src !");
1097
1098         return (-1, '');
1099
1100     }
1101
1102     my ($bt_len, $et_len, $src_len) = (
1103                                        length($bt),
1104                                        length($et),
1105                                        length($src)
1106                                       );
1107
1108     #
1109     #return ('_e03_', $main::strerr{'_e03_'})
1110     #
1111     #if ($bt_len > $src_len || $et_len > $src_len);
1112     #
1113
1114     if ($bt eq $et) {
1115
1116
1117         # Let's search for ...$tag... ;
1118
1119         # $bt == $et == $tag ;
1120
1121
1122         my $tag = $bt;
1123
1124         my $tag_pos = index($src, $tag);
1125
1126         if ($tag_pos < 0) {
1127
1128             push_el(\@main::el, 'get_tag()', "ERROR: '$bt' eq '$et', missing '$bt' in src !");
1129
1130             return (-4, '');
1131
1132         } else {
1133
1134             push_el(\@main::el, 'get_tag()', 'Ending...');
1135
1136             return (0, $tag);
1137
1138         }
1139
1140     } else {
1141
1142         if ($bt_len + $et_len > $src_len) {
1143
1144             push_el(\@main::el, 'get_tag()', "ERROR: len($bt) + len($et) > len(src) !");
1145
1146             return (-1, '');
1147
1148         }
1149
1150
1151         # Let's search for ...$bt...$et... ;
1152
1153
1154         my ($bt_pos, $et_pos) = (index($src, $bt), index($src, $et));
1155
1156         if ($bt_pos < 0 || $et_pos < 0) {
1157
1158             push_el(\@main::el, 'get_tag()', "ERROR: '$bt' ne '$et', '$bt' or '$et' missing in src !");
1159
1160             return (-5, '');
1161
1162         }
1163
1164         if ($et_pos < $bt_pos + $bt_len) {
1165
1166             push_el(\@main::el, 'get_tag()', "ERROR: '$bt' ne '$et', '$et' overlaps '$bt' in src !");
1167
1168             return (-1, '');
1169
1170         }
1171
1172         push_el(\@main::el, 'get_tag()', 'Ending...');
1173
1174         my $tag_len = $et_pos + $et_len - $bt_pos;
1175
1176         return (0, substr($src, $bt_pos, $tag_len));
1177
1178     }
1179
1180 }
1181
1182 sub repl_tag {
1183
1184     my ($bt, $et, $src, $rwith, $function) = @_;
1185
1186     if (!defined($function)) {
1187         $function = "not defined function"
1188     }
1189
1190     push_el(\@main::el, 'repl_tag()', "Starting...");
1191
1192     if (!defined($rwith)) {
1193
1194         push_el(\@main::el, 'repl_tag()', "ERROR: Undefined template replacement data in ".$function."!");
1195
1196         return (-1, '');
1197
1198     }
1199
1200     my ($rs, $rdata) = get_tag($bt, $et, $src);
1201
1202     return $rs if ($rs != 0);
1203
1204     my $tag = $rdata;
1205
1206     my ($tag_pos, $tag_len) = (index($src, $tag), length($tag));
1207
1208     if ($rwith eq '') {
1209
1210         substr($src, $tag_pos, $tag_len, '');
1211
1212     } else {
1213
1214         substr($src, $tag_pos, $tag_len, $rwith);
1215
1216     }
1217
1218     push_el(\@main::el, 'repl_tag()', "Ending...");
1219
1220     return (0, $src);
1221 }
1222
1223 sub add_tag {
1224
1225     my ($bt, $et, $src, $adata) = @_;
1226
1227     push_el(\@main::el, 'add_tag()', "Starting...");
1228
1229     if (!defined($adata) || $adata eq '') {
1230
1231         push_el(\@main::el, 'add_tag()', "ERROR: Undefined input data, adata: |$adata| !");
1232
1233         return (-1, '');
1234     }
1235
1236     my ($rs, $rdata) = get_tag($bt, $et, $src);
1237
1238     return ($rs, '') if ($rs != 0);
1239
1240     my $rwith = '';
1241
1242     if ($bt eq $et) {
1243
1244         $rwith = "$adata$bt";
1245
1246     } else {
1247
1248         $rwith = "$adata$bt$et";
1249
1250     }
1251
1252     ($rs, $rdata) = repl_tag($bt, $et, $src, $rwith, "add_tag: ($adata)");
1253
1254     return (-1, '') if ($rs != 0);
1255
1256     push_el(\@main::el, 'add_tag()', "Ending...");
1257
1258     return (0, $rdata);
1259 }
1260
1261 sub del_tag {
1262
1263     my ($bt, $et, $src) = @_;
1264
1265     push_el(\@main::el, 'del_tag()', "Starting...");
1266
1267     my ($rs, $rdata) = get_tag($bt, $et, $src);
1268
1269     return ($rs, '') if ($rs != 0);
1270
1271     ($rs, $rdata) = repl_tag($bt, $et, $src, '', "del_tag");
1272
1273     return (-1, '') if ($rs != 0);
1274
1275     push_el(\@main::el, 'del_tag()', "Ending...");
1276
1277     return (0, $rdata);
1278
1279 }
1280
1281 sub get_var {
1282
1283     my ($var, $src) = @_;
1284
1285     push_el(\@main::el, 'get_var()', "Starting...");
1286
1287     my ($rs, $rdata) = get_tag($var, $var, $src);
1288
1289     return ($rs, '') if ($rs != 0);
1290
1291     push_el(\@main::el, 'get_var()', "Ending...");
1292
1293     return (0, $rdata);
1294
1295 }
1296
1297 sub repl_var {
1298
1299     my ($var, $src, $rwith) = @_;
1300
1301     my ($rs, $rdata, $result) = (0, $src, '');
1302
1303     push_el(\@main::el, 'repl_var()', "Starting...");
1304
1305     while ($rs == 0) {
1306
1307         $result = $rdata;
1308
1309         ($rs, $rdata) = repl_tag($var, $var, $rdata, $rwith, "repl_var: $var");
1310
1311         return -1 if ($rs != 0 && $rs != -4);
1312
1313     }
1314
1315     push_el(\@main::el, 'repl_var()', "Ending...");
1316
1317     return (0, $result);
1318 }
1319
1320 sub add_var {
1321
1322     my ($var, $src, $adata) = @_;
1323
1324     push_el(\@main::el, 'add_var()', "Starting...");
1325