[Kroupware] /openpkg...
Lutz Badenheuer
kroupware@mail.kde.org
Thu, 28 Nov 2002 21:57:41 +0100
Hi,
Am Mittwoch, 27. November 2002 16:04 schrieb Tassilo Erlewein:
> Am Mittwoch, 27. November 2002 11:49 schrieb Lutz Badenheuer:
> > I've had a short look at kolab.ldif and discovered that there are
> > several "config-dir:"-Attributes which contain /openpkg pathes.
> > Shouldn't we use /kolab?
>
> Yes, you're right. That setting needs to be chosen according to
> your openpkg prefix.
>
> BTW we have already fixed the installation procedure for the beta,
> now the ldap entries are generated during rpm install.
>
> the beta looks good but we're fighting with some nasty perl habits.
> It seems the openpkg perl behaves differently from "regular"
> packages.
>
> Could anybody provide me code snippets which successfully use
> IO::Select to block on a tcp socket ?
Maybe I didn't get you right, but you want to *block*? If my
understanding of the select(2) system call and its OO-Perl wrapper
IO::Select is correct, then you would use this to _avoid_ blocking
I/O.
If you specify a timeout to the can_read() method, the program will
stop at this point for the duration of that timeout. If you do not
specify a timeout to can_read(), then the program will wait forever.
A simple TCP server listening to two ports could look like this:
--snip-----
#!/usr/bin/perl -w
use strict;
use IO::Select;
use IO::Socket::INET;
my $IO_Handle_0 = IO::Socket::INET->new( Listen => 1,
LocalAddr => '127.0.0.1',
LocalPort => '9090',
Proto => 'tcp',
Type => SOCK_STREAM )
or die 'couldn\'t create socket';
my $IO_Handle_1 = IO::Socket::INET->new( Listen => 1,
LocalAddr => 'localhost',
LocalPort => '9091',
Proto => 'tcp',
Type => SOCK_STREAM )
or die 'couldn\'t create socket';
my $Selection = IO::Select->new();
$Selection->add($IO_Handle_0);
$Selection->add($IO_Handle_1);
my $line = '';
while( my @can_read_from = $Selection->can_read(50) ) {
foreach my $handle (@can_read_from) {
my $client = $handle->accept;
$line = <$client>;
chomp $line;
print $client "Thanks for \"$line\"\n";
print "client sent: \"" . $line . "\"\n\n";
close($client);
}
}
--snap-----
In this very simple example, the program will terminate after 50
seconds if no connect takes place during this time, or 50 seconds
after the last connect has been made (look at the timeout param to
can_read()). If can_read() would have been called without parameter,
the program would wait forever for connects.
> Any of you used Convert::ASN1 ?
I did not understand why you want to use Convert::ASN1. As far as
I've read and understood your code at this time, you simply use it to
connect to the LDAP server and access its data. There are Perl
modules like Net::LDAP, why not use these or own objects inheriting
from these?
> another thing is non-blocking IO on a fifo ...
This should be done with IO::Socket::UNIX in a way similar to the one
described above.
> (code examples would be nice, the O'Reilly stuff doesn't seem to
> work for me)
>
> I have attached the two supposedly buggy perl programs.
> The beta very much depends on that stuff to get running and I would
> appreciate every help I could get.
Well, I've had a very close look at the code, but at the moment I've
got no machine I could test this on: my good 18GB 10kRPM U2W-SCSI
disk produces I/O- and SCSI-errors and, from time to time, makes some
horrible sounds. Unfortunately, this is exactly the disk with all the
kolab stuff on it...
But from my short look, there are some things I'd like to mention:
first of all, mixing function definitions with the main program flow
makes it a little.. hard to read the code. I would prefer to put all
that configuration and initialization stuff into some simple, easy to
maintain and extensible objects. This would not only make the code
much cleaner, simpler to read and maintain, but also provide an API
to our kolab server which can later be easily used to extend the
functionality of the kolab server.
Second, I do not understand why you do not fork() when a connet has
taken place. Thus, every client would be handled by an own proces, so
you don't have to worry with IO::Select.
Third, I do not understand who had the idea to write the config files
line by line with print() statements. We should use Text::Template
instead of this <censored> idea. The e-Smith guys work with this
technique, and as for my tests I did some months ago, it all works
perfectly great.
This provides us with big advantages: if there is one configuration
option a user needs, but which is not covered by the web frontend,
the user can simply add this option to the template without touching
the code of any of our perl scripts. Additionally, this approach is
much easier to write, debug and maintain than the current
implementation. So we could put the configuration of each subsystem
(apache, Courier, ProFTP, Postfix, OpenLDAP etc.) into an own object
which is a child of, lets say, KolabConfig.
I've added an oo-style pseudocode idea how to improve the scripts.
Kind regards,
Lutz
PS: pseudocode
--snip-----
#!/usr/bin/perl -w
use strict;
use Kolab::Config;
my $Config = new Kolab::Config($cfgfile);
exit $Config->writeFiles();
--snap-----
--snip-----
package Kolab::Config;
use strict;
sub new {
my $proto = shift;
my $class = ref($proto) || $proto;
my $self = {};
open(CFG, "</kolab/etc/kolab/kolab.conf")
or die "Couldn't open /kolab/etc/kolab/kolab.conf: $!";
my $line = '';
while( $line = <CFG> ) {
chomp $line;
$line =~ s/#.*$//g;
$line =~ m/^(.*) : (.*)$/;
$self->{$1} = $2;
}
if( ( !defined($self->{base_dn}) )
|| ( !defined($self->{bind_dn}) )
|| ( !defined($self->{bind_pw}) )
|| ( !defined($self->{bind_dn}) )
|| ( !defined($self->{ldap_uri}) ) {
die "syntax error in /kolab/etc/kolab/kolab.conf";
}
# here a little inheritance to push PostfixConfig, ApacheConfig
# into several modules and references to inctances into an array
bless ($self, $class);
return $self;
}
1;
--snap-----
Just some ideas...
---LB
--
Lutz Badenheuer | IT--Consulting, Development, Networksolutions
luke@the-web-ac.com | C/C++, OO-Perl, sh | Linux, SCO UNIX, Solaris