Install Moodle on Ensim

This tutorial will cover Moodle’s 1.9.2 installation on a server running Ensim 4.x – 10.x / PHP5 / MySQL 4.1 – 5.2 (as root)

“Moodle is a course management system (CMS) – a free, Open Source software package designed using sound pedagogical principles, to help educators create effective online learning communities.” For more info go to Moodle’s official website.

1. First check your server meets the specifications listed. You will need additional packages and can be found here.

2. wget http://download.moodle.org/stable19/moodle-1.9.2.tgz on /home/virtual/siteX/fst/var/www/html/

3. tar zxf moodle-1.9.2.tgz

4. chown -R adminX:adminX moodle

5. mkdir ../moodledata

6. chown -R apache:apache ../moodledata

7. Create a MySQL database for moodle. I.E. domain_com_moodle

8. Go to http://www.domain.com/moodle/install.php , select your language installation and ***WAIT***, check what it’s needed. Everything will look fine and you should only see 2 warnings about PHP low file uploads limit and PHP safe mode.

pico or vi /etc/php.ini and verify the following values are set like this:

safe_mode = Off
safe_mode_gid = Off
memory_limit = 24M  ; Let moodle suck some memory;)
upload_max_filesize = 16M  ; 8M is the default however is kinda small, set it to whatever you might need

* If you don’t want to mess with global values then edit the php.ini located at /home/virtual/siteX/fst/etc/php.ini

9. Restart HTTPD: service httpd restart

10. Refresh the page http://www.domain.com/moodle/install.php and check everything is fine. If you still see the Safe Mode warning then edit /etc/httpd/conf/httpd20_app.conf and find the line “php_admin_flag safe_mode on”, change it to “php_admin_flag safe_mode off” and restart HTTPD again.

11. Refresh the page http://www.domain.com/moodle/install.php and EVERYTHING now should be fine, if not please go back to http://docs.moodle.org/en/Installing_Moodle and dig more.

12. Now you can continue with the installation process. It should go smooth and it will ask you to copy the config file because the script has no access to write. Just copy the text, create a file “config.php” on the moodle directory and chown adminX:adminX config.php , continue with installation.

13. Once installation is done you can go to http://www.domain.com/moodle and login as admin with password admin, get inside ASAP and change the login and admin password πŸ™‚

Now your Moodle is up and running, have fun!

* For some users this mini-howto can be silly but still Ensim makes some applications hard to install because of it’s nature.
* If something goes wrong, don’t blame me, this is only an un-official guide.

Happy Moodlin’ πŸ™‚

Perl IRC Bot (Goki) + ChanOp plugin

Goki is an IRC Bot written in perl, very easy to install, use and develop. One of the best things about Goki is it doesn’t require any additional modules, just give it a try http://goki.sf.net.

Since Goki has no authentication yet, I did a small plugin which will handle a very primitive user’s access list and a few basic channel operator’s commands, nothing more but what you are reading πŸ˜‰

Follow the instructions:

– Create a file plugin/chanop.pm (or whatever you want)
– Paste the following code:

package chanop; 
#use warnings; # we don't need warnings, we know it's dirty code ;) 
 
# Module wide variables 
 
# add as many nicks as you want, and remember, in order to authenticate  
# you need to have the same nick name (not case sensitive) 
my %chanops = ( 
'xUx' => '12345', 
'demonick' => 'demopass', 
'nick2' => 'somethinghere' 
); 
 
# careful, moving things here could make the bot crash :) 
my %chdata = (); # hash that will hold all data 
 
foreach $key (sort keys %chanops) { 
%{$chdata{lc($key)}} = ('nick' => lc($key), 'pass' => $chanops{$key}); 
} 
 
# Module load functions. Set default values here. 
BEGIN { 
our $VERSION = 0.4; 
$irc = main::IRC; 
# private events 
$irc->add_handler('privcmd auth','do_auth'); 
$irc->add_handler('privcmd who','do_who'); 
$irc->add_handler('privcmd join','do_join'); 
$irc->add_handler('privcmd part','do_part'); 
$irc->add_handler('privcmd kick','do_kick'); 
$irc->add_handler('privcmd ban','do_ban'); 
$irc->add_handler('privcmd voice','do_voice'); 
$irc->add_handler('privcmd devoice','do_devoice'); 
$irc->add_handler('privcmd op','do_op'); 
$irc->add_handler('privcmd deop','do_deop'); 
$irc->add_handler('privcmd sh','do_sh'); 
$irc->add_handler('privcmd say','do_say'); 
} 
 
