J'attendais avec impatience la sortie de Blue Mind depuis un moment et j'aimerais essayer de le faire tourner sur un serveur existant qui propose déjà un ensemble de services et qui tourne sous Debian.
Je comprends tout à fait cette volonté de vouloir fournir un outil qui s'installe en 3 clics et je trouve ça très bien. Cependant, si jamais on n'utilise pas une Ubuntu, qu'on veut installer une sous-partie du système, ou qu'on a déjà une architecture web déjà installée, c'est un peu délicat de partir du .deb… J'ai vu qu'il y avait un dépôt git avec des sources et des scripts bash, mais où est la documentation ?
Merci et félicitation pour ce nouveau projet qui m'a l'air fort prometteur.
C'est plus ou moins l'idée. En gros Jappix utilise Bochs pour communiquer avec le serveur distant et donc à un moment où à un autre, il va envoyer, via un script JS, le login et le mot de passe. Il ne passe pas de mot de passe en GET à proprement parler puisque Jappix tourne côté client, c'est le serveur PHP qui va altérer le code de Jappix pour renseigner login et mot de passe (le login et le mot de passe sont enregistrés dans une session).
Tu y vois notamment : launchMini(autoconnect, show_pane, domain, username, password); Et c'est donc dans le script JS qu'on rajoute un brin de PHP pour modifier le login/password pour que le client utilise le mot de passe temporaire.
Le principe doit aussi marcher avec du Jappix classique puisque c'est le client qui communique avec le serveur Jabber, donc il suffit de remplacer le formulaire pour le compléter automatiquement en PHP.
Dans la conf, j'utilise "internal" pour les comptes locaux comme "admin" et "pam" pour le ldap, les comptes locaux autorisés et l'authentification internet (celui avec un mot de passe différent).
Je ne vais pas expliquer le fichier /etc/pam.d/ejabberd pour 2 raisons : j'ai fait ça il y a longtemps et je n'ai pas le temps :). Mais en gros, il faut utiliser pam_mysql.
J'ai utilisé OpenFire il y a environ 2 ou 3 ans, j'avais été séduit en particulier pour sa configuration par interface graphique vraiment pratique. Malheureusement, les mises à jours se font rares, j'avais de petits bugs non critiques mais non corrigés pendant des mois, les comptes utilisateurs devaient être sur le ldap ou sur un compte interne mais pas les 2 à la fois, ou un truc du genre. Il me semble que le bochs n'était pas tout à fait compatible avec les clients web que je voulais utiliser. Je ne sais plus exactement ce qui m'a décidé mais finalement j'ai laissé tomber pour ejabberd.
Ejabberd consomme moins de mémoire et de ressource cpu, il plante moins, et il est ultra configurable. On peut facilement étendre l'identification en utilisant pam ou autre ce qui m'a permis quelques bidouilles fort utiles.
Sur le site dont je m'occupe, nous avons une contrainte forte : interdiction de sauvegarder un mot de passe et aucun mot de passe ne doit passer en clair. Afin d'éviter de redemander aux utilisateurs déjà identifiés sur le site (via ldap) de se relogguer pour accéder au chat, nous générons un mot de passe à usage temporaire (le temps de la session) qui sert de mot de passe pour jabber. Ainsi les clients web utilisent ce mot de passe pour s'authentifier. Ceci était plutôt simple à mettre en place avec ejabberd et tout simplement impossible avec OpenFire.
Dans les clients, nous utilisons principalement gajim en client lourd et jappix + muckl en client web. Pour faire marcher Jappix, il a juste fallu configurer ejabberd pour activer bochs, je ne vois pas ce qu'une intégration pourrait apporter de plus, surtout que notre jappix est intégré au portail web (et comme expliqué, se connecte sans demande de mot de passe si l'utilisateur est déjà connecté au portail).
Je viens d'essayer mais visiblement, ça ne change rien au code assembleur généré.
Du coup j'ai essayé d'afficher l'eflag et même de le modifier et : il est bien à 0 (vérifié depuis bochs mais aussi en rajoutant du code assembleur dans le code de test) et si je le change de sens, ça plante aussi.
(bon cela dit, effectivement, on s'en est pas soucié non plus il me semble donc ça aurait pu être une source de problème similaire à linux)
C'est une excellente remarque, peut-être que qemu n'est pas aussi regardant sur les problèmes d'alignement. Ce qui m'étonne c'est que j'ai tout un tas d'autres applications et que je n'ai jamais rencontré ce problème avant.
Ce soir, je jouerai un peu avec la pile pour voir. C'est vrai qu'on y place un tas d'infos (argc, argv, envp) sans se soucier de grand chose en terme d'alignement… Cette partie ne m'est pas entièrement familière car elle a été codée par un pote.
1) tu t'es trompé et le problème ne vient pas de là
J'ai eu ce problème aussi avec une autre application qui cherchait à faire un truc similaire et remplacer newt = oldt; par un memcpy a aussi résolu le bug. Si je ne me trompe pas de bug, sur cette application, l'exception levée était un General Protection Fault (GDT:0x00000000) et j'avais le bug avec bochs, kvm et virtualbox.
Mais sinon, je veux bien croire à un effet de bord, c'est justement la raison pour laquelle je pose la question au lieu de me dire que le problème est réglé. Mais je ne vois pas trop… J'essaierai de faire d'autres tests ce soir pour voir si le problème se pose avec toutes les structures, si les syscall qui précèdent ont une importance, etc.
2) la différence sur les octets de bourrage ont un impact sur l'émulateur (??)
wtf :).
3) bug du compilateur: essayer de regarder l'assembleur généré.
Ouais, j'y ai songé, mais ce qui m'étonne c'est que justement ça varie d'un émulateur à l'autre (et compilé avec glibc puis exécuté sous Linux, je n'ai aucun problème non plus).
1) Ce n'est pas si cher que ça. C'est rien comparé au prix d'un verre d'alcool dans n'importe quel bar.
2) Le gros souci du "2 verres épicétou" c'est que 2 verres d'alcool fort avec un dosage maison, ou 2 pintes de bière, c'est déjà trop.
Je ne prends jamais le volant si j'ai bu plus d'une bière (disons > 30cl). Ce n'est pas parce que la loi est souple et permet plus que c'est une bonne idée. La loi ne m'interdit pas de conduire à 5h du matin sans avoir dormi depuis plus de 20h, ce n'est pas pour autant une bonne idée.
Tu as en effet des règles qui ont je pense tendance à augmenter la difficulté. Cependant on retrouve des problématiques communes.
Le probleme étant qu'un coup qui rapporte peu de points n'est pas forcement moins bien qu'un coup qui rapport beaucoup de points car ça peut amener un autre coup qui rapporte beaucoup de points (et cela le coup suvant ou 10, 20 ou 30 coups plus tard…)
C'est typiquement pour cette raison que s'arrêter sur un graphe non fini donnait de moins bons résultats que de continuer avec un algo glouton.
Sur tes autres pistes :
- Jouer bêtement : Je ne crois pas trop à cette approche mais ça me fait penser qu'il serait intéressant de mettre en place un réseau de neurones pour qu'il apprenne à reconnaître certains patterns de jeu et voir ce qu'il arrive à en apprendre :). L'avantage c'est qu'une fois qu'il est bien entraîné, il sera rapide. J'ai aucune idée de l'efficacité d'une telle approche et encore moins du temps d'apprentissage nécessaire.
- Brute force :) Ça va dépendre de la taille de ta grille mais si une partie fait environ 20 clics et qu'il y a à chaque clics disons 5 possibilités, ça fait déjà un bon paquet :)
- La dernière solution : cf prob du super coup à k+1.
Je ne me souviens plus de la taille de la grille, mais je dirais de l'ordre de ton mode extra large.
J'ai simplifié mon algo pour les explications, c'était un peu plus compliqué que ce que j'ai annoncé mais je ne m'en souviens plus maintenant :). En tout cas, une bonne source d'inspiration à l'époque c'était un papier de recherche. Je me demande si ce n'était pas : "Single-Player Monte-Carlo Tree Search" de Maarten et al.
J'avais dev il y a 3-4 ans un samegame dans le cadre de mes études en GtkAda et l'une des particularités c'était un mode où l'ordi encadrait le groupe de boules qu'il te conseillait de supprimer.
Alors de mémoire, l'idée c'était de faire un parcourt exhaustif en profondeur dans le graphe d'états sur genre 5 niveaux puis de finir avec une heuristique du genre : "je choisi une couleur et tant que je peux je ne joue que cette couleur, sinon j'en change". Ça me donnait donc un ensemble de scores sur les feuilles et je choisissais donc la branche qui m'avait donné le meilleur score. (l'utilisation d'une heuristique pour "finir" le jeu était bien meilleure que de pousser sur un niveau de profondeur supplémentaire et prendre en compte que le score intermédiaire pour évaluer les noeuds)
La grille de jeu était plus grande (d'où l'obligation de se limiter à 4 ou 5 en profondeur) et il n'était pas nécessaire de détruire toutes les billes pour gagner, seul le score comptait.
Dans le même genre, il y a de ça un bon nombre d'années maintenant, j'ai eu droit en pleine nuit à un curseur de souris qui s'est mis à bouger un peu dans tous les sens sur une amplitude de 1 à 2cm environ.
Au bout de quelques minutes, j'ai enfin trouvé la réponse à ce mystère : un papillon de nuit s'était glissé dans le trou où il y a le capteur de la souris optique.
C'est beaucoup plus simple... Un Linuxien a le sentiment de faire partie d'une communauté (de part son nombre plus réduit) dont il est fier et il a envie de faire honneur à sa communauté en étant plus généreux que les autres. Ça ne va pas plus loin que ça.
# Documentation plus technique...
Posté par Maxime (site web personnel) . En réponse à la dépêche Blue Mind : une nouvelle messagerie collaborative open source. Évalué à 4.
Bonjour,
J'attendais avec impatience la sortie de Blue Mind depuis un moment et j'aimerais essayer de le faire tourner sur un serveur existant qui propose déjà un ensemble de services et qui tourne sous Debian.
Je comprends tout à fait cette volonté de vouloir fournir un outil qui s'installe en 3 clics et je trouve ça très bien. Cependant, si jamais on n'utilise pas une Ubuntu, qu'on veut installer une sous-partie du système, ou qu'on a déjà une architecture web déjà installée, c'est un peu délicat de partir du .deb… J'ai vu qu'il y avait un dépôt git avec des sources et des scripts bash, mais où est la documentation ?
Merci et félicitation pour ce nouveau projet qui m'a l'air fort prometteur.
[^] # Re: Retour d'expérience diverse
Posté par Maxime (site web personnel) . En réponse au journal Réseau social et chat libre (Openfire + Jappix). Évalué à 2. Dernière modification le 05 avril 2012 à 15:22.
C'est plus ou moins l'idée. En gros Jappix utilise Bochs pour communiquer avec le serveur distant et donc à un moment où à un autre, il va envoyer, via un script JS, le login et le mot de passe. Il ne passe pas de mot de passe en GET à proprement parler puisque Jappix tourne côté client, c'est le serveur PHP qui va altérer le code de Jappix pour renseigner login et mot de passe (le login et le mot de passe sont enregistrés dans une session).
Ici on utilise Jappix Mini, voici la doc : http://codingteam.net/project/jappix/doc/JappixMini
Tu y vois notamment : launchMini(autoconnect, show_pane, domain, username, password); Et c'est donc dans le script JS qu'on rajoute un brin de PHP pour modifier le login/password pour que le client utilise le mot de passe temporaire.
Le principe doit aussi marcher avec du Jappix classique puisque c'est le client qui communique avec le serveur Jabber, donc il suffit de remplacer le formulaire pour le compléter automatiquement en PHP.
[^] # Re: Retour d'expérience diverse
Posté par Maxime (site web personnel) . En réponse au journal Réseau social et chat libre (Openfire + Jappix). Évalué à 3.
Dans la conf, j'utilise "internal" pour les comptes locaux comme "admin" et "pam" pour le ldap, les comptes locaux autorisés et l'authentification internet (celui avec un mot de passe différent).
{auth_method, [internal, pam]}.
{pam_service, "ejabberd"}.
Je ne vais pas expliquer le fichier /etc/pam.d/ejabberd pour 2 raisons : j'ai fait ça il y a longtemps et je n'ai pas le temps :). Mais en gros, il faut utiliser pam_mysql.
# Retour d'expérience diverse
Posté par Maxime (site web personnel) . En réponse au journal Réseau social et chat libre (Openfire + Jappix). Évalué à 2.
Bonjour,
J'ai utilisé OpenFire il y a environ 2 ou 3 ans, j'avais été séduit en particulier pour sa configuration par interface graphique vraiment pratique. Malheureusement, les mises à jours se font rares, j'avais de petits bugs non critiques mais non corrigés pendant des mois, les comptes utilisateurs devaient être sur le ldap ou sur un compte interne mais pas les 2 à la fois, ou un truc du genre. Il me semble que le bochs n'était pas tout à fait compatible avec les clients web que je voulais utiliser. Je ne sais plus exactement ce qui m'a décidé mais finalement j'ai laissé tomber pour ejabberd.
Ejabberd consomme moins de mémoire et de ressource cpu, il plante moins, et il est ultra configurable. On peut facilement étendre l'identification en utilisant pam ou autre ce qui m'a permis quelques bidouilles fort utiles.
Sur le site dont je m'occupe, nous avons une contrainte forte : interdiction de sauvegarder un mot de passe et aucun mot de passe ne doit passer en clair. Afin d'éviter de redemander aux utilisateurs déjà identifiés sur le site (via ldap) de se relogguer pour accéder au chat, nous générons un mot de passe à usage temporaire (le temps de la session) qui sert de mot de passe pour jabber. Ainsi les clients web utilisent ce mot de passe pour s'authentifier. Ceci était plutôt simple à mettre en place avec ejabberd et tout simplement impossible avec OpenFire.
Dans les clients, nous utilisons principalement gajim en client lourd et jappix + muckl en client web. Pour faire marcher Jappix, il a juste fallu configurer ejabberd pour activer bochs, je ne vois pas ce qu'une intégration pourrait apporter de plus, surtout que notre jappix est intégré au portail web (et comme expliqué, se connecte sans demande de mot de passe si l'utilisateur est déjà connecté au portail).
[^] # Re: Type de compilation ?
Posté par Maxime (site web personnel) . En réponse au message Différence affectation de structure et memcpy. Évalué à 2.
Je viens d'essayer mais visiblement, ça ne change rien au code assembleur généré.
Du coup j'ai essayé d'afficher l'eflag et même de le modifier et : il est bien à 0 (vérifié depuis bochs mais aussi en rajoutant du code assembleur dans le code de test) et si je le change de sens, ça plante aussi.
(bon cela dit, effectivement, on s'en est pas soucié non plus il me semble donc ça aurait pu être une source de problème similaire à linux)
[^] # Re: Type de compilation ?
Posté par Maxime (site web personnel) . En réponse au message Différence affectation de structure et memcpy. Évalué à 2.
Merci pour le lien, je regarderai ça plus tard. J'ai testé vite fait l'affichage des adresses des variables a et b :
Et là, j'obtiens bien des adresses multiples de 4… Et ça plante après les printf.
[^] # Re: Type de compilation ?
Posté par Maxime (site web personnel) . En réponse au message Différence affectation de structure et memcpy. Évalué à 2.
C'est une excellente remarque, peut-être que qemu n'est pas aussi regardant sur les problèmes d'alignement. Ce qui m'étonne c'est que j'ai tout un tas d'autres applications et que je n'ai jamais rencontré ce problème avant.
Ce soir, je jouerai un peu avec la pile pour voir. C'est vrai qu'on y place un tas d'infos (argc, argv, envp) sans se soucier de grand chose en terme d'alignement… Cette partie ne m'est pas entièrement familière car elle a été codée par un pote.
[^] # Re: Type de compilation ?
Posté par Maxime (site web personnel) . En réponse au message Différence affectation de structure et memcpy. Évalué à 3.
Après avoir fait du pas à pas avec le debugguer de bochs, voici des infos complémentaires :
(0).[6946995606] [0x0000000002669023] 001b:40000023 (unk. ctxt): rep movsd dword ptr es:[edi], dword ptr ds:[esi] ; f3a5
CPU 0: Exception 0x0d - (#GP) general protection fault occured (error_code=0x0000)
CPU 0: Interrupt 0x0d occured (error_code=0x0000)
[^] # Re: Alignement?
Posté par Maxime (site web personnel) . En réponse au message Différence affectation de structure et memcpy. Évalué à 3.
Oui, cela serait étrange… Surtout que ça plante aussi avec
Mais peut-être l'utilisation d'une instruction non supportée par la plateforme émulée par Bochs ?
[^] # Re: Type de compilation ?
Posté par Maxime (site web personnel) . En réponse au message Différence affectation de structure et memcpy. Évalué à 3.
En fait, mon extrait était bien incomplet, le pushl %ebp est juste au dessus, commun aux 2 codes :
[^] # Re: Type de compilation ?
Posté par Maxime (site web personnel) . En réponse au message Différence affectation de structure et memcpy. Évalué à 3.
Je pense que mon extrait est assez complet, voici un diff pour compléter :
Qu'est-ce qui pourrait être à l'origine de ce problème ? D'ailleurs, j'ai remplacé la structure termios par :
struct toto {
int c[17];
};
Et j'ai le bug pour une valeur >= 17. En dessous, il ne fait pas de push/pop mais plein de movl.
[^] # Re: Type de compilation ?
Posté par Maxime (site web personnel) . En réponse au message Différence affectation de structure et memcpy. Évalué à 2.
J'ai donc compilé avec ma libc une fonction qui contient le code ci-dessus.
Code qui plante :
code qui ne plante pas :
Est-ce que quelqu'un qui parle l'assembleur x86 couramment pourrait en faire un petit commentaire ?
[^] # Re: Type de compilation ?
Posté par Maxime (site web personnel) . En réponse au message Différence affectation de structure et memcpy. Évalué à 3.
Voici un code minimaliste qui fait planter sous Bochs :
[^] # Re: Type de compilation ?
Posté par Maxime (site web personnel) . En réponse au message Différence affectation de structure et memcpy. Évalué à 2.
J'ai eu ce problème aussi avec une autre application qui cherchait à faire un truc similaire et remplacer newt = oldt; par un memcpy a aussi résolu le bug. Si je ne me trompe pas de bug, sur cette application, l'exception levée était un General Protection Fault (GDT:0x00000000) et j'avais le bug avec bochs, kvm et virtualbox.
Mais sinon, je veux bien croire à un effet de bord, c'est justement la raison pour laquelle je pose la question au lieu de me dire que le problème est réglé. Mais je ne vois pas trop… J'essaierai de faire d'autres tests ce soir pour voir si le problème se pose avec toutes les structures, si les syscall qui précèdent ont une importance, etc.
wtf :).
Ouais, j'y ai songé, mais ce qui m'étonne c'est que justement ça varie d'un émulateur à l'autre (et compilé avec glibc puis exécuté sous Linux, je n'ai aucun problème non plus).
[^] # Re: Type de compilation ?
Posté par Maxime (site web personnel) . En réponse au message Différence affectation de structure et memcpy. Évalué à 2.
C'est du C99.
[^] # Re: Je sais pas quels lobbyistes sont les plus lourds...
Posté par Maxime (site web personnel) . En réponse au journal A moto, pour l'égalité il est encore trop tôt. Évalué à 6.
Je ne moinsse pas pour ton honnêteté mais :
1) Ce n'est pas si cher que ça. C'est rien comparé au prix d'un verre d'alcool dans n'importe quel bar.
2) Le gros souci du "2 verres épicétou" c'est que 2 verres d'alcool fort avec un dosage maison, ou 2 pintes de bière, c'est déjà trop.
Je ne prends jamais le volant si j'ai bu plus d'une bière (disons > 30cl). Ce n'est pas parce que la loi est souple et permet plus que c'est une bonne idée. La loi ne m'interdit pas de conduire à 5h du matin sans avoir dormi depuis plus de 20h, ce n'est pas pour autant une bonne idée.
[^] # Re: Solveur SameGame-like
Posté par Maxime (site web personnel) . En réponse à la dépêche Bubble Crusher 0.9 bêta release. Évalué à 2.
Tu as en effet des règles qui ont je pense tendance à augmenter la difficulté. Cependant on retrouve des problématiques communes.
C'est typiquement pour cette raison que s'arrêter sur un graphe non fini donnait de moins bons résultats que de continuer avec un algo glouton.
Sur tes autres pistes :
- Jouer bêtement : Je ne crois pas trop à cette approche mais ça me fait penser qu'il serait intéressant de mettre en place un réseau de neurones pour qu'il apprenne à reconnaître certains patterns de jeu et voir ce qu'il arrive à en apprendre :). L'avantage c'est qu'une fois qu'il est bien entraîné, il sera rapide. J'ai aucune idée de l'efficacité d'une telle approche et encore moins du temps d'apprentissage nécessaire.
- Brute force :) Ça va dépendre de la taille de ta grille mais si une partie fait environ 20 clics et qu'il y a à chaque clics disons 5 possibilités, ça fait déjà un bon paquet :)
- La dernière solution : cf prob du super coup à k+1.
Je ne me souviens plus de la taille de la grille, mais je dirais de l'ordre de ton mode extra large.
J'ai simplifié mon algo pour les explications, c'était un peu plus compliqué que ce que j'ai annoncé mais je ne m'en souviens plus maintenant :). En tout cas, une bonne source d'inspiration à l'époque c'était un papier de recherche. Je me demande si ce n'était pas : "Single-Player Monte-Carlo Tree Search" de Maarten et al.
# Solveur SameGame-like
Posté par Maxime (site web personnel) . En réponse à la dépêche Bubble Crusher 0.9 bêta release. Évalué à 3.
J'avais dev il y a 3-4 ans un samegame dans le cadre de mes études en GtkAda et l'une des particularités c'était un mode où l'ordi encadrait le groupe de boules qu'il te conseillait de supprimer.
Alors de mémoire, l'idée c'était de faire un parcourt exhaustif en profondeur dans le graphe d'états sur genre 5 niveaux puis de finir avec une heuristique du genre : "je choisi une couleur et tant que je peux je ne joue que cette couleur, sinon j'en change". Ça me donnait donc un ensemble de scores sur les feuilles et je choisissais donc la branche qui m'avait donné le meilleur score. (l'utilisation d'une heuristique pour "finir" le jeu était bien meilleure que de pousser sur un niveau de profondeur supplémentaire et prendre en compte que le score intermédiaire pour évaluer les noeuds)
La grille de jeu était plus grande (d'où l'obligation de se limiter à 4 ou 5 en profondeur) et il n'était pas nécessaire de détruire toutes les billes pour gagner, seul le score comptait.
[^] # Re: Curiosité
Posté par Maxime (site web personnel) . En réponse au journal Le pointeur qui va au coin, c'est la faute au noyau . Évalué à 7.
Dans le même genre, il y a de ça un bon nombre d'années maintenant, j'ai eu droit en pleine nuit à un curseur de souris qui s'est mis à bouger un peu dans tous les sens sur une amplitude de 1 à 2cm environ.
Au bout de quelques minutes, j'ai enfin trouvé la réponse à ce mystère : un papillon de nuit s'était glissé dans le trou où il y a le capteur de la souris optique.
/mavie
[^] # Re: Liberté ≠ gratuité
Posté par Maxime (site web personnel) . En réponse au journal Humble Bundle Mojam. Évalué à 3.
C'est beaucoup plus simple... Un Linuxien a le sentiment de faire partie d'une communauté (de part son nombre plus réduit) dont il est fier et il a envie de faire honneur à sa communauté en étant plus généreux que les autres. Ça ne va pas plus loin que ça.
[^] # Re: Alors si j'ai bien compris
Posté par Maxime (site web personnel) . En réponse au journal On devrait manger ce qu'on donne à notre chien. Évalué à 5.
Je comprends mieux certains choix ergonomique. Tout s'éclaire !
[^] # Re: Choquant
Posté par Maxime (site web personnel) . En réponse au journal Fin du financement de Kubunt par Canonical : à quel sein se vouer ?. Évalué à 3.
Soyons précis, quelle gauche ? La mienne ou la sienne ?
# Forums
Posté par Maxime (site web personnel) . En réponse au journal Fin du financement de Kubunt par Canonical : à quel sein se vouer ?. Évalué à 6.
Tu as essayé de poser ta question sur les forums ?
[^] # Re: Vous l'avez vécue la vie de développeur de logiciel?
Posté par Maxime (site web personnel) . En réponse au journal Mégaupload fermé, tant mieux ! Je suis comédien, mes films ne sont pas gratuits. Évalué à 7.
C'est clair, à cause d'eux, il y a concurrence déloyale !
[^] # Re: C'est vendredi ?
Posté par Maxime (site web personnel) . En réponse au journal Mégaupload fermé, tant mieux ! Je suis comédien, mes films ne sont pas gratuits. Évalué à 4.
Pour mettre en valeur la bonne musique.