linux tricks [en]

A few scripts and other tricks I store mainly for myself, but if they can be of use to you too...

Adding a form filter to SPIP

I recently needed to generate on the fly a text document from the field values of a form inside of a SPIP article. Based on the code I found by F.Quointeau to invoke a php script from a SPIP article, I wrote a filter that enabled me to solve my issue.

Usage

This code will allows us to place a tag

#FORM (filename)

within the body of an article and have it replaced by the content of an html template named „filename“ and placed in a directory named „formulaires“ at the root of our SPIP hierarchy.

The content of our template could look like :

<form enctype="multipart/form-data" method="post" name="postref">
<fieldset>
<legend style="caption-side: left;">Vos informations personelles</legend>
<table width="100%" border="0">
  <tr>
    <td width="200">
      <label for="PRENOM">N:</label>
    </td><td>
      <input maxlength="80" size="40" name="PRENOM" value="<!--%PRENOMf%-->">
    </td>
  </tr><tr>
    <td width="200">
      <label for"NOM">Nom :</label>
    </td><td>
      <input maxlength="80" size="40" name="NOM" value="<!--%NOMf%-->">
    </td>
  </tr>
</table>
<input name="submit" value="Valider" type="submit"><br>
</form>

<h2> Ceci est le texte qui sera remplacé </h2>

<p> Bonjour, je m'appelle <!--%PRENOM%--> <!--%NOM%--></p>

In order for out filter to be called, we need to modify the squelette that will use it so that the filter is added as a parameter of the #TEXTE tage. Ex :