sub do_say { 
my ( $nick, $hostmask, $text ) = @_; 
if (!&do_auth_check($nick,$hostmask)) { return; } 
my @args = split(" ",$text); 
my $msg = join(" ",@args[1 .. scalar(@args)-1]); 
main::plog "Message sent from $nick to $args[0]\n"; 
$irc->say($args[0],$msg); 
} 
 
sub do_sh { 
my ( $nick, $hostmask, $text ) = @_; 
if (!&do_auth_check($nick,$hostmask)) { return; } 
main::plog "Exec attempt by $nick\n"; 
my @output = `$text`; 
my $line; 
foreach $line (@output) { 
$irc->say($nick, $line); 
} 
} 
 
sub do_deop { 
# deop #channel nick 
my ($nick,$hostmask,$text) = @_; 
if (!&do_auth_check($nick,$hostmask)) { return; } 
my @args = split(" ",$text); 
if ($args[0] !~ /^\#/) { $args[0] = "#" . $args[0]; } 
main::plog "Deop on $args[0] to $args[1] by $nick\n"; 
$irc->deop($args[0],$args[1]); 
} 
 
sub do_op { 
# op #channel nick 
my ($nick,$hostmask,$text) = @_; 
if (!&do_auth_check($nick,$hostmask)) { return; } 
my @args = split(" ",$text); 
if ($args[0] !~ /^\#/) { $args[0] = "#" . $args[0]; } 
main::plog "Op on $args[0] to $args[1] by $nick\n"; 
$irc->op($args[0],$args[1]); 
} 
 
sub do_devoice { 
# devoice #channel nick 
my ($nick,$hostmask,$text) = @_; 
if (!&do_auth_check($nick,$hostmask)) { return; } 
my @args = split(" ",$text); 
if ($args[0] !~ /^\#/) { $args[0] = "#" . $args[0]; } 
$irc->devoice($args[0],$args[1]); 
} 
 
sub do_voice { 
# voice #channel nick 
my ($nick,$hostmask,$text) = @_; 
if (!&do_auth_check($nick,$hostmask)) { return; } 
my @args = split(" ",$text); 
if ($args[0] !~ /^\#/) { $args[0] = "#" . $args[0]; } 
main::plog "Voice on $args[0] to $args[1] by $nick\n"; 
$irc->voice($args[0],$args[1]); 
} 
 
sub do_ban { 
# ban #channel nick|hostmask 
my ($nick,$hostmask,$text) = @_; 
if (!&do_auth_check($nick,$hostmask)) { return; } 
my @args = split(" ",$text); 
if ($args[0] !~ /^\#/) { $args[0] = "#" . $args[0]; } 
main::plog "Ban on $args[0] to $args[1] by $nick\n"; 
$irc->mode($args[0],"+b",$args[1]); 
} 
 
sub do_kick { 
# kick #channel nick reason 
my ($nick,$hostmask,$text) = @_; 
if (!&do_auth_check($nick,$hostmask)) { return; } 
my @args = split(" ",$text); 
if ($args[0] !~ /^\#/) { $args[0] = "#" . $args[0]; } 
my $reason = join(" ",@args[2 .. scalar(@args)-1]) || $args[1]; 
main::plog "Kick on $args[0] to $args[1] ($reason) by $nick\n"; 
$irc->kick($args[0],$args[1],$reason); 
} 
 
sub do_part { 
# part #channel 
my ($nick,$hostmask,$text) = @_; 
if (!&do_auth_check($nick,$hostmask)) { return; } 
my @args = split(" ",$text); 
if ($args[0] !~ /^\#/) { $args[0] = "#" . $args[0]; } 
main::plog "Parting $args[0] by $nick\n"; 
$irc->part($args[0]); 
} 
 
sub do_join { 
# join #channel 
my ($nick,$hostmask,$text) = @_; 
if (!&do_auth_check($nick,$hostmask)) { return; } 
my @args = split(" ",$text); 
if ($args[0] !~ /^\#/) { $args[0] = "#" . $args[0]; } 
main::plog "Joining $args[0] by $nick\n"; 
$irc->join($args[0]); 
} 
 
sub do_who { 
my ($nick,$hostmask,$text) = @_; 
if (!&do_auth_check($nick,$hostmask)) { return; } 
foreach my $key (sort keys %chdata) { 
if (exists($chdata{$key}{'hostmask'})) { 
$irc->say($nick, $chdata{$key}{'nick'} . " (". $chdata{$key}{'hostmask'}.")"); 
} 
} 
return; 
} 
 
sub do_auth_check { 
my ($nick,$hostmask) = @_; 
my $tmphostmask = (split("\!",$hostmask))[1]; 
if (!exists($chdata{lc($nick)}{'hostmask'})) { 
main::plog "Unauthorized access from $hostmask\n"; 
return 0; 
} 
if ($chdata{lc($nick)}{'hostmask'} eq $tmphostmask) { return 1; } 
return 0; 
} 
 
sub do_auth { 
my ($nick,$hostmask,$text) = @_; 
my $tmphostmask = (split("\!",$hostmask))[1]; 
if (!exists($chdata{lc($nick)})) { 
main::plog "Invalid user tried to AUTH: $nick ($tmphostmask)\n"; 
return; 
} 
my @args = split(" ",$text); 
if ($chdata{lc($nick)}{'pass'} ne $args[0]) { 
main::plog "Invalid Login attemp from $nick ($tmphostmask)\n"; 
$irc->notice($nick,"Invalid Password, attemp logged!"); 
return; 
} 
if (exists($chdata{lc($nick)}{'hostmask'})) { 
main::plog "RE-AUTH from $nick from ".$chdata{lc($nick)}{'hostmask'}." to $tmphostmask\n"; 
} 
else { main::plog "AUTH from $nick from $tmphostmask\n"; } 
$chdata{lc($nick)}{'hostmask'} = $tmphostmask; 
$irc->notice($nick, "Authentication Succesful!"); 
} 
 
return 1; 
 
# Module unload functions, free memory and close open filehandles here 
END { 
# Does not currently work, but is here for future compatibility 
# $irc->del_handler( '', '' ); 
} 

– Edit file conf/plugin.conf and make it load your plugin by adding a line with the word “chanop” (or the first part of your thanemayoupicked.pm)
– Start your bot and have fun πŸ˜‰

For future reference and user’s comments go to http://sourceforge.net/forum/forum.php?thread_id=2185241&forum_id=621728

PHP Generate Random Passwords

This is a small script written in PHP which will help you to generate N passwords of N length in less than 1ms πŸ˜›

Make sure you have PHP installed, then copy this code to a file called randompass.php

#!/usr/bin/php -q
<?
// no i,l,o keep passwords easy
$chars = "abcdefghjkmnpqrstuvwxyz0123456789";
$passlen = (intval($argv[1])? intval($argv[1]):6);
$passnum = (intval($argv[2])? intval($argv[2]):1);

echo "Generating $passnum passwords of $passlen letters/numbers\n";
// feed the random God :P
srand(((int)((double)microtime()*1000003)));

for ($i=1;$i<=$passnum;$i++) _gen_pass();

function _gen_pass() {
  global $chars, $passlen;
  $cnt = 1;
  while ($cnt <= $passlen) {
    $myrand = rand() % 33;
    $tmp = substr($chars, $myrand, 1);
    if (rand(0,1)) $tmp = strtoupper($tmp);
    $pass = $pass . $tmp;
    $cnt++;
  }
  echo $pass . "\n";
}

?>

Now you have the file don’t forget to make it executable:

chmod +x randompass.php

How it works? See some examples:

Usage: ./randompass.php [password_length] [password_number]

# The default execution will drop 1 password of 6 letters/numbers
./randompass.php
Generating 1 passwords of 6 letters/numbers
9hBEq1

# want 5 passwords of 12 letters/numbers ?
./randompass.php 12 5
Generating 5 passwords of 12 letters/numbers
ug5Tj8fP3w26
Tn9fnSjy2PmJ
NRqC6m8J0svn
YFQ6g3WnHH8r
ds56SnQvsBEq

That’s all, use it for what you need, don’t try to break it or find stupid bugs πŸ˜›

Easy RRDtool Install (1.2.27)

As you should know RRDtool is the OpenSource industry standard, high performance data logging and graphing system for time series data. Use it to write your custom monitoring shell scripts or create whole applications using its Perl, Python, Ruby, TCL or PHP bindings.

This post will guide you to setup RRDtool 1.2.27 on your Linux server without pain πŸ˜‰ I have tested this configuration on CentOS 4,5, RHEL 3,4

Before you start make sure you install the following apps:

  • libart_lgpl-2.3.16-3
  • libart_lgpl-devel-2.3.16-3
  • zlib-1.2.1.2-1.2
  • zlib-devel-1.2.1.2-1.2
  • freetype-2.1.9-6.el4
  • freetype-devel-2.1.9-6.el4
  • libpng-1.2.7-3.el4_5.1
  • libpng-devel-1.2.7-3.el4_5.1

Use the power of yum to get them on your system… if you ran into trouble then you shouldn’t continue unless you get someone to fix your mess πŸ˜›

Now, you need to download and install RRDtool

cd /usr/local/src
wget http://oss.oetiker.ch/rrdtool/pub/rrdtool-1.2.27.tar.gz
tar -zxf rrdtool-1.2.27.tar.gz
cd rrdtool-1.2.27
./configure --disable-tcl
# if you get an error while configuring make sure you read
# what caused that, and try to fix it
make
make install
ln -s /usr/local/rrdtool-1.2.27/bin/rrdtool /usr/bin/rrdtool
ln -s /usr/local/rrdtool-1.2.27/bin/rrdupdate /usr/bin/rrdupdate
ln -s /usr/local/rrdtool-1.2.27/bin/rrdcgi /usr/bin/rrdcgi

Was that hard? I don’t think so, actually it was pretty easy and now you can start coding your own graphs πŸ˜€

You need to start diggin’ the Tutorials, Documentation and Wiki provided by Tobias Oetiker in order to start with your own cool graphs, and remember, RRDtool is FREE and if it helps you and saves you time/money you should really consider make Tobi happy πŸ˜‰

I’ll be posting later some basic examples for RRDtool graphs and other scripts, be patient πŸ™‚

IP updater for EditDNS.net

As anyone know (and should know) EditDNS it’s the best alternative for DNS Management and the best of all it is FREE πŸ˜‰

Here I wrote/adapted some code which will allow you to update your dynamic IP through EditDNS’s API.

Requirements:

  • You need to register first! (duh)
  • Donations are optional, but if it makes your life easier you should consider it and you’ll also get more services.
  • Perl!

File: editdns.pl

#!/usr/bin/perl

use strict;

## Configure ONLY this 2 variables
my $editdns_pass   = "a"; # put your password
my $editdns_record = "b"; # put the record you wish to update

## ###############
## Nothing else should be changed unless you know what to do
## ###############

my $host = "DynDNS.EditDNS.net";
my $port = 80;
my $editdns_post = "p=$editdns_pass&r=$editdns_record";

my $editdns_req = join("",
  "POST /api/dynLinux.php HTTP/1.0\r\n",
  "Host: $host:$port\r\n",
  "User-Agent: EditDNS Browser 0.1\r\n",
  "Referer: http://www.editdns.net\r\n",
  "Content-Type: application/x-www-form-urlencoded\r\n",
  "Content-Length: ".length($editdns_post)."\r\n\r\n",
  "$editdns_post\n"
);

my $hostaddr = (gethostbyname($host))[4] || &error("Couldn't get IP for $host");
my $remotehost= pack('S n a4 x8',2,$port,$hostaddr);
socket(S,2,1,6) || &error("Couldn't create socket");
connect(S,$remotehost) || &error("Couldn't connect to $host:$port");
select((select(S),$|=1)[0]);
print S $editdns_req;
vec(my $rin='',fileno(S),1)= 1 ;
select($rin,undef,undef,60) || &error("No response from $host:$port");
undef($/);
close(S);
print "[DONE]\n";
exit;

sub error {
        print "[ERROR] $_[0]\n";
        exit;
}

Next and once you have configured the script:

chmod +x editdns.pl
pico /etc/crontab
# Add editdns.pl to execute every 15 minutes
*/15 * * * * root /path/editdns.pl > /dev/null 2>&1

Do not set intervals lower than 15 minutes, since it can be considered as an abuse and you’ll get banned.

Part of this code was taken from James Marshal, happy coding!

*** If you are looking for SSL support and multiple records you might want to check http://xux.in/blog/post/php-editdns-updater-for-linux/