Mihamina Rakotomandimby

To content | To menu | To search

Wednesday 18 January 2012

Entreprise, formation, langues, développement personnel, madagascar

Dans mon fil de nouvelles, j'ai remarqué 2 liens:

Dans un précédent billet annonçant ma nouvelle prise de fonction, j'ai parlé de mes différentes tâches.

Continue reading...

Tuesday 3 January 2012

headers check for mailing list and autoreply

Autoresponder and mailing lists

I am subscribed to much mailing lists, and espacially on holidays, I notice many people set their autoresponders to reply to the mailing list.
It's annoying and whenever possible should be avoided, by checking several headers befor autoreplying.

Headers to check and patterns

Mailing lists have pretty verbose footprints. Unfortunately, There is no standard I know about that, but there is a simple enumeration of what headers and patterns a mailing list has.

Return-Path: and Sender:

Return-Path: and Sender: match owner\-\.+@, ^\.+\-request@, and ^\.+\--bounces@

List-ID: or X-Mailing-List:

If there is a List-ID: or X-Mailing-List: header, it's probably from a mailing list!

To: or Cc:

If you receive an email, but you're not in the To: or Cc:, then you probably should avoid autoreplying.

"Precedence: Bulk" or "Precedence: List"

A little documentation about the "Precedence:" header where we see that "bulk" value mean the message is a "one-to-many" (typical for mailing lists)

Conclusion

We then have a set of criteria to check, have a good time... :-)

Monday 2 January 2012

Sas 02 et Mercurial

Avant d'aller plus loin dans le développement d'application, il est nécessaire de maîtriser l'outil utilisé en interne pour collaborer: Mercurial.

Continue reading...

Thursday 29 December 2011

Situation légale Internet Madagascar

Le microcosme Internet est dans une situation ambigüe à Madagascar.

Continue reading...

Monday 19 December 2011

Sas 02 et HTML

Produire du HTML de qualité nécessite un peu plus que des notions "académiques". Beaucoup croient que l'intégration n'est pas une tache d'ingénieur: ils ont tort. De plus, chez Ideo Neov, un Intégrateur fait désormais beaucoup de Javascript et porte l'intégration vers les mobiles.

Continue reading...

Monday 12 December 2011

sas 02 et HTTP

Dans le développement web, nous sommes en permanence confronté à HTTP.

Continue reading...

Friday 9 December 2011

sas 02 démarrage

Le sas de formation, seconde session a démarré aujourd'hui.

Continue reading...

Thursday 1 December 2011

Emails Jirama récoltés

J'ai cherché sur Google comment envoyer des emails à la Jirama, voici les résultats.

Continue reading...

nostalgie

En lisant un article du blog R&D d'Ideo Technologies et en y suivant un lien proposant de m'expliquer ce qu'est un petit chef, cela m'a rappelé des grands moments de ma vie passée...

Attention, je ne nomme personne, et toute ressemblance avec quoi que ce soit est fortuit.

Continue reading...

Friday 25 November 2011

Le malgache veut vendre

Vendre, faire du marketing, c'est montrer qu'on est un professionel. Voici comment certains s'y prennent...

Continue reading...

Monday 21 November 2011

sas 01 et jelix

Il y a quelques semaines, le sas 01 s'est vu confier la tâche de coder un espèce d'espace de travail numérique. Il fallait partir "from scratch" sans utiliser de framework PHP. Les framework jQuery était autorisé. Maintenant, il est demandé de recoder l'espace de travail mais en utilisant Jelix.

Continue reading...

Monday 14 November 2011

Sas 01 et theme Drupal

Apprendre à faire un thème Drupal 6 puis Drupal 7.

Continue reading...

Thursday 10 November 2011

sas 01 et approfondissement des workflow

J'ai demandé aux élèves du sas de formation de me reproduire le workflow suivantavec Drupal:un workflow Il s'agit d'un Workflow par défaut sur Plone, je l'ai chois pour l'exercice.

Continue reading...

Tuesday 8 November 2011

Etude Drupal 7 dans le sas 01

Ideo Neov est acteur dans le développement autour de Drupal, les éléments du sas de formation doivent passer par l'apprentissage du développement avec Drupal.

Continue reading...

Friday 28 October 2011

On fusionne les branches et on observe

Sur le mini-projet PHP ENT-EIN, nous allons fusionner les branches de développement.

Continue reading...

Friday 21 October 2011

Finalement, on recommence

Nous vîmes que nous etions dans l'erreur, reprenons du début.

Continue reading...

Wednesday 19 October 2011

Au commencement

Commencer un projet de zero...

Continue reading...

Monday 17 October 2011

Focus sur jQuery

HTML, Javascript, puis jQuery

Continue reading...

Thursday 13 October 2011

actuellement directeur de formation et ressources humaines

Parcours précédent

Ceux qui me fréquentent savent que j'ai travaillé chez Blueline, mais ne savent pas tous que j'ai depuis changé d'employeur. Ce billet est entre autres pour leur informer de ce fait

Actuellement, Directeur de formation et RH

Je dirige actuellement le département de formation d'IdeoNeov. Mon job consiste à former les nouvelles recrues à nos outils et technologies ainsi qu'encadrer les stagiaires de fin d'études qui sont dans nos mûrs.

Concrètement, immersion préalable

Pour aller plus en détails, mon rôle consiste à immerger tous les "nouveaux" à nos outils de travail:

  • HTML, qui est notre produit de base
  • Mercurial, notre gestionnaire de source que nous comptons remplacer par Git à terme
  • Javascript, PHP, Java,... qui nous servent à produire du HTML
  • MySQL, qui nous sert de système de base de données principal

Quand nous recrutons, nous avons constaté le besoin d'un tronc commun d'immersion pour habituer la nouvelle recrue à nos conventions d'usage et d'organisation. Et quand bien même nous ne selectionnons que les meilleurs au recrutement, nous avons l'expérience des pièges dans lesquels certains seniors de l'entreprise sont tombés. Des sessions de formation sont concues et organisées pour prévenir et contourner ces faiblesses du passé.

Depuis Aout 2011

Ainsi, depuis le début du mois d'Aout 2011, j'officie en tant de directeur de la formation et du développement des compétences chez Ideo Neov (Madagascar). C'est un poste qui me donne la possibilité:

  • D'enseigner: transmettre ce que je sais
  • Diriger: décider et trancher de ce qui doit être fait et comment le faire
  • Prendre des initiatives spontannées: pouvoir changer le cours des choses en fonction de beaucoup d'évènements imprévisibles

Pour en discuter avec moi

J'ai vocation à recevoir du monde, discuter, me tenir au fait de ce qui se fait,... Pour me rencontrer, rien de plus facile, mes coordonnées sont disponibles un peu partout sur Internet, à commencer par sur ce blog.

Tuesday 11 October 2011

Apres le HTML, Javascript

Apres le HTML, Javascript

Maintenant que nous avons pris le temps d'aborder HTML via un exercice d'intégration HTML, nous pouvons passer à l'étape suivante qui est Javascript

Javascript de base

Avant de manipuler les documents avec les frameworks comme jQuery, Mootools, Prototype,... nous allons dans un premier temps aborder "les bases". De nos jours, peu de gens utilisent Javascript de cette façon mais il est primordial de savoir comment les choses se passent au plus bas niveau avant de manipuler des outils qui font abstraction de ces bases-là.

Qu'avez-vous appris?

En utilisant les commentaires à ce billet, Racontez votre parcours et les choses que vous avez découvert dans le sas de formation que vous êtes actuellement en train de suivre.

Friday 7 October 2011

Un peu de CSS et de Mercurial mais encore

Qu'avez-vous appris dans le sas de formation d'Ideo Neov durant cette journée?

Continue reading...

Saturday 1 October 2011

facebook mistake disable account

Arguing I have a virus on my computer, My facebook account was disabled. I had to log via the "computer version" and attest I ran all the virus check before being able to use Facebook again.

Continue reading...

Tuesday 27 September 2011

mon nouveau samsung galaxy s II

Content...

"Fan" de Linux, et heureux propriétaire d'un Galaxy S GT-i9000, j'ai acquis un Samsung Galaxy S II. De ce que je sais, les Américain n'ont pu aussi en acheter que ce mois-ci. J'ai certainement tort, peu importe, il est là... avec moi. Et je suis content.

Mon Samsung Galaxy S II

Je ne suis pas spécialiste de la marque ni des détails, J'ai un Samsung Galaxy S II, GT-i9100. D'origine sous Android 2.3.3, Mais que je compte flasher rapidement en 2.3.5.

Mon impression

Je compare le nouveau S II à mon ancien S I.

Ecran

L'écran semble à priori plus "jaune" que celui de précédent. C'est juste un a priori, c'est en fait la gestion de la luminosité en fonction de la lumière ambiante qui est différente. La différence de taille par rapport à l'ancien n'est pas très sensible lors des pointages de boutons et de liens. Par contre, on sens un que finalement les boutons sont un peu plus grands sur le clavier virtuel. C'est bien mieux.

Performances