(#TEXTE|form_nb)

Code

<?php
/*****************************************************************************/
/**  Cette fonction permet de placer un formulaire de génération de texte
/**
/**  La syntaxe est la suivante :
/**    #FORM ( nom_fichier )
/**
/**  Auteur  : N.Barcet
/**  Version : 0.0.1
/**  Date    :  13 Avril 2007
/*****************************************************************************/

function form_nb ( $texte ) {

    // Dossier où sont stockés les formulaires
    $dossier_inclus = 'formulaires/';


    // Les fichiers inclus autorises sont :  *.htm, *.html, *.tpl
    $chaine_recherche = '/#FORM( *)\(( *)([^\)]*\.(tpl|htm|html))( *)\)/i';

    // Recherche la chaine #FORM(form)
    while( preg_match( $chaine_recherche, $texte, $resultats)) {

                // Verifie que le fichier existe
                if( file_exists ( $dossier_inclus . $resultats[3])) {
                        // Vide le buffer de sortie
                        $affichage_php = '';

                        //Liste des champs que nous devons traiter dans le formulaire
                        $fields = array("PRENOM","NOM");

                        $file = $dossier_inclus . $resultats[3];

                        //On récupère le contenu de la template du formulaire
                        $fd = fopen($file, "r");
                        $doc = fread($fd, filesize ($file));
                        fclose($fd);

                        //Remplace les champs par leur valeur
                        $size = count($fields);
                        for ($i=1 ; $i <= $size; $i++) {
                          $doc = str_replace("<!--%".$fields[$i]."%-->",  htmlentities(utf8_decode($_POST["$fields[$i]"])), $doc);
                          $doc = str_replace("<!--%".$fields[$i]."f%-->",  $_POST[$fields[$i]], $doc);
                        }

                        //retourne le formulaire complet
                        $affichage_php = $doc;
                } else {
                        $affichage_php = "<b>#INCLURE: Le fichier de formulaire n'existe pas !</b>";
                }
        // Attention, n'effectue qu'un seul remplacement à la fois !
        $texte = preg_replace( $chaine_recherche, $affichage_php, $texte, 1);
    }

    return( $texte);
}
?>

Automatically configure your wlan settings

I use the following script to easily configure my wlan connexions.

It can be used in 3 ways :

1 - no parameters : it is going to detect automatically available wlan and connect me automatically to the first know one as found in /etc/sysconfig/network/wlan/.

2 - eth0 : deactivates wlan0 and activate eth0

3 - conf name : it directly applies a conf whose name is found in /etc/sysconfig/network/wlan/

I have added to my K menu the following 3 entries :
- iwautoconfig eth0
- iwautoconfig
- iwautoconfig barnucopia
To make switching network easier.

I use it on Suse Linux Pro 9.3 with great success...

#!/bin/bash
#
# Usage:  iwautoconfig [eth0|wlanconfname]
# 
# Automatically configures wlan based on the findings of
# known networks compared to available networks.
# Use param eth0 to disable your wlan interface and 
# enable eth0.  If you specify a wlanconfname, it must be
# the name of a valid conf file that will be used without
# searching for it.
#
# You need to have a dir specified by WLAN that contains
# various valid config file.  Name of the file should be
# the essid of the network it applies to.  To add a new
# network, configure it using yast, then copy the file
# /etc/sysconfig/network/ifcfg-{interface} to the wlan dir.
# If no network seems to match, the config file named 
# 'default' will be used.
#
# Note that the user executing this command must be 
# configured as a sudoer...
# 
# Author : nicolas@barcet.com

##### CONSTANTS :
# WLAN : Specify the dir where valid config are stored
WLAN=/etc/sysconfig/network/wlan/

# NETWORK : Place here the root name of the config file
NETWORK=/etc/sysconfig/network/ifcfg-

# INTERFACE : name of the interface to be configured
INTERFACE=wlan0


CONFDIR=$(sudo ls $WLAN)  # Get list of valid configurations
ESSID=""

if [[ $1 != "eth0" ]]; then
	sudo /sbin/ifdown eth0 &> /dev/null
	sudo /usr/sbin/iwlist wlan0 scanning > /tmp/iwlist.tmp # Retrieve list of advertised wlan

	if [[ $1 != "" ]]; then
		ESSID=$1
	else	
		# search in list of available conf a net that is available
		for NN in $CONFDIR ; do
			if [[ `cat /tmp/iwlist.tmp | grep $NN`  != "" ]]; then 
				ESSID=$NN
				break;
			fi;
		done
	fi;
	
	# if we did not find any valid net, use default
	if [[ $ESSID == "" ]]; then 
		ESSID=default
	fi;
	
	#copy the good conf to make is active
	sudo cp $WLAN$ESSID $NETWORK$INTERFACE

	#set iwconfig appropriately
	source $WLAN$ESSID # Read the var values from the file
	if [[ $WIRELESS_AUTH_MODE == open ]]; then 
		WIRELESS_KEY_0='off' 
	fi;
	sudo iwconfig $INTERFACE rate $WIRELESS_BITRATE
	sudo iwconfig $INTERFACE mode $WIRELESS_MODE
	sudo iwconfig $INTERFACE enc $WIRELESS_KEY_0
	sudo iwconfig $INTERFACE essid $WIRELESS_ESSID
	sudo iwconfig $INTERFACE commit
	
	#force full reload if conf has changed from before
	if [[ $ESSID != `iwgetid wlan0 -s -r` ]]; then
		echo Found : $WIRELESS_ESSID - Forcing conf reload...
		sudo /sbin/ifdown $INTERFACE &> /dev/null
		sudo /sbin/ifup $INTERFACE &> /dev/null
	else
		echo Found : $WIRELESS_ESSID - No Change
		sudo /sbin/ifup $INTERFACE &> /dev/null
	fi;
	
	#set iwconfig again !!! Just to make sure
	sudo iwconfig $INTERFACE rate $WIRELESS_BITRATE
	sudo iwconfig $INTERFACE mode $WIRELESS_MODE
	sudo iwconfig $INTERFACE enc $WIRELESS_KEY_0
	sudo iwconfig $INTERFACE essid $WIRELESS_ESSID
	sudo iwconfig $INTERFACE commit
	
	sleep 10
	
	#Are we now really connected ?
	NEWESSID=`iwgetid $INTERFACE -s -r`
	if [[ $NEWESSID == "" ]]; then
		echo ERROR !! Not connected to anything...
		echo 'Available nets follows :'
		grep ESSID /tmp/iwlist.tmp
                kdialog --passivepopup "ERROR !! Not connected to anything..." 30 &> /dev/null &
	else
		echo ---------------------------------------
		echo Now connected to $NEWESSID
		echo ---------------------------------------
                kdialog --passivepopup "Now connected to $NEWESSID" 30 &> /dev/null &
	fi;
	rm /tmp/iwlist.tmp
else
	#We want to switch back to eth0
	sudo /sbin/ifdown $INTERFACE &> /dev/null
	sudo /sbin/ifup eth0 &> /dev/null
fi;


Check the status of an md device

The following script allows to check the satus of an md device, and therefore to know if a disc from a raid is faulty. It is done by storing the result of cat /proc/mdstat the first time the script is called, then by comparing it to the current output on following calls.

#!/bin/sh
#
# RAID monitor
#
BASE_FILE=/etc/mdstat.ok
DIFF_FILE=/tmp/mddiff$$.out
#
# make the comparison template
#
if [ ! -s ${BASE_FILE} ]
then
   if [ "0" != "`id -u`" ]
   then
      echo "Must be 'root' to run this script for the first time!"
       exit 0
   fi
   cat /proc/mdstat >${BASE_FILE}
fi
#
# compare current mdstat with saved good version
#
diff -C1 ${BASE_FILE} /proc/mdstat >${DIFF_FILE}
if [ -s ${DIFF_FILE} ]
then
   rm -f ${DIFF_FILE}
   echo "Raid problem ??"
   exit 1
fi
rm -f ${DIFF_FILE}
echo "Raid OK"
exit 0

How-to configure NLD9 to allow multiple VNC logins

The following How-to explains how to configure Novell Linux Desktop 9 (or Suse Linux in general) with Gnome in order to allow multiple session loging in from VNC.

Security warning: Beware that this is not a secure solution as is for multiple reasons and should not be setup on the internet without tuneling it through ssh as all information will transit unencrypted otherwise.

1 – Login as root, or execute the following as such

2 – Enable Remote Administration in Yast :
In the system menu, select Administrator settings -> this launches yast
In yast, select "Network Services", then click on "Remote administration"
In the window that appears select "Allow remote administration" then click on "Finish"
Close the yast window

3 – Edit file /etc/X11/xdm/Xaccess and add a line :

* #any host can get a login window

4 – Edit the file /etc/opt/gnome/gdm/gdm.conf and check the settings values below, all other settings to remain untouched :

	[daemon]
	RemoteGreeter=/opt/gnome/bin/gdmgreeteremon
	
	[xdmcp]
	Enable=true
	MaxSessions=16
	DisplaysPerHost=5
	PingIntervalSeconds=15

5 – Edit the file “/etc/xinetd.d/vnc”, find section "vnc1" and add arguments "-kb -noloadxkbd" to the server_args parameters. Resulsuting section should look like :

service vnc1
{
        socket_type     = stream
        protocol        = tcp
        wait            = no
        user            = nobody
        server          = /usr/X11R6/bin/Xvnc
        server_args     = :42 -inetd -once -query localhost -geometry 1024x768 -depth 16 -kb -noloadxkb
        type            = UNLISTED
        port            = 5901
}

6 – Reboot the computer or do "rcxdm restart; rcxinetd restart" after login off and switching to console 0 (don't do it from the graphical environment as it will kill it ;-)

7 – You should be able to login using vnc to @server:5901 or from a browser at http://@server:5801/

LDAP to Mailman

I maintain various web sites which use LDAP to maintain information about users. I often need these user to be subscribed to mailing lists based on groups or other attributes stored in the LDAP directory. The following script, called regurlarly with a few appropriate parameters will do just that :

#! /bin/sh
# mmldap : An ldap extractor for mailman
#
# Usage: mmldap <listname> <base> <filter> [<listoptions>]
#  <listname> is the name of and existing mailman list
#  <base> is the basedn for ldapsearch
#  <filter> is the ldap filter for ldapsearch
#  <listoptions> are the parameters passed to mailman's sync_members command
#     defaults are : -a -w=no -g=no
#
# Example :
#   mmldap MyList ou=users,o=test "(&(objectclass=user)(mail=*@*)(subscribeML=true)(!(logindisabled=true)))
#
# Author : nicolas@barcet.com


## You can define here the ice command option. Type ice on the command prompt
## for more help.
LDAPOPTIONS=""

#set default is nothing set above
if (test LDAPOPTIONS="") then
        # by default will connect anonymously to localhost with a subtree search
        LDAPOPTIONS="-s sub -h localhost"
fi

case "$1" in
    -h)
        cat $0.help
        ;;

    --help)
        more $0.readme
        ;;

    *)
        if (test -n "$3") then
                LISTNAME=$1
                BASE=$2
                FILTER=$3

                echo "$0 invoked at `date` for $LISTNAME"

                if (test -n "$4") then
                        OPTIONS=$4
                else
                        OPTIONS="-a -w=no -g=no"
                fi

                ldapsearch $LDAPOPTION -b $BASE -x $FILTER mail | grep mail: | awk '{print $2}' > /tmp/maillist
                /usr/lib/mailman/bin/sync_members $OPTIONS -f /tmp/maillist $LISTNAME
                rm /tmp/maillist

        else
                echo "  Usage: $0 <listname> <base> <filter> [<listoptions>]"
                echo "  <listname> is the name of and existing mailman list"
                echo "  <base> is the basedn for ldapsearch"
                echo "  <filter> is the ldap filter for ldapsearch"
                echo "  <listoptions> are the parameters passed to mailman's sync_members command"
                echo "     defaults are : -a -w=no -g=no"
        fi
        ;;
