Tuesday, October 4, 2011

Creating a Basic Drupal Module!

It is quite easy creating a drupal module. The rule what you have to know is just selecting the function you need to use. Because, Drupal has got so many functions that you can use. But before coding, we must create a folder for our module. This folder has two important files:

  1. Mymodule (folder)
    • mymodule.info (must)
    • mymodule.module (must)
    • mymodule.inc
Let's view!


For step 1;

mymodule.info includes;

name = Honda HR-V //this is the name of the module
description = HONDA HR-V car is the best i have ever seen in this world! //the description
package = packageName //which package the module is in
core = 7.x //the core number
version = 7.8 //the version
files[] = honda.module //files that'll include to
dependencies[] = views //the modules which we must include



 
For step 2;

mymodule.module details are;

When we code a module of Drupal, we should know how to use the PHP tags. After the end of our code, we don't put the "<?>" tag on it.

    function honda_menu() {
      $items['honda/hrv'] = array(
        'title' => 'Honda HR-V',
        'page callback' => 'honda_page',
        'access arguments' => array('access content'),
        'file' => 'honda.inc',
      );
      return $items;
    }
    
     Please check "honda/hrv" out. This is the direction we go on the browser. If we click this, it's going to start on "honda.inc" page. Here is one of the most important things we have to know on drupal, is the way of how Drupal's work. "honda_page" is a function actually. When the module opened, this function'll be started.

    For step 3;

    Then let me show you the page which's name is honda.inc:

    function honda_page() {
      return t('This is the first module i created!');
    }
    
    As you see here, we've never used the ending tag ,"? >".
    This honda_page function's been used before When we coding mymodule.module page, page callback.


    By the way, you may ask me what the "t" is. t() is a function that used on drupal. This method handles the outputting works including the multilingual operations.

    If you want to see more information about t() function, you can visit official web site, here is api.drupal.org/t .


    We'll see you next article!

    Thursday, September 29, 2011

    Contribute to Practical Code Solutions

    Practical Code Solutions has three active authors now and they post blog entries about programming, open source software, networking, scripting and other issues about computers. Since it is not a private site,we are calling new participants which have aimed to write about the issues stated above.

    Also the authors which are interested in web programming, desktop programming, databases, operating systems, compilers and interpreters, algorithms, statistics, operations research are welcome!. Requirements are average level of plain English and being a professional or hobbyist on one or more of the subjects described.

    Please contact one of the authors of Practical Code Solutions or leave a message under this post to participate. Do not hesitate to share new ideas with us.

    DHCP server configuration on Linux.



    This page is about configuring a dhcp3-server on a Debian system. You can install the service library with following command;



    sudo atp-get install dhcp3-server


    When you install dhcp3-server service, you will see dhcp3 directory in folder /etc. That directory contains dhcp3-server configuration file dhcpd.conf. My dhcp3-server service configuration file seems like this;


    ddns-update-style none;
    option domain-name "sample-dom.sample-com";
    option domain-name-servers 172.28.202.143, 172.28.202.142;

    default-lease-time 600;
    max-lease-time 7200;

    subnet 172.28.24.0 netmask 255.255.255.0 {
    range 172.28.24.10 172.28.24.254;
    option subnet-mask 255.255.255.0;
    option broadcast-address 172.28.24.255;
    option routers 172.28.24.1;
    }

    host printer {
    hardware ethernet 00:26:73:04:08:3f;
    fixed-address 172.28.24.37;
    }

    host printer1 {
    hardware ethernet 00:00:f0:a6:ef:5b;
    fixed-address 172.28.24.90;
    }

    host AccessPoint_Symbol {
    hardware ethernet 00:A0:F8:A7:77:88;
    fixed-address 172.28.24.70;
    }
    authoritative;

    log-facility local7;


    First 3 lines are abo ut dn s settings. You can set the domain in domain-name line and you can set dns servers on domai-name-servers line. You can also set multiple dns servers in a single line. If a client gets an ip address and never opens it for 7200 seconds, all information will be deleted for that client. So this date is called expiration date. subnet 172.28.24.0 netmask 255.255.255.0 part defines a scope between "{" and "}" characters. Scope properties are located between parentheses. For example, I want service to distribute ips only from the range of 172.28.24.10 and 172.28.24.254. I don't want the service to distribute ips from the range of 172.28.24.1 and 172.28.24.9. I also want to use this range to special purposes. And then, there are other options needed. subnet-mask, broadcast address and router address. Router address is usually called default gateway.

    Host part is used for reservation. printer, printer1 and AccessPoint_Sympol parts are name of the reservations. You have to define a MAC address in a hardware ethernet line and you have to define some reserved ip addresses in fixed-address line. if you use "authoritative" line (you can delete it), all of the clients will record themself to dns server. The last line is just for defining the logging level.

    Finally, you will need to start the service. You can use /etc/init.d/dhcp3-server shell script with start, stop, restart, force-reload or status options. If you execute that script without any parameter, it cats the possible options defined below:

    /etc/init.d/dhcp3-server
    Usage: /etc/init.d/dhcp3-server {start|stop|restart|force-reload|status}

    Wednesday, September 28, 2011

    How to configure site to site VPN profile on Linux,

    In this little page I will describe how to configure a vpn connection between two different networks. This connection is usually called site2site vpn.


    I used ipsectools and recoon projects to establish a vpn tunnel. In Debian distributions, to install required packages we type:

    # sudo apt-get install ipsec-tools racoon



    We have to edit some configuration files. I want to explain the related services using the sample configuration. We call Branche Office for the node on the left and central office for the other one. The vpn tunnel is shown in the picture above. The branche office, which is the one we are talking about is a Linux installed machine and the central office is using Nortel Contivity 1740 VPN BOX. The branch office has got 172.28.24.0 / 24 network address. The central office has got 172.28.0.0 / 16 network address. 172.28.0.0 / 16 is for to contain the brache office segment.

    But as you know, If you look at from branch office, all other branch offices are behind the central office. So first of all, we have to fix this problem.

    The problem is that, if we will define the destination network as 172.28.0.0/16, our vpn box device sends packets through the tunnel interface for accessing to 172.28.24.0 / 24 segment. But 172.28.24.0 / 24 segment is already connected to itself! In this sample, our vpn destination network is 0.0.0.0 / 0. Because, this is a branch office and we want to have full control on internet access requests from the branch office. The spd.conf file (/etc/spd.conf) seems like that;

    spdadd 172.28.24.0/24 172.28.24.0/24 any -P in none;
    spdadd 172.28.24.0/24 172.28.24.0/24 any -P out none;
    spdadd 172.28.24.0/24 0.0.0.0/0 any -P out ipsec ah/tunnel/bb.bb.bb.bb-aa.aa.aa.aa/require;
    spdadd 0.0.0.0/0 172.28.24.0/24 any -P in ipsec ah/tunnel/aa.aa.aa.aa-bb.bb.bb.bb/require;



    first two lines are required to fix the problem. Last two lines are required to establish vpn tunnel. These are define tunnel source/destination networks and tunnel source/destinatio ends. (aa.aa.aa.aa is ip address of vpn catcher device on the central office and bb.bb.bb.bb is ip address of branch office box. So it is our linux ip address.)

    This site to site vpn tunnel is using pre-shared key mechanism. So we need a pre-shared key configuration file. The file seems like that;

    aa.aa.aa.aa [pre-shared key]



    This file must be located in /etc/racoon directory in our defined system. The other configuration file that located in /etc/rac oon directory is racoon.conf:

    listen {
    adminsock "/var/run/racoon.sock" "root" "wheel" 0660;
    }
    path pre_shared_key "/etc/racoon/psk.txt";

    path certificate "/etc";

    remote aa.aa.aa.aa {
    exchange_mode aggressive;
    my_identifier fqdn "BranchOfficeName";

    peers_identifier address aa.aa.aa.aa;
    initial_contact on;
    ike_frag on;
    support_proxy on;
    proposal_check obey;

    proposal {
    encryption_algorithm 3des;
    hash_algorithm md5;
    authentication_method pre_shared_key;
    dh_group 2;
    }
    }

    sainfo address 172.28.24.0/24 any address 0.0.0.0/0 any {
    encryption_algorithm des,3des;
    authentication_algorithm hmac_sha1,hmac_md5;
    compression_algorithm deflate;
    lifetime time 5 min;
    pfs_group 2;
    }



    the racoon.conf file contains this tunnel configuration, source and destionation network addresses and some ipsec option selections. So you can select different encryption options in this file. But the important point is, each ends should have the same selections. bb.bb.bb.bb might be a problem for you if it's changeable. If this ip address is changeable, you have to recognize the current value and you have to update it in /etc/spd.conf file. And then, you have to update it on the running service. You can use setkey command to manage tunnel properties.

    setkey -D
    setkey -DP
    setkey -F
    /etc/init.d/setkey {start|stop|restart|force-reload}



    -D Dump the SAD entries, -F Flush the SAD entries and /etc/init.d/setkey is initialize shell script.

    If you create new spd.conf file in different path, you have to kill existing setkey process (or you can use '/usr/sbin/setkey -F -FP' command) and load new conf file with following command:

    kill existing setkey process;

    /usr/sbin/setkey -F -FP



    start setkey with new spd.conf file

    /usr/sbin/setkey -f /etc/spd.conf



    Finally, if your Linux box's public ip address is changable you can sense current ip address on external interface and update spd.conf file with following php script. It reads some informations from racoon.conf file. If you don't need these parts, you can mark the line with "#" to make it commented.

    The filename is createSpd.php (full path: /root/fwscripts/createSpd.php):

    #!/usr/bin/php
    <?php
    $k = 0;
    $i = 1;
    while($k < 5){
    $lan = exec("/sbin/ifconfig eth0 | /bin/grep 'inet addr' | /usr/bin/gawk -F ' ' '{print $2}' | /usr/bin/gawk -F ':' '{print $2}'");
    $wan = exec("/sbin/ifconfig ppp0 | /bin/grep 'inet addr' | /usr/bin/gawk -F ' ' '{print $2}' | /usr/bin/gawk -F ':' '{print $2}'");
    //$peer = 'aa.aa.aa.aa'; // you can use this line or following line.
    $peer = exec("/bin/grep remote /etc/racoon/racoon.conf | /usr/bin/gawk -F ' ' '{ print $2 }'");

    $localNet = exec("/bin/grep sainfo /etc/racoon/racoon.conf | /usr/bin/gawk -F ' ' '{ print $3 }'");
    $remoteNet = exec("/bin/grep sainfo /etc/racoon/racoon.conf | /usr/bin/gawk -F ' ' '{ print $6 }'");

    $blan = strlen($lan);
    $bwan = strlen($wan);

    echo "strlen($lan):$blan,strlen($wan):$bwan \n";

    if($blan < "6" || $bwan < "6" ) {
    echo "LAN or WAN hasn't got usable ip address.\n";
    echo "The script wait and will be try again!!! ($i) # # # # # # # # # # # \n";
    $i++;
    sleep(10);
    } else {
    echo "writing to /etc/spd.conf file as collected information:\n";
    exec("/bin/rm -rf /etc/spd.conf.old;/bin/mv /etc/spd.conf /etc/spd.conf.old");
    exec("echo 'spdadd 172.28.10.254/32 0.0.0.0/0 any -P out none;' > /etc/spd.conf");
    exec("echo 'spdadd 0.0.0.0/0 172.28.10.254/32 any -P in none;' >> /etc/spd.conf");
    exec("echo 'spdadd $localNet $localNet any -P in none;' >> /etc/spd.conf");
    exec("echo 'spdadd $localNet $localNet any -P out none;' >> /etc/spd.conf");
    exec("echo 'spdadd $localNet $remoteNet any -P out ipsec ah/tunnel/$wan-$peer/require;' >> /etc/spd.conf");
    exec("echo 'spdadd $remoteNet $localNet any -P in ipsec ah/tunnel/$peer-$wan/require;' >> /etc/spd.conf");
    $k = 5;
    }
    if($i > 5){
    $k = 7;
    }
    }
    echo "FNSH\n";
    ?>


    If you want to manage the setkey process with a shell script, you can practically use the following script.

    #!/bin/sh

    case "$1" in
    start)
    echo "Running ipsec VPN rules file: /etc/spd.conf";
    /root/fwscripts/createSpd.php
    /usr/sbin/setkey -f /etc/spd.conf
    ;;
    stop)
    echo "Remove ipsec VPN rules file: /etc/spd.conf"
    /usr/sbin/setkey -F -FP
    ;;
    restart)
    echo "Remove ipsec VPN rules file: /etc/spd.conf"
    /usr/sbin/setkey -F -FP
    echo "Running ipsec VPN rules file: /etc/spd.conf";
    /root/fwscripts/createSpd.php
    /usr/sbin/setkey -f /etc/spd.conf
    ;;
    *)
    echo "Usage: /etc/init.d/setkeyHandle {start|stop|restart}"
    ;;
    esac

    exit 0


    And then, if you want to add this script to boot progress, you can use update-rc.d command in Debian based Linuxs like following,

    # update-rc.d setkeyHandle defaults
    Adding system startup for /etc/init.d/setkeyHandle ...
    /etc/rc0.d/K20setkeyHandle -> ../init.d/setkeyHandle
    /etc/rc1.d/K20setkeyHandle -> ../init.d/setkeyHandle
    /etc/rc6.d/K20setkeyHandle -> ../init.d/setkeyHandle
    /etc/rc2.d/S20setkeyHandle -> ../init.d/setkeyHandle
    /etc/rc3.d/S20setkeyHandle -> ../init.d/setkeyHandle
    /etc/rc4.d/S20setkeyHandle -> ../init.d/setkeyHandle
    /etc/rc5.d/S20setkeyHandle -> ../init.d/setkeyHandle


    If you don't want to use default values, you can define your values in the update-rc.d command like following;

    # update-rc.d setkeyHandle start 20 2 3 4 5 . stop 80 0 1 6 .

    Passing plain Java objects to R using RCaller

    Well, you are using RCaller for your statistical calculations. Probably, you are passing your double arrays to R and type some R commands in order to get the desired outputs. After a calculation process, you handle the returned arrays through the parser. This is the general use of RCaller.

    Suppose that you have got a Java class which has got some variables with data types int, short, long, float, double and String. This class also includes some arrays of types int[], double[], ..., String[]. Of course it may include some functions, constructors or anything else. But we don't care about this for now.  How about passing this class with its publicly defined variables to R? Yeah! It is possible in its last submitted revision.

    Have a look at the Java class below:


    class TestClass {
    
      public int i = 9;
      public float f = 10.0f;
      public double d = 3.14;
      public boolean b = true;
      public String s = "test";
    }
    

    This class simply includes five publicly defined variables with basic data types. Our other class inherits the TestClass and defines some additional arrays:


    class TestClassWithArrays extends TestClass {
    
      public int[] ia = new int[]{1, 2, 3, 4, 5};
      public double[] da = new double[]{1.0, 2.0, 3.0, 4.0, 9.9, 10.1};
      public String[] sa = new String[]{"One", "Two", "Three"};
      public boolean[] ba = new boolean[]{true, true, false};
    }
    

    Ok, they are very simple but there is no reason those classes not to have any methods. Whatever those classes have methods, we consider them as data structures.

    Lets pass this data structure to R:


    TestClassWithArrays tcwa = new TestClassWithArrays();
        JavaObject jo = new JavaObject("tcwa", tcwa);
    
        RCaller rcaller = new RCaller();
        rcaller.setRscriptExecutable("/usr/bin/Rscript");
        rcaller.cleanRCode();
    
        rcaller.addRCode(jo.produceRCode());
        rcaller.runAndReturnResult("tcwa");
    


    Well, if there is no expection we have the results in a R list named "tcwa". This R list includes all of the elements that included in TestClassWithArrays and TestClass with their values.

    This is an example of proof, the related @Test method is ready for browsing in the Google Code:

    @Test
      public void TestClassWithArrays() throws IllegalAccessException, IOException {
        TestClassWithArrays tcwa = new TestClassWithArrays();
        JavaObject jo = new JavaObject("tcwa", tcwa);
    
        RCaller rcaller = new RCaller();
        rcaller.setRscriptExecutable("/usr/bin/Rscript");
        rcaller.cleanRCode();
    
        rcaller.addRCode(jo.produceRCode());
        rcaller.runAndReturnResult("tcwa");
    
        int[] expectedIntArray = rcaller.getParser().getAsIntArray("ia");
        for (int i = 0; i < tcwa.ia.length; i++) {
          assertEquals(expectedIntArray[i], tcwa.ia[i]);
        }
    
    
        double[] expectedDoubleArray = rcaller.getParser().getAsDoubleArray("da");
        for (int i = 0; i < tcwa.da.length; i++) {
          assertEquals(expectedDoubleArray[i], tcwa.da[i], delta);
        }
    
        String[] expectedStringArray = rcaller.getParser().getAsStringArray("sa");
        for (int i = 0; i < tcwa.sa.length; i++) {
          assertEquals(expectedStringArray[i], tcwa.sa[i]);
        }
    
      }
    

    It is shown that in examples, in R side, we can access to elements with their original names that defined in the Java class. That sounds good.

    Finally, we can pass our Java objects with defined contents. This use of RCaller narrows the code of addDoubleArray, addIntArray and reduce all of them to simple command of

     JavaObject jo = new JavaObject("tcwa", tcwa);
    .
    .
    .
    rcaller.addRCode ( jo.produceRCode() );
     
    
    It is simplicity...