darkBlog

jeudi 30 mars 2006

Mars, le mois du changement ? Oui, mais pas autant que prévu

Je me dépêche d'écrire ce billet, Mars étant bientôt terminé. Oui, les changements évoqués dernièrement sont toujours d'actualité (d'ailleurs demain est le dernier jour chez mon client), toutefois, en ce qui concerne ma demoiselle, l'emménagement est différé.

En effet, bien que son déménagement ait eu lieu comme planifié, dans les quelques jours qui ont suivi, son ancien employeur l'a recontacté pour lui proposer un nouveau CDD de 6 mois. Nous en avons beaucoup discuté, et finalement elle a accepté cette offre, et est repartie vivre chez ses parents au Havre. Je pense que c'était la meilleure décision à prendre, car cela va lui permettre de chercher un travail (si possible) en région parisienne en parallèle, tout en gagnant de l'expérience, faisant un travail qui lui plait et - détail non négligeable - étant rémunérée.

Je suis bien entendu déçu dans la mesure où j'aspirais (et m'étais préparé) à partager son quotidien, toutefois, les conditions dans lesquelles cela se serait produit n'étaient pas idéales : comme je l'évoquais, une unique pièce de 24m², avec le lit à 2m des ordinateurs. Peut-être que ce "sacrifice" nous permettra, d'ici quelques mois, d'envisager à nouveau la vie commune, avec chacun un travail ainsi que la possibilité financière d'envisager un 2 pièces sur Paris. En attendant, c'est reparti comme avant : moi vivant en célibataire à Paris, elle chez ses parents au Havre , et 4h de train1 tous les week-end pour se voir.

1: bah. ça me donne l'occasion de (re)faire Zelda 3 sur GBA.

Décodage des URL avec Domino : oui mais non

Décidemment, je crois que je ne m'en sortirai jamais avec ces histoires d'encodage et décodage d'URL. Pour ceux qui prennent le sujet en cours de route, petit rappel chronologique :

Quel est le problème cette fois-ci, me demanderiez-vous ? Et bien observez l'extrait de code publié dans ce billet, rapprochez le de cet autre récent billet évoquant la limite de taille des chaînes de caractères dans une formule, et je vous laisse deviner la suite : un texte à décoder trop volumineux amène à un lamentable croûtage de l'Evaluate(). Voilà qui est bien fâcheux. Alors, comment gérer ce type de situation, sachant qu'il n'existe pas de méthode native en LS pour décoder des URLs et que l'utilisation des formules est à proscrire ?