esac


SQL to Mailman

I also maintain various web sites which use MySQL to maintain information about users. I often need these user to be subscribed to mailing lists based on groups or other attributes stored in the database. The following script, called regurlarly with a few appropriate parameters will do just that :


#! /bin/sh
# mmsql: An sql extractor for mailman
#
# Usage: mmsql      []
#   is the name of and existing mailman list
#   is the name of an existing mysql db
#   is the username to login to mysql
#   is the password to login to mysql
#   is the select clause to run
#   are the parameters passed to mailman's sync_members command
#     defaults are : -a -w=no -g=no
#
# Example :
#   mmsql MyList MyDB user password "SELECT email FROM users"
#
# Author : nicolas@barcet.com


case "$1" in
    -h)
        cat $0.help
        ;;

    --help)
        more $0.readme
        ;;

    *)
        if (test -n "$3") then
                LISTNAME=$1
                BASE=$2
                USER=$3
                PWD=$4
                SELECT=$5

                echo "$0 invoked at `date` for $LISTNAME"

                if (test -n "$6") then
                        OPTIONS=$6
                else
                        OPTIONS="-a -w=no -g=no"
                fi

                mysql $BASE -B -u $USER -p$PWD -e"$SELECT" | awk "/@/ { print }" >/tmp/maillist
                /usr/lib/mailman/bin/sync_members $OPTIONS -f /tmp/maillist $LISTNAME
                rm /tmp/maillist

        else
                echo " Usage: mmsql      []
   is the name of and existing mailman list
   is the name of an existing mysql db
   is the username to login to mysql
   is the password to login to mysql
   is the select clause to run
   are the parameters passed to mailman's sync_members command
     defaults are : -a -w=no -g=no"
        fi
        ;;