Le dual core est clairement sensible, et l'OS sous-jacent est multitache, c'est un téléphone (oups, l'insulte!!) performant. Malheureusement pour les gamers, je n'aime pas les "jeux". Je prefère les outils de "travail". La vitesse de rendu d'un PDF est améliorée. Par défaut, j'ai "Polaris Office" sur le SII alors que j'avais "Think Free" sur le S I. Par contre, la Bible se charge encore "aussi lentement" (switch d'une langue à l'autre: MG, EN, FR).

Camera

Les 2 cameras (front & back) sont bien meilleures. J'ai un flash LED qui permet de filmer à 3m dans la pénombre, ça me suffit.

Globalement

Bon modèle. J'étais un inconditionnel de Nokia, mais depuis l'apparition des Galaxy S, mon coeur a basculé. Et en attendant la sortie des Motorola haut de gamme, je pense que je suis un téléphoneur comblé. Le temps de ce post soit référencé et trouvé, il y aura certainement de snouveraux modèles sur le marché et mon S II sera obsolète, mais je tiens à féliciter Samsung, Google, et tous ceux qui ont travaillé pour ce produit. L'une des actions que je fais pour eux est d'acheter leur produit.

Tuesday 30 August 2011

xubuntu early lightdm bug

My system

I have a Natty system where I wanted to early install GTK3 ported packages such as Evince, LightDM,...

To do so, I just temporarily enabled Oneiric repositories (without no more pinning configuration, I love my hairs) then installed

Ecountered problems

I got the lightDM login screen without problem. For some obscur reasons, I had to disable splashscreen at boot. That doesn't disturb me, I love seeing lines on my screen, it's an indication that things are going on.

But, after entering my credentials and choosing "Xubuntu Session" or "Xfce Session", I just got a framebuffer screen with a mouse pointer. Not more. I can escape from that state with "Ctrl-Backspace".

I joined the bug huntings:

Solution for me

Completely disappointed, I randomly tried to enter a "guest" session on the computer and the Xfce environment launched.

I tried then to move out all my $HOME files and directories and gave a try: It worked!

So, something in my ".config/" or any dotfile prevented Xfce to launch.

If you encouter that bug, try oyrself and tell me!

Thursday 25 August 2011

ocaml random string and word generation

Goal

I had to insert sample data in a database:

  • Users
    • username
    • enabled
  • Products
    • name
    • description
    • price
All should be random, and to "benchmark" the rendering (HTML/CSS), I must make the effort to have different text and number length. I decide to generate the sample data with OCaml.

Random Int

Generate a random integer between 1 and 1000 and return it as a string:

        let rand_price () = string_of_int (1+ (Random.int 999)) ;;
      

Random Char

Generate a random lowercase character (between 'a' and 'z'). 'a' ASCII code is 97 and the 26 following letters are the 26 following numbers:

    
        let rand_chr () = (Char.chr (97 + (Random.int 26)));;
      

Random vowel

Generate a random character until it matches a vowel. Please add a comment if you would suggest another algorithm:

    
        let rec rand_voy () = 
        let got = (rand_chr ())
          in 
          match got with 
            | 'a' | 'e' | 'i' | 'o' | 'u' | 'y' ->  got 
            | _ -> rand_voy ();;
      

Random consonant

Generate a random character until it doesnt matche a vowel. Please add a comment if you would suggest another algorithm:

        let rec rand_con () = 
          let got = (rand_chr ())
            in 
            match got with 
              | 'a' | 'e' | 'i' | 'o' | 'u' | 'y' ->  rand_con ()
              | _ -> got ;;
      

Random syllable(s)

In this document, a syllable is a consonant followed by a vowel. Generate a finite number of random syllables:

        let rec rand_convoy acc syll_number () =
          match syll_number with 
            | 0 -> acc;
            | _ -> rand_convoy (acc ^ (Char.escaped (rand_con ())) ^ (Char.escaped(rand_voy()))) (syll_number - 1) ();;
      
The final goal is to use all this as a "string", so we make "char" to "string" conversion at this level with the "Char.escaped" function.

Random short word

Short word: between 3 and 6 syllables.

        (* mot: entre 3 et 6 syllabes *)
        let rand_word () = (rand_convoy "" (3 + (Random.int 3)) ());;
      
Wel will also need a fixed length word, of 4 syllables.
 
        (* nom: 4 syllabes c'est tout *)
        let rand_name () = rand_convoy "" 3 ();;
      

Random sentence

Random sentence is a random number of random words. We will limit the number of words (to avoid bloating the database). Wel will end the sentences with a ".".

        let rec rand_sentence acc word_number () =
          match word_number with 
            | 0 ->               (acc ^ (rand_word ()) ^ ".");
            | _ -> rand_sentence (acc ^ (rand_word ()) ^ " ") (word_number - 1) ();;
      

Utilities

Generate a "description", and quote a string in preparation for INSERT in the database:

        let rand_description () = rand_sentence "" (10 + (Random.int 10))  ();;
        let sql_quote a_string = "'"^a_string^"'";;
        let generate_insert_user () = "INSERT INTO users VALUES ("^sql_quote (rand_name ())^" ,1)" ;;
        let generate_insert_product p_id  = 
          "INSERT INTO products VALUES ("^(string_of_int p_id)^", '"^(rand_name ())^"', '"^(rand_description ())^"', "^(rand_price ())^")";;
      

SQLite filling

SQLite manipulation has already been introduced in another post.

        let db = Sqlite3.db_open "/var/www/database.db";;

        Sqlite3.exec db (generate_insert_user ());;
        let rec fill_users number = 
          match number with 
            | 0 -> ()
            | _ -> 
              Sqlite3.exec db (generate_insert_user ()) ; 
              fill_users (number-1); 
              ();;
        
        let rec fill_products number =  
          match number with 
            | 0 -> ()
            | _ -> 
              Sqlite3.exec db (generate_insert_product number) ; 
              fill_products (number-1); 
              ();;
      

Wednesday 17 August 2011

ocaml sqlite3 date

Use case

I have a SQLite3 database, with Date, Integers and Float fields. I use it to make a poor-man accountig of my ppp0 interface traffic. Data I want to play with are in the format:

$ sqlite3 accouting-copy "SELECT * FROM ifconfig"
1|2011-08-12 09:37:47|0.0       |0.0
2|2011-08-12 09:43:01|18629153.0|8124895.0
3|2011-08-12 09:43:03|18636044.0|8125679.0
4|2011-08-12 09:44:32|18694283.0|8159197.0
5|2011-08-12 09:50:01|19203494.0|8270963.0
6|2011-08-12 09:55:01|19265098.0|8311962.0
Where:
  • Field #1: integer, incremental
  • Field #2: date, SQLite "DATETIME('NOW')"
  • Field #3 and #4: Float, "RX" and "TX" counters parsed from "ifconfig ppp0". Sometimes, these counters reset: If the modem hangs and I must perform a "ifdown ppp0; ifup ppp0". That is why I need computation.

I want to account the traffic:

  • Between to Dates: To know how much I had for a given month
  • From a given Date to Now(): To approximately know my remaining traffic

I am not going to care about to computing logic in this article, but focus on data extraction.

Preparing the toplevel

In order to use these examples, those modules are needed:

#use "topfind";;
#require "calendar";;
#require "sqlite3";;

Auxilliary functions and variables

Some variables:

let db = Sqlite3.db_open "/home/mihamina/accouting-copy";;
let the_query = "SELECT * FROM ifconfig";;

I need a couple of auxilliary functions.

To convert a "String Option" (Some "foo") to a String:

let so_to_strig the_so =
match the_so with
| Some s -> s;
| _ -> "";;

To get a Calendar Date from a an SQLite Date String:

let date_from_sql  = CalendarLib.Printer.Precise_Fcalendar.from_fstring "%F %T" ;;

To print a Date:

let date_to_string = CalendarLib.Printer.Precise_Fcalendar.to_string ;;

To add tso days to a Date (For testing or demonstration prupose):

let add_2_days a_date = CalendarLib.Fcalendar.Precise.add a_date (CalendarLib.Fcalendar.Precise.Period.make 0 0 2 0 0 0.);;

The callback just to print the table content:

let the_print_callback row headers =
(Array.iter (fun s -> Printf.printf "  %-12s"              s)  headers);
(print_endline "");
(Array.iter (fun s -> Printf.printf "  %-12s" (so_to_strig s)) row);
(print_endline "");;
Thanks and Acknowledgments

The callback to play with the data, which is the most important for the work:

let the_data_callback row headers=
(* row.(0) row.(1)  row.(2)  row.(3)  *)
(* id      date     rx       tx       *)
(* int     Date     float    float    *)
(* "headers" is no used at the moment *)
let the_id = int_of_string   (so_to_strig (row.(0)))
and the_rx = float_of_string (so_to_strig (row.(2)))
and the_tx = float_of_string (so_to_strig (row.(3)))
and the_date = CalendarLib.Printer.Precise_Fcalendar.from_fstring "%F %T" (so_to_strig (row.(1)))
in
print_string "the_id: "  ; print_int   the_id                    ; print_string "\t\t the_id doubled: "        ; print_int    (the_id * 2)                          ; print_string "\n";
print_string "the_tx: "  ; print_float the_tx                    ; print_string "\t\t the_tx doubled: "        ; print_float  (the_tx *. 2.)                        ; print_string "\n";
print_string "the_rx: "  ; print_float the_rx                    ; print_string "\t\t the_rx doubled: "        ; print_float  (the_rx *. 2.)                        ; print_string "\n";
print_string "the_date: "; print_string (date_to_string the_date); print_string "\t\t twodays after the_date: "; print_string (date_to_string (add_2_days the_date)); print_string "\n";
print_endline "==================================================================================================================";
;;

Launching

To print all the table content:

let result = Sqlite3.exec db ~cb:the_print_callback the_query;;

To make sample operations with the data:

  • double the ID and print it
  • double the RX and TX and print them
  • add 2 days to the Date and print it
let result = Sqlite3.exec db ~cb:the_data_callback the_query;;

Sample Source code

The source code is on my Google Code Repository

more on precise date on ocaml

Dealing with "Precise" Dates

I already posted an article on (begining) playing with Dates on OCaml.

Preparing the Toplevel

As usual, we have to load and use several modules:

#use "topfind";;
#require "calendar";;

Creating a Second

To create a second, the top reachable precision:

CalendarLib.Time.Second.from_int 5;;

Creating a Precise Date

To create a precise date, let's use the "make" function:

CalendarLib.Fcalendar.Precise.make 2011 08 12 05 32 (float_of_int (CalendarLib.Time.Second.from_int 5));;
CalendarLib.Fcalendar.Precise.make 2011 08 12 05 32 5.;;

Create a Precise Period

When wanting to add 2 days to a date, we must use "The Date + 2 days Period". To create that "Period":

CalendarLib.Fcalendar.Precise.Period.make 2011 08 12 05 32 (float_of_int (CalendarLib.Time.Second.from_int 5));;
CalendarLib.Fcalendar.Precise.Period.make 2011 08 12 05 32 5.;;

Make an operation (add)

Let's create a Date, and calculate the "two days later" Date:

let d2 = CalendarLib.Fcalendar.Precise.add
(CalendarLib.Fcalendar.Precise.make 2011 08 12 05 32 (float_of_int (CalendarLib.Time.Second.from_int 5)))
(CalendarLib.Fcalendar.Precise.Period.make 0 0 2 0 0 (float_of_int (CalendarLib.Time.Second.from_int 0)))
;;
let d2 = CalendarLib.Fcalendar.Precise.add
(CalendarLib.Fcalendar.Precise.make 2011 08 12 05 32 5.)
(CalendarLib.Fcalendar.Precise.Period.make 0 0 2 0 0 0.)
;;
Then display it:
CalendarLib.Printer.Precise_Fcalendar.to_string d2;;

If the Date was from a string

I mostly intend to take the Date from an external source: A "date" field from a SQLite3 database, which is formatted "2011-08-16 16:00:01". To use it:

let initiale = CalendarLib.Printer.Precise_Fcalendar.from_fstring "%F %T" "2011-08-16 16:00:01";;
Then to add 2 days to it:
let initiale_2 =
CalendarLib.Fcalendar.Precise.add
initiale
(CalendarLib.Fcalendar.Precise.Period.make 0 0 2 0 0 (float_of_int (CalendarLib.Time.Second.from_int 0)))
;;
Finally print it:
CalendarLib.Printer.Precise_Fcalendar.to_string initiale_2;;

Tuesday 16 August 2011

tutorial date ocaml

OCaml using Calendar

Some acknowledgement

From the toplevel

# #use "topfind";;
# #require "calendar";;
/usr/lib/ocaml/unix.cma: loaded
/usr/lib/ocaml/str.cma: loaded
/usr/lib/ocaml/calendar: added to search path
/usr/lib/ocaml/calendar/calendarLib.cma: loaded

Note that the library is "Calendar", but "calendarLib.cma" is loaded. So, to set a Date from a String:

# let d = CalendarLib.Printer.Precise_Fcalendar.from_fstring "%F %T" "2011-08-16 16:00:01";;
val d : CalendarLib.Printer.Precise_Fcalendar.t = 
Or to print a Date to a String:
# CalendarLib.Printer.Precise_Fcalendar.to_string d;;
- : string = "2011-08-16 16:00:01"
# CalendarLib.Printer.Precise_Fcalendar.sprint "%Y-%m-%d %H" d;;
- : string = "2011-08-16 16"
# CalendarLib.Printer.Precise_Fcalendar.sprint "%Y-%m-%d %H:%M:%S" d;;
- : string = "2011-08-16 16:00:01"

numbering the outlines

Headings then outline

  • I write a text
  • I set the headings
  • I insert a "Table of contents" (TOC)
  • Neither the TOC nor the paragraph headings dont outline the chapter number

To add the outline numbering

  • Format
  • Bullets & Numbering
  • Outline
  • Choose the style of numbering
  • OK

Thursday 28 July 2011

Google plus Madagascar Market Enabler

Google plus Android in Madagascar

I wanted to download the Google Plus (google+) client on my Android telephone but could not, because of my country (Madagascar)

Market enabler

Fortunately, there is the Market Enabler App. On the Phone, go to the market and search for "Market Enabler". On the "Set Custom" tab, change the 6 digit number: Mine was 64604 (Telma Mobile SA) , I changed it to "France Telecom".

I'm done!

natty epiphany3 gtk2 gtk2

Natty GTK2 and GTK3

My Ubuntu Natty default shipped GTK2 and Epiphany (browser) 2.x. I wanted to switch to Epiphany 3.x but it comes along with several GTK3 stuff.

This is how I did it

Enable Oneiric reposotiry

Although it's only alpha at this moment, I enabled them in my "sources.list" I did not enable any pinning. Dont forget to apt-get update.

Install wanted softwares and dependences

After installing Epiphany, Evince and Evolution (yes...), It worked well but the aspect of GTK3 windows was different because of my current GTK2 theme was not ported to GTK3 yet. As far as I searched, Radiance and Ambiance were ported so I switched to them on my XFCE Theme manager and all went well. Radiance and Ambiance are part of the light-themes package (on Ubuntu).

GLib-GIO-ERROR **: Settings schema 'org.gtk.Settings.FileChooser' does not contain a key named 'last-folder-uri'

I encoutered that error:

  • Epiphany: When I open the preference menu (the download location?)
  • Evolution: When replying to a message (the attachment folder to open?)
After some search I found:

Wednesday 20 July 2011

OCaml RSS Feed Parser

Using Cameleon RSS Feed Parser

Looking for a way to parse RSS (or ATOM) feeds with OCaml, I performed a Google search on "ocaml rss":

Here is how to begin to use it...

Installing on Ubuntu/Debian

I assume the user has all de basic OCaml installation. Installing the RSS feed parser requires:

    sudo apt-get install libcameleon-ocaml-dev cameleon
  

Getting a sample RSS file

Let's get the RSS2 file of OCamlCore:

    wget http://planet.ocamlcore.org/rss20.xml
  
The file is saved as "rss20.xml" use the -O option of wget if you want another saving name.

Using it in the toplevel

The user needs to load several modules:

       Objective Caml version 3.11.2


    #use "topfind"                  ;;
    #require "unix"                 ;;
    #require "cameleon"             ;;
    #require "cameleon.config_file" ;;
    #require "cameleon.configwin"   ;;
    #require "cameleon.ffind"       ;;
    #require "cameleon.gdir"        ;;
    #require "cameleon.gmylist"     ;;
    #require "cameleon.gstuff"      ;;
    #require "cameleon.okey"        ;;
    #require "cameleon.report"      ;;
    #load "/usr/lib/ocaml/cameleon/rss.cma";;
  
Load the XML RSS file (Pretty Long output)
    let my_channel = Rss.channel_of_file "rss20.xml";;
  
Get the list of items (Pretty Long output)
    let items = my_channel.Rss.ch_items);;
  
Grab the first item
    List.hd items;;
  
Get the title of that first item
    (List.hd items).Rss.item_title;;
  

Note

Please note that it is a quick and dirty way to do it, the reader is encouraged to suggest cleaner ways by commenting this post.

Monday 4 July 2011

Comparison of OCaml and other languages

Rosetta and PLEAC

When discovering OCaml and trying to introduce it to the people surrounding me, there is always a kind of contest about "who has the shortest".

That lead me to find how to resolve common real-life and academic "problems" with my friend's preferred language and compare it with the OCaml solution.

I found 2 ressources on the web about that:

I am looking at more ressources like these ones, if you have some in your bookmarks, because I am going to teach and the new task I'm facing requires some comparisons.

Wednesday 29 June 2011

using ocamlinit and tip on macos

Randomly found

Randomly browsing for several things, I ran into some Ocaml users blogs and found 2 tips:

Friday 20 May 2011

lookup reverse ip

Reverse IP

Reverse lookup is needed for several uses. To check what is the reverse of an IP address, one can issue:

        dig -t PTR +short 99.123.204.41.in-addr.arpa.
      

Easily reverse an IP

Using "awk", reversing an IP address can be done with

        $ echo "41.204.123.99" | awk -F "." '{for (i=NF;i>=1;i--) printf $i"."; print "in-addr.arpa."}'
      
Or putting this in a simple SHELL script (i.e "flip-ip.sh"):
        #!/bin/bash
        echo $1 | awk -F "." '{for (i=NF;i>=1;i--) printf $i"."; print "in-addr.arpa."}'
      
and calling it:
        $ ./flip-ip.sh  41.204.123.99
      
Used in one line with "dig":
        $ dig -t PTR +short $(flip-ip.sh  41.204.123.99)
      

Friday 11 February 2011

EzPublish EzTeamroom No XML data available

Installing EzTeamroom

When launching the final installation command of Ezpublish:

www-data@dev-01:/var/www/PDCH.ezpublish440$ php extension/ezxmlinstaller/bin/php/xmlinstaller.php --template=teamroom/installezteamroom --siteaccess=plain_site --allow-root-user
Using siteaccess "plain_site" for installation from XML
Checking requirements...
Trying to install data from XML ...
No XML data available.

How I solved

When you face this "No XML" Error, first go to the Administrator Web interface:

  • Setup
  • Extensions
  • Check: ezxmlinstaller, ezjscore, ezie, ezevent, ezlightbox, ezteamroom
  • Update
Then re-launch the command.

Monday 3 January 2011

edit email user

Editing an "email user"

After adding a user, I sometimes need to edit it.

Using a shell script

This is how I edit it

#!/bin/bash

EMAIL=$1
PASS=$2
EXIM_VIRT_DIR="/etc/exim4/virtual/"

DOMAINE=$(echo ${EMAIL} | awk -F"@" '{print $2}')
LOCALPART=$(echo ${EMAIL} | awk -F"@" '{print $1}')

U=$(echo ${EMAIL} | sed 's/\./-/g' | sed 's/@/-/g')
CRYPT1_PASS=$(mkpasswd ${PASS})

echo ${EMAIL}
echo ${PASS}
echo ${DOMAINE}
echo ${LOCALPART}
echo ${CRYPT1_PASS}
echo ${U}

usermod  --password ${CRYPT1_PASS} ${U}

      

delete email user

Deleting an "email user"

After adding a user, I sometimes need to delete it.

Using a shell script

This is how I delete it

#!/bin/bash

EMAIL=$1
PASS=$2
EXIM_VIRT_DIR="/etc/exim4/virtual/"

DOMAINE=$(echo ${EMAIL} | awk -F"@" '{print $2}')
LOCALPART=$(echo ${EMAIL} | awk -F"@" '{print $1}')

U=$(echo ${EMAIL} | sed 's/\./-/g' | sed 's/@/-/g')
CRYPT1_PASS=$(mkpasswd ${PASS})

echo ${EMAIL}
echo ${PASS}
echo ${DOMAINE}
echo ${LOCALPART}
echo ${CRYPT1_PASS}
echo ${U}

userdel   ${U}
grep -v "${LOCALPART}:" ${EXIM_VIRT_DIR}${DOMAINE} > /tmp/${DOMAINE} 
cp /tmp/${DOMAINE} ${EXIM_VIRT_DIR}
invoke-rc.d exim4 restart

      

email address to system user

Email address to user

My goal is to build a bash script to which I give "mihamina@rktmb.org" and "password" as argument, and then it creates a system user named "mihamina-rktmb-org".

The discribed method requires you to install the package "whois", containing "mkpasswd". Dont ask me why.

At the same time, the script will insert an alias entry into an alias flat file. For "mihamina@rktmb.org", it will insert

mihamina: mihamina-rktmb-org
in "/etc/exim4/virtual/rktmb.org".

The BASH script

#!/bin/bash
EMAIL=$1
PASS=$2
EXIM_VIRT_DIR="/etc/exim4/virtual/"
DOMAINE=$(echo ${EMAIL} | awk -F"@" '{print $2}')
LOCALPART=$(echo ${EMAIL} | awk -F"@" '{print $1}')
U=$(echo ${EMAIL} | sed 's/\./-/g' | sed 's/@/-/g')
CRYPT1_PASS=$(mkpasswd ${PASS})
echo ${EMAIL}
echo ${PASS}
echo ${DOMAINE}
echo ${LOCALPART}
echo ${CRYPT1_PASS}
echo ${U}
useradd  \
--home-dir /home/${U} \
--create-home  \
--password ${CRYPT1_PASS} \
--shell "/bin/bash" ${U}
echo "${LOCALPART}:  ${U}" >> ${EXIM_VIRT_DIR}${DOMAINE}
invoke-rc.d exim4 restart

Saturday 25 December 2010

interfaces pon poff wvdial

/etc/networking/interfaces

As a full Debian/Ubuntu nerd, I use "/etc/networking/interfaces" to setup my network. But as far as I have Two different modems to connect with, I wondered how to make them work with "/etc/networking/interfaces". I found.

ppp

To connect with "ppp", I type "pon bluenet". To use "/etc/networking/interfaces" with it:

iface ppp0 inet ppp
provider bluenet

wvdial

To connect with wvdial, I type "wvdial orange". To use "/etc/networking/interfaces" with it:

iface ppp0 inet wvdial
provider orange

How to use it

zte g x760 blueline debian ubuntu

ZTE G X760

The ZTE G X760 is also known as "Orange VEGAS". I use one branded "T-Mobile", byt unlocked. I use it to phone and as a backup modem. It's a GPRS (2G) phone. When plugged to a computer through the USB, the telephone promts if it will be connected as "Mass storage" or "COM Port". Depending on the usage, You've got to choose.

Blueline

Blueline is one of the best Internet Service provider in Madagascar. With their mobile telephone product, they have a Data service. I use it to access Internet, with my telephone (see above), on my Ubuntu and Debian laptop. The APN is "bluenet". No password required.

Connecting to Internet

After pluggin the phone and choosing "COM Port", the phone is then detected as a modem

        cdc_acm 3-2:1.1: ttyACM0: USB ACM device
        usbcore: registered new interface driver cdc_acm
        cdc_acm: v0.26:USB Abstract Control Model driver for USB modems and ISDN adapters
      
Then, I had to setup several files:
/etc/chatscripts/bluenet
      ABORT BUSY
      ABORT 'NO CARRIER'
      ABORT ERROR
      REPORT CONNECT
      TIMEOUT 10
      "" "ATZ &F"
      OK 'AT+CGDCONT=1,"IP","bluenet"'
      TIMEOUT 60
      OK "ATD*99***1#"
      CONNECT \d\c
    
/etc/ppp/peers/bluenet
      hide-password
      noauth
      modem
      connect "/usr/sbin/chat -v -f /etc/chatscripts/bluenet"
      debug
      /dev/ttyACM0
      115200
      defaultroute
      noipdefault
      user any
      password any
      remotename bluenet
      ipparam bluenet
      usepeerdns
      novj
      lcp-echo-interval 0
    
To connect to internet, just do: pon bluenet and tail your logs.

Friday 24 December 2010

huawei e1552 orange ubuntu debian

Orange Madagascar

This internet access provider had initially provided a USB Huawei E160. Then, then switched to the USB Huawei E1552 device.

The modem is composed by

  • A modem. (Why not?)
  • An USB mass storage, read-only, containing Windows drivers

Funny Windows

After I got the USB Huawei E1552, I wanted to to try it out on a spare Laptop running Microsoft Windows 7 32bits. I failed, because the driver provided on the USB stick is XP/Vista only, and known to be weird on Microsoft Windows 7 32bits.

On Linux

If the usb-modeswitch package is not installed, when plugging the modem, only the USB mass storage part is detected:

        usb 1-2: new high speed USB device using ehci_hcd and address 3
Initializing USB Mass Storage driver...
scsi6 : usb-storage 1-2:1.0
scsi7 : usb-storage 1-2:1.1
usbcore: registered new interface driver usb-storage
USB Mass Storage support registered.

After installing usb-modeswitch and without any setup, when plugging the modem, the the USB mass storage part is detected and actived, then switched to the "GSM Modem" feature:

        usb_modeswitch: switching 12d1:1446 (HUAWEI Technology: HUAWEI Mobile)
kernel: [10694.027147] usb 1-2: USB disconnect, address 3
kernel: [10700.190056] usb 1-2: new high speed USB device using ehci_hcd and address 4
kernel: [10700.361471] scsi10 : usb-storage 1-2:1.2
kernel: [10700.501603] usbcore: registered new interface driver usbserial
kernel: [10700.501635] USB Serial support registered for generic
kernel: [10700.502713] usbcore: registered new interface driver usbserial_generic
kernel: [10700.502718] usbserial: USB Serial Driver core
kernel: [10700.589257] USB Serial support registered for GSM modem (1-port)
kernel: [10700.589427] option 1-2:1.0: GSM modem (1-port) converter detected
kernel: [10700.592132] usb 1-2: GSM modem (1-port) converter now attached to ttyUSB0
kernel: [10700.592185] option 1-2:1.1: GSM modem (1-port) converter detected
kernel: [10700.592500] usb 1-2: GSM modem (1-port) converter now attached to ttyUSB1
kernel: [10700.593596] usbcore: registered new interface driver option
kernel: [10700.593603] option: v0.7.2:USB Driver for GSM modems
usb_modeswitch: switched to 12d1:141b (HUAWEI Technology: HUAWEI Mobile)
kernel: [10701.375029] scsi 10:0:0:0: Direct-Access     HUAWEI   MMC Storage      2.31 PQ: 0 ANSI: 2
kernel: [10701.381072] sd 10:0:0:0: Attached scsi generic sg2 type 0
kernel: [10701.389031] sd 10:0:0:0: [sdb] Attached SCSI removable disk

Using "wvdial"

I use wvdial to connect to internet. This is the wvdial.conf part:

        [Dialer orange]
Init0 = ATZ
Modem Type = Analog Modem
Baud = 921600
New PPPD = yes
Modem = /dev/ttyUSB0
Phone = *99#
Username = ''
Password = ''
Stupid Mode = 1
ISDN = 0
Thanks to Elie Zedeck Randriamiandriray for the tips.

To connect, just run wvdial orange and you're done.

Using Gnome Network Manager

Use these settings:

Friday 3 December 2010

no switchport mode dynamic desirable

mode access to mode trunk

I got a Cisco 2950 swicth where a port is configured "access vlan 54". I want to make vlan 54 native on this and put a vlan 150 over it.

I then have to enter something like:

interface FastEthernet0/4
 description vers switch admin1 fa0/17
 switchport trunk encapsulation dot1q
 switchport trunk native vlan 54
 switchport trunk allowed vlan 54,150
 no cdp enable
Unfortunately, when runnnig the configuration, I get:
interface FastEthernet0/4
 description vers switch admin1 fa0/17
 switchport trunk encapsulation dot1q
 switchport trunk native vlan 54
 switchport trunk allowed vlan 54,150
 switchport mode dynamic desirable
 no cdp enable
Whatever I tried, I always got the "switchport mode dynamic desirable"...

no, then mode trunk

The solution was to negate the dynamic and directly force trunk. I entered the configuration in this order:

interface FastEthernet0/4
 no  switchport mode dynamic desirable
 switchport mode trunk
 switchport trunk encapsulation dot1q
 switchport trunk native vlan 54
 switchport trunk allowed vlan 54,150
 no cdp enable
I'm done!

Wednesday 10 November 2010

ezpublish add siteaccess

Goal

I first wanted to install ezteamroom on my ezpublish 4.3, but it requires me to have created "siteaccess" before. This is how to create "siteaccesses"

Documentation

There is an existing documentation, but guess why screenshots did not match my installation.

Download requirements

I had to install ezwebin, and as I am there, I also installed all the ezteamroom requirements:

git clone https://github.com/ezsystems/ezwebin.git ezwebin
git clone https://github.com/ezsystems/ezlightbox.git ezlightbox
git clone https://github.com/ezsystems/ezxmlinstaller.git ezxmlinstaller
git clone https://github.com/ezsystems/ezteamroom.git ezteamroom
git clone https://github.com/ezsystems/ezevent.git ezevent
Then following the documentation is OK, but you just dont need to swap the "Home" page because the root node is already a folder.

What's next

Let's install ezteamroom, then...

Sunday 7 November 2010

installing ezpublish 4.3 on debian lenny

Goal

These are the steps I followed to install ezpublish 4.3 on Debian Lenny. Lenny is shipped with PHP 5.2.6, while ezpublish 4.4 requires 5.2.14+

apt-get install things

apt-get install php5 php5-common php-pear php5-cli \
  php5-gd php5-curl libapache2-mod-php5 \
  php5-mcrypt imagemagick php5-mysql \
  apache2-mpm-prefork libapache2-mod-php5 mysql-server

Use PEAR to go on

pear channel-discover components.ez.no
pear install -a ezc/eZComponents
This will install many thing in /usr/share/php/ezc/

Database

Just have to create a database and when installing ezpublish through the web installer, give the credentials.

Tuesday 2 November 2010

Les informations sur Facebook et internet en general

C'est quoi ton email? ton téléphone?

Sur Facebook, plusieurs fois, on m'a demandé via message privé mes coordonnées. Plusieurs fois, je réponds: "regarde mon profil", les informations que tu recherches sont publiques. Plusieurs fois on me traite de "méchant".

Ce que je ne comprends pas, moi c'est que le temps que je réponde à la demande de coordonnées, la personne qui demande aurait pour trouver l'information bien avant! En moins de 30 secondes! Et evidemment, c'est moi le méchant et pas l'autre qui est est idiot.

Pourquoi c'est comme ça?

Pour moi, la raison est simple: 90% des membres de Facebook et autres réseaux sur internet mettent n'importe quoi comme coordonnées.

En fait c'est un n'importe quoi généralisé:

  • Orthographe d'illétré
  • Renseignements bordéliques
  • Faux noms
Pourquoi s'incrire sur Facebook quan on fait ça?

Les gens mettent sur internet leur amour pour le désordre. Par exemple, quand on upload un album photo:

  • On tag n'importe comment
  • On ne renseigne pas les champs des formulaires
Bref, on se croit "actuel" mais en fait on est attardé. Et tout le monde semble d'accord... puisque tout le monde fait pareil.

Et donc quoi?

Mon profil contient mes informations, mes albums photos contiennent les informations de base sur les photos publiées. Et manifestement je suis le seul à savoir le faire.

Ben oui, sinon, tout le monde aurait fait comme moi.

la crise ne sera pas a madagascar

Les copains du Rotary, Lions, COT,...

Pour beacoup de gens, le Rotary, le Lions, et autres clubs sont des clubs de "gens riches". Pour faire simple, dans ces clubs, on retrouve les plus gros DG et PDG du pays. C'est dans ces espaces que ce decident les contrats (avoir des commerciaux, c'est juste pour faire joli). C'est entre eux que se décident les alliances, les collaborations, les partenariats...