Pour peu que l'on recherche sur le net, on peut trouver des fonctions LS de décodage des URL développées par des tiers : chez Mike Golding, ou encore chez Johan Känngård par exemple. Malheureusement, lors des différents tests que j'ai pû mener, les caractères spéciaux étaient mal restitués, pour des raisons que je n'ai pas vraiment réussi à élucider mais manifestement liées au fait que la tâche HTTP de Domino sert et reçoit (dans ma configuration) les pages en UTF-8 et que, à en croire la documentation, le jeu de caractères natif de l'environnement Domino est celui de la plateforme sur laquelle il s'exécute (dans mon cas Windows 2000), soit selon toutes vraissemblances l'ISO-8859-1 (en tout cas, pas l'UTF-8). Quoi qu'il en soit, même si ce point reste obscur (et ma déduction probablement bancale), il semble clair que le problème est lié à l'encodage des caractères, et on peut en conclure sans crainte qu'il manque un paramètre à toutes ces fonctions de décodage des URL : le jeu de caractères considéré.

Les recherches du coté de LotusScript n'ayant pas donné grand chose de concluant, tournons nous vers Java. Premier réflexe : jeter un coup d'oeil aux spécifications de l'API. Chouette, se dit-on après quelques recherches, Java possède une classe de décodage d'URL : java.net.URLDecoder, et même qu'on peut spécifier le jeu de caractères !
La joie est toutefois de courte durée, puisqu'on s'aperçoit (plus ou moins) rapidement que ce paramètre a été introduit dans la version 1.4 de Java et que la version précédente en est démunie. Or, avec Domino 6.x, c'est bien une JVM 1.3 qui est embarquée. Aussi, à moins d'utiliser un serveur Domino 7 - ce qui n'est pas mon cas - on est de nouveau coincé.
C'est finalement chez Apache que nous trouverons notre salut, du coté du projet Jakarta Commons, avec l'ensemble de composants Commons Codec et plus précisément la classe URLCodec qui - miracle - permet de spécifier un jeu de caractères.

Pour utiliser cette librairie avec Domino, deux solutions : soit dans un agent Java, soit dans un agent LotusScript via LS2J. J'ai opté pour la seconde solution car mon agent LS devant réaliser le décodage était déjà écrit et utilisait tout un tas d'autres bibliothèques LS que je n'avais pas forcément envie de porter en Java. Mais rien ne vous empêche choisir la première.
Pour une solution LS2J, la première étape consiste à mettre au point une librairie de scripts interfaçant cette librairie, que l'on va s'empresser de créer en l'intitulant "URLDecoder" et en y incluant le fichier commons-codec-1.3.jar (téléchargeable ici).

Inclusion de la librairie Commons Codec dans la librairie de scripts URLDecoder
Inclusion de la librairie Commons Codec dans la librairie de scripts URLDecoder

Puis on y insère le code suivant :

import org.apache.commons.codec.net.URLCodec;

public class URLDecoder {
  public static String decode(String s) {
    try {
      URLCodec codec = new URLCodec("UTF-8") ; // selon la plateforme
      return codec.decode(s) ;
    }
    catch (org.apache.commons.codec.DecoderException e) {
      return "URLDecoder error : "+e.getMessage();
    }
  }
}

L'interface Java étant créée, on peut maintenant l'utiliser très naturellement dans nos agents LotusScript via des appels LS2J :

Uselsx "*javacon"

Dim jSession As JavaSession
Dim urlDecoder As JavaClass
Dim decodedString as String

Set jSession = New JavaSession()
Set urlDecoder = jSession.GetClass("URLDecoder")

decodedString = urlDecoder.decode("la chaîne encodée")

Et voilà. Avec cette méthode, les chaînes de caractères sont proprement décodées, les caractères spéciaux correctement restitués, et ce sans limite de taille (puisque c'était là notre problème, pour rappel). Est-ce à utiliser systématiquement pour autant ? Non, car les temps d'exécution sont nettement plus longs qu'avec une méthode basée sur les formules. Toutefois, quand vous ne maîtrisez pas la longueur de la chaîne que vous devez décoder, cette solution peut vous sauver la mise.

Et j'espère ne plus jamais avoir à revenir sur ce sujet.

mardi 28 mars 2006

Perte de mon disque dur de stockage

Je viens de perdre mon disque dur de stockage principal à l'instant : un Maxtor DiamondMax Plus 9 de 160 Go. C'est survenu d'un seul coup : en dézippant une archive, paf, les têtes se mettent à cliquer, le système plante. Reboot. Au démarrage, les têtes cliquent toujours, et, bien que le BIOS détecte le disque dur (non sans peine), une erreur indiquant que le disque n'est pas fonctionnel est affichée. Je viens de passer PowerMax, l'outil de diagnostic de Maxtor, en vain : le disque n'est pas reconnu. Je crains malheureusement qu'il n'y ait plus grand chose à faire pour lui.

Bien que celui-ci soit toujours sous garantie, c'est surtout pour son contenu que j'ai les boules. Outre la perte de sauvegardes de jeux, de pas mal de musique et de toutes les photos que j'ai prises en 2006 (ce dont je pourrais me remettre -- une partie étant sur ce blog), j'ai surtout perdu l'intégralité de mes travaux menés depuis février 2005. Sans compter divers documents administratifs (impôts, etc). Par chance, j'ai un backup de mes comptes bancaires sur mon disque dur système.

Ce qui me chagrine le plus, c'est que j'ai toujours été plutôt paranoïaque et ai systématiquement archivé à un rythme régulier mes données importantes, jusqu'à en doubler les backups ainsi qu'à renouveler les supports âgés (des vieux CD-R de 1996 ou 1997 sur des DVD-R flambants neufs). Toutefois, par manque de temps (car cela en prend beaucoup, de temps), j'ai été clairement laxiste ces derniers mois, et c'est aujourd'hui que je perds un disque dur quasiment plein, alors que cela ne m'est jamais arrivé en 10 ans (sigh).

Apparemment Maxtor effectue un échange standard, mais ne répare pas les disques durs endommagés. Et de ce que j'ai pu en voir de-ci de-là, les sociétés réalisant ce genre de prestation ne sont pas à ma portée financière. Quoi qu'il en soit, je crois que je vais repenser ma politique de stockage ; vu que je n'aurais pas forcément plus de temps par la suite qu'aujourd'hui, je pense que je vais coller 2 disques durs en RAID 1 pour mon stockage. Et automatiser des backups réguliers vers les autres PC (et inversement, d'ailleurs). Si jamais vous avez une idée pour réparer ce disque (ou du moins me permettre d'en récupérer le contenu), n'hésitez pas à m'en faire part.

PS : je ris jaune quand je me remémore ce genre de commentaire.

vendredi 24 mars 2006

Web dynamique avec Domino : pareil, mais en mieux

Vous vous souvenez de la méthode de développement web dynamique que j'ai présenté fin 2004 ? L'idée de base était d'utiliser des sous-masques comme support de cache, en regénérant des bouts de code HTML (typiquement des "portlets") sur action de l'utilisateur ou sur exécution d'une tâche planifiée, en les stockant dans des sous-masques (donc directement dans le design de la base) puis en les restituant aux visiteurs en incluant lesdits sous-masques. Ce qui permet, par exemple, de monter une architecture type portail sans frame ni javascript, et surtout sans la moindre consommation de ressource serveur (pas d'agent WQO, pas de @DbLookup, etc), ce qui est loin d'être négligeable quand la performance est un point critique. Inconvénient toutefois, de par la nature du mécanisme (un cache), la gestion de profils est rendue difficile.

Quoi qu'il en soit, Je n'en ai jamais vraiment reparlé depuis, mais sachez que j'ai mis en place l'année dernière (une partie d')un intranet basé sur ce principe, et que cela fonctionne furieusement bien : 20 000 pages vues par jour, des temps de réponse très faibles, et absolument aucun problème malgré l'apparent bidouillage qu'il y a derrière. Pour éviter tout conflit sur la structure, lors des opérations critiques j'ai utilisé des Locks à la manière d'un mutex. Et pour éviter l'explosion de la base en cas de pépin (ce qui n'est soit dit en passant jamais arrivé), j'ai déporté les sous-masques modifiés par programmation dans une base à part ; la base principale contenant les documents n'est donc jamais modifiée par cette voie. Une sécurité supplémentaire qui induit cependant une maintenance plus délicate, car elle nécessite de fait l'inclusion de sous-masques entre bases (j'ai d'ailleurs découvert des choses amusantes à ce sujet, j'y reviendrai une autre fois).

Si je reviens aujourd'hui sur le sujet, c'est parce que je me suis rendu compte lors de ma récente exploration de DXL que celui-ci introduit des méthodes natives pour réaliser ce même traitement plus simplement, et surtout plus proprement. Explications. Un export DXL d'un sous-masque ressemble à ceci (j'ai simplifié le document XML pour des raisons de lisibilité) :

<?xml version="1.0" encoding="utf-16"?>
<!DOCTYPE subform>
<subform name='portlet-de-test' xmlns='http://www.lotus.com/dxl' replicaid='C12A00Z2013C1485'>
<noteinfo unid='4C240A1EA7321952C131713410135EDC' noteid='5ef'/>
<body><richtext><par><run html='true'>ceci est du code HTML de test&lt;br>et une seconde ligne</run></par></richtext></body>

</subform>

Vous constaterez donc que le code HTML de notre sous-masque est contenu dans un élément par (paragraphe), lui même contenu dans un élément richtext, et que le tout est HTML relai-isé (passthru HTML) via un élément run. Plutôt intéressant, non ? De là à imaginer un traitement qui réalise un export XML d'un sous-masque, qui en modifie les parties qui vont bien (en l'occurence notre code HTML) à l'aide d'un parser XML (DOM ou SAX) voire de XSLT, puis qui réimporte le tout dans la base en remplaçant l'existant, il n'y a qu'un pas. Pas que nous allons franchir un peu plus bas.

Contrairement à leurs homologues Java, les processeurs XML disponibles en LotusScript supportent la notion de pipelining (chaînage) : la sortie d'un processeur sera l'entrée du suivant. Du coup, la réaction en chaîne se produit automatiquement et il n'est pas nécessaire de passer par des fichiers et/ou variables temporaires. Au final, le tout tient en quelques lignes de code (ici avec un parser DOM) :

' Initialisations des processeurs XML
Set Me.exporter = session.CreateDXLExporter()
Set Me.parser = session.CreateDOMParser()
Set Me.importer = session.CreateDXLImporter()

' Exporter
exporter.OutputDOCTYPE = True
Call exporter.setInput(subform)

' Parser
On Event PostDOMParse From parser Call doPostDOMParse
Call parser.setInput(exporter)

' Importer
importer.DesignImportOption = DXLIMPORTOPTION_REPLACE_ELSE_CREATE
Call importer.setInput(parser)
Call importer.setOutput(db)

' Lancement du traitement en chaîne (pipeline)
Call exporter.Process()

Ici subform est notre sous-masque ; il est manipulé comme un document notes et est récupéré via une vue modifiée pour lister les sous-masques de la structure (voir ici pour plus d'infos). L'option DXLIMPORTOPTION_REPLACE_ELSE_CREATE indique au DXL Importer de remplacer l'élément de structure s'il existe déjà (et c'est justement le cas, tiens). La transformation proprement dite du document XML, que je ne détaillerai pas, est réalisée dans le callback doPostDOMParse qui effectue un parcours du document XML à l'aide de DOM et modifie les noeuds concernés. D'ailleurs, la création d'un noeud de type texte (CreateTextNode()) entraîne automatiquement la transformation des caractères spéciaux en entités HTML. C'est beau.

On arrive donc au même résultat qu'avec la méthode présentée fin 2004, mais avec l'assurance d'un code robuste et entièrement basé sur des fonctionnalités natives de Domino, ce qui est un peu plus rassurant quand on envisage de le déployer chez un client. Quant à DXL, je dois avouer que c'est l'une des choses les plus excitantes que j'ai découvert avec Domino dernièrement. D'autres billets à venir sur le sujet. Enfin, ceux qui le souhaitent pourront trouver la classe ici : CacheManagement.lss.

lundi 20 mars 2006

Versioning de bases Domino avec Subversion

Il y a une idée qui me trottait dans la tête depuis pas mal de temps et que j'ai évoqué il y a quelques jours : versionner les bases Domino avec Subversion. Enfin, pas les bases en elles-même car ça n'aurait pas vraiment d'intérêt, mais plutôt leurs exports DXL (DXL permettant d'exporter une base sous forme de fichier XML structuré selon la DTD Domino).

Dès lors, on pourrait imaginer historiser chaque évolution d'une base dans un repository SVN (ce qui peut se faire sans recourir à DXL), mais surtout comparer différentes versions de cette même base (c'est à partir de là qu'intervient DXL), voire même assembler les travaux de plusieurs développeurs sur une même ressource (un agent, une librairie de script..) ou pourquoi pas générer des nighty builds (sachant qu'il est possible de concevoir une base depuis des données DXL, soit l'opération inverse de la précédente)... Plutôt alléchant, non ?

Différences entre 2 versions d'une même base avec TortoiseMerge
Différences entre 2 versions d'une même base avec TortoiseMerge

En pratique, le bilan est plutôt mitigé. Si la comparaison donne de bons résultats sur une base ayant subit peu de changements (voir la capture d'écran ci-dessus), elle a tendance à s'emmêler les pinceaux sur une base dont la structure a pas mal évolué, et ne retrouve pas forcément ses petits (du coup, un bout de code qui n'a pas changé peut être considéré comme supprimé dans l'ancienne version et ajouté dans la nouvelle).

Pour éviter cet effet, il conviendrait de réduire la granularité ; non pas historiser des exports de bases complètes, mais des exports d'ensembles d'éléments de design, voire même des éléments de design un par un. Ce qui signifie exporter les éléments de design un par un. Bien que cela reste techniquement faisable moyennant l'agent qui va bien, cela pose derrière, je crains, des problèmes de cohésion : comment vérifier l'évolution d'une base dans son ensemble, sachant qu'il n'y a plus d'historique global de la base ?

Bref, ce n'est pas si évident que ça. J'avoue ne pas trop savoir quoi en penser ; je suis convaincu qu'il y a quelque chose de puissant à faire avec Subversion et Domino, mais en l'état cela ne me paraît pas vraiment exploitable. Vous en pensez quoi ?

Pour info, j'ai essayé d'interfacer un agent Java avec un repository SVN pour automatiser le commit de la base. La seule API que j'ai trouvé est JavaSVN, qui malheureusement nécessite J2SE 1.4 et supérieur. Or, c'est le JDK 1.3 qui est embarqué dans Notes et Domino R6.x. N'ayant pas plus de serveur Domino que de client ou designer Lotus R7, je n'ai pu pousser mes tests plus loin.

mardi 14 mars 2006

Champion plus fort que Quick !

A Champion, y'a peut-être pas de wifi, mais à coté ils assurent la vie éternelle à leurs clients. La grande classe.

Vous êtes accueili par : Jesus

PS : Oui, j'aime manger des Crunchy chocolat le matin.

Limite de taille d'une chaîne de caractères dans une formule

Julien a évoqué dernièrement les limitations connues de Domino 5, 6 et 7. Pour ma part j'ai été confronté aujourd'hui à ce qui semble être une limite peu voire pas connue de Domino (R6.5) : les chaînes de caractères dans les formules ont une taille qui semble se limiter à environ 2050 caractères. Au delà, il devient impossible de sauvegarder la formule, et le message d'erreur Quoted string is too long est retourné. Je n'ai pas trouvé la limite exacte, j'imagine qu'elle s'exprime en octets et non en nombre de caractères, et qu'en ce sens elle doit varier selon la nature desdits caractères (codés sur 1 ou 2 octets en interne ?).

Quoted string is too long : Lorem Lipsum...

Dans l'exemple ci-dessus on se rend compte aisément du problème, mais pour peu que le traitement soit réalisé au travers d'un Evaluate() embarqué dans du code LS ou Java, la formule plante sans rien dire, et le script sans raison apparente.
C'est ça qui est beau avec Domino : quand on entame avec morosité une journée de développement que l'on croit déjà toute traçée, il y aura toujours une petite subtilité sur laquelle bûter pour egayer la journée !

jeudi 9 mars 2006

Mars, le mois du changement ?

Outre les excellentes affiches que j'ai pu évoquer dernièrement (d'ailleurs No Return et Psoriasis c'est demain, et c'est l'ami Damien de Luna Frigidis qui organise ça, alors venez nombreux !), mars disais-je, c'est du blast, mais c'est aussi pas mal de changements dans ma vie. A savoir :

  • Mes parents quittent définitivement Le Havre pour s'installer dans leur contrée natale : la Bretagne. Le déménagement aura lieu la semaine prochaine. Du coup, je les verrai moins souvent (plus loin, plus cher), tout comme je retournerai moins au Havre (moins d'attaches ; il y restera une partie de ma famille ainsi qu'une poignée d'amis). D'ailleurs, la Darkmobile, que j'ai lâchement abandonné depuis mon arrivée à Paris et qui accessoirement revient encore une fois de loin (changement du joint de culasse ainsi que du tableau de bord que j'avais grillé par mégarde), part avec eux. Etrange sensation, ceci dit, après avoir passé 24 ans dans une ville, que de s'y sentir étranger, plus vraiment chez soi.
  • Ma demoiselle est parallèlement en train de s'installer avec moi, à Paris. D'ailleurs, le déménagement, c'est pour demain. La grande arrivée des chaussettes, des peluches, des services de couverts qu'on a pu lui offrir aux noëls passés, tout ça. Curieux, cela coïncide (presque) jour pour jour avec nos 4 ans, tiens. Quoi qu'il en soit, je me demande bien où on va pouvoir caser tout ça dans mon notre studio de 30m². Et surtout, si on va tenir 15 jours dans un espace si confiné sans en venir aux mains. Se voir le week-end et les vacances c'est une chose, vivre ensemble au quotidien doit en être une autre, j'imagine. D'autant plus quand l'un débarque dans des lieux occupés par l'autre depuis un an, et que ce dernier a pris de mauvaises habitudes de geek célibataire (oui, l'autre, c'est moi). Comment le premier peut se sentir chez soi dans un espace rempli de cables RJ45 et de claviers en vrac ? Comment l'autre (moi) va vivre cette "intrusion" ? Sans parler des goûts musicaux divergents en pas mal de points. Ne vous méprenez pas, je suis foncièrement heureux que Sophie (c'est son petit nom) me rejoigne. Je crains toutefois que la cohabitation ne soit pas forcément facile. En être conscient, déjà bien, me diriez-vous. Bref, plein de joie, mais aussi plein d'interrogations, de craintes, de doutes. La suite au prochain épisode.
  • Enfin, je quitte - sur ma demande - mon client actuel à la fin du mois, après 19 mois de prestation. Non pas que ça se passait mal, mais 19 mois, c'est long. On tutoie tout le monde dans la boite, on fait la bise aux nanas des ressources humaines, on a vu des tas de gens arriver, partir ; bref, on fait presque parti des meubles. Mais je ne fais pas parti des meubles, justement. Je pense que voir de nouvelles têtes, de nouveaux contextes, être confronté à de nouvelles problématiques va me faire du bien. J'espère aussi que cela me permettra de m'orienter vers d'autres technologies, en l'occurence revenir vers PHP, que je crois aujourd'hui mature pour l'entreprise (ce qui n'était, il me semble, pas le cas il y a 2 ans). Je vais consacrer une grande partie de mon temps chez un nouveau client (d'ailleurs rencontré par l'intermédiaire de ce blog, comme quoi tout peut arriver) pour des réalisations Lotus Domino, j'espère que je pourrais m'atteler sur le temps restant à des réalisations PHP (d'ailleurs, si vous cherchez quelqu'un, vous pouvez toujours me faire signe). En tout cas, développer un pôle PHP est une volonté de ma société, j'espère que nous arriverons à amorcer ce virage, après 7 ans d'activité purement Lotus, et un paquet de clients fidèles demandeurs et à satisfaire (sachant que nous sommes 4).

Quant au reste, vous aurez sans doute noté une baisse d'activité sur ce blog. Toujours pas de suite à l'épopée FreeBSD, toujours pas de billet sur Domino (pourtant j'ai un truc en suspend que je pense être très prometteur : le versioning des bases Domino avec Subversion -- me reste à finir de coder l'agent Java qui va bien et à confirmer le concept), plus de séance photos, etc. Cela reflète assez bien mon activité du moment, à savoir, à part trainer chezwat, matter des DVD et jouer à la DS : pas grand chose. Je sais pas, je n'ai pas vraiment envie de grand chose en ce moment. Et le plus triste, c'est que je m'y accommode plutôt bien, à ne rien faire. Il va falloir que je me reprenne un peu en main, toutefois, mes priorités prochaines vont sans doute ne pas être dans l'informatique (voir le point n°2 de la liste précédente). Bref, ne m'enlevez pas tout de suite de votre aggrégateur RSS, je prédis deux ou trois trucs intéressants dans les prochains jours semaines mois à venir.

jeudi 2 mars 2006

Conférence sur les clients riches avec XUL

Ce soir l'AFUP organise une conférence sur les clients riches avec XUL, à 20h00 dans le 14ème (à 5 stations de métro de chez moi !). Y interviendront Laurent Jouanneau de Xulfr.org et Edouard Andrieu ainsi qu'Olivier Grange-Labat de LeMonde.fr. C'est donc avec grand plaisir que je vais m'y rendre (avec plus ou moins de retard, selon la séance de squash), et j'espère voir de mes yeux à quoi ressemble le back-office de LeMonde.fr fait à base de XUL (enfin une vrai application à montrer ?).

Edit : Bon ben c'était très intéressant, même si je m'attendais à un peu plus de pragmatisme et moins d'évangélisme de la part de l'équipe de LeMonde.fr. En tout cas, merci l'AFUP, merci JMF pour l'invit, et merci aux intervenants.

Fichiers créés par des applications web et droits d'accès

Ca ne vous est jamais arrivé qu'une application web vous génère des fichiers auxquels vous n'avez pas accès en écriture avec votre utilisateur courant ? Moi si, souvent. Et pas plus tard qu'il y a quelques jours, quand j'ai voulu migrer ce Dotclear en 1.2.3. Jusqu'à présent, je m'étais toujours trouvé dans l'incapacité à régler ce genre de problème. Par chance, mon hébergeur étant fort sympathique, il me rétablissait gentiment les droits derrière.

Pourtant, il existe une solution toute simple, tellement simple que cela explique probablement pourquoi je n'y ai jamais pensé (...) : modifier les droits des fichiers concernés au travers d'un script exécuté depuis le web1 (et donc - c'est là l'astuce - avec l'utilisateur sous lequel serveur web tourne).

Démonstration :

> ll
-rwxr-xr-x 1 darkmag darkmag 43 Nov 30 15:44 UPDATE*
-rw------- 1 nobody darkmag 1893 Feb 24 12:44 config.php
-rwxr-xr-x 1 darkmag darkmag 1908 Nov 30 15:44 config.php.in*

> chmod 777 config.php
chmod: config.php: Operation not permitted

> vi chmod.php
<?php
system("chmod 777 /usr/home/darkmag/public_html/blog/conf/config.php");
?>

> lynx http://darkmag.net/blog/chmod.php

> ll
-rwxr-xr-x 1 darkmag darkmag 43 Nov 30 15:44 UPDATE*
-rwxrwxrwx 1 nobody darkmag 1893 Feb 24 12:44 config.php*
-rwxr-xr-x 1 darkmag darkmag 1908 Nov 30 15:44 config.php.in*

Et voilà !

1 : en mode SAPI pour PHP, tout du moins. Je me demande sous quel utilisateur tourne un PHP en mode CGI. J'imagine que c'est celui du serveur web également, vu qu'à ma connaissance c'est lui qui lance l'exécutable PHP. Quelqu'un peut confirmer ?