esac


SuSE Linux 10.1 on my IBM T43 Laptop

I have just finished installing and configuring SuSE Linux 10.1 on my IBM T43 laptop and I must say that I am quite happy with the results. I had to fight with a few things to put on it everything I wanted, but the result is just great.

What works :

What does not work :

Software I installed :

Here are the steps I went through to do this :

1 - Download and install

Here I have chosen to download the DVD image that can be found on many mirrors. Personally I picked the french mirror at cict.

Once burned on a DVD, installation was pretty straight forward, but in order to have my ipw2945 wireless lan card be functional I made sure to add to the default selection of packages the "Non-Open Source Packages" which contains, among other the daemons, drivers and firmware for Intel cards.

Full install took about an hour, with only one reboot.

3 - Configure your installation source

In order to have any of the following steps work, you'd better modify your installation sources. This is necessary because

Doing so with the graphical interface is quite easy (right click on the software update icon in the icon tray and select configure), but here is how to do so using the command line:
#rug sa http://ftp.gwdg.de/pub/linux/misc/suser-guru/rpm/10.1/RPMS/ guru
#rug sub guru
#rug sa http://packman.mirrors.skynet.be/pub/packman/suse/10.1/ packman
#rug sub packman
#rug sa http://opensuse.cict.fr/distribution/SL-10.1/inst-source/suse/ install
#rug sub install

Other advantage of this: you do not need to have the DVD with you if you need to add additional software...

3 - Install the ATI M300 drivers from ATI

