Re: Citrix plugin

Jens Kruse <[email protected]>
Newsgroups gmane.network.netsaint.user
Message-ID <[email protected]>
Hi Tom,

No it didn't work so far. Either single nor double quotes helped, even 
back slashes in different combination did not help.
I also tried back slashing and quotes for the space - the check still 
stops after APPLICATION.
Just now I tried commas instead of quotes, that also didnt work.

I'm not good in perl, but AFAICS the solution seems to be found in line 105:

my @crit_pub_apps = $crit_pub_apps ? split(/,/, $crit_pub_apps) : () ;

What about checking, that space(s)
- before a comma
- within commas and
- behind commas
within @crit_pub_apps are ignored?

Regards, Jens


Tom DE BLENDE wrote:
> Dear Jens,
> 
> Did this solve your issue (either using single or double quotes in
> your service definition)?
> 
> Please advise,
> Tom
> 
> "Bishop, Dean" wrote:
> 
>>you need to guard your arument (APPLICATION ONE) with some form of
>>quotes...probably doubles will do the trick
>>
>>-----Original Message-----
>>From: Jens Kruse [mailto:[email protected]]
>>Sent: Monday, October 07, 2002 12:03 PM
>>To: Tom DE BLENDE
>>Cc: [email protected]
>>Subject: Re: [netsaint] Citrix plugin
>>
>>Hi Tom,
>>
>>thanks for this nice plug-in!
>>
>>One question so far:
>>
>>- Calling './check_cit -C SERVER -P 'APPLICATION ONE' works
>>
>>- When I implement it in our netsaint environment, I receive the
>>following error code:
>>Failed. "'APPLICATION" not found in list of published applications
>>"APPLICATION ONE,APPLICATION TWO,APPLICATION THREE" from master browser
>>"10.10.10.99".
>>
>>The command.cfg-statement looks like this:
>>command[check_cit]=/usr/lib/netsaint/plugins/check_cit -C $HOSTADDRESS$
>>-P '$ARG1$'
>>service[SERVER]=Published Application APPLICATION
>>ONE;0;24x7;3;5;1;nt-admins;360;24x7;1;1;1;;check_cit!APPLICATION ONE
>>
>>any idea what might be wrong?
>>
>>TIA, Jens
>>
>>Tom DE BLENDE wrote:
>>
>>>Dear all,
>>>
>>>Thanks to the great efforts made by Ed Rolison who created the
>>>original plugin for Big Brother, and Stanley Hopcroft who cleaned up
>>>the Netsaint port I've made, I am now able to release a beta version
>>>of the check_cit plugin.
>>>
>>>Help can be obtained by running "./check_cit --help". Basicly this
>>>plugin checks for the availability of published applications in a
>>>Citrix environment. It does this either by means of a broadcast, or by
>>>using a query to a specific server.
>>>
>>>I would like to ask those of you who have a Citrix environment to try
>>>out the plugin, and see if it works OK. Any comments are welcome.
>>>
>>>Kind regards,
>>>Tom De Blende
>>>
>>>
>>>------------------------------------------------------------------------
>>>
>>>#!/usr/bin/perl -w
>>>
>>># $Id: check_cit,v 1.6 2002-10-03 16:16:44+10 anwsmh Exp anwsmh $
>>>
>>># $Log: check_cit,v $
>>># Revision 1.6  2002-10-03 16:16:44+10  anwsmh
>>># Contributions from Mr Bas Rijniersce
>>>#  1 Decode unicode in application list if it looks as if the app list
>>
>>contains unicode
>>
>>>#  2 Only stop receiving packets from the browser after the socket times
>>
>>out
>>
>>>#    (formerly would only read 2 packets and this was useless for more
>>
>>than 20 apps)
>>
>>>#    if -L option.
>>>#  3 Change meaning of -T and default value. Now this is the UDP packet
>>
>>timeout
>>
>>>#    value and is set to be 1 second.
>>>#
>>># Revision 1.5  2002-10-01 19:26:07+10  anwsmh
>>># Provide -L option to deal with long lists of published apps (use -T
>>
>>probably indicated also).
>>
>>>#
>>># Revision 1.4  2002-10-01 16:53:56+10  anwsmh
>>># Roll version to accomodate
>>>#  . -P no longer mandatory (either -P or -W will do)
>>>#  . remove some redundant pack and unpacks after getting the
>>>#    app list from the browser.
>>>#
>>>
>>># Ed Rolison 15/06/02
>>># [email protected]
>>># If it doesn't work, please let me know, I've only had access to my
>>># environment so I'm not 100% sure.
>>>#
>>># If you want to mess around with this script, then please feel free
>>># to do so.
>>># However, if you add anything 'funky' then I'd really appreciate
>>># hearing about it.
>>>#
>>># Oh, and if you do ever make huge amounts of money out of it, cut me
>>># in :)
>>>
>>>use strict ;
>>>
>>>use IO::Socket;
>>>use IO::Select;
>>>use FileHandle;
>>>use Getopt::Long ;
>>>
>>>use vars qw($opt_H $opt_B $opt_W $opt_T $debug @citrix_servers
>>
>>$crit_pub_apps $warn_pub_apps $long_list);
>>
>>>use utils qw(%ERRORS &print_revision &support &usage);
>>>
>>>my $PROGNAME = 'check_citrix' ;
>>>
>>>sub print_help ();
>>>sub print_usage ();
>>>sub help ();
>>>sub version ();
>>>
>>>delete @ENV{'PATH', 'IFS', 'CDPATH', 'ENV', 'BASH_ENV'};
>>>
>>># You might have to change this...
>>>
>>>use constant PACKET_TIMEOUT   => 1;
>>>                              # Number of seconds to wait for further UDP
>>
>>packets
>>
>>>use constant TEST_COUNT               => 2;
>>>                              # Number of datagrams sent without reply
>>>use constant BUFFER_SIZE      => 1500;
>>>                              # buffer size used for 'recv' calls.
>>>use constant LONG_LIST                => 0 ;
>>>                              # this is for if you have many published
>>
>>applications.
>>
>>>                              # if you set it, it won't do any harm, but
>>
>>may slow the test
>>
>>>                              # down a little. (Since it does a 'recv'
>>
>>twice instead of
>>
>>>                              # once and therefore may have to wait for a
>>
>>timeout).
>>
>>>use constant ICA_PORT => 1604;
>>>                              # what port ICA runs on. Unlikely to change.
>>>
>>># End user config.
>>>
>>>Getopt::Long::Configure('bundling', 'no_ignore_case');
>>>GetOptions
>>>        ("V|version"     => \&version,
>>>         "h|help"        => \&help,
>>>         "d|debug"       => \$debug,
>>>         "B|broadcast_addr:s" => \$opt_B,
>>>         "C|citrix_servers:s" => \@citrix_servers,
>>>         "L|long_list"        => \$long_list,
>>>         "P|crit_pub_apps:s"  => \$crit_pub_apps,
>>>         "T|Packet_timeout:i"   => \$opt_T,
>>>         "W|warn_pub_apps:s"  => \$warn_pub_apps,
>>>) ;
>>>
>>># configuration section
>>>
>>>my $broadcast_addr = $1 if $opt_B and $opt_B =~ m#(\d+\.\d+\.\d+\.\d+)# ;
>>>usage("Invalid broadcast address: $opt_B\n") if $opt_B and not
>>
>>defined($broadcast_addr)  ;
>>
>>>usage("You must provide either the names of citrix servers or the
>>
>>broadcast address of the subnet containing them\n")
>>
>>>  unless (@citrix_servers or $broadcast_addr) ;
>>>
>>>my @target = defined $broadcast_addr ? ($broadcast_addr) : @citrix_servers
>>
>>;
>>
>>>usage("You must provide the names of the published applications that the
>>
>>Citrix browser should be advertising\n")
>>
>>>  unless $crit_pub_apps or $warn_pub_apps ;
>>>
>>>my $Timeout = $opt_T          if defined $opt_T ;
>>>$Timeout = PACKET_TIMEOUT     unless defined $Timeout ;
>>>$long_list = LONG_LIST                unless defined $long_list ;
>>>
>>>my @crit_pub_apps = $crit_pub_apps ? split(/,/, $crit_pub_apps) : () ;
>>>my @warn_pub_apps = $warn_pub_apps ? split(/,/, $warn_pub_apps) : () ;
>>>
>>># definitions of query strings. Change at your own risk :)
>>># this info was gathered with tcpdump whilst trying to use an ICA client,
>>># so I'm not 100% sure of what each value is.
>>>
>>>my @bcast_helo = &tethereal2list(<<'End_of_Tethereal_trace', '1e') ;
>>>0020  ff ff 04 d6 06 44 00 26 4a 76 1e 00 01 30 02 fd   .....D.&Jv...0..
>>>0030  a8 e3 00 02 f5 95 9f f5 30 07 00 00 00 00 00 00   ........0.......
>>>0040  00 00 00 00 00 00 01 00
>>>End_of_Tethereal_trace
>>>
>>>my @bcast_query_app = &tethereal2list(<<'End_of_Tethereal_trace', '24') ;
>>>0020  64 17 04 50 06 44 00 2c 85 6a 24 00 01 32 02 fd   d..P.D.,.j$..2..
>>>0030  a8 e3 00 00 00 00 00 00 00 00 00 00 00 00 00 00   ................
>>>0040  00 00 00 00 00 00 21 00 02 00 00 00 00 00         ......!......
>>>End_of_Tethereal_trace
>>>
>>>my @direct_helo = &tethereal2list(<<'End_of_Tethereal_trace', '20') ;
>>>0020  64 17 05 0f 06 44 00 28 ab b5 20 00 01 30 02 fd   d....D.(.. ..0..
>>>0030  a8 e3 00 00 00 00 00 00 00 00 00 00 00 00 00 00   ................
>>>0040  00 00 00 00 00 00 00 00 00 00
>>>End_of_Tethereal_trace
>>>
>>>my @direct_query_app = &tethereal2list(<<'End_of_Tethereal_trace', '2c') ;
>>>0020  64 17 05 10 06 44 00 34 7a 9a 2c 00 02 32 02 fd   d....D.4z.,..2..
>>>0030  a8 e3 00 00 00 00 00 00 00 00 00 00 00 00 00 00   ................
>>>0040  00 00 00 00 00 00 21 00 02 00 01 00 00 00 00 00   ......!.........
>>>0050  00 00 00 00 00 00
>>>End_of_Tethereal_trace
>>>
>>>my $Udp =  IO::Socket::INET->new( Proto => 'udp' ) || die "Socket failure:
>>
>>$!";
>>
>>># select is here to allow us to set timeouts on the connections.
>>
>>Otherwise they
>>
>>># just 'stop' until a server appears.
>>>
>>>my $select =  IO::Select->new($Udp) || die "Select failure: $!";
>>>
>>># helo needs to be broadcast, but query does not.
>>>
>>>$Udp->sockopt(SO_BROADCAST, 1 );
>>>$Udp->autoflush(1);
>>>
>>>my ($remote_host, $buff, $buff2, $raddr, $rport, $rhost,
>>
>>@remote_response);
>>
>>>my (@query_message, $send_addr, $this_test) ;
>>>
>>>$buff = $buff2 = '';
>>>$this_test = 0;
>>>
>>># If there is no response to the first helo packet it will be resent
>>># up to TEST_COUNT (see at the top).
>>>
>>>while ( ++$this_test <= TEST_COUNT && !$buff ) {
>>>
>>>  print "Sending helo datagram. datagram number: ", $this_test, "\n" if
>>
>>$debug ;
>>
>>>  # if we have multiple targets, we probe each of them until we get a
>>>  # response...
>>>
>>>  foreach my $destination (@target) {
>>>     @query_message = ( $broadcast_addr ? @bcast_helo : @direct_helo) ;
>>>     print "Querying $destination for master browser\n" if  $debug  ;
>>>     $send_addr = sockaddr_in(ICA_PORT, inet_aton($destination) );
>>>     &dump(pack('C*', @query_message)) if $debug ;
>>>     $Udp->send( pack('C*', @query_message), 0, $send_addr );
>>>     if ( $select->can_read($Timeout) ) {
>>>       $remote_host = $Udp->recv($buff, BUFFER_SIZE, 0 );
>>>     }
>>>
>>>     last if $buff ;
>>>     sleep 1 ;
>>>
>>>  } # foreach destination
>>>} # while loop
>>>
>>># ok we've looped several times, looking for a response. If we don't have
>>
>>one
>>
>>># yet, we simply mark the whole lot as being unavailable.
>>>
>>>unless ( $buff ) {
>>>  print "Failed. No response to helo datagram (master browser query) from
>>
>>", $broadcast_addr ? $broadcast_addr : "@citrix_servers", ".\n" ;
>>
>>>  exit $ERRORS{CRITICAL} ;
>>>}
>>>
>>>($rport, $raddr) = sockaddr_in( $remote_host );
>>>$rhost = gethostbyaddr( $raddr, AF_INET );
>>>my @tmpbuf = unpack('C*', $buff );
>>>if ( $debug ) {
>>>  print "$rhost:$rport responded with: ",length($buff), " bytes\n";
>>>  &dump($buff) ;
>>>} #if debug
>>>
>>># now we have a response, then we need to figure out the master browser,
>>
>>and
>>
>>># query it for published applications...
>>>
>>>my $master_browser = join '.', @tmpbuf[32..35] ;
>>>
>>># ok should probably error check this, because it's remotely possible
>>># that a server response might be completely wrong...
>>>
>>>print "Master browser = $master_browser\n" if  $debug ;
>>>
>>>$send_addr = sockaddr_in(ICA_PORT, inet_aton($master_browser));
>>>
>>>if ( $broadcast_addr ) {
>>>  print "using broadcast query\n" if $debug ;
>>>  @query_message = @bcast_query_app;
>>>} else {
>>>  print "using directed query\n" if $debug ;
>>>  @query_message = @direct_query_app;
>>>}
>>>
>>># now we send the appropriate query string, to the master browser we've
>>
>>found.
>>
>>>$buff = '';
>>>$this_test = 0 ;
>>>
>>>print "Querying master browser for published application list\n" if
>>
>>$debug  ;
>>
>>>while ( ++$this_test <= TEST_COUNT && !$buff ) {
>>>  print "Sending application query datagram.  datagram number: ",
>>
>>$this_test, "\n" if $debug ;
>>
>>>  &dump(pack('C*', @query_message)) if $debug ;
>>>  $Udp->send( pack ('C*', @query_message), 0, $send_addr );
>>>
>>>  if ( $select->can_read($Timeout) ) {
>>>    $remote_host = $Udp->recv($buff, BUFFER_SIZE, 0 );
>>>    # $buff = substr($buff, 32) ;
>>>                                              # Hope that ICA preamble is
>>
>>first 32 bytes
>>
>>>   }
>>>
>>>  # long application lists are delivered in multiple packets
>>>
>>>  my $buff2 = '' ;
>>>  while ( $long_list && $select->can_read($Timeout) ) {
>>>    $remote_host = $Udp->recv($buff2, BUFFER_SIZE, 0 );
>>>    $buff .= $buff2 if $buff2 ;
>>>    # $buff .= substr($buff2, 32) if $buff2 ;
>>>                                              # Hope that ICA preamble is
>>
>>first 32 bytes
>>
>>>  }
>>>
>>>  last if $buff ;
>>>  sleep 1 ;
>>>
>>>} # while test_count
>>>
>>>unless ( $buff ) {
>>>  print "Failed. No response to application query datagram from ",
>>
>>$master_browser, ".\n" ;
>>
>>>  exit $ERRORS{CRITICAL} ;
>>>}
>>>
>>># we got a response from a couple of retries of the app query
>>>
>>>($rport, $raddr) = sockaddr_in ( $remote_host );
>>>$rhost = gethostbyaddr ( $raddr, AF_INET );
>>>if ( $debug ) {
>>>  print "$rhost:$rport responded to app query with: ",length($buff), "
>>
>>bytes\n";
>>
>>>  &dump($buff) ;
>>>} #debug
>>>
>>>my $app_list = $buff ;
>>>                                              # delete nulls in unicode
>>>                                              # but only if there is
>>
>>unicode (usually from
>>
>>>                                              # broadcast query)
>>>
>>>$app_list =~ s/(?:(\w| |-)\x00)/$1/g
>>>  if $app_list =~ /(?:(?:(?:\w| |-)\x00){3,})/ ;
>>>                                              # FIXME an application name
>>
>>is
>>
>>>                                              # 3 or more unicoded
>>
>>characters
>>
>>>                                              # FIXME locale
>>>                                              # extract null terminated
>>
>>strings
>>
>>>my (@clean_app_list, $clean_app_list) ;
>>>$clean_app_list = join(',', @clean_app_list = $app_list =~ m#([A-Z](?:\w|
>>
>>|-)+?(?=\x00))#g ) ;
>>
>>>                                              # FIXME everyones apps don't
>>
>>start with caps
>>
>>>print qq(Received list of applications: "$clean_app_list".\n) if $debug ;
>>>
>>>if ( scalar @crit_pub_apps and my @missing =
>>
>>&simple_diff(\@clean_app_list, \@crit_pub_apps) ) {
>>
>>>  print qq(Failed. "@missing" not found in list of published
>>
>>applications),
>>
>>>        qq( "$clean_app_list" from master browser "$master_browser".\n) ;
>>>  exit $ERRORS{CRITICAL} ;
>>>}
>>>
>>>if ( my @missing = &simple_diff(\@clean_app_list, \@warn_pub_apps) ) {
>>>  print qq(Warning. "@missing" not found in list of published
>>
>>applications),
>>
>>>        qq( "$clean_app_list" from master browser "$master_browser".\n) ;
>>>  exit $ERRORS{WARNING} ;
>>>}
>>>
>>>my @x = (@crit_pub_apps, @warn_pub_apps) ;
>>>my $blah = ( scalar(@x) == 1 ? 'the published application "' . join(',',
>>
>>@x) . '" is available' :
>>
>>>                             'the published applications "' . join(',',
>>
>>@x) . '" are available' ) ;
>>
>>>print qq(Ok. Citrix master browser "$master_browser" reported that
>>
>>$blah.\n) ;
>>
>>>exit $ERRORS{OK} ;
>>>
>>># sleep $Timeout;
>>>                                              # because otherwise we can
>>
>>get responses from
>>
>>>                                              # the WRONG servers. DOH
>>>close $Udp;
>>>
>>>
>>>sub print_usage () {
>>>        print "Usage: $PROGNAME (-B <broadcast_address>| -C
>>
>><citrix_server>..) -W <pub_app1,pub_app2..> -P <pub_app1,pub_app2,>\n";
>>
>>>}
>>>
>>>sub print_help () {
>>>        print_revision($PROGNAME,'$Revision: 1.6 $ ');
>>>        print "Copyright (c) 2002 Ed Rolison/Tom De Blende
>>>
>>>Perl Check Citrix plugin for NetSaint.
>>>
>>>Returns OK if the Citrix master browser returns  a 'published application'
>>
>>list that contain names specified by the -W or -P options
>>
>>>The plugin works by
>>>  If the -B option is specified, sending a broadcast helo to find the
>>
>>address of the Citrix master browser in the specified subnet.
>>
>>>    return critical if there is no reply;
>>>  Else if the -C option is specified
>>>    send a direct helo to the specified server until there is a response
>>
>>(containing the address of the Citrix master browser)
>>
>>>  Query the master browser (using a 'broadcast published applications
>>
>>query ' if -B) and compare the published applications returned
>>
>>>    to those specified by -W and -P options
>>>
>>>  return Critical if the published applications specified by -P is not a
>>
>>subset of the query responses;
>>
>>>  return Warning  if the published applications specified by -W is not a
>>
>>subset of the query responses;
>>
>>>  return OK
>>>
>>>";
>>>        print_usage();
>>>        print '
>>>-B, --broadcast_address=STRING
>>>   The broadcast address that should contain Citrix master browser. This
>>
>>option takes precedence over -C.
>>
>>>-C, --citrix_server:STRING
>>>   Optional __name(s)__ of Citrix servers that could be the master browser
>>
>>(used when broadcast not possible).
>>
>>>-L, --long_list
>>>   Set this if you have heaps of published applications (ie more than will
>>
>>fit in _one_ UDP packet)
>>
>>>-P, --crit_published_app=STRING
>>>   Optional comma separated list of published application that must be in
>>
>>the response from the master browser.
>>
>>>   Check returns critical otherwise.
>>>-T, --packet-timeout:INTEGER
>>>   Time to wait for UDP packets (default 1 sec).
>>>-W, --warn_published_app=STRING
>>>   Optional comma separated list of published application that should be
>>
>>in the response from the master browser.
>>
>>>   Check returns warning otherwise.
>>>-d, --debug
>>>   Debugging output.
>>>-h, --help
>>>   This stuff.
>>>
>>>';
>>>        support();
>>>}
>>>
>>>sub version () {
>>>        print_revision($PROGNAME,'$Revision: 1.6 $ ');
>>>        exit $ERRORS{'OK'};
>>>}
>>>
>>>sub help () {
>>>        print_help();
>>>        exit $ERRORS{'OK'};
>>>}
>>>
>>>sub dump {
>>>  my ($x) = shift @_ ;
>>>  my (@x, @y, $y, $i, $rowcount) ;
>>>  my ($nr, $j, $number_in_row, $number_of_bytes) ;
>>>  my $dump ;
>>>
>>>  $number_in_row = 16 ;
>>>  $number_of_bytes = length $x ;
>>>  $nr = 0 ;
>>>
>>>  # styled on tethereal.
>>>
>>>  foreach $j (1 .. int( $number_of_bytes / $number_in_row) ) {
>>>    $y = substr($x, ($j - 1)*$number_in_row, $number_in_row) ;
>>>    @y = unpack("C*", $y) ;
>>>    $y =~ tr /\x00-\x19/./ ;
>>>    $rowcount = sprintf("%4.4x", ($j - 1) * 0x10 ) ;
>>>    $dump .= sprintf "%s  %s   %s\n", $rowcount, join(" ", map { sprintf
>>
>>"%2.2x", $_} @y), $y ;
>>
>>>    $nr++ ;
>>>  }
>>>
>>>  if ( $number_of_bytes % $number_in_row > 0 ) {
>>>    my $spaces_to_text = $number_in_row * 3 - 1 + 3 ;
>>>    $rowcount = sprintf("%4.4x", $nr * 0x10 ) ;
>>>    $y = substr($x, $nr * $number_in_row ) ;
>>>    @y = unpack("C*", $y) ;
>>>    my $bytes = join(" ", map { sprintf "%2.2x", $_} @y) ;
>>>    my $spaces = ' ' x ($spaces_to_text - length($bytes)) ;
>>>    $dump .= sprintf "%s  %s%s%s\n", $rowcount, $bytes, $spaces, $y ;
>>>  }
>>>
>>>  print $dump, "\n" ;
>>>
>>>}
>>>
>>>sub tethereal2list {
>>>  my ($tethereal_dump, $start_byte) = @_ ;
>>>
>>>  # return an array containing qw(0xef 0xab 0x00 ...) from a tethereal
>>
>>trace.
>>
>>>  # skip all stuff until the first byte given by $start_byte.
>>>
>>>  return undef unless $tethereal_dump =~ /\d\d\d\d  \S\S(?: \S\S){1,15}/ ;
>>>
>>>  my $hex_start_byte = hex($start_byte) ;
>>>  my @x = $tethereal_dump =~ m#(.+)#g ;
>>>  my @y = map unpack("x6 a47", $_), @x ;
>>>  my @z = map { my $y = $_; $y =~ s/(\S\S)/hex($1)/eg; my @a = split(' ',
>>
>>$y); @a  } @y ;
>>
>>>  shift @z, while $z[0] ne $hex_start_byte ;
>>>
>>>  @z ;
>>>
>>>}
>>>
>>>sub simple_diff {
>>>
>>>  my ( $a_list, $b_list) = @_ ;
>>>
>>>  # simple set difference 'Recipe 4.7 Perl Cookbook', Christiansen and
>>
>>Torkington
>>
>>>  my (%seen, @missing) ;
>>>
>>>  @seen{@$a_list} = () ;
>>>
>>>  foreach my $item (@$b_list) {
>>>    push @missing, $item unless exists $seen{$item} ;
>>>  }
>>>
>>>  @missing ;
>>>}
>>>
>>>
>>>
>>
>>--
>>Mit freundlichen Grüßen
>>
>>Jens Kruse
>>Linux Systemadministrator
>>
>>MobilCom AG
>>Hollerstraße 126
>>24782 Büdelsdorf
>>Telefon: +49 (0)4331/ 447 - 2168
>>Telefax: +49 (0)4331/ 434 - 4010
>>[email protected]
>>
>>Besucher:
>>Am Friedrichsbrunnen
>>
>>-------------------------------------------------------
>>This sf.net email is sponsored by:ThinkGeek
>>Welcome to geek heaven.
>>http://thinkgeek.com/sf
>>_______________________________________________
>>Netsaint-users mailing list
>>[email protected]
>>https://lists.sourceforge.net/lists/listinfo/netsaint-users
> 
> 



-- 
Mit freundlichen Grüßen

Jens Kruse
Linux Systemadministrator

MobilCom AG
Hollerstraße 126
24782 Büdelsdorf
Telefon: +49 (0)4331/ 447 - 2168
Telefax: +49 (0)4331/ 434 - 4010
[email protected]

Besucher:
Am Friedrichsbrunnen




-------------------------------------------------------
This sf.net email is sponsored by:ThinkGeek
Welcome to geek heaven.
http://thinkgeek.com/sf
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.