Auto préservation de l'eco-système

Tel que nous connaissons les hommes et femmes d'affaires qui brassent des milliards de chiffre d'affaire, qui pense que c'est dans linteret de ces gens que le peuple crève?

Pour ces gens, leurs enterprises (zones franches, usines en tout genre,...) doivent fonctionner.

De plus, en prenant l'exemple precis de la STAR et de JB, la situation doit rester telle que les employés des autres entreprises puissent encore acheter de la biere et des biscuits à leurs enfants.

Je vous l'assure, il n'y aura pas de "crise". Tout au plus y aura-t-il encore plus d'emprise de ces clubs sur l'économie et la politique, mais certainement pas d'appauvrissement financier grave.

Et alors?

Il faut arreter de fantasmer sur l'appauvrissement du pays. Madagascar sera toujours maintenu "en vie", et il suffit d'être un petit peu malin pour ne pas faire partie de ceux qui subissent la situation.

Un bon début serait de me lire attentivement...

Thursday 21 October 2010

ssh on wan port after install

Context

I installed an openWRT system, I want to connect to SSH on it.

After a fresh install only telnet is available.

One could always use telnet through the wan interface, but it's not a good choice

Dropbear

Dropbear is the lightweight SSH server for the situation.

It's installed by default, we just have to configure it

Allow TCP port 22 from wan (/etc/config/firewall)

The default behaviour is to REJECT any INPUT from wan:

      
        config zone
        option name             wan
        option input    REJECT
        option output   ACCEPT
        option forward  REJECT
        option masq             1
        option mtu_fix  1
      
That is the POLICY (default behaviour).

We are going to add a specific "rule" to allow TCP/22

        config rule
        option src              wan
        option proto            tcp
        option dest_port        22
        option target           ACCEPT
        option family   ipv4
      

Don't forget to setup a password for root, and we're done!

Wednesday 13 October 2010

LXC sous Linux Debian Lenny Squeeze

Avantage des LXC

  • Pas besoin de patch kernel, c'est dedans.
  • La migration des containers OpenVZ vers les LXC se fait par simple "cp -R". Rien de plus.

se mettre en root

C'est mal pour nous, mais un sudo -s pour les essais est plus facile.

cgroup

Mounter les cgroup:

mount none -t cgroup /cgroup

fichier de configuration

Nous choisissons d'appeler demo-02 le LXC à créer.

nano -w /etc/lxc/demo-02.conf

Et mettre dedans

lxc.utsname = demo-02
lxc.tty = 3
lxc.network.type = veth
lxc.network.flags = up
lxc.network.link = br0
lxc.network.ipv4 = 192.168.1.162/24
lxc.network.name = eth0
lxc.mount = /home/lxc/demo-02/etc/fstab
lxc.rootfs = /home/lxc/demo-02

Disque dur du LXC

Créer un LVM

lvcreate -L 5G -n demo-02 lvm0

Le formatter

mkfs.ext3 /dev/lvm0/demo-02

Penser à le monter au boot

echo "/dev/lvm0/demo-02 /home/lxc/demo-02 ext3 noatime 0 2" >> /etc/fstab

Créer le "private" du LXC

mkdir -pv /home/lxc/demo-02

Créer le système

debootstrap --arch=amd64 lenny /home/lxc/demo-02  http://mirror.malagasy.com/debian

Entrer dans le système créé

chroot /home/lxc/demo-02

Mettre les outils communs

Ajuster le hostname

/etc/hosts

127.0.0.1 localhost demo-02
192.168.1.162 demo-02.malagasy.com

/etc/hostname

demo-02

/etc/mailname

demo-02.malagasy.com

/etc/network/interfaces

auto lo
iface lo inet loopback

auto eth0
iface maison inet static
 address 192.168.1.162
 gateway 192.168.1.254
 netmask 255.255.255.0

Sortir du "chroot"

logout

Définir les mountages

/home/lxc/demo-02/etc/fstab

none /home/lxc/demo-02/dev/pts devpts defaults 0 0
none /home/lxc/demo-02/proc    proc   defaults 0 0
none /home/lxc/demo-02/sys     sysfs  defaults 0 0
none /home/lxc/demo-02/dev/shm tmpfs  defaults 0 0

Peupler /dev

Aller à la racine du LXC

cd /home/lxc/demo-02/

Créer un fichier dev.sh contenant

ROOT=$(pwd)
DEV=${ROOT}/dev
rm -rf ${DEV}.old
mv ${DEV} ${DEV}.old
mkdir  ${DEV}
mkdir -pv ${ROOT}/proc
mkdir -pv ${ROOT}/sys
mknod -m 666 ${DEV}/null c 1 3
mknod -m 666 ${DEV}/zero c 1 5
mknod -m 666 ${DEV}/random c 1 8
mknod -m 666 ${DEV}/urandom c 1 9
mkdir -vm 755 ${DEV}/pts
mkdir -vm 1777 ${DEV}/shm
mknod -m 666 ${DEV}/tty c 5 0
mknod -m 600 ${DEV}/console c 5 1
mknod -m 666 ${DEV}/tty0 c 4 0
mknod -m 666 ${DEV}/full c 1 7
mknod -m 600 ${DEV}/initctl p
mknod -m 666 ${DEV}/ptmx c 5 2
mknod -m 666 ${DEV}/null c 1 3
mknod -m 666 ${DEV}/zero c 1 5
mknod -m 666 ${DEV}/random c 1 8
mknod -m 666 ${DEV}/urandom c 1 9
mkdir -m 755 ${DEV}/pts
mkdir -m 1777 ${DEV}/shm
mknod -m 666 ${DEV}/tty c 5 0
mknod -m 666 ${DEV}/tty0 c 4 0
mknod -m 666 ${DEV}/tty1 c 4 1
mknod -m 666 ${DEV}/tty2 c 4 2
mknod -m 666 ${DEV}/tty3 c 4 3
mknod -m 666 ${DEV}/tty4 c 4 4
mknod -m 600 ${DEV}/console c 5 1
mknod -m 666 ${DEV}/full c 1 7
mknod -m 600 ${DEV}/initctl p
mknod -m 666 ${DEV}/ptmx c 5 2

Rendre le fichier execuble:

chmod 755 dev.sh

Lancer le peuplement:

./dev.sh

Ca fait plein d'erreur, mais c'est pas tres grave. ( /!\ script à améliorer)

Créer le LXC

En indiquant le fichier de configuration et un petit nom

lxc-create -f /etc/lxc/demo-02.conf -n demo-02

Démarrer le LXC

lxc-start -n demo-02

Se connecter

Avec la méthode que j'ai rédigé, j'ai créé 2 LXC avec succès (Oh! ça rime!).

Dites moi ce qu'on peut trouver sous OpenVZ et qu'on n'a pas sous LXC.

Friday 8 October 2010

my ocsigen project template

Context

I often try to develop micro projects with Ocsigen. They are Quick and Dirty things without coplexity, just needing an admin login and deveral things.

I mostly start with this Project Template, and clean it the step after.

My Ocsigen Project template

Its composed by:

  • A main file: index.ml
  • An utility file: gs.ml
  • A Makefile
  • Some tuning to the Ocsigen cofiguration file
  • Some Debian/Ubuntu packages installed

The main File

open Lwt
open XHTML.M
open Eliom_services
open Eliom_parameters
open Eliom_sessions
open Eliom_predefmod.Xhtml

open Gs

module Ep=Eliom_parameters;;

let session_table = Eliom_sessions.create_volatile_table ();;

let root_service =
  Eliom_services.new_service
    ~path:[""]
    ~get_params:Eliom_parameters.unit
    () ;;
    
let root_service_with_post =
  Eliom_services.new_post_service
    ~fallback:root_service
    ~post_params:((Ep.string "login")**(Ep.string "password"))
    () ;;

let logout_service =
  Eliom_services.new_service
    ~path:["logout"]
    ~get_params:Eliom_parameters.unit
    () ;;

(* Handlers *)
   
let root_handler sp _ _  =
    let session_data = Eliom_sessions.get_volatile_session_data  
      ~table:session_table 
      ~sp:sp () 
    in
      match session_data with 
           Eliom_sessions.Data (name,password) ->
             return
               (html
                  (head (title (pcdata "Accueil")) [])
                  (body
                     [(Gs.greeter_auth  logout_service sp (name,password))])) ;
        | Eliom_sessions.Data_session_expired
        | Eliom_sessions.No_data ->
            return (Gs.login_page root_service_with_post sp "Accueil")  ;;

let root_handler_with_post sp _ (login,password) =
  let clean_login = Gs.trim login 
  in
    match (Gs.ok_credentials (clean_login, password)) with
      | true ->
        Lwt.bind
          (Eliom_sessions.close_session  ~sp:sp ())
          (fun () ->
            Eliom_sessions.set_volatile_session_data  ~table:session_table ~sp:sp (clean_login, password);
            return
              (html
                 (head (title (pcdata "Identifié")) [])
                 (body
                    [Gs.greeter_auth logout_service sp (clean_login,password)]))) ;
      | false -> 
        return (Gs.login_page root_service_with_post sp "Recommencez SVP");;

let logout_handler sp () () =
  Lwt.bind
    (Eliom_sessions.close_session  ~sp:sp ()) 
    (fun () ->
      return (Gs.login_page root_service_with_post sp  "Deconnecté")) ;;

let () =
  Eliom_predefmod.Xhtml.register
    root_service
    root_handler;
  Eliom_predefmod.Xhtml.register
    root_service_with_post
    root_handler_with_post;
  Eliom_predefmod.Xhtml.register
    logout_service
    logout_handler;;

    

The utility File

open Lwt
open XHTML.M
open Eliom_services
open Eliom_parameters
open Eliom_sessions
open Eliom_predefmod.Xhtml

(*
 #use"topfind";;
 #require"mysql";;
 #require"str";;
*)

open Str
open Mysql

module Ep = Eliom_predefmod;;


let trim the_input =
  let space_regexp = Str.regexp " +"
  and semicolumn_regexp = Str.regexp ";"
  and replace = Str.global_replace
  in replace semicolumn_regexp ""               (* Remplacement des point-virgules *) 
       (replace space_regexp "" the_input);;    (* et des espaces. anti-problemes  *)

let semicolumn_regexp = Str.regexp ";";;


let ok_credentials (u,p) = match (u,p) with
  | ("admin","sdlqskd6dsf") -> true;
  | _                       -> false;;


(* begin HTML constructions *)

let greeter_auth close_serv server_params (login, password)=
  p [pcdata ("Bienvenue, titulaire de l'adresse "^login^".");
     br ();
     (Eliom_predefmod.Xhtml.a
        close_serv
        server_params 
        [pcdata "Se déconnecter."] ());
    ] ;;


let login_page attached_serv server_params titre= 
  let login_form =
    Eliom_predefmod.Xhtml.post_form
      attached_serv
      server_params
      (fun (login, password) ->
        [p [pcdata "Identifiant:";
            (Eliom_predefmod.Xhtml.string_input ~input_type:`Text ~name:login ());
            br ();
            pcdata "Mot de passe";
            (Eliom_predefmod.Xhtml.string_input ~input_type:`Text ~name:password ());
            br ();
            (Eliom_predefmod.Xhtml.string_input ~value:"S'identifier" ~input_type:`Submit ())]]) ()
  in
  (html
     (head (title (pcdata titre)) [])
     (body
        [login_form]));;


(* end HTML constructions *)
    

The MakeFile

########
# ocamlfind ocamlc -verbose -package str,ocsigen,postgresql,mysql -linkpkg


LAPTOP_FLAGS= -I /usr/lib/ocaml/pcre       -ccopt -I/usr/lib/ocaml/pcre       \
              -I /usr/lib/ocaml/netsys     -ccopt -I/usr/lib/ocaml/netsys     \
              -I /usr/lib/ocaml/netstring  -ccopt -I/usr/lib/ocaml/netstring  \
              -I /usr/lib/ocaml/ssl        -ccopt -I/usr/lib/ocaml/ssl        \
              -I /usr/lib/ocaml/lwt        -ccopt -I/usr/lib/ocaml/lwt        \
              -I /usr/lib/ocaml/ocsigen    -ccopt -I/usr/lib/ocaml/ocsigen    \
              -I /usr/lib/ocaml/postgresql -ccopt -I/usr/lib/ocaml/postgresql \
              -I /usr/lib/ocaml/mysql      -ccopt -I/usr/lib/ocaml/mysql      \
              -ccopt -L/usr/lib/ocaml/pcre                                           \
              -ccopt -L/usr/lib/ocaml/netsys                                         \
              -ccopt -L/usr/lib/ocaml/netstring                                      \
              -ccopt -L/usr/lib/ocaml/ssl                                                   \
              -ccopt -L/usr/lib/ocaml/lwt                                            \
              -ccopt -L/usr/lib/ocaml/ocsigen                                        \
              -ccopt -L/usr/lib/ocaml/postgresql                                     \
              -ccopt -L/usr/lib/ocaml/mysql                                          \
              /usr/lib/ocaml/unix.cma                                                \
              /usr/lib/ocaml/threads/threads.cma                                     \
              /usr/lib/ocaml/str.cma                                                 \
              /usr/lib/ocaml/pcre/pcre.cma                                           \
              /usr/lib/ocaml/netsys/netsys.cma                                       \
              /usr/lib/ocaml/netstring/netstring.cma                                 \
              /usr/lib/ocaml/netstring/netstring_mt.cmo                              \
              /usr/lib/ocaml/netstring/netaccel.cma                                  \
              /usr/lib/ocaml/netstring/netaccel_link.cmo                             \
              /usr/lib/ocaml/ssl/ssl_threads.cma                                     \
              /usr/lib/ocaml/dynlink.cma                                             \
              /usr/lib/ocaml/lwt/lwt.cma                                             \
              /usr/lib/ocaml/postgresql/postgresql.cma                               \
              /usr/lib/ocaml/mysql/mysql.cma


OCAMLC = ocamlc -c -thread

gs: 
        $(OCAMLC) $(LAPTOP_FLAGS) gs.ml

index:  gs 
        $(OCAMLC) $(LAPTOP_FLAGS) gs.cmo index.ml

all:  gs index 
        echo "all OK"
    

The Ocsigen configuration file

Load the modules listed in the Makefile
    <<extension module="/usr/lib/ocaml/str.cma"/>>
    <<extension module="/usr/lib/ocaml/pcre/pcre.cma"/>>
    <<extension module="/usr/lib/ocaml/netsys/netsys.cma"/>>
    <<extension module="/usr/lib/ocaml/netstring/netstring.cma"/>>
    <<extension module="/usr/lib/ocaml/netstring/netstring_mt.cmo"/>>
    <<extension module="/usr/lib/ocaml/netstring/netaccel.cma"/>>
    <<extension module="/usr/lib/ocaml/netstring/netaccel_link.cmo"/>>
    <<extension module="/usr/lib/ocaml/ssl/ssl.cma"/>>
    <<extension module="/usr/lib/ocaml/ssl/ssl_threads.cma"/>>
    <<extension module="/usr/lib/ocaml/dynlink.cma"/>>
    <<extension module="/usr/lib/ocaml/react/react.cmo"/>>
    <<extension module="/usr/lib/ocaml/lwt/lwt.cma"/>>
    <<extension module="/usr/lib/ocaml/nums.cma"/>>
    <<extension module="/usr/lib/ocaml/toplevellib.cma"/>>
    <<extension module="/usr/lib/ocaml/ocamldap/ocamldap.cma"/>>
    <<extension module="/usr/lib/ocaml/mysql/mysql.cma"/>>
    <<extension module="/usr/lib/ocaml/postgresql/postgresql.cma"/>>

    
Declare the host

      <<host defaulthostname="xxxxxxx">>
        <<site path="">>
          <<static dir="/home/mihamina/XXXXXXXX/static/" />>
          <<eliom module="/home/mihamina/XXXXXXX/index.cmo" />>
        <</site>>
      <</host>>
      
    

Installed packages

Got with:
dpkg -l | awk '/^ii.+(ocaml|make|ocsigen)/{print $2}'
automake
libcryptgps-ocaml-dev
libcryptokit-ocaml
libcryptokit-ocaml-dev
libfindlib-ocaml
libfindlib-ocaml-dev
libldap-ocaml-dev
liblwt-ocaml
liblwt-ocaml-dev
liblwt-ocaml-doc
liblwt-ssl-ocaml-dev
libmysql-ocaml
libmysql-ocaml-dev
libnethttpd-ocaml-dev
libobrowser-ocaml-dev
libocamlnet-ocaml
libocamlnet-ocaml-dev
libocamlnet-ocaml-doc
libocsigen-ocaml
libocsigen-ocaml-dev
libocsigen-ocaml-doc
libocsigen-xhtml-ocaml-dev
libpcre-ocaml
libpcre-ocaml-dev
libpostgresql-ocaml
libpostgresql-ocaml-dev
libreact-ocaml
libreact-ocaml-dev
libsqlite3-ocaml
libsqlite3-ocaml-dev
libssl-ocaml
libssl-ocaml-dev
libtext-ocaml
libtext-ocaml-dev
libzip-ocaml
libzip-ocaml-dev
make
makedev
ocaml-base-nox
ocaml-findlib
ocaml-interp
ocaml-nox
ocamlduce
ocamlduce-base
ocsigen
ocsigen-dev
    

Wednesday 6 October 2010

ocaml get the standard output of command

Context

Nothing special, I just write i because I wrote a previousentry about "piping to a command"

Get the output

let buf = Unix.open_process_in "echo sdssdsdsdsds";;
Pervasives.input_line buf;;
Unix.close_process_in buf;;

ocaml pipe to a command

Context

As Linux system administrator I sometimes need to use pipes. A simple example:
$ echo "some content text" | mail -s "this is" mihamina@rktmb.org
I wondered how to do it with OCaml.

Pipe with Ocaml

What should be done:
  • Open the command as an output channel
  • Send what you want to that channel
How to:
let buf = Unix.open_process_out "mail -s ddd mihamina@rktmb.org";;
Pervasives.output_string buf "eeeeeeeeehol";;
Pervasives.flush buf;;
Unix.close_process_out buf;;
And you're done!

Wednesday 15 September 2010

ecrire un email

C'est quoi le problème?

Il y a un problème global: Les gens qui utilisent les emails ne savent pas utiliser les emails.

Un email c'est un message: du contenu. Ce contenu doit être lisible le plus rapidement possible.

Ecrire en HTML

Ecrire un message en HTML, c'est utiliser sont Outlook ou Thunderbird dans sa cofiguration par défaut.

Cela permet de faire des messages avec de la mise en forme, des couleurs, insérer des images,... Mais:

  • On ne sait pas comment le destinataire va lire le message, on ne sait donc pas si l'HTML est supporté et par principe on utilise le plus petit dénominateur commun.
  • Un message HTML prend trois fois plus de place au moins qu'un message en "texte brut", soit trois fois plus de bande passante (multiplié par les centaines d'aliases qu'on a dans une entrepise)
  • De nombreux utilisateurs gardent les messages sur le disque pour pouvoir effectuer des recherches, en augmentant la taille par 3 on augmente d'autant le temps de recherche. Sur les milliers de messages reçus des différents services d'une enterprise, c'est beaucoup.
  • Il est plus confortable et reposant de lire tous des messages formattés de la même façon que de devoir à chaque message s'adapter à des couleurs, des fonds, des polices,... différentes
  • En général, on respecte le choix de celui à qui on écrit. Plutot que d'imposer des couleurs et des polices de caractères au lecteur, on envoie le message en texte brut, et on laisse le soin au destinataire d'avoir choisi comment afficher le simple texte brut.

Répondre au dessus

Beaucoup de gens placent la réponse au dessus, sans raison valable.

Par exemple, soit le dialogue suivant:

R: Parce que ça renverse bêtement l'ordre naturel de lecture !
Q: Mais pourquoi citer en fin de message est-il si effroyable ?
R: Répondre au dessus de la citation
Q: Quelle est la chose la plus désagréable dans un message ?

En le lisant naturellement (du haut vers le bas), il n'a pas beaucoup de sens.

En le lisant anti-naturellement (du bas vers le haut), un cerveau en état de marche remarquera la similitude avec certaisn E-Mail qu'on a échangé il y a quelques minutes.
Un cerveau toujours en état de marche remarquera que la façon naturelle de lire est perturbé par le fait de répondre en haut.

Placer sa réponse au-dessus du message revient à couper la parole à l'interlocuteur. En effet, c'est ce qu'on lira en premier dans votre message.

De même, citer l'intégralité d'un message est superflu. Le message va être transporté sur de nombreux serveurs, un grand nombre de personnes vont télécharger ce message. Ils n'ont pas envie d'attendre une demi-heure (Tout le monde n'a pas une connexion 10Mbps) pour vous lire. Il vaut mieux être concis.

Donc quoi?

Arreter les E-mails en HTML et répondre en bas, intelligemment.

Si on souhaite que le destinataire fournisse l'effort de lire, il faut fournir l'effort d'écrire correctement.

Tuesday 7 September 2010

mysql case when then end

Use case

I use a Dovecot IMAP & POP server, against a MySQL user database. In database, the users are stored this way:

id pwd
mihamina@gulfsat.mg $1$HSBxVt/clgdj0L5Fgzm61
mihamina@freedsl.mg $1$7TCTJJMG9cUvAlWuAbvE.
mihamina@rktmb.org $1$H23xVt.bbgdj0L5Fgzm61

On my server I have mutiple IP adresses:

  • A legacy IP (1.2.3.4) where "@rktmb.org" users sometimes log in only with the localpart, sometimes with the full email address
  • A legacy IP (5.6.7.8) where "@freedsl.mg" users sometimes log in only with the localpart, sometimes with the full email address
  • A last IP (7.8.9.0) where users log in with the full email address

In usual condition, on a mail system, all users either all login with the full email address or all with the localpart. But on my alien system, they mix their habits, for legacy reasons.

Therefore:

  • The "mihamina@rktmb.org" user always logs in on the 1.2.3.4 IP but sometimes with "mihamina", sometimes with "mihamina@rktmb.org"
  • The "mihamina@freedsl.mg" user always logs in on the 5.6.7.8 IP but sometimes with "mihamina", sometimes with "mihamina@freedsl.mg"
  • The other users always log in on 7.8.9.0 with their full email address

The SQL query using CASE WHEN THEN END

Dovecot allows to use "%u" as username and "%l" as local IP in SQL queries. This is how I did it:

SELECT id AS user, pwd AS password 
FROM passwdc 
WHERE (((id = '%u') OR (id = (
                              CASE
                                WHEN ("%l" = "1.2.3.4") THEN ('%u@rktmb.org')
                                ELSE ('%u@freedsl.mg')
                              END
                             ))) AND en = 1)
    
or
SELECT id AS user, pwd AS password 
FROM passwdc 
WHERE (((id = '%u') OR (id = (
                              CASE
                                WHEN ("%l" = "1.2.3.4") THEN ('%u@rktmb.org')
                                WHEN ("%l" = "5.6.7.8") THEN ('%u@freedsl.mg')
                              END
                             ))) AND en = 1)
    

Thursday 2 September 2010

A pgrep like with ocaml

pgrep

"pgrep" is a tool to "grep" processes. If you want to know if a process containing a pattern exists, you use "pgrep pattern".

informations

The informations about a process are stored in

/proc/$PID/cmdline

ocaml

To make a pgrep-like with Ocaml, we'll have to loop on all /pro/$PID and check if

/proc/$PID/cmdline
has the pattern we look for.

I made it with this (crappy) piece of code, in which you fill find how, in OCaml, to:

  • Open a File
  • Write recursive functions
  • Replace a string with another
  • Deal with command line arguments
open Unix   ;;
open List   ;;
open Str    ;;
open Sys    ;;
open Printf ;;
open String ;;
open Array  ;;
(* In /proc//cmdline, the field separator is '\000' *)
let rec cmd_to_string accumulator cmd_channel =
try
let red = input_char cmd_channel in
match red with
| '\000' -> cmd_to_string (accumulator^(" ")) cmd_channel;
| _      -> cmd_to_string (accumulator^(String.make 1 red)) cmd_channel;
with End_of_file -> accumulator;;
let a_pid_cmd a_pid =
let cmd_handle = open_in ("/proc/"^a_pid^"/cmdline") in
let the_cmd = cmd_to_string "" cmd_handle in
close_in cmd_handle;
the_cmd;;
(* Improve: I could have returned the tuple (binary, arguments) *)
let slash_proc_list = to_list (readdir "/proc");;
(* Number-only == PID *)
let r_number = regexp "^[0-9]+$";;
let rec proc_list accumulator slash_proc_list =
match slash_proc_list with
| [] -> accumulator;
| tete::queue ->
match (string_match r_number tete 0) with
| true  -> (proc_list ((a_pid_cmd tete)::accumulator) queue);
| false -> (proc_list (accumulator) queue);;
let the_proc_list = proc_list [] slash_proc_list;;
(* Extraction of the binary, includes the basedir *)
let invoked a_line=
try
List.hd (Str.split (regexp " ") a_line)
with _ -> "";;
let rec procs_matching accumulator regex_as_string a_proc_list =
match a_proc_list with
| [] -> accumulator;
| tete::queue ->
let r_asked   = regexp regex_as_string
and proc_name = invoked tete in
match (string_match r_asked proc_name 0) with
| true  -> procs_matching (tete::accumulator) regex_as_string queue;
| false -> procs_matching (accumulator)       regex_as_string queue;;
(* Improve: Should know how to deal with basedirs /usr/bin, /bin,... *)
let the_procs_matching = procs_matching [] Sys.argv.(1) the_proc_list;;
let rec print_list a_list =  match a_list with
| []          -> ();
| tete::queue -> Printf.printf "%s \n" tete;  print_list queue;;
let check_procs max_number a_proc_list =
let the_length = List.length a_proc_list in
match (the_length < int_of_string(max_number)) with
| true  ->
Printf.printf "%d processes found:\n" the_length;
print_list a_proc_list;
WEXITED 0;
| false ->  WEXITED 2;;
check_procs Sys.argv.(2) the_procs_matching;;

Monday 30 August 2010

ocaml imap

I am still lookig for an IMAP module for OCaml. during my searches I saw how the POP module is implemented in OCamlNet and I think I could go from this to implement IMAP on OCamlnet

Given the small knowledges I have, some help will always be welcomed, if any...

Friday 27 August 2010

cherche stagiaire

Là, tout de suite et pour une période de trois mois, je recherche un stagiaire à superviser pour mettre en place la consolidation de notre système de base de données.

Le candidat viendra avec sa machine que nous allons reinstaller complètement, et le stage se déroule à Antananarivo.

Voir la page Contact pour postuler.

Sunday 22 August 2010

PHP session data support

Store a class PHP $_SESSION

This is not yet possible in PHP.
You have to find a workaround and it depends on your programm.

Friday 13 August 2010

And Drivel...

I had a quick apt-cache lookup and found that "drivel" existed... I test it...

Monday 9 August 2010

apt-pinning with origin...

apt-pinning with origin criteria

When wanting to set preferences over the origin repository, this is an example from 2 sources:

EeeUsers

Argon

Package: *
Pin: origin www.debian-multimedia.org
Pin-Priority: 600
Package: *
Pin: origin www.ibiblio.org
Pin-Priority: 610
Package: *
Pin: origin www.argon.org
Pin-Priority: 620

Thursday 5 August 2010

BloGTK broken, Gnome Blog...

BloGTK broken, Gnome Blog then

As far as BloGTK is broken for me at the moment, let's give a try to GnomeBlog!

It seems to use Python 2.6 and is OK with my XFCE system & environment.

Wait and see then.

Monday 21 June 2010

Software RAID

Already existing documentation

There is a lot documentation on Internet teachnig how to make software RAID arrays.

What I forgot

The only thing I did not read from them is how to save the created array for the next reboot.
It's just about:
  • scanning the array with "sudo mdadm --detail --scan"
  • appending the relevant result line to mdam.conf

Friday 11 June 2010

git debian xinetd

Goal

Install a git server on Debian. We will only install a simple GIT daemon, without authentification.
If you need authentification you will have to use an external mechanism:
  • Apache + LDAP/MySQL and access the repositories with the "http://" schema
  • SSH + the system authentication tool and access the repositories with the "ssh://" schema
The git daemon wont be standalone, we'll use xinetd.

Xinetd configuration

in /etc/xinetd.d/git-daemon:
# default: on
# description: The git server offers access to git repositories
service git
    {
        disable = no
        type            = UNLISTED
        port            = 9418
        socket_type     = stream
        wait            = no
        user            = git
        server          = /usr/bin/git-daemon
        server_args     = --inetd --export-all --verbose --enable=receive-pack  --reuseaddr --base-path=/home/git/
        log_on_failure  += USERID
    }

/home/git

From the git-daemon setting above, the repositories will be in /home/git/

Using it

If there is a project in /home/git/test-project.git, with the above setting you will clone the project with:
git clone git://git.rktmb.org/test-project.git

gitweb debian apache

Goal

Install gitweb on a Debian system

Packages

Needed packages are git, gitweb and git-core.
We are going to put the repositories in /home/git/

Apache Setup

The Apache virtual host configuration needed:
(VirtualHost *:80)
        ServerAdmin mihamina@rktmb.org
        ServerName git.rktmb.org
        DocumentRoot /usr/share/gitweb
        ScriptAlias /cgi-bin/ /usr/lib/cgi-bin/
        (Directory /usr/share/gitweb)
                Options Indexes FollowSymlinks ExecCGI
                DirectoryIndex /cgi-bin/gitweb.cgi
                AllowOverride All
        (/Directory)
        ErrorLog /var/log/apache2/error-git-rktmb-org.log
        LogLevel warn
        CustomLog /var/log/apache2/access-git-rktmb-org.log combined
(/VirtualHost)

GitWeb setup

Just change the line:
$projectroot = "/home/git";
The other lines are all OK.

Testing

Restart apache.
Now go to the ServerName you put in the Apache configuration.

Monday 7 June 2010

26 juin 2010 a madagascar

Independance et resultats

Pour le malgache, depuis 1961, chaque 26 Juin qui passe a été un 26 Juin plus pauvre que celui précédent.
Et pourtant, cela fait 50 ans, que tout le monde le fête, le célèbre et il arrive même qu'on tire des feux d'artifices à l'occasion.
Comble des combles, en 2010, on effectuera un défilé militaire, histoire de montrer qu'il reste encore quelques munitions pour se tirer dessus....

Deuil et aveu d'échec

En ce qui me concerne, le 26 Juin est un deuil à célébrer.
Force est de constater qu'aucun dirigeant malgache n'a su au moins conserver le niveau de vie à madagascar.
Je me demande pourquoi le peuple fait la fête pour cette occasion précise et je me dis que c'est peut-être pour cette raison que rien de bien n'arrive à ce peuple.
Qui oserait prétendre, avec des arguments lourds, que l'indépendance à réussi à Madagascar? (Je l'attends dans les commentaires à ce billet)
Pauvre peuple...

Thursday 3 June 2010

tarifs 4G blueline

Offre Blueline à Madagascar

Pour ceux qui se posent la question, à ce jour (voir date de ce message) voici les prix de l'offre 4G de blueline. On a 2 options: louer ou acheter l'équipement (le modem). Les offres sont plus chères en location
type mise en service frais mensuels
40h/mois à 512Kbps 99000 99000
"illimité" à 512Kbps 99000 149000
"illimité" à 1Mbps 99000 249000
"illimité" à 2Mbps 0 390000
"illimité" à 4Mbps 0 690000
C'est juste un résumé, moi ce n'est que Internet qui m'interesse, mais dans les offres il y a une carte SIM "Blueline" et un pack de chaines TV différent selon les offres prises. Les prix sont en MGA, TTC. Il y a engagements sur 24 mois.

Wednesday 26 May 2010

Get email date of yesterday

Context

I receive a daily bunch of messages from apticron telloing me the servers I need to upgrade.
I want to get the list of hostnames needing updates from the las two days.

Recipe

  • Get into the Maildir folder
  • Get to day and yesterday date
  • Grep the Messages for it
cd /home/mihamina/Mail/
export TODAY=$(date +%Y%m%d)
export TODAY_STRING=$(date +"%a, %d %b %Y")
export YESTERDAY=$(($(date +%Y%m%d)-1))
export YESTERDAY_STRING=$(date +"%a, %d %b %Y" --date=$YESTERDAY)

(for MESS in $(grep -E "^Date: (${TODAY_STRING}|${YESTERDAY_STRING})" * \
    | awk 'BEGIN{FS=":"}{print $1}'); 
 do 
   grep -E "^Subject: " $MESS | awk 'BEGIN{FS=" on "}{print $2}'; 
 done) | sort | uniq 

Tuesday 11 May 2010

one cisco alternative

Always Cisco!

I am amazed people I meet always have Cisco as their first idea when thinking about network equipement.

What else then?

Well,... at least I know Lannerinc making network appliance running Intel or AMD chipsets, standard RAM sticks, standard IDE or SATA drives, standard...
I have installed dozen of them as routers, with standard Debian. It works quite well, and we also charged them with "tc" to manage bandwidth limitation, "iptables" to track and drop nasty traffic, "dhcp" to serve clients, and an MTA to relay and filter mail.

So what?

Well, just wanted to inform you there are alternatives to Cisco. But if you feel happy with their applianances, no proble: ;-)

Thursday 6 May 2010

lvm and PV listing

Goal

I would like to list the PVs involved in a VG. Neither "vgs" nor "vgdisplay" tells me. I need that information in order to install and clone an existing Debian using LVM and want to have the same LVM configuration.

Recipe

The "vgs" output:
root@maila:~# vgs
  VG    #PV #LV #SN Attr   VSize   VFree  
  disk0   1   1   0 wz--n- 931,51G 520,00M
  disk1   1   2   0 wz--n- 447,13G 397,13G      
    
The "pvs" output:
root@maila:~# pvs
  PV         VG    Fmt  Attr PSize   PFree  
  /dev/md1   disk1 lvm2 a-   447,13G 397,13G
  /dev/md2   disk0 lvm2 a-   931,51G 520,00M      
    
How to read it:
  • There is only one PV per VG
  • "md1" belongs to the VG disk1
  • "md2" belongs to the VG disk0
If the output where:
root@maila:~# pvs
  PV         VG    
  /dev/md1   disk1 
  /dev/md2   disk0       
  /dev/md3   disk1 
  /dev/md4   disk0       
  /dev/md5   disk1 
  /dev/md6   disk0       
  /dev/md7   disk1 
  /dev/md8   disk0       
    
Then that would mean:
  • There are 4 PVs per VG
  • "md1", "md3", "md5" and "md7" belong to the VG disk1
  • "md2", "md4", "md6" and "md8" belong to the VG disk0

Wednesday 5 May 2010

dovecot mysql nfs

Existing

  • Debian Lenny
  • Dovecot querying MySQL (virtual users)
  • Remote NFS server storing Maildirs (owned by vmail, iud 500)

Configuration

Dovecot is able to fetch (through IMAP or POP) Maildirs message if it has:
  • The user's HOME
  • The user's UID
  • The user's GID
For Dovecot:
  • The user's Maildir is the user's HOME appended with "/Maildir"
  • Dovecot executes the message fetching as the user's UID
  • Dovecot executes the message fetching as the user's GID

My troubles

My
user_query
returned something like:
home uid gid
/data/mailaka/gulfsat.mg/m/mihamina/ 500 500
I found those lines in my debug logs:
maildir: access(/data/mailaka/gulfsat.mg/m/mihamina//Maildir, rwx):
failed: No such file or directory
maildir: couldn't find root dir
mbox: root exists (/data/mailaka/gulfsat.mg/m/mihamina//mail)
mbox: INBOX: access(/var/mail/mihamina@gulfsat.mg, rw)
failed: No such file or directory
mbox: INBOX: access(/var/spool/mail/mihamina@gulfsat.mg, rw)
failed: No such file or directory
mbox: INBOX defaulted to /data/mailaka/gulfsat.mg/m/mihamina//mail/inbox
Dovecot tried to look for the Maildir structure in
/data/mailaka/gulfsat.mg/m/mihamina//Maildir
which doesnt exist on my system.

The solution

I found that my
user_query
may return an additional column "mail", sot that the result is:
home mail uid gid
/data/mailaka/gulfsat.mg/m/mihamina/ /data/mailaka/gulfsat.mg/m/mihamina/ 500 500
Dovecot immediately found my messages...

Tuesday 4 May 2010

grep et expressions regulieres

But

Affichier un fichier de configuration sans les commentaires. Les commentaires sont délimités par un "#" en début de ligne. Des fois, les "#" sont doublés et sont précédés d'un ou plusieurs espaces ou tabulations (mais restent des commentaires valides)

Avec "grep"

Sous Linux, pour faire ça, on peut utiliser "grep". Pour atteindre mon but, j'utilise cette ligne:
grep -v -E "#" /etc/dovecot/dovecot.conf | grep -v -E "^$" 
L'exemple portait sur un fichier de configuration de Dovecot.

Avec "awk"

En une ligne:
awk '($0 !~ /#/) && ($0 !~ /^$/){print $0}'  /etc/dovecot/dovecot-with-comments.conf 

Thursday 15 April 2010

utiliser les vues de BIND

Resolution variable de "smtp.rktmb.org"

Le but est de faire en sorte que
  • Depuis 192.168.1.0/24, "smtp.rktmb.org" resolve vers 111.222.333.444
  • Depuis 192.168.2.0/24, "smtp.rktmb.org" resolve vers 555.666.777.888
Globalement il s'agit d'utiliser les "view" de BIND.
Actuellement "smtp.rktmb.org" est une enregistrement de type A dans la zone "rktmb.org".

Prérequis

Il y a deja 2 serveurs BIND en production, que nous appellerons "NS1" et "NS2"
Les vues ne seront opérationelles que sur "NS2", si le client fait directement sa requete sur "NS2".

Déléguer les DNS

Dans NS1, /etc/bind/hosts/masters/rktmb.org-hosts:
smtp IN NS ns1.rktmb.org.
smtp IN NS ns2.rktmb.org.
Penser à supprimer les enregistrements A!
"smtp.rktmb.org" n'est plus un simple enregistrement, mais maintenant une zone.

Créer la zone

sur NS1

Dans /etc/bind/named.conf.local:
zone "smtp.rktmb.org" {
 type master;
 file "/etc/bind/hosts/masters/smtp.rktmb.org-hosts";
 allow-query { any; };
 };
Dans /etc/bind/hosts/masters/smtp.rktmb.org-hosts
$ttl 38400
smtp.rktmb.org.      IN      SOA     ns1.rktmb.org. postmaster.rktmb.org. (
                       2010041501
                       10800
                       3600
                       604800
                       38400 )
@   IN NS ns1.rktmb.org.
@   IN NS ns2.rktmb.org.
@ 1 IN  A 111.222.333.444

sur NS2

Dans /etc/bind/named.conf.local, créer la zone slave "smtp.rktmb.org.":
zone "smtp.rktmb.org." {
        type slave;
        file "smtp.rktmb.org.hosts";
        masters {
                ns1.rktmb.org;
                };
        allow-query { any; };
        };
Dans /etc/bind/named.conf.options, dans chaque vue existante, créer des zones master:
view "les-1" {
        match-clients { 192.168.1.0/24 ; };
[...]
        zone "smtp.rktmb.org" {
                type master;
                file "/etc/bind/hosts/masters/smtp.rktmb.org-1";
                allow-query { any; };
        };
};
view "les-2" {
        match-clients { 192.168.2.0/24 ; };
[...]
        zone "smtp.rktmb.org" {
                type master;
                file "/etc/bind/hosts/masters/smtp.rktmb.org-2";
                allow-query { any; };
        };
};

Dans les fchiers de "vues"

/etc/bind/hosts/masters/smtp.rktmb.org-1

$ttl 38400
smtp.rktmb.org.      IN      SOA     ns1.rktmb.org. postmaster.rktmb.org. (
                        2010041501
                        10800
                        3600
                        604800
                        38400 )
@ IN NS ns1.rktmb.org.
@ IN NS ns2.rktmb.org.
@ 1 IN A 111.222.333.444

/etc/bind/hosts/masters/smtp.rktmb.org-2

$ttl 38400
smtp.rktmb.org.      IN      SOA     ns1.rktmb.org. postmaster.rktmb.org. (
                        2010041501
                        10800
                        3600
                        604800
                        38400 )
@ IN NS ns1.rktmb.org.
@ IN NS ns2.rktmb.org.
@ 1 IN A 555.666.777.888

create an LVM volume

Goal

On a machine with LVM installed I would like to create some more /tmp space

Recipe

Ask for information
  # vgs
  VG    #PV #LV #SN Attr   VSize   VFree  
  scsi0   1   3   0 wz--n- 461,10G 195,10G
  scsi1   1   1   0 wz--n- 931,51G  23,85G
  # lvdisplay 
  ...
Create the LVM according to the space left on the Volume group:
  #lvcreate  -L 200G scsi0 -n tmp
  Logical volume "tmp" created
# lvdisplay 
...
 --- Logical volume ---
  LV Name                /dev/scsi0/tmp
  VG Name                scsi0
  LV UUID                ea10iW-wAnS-lUSA-clHW-X2M5-ibN3-uAUrws
  LV Write Access        read/write
  LV Status              available
  # open                 0
  LV Size                200,00 GB
  Current LE             51200
  Segments               1
  Allocation             inherit
  Read ahead sectors     auto
  - currently set to     256
  Block device           253:3
...
Format it
# mkfs.ext3 /dev/scsi0/tmp
Mount and use it
# rm -rf /tmp/* ; 
# mount -t ext3 /dev/mapper/scsi0-tmp /tmp
Note: use "/dev/mapper/scsi0-tmp" not "/dev/scsi0/tmp"
To remove it
# lvremove /dev/scsi0/tmp

Friday 19 March 2010

logrotate bzip2

Goal

I want logrotate to use bzip2 instead of the traditional gzip

Recipe

In /etc/logrotate.conf:
compress
compresscmd /bin/bzip2
compressoptions --best
compressext .bz2

Friday 12 March 2010

pauvres malgaches

Il parait que les Malgaches sont pauvres

(D'apres un commentaire de cet edito)
La pauvreté est comme la guerre, elle laisse des traumatismes et des traces qui sont inconsciemment transmis de génération en génération. Quand on élève et éduque les enfants, on transmet des choses dont on est conscient et d'autres dont on n'est même pas conscient. Les malgaches ne sont pas mauvais mais pauvres, trop pauvres depuis trop longtemps, avec toutes les frustrations qui vont avec, et voilà le résultat.
Alors la solution est dans la profondeur de cette pauvreté, qu'aucun des dirigeants précédents n'on su amoindrir, au contraire. Des solutions efficaces ne vont pas être des solutions rapides car il va falloir s'attendre à plusieurs générations aussi pour rétablir l'équilibre, à condition de commencer le travail maintenant, chacun à son niveau et à sa manière, comme Sobika le fait déjà par exemple en posant les problèmes, en n'ayant cesse de favoriser le dialogue (malgré le fanatisme de certains) et d'inciter chacun de nous ici, de tout bord, à offrir des solutions.

Ben non, les malgaches ne sont pas pauvres

  • J'ai constaté un bond dans immatriculation de vehicules depuis les "TAM"
  • Je vois circuler de plus en plus de Hummers
  • J'ai meme vu une limmousine américaine dans les rues de Tana
  • Et aussi une Porsche Cayman S
  • Chez Geant Score on voit beaucoup de gens faire la queue à la caisse
De quoi se plaint-on?

les malgaches

Critique des malgaches

Apres cet edito de sobika, et les quelques commentaires qui en suivent:
  • Rien à tirer de bon chez les Gasy
  • Misy tokoa ny Malagasy ory hava-manana.
  • Raha ny hevitro dia ny gasy TSY mahavita azy ihany no be vava.
  • les Gasy de France, se jalousent entre eux et ne font preuve que de vantardise avec un état d'esprit "bling bling" et n'ont rien à foutre de ce qui se passe au pays
  • Les malgaches envient trop l'autre et ne supporte pas qu'un des leurs réussisse dans la vie.
Mon avis est que c'est vrai. Si il y avait quelquechose à tirer de positif à Madagascar, ça se saurait.
Il y a bien quelques entrepreneurs qui y arrivent, mais ils sont rares.
Et ils ne sont pas Malgaches...
Chacun en tire les conclusions qu'il veut.
PS: N'oubliez pas le Fecbook version Malgache, pour ce que ça vaut...

Thursday 11 March 2010

Encore une erreur

Après cet édito de Sobika, je me pose la question de la compétence de Ravalomanana. Il avait le pouvoir, pourquoi n'a-t-il pas simplement arrangé le dossier pour qu'on ne puisse pas l'embeter plus tard? En étant un président de la république, c'est extremement facile de demander à la chambre de commerce de valider ce dossier comme étant réglé définitivement! Mais non, il n'a pas fait les choses dans ce sens...

Thursday 18 February 2010

shell random string

Goal

Generate a random string picked from a pattern

Recipe

Build the pattern, the random letter will be taken from it.
export ALPHABET="azertyuiopqsdfghjklmwxcvbn";
The length of the string
mihamina@pbmiha:~$ echo ${#ALPHABET}
26
Generate a random RANK to pick
RANK=$(($RANDOM % ${#ALPHABET}))
Pick one random letter fro the pattern
RANK=$(($RANDOM % ${#ALPHABET})); echo ${ALPHABET:$RANK:1}
Build a 20 characters long random string from the pattern
RANDSTRING=""; 
for I in $(seq 1 20)
do
  RANK=$(($RANDOM % ${#ALPHABET})); 
  RANDSTRING=${ALPHABET:$RANK:1}${RANDSTRING}; 
done; 
echo $RANDSTRING
Make a function to summarize it
function random_string ()
{
    ALPHABET="azertyuiopqsdfghjklmwxcvbn";    
    RANDSTRING=""; 
    for I in $(seq 1 $1)
    do
        RANK=$(($RANDOM % ${#ALPHABET})); 
        RANDSTRING=${ALPHABET:$RANK:1}${RANDSTRING}; 
    done; 
}
random_string 3 ; echo $RANDSTRING
random_string 5 ; echo $RANDSTRING
random_string 15; echo $RANDSTRING

Thursday 11 February 2010

Apple et l'education

Contexte

Sur businessmobile.fr j'ai vu une reaction qui m'a irrité. Je la cite: J'approuve qu'Apple réglemente et contrôle l'ensemble des applications destinées à l'iphone et à l'iPOD Touch. S'il ne faisait pas l'on se retrouverait avec un ensemble de programmes merdiques et/ou pornographiques, voire des jeux débiles comme on en trouve en quantité sur différentes consoles de jeux. Pour ma part je suis d'accord,compte tenu que l'on trouve encore beaucoup d'adultes incapables de contrôler les achats de leur progéniture.

Ma reaction

Si les gens ne sont pas capables d'éduquer correctement leurs enfants, alors c'est à ces parents qu'il faut s'en prendre. Pourquoi acheter un iPhone à des enfants qui ne sont pas capables de reflechir?

Friday 15 January 2010

bash fichiers avec tiret

Problème

J'ai plein ed fichiers avec un "-" dans le nom, et pas partout dnas lenom mais au debut.
Un "ls *" s'y perd, considérant ces fichiers comme des "options" de ligne de commande.
Dans les faits meme un "mv" et un "cp" s'y perdent aussi.

Solution

D'apres un message sur stackoverflow, il suffit de mettre un "--", qui indique la fin des options transmises.

Saturday 2 January 2010

update LILO GRUB2

But

Les serveurs OVH sont installés avec LILO par défaut, je souhaite installer GRUB2 à la place.
Je suis sous Ubuntu Karmic.

Prérequis

Il faut au prealable installer GRUB1
apt-get install grub
et le configurer:
grub-install /dev/sda

Recette

Installer GRUB2, et les package ne s'appelle pas "GRUB2":
apt-get install grub-pc
Catte installation va mettre en place une étape de transition GRUB1 -> GRUB2. Modifier:
nano -w /etc/default/grub
Enlever l'étape de transition par GRUB1
upgrade-from-grub-legacy
Vérifier que tout s'est bien passé
nano -w /boot/grub/grub.cfg 
Supprimer LILO
apt-get remove lilo
Rebooter
reboot

Wednesday 9 December 2009

libvirt virt-install use block device

Goal

I want to use /dev/sda10 as File System of my guest.

Recipe

Just replace the qcow file path with the device and remove the size parameter:
sudo virt-install --connect qemu:///system 
  -n xpsp2 -r 512 -f /dev/sda10
  -c windowsxpsp2.iso 
  --vnc --noautoconsole 
  --os-type windows --os-variant winxp

Thursday 26 November 2009

git resolve conflicts

Goal

I want to resolve file with conflicts

Recipe

First, when a file is in conflict state, git removes it from tracking. The steps are about to edit the file and re-add it:
Here is a sample of conflicted file content
<<<<<<< HEAD:file.txt
Hello world
=======
Goodbye
>>>>>>> 77976da35a11db4580b80ae27e8d65caf5208086:file.txt
Just edit it and then
git add file.txt
git commit

git undo commit

Goal

I accidentally added commited. How can i undo?

Recipe

To Leaves working tree as it was before:
git reset --soft HEAD^
To get 2 commits back
git reset --soft HEAD^^
and so on...
Then
git commit -a -m -c ORIG_HEAD

Other option

If wanting to do a hard reset, just replace "soft" by "hard".

Tuesday 24 November 2009

ocsigen class and id

Goal

Set "class" and "id" attributes on elements

Recipe

open Lwt
open XHTML.M
open Eliom_services
open Eliom_parameters
open Eliom_sessions
open Eliom_predefmod.Xhtml


let main_handler sp () () =
    Lwt.return
      (html
         (head (title (pcdata "ttt") [] ))
         (body [ (div [pcdata "blabla"]) ; 
                 (div ~a:[(a_class ["ak"]); (a_id "ik")] [pcdata "blabla"])]))


let main_service =
  Eliom_predefmod.Xhtml.register_new_service
    ~path: [""]
    ~get_params: Eliom_parameters.unit
    main_handler

ocsigen img tag

Goal

I want an IMG tag

Recipe

open Lwt
open XHTML.M
open Eliom_services
open Eliom_parameters
open Eliom_sessions
open Eliom_predefmod.Xhtml


let main_handler sp () () =
    Lwt.return
      (html
         (head (title (pcdata "ttt")) [] )
         (body [ (div [img ~alt:"Ocsigen" ~src:(make_uri ~service:(static_dir sp) ~sp:sp ["logo.gif"]) ()]) ; 
                 (div [pcdata "blabla"])])


let main_service =
  Eliom_predefmod.Xhtml.register_new_service
    ~path: [""]
    ~get_params: Eliom_parameters.unit
    main_handler
Of course, we need static directory. to be setup in the "ocsigen.conf" file

ocsigen css and javascript in head

Goal

I would like to have this:
< head >
  < title >a sample title< /title >    
  < link href="style.css" type="text/css" rel="stylesheet" / >
  < script type="text/javascript" src="script.js">< / script >
< / head >
This would load one "style.css" file and one "script.js" from the HEAD tag.

Recipe

Static directory in configuration

There must be a "static" directory from where we load the static files.
In the "ocsigen.conf" file:
    < host >
        < site path="xxxx" >
            < static dir="/home/mihamina/public_html/static/" />
            < eliom module="/xxx/xxx.cmo" />
        < / site >
     < / host >

The (Da Mihamina) code :-)

open Lwt
open XHTML.M
open Eliom_services
open Eliom_parameters
open Eliom_sessions
open Eliom_predefmod.Xhtml


let main_handler sp () () =
    Lwt.return
      (html
         (head (title (pcdata "ttt")) [(css_link  (make_uri (static_dir sp) sp ["style.css"]) ()); 
                                       (js_script (make_uri (static_dir sp) sp ["script.js"]) ())])
         (body [   (div [pcdata "blabla"]) ; (div [pcdata "blabla"]) ]))


let main_service =
  Eliom_predefmod.Xhtml.register_new_service
    ~path: [""]
    ~get_params: Eliom_parameters.unit
    main_handler

Thursday 19 November 2009

Just serve an image

Use Case

I have one image URL, I want to serve a different image by IP client

Recipe

open Lwt
open XHTML.M
open Eliom_services
open Eliom_parameters
open Eliom_sessions
open Eliom_predefmod.Any
open Eliom_predefmod.Files 
open Eliom_predefmod.Xhtml


let logo = Eliom_services.new_service
  ["logo"] 
  Eliom_parameters.unit ();;


let logo_handler =
  Eliom_predefmod.Any.register logo
    (fun sp () () -> 
       Eliom_predefmod.Files.send ~sp:sp "/home/mihamina/public_html/GCI/rakotomandimby-logo.png");;
I just have to build a function that returns a different PATH if I want to change the served image

ocsigen upload two files with dynamic name

The goal

I want to upload two files, and put the IP address of the uploader in the filename

The solution

open Lwt
open XHTML.M
open Eliom_services
open Eliom_parameters
open Eliom_sessions
open Eliom_predefmod.Xhtml

let upload = Eliom_services.new_service
  ~path:[""]
  ~get_params:unit ();;

let upload2 = register_new_post_service
  ~fallback:upload
  ~post_params:((file "file_horizontal")**(file "file_vertical"))
  (fun sp () (f_h,f_v) ->
     let to_display =
       let name_h = ("/tmp/t_f_h-"^(Unix.string_of_inet_addr (Eliom_sessions.get_remote_inet_addr sp))) 
       and name_v = ("/tmp/t_f_v-"^(Unix.string_of_inet_addr (Eliom_sessions.get_remote_inet_addr sp))) 
       in
         (try  Unix.unlink name_h
          with _ -> ()); Unix.link (Eliom_sessions.get_tmp_filename f_h) name_h;
         (try  Unix.unlink name_v
          with _ -> ()); Unix.link (Eliom_sessions.get_tmp_filename f_v) name_v;
         (name_h^" et aussi "^name_v);
     in
       Lwt.return
         (html
            (head (title (pcdata "Upload")) [])
            (body [h1 [pcdata to_display]])));;


let uploadform = 
  register upload
    (fun sp () () ->
       let f =
         (post_form upload2 sp
            (fun (file_horizontal, file_vertical) ->
               [p [file_input ~name:file_horizontal ();
                   br ();
                   file_input ~name:file_vertical ();
                   br ();
                   string_input ~input_type:`Submit ~value:"Send" ()]]
            ) ()) 
       in
         Lwt.return
           (html
              (head (title (pcdata "form")) [])
              (body [f])));;

Ocsigen form select

The goal

How to make a Select input with Ocsigen

The solution

open Lwt
open XHTML.M
open Eliom_services
open Eliom_parameters
open Eliom_sessions
open Eliom_predefmod.Xhtml

open Mysql
open Postgresql

let coucou_handler _ selection () =
  Lwt.return
    (html
       (head (title (pcdata "Results")) [])
       (body [p [ pcdata ("You sent: " ^ selection)]]))


let coucou_service =
  Eliom_predefmod.Xhtml.register_new_service 
    ~path: ["coucou"]
    ~get_params: (Eliom_parameters.string "selection")
    coucou_handler

let coucou_form enter_selection =
  [XHTML.M.fieldset
      [Eliom_predefmod.Xhtml.string_select ~name:enter_selection
         (Eliom_predefmod.Xhtml.Option ([], "one",   Some (pcdata "um"),   false))
         [Eliom_predefmod.Xhtml.Option ([], "two",   Some (pcdata "dois"), false);
          Eliom_predefmod.Xhtml.Option ([], "three", Some (pcdata "três"), true)];
       Eliom_predefmod.Xhtml.string_input ~input_type:`Text ~value:"un email seulement" ();
       Eliom_predefmod.Xhtml.string_input ~input_type:`Submit ~value:"Send" ()]]

let main_handler sp () () =
  let myform = Eliom_predefmod.Xhtml.get_form coucou_service sp coucou_form in
    Lwt.return
      (html
         (head (title (pcdata "")) [])
         (body [p [pcdata "Form for coucou:"]; myform]))


let main_service =
  Eliom_predefmod.Xhtml.register_new_service
    ~path: [""]
    ~get_params: Eliom_parameters.unit
    main_handler

Tuesday 17 November 2009

Output a simple Image

Use case

I want to output only an Image with Ocsigen, with the "image" content-type send by the server. I have the path of the image I want to output.

Realisation

open Lwt
open XHTML.M
open Eliom_services
open Eliom_parameters
open Eliom_sessions
open Eliom_predefmod.Xhtml
open Eliom_predefmod.Files

let photo_service = Eliom_services.new_service
  ~path:["photo"] 
  ~get_params:Eliom_parameters.unit ()

let photo_handler =
 Eliom_predefmod.Any.register photo_service
   (fun sp () () -> Eliom_predefmod.Files.send ~sp:sp "rakotomandimby-logo.png")
And that's all.

Sunday 15 November 2009

Settting up network in KVM

When installing a KVM VM in Ubuntu, one of the question is: How to configure its network.
There is basically two choices:
  • A virtual bridge that will NAT the VMs connected to it.
  • A physical bridge so that all VMs will be able to have a "public" IP address