This step was maybe the most complicated one. Gladly I found a how-to at linux.wordpress.com. Not all went as described, here is precisely what I have done.

  1. First of all, make sure you have installed the following packages :

    • compat-expat1
    • kernel-source
    • gcc
    • make

    For this I used zlm installation tool which is found in the Gnome menu Applications > System > Configuration > Install software. It works almost as nicely as the equivalent apt graphical tool synaptic found on ubuntu, if not a bit slower... Just make sure you have modified your installation sources as described above. Note that some people have had problem if they had not rebooted once prior to using it.

  2. Execute the following commands as root :
    #cd /usr/src/linux
    #make mrproper
    #make cloneconfig
    #make modules_prepare
    #make clean
    #rpm -e $(rpm -qa | grep fglrx)
  3. Download the drivers from ATI using Firefow or your favorite browser. It is found in "ATI Customer care > Drivers and software > Linux > Linux x86 > Radeon" and click on download on the line that says "ATI Driver Installer". Make sure you remember where you put the file. Personally I put it /home/nbarcet/tmp/. I ended up with a file titled ati-driver-installer-8.25.18-x86.run
  4. Exit the graphical environment:
    #init 3
  5. Log in as root and cd to the folder where you downloaded the above file
  6. build, install and configure the package:
    #sh ./ati-driver-installer-8.25.18-x86.run --buildpkg SuSE/SUSE101-IA32
    #rpm -ivh fglrx_6_9_0_SUSE101-8.25.18-1.i386.rpm
    #ldconfig
    #aticonfig --initial --input=/etc/X11/xorg.conf
    #sax2 -r -m 0=fglrx
  7. Restart the graphical environment:
    #init 5

    and login
  8. Verify that you see the following after executing the command fglrxinfo:
    #fglrxinfo
    Xlib: extension "XFree86-DRI" missing on display ":0.0".
    display: :0.0 screen: 0
    OpenGL vendor string: ATI Technologies Inc.
    OpenGL renderer string: MOBILITY RADEON X300 Generic
    OpenGL version string: 1.2 (2.0.5814 (8.25.18))
  9. Same with glxinfo:
    #glxinfo
    name of display: :0.0
    Xlib: extension "XFree86-DRI" missing on display ":0.0".
    display: :0 screen: 0
    direct rendering: No
    server glx vendor string: SGI
    server glx version string: 1.2
    server glx extensions:
    GLX_ARB_multisample, GLX_EXT_visual_info, GLX_EXT_visual_rating,
    GLX_EXT_import_context, GLX_EXT_texture_from_pixmap, GLX_OML_swap_method,
    GLX_SGI_make_current_read, GLX_SGIS_multisample, GLX_SGIX_hyperpipe,
    GLX_SGIX_swap_barrier, GLX_SGIX_fbconfig
    client glx vendor string: ATI
    client glx version string: 1.3
    client glx extensions:
    GLX_EXT_visual_info, GLX_EXT_visual_rating, GLX_EXT_import_context,
    GLX_ARB_get_proc_address, GLX_ARB_multisample, GLX_ATI_pixel_format_float,
    GLX_ATI_render_texture
    GLX extensions:
    GLX_EXT_visual_info, GLX_EXT_visual_rating, GLX_EXT_import_context,
    GLX_ARB_multisample
    OpenGL vendor string: ATI Technologies Inc.
    OpenGL renderer string: MOBILITY RADEON X300 Generic
    OpenGL version string: 1.2 (2.0.5814 (8.25.18))
    [...]
  10. Go back to graphical mode:
    #init 5
  11. Your card should be enabled with 3D!

4 - Enable 3D Desktop effet

Once the above is done, we need to

  1. install the following packages :

    • xgl
    • compiz
  2. Configure the 3D effect from the Gnome Control Center > Desktop Effect Settings
  3. In the first pane of the control panel, click on "Update 3D Desktop settings"
  4. This should prompt you to log out : do so to restart X
  5. Log back in and look at the configuration options you have in the other panes of the 3D Desktop settings
  6. Close the panel : 3D effects are now enabled! Have fun.

Ubuntu 7.10 (Gutsy) on my MacBookPro 3.1 (SantaRosa)

Starting my new job at Ubuntu was a lot of fun. It also gave me the opportunity to buy what I think is one excellent piece of hardware, a MacBook Pro 15".

Setting it up was quite fun as I started with the development version of Gutsy. Now that it is in beta, everything works well if you follow the instruction at https://wiki.u­buntu.com/…ro­/SantaRosa. I've updated the instructions a bit as I went along and wrote a little daemon script to help me have a cooler laptop. You'll be able to find it there, and more precisely at https://wiki.u­buntu.com/…sa­FanControl

Have fun with your Ubuntu on a Mac :)

Ubuntu JeOS Virtual Appliance Tutorial

Last month I have written with Soren Hansen a little tutorial on how to create a virtual appliance using JeOS. It's on Ubuntu's docu­mentation community wiki at https://help.u­buntu.com/com­munity/JeOS.