NATing virtual bridge (default, virbr0)

This is the default bridge if you follow the Ubuntu Official tutorial.
This bridge will act as a DHCP server + a gateway. VMs will be able to reach internet but their source IP address will be seen as the virbr0 IP.

Non-NATing bridge

Most of my time, I want to use VMs as public servers. Having them NATed as described above is quite uselss for that purpose.
Libvirt allows to do that, assuming you have
The steps:
  • Create a bridge containing only the physical existing interface
  • Each created VM will then join that bridge
Creating a VM that way is described on a precedent blog post.

Monday 9 November 2009

KVM Ubuntu

Installer KVM

# aptitude install kvm libvirt-bin virt-manager virt-viewer python-libvirt python-virtinst bridge-utils

Mettre l'utilisateur courant dans le bon groupe:

# adduser `id -un` libvirtd

Configurer le réseau de la machine hôte:


auto eth0
 iface eth0 inet manual


auto eth0
iface eth0 inet manual

auto br0
iface br0 inet static
  address 192.168.1.13
  netmask 255.255.255.0
  gateway 192.168.1.254
  bridge_ports eth0 bridge_stp off
  bridge_fd 0
  bridge_maxwait 0

Lancer l'installation d'une machine:

virt-install --connect qemu:///system \
  -n debian-testing-i386-003 \
  -r 1024 \
  -f /data/vm-hd/debian-i386-003.qcow2 \
  -s 12 \
  -c /data/vm-isos/debian-testing-i386-netinst.iso \
  -k fr \
  --accelerate \
  --noautoconsole \
  --network=bridge:br0

Tuesday 3 November 2009

compiler ocaml ocamlc ocamlfind

Pour compiler du code Ocaml, on peut utiliser ocamlc ou ocamlfind.
Ocamlfind trouvera pour nous les bonnes inclusions et les bons flags qu'il faut.
Cependant, comme j'aime bien rester générique, j'utilise l'option verbose de ocamlc pour faire affichier l'invocation entiere.
Ceci me permet de rester avec mon ocamlc favori:
ocamlfind ocamlc -verbose -package str,netcgi2,netcgi_apache,postgresql,mysql -linkpkg -o params.cgi params.ml
Donne
ocamlc -verbose -o params.cgi \
  -I /usr/lib/ocaml/3.10.2/pcre -ccopt -I/usr/lib/ocaml/3.10.2/pcre \
  -I /usr/lib/ocaml/3.10.2/netsys -ccopt -I/usr/lib/ocaml/3.10.2/netsys \
  -I /usr/lib/ocaml/3.10.2/netstring -ccopt -I/usr/lib/ocaml/3.10.2/netstring \
  -I /usr/lib/ocaml/3.10.2/netcgi2 -ccopt -I/usr/lib/ocaml/3.10.2/netcgi2 \
  -I /usr/lib/ocaml/3.10.2/netcgi_apache -ccopt -I/usr/lib/ocaml/3.10.2/netcgi_apache \
  -ccopt -L/usr/lib/ocaml/3.10.2/pcre \
  -ccopt -L/usr/lib/ocaml/3.10.2/netsys \
  -ccopt -L/usr/lib/ocaml/3.10.2/netstring \
  -ccopt -L/usr/lib/ocaml/3.10.2/netcgi2 \
  -ccopt -L/usr/lib/ocaml/3.10.2/netcgi_apache \
  /usr/lib/ocaml/3.10.2/str.cma \
  /usr/lib/ocaml/3.10.2/unix.cma \
  /usr/lib/ocaml/3.10.2/pcre/pcre.cma \
  /usr/lib/ocaml/3.10.2/netsys/netsys.cma \
  /usr/lib/ocaml/3.10.2/netstring/netstring.cma \
  /usr/lib/ocaml/3.10.2/netstring/netaccel.cma \
  /usr/lib/ocaml/3.10.2/netstring/netaccel_link.cmo \
  /usr/lib/ocaml/3.10.2/netcgi2/netcgi.cma \
  /usr/lib/ocaml/3.10.2/netcgi_apache/netcgi_apache.cma \
params.ml

Wednesday 14 October 2009

Les spammeurs Malgaches

Devinez quels sont les plus gros spammeurs à Madagascar?

  • les entreprises de service off-shore (délocalisées)
  • les utilisateurs Windows

Etonnant? Non.

Gandi, Dotclear, bloGTK

Bien,

C'est depuis un client XML-RPC que j'écris ce post: BloGTK. j'utilise le système de "blog" proposé "gratuitement" par mon hébergeur (de nom de domaine): dotclear. J'ai passé ma période de petit geek qui aime avoir un serveur dédié rien que pour mettre son site personnel.

Comme je n'aime pas du tout Facebook, je préfère un blog, quand meme presque 10 ans apres leurs apparition..

Je vais tenter de récuperer le code de mes anciens tutoriaux et les coller ici.

En attendant, c'est aprti pour une journée de travail passionnant

Tuesday 13 October 2009

Les pauvres, qui voudra bien faire quelquechose?

On peut se poser la question suivante: "Pour quelles raisons un dirigeant compétent devrait en premier lieu penser au bien du peuple Malgache?" Avant d'y répondre, deux petites histoires.

1°) J'avais besoin de débrousailler un lopin de terre. Je me suis dit qu'il serait judicieux de créer un emploi pour cette tache. Je fais passer de bouche à oreille le message et un épicier du coin me souffle qu'un gars convient à parfaitement à cela. On me le présente, je l'emmène voir le terrain pour convenir d'un salaire. En voyant le terrain, je sens comme une fuite d'enthousiasme. Sensation confirmée par sa mauvaise foi lors de la négiciation du salaire: il propose très cher, sans consentir de négocier (j'ai des chantiers à mon actif, je connais le salaire moyen, j'étais pret à lui accorder la fourchette haute, pas plus). Apres l'échec de négociation, je reviens vers l'épicier en lui demandant ce que le candidat avait. L'épicier demande:
  • pour combien de temps la tache était prévue?
  • "une semaine", répondis-je
  • Ah mais c'est pour ça! il ne travaillera pas plus d'une journée! j'aurais du vous dire....
2°) Je devais accueuillir quelqu'un à la gare des taxi-brousse. Le taxi-brousse a eu 2heures30 de retard, j'ai donc poireauté presque 3h Ambodivona. Je me suis mis près des pousse-pousses, charettes camions et camionnettes. Tout autour on trouve aussi des "dockers", assis. Vers 9 h, 90% des dockers étaient assis, à discuter, jouer au fanorona,... Les 10% qui travaillaient, (il y a une pente montante assez penible au bout de la route), ils (les 90%) rigolaient meme d'eux (les 10%). Vers 11h30 une partie des 90% commencèrent à aider ceux qui travaillent, en négociant rapidement un petit billet en échange. Petit à petit, jusqu'à midi, tout le monde assis avait disparu. En fait, ils ne se sont que levé parcequ'ils avaient besoin d'acheter à manger.

Et c'est comme ça que tous ces pauvres gens (95% des malgache) vivent: Au jour, le jour. Ils ne travaillent que quand ils en ressentent le besoin. Un travail pérenne, à long terme, il n'en veulent pas. Il gagnent de l'argent aujourd'hui, ne chercheront à travailler que quand ils n'auront plus rien en poche. Et 95% de la population malgache est comme ça. Maintenant, quand on est intelligent, compétent qu'on arrive au pouvoir, et qu'on constate cela: a-t-on l'envie de faire du bien à ce genre de gens?