https://si3t.ch/log/ prx's log prx prx@si3t.ch 2026-07-22T17:42:33Z w https://si3t.ch/log/2026-07-22-w.txt 2026-07-22T17:33:02Z et le alt en
pour pouvoir écrire des légendes. Je ne suis pas développeur, on doit pouvoir faire mieux. Si vous avez des suggestions pour rendre le truc plus facile à utiliser et pour améliorer le code CSS et le rendu à l'impression, je suis preneur :) Les sources sont là : https://git.sr.ht/~prx/w --- Une réaction? Envoyez votre commentaire par mail ✉️: => mailto:prx@si3t.ch?subject=w Ou rejoignez le salon XMPP 💬: => xmpp:fremen@chat.si3t.ch?join ~*´¨¨) ⹁.•´¸.•*´¨) ¸.•*¨) (¸.•´ (¸.• ;⹁.~!prx ]]> Réponse à arpi https://si3t.ch/log/2026-07-08-Reponse-a-arpi.txt 2026-07-08T21:18:20Z mailto:prx@si3t.ch?subject=Reponse-a-arpi Ou rejoignez le salon XMPP 💬: => xmpp:fremen@chat.si3t.ch?join ~*´¨¨) ⹁.•´¸.•*´¨) ¸.•*¨) (¸.•´ (¸.• ;⹁.~!prx ]]> stagal static gallery generator https://si3t.ch/log/2026-06-24-stagal-static-gallery-generator.txt 2026-06-24T13:46:44Z https://git.sr.ht/~prx/stagal ## Description Pourquoi un nouveau générateur alors qu'il y a MinigalNano? => https://github.com/sebsauvage/MinigalNano Même si j'aime beaucoup Minigalnano, il reste en PHP dont j'essaie de me débarasser pour me simplifier l'administration de mon serveur. À ce titre, il ne mereste plus qu'à trouver un remplaçant à baïkal pour mes CalDAV/CardDAV. Par ailleurs, MinigalNano ne prends pas en charge tous les formats vidéos (webm notamment), et demande à mon petit serveur limité des ressources pour générer les aperçus. En passant, sfpg est génial aussi (mais en PHP): => https://sye.dk/sfpg/ Bref, avec ma chérie, on a un site qui nous sert d'album photo : les parents gagas que nous sommes. On a pris énormément de retard dans le classement, et ma dame a récemment tout refait pour s'occuper l'esprit pendant son arrêt de travail. De mon côté, j'avais commencé un truc à base de awk, puis ensuite tout réécrit en C (à peine), puis finalement suis revenu au awk, moins rapide mais tellement plus pratique pour tous les petits cas de figure et la gestion du texte. Oui, awk, pas python, parce que awk est présent par défaut partout, et en python il y a déjà l'énorme sigal que je ne saurais ajuster à mes besoins. => https://github.com/saimn/sigal Bref, stagal est né. Il s'agit d'un script awk qui appelle "find" sur un répertoire, crée des fichiers html uniques et des thumbnails si besoin qu'il suffit ensuite d'envoyer sur le serveur http, chacun étant dans son dossier respectif. Je tenais à un truc qui ne touche pas aux photos sources : on utilise Syncthing pour garder nos photos triées entre tous nos appareils. => https://syncthing.net/ Je vous invite à tester et me faire des retours si vous le voulez, stagal est là : => https://git.sr.ht/~prx/stagal --- Une réaction? Envoyez votre commentaire par mail ✉️: => mailto:prx@si3t.ch?subject=stagal-static-gallery-generator Ou rejoignez le salon XMPP 💬: => xmpp:fremen@chat.si3t.ch?join ~*´¨¨) ⹁.•´¸.•*´¨) ¸.•*¨) (¸.•´ (¸.• ;⹁.~!prx ]]> Que faire après linstallation dOpenBSD ? https://si3t.ch/log/2026-05-29-Que-faire-apres-linstallation-dOpenBSD-.txt 2026-05-29T21:32:36Z /misc/logiciel-libre/openbsd/postinst/ Voici donc une copie de cette page actualisée : --- # Choses à faire après l'installation d'OpenBSD Notes personnelles pour profiter d'OpenBSD dans un usage "desktop". ## Sécurité ### /home en 700 Personne d'autre que moi ne peut lire dans mon dossier. ``` $ chmod 0700 $HOME ``` ### Parefeu + sévère On laisse tout sortir, mais rien rentrer sauf pour le ping (icmp). Seule l'interface wg0 pour le VPN est plus permissive. ``` # cat << EOF > /etc/pf.conf set skip on lo antispoof quick for { egress } block pass in proto icmp pass in proto icmp6 pass on wg0 pass out EOF ``` ### doas Commandes que je veux pouvoir lancer sans entrer de mots de passe. Surtout pour les scripts. ``` cat << EOF > /etc/doas.conf permit persist :wheel permit nopass :wheel cmd /sbin/disklabel permit nopass :wheel cmd /sbin/umount permit nopass :wheel cmd /sbin/mount EOF ``` ### Sync fs Pour assurer le moins de perte de données possible en cas de crash, en dépit d'un léger ralentissement potentiel (jamais remarqué), je préfère monter toutes mes partitions avec l'option "sync" : ``` # sed -i s/rw/rw,sync/g /etc/fstab ``` ### Autologin Si on est le seul utilisateur de la machine et que l'ensemble est chiffré et qu'on éteint son ordi lorsqu'on ne l'utilise pas, alors on peut activer l'autologin pour xenodm : ``` echo 'DisplayManager._0.autoLogin: user' >> /etc/X11/xenodm/xenodm-config ``` Dans ce cas, je vous conseille de désactiver la possibilité de fermer la session graphique avec Ctrl-Shift-backspace. Sinon, n'importe qui peut prendre le contrôle de votre session même si vous l'avez verrouillée avec xlock (ou autre). On en profite aussi pour retirer la possiblité d'accéder à un tty avec Ctrl-Alt-F*. ``` cat << EOF >> /etc/X11/xorg.conf Section "ServerFlags" Option "DontZap" "True" Option "DontVTSwitch" "True" EndSection EOF ``` ### Résolveur DNS indépendant (unwind) + adblock /etc/unwind.conf: ``` fdn1=80.67.169.12 fdn2=80.67.169.40 fdn61=2001:910:800::12 fdn62=2001:910:800::40 wikimedia=185.71.138.138 wikimedia6=2001:67c:930::1 bortzmeyer=193.70.85.11 block list "/var/db/unwind-block.txt" log forwarder { $fdn61 DoT $fdn62 DoT $fdn1 DoT $fdn2 DoT $wikimedia6 DoT $wikimedia DoT $bortzmeyer } preference { recursor DoT oDoT-forwarder oDoT-autoconf stub } ``` Le script : /usr/local/sbin/unwindblock ``` #!/bin/sh db=/var/db/unwind-block.txt if [ -n "$(find $db -mtime +7)" ]; then # wait for internet access while true; do nc -zw1 si3t.ch 443 && break || sleep 60 done ftp -o- https://si3t.ch/pub/evils/unwind-block.txt.gz |gzcat > $db fi ``` Première installation et activation : ``` ftp -o- https://si3t.ch/pub/evils/unwind-block.txt.gz |\ gzcat > /var/db/unwind-block.txt rcctl enable unwind rcctl start unwind chmod +x /usr/local/sbin/unwindblock # crontab -e @reboot /usr/local/sbin/unwindblock ``` Voir la liste des ip blacklistées => /evils/ ### ntpd J'évite google à tout prix, même pour l'heure! ``` sed -i 's/www\.google\.com/www.openbsd.org/' /etc/ntpd.conf ``` ### VPN J'utilise un VPN wireguard via openbsd.amsterdam sur le rdomain 2 pour l'utiliser seulement au besoin. J'ai donc un fichier /etc/hostname.wg0 ``` wgkey ... wgpeer ... \ wgendpoint 46.23.90.144 4545 \ wgaip 0.0.0.0/0 \ wgaip ::0/0 inet 10.0.0.2/24 inet6 fd54:49bc:c233:fde:cafe::2/64 rdomain 2 !route -T2 add -inet default 10.0.0.1 !route -T2 add -inet6 default fd54:49bc:c233:fde:cafe::1 up ``` unwind n'est pas accessible sur la table de routage 2. Il faut donc lancer un second unwind: ``` cat << EOF > /etc/hostname.lo1 rdomain 2 127.0.0.1 up" EOF sh /etc/netstart lo1 ln -s /etc/rc.d/unwind /etc/rc.d/unwind2 rcctl enable unwind2 echo "unwind2_rtable=2" >> /etc/rc.conf.local rcctl start unwind2 ``` Pour utiliser le VPN, je lance le programme souhaité avec : ``` route -T2 exec le_nom_de-l_outil -flag1 -flag2... ``` ## /etc/fstab ### Montage de cdrom/DVD ``` $ doas mkdir /cdrom $ cat /etc/fstab /dev/cd0a /cdrom cd9660 ro,noauto 0 0 ``` ### Disque dur externe de musique Toute ma musique est sur une carte SD. ``` b2a7ab562311a08f.a /home/prx/mpd ffs rw,nodev,nosuid,noatime 1 2 ``` ### /tmp en ram Je monte "/tmp" en ram, et j'attribue 1/10 de la RAM disponible pour ça. Ça permet de gagner en rapidité et limite les écritures sur le disque. On commente avant tout la ligne contenant déjà une entrée pour "/tmp" dans "/etc/fstab". ``` # sed -i '/\/tmp /s/^/\#/' /etc/fstab # printf "swap /tmp mfs rw,nodev,nosuid,-s=%sB 0 0\n" \ $(dmesg |awk '/avail mem/ { print int($4 / 10)}') \ >> /etc/fstab # echo "chmod 1777 /tmp" >> /etc/rc.local ``` Ou plus simplement, pour allouer 1G de ram : ``` swap /tmp mfs rw,nodev,nosuid,-s=1G 0 0 ``` ## Confort ## Boot plus rapide Ça, c'est juste du caprice. ``` echo "set timeout 1" > /etc/boot.conf ``` ### user dans + de groupes Pour éteindre sans avoir besoin de "doas", il faut appartenir au groupe "_shutdown". Afin d'utiliser "cu", c'est à dire accéder à mon apu2, il faut être dialer. Pour travailler avec les sources, il faut être wsrc. ``` # usermod -G _shutdown prx # usermod -G dialer prx # usermod -G wsrc prx ``` Enfin, pour être moins limité en terme de ressources, c'est mieux d'appartenir à la class de login "staff", ce qui est de toute façon le cas si on est le premier utilisateur créé à l'installation (voir login.conf(5)). ``` # usermod -L staff prx ``` À la fin: ``` > userinfo prx login prx passwd * uid 1000 groups prx wheel operator wsrc staff dialer _shutdown change NEVER class staff gecos prx dir /home/prx shell /bin/ksh expire NEVER ``` ### wsconsctl Pas de bip clavier. Luminosité réduite : 40% me permet de bien voir et réduit la consommation d'énergie. Mise en veille de l'écran après 1 minute si inactif. vblank pour économiser l'énergie. ``` cat << EOF > /etc/wsconsctl.conf keyboard.bell.volume=0 display.brightness=40 display.screen_off=60000 display.vblank=on EOF ``` ### Bruit dans le casque Dans mon casque audio, il y a parfois du bruit blanc. Pour le retirer: ``` cat << EOF > /etc/mixerctl.conf inputs.mix2_source=dac-0:1 EOF ``` => https://www.mail-archive.com/misc@openbsd.org/msg182180.html ### Gestion de l'énergie Le système sera suspendu si la batterie descend en-dessous de 10%. Ça permet de brancher la machine sans perdre son travail. La batterie est considérée comme faible à partir de 20% et déclenche le script warnlow. ``` rcctl enable apmd rcctl set apmd flags -A -z 10 -w20 ``` Et pour que l'écran soit verrouillé après avoir suspendu la machine: ``` # cat /etc/apm/suspend #!/bin/sh pkill -USR1 xidle ``` Pour être averti si la batterie a un niveau trop faible: ``` # cat /etc/apm/warnlow #!/bin/sh export DISPLAY=:0.0 notify-send "ALERT!!! Batt: $(apm -l) %" exit 0 ``` On n'oublie pas de rendre éxécutable ces scripts: ``` # chmod +x /etc/apm/* ``` ### /etc/sysctl.conf Pour éviter d'abîmer la batterie en lui imposant une tension de charge lorsque le secteur est branché : ``` hw.battery.chargemode=1 hw.battery.chargestart=0 hw.battery.chargestop=85 ``` Pour xorg, si c'est demandé dans /var/log/Xorg.0.log ``` machdep.allowaperture=1 ``` Si on veut utiliser micro et webcam... Perso je préfère lancer un script "visio-enable" seulement au besoin pour activer ces éléments... ``` #!/bin/sh doas sysctl kern.audio.record=1 doas sysctl kern.video.record=1 doas chown $USER /dev/video* sndioctl input.mute=1 sndioctl input.level=0.9 doas mixerctl record.volume.mute=off doas mixerctl record.adc-0:1_source=mic ``` ### Syncthing Pour Syncthing, comme indiqué dans le pkg-readme, il faut augmenter quelques limites: /etc/login.conf : ``` staff:\ [...] :openfiles-cur=8192:\ :openfiles-max=8192:\ [...] ``` /etc/sysctl.conf ``` kern.maxfiles=8192 ``` ### réseau et WiFi Sur un portable, on peut activer le WiFi et le filaire avec de préférence le filaire. En cas de déconnexion, l'autre carte réseau prend le relais. Dans mon cas, sur un x250 : ``` # cat /etc/hostname.iwn0 join wifi1 wpakey blabla join wifi2 wpakey pouet join "" up # cat /etc/hostname.em0 up # cat /etc/hostname.trunk0 trunkproto failover trunkport em0 trunkport iwm0 inet autoconf inet6 autoconf ``` ### Outils audio USB prioritaires ``` # rcctl set sndiod flags -f rsnd/0 -F rsnd/1 # rcctl restart sndiod ``` ### Imprimante USB ``` # echo 'disable ulpt' >>/etc/bsd.re-config ``` ### ports Liste générée avec "pkg_info -zm > obsdpkglist.lst". Probablement pas à jour... ``` ftp https://si3t.ch/misc/logiciel-libre/openbsd/obsdpkglist.lst pkg_add -vmzl obsdpkglist.lst ``` ### dotfiles Récupérer les dotfiles .profile, .Xresouces, .kshrc, .exrc, .xsession ``` # extrait de .profile PATH=$HOME/bin:$HOME/.local/bin:/bin:/sbin:/usr/bin:/usr/sbin:/usr/X11R6 /bin:/usr/local/bin:/usr/local/sbin:/usr/games:/opt/bin:/usr/local/jdk-1 .8.0/jre/bin/:$HOME/.cabal/bin EDITOR='e' VISUAL='vi' TOP='-s .5' PAGER=less ENV=$HOME/.kshrc MANPATH=:$HOME/man if [ -n "$DISPLAY" ]; then BROWSER=firefox-esr else BROWSER=w3m fi export VISUAL EDITOR PATH HOME TOP PAGER BROWSER ENV MANPATH # code X11INC=/usr/X11R6/include X11LIB=/usr/X11R6/lib FREETYPEINC=${X11INC}/freetype2 CFLAGS="-I/usr/local/include -I${X11INC} $CFLAGS" LDFLAGS="-L/usr/local/lib -L${X11LIB} $LDFLAGS" export CFLAGS LDFLAGS # locale LANG="fr_FR.UTF-8" LC_CTYPE="fr_FR.UTF-8" export LANG LC_CTYPE #w3m export WWW_HOME=/home/prx/work/si3t.ch/site/links/index.html export XCURSOR_THEME=dmz # sfeed export SFEED_PLUMBER="$BROWSER" export SFEED_YANKER="xclip -selection clipboard" export SFEED_AUTOCMD="1tgo>>>>" export SFEED_HTMLCONV="w3m -o display_link_number=1 -F -dump -I utf-8 -O utf-8 -T text/html" export SFEED_NEW_AGE=129600 # firefox export MOZ_ACCELERATED=1 export MOZ_WEBRENDER=1 # soulcoud export SOULCOUD_MAIL="prx@si3t.ch" # rover and noice #export ROVER_OPEN=olab export NOPEN=olab # nethack export NETHACKDIR=~/.nethack/ ``` --- Une réaction? Envoyez votre commentaire par mail ✉️: => mailto:prx@si3t.ch?subject=Que-faire-apres-linstallation-dOpenBSD- Ou rejoignez le salon XMPP 💬: => xmpp:fremen@chat.si3t.ch?join ~*´¨¨) ⹁.•´¸.•*´¨) ¸.•*¨) (¸.•´ (¸.• ;⹁.~!prx ]]> motd gopher https://si3t.ch/log/2026-05-25-motd-gopher.txt 2026-05-25T15:14:07Z mailto:prx@si3t.ch?subject=motd-gopher Ou rejoignez le salon XMPP 💬: => xmpp:fremen@chat.si3t.ch?join ~*´¨¨) ⹁.•´¸.•*´¨) ¸.•*¨) (¸.•´ (¸.• ;⹁.~!prx ]]> Toutes ces failles https://si3t.ch/log/2026-05-18-Toutes-ces-failles.txt 2026-05-18T08:55:49Z https://www.phoronix.com/news/Linux-ssh-keysign-pwn => https://www.phoronix.com/news/Dirty-Frag-Linux => https://www.phoronix.com/news/Linux-Fragnesia => https://copy.fail/ Une de temps en temps, c'est assez normal, mais là, ça semble s'intensifier. Notez que je suis cela de loin, puisque je ne suis pas vraiment concerné étant utilisateur d'OpenBSD. Bref, j'arrête là, on va me dire que je fais le troll après ;). Pas tout à fait ceci dit, car ma chérie utilise debian au quotidien, dans son école c'est debian sur tous les ordinateurs, sur nos smartphones, c'est /e/ (donc Linux)... Et j'en oublie sûrement puisque Linux est devenu très courant. Et c'est là tout mon propos : puisque Linux devient populaire, il devient intéressant de le décortiquer pour y déceler des failles. Si un autre système devenait plus populaire, il subirait le même sort. Le fait qu'OpenBSD n'ait connu que si peu de failles tient aussi du fait qu'il ne se corrompt pas pour devenir accessible. En effet, on n'a pas de Ubuntu-like qui installe des pilotes propriétaires à la volée, des firmware-linux-nonfree ou des dépots tiers avec microcode propriétaire. Ce n'est pas vrai, il y a fw_update. Il faut utiliser du matériel compatible ou c'est marre. Il faut faire ses devoirs et lire la FAQ et les man pour l'utiliser : on apprend beaucoup et on gagne du temps sur le long terme. De plus, pour simplifier toujours plus la vie des utilisateurs, les distributions sont devenues de plus en plus complexes, avec des tas de services qui deviennent autant de sources d'erreurs. En vérité, le gros succès de Linux, c'est d'avoir Wine, qui fait tout comme si c'était Windows, et permet à chacun de faire tout comme d'habitude sans vraiment revoir sa façon de consommer le numérique, et qui permet à la moindre irritation d'activer une compatibilité avec des trucs pas libres. (Non, pas de Netflix sur OpenBSD par exemple). Ça ne veut pas dire que c'est mieux. Juste que c'est moins populaire, donc moins intéressant à "casser". Heureusement, Linux reste libre, c'est donc vite corrigé! Restons vigilants avec tous les systèmes pas à jour qui traînent dans nos placards et nos poches... --- Une réaction? Envoyez votre commentaire par mail ✉️: => mailto:prx@si3t.ch?subject=Toutes-ces-failles Ou rejoignez le salon XMPP 💬: => xmpp:fremen@chat.si3t.ch?join ~*´¨¨) ⹁.•´¸.•*´¨) ¸.•*¨) (¸.•´ (¸.• ;⹁.~!prx ]]> fin de Message to the void https://si3t.ch/log/2026-05-17-fin-de-Message-to-the-void.txt 2026-05-17T17:00:10Z https://si3t.ch/log/2024-09-17-message-to-the-void.txt => https://git.sr.ht/~prx/m2void --- Une réaction? Envoyez votre commentaire par mail ✉️: => mailto:prx@si3t.ch?subject=fin-de-Message-to-the-void Ou rejoignez le salon XMPP 💬: => xmpp:fremen@chat.si3t.ch?join ~*´¨¨) ⹁.•´¸.•*´¨) ¸.•*¨) (¸.•´ (¸.• ;⹁.~!prx ]]> Resilience https://si3t.ch/log/2026-05-16-Resilience.txt 2026-05-16T21:17:08Z https://si3t.ch/misc/resilience/ --- ... Ou comment éviter la panique en situation d'urgence. Ici, on ne parle pas de scénario post-apocalyptique, mais de réfléchir aux impacts du changement climatique et à la situation géopolitique instable. Il s'agit plutôt d'une réflexion sur ce qui est vraiment essentiel, et comment se préparer à se débrouiller plutôt que de faire des bêtises si on doit faire face à : * Un confinement * Une coupure de courant prolongée * Une pénurie (essence, nourriture, eau...) * Une fuite précipitée * Une canicule, une inondation, une tempête... * ... ## Données numériques Une simple panne de disque dur peut causer bien des soucis. Avec des amis, créez de petits clusters de sauvegarde partagés entre vos ordinateurs et téléphones portables. Un dossier partagé avec Syncthing est assez facile à mettre en place : => https://syncthing.net/ ### Site web Si vous possédez un site web, cela peut être intéressant de prévoir un miroir : * Sur un autre serveur (si le principal est en panne) * Sur un autre nom de domaine (si le premier est censuré) ### Environnement de travail partout On peut se préparer une liveUSB avec persistence à l'avance. => https://wiki.debian.org/DebianLive/LiveUsbPersistence Ou tout simplement s'installer Linux/OpenBSD sur un disque sur externe. ## Transport En cas de crise, la voiture est à oublier : c'est très difficile à réparer soi-même, on est dépendant de l'approvisionnement en carburant. Le plus adapté semble le vélo. Le VRAI vélo, pas le vélo électrique (on ne doit pas compter sur l'approvisionnement en électricité). Avec un sac à dos, on peut aller faire ses courses, éviter les bouchons, et même quitter les routes s'il le faut. Prévoir à l'avance une petite trousse de dépannage : de quoi changer une chambre à air et une chaîne, une pompe, 2 chambre à air de rechange, 2 chaînes neuves. => https://ploum.net/2024-10-15-bikepunk.html Bikepunk ## Sac d'urgence Il existe des "kits de survie" tous prêts, et peuvent constituer une bonne base de départ, bien que des choses soient inutiles ou alors manquantes. Il doit être léger, pratique à emporter, de façon à ce que se soit la seule chose à prendre puis partir à toutes jambes. Il est aussi prtatique en cas de confinement. À l'intérieur, on trouve : * Une trousse médicale d'urgence. Rien de fou, juste du désinfectant et de quoi bander une plaie. * Des couvertures de survie : pour s'abriter du chaud et du froid. En prévoir plusieurs, de quoi faire un abri. Bien pliées, ça ne prend pas de place. * De l'eau. 2 gourdes pleines au moins. Davantage, c'est trop lourd. * De quoi remplir les gourdes. Pour cela, une paille filtrante fait l'affaire. * Quelques vivres : barres énergétiques, nourriture déshydratée, boite de conserve... à chacun de voir. De quoi tenir 24h, un peu plus en se rationnant. * De la ficelle : ça sert toujours pour réparer, faire un abri, attacher des objets à transporter... * De quoi allumer un feu. Un briquet par exemple. * Une petite casserole de camping. En alu, c'est très léger et ne prend pas de place. * Une pince multi-outils et/ou juste un très bon couteau. * Une radio à piles ou à manivelle rechargeable pour se tenir informé sans dépendre du réseau de distribution électrique. * Une lampe torche. * Un peu d'argent liquide, dans une pochette à l'abri de l'humidité. * Une copie des papiers d'identité et livret de famille, plastifié ou dans une pochette plastique. * Un bête savon. * Du papier, un crayon de bois et un marqueur. Liens : => https://www.info.gouv.fr/risques/se-preparer-a-une-situation-durgence => https://www.croix-rouge.fr/faire-face-au-choc-climatique-nos-proposition s-pour-une-meilleure/catakit-preparer-son-sac-durgence => https://si3t.ch/log/2025-01-06-sac-d-urgence.txt ## Alimentation Prévoir un stock d'eau. Au moins 6L par personne. De la nourriture variée en conserve qui n'a pas forcément besoin d'être cuite : boites de thon, d'haricots, de pois chiche, petits pois, fruits confits... Pour des situations plus longues, apprendre à se faire un petit potager tout simple, dans des bacs ou même un bidon semble nécessaire. On peut très bien faire pousser des pommes de terre dans un bidon : on rajoute de la terre au fur et à mesure que la plante grandi : sur 1m², des tas de patates vont pousser. => https://www.comment-economiser.fr/faire-pousser-45-kg-pommes-terre-tonne au.html On peut aussi se renseigner sur la culture "lasagne". ## Énergie Si une coupure de courant doit se prolonger, il faudrait pouvoir alimenter quelques appareils : téléphones, ordinateurs, routeur (pour se tenir informé, glacière, éclairage.) Avant de se fabriquer une éolienne à axe vertical, il est possible de se procurer des panneaux solaires pliables de camping avec batterie. Il en existe avec des ports USB, mais aussi des prises électriques classiques EU. Par exemple : => https://www.amazon.fr/MARBERO-27-000mAh-Electrogene-Silencieux-Bricolage /dp/B0FQJ7XQ8W C'est un peu cher... On peut aussi vouloir une batterie externe avec panneau solaire intégré : on peut au moins recharger un téléphone, c'est moins lourd si on doit se déplacer et surtout moins onéreux. ## Communication Avec notre grande dépendance à l'infrastructure en place (FAI, antennes, cables), souvent énergivore, c'est difficile de s'en passer. Si votre ligne internet a déjà été coupée suite à une tempête, ou juste en cas d'erreur de branchement chez vos voisins, vous savez combien on est impuissant. Il faudrait une solution qui demande peu d'énergie afin qu'on puisse soi-même s'auto alimenter. Un truc qui ne passe pas par l'infrastructure déjà existante, et si possible chiffré. Ça existe déjà, cela s'appelle Meshtastic. Ça fonctionnera d'autant mieux si on est nombreux à l'utiliser : chaque appareil constitue un relai. Meshtastic est un projet open source communaitaure qui permet de créer des réseaux maillés décentralisés, sans avoir besoin de tous, WiFi, internet... Il s'appuise sur des ondes radio longue portée (LoRa) sur plusieurs km, demande peu d'énergie et chiffre les communications par défaut en AES-256. Il existe des appareils prêts à l'emploi, pas si chers. => https://meshtastic.org/docs/hardware/devices/seeed-studio/sensecap/card- tracker/ Perso, j'ai choisi celui-ci pour mes tests : le cable peut se changer facilement. => https://meshtastic.org/docs/hardware/devices/lilygo/techo/ Liens : => https://meshtastic.org/ => https://bowshock.nl/irc/ => https://meshmap.net/ --- Une réaction? Envoyez votre commentaire par mail ✉️: => mailto:prx@si3t.ch?subject=Resilience Ou rejoignez le salon XMPP 💬: => xmpp:fremen@chat.si3t.ch?join ~*´¨¨) ⹁.•´¸.•*´¨) ¸.•*¨) (¸.•´ (¸.• ;⹁.~!prx ]]> trois rivieres https://si3t.ch/log/2026-05-15-trois-rivieres.txt 2026-05-15T16:02:14Z https://www.trois-rivieres.net/ Je le trouve tout mignon, et le fond est instructif concernant le simpacts écologiques du numérique. C'est fait avec phaser, je me souviens avoir bidouillé avec il y a quelques années. Ça donne envie de s'y remettre. Bref, bon jeu ! :) --- Une réaction? Envoyez votre commentaire par mail ✉️: => mailto:prx@si3t.ch?subject=trois-rivieres Ou rejoignez le salon XMPP 💬: => xmpp:fremen@chat.si3t.ch?join ~*´¨¨) ⹁.•´¸.•*´¨) ¸.•*¨) (¸.•´ (¸.• ;⹁.~!prx ]]> Big up aux SEGPAS et ULIS https://si3t.ch/log/2026-05-06-Big-up-aux-SEGPAS-et-ULIS.txt 2026-05-06T15:35:12Z mailto:prx@si3t.ch?subject=Big-up-aux-SEGPAS-et-ULIS Ou rejoignez le salon XMPP 💬: => xmpp:fremen@chat.si3t.ch?join ~*´¨¨) ⹁.•´¸.•*´¨) ¸.•*¨) (¸.•´ (¸.• ;⹁.~!prx ]]> Modele de document accessible https://si3t.ch/log/2026-04-10-modele-de-document-accessible.txt 2026-04-10T14:42:49Z /pub/Modele-document.accessible.odt --- Une réaction? Envoyez votre commentaire par mail ✉️: => mailto:prx@si3t.ch?subject=modele-de-document-accessible Ou rejoignez le salon XMPP 💬: => xmpp:fremen@chat.si3t.ch?join ~*´¨¨) ⹁.•´¸.•*´¨) ¸.•*¨) (¸.•´ (¸.• ;⹁.~!prx ]]> Presque 800 IP de bot IA déjà blacklistées ! https://si3t.ch/log/2026-04-04-Presque-800-IP-de-bot-IA-deja-blacklistees.txt 2026-04-04T13:53:17Z https://si3t.ch/log/2026-04-02-bloquer-les-IP-des-bots-IA.txt Alors si vous n'utilisez pas OpenBSD, je vous invite à nouveau à récupérer la liste des IP que j'ai pu voir passer de façon quotidienne afin d'alléger la charge de votre serveur : => https://si3t.ch/pub/evils/ai.txt Ça me donne à réfléchir... Est-ce que ça ne vaudrait pas le coup de bloquer aussi les scrapers de "moteurs de recherche", et écrire pour des humains comme le dit sebsauvage? --- Une réaction? Envoyez votre commentaire par mail ✉️: => mailto:prx@si3t.ch?subject=Presque-800-IP-de-bot-IA-deja-blacklistees Ou rejoignez le salon XMPP 💬: => xmpp:fremen@chat.si3t.ch?join ~*´¨¨) ⹁.•´¸.•*´¨) ¸.•*¨) (¸.•´ (¸.• ;⹁.~!prx ]]> bloquer les IP des bots IA https://si3t.ch/log/2026-04-02-bloquer-les-IP-des-bots-IA.txt 2026-04-02T21:27:48Z https://sebsauvage.net/wiki/doku.php?id=stupidantibot Avant, j'utilisais un fichier robots.txt, naïf que je suis, puisque les bots ne semblent pas s'en préoccuper: => https://github.com/ai-robots-txt/ai.robots.txt Je me suis dit qu'on pouvait faire mieux. Puis j'ai pensé que bloquer directement les IP de ces bots au niveau du parefeu, ça serait nettement plus efficace. J'ai donc écrit ban-ai, un petit script avec du awk dedans. => https://git.sr.ht/~prx/ban-ai code source de ban-ai C'est très inspiré de "nono", un autre outils qui repère les tentatives de scan ou d'abus. => https://si3t.ch/code/nono/ En gros, quand l'User-Agent d'un bot IA est détecté, son IP est ajoutée à une table et bloquée, et la connexion fermé. es prochaintes tentatifs vont échouer. Bit sûr, on doit pouvoir faire mieux : rien n'empêche un bot d ementir sur son user-agent. De plus, avoir toutes les IP possibles du bot serait plus efficace, mais je n'ai pas trouvé un moyen de connaître la rangée d'IP correspondantes. C'est plutôt pensé pour OpenBSD, mais on doit pouvoir le modifier facilement pour d'autres systèmes. Je rend disponible un fichier qui contient la liste des IP de bots IA vus sur monserveur, mis à jour quotidiennement. Servez-vous si vous voulez: => https://si3t.ch/pub/evils/ai.txt Si vous avez des idées d'amélioration, n'hésitez pas à proposer vos patches ;) --- Une réaction? Envoyez votre commentaire par mail ✉️: => mailto:prx@si3t.ch?subject=bloquer-les-IP-des-bots-IA Ou rejoignez le salon XMPP 💬: => xmpp:fremen@chat.si3t.ch?join ~*´¨¨) ⹁.•´¸.•*´¨) ¸.•*¨) (¸.•´ (¸.• ;⹁.~!prx ]]> block AI scraper at IP level https://si3t.ch/log/2026-04-02-block-AI-scraper-at-IP-level.txt 2026-04-02T20:50:13Z https://sebsauvage.net/wiki/doku.php?id=stupidantibot Before, I was using, as naive as I am, a robots.txt file : => https://github.com/ai-robots-txt/ai.robots.txt However, I thought we can do better. What about stopping ai scraper with the firewall when their IP is seen, and don't waste any more power for them? So I wrote ban-ai, a little script with awk inside. => https://git.sr.ht/~prx/ban-ai ban-ai source code It is heavily inspired by "nono" who cares about bad behaviours. => https://si3t.ch/code/nono/ In short, when an AI scraper User-agent is detected, the corresponding IP is blocked and the connection is dropped. Next attempts will fail. Of course, gathering such IP another way, without User-Agent, a field where scrapers can lie, would be event better. Actually, IP ranges of each bot would be ideal. It is oriented towards OpenBSD, but should be easily modified for others. I'll keep a text file of detected IP here, use it if you want: => https://si3t.ch/pub/evils/ai.txt Please, send patches if you have better ideas. --- Une réaction? Envoyez votre commentaire par mail ✉️: => mailto:prx@si3t.ch?subject=block-AI-scraper-at-IP-level Ou rejoignez le salon XMPP 💬: => xmpp:fremen@chat.si3t.ch?join ~*´¨¨) ⹁.•´¸.•*´¨) ¸.•*¨) (¸.•´ (¸.• ;⹁.~!prx ]]> La Cité Diaphane https://si3t.ch/log/2026-03-12-La-Cite-Diaphane.txt 2026-03-12T13:53:11Z https://anouckfaure.com/publications/lacitediaphane/ --- Une réaction? Envoyez votre commentaire par mail ✉️: => mailto:prx@si3t.ch?subject=La-Cite-Diaphane Ou rejoignez le salon XMPP 💬: => xmpp:fremen@chat.si3t.ch?join ~*´¨¨) ⹁.•´¸.•*´¨) ¸.•*¨) (¸.•´ (¸.• ;⹁.~!prx ]]> Une session fraîche à chaque démarrage https://si3t.ch/log/2026-03-01-Une-session-fraiche-a-chaque-demarrage.txt 2026-03-01T15:48:24Z mailto:prx@si3t.ch?subject=Une-session-fraiche-a-chaque-demarrage Ou rejoignez le salon XMPP 💬: => xmpp:fremen@chat.si3t.ch?join ~*´¨¨) ⹁.•´¸.•*´¨) ¸.•*¨) (¸.•´ (¸.• ;⹁.~!prx ]]> bah alors? https://si3t.ch/log/2026-01-20-bah-alors.txt 2026-01-20T09:05:38Z mailto:prx@si3t.ch?subject=bah-alors Ou rejoignez le salon XMPP 💬: => xmpp:fremen@chat.si3t.ch?join ~*´¨¨) ⹁.•´¸.•*´¨) ¸.•*¨) (¸.•´ (¸.• ;⹁.~!prx ]]> avis-de-tempete https://si3t.ch/log/2026-01-08-avis-de-tempete.txt 2026-01-08T16:55:25Z Jeu de piste Toki Pona https://si3t.ch/log/2025-12-31-jeu-de-piste-toki-pona.txt 2025-12-31T15:45:04Z (ma chérie) Tu peux venir m'aider à décharger la voiture? > (mon fils, planqué dans les toilettes) : Papaaa???? tu peux m'aider? j'ai disséminé quelques indices dans sa maison. À son retour, il a trouvé sur la table basse une feuille : ``` Très cher explorateur, La terrible Chouette Spectrale a dérobé des pages du Grimoire de Fourier, source de tous les secrets du Grand Manoir des Géants. Si elles ne sont pas retrouvées avant la prochaine lune, les sciences des Êtres tomberont dans l’oubli. Ton esprit vif et ta curiosité insatiable sont notre dernier espoir. Résous les énigmes, suis les traces de la Chouette et découvre l’artefact caché. Que la poussière des étoiles éclaire tes calculs. – Jan Kasi Awen ``` Au dos, figurait ce message avec un plan de sa maison : ``` Les Géants regardent le monde de haut, mais les Êtres lisent la lumière qui tombe du ciel. Là où les rayons traversent le verre, la première trace de la Chouette t’attend. La Chouette cache ses secrets dans les reflets. Les Êtres savent réfléchir. ``` => /log/plan-jb.png Plan de la maison Le plan est de forme hexagonale comme on peut le trouver dans Mausritter, avec un style snes. => https://mausritter.com/ Mausritter Il n'a eu aucun mal à se diriger vers le premier indice au bord de sa fenêtre : un texte à l'envers qui le redirigeait dans sa cuisine ``` ɘmɿoʇƨnɒɿƚ ɘiqlɒʜƚnɘ’l ùo à⅃ bnɘƚƚɒ’ƚ ɘimiʜɔlɒ’l ,zɒǫ nɘ ɘbiupil ɘɿèloɔ ɒl ɘǫnɒléM ɘlioƚé’b ɘɿèiƨƨuoq ɒl à noǫɒɿb ub ƚnɒéᎮ ɘb ƨɘmɿɒl ƨɘᗡ ɘɔnɘƨƨɘ ɿuɘl ƚnɘlèvéɿ ``` Après avoir un peu fouillé, il a trouvé un grand verre avec le message "StarDust" collé dessus, ainsi que 2 petits flaçons "écailles de dragon en poudre". Il a mélangé le tout, ajouté un peu d'eau (les larmes de géant), et hop, ça a réagi. En fait, il y avait au fond du récipient du bicarbonate de soude cristalisé qui recouvrait un petit message plastifié. L'écaille de dragon n'était que de l'acide citrique en poudre, l'eau l'a dissout et la réaction entre les 2 a pu avoir lieu, libérant ainsi le message. ``` Sur des collines de coton Se reposent les Êtres. ``` Il a trouvé sous un coussin du canapé un autre message : ``` ascii 66² ascii 73² ascii 76 ascii 79ascii ``` Le mot ascii était écrit minuscule, un loupe lui aura permis de le lire, puis de savoir comment décoder le message : BIBLIO. Hop, il farfouille dans sa bibliothèque, et trouve disséminés 4 QR codes et l'énigme suivante : ``` Dans leurs voyages, les Êtres ont appris la langue simple des esprits du monde : la langue des mots minuscules. On l’appelle toki pona. sina wile alasa e poki. poki li lon tomo lape. poki li lon supa lili. poki suli pi ijo ante li awen lon tomo ni. ``` Les QR codes sont en fait le dictionnaire Toki Pona => https://si3t.ch/misc/toki-pona/ Après un peu de traduction, il se dirige vers sa chambre où il trouve un bracelet "Jan Pona" qui veut dire "bonne personn", un jeu de 54 cartes avec "l'alphabet" toki pona en sitelen et le message : 󱤿 󱥣 󱥡 󱤧 󱥇. Traduit, cela donne "ton aventure commence". Cela me permet de l'introduire à un jeu de rôle sur le base de Biburukado, où il devra interpéter le rôle d'une souris de l'espace. => https://si3t.ch/misc/jeux/biburukado/ Mais ça, il ne le sait pas encore... Il a reçu il y a quelques jours une carte postale avec une soucoupe volante en arrière plan d'un vieux tableau qui représente des bretons d'autrefois. Derrière, en sitelen pona, était écrit un message faisait référence à la fois où il avait sauvé une souris. J'aî hâte de commencer :) --- Une réaction? Envoyez votre commentaire par mail ✉️: => mailto:prx@si3t.ch?subject=jeu-de-piste-toki-pona Ou rejoignez le salon XMPP 💬: => xmpp:fremen@chat.si3t.ch?join ~*´¨¨) ⹁.•´¸.•*´¨) ¸.•*¨) (¸.•´ (¸.• ;⹁.~!prx ]]> Biburukādo uno https://si3t.ch/log/2025-11-29-biburukado-uno.txt 2025-11-29T13:34:33Z https://si3t.ch/log/2025-11-28-biburukado.txt Il est plus adapté aux situations de combats et si l'on souhaite faire gagner des niveaux à un personnage au fil du temps. Dans ce cas, il est conseillé de diviser le Deck en 2 après avoir mélangé, puisqu'un jeu de UNO est constitué de 108 cartes. En début de partie, un Deck devrait être constitué de 54 cartes aussi, il reste donc 54 cartes en réserve à ajouter lors des gains de niveau. À la place des enseignes (Trèfle, Coeur, Pique, Carreau), on regardera la couleur des cartes avec les mêmes effets bonus : * Dextérité : Jaune * Endurance : Rouge * Aura : Vert * Esprit : Bleu Il n'y a pas de Joker. Les cartes spécifiques au jeu de UNO ont ce fonctionnement: * Passe ton tour : Echec automatique * Changement de sens : Réussite automatique (retour à l'envoyeur) * "Joker" (4 couleurs) : Regarder les 3 prochaines cartes du Deck, les réorganiser ou les mettre à la fin. (=Valet) * +4 : Soin de +4 (= Dame) * +2 : apporte un bonus de +2 aux prochains évènements, peut être gardé en réserve. (=Roi) --- Une réaction? Envoyez votre commentaire par mail ✉️: => mailto:prx@si3t.ch?subject=biburukado-uno Ou rejoignez le salon XMPP 💬: => xmpp:fremen@chat.si3t.ch?join ~*´¨¨) ⹁.•´¸.•*´¨) ¸.•*¨) (¸.•´ (¸.• ;⹁.~!prx ]]> biburukado https://si3t.ch/log/2025-11-28-biburukado.txt 2025-11-28T21:13:43Z mailto:prx@si3t.ch?subject=biburukado Ou rejoignez le salon XMPP 💬: => xmpp:fremen@chat.si3t.ch?join ~*´¨¨) ⹁.•´¸.•*´¨) ¸.•*¨) (¸.•´ (¸.• ;⹁.~!prx ]]> lueur https://si3t.ch/log/2025-11-27-lueur.txt 2025-11-27T15:31:37Z https://www.philibertnet.com/fr/bombyx/93241-lueur-3760267990526.html Il est censé s'adresser à un public à partir de 8 ans... Mais en fait, cela peut être joué bien avant (mon fils de 6 ans s'éclate... et nous éclate!). La mécanique est intéressante par rapport à bien d'autres jeux... Il y a une part de probabilités, de paris, de stratégie... L'objectif est de récolter un maximum de points de victoire. Jusque là, rien de très nouveau. Au début de chaque tour, vous choisissez une créature que vous rencontrez. Vient avec elles certains pouvoirs, et des dés à jeter. Selon le résultats des dés, les pouvoirs s'appliquent, qu'ils soient bons ou mauvais. Selon les résultats de ces même dés, vous pourrez voyager sur le plateau. Enfin, selon le résultat des dés, ils seront replacés sur une autre créature au prochain tour. Il faut donc ajuster sa stratégie selon ses objectifs, et éventuellement perdre des points de victoire pour pouvoir relancer les dés. Évidemment, selon la couleur du dé, la probabilité d'obtenir une flamme, un feuille, un nuage ou que sais-je n'est psa la même. Mais c'est très facile à suivre, les symboles et couleurs sont bien pensées. Et quand vient la possibilité de maudir ses adversaires ou de leur lancer des sorts, ou de déjouer leurs plans, c'est vraiment jouissif! En plus de cela, les dessins, la DA est vraiment manifique Bref, je recommande ;) --- Une réaction? Envoyez votre commentaire par mail ✉️: => mailto:prx@si3t.ch?subject=lueur Ou rejoignez le salon XMPP 💬: => xmpp:fremen@chat.si3t.ch?join ~*´¨¨) ⹁.•´¸.•*´¨) ¸.•*¨) (¸.•´ (¸.• ;⹁.~!prx ]]> En quête d'un bon fournisseur mail https://si3t.ch/log/2025-11-25-en-quete-dun-bon-fournisseur-mail.txt 2025-11-25T07:58:23Z https://sebsauvage.net/links/?lvn_4g Depuis des années j'ai un mail en laposte.net, et bêtement, je pensais que c'était français. Bah oui, laposte -> france. Bah non :/ => https://check-host.net/ip-info?host=laposte.net C'est Google qui héberge laposte!!! AUX FUCKING USA!!! Ça signifie que tous mes mails administratifs, impots, publicités de sites marchands où j'ai commandé des chose, sont sur les serveurs de google, qui comme pour beaucoup de gens, savent potentiellement une bonne partie de ma vie et préférences. Rien de nouveau sous le soleil me direz vous... Certes, mais ça me gêne. J'ai donc fouillé un peu plus, après avoir testé et été déçu par le bazar d'Infomaniak, qui demande de créer un compte, puis un service kSuite, avec une interface très lente et une configuration IMAP qui ne marche pas... Là, j'ai demandé la suppression de mon compte car ça a buggé quand j'ai suivi le formulaire, j'attends une réponse du ticket... En faisant le tour, je m'aperçois d'un truc évident : les bonnes offres sont payantes. C'est logique en fait : il faut bien que le fournisseur soit rentable : si le client ne paie pas un petit peu, il se fera de l'argent dans votre dos avec des pubs (au mieux) ou bien par la revente de données personnelles à des tiers. Pour le coup, mailo semblait pas mal, ils proposent plusieurs offres, notamment pour les jeunes. La version gratuite contient des publicités. Ça ne me donne pas confiance, et j'aime pas trop la façon de faire. Tutanota me fait bonne impression, quoi que peut-être un peu cher (3€/mois). Le problème, c'est qu'il demande une applicatoin spécifique pour consulter les mails, et ça ne me va pas : je veux pouvoir utiliser les clients que je veux, de partout. ## Le graal : posteo Bref, assez vite j'arrive sur posteo. => https://posteo.de/fr Je me sens vite en confiance par de multiples détails. Ils prennent le temps de bien documenter leurs choix dans la façon d'héberger les mails. Voici en vrac ce que j'ai retenu, et qui m'a bien plu : * Chiffrement des mails sur leurs serveurs : cela signifie qu'ils ne peuvent en théorie pas être lus par quelqu'un qui fouille leurs disques. Il faut mon mot de passe pour ça. * On peut créer 20 alias gratuitement, avec de nombreux tld. Ça multiplie le nombre d'adresses mails dispo. * Chaque étape est documentée et expliquée. * Le prix est très accessible : 1€/mois. C'est pas dans nos habitudes de payer pour le mail, mais encore une fois, c'est bien normal si on réfléchi 2 minutes. Et à ce prix, c'est bien moins cher que des tas d'autres trucs pas si utiles. * configuration des clients de messagerie transparente * Pour utiliser le client mail du smartphone ou de l'ordinateur, ce n'est pas le même mot de passe que celui du compte qui est utilisé. C'est très malin : si mon téléphone est volé, mon compte n'est pas compromis. * Aucun souci pour configurer mes outils minimalistes : fdm (imap) et msmtp * On peut augmenter lespace de stockage : 1G pour 0,25€. Pas forcément utile pour moi qui télécharge tous mes mails mais ça peut être utile à d'autres. * Le support de GPG est prévu. * L'authentificatoin à 2 facteurs est disponible. * Ils annoncent faire tourner leurs serveur avec de "l'énergie verte". Ça pue le green washing, mais l'intention est là. Je n'ai pas creusé comment procédait leur fournisseur d'énergie. * Le webmail est sobre, propre, claire, rapide! Je n'ai pas à attendre 10 à 15 secondes comme chez certains concurrents. * Hébergé en europe (Allemagne) Je suis conquis. Je vais donc rester chez posteo à priori un petit moment pour tout ce qui est administratif. Je garde mes adresses en si3t.ch pour le privé. --- Une réaction? Envoyez votre commentaire par mail ✉️: => mailto:prx@si3t.ch?subject=en-quete-dun-bon-fournisseur-mail Ou rejoignez le salon XMPP 💬: => xmpp:fremen@chat.si3t.ch?join ~*´¨¨) ⹁.•´¸.•*´¨) ¸.•*¨) (¸.•´ (¸.• ;⹁.~!prx ]]> infomaniak mail https://si3t.ch/log/2025-11-24-infomaniak-mail.txt 2025-11-24T09:30:32Z https://www.infomaniak.com/fr/support/faq/2427/synchroniser-les-e-mails-sur-tous-vos-appareils Pour supprimer un compte mail (c'est mieux de tester avant), c'est galère, il faut désouscrire à l'offre koffice, puis après supprimer son compte. Cependant, supprimer le premier service ne marche pas : il faut contacter le support... Mais quand même, c'est dommage de ne pas avoir une messagerie propre et légère. Je vais continuer à chercher une alternative... Peut-être Mailfence, hébergé par OVH. Posteo me plait bien aussi, mais c'est payant. En même temps, n'importe quel hébergeur qui est gratuit doit bien se faire de l'argent quelque part : avec de la pub ou avec vos données. Il y a aussi OVH, avec 0,36€/mois. J'ai déjà un compte chez eux, alors pourquoi pas... --- Une réaction? Envoyez votre commentaire par mail ✉️: => mailto:prx@si3t.ch?subject=infomaniak-mail Ou rejoignez le salon XMPP 💬: => xmpp:fremen@chat.si3t.ch?join ~*´¨¨) ⹁.•´¸.•*´¨) ¸.•*¨) (¸.•´ (¸.• ;⹁.~!prx ]]> sysclean destructeur https://si3t.ch/log/2025-11-17-sysclean-destructeur.txt 2025-11-17T08:46:21Z https://fossil-scm.org/home/doc/trunk/www/server/openbsd/fastcgi.md => https://fr.forum.puffy.cafe/wiki?name=Index Cela fait des semaines que je ne m'en était pas aperçu (je n'avais pas fait de reboot)... Ça en dit long sur l'inutilité de ce forum, personne n'a rien remarqué. Je devrais probablement le supprimer... --- Une réaction? Envoyez votre commentaire par mail ✉️: => mailto:prx@si3t.ch?subject=sysclean-destructeur Ou rejoignez le salon XMPP 💬: => xmpp:fremen@chat.si3t.ch?join ~*´¨¨) ⹁.•´¸.•*´¨) ¸.•*¨) (¸.•´ (¸.• ;⹁.~!prx ]]> frm sans ramer : mpv + yt-dlp https://si3t.ch/log/2025-11-15-frm-sans-ramer.txt 2025-11-15T14:32:18Z mailto:prx@si3t.ch?subject=frm-sans-ramer Ou rejoignez le salon XMPP 💬: => xmpp:fremen@chat.si3t.ch?join ~*´¨¨) ⹁.•´¸.•*´¨) ¸.•*¨) (¸.•´ (¸.• ;⹁.~!prx ]]> Utopiales 2025 https://si3t.ch/log/2025-11-12-Utopiales-2025.txt 2025-11-12T20:17:18Z Quel plaisir de voir autant de personnes rassemblées pour réfléchir > ensemble à un avenir plus humain. Surtout en ces temps où on voudrait de > plus en plus nous en empêcher. Voilà des jours que je reporte le moment où je vais écrire ce billet. Mais je dois l'admettre, je n'aurai pas le temps de bien l'écrire. (prenez soin de votre santé les amis). Alors tant pis, je vais déposer en vrac mes sentiments et mes notes, en espérant que cela inspire quelqu'un. Pour moi, les Utopiales, c'est devenu vital. Dans un monde comme le notre, où la richesse est proportionnelle à l'imbécilité, un tel endroit fait du bien. C'est facile de discuter avec tout le monde, car tout le monde est sympa. Les idées sont fascinantes, et même si on est maladroit, l'écoute est de mise, le respect avant tout. Bref, j'ai l'impression pendant quelque jours d'être entouré d'humains, et ça me fait du bien. Se promener dans l'expo est toujours agréable, on remarque des choses à chaque passage. Une grande fresque a été peinte sous nos yeux pendant les 4 jours, un mur entier. Fascinant à observer, à voir naitre et évoluer. Respect! Il y avait des petits jeux ci et là, du genre deviner combien de legos il y avait dans un bocal. C'était chouette. Je n'ai pas craqué et n'ai pas dévalisé la libraire! J'ai juste acheté des livres pour ma chérie, ça ne compte pas hein? Comme toujours, je suis fasciné par la créativité humaine, et l'envie de liiiiire! Mon meilleur ami m'avait précommandé le jeu "singularité". Les designs sont excellents, avec des cartes à l'effigie d'intervenants réguliers des Utopiales ou d'auteurices de SF. J'ai pu faire dédicacer ma carte de Roland Lehoucq \o/. Sinon, 2 sessions de courts-métrages, que j'ai beaucoup apprécié. Pas trop de trucs expérimentaux qui éclatent la tête avec des effets stromboscopiques et un son désagréable. Des histoires intelligentes, belles d'une certaine façon, et souvent drôles. Bravo! Le 5e jour, j'ai accompagné mes classes. C'était génial. Pouvoir les voir réagir face à Ex MAchina, leur parler du mythe de Chtulu repris dans des oeuvres de l'exposition, et puis finalement vulgariser la conférence de Roland Le houcq trop compliquée pour des collégiens et leur parler de voyage dans le temps, c'était jouissif :) L'année prochaine, on fait une session JdR! Comme d'habitude, j'ai passé beaucoup de temps à écouter les tables rondes et les conférences. En voici quelques notes, à méditer? Plus que notes, ce sont surtout des citations, et des idées posées à la volée. --- Pourquoi le ciel est noir la nuit? En théorie, où que pointe notre regard, il existe une étoile dans cette direction, puisque l'univers est infini. Alors pourquoi ce noir? La lumière de l'étoile ne nous est pas encore parvenu? Quand tous les points s'éloignent les uns des autres, ce n'est pas exactement une explosion. La Terre en tant que telle est une singularité. Elle reçoit un rayonnement entropique faible et émet une entropie élevée. --- Face à la censure, aux USA, on s'auto-censure. Aux USA, on fait passer pour canular la science du réchauffement climatique. Mais on n'est pas à l'abri en France. Il y a peu de temps, notre premier ministre disait publiquement qu'il y a 1000 millions d'étoiles dans le système solaire. (la vidéo est ridicule, personne n'ose lui dire qu'il raconte des conneries, hein Bayrou?). Une initiative de chercheure publie un max de bullshit en ligne pour empoisonner les IA. La question de l'effort et en jeu. Le journalisme scientifique est mauvais, il faut réfléchir à comment communiquer. Ce n'est pas parce qu'un scientifique explique son raisonnement qu'on change des idées. On peut vous dire A + B = C, mais ça ne change pas profondément vos certitudes. Il faut être prêt à faire un pas en avant. La valeur face à l'autorité ou face à l'expérience en question? Il y a les sciences que l'on fait, et celles que l'on ne fait pas (à propos des producteurs de tabac qui ont financé des recherches pour montrer toutes les causes du cancer du poumon pas dues au tabac, et donc ainsi camoufler leur responsabilité). --- Comme dans un livre, on n'entre jamais 2 fois dans la même forêt, car elle a changé entre temps, et nous aussi. Face au réchauffement climatique, l'avenir est incertain, mais inéluctable. La violence climatique faite au vivant rapproche les différentes espèces. --- Une mémoire pour nous gouverner tous. (Archivez, gardez des copies!!!) De la mémoire découle l'identité. Indique d'où on vient. C'est l'histoire qui nous forme. Dans beaucoup de familles, ce sont les femmes les gardiennes de la mémoire. La mémoire est-elle une garantie de liberté ou un obstacle? Il n'y a pas de mémoire sans oublie, sans possiblité d'oublie. Aujourd'hui, avec les IA et tout le merdier des fake news, ce qui devient le plus fiable, ce sont les interactions en direct avec d'autres humains, et peut-être les livres. --- Les scientifiques n'ont pas d'égo (d'égaux). L'humain veut toujours franchir les limites / les frontières / l'interdit. Faut-il interdire l'écologie pour faire envie? + on se rapproche de la vitesse de la lumière, moins le temps passe vite, plus on est lourd. La vitesse de la lumière : limite de la causalité, de l'information. La science d ela fiction est que vraisemblance? Toy Story est un monde quantique : le sobjets vivent quand on ne les regarde pas. --- Le cerveau ne définit pas la la personne, de l'identité. LE cerveau se modifie en permanence, mais pas notre personnalité. Le cerveau envoie le signalt qu'une décision doit être prise entre 2 et 10 secondes avant la prise de décision : cela questionne un peu le libre arbitre. Et si avec des OEM on créait les impulsions apropriées pour engendrer une prise de décision dans un cerveau? Il y a un facteur très humain dans les ordinateurs (les programmes), car ils sont programmés par des humains avant tout, comme vous et moi, même les IA. --- Pour les plus curieux(ses), j'ai mis des photos sur motd. --- Une réaction? Envoyez votre commentaire par mail ✉️: => mailto:prx@si3t.ch?subject=Utopiales-2025 Ou rejoignez le salon XMPP 💬: => xmpp:fremen@chat.si3t.ch?join ~*´¨¨) ⹁.•´¸.•*´¨) ¸.•*¨) (¸.•´ (¸.• ;⹁.~!prx ]]> optimiseur d'images dans mes outils en ligne https://si3t.ch/log/2025-10-27-optimiseur-dimages-dans-mes-outils-en-ligne.txt 2025-10-27T14:43:17Z https://si3t.ch/tools/imgopti/ Le nombre d'options des très limité, un peu volontairement pour garder le truc facile d'accès, et aussi parce que je n'y comprends pas grand chose aux algos de dithering et compagnie et que je n'ai pas le temps de m'y intéresser pour l'instant ^^'. Comme déjà dit, tout se fait dans le navigateur. Vous pouvez même télécharger la page html et l'enregistrer sur votre disque dur, ça fonctionnera pareil. Pas de libs JS, juste canvas. Merci à l'IA qui m'a aidé à pondre le code que j'ai modifié ensuite pour le vérifier un peu et le simplifier un peu aussi. J'espère que le nombre d'images qui seront optimisées pour réduire la quantité de données chargées compensera l'impact carbone généré par les calculs de l'IA. N'hésitez pas à modifier et améliorer le code, et surtout de me faire part de vos modifications, ça m'intéresse ;) --- Une réaction? Envoyez votre commentaire par mail ✉️: => mailto:prx@si3t.ch?subject=optimiseur-dimages-dans-mes-outils-en-ligne Ou rejoignez le salon XMPP 💬: => xmpp:fremen@chat.si3t.ch?join ~*´¨¨) ⹁.•´¸.•*´¨) ¸.•*¨) (¸.•´ (¸.• ;⹁.~!prx ]]> Webalizer plus responsive https://si3t.ch/log/2025-10-21-Webalizer-plus-responsive.txt 2025-10-21T14:06:08Z https://0x0.st/KjF1.png ``` HTMLHead HTMLHead TableBorder 1 ChartBorder 0 ColorBackground eceff4 ColorText 2e3440 ColorLink 3b4252 ColorVLink b48ead ColorALink 5e81ac ColorGrp 434c5e ColorHeadline d8dee9 ColorCounter 4c566a ColorHit 8fbcbb ColorFile 5e81ac ColorSite bf616a ColorKbyte d08770 ColorPage ebcb8b ColorVisit a3be8c ColorMisc b48ead ChartBackgroundColor e5e9f0 ChartLegendColor 2e3440 ChartShadowColor1 2e3440 ChartShadowColor2 2e3440 PieColor1 d08770 PieColor2 a3be8c PieColor3 ebcb8b PieColor4 81a1c1 ``` Il y a les couleurs nord qui rendent pas mal je trouve. Et vous, comment vous avez personnalisé webalizer? --- Une réaction? Envoyez votre commentaire par mail ✉️: => mailto:prx@si3t.ch?subject=Webalizer-plus-responsive Ou rejoignez le salon XMPP 💬: => xmpp:fremen@chat.si3t.ch?join ~*´¨¨) ⹁.•´¸.•*´¨) ¸.•*¨) (¸.•´ (¸.• ;⹁.~!prx ]]> motd bis https://si3t.ch/log/2025-10-12-motd-bis.txt 2025-10-12T13:31:16Z mailto:prx@si3t.ch?subject=motd-bis Ou rejoignez le salon XMPP 💬: => xmpp:fremen@chat.si3t.ch?join ~*´¨¨) ⹁.•´¸.•*´¨) ¸.•*¨) (¸.•´ (¸.• ;⹁.~!prx ]]> Nethack configuration https://si3t.ch/log/2025-10-11-Nethack-configuration.txt 2025-10-11T20:50:37Z https://www.nethack.org/ Ce jeu m'obsède, j'adore ses mécanismes, et l'intelligence dans sa cànception. J'ai ajouté quelques éléments de configuration que je trouve bien utile et que je voudrais partager. Le tout est répertorié ici : => https://si3t.ch/misc/jeux/nethack/ Tout d'abord, je conseille de définir un répertoire pour stocker les sauvegardes, les scores et les bones. En effet, j'ai eu la mauvaise surprise de voir mes "meilleurs scores" oubliés après avoir désinstallé le paquet nethack pour en tester la version X11 (avant de revenir en arrière, la version X11 est dégueu, mieux vaut l'ASCII!). En effet, pour éviter la triche, tout est stocké dans un dossier "système" où l'on n'est pas censé pouvoir intervenir en tant que simple user. Pour contourner ce problème, si vous voulez tricher en gardant vos sauvegardes (bouh!), ou comme moi garder vos scores, c'est en fait très simples. Il suffit de modifier quelques variables d'environnement. Pour ma part, j'ai ajouté ceci dans mon fichier ~/.profile ``` # nethack export BONESDIR=~/.nethack/bones export SCOREDIR=~/.nethack/scores ``` Bien sûr, il faudra avoir créé les dossiers ci-dessus au préalable. => https://nethackwiki.com/wiki/Playground En complément, voici le fichier de configuration que j'utilise, le ~/.nethackrc qui me permet notamment d'avoir un peu plus d'infos dans l'interface et d'autopickup des objets intéressants: ``` # improve interface, show more info OPTIONS=showexp,showscore,time,color # dig if you move when holding a pickaxe OPTIONS=autodig # autopickup, but uder conditions OPTIONS=autopickup # only if not encumbered OPTIONS=pickup_burden:Unencumbered # don't pick everything OPTIONS=pickup_types:$?!/(=+" # Always pick these: AUTOPICKUP_EXCEPTION=" mailto:prx@si3t.ch?subject=Nethack-configuration Ou rejoignez le salon XMPP 💬: => xmpp:fremen@chat.si3t.ch?join ~*´¨¨) ⹁.•´¸.•*´¨) ¸.•*¨) (¸.•´ (¸.• ;⹁.~!prx ]]> motd : Message Of The Day https://si3t.ch/log/2025-10-05-motd--Message-Of-The-Day.txt 2025-10-05T20:23:32Z http://huld.re (javascript requis ^^) Publier mais cacher... Rendre publique mais dissimuler, ça n'a pas de sens me direz-vous! Il y a dans cette démarche une sorte de pudeur : ne pas vouloir afficher en grand ni faire la publicité de ce qu'on compose. Il y a aussi une forme de honte, c'est très personnel, qui cela pourrait-il bien intéresser? À cela s'ajoute un peu de syndrome de l'imposteur, compensé par le fait d'avoir son propre site sur lequel, après tout, on fait bien ce qu'on veut! En parallèle, on discutait des pages /now de l'Indieweb. => https://indieweb.org/now Une telle page me plaisait bien, mais je craignais de ne pas être capable de la tenir à jour, simplement d'y penser. f6k quant à lui, a choisi d'utiliser finger pour publier de ses nouvelles. À la place, je me disais qu'un fichier twtxt.txt serait tout à fait suffisant. => https://github.com/buckket/twtxt J'adore l'idée d'un fichier twtxt. Le peu d'interaction avec d'autres me plaisait beaucoup. Pour m'affranchir dee l'abonnement nécessitant un client spécifique, j'en faisais même un flux atom : => https://si3t.ch/code/twtxt2atom/ Sauf que voilà, il me posait finalement quelques problèmes : * Je ne peux l'éditer que depuis mon ordinateur. Alors que je veux passer moins de temps devant ce dernier, il devenait un peu inutile, et je prenais finalement davantage de notes sur un bloc-note ou avec Markor sur Android. * Je me sentais limité par les entrées sur une ligne simple. En parallèle, j'avais un script "notd" qui ajoutait à un fichier texte la date du jour, puis l'ouvrait à la ligne correspondante avec vi, dans lequel je déposais des liens intéressants, des remarques, des idées... Ajoutez à ceci l'utilisation de Syncthing pour avoir mes notes sur mon smartphone et sur mon ordinateur, et vous avez la genèse de motd. J'aurais pu reprendre scribo, qui permet d epublier par mail, mais le souci c'est qu'on ne peut pas éditer facilement un message si on veut faire une édition en plusieurs fois. => gopher://z3bra.org/0/projects/scribo.txt Pour remplacer mon twtxt et moins m'auto censurer, je me décide à ouvrir un "message of the day", qui ne sera qu'un flux atom à la mode "shinobi" et un petit gopherhole pour lister plus facilement chaque entrée. => https://shinobi.btxx.org/ > Quoi??? Gopher? Mais, t'avais dit que... Oui, c'est ma façon de garder cet espace de publication "semi privé". C'est à dire que si quelqu'un a envie de lire mes jérémiades, c'est qu'il se sera vraiment donné la peine de faire la démarche d'aller sur le gopherhole. C'est d'ailleurs pour cela que j'hésite à garder le flux atom... ## MOTD : mise en place (description rapide...) Tout d'abord, j'installe Syncthing sur tous mes appareils, (ordinateur, téléphone, serveur). => https://syncthing.net/ Je configure Syncthing pour que les 3 appareils ci-dessus disposent des notes écrites avec Markor. De cette façon, je pourrai écrire tant sur mon ordinateur que smartphone. => https://github.com/gsantner/markor Dans Markor, je crée un dossier "motd" qui contiendra toutes mes notes. J'installe geomyidae pour configurer un gopherhole: => https://si3t.ch/ah/fr/09-services/#Gophergeomyidae Je crée un dossier pour contenir le gopher hole et j'ajuste la façon dont geomyidae sera lancé: ``` # mkdir -p /var/gopher/motd.si3t.ch # chmod 666 /var/gopher/motd.si3t.ch # rcctl enable geomyidae # rcctl set geomyidae flags -c -e -b /var/gopher/motd.si3t.ch -l /var/log/motd.si3t.ch.log # rcctl start geomyidae ``` J'ajuste le roulement des logs: ``` # cat /etc/newsyslog.conf /var/log/motd.si3t.ch.log 644 4 * * Z "rcctl reload geomyidae" ``` Je crée un espace http et ajuste la configuration de httpd pour servir le flux atom par défaut: ``` # mkdir -p /var/www/htdocs/motd.si3t.ch # chmod 666 /var/www/htdocs/motd.si3t.ch # cat /etc/httpd.conf server "motd.si3t.ch" { listen on * port 80 directory index "atom.xml" root "/htdocs/motd.si3t.ch" gzip-static } # rcctl reload httpd ``` J'ajoute une tâche cron qui copiera les notes dans le gopherhole chaque nuit et générera le flux atom pour la partie http: ``` $ crontab -e # motd 0 0 * * * /home/bibi/jobs/motd.sh ``` le script motd.sh ressemble à ça : ``` #!/bin/sh -e # generate motd text files to atom file # the file must start with publication date : # YYYY-MM-DD-title.txt # or # YYYY-MM-DD.txt # srcdir=/var/syncthing/Notes-x/motd/ motd=/var/gopher/motd.si3t.ch/ atom="/var/www/htdocs/motd.si3t.ch/atom.xml" domain="motd.si3t.ch" id="http://motd.si3t.ch/" url="//${domain}" feedtitle="prx's Message Of The Day" author="prx" email="prx@si3t.ch" tag="motd" # sync files openrsync -vr --delete ${srcdir} ${motd} # header template of the atom cat << EOF > "${atom}" ${id} ${feedtitle} ${author} ${email} $(date -u +%FT%TZ) EOF for f in "${motd}"/*.txt; do bn="$(basename $f)" pubdate="$(printf "${bn})" | cut -c-10)" timestamp="$(printf "${bn}" | tr -cd '[^[:digit:]]')" entryid="tag:${domain},${pubdate}:${tag}${timestamp}" cat << EOF >> "${atom}" ${entryid} ${bn} ${pubdate}T23:59:59Z ", "]]]]]]>")}1' ${f}) ]]]]> EOF done printf '%s' '' >> "${atom}" gzip -k9 "${atom}" exit 0 ``` Je reviendrai peut-être une autre fois sur la génération d'un flux ATOM. C'est vraiment facile une fois qu'on a chopé le truc, et c'est tellement génial! ## Publication Concrètement, si j'ai mon téléphone, je crée un nouveau fichier avec Markor. Ce dernier permet de directement choisir un nom de fichier suivant le modèle YYYY-MM-DD-blablabla.txt. Sinon, avec mon ordinateur, je lance le script "motd": ``` #!/bin/sh # motd : message of the day. # open a new YYYY-MM-dd.txt in $MOTDDIR with $EDITOR # Author: prx MOTDDIR=~/work/notes/motd dotd="$(date +%Y-%m-%d)" title="$(echo "$@" | awk ' { gsub(/[[:space:]]/, "-") gsub(/[éèêë]/, "e") gsub(/[àâ]/, "a") gsub(/[ùû]/, "u") gsub("ç", "c") gsub(/[^[:alnum:]_-]/, "") print } ')" if [ -n "${title}" ]; then f="${MOTDDIR}/${dotd}-${title}.txt" else f="${MOTDDIR}/${dotd}.txt" fi # add date of the day and title inside if [ -z "$(grep $dotd $f)" ]; then printf "# %s %s\n\n" "${dotd}" "${@}" >> "${f}" fi # edit à la fin du fichier: ${EDITOR} + "${f}" ``` Ce script permet juste d'ajouter un titre éventuel si je le passe à la ligne de commande et de retirer les caractères spéciaux du nom de fichier. --- Une réaction? Envoyez votre commentaire par mail ✉️: => mailto:prx@si3t.ch?subject=motd--Message-Of-The-Day Ou rejoignez le salon XMPP 💬: => xmpp:fremen@chat.si3t.ch?join ~*´¨¨) ⹁.•´¸.•*´¨) ¸.•*¨) (¸.•´ (¸.• ;⹁.~!prx ]]> Nethack -- Épisode 17 https://si3t.ch/log/2025-09-29-Nethack----pisode-17.txt 2025-09-29T09:27:18Z mailto:prx@si3t.ch?subject=Nethack----pisode-17 Ou rejoignez le salon XMPP 💬: => xmpp:fremen@chat.si3t.ch?join ~*´¨¨) ⹁.•´¸.•*´¨) ¸.•*¨) (¸.•´ (¸.• ;⹁.~!prx ]]> Studio17 https://si3t.ch/log/2025-09-24-Studio17.txt 2025-09-24T13:34:57Z https://www.studio17.video/home Ça fonctionne très bien, c'est sobre, il n'y a pas de publicité, et le prix est tout à fait abordable. C'est même nettement moins cher que de soutenir ces créateurs via Patreon, qui de toute façon se fait une belle marge sur leur dos. Je vous invite chalheureusement à aller y faire un tour, juste pour voir : la première semaine est gratuite et c'est sans engagement, donc vous ne risquez rien. Vous pourrez y découvrir des humains supers qui jouent à des jeux de rôle. C'est drôle, c'est magique, c'est fascinant, c'est divertissant, et surtout, ça fait du bien. --- Une réaction? Envoyez votre commentaire par mail ✉️: => mailto:prx@si3t.ch?subject=Studio17 Ou rejoignez le salon XMPP 💬: => xmpp:fremen@chat.si3t.ch?join ~*´¨¨) ⹁.•´¸.•*´¨) ¸.•*¨) (¸.•´ (¸.• ;⹁.~!prx ]]> C'est quoi ces Referrers? https://si3t.ch/log/2025-09-24-Cest-quoi-ces-Referrers.txt 2025-09-24T14:10:01Z mailto:prx@si3t.ch?subject=Cest-quoi-ces-Referrers Ou rejoignez le salon XMPP 💬: => xmpp:fremen@chat.si3t.ch?join ~*´¨¨) ⹁.•´¸.•*´¨) ¸.•*¨) (¸.•´ (¸.• ;⹁.~!prx ]]> Les protocoles Gemini et Gopher ne desservent-ils pas le smolweb https://si3t.ch/log/2025-09-17-Les-protocoles-Gemini-et-Gopher-ne-desservent-ils-pas-le-smolweb.txt 2025-09-17T16:01:10Z https://tildegit.org/solene/vger À cela je rétorque : "y a que les idiots qui ne changent pas d'avis". Non, pas du tout. Je vais peut-être dire des conneries, et surtout il ne faudra pas hésiter à me dire pourquoi. C'est simplement que j'ai réfléchi (Ha ha ha XD), et j'en suis arrivé à vouloir partager ces idées. Je me demande actuellement si inciter à la publication avec les protocoles gemini et gopher n'irait pas à l'encontre du smolweb, le web qu'on aimerait plus voir. ## Quelques définitions Puisque le terme smolweb est un peu large, je préfère préciser que je l'envisage tel qu'il est décrit ici : => https://smolweb.org/ > Promoting a simple unbloated web! Quant à gemini et gopher, ce sont deux protocoles distincts du http classique, le premier étant entièrement chiffré, le second étant nettement plus vieux. ## Répondre à un besoin Publier sur gopher ou gemini semble répondre à un besoin. Plus que s'afranchir des publicités et autres lourdeurs pénibles, ce dernier peut être : * Pour s'amuser * Se retrancher * Retrouver les essentiels du texte brut * Revendiquer la simplicité perdue sur le web bourré de trackers/pubs/... * un peu de nostalgie (pour gopher) Je n'ai rien à redire sur les 2 premiers points. Par contre, il n'y a nul besoin d'un autre protocole pour le reste. Quoi qu'il en soit, il n'y a PAS UN de ces points qui ne puissent être réalisé avec le web classique, c'est à dire http + html (éventuellement) : * On n'est pas obligé de diffuser partout son site. Il en existe des bien cachés, même des sites cachés dans des sites (coucou f6k ;) ) * On peut très bien publier du texte brut. Tiens, c'est d'ailleurs ce que j'aime faire. O:) Pour cela, gemini avec le gemtext proposait une alternative intéressante par sa simplicité, mais finalement pas si indispensable si on fait du plaintext plutôt qu'un gophermap. Et puis soyons honnête, les balises de base du html ne sont tout de même pas si compliquées à retenir. * On peut publier un site simple, sans tracker, sans JS. * On peut faire un site au look oldschool, d'ailleurs http n'est pas si récent. * Ça peut être fun, il y a des tas d'exemples de sites qui sont carrément des oeuvres d'art à mon avis : => http://superpixelquest.com/ => https://ellesho.me/ (merci f6k!) => https://floor796.com/ => https://www.hyperreve.fr/ => https://nostalgic-css.github.io/NES.css/ ## Le principal problème... > Il n'y a pas de code d'erreur 418 : "I'm a teapot". ! Ahem... Publier sur gopher ou gemini, c'est justement rendre moins facile d'accès une autre façon de faire. C'est cacher ce que pourrait être le web actuel, en mieux. À moins que cela soit l'objectif, cela va à contre sens ce vers quoi on voudrait voir le web évoluer. Pour en profiter, il faut installer et apprendre des outils spécifiques, des clients adaptés, ce qui représent un sacré frein à la popularisation de ce qu'on aime... Pour ma part, c'est un vrai souci pour les flux RSS/ATOM par exemple. Alors que fait-on? On utilise un proxy http: => http://portal.mozz.us => https://warmedal.se/~wobbly/ ... Petite anecdote en passant, j'ai découvert que certains de ces services publient leurs logs, ce qui questionne sur la vie privée... oO => https://gopher.floodgap.com/gopher/gw?gopher.floodgap.com/0/recent Pire que les proxy, on voit fleurir des tentatives pour rendre accessible via ces protocoles ce qui existe déjà ailleurs : reddit, wikipedia, ... Autrement dit, on ne s'affranchit pas du tout du web "classique". ## Les solutions ? Retrouver le plaisir de surfer à nouveau. Sauter d'un lien à l'autre, suivre les recommandations de personnes plutôt que celles d'un moteur de recherche. Pour ça, le mot clé est "blogroll". À la rigueur, on pourrait utiliser un moteur de recherche adapté au smolweb, comme wiby: => https://wiby.me/ Ou encore découvrir des pépites dans des répertoires : => http://biglist.terraaeon.com/ The big list of personal websites => https://indieblog.page/all indieblog => https://512kb.club/ 512kb club => https://250kb.club/ 250KB club => https://ooh.directory/ => https://personalsit.es/ => https://smallweb.cc/ => ... Mais à mon avis, le plus important serait de publier un vrai smolweb, comme indiqué ici : => https://smolweb.org/ On pourrait penser que c'est trop technique. Que nenni, il existe plusieurs services à différents niveaux de geekitudes, du plus facile au moins facile à utiliser: => https://bearblog.dev/ Prérequis : aucun. est une plateforme de blog vraiment hyyyyper simple à prendre en main. On crée un compte, on écrit, et voilà! => https://mataroa.blog/ Aucun prérequis. => https://smol.pub/ Aucun prérequis. => https://midnight.pub/ Aucun prérequis.. => https://pages.casa/ Prérequis : savoir utiliser filezilla. C'est très bien documenté sur le site. => https://neocities.org/ Prérequis : à priori aucun, il y a un éditeur html intégré, mais je n'ai pas pu tester. => https://prose.sh/ Prérequis : savoir utiliser la commande "ssh". => https://www.nearlyfreespeech.net/ Prérequis : savoir écrire son html et utiliser ssh => https://sdf.org/ Prérequis : avoir l'habitude d'UNIX. ... Les solutions ne manquent pas pour faire l'exemple de ce qu'on souhaiterait voir davantage. Pour cela, il faut rendre vos créations disponibles pour inspirer. Et pour aller plus loin, on peut même se prendre un nom de domaine et suivre des idées de l'indieweb, si on a envie: => https://indieweb.org/ ## Le mot de la fin Si ça vous fait plaisir, n'arrêtez pas de publier sur gopher ou gemini. Car après tout, chacun est libre et la diversité est riche :) --- Une réaction? Envoyez votre commentaire par mail ✉️: => mailto:prx@si3t.ch?subject=Les-protocoles-Gemini-et-Gopher-ne-desservent-ils-pas-le-smolweb Ou rejoignez le salon XMPP 💬: => xmpp:fremen@chat.si3t.ch?join ~*´¨¨) ⹁.•´¸.•*´¨) ¸.•*¨) (¸.•´ (¸.• ;⹁.~!prx ]]> Du tri dans mes flux RSS ATOM https://si3t.ch/log/2025-09-15-DutridansmesfluxRSSATOM.txt 2025-09-15T12:18:23Z mailto:prx@si3t.ch?subject=DutridansmesfluxRSSATOM Ou rejoignez le salon XMPP 💬: => xmpp:fremen@chat.si3t.ch?join ~*´¨¨) ⹁.•´¸.•*´¨) ¸.•*¨) (¸.•´ (¸.• ;⹁.~!prx ]]> rss2email https://si3t.ch/log/2025-09-13-rss2email.txt 2025-09-13T15:32:33Z https://codemadness.org/sfeed.html Il est vraiment excellent. Son côté KISS permet de très finement l'adapter à ses besoins. On peut même filtrer les trackers, ou remplacer les youtube par invidious (et équivalents). Le fait qu'il utilise curl permet même de récupérer un flux sur gopher. Je vérifiais une fois par jour mes flux, et les lisais avec sfeed_curses. Seulement voilà, je ne lisais pas tout. Loin de là. Du coup j'en arrivais à me dépêcher de lire un maximum de choses avant que la fatigue ne l'emporte. C'était bacler. f6k m'a rappelé récemment l'existence de rss2email, qui est bien connu : => https://github.com/rss2email/rss2email Cet outil envoie vers une adresse mail les nouveaux éléments de flux. > Mais tu peux faire pareil avec sfeed_mbox et fdm Oui, j'en ai bien conscience, mais sfeed_mbox ne fait qu'envoyer le lien vers l'article. C'est d'ailleurs un des principaux reproches que j'ai à faire à sfeed, le contenu des articles est rarement incluse, sauf dans sfeed_curses. Alors je pourrais éditer le code, mais là je n'en ai pas le temps ni l'énergie. Je me sentais restreint dans le fait d'être forcé à ouvrir sfeed_curses pour lire. L'envoie d'un article par mail me permet de les lire depuis mutt, mais aussi depuis n'importe quel autre endroit qui me permet de consulter mes mails. Cette petite liberté fait tout. Tout n'est pas parfait : rss2email ne supporte pas gopher, ni gemini. Tant pis. De toute façon, ça fait partie des choses qui m'agacent avec ces autres protocoles, surtout gemini qui n'est toujours pas reconnu. C'est bien beau de vouloir refaire un web propre et sain, mais c'est inutile s'il est restreint. À la place, on voit fleurir des proxys gopher->http ou gemini->http. Ça me paraît hypocrite, alors que proposer son contenu dans du http propre dépourvu de publicité/trackers/cookies me semble une façon active de montrer l'exemple et promouvoir un indieweb qu'on aime. Bref, il faudra qu'on en reparle... En attendant, rss2email fait très bien le job. Un jour, peut-être, je me plongerai dans le code pour ajouter gopher et gemini. (gemini qui en passant a inventé son propre format, le gemfeed, qui limite à un post par jour ce qui est aberrant, comme si on n'avait pas pu penser à ajouter l'heure à un post...). Quoi? Je digresse? Bienvenue dans ma tête :D. Ça fait longtemps que je n'ai pas fait de python, ça serait l'occasion. --- Une réaction? Envoyez votre commentaire par mail ✉️: => mailto:prx@si3t.ch?subject=rss2email Ou rejoignez le salon XMPP 💬: => xmpp:fremen@chat.si3t.ch?join ~*´¨¨) ⹁.•´¸.•*´¨) ¸.•*¨) (¸.•´ (¸.• ;⹁.~!prx ]]> calendar https://si3t.ch/log/2025-09-11-calendar.txt 2025-09-11T12:54:06Z https://terokarvinen.com/2021/calendar-txt/ Calendar.txt => https://ploum.net/2025-09-03-calendar-txt.html How I fell in love with calendar.txt => https://galusik.fr/twtxt.txt entrée du https://galusik.fr/twtxt.txt => https://orangina-rouge.org/shaarli/shaare/mEMTXQ Et pour cause, je suis le premier à apprécier la simplicité et la puissance du texte brut. Contrairement à ce qui est évoqué par endroit, c'est simplissime de synchroniser un tel calendrier entre différentes machines, smartphone et ordinateur, par exemple avec Syncthing : => https://syncthing.net Syncthing Cependant, il n'y a pas de client Android tout prêt, mais j'imagine que c'est assez simple à créer. Ce qui m'étonne, c'est la redécouverte d'un outil calendrier de ce genre. En effet, ce dont je veux parler aujourd'hui, c'est de la commande "calendar", disponible sur la plupart des outils UNIX, donc probablement votre distro Linux: => https://man.openbsd.org/calendar => https://manpages.debian.org/testing/calendar/calendar.1.en.html Un peu comme l'évoque Ploum, j'ai depuis un moment la commande suivante qui est lancée quand j'ouvre un terminal : ``` calendar -A 7 ``` Cela m'affiche tous les évènements à venir les 7 prochains jours. J'en parlais ici (presque 4 ans, que ça passe vite!!!): => https://si3t.ch/log/2021-05-26-calendar.txt Le fichier ~/.calendar/calendar est un simple fichier texte. Pour ma part, je le trouve nettement plus clair que la syntaxe de calendar.txt : ``` Mois jour évènement ``` On y retrouve tous les avantages très bien décrits par Ploum, avec quelques autres. Par exemple, les évènements récurrents, par exemple "tous les mardis". Pas besoin d'éditer touuuus les mardis du calendrier, une simple ligne de ce genre suffit : ``` Tue 10h : prendre une douche ``` Il y a un tout petit bémol : la tabulation qui sépare la date de la description de l'évènement. Ce n'est pas très pratique à entrer sur un smartphone. Mais on peut le faire quand même avec le clavier virtuel qui va bien. calendar comprend plusieurs façon d'écrire les dates, à chacun de choisir ce qu'il préfère. Mais encore plus pratique : on peut inclure des évènements de divers calendriers, par exemple: ``` #include ``` Nul besoin de devoir télécharger un fichier pré-rempli, qui sera obsolète dans quelques (longues, il faut le reconnaître) années. Je vous invite à en apprendre plus sur ces solutions KISS et à lire les liens donnés plus haut, peut-être vous inspireront-ils. En tout cas, j'en suis venu à ne plus pouvoir m'en passer. --- Une réaction? Envoyez votre commentaire par mail ✉️: => mailto:prx@si3t.ch?subject=calendar Ou rejoignez le salon XMPP 💬: => xmpp:fremen@chat.si3t.ch?join ~*´¨¨) ⹁.•´¸.•*´¨) ¸.•*¨) (¸.•´ (¸.• ;⹁.~!prx ]]> teapot https://si3t.ch/log/2025-09-09-teapot.txt 2025-09-09T11:38:07Z https://si3t.ch/teapot Dans le configuration de httpd, j'ai juste ajouté : ``` location "/teapot" { block return 418 } ``` Indispensable! --- Une réaction? Envoyez votre commentaire par mail ✉️: => mailto:prx@si3t.ch?subject=teapot Ou rejoignez le salon XMPP 💬: => xmpp:fremen@chat.si3t.ch?join ~*´¨¨) ⹁.•´¸.•*´¨) ¸.•*¨) (¸.•´ (¸.• ;⹁.~!prx ]]> Générateur de plan de classe https://si3t.ch/log/2025-09-03-Generateurdeplandeclasse.txt 2025-09-03T21:52:18Z https://si3t.ch/tools/plan-de-classe/ ## En détails En ce début d'année, avec M, on a eu envie d'un générateur de plan de classe aléatoire. Dit autrement, un outil qui nous permette d'imprimer/projeter/modifier un plan de classe sans trop de prise de tête, avec environ 300 élèves dans notre carquois. (on est bien d'accord, on ne peut pas se reposer uniquement sur le hasard, mais l'aléatoire est parfois un point de départ comme un autre). Par ailleurs, ça peut être un outil pratique pour varier la composition des groupes. On a pensé que cela pourrait vous intéresser. Sans prétention, on a commencé à écrire quelques lignes de code, et ChatGPT aidant (Saint Bilan-Carbone nous pardonne), nous avons étoffé l'outil afin qu'il permette : * D'importer une liste de classe exportée depuis Pronote. * Placer de façon aléatoire les élèves. * Modifier le plan de classe aléatoire par glisser-déposer * Figer un élève à une place bien précise. Si si, on sait que vous avez vos chouchous à garder tout près du bureau. ;) * Diffuser un plan de classe pour permettre de se placer à l'entrée en classe. * Disposer du même plan de classe du point de vue du prof (inversé). * Imprimer ce plan de classe (export PDF). Si cela vous intéresse, l'essayer vaudra mieux que ce long discours : => https://si3t.ch/tools/plan-de-classe/ Oui, ce n'est pas très joli, mais on a pensé que des couleurs et des dégradés à paillettes, ça ne serait pas l'idéal pour le toner de notre précieuse photocopieuse. Rassurez-vous : cet outil ne fait travailler que votre ordinateur uniquement. Autrement dit, il n'y a pas de serveur qui traite les données sensibles de nos élèves : tout se fait sur votre ordinateur uniquement. (Captain' RGPD est ok). D'ailleurs, les plus sceptiques (bravo!) pourront télécharger la page sur leur disque dur et l'ouvrir le fichier plan-de-classe.html avec un navigateur (Firefox, Chrome) : le résultat sera exactement le même. ## Comment l'utiliser? Ouvrez Pronote dans votre navigateur. Dans l'onglet "Mes données", ouvrez "Liste des élèves". Après avoir choisi votre classe favorite, vous pourrez récupérer la liste de vos élèves adorés au format CSV avec un clic sur le bouton tout à droite à la forme de deux feuilles superposées. Ouvrez maintenant le générateur de plan de classe sus-mentionnée. (indice : https://si3t.ch/tools/plan-de-classe/ ) Avec un clic sur le bouton "Parcourir", vous pourrez donner à votre navigateur la liste de votre classe préférée à traiter. Aussitôt, il propose un plan de classe aléatoire. Tant que vous cliquez sur "Nouvelle disposition", il mélange les élèves. Vous pouvez déplacer les élèves avec un glisser-déposer. Un double clic sur un élève le fige à cette place : il ne sera plus modifiable. (on oublie l'aléatoire assez vite) Un bouton "Retourner" vous permet d'obtenir un point de vue "prof". Enfin, vous pouvez exporter votre plan de classe en PDF tel qu'il apparaît à l'écran. Petit bémol : la répartition des tables correspond à nos salles de sciences, ce qui n'est probablement la configuration de vos salles. Modifiez alors le nombre de rangées et de colonnes selon vos besoins. Nous n'avons pas prévu d'outil pour les ilôts (vois plus loin ;) ). ## Pour compléter Vous aimerez peut-être l'outil de ladigitale qui permet de constituer des groupes aléatoires : => https://ladigitale.dev/digitools/groupes/ Et de façon plus large tous les outils de la digitale bien pratique aux enseignants : => https://ladigitale.dev/ Voire encore le bien connu tableau de classe avec chronomètres, compte à rebours, sondage... => https://classroomscreen.com/app/ ## Mot de la fin Petite pensée pour toutes celleux qui n'ont pas d'ordinateur fonctionnel dans leur salle qui trouveront ce message pour le moins ironique. Consolez-vous, votre exemple de sobriété énergétique fait du bien à Gaïa... (désolé... 😕) Ça y est, ce mail est enfin terminé, vous pouvez comme le dit l'ami arpi, éteindre votre ordinateur et reprendre une activité normale. --- Une réaction? Envoyez votre commentaire par mail: prx@si3t.ch Ou rejoignez le salon XMPP: fremen@chat.si3t.ch ~*´¨¨) ⹁.•´¸.•*´¨) ¸.•*¨) (¸.•´ (¸.• ;⹁.~!prx ]]> Tous les émojis à portée de main https://si3t.ch/log/2025-09-01-Touslesemojisaporteedemain.txt 2025-09-01T10:23:57Z https://www.unicode.org/emoji/charts/full-emoji-list.html Ensuite, un peu de awk m'a permis d'obtenir emoji.txt : => https://si3t.ch/tools/secret/?7b195ddc9d320f02#HKhPA5BaLia4UjnBUuyjtsJxMEPVYgASmJ4fMUmJzMUZ ``` awk ' /td.*'chars'/ { split($0, a, ">") split(a[2], b, "<") emoji = b[1] } /td.*'name'/ { split($0, a, ">") split(a[2], b, "<") name = b[1] } (emoji != "") && (name != "") { printf("%s %s\n", emoji, name) emoji="" name="" } ' full-emoji-list.html > emoji.txt ``` Enfin, je veux pouvoir copier un de ces symboles facilement. J'utilise pour cela dmenu ou fzy => https://github.com/jhawthorn/fzy ``` fzy -p emoji < emoji.txt | awk '{print $1}' | xclip -selection clipboard ``` Ceci mis en alias ou dans un script appelé via raccourci clavier, et hop! À vrai dire, il me manquait aussi quelques symboles mathématiques, qui ne font pas partie des emojis. Mais c'est enfantin d'ajouter un symbole qui pourait me manquer pour une future utilisation :) Pour le retrouver, ce site est pas mal du tout: => https://www.utf8icons.com --- Une réaction? Envoyez votre commentaire par mail: prx@si3t.ch Ou rejoignez le salon XMPP: fremen@chat.si3t.ch ~*´¨¨) ⹁.•´¸.•*´¨) ¸.•*¨) (¸.•´ (¸.• ;⹁.~!prx ]]> parfois ça a du bon d'être un geek https://si3t.ch/log/2025-08-29-parfoiscaadubondetreungeek.txt 2025-08-29T21:54:12Z 1 {gsub("\"","", $1); print $1}' ``` Un petit coup de sort -R est c'est randomisé pour un début d'année. ``` awk -F ';' 'NR > 1 {gsub("\"","", $1); print $1}' | sort -R ``` C'est pas parfait, j'en connais quelques uns qu'il vaut mieux séparer pour commencer, mais c'est un bon début. Sinon, il y a aussi digigroupes: => https://ladigitale.dev/digitools/groupes/ Bon, je n'ai pas encore trouvé comment générer un plan de classe aléatoire, mais j'imagine qu'avec des tableaux markdown + pandoc on doit pouvoir le faire. Ça ne fait pas partie de mes envies, je laisse ça comme exercice au lecteur ^^ --- Une réaction? Envoyez votre commentaire par mail: prx@si3t.ch Ou rejoignez le salon XMPP: fremen@chat.si3t.ch ~*´¨¨) ⹁.•´¸.•*´¨) ¸.•*¨) (¸.•´ (¸.• ;⹁.~!prx ]]> La guerre des Rose https://si3t.ch/log/2025-08-28-LaguerredesRose.txt 2025-08-28T10:00:01Z amore: a more readable plaintext markup https://si3t.ch/log/2025-08-22-amore-a-more-readable-plaintext-markup.txt 2025-08-22T15:38:17Z https://sr.ht/~prx/amore/ J'aime beaucoup le format gemtext, mais avoir des lignes hyper longues, c'est vraiment pénible. Il me manquait la possibilité de pouvoir appeler "fmt" ou "fold" sur mes documents afin qu'ils soient aussi bien lisibles au format texte brut qu'une fois convertis en html (ou autre). Vous me direz, je n'avais qu'à repasser au markdown. Oui mais, le markdown, c'est n'importe quoi pour les liens. Franchement, qui a envie de se casser les doignes à mettre des [ et des ] puis des (), et de penser à mettre un ! pour les images. Et encore, il ne faut pas se tromper dans l'ordre des [] et des (). J'aurais pu me contenter de coller un lien tout seul sur sa ligne après tout sans ces notations bizarres... Ainsi, le lien reste bien identifiable. Mais ça aurait été passer à côté des vidéos et du son. C'était aussi l'occasion de me remettre au C. Après une implémentation en awk, le C est prêt, et la différence est comme d'habitude notable pour générer tout mon site: En awk: 0m14.33s real 0m05.73s user 0m04.91s system En c: 0m08.99s real 0m02.53s user 0m03.87s system J'en ai profité pour ajouter 2 sortes de paragraphes : les messages importants (strong) et le mode verbatim si je veux coller du html direct. J'ai en tête de convertir ça en d'autres formats, notamment PDF (LaTeX), afin de pouvoir rédiger mes cours ainsi. Si vous voulez regarder la syntaxe, je détaille cela en français ici : => https://si3t.ch/misc/plaintext/ Sinon, n'hésitez pas à aller chasser les bugs: => https://sr.ht/~prx/amore/ En attendant, je vais pouvoir reprendre mes citations pour les formater sur plusieurs lignes :) --- Une réaction? Envoyez votre commentaire par mail: => prx@si3t.ch?subject=amore-a-more-readable-plaintext-markup Ou rejoignez le salon XMPP: => fremen@chat.si3t.ch ~*´¨¨) ⹁.•´¸.•*´¨) ¸.•*¨) (¸.•´ (¸.• ;⹁.~!prx ]]> atom.awk corrigé https://si3t.ch/log/2025-08-21-atom.awk-corrige.txt 2025-08-21T07:09:40Z https://si3t.ch/code/atom.awk/ Il ignore les fichiers dont le nom commence par un "_". Cependant, là, j'ai un fichier qui n'est pas une entrée du flux, mais qui ne commence pas par un "_". J'ai donc ajouté une vérification qui devrait être là depuis longtemps : si la date de plublication indiquée sur la 2e ligne n'est pas au bon format, alors ce n'est sans doute pas une entrée de blog et le fichier doit être ignoré. Voici à quoi ressemble la regex (awk rocks!) ``` if (pubdate !~ /[0-9]{4}-[0-9]{2}-[0-9]{2}T[0-9]{2}:[0-9]{2}:[0-9]{2}Z/) { ``` On doit pouvoir faire plus court, mais j'aime autant la laisser ainsi car c'est plus clair pour moi. Elle est constituée des éléments suivants : * [0-9] : il doit y avoir un chiffre * [0-9]{4} : Ce doit être un nombre de 4 chiffres * [0-9]{4}-[0-9]{2} : Un nombre de 4 chiffres suivi d'un tiret suivi d'un nombre de 2 chiffres * [0-9]{4}-[0-9]{2}-[0-9]{2}T : Encore 2 chiffres après un tiret puis un "T" La suite c'est la même logique pour l'heure, mais c'est séparé par des ":" et pas des "-". AWK permet de tester une regex avec l'opérateur "~", et la regex est indiquée entre "/". En tout cas, désolé pour ceux qui auraient vu le mauvais billet apparaître dans leur flux. Comme il n'avait pas de date, je ne sais pas trop comment les lecteurs de flux l'auront traité. --- Une réaction? Envoyez votre commentaire par mail: => prx@si3t.ch?subject=atom.awk-corrige Ou rejoignez le salon XMPP: => fremen@chat.si3t.ch ~*´¨¨) ⹁.•´¸.•*´¨) ¸.•*¨) (¸.•´ (¸.• ;⹁.~!prx ]]> Helldebert https://si3t.ch/log/2025-08-15-Helldebert.txt 2025-08-15T08:03:33Z https://www.youtube.com/watch?v=mfY87bZbUVM&list=OLAK5uy_mjIuKYPZE49IuA65XgbYyTA78oVxkoht8&index=2 --- Une réaction? Envoyez votre commentaire par mail: => mailto:prx@si3t.ch?subject=Helldebert Ou rejoignez le salon XMPP: => xmpp:fremen@chat.si3t.ch?join fremen@chat.si3t.ch ~*´¨¨) ⹁.•´¸.•*´¨) ¸.•*¨) (¸.•´ (¸.• ;⹁.~!prx ]]> Des notes accessibles de partout https://si3t.ch/log/2025-08-14-notes-multiples-appareils.txt 2025-08-14T14:27:07Z ls ~/work/notes/ achats.txt articles.txt bricolage.txt checklist-impots-revenus.txt code.txt dl.txt educ.txt idees_cadeau.txt isotop.txt notd.txt nouvelles.txt ports-openbsd.txt projets.txt series.txt todo.txt toread.txt tty.txt workout-playlist.txt ``` Je me retrouve avec des choses sur papier, des doublons sur ordinateur, des triplets avec le téléphone, et je n'ai pas toujours ce que j'ai besoin sours la main, et parfois j'oublie de copier d'un outils à l'autre. C'est le bazar quoi. J'ai enfin mis en place un truc auquel j'aurais du penser avant : * Installation de Markor sur mon smartphone : https://github.com/gsantner/markor * Installation de Syncthing sur mon smartphone et mon ordinateur : https://syncthing.net/ * Partage du dossier /storage/emulated/0/Documents/markor avec mon ordinateur (et mon serveur pour backup). Désormais, peu importe ce que je copie de mon téléphone ou de mon ordinateur, j'ai toutes mes notes synchronisées dans la minute. C'est terriblement pratique!!! Je tombe sur un site qui a l'air cool : hop, dans la liste des trucs toread.txt. ... Bref, prenez 10min pour mettre ça en place, n'attendez pas comme j'ai pu le faire :) --- Une réaction? Envoyez votre commentaire par mail: => mailto:prx@si3t.ch?subject=notes-multiples-appareils Ou rejoignez le salon XMPP: => xmpp:fremen@chat.si3t.ch?join fremen@chat.si3t.ch ~*´¨¨) ⹁.•´¸.•*´¨) ¸.•*¨) (¸.•´ (¸.• ;⹁.~!prx ]]> Le temps qui pousse https://si3t.ch/log/2025-08-12-le-temps-qui-pousse.txt 2025-08-12T14:12:16Z https://phauneradio.bandcamp.com/album/le-temps-qui-pousse => https://archive.phauneradio.com/creations/Temps-Qui-Pousse/2025_Temps-qui-pousse_transcript-translation.pdf > Vos souvenirs percolent vers l’avenir. Le temps ne passe plus : il pense, il ponce les pierres sous vos pas, il serait touffe d’herbe dans vos failles, il fut fleur et fruit — il pousse. -- A. Damasio --- Une réaction? Envoyez votre commentaire par mail: => mailto:prx@si3t.ch?subject=le-temps-qui-pousse Ou rejoignez le salon XMPP: => xmpp:fremen@chat.si3t.ch?join fremen@chat.si3t.ch ]]> Bien utiliser rsync https://si3t.ch/log/2025-08-11-bien-utiliser-rsync.txt 2025-08-11T08:49:10Z mailto:prx@si3t.ch?subject=bien-utiliser-rsync Ou rejoignez le salon XMPP: => xmpp:fremen@chat.si3t.ch?join fremen@chat.si3t.ch ]]> Trouver les fichiers volumineux https://si3t.ch/log/2025-08-10-trouver-les-fichiers-volumineux.txt 2025-08-10T08:29:31Z mailto:prx@si3t.ch?subject=trouver-les-fichiers-volumineux Ou rejoignez le salon XMPP: => xmpp:fremen@chat.si3t.ch?join fremen@chat.si3t.ch ]]> Sauvegarde de culture pour la postérité https://si3t.ch/log/2025-08-04-sauvegarde-de-culture-posterite.txt 2025-08-04T08:45:14Z https://pen.org/magic-tree-house-author-calvin-and-hobbes-among-hundreds-of-tennessee-book-bans/ => https://web.archive.org/save/https://pen.org/magic-tree-house-author-calvin-and-hobbes-among-hundreds-of-tennessee-book-bans/ => https://archive.is/diExo Me voilà donc avec un disque dur qui se rempli de Pixar et autres films qui m'ont formés, dans l'espoir de pouvoir les partager avec mes enfants bientôt, et puisque les lecteurs DVD se font rares. Il y a aussi quelques ressources documentaires : vikidia, wikipedia, ... => https://download.kiwix.org/zim Mais il manquait les livres. Sur mon serveur se trouvent désormais quelques ouvrages: 1984, Dune, Fondation, Farenheit 451, Mars... La culture et la connaissance ne prennent de la valeur que lorsqu'on les partage :). --- Une réaction? Envoyez votre commentaire par mail: => mailto:prx@si3t.ch?subject=sauvegarde-de-culture-posterite Ou rejoignez le salon XMPP: => xmpp:fremen@chat.si3t.ch?join fremen@chat.si3t.ch ]]> Steam-workshop : où sont les mods ? https://si3t.ch/log/2025-06-25-steam-workshop-ou-sont-mods.txt 2025-06-25T14:46:15Z mailto:prx@si3t.ch?subject=steam-workshop-ou-sont-mods Ou rejoignez le salon XMPP: => xmpp:fremen@chat.si3t.ch?join fremen@chat.si3t.ch ]]> warnlow https://si3t.ch/log/2025-06-24-warnlow.txt 2025-06-24T08:27:55Z https://man.openbsd.org/apmd --- Une réaction? Envoyez votre commentaire par mail: => mailto:prx@si3t.ch?subject=warnlow Ou rejoignez le salon XMPP: => xmpp:fremen@chat.si3t.ch?join fremen@chat.si3t.ch ]]> DOS: Baby Jo https://si3t.ch/log/2025-05-18-DOS-Baby-Jo.txt 2025-05-18T20:57:46Z https://dos.zone/babyjo/ --- Une réaction? Envoyez votre commentaire par mail: => mailto:prx@si3t.ch?subject=DOS-Baby-Jo Ou rejoignez le salon XMPP: => xmpp:fremen@chat.si3t.ch?join fremen@chat.si3t.ch ]]> kamehameha interdit à table https://si3t.ch/log/2025-05-13-kamehameha-interdit-a-table.txt 2025-05-13T21:05:04Z https://si3t.ch/pub/img/kame.svg => https://si3t.ch/pub/img/kame.png C'est pas parfait, loin de là, mais ça m'amuse :) Merci Péhä! --- Une réaction? Envoyez votre commentaire par mail: => mailto:prx@si3t.ch?subject=kamehameha-interdit-a-table Ou rejoignez le salon XMPP: => xmpp:fremen@chat.si3t.ch?join fremen@chat.si3t.ch ]]> musicforprogramming https://si3t.ch/log/2025-05-04-musicforprogramming.txt 2025-05-04T13:20:08Z https://si3t.ch/log/2020-09-27.txt Depuis, j'ai je crois fait mieux : ``` #!/bin/sh # downoad every musicforprogramming files curl "https://musicforprogramming.net/rss.xml" | awk ' /.*mp3/ { sub("", "") sub("", "") print } ' | xargs -I "{}" wget -c "{}" ``` --- Une réaction? Envoyez votre commentaire par mail: => mailto:prx@si3t.ch?subject=musicforprogramming Ou rejoignez le salon XMPP: => xmpp:fremen@chat.si3t.ch?join fremen@chat.si3t.ch ]]> /quotes https://si3t.ch/log/2025-03-24-quotes.txt 2025-03-24T10:35:36Z https://si3t.ch/quotes/ J'adore les citations, si bien que j'en ajoute à la fin de la plupart des évaluations distribuées à mes élèves. Évidemment, selon l'état d'esprit du moment, elles ne résonnent pas toujours de la même façon. J'imagine qu'il s'agit d'un assez bon reflet de comment ça fonctionne dans ma tête, alors c'est aussi une façon de mieux se connaître. Peut-être voudrez-vous avoir votre /quotes vous aussi ;) Actuellement, je m'occupe de remplir cette page avec tout ce que j'ai pu noter ci et là sans les rassembler. Je suis d'ailleurs horrifié de voir dans certains recueils des phrases de "grands" hommes mysogines qui sous des airs humoristiques méprisent les femmes, le mariage et le respect d'autrui finalement. Le pire, c'est que certaines femmes célèbres participent à cette discrimination. Coco Chanel, A Nothomb... (à quoi m'attendais-je de quelqu'un qui dine avec Bardella après tout?) Voici les 2 dernières citations ajoutées: > L'éducation est l'arme la plus puissante qu'on puisse utiliser pour changer le monde. -- Nelson Mandela > Leur peine fut la mort, la mienne fur la vie. -- Audrey Pleynet. --- Une réaction? Envoyez votre commentaire par mail: => mailto:prx@si3t.ch?subject=quotes Ou rejoignez le salon XMPP: => xmpp:fremen@chat.si3t.ch?join fremen@chat.si3t.ch ]]> La Bonne Auberge https://si3t.ch/log/2025-03-18-lba.txt 2025-03-18T16:35:24Z https://www.youtube.com/channel/UCY8XxCWoDsPwMQT2_P6gtKQ => https://labonneaubergejdr.fr/ Si ça vous plaît, peut-être voudrez-vous participer à leur campagne de financement participatif: => https://fr.ulule.com/lba-studio17/ --- Une réaction? Envoyez votre commentaire par mail: => mailto:prx@si3t.ch?subject=lba Ou rejoignez le salon XMPP: => xmpp:fremen@chat.si3t.ch?join fremen@chat.si3t.ch ]]> slashpages https://si3t.ch/log/2025-03-16-slashpages.txt 2025-03-16T14:52:49Z https://slashpages.net/ Je trouve certaines idées plutôt sympa, et c'est finalement assez pratique à écrire. Cela m'a aidé à réorganiser un peu le site pour avoir: => /about : ça parle de moi, du site, comment me contacter => /uses : il faut que je pense à mettre cette page à jour ^^ => /sitemap : j'avais déjà nue page pour mettre les liens vers toutes les pages du site, il a suffit de renommer. => /links : tous les liens au fil du web, il faut que je réorganise tout ça et ajouter des explications. Pas de /now, pour cela, il y a le /log. Pour finir, j'ai ajouté la page /wall. Il s'agit d'un livre d'or, ou guestbook. Très largement inspiré de : => https://github.com/shannonkay/guestbook/ J'ai quand même un peu modifié le code, car certaines choses ne m'allaient pas: * Les retours à la ligne sont supportés. Cela permet d'avoir du ascii art si on veut. Cela se fait en remplaçant \r\n par l'entité html correspondante * Je retire l'éventuel html avec la fonction prévue pour : strip_tags() * Pour être vraiment tranquille, on appelle htmlspecialchars(). * Pour valider l'url, c'est directement le html qui s'en charge plutôt que forcer le protocole http:// (pas chiffré en +...) Le code était suffisamment simple, et j'ai réussi à me l'approprier. Si vous remarquez des défauts, n'hésitez pas à m'en faire part :) Le code est là : => https://git.sr.ht/~prx/wall/ --- Une réaction? Envoyez votre commentaire par mail: => mailto:prx@si3t.ch?subject=slashpages Ou rejoignez le salon XMPP: => xmpp:fremen@chat.si3t.ch?join fremen@chat.si3t.ch ]]> Outils https://si3t.ch/log/2025-03-14-outils.txt 2025-03-14T16:42:42Z https://si3t.ch/tools On y trouve un featherwiki que je trouve pratique pour créer une simple page web, une calculatrice, de quoi afficher son IP, un chronomètre, un timer... J'ai piqué pas mal d'outils à Timo et à ladigitale, merci à eux pour les modèles! => https://lehollandaisvolant.net/tout/tools/ => https://ladigitale.dev/digitools L'idée c'est d'avoir en version hors ligne des outils qui me servent souvent en classe. J'essaie de m'approprier le code des autres, ça me fait réviser mon javascript rouillé. À ce titre, j'ai envie de me créer une petite startpage perso. Et en plus gros projet, un board pour le jeu de rôle, avec : * Génération de personnage aléatoire * Dés à cliquer pour les faire rouler * Timer * Générateur de map * bloc note... ? J'en ai profité pour réorganiser un peu le site avec des slashpages. => https://slashpages.net/ J'hésite à mettre un guestbook: => https://web.pixelshannon.com/aguestbook/index.html À ce propos, j'ia failli retirer la mention de mon adresse mail pour les commentaires. Cependant, passer par Mastodon pour avoir des commentaires d'articles, bien que séduisant au départ, ne me paraît pas une si bonne idée : ça impose de créer un compte sur Mastodon. Alors que le mail, tout le monde en a déjà un... C'est agréable de s'occuper de son petit espace à soi, un peu comme un petit jardin numérique :) Reste à réorganiser mes marques pages et commenter un peu pour chacun d'entre eux. :) --- Une réaction? Envoyez votre commentaire par mail: => mailto:prx@si3t.ch?subject=outils Ou rejoignez le salon XMPP: => xmpp:fremen@chat.si3t.ch?join fremen@chat.si3t.ch ]]> Que faire si votre TRX fait bouger votre porte ? https://si3t.ch/log/2025-02-25-trx-porte-qui-bouge.txt 2025-02-25T11:59:34Z https://www.trxtraining.com/ --- Une réaction? Envoyez votre commentaire par mail: => mailto:prx@si3t.ch?subject=trx-porte-qui-bouge Ou rejoignez le salon XMPP: => xmpp:fremen@chat.si3t.ch?join fremen@chat.si3t.ch ]]> bloque bollore https://si3t.ch/log/2025-02-18-bloque-bollore.txt 2025-02-18T20:42:28Z https://d4llo.codeberg.page/BloquonsBollore/ J'ajoute ma petite touche, avec quelques lignes à intégrer à votre fichiers /etc/hosts ``` 0.0.0.0 havas.com 0.0.0.0 dailymotion.com 0.0.0.0 cnews.fr 0.0.0.0 canalplus.com 0.0.0.0 caminteresse.fr 0.0.0.0 capital.fr 0.0.0.0 cotemaison.fr 0.0.0.0 croq-kilos.com 0.0.0.0 cuisineactuelle.fr 0.0.0.0 cuisineaz.com 0.0.0.0 deco.fr 0.0.0.0 drgood.fr 0.0.0.0 femmeactuelle.fr 0.0.0.0 flowmagazine.fr 0.0.0.0 fourchette-et-bikini.fr 0.0.0.0 gentside.com 0.0.0.0 gamesider.com 0.0.0.0 geo.fr 0.0.0.0 telez.fr 0.0.0.0 turbo.fr 0.0.0.0 uppercutmma.com 0.0.0.0 voici.fr 0.0.0.0 hbr.org 0.0.0.0 meteocity.com 0.0.0.0 milkdecoration.com 0.0.0.0 milkmagazine.net 0.0.0.0 mortelleadele.com 0.0.0.0 nationalgeographic.fr 0.0.0.0 neonmag.fr 0.0.0.0 ohmymag.com 0.0.0.0 passeportsante.net 0.0.0.0 programme.tv 0.0.0.0 programme-tv.net 0.0.0.0 harpersbazaar.fr 0.0.0.0 europe1.fr 0.0.0.0 europe2.fr 0.0.0.0 rfm.fr 0.0.0.0 lejdd.fr 0.0.0.0 relay.com 0.0.0.0 larousse.fr 0.0.0.0 valeursactuelles.com 0.0.0.0 tvlibertes.com 0.0.0.0 breizh-info.com 0.0.0.0 burdigala-presse.fr 0.0.0.0 nice-provence.info 0.0.0.0 infos-bordeaux.fr 0.0.0.0 lengadoc-info.com 0.0.0.0 fdesouche.com 0.0.0.0 dreuz.info 0.0.0.0 unebonnedroite.fr 0.0.0.0 contre-info.com 0.0.0.0 causeur.fr 0.0.0.0 bvoltaire.fr 0.0.0.0 frontieresmedia.fr 0.0.0.0 omertamedia.fr 0.0.0.0 lafuria.fr 0.0.0.0 nouveaupresent.fr 0.0.0.0 rc.fr 0.0.0.0 lesalonbeige.fr 0.0.0.0 medias-presse.info 0.0.0.0 chire.fr 0.0.0.0 lectures-francaises.info 0.0.0.0 rivarol.com 0.0.0.0 lincorrect.org 0.0.0.0 francesoir.fr ``` J'hésite à l'ajouter à => https://si3t.ch/evils/ Car en ce qui me concerne, ça ne me manquera pas du tout... --- Une réaction? Envoyez votre commentaire par mail: => mailto:prx@si3t.ch?subject=bloque-bollore Ou rejoignez le salon XMPP: => xmpp:fremen@chat.si3t.ch?join fremen@chat.si3t.ch ]]> Time to update zim archives https://si3t.ch/log/2025-02-16-update-zim.txt 2025-02-16T14:21:42Z mailto:prx@si3t.ch?subject=update-zim => xmpp:fremen@chat.si3t.ch?join fremen@chat.si3t.ch ]]> Rose à paillettes multicolores https://si3t.ch/log/2025-02-08-rose-a-paillettes-multicolores.txt 2025-02-08T15:12:11Z Les vêtements qui brillent multicolores, il n'y en a que pour les filles! C'est pareil pour le rose, et moi j'aime bien cette couleur! Il a tellement raison. On fait le maximum pour dire aux jeunes filles qu'elles ne se destinent pas forcément à être des princesses délicates et parfaites et qu'elles ont le droit d'adorer casser des trucs et courir dans tous les sens si ça leur plait, qu'on en oublie que les garçons aussi n'ont pas à être des grosses brutes toxiques. J'exagère le trait volontairement. Mais il suffit d'aller dans un magasin de jouets pour être agressé soit de bleu ou bien de rose. Il en va de même pour les habits pour enfants : c'est très genré. Dans l'idéal, on a quelques vêtements "neutres" en jaune ou en vert. Mais dès 6 ans à peine, notre environnement est déjà balisé avec une forte incitation à se ranger d'un côté ou de l'autre, sans plus de réflexion que le choix d'une couleur. C'est juste des chaussettes qu'on veut bordel. C'est pas mieux pour les chaussures de sport pour les petites filles : au mieux c'est sandalettes ouvertes, ou alors des baskets avec une semelle lisse. Alors on fait les wokes comme disent certains : * On achète des baskets dans les rayons "garçons" pour notre fille : bah oui, les filles aussi on le droit de courir et s'éclater dans l'herbe et la boue sans glisser. * On achète des chaussettes roses à paillettes multicolores pour notre fils. Il marche et court aussi bien qu'avant, sauf que ça lui donne le sourire de porter ses couleurs favorites. --- Une réaction? Envoyez votre commentaire par mail: => mailto:prx@si3t.ch?subject=rose-a-paillettes-multicolores Ou rejoignez le salon XMPP: => xmpp:fremen@chat.si3t.ch?join fremen@chat.si3t.ch ]]> Mesure de masses et de volumes puis transformation chimique https://si3t.ch/log/2025-02-01-mesure-masse-volumes-transfo-chimique.txt 2025-02-01T15:48:07Z mailto:prx@si3t.ch?subject=mesure-masse-volumes-transfo-chimique Ou rejoignez le salon XMPP: => xmpp:fremen@chat.si3t.ch?join fremen@chat.si3t.ch ]]> ralf : Rename A Lot of Files https://si3t.ch/log/2025-01-27-ralf.txt 2025-01-27T21:03:40Z https://github.com/lecram/rover C'est ainsi qu'est née l'envie d'écrire ralf, comme "Rename A Lot of Files" (le nom a beaucoup changé...). Vous pouvez le récupérer et le tester à partir de cette URL: => https://git.sr.ht/~prx/ralf J'ignore si c'est bien portable en dehors d'OpenBSD, puisque j'utilise strlcat et sltrcpy pour assurer le bon fonctionnement du traîtement des chaînes de caractères. Je pourrais m'en passer avec memcpy() et memmove(), mais autant m'appuyer sur le travail de gens sérieux. Sur debian, il faut installer libbsd-dev je crois. ralf est encore tout nouveau, il y a sans doutes des améliorations à y apporter. Avant cela, et aussi pour me permettre de réfléchir à ce que j'ai écrit, voici quelques explications sur le code. ## Options? Flags? Au départ, j'ai envisager de recopier les diverses façons de renommer que propose Thunar: * Supprimer à partir d'une position * Remplacer à partir d'une position * Chercher/remplacer * Chercher/remplacer avec une regex Après avoir écrit un menu pour sélectionner la méthode, j'ai finalement réalisé que les regex permettaient de faire le tout. ## Liste des fichiers ? Initialement, ralf listait les fichiers présents dans le dossier courant avec scandir(3). C'est une fonction que j'ai déjà utilisé, qui permet d'avoir rapidement une liste des fichiers/dossiers présents. Puis, je me suis dit que restreindre au dossier courant n'était pas très pratique, et que devoir réallouer la taille de la liste en mémoire avec des mallocs n'était pas très efficace. De plus, on peut profiter des méthodes de sélection du shell, comme le fameux glob "*". Alors, tant qu'à faire, je laisse le shell et l'utilisateur décrire les fichiers à renommer en les passant en argument. En passant, j'ai réalisé que le premier argument est toujours le programme en cours d'exécution, j'ai donc retiré le premier paramètre dans argc. ## Enregistrement des fichiers à traîter Pour commencer, j'ai enregistré la liste des fichiers à éventuellement renommer dans une liste, tout simple après avoir vérifié que le fichier existe bel et bien: ``` int file_exist(const char *fn) { struct stat sb; if (stat(fn, &sb) == 0) { return 1; } else { return 0; } } ``` Ça fonctionnait bien, mais cela devenait plus compliqué lorsque je voulais associer le nouveau nom de fichier et parcourir la liste en question. Puis je me suis souvenu qu'il existe déjà tout ce qu'il faut pour ce genre de taches : les queues! Avec sys/queue.h, il y a des méthodes toutes prêtes pour insérer/traiter dans l'ordre une liste chaînée d'objets. Me voilà donc avec une structure qui me permet d'avoir pour chaque fichier le nom courant et à côté le nom à donner: ``` struct Filename { int modified; char name[FILENAME_MAX]; char new[FILENAME_MAX]; SIMPLEQ_ENTRY(Filename) filename; }; SIMPLEQ_HEAD(Filelist_head, Filename); ``` On remarque la variable "modified", qui me permet de savoir ensuite si le fichier doit effectivement être renommé, et mettre un peu de couleur pour identifier le changement prévu. ## Interface utilisateur Je ne connais pas ncurses.h. Alors j'en suis resté aux bons vieux fgets() et getchar(). Oups, je devrais dire getline() et getchar(), puisque le manpage de fgets() conseille d'utiliser getline dans le cas d'entrée hasardeuse. Là encore, tout est prêt et bien pensé, c'est du gâteau. J'ai choisi de tout simplement demander à l'utilisateur la regex à rechercher puis par quoi remplacer. ## La gestion des regex. Là, j'au un peu plus réfléchi. Au départ, j'avais une boucle qui cherchait dans le nom du fichier les patterns correspondant à la regex entrée et qui remplaçait dans ce nom du fichier par la chaîne choisie par l'utilisateur. Cependant, ça posait un problème de boucles infinie. Imaginez que l'on a le fichier "babar.txt". L'utilisateur demande de remplacer "[a-c]" par "b". On comprend qu'il voudrait que "babar.txt" devienne "bbbbr.txt". Cependant, puisque "b" fait partie de "[a-c]", alors ça boucle sans cesse. J'ai donc modifié mon algorithme pour ne traîter chaque pattern qu'à une seule reprise. Au final, la fonction est nettement plus simple: ``` regex_t regex; regmatch_t match[1]; int regret = 0; int n = 0; int lastpos = 0; char buf[BUFSIZ] = {'\0'}; char tmp[FILENAME_MAX] = {'\0'}; /* copy the string to tmp, then modify it */ estrlcpy(tmp, str, sizeof(tmp)); if ((regret = regcomp(®ex, pattern, REG_EXTENDED)) != 0) { regerror(regret, ®ex, buf, sizeof(buf)); regfree(®ex); err(1, "%s", buf); } while (regexec(®ex, tmp, 1, match, 0) == 0) { /* append beginning of tmp in new until match start */ tmp[match[0].rm_so] = '\0'; estrlcat(new, tmp, newsiz); /* replace this part */ estrlcat(new, rep, newsiz); /* move the end of the string at the beginning of tmp */ memmove(tmp, tmp + match[0].rm_so + 1, sizeof(tmp)); n++; } /* at the end, copy the unmatching ending of tmp in new */ estrlcat(new, tmp, newsiz); regfree(®ex); return n; ``` ## stack J'ai choisi d'éviter les malloc(). Ce n'est pas par fainéantise (un peu), mais puisqu'il existe déjà FILENAME_MAX définit dans POSIX. Par ailleurs, ça simplifie le code plutôt que d'allouer de la mémoire et lancer free() ci et là. ## Ce qu'il manque Ça, c'est à vous de me le dire ^^. Pour l'instant, j'ai identifié le souci qui se pose quand un nom de fichier existe déjà : il est tout simplement écrasé. Mettre un petit warning serait pas mal ^^. J'hésite aussi à virer strlcpy et strlcat pour rendre le code plus portable, et aussi pour l'exercice. Qu'en pensez-vous? Ah, il faudrait aussi une manpage. --- Une réaction? Envoyez votre commentaire par mail: => mailto:prx@si3t.ch?subject=ralf Ou rejoignez le salon XMPP: => xmpp:fremen@chat.si3t.ch?join fremen@chat.si3t.ch ]]> La trilogie Mars est solarpunk https://si3t.ch/log/2025-01-25-mars-KSR.txt 2025-01-25T13:29:23Z https://si3t.ch/misc/solarpunk/ --- Une réaction? Envoyez votre commentaire par mail: => mailto:prx@si3t.ch?subject=mars-KSR Ou rejoignez le salon XMPP: => xmpp:fremen@chat.si3t.ch?join fremen@chat.si3t.ch ]]> Sans suite ? https://si3t.ch/log/2025-01-23-sans-suite.txt 2025-01-23T11:02:47Z Je ne connais pas la peur, car la peur tue l'esprit. > La peur est la petite mort qui conduit à l'oblitération totale. > J'affronterai ma peur. > Je lui permettrai de passer sur moi, au travers de moi. > Et lorsqu'elle sera passée, je tournerai mon oeil intérieur sur son chemin. > Et là où elle sera passée, il n'y aura plus rien. > Rien que moi. --- Une réaction? Envoyez votre commentaire par mail: => mailto:prx@si3t.ch?subject=sans-suite Ou rejoignez le salon XMPP: => xmpp:fremen@chat.si3t.ch?join fremen@chat.si3t.ch ]]> nuage https://si3t.ch/log/2025-01-22-nuage.txt 2025-01-22T15:01:31Z https://nuage.apps.education.fr/ C'est fait pour le boulot, alors c'est parfait pour le besoin que j'en ai. Me voilà donc à tester nextcloudcmd pour envoyer mes cours sur nuage. Je m'y suis peut-être mal pris, mais l'application de synchronisation Nextcloud plante sur mon OpenBSD -current (bug à faire remonter si je prends le temps...), et nextcloudcmd ne fait rien... Je me suis donc tourné vers rclone, et là, je suis ravi tellement ça marche bien. Il uploade les changements via le protocole webDAV, et j'ai mes documents toujours à portée de main même si mon matériel n'est plus accessible. --- Une réaction? Envoyez votre commentaire par mail: => mailto:prx@si3t.ch?subject=nuage Ou rejoignez le salon XMPP: => xmpp:fremen@chat.si3t.ch?join fremen@chat.si3t.ch ]]> Privatebin et le partage de fichiers https://si3t.ch/log/2025-01-15-Privatebin.txt 2025-01-15T14:04:57Z /dev/null 2>&1 printf "%s\n" "${url}/${out}" | xclip -i -selection clipboard printf "%s\n" "${url}/${out}" exit 0 ``` Régulièrement, les fichiers qui sont trop vieux sont supprimés. J'ai pour cela une tâche cron qui s'en occupe: ``` @weekly find /var/www/htdocs/si3t.ch/pub/tmp/ -type f -mtime +8 -delete ``` Mais je ne peux utiliser cette méthode que si je dispose d'un ordinateur capable de faire du ssh, et à fortiori qui contient ma clé SSH. Me voilà donc en quête d'un outil à auto-héberger. Et là c'est la misère, à croire qu'il n'existe plus que docket et nodejs pour développer des trucs. Rendez-nous les petits CGI propres ou les bouts de PHP pas compliqués! Par hasard, je suis ensuite tombé sur le Privatebin de mon académie: => https://secret.ac-nantes.fr/ Je fais confiance à l'admin de mon serveur, je vais donc héberger Privatebin qui non seulement chiffre les données dans le navigateur (zero-knowledge pour le serveur) et permet de joindre des fichiers. Après un peu de configuration, j'ai un truc qui me plaît : * Pas de partages éternels * Durée de validité d'1 jour maxi * Upload de 100M maxi. C'est beaucoup! La configuration de httpd pour les curieux est tout bête: ``` # Privatebin # Interdit de lire les données pastées location "/tools/secret/data/*" { block } # seul le index.php est traîté par PHP location "/tools/secret/" { directory index index.php } location "/tools/secret/index.php" { fastcgi socket "/run/php-fpm.sock" } ``` Si vous en avez besoin, c'est par ici: => https://si3t.ch/tools/secret/ Je suis curieux de découvrir de nouveaux outils à héberger, si possible de type zero-knowledge. --- Une réaction? Envoyez votre commentaire par mail: => mailto:prx@si3t.ch?subject=Privatebin Ou rejoignez le salon XMPP: => xmpp:fremen@chat.si3t.ch?join fremen@chat.si3t.ch ]]> Sac d'urgence https://si3t.ch/log/2025-01-06-sac-d-urgence.txt 2025-01-06T11:30:46Z "Tout bon père de famille devrait avoir un sac d'urgence à portée de main". 😊 Ça me fait penser que peut-être certains trouveront intéressant le contenu de ce sac d'urgence. Il existe des "kits de survie" tous prêts, et peuvent constituer une bonne base de départ, bien que des choses soient inutiles ou alors manquantes. Il doit être léger, pratique à emporter, de façon à ce que se soit la seule chose à prendre puis partir à toutes jambes. Mon vieux sac à dos qui me servait au collège à transporter mes affaires de sport fait tout à fait l'affaire: :) À l'intérieur, on trouve : * Une trousse médicale d'urgence. Rien de fou, juste du désinfectant et de quoi bander une plaie. * Des couvertures de survie : pour s'abriter du chaud et du froid. J'en ai pris plusieurs, de quoi faire un abri. Bien pliées, ça ne prend pas de place. * De l'eau. J'ai prévu 2 gourdes pleines. * De quoi remplir les gourdes. Pour cela, une paille filtrante fait l'affaire. * Quelques vivres : barres énergétiques, nourriture déshydratée, boite de conserve... à chacun de voir. De quoi tenir 24h, un peu plus en se rationnant. * De la ficelle : ça sert toujours pour réparer, faire un abri, attacher des objets à transporter... * De quoi allumer un feu. Un briquet par exemple. * Une petite casserole de camping. En alu, c'est très léger et ne prend pas de place. * Une pince multi-outils ou juste un très bon couteau. * Une radio à piles ou à manivelle rechargeable pour se tenir informé sans dépendre du réseau de distribution électrique. * Une lampe torche. * Un peu d'argent liquide, dans une pochette à l'abri de l'humidité. * Une copie des papiers d'identité et livret de famille, plastifié ou dans une pochette plastique. * Un bête savon. * Du papier, un crayon de bois et un marqueur. Un jour, j'apprendrai à fabriquer un radio-émetteur pour compléter ce kit... Il manque peut-être des couverts... Mais on ne part pas pour un camping ^^ Pareil pour la petite pelle... Pas sûr que ce soit le + important en cas d'urgence. Il y a même une page gouvernementale sur le sujet: => https://www.info.gouv.fr/risques/se-preparer-a-une-situation-durgence Une autre source avec des idées intéressantes : => https://www.croix-rouge.fr/faire-face-au-choc-climatique-nos-propositions-pour-une-meilleure/catakit-preparer-son-sac-durgence Si vous avez des suggestions d'amélioration, je suis preneur :) --- Une réaction? Envoyez votre commentaire par mail: => mailto:prx@si3t.ch?subject=sac-d-urgence ]]> bibliotheque https://si3t.ch/log/2025-01-06-bibliotheque.txt 2025-01-06T08:52:51Z Mais t'en avais pas déjà plein à lire ? Ahem... Bref, je me la pète avec la photo du résultat :) : => https://0x0.st/8iWs.jpg --- Une réaction? Envoyez votre commentaire par mail: => mailto:prx@si3t.ch?subject=bibliotheque Ou rejoignez le salon XMPP: => xmpp:fremen@chat.si3t.ch?join fremen@chat.si3t.ch ]]> dmz : pour X ok, mais pas pour Firefox https://si3t.ch/log/2025-01-04-dmz.txt 2025-01-04T14:47:35Z > ~/.icons/dmz/cursor.theme <> ~/.icons/dmz/index.theme <> ~/.icons/default/index.theme < mailto:prx@si3t.ch?subject=dmz Ou rejoignez le salon XMPP: => xmpp:fremen@chat.si3t.ch?join fremen@chat.si3t.ch ]]> sfeed_clean https://si3t.ch/log/2025-01-03-sfeed-clean.txt 2025-01-03T14:55:54Z https://codemadness.org/git/sfeed/file/README.html Amongst other thigs, I use it to display new entries when I first open a terminal, meaning automagically in tmux when my session pops up. Recently, I noticed it was a little slower to display latest entries. I had to clean up older entries and no longer subscribed feeds. To do so, the README is very clear, but I had to gather things in a little script for later purpose : ```sfeed_clean #!/bin/sh # remove previous feeds older than a week. feeds_dir=~/.sfeed/feeds for i in "${feeds_dir}"/*; do echo "${i}" awk -F '\t' -v "old=$(($(date +'%s') - 604800))" 'int($1) > old' < "${i}" > "${i}".new mv "${i}".new "${i}" done ``` --- Comments? => mailto:prx@si3t.ch?subject=sfeed-clean => xmpp:fremen@chat.si3t.ch?join fremen@chat.si3t.ch ]]> Philosophie de vie https://si3t.ch/log/2024-12-16-philovie.txt 2024-12-16T09:32:11Z https://si3t.ch/misc/philovie/ J'ai essayé de rester très générique, de façon à ce que chacun et chacune puisse s'y retrouver. Pour ma part, ça me fait penser à ma responsabilité de père, ma mission d'enseignant, mes inquiétudes écologiques, mon appétit pour le logiciel-libre. Je me tais désormais et vous laisse lire, je suis curieux de lire vos réactions tel qu'est le texte ainsi. ``` ## Faire le bien Refuse la violence, c'est le raccourci des faibles. Emprunte le long chemin de la gentillesse, c'est la voie des braves. Patiente. Comme une prière, un gage de confiance, une main intransigeante mais tendue vers le changement. Écoute, observe. Fais preuve d'empathie, nous ne sommes que des humains, un espèce bien jeune qui a tout à apprendre. Seul le bien peut engendrer le bon. ## Inspirer Sois digne de confiance. Reste fiable, toujours. Tiens tes promesses. Inspire par l'exemple, pas par l'obligation, alors réfléchis. ## Préserver Préserve les connaissances et les ressources. Partage. ``` --- Une réaction? Envoyez votre commentaire par mail : => mailto:prx@si3t.ch?subject=philovie ]]> Philosophie https://si3t.ch/log/2024-12-15-philosophie.txt 2024-12-15T15:27:36Z https://si3t.ch/misc/philovie/ --- C'est dans mes flux que j'ai vu passer cette idée : quelle est la façon dont on voit la vie? Quelle est sa philosophie? => https://manuelmoreale.com/@/page/3bg8rYZBhA7cNjBA J'aime beaucoup cette idée, et j'y vois une sorte de voeux à la vie. Je dois y réfléchir, mais en ce qui me concerne, ce qui me vient à l'esprit en premier, ce serait très court : "sois gentil". La gentillesse est la plus importante des qualités. Je ne veux pas d'un monde où être gentil est considéré comme une faiblesse. Être gentil, c'est être patient. Une patience comme une grande prière. De la patience en guise d'acte de foi pour avoir un courage à toute épreuves. Faire preuve de gentillesse, c'est s'ouvrir à l'autre, une forme d'empathie à l'état pur qui renvoie à notre condition de simple être humain et nécessite un respect viscéral. Enfin, la gentillesse, c'est souhaiter le meilleur pour chacun et contribuer à sa mise en oeuvre. Cela demande de l'exigence et de la générosité. Il en découle la nécessité de sauvegarder la connnaissance pour la rendre accessible et la transmettre le plus largement possible. (vivre les livres!) Peut-être y ajouterai-je le minimalisme? Ou en tout cas "faire avec moins"? Et le karma... Comme me le rappelle souvent arpinux, faire le bien, la vie te le rendra... J'aime bien, c'est rassurant, mais a la facheuse tendance à être biaisé de façon intéressée, de réclamer au mérite lorsque le retour n'est pas assez rapide. C'est pas clair dans ma tête. ## Divers J'ai ajouté une page "*" au si3tch qui contient la liste de toutes les pages: => /everything/ ## Dons Pour 2025, j'ai activé le don récurrent à Framasoft. => https://soutenir.framasoft.org/fr/ C'est défiscalisé, pensez-y ;) Dans un tout autre domaine, j'ai fait de même pour La Bonne Auberge: => https://www.patreon.com/c/LaBonneAuberge/membership ## Citation > Deserves it! I daresay he does. Many that live deserve death. And some that die deserve life. Can you give it to them? Then do not be too eager to deal out death in judgement. For even the very wise cannot see all ends. I have not much hope that Gollum can be cured before he dies, but there is a chance of it. And he is bound up with the fate of the Ring. My heart tells me that he has some part to play yet, for good or ill, before the end; and when that comes, the pity of Bilbo may rule the fate of many – yours not least. -- Gandalf (Tolkien) ... > All we have to decide is what to do with the time that is given us.' --- Une réaction? Envoyez votre commentaire par mail : => mailto:prx@si3t.ch?subject=philosophie ]]> Block AI bots with relayd on OpenBSD https://si3t.ch/log/2024-11-27-block-ai-bots-with-relayd-openbsd.txt 2024-11-27T09:08:57Z I don't feed IA" ``` As you can see, in the end, I add a little message :) The user-agent list has been found here: => https://raw.githubusercontent.com/ai-robots-txt/ai.robots.txt/refs/heads/main/robots.txt) After reloading relayd, check it works as expected with curl: ``` > curl -H "User-Agent:GPTBot" https://si3t.ch [... snip ...]

Forbidden

Forbidden
I don't feed IA

OpenBSD relayd at 2a01:e0a:2b8:ca70::1bad port 443
``` \o/ ]]>
Resister -- notes https://si3t.ch/log/2024-11-26-resister.txt 2024-11-26T07:47:59Z https://www.lalibrairie.com/livres/resister_0-11697790_9782228937597.html?ctx=397de3ecca38cf20254f77d136f28b52 => https://www.babelio.com/livres/Saque-Resister/1725653 Sinon je continue de découvrir la trilogie de Mars de KS Robinson. J'aime beaucoup la façon dont les personnages sont traités, comment les individues forgent une nouvelle société, comment les sciences constituent un outil qu'on ne peux que respecter. Nadia <3. ## Temps libre Au lieu de traîner sur le plus en plus problématique 9gag ou sur Mastodon, je découvre anki, pourtant déjà bien connu : => https://apps.ankiweb.net/ La méthode des flashcards n'a rien de nouveau pour un prof, mais que c'est pratique de l'avoir en version numérique avec un outil qui gère soi-même la fréquence des rappels. Me voilà à apprendre la LSF avec plaisir, c'est gratifiant de progresser si vite, et voilà bien longtemps que je n'avais pas appris quelque chose de nouveau. Avec mon fils, on s'amuse bien à se parler en langue des signes, et je sais que cela sera utile pour s'ouvrir aux autres, mais aussi pour faire comme les Atréides :) Prochains apprentissages : le morse (obligé), le japonais, et... Le russe et l'arabe? L'apprentissage des langues me fait peur, surtout avec des écritures/alphabets qui ne ressemblent en rien au latin ou l'anglo-saxon qui sont des repères pour moi. Vous auriez des suggestions de decks? ## Lectures de RSS J'ai tendance à me perdre dans tous les flux RSS que je suis. Je m'aperçois que le fait qu'ils soient ouverts par ordre alphabétique dans sfeed_curses en privilégie certains. Désormais, à l'ouverture de ma session, j'affiche les nouveaux articles avec leurs titres. De cette façon, je repère rapidement si l'un d'entre eux peux m'intéresser et saute dessus aussitôt, et prends le temps de lire les autres + tard. ``` sfeed_plain ~/.sfeed/feeds/* | grep "^N" | cut -d" " -f5- ``` ## Citations > New rule, After you reach 999$ million, every red cent goes to schools and health care. You get a trophy that says, "I won capitalism" and we name a dog park after you. --- Une réaction? Envoyez votre commentaire par mail : => mailto:prx@si3t.ch?subject=resister ]]> Utopiales 2024 - notes https://si3t.ch/log/2024-11-16-notes-utopiales-2024.txt 2024-11-16T20:11:51Z https://www.youtube.com/@ideasinscience Les premiers jours furent plus pessimistes que d'habitude. C'était peut-être (sans doute) lié à mon état d'esprit un peu dépressif du moment et l'état du monde franchement pas terrible. J'ai eu le sentiment d'assister à des Dystopiales, malgré des conférences sur la réponse à apporter à l'arrivée de l'extrême droite aux portes du pouvoir. C'était d'autant plus vrai à écouter Nicolas Martin déchaîné, joussif à écouter et galvanisant malgré la noirceur de l'avenir possible. => https://www.youtube.com/watch?v=PqYjpWQuLEg Cléo Collomb aussi pertinente qu'intelligente, toute en mesure, très inspirante. Et lorsqu'Audrey Pleynet lui fait echo, c'est un régal! À plusieurs reprise, les gouvernements en place ont été pointés du doigt comme les sources de nos malheurs quotidiens (coucou Manu!). Ça fait du bien d'entendre des gens intelligents :) J'y ai découvert l'idée de Fiction Panier d'Ursula Le Guin. => https://www.terrestres.org/2018/10/14/la-theorie-de-la-fiction-panier/ Fiction panier Lisez ce texte, c'est court, très bien écrit. Il faut juste avoir vu le début de 2001 l'Odyssée de l'espace pour vraiment en profiter ;) Cela résonne tout à fait avec l'idée que je me fais du solarpunk, dont j'ai plus que jamais besoin. À ce propos, Alain Damasio parle de biopunk, avec l'idée d'être très orienté vers le vivant. Je regrette de ne pas avoir entendu mention du solarpunk pendant ces 4 jours, mais on m'a fait très plaisir en me complimentant sur ma veste XD. Ça fait partie des choses que j'adore aux Utopiales, la gentillesse, la simplicité, le respect, la proximité avec les gens. Une sorte d'expérience de société qui me conviendrait bien. Et encore, je ne vous évoque même pas la salle Zen : aucun bruit, des gens dorment allongés sur le sol, d'autres dessinent, les autres lisent... En plein coeur d'un festival avec des centaines de gens! J'ai craqué, on m'a laissé seul à la librairie, sans aucune surveillance. J'ai donc tout un tas de livres de Becky Chambers que j'aurais pu découvrir autrement. Ça me fait réalser que j'adore tout un tas d'autrices : Robin Hobb, Becky Chambers, Ursula Le Guin, Ada Palmer, Claire North, Fiona McIntosh... Pendant une table ronde sur la traduction et la Langue des Signes (LSF), ils ont évoqué le mot italien pour science-fiction : La fantascience. J'adore :) La rencontre avec Alain Damasio m'a retourné, j'avais enfin mes Utopiales et cet élan qui me donne envie d'avancer. J'ai vibré pendant 1h à l'écouter, c'était magique. Quelques extraits et citations approximatives : > On arrête de se battre contre, on se bat pour. > L'harmonie, c'est entrer en résonnace avec une oeuvre, avec les autres, sans altérer les individus ni gommer les différences. C'est tout tout sauf la fusion. > On crève de ne pas vouloir se composer avec ce qui n'est pas nous. > Les phonèmes sont comme les couleurs de Kandinsky. Le chromatisme des mots. Oh, j'allais oublier, il y avait une chasse au trésor dans le café de la cité. La veille du premier jour, mon ami m'a envoyé l'affiche annonçant cette chasse en photo au moment où j'allais me coucher. Très vite, on a reconnu du morse. Un indice dans l'imprimé indiquait que c'était à l'envers. Je me suis empressé de le traduire, en inversant . et _. Le message disait de suivre la file... Dès le premier jour, on a suivi les indices, avec les énigmes diffusées sur l'écran télé, dans la bibliothèque, sur la playlist Spotify... On aurait presque pu gagner si on n'était pas parti voir les tables rondes. Peu importe, c'était vraiment amusant et sympa de parler avec les gens qui cherchaient en même temps, même si la chasse était fermée ensuite. De belles rencontres! La dessinatrice qui était exposée et autrice de l'affiche de sUtopiales cette année a dû s'absenter, la vie n'est pas toujours tendre. Elle a quand même pris la peine de se filmer pour envoyer un message, qui a été diffusé. C'était émouvant, poignant. Roland Lehoucq a pris la relève avec une conférence sur la possibilité physique d'avoir des monstres aussi gros que Godzilla. Tout ce que j'adore dans ce qu'il fait :) À cette occasion, il a cité la phrase suivante qui m'a fait bien rire: > Les mathématiques, c'est cette branche de la physique pour laquelle les expériences ne coutent pas très cher. Sinon, à la tour LU, j'ai découvert des tables rondes de physique un peu + pointues, juste après avoir écouté Nathalie Besson sur le stand à côté de la scène Shayol qui parle du projet d'avoir des interféromètrs qui suivent la Terre sur son orbite pour détecter ondes gravitationnelles. Observer l'univers avec des ondes gravitationnelles plutôt que des photons qui mettent des centaintes voire des milliers d'années à sortir d'une étoile. Passionnant. Ce sont des projet sur 60 ans, la Terre est un vaisseau générationnel pour les scientifiques. Cela fait echo à l'unde des tables rondes des premiers jours d'ailleurs. Réfléchir à long terme, ce que ne font pas nos élus qui ne veulent qu'être... Réélus. Il y a aussi eu la conférence avec Michèle Leduc qui parle physique quantique. Une femme à qui on laisserait la place asisse dans le tram, mais qui est bien différente en réalité des apparences. Bluffante et si drôle! Les jeunes filles ont des modèles auxquels s'identifier pour voir émerger de belles vocations scientifiques. Je suis retourné aux Utopiales avec élèves le lundi. La conférence de physique de Roland Lehoucq était bien sérieuse et trop peu interactive. D'habitude, il fait du lien avec des oeuvres de SF... Là, c'était un VRAI cours de physique, difficile à tenir pour mes élèves de 3e. Mais j'ai eu le privilège et le plaisir de discuter avec lui quelques minutes ensuite, à propos de neutrinos qui nous permettraient d'observer l'univers à l'instar des photos, mais en mieux puisqu'ils n'interagissent pas avec la matière. Cela ressemblait à l'indée du projet expliqué par Nathalie Besson, c'est génial, ça fait rêver!!! Tout ce qui reste à découvrir... Tout ce potentiel humain... Tous ces rêves possibles... Vivement l'an prochain! Mars express revu pour la 2e fois, j'y ai compris encore d enouvelles choses, ce film est absolument génial avec une double fin. --- Une réaction? Envoyez votre commentaire par mail : => mailto:prx@si3t.ch?subject=notes-utopiales-2024 ]]> De retour après les Utopiales https://si3t.ch/log/2024-11-13-de-retour-utopiales.txt 2024-11-13T14:12:11Z https://www.utopiales.org/ Utopiales ## Panne réparée En fait, SFR, qui gère les lignes, a changé l'armoire. Ils ont débranché tout le monde, sans prévenir personne. Les enfoirés. Je suis client chez Free, j'ai donc du attendre qu'un technicien vienne me rebrancher :s C'est donc enfin résolu après 2 longues semaines! Ce qui m'aura le + manqué? * Mes sauvegardes, c'est toujours un peu stressant de ne pas pouvoir avoir une copie de mes cours * Mon compte XMPP pour échanger avec ma famille. * Mes mails * Publier des notes C'est pénible, mais ce n'est pas si grave, et ça fait partie du "jeu" de l'auto-hébergement. Heureusement, Vinishor m'accorde gentiement un backup mail pour récupérer mes messages. Ma VM chez openbsd.amsterdam fait de même. => https://vinishor.xyz/fr/ vinishor => https://openbsd.amsterdam/ Normalement, je devrai recevoir les mails qui m'ont été envoyés prochainement. J'espère vraiment ne pas en avoir perdu. Sinon, je devrai me résoudre, je préfère ça que de vendre mes données à un autre fournisseur. Ce qui m'inquiète, c'est que le roulement des signatures DNS avait lieu à cette période, du coup ça a mis le bazar puisque tous les serveurs autoritaires n'ont pas reçu les zones avec les nouvelles signatures en même temps. ## Les Utopiales J'ai plein de trucs à raconter sur les Utopiales. J'en ferai un article plus tard je pense, le temps de mettre de l'ordre dans mes notes manuscrites :) --- Une réaction? Envoyez votre commentaire par mail : => mailto:prx@si3t.ch?subject=de-retour-utopiales ]]> How to play Dwarf Fortress on OpenBSD? https://si3t.ch/log/2024-09-18-how-to-play-dwarffortress-on-openbsd.txt 2024-09-18T15:48:00Z https://www.bay12games.com/dwarves/features.html Well, you already knew this ;) ## How to install Debian in vmd? Since that's what I know the best, I choosed to run Debian with vmd. => https://www.debian.org/ ``` sysctl net.inet.ip.forwarding=1 rcctl enable vmd rcctl start vmd vmctl create -s 20G debian.qcow2 vmctl start -c -m 1G -L -i 1 -r debian.iso -d debian.qcow2 debian ``` Before loading the installer, you must setup a few things to get the console. Press TAB, then enter: ``` /install.amd/vmlinuz vga=off initrd=/install.amd/initrd.gz --- quiet console=ttyS0,115200n8 ``` A few things may be set in your /etc/pf.conf. Here is mine, it use my local unwind for DNS resolution: ``` set skip on lo antispoof for egress block ### Required to install debian with network access pass on tap0 match out on egress from tap0:network to any nat-to (egress) pass in proto { tcp udp } from tap0:network to any port domain \ rdr-to localhost port domain ### pass in proto icmp pass in proto icmp6 pass out ``` ## How to install Dwarf Fortress? On your debian fresh, install, add a few things: ``` apt install libsdl2-2.0-0 libsdl2-image-2.0-0 libsdl2-ttf-2.0-0 libgtk2.0-0 libopenal1 libsndfile1 libncursesw5 apt install xserver-xorg apt install openssh-server ``` Now you may log on your VM using ssh : ``` ssh dwarf@100.64.1.3 ``` Check your ip with "ip a" on the console if necessary. Then, get dwarf fortress: ``` wget https://www.bay12games.com/dwarves/df_50_13_linux.tar.bz2 tar xjvf df*.tar.bz2 ``` ## Run Dwarf Fortress Use ssh "-Y" flag: ``` ssh -Y dwarf@100.64.1.3 "./run_df" ``` I won't lie, it's kinda slow. But it works \o/. => https://0x0.st/X3_l.png ## Conclusion Actually Dwarf Fortress isn't really running on OpenBSD, but I find this trick handy if one day I miss a software only running on Linux. --- Comments? => mailto:prx@si3t.ch?subject=how-to-play-dwarffortress-on-openbsd ]]> Message to the void https://si3t.ch/log/2024-09-17-message-to-the-void.txt 2024-09-17T08:35:34Z https://void.si3t.ch => gemini://void.si3t.ch Il n'y a pas gopher, geomyidae ne supporte pas les vhosts. L'idée est d'offrir un espace où chacun peut s'exprimer de façon anonyme. Un peu comme lancer une bouteille à la mer. La publication se fait en écrivant à une adresse mail dédiée. Ça me permet de ne pas avoir à me soucier d'un captcha. Mon antispam fera bien les choses, en tout cas mieux que ce que je pourrais coder. Comme on me l'a fait remarqué, c'est un peu comme un pastebin par mail. => https://codemadness.org/mailservice.html Ce n'est pas tout à fait vrai : j'y vois plutôt un espace d'échange à la midnight.pub mais anonyme. Je l'espère bienveillant et salutaire pour ceux qui en ont gros sur le coeur. Si on veut lire les messages comme s'il s'agissait d'un journal, j'ai prévu un flux ATOM. On peut s'y abonner ou le consulter directement dans le navigateur. Vous l'aurez remarqué, c'est très minimaliste. Il faudrait peut-être améliorer le atom.xsl pour une apparence plus agréable dans le navigateur. ## Comment ça marche? C'est tout simple, je me suis servi de ce qui existe déjà, à savoir un fichier ".forward" et d'un script à base de mblaze pour extraire le corps des messages et les mettre dans un dossier après leur avoir donné un nom unique. J'ai hésité à mettre le sujet comme titre dans les liens vers les messages, mais finalement, je préfère laisser chacun choisir de préciser ou non un sujet. Une tâche cron vérifie régulièrement si de nouveaux messages sont présents et régénère les pages html, gmi et le flux atom. Si vous êtes curieux, voici le dépôt: => https://git.sr.ht/~prx/m2void --- Une réaction? Envoyez votre commentaire par mail : => mailto:prx@si3t.ch?subject=message-to-the-void ]]> Encrypt all incoming emails with gpg https://si3t.ch/log/2024-09-15-Encrypt-all-incoming-emails-with-gpg.txt 2024-09-15T14:40:43Z /code/encrypt-all-incoming-mails/ If for some reasons you don't want to keep your emails unencrypted on your server => https://dataswamp.org/~solene/2024-09-12-email-selfhost-to-protonmail.html You may encrypt all of them as long as your public key is available: => https://dataswamp.org/~solene/2024-08-14-automatic-emails-gpg-encryption-at-rest.html As far as I'm concerned, I don't keep my emails on my server, I mainly use one computer, so I download (rsync) my Maildir and run mutt on it. So I wrote a little script to encrypt all my incoming emails without requiring dovecot. However, the whole email is encrypted, headers are unreadable. That's fine, mutt know how to open them, they're just not sorted. Actually, I decrypt them after downloading the messages and before opening mutt. First, set up a .forward file on your server home: ``` echo "|/usr/local/bin/encrypt-mail.sh -r you@domain.tld" > ~/.forward chmod 600 ~/.forward ``` The encrypt-mail.sh file is: ``` #!/bin/sh # encrypt incoming mail # # "Initial setup:\n" # "echo "|/usr/local/bin/encrypt-mail.sh -r you@domain.tld" > ~/.forward\n" # "chmod 600 ~/.forward\n" usage() { printf "usage: $0 [-r email@domain.tld] [-h]\n" printf " -h: show this help\n" printf " -r: set recipient email, default to user@hostname\n" printf "---\n" exit 1 } # default user email recipient="$(whoami)@$(hostname)" while getopts 'r:h' c do case $c in h) usage ;; r) recipient="${OPTARG}" ;; esac done # check if Maildir/new is here d="$HOME/Maildir/new" test ! -d "${d}" && mkdir -p "${d}" # create a path to a new email # format: # gettimeofday().uniqu-id.gethostname() timeofday="$(date +%s)" uniq_id="$$" myhostname="$(hostname | sed -e 's;/;\\057;' -e 's;:;\\072;g')" new_mail_filename="$HOME/Maildir/new/${timeofday}.${uniq_id}.${myhostname}" # encrypt gpg --output "${new_mail_filename}" --encrypt --armor --recipient "${recipient}" ``` One may want a better setup to keep different IMAP clients synchronised. Someone told me Solène had a better idea 👼. --- Comments? => mailto:prx@si3t.ch?subject=Encrypt-all-incoming-emails-with-gpg Instructions: ]]> Les premières choses à faire sur un serveur OpenBSD https://si3t.ch/log/2024-09-12-premieres-choses-a-faire-serveur-openbsd.txt 2024-09-12T09:23:06Z persist table persist table persist file "/var/prx-brutes.txt" table persist file "/var/pf-badhost.txt" set skip on { lo } set limit table-entries 409600 antispoof for $ifaces block block quick from label "BRUTES" block quick from label "SSHGUARD" block quick from label "PRX" block quick from label "PFBADHOST" # allow ping pass on $ifaces inet6 proto ipv6-icmp all #icmp6-type echoreq pass on $ifaces inet proto icmp all # icmp-type echoreq pass in on $ifaces proto tcp to port ssh modulate state \ (source-track rule, \ max-src-conn 8, max-src-conn-rate 15/5, \ overload flush global) #pass in on $ifaces proto tcp to port $tcp_pass modulate state #pass in on $ifaces proto udp to port $udp_pass pass out on $ifaces proto { tcp udp } ``` Bien sûr, on recharge pf: ``` # pfctl -f /etc/pf.conf ``` Maintenant, on prévoit la mise à jour des listes noires chaque jour: ``` # /etc/daily.local ftp -o- https://si3t.ch/pub/evils/prx-brutes.txt.gz | \ gzcat > /var/prx-brutes.txt && \ pfctl -t prx -T replace -f /var/prx-brutes.txt ftp -o- https://si3t.ch/pub/evils/pf-badhost.txt.gz | \ gzcat > /var/pf-badhost.txt && \ pfctl -t pf-badhost -T replace -f /var/pf-badhost.txt ``` Pour aller plus loin avec le parefeu, j'installe aussi iblock avec une version modifiée pour ne pas avoir besoin d'inetd : => https://tildegit.org/prx/iblock/src/branch/icanserve --- Une réaction? Envoyez votre commentaire par mail : => mailto:prx@si3t.ch?subject=premieres-choses-a-faire-serveur-openbsd ]]> First things to do after installing OpenBSD on a server https://si3t.ch/log/2024-09-12-first-things-to-do-on-openbsd-server.txt 2024-09-12T09:37:08Z > /etc/doas.conf permit persist user EOF ``` Change root password with random chars produced by jot: ``` # su - # jot -rcs '' $l 32 126 # passwd ``` ## aliases J'ajoute mon mail dans /etc/mail/aliases Add yourself to root alias, then run "newaliases": ``` /etc/mail/aliases: root: me@stuff.tld ``` ## SSH ``` # /etc/ssh/sshd_config PermitRootLogin no ``` Install sshguard ``` # pkg_add sshguard # rcctl enable sshguard # rcctl start sshguard ``` ## pf.conf * will use sshguard * reduce bruteforce on ssh * Use blacklists from https://si3t.ch/evils/ * prepare future work with lines to edit/uncomment ``` touch /var/prx-brutes.txt touch /var/pf-badhost.txt ``` ``` #/etc/pf.conf ifaces = "{ egress }" # maybe useful later #tcp_pass = "{ www https }" # change me #udp_pass = "{ domain }" # change me table persist table persist table persist file "/var/prx-brutes.txt" table persist file "/var/pf-badhost.txt" set skip on { lo } set limit table-entries 409600 antispoof for $ifaces block block quick from label "BRUTES" block quick from label "SSHGUARD" block quick from label "PRX" block quick from label "PFBADHOST" # allow ping pass on $ifaces inet6 proto ipv6-icmp all #icmp6-type echoreq pass on $ifaces inet proto icmp all # icmp-type echoreq pass in on $ifaces proto tcp to port ssh modulate state \ (source-track rule, \ max-src-conn 8, max-src-conn-rate 15/5, \ overload flush global) #pass in on $ifaces proto tcp to port $tcp_pass modulate state #pass in on $ifaces proto udp to port $udp_pass pass out on $ifaces proto { tcp udp } ``` Reload pf: ``` # pfctl -f /etc/pf.conf ``` Prepare blacklist updates: ``` # /etc/daily.local ftp -o- https://si3t.ch/pub/evils/prx-brutes.txt.gz | \ gzcat > /var/prx-brutes.txt && \ pfctl -t prx -T replace -f /var/prx-brutes.txt ftp -o- https://si3t.ch/pub/evils/pf-badhost.txt.gz | \ gzcat > /var/pf-badhost.txt && \ pfctl -t pf-badhost -T replace -f /var/pf-badhost.txt ``` To go further, I also install iblock with a modified version not requiring inetd: => https://tildegit.org/prx/iblock/src/branch/icanserve --- Comments? => mailto:prx@si3t.ch?subject=first-things-to-do-on-openbsd-server How to: ]]> Introduire les thèmes de physique-chimie avec des films https://si3t.ch/log/2024-08-20-Introduction-themes-physique-chimie-films.txt 2024-08-20T20:46:34Z https://www.utopiales.org/ Utopiales 4 thèmes principaux sont à couvrir: * La matière (chimie) * Les mouvements * Les signaux * L'énergie. Pour ce dernier, une grosse partie porte sur l'électricité. ## La matière (chimie) Pour introduire la notion d'acide quoi de mieux que le "sang" qui s'achappe de l'Alien lorsque le facehugger est étudié ? => https://0x0.st/XJgL.mkv En alternative, la bande annonce du film plus récent ACIDE permet de présenter cette notion. En plus, c'est un film français qui m'a très agréablement surpris: => https://0x0.st/XJg_.mkv Comme vous le voyez, il me manque des choses pour la chimie. Ça ne se limite pas à l'acide... J'ai bien pensé à Breaking Bad, mais aucun extrait concernant la chimie en particulier ne me vient à l'esprit. Et je m'adresse à des collégiens, donc attention au message passé, même si J'ADORE Breaking Bad. ## Les mouvements Pour les mouvements et tout particulièrement la notion de point de vue et relativité, les exemples ne manquent pas. On dispose de 2 scènes qui se déroulent dans l'espace : un vaisseau en aborde un autre. Le premier est calme et reposant, c'est dans 2011 l'odyssée de l'espace. => https://0x0.st/XJgp.webm Le second me fascine davantage, mais c'est sans aucun doute lié à l'excellent bande son. Je parle bien sûr d'Interstellar: => https://0x0.st/XJgW.webm Ensuite, on peut illustrer la seconde loi de Newton, le principe d'action/réaction avec Wall-e qui vide son extincteur: => https://0x0.st/XJg4.mkv Ça m'amuse de remarquer qu'on retrouve exactement le même principe dans Gravity: => https://0x0.st/XJgy.mkv Finalement, on retrouve une belle fusion des précedents thèmes avec Seul sur Mars : la relativité de mouvement et la 2e loi de Newton dans une scène où Matt Damon m'émeut à coup sûr. => https://0x0.st/XJgx.mkv ## Les signaux On commence doucement avec Premier Contact, si on veut parler d'anthropomorphisme et pourquoi pas de la plaque dans la sonde Pioneer: => https://0x0.st/XJgY.mkv Mais pour vraiment s'éclater, Contact en 2 parties permet d'aborder la notion de fréquence, de ce qui est signe d'intelligence, et travailler sur les stéréotypes portés par les acteurs de l'époque. Une femme ne peut pas être intelligente ET canon, donc on lui met de slunettes et on lui attache les cheveux :) => https://0x0.st/XJg6.webm => https://0x0.st/XJgI.webm ## L'énergie Bien évidemment, Matrix propose une présentation de source d'énergie un peu dérangeante : les humains commes des piles. C'est à mon avis un rare exemple de forme d'énergie chimique ^^ => https://0x0.st/XJgR.mkv Plus "tout publics", on a retour vers le futur avec un réacteur à base de plutonium : => https://0x0.st/XJgk.mkv Et puis finalement, un excellent recycleur de peaux de bananes: => https://0x0.st/XJgU.mkv ## À vous! J'imagine que je n'ai pas pensé à toutes les possibilités. N'hésitez pas à me faire part de vos suggestions ;) ps : merci JB pour toutes les bonnes idées ;) ## Les extraits? Si les extraits ne sont plus disponibles via les liens ci-dessus, demandez-moi par mail ;) --- Une réaction? Envoyez votre commentaire par mail : => mailto:prx@si3t.ch?subject=Introduction-themes-physique-chimie-films ]]> fuzzy find in your terminal history https://si3t.ch/log/2024-08-13-fuzzy-find-terminal-history.txt 2024-08-13T11:55:44Z https://pedantic.software/git/choice => https://github.com/jhawthorn/fzy => https://github.com/junegunn/fzf Now I wrote this, I can read in the pick manpage this : ``` Select a command from the history to execute: $ eval $(fc -ln 1 | pick) ``` Seems like I should have read it before :) So, now, it's : alias hf='eval $(fc -ln 1 | pick)' --- Comment? => mailto:prx@si3t.ch?subject=fuzzy-find-terminal-history See instructions: ]]> L'arrivée des capybaras https://si3t.ch/log/2024-08-05-arrivee-capybaras.txt 2024-08-05T07:10:33Z https://www.babelio.com/livres/Soderguit-Larrivee-des-capybaras/1216367 Sur le modèle du prix des incorruptibles, nous nous sommes amusés à emprunter des livres à la médiathèque. Chaque membre de la famille devait en choisir 2. Tous les jours, nous avons lu un livre ensemble, pour finalement "voter" : on a posé des jetons sur les livres que nous avions préférés. Le livre avec le plus de jetons sera acheté. Bref, j'ai eu un gros coup de coeur pour "L'arrivée des capybaras". L'histoire est simple. Nous voyons un poulailler, les poules décrivent leur vie paisible et bien rangée. Le dessin est sombre, et on distingue clairement que les hommes mangent les poules et leurs oeufs, les grillages sont partout. Un jour, des capybaras arrivent au poulailler. Ils ne sont pas pareils, ils vont prendre notre nourriture et notre espace de vie. Ils mangeront donc à part, et resteront à l'écart. Interdiction pour les jeunes poussins de jouer avec les jeunes capybaras. Et là, fierté du papa que je suis, mon fils s'est vite exclamé : > Mais c'est pas juste, la terre elle est pour tout le monde! On y découvre ensuite, à l'arrivée de vilains chasseurs, une belle leçon d'humanité, et une fin ouverte comme je les aime. N'hésitez pas à y jeter un oeil! --- Une réaction? Envoyez votre commentaire par mail : => mailto:prx@si3t.ch?subject=arrivée-capybaras ]]> Pour les racistes https://si3t.ch/log/2024-06-30-pour-les-racistes.txt 2024-06-30T13:29:54Z Dis papa, tu vas choisir celui-là? > Tu sais, les gens ne disent pas trop pour qui ils votent. Il insiste en pointant le numéro d'à côté : > Tu vas voter pour lui? > Ah non mon chéri, celui-là, c'est pour les racistes. 👼 --- Une réaction? Envoyez votre commentaire par mail : => mailto:prx@si3t.ch?subject=pour-les-racistes ]]> Les rues sont vides https://si3t.ch/log/2024-06-10-les-rues-sont-vides.txt 2024-06-10T08:45:11Z https://www.lemonde.fr/les-decodeurs/article/2022/04/20/quels-sont-les-liens-de-marine-le-pen-avec-la-russie-de-vladimir-poutine_6122903_4355770.html "Jamais plus de 20%"... => https://invidious.fdn.fr/watch?v=CuZB9hOQ0DQ Pourtant, les rues sont vides. Bande d'hypocrites. --- Une réaction? Envoyez votre commentaire par mail : => mailto:prx@si3t.ch?subject=les-rues-sont-vides ]]> fossil is great to self-host https://si3t.ch/log/2024-05-13-fossil-great-self-host.txt 2024-05-13T12:51:38Z https://fossil-scm.org/ It is solene, you probably already know her, who proposed to use it to host a forum for a french community about OpenBSD. => https://dataswamp.org/~solene/ => https://fr.forum.puffy.cafe/wiki?name=Index Indeed, fossil is well known as an alternative to git or hg. And a good one if you ever tried. You can host your projects and publish source code quite easily. But it's more than that. It offers: * a forum engine * a wiki engine, and btw a sort-of website content manager * a real-time chat All this while staying very light and thus, self-hosting friendly. It even serve gzipped content by default! Backups are easy, just lcone the repository or copy/rsync/scp/whatever the ".fossil" file. Upgrades are painless, just upgrade the binary. There are already good instructions to set it up: => https://fossil-scm.org/home/doc/trunk/www/server/openbsd/fastcgi.md As you could read, fossil is very selfhosting friendly. I found quite clever the use of a template to fill the mfs. One may add a new "/etc/newsyslog.conf" entry to avoid evergrowing error log file. ``` /var/www/logs/fossil.log 644 5 300 * Z ``` I wonder if it is worth adding a part about fossil on https://si3t.ch/ah/en/09-services/ ? What do you think about fossil? ]]> Garder les modules prosody à jour https://si3t.ch/log/2024-05-07-xmpp-prosody-up-to-date-modules.txt 2024-05-07T09:07:56Z https://prosody.im/doc/installing_modules --- Une réaction? Envoyez votre commentaire par mail : => mailto:prx@si3t.ch?subject=xmpp-prosody-up-to-date-modules ]]> Mon fils m'a envoyé un courrier https://si3t.ch/log/2024-03-24-mon-fils-m-a-envoye-un-courrier.txt 2024-03-24T15:11:31Z mailto:prx@si3t.ch?subject=mon-fils-m-a-envoye-un-courrier ]]> sloweb partie 3 : lecture https://si3t.ch/log/2024-03-21-sloweb-part-3-whatsinthebox.txt 2024-03-21T12:32:06Z " read ans case "${ans}" in k|K) printf "Keep ${f}\n" ;; e|E) exit ;; *) #d|D|n|N) printf "Delete ${f}, next!\n" rm -f "${f}" rm -rf "${f}-data" ;; esac done IFS=$OLDIFS ``` On voit qu'il appelle "SLOWEB_OPENER" pour ouvrir un fichier. Par défaut, il s'agit d'olab, un autre script à modifier qui effectue une action selon l'extension du fichier. Par défaut, il appelle xdg-open: ``` #!/bin/sh # olab : open like a boss # Usage: # ./olab.sh /path/to/file # get extension + lower extension ext="$(echo .${1#*.} | tr '[:upper:]' '[:lower:]')" case "${ext}" in *.htm|*.html|*.xhtml) #fmt="w3m %s" fmt="surf %s" ;; *.pdf|*.xps|*.cbz|*.epub) fmt="mupdf %s" ;; *.jpg|*.jpeg|*.png|*.gif|*.tiff|*.svg) fmt="nsxiv %s" ;; *.odt|*.odt|*.ods|*.od*|*.docx|*.doc|*.xls|*.xlsx|*.ppt*) fmt="libreoffice %s" ;; *.mp4|*.avi|*.mpg|*.ogv|*.webm|*.mkv) fmt="mpv %s" ;; *.ogg|*.flac|*.wav|*.mp3|*.opus) fmt="mpv %s" ;; *.[1-9]) fmt="man -l %s" ;; *.c|*.h|*.sh|*.lua|*.py|*.ml|*[Mm]akefile|*.md|*.tex) fmt="st -e $EDITOR %s" ;; *.txt|*.gmi|*.gemtext) which bat && fmt="bat %s" || fmt="less %s" ;; *) fmt="xdg-open %s" ;; esac printf "$fmt" "\"$1\"" | ${SHELL:-"/bin/sh"} exit ``` En passant, on remarquera que pour les fichiers gmi, la coloration est obtenue avec "bat" s'il est présent. À l'usage, je me dis qu'utiliser un navigateur de fichier comme noice serait tout aussi pratique, mais retire la possibilité de supprimer par défaut. => https://git.2f30.org/noice/log.html --- Une réaction? => mailto:prx@si3t.ch?subject=sloweb-part-3-whatsinthebox ]]> sloweb partie 2 : les flux https://si3t.ch/log/2024-03-14-sloweb-part-2-feeds.txt 2024-03-14T12:29:58Z https://github.com/rss2email/rss2email Cependant, je lui ai trouvé 2 défauts: * La gestion des abonnements est un peu pénible, surtout si je charge mon serveur de faire tourner rss2email. * Les articles étant des mails, je suis trop tenté d'ouvrir mon application de messagerie pour vérifier s'il y a de nouveaux articles. C'est de ma faute, mais je retombe dans les travers du "plus, encore, maintenant!". À la place, je lui préfère sfeed et son interface éventuelle qui rappelle newsboat: => https://codemadness.org/sfeed.html => https://codemadness.org/sfeed_curses-ui.html sfeed est justement très modulaire, et s'entoure de plusieurs petits outils faciles à articuler entre eux. On peut d'ailleurs très bien faire de sfeed un équivalent de rss2email si on le souhaite, tout est expliqué dans le readme. Sur mon ordinateur, sfeed m'apporte les avantages suivants : * Récupération des flux avec curl, ou une autre commande. Ça supporte ainsi aussi le protocole gopher, donc les phlogs. Il ne devrait pas être trop difficile d'y ajouter les gemlogs, mais j'ai écrit un script dédié pour ça. * Il garde en mémoire les articles déjà lus dans sfeed-curses. On peu les lire ou ouvrir dans le navigateur. Le lien de l'article est affiché, je peux l'utiliser pour l'envoyer à d'autres outils (voir Exemple). * Il permet de filtrer les flux et d'effectuer des remplacements du type youtube > invidious, ou encore retirer des liens publicitaires... On peut même choisir de télécharger les vidéos des abonnements youtubes avec yt-dlp. * La mutliplicité des outils pour lire me plaît : dmenu, mail, texte, ... Il reste limité à un affichage en mode texte, parfois gênant pour des articles contenant des images (xkcd, APOD) que j'aimerais pouvoir voir même hors-ligne. Pour cela, le script sloweb_forlater est là. ## Un exemple avec APOD Si vous ne connaissez pas, sachez que la NASA publie chaque jour une photo d'astronomie avec des commentaires d'astronomes profesionnels. => https://apod.nasa.gov/apod/ Ça n'a d'intérêt que si on a l'image sous la main. Lorsqu'une nouvelle entrée apparaît dans le flux, je passe l'URL à forlater: ``` forlater https://apod.nasa.gov/apod/ap240314.html ``` Ce script est très court. Il va faire en sorte que la commande sloweb_forlater soit exécutée la prochaine fois que sloweb tourne, avec l'aide de sloweb_cmd déjà présenté dans l'article précédent. ``` sloweb_cmd "cd \"${SLOWEB_BOX}\"; sloweb_forlater \"$1\"" ``` La commande sloweb_forlater sera alors exécutée dans le dossier ~/sloweb/box pour enregistrer la page apod ainsi que l'image. ## sloweb_forlater sloweb_forlater est un des outils dont je suis le plus content car il permet d'avoir une version locale d'une page web/gemini/gopher. Dans le cas d'une page web, je sais que wget sait déjà aspirer un site. Cependant, les liens vers le ressources ne sont pas réécris. Autement dit, si la page appelle un script vers googleapis, ou encore si elle demande le chargement d'une image avec un lien du type "https://bla/blop/blup.jpg", alors impossible de charger l'image si on est hors-ligne. sloweb_forlater se charge donc de réécrire les liens vers les images. Ces liens sont des liens locaux du type "./chemin_vers_limage.jpg". Pour télécharger les ressources, je vais appel à "sloweb_anyget", qui n'est qu'un "wrapper" afin d'appeler la bonne commande de téléchargement selon si le protocole esthttp, gopher ou gemini. À la même occasion, si le lien est une vidéo youtube, alors yt-dlp va la télécharger. Ainsi, je peux lire les pages et médias gardés dans la "box" sans avoir besoin d'un accès à internet. Cela fera appel au script sloweb_whatsinthebox, mais c'est pour un futur article ;) --- Une réaction? => mailto:prx@si3t.ch?subject=sloweb-part-2-feeds ]]> sloweb partie 1 : run_cmds https://si3t.ch/log/2024-03-13-sloweb-part-1-run-cmds.txt 2024-03-13T13:42:23Z https://git.sr.ht/~prx/sloweb ## sloweb_online Tout d'abord, sloweb vérifie que l'on a bien un accès en ligne, et appelle pour cela le script sloweb_online. Si tout va bien, ce dernier retourne 0, sinon il retourne une erreur. On peut lire au tout début de ce script quelques lignes communes à tous les scripts sloweb_*. Cela concerne la configuration : ``` # configuration # if SLOWEB_DIR not set as ENV VARS, set default test -z "${SLOWEB_DIR}" && SLOWEB_DIR=~/sloweb config="${SLOWEB_DIR}/slowebrc" if [ ! -f "${config}" ]; then printf "%s" "Configuration not found, copy slowebrc.example to ${config}" exit 1 fi # import config . "${config}" ``` On peut voir qu'à moins qu'une variable d'environnement soit déjà définie, on va aller chercher le fichier ~/sloweb/slowebrc comme configuration. Utiliser une variable d'environnement facilite la possibilité de changer la structure des répertoires utilisés par sloweb sans se prendre la tête. Dans le fichier ~/.profile, on pourra écrire: ``` export SLOWEB_DIR=/var/sloweb/or/else ``` On retiendra donc que par défaut, la configuration de sloweb a lieu dans ~/sloweb/slowebrc. Un exemple est fourni, il est commenté pour expliquer à quoi servent chaque partie. On trouve notamment dans ce fichier la partie relative à sloweb_online: ``` # sloweb_online # connectivity check, multiple domains in case one of them is down SLOWEB_ONLINE_DOMAINS="openbsd.org wikipedia.org www.nasa.gov" SLOWEB_ONLINE_PORT=443 ``` Voici une liste de domaines qu'on va chercher à atteindre via le port 443. Si le premier échoue, alors on essaie le suivant : après tout, un site peut bien être en panne alors que vous êtes pourtant connecté. Dès qu'un accès a réussi, alors sloweb_s'arrête et retourne 0. Ça tient finalement en quelques lignes: ``` # check if currently connected connected=0 for d in ${SLOWEB_ONLINE_DOMAINS}; do # uncomment to use ping instead of netcat # ping -c1 -w2 "$d" >/dev/null 2>&1 nc -zw1 "${d}" $SLOWEB_ONLINE_PORT >/dev/null 2>&1 if [ $? -eq 0 ]; then connected=1 break fi done if [ $connected -eq 0 ]; then _err "It seems you cannot reach the Internet" exit 1 fi exit 0 ``` Vous aurez noté l'utilisation de netcat. Il est présent par défaut sous OpenBSD. Certains préféreront décommenter l'appel à "ping" à la place. J'ai cependant lu à ce propos que certains fournisseurs bloquent le ping, pas tant le serveur que le point d'accès : pensez WiFi public, ce qui donnerait l'impression d'être hors ligne, alors que le port 443 protocole TCP utilisé pour les "accès https" est bien ouvert. J'avoue, je n'ai pas trop d'avis là-dessus, je n'ai jamais été confronté à ça. Pour finir, vous aurez remarqué la fonction "_err", qu'on retrouvera dans d'autres scripts. J'aurais pu l'écrire dans le fichier de configuration, mais je craignais de rentre les choses trop confuses en mélangeant fonctions et configuration. ## sloweb_run_cmds le script sloweb_run_cmds va exécuter toutes les commandes présentes dans des fichiers, eux-même stockés dans le dossier SLOWEB_CMDS (~/sloweb/cmds par défaut). ``` find "${SLOWEB_CMDS}" -type f | while read -r cmd; do ${SHELL:-"/bin/sh"} -e "${cmd}" if [ $? -ne 0 ]; then _err "'$(cat ${cmd})' in ${cmd} failed" else _log "'$(cat ${cmd})' successfully executed" rm -f "${cmd}" fi done ``` "find" permet de lister tous les fichiers du dossier cité ci-dessus puis d'en exécuter le contenu comme un script. On passe ce fichier au shell par défaut et on informe l'utilisateur si tout s'est bien déroulé. Dans ce cas, on supprime le fichier. On laisse le fichier présent pour que l'utilisateur puisse éventuellement corriger la commande. On pourrait laisser l'utilisateur créer des fichiers dans ce dossier, mais autant l'aider avec un script qui va créer des fichiers uniques pour les commandes qu'il voudra exécuter lors de son retour en ligne. C'est ce que fait sloweb_cmd. ## sloweb_cmd Ce script se charge de créer un fichier dont le nom est unique pour ne pas écraser un éventuel fichie déjà existant. Pour cela, la commande "mktemp" est parfaite. ``` # use mktemp for unique file, and a timestamp to keep order cmd_file=$(mktemp "${SLOWEB_DIR}/cmds/$(date +%s).XXXXXXXX") printf "%s\n" "$*" >> "${cmd_file}" ``` Le "printf" permet de conserver tous les caractères qui seraient sinon interprétés. ## Le mot de la fin J'ai commencé par une partie un peu technique de sloweb. Le prochain coup, je présenterai la partie sur les abonnements aux flux RSS/ATOM, qui utilise des outils déjà existants. --- Une réaction? => mailto:prx@si3t.ch?subject=sloweb-part-1-run-cmds ]]> sloweb -- Le web sans s'essouffler https://si3t.ch/log/2024-03-12-sloweb-le-web-sans-s-essoufler.txt 2024-03-12T20:47:27Z gemini://ploum.net/3-janvier-2022-quest-ce-quune-deconnexion/ => https://ploum.net/3-janvier-2022-quest-ce-quune-deconnexion/index.html J'ai suivi son exemple et écrit un "do-the-internet.sh" à ma sauce. Le résultat, c'est "sloweb" : on prend le temps de respirer, on y va doucement. Avant qu'il ne m'écrive agacé par mes divagations, notez que la plupart des choses que fait sloweb se retrouvent aussi dans offpunk de ploum: => https://sr.ht/~lioploum/offpunk/ Cependant, j'avais besoin de m'approprier la démarche, de me faire mon petit outil afin de bien cerner mes besoins, mais aussi mes défauts dans mon utilisation d'internet. Voilà quelques semaines que je l'utilise, je peux désormais détailler ses différents aspects dans une série de petits articles. En effet, sloweb ne se limite pas à la navigation, mais va intervenir dans de nombreux aspects de mes accès en ligne. Pour les plus pressés et plus curieux, voici le code source : sloweb: tools to stay offline/offtime => https://sr.ht/~prx/sloweb/ ## À l'allumage de mon ordinateur Lorsque ma session s'ouvre, sloweb se charge de : * Récupérer les nouveaux articles des flux RSS/ATOM auxquels je suis abonnés. * Télécharger les nouveaux articles des capsules gemini (gemlogs) suivis. * Télécharger mes mails * Vérifier et récupérer les changements éventuels de sites qui n'auraient pas de flux. * Enregistrer dans un fichier ma timeline mastodon. * Afficher le nombre de nouveaux mails et la météo à venir. ## Lorsque je ferme ma session/éteins mon ordinateur Dans ce cas, sloweb se charge "d'envoyer" mon activité en ligne, c'est à dire: * Envoyer les mails rédigés, en attente * Exécuter une liste de commandes. Ces derniers peuvent être l'envoi de status mastodon, des réponses à des posts, booster un message, télécharger une page web et les médias associés pour lecture ultérieure, ... * Sauvegarder mes documents * Uploader mon site web/capsule/gopherhole ## Entre les deux sloweb me permet de garder en stock les commandes qui seraient à exécuter lors de mon retour en ligne. Quelques scripts sont alors utile pour prévoir le téléchargement d'une vidéo youtube ou bien une page web avec ses images. D'autres se chargent de garder les toots/twtxt à envoyer. Enfin, un autre script me permet de lire les documents gardés dans la bibliothèque. Tous les trucs "à lire + tard" : flux rss, vidéos récupérés, ... ## Pour finir J'ai pour l'instant l'impression que ça fonctionne. Je prends plus le temps de lire, je découvre de nouvelles choses. Je redécouvre aussi les petits bonheurs simples : discuter avec mon entourage, profiter du spectacle à ma fenêtre, ou simplement m'asseoir et profiter du temps qui coule. --- Une réaction? => mailto:prx@si3t.ch?subject=sloweb-le-web-sans-s-essoufler ]]> Dune partie 2, le garçon pas content qui voulait se venger https://si3t.ch/log/2024-03-01-dune-partie-2.txt 2024-03-01T09:06:46Z Aucun titre pour moi, dit Chani. Rien. Je vous en supplie. Paul rencontra son regard et il la revit soudain avec le petit Leto dans ses bras, leur fils qui avait trouvé la mort dans toute cette violence. > Je te jure, dit-il, que tu n'as besoin d'aucun titre. Cette femme, là-bas, sera mon épouse et tu ne seras qu'une concubine parce que ceci est une affaire politique et que nous devons conclure la paix et rallier les Grandes Maisons du Landsraad. Il faut obéir aux usages. Mais cette princesse n'aura de moi que mon nom. Elle n'aura nul enfant, nul geste, nul regard, nul instant de désir. --- Une réaction? => mailto:prx@si3t.ch?subject=dune-partie-2 ]]> uptm: just show system uptime https://si3t.ch/log/2024-02-10-uptm-only-show-system-uptime.txt 2024-02-10T14:32:16Z #include #define SECSPERHOUR (60 * 60) #define SECSPERDAY (24 * 60 * 60) int main(void) { struct timespec boottime; time_t uptime, now; int days, hrs, mins; time(&now); /* * Print how long system has been up. */ if (clock_gettime(CLOCK_BOOTTIME, &boottime) != -1) { uptime = boottime.tv_sec; if (uptime > 59) { uptime += 30; days = uptime / SECSPERDAY; uptime %= SECSPERDAY; hrs = uptime / SECSPERHOUR; uptime %= SECSPERHOUR; mins = uptime / 60; if (days > 0) (void)printf("%d day%s", days, days > 1 ? "s" : ""); if (hrs > 0 && mins > 0) (void)printf("%2d:%02d", hrs, mins); else { if (hrs > 0) (void)printf("%d hr%s", hrs, hrs > 1 ? "s" : ""); if (mins > 0 || (days == 0 && hrs == 0)) (void)printf("%d min%s", mins, mins != 1 ? "s" : ""); } } else printf("%d secs", (int)uptime); } return 0; } ``` --- Comments? => mailto:prx@si3t.ch?subject=uptm-only-show-system-uptime ]]> miroirs https://si3t.ch/log/2024-02-07-miroirs.txt 2024-02-07T21:24:39Z https://srht.site/ J'ai ensuite tenté un accès chez sdf.org. C'est excellent ce truc, mais pas possible d'utiliser rsync avec mon compte. De plus, il n'est pas possible d'avoir du https. Ça fonctionne, je le garde sous le coude, puisque je peux toujours mettre à jour à partir du dépôt git. => https://sdf.org Finalement, j'ai configuré un truc un peu plus propre avec ma VM chez openbsd.amsterdam. => https://openbsd.amsterdam/ J'ai édité ma zone DNS pour y ajouter un nouveau champ et j'ai configuré acme-client pour activer le https. J'uploade les changements via rsync, et je me garde une crontab qui met à jour le dépôt git sous le coude si un jour le rsync m'ennuie. Cette VM me laisse la possibilité d'activer un jour les protocoles gopher/gemini si j'ai envie. Finalement, voici les miroirs: => https://si3t.ch => https://mirror.si3t.ch => https://git.sr.ht/~prx/si3t.ch --- Une réaction? => mailto:prx@si3t.ch?subject=miroirs ]]> Update zim library https://si3t.ch/log/2024-01-23-update-zim-library.txt 2024-01-23T15:15:42Z https://kiwix.org/en/ It uses dumps writen in zim files. You can find a lot of them here: => https://download.kiwix.org/zim From wikipedia to gutenberg and even french show "C'est pas sorcier" i used to watch when I was a kid. Most of the times, zim files are big. To update them one in a while, i wrote a script: zim-update.sh. It require curl to download zim files, but you can use wget or another tool if you prefer. I strongly suggest to uncomment parts of the script using aria2 to download zim with bittorrent protocol. In the end, kiwix-manage add new zim to your library, you can read them in a browser thanks to kiwix-serve. It looks like this: => /log/img/kiwix-serve-shot.png ```zim-update.sh #!/bin/sh # update zim files # see https://wiki.kiwix.org/wiki/Content_in_all_languages # require kiwix-tools and curl zim_dir=~/docs/zim zim_library=~/docs/zim/library.xml zims="wikipedia_fr_all_nopic wiktionary_fr_all_nopic vikidia_fr_all_maxi lesbelleshistoires_fr" dlurl="https://download.kiwix.org/zim" cd "${zim_dir}" for z in ${zims}; do # please uncomment to use torrent if you can. Install aria2 to do so #zimurl="${dlurl}/${z}.zim" #zimtorrent="${zimurl}.torrent" #aria2c --seed-time=0 "${zimtorrent}" # disable seed #rm *.torrent # direct download curl -L -O -C - "${zimurl}" done # add zims to library for zim in *.zim; do kiwix-manage "${zim_library}" add "${zim}" done cat << EOF You can now run kiwix-serve --library ${zim_library} -p 51318 and open a browser at http://127.0.0.1:51318 EOF ``` --- Comment? Send it to: => mailto:prx@si3t.ch?subject=update-zim-library Find instructions here: ]]> gghget: téléchargement multi-protocole gemini/gopher/http(s)/... https://si3t.ch/log/2024-01-21-gghget-wget-pour-tous-protocoles.txt 2024-01-21T15:52:23Z https://everything.curl.dev/protocols/curl Restait à trouver comment faire pour gemini. La commande openssl fait le job, il faut juste virer l'entête avec "sed '1d'" et on est bon :) Au final, ça donne le script suivant qui permet de préciser si on le souhaite le nom du fichier à écrire. J'aurais bien laissé vers stdout, mais ça met le bazar quand on récupère des binaires ^^. ``` #!/bin/sh # gghget : download file grom gemini, gopher or http(s) # require curl and openssl usage() { printf "usage: %s 'protocol://url/something' '[output_file]'\n" "$0" exit 1 } # remove ending "/" if any to get the filename if [ -z "$2" ]; then name="$(printf "$1" | awk -F/ '{sub("/+$", "", $0); print $NF}')" else name="$2" fi case "$1" in -h|--help|help) usage ;; gemini://*) # set default port if not specified next to domain in url host="$(printf "$1" | awk -F/ '$3 !~ /:[[:digit:]]+/ {$3=$3 ":1965"} END {print $3; exit}')" # sed will remove response header printf "$1\r\n" |\ openssl s_client -crlf -quiet -connect "${host}" 2>/dev/null |\ sed '1d' \ > "${name}" ;; *://*) curl \ -L \ -f \ -s \ -m 5 \ -H "User-Agent:" \ --compressed \ "$1" \ > "${name}" ;; *) printf "The URL must start with protocol://\n" ;; esac ``` Voir aussi hurl: => https://codemadness.org/hurl.html --- Une réaction? => mailto:prx@si3t.ch?subject=gghget-wget-pour-tous-protocoles ]]> Afficher les paroles de la chanson jouée par mpd https://si3t.ch/log/2024-01-18-afficher-paroles-mpd.txt 2024-01-18T13:47:20Z mediacenter-sync-at-startup https://si3t.ch/log/2023-12-12-mediacenter-sync-at-startup.txt 2023-12-12T10:44:44Z https://si3t.ch/log/2023-07-30-light-mediacenter-with-alpine.txt Désormais, quand j'allume mon mediacenter, il récupère les fichiers que j'ai déposé sur mon serveur. C'est tout simple, j'ai simplement configuré ssh pour une identification par clé: => https://si3t.ch/w/doku.php?id=ah:fr:02-admin#connexion_par_cles_sans_mot_de_passe Puis j'ai installé rsync. Dans ~/.profile, il y a désormais : ``` /home/watcher/syncvids.sh ranger ~/videos ``` Le script syncvid récupère les vidéos et supprime les fichiers d'origine après le transfert. ``` #!/bin/sh rsync \ -zriv \ --progress \ --remove-source-files \ ledzep:/var/users-backups/watcher/videos/ \ /home/watcher/videos/ ``` C'est très pratique, je n'ai plus à transférer manuellement les vidéos : je les dépose tranquilou sur mon serveur, je sais qu'elle seront automatiquement récupérées et effacées le moment venu quand je voudrai les regarder. --- Une réaction? => mailto:prx@si3t.ch?subject=mediacenter-sync-at-startup ]]> Nethack -- Épisode 16 https://si3t.ch/log/2023-10-21-nethack-16.txt 2023-10-21T10:27:09Z Hello prx, welcome to NetHack! You are a lawful male human Monk. Je recommence en tant que moine. NINJA! Dans mon inventaire, j'ai un parchemin de détection de nourriture... Ça donnera des indices j'imagine. Oh, et mon livre de sort c'est pour lancer "protection". Cool, ça compensera le manque d'armure. Cette fois-ci, je suis accompagné d'un chien. Très vite, ce dernier m'abandonne et file buter des monstres loin de moi... Que c'est pénible de ne pas pouvoir appeler son animal de compagnie :/ Je décide de ne plus perdre mon temps à le retrouver et file vers le prochain escalier. J'écrase un triton sur le et trouve un ouvre-boîte en-dessous :). Une fois près de l'escalier, mon chien réapparaît. Je vais lui donner un petit nom tiens : > What do you want to call the little dog? Gaby À peine au niveau 2, j'ai déjà trouvé 3 baguettes magiques. C'est la partie des baguettes! Et un sifflet aussi, peut-être que ça m'aidera à rappeler Gaby! Au niveau 4, je retrouve une fourmi, je vais prendre ma revanche cette fois! Sans oublier mon armure magique ;) Un peu plus loin : un commerce! Chouette, il était temps! J'y trouve un parchemin à pas cher que j'ai déjà dans mon inventaire : j'espère que c'est bien un parchemin d'identification... Hé ben non, c'est un parchemin de téléportation ^^ J'ai une autre paire de parchemins, au moins cette fois c'est la bonne, je peux identifier des chose :) Ça me permet de revendre un scroll of punishment :) À peine arrivé au niveau 5, mon chien file se défouler et je trouve juste à côté une pièce pleine de monstres. > You enter an opulent throne room! Décidément, j'ai de la chance! Bon, je tente ma chance hein ! Mon chien est de retour, je lance mon sort de protection, et zou! Résultat : > Dlvl:5 $:237 HP:50(50) Pw:33(36) AC:2 Xp:6 Hungry Bon évidemment, je tombe nez à nez avec un leprechaun à la pièce suivante . GRRR Et mon chien qui a encore disparu... Je tente de déposer mon or un peu plus loin pour faire face au leprechaun... Celui-ci me contourne, et vole mon or posé un peu plus loin, je suis ruiné! Un autre est dans ma ligne de mire mais s'échappe rapidement. Décidément, c'est compliqué de faire face à ces lutins. Un peu plus loin, j'en retrouve un : je l'assaille de ma baguette de "strike" et finit par récupérer 300 pièces. Yay! Je continue ma recherche et retrouve le 2e. Ce dernier recoit un petit boomegang en pleine face, bien visé mon gars! Il s'enfuit et tombe dans un piège : sprotch, écrabouillé par un boulet! Niveau 6, j'y découvre de nouveaux monstres : un rat-garou, un homonculus. Changement d'ambiance, ce n'est plus les petits tritons. Au niveau 7, un singe me vole ma robe! Non mais sans dec'! C'est à poil que je l'écrabouille! Na! Dans ce niveau, ça regorge d'orcs! Yaaa! Un yéti me met la misère. Je bois toutes mes potions de soin pour l'affronter et descent avec plusieurs sorts mon AC à -2. ouf! En voulant ouvrir un coffre, j'équipe un sabre qui semble maudit, impossible de le retirer. Je n'ai plus qu'à tester tous mes parchemins encore non identifiés... Il y en a trop de toute façon. Je découvre ainsi les parchemins de lumière, de magic mapping et au 3e essai d'enchant weapon (ou de remove curse). Cool! Emballé par ces découvertes, j'en tente un autre : mes potions explosent, mes parchemins brûlent, mon livre de sort brûle, ma robe brule et il me reste 3 points de vie... Woah, c'était chaud! J'essaie de récupérer mais des monstres ne cessent de réapparaître. Galère. J'ai beau me démener, je finis par succomber aux multibles attaques de poneys (oui...) et d'un jaguar. ---------- / \ / REST \ / IN \ / PEACE \ / \ | prx | | 623 Au | | killed by a | | jaguar | | | | | | 2023 | *| * * * | * _________)/\\_//(\/(/\)/\//\/|_)_______ Goodbye prx the Monk... You died in The Dungeons of Doom on dungeon level 6 with 5265 points, and 623 pieces of gold, after 3987 moves. You were level 7 with a maximum of 55 hit points when you died. --- Une réaction? => mailto:prx@si3t.ch?subject=nethack-16 ]]> Nethack -- Épisode 15 https://si3t.ch/log/2023-10-20-nethack-15.txt 2023-10-20T15:03:32Z Hello prx, welcome to NetHack! You are a neutral male human Monk. > Be careful! New moon tonight. Ça commence bien... Cette fois-ci, je jette un oeil à mon inventaire : j'y découvre un "scroll of punishment", le genre de trucs que je vais revendre au plus vite et que je suis bien content d'avoir identifié. Le gros boulet que je suis ne savais pas que j'avais un livre de soin, ce qui semble assez logiue pourtant pour un moine. Il y a aussi une lampe à huile tiens :) Bref, allons-y! Au niveau 2, je dois sonder pour trouver mon chemin. Je gagne un peu d'expérience au combat, et entend tinter au loin des pièces : un commerce doit être proche. Pas moyens de mettre la main dessus cependant! Au niveau 3, un corps traîne au sol juste à côté de l'escalier. Muhahaha, je ne m'y ferai pas prendre cette fois : je vérifie si un piège est en-dessous. > You know of no traps there. \o/ cool, je vais dessus : > An arrow shoots out at you! You are almost hit by an arrow. Bon, je m'y prends mal apparemment :/ Il ne faut pas utiliser "#untrap" mais "s". Au niveau 4, je découvre un marchand de parchemins et de livres. Au milieu des pages, un mimic me grignote les orteils, mais j'en fait de la patée pour chat! Je découvre ici un parchemin pas trop cher en espérant que ce soit un parchemin d'identification et revent pour 150 pièces d'or mon parchemin de punishment. Yay, bingo! Du coup j'achète tous les autres parchemins d'identification dans la foulée, il me reste même 81 pièces \o/ J'en profite pour identifier un max de trucs dans mon inventaire: j'y avais un anneau de téléportation maudit, j'ai bien fait de ne pas l'enfiler! Il y a aussi une potion maudite de lévitation, le genre de trucs dont on se passerait bien... Enfin, j'identifie un parchemin maudit de magic mapping, le truc qui permet de connaître tout un niveau. Mais... maudit??? Ça change quoi ? J'oublie tout un niveau à la place? Je préfère m'abstenir ^^ Un peu plus loin, au milieu d'un couloir, je tombe nez à nez avec un floating eye. Oh non, pas ça!!! Je tente d'utiliser une baguette magique non identifiée : je n'ai pas mieux, ou alors un parchemin de feu, mais invoquer une grosse explosion au milieu d'un minuscule couloir, bof! > The floating eye turns transparent! Je ne sais pas si c'est une bonne idée... Parce que du coup, je ne le vois plus, donc je ne suis plus paralysé en théorie. Mais par contre, il peut me taper à sa guise : je fuis! Après quelques tours, je me rend invisible et retourne tuer l'oeil... Autant vous dire qu'heureusement, mon chat était là, je me suis quand même trouvé paralysé (le boulet). Un peu plus loin, un leprechaun me vole tout mon or! NOOON ! Impossible à éviter en plus le bougre! Tant pis, il faudra faire sans... Un peu plus loi je manque de peu de perdre mon chat, celui-là va un peu n'importe où... Du coup je perds un temps fou à aller le chercher... Je n'ai pas trouvé dans l'aide comment l'appeler. J'ai l'impression de ne pas trop mal me débrouiller pour l'instant: > Prx the Novice St:18/04 Dx:13 Co:11 In:10 Wi:14 Ch:9 Neut > Dlvl:6 $:18 HP:34(34) Pw:30(30) AC:2 Xp:5 Au niveau 7, je croise la route d'un golem doré, il tape fort celui-là ! Je prend la fuite avant de décéder. Un peu plus loin, je tombe sur un véritable zoo! Tout un tas de créatures, qu'on ne peut malheureusement pas adopter, mais qu'il va falloir dégommer pour récupérer les trésors en-dessous. Ça prend du temps, je préfère jeter des flèches plutôt que me retrouver encercler... Et le golem doré rôde toujours. Centaure, nymphe, nain shaman, orc... Il y a même une licorne XD. Au final, j'ai récupéré un trésor considérable, plus de 1000 pièces d'or!!! Je file donc dépenser tout ça dans un des précédents commerce. En chemin, je suis coincé dans une embuscade avec des fourmis qui tapent fort! À croire que l'or les attire oO. Et bien évidemment, idiot que je suis, enthousiasmé par ce bon début de partie et les poches pleines de pièces, j'en oublie de faire appel à Elbereth ou même de lancer un sort de soin... ---------- / \ / REST \ / IN \ / PEACE \ / \ | prx | | 1301 Au | | killed by a | | soldier ant | | | | | | 2023 | *| * * * | * _________)/\\_//(\/(/\)/\//\/|_)_______ Goodbye prx the Monk... You died in The Dungeons of Doom on dungeon level 6 with 3949 points, and 1301 pieces of gold, after 3564 moves. You were level 6 with a maximum of 36 hit points when you died. Être riche, ça peut être dangereux? Moins que d'être étourdi. --- Une réaction? => mailto:prx@si3t.ch?subject=nethack-15 ]]> Nethack -- Épisode 14 https://si3t.ch/log/2023-10-19-nethack-14.txt 2023-10-19T21:24:29Z Hello prx, welcome to NetHack! You are a chaotic female human Monk. Un rôle que je ne connaîs pas du tout, ça fait envie. Je me sens déjà être une sorte de ninja en robe hyper fit et intelligente! Je trouve rapidement une grande boîte, impossible à ouvrir sans outils pour l'instant. Être moine c'est trop cool, je dégomme tout ce qui passe sans soucis. Bon par contre, même en étant chaotique, ça ne semble pas bon pour mon karma de manger des cadavres O:) Je trouve un petit commerce en passant. Beaucoup de choses à manger, je dois m'en rappeler pour plus tard : boîte à ouvrir, commerce à manger :) D'ailleurs, dès le niveau 3, un hobbit laisse tomber par inadvertance une dague lorsqu'il décède. Hop, direction le niveau 1 pour ouvrir la boîte :) J'ytrouve 3 parchemins, un livre et une baguette magique. Pour l'instant, leurs effet est inconnu. Je tente de lire le livre pour voir, il se tranforme en poussière et je me sens menacé... Ça ira comme ça hein ;) Je retourne dans les mines au lieu du niveau 3 classique pour tester ma baguette : ça tue un gnome direct! oO C'est une baguette de "striking". Par contre mon petit chien se fait écrabouiller par un rocher dans un piège des mines. Snif! Je gagne vite de l'expérience dans les mines, trouve des chaussures, de quoi un peu progresser en tant que moine. Les mines me mettent vite en danger à partir du 2e niveau, je choisis de remonter explorer le donjon sans mourir ^^. Par contre, la nourriture se fait rare... Je vais vite remonter au niveau 2 acheter à manger à ce rythme. Cependant, un boulet me barre la route puisqu'un montre se trouve derrière :s. Heureusement, la "wand of striking" l'éclate vite fait. Niark! Je remontre acheter quelques fruits, je n'ai pas encore assez d'argent pour des rations complètes. Au niveau 4, je trouve une nouvelle boîte. Après l'avoir crochetée, je me fais engloutir par des flammes en l'ouvrant : c'était un vilain piège!!! Mes gants brûlent :s. Quelques pièces plus loin, je tombe nez à nez face à un oeil flottant!!! Impossible de fuir, je suis paralysé. Et ce con invoque des trucs qui me frappent en tous sens!!! Aaargh, ça semblait si bien partiiii!! ---------- / \ / REST \ / IN \ / PEACE \ / \ | prx | | 31 Au | | killed by a | | manes | | | | | | 2023 | *| * * * | * _________)/\\_//(\/(/\)/\//\/|_)_______ Goodbye prx the Monk... You died in The Dungeons of Doom on dungeon level 4 with 1262 points, and 31 pieces of gold, after 2006 moves. You were level 5 with a maximum of 32 hit points when you died. --- Une réaction? => mailto:prx@si3t.ch?subject=nethack-14 ]]> Nethack -- Épisode 13 https://si3t.ch/log/2023-10-18-nethack-13.txt 2023-10-18T15:38:53Z Salutations prx, welcome to NetHack! You are a lawful male human Knight. Tiens, je suis un chevalier. Ça va changer un peu. Pas trop besoin de réfléchir à priori : on fonce et on tape. :) Bon, je dois juste me souvenir de ne pas tenter de monter sur mon poney, la dernière fois que j'ai tenté un truc du genre en début de partie, je suis mort en tombant de la selle XD. À la 3e pièce du donjon, je fonce bêtement dans un piège : je devrais vraiment prendre le temps de regarder ce qui est au sol avant d'y aller. Il y avait au sol un elfe mort avec des flèches, les indices étaient là. Heureusement, pas de mal, et j'ai la chance de trouver une serviette, accessoire indispensable pour nfaire de l'auto-stop intergalactique ;). Dans la pièce suivante, je tombe sur un gobelin imprudent. Hop, couic! Il y a de la viande au menu: > Blecch! Rotten food! Everything suddenly goes dark. DONC, manger de la viande fraîchement hachée, qui est apparemment déjà pourrie, me rend AVEUGLE! Bien joué mon gars! Tant pis, pas le choix, il faut continuer. Ça passe vite heureusement. Pour une fois, le niveau semble bien grand, je trouve un passage tout à l'ouest: ``` ---------- ------------- |<.......| ----- ###-...........| |........| ------ |...| # |...........| |........-#####.....| |...| # |...........| -------.--# |....| |...| # ----------.-- ## # --.--- |...-### ## # ## # |...| # # # ### --.-- # # # # # -.----- ### ## #### # |.....| # # --------|-- # |...:.-##################################..........| -@- |.....|#####------- ---.-- ##|.........| |.%.| |......# #...>...######|....| #|.........| |.... -------## |.....| #|....| #|.........| |{..| ####-......## #|....| #..........| ----- |.....| ### #|....| |..%......| ------- ###.....| ----------- #------ Prx the Gallant St:15 Dx:9 Co:10 In:9 Wi:15 Ch:17 Lawful Dlvl:1 $:10 HP:16(16) Pw:5(5) AC:3 Xp:1 ``` Ça sent le piège, mais il y a une tasse avec une fontaine à côté. Dois-je boire l'eau? Allez, j'y vais! Tout va bien, comme quoi, nethack n'est pas toujours si méchant :) Ma route continue, le niveau 2 se passe tout seul, mis à part qu'il y a un coffre et une boîte que je ne peux pas encore ouvrir : il me manque des outils de crochetage. Note à moi-même : revenir ici un peu plus tard. Il y a d'ailleurs 2 escaliers vers le bas, qui ne mènent pas au même niveau. Dans l'un des niveaux 3, j'ai bien failli y rester face à une chauve-souris géante. Heureusement mon poney mort fort. Tiens, hop, une carrote non-maudite pour toi! Ça commence à devenir compliqué de tout porter. Et pas un seul parchemin à l'horizon pour identifier mes potions. J'ai compris ce que c'était l'autre niveau 3 : c'est les mines. Mon poney fait des ravages, quand soudain: > Your saddled pony grows up into a horse. Alleeeeez, si ça continue comme ça il va évoluer en licorne. Ça serait la classe! (le wiki dit que ça deviendra un cheval de guerre). En descendant au niveau 4 des mines, je me fais attaquer à coup de carreaux, on me jette une carafe à la tronche, et je suis tellement lent que je peine à me défendre. Je remonte bien vite alors qu'il me reste 5HP, mais il vaut mieux fuir! En passant, je découvre une amulette que j'essaie: > It constricts your throat! Génial, je me fais étrangler... C'est mal barré! > You find it hard to breathe. > You're gasping for air. You can no longer breathe. > You're turning blue. > You suffocate. 4 tours... Les colliers, c'est pourri! ``` ---------- / \ / REST \ / IN \ / PEACE \ / \ | prx | | 41 Au | | killed by | | strangulation | | | | | | 2023 | *| * * * | * _________)/\\_//(\/(/\)/\//\/|_)_______ Fare thee well prx the Knight... You died in The Dungeons of Doom on dungeon level 2 with 575 points, and 41 pieces of gold, after 2218 moves. You were level 4 with a maximum of 40 hit points when you died. ``` --- Une réaction? => mailto:prx@si3t.ch?subject=nethack-13 ]]> mission terroriste réussie https://si3t.ch/log/2023-10-16-mission-terroriste-reussie.txt 2023-10-16T20:36:33Z C'était un professeur [...] qui pensait que savoir était un grand trésor, que tous les "moins que rien", n'avaient pour s'en sortir, que l’école et le droit qu’a chacun de s’instruire. Il y mettait du temps, du talent et du cœur... Puis la vie continue. Heureusement, les enfants/élèves sont dépassés par tout ça. On enseigne, et c'est ce qui est le plus important. Mais le Soleil est lent dans le ciel, la bouche a un gout amer. Tout le monde est déjà passé à autre chose. Dommage colatéral. On a fait rentrer les profs dans les rangs et garder les enfants pour que les ouvriers puissent continuer à faire tourner la fraiseuse au lieu de garder leurs enfants si l'école ferme, le PIB passe d'abord. Rien à faire. Et les collègues qui intellectualisent le truc en salle de pause... Et gnagnagna l'histoire, et blablabla la Palestine et l'Israël, et vas-y que je te lance des trucs en fait racistes, toi, le collègue si humain que j'estime tant. Bravo. Mission terroriste réussie. Les religions sont un poison. Les territoires sont des illusions. Pendant ce temps, les collègues du primaire recevaient la consigne de Gabriel Attal, Ministre de l'Éducation Nationale, de préparer des choses pour une commémoration, pendant leur PAUSE DÉJ'! Au lieu d'inventer des problèmes d'Abaya, y avait peut-être mieux à faire... Fatigue... Colère... Fatigue... Tant de fatigue! Désespoir. Futilité. Vanité! Ça ne profite à personne. Il y a juste des morts et du temps gaspillé. À quoi bon? Et le soir... alors que les enfants sont censés être endormis : > Mais maman, ça aurait pu être toi?! Bravo. Mission terroriste réussie. --- Une réaction? => mailto:prx@si3t.ch?subject=mission-terroriste-reussie ]]> teach-even-harder https://si3t.ch/log/2023-10-14-teach-even-harder.txt 2023-10-14T16:11:03Z You know what, I'm gonna start teaching even harder! Quelques heures plus tard, Gabriel Attal, Ministre de l'éducation nationale: > les cours sont annulés pour les élèves jusqu’à 10 heures. 😫 --- Une réaction? => mailto:prx@si3t.ch?subject=teach-even-harder ]]> À lire + tard https://si3t.ch/log/2023-10-10-a-lire-plus-tard.txt 2023-10-10T20:51:11Z https://forlater.email/ D'autres utilisent shaarli et taggent les liens avec "#toread" ou "#souslecoudé" ^^. En ce qui me concerne, une certaine personne qui se reconnaîtra vite ici m'a envoyé des articles que j'ai vraiment très envie de lire. VRAIMENT lire, pas regarder à toute vitesse en 2 minutes entre le grand qui hurle parce qu'il n'arrive pas à terminer son bricolage avec un trait qui n'est pas parfaitement droit et sa petite soeur qui lui chipe ses crayons et en profite pour les mettre dans la bouche tout en criant parce que elle veut elle aussi la même feuille pour dessiner tout en ayant peur du chat qui veut juste des caresses... Juste, pouvoir lire calmement, car ça semble très intéressant, et ça demande + de 2 minutes de lecture, et être sûr de ne pas l'oublier. En plus, je suis du genre à être anxieux à l'idée que des textes ou ressources peuvent disparaître entre le moment où je note le lien et celui où je vais effectivement le lire et encore le jour où je vais y faire référence pour un ami ou parce que j'en ai besoin. C'est là qu'intervient archive.org et sa machine à remonter le temps. Voici donc un petit script nommé ''soulcoud'' (ouais...) qui va récupérer une copie d'un lien avec lynx, 100% plaintext, effectuer une copie chez archive.org et envoyer le tout par mail. C'est tout nouveau, ça va sans doute être modifié un peu à l'avenir, du coup les conseils sont bienvenus. Vous remarquerez que l'adresse mail à laquelle l'article doit être envoyé est définie dans une variable d'environnement, ça me paraissait + simple pour l'utiliser via dmenu. De plus, les liens gopher sont supportés, ça ne doit pas être trop dur d'ajouter d'autres protocoles. Ça s'utilise ainsi : ``` soulcoud https://www.filfre.net/2023/07/going-rogue/ recommended by f6k ``` Bref, voici soulcoud: ``` #!/bin/sh # soulcoud: save an url on archive.org and send a copy by email to read later # the email address is read from environment SOULCOUD_MAIL # Author: prx # licence: MIT # Require: curl, lynx or reader # one may replace mail command with msmtp or else # improve with wkhtml2pdf or other snapshot tool usage() { printf "usage:\n\t" printf "%s (-h) \n" "$0" printf "\t-h : print help\n" printf "\nexample:\n" printf "\t%s 'http://who-is-clarkkent.net' Superman id?\n" "$0" printf "\nThe page is sent to the mail address set in environment variable SOULCOUD_MAIL\n" exit } archive_url() { # archive the url and output the page link on archive.org curl -s "https://web.archive.org/$1" | sed -n 's/.*href="\([^"]*\).*/\1/p' } dump_page() { # use reader or lynx to echo page content #reader "$1" lynx \ -dump \ -underline_links \ -image_links \ -collapse_br_tags \ -list_inline \ "$1" } if [ -z "${SOULCOUD_MAIL}" ]; then printf "You must set the environment variable SOULCOUD_MAIL\n" printf "Example: in ~/.profile, enter\n" printf "\texport SOULCOUD_MAIL=bruce.wayne.corp\n" exit fi while getopts 'h' c do case $c in h) usage ;; esac done shift $((OPTIND - 1)) test $# -lt 1 && usage url="$(printf "$*" | cut -d' ' -f1)" title="$(printf "$*" | cut -d' ' -f2-)" test -z "${title}" && title="${url}" ( # save the page with lynx dump_page "${url}" printf "\n---\n" printf "url: "${url}" # then save on archive.org case "${url}" in http* ) archived="$(archive_url "${url}")" if [ $? -eq 0 ]; then printf "Saved on: https://web.archive.org/%s\n" "${archived}" fi ;; esac ) | mail -s "${title}" "${SOULCOUD_MAIL}" ``` Pour l'utiliser, vous devrez avoir installé curl, lynx, et un serveur mail en route ou bien remplacer ''mail'' par ''msmtp'' ou équivalent. --- Une réaction? => mailto:prx@si3t.ch?subject=a-lire-+-tard ]]> </content> </entry> <entry> <title type="text">Nethack -- Épisode 12 https://si3t.ch/log/2023-10-05-nethack-12.txt 2023-10-05T21:20:27Z Aloha prx, welcome to NetHack! You are a neutral female human Tourist. Voilà trop longtemps que je n'ai pas pris le temps de jouer. J'espère ne pas avoir oublié trop de choses. J'indiquerai ici les éléments importants de l'aventure selon ce que je découvre. C'est reparti! Déjà, inventaire de fou : 764 pièces d'or, 3è flèches, plein de trucs à manger, et le reste classique chez le touriste : appareil photo et carte de crédit :D. Le premier niveau se passe bien. J'avais oublié qu'on est vraiment faible au début. Un rat a failli m'avoir, mais mon appareil photo a fait le reste ;) Au niveau 2, je découvre un coffre, mais impossible de le forcer sans armes. Plus loin, je récupère une massue (dans un piège...), alors je tente d'ouvrir, mais la massue est maudite :s. Du coup je suis lent, j'ai faim, alors j'ouvre une boîte de conserve, et là, j'éclate de rire : > Eating french fried food made your fingers very slippery. Ça ne va pas m'aider à ouvrir cette malle !!! Je finis par y parvenir et découvre une potion effervescente, une baguette magique, 2 gemmes (il faut décidément que je découvre à quoi servent les gemmes!) et un livre de sorts poussiéreux. Bof, rien d'hyper essentiel pour une touriste. Cependant, un peu plus loin, un marchand!!! J'ai donc des choses à vendre si besoin de sous. Ah, je suis content, c'est la première fois que je trouve un marchand si tôt dans le jeu en tant que touriste. D'ailleurs, heureusement que je suis riche, mon chat mange les tripes du magasin :s J'y trouve une hache, une armure simple, et surtout, un parchemin d'identification qui est bien pratique!! En tout cas, je me ruine avant de descendre au niveau 3. Hâte de me débarasser de cette massue maudite! Au niveau 4, je découvre une cape elfique. Youpi ! Plus loin, un gnome m'attaque. Je le découpe en petites rondelles alors que mon chat lui griffe les fesses. Cela me laisse affamé, je dévore les morceaux restants : > Ulch - that meat was tainted! You feel deathly sick. > (It must have died too long ago to be safe to eat.) > You die from your illness. oO Mais POURQUOI n'ai-je pas bu une de mes super potions de soin??? ``` ---------- / \ / REST \ / IN \ / PEACE \ / \ | prx | | 122 Au | | poisoned by a | | rotted gnome | | corpse | | | | 2023 | *| * * * | * _________)/\\_//(\/(/\)/\//\/|_)_______ Aloha prx the Tourist... You were poisoned in The Dungeons of Doom on dungeon level 4 with 250 points, and 122 pieces of gold, after 2206 moves. You were level 2 with a maximum of 16 hit points when you were poisoned. ``` --- Une réaction? mailto:prx@si3t.ch?subject=nethack-12 ]]> À quoi peut me servir OpenBSD ? (édition serveur) https://si3t.ch/log/2023-10-02-octopenbsd-server.txt 2023-10-02T12:56:36Z À quoi peut me servir OpenBSD ? https://si3t.ch/log/2023-10-02-octopenbsd-desktop.txt 2023-10-02T12:50:38Z ${LOCKFILE} set_status DELAY=".5" # clock (while true; do sleep 60; set_status; done) & # mpd changes (while true; do mpc -q --wait current >/dev/null 2>&1; set_status; done) & # global loop while true; do sleep $DELAY; done ``` , j'envoie les fenêtres sur la sortie du vidéo-projecteur avec un petit raccourci. Sur mon écran à moi, j'affiche dans la sortie qui s'affiche dans mon dos avec ffplay : ``` #!/bin/sh res="800x600" ffplay -f x11grab -s $res -framerate 25 -i :0.0+1366,0 ``` Je peux voir ma classe tout en écrivant ou en bricolant ce qui est affiché, c'est très pratique. Avec le gestionnaire de fichiers rover dans tmux, j'ouvre mes documents en quelques frappes. En cas de doute, j'utilise le script "f" pour chercher un fichier dont je ne me souviens plus l'emplacement : ``` #!/bin/sh # find and open a file if [ "$#" == "0" ] ; then file="$(find . -type f | match)" else file="$(find . -name "*${*}*" -type f | match)" fi test -f "$file" && opener "$file" ``` Autant dire qu'il y a des scripts partout. match appelle dmenu ou pick, opener ouvre les fichiers selon leur extension... Avec ce dernier, j'écoute de la musique avec mpd. L'espace disque est limité, je branche donc un SSD externe qui contient mes musiques. Un script se charge de le monter et lancer mpd: ``` #!/bin/sh slice=$(dmesg | awk '/serial.21090715000000123E9A/ {d=$1} END{print d}') test $? || exit if [ -n "$slice" ]; then doas /sbin/mount "/dev/${slice}i" /home/prx/mpd #doas /sbin/mount /home/prx/mpd pgrep -q mpd || mpd mpc play echo "ok" fi ``` Quand un élève a des documents à projeter ou à me donner, il vient avec une clé USB que je monte avec "mnt". Ça évite de monter automatiquement des trucs potentiellement dangereux: ``` #!/bin/sh # detect recently insterted media # look for slice # choose the one to mount. # mount the partition in $mountdir/sdnm # where "n" is the disk and "m" the slice # doas.conf : #permit nopass :wheel cmd /sbin/mount #permit nopass :wheel cmd /sbin/disklabel # change "mountdir" according to your needs mountdir=$HOME/mnt/ sdn="$(dmesg | grep "sd[0-9] "| tail | \ match -p 'disk ?'|\ awk '{print $1}')" test -z "${sdn}" && exit 1 slice="$(doas /sbin/disklabel ${sdn} |\ awk '/^ / { gsub("[:,c]","",$1); print $1}' |\ match -p 'slice ?')" test -z "${slice}" && exit 1 partition="${sdn}${slice}" mntpt="${mountdir}/${partition}" mkdir -p "${mntpt}" if [ "$sdn" != "" ]; then doas /sbin/mount /dev/"${partition}" ${mntpt} # xfe ${mntpt} fi rover "${mntpt}" exit $? ``` Avec nvi, je code à l'occasion. Il y a tout sous OpenBSD pour compiler. À la connexion, calendar m'indique si j'ai des trucs à penser (anniversaires, choses à faire...) Pour ma ToDo list, j'ai un alias qui ouvre un fichier texte qui suit les idées indiquées là : https://codemadness.org/todo-application.html Un script rsync sauvegarde périodiquement tous mes documents importants sur mon serveur, ainsi que lorsque j'éteins mon ordi: ``` #!/bin/sh if [ -n "$TERM" ]; then prxsync push else xterm -e "prxsync push" fi shutdown -hp now ``` Pour la connectivité, au travail j'utilise le partage 4G de mon téléphone, à la maison y a le wifi, je n'ai rien à faire depuis que c'est configuré: ``` # cat /etc/hostname.iwm0 up join kamehameha wpakey ******************** join prxAP wpakey ******************************* join WIFI_PUBLIC -wpa ``` Lorsque je branche un cable ethernet, il devient prioritaire: ``` # cat /etc/hostname.trunk0 trunkproto failover trunkport em0 trunkport iwm0 inet6 autoconf inet autoconf ``` Et puis au besoin, j'ai wireguard prêt si j'ai besoin de changer d'IP: juste à lancer le script qui va bien 👼. Firefox, gimp, Libreoffice, LaTeX, rien de très original pour un prof. C'est mutt qui me permet de répondre aux mails. fdm récupère les messages quand je lui demande, ça m'évite les notifications trop distrayantes. Dedans, je lis mes flux RSS puisque mon serveur fait tourner rss2email. Alors ok, il y a quelques scripts qui facilitent la vie : charger un bookmark avec dmenu, prendre des notes grâce à dmenu, choisir une musique grâce à dmenu, chercher sur le web grâce à dmenu, chercher des fichiers grâce à dmenu... Rien de propre à OpenBSD à vrai dire. Si ma batterie est trop faible, alors l'ordinateur se met en veille le temps que j'aille trouver un cable d'alimentation: ``` # rc.conf.local apmd_flags=-A -z 8 ``` D'ailleurs, la batterie ne sera pas chargée au delà des 80% pour éviter son vieillissement prématuré: ``` # /etc/sysctl.conf hw.battery.chargemode=1 hw.battery.chargestart=75 hw.battery.chargestop=80 ``` Unwind, le résolveur DNS local se charge de filtrer les pubs et autres domaines malveillants et allège considérablement mon quotidien. J'ai un script associé à une combinaison de touches qui me permet d'afficher/cacher une session tmux dédiée. Pratique pour écrire en 2 secondes une petite interro ou les devoirs pour la semaine suivante, lancer un compte à rebours... Oh, et j'allais oublier. Je joue parfois dessus: nethack, moria, wesnoth, xonotic, terraria, rogue ledacy, ... ## moria Il y a un autre ordinateur à la maison, un pc fixe que je synchronisais avec mon pc portable avant. Avant, quand je pouvais rester dans 1 pièce sans être interrompu pour bosser ni craindre de réveiller les enfants. Pour l'instant il est au repos, il servira peut-être un jour à nouveau. Cela dit, ça reviendra, et tout est prêt pour avoir un clone de ce qui est déjà présent sur mon ordinateur portable. La synchronisation se réalisait avec synthing, puis unison, et finalement des scripts rsync qui déposent ou récupèrent sur mon serveur selon si l'ordinateur est en avance ou en retard. Pour le savoir, un fichier témoin contenant un timestamp de la dernière synchronisation est déposé. J'ai mis ça en place puisque unison, qui est EXCELLENT, nécessite exactement les même version de chaque côté, ce qui n'était pas le cas entre ma -current et mon serveur en -stable. Le script en question s'appelle "prxsync", il est appelé en début de session, toutes les heures, puis à l'extinction. ``` #!/bin/sh -e # sync my data between over my server # # ~/.lastsync : date of last sync # ~/.prxsync.lst : list of files to sync, relative to $HOME. Must containt ~/.lastsync usage() { echo "$0 push/pull"; exit 1 } test $# -eq 1 || usage # check if network access nc -zw1 "si3t.ch" 22 > /dev/null 2>&1 || exit 1 DISPLAY=:0 xsetroot -name "prxsync running..." tosync=$HOME/.prxsync.lst # dirs MUST end with / exclude=$HOME/.prxsync-exclude.lst lastsync=.lastsync localdir=$HOME remote=ledzep:/var/users-backups/prx locallastsync=$localdir/$lastsync # get remote lastsync remotelasttmp=$(mktemp) scp $remote/$lastsync $remotelasttmp remotelast=$(cat $remotelasttmp) rm $remotelasttmp # compare remote w local lastsync locallast=$(cat $locallastsync) case "$1" in "push") if [ $remotelast -gt $locallast ]; then echo "/!\ Remote newer than local, please check manually" exit 1 fi SRC=$localdir DST=$remote ;; "pull") if [ $remotelast -eq $locallast ]; then echo "Already sync, nothing to do" exit elif [ $remotelast -lt $locallast ]; then echo "/!\ Local newer than remote, you may push" exit 1 fi SRC=$remote DST=$localdir ;; esac echo ".:!|-- Start prxsync --|!:." /usr/local/bin/rsync \ --exclude-from=$exclude \ --delete \ --files-from=$tosync \ --progress \ -zrltpuv $SRC $DST # keep track of last sync date date +%s > $locallastsync reload-dwm-status ``` ## Liste de liens https://si3t.ch/w/doku.php?id=notes:uses ^ Ce que j'utilise https://si3t.ch/w/doku.php?id=notes:openbsd:postinst ^ Ce que je configure après l'installation d'OpenBSD https://si3t.ch/w/doku.php?id=evils ^ Listes d'IP à blacklister, générées et préparées sur mon serveur --- Une réaction? mailto:prx@si3t.ch?subject=octopenbsd-desktop ]]> Préserver sa batterie avec OpenBSD : hw.battery.* https://si3t.ch/log/2023-09-14-preserver-batterie-openbsd.txt 2023-09-14T12:31:55Z > /etc/sysctl.conf hw.battery.chargemode=1 hw.battery.chargestop=80 hw.battery.chargestart=75 EOF ``` --- Une réaction? => mailto:prx@si3t.ch?subject=preserver-batterie-openbsd ]]> Display div when link anchor is active https://si3t.ch/log/2023-09-05-display-div-when-link-anchor-is-active.txt 2023-09-05T13:01:26Z and
tag. However, it can be replaced with a link whose href refer to the id of a container. Then, CSS can make the container visible when targeted. Example : ``` Click me
Something
``` CSS : ``` #to_show_on_click {visibility:hidden} #to_show_on_click:target {visibility:visible} ``` ]]> Super Mario War ou Cat Wars sur retroarch https://si3t.ch/log/2023-08-16-super-mario-war-retroarch.txt 2023-08-16T12:08:25Z mailto:prx@si3t.ch?subject=super-mario-war-retroarch ]]> Ultra light mediacenter with alpinelinux and ranger in tty https://si3t.ch/log/2023-07-30-light-mediacenter-with-alpine.txt 2023-07-30T14:52:18Z https://wiki.alpinelinux.org/wiki/ALSA Configure mpv: ``` mkdir -p ~/.config/mpv cat << EOF >> ~/.config/mpv/mpv.conf alang=en,fr slang=fr,en save-position-on-quit=yes fullscreen=yes EOF ``` Configure ranger: ``` ranger --copy-config all ``` Enable image preview in .config/ranger/rc.conf: ``` set preview_images true set colorscheme snow ``` Uncomment video preview in .config/ranger/scope.sh: ``` video/*) # Thumbnail ffmpegthumbnailer -i "${FILE_PATH}" -o "${IMAGE_CACHE_PATH}" exit 1;; ``` Open ranger in the video directory when "watcher" user is logged in: ``` echo "ranger ~/videos" > .profile ``` At boot, log watcher user in automatically. Edit /etc/inittab: ``` tty1::respawn:/bin/login -f watcher ``` Reboot. Enjoy. Press power button briefly to turn off. => https://alpinelinux.org/ => https://github.com/ranger/ranger => https://mpv.io/ UPDATE: Set a nice font for subtitles ``` mkdir -p ~/.config/mpv cat << EOF >> ~/.config/mpv/mpv.conf alang=en,fr slang=fr,fre,en save-position-on-quit=yes fullscreen=yes sub-font="Roboto" sub-auto=fuzzy EOF ``` ``` apk add font-roboto font-terminus font-dejavu font-noto font-noto-cjk font-noto-extra terminus-font ``` Increase console font size: ``` vi /etc/conf.d/consolefont consolefont="ter-132n.psf.gz" rc-update add consolefont boot ``` UPDATE 2: mpv needs some xorg files: ``` setup-xorg-base ``` --- Comment to: => mailto:prx@si3t.ch?subject=light-mediacenter-with-alpine ]]> Nouveau mot de passe à chaque démarrage ou périodique https://si3t.ch/log/2023-07-08-new-password-at-each-boot.txt 2023-07-08T13:18:57Z mailto:prx@si3t.ch?subject=new-password-at-each-boot ]]> nono : détecter les tentatives d'intrusion et sévir https://si3t.ch/log/2023-06-30-nono.txt 2023-06-30T13:40:08Z Réécrire vilain en C Vilain, c'était un outil en python pour analyser les logs et détecter des tentatives d'intrusion pour bannir les IP correspondantes. https://framagit.org/prx/vilain Ça a vieilli, ce n'est pas si bien écrit, et ça intègre un démon alors qu'on doit pouvoir faire mieux avec moins. Alors, quand j'ai vu l'article de Solène qui présentait une solution similaire mais en awk, j'y ai vu un cadeau : https://dataswamp.org/~solene/2023-06-22-opensmtpd-block-attempts.html Mais oui! awk est parfait pour ce genre de tâches! J'ai eu l'idée d'utiliser ''tail -f'' pour monitorer en continu les logs. En cas de rotation, tail sait se débrouiller, ce qui permet d'avoir un démon à moindre cout :) Solène m'a donné envie de m'y mettre, et en quelques heures, j'avais un nouvel outil qui faisait comme vilain, mais en mieux, car en awk. Ça s'appelle nono, et c'est par ici : https://si3t.ch/w/doku.php?id=code:nono.awk Je pourrais y ajouter un démon... Pour l'instant, je le laisse dans tmux pour voir ce que ça donne. Et semble-t-il, ça tourne bien : ``` Jun 30 10:26:55 ledzep nono: 65.49.1.48 is naughty and is now banned because: ssh wrong pw or invalid user Jun 30 12:47:13 ledzep nono: 178.151.169.14 is naughty and is now banned because: ssh wrong pw or invalid user Jun 30 13:33:45 ledzep nono: 118.185.157.225 is naughty and is now banned because: ssh wrong pw or invalid user Jun 30 13:33:57 ledzep nono: 122.0.26.154 is naughty and is now banned because: ssh wrong pw or invalid user ``` Le code se présente ainsi. On commence par vérifier si l'utilisateur a défini les options, sinon on attribue des valeurs par défaut. La fonction ''usage()'' ne fait qu'afficher l'aide. ``` BEGIN { if ((ARGV[2] == "-h") || (ARGV[2] == "--help")) { usage() } # check for options or set defaults if ( ! TRIES ) { TRIES = 5 } if ( ! BANCMD ) { BANCMD = "pfctl -T add -t bot" } if ( ! KILLSTATE ) { KILLSTATE = "pfctl -k" } if ( ! IGNORE ) { IGNORE = "/etc/nono.ignore" } } ``` Ensuite, on a des blocs correspondant aux lignes des logs pouvant indiquer un défaut. Par exemple, pour les tentatives de connexion ssh: ``` / sshd.* Failed password | sshd.* Invalid user / { match($0, "from ([0-9\.:abcdef]*)") ``` Dans l'exemple ci-dessus, on recherche une ip/ipv6 dans la ligne détectée. Si une ip est obtenue, on appelle la fonction 'ban' qui enregistre dans un tableau si l'ip a déjà été vue. Si cela dépasse le nombre maximum de tentatives, elle est bannie : ``` function ban(seen, ip, reason) { seen[ip]++ if(seen[ip] >= tries) { if (isignored(ip) == 0) { system(sprintf("logger -t \"nono\" \"%s is naughty and is now banned because: %s\"", ip, reason)) system(sprintf("%s %s", BANCMD, ip)) system(sprintf("%s %s", KILLSTATE, ip)) } seen[ip] = 0 # reset } } ``` Un tableau était tout à fait adapté pour ça. Ici, j'utilise la fonction ''system'' pour appeler une commande qui enregistre l'activité de nono et bannit l'ip. Utiliser xargs comme le fait Solène semble tout aussi intéressant, ici je me suis juste restreint à awk. On voit qu'avant de bannir l'ip, un appel à ''isignored'' est réalisé pour éviter de s'auto-bannir. Cette fonction va parcourir les lignes d'un fichier à la recherche de l'ip. Merci ''getline'': ``` function isignored(ip) { ret = 0 while ((getline current_ip < IGNORE) == 1 ) { if (ip == current_ip ) { ret = 1 break } } close(IGNORE) return ret } ``` Et voilà, c'est à peu près tout :) Merci Solène ! ]]> Générateur de liste de lecture amélioré https://si3t.ch/log/2023-06-19-generateur-de-liste-de-lecture-ameliore.txt 2023-06-19T20:41:49Z /%3E/g; s/\#/%23/g; s/{/%7B/g; s/}/%7D/g; s/|/%7C/g; s/\\/%5C/g; s/\^/%5E/g; s/~/%7E/g; s/\[/%5B/g; s/\]/%5D/g; s/`/%60/g; s/;/%3B/g; s/?/%3F/g; s/:/%3A/g; s/@/%40/g; s/:/%3D/g; s/&/%26/g; s/\$/%24/g; ' } usage() { printf "usage:\n\t" printf "%s (-h) (-u )\n" "$0" printf "\t-h : print help\n" printf "\t-u : prepend to path for streaming\n" printf "\t\t i.e. -u "http://example.com/audio/"\n" exit } while getopts 'hu:' c do case $c in h) usage ;; u) url="${OPTARG}" ;; esac done printf "#EXTM3U\n\n" find . -type f \ -name '*.flac' -o \ -name '*.FLAC' -o \ -name '*.mp3' -o \ -name '*.MP3' -o \ -name '*.m4a' -o \ -name '*.M4A' -o \ -name '*.ogg' -o \ -name '*.OGG' -o \ -name '*.opus' -o \ -name '*.OPUS' -o \ -name '*.webm' -o \ -name '*.WEBM' | \ sed 's/^\.\///' |\ while read -r line; do duration="$(ffprobe -v 0 -show_entries stream=duration "${line}" |\ awk -F '=' '/duration=/ {sub("\\..*", "", $2); printf $2; exit}')" title="$(ffprobe -v 0 -show_entries 'format_tags=title' "${line}" |\ awk -F '=' '/title=/ {print $2}')" artist="$(ffprobe -v 0 -show_entries 'format_tags=artist' "${line}" |\ awk -F '=' '/artist=/ {print $2}')" test -z "${title}" && title="$(basename "${line}")" printf "#EXTINF:${duration}, %s - %s\n" "${artist}" "${title}" path="$(printf "%s" "${line}" | urlescape)" printf "${url}%s\n\n" "${path}" done ``` ]]> Diffuser de la musique vraiment facilement https://si3t.ch/log/2023-06-18-Diffuser-de-la-musique-vraiment-facilement.txt 2023-06-18T14:42:39Z > file.m3u\n", $0 exit 1 } #https://rosettacode.org/wiki/URL_encoding#AWK urlencode() { awk ' BEGIN { for (i = 0; i <= 255; i++) ord[sprintf("%c", i)] = i } # Encode string with application/x-www-form-urlencoded escapes. function escape(str, c, len, res) { len = length(str) res = "" for (i = 1; i <= len; i++) { c = substr(str, i, 1); if (c ~ /[-._*0-9A-Za-z]/) res = res c else if (c == " ") res = res "+" else res = res "%" sprintf("%02X", ord[c]) } return res } # Escape every line of input. { print escape($0) } ' } test -d "$1" || usage find "$1" -type f \ -name '*.flac' -o \ -name '*.FLAC' -o \ -name '*.mp3' -o \ -name '*.MP3' -o \ -name '*.m4a' -o \ -name '*.M4A' -o \ -name '*.ogg' -o \ -name '*.OGG' -o \ -name '*.opus' -o \ -name '*.OPUS' -o \ -name '*.webm' -o \ -name '*.WEBM' |\ cut -c 3- |\ urlencode ``` Reste à créer des fichiers m3u pour chaque dossier. Pour l'instant, je laisse en aléatoire, et ça me va :) Petit détail, j'ai légèrement modifié ce script pour intégrer les identifiants puisque je protège l'accès au dossier contenant les musiques par mot de passe, histoire de ne pas être accusé de diffuser du contenu illégalement. J'ai donc ajouté à la fin: ``` cut -c 3- |\ urlencode |\ xargs printf "https://user:password@si3t.ch/dossier-inexistant-de-musique/%s\n" ``` ]]> TaBr - un Makefile pour tout installer proprement https://si3t.ch/log/2023-05-15-TaBr-part5-tabr-Makefile.txt 2023-05-15T15:26:55Z /code/TaBr.tgz Si vous souhaitez vous approprier la suite "TaBr" dont je parle depuis plusieurs articles, vous pouvez en consulter les sources ici. (TaBr.tgz) Vous y trouverez un fichier README.txt qui explique rapidement les différents composants ainsi que les instructions pour créer les utilisateurs et configurer doas pour bien séparer les privilèges. Pour le reste, je vous ai préparé un Makefile qui simplifie l'installation et ajuste automatiquement les permissions. Je voudrais ici mettre en avant la commande "install" qui permet de faire ça beaucoup plus proprement qu'une suite de "cp", "mkdir", "chown" et "chmod". En gros, un simple "make install" et c'est prêt :) Tout d'abord, on précise quelques variables. Ce n'est sans doute pas parfait, mais c'est un bon début pour rendre la suite portable si un jour quelqu'un en a l'intention: ``` PREFIX ?=/usr/local BINDIR ?=${PREFIX}/bin SBINDIR ?=${PREFIX}/sbin CGIDIR ?=/var/www/cgi-bin CHPWREQDIR ?=/var/www/tabr_chpw_requests ``` Je précise ensuite les trucs qui devront être compilés: ``` all: src/tabr_chpw_cgi src/hashmatchstr ``` Reste à préciser les dépendances des fichiers à compier, histoire qu'ils soient recompilés en cas de modification de la configuration: ``` src/chpw_cgi/main.c: src/chpw_cgi/config.h src/tabr_chpw_cgi: src/chpw_cgi/main.c ${CC} -static -o $@ $? src/hashmatchstr: src/hashmatchstr.c ${CC} -o $@ $? ``` Avant d'aller plus loin, on précise comment nettoyer les fichiers compilés. C'est surtout utile pour les tests ``` clean: rm src/tabr_chpw_cgi rm src/hashmatchstr ``` La suite permet d'installer les fichiers en les rendant éxécutables et en les faisant appartenir à root ou _tabr_admin selon les cas : ``` install: src/tabr_chpw_cgi src/hashmatchstr install -o root -g daemon -m 0755 src/tabr_chpw_cgi ${CGIDIR}/tabr_chpw.cgi @# IMPORTANT: chmod 730, www can write but can't read install -o _tabr_admin -g www -m 0730 -d ${CHPWREQDIR} install -m 0755 -o root -g bin src/hashmatchstr ${BINDIR}/hashmatchstr install -m 0755 -o root -g bin src/tabr_adduser.sh ${SBINDIR}/tabr_adduser install -m 0755 -o root -g bin src/tabr_passwd.sh ${SBINDIR}/tabr_passwd install -m 0755 -o root -g bin src/tabr_deluser.sh ${SBINDIR}/tabr_deluser install -m 0644 -o root -g wheel src/tabr.conf /etc/ ``` Remarquez la ligne avec "-m 0730" qui permet de restreindre l'accès au dossier qui contiendra les requêtes pour changer de mot de passe. Enfin, parce que ça me manque dans de nombreux Makefile, je prévois de quoi faire le ménage: ``` uninstall: rm -rf ${CGIDIR}/tabr_chpw.cgi rm -f ${BINDIR}/hashmatchstr rm -f ${BINDIR}/tabr_adduser rm -f ${BINDIR}/tabr_passwd rm -f ${BINDIR}/tabr_deluser @printf "You probably should remove %s and %s too\n"\ "${CHPWREQDIR}" "/etc/tabr.conf" ``` Voilà de quoi me simplifier la vie et proposer des services à ma famille. Ici, je n'ai présenté que le mail et xmpp, mais il y en a en réalité un peu d'autres de prévus : dokuwiki (grâce à son interface de gestion des utilisateurs en CLI) qui offre un espace de publication ET de stockage. Il faut juste bien ajuster les ACL. => /contact/ J'y pense, si ça intéresse quelqu'un, je peux vous proposer une adresse en @si3t.ch, il suffit de me faire signe. ## Une réaction? => mailto:prx@si3t.ch?subject=TaBr-Makefile-part5 Envoyez votre commentaire par mail (anonyme). ]]> TaBr - tabr_chpw_cgi interface web pour réclamer un autre mot de passe https://si3t.ch/log/2023-05-15-TaBr-part4-tabr_chpw_cgi.txt 2023-05-15T14:10:19Z /img/log/tabr-oubli.png Aperçu de l'interface Oui, c'est il n'y a pas de paillettes, d'animations ou de boutons de partages vers les réseaux sociaux. Mais c'est accessible et ça fonctionne dans n'importe quel navigateur, même lynx. Moi, je trouve ça beau :P On remarque 4 champs : * le nom d'utilisateur, normal * son code de récupération. Merci le html5 pour proposer un placeholder, bien que ça ne soit pas forcément utile (c'est facile de mettre un exemple à côté du label du champ. * le nouveau mot de passe demandé (normal). * un captcha aléatoire. À propos du html5, je m'en sers pour valider au maximum ce que les utilisateurs proposent (longueur du mot de passe, validité du nom d'utilisateur...). Cependant, il vaut mieux revérifier ensuite, je ne vais pas confiance à tous les navigateurs pour supporter ces éléments correctement. ## Le code Le code est du C. C'est quelque chose que je maîtrise et qui me permet de profiter sans difficultés des générateurs de nombres aléatoires avec arc4random, de unveil, de pledge... Puisque c'est un peu long (~246 lignes uniques), je vais me concentrer ici seulement sur les parties "intéressantes". ### config.h On configure directement en C. On y trouve des variables, et surtout les templates html. Ces derniers ne sont pas très propres car il y a beaucoup de guillemets échappés, mais ce n'est pas quelque chose qu'on édite souvent. Par exemple, on y définit le dossier (à l'intérieur du chroot) où seront stockées les demandes de changement de mot de passe: ``` static const char *chpw_requests_dir = "/tabr_chpw_requests"; ``` On y voit aussi les différents types de captchas possibles avec les consignes associées: ``` /* captcha config */ enum { DIGIT, LOWER, UPPER, PUNCT }; /* instructions displayed for humans, same order as above! */ static const char *instructions[] = { "Recopiez uniquement les chiffres", "Recopiez uniquement les lettres minuscules", "Recopiez uniquement les lettres majuscules", "Recopiez uniquement les symboles et ponctuation", }; ``` Au niveau des templates html, je veux être sûr que la page ne soit pas mise en cache (avec un succès limité): ``` "\n" "\n" "\n" ``` j'attire votre attention sur la validation des champs. Un "title" permet de préciser ce qui est attendu à chaque fois. ``` "

\n" "\n" "\n" ``` Ici, le "pattern" me permet de reproduite une regex trouvée dans le code de "adduser", en la modifiant un peu au passage. Qui voudrait d'un nom d'utilisateur terminant pas "$"??? J'impose aussi 15 caractères pour le nouveau mot de passe: ``` "

\n" "

\n" "\n" ``` Pour le captcha, il y a les "%s" qui me permettront d'y mettre ce que je veux le moment voulu, puisque c'est une énigme aléatoire à chaque fois: ``` "
\n" "

%s

\n" "
%s
\n" "\n" "
\n" "
\n" "\n" "
\n" ``` Pour finir, il y a les messages d'erreur affichés selon les cas: j ``` /* error messages */ static const char *errcaptcha = "Mauvaise réponse! 😱"; static const char *errusername = "Mauvais format. Le nom d'utilisateur doit avoir une longueur entre 1 et 31 caractères, ne peut pas commencer par un \"-\" et ne peut contenir que les symboles suivants: \"abcdefghijklmnopqrstuvwxyz0123456789-_.\""; static const char *errshortpw = "Mot de passe trop court : au moins 15 caractères sont attendus. Une phrase peut fonctionner."; ``` ### main.c C'est ici que le vrai code commence. Mais avant d'aller plus loin, je vais me préparer un petit café à partager avec vous. > ☕ Slurp! Je vous avais promis du unveil et du pledge. Rien de plus simple, on n'autorise l'accès que au dossier contenant les requêtes pour pouvoir y créer des fichiers avec unveil, et on promet seulement des entrée/sorties et écritures dans des fichiers avec pledge: ``` #ifdef __OpenBSD__ /* if (unveil(chpw_requests_dir, "rwc") == -1) err(1, "unveil"); unveil(NULL, NULL); if (pledge("stdio cpath wpath", NULL) == -1) err(1, "pledge"); */ #endif ``` Avant d'aller plus loin, on va faire patienter un peu celui ou celle qui fait la requête avec un appel à "sleep". Le nombre de secondes d'attente sera aléatoire grâce à arc4random_uniform: ``` sleep(arc4random_uniform(MAXWAIT)); ``` On regarde maintenant si on doit traiter une demande. Cette dernière est passée en entrée, donc on lit stdin avec fgets: ``` if (fgets(rawpost, sizeof(rawpost), stdin) == NULL) if (ferror(stdin)) http400("Request too long ?"); ``` On note au passage la fonction "http400", qui au même titre que "http500" permet de renvoyer le code d'erreur au navigateur si beosin et d'afficher un petit message en passant. Dans le cas où il n'y a pas de demande à traiter, on affiche un formulaire vide. ``` if (strlen(rawpost) == 0) { while (strlen(secret) < 6) { //secret[0] = '\0'; memset(secret, '\0', sizeof(secret)); rdmstr(question, sizeof(question)); secret_class = strtosecret(question, secret); } ``` Ici, je cherche à créer une chaîne de caractère aléatoire suffisamment longue, d'où la boucle "while" qui se répète tant que la longueur est inférieure à 6. À chaque tour, memset() s'assure que le chaîne est bien vide, puis un appel à rdmstr() permet d'obtenir une chaîne aléatoire. ``` size_t rdmstr(char *s, size_t len) { /* fill s with random chars */ size_t l=0; const char charset[] = "0123456789" "abcdefghijklmnopqrstuvwxyz" "ABCDEFGHIJKLMOPQRSTUVWXYZ" "-_+~#()%,?;.:/!="; for (size_t i = 0; i < len; i++) { s[i] = charset[arc4random_uniform(strlen(charset))]; l++; } s[len] = '\0'; return l; } ``` Cette fonction pioche dans la liste de caractères définie dans "charset" grâce à arc4random_uniform(). Notez que je n'ai choisi que des caractères spéciaux assez faciles d'accès sur un clavier (de smartphone notamment). On pourrait y ajouter des espaces et d'autres symboles plus étranges encore. On peut aussi prciser plusieurs fois un caractère si on veut augmenter sa probabilité d'apparaître. Je n'ai pas mis d'espace, j'ai pensé que ça pourrait prêter à confusion. S'ensuit la fonction strtosecret qui va choisir une classe de caractères à recopier et qui constituera la réponse au captcha: ``` int strtosecret(const char *s, char *secret) { /* choose a random class of char * secret is all char of the selected class * from string s */ int char_classes[] = { DIGIT, LOWER, UPPER, PUNCT }; int char_class = char_classes[arc4random_uniform(LEN(char_classes))]; for (size_t i=0; i < strlen(s); i++) { switch (char_class) { case DIGIT: if (isdigit(s[i])) secret[strlen(secret)] = s[i]; break; case LOWER: if (islower(s[i])) secret[strlen(secret)] = s[i]; break; case UPPER: if (isupper(s[i])) secret[strlen(secret)] = s[i]; break; case PUNCT: if (ispunct(s[i])) secret[strlen(secret)] = s[i]; break; } } return char_class; } ``` Vous l'aurez compris, cette fonction lit la chaîne caractère par caractère et le recopie s'il correspond à la condition choisie aléatoirement. La classe de caractère choisie est retournée pour savoir quelle consigne afficher à l'utilisateur. On transforme la réponse en hash avec crypt_newhash(), pour permettre la vérification du captcha ensuite: ``` if (crypt_newhash(secret, "bcrypt,a", anshash, sizeof(anshash)) != 0) ``` Reste à afficher le formulaire: ``` http200("text/html; charset=utf-8"); printf(form, instructions[secret_class], question, anshash ); ``` Si au contraire on a reçu des données, il faut traiter la demande. Pour cela, on va découper le texte d'entrée: ``` get_post_field("user=", rawpost, user); get_post_field("recovery=", rawpost, recovery); get_post_field("newpass=", rawpost, newpass); get_post_field("answer=", rawpost, answer); get_post_field("anshash=", rawpost, anshash); ``` La fonction get_post_field recherche dans "rawpost" la chaîne passée en premier argument et l'enregistre dans la dernière variable. Regardons-là de plus près: ``` char * get_post_field(const char *str, const char *post, char *field) { char *pos = NULL; char buf[BUFSIZ] = {'\0'}; char *r = strdup(post); char *tofree = r; char *tok = NULL; while ((tok = strsep(&r, "&")) != NULL) { if ((pos = strstr(tok, str)) == NULL) { continue; } else { if (strlcpy(buf, tok + strlen(str), sizeof(buf)) >= sizeof(buf)) http500("strlcpy"); break; } } if (urldecode(buf, field) < 0) http400("Bad request"); free(tofree); return field; } ``` On remarque qu'elle fait appel à strsep(). Cette fonction modifie la chaîne, c'est pourquoi on a utilisé strdup() au préalable, et enregistré dans tofree la référence au pointeur qu'il faudra libérer avec free() ensuite. Une fois ces éléments rassemblés, on va vérifier que le nom d'utilisateur correspond à une regex: ``` if (regcomp(®_username, valid_username_regex, REG_EXTENDED) != 0) { regfree(®_username); http500("can't compile regex"); } if (regexec(®_username, user, 0, NULL, 0) != 0) { regfree(®_username); http400(errusername); } regfree(®_username); ``` Ici, regex.h n'est pas trop compliqué à utiliser puisqu'il s'agit de seulement vérifier si "ça match". Plus simple, on vérifie juste si le nouveau mot de passe demandé est assez long: ``` if (strlen(newpass) < 15) http400(errshortpw); ``` Oui, 15 seulement... On va me détester si j'impose +. Reste à enregistrer la demande dans un fichier portant le nom d'utilisateur. La suite est donc un peu barbante, il s'agit juste de créer un chemin puis d'écrire dedans: ``` /* build the path to file with request */ if ((strlcpy(request_file, chpw_requests_dir, sizeof(request_file)) > sizeof(request_file)) || (strlcat(request_file, "/", sizeof(request_file)) > sizeof(request_file)) || (strlcat(request_file, user, sizeof(request_file)) > sizeof(request_file))) http500("strlcpy & strlcat"); /* open the file and save data */ f = fopen(request_file, "w"); if (f == NULL) http500("can't open file to write"); fprintf(f, "%s\n", recovery); fprintf(f, "%s\n", newpass); fclose(f); ``` Je termine en faisant un petit chmod afin de limiter qui aura accès à ce fichier. ``` chmod(request_file, S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH ); ``` C'est le point dont je suis le moins satisfait, mais je n'ai pas trouvé mieux car: * httpd (slowcgi) doit pouvoir écrire dans les fichiers. Le propriétaire est donc "www". * _tabr_admin doit pouvoir lire ces fichiers. Cependant, ce dernier n'appartient pas au groupe "www". Par conséquent, ces fichiers sont lisibles par tous. TOUTEFOIS, le dossier dans lequel ils sont stockés n'est accessible en lecture QUE par _tabr_admin. L'utilisateur www ne peut que écrire dedans, et les autres n'ont aucune permission : ``` drwx-wx--- 2 _tabr_admin www 512 May 13 13:39 tabr_chpw_requests ``` C'est LA partie de l'installation à ne pas rater. Heureusement, un petit Makefile est prévu pour ça. On en parle dans le prochain article :) ## Une réaction? => mailto:prx@si3t.ch?subject=TaBr-tabr_chpw_cgi-part4 Envoyez votre commentaire par mail (anonyme). ]]>
TaBr - tabr_passwd pour modifier un mot de passe https://si3t.ch/log/2023-05-15-TaBr-part3-tabr_passwd.txt 2023-05-15T13:54:04Z " exit 1 } ``` Ensuite, voici une fonction qui va se charger de terminer le script en alertant dans tous les cas l'admin. D'ailleurs, on voudra sans doute créer un alias dans "/etc/mail/aliases" pour rediriger le mail ``` end() { # $1 : file # $2 : message # $3 : exit code ## alert root cat << EOF | mail -s "$(basename $1) password change request" ${admin} $1 was created to change password and returned: $2 EOF rm -f "$1" exit $3 } ``` On voit dans cette fonction qu'elle envoie un mail à l'admin définit dans "/etc/tabr.conf" indiquant qu'il y a eu demande de changement de mot de passe. Ensuite, on indique un éventuel message d'erreur. Dans tous les cas, on supprime le fichier de demande de changement de mot de passe avant de quitter. On peut passer à la fonction qui va se charger de traiter la demande: ``` handle_request() { u="$(basename ${1})" ## check if user is indeed registered [[ -e $data/$u ]] || end "${1}" "No user $u found" 1 ``` Cette fonction prend en argument le chemin complet vers le fichier de demande de changement. Ce fichier porte le nom de l'utilisateur, on le met dans une variable "$u" comme à l'accoutumée. On vérifie avant d'aller plus loin qu'on a bien un fichier de récupération pour l'utilisateur en question. ``` ## check if recovery match user hashed recovery # recovery is on first line #recovery="$(sed -n '1p' ${1})" head -n 1 "${1}" | /usr/local/bin/hashmatchstr $(cat ${data}/${u}) \ || end "${1}" "Wrong recovery code" 1 ``` On vérifie ici que le code de récupération précisé par l'utilisateur correspond au hash de ce code enregistré lors de l'inscription. Pour cela, on utilise un bout de C "hashmatchstr". => /log/2023-05-04-Check-if-a-string-match-a--bcrypt--hash.xhtml hasmatchstr fait appel à la fonction "crypt_checkpass". Ensuite, on récupère le mot de passe demandé et on procède aux modification: ``` newpw="$(sed -n '2p' ${1})" # pw on 2nd line newpwhash="$(print "%s" "${newpw}" | encrypt -b a )" ## change system pw doas /usr/sbin/usermod -p "${newpwhash}" "${u}" ## xmpp printf "%s\n%s\n" "${newpw}" "${newpw}" | doas /usr/local/sbin/prosodyctl passwd "${u}@${domain}" end ${1} "Everything seems OK" 0 } ``` usermod attend le hash du mot de passe, d'où l'appel à "encrypt". Vous noterez ici la petite astuce avec "printf" pour prosody qui attend le nouveau mot de passe en entrée. Enfin, on appelle la fonction ci-dessus par une boucle sur tous les fichiers du dossier passé en argument. On se sert pour cela de "find", c'est plus propre et gère les éventuels noms de fichiers chelous (je ne fais pas confiance à ce qu'un petit malin a pu éventuellement réussir à déposer malgré toutes mes précautions). ``` [[ $# -ne 1 ]] && usage # loop over file lists find "$1"/ -type f | while read -r request_file; do handle_request "${request_file}" done ``` Ces fichiers contenant les requêtes peuvent être créés via un script, appelé via l'instruction "ForceCommand" lors d'une connexion SSH. Cependant, ce n'est pas très facile d'accès pour les gens normaux. Aussi, j'ai prévu un petit code CGI afin de demander le changement de mot de passe en ligne. Mais ça, c'est pour le prochain article ^^ ## Une réaction? => mailto:prx@si3t.ch?subject=TaBr-tabr_passwd-part3 Envoyez votre commentaire par mail (anonyme). ]]> TaBr - tabr_deluser pour supprimer un utilisateur https://si3t.ch/log/2023-05-14-TaBr-part2-tabr_deluser.txt 2023-05-14T21:38:21Z \n" $0 exit 1 } ## get arguments into variables [[ -z "${1}" ]] && usage ``` Vous noterez ici que j'utilise un test "si chaîne nulle" et non "si nombre d'argument est égal à 1". C'est parce que j'ai passé le flag "-e" au shebang, qui provoque l'arrêt du script en cas d'erreur. Or, si un test échoue, c'est considéré comme une erreur. Pour simplifier la suite, on met le nom d'utilisateur dans une variable: ``` u="${1}" ``` Et c'est tout, on peut supprimer l'utilisateur: ``` ## system user doas /usr/sbin/userdel -r "${u}" ``` Vous noterez l'option "-r" qui permet de supprimer aussi le dossier personnel de l'utilisateur. ``` ## xmpp account doas /usr/local/sbin/prosodyctl deluser "${u}@${domain}" ``` On en fait de même avec prosody. Si on avait ajouté l'utilisateur à une installation dokuwiki, on pourrait aussi avoir ensuite: ``` php /path/to/dokuwiki/bin/plugin.php usermanager delete hseldon ``` Pour terminer, on supprimer les fichiers qui contenaient le code de récupération et les instructions destinées à l'utilisateur: ``` ## recovery file rm ${data}/${u} ## instructions rm "${data_instructions}/${u}.txt" ``` Et voilà! Prochains articles : on décrit le changement de mot de passe, et l'interface CGI qui permettra de faire la demande. ## Une réaction? => mailto:prx@si3t.ch?subject=TaBr-tabr_deluser-part2.gmi Envoyez votre commentaire par mail (anonyme). ]]> TaBr - tabr_adduser pour ajouter un utilisateur au serveur familial https://si3t.ch/log/2023-05-13-TaBr-part1-tabr_adduser.txt 2023-05-13T13:22:25Z \n" "$0" printf "if not specified, a random recovery-passphrase will be generated\n" exit 1 } ``` Voici une fonction pour générer un mot de passe aléatoire: ``` genpw() { #jot -rcs '' $1 33 126 tr -cd '[:alnum:]~#()%@,?;.!*' < /dev/urandom |\ fold -w $1 | head -n 1 } ``` Comme on peut le voir, j'ai commenté une version avec "jot" qui proposait une suite aléatoire de tous les caractères entre le n°33 et le 126 (voir man ascii). Cependant, j'ai opté pour une solution avec "tr" me laissant le choix des caractères possibles. J'en reste donc aux lettres, chiffres et ponctuation habituelle. Cela évite pour les utilisateurs moins à l'aise de devoir fouiller dans le clavier de leur smartphone. Ensuite, on génère un code de récupération aléatoire: ``` rdm-recovery-pass() { genpw 30 | sed -E 's/^(.{6})(.{6})(.{6})(.{6})/\1-\2-\3-\4-/' } ``` L'appel de "sed" permet d'insérer des tirets "-" à intervalles réguliers pour faciliter la saisie ensuite. On s'assure ensuite qu'on a bien le bon nombre d'arguments pour le bon fonctionnement du script: ``` ## get arguments into variables [[ $# -ge 1 ]] && [[ $# -lt 3 ]] || usage ``` On met le nom d'utilisateur dans une variable plus facile à identifier: ``` u="${1}" ``` S'ensuit un test pour vérifier si une phrase de récupération a été précisée. Je pense notamment à ma famille pour qui il serait facile de proposer des phrases faciles à retenir en référence à un vécu commun. Sinon, un code de récupération est généré. ``` [[ -z "${2}" ]] && recovery="$(rdm-recovery-pass)" || recovery="${2}" ``` On vérifie si un utilisateur au nom de celui demandé existe déjà: ``` ## check if user already exist id -u $u > /dev/null 2>&1 && die "User already exists" #[[ -e $data/$u ]] && die "User already exists" # commented, previous is safer ``` On génère un mot de passe totalement aléatoire. J'ai choisi une longueur de 16 caractères. On peut bien sûr faire mieux, mais si j'en rajoute, on va m'envoyer des cailloux. ``` ## generate random password pw="$(genpw 16)" ``` On enregistre le code de récupération dans un fichier portant le nom de l'utilisateur (unique), situé dans un dossier qui appartient à _tabr_admin, dont seul _tabr_admin a accès. C'est en réalité dans un dossier de son répertoire personnel, dont j'ai ajusté le spermissions en 0700. ``` ## store recovery pass encrypt -b a ${recovery} > $data/$u ``` On crée l'utilisateur système. ``` ## create system user doas /usr/sbin/useradd -m -g $usergroup -s /sbin/nologin -p "$(encrypt -b a "${pw}")" "$u" ``` Cet utilisateur peut recevoir des mails puisque dovecot et smtpd sont configurés pour utiliser le processus de login de l'OS. On remarque plusieurs choses dans cette commande: * On crée un $HOME à l'utilisateur (-m) * On demande à ce qu'il appartienne au groupe _tabr_users * On lui attribue le shell /sbin/nologin. Autrement dit, il est désactivé. * On définit aussitôt son mot de passe en passant le hash de ce dernier avec la commande "encrypt" . On peut désormais créer le compte xmpp. Ici, il y a une petite bidouille pour passer le mot de passe avec printf: ``` ## create xmpp account printf "%s\n%s\n" "${pw}" "${pw}" | doas /usr/local/sbin/prosodyctl adduser "${u}@${domain}" ``` On termine par générer les instructions à envoyer qui seront stockées dans un fichier puis affichée. Libre à l'admin d'envoyer/imprimer/...? ce fichier texte. ``` ## generate notice with qr code print_notice "${u}" "${pw}" "${recovery}" > ${data_instructions}/${u}.txt cat ${data_instructions}/${u}.txt ``` Enfin, on rappelle à l'admin de supprimer le fichier contenant les données du nouvel utilisateur rapidement, une fois qu'elles ont été transmises: ``` print "*** WARNING ***\n%s\n" \ "You probably should delete ${data_instructions}/${u}.txt very soon" ``` ## Une réaction? => mailto:prx@si3t.ch?subject=TaBr-tabr_adduser-part1 Envoyez votre commentaire par mail (anonyme). ]]> TaBr - gestion d'un serveur familial partie 1 https://si3t.ch/log/2023-05-12-TaBr-suite-gestion-serveur.txt 2023-05-12T13:59:15Z https://si3t.ch/ah/fr/#_89_SFTPdansunchroot Pour la mise en place d'un chroot SFTP, c'est facile. 4 composants sont prévus : * tabr_adduser : pour ajouter les utilisateurs. Il crée au passage un code de récupération pour changer le mot de passe. * tabr_deluser : supprime un utilisateur et toute référence à ce derier * tabr_passwd : traite les demandes de changement de mot de passe. Il sera appelé via une tâche cron. * tabr_chpw_cgi : une interface web pour demander le changement de mot de passe. Pour un public un peu plus geek, j'utiliserais plutôt une identification par clé ssh et un script appelé à la connexion avec "ForceCommand". On détaillera chaque composants dans une série d'articles à venir. Pour finir celui-ci, je vous présente seulement le fichier Makefile qui permet l'installation: ``` # tabr suite # prx # Quelques variables... PREFIX ?=/usr/local BINDIR ?=${PREFIX}/bin SBINDIR ?=${PREFIX}/sbin CGIDIR ?=/var/www/cgi-bin CHPWREQDIR ?=/var/www/tabr_chpw_requests # Tout ce qu'il faudra compiler all: src/tabr_chpw_cgi src/hashmatchstr # chpw_cgi sera à recompiler si on modifie sa configuration src/chpw_cgi/main.c: src/chpw_cgi/config.h # Comment compiler tabr_chpw_cgi. # On utilise -static car il sera dans un chroot src/tabr_chpw_cgi: src/chpw_cgi/main.c ${CC} -static -o $@ $? # Compilation de hashmatchstr, l'outil # qui permet de comparer les hash et les passwords src/hashmatchstr: src/hashmatchstr.c ${CC} -o $@ $? # On prévoit comment remettre à zéro clean: rm src/tabr_chpw_cgi rm src/hashmatchstr # Installation des fichiers. # On utilise la commande install pour # gérer finement les permissions install: src/tabr_chpw_cgi src/hashmatchstr install -o root -g daemon -m 0755 src/tabr_chpw_cgi ${CGIDIR}/tabr_chpw.cgi @# IMPORTANT: chmod 730, www can write but can't read install -o _tabr_admin -g www -m 0730 -d ${CHPWREQDIR} install -m 0755 -o root -g bin src/hashmatchstr ${BINDIR}/hashmatchstr install -m 0755 -o root -g bin src/tabr_adduser.sh ${SBINDIR}/tabr_adduser install -m 0755 -o root -g bin src/tabr_passwd.sh ${SBINDIR}/tabr_passwd install -m 0755 -o root -g bin src/tabr_deluser.sh ${SBINDIR}/tabr_deluser install -m 0644 -o root -g wheel src/tabr.conf /etc/ # On prépare aussi le nettoyage uninstall: rm -rf ${CGIDIR}/tabr_chpw.cgi rm -f ${BINDIR}/hashmatchstr rm -f ${BINDIR}/tabr_adduser rm -f ${BINDIR}/tabr_passwd rm -f ${BINDIR}/tabr_deluser @printf "You probably should remove %s and %s too\n"\ "${CHPWREQDIR}" "/etc/tabr.conf" ``` ## Une réaction? => mailto:prx@si3t.ch?subject=TaBr-suite-gestion-serveur Envoyez votre commentaire par mail (anonyme). ]]> Check if a string match a (bcrypt) hash https://si3t.ch/log/2023-05-04-Check-if-a-string-match-a--bcrypt--hash.txt 2023-05-04T16:55:17Z #include #include #include #include #include /* compare password passed on stdin with hash passed as argv[2] */ int main(int argc, char *argv[]) { char pw[LINE_MAX] = {'\0'}; if (argc != 2) errx(1, "usage: printf \"pw\" | %s ", argv[0]); if (fgets(pw, LINE_MAX, stdin) == NULL) err(1, "fail to read from stdin"); pw[strcspn(pw, "\n")] = '\0'; /* remove ending \n if any */ if (crypt_checkpass(pw, argv[1]) != 0) return 1; printf("match \\o/\n"); return 0; } ``` ]]> Un serveur pour les communications familiales https://si3t.ch/log/2023-05-01-family-server.txt 2023-05-01T14:18:46Z Allez, ça serait quand même bien que vous mettiez Whatsapp, comme ça on pourrait créer un groupe. Ça serait vachement sympa pour les photos des enfants. Et puis c'est pas pratique les SMS groupés, on ne sait jamais trop si on répond à tout le monde. Alors non, Whatsapp, vraiment pas. GAFAM, vie privée, données personnelles, tout ça tout ça. Mais je sais bien au fond de moi que les photos envoyées par MMS, ce n'est pas tellement privé non plus finalement. Alors si je refuse, que puis-je proposer à la place? => https://delta.chat/fr/ Deltachat est génial en remplacement. Il suffit d'une adresse mail, que tout le monde a. Encore faut-il, si je veux pleinement garder le contrôle sur les photos de famille, que tout le monde utiliser un serveur mail adapté -- PAS GMAIL. J'ai la chance d'avoir un serveur à la maison, je peux donc en théorie créer un compte mail pour chaque personne dans la famille. C'est un peu pénible pour moi, et j'entends déjà les "j'ai oublié mon mot de passe :s". Ceci dit, ça pourrait être un joli cadeau de Noël un jour pour tout le monde : une adresse mail propre gérée à la maison. Bon, sinon, il y a Signal. Cependant, ça m'ennuie vraiment de devoir m'appuyer sur un système qui n'existera peut-être plus dans 5 ans. C'est aussi le cas pour Deltachat en théorie, même si le mail sur lequel cet outil repose restera toujours fonctionnel. Un autre défaut à Deltachat qui pourtant semble quasi-parfait avec son système d'invitation une fois l'effort de créer des comptes mails à tout le monde : il n'y a pas de client disponible sous OpenBSD. Je rêve juste d'un petit client en console, même pas besoin du gros machin GUI. Un jour peut-être ^^. Ceci dit, Deltachat pose le souci de pouvoir lire les messages qui ont été chiffrés avec un client mail aute que celui de DeltaChat. Ça risque d'en perturber quelques uns. Une autre idée que je souhaite tester, ce serait d'utiliser mon serveur XMPP. J'ai pensé à utiliser le système d'invitations. Cependant, ce n'est pas si simple pour quelqu'un n'ayant pas trop l'habitude des clients XMPP (mais je conseille vivement mod_invites). Je me suis demandé aussi si prévoir un répertoire LDAP avec identifiants pour chaque user ne serait pas pratique, mais il faut avouer que l'intégration de LDAP n'est pas très bien documentée. En tout cas, pas assez pour moi. De plus, ça signifie que chaque service soit capable de parler LDAP, donc chacun de ces services est une nouvelle voie d'accès pour des attaques sur le serveur afin de piquer les identifiants de quelqu'un. Je préfère les choix par défaut des développeurs, c'est + sûr. Il faut me rendre à l'évidence : je vais créer des comptes pour chacun. À moi de réfléchir à une façon de leur permettre de changer/récupérer leurs mots de passe. Non seulement cela m'évitera d'intervenir, mais m'évitera d'avoir connaissance de ces identifiants. Pour l'instant, j'envisage les choses ainsi: * Création d'un compte avec mot de passe aléatoire ainsi qu'un code de récupération, une sorte de longue phrases. À la création, une fiche imprimable avec un QR code contenant les instructions et codes de récupération sera généré : c'est ce que j'enverrai à mes proches. * Interface pour changer le mot de passe via un script CGI. Je me rend compte que le faire via gemini serait presque plus sûr puisque ça permettrait d'utiliser les certificats utilisateurs plutôt qu'un mot de passe, mais bon, mes proches n'en sont pas là. Pour l'instant, ça sera derrière une authentification http (htpasswd). * Pour aller + loin, pour les + geeks, on pourrait envisager plutôt d'utiliser les clés SSH, avec un ForceCommand qui appelerait un script permettant le changement de mot de passe. * Le changement de mot de passe modifiera pour chacun des services : mail, xmpp, dokuwiki, ... que sais-je? Tout ceci devrait être scripté pour faciliter l'automatisation. > Mais tu recrées un CHATONS en fait? C'est un peu l'idée, alors que dernièrement avec les 3hg on a quitté le collectif CHATONS. Ce que j'envisage de faire ici sera à une bien plus petite échelle, avec 1 seul domaine. De plus, je n'ai pas le temps de participer au collectif, alors s'estampiller membre des CHATONS semblait un peu trop hypocrite. Par ailleurs, ça sera nettement mieux organisé. Je me laisse le temps :) Quoi qu'il en soit, ce ne sont que des idées pour l'instant : c'est parti pour le code! ## Une réaction? => mailto:prx@si3t.ch?subject=family-server Envoyez votre commentaire par mail (anonyme). ]]> random passwords from manpages https://si3t.ch/log/2023-04-23-random-passwords-from-manpages.txt 2023-04-23T13:45:12Z # usage : rdmempw.sh (default: 6) # default is 6 words [[ $1 -gt 0 ]] && w=$1 || w=6 # find a random manpage manpage="$((apropos -s 1 .; apropos -s 5 .; apropos -s 6 .) |\ sort -R |\ awk '{sub("\\(.*|,", "", $1); print $1; exit}')" man $manpage |\ tr " " "\n" |\ sort -Ru |\ awk -v w="$w" ' # keep only word at least 4 char long /^[[:alnum:][:digit:]]{4,}$/ { pw = pw $0 n++ if (n > w) { exit } pw = pw "-" } END { print pw } ' ``` As you can see, "apropos" gives a list of availables manpages. I only use sections 1, 5 and 6 since the others are quite complex. I use a lot of "sort -R" to randomize the wordlists. Then, "awk" print the manpage, removing parentheses. After, I call "man" and "tr" to replace every spaces with newlines so I can randomize with "sort" the wordlist. "awk" is used again to store words long enough in a string. When anough words are picked, we exit and display the password. I guess it could be faster by using a cache. ## Comments? => mailto:prx@si3t.ch?subject=random-passwords-from-manpages Comments by mail ]]> Configurer unwind pour limiter la censure https://si3t.ch/log/2022-11-17-unwind-config-no-censorship.txt 2022-11-17T11:08:23Z mailto:prx@si3t.ch?subject=unwind-config-no-censorship Envoyez votre commentaire par mail. ]]> match : dmenu ou pick https://si3t.ch/log/2022-09-17-match-finder.txt 2022-09-17T21:00:39Z https://tools.suckless.org/dmenu dmenu => https://github.com/mptre/pick pick => https://github.com/jhawthorn/fzy fzy => https://pedantic.software/git/choice choice ## Une réaction? => mailto:prx@si3t.ch?subject=match-finder Envoyez votre commentaire par mail. ]]> I installed squirrelmail on OpenBSD again https://si3t.ch/log/2022-09-14-squirrelmail-nice-webmail.txt 2022-09-14T15:52:05Z https://squirrelmail.org Squirrelmail is an old webmail. "Old" since it looks old. Actually, it doesn't even require javascript. And that's fine to me, I'm self-hosting and only need a webmail access for friends who don't configure a mail client. It is a very simple software, light and easy to set up compared to big alternatives. No database, no mess. Just PHP. Good news, PHP-8 is supported. So, I installed squirrelmail and it feels great. => https://0x0.st/oOQu.png This is how it looks with custom CSS. ## Notes to install squirrelmail on OpenBSD ### Install files and set permissions ``` mkdir /var/www/htdocs/webmail/ cd /var/www/htdocs/webmail ftp -o squirrelmail.tar.gz https://squirrelmail.org/countdl.php?fileurl=http%3A%2F%2Fsnapshots.squirrelmail.org%2Fsquirrelmail-20220914_0200-SVN.stable.tar.gz ftp -o locales.tar.gz https://squirrelmail.org/countdl.php?fileurl=http%3A%2F%2Fsnapshots.squirrelmail.org%2Fsquirrelmail-20220914_0200-SVN.locales.tar.gz for i in *.tar.gz; do tar xvzf $i; done mv squirrelmail.stable squirrelmail rm *.tar.gz cp -r squirrelmail.locales/locale/fr_FR squirrelmail/locale/ cp -r squirrelmail.locales/images/*fr_FR* squirrelmail/images/ cp -r squirrelmail.locales/help/fr_FR squirrelmail/help/ rm -r squirrelmail.locales mkdir -p {data,temp} chown -R www:daemon . chmod -R 750 . chmod 0730 data chmod 0730 temp ``` ### Configure ``` cd squirrelmail/config ./conf.pl ``` Have fun in Organization Preferences and Server Settings. Defaults are fine if webmail is on the same machine that the mail server. Just make sure in "General Options" to set : ``` 1. Data Directory : ../data/ 2. Attachment Directory : ../temp/ ``` ### Configure httpd I suppose here you already have a SSL certificate. ``` server "squirrelmail.host.tld" { listen on * port 80 no log location * { block return 301 "https://$SERVER_NAME$REQUEST_URI" } } server "squirrelmail.host.tld" { root "/htdocs/squirrelmail.host.tld/squirrelmail" connection max request body 36700160 directory index index.php listen on * tls port 443 hsts preload hsts subdomains tls { certificate "/etc/ssl/host.tld.crt" key "/etc/ssl/private/host.tld.key" ticket lifetime default } location "*.php*" { fastcgi socket "/run/php-fpm.sock" } location "/.well-known/acme-challenge/*" { root "/acme" request strip 2 } # block everything not listed in .htaccess location "README" { block } location "class" { block } location "config" { block } location "configure" { block } location "contrib" { block } location "data" { block } location "doc" { block } location "functions" { block } location "help" { block } location "include" { block } location "locale" { block } location "po" { block } } ``` ### Subscribe => https://squirrelmail.org/docs/admin/admin-12.html#mailinglists subscribe to annouces to get important notices. ]]> Je n'aurai plus d'enfants https://si3t.ch/log/2022-08-25-sterile.txt 2022-08-25T15:01:30Z https://boris.schapira.dev/notes/2021-06-je-ne-ferai-plus-d-enfants/ Il s'appelait je crois "je n'aurais plus d'enfants", je reprends donc le même titre en guise d'hommage. Si vous l'avez épinglé, merci de m'envoyer le lien que je l'indique en référence. Je vais donc suivre son modèle et expliquer comment j'ai vécu cette vasectomie, histoire de déconstruire quelques idées reçues. 😉 ## La vasectomie, c'est quoi ? C'est une méthode de contraception masculine définitive. L'opération bénigne consiste à sectionner les canaux déférents. C'est juste les petits tuyaux qui permettent aux spermatozoïdes d'aller se mélanger au sperme. Après, le sperme est 100% spermato-free. C'est tout. ## Pourquoi cette décision Subir une vasectomie est un choix personnel, et je n'ai pas pour objectif de convaincre qui que ce soit. Je ne souhaite plus d'enfants. C'est fiable à 99%, le 1% restant étant dû à un mauvais suivi des recommandations juste après l'opération : il peut persister des spermatozoïdes vivants dans les tuyaux pendant encore 3 mois. Il faut donc poursuivre une contraception pendant 3 mois, après c'est réglé. Il existe d'autres méthodes contraceptives, le caractère définitif de la vasectomie peut rassurer : il n'y a pas un préservatif à enfiler au dernier moment ou une pilule à prendre à heure fixe quotidiennement. Alors que j'étais fertile tous les jours, c'était pourtant ma conjointe qui prenait la pilule. Ma conjointe qui, pour sa part, n'est fertile que quelques jours par mois. Chaque jour, il fallait penser à cette pilule, et cette charge mentale est pénible, voire stressante. La pilule, c'est un traitement hormonal avec de nombreux effets secondaires : * Maux de tête * Troubles de l'humeur * Baisse de la libido * Risque de thrombose * Prise de poids * (je note pas tout, il y en a d'autres) et je ne parle pas des stérilets... Alors que la vasectomie, les effets secondaires, c'est peau de zob si j'ose dire. ## Effets secondaires? ## Sur le long terme Rien. * Non, il n'y a pas de baisse de la libido. * Les testicules sont toujours là et bien branchées. Pas de modifications hormonales donc. Bref, tout est comme avant, sauf que les spermatozoïdes restent bien au chaud. ### Juste après l'opération J'insiste sur le fait qu'il s'agit de mon expérience personnelle. J'imagine qu'on ne réagit pas tous de la même façon à une intervention chirurgicale. En tout cas, pour ma part, si je n'avais pas su que j'avais subi cette opération, je n'aurai pas vu grande différence. Les points ont tiré un peu lorsqu'ils s'accrochaient dans mes vêtements. C'est tout. Alors je ne m'amusais pas à faire le grand écart ou à jouer à ninja warrior non plus ^^. Certains semblent sentir une gêne jusqu'à une semaine après, une sorte de lourdeur qui passe avec des anti-inflammatoires (ibuprofène). ## Et concrètement, comment ça se passe ? J'ai commencé par en parler à mon médecin traitant. Heureusement pour moi, et merci à lui, il m'a tout de suite mis à l'aise, alors qu'il s'agit d'un sujet un peu délicat. Il a vérifié que je savais bien de quoi il s'agissait, m'a expliqué la procédure et à quoi m'attendre. Il m'a recommandé un collègue urologue, le même qui avait déjà vasectomisé mon médecin. Rendez-vous ensuite avec l'urologue, qui pose les questions qui dérangent. Et c'est très bien. Par exemple : > Si vos enfants et votre femme meurent subitement dans un accident de voiture, vous voudrez peut-être refaire votre vie ? C'est pas rigolo, mais c'est nécessaire, car la vasectomie est définitive. Ensuite, il explique en quoi consiste l'opération : on fait une petite incision là sur le côté des bourses, on coupe les canaux déférents, on fait un noeud et on brûle, puis on recoud. Enfin, il donne rendez-vous dans au moins 2 mois. C'est comme ça. C'est obligatoire, il faut ce délai de réflexion. Ça permet de bien s'assurer qu'on ne fait pas les choses à la légère, d'en rediscuter avec sa compagne et avec soi-même. C'est aussi la période pendant laquelle on entends pas mal de conneries du genre "t'arriveras encore à satisfaire ta chérie?" ou "j'ai vu sur internet..." ou encore "moi je préfère rester entier, on touche pas à mes bijoux de famille". Bref. Notez qu'on peut faire congeler du sperme si on veut assurer le coup pour avoir des enfants + tard. C'est ~ 30€/an. Arrive le jour de l'intervention et la préparation. C'est là le plus stressant : les questions pour l'anesthésie, toutes les recommandations médicales. En même temps, c'est une opération, on fait les choses sérieusement. Concrètement, je suis arrivé à l'hôpital bien douché à 9h15 le matin, à jeun. La veille, il a fallu appliquer une crême dépilatoire, logique. On m'a accueilli, vérifié mon dossier, donné 1 paracétamol, 1 ibuprofène et 1 anti-inflammatoire (l'ibuprofène fait mal au ventre sinon). J'ai attendu 1h, le temps de pouvoir être anesthésié suite à la prise des médicaments ci-dessus. Ensuite on m'a conduit au vestiaire où j'ai enfilé la tenue opératoire : top tendance, tout en papier. Et puis c'est parti, hop sur le lit, puis au bloc. Là, on m'a endormi : c'est de la bonne ce truc! Réveil en salle de réveil, on vérifie les cicatrices, tout va bien. Zou, en chambre pour finir de se réveiller, et enfin manger un peu! L'urologue passe me voir, vérifie avec moi que je n'ai pas d'autres questions, me rappelle qu'il faut éviter des rapports dans les prochains jours et d'aller courir dans les champs. 15h15, je sors de l'hôpital et rentre chez moi à pieds. Oui, à pieds, je me sentais vraiment bien, j'ai marché 7 km sans peine. Par contre, la nuit suivante, impossible de dormir : l'insomnie après l'anesthésie, c'est pas trop étonnant. Les jours d'après, j'ai fait gaffe de ne pas me cogner. Les cicatrices sont toutes petites, moins d'1 cm de chaque côté, et les points tombent tout seul. C'est mieux d'attendre aussi au moins 1 semaine avant d'aller courir. On m'avait prévenu, mais comme je me sentais vraiment bien, je n'ai pas eu cette patience, résultat ça fait un peu mal après pendant 2-3 jours, alors que je n'avais pas mal avant. Après 3 mois, un spermogramme permet de confirmer ma stérilité officiellement, surtout pour rassurer le patient. Voilà. ## Une réaction? => mailto:prx@si3t.ch?subject=sterile Envoyez votre commentaire par mail. ]]> Comment utiliser regex.h ? https://si3t.ch/log/2022-08-19-comment-utiliser-regex-h.txt 2022-08-19T13:46:36Z https://tildegit.org/solene/vger vger => http://man.openbsd.org/regex.3 regex.3 ## La regex utilisée Imaginons que nous ayons la phrase : "Mon nom est Paul Muad'Dib". On veut récupérer le prénom et le nom. On pourrait alors utiliser cette regex "^.* (.*) (.*)$" Les subexpressions à récupérer sont entre parenthèses. ## Déclarations de variables Il nous faut une variable de type regex_t pour compiler la regex. On enregistrera les subexpressions dans une structure regmatch_t qu'on appelera "match". Cette dernière est un tableau. Elle doit être assez grande pour contenir la ligne complète correspondant à la regex et chaque substring à capturer. Dans notre cas, ça fait 2 captures + la phrase complète. * match[0] contiendra la phrase complète. * match[1] la première parenthèse. * match[2] la seconde parenthèse. J'ai vu dans le code source de ed qu'ils utilisent un #define, ce qui me parait assez malin. (ils définissent la taille à 30 oO). Cela nous donne : ``` #define SE_MAX 3 /* number of expected subexpressions + 1 /* ... regex_t reg; regmatch_t match[SE_MAX]; size_t nmatch = SE_MAX; ``` ## On éxécute la regex On appelle donc regcomp pour compiler la regex, et regexec pour l'éxécuter (PAN!). ``` regcomp(®, regex, REG_EXTENDED); regexec(®, s, nmatch, match, 0); ``` ## On récupère les substrings Maintenant, match[1] doit contenir le prénom et match[2] le nom. Ainsi, reg.re_nsub doit être égal à 2. Chaque élément dans match est constitué de 2 éléments : rm_so et rm_eo. Ils décrivent l'offset (le décalage) où commence et termine une substring dans la phrase de départ. Dans notre phrase, le prénom commence après avoir déplacé un curseur imaginaire 12 fois depuis le début. ``` Mon nom est Paul Muad'Dib ^ ^ | | | +-> match[1].rm_eo = 16 | +-> match[1].rm_so = 12 ``` Si rien n'a été trouvé, rm_so et rm_eo sont égaux. On vérifie donc tout d'abord qu'on a bien trouvé le prénom : ``` if ((len = match[i].rm_eo - match[i].rm_so) > 0) { ``` On en profite pour calculer la longeur de la chaîne à récupérer. Ensuite, on copie cette substring, située à s + match[i].rm_so, s étant notre phrase de départ. ``` memcpy(first, s + match[i].rm_so, len); ``` ## Le code entier Ici on rajoute de quoi gérer d'éventuelles erreurs, dont le message est enregistré dans "buf". ``` #include #include #include #include #include #define SE_MAX 3 /* max subexpression, in nmatch. hard to really understand */ int main(int argc, char *argv[]) { regex_t reg; regmatch_t match[SE_MAX]; size_t nmatch = SE_MAX; size_t len = 0; int ret = 0; char buf[BUFSIZ] = {'\0'}; char *regex = "^.* (.*) (.*)$"; char *s = "My name is Paul Muad'Dib"; char first[10] = {'\0'}; char last[10] = {'\0'}; if ((ret = regcomp(®, regex, REG_EXTENDED)) != 0) { regerror(ret, ®, buf, sizeof(buf)); goto stop; } if ((ret = regexec(®, s, nmatch, match, 0)) != 0) { regerror(ret, ®, buf, sizeof(buf)); goto stop; } for (int i = 1; i <= reg.re_nsub; i++) { if ((len = match[i].rm_eo - match[i].rm_so) > 0) { switch (i) { case 1: memcpy(first, s + match[i].rm_so, len); case 2: memcpy(last, s + match[i].rm_so, len); } } } stop: regfree(®); puts(buf); printf("first name: %s\nlast name: %s\n", first, last); return 0; } ``` ## Une réaction? => mailto:prx@si3t.ch?subject=comment-utiliser-regex-h Envoyez votre commentaire par mail. ]]> How to actually use regex.h https://si3t.ch/log/2022-08-18-how-to-regex-h.txt 2022-08-18T14:40:18Z https://tildegit.org/solene/vger vger => http://man.openbsd.org/regex.3 regex.3 ## The regex we'll use Let's say we have the string: "My name is Paul Muad'Dib". We need to get the first and last name. So we could write this stupid regex: "^.* (.*) (.*)$" Subexpressions are between (). ## Variables declaration To work, we need a regex_t type to store our compiled regex. We need to store the subexpressions in a regmatch_t structure we'll call "match". This structure must be wide enough to keep in memory the full match and the substrings. In our case, we hope to match 2 substrings. This means our regmatch_t must be 2+1 wide. * match[0] contains the full matched string * match[1] is the first match * match[2] is the second match. I found in the ed source code the use of a define to store this and think it's clever (they set it to 30 oO). This gives us : ``` #define SE_MAX 3 /* number of expected subexpressions + 1 /* ... regex_t reg; regmatch_t match[SE_MAX]; size_t nmatch = SE_MAX; ``` ## Run the regex This is quite easy, we call regcomp to compile the regex and regexec to run it. ``` regcomp(®, regex, REG_EXTENDED); regexec(®, s, nmatch, match, 0); ``` ## Extract the substrings Now, match[1] should have the first name and match[2] the last name. If so, reg.re_nsub must be 2. Items in match have two elements, rm_so and rm_eo storing the starting and ending offset of match copared to the original string. In other words, the position in the original string where the subexpression starts and ends. In our case, the first names starts after shifting 11 times on the right and stops at position 15. ``` My name is Paul Muad'Dib ^ ^ | | | +-> match[1].rm_eo = 16 | +-> match[1].rm_so = 12 ``` If no match were found, rm_so and rm_eo are equals. So we first check if we have a match : ``` if ((len = match[i].rm_eo - match[i].rm_so) > 0) { ``` Doing so, we get the length of the substring to copy. Then, we can copy the match located at s + match[i].rm_so, s being our original string. ``` memcpy(first, s + match[i].rm_so, len); ``` ## Full code In order to handle errors, we call regerror to store the error in a buffer "buf" : ``` #include #include #include #include #include #define SE_MAX 3 /* max subexpression, in nmatch. hard to really understand */ int main(int argc, char *argv[]) { regex_t reg; regmatch_t match[SE_MAX]; size_t nmatch = SE_MAX; size_t len = 0; int ret = 0; char buf[BUFSIZ] = {'\0'}; char *regex = "^.* (.*) (.*)$"; char *s = "My name is Paul Muad'Dib"; char first[10] = {'\0'}; char last[10] = {'\0'}; if ((ret = regcomp(®, regex, REG_EXTENDED)) != 0) { regerror(ret, ®, buf, sizeof(buf)); goto stop; } if ((ret = regexec(®, s, nmatch, match, 0)) != 0) { regerror(ret, ®, buf, sizeof(buf)); goto stop; } for (int i = 1; i <= reg.re_nsub; i++) { if ((len = match[i].rm_eo - match[i].rm_so) > 0) { switch (i) { case 1: memcpy(first, s + match[i].rm_so, len); case 2: memcpy(last, s + match[i].rm_so, len); } } } stop: regfree(®); puts(buf); printf("first name: %s\nlast name: %s\n", first, last); return 0; } ``` ]]> How do I set dwm's status bar https://si3t.ch/log/2022-08-09-dwm-status.txt 2022-08-09T14:54:02Z /dev/null; reload; done) & ``` And at last, I call a stupid loop doing nothing except waiting for signals : while true; do sleep .1; done The complete script : ``` #!/bin/sh # set dwm's status when USR1 signal is received # pkill -USR1 statusloop # kill -USR1 $(cat /tmp/statusloop.lock) LOCKFILE=/tmp/statusloop.lock set_status() { xsetroot -name " $(status) " } reload() { kill -USR1 $(cat ${LOCKFILE}) } if [ -e ${LOCKFILE} ]; then echo "already running, killing" kill -9 $(cat ${LOCKFILE}) fi trap set_status USR1 # make sure the lockfile is removed when we exit trap "rm -f ${LOCKFILE}; exit" INT QUIT TERM echo $$ > ${LOCKFILE} set_status # update clock every minutes (while true; do sleep 60; reload; done) & # mpd changes (while true; do mpc --wait current >/dev/null; reload; done) & # global loop while true; do sleep .1; done ``` ]]> Comment rafraîchir sa maison sans climatisation ? https://si3t.ch/log/2022-06-18-rafraichir-maison-physique.txt 2022-06-18T10:28:06Z mailto:prx@si3t.ch?subject=rafraichir-maison-physique Envoyez votre commentaire par mail. ]]> How to write an atom feed ? https://si3t.ch/log/2022-06-15-how-to-atom-feed.txt 2022-06-15T14:31:10Z https://si3t.ch/log/ log de prx /favicon.svg prx prx@si3t.ch 2022-06-08T15:55:32Z ``` As you can see, the two first line are xml declaration, the 2nd call a stylesheet to display the atom feed. It is optional. Then, we open a tag "". id should be unique, use an URL as example. You should specify linksto tell where is the content (alternate) and where the feed actually is (self) in case of redirections. Add an author section if you want. Finally, insert a date when your feed has been updated. It has to be modified each time you update your feed. Format is --T::Z. Then, you can add entries : they are your content. 1 entry = 1 article. Add as many as you want. ``` Youtube to mpd gemini://si3t.ch/log/2022-06-06-yt2mpd.gmi 2022-06-06T14:57:30Z ``` As you can see, you can write some metadata : * a title * the id of the entry. It must be unique (the url is quite good). * time when it has been updated (created) * a link to the article. * A new tag to add the content. As example, I show here a plain text content wrapped in CDATA to avoid escaping and issues with html. If you se the type to "html", make sure you escape &,<,>,'," to &, <, >, ' ". To end an entry : * Close the CDATA tag with "]]]]>" and content tag. * Close entry tag. Finally, close your feed since it must be XML valid content. ``` ``` That's it 😉 ## See also => https://aboutfeeds.com/ About feeds. => https://validator.w3.org/feed/docs/atom.html What is Atom ? ]]> Youtube to mpd https://si3t.ch/log/2022-06-06-yt2mpd.txt 2022-06-06T14:57:30Z Utiliser une tondeuse à main https://si3t.ch/log/2022-05-25-tondeuse-a-main.txt 2022-05-25T14:50:34Z mailto:prx@si3t.ch?subject=tondeuse-a-main Envoyez votre commentaire par mail. ]]> atom.awk : Générer un flux atom à partir de billets texte brut https://si3t.ch/log/2022-05-09-generate-atom-feed-from-any-plaintextfr.txt 2022-05-09T12:50:44Z blog/entry1.txt.pubdate $ find blog/ | awk -v domain="domain.tld" -v max=100 -v template=template.xml -f atom.awk > atom.xml ``` ## Description Que vous écriviez vos billets de blog en text brut, markdown, gemtext ou je ne sais quel autre langage, vous souhaitez probablement créer un flux atom. Avoir du contenu html est peu pratique (il faut échapper le code html) et ajoute des contraintes inutiles à un flux atom. Je vous propose de publier vos articles avec la même apparence dans le flux que dans le fichier source. C'est ce qui est d'ailleurs proposé sur le site shinobi.website : publier du contenu via un flux ATOM seulement. Cet outil va prendre en entrée une liste de fichiers contenant les billets de blog et génère un flux ATOM valide. Chaque objet du flux ATOM a pour description le contenu du billet. Pas besoin d'échapper du html : c'est du texte brud dans une balise CDATA. Vous pouvez même écrire "]]]]>" dans vos billets, ça sera échappé (pas comme le script de shinobi.website). Pour intégrer un fichier "blogentry.txt" dans le flux, un autre fichier nommé "blogentry.txt.pubdate" doit se trouver juste à côté. Ce dernier contient la date de publication au format '%Y-%m-%dT%TZ' (voir strftime). Il suffit d'awk pour utiliser atom.awk, disponible sur la plupart des unix-likes. ## Téléchargement => /code/atom.awk.tgz atom.awk.tgz ## Options * "max" : maximum d'entrées dans le flux * "domain" : Nom de domaine du flux * "template" : Fichier modèle au début du flux à ajuster à vos beosin. voir template.xml dans l'archive ## Exemple ``` $ find blog/ | awk -v domain="domain.tld" -v max=100 -v template=template.xml -f atom.awk > atom.xml ``` ## Voir aussi => https://shinobi.website/index.txt ## Une réaction? => mailto:prx@si3t.ch?subject=generate-atom-feed-from-any-plaintext Envoyez votre commentaire ]]> atom.awk : Generate an atom feed from plaintext blog posts https://si3t.ch/log/2022-05-09-generate-atom-feed-from-any-plaintext.txt 2022-05-09T12:45:44Z blog/entry1.txt.pubdate $ find blog/ | awk -v domain="domain.tld" -v max=100 -v template=template.xml -f atom.awk > atom.xml ``` ## Description Whether you write files in plaint text, markdown or any other markup language, you may want to create an atom feed. That's actually what is proposed on shinobi.website. You can even publish a whole blog only using ATOM feed. This tool take a list of file as input and will generate an atom feed with the content of each fil as description. No need for html escape or any conversion : it is plain text in a CDATA tag. You can even write " /code/atom.awk.tgz atom.awk.tgz ## Options * "max" : maximum of item in the feed. * "domain" : domain name of your feed. * "template" : template file, the header of your atom feed. See template.xml as example. ## Example ``` $ find blog/ | awk -v domain="domain.tld" -v max=100 -v template=template.xml -f atom.awk > atom.xml ``` Now publish atom.xml file. ## See also => https://shinobi.website/index.txt ## Something to say => mailto:prx@si3t.ch?subject=generate-atom-feed-from-any-plaintext Any comment ? ]]> Session tmux à l'ouverture d'un terminal https://si3t.ch/log/2022-05-04-tmux-automatique.txt 2022-05-04T16:16:44Z https://dwm.suckless.org dwm ## Une réaction? => mailto:prx@si3t.ch?subject=tmux-automatique Envoyez votre commentaire par mail. ]]> Des solutions énergétiques existent. https://si3t.ch/log/2022-04-08-solutions-energetiques-existent.txt 2022-04-08T10:59:13Z https://www.sciencesetavenir.fr/nature-environnement/climat/3-ans-pour-agir-l-alerte-du-nouveau-rapport-du-giec_162698 Urgence oui, 3 ans pour agir... La plupart du temps, on parle des sources comme les éoliennes, l'hydraulique, en insistant sur leurs défauts plutôt que les avantages que ces solutions représentent face aux hydrocarbures. Je me permets à ce titre de rappeler que du charbon, du gaz, une fois brulé, c'est du CO₂ qui se balade dans notre atmosphère sans solution évidente pour le retirer. C'est un réchauffement inévitable est des morts certaines. Pour répondre à ce problème, rappelons que le nucléaire ne rejette pas DU TOUT de CO₂. En terme de gaz polluants, le nucléaire, c'est propre. Oui, la construction des centrales, le traitement des déchets, la sécurité à assurer ne sont pas négligeables. Oui. Comme toujours, il y a des inconvénients, qui sont pourtant moins préoccupants que l'inévitabilité des dégats causés par les hydrocarbures. J'aimerais profiter de ce billet pour rappeler, à mes élèves, à mes lectrices et lecteurs et à moi même (jeune papa) qu'il EXISTE DES SOLUTIONS. Parfaites? Sans doute pas, mais sans aucun doute meilleures que celles précédemment citées, ou en tout cas complémentaires. L'espoir est permis, et ne laissons pas des débats politiques et peu scientifiques éclipser ces possibilités. Ce que je vais décrire là, c'est un petit peu de chimie toute bête, pas besoin d'avoir un master pour comprendre. Plutôt que de brûler des hydrocarbures, on peut brûler le dihydrogène (H₂). Cette combustion dégage de la chaleur que l'on peut utiliser pour faire tourner un alternateur et récupérer de l'électricité : exactement ce qui se passe dans une centrale à charbon, dans une centrale nucléaire, dans une centrale hydraulique... L'avantage de cette combustion, c'est que son unique produit est de l'eau. DE L'EAU! Juste de la vapeur d'eau qui donnera de la pluie si on ne la récupère pas : 2 H₂ + O₂ → 2 H₂0 Le point critique est la façon dont on obtient du dihydrogène. Ça peut être très polluant, mais aussi très propre. En effet, on peut casser la molécule d'eau (hydrolyse) et faire la réaction inverse : 2 H₂0 → 2 H₂ + O₂ C'est très facile à réaliser, vous pouvez même le faire avec une pile : reliez un fil électrique de chaque borne dans de l'eau : des bulles vont apparaître. D'une borne, c'est le O₂ qui se forme, de l'autre le H₂. Si vous tentez, faîtes-le avec une pile, c'est dangereux de le faire avec le secteur, à moins de savoir ce que vous faîtes. Il suffit alors de stocker H₂ et O₂ pour les utiliser comme combustibles lorsqu'on a besoin d'énergie. Le courant électrique utilisé pour les récupérer, c'est celui dont on n'a pas besoin lorsqu'il y a trop de soleil ou trop de vent, ou qui vient de smarées, ou une autre source propre... Bien sûr, stocker le dihydrogène n'est pas si simple (c'est explosif), cela demande des matériaux qu'il faudra recycler (comme pour les éoliennes), mais ces contraintes sont TELLEMENT moins pénibles que celles imposées par les autres alternatives (déchets radioactifs, gaz à effets de serre). C'est un système pour laquelle nous comprenons les principes et pour lequel nous avons la technologie, qu'il reste à développer si on le souhaite. À ce titre, je l'affirme, il existe des solutions propres, l'espoir est possible, mais il faut déjà en avoir conscience. La 2e solution, c'est d'arrêter de consommer n'importe comment. À ce titre, je vais bientôt passer 1 journée sans électricité. Ça va arrêter mon serveur, ainsi que tous les autres appareils. Cette petite expérience, je l'ai déjà faite, et j'en ressort toujours satisfait et apaisé pour de mutiples raisons qui sortent du cadre de cet article. Je vous invite à tenter, rien que pour démontrer qu'on peut très bien vivre avec moins (pas) d'électricité pendant une journée sans problème :) ## Une réaction? => mailto:prx@si3t.ch?subject=solutions-energetiques-existent Envoyez votre commentaire par mail. ]]> nethack -- Épisode 11 https://si3t.ch/log/2022-03-22-nethack-11.txt 2022-03-22T21:47:28Z Hello prx, the gnomish Wizard, welcome back to NetHack! Mouhahaha, à moi les forces du cosmos! Je me promène un peu, tout va bien, le sort "force bolt" fait des dégats et mon chaton m'aide bien. Ce n'est qu'arrivé au niveau 3 que je pense à revérifier mon inventaire, après avoir laissé cette partie traîner quelques semaines. Et que vois-je? Des anneaux! Je m'empresse de les enfiler, et je ne suis pas déçu : J'enfile d'abord l'anneau d'invisibilité : > Gee! All of a sudden, you can't see yourself. Puis un anneau pour voir l'invisible : > Suddenly you are transparent, but there! Les devs ont vraiment pensé à tout ! Je termine le niveau 3 sans encombre et gagne un peu d'expérience. Maintenant que je suis invisible (je suppose), je vois ce message apparaître sur le sol : > "You nig?t tr?c? a ?hopkeepcr if you'r? ?nvi?ib|c.". Hum... Apparemment je dois pouvoir faire un truc à un vendeur si je suis invisible... Le truc quand on lance des sorts, c'est que ça donne faim. Je trouve heureusement 2 rations par coup de chance. Ce niveau est tout en zig zag, c'est difficile de trouver les passages secrets. Alors que mon chaton tombe dans un piège qui le téléporte, je choisis de descendre un peu plus profond. C'est en fait un escalier vers les mines. Pas sûr qu'y aller sans mon chat soit très prudent... Tant pis, je suis un sorcier, il faut que j'entraîne mes sorts :) J'y trouve une amulette, et puisque je suis curieux, je l'envie aussitôt : > It constricts your throat! B - an amulet of strangulation (being worn). Quelle bonne idée! Et bien sûr, elle est maudite, impossible de l'enlever. Vite, un parchemin pour retirer ce mauvais sort > You feel like someone is helping you. You find it hard to breathe. > You can breathe more easily! Ouf ! Je craignais de ne pas pouvoir lire tout en étant étranglé. L'exploration continue, et j'ai la joie de découvrir un pot de graisse. Merveilleux! On croise des nains et des gnomes sympas dans le coin. C'est rare de ne pas se faire attaquer dans nethack, c'est sans doute parce que je suis invisible, et parce que je suis moi même un gnome :). J'en profite pour amasser les XP en tuant tout ce que je croise. Malheureusement, je tombe dans un trou pendant cette exploration! Je ne perds pas de PV, mais je n'ai plus d'échappatoire. Alors que j'explore tranquilou, récupère une bagette magique sur le corps d'un hobgoblin, je re-tombe dans un trou !!! Me voilà donc au niveau 8 du donjon, avec 2 niveaux partiellement explorés et sans mon chat. Toutefois je tombe juste à côté d'un escalier. Le bol! Alors je remonte :) Cela me permet de reprendre mon exploration. Je trouve des baguettes que je m'empresse de tester. La première accélère un rat. La seconde resuscite un orc. La seconde n'était pas une bonne idée... Je n'ai plus de points de magie, je dois trouver refuge alors que les orcs sortent du mordor. C'est en remontant d'un niveau qu'un werejackal se transforme en humain XD. Heureusement je récupère vite pour pouvoir déguster mon plat : > This Mordor orc corpse tastes okay. You finish eating the Mordor orc corpse. Me voilà niveau 6 avec le debuff "Satiated", ce qui fait plaisir après avoir frôlé la famine :) En reprenant mon exploration, sans savoir pourquoi, je me transforme! > You turn into a werejackal! You shrink out of your cloak! > Your helm falls to the floor! Your boots are pushed off your feet! > You find you must drop your quarterstaff! > Use the command #monster to summon help. > You can't even move a handspan with this load! Donc, ça veut dire plus d'équipement et surcharge qui m'empêche de bouger. Mais POURQUOI??? Serait-ce parce que je me suis fait mordre auparavant par un werejackal ? Si oui, c'est vraiment embêtant (et très bien pensé par les devs :)) Je n'aurais peut-être pas dû en manger aussi... Je suis le conseille et lance "#monster" : cela attire des jackals à ma rescousse!!! oO Je n'ai vraiment pas envie de rester un lycan. Tentons le tout pour le tout : > #pray > The voice of Thoth booms out: "Thou hast strayed from the path, creature. > "Thou must relearn thy lessons!" You feel foolish! Hum... Le cannibalisme n'a pas dû être apprécié! Quel chipoteur ce Thoth! Il n'avait plus besoin de ses jambes voyons, il était décédé ce gnome! (en vrai j'avais oublié que j'étais un gnome à ce moment là, à force de jouer en découpé...) Bon, plus qu'à continuer ainsi... Ou alors, je tente de boire les potions dont j'ignore les effets... Avec une énooorme chance, qui sait? En vrai, je n'ai surtout pas envie de continuer dans cet état, alors je jouerai bien le tout pour le tout. Gloups! Bon, ça ne fait rien apparemment... Je me débarasse de mon équipement superflu et c'est reparti. En quelques tours, me revoilà sous forme normale, mais entouré de tous ces anciens copains venus à mon aide, qui maintenant sont hostiles ! Pas de problème, j'utilise la baguette lance missile qui traverse tous ces ennemis dans le couloir \o/. Sauf que de l'autre côté, des orc du Mordor se lancent à l'attaque. Gasp Je n'ai plus que 11 PV et presque plus de Mana, coincé dans un couloir. Ça semble vraiment mal barré. Pas le choix : > What do you want to write in the dust here? Elbereth Ça n'a pas l'effet escompté : > The wolf bites! > You die... Leçons : ne pas manger les gens et se méfier des lycans ``` ---------- / \ / REST \ / IN \ / PEACE \ / \ | prx | | 120 Au | | killed by a wolf | | | | | | | | 2022 | *| * * * | * _________)/\\_//(\/(/\)/\//\/|_)_______ Goodbye prx the Wizard... You died in The Gnomish Mines on dungeon level 6 with 1942 points, and 120 pieces of gold, after 3026 moves. You were level 6 with a maximum of 56 hit points when you died. ``` La prochaine fois, je fais une partie d'une traite. ## Une réaction? => mailto:prx@si3t.ch?subject=nethack-11 Envoyez votre commentaire par mail. ]]> Support de gzip pour httpd commité https://si3t.ch/log/2022-02-28-httpd_gzip-committed.txt 2022-02-28T09:37:31Z https://cvsweb.openbsd.org/src/usr.sbin/httpd/server_file.c?rev=1.71&content-type=text/x-cvsweb-markup Aujourd'hui, j'ai pu lire le message suivant : > Add gzip-static option to httpd. This allows to deliver precompressed files with content-encoding gzip. from prx at si3t dot ch; OK tracey@ Wouhou, après avoir été initié par Solène, proposé une fois, puis reproposé récemment, puis légèrement modifié, c'est finalement intégré \o/ Le serveur http par défaut d'OpenBSD peut désormais servir les fichiers compressés de façon transparente et réduire considérablement la quantité de bande passante nécessaire. Autrement dit, si une version gzippée d'un fichier est disponible à côté du fichier non compressé, et si le navigateur supporte la décompression, alors c'est le fichier compressé qui est transféré. ## Une réaction? => mailto:prx@si3t.ch?subject=httpd_gzip-committed Envoyez votre commentaire par mail. ]]> nethack -- Épisode 10 https://si3t.ch/log/2021-12-21-nethack-10.txt 2021-12-21T15:40:08Z Hello prx, welcome to NetHack! You are a neutral male human Monk. ## Niveau 1 Ça commence mal, je me prends les pieds dans un piège à ours dès les premiers pas. Finalement je m'en sors, mais en ayant perdu la moitié de mes points de vie :/ Ceci dit, je trouve un peu plus loin un fléau pour taper un peu plus fort, et l eniveau se termine vite : ``` ---------- --------- |........| ####-.......| ------------ |.........## |.......| #-..........| |.....#{.| ## |.......| #|..........| -------------- -.-------- --|-#-.-- #|..........| |.......%....| # # # #---------.-- |............| # ######## # |.........^..| # # ## # |............| ## ###### ###### ### |<............#### ------|--- # # -.--.- -------------- ## |........| ## ## |....| ## |..@.....| ### # |....| ###-........| -.-|-## |..^.| |........| |...|# |....| ---------- |...|# |....| |....# ------ |...| |...| ----- Prx the Candidate St:16 Dx:10 Co:10 In:12 Wi:17 Ch:8 Neutral Dlvl:1 $:13 HP:14(14) Pw:4(4) AC:4 Xp:1 ``` ## Niveau 2 Descendons bien vite au niveau suivant. Je constate alors que j'ai un livre de soin dans mon inventaire. En effet, je suis un moine, j'ai donc la possiblité de lancer des sorts. Chouette, c'est le genre qui devrait me plaire : des sorts et pas à m'inquiéter de l'arme choisie : je me bats à mains nues. Kiaï! En me promenant dans ce niveau, je n'ai aucun mal à y tuer les monstres : un gobelin par ci, une grid bug par là... J'ai l'heureuse surprise de trouver une grosse boite contenant plein d'or, un parchemin et encoooore un livre de soins. De quoi bien m'équipper dans le prochain commerce :) ``` ------ --------------- |....| |.............| |.....#########|.............| ------ |....| #-.............| #-....| |<...| #####|.............| ###|....| -.---- ## #|.............| ############..>..| # ## #----.---------- ############### # |..(.| # # ###### #### ## #### ------ # # # ## ### ## # ### # # ## -----.---.----- # # # -.------------ # |.............|##### # # |.........>..-#### |.............|# # # |.........@..| #..............|# # # |.........f..| ####|.............-# -.----# |.............###### |.............| |....|# |............| --------------- |.....# -------------- |....| ------ Prx the Candidate St:16 Dx:10 Co:10 In:12 Wi:17 Ch:8 Neutral Dlvl:2 $:147 HP:14(14) Pw:4(4) AC:4 Xp:1 ``` ## Niveau 3 Ici je découvre un nouveau monstre : un seigneur gnome. Après l'avoir aperçu, j'entends : > You hear crashing rock Hum... pas sûr si c'est dangereux ou non... Tant pis, j'y vais, c'est le tout début. Alors en fait, il y a des gnomes partout... oO Un gnome m'envoie une flèche, mais touche heureusement celui qui est devant lui et le tue. Je fonce au combat, yaaah! Ça secoue un peu, je tue un, puis 2 gnomes, et me trouve face à un sorcier. Et après m'être fait pointé du doigt de multiples fois par ce sorcier gnome : > The gnomish wizard staggers from your powerful strike! You kill the gnomish wizard! Welcome to experience level 2 Je pense avoir compris : c'est comme la dernière fois, je ne suis pas dans le donjon principal, mais dans les mines. Je vais continuer un peu et m'enfuir dès que ça devient trop dur. En quelques tours, j'en suis au niveau 4 à force de taper du nain et du gnome \o/ Mon chat a disparu cependant... C'est étonnant comme niveau, c'est plein de petites pièces. Il y a un piège, mais je survis. Le sort "healing" est finalement très utile. Je retrouve mon chat un peu plus loin, il a du manger du gnome ^^ Sous un piège, j'y trouve un stétoscope. Bizarre, mais qui sait, peut-être pourrais-je l'utiliser contre un mur pour trouver des passages secrets? Ça semble tordu mais bon... Je trouve aussi une pioche et un miroir \o/ Pour rigoler, je teste le stétoscope sur mon chat : > Status of the kitten (neutral): Level 1 HP 1(8) AC 6, tame. Je crois qu'il a bien besoin de soins le pauvre :/ Après m'en être occupé, je crois avoir terminé d'explorer ce niveau qui ne mène nulle-part : il faut remonter : ``` -------- ----- ---- --- .......---- |...| |..-----------..| ...---....------- --- --.-- |.`........%)...----...|---.<.@...| |.-- ------ |.| --.------------.......|.---|..#---.| --.-- -....| |.| --..| -----.----.|....##-- |.----- |.[| # |.^...| |.-- --.)-- --..--.| ...--..--- -.....----#.-- -#-...--- |..| |..-- ----......| ---#..#-....--..--([......#--# |...-- --.| |%-- --.........---.#...----......|--.)........-- |.-#- |.| --.| |...........|................-----......|..-- |.| # |.| |..| |`..^)............----.--......| --...---..--|.| |.| |.-- -.............. --..--......-- --..| -...|.| |.---- |.| |.+--......... -............|.--...| --...|--. |....| |.| ---|..................................| -...|..- ----.| |.| |.-..........*..................---- |......:.| |...------.-- |.................---..........-- --........| ---...........----- ---.#...............| -.........| |.....--.-- |........(........-- |...|........-......| --........| |.....|--- |..........|.......| |..-|..---......|...| ---------- ----..| ---.|..--.---..--.-- ---- --- -----.---.-- ---- ----- --- ------- --- --- Prx the Novice St:16 Dx:10 Co:11 In:12 Wi:17 Ch:8 Neutral Dlvl:3 $:189 HP:34(34) Pw:17(22) AC:4 Xp:4 ``` ## Niveau 3 (le vrai) On se sent tellement mieux avec un niveau de vie correct et assez de force pour taper ce qui se présente sans se mettre en danger. Ce niveau est plein de passages secrets, mais rien de trop surprenant. J'ai trouvé 2 anneaux, sans trop savoir à quoi ils pourront m'être utiles. Voici à quoi il ressemble : ``` -------- |......| ----- |).....| |...| ----------- ------- ----- #####........# |...| |..........###### |.....| |...|### ---|--|-######-...-# |.........| ######## -.....| |...|# # ##### |...|#######.....).[..| # # # ## #|.....| |.<.|# ########### # |...| |.........| -.----- ######-.....| |...-# # # --.-- ##...........#####-.....| #|.....| -----## # # ### ### ----.------ |.....| ###|.....| # ## # # ### # #......| ## ------- # # ## # ## ### #####|.....| ### # * # ######## # # |.....| # ## # # #------- -.------- # |.....| # # ----.---- # #|.....| |.......| # -------## ####-.......| ###|.....| |........############## |.......| ##-.....| |.......| |.@.....| ## |.....| --------- |.>..f...### ------- --------- Prx the Novice St:16 Dx:10 Co:11 In:12 Wi:17 Ch:8 Neutral Dlvl:3 $:219 HP:40(40) Pw:28(28) AC:4 Xp:5 ``` Vivement un magasin pour vendre tout le bazar que je laisse trainer. Avant de descendre, je vais tenter de lire les parchemins : j'ai trop de trucs dont j'ignore la fonction, et j'espère toruver un scroll d'identification. Le premier semble être un parchemin d'exorcisme. Le second, bim, est un parchemin d'identification \o/ Bon, je n'en ai qu'un seul malheureusement et cela me permet d'identifier un parchemin "create monster" qui semble prometteur :) ## Niveau 4 Ici on tombe sur des monstres plus coriaces : un "imp" m'aura donné du mal, mais mon petit chat m'aide :) Du coup on s'en sort sans trop de soucis : ``` -------- ----- ------------ |.......#####-...| |..........| --------- |......|# |...| |..........| |...).._| #-......|# ....| |..........| |.......-# #--------# |....######...........| -.-------# ### ## |.<.| |..........| ## # # ###` --|-- |..........| # # # ## # # -----.------ # # ## ## # # # # ## # # # ##### % # ###--------# ## # # # # #|.......# ## # # ##############%###`########` ---|------ #|......| ## # # ############### --.--- |......... ##|......-##### # # -.-.---- |....| |........| #-------- # #-.-.------- |.......######|....| |.........################## #.......[..| |......| #-....| |........| |>@.......| |......| ------ |........| |......f..| -------- ---------- ----------- Prx the Novice St:16 Dx:10 Co:11 In:12 Wi:17 Ch:8 Neutral Dlvl:4 $:226 HP:40(40) Pw:28(28) AC:4 Xp:5 ``` En route pour le niveau 5! ## Niveau 5 En visitant ce niveau, j'ai la malchance de tomber sur un leprechaun qui me vole quasiment tout mon or lorsque je le tue! J'ai intérêt à m'en souvenir de ce monstre... GRRR. En voilà un qu'il vaut mieux faire fuir plutôt que combattre lorsqu'on ne peut pas envoyer d'attaques à distance. Je me retrouve vite coincé, il semble que je manque d'expérience pour repérer les passages secrets... Tant pis, on va descendre au niveau 6. ``` --------#- ----- -------- |........| |...-# |......-# |.........# *` |..||# #....)..|#####-........|# #` ---------- |...|# #|......|# |........|# # |.........####..*.|# #|......|# |........|# # # ####.........| -----# #--------# -.--------# ------.---## |........-########### # # # # |.....<..-[####---------- # # # # # |........| #` **#*###*#### # # ## # # |.........## #**# ###### # # # ## # |........| # # # # # |........| # # #---.----- # |........| #-----# #|.......| # ---------- #|.f[.# #-..{....| # ------ #-.@.| |.......| # |....| |.>..## --------- ##.....| ----- ------ Prx the Novice St:16 Dx:10 Co:11 In:12 Wi:17 Ch:8 Neutral Dlvl:5 $:23 HP:40(40) Pw:28(28) AC:4 Xp:5 ``` ## Niveau 6 Oh ! À peine descendu, mon chat disparaît : > Suddenly, the kitten disappears out of sight. Il semble qu'il ait marché dans une trappe de téléportation. Je vais le suivre en espérant que cela me mène près de lui. On me dit : > You escape a level teleporter. Mais je veux y alleeeeer ! Bon, tant pis... Je le retrouverai peut-être plus loin. Je trouve une nymphe des montagnes. Elle ne semble pas belliqueuse, alors passons. La difficulté semble plus importante : on trouve des killer bee, des portes sont piégées, des zombis, des orcs du Mordor... Cependant je trouve un marchand de potions. Je n'ai malheureusement plus assez d'argent à cause de ce fichu leprechaun. Après avoir mangé un truc pas frais, je commenc eà halluciner. Sans trop savoir de quoi il s'agit, si je rêve ou si c'est la réalité, me voilà encerclé par des monstres qui changent de forme à chaque tour. J'ai beau me soigner, rien n'y fait, je succombe sous leurs coups. > You hit Strong Bad. The fog cloud summons help! The xorn bites! > You feel better. The glass golem bites! The wereplatypus bites! > The white dragon summons help! You feel hemmed in. The giant rat bites! > You die... ``` ---------- / \ / REST \ / IN \ / PEACE \ / \ | prx | | 40 Au | | killed by a | | hallucinogen-dis | | torted warg | | | | 2021 | *| * * * | * _________)/\\_//(\/(/\)/\//\/|_)_______ Goodbye prx the Monk... You died in The Dungeons of Doom on dungeon level 6 with 1948 points, and 40 pieces of gold, after 3631 moves. You were level 6 with a maximum of 47 hit points when you died. ``` C'était une bonne partie, je ne suis jamais allé aussi loin :) ## Une réaction? => mailto:prx@si3t.ch?subject=nethack-10 Envoyez votre commentaire par mail. ]]> Comment j'utilise tmux ? https://si3t.ch/log/2021-12-17-comment-jutilise-tmux.txt 2021-12-17T11:16:39Z https://www.romanzolotarev.com/openbsd/tmux.conf Configuration tmux de Roman Zolotarev Au fait, tmux est présent de base dans OpenBSD :) ## Ça ressemble à quoi ? => /img/log/tmux-shot.png Démonstration de tmux (IMG) Comme vous pouvez le voir, ma fenêtre est divsée en plusieurs parties un peu comme le ferait un tiling window manager. Chaque partie est appelée un "pane", avec à gauche cet article pendant que je le rédige, en haut à droite un peu de code awk et en bas à droite la prise de capture d'écran. Vous distinguez en bas à gauche la liste des fenêtres disponibles : je les ai regroupées par thèmes, la plupart sont lancés automatiquement avec ma session. En bas à droite, il s'agit d'une barre de status : mon terminal est en plein écran. J'y affiche l'espace disque restant, le niveau de batterie, le volume sonore et la date. Lorsque mpd joue de la musique, on voit le titre de la chanson jouée. ## Au démarrage Je démarre à chaque début de session un script qui va créer les différentes fenêtres que je veux dans tmux, à savoir une pour mes mails, une pour un client XMPP, une pour pouvoir accéder rapidement à mes cours. Cela se passe dans le script starttmux suivant : ```script shell starttmux #!/bin/ksh session=0 showtmux() { xterm -class tmux -e tmux a -t $session exit } # set up tmux tmux has-session -t $session && showtmux # show sync by default, then run ksh tmux new -d -s $session "/home/prx/bin/prxsync pull; ksh" # mutt tmux new-window -d -n "mails" "mutt" # xmpp tmux new-window -d -n "chat" "profanity" # educ tmux new-window -d -n "educ" -c "$HOME/work/educ/College/Cours" rover tmux split-window -h -d -t "educ" -c "$HOME/work/educ/College/Cours" ksh showtmux ``` Je n'utilise qu'une seule session tmux, sauf exceptions : la 0. Au début, le script vérifie si la session n'existe pas déjà pour l'afficher au lieu de la charger. Ensuite, je lance un script de synchronisation appelé "prxsync" et ouvre un shell ksh dans la fenêtre principale. Puis, j'ouvre dans leurs fenêtres respectives mutt et profanity. Enfin, je crée une nouvelle fenêtre "educ" que je divise en 2 (split-window) pour y afficher mes cours avec le gestionnaire de fichiers rover. La dernière ligne permet d'afficher tmux dans xterm. ## La configuration Pour retrouver les mêmes habitudes, peu importe la machine sur laquelle je me retrouve, j'essaie au maximum d'utiliser les raccourcis par défauts. J'ai bien évidemment réalisé quelques ajustements, mais je dois avouer qu'on se fait très bien aux raccourcis de tmux au départ un peu étonnants (ctrl-b par exemple). Voici ma configuration : ```configuration de tmux set-option -g base-index 1 # my keyboard start from 1 at the left set-option -g escape-time 0 # vi set-option -g history-limit 50000 set-option -g default-command "/bin/ksh" set-option -g default-terminal tmux-256color set-option -g mouse on set-option -g status-interval 10 set-option -g status-right-length 142 set-option -g status-right '#{?client_prefix,#[fg=green#,bg=black] PREFIX,#(bin/status)}' ``` Je veux que la numérotation commence à 1, pas à 0. Ensuite, je retire le délai avant de prendre en compte la touche echap, que j'utilise très souvent avec vi. La dernière ligne permet de définir une barre de status simple que je détaillerai ensuite. "PREFIX" est affiché lorsque j'ai entrée ctrl-b, ça évite les étourderies. Voici maintenant les raccourcis que j'ai rajouté : ```suite de la configuration de tmux # map prefix to 'C-space', disabled #unbind C-b #set-option -g prefix C-space #bind-key C-space send-prefix # vi <3 set -g mode-keys vi set -g status-keys vi # à la dwm keybinds : resize with HJKL, select with hjkl. bind -r H resize-pane -L 2 bind -r J resize-pane -D 2 bind -r K resize-pane -U 2 bind -r L resize-pane -R 2 bind -r h select-pane -L bind -r j select-pane -D bind -r k select-pane -U bind -r l select-pane -R # move to urgent window bind a previous-window -a # last window bind Tab select-window -l # copy-mode : v bind v copy-mode # copy whole visible pane in new buffer, choose with "#" bind y capture-pane -N -J # split in same directory bind c new-window -c "#{pane_current_path}" bind % split-window -h -c "#{pane_current_path}" bind '"' split-window -c "#{pane_current_path}" # Save buffer also in X clipboard bind -T copy-mode-vi 'y' send -X copy-pipe-and-cancel \ 'xclip -i -selection clipboard' bind -T copy-mode-vi MouseDragEnd1Pane send -X copy-pipe-and-cancel \ 'xclip -i -selection clipboard' bind -n MouseDown2Pane run \ 'tmux set-buffer "$(xclip -o -selection clipboard)";tmux paste-buffer' ``` J'ai laissé en exemple au début une façon d'utiliser ctrl-space au lieu de ctrl-b pour préfixe. Je définis très rapidement des raccourcis ressemblant à ceux de vi, par habitude. * H/J/K/L permet de redimensionner les panneaux * h/j/k/l permet de sélectionner les panneaux souhaités * Tab permet de retourner à la fenêtre précédente : cela imite le comportement de dwm * "a" focalise la fenêtre urgente. Pratique quand un message arrive dans profanity par exemple * Pour entrer en mode copie, je définis la touche "v" plutôt que "[", c'est un vrai caprice. * "y" me permet de copier tout le contenu d'un pane. Je peux sélectionner cette portion de texte ensuite avec "#" lorsque je suis en mode copie. * Suivent des options me permettant d'ouvrir de nouvelles fenêtres ou pane dans le même dossier que celui actuel. Cela me semblait plus logique que de devoir à chaque fois me déplacer dans le dossier dans lequel j'étais juste avant d'ouvrir un nouveau shell. Dans les rares cas où je n'en a pas besoin, c'est plus rapide d'entrer "cd" pour revenir dans mon $HOME que d'entrer tout le chemin vers le dossier courant. * Enfin j'ai piqué à Roman Zolotarev la configuration pour que ce que je copie avec tmux soit aussi dans le presse-papier de la session X, si j'en utilise une... Ça ne m'est pas très utile, mais c'est plus naturel lorsque je colle du texte dans firefox après l'avoir copié dans tmux. ## Le status Voici le script pour afficher les infos en bas à droite : ```script shell fs_perc() { df -h $1 | awk 'NR==2 {print $5}' } get_vol() { sndioctl output.level | awk -F = '{printf "%d\n",$2*100}' } loadavg() { sysctl -n vm.loadavg } bat() { #apm | awk 'NR==1 && !/absent/ {printf " ⚡%s", $4}' test $(apm -a) -eq 0 && printf "⚡%s%%" $(apm -l) } printf "%s %s 💽 %s 🔉 %s %s" \ "$(mpd-status)"\ "$(bat)" \ "$(fs_perc /home)" \ "$(get_vol)%" \ "$(date "+📆 %Y-%m-%d 🕓 %H:%M ")" ``` Le script mpd-status est le suivant : ```mpd-status script #!/bin/sh mpc | awk ' (NR == 1) { status = $0 if (length(status) > 42) { status = substr($0, 1, 42) "..." } } (NR == 2) && /playing/ { isplaying = 1 } END { if (isplaying) { printf "♪ %s \n", status } } ' ``` ## Le mot de la fin Comme pour awk, je regrette de ne pas avoir pris le temps de me familiariser avec tmux plus tôt. Je vous invite donc à le faire ;) ## Une réaction? => mailto:prx@si3t.ch?subject=comment-jutilise-tmux Envoyez votre commentaire par mail. ]]> nethack -- Épisode 9 https://si3t.ch/log/2021-12-14-nethack-9.txt 2021-12-14T13:35:29Z Hello prx, welcome to NetHack! You are a chaotic female human Rogue. ## Niveau 1 Ce premier niveau est grand. Il y a beaucoup de boulets à ne pas déplacer, et pour une fois ce n'est pas moi. J'y trouve des anneaux, des feuilles de lembas, une clé (que va-t-elle ouvrir?) et une potion rose. Voilà donc des objets à identifier pour plus tard, car les tester maintenant c'est un coup à décéder. On tue des renards, des rats, des kobolds, et on s'apprête à descendre : ``` --------------- ------------ ------- |.............| -------- #-..........| |.....-# #..>............##`###|......| #|..........| |.....|# #|.@...........| #|......| #######|..........| |.....|# ##|.............| #|......|############### # ----------.- |.....|# ## --.------------ #|..<...-## -------- ## ### -------# ## ### #|......|####-...`..-####### # # ## #### #.......| |......| # # # #### #-------- ###........##### # ## # ------.- ############### --------##### # # # |.....%.#####`####### ########### #######`## # # # |......|#### ##### ##-----|----|--- ##### # |.......###########`# # #|............| #---.-# --------# ########################|............| #|....# ########### #####|......._....| #|...| #.............| #..{d| |............| ----- -------------- Prx the Footpad St:11 Dx:18 Co:18 In:10 Wi:7 Ch:11 Chaotic Dlvl:1 $:6 HP:8(12) Pw:2(2) AC:7 Xp:1 ``` ## Niveau 2 L'exploration ne pose pas de soucis. Quelques portes fermées ne résistent pas à mon matériel de crochetage. J'entends souvent des bruits, il faut dire que Cahouète s'en donne à coeur joie. (Cahouète, c'est mon chien. C'est un gourmand Cahouète). Un gobelin imprudent me permet d'atteindre le niveau 2 et je me sens prêt à descendre au niveau 3 : ``` # -.--- ---------- |...| ------- -------- |........| |...-####-.<...-#############-......| |........| ###....| ##|.....| |......| |........-## # -.--- ##|......#############......{| |........| ## # ### ##------- --.----- -|---|---- # ##### # #### # ##` # ##### ### ### # #### # ## # -----###### # # ##### # # #####|...d# ###` # # # # #|.@>| #### # ###### #|...|############ # ### --------------- # #### #....|# -------|------# #####..............| ---.----|- --.--### +............|# ###|.............| |........| ########## |............|# #..............| |........-###### |............-# --------------- |........| |............| ---------- |............| -------------- Prx the Footpad St:11 Dx:18 Co:18 In:10 Wi:7 Ch:11 Chaotic Dlvl:2 $:14 HP:20(20) Pw:6(6) AC:7 Xp:2 Hungry ``` ## Niveau 3 Un niveau vraiment tranquille. Pas de gros pièges pour l'instant. Cahouète continue de se régaler. Quant à moi, je me retiens de tester les 2 parchemins que je viens de trouver. ``` -------- ---------- |......| # #|........| |.......###### -.-- #.........| #-......| # `#####-..| ----------- ###|........| #|.......# # |..| |.......... ####--.------- ####--------# #### |.^| ####..........| # # ### ## ############ |..| ## |.@....d..-####################### # ### #######...| # |.........| # # ## # -.-- -------# #-..........### # # # # |......#####-|--------- ## # # # |.....|# # ####### # # ## |.....| -----|--------# ### # |.....| |............|# # ## ------- |............|# ##### # |............|# #---.--- |<..........[|# #|...{.| |............-# #......| -------------- ------- Prx the Footpad St:11 Dx:18 Co:18 In:10 Wi:7 Ch:11 Chaotic Dlvl:3 $:23 HP:20(20) Pw:6(6) AC:7 Xp:2 ``` En route pour le niveau suivant. ## Niveau 4 À peine arrivé, un hobgoblin m'attaque sauvagement. Mes blessures me laissent avec le quart de mes points de vie en moins. GASP. Heureusement Cahouète et moi parvenons facilement à le mettre en pièces. \o/ > The little dog eats a hobgoblin corpse. Niark niark niark Je décide de prendre un peu de repos et reprends ma partie un peu plus tard (à vrai dire quelques jours plus tard). À mon retour : > Be careful! New moon tonight. Hum, ça sonne encore comme une menace ça. Quand mon beau frêre me parle de pleine Lune, ça peut vite être traumatisant alors je vais rester méfiant. Je fais bien, me voilà rapidement face à un chacal garou rouge!! Fuyons ! Alors que Cahouète mord ce chacal garou : > The werejackal reads a scroll labeled PHOL ENDE WODAN! Oh mon dieu, un chacal lettré! Il a disparu. Je suppose que PHOL ENDE WODAN permet de se téléporter... Je le retrouve d'ailleurs un peu plus loin. Et cette fois : > The werejackal zaps herself with a curved wand! > The werejackal is suddenly moving faster Maman! Un chacal magicien! Il faut s'y résoudre, cet animal est un danger sur lequel je ne peux risquer de retrouver plus tard, peut-être affaibli. Je décide donc avec bravoure de le combattre... De loin, en lui lançant des dagues. > The dagger hits the werejackal > You throw 2 daggers. The 1st dagger hits the werejackal > The 2nd dagger hits the werejackal > You hit the werejackal! The werejackal hits! > You kill the werejackal! Welcome to experience level 3. Ouuuuuh yeah \.o./ Le niveau se termine sans encombre, si ce n'est que la nourriture commence à manquer. Voilà où j'en suis juste avant de descendre les escaliers menant au niveau suivant: ``` ------------- -------------- |............############....^........-# |..<........| |............|# ------------ |............# --|-----------# |...........### ---------.---# # # |..........| # # # # # |..........| # # # # # |......d...| # ## # # # |.......@..| ####### ## ## #### # |..........| ############ ###### # -.--------- # ----------.- ## ### -|---.-- ######## |........^| # # #### ##|......| #-----# ###-.........| #--.--- #|{......#######|...-### |.........| #|....| #|......| #%...|# ## |.........| #|....| #-......| #|....### |>........| #|....| -------- #-...| ###..........| #.....| ----- ----------- ------ Prx the Cutpurse St:11 Dx:18 Co:18 In:10 Wi:7 Ch:11 Chaotic Dlvl:4 $:29 HP:30(30) Pw:8(8) AC:7 Xp:3 ``` ## Niveau 5 > The little dog falls into a pit! Houla, attention à toi Cahouète! Me voilà seul... J'avance à peine qu'un gnome se rue sur moi. J'ai vite fait de le tuer et récupère les 2 gemmes rouges qu'il laisse tomber. Cependant, quelques pas plus loin : > You are almost hit by a stout spear. > The dwarf wields a broad short sword! > You hit the dwarf. The dwarf thrusts her broad short sword. > The dwarf hits! > You hit the dwarf. You hear some noises in the distance. > The dwarf thrusts her broad short sword. The dwarf hits! Quoi??? Un 2e nain ? Fuyons ! > The dwarf thrusts her dagger. The dwarf hits! > The dwarf thrusts her broad short sword. The dwarf hits! > You die... Gasp... Adieu monde cruel! (il semble qu'il y avait 2 escaliers au niveau d'avant. Je suis descendu dans les mines, l'autre escalier aurait-il été plus à mon niveau ?) ``` ---------- / \ / REST \ / IN \ / PEACE \ / \ | prx | | 29 Au | | killed by a | | dwarf | | | | | | 2021 | *| * * * | * _________)/\\_//(\/(/\)/\//\/|_)_______ Goodbye prx the Rogue... You died in The Gnomish Mines on dungeon level 5 with 451 points, and 29 pieces of gold, after 2559 moves. You were level 3 with a maximum of 30 hit points when you died. ``` ## Une réaction? => mailto:prx@si3t.ch?subject=nethack-9 Envoyez votre commentaire par mail. ]]> Obtenir le status de mpd avec awk https://si3t.ch/log/2021-12-06-mpd-status-avec-awk.txt 2021-12-06T13:27:53Z mailto:prx@si3t.ch?subject=mpd-status-avec-awk Envoyez votre commentaire par mail. ]]> Les livres que j'ai aimé https://si3t.ch/log/2021-11-20-livres-favoris.txt 2021-11-20T16:17:00Z La science fiction est un excellent outil de pédagogie du réel. -- Roland Lehouq, président des Utopiales Je ne prétends pas être une référence en terme littéraire. Aussi mes goûts peuvent être critiqués, je n'en doute pas. Piochez, découvrez, lisez, et n'hésitez pas à me faire part de vos coups de coeur ;). Je tiendrai cette liste à jour ici : => /notes/livres_favoris.gmi Livres favoris (gemini) => /notes/livres_favoris.html Livres favoris (http) ## Fils des brumes (Sanderson) Nous suivons une héroïne (pour une fois!) aux pouvoir particuliers. Brandon Sanderson décrit une magie particulière : on puise des pouvoirs différents selon le métal que l'on "brulant". Sanderson est très fort pour inventer des règles et jouer avec. Pour sûr, il est inventif et sait nous tenir en haleine. En toile de fond, on y retrouve la question de l'écologie. Il faut en effet sauver le monde d'une menace venant des origines de l'univers. ## Les archives de Roshar (Sanderson) Un univers complet et riche nous est décrit ici (nations, coutumes et croyances...). Les émotions des hommes se manifestent sous forme de sprènes. On y suit des personnages profonds qui découvriront des pouvoirs en même temps que le lecteur. C'est aussi amusant que surprenant. On est loin des pouvoirs "classiques" : l'un peut contrôler la gravité (en quelque sorte), l'autre tire ses capacités de son imagination ou encore peut retirer à sa guise les forces de frottement l'entourant. On y retrouve ici aussi la question de l'écologie : une tempête régulière et mortelle ravage régulièrement les contrées : comment s'y adapter? Quelle est son origine? ## Le cycle Drenaï (Gemmel) Avec Druss la légende ou encore Waylander, on plonge dans l'univers de David Gemmel où les ambitions des hommes se heurtent à leurs passions. J'ai découvert cette saga avec Druss la légende. Il y est question d'honneur. On suit un homme qui semble indestructibe et si fort que tous ses ennemis échouent. Pourtant, la forcé véritablement importante est-elle celle des muscles de nos bras? C'est toute la contradiction de Druss. Récits épiques et guerres perdures d'avance, la valeur des Hommes (et des femmes) y est décrite de façon touchante. Depuis, je recommande chaudement tout ouvrage de David Gemmel :) ## La citadelle des ombres, Les aventuriers de la mer, Dragons et serpents (Robin Hobb) Dans la saga "La citadelle des ombres", bous découvrirez le monde de Fitz, l'homme le plus nul de tous les temps! Il est faible, il fait constamment des erreurs, et pourtant c'est le héros. Rien de comique ici, mais que c'est frustrant d'être confronté à ses erreurs. Il doit pourtant dans le secret aider à sauver le royaume de pirates qui forgisent la population : les habitants sont dénués de sentiments et d'émotion. Qu'en faire ensuite? Et d'où vient cette menace exactement? Les anciens parlent de dragons qui pourraient leur venir en aide, mais semblent avoir disparu. Robin Hobb invente de nouvelles formes de magie : l'Art (qui permettrait de communiquer à distance par la pensée notamment) et le Vif pour échanger avec les animaux. Poursuivez l'aventure avec les aventuriers de la mer et Dragons et serpents qui se déroulent dans le même monde, avec des personnages différents mais toujours aussi riches. Ainsi on comprend l'origine de la magie et des Dragons de cet univers. Comme tous les ouvrages de Robin Hobb, c'est lent... mais on en veut toujours plus ! Les personnages sont d'une richesse et d'une profondeur passionnante. C'est à mon avis toute la force de ses récits : les voir évoluer, changer, souffrir, espérer... Qu'ils sont vivants! ## Le soldat chamane (Robin Hobb) Encore du Robin Hobb. Un gros coup de coeur pour moi. Différents peuples se partagent un monde, et forcément, ils ne sont pas en paix. Le héros doit se former en tant que soldat pour plaire à son père, mais est confronté à la magie des autres peuples qui va le transformer en profondeur. L'identité de ce dernier est fractionnée. Il souffre et trébuche encore et encore. Entre plusieurs cultures et mondes, il doit faire des choix impossibles pour protéger ces derniers. ## Le seigneur des anneaux (Tolkien) Est-ce vraiment nécessaire de présenter cette saga? Je me souviens d'entendre mon coeur battre à tout rompre au rythme des tambours de la Moria et l'angoisse m'étreindre alors que Minas Morgul vomit ses armés et que mon lecteur cassette jouait du Gorillaz. ^^ ## Le cycle de Dune (Frank Herbert) Bon vous vous en doutez, c'est ma saga préférée. L'univers développé est aussi complexe que riche. On y parle écologie, mythologie, religion, croyances et intrigues politiques. Il y est question de libre arbitre, et d'intelligence! Quoi de mieux que de la SF dans un univers où les ordinateurs sont interdits? À lire ! ## Fondation (Asimov) Une suite de nouvelles dont l'issue est à chaque fois étonnante. Alors que tout semble perdu, une solution à laquelle on n'avait pas pensé surgit : si seulement on réfléchissait un peu plus... C'est mon 2e ouvrage préféré avec Dune :) À lire! ## Les robots (Asimov) Quoi de mieux que les robots pour parler des humains ? On ne présente pas Asimov : il joue avec les 3 lois de la robotique avec finesse. À lire! ## Le Don, le Sang, l'Âme (Fiona McIntosh) Malédiction : à chaque fois que le personnage principal est tué, il se retrouve dans le corps de son assassin. C'est gé-nial ! ## Les racines du mal (Maurice G. Dantec) Première partie : on suit un assassin complètement félé. Un homme est chargé de développer une IA qui modélise le cerveau de ce genre d'assassin. Deuxième partie : l'IA révèle que certains meutres qui ont été commis ne correspondent pas au mode opératoire. L'assassin a donc été condamné à tort, et les véritables coupables sont toujours en liberté... et sont bien pires. C'est aussi horrible que bien écrit. Accrochez-vous et préparez les somnifères! ## Farenhein 451 (Ray Bradbury) Il faut vraiment le présenter ? À lire! ## Le Petit Prince (A. de St Exupery) Ben oui, j'adore! C'est très vite lu, et ce voyage initiatique rappelle la vraie valeur des choses. ## Zadig ou la destinée (Voltaire) Plusieurs comptes philosophiques dont j'apprécie la morale pour en discuter avec autrui. ## Notre Dame de Paris (V. Hugo) Un drame comme on les aime. Hugo écrit vraiment bien et je trouve ce livre très poétique bien que triste. ## Nouvelles (P. K. Dick) ## Une réaction? => mailto:prx@si3t.ch?subject=livres-favoris Envoyez votre commentaire par mail. ]]> What if there is no more internet ? https://si3t.ch/log/2021-10-22-internet-no-more.txt 2021-10-22T21:07:51Z gemini://perso.pw/blog/articles/huge-disaster-recovery-plan.gmi Like a physicists wonders what happens when a force disappear to understand an equilibrium situation, I must say I like such questions. What if...? => https://what-if.xkcd.com At first, I thought like Solène : save human kind knowledge. This means Wikipedia dumps at least. Save important personal data too, mostly pictures and memories. (Note to myself : print your favourite family pictures.) Also, I thought : some games are like piece of art and must be kept safe. Music too. Then I wondered : "what for do you use your computer?" The answer makes me wonder... I use it for my work. documents for my lessons. But actually, my best lectures are the ones without computer presentation but with more experiments and intelligence shared beteween students. So... meh. I use my computer to communicate over the Internet (mostly emails, blog reading and XMPP). No internet means less time spend watching cats on youtube, drama about the color of a dress, reading jokes here and there while sitting on the toilet. Seriously, I would miss the opportunity to meet great people, some with who I feel closer than my own neighbours. Taht would be a pity. So, backup those persons adress to write them letters (some around Lyon, other at Not-in-Canada-Montreal, even some in cities called something-over-Meu :)) On second thought, saving Wikipedia is probably not so relevant. Except programming, which is useless if computers disappear, almost everything I know doesn't comes from the Internet. The most important is already in good books like printed encyclopedia. Of course, if there is no Internet anymore, you won't be able to read the Kardashian's Wikipedia page. And this page probably doesn't exist in the library encyclopedia. Is it bad? Infact, stupid stuffs like Kardashian's hype probably exists only because of internet. No internet, no need to learn about it. When searching "Top 100 Most Visited Websites by Search Traffic", it seems that most website are visited to look for/understand/waste time on other websites. I don't see anything in the top 10 I couldn't replace or stop using : (from https://ahrefs.com/blog/most-visited-websites/) * 1. en.wikipedia.org : books * 2. youtube.com : Go to theater. Except some great creative content, it's a waste of time. Less access to creative content doesn't means it disappear. * 3. amazon.com : There are stores. Next to your house. That's probably better than buying cheap stuff delivered across hundred of kilometers by underpaid people. * 4. facebook.com : Talk. * 5. twitter.com : Again, talk. * 6. fandom.com : I only used it to read stuff about video games. No video games, no need fandom for me. I guess I could read the game files instead. * 7. pinterest.com : Hum, doesn't use already. * 8. imdb.com : Once upon a time, there was video clubs. * 9. reddit.com : speak god dammit! * 10. yelp.com : never used What I mean here is that Internet self-feed itself and let us think it has become something we can't live without. Big joke. Try to live one entire day without screens. Shut down the house power and tell everyone with a very convincing voice : > Oh no, there is a problem at the power plant. (/quavering/) What a pity. Then, go out, play with your kids, invite friends to eat marshmallow over a wood fire, sing songs, play hide and seeks, walk in the forest, gather some flowers, paint some stones to spread in the town to decorate, bring a pie to your grandma, watch the clouds, build a hut, listen to the wind, read a book at the candle light, write a letter to a long time no see friend, listen to music or dance, make love under the stars. not necessarily in this order ;) ## Something to say ? => mailto:prx@si3t.ch?subject=internet-no-more Send your reaction by mail ]]> Retour sous XMPP https://si3t.ch/log/2021-10-15-xmpp.txt 2021-10-15T21:07:51Z https://tilde.team/~kiedtl/blog/irc/ IRC's flaws J'aimerais bien voir XMPP plus souvent utilisé, aussi je vous invite à réessayer :) Un compte se crée en quelques instants, et un serveur se configure aussi très vite (prosody). Je n'ai pas encore ouvert les inscriptions sur mon propre serveur. À vrai dire, je serais curieux de savoir si ça intéresse quelqu'un ? Ça pourrait être un truc que j'ajoute comme service en @si3t.ch (un CHATONS inofficiel ^^). ## Par où commencer? Téléchargez un client, créez un compte (une adresse), et c'est parti! => https://xmpp.org/getting-started/ Getting started ## Quel client utiliser? Un client, c'est un logiciel qui permet d'utiliser un compte XMPP. Voici des clients de qualité : gajim, dino, conversations (android), profanity (en console, j'adore \o/). => https://conversejs.org/ ConverseJS, client en ligne (bof, ça dépanne) => https://dino.im/ Dino, efficace et sobre => https://gajim.org/ Gajim, le vénérable => https://f-droid.org/en/packages/eu.siacs.conversations/ Conversations sur Android, excellent! => https://profanity-im.github.io/ profanity (en console, j'adore \o/). ## Quels salons de discussion? Voici quelques salons que j'apprécie: * auto-hébergement@muc.chapril.org : salon d'antraide autour de l'hébergement en général. On y apprends plein de choses et les gens sont sympas. * geminauts@chat.kwiecien.us pour parler de gemini, et tout un tas d'autres trucs sympas * openbsd@chat.si3t.ch : salon de discussion autour d'OpenBSD. Un certain Thuban avait créé il y a des années un salon équivalent sur jabberfr.org, mais ce dernier a paumé ses identifiants comme un gros boulet :-*. * openbsd_fr@chat.si3t.ch : pareil, mais pour parler en français * fremen@chat.si3t.ch : mon petit salon où vous êtes les bienvenus :) Si vous cherchez un salon de discussion, il y a cette interface : => https://search.jabber.network/rooms/1 Vous en connaissez d'autres ? N'hésitez pas à m'en faire part. :) ## Une réaction? => mailto:prx@si3t.ch?subject=xmpp Envoyez votre commentaire par mail. ]]> Nethack -- Épisode 8 https://si3t.ch/log/2021-10-10-nethack-8.txt 2021-10-10T21:07:51Z Aloha prx, welcome to NetHack! You are a neutral female human Tourist. Ça faisait un longtemps n'est-ce pas? Me voilà touriste :) Youpi, c'est les vacances! Et puisque le monde de Nethack est merveilleux, j'ai plein de thunes, de nourriture, des fléchettes et... ``` i - an uncursed carrot ``` À moi l'orbe ! ;) ## Niveau 1 Le premier niveau se passe plutôt pas mal. J'aveugle les ennemis trop gros avec l'appareil photo et mon chat les défonce. Brave Kiki. À la fin, il ressemble à ça : ``` ----------- ---------- |..........######|.........##################### ------- |.........| #.........| |.....| |.........| #|......<.| |.....| |.........-# #-----.---- --------- |.....| ---.-------# # # |........# ---.--- # # # ## ###........|# ##### ##### # # ## # |.......|# # # ### # # # ---------# ### -.---- # ### # ### # # |....| ## ###`## # # # # |.....################################################### |....| # # # # # # # ---|---.--- |....| #------# ----.-- ### ##-.........| |....| #.....-# |......# |.........| |....| |....| |.....|## |.........| ------ |....| |.....|# |......@>.| ------ |......# |......f..| ------- ----------- Prx the Rambler St:12 Dx:15 Co:14 In:12 Wi:9 Ch:14 Neutral Dlvl:1 $:176 HP:10(10) Pw:3(3) AC:10 Xp:1 ``` Je suppose que je n'ai pas trouvé tous les passages, mais tant pis, je continue. ## Niveau 2 Au niveau 2, je bloque sans faire exprès une porte avec un boulet. J'enrage : il y avait certainement un truc super dans cette pièce! Certainement un commerce vu les messages concernant des bruits de pièces d'or en train de tomber qui apparaissent. GRRR. Plus loin je trouve des lentilles. Je tente de les porter pour voir si ça change quelque chose, mais il semble que non. Quelques jackal, rats et goblin plus loin, je décide de filer au niveau suivant. ``` --------------- #..............| -------------- #|..<..........| |..>.........-# | #|.............| #######-............|# |. ##|..............####### |............|## | # -.-------------# ####.............| # `################ ###### ## ----.--------- # #### ##### # ###### # # ###### ### ## # # ##-.-.----- # ## # # ##|.......| ### ## # ### ######|{......| # # `#######`#### ---|------#### |........### #---.------------ #--.-- |........|# # #........| ######## #-..@f).........| #|...| |........-#######|^......| ### |.............{| #....| |........| # --------- ## |..............| |...| |.........### ###-..............| ----- ---------- ---------------- Prx the Rambler St:12 Dx:15 Co:14 In:12 Wi:9 Ch:14 Neutral Dlvl:2 $:192 HP:4(15) Pw:7(7) AC:10 Xp:2 ``` Ouep, pas top ce 4 HP. Il faudra faire gaffe ^^ ## Niveau 3 Youpi! Un magasin est présent dans ce niveau \o/ Et bien sûr, alors que je me précipite ... ``` Wait! That's a small mimic! ``` Ouille, voilà les HP descendus à 2/15 :s Je m'enfuis aussi vite que possible. Ouf, il semble que cette bestiole ne me suis pas. ``` Wait! That's a small mimic! The small mimic hits! You die... ``` C'était trop bien parti ^^ ``` ---------- / \ / REST \ / IN \ / PEACE \ / \ | prx | | 201 Au | | killed by a | | small mimic | | | | | | 2021 | *| * * * | * _________)/\\_//(\/(/\)/\//\/|_)_______ Aloha prx the Tourist... You died in The Dungeons of Doom on dungeon level 3 with 261 points, and 201 pieces of gold, after 1473 moves. You were level 2 with a maximum of 15 hit points when you died. ``` ## Une réaction? => mailto:prx@si3t.ch?subject=nethack-8 Envoyez votre commentaire par mail. ]]> Code d'intégration du support de gzip à httpd https://si3t.ch/log/2021-10-06-httpd_gzip_code.txt 2021-10-06T21:07:51Z gzip_static) { ``` Ensuite, nous allons avoir besoin de quelques variables : ``` struct http_descriptor *desc = clt->clt_descreq; struct http_descriptor *resp = clt->clt_descresp; struct stat gzst; struct kv *r, key; char gzpath[PATH_MAX]; ``` "desc" et "resp" permettront de vérifier que le navigateur supporte la compression gzip et d'envoyer l'entête indiquant que le contenu est bien compressé. "r" et "key" serviront à fouiller dans les entêtes. (je m'aperçois que "desc" devrait plutôt s'appeler "req"...). "gzst" et "gzpath" permettront de remplacer les informations sur le fichier demandé et son chemin d'accès si ce dernier est bien disponible chiffré. On vérifie tout d'abord que le navigateur accepte le "gzip" en cherchant l'entête "Accept-Encoding". Si ce dernier existe, on cherche "gzip" puis on continue : ``` /* check Accept-Encoding header */ key.kv_key = "Accept-Encoding"; r = kv_find(&desc->http_headers, &key); if (r != NULL) { if (strstr(r->kv_value, "gzip") != NULL) { ``` Ensuite, on ajoute ".gz" au nom du fichier demandé ``` strlcpy(gzpath, path, sizeof(gzpath)); strlcat(gzpath, ".gz", sizeof(gzpath)); ``` La variable "gzpath" contient maintenant "path" + ".gz". Reste à tester si l'accès à ce fichier gzippé est possible : s'il existe et s'il est lisible : ``` if ((access(gzpath, R_OK) == 0) && (stat(gzpath, &gzst) == 0)) { ``` Si c'est tout bon, alors on remplace le chemin d'accès par la version gzippée et on l'indique dans les entêtes envoyés : ``` path = gzpath; st = &gzst; kv_add(&resp->http_headers, "Content-Encoding", "gzip"); ``` Et voilà :) Le reste, on n'y touche pas, le serveur httpd se charge de servir le fichier. Il aura fallu tout de même déplacer une ligne pour obtenir le type de fichier demandé avant de tester le gzip : ``` media = media_find_config(env, srv_conf, path); ``` Ça paraît en fait tout simple. Il aura fallu réfléchir tout de même un peu, mais très franchement il faut très peu de lignes. J'apprécie énormément la clarté du code d'OpenBSD, finalement très accessible pour un débutant en C comme moi. :) ## Tester le diff Pour ceux que ça intéresse, voici comment tester le diff : * Récupérer le code source comme indiqué ici : http://www.openbsd.org/anoncvs.html * Aller dans /usr/src/usr.sbin/httpd * Récupérer le diff et l'enregistrer dans /tmp/httpd_gzip.diff * Patcher : "patch -p1 < /tmp/httpd_gzip.diff * make && doas make install Ajoutez l'option "gzip_static" dans la configuration d'un domaine servi par httpd. Compressez les fichiers que vous voulez servir gzippés ainsi : ``` $ gzip -9 -c fichier.html > fichier.html.gz ``` Ouvrez un navigateur pour demander "fichier.html" et vérifiez que l'entête "Content-Encoding : gzip" est présent. Vous pouvez aussi remarquer que la taille téléchargée est bien plus petite qu'avant. ## Le diff ``` Index: httpd.conf.5 =================================== RCS file: /cvs/src/usr.sbin/httpd/httpd.conf.5,v retrieving revision 1.118 diff -u -r1.118 httpd.conf.5 --- httpd.conf.5 7 Jun 2021 10:53:59 -0000 1.118 +++ httpd.conf.5 5 Oct 2021 19:27:34 -0000 @@ -381,6 +381,10 @@ features in use .Pq omitted when TLS client verification is not in use . .El +.It Ic gzip_static +Enable static gzip compression. +.Pp +When a file is requested, serves the file with .gz added to its path if it exists. .It Ic hsts Oo Ar option Oc Enable HTTP Strict Transport Security. Valid options are: Index: httpd.h ======================================== RCS file: /cvs/src/usr.sbin/httpd/httpd.h,v retrieving revision 1.157 diff -u -r1.157 httpd.h --- httpd.h 17 May 2021 09:26:52 -0000 1.157 +++ httpd.h 5 Oct 2021 19:27:34 -0000 @@ -85,6 +85,7 @@ #define SERVER_DEF_TLS_LIFETIME (2 * 3600) #define SERVER_MIN_TLS_LIFETIME (60) #define SERVER_MAX_TLS_LIFETIME (24 * 3600) +#define SERVER_DEFAULT_GZIP_STATIC 0 #define MEDIATYPE_NAMEMAX 128 /* file name extension */ #define MEDIATYPE_TYPEMAX 64 /* length of type/subtype */ @@ -542,6 +543,8 @@ struct server_fcgiparams fcgiparams; int fcgistrip; + + int gzip_static; TAILQ_ENTRY(server_config) entry; }; Index: parse.y ======================================== RCS file: /cvs/src/usr.sbin/httpd/parse.y,v retrieving revision 1.125 diff -u -r1.125 parse.y --- parse.y 10 Apr 2021 10:10:07 -0000 1.125 +++ parse.y 5 Oct 2021 19:27:34 -0000 @@ -140,7 +140,7 @@ %token PROTOCOLS REQUESTS ROOT SACK SERVER SOCKET STRIP STYLE SYSLOG TCP TICKET %token TIMEOUT TLS TYPE TYPES HSTS MAXAGE SUBDOMAINS DEFAULT PRELOAD REQUEST %token ERROR INCLUDE AUTHENTICATE WITH BLOCK DROP RETURN PASS REWRITE -%token CA CLIENT CRL OPTIONAL PARAM FORWARDED FOUND NOT +%token CA CLIENT CRL OPTIONAL PARAM FORWARDED FOUND NOT GZIPSTATIC %token STRING %token NUMBER %type port @@ -288,6 +288,8 @@ s->srv_conf.hsts_max_age = SERVER_HSTS_DEFAULT_AGE; + s->srv_conf.gzip_static = SERVER_DEFAULT_GZIP_STATIC; + if (last_server_id == INT_MAX) { yyerror("too many servers defined"); free(s); @@ -1140,6 +1142,9 @@ srv_conf->flags &= ~SRVFLAG_BLOCK; srv_conf->flags |= SRVFLAG_NO_BLOCK; } + | GZIPSTATIC { + srv_conf->gzip_static = 1; + } ; block : BLOCK { @@ -1400,6 +1405,7 @@ { "fastcgi", FCGI }, { "forwarded", FORWARDED }, { "found", FOUND }, + { "gzip_static", GZIPSTATIC }, { "hsts", HSTS }, { "include", INCLUDE }, { "index", INDEX }, Index: server_file.c ============================================ RCS file: /cvs/src/usr.sbin/httpd/server_file.c,v retrieving revision 1.70 diff -u -r1.70 server_file.c --- server_file.c 29 Apr 2021 18:23:07 -0000 1.70 +++ server_file.c 5 Oct 2021 19:27:34 -0000 @@ -229,20 +229,49 @@ goto abort; } + media = media_find_config(env, srv_conf, path); + if ((ret = server_file_modified_since(clt->clt_descreq, st)) != -1) { /* send the header without a body */ - media = media_find_config(env, srv_conf, path); if ((ret = server_response_http(clt, ret, media, -1, MINIMUM(time(NULL), st->st_mtim.tv_sec))) == -1) goto fail; goto done; } + /* change path to path.gz if necessary. */ + if (srv_conf->gzip_static) { + struct http_descriptor *desc = clt->clt_descreq; + struct http_descriptor *resp = clt->clt_descresp; + struct stat gzst; + struct kv *r, key; + char gzpath[PATH_MAX]; + + /* check Accept-Encoding header */ + key.kv_key = "Accept-Encoding"; + r = kv_find(&desc->http_headers, &key); + + if (r != NULL) { + if (strstr(r->kv_value, "gzip") != NULL) { + /* append ".gz" to path and check existence */ + strlcpy(gzpath, path, sizeof(gzpath)); + strlcat(gzpath, ".gz", sizeof(gzpath)); + + if ((access(gzpath, R_OK) == 0) && + (stat(gzpath, &gzst) == 0)) { + path = gzpath; + st = &gzst; + kv_add(&resp->http_headers, + "Content-Encoding", "gzip"); + } + } + } + } + /* Now open the file, should be readable or we have another problem */ if ((fd = open(path, O_RDONLY)) == -1) goto abort; - media = media_find_config(env, srv_conf, path); ret = server_response_http(clt, 200, media, st->st_size, MINIMUM(time(NULL), st->st_mtim.tv_sec)); switch (ret) { ``` ## Liens => https://dataswamp.org/~solene/ Solène => https://si3t.ch/Logiciel-libre/Code/archive.tgz sbw dans l'archive de code ## Une réaction? => mailto:prx@si3t.ch?subject=httpd_gzip_code Envoyez votre commentaire par mail. ]]> 10km https://si3t.ch/log/2021-09-27-10km.txt 2021-09-27T21:07:51Z mailto:prx@si3t.ch?subject=10km Envoyez votre commentaire par mail. ]]> Notes sur l'installation de prosody (XMPP) sur OpenBSD https://si3t.ch/log/2021-09-19-prosody.txt 2021-09-19T21:07:51Z https://prosody.im/doc ## Une réaction? => mailto:prx@si3t.ch?subject=prosody Envoyez votre commentaire par mail. ]]> Wiby https://si3t.ch/log/2021-09-17-wiby.txt 2021-09-17T21:07:51Z https://www.wiby.me wiby Un champ pour entrer sa recherche, un bouton "surprise me" pour aller sur une page au hasard, et un bel ascii art :) ``` .n. | /___\ _.---. \ _ / [|||] (_._ ) )--;_) =- [_____] '---'.__,' \ }-=-{ | |-" | |.-"| p ~^=~^~-|_.-|~^-~^~ ~^~ -^~^~|\ ~^-~^~- ^ .=.| _.|__ ^ ~ /| \ ~ /:. \" _|_/\ ~ /_|__\ ^ .-/::. | |""|-._ ^ ~~~~ `===-'-----'""` '-. ~ jgs __.-' ^ ``` Alors déjà, le bouton "surprise me" est génial : il permet de découvrir de nouvelles choses et sortir de sa zone de confort. On y retrouve donc un esprit pre-web 2.0 que j'apprécie fortement. En fouillant un peu, on découvre des bonus, comme une page de chat (wiby.me/chat), une API pour y faire des recherches (https://wiby.me/json/). Il s'agit là d'un moteur de recherche qui indexe les pages simples, non commerciales et sans surcharges de CSS et JS. De plus, lorsqu'on lit la page d'ajout (https://www.wiby.me/submit/), on se rend compte que seules les pages soumises sont indexées : il n'y a donc pas de bot qui scanne tout le web en permanence. Merci donc à la personne qui a demandé l'indexation de mon site, le voir sur wiby me fait chaud au coeur. Je vous invite à tester ce moteur et à prendre le temps de découvrir les perles qui s'y trouvent, à l'ancienne. ^^ ## Une réaction? => mailto:prx@si3t.ch?subject=wiby Envoyez votre commentaire par mail. ]]> Vaccin, covid, doutes et réflexions https://si3t.ch/log/2021-07-16-vaccin-doute-reponses.txt 2021-07-16T21:07:51Z /img/think/dictature-complots-covid.png On peut alors lire beaucoup de colère qui semble empêcher tout discernement. Il est question de soi disant atteinte à la liberté, d'appels à la révolte et j'en passe. Florence Porcel met le doigt sur un point à mon avis essentiel : si on vit seul, alors on est lire de (ne pas) faire comme bon nous semble. Or, nous vivons en société. Cela restreint donc nos libertés : on ne conduit pas à gauche en France, on n'achète pas une arme sans autorisation, on ne jette pas ses déchets dans la rue. Ces contraintes sont le prix à payer pour que tout le monde vive sereinement, et le gouvernement n'a rien à voir là dedans. Rassurez-moi, vous avez entendu ça quand vous étiez petits? > La liberté de chacun s'arrête là où commence celle des autres. ## Compilation des raisons pour ne pas se faire vacciner. Voici une petite sélection de ce que j'ai pu lire ou entendre. Vous remarquerez qu'un schéma se répète : méfiance, crainte et désinformation. Lorsque je dis ça, ce n'est en rien une critique. > Je connais des gens qui ont eu la COVID, et ils vont très bien. Remplacez "COVID" par "cancer", et ça marche aussi. Qu'une proportion de personnes s'en sorte bien ne diminue pas la dangerosité de la maladie. Perso, je n'ai pas envie de prendre le risque. > Ouvre les yeux, on nous manipule. C'est vrai : on peut même voir que ça marche : des millions de prises de rendez-vous dès l'instant où on n'a plus le droit de peut-être propager un virus mortel en allant au resto ou au spectacle. Cette réaction très égoiste en dit long. C'est triste qu'il faille en arriver là. Ça serait tellement mieux si chacun prenait ses responsabilités pour le bien être de tous. Si on nous manipule, c'est dans l'intérêt de qui? > De l'État Je vous laisse méditer sur ce que c'est, "L'État". Je vois surtout que c'est gratuit et que ça évite des morts. > Je refuse que l'on m'injecte un truc qui me fera peut-être mourir dans 10 ans. La molécule injectée a une durée de vie très courte. C'est même pour ça qu'il faut la congeler à -70°C. Elle reste donc très peu de temps dans l'organisme. Si effets secondaires néfaste il y aurait, on s'en serait aperçu avec les premières personnes testées lors de la recherche. > Le développement du vaccin est allée trop vite. C'est allé très vite, parce que : * Face à l'urgence, les gouvernements ont investit de l'argent dans la recherche (ce qui n'est pas le cas habituellement) * Les techniques existaient déjà (ARNm...) Cela ne signifie pas que le protocole expérimental a été baclé. Des tests ont été effectués, et des vérifications rigoureuses aussi. Les publications nombreuses par des experts se corrèlent. Pour le vérifier, il faut aller les lire (voir le tout dernier lien à la fin). J'imagine que l'efforts que cela demande est plus important que de scroller sur son smartphone en faisant caca. Il faut effectivement faire confiance. Je fais davantage confiance à des experts dans leurs domaines qu'à Gwladys qui se fait des cataplasmes au miel. Je me dis que si on envoyait aujourd'hui pour la première fois des gens sur la Lune, personne n'y croirait. > Etre vacciné n'empêche pas de propager le virus ou de tomber malade Ça réduit énormément le risque de propager le virus. Ça réduit énormément le risque de tomber GRAVEMENT malade, et donc de subir des séquelles > La grippe fait des morts, et le vaccin contre la grippe ne sert à rien Faux, le vaccin contre la grippe sauve des vies tous les ans. Le virus de la grippe n'est pas de la même nature que le COVID-19. Il mute régulièrement, donc le vaccin doit anticiper la forme qu'il aura. Vous savez, les mutations, commes celles que l'on craint. Ce n'est pas fiable à 100%, mais ça ne veut pas dire qu'il est inefficace. > C'est une histoire de gros sous Il y a un marché, c'est vrai. Mais un vaccin, on le fait une fois dans toute sa vie. Ça veut dire qu'on vend les doses pour un patient une fois, et après il n'y a plus de revenu. Si j'étais à la tête d'un labo, et que je voulais juste me faire du fric, je miserai plutôt sur des médicaments administrés très souvent tout au long d'une vie (paracétamol, insuline, pilule contraceptive, homéopathie (lol)...). > On te manipule avec de faux chiffres Autrement dit, tous les états, souvent en conflit entre eux, se sont mis d'accord pour publier de faux chiffres allant tous dans le même sens pour... Pourquoi en fait? Qu'est-ce qu'il y aurait à y gagner? > J'ai pas le temps de lire tout ça (en référence aux publications et articles explicatifs) Alors arrête de dire des conneries? > Sincèrement on nous ment on nous injecte un danger dont on est les cobayes => /img/Fun/vaccin_magnet_prepuce.png Je m'arrête là :) ## Pourquoi tant de méfiance ? Il est certain que les annonces gouvernementales incohérentes voire contradictoires n'aident en rien. C'est aussi triste que comique. De plus, la france souffre d'une très mauvaise culture scientifique. Demandez à quelqu'un de dessiner un scientifique, il vous représentera un type mal coiffé à l'air un peu fou. Il y a donc aussi un problème culturel de représentation des sciences. Ça se sent dans les décisions politiques (carrément à l'ouest) et dans les explications des journalistes (sans formation scientifique) souvent maladroites. Je souhaite donc rappeler que la science : * c'est accepter de se tromper. * c'est chercher des heures, échouer encore et encore pour comprendre. * c'est apprendre de ses erreurs avec humilité. => /img/kaamelott/humilite.gif Les sciences sauvent des vies. Elles nous permettre de vivre dignement dans le confort et le luxe. Il suffit de comparer notre mode de vie avec celui des années 1600 pour s'en rendre un peu compte. ## Chance d'être vacciné En France, le vaccin est gratuit et pour tout le monde. On est vraiment privilégiés. ## Course contre la montre ? Juste comme ça : tant que le virus circule, il mute. Il est donc tout à fait envisageable qu'une mutation beaucoup plus contagieuse voire mortelle que celles existantes voit le jour. Cela laisse la place à une forme résistante, comme pour la grippe. Perso, j'ai pas envie. J'aimais bien pouvoir serrer la main des gens et ne pas avoir à prendre toutes ces précautions. ## Mots de la fin Patience, Instruction, Amour... ou sélection naturelle ? ## Sources On ne le rappellera jamais assez : vérifiez ce que vous lisez en croisant les sources et en vous demandant si la source est de confiance. Ne prenez jamais une affirmation péremptoire comme vérité. Voici une partie des sources qui m'ont permis d'écrire cette page : => https://fr.wikipedia.org/wiki/Vaccination#Histoire Histoire de la vaccination. => https://fr.wikipedia.org/wiki/Louis_Pasteur Louis Pasteur => https://couleur-science.eu/?d=f4787a--cest-quoi-larnm-comment-fonctionne-un-vaccin Comment fonctionne un vaccin. => https://www.service-public.fr/particuliers/vosdroits/F2366 Vaccins obligatoires pour les soignants. => https://www.pasteur.fr/fr/centre-medical/preparer-son-voyage Vaccins à réaliser pour visiter certains pays. => https://www.ameli.fr/assure/sante/themes/vaccination/vaccins-obligatoires Liste des vaccins obligatoires. => https://twitter.com/FlorencePorcel/status/1415253258101215233 Réflexions de L. Porcel sur la liberté en société => https://www.letemps.ch/sciences/dix-doutes-legitimes-vaccination-zero-bonne-raison-ne-y-aller Dix doutes légitimes sur la vaccination => https://twitter.com/OSS117_Helsinki/status/1415022127200227329?s=19 Incohérences des annonces gouvernementales => https://twitter.com/ComplotsFaciles/status/1415287284002443267 Complots faciles => https://covidtracker.fr/vaccintracker/ Données publiques sur la vaccination => https://www.bbc.com/news/health-57678942 Comparaison avec/sans vaccination du nombre de cas graves => https://www.nejm.org/doi/full/10.1056/NEJMoa2034577 Publication sur le vaccin Pfizer (le plus administré en France) (Safety and Efficacy of the BNT162b2 mRNA Covid-19 Vaccine) ]]> Copier du texte dans un tty https://si3t.ch/log/2021-06-07-copy-tmux.txt 2021-06-07T21:07:51Z https://github.com/tmux/tmux Code source de tmux ## Une réaction? => mailto:prx@si3t.ch?subject=copy-tmux Envoyez votre commentaire par mail. ]]> calendar pour ne plus oublier https://si3t.ch/log/2021-05-26-calendar.txt 2021-05-26T21:07:51Z Euh, faut t'inquiéter là prx, c'est Alzheimer précoce. Alors d'abord, j'ai écrit "Alzheimer" de mémoire sans faute. Mais mon cerveau, c'est de la RAM. Ensuite, je retiens pleins de trucs vraiment utiles : * La couleur des yeux de ma chérie * Les histoires préférées de mon fils * Comment je m'appelle * La recette des crêpes * Les premières périodes du tableau périodique * Les 6 premières décimales de π * Un grand nombre de répliques de l'épisode "blink" de Dr Who * 6 premières décimales de π * Comment utiliser vi > gné gné gné, avec mon caldav Nextcloud et un client droid, j'ai des notifs pour tous les trucs importants, t'es trop naze". Certes. Mais j'aime les choses simples, que voulez-vous. Et devoir installer tout un tas de trucs juste pour me souvenir de dates, ça ne me plaît pas. Aussi, j'étais ravi de découvrir la commande "calendar". > Ha ha, mais ça fait un bail que ça existe! En effet, et c'est le genre d'outils que j'aurais bien aimé connaître plus tôt. Cette commande regarde les évènements listés dans un fichier "$HOME/.calendar/calendar" puis affiche ceux à venir les prochains jours. C'est en plus très symple à sauvegarder et synchroniser sur plusieurs machines. Du coup, une fois ce fichier rempli, il suffit de lancer la commande "calendar" chaque jour. Plusieurs possibilités s'offrent à nous : * Lancer "calendar -a" dans un crontab root, qui envoie le résultat par email * Ajouter une tâche cron "@daily" avec "calendar | mail -s prx@si3t.ch" sur mon serveur. * Ajouter la commande "calendar" à la fin de mon fichier .kshrc. * Lancer en début de session "notify-send "$(calendar)". C'est cette dernière solution que j'ai choisie pour l'instant. Je trouve génial la façon dont le fichier contenant les dates peut être compris. On peut écrire les dates de différentes façons, et on peut même inclure des fichiers déjà présents sur le système. La syntaxe est la suivante : ``` \t ``` le "\t" est là pour indiqué qu'il faut utiliser une tabulation. Le format du mois et des jours estr très souple. Je préfère garder un format chiffré pour m'y retrouver. Des commentaires avec "/* ... */" et des "#include" peuvent être utilisés, comme si c'était du C. Pas besoin de réinventer des trucs qui marchent :) Au final, ça me donne ça : ``` LANG=fr #include #include #include /* MM dd\t description */ 11 30 Anniv' arpi 04 18 Anniv Péhä 05 17 Anniv Starsheep 05 05 Anniv Vinishor 09 02 Anniv JB 08 * Contrôle technique twingo ``` Voilà, je n'aurais plus d'excuses pour oublier l'anniversaire de Starsheep (coucou à tous les autres :)) Autant dire que cet outil va vite m'être indispensable. Le manuel de "calendar" contient des exemples très utiles, comme d'hab :). ### Edit En fait, je n'utilise pas notify-send, mais un terminal. AVec "read", je peux fermer le terminal avec Entrée. J'ajoute l'option "-A 7" pour voir à l'avance d'une semaine. ``` xterm -e "echo 'à venir...\n---'; calendar -A 7; read a" & ``` ## Une réaction? => mailto:prx@si3t.ch?subject=calendar Envoyez votre commentaire par mail. ]]> Nethack -- Épisode 7 https://si3t.ch/log/2021-04-28-nethack-7.txt 2021-04-28T21:07:51Z Pourquoi dwm est mon gestionnaire de fenêtres préféré ? https://si3t.ch/log/2021-04-26-pourquoi-dwm.txt 2021-04-26T21:07:51Z /Logiciel-libre/Suckless/dwm-tour.gmi visite guidée de dwm => /Logiciel-libre/Suckless/dwm.gmi dwm : le guide à la prx (Oui, je pose des liens vers les fichiers gmi pour les utilisateurs de gemini. Les autres peuvent remplacer "gmi" par "html" ou bien lire le texte directement, c'est tout à fait lisible ;)) dwm est mon gestionnaire de fenêtres préféré depuis des années. Et pourtant, j'en ai essayé (fluxbox <3, i3, spectrwm, wmii, evilwm, openbox, pekwm, fvwm, twm, cwm, ...). À chaque fois, je reviens vers dwm car il répond davantage à mes besoins, et surtout, ne RAJOUTE PAS des problèmes. Voici la liste non exhaustive des raisons pour lesquelles je préfère dwm : * Il est rapide. Vraiment très rapide! Niveau ressource, difficile de faire moins gourmand. * Il fonctionne bien. C'est simple, je n'ai jamais eu de bug en l'utilisant (oui, je te regarde cwm). * J'apprécie son style épuré qui évite trop de distraction. Malgré tout, les éléments visuels sont clairs et pratiques (carrés pleins ▪ ou ▫ pour indiquer la présence d'une fenêtre avec un tag, bordure de fenêtre qui va avec le titre affiché pour montrer la fenêtre active, tags actifs surlignés, tag avec fenêtre urgente en surbrillance). * Le système de tag justement : c'est brillant. Les espaces de travail, c'était cool, mais alors les tags, c'est encore mieux. Pouvoir coller des étiquettes aux fenêtres pour ensuite choisir d'afficher plusieurs étiquettes à la fois. cwm tente de reproduire ce schéma avec les groupes (mais cwm a des bugs gênants, surtout sur les raccourcis clavier). Les tags me permettent de passer d'une activité à l'autre sans avoir à chaque fois à réorganiser les fenêtres. * dwm est un outil, pas une contrainte : je n'ai jamais à redimensionner une fenêtre pour en voir le contenu ni à en déplacer une autre qui cacherait légèrement l'information importante de celle en-dessous. * Il n'y a pas d'espace inutilisé à l'écran : je n'ai pas un moniteur géant, ni plusieurs moniteurs. Chaque pixel a son importance. * Par défaut, l'utilisation du clavier est privilégiée. Je trouve ça pratique et rapide. Cependant, ce n'est pas du tout une limitation, on peut très bien utiliser la souris pour gérer les fenêtres. Les seuls ajout à faire c'est : clic-droit sur le titre pour fermer une fenêtre, scroll sur le titre pour changer la fenêtre active, clic-droit sur le status pour lancer un menu (jgmenu ou ddesktop ou xfce4-appfinder ou ...). Si vous n'en avez pas encore eu l'occasion, je vous invite à tester de gestionnaire de fenêtres ;) ]]> Que devient mon serveur si je disparais? https://si3t.ch/log/2021-04-12-si-je-disparais.txt 2021-04-12T21:07:51Z https://si3t.ch/pub/canari.txt canari.txt Ce dernier contiendra tout le nécessaire pour contacter qui sera en mesure de donner la passphrase pour déchiffrer le disque du serveur. En voici un extrait : ``` Bonjour, si vous lisez ce fichier, c'est probablement que je suis mort. Ou bien pas très en forme. On m'a sans doute forcé à prendre une surdose d'homéopathie. Pire, on m'a privé de crêpes et mon corps n'a pas tenu le coup. Plus sérieusement, ce message s'affiche automatiquement lorsque je n'ai pas accédé à mon serveur pendant 2 mois. Si vous voulez prendre des nouvelles, vous pouvez contacter ma chérie au xxxxxxxx (sauf si elle m'a accompagné sur Dune, ça capte mal là bas). ... ``` Le tout reste de savoir comment détecter si je ne me suis pas connecté récemment. Mais tout est prévu d'avance : la commande "last" est faîte pour ça. La suite, c'est un script qui compare des nombres (j'aime bien les dates à partir de l'Epoch pour ça :P) et qui copie le fichier contenant les informations au bon endroit. ``` #!/bin/sh # check if user $1 has logged in since $2 seconds # if not, a file $3 is copied to $4 # Add an entry in a cron task set -e usage() { printf "%s \n" "$0" printf "Example for a month\n" printf "%s batman 2592000 /var/canari /var/www/htdocs/canari.txt\n" "$0" exit 1 } test $# -ne 4 && usage u="$1" delay="$2" content="$3" canari="$4" now=$(date +%s) lastlogin=$(last -s $u | awk 'NR==1 {print $4}') if [ $(( $now - $lastlogin )) -gt $delay ]; then printf "$u not logged for a while, copying canari\n" install -m 555 $content $canari fi exit 0 ``` Ce script est appelé quotidiennement via une tâche cron : ``` @daily /home/pi/bin/canari.sh utilisateur 5184000 /home/utilisateur/canari.txt /var/www/htdocs/si3t.ch/pub/canari.txt ``` Si jamais je devais me faire enlever par des aliens rouxphiles, vous aurez quand même de mes nouvelles :) ]]> Nethack -- Épisode 6 https://si3t.ch/log/2021-04-07-nethack-6.txt 2021-04-07T21:07:51Z Aloha prx, welcome to NetHack! You are a neutral female human Tourist. Ce coup-ci, j'attrappe mon appareil photo d'athée, et c'est parti pour l'aventure accompagnée de mon fidèe petit minou et mon t-shirt hawaïen :) Mon inventaire contient ``` Coins $ - 836 gold pieces Weapons a - 38 +2 darts (at the ready) Armor k - an uncursed +0 Hawaiian shirt (being worn) Comestibles b - 2 uncursed apples c - 5 uncursed food rations d - an uncursed pancake e - an uncursed slime mold f - an uncursed lembas wafer g - an uncursed tin of lichen Scrolls i - a blessed scroll of magic mapping j - 3 uncursed scrolls of magic mapping Potions h - 2 uncursed potions of extra healing Tools l - an expensive camera (0:95) m - an uncursed credit card n - an uncursed towel ``` Je suis blindée aux as... Mais dis donc... Que vois-je ? ``` c - an uncursed pancake ``` Donc, logiquement, dans nethack, on peut trouver... des CRÊPES MAUDITES??? XD J'ai aussi une serviette, il faut toujours en avoir une sur soi (à quoi ça va bien pouvoir me servir...? N'allez pas lire le wiki, la serviette mouillée en tant qu'arme m'a trop fait marrer :)). Il y a un gobelin à côté, l'occasion de tester mon appareil photo: ``` The goblin is blinded by the flash! ------------ |....o..@..| |.......+..| --------f--- ``` Je me disais bien que ça pourrait faire un truc de ce genre. Et maintenant, je m'enfuis? Mais il pourra toujours me rattrapper plus tard... Je crois que je vais taper dessus un petit peu pour voir. Enfin pas taper, délicatement lui jeter des fléchettes à la figure pour soigner ses yeux. ``` You kill the goblin! ``` Qu'on se le dise, 'faut pas faire chier les touristes! Une femme a le droit de marcher dans un donjon tranquille! Bon le premier niveau se passe bien. Je trouve un peu d'équippement, dont une hache et un sac. Au niveau 2, tout semble indiquer qu'il y a un magasin quelque part : ``` You hear the chime of a cash register. ``` Après pas mal de recherche, je le trouve caché dans un coin : ``` --- |(% |%). ----- ------ |!@.| #....| #.<...| |?(.@f #|....# ---------------- #|....| -----# #|...|#### |..............| #|....| # #-----# # #-...............##########|....| # #### # # ###|..............| ------ ### # # ## # ------|--------- #--------# # # # # #-......|# ## ##### # ### |.......# # ##### ### # |......| # ##### # |......| #------- # # ### -------- |......| #|.....| # #-------|- ########........## ------- -------- #-.....-#### #|..`.....## |......| # |.....| |.....| #......>.|#########.......| # |.....| |.....| |........# -------- ######.....{| ------- ---------# ------- Prx the Rambler St:14 Dx:9 Co:18 In:13 Wi:8 Ch:13 Neutral Dlvl:2 $:858 HP:10(10) Pw:2(2) AC:9 Xp:1 ``` Je découvre en faisant mes achats qu'acheter un parchemin ne permet pas de l'identifier.. Zut! Je teste quand même mes nouveaux parchemins : j'ai nettoyé le niveau, il ne devrait rien m'arriver de trop grave. Je tombe sur un parchemin d'identification, et je découvre que ça identifie TOUT ce que je porte (pas comme dans DCSS). J'ai un parchemin de génocide du coup.. Ça semble assez violent oO. Pour le coup, j'ai une lampe magique bénie! Ça semble bien cool ce truc! Apparemment, il faut utiliser la commande "#rub" pour en profiter. ``` You now wield a blessed magic lamp. In a cloud of smoke, a djinni emerges! The djinni speaks. "I am in your debt. I will grant one wish!" You may wish for an object. For what do you wish? ``` Ok, donc là, il ne faut pas me planter. Qu'est-ce que je peux bien demander? Il faut écrire le nom de l'object exact, ou bien juste "weapon" pour une arme? Du coup je lis un peu le wiki (non c'est pas bien...) et obtient une armure en écailles de dragon. Allez, zou, niveau suivant! Devant une porte, on me dit : ``` Something is written here in the dust. You read: "Closed for inventory". ``` Ça semble une mauvaise idée de défoncer la porte. ... WHAMMM!!! ``` "Minx! You did 400 zorkmids worth of damage!" Pay? [yn] (n) ``` Je me disais bien aussi, mais je n'ai pas résisté. Et évidemment, je me fais tuer par le marchand ultra bien équippé... Pas très malin je suis. Leçon n°6 : ne pas déranger les marchands, ou au moins accepter de les payer. ``` ---------- / \ / REST \ / IN \ / PEACE \ / \ | prx | | 0 Au | | killed by a wand | | | | | | | | 2021 | *| * * * | * _________)/\\_//(\/(/\)/\//\/|_)_______ Aloha prx the Tourist... You died in The Dungeons of Doom on dungeon level 3 with 188 points, and 0 pieces of gold, after 1274 moves. You were level 1 with a maximum of 10 hit points when you died. ``` ]]> NetHack -- Épisode 5 https://si3t.ch/log/2021-03-30-nethack-5.txt 2021-03-30T21:07:51Z Nethack -- Épisode 4 https://si3t.ch/log/2021-03-24-nethack-4.txt 2021-03-24T21:07:51Z .....| #|.............| |.............| |..........# #|.............| |..........f..@# |.........|# #............%.| |.............|# -----------# #|.............| ----.---------- # #----|-.-------- ## # ##%################## # # # # ############### # # ## ----------.- # ## ###### ###-..........| ## # ---.-- |..........| ## # |...<+####-..........| ### # |....| ------------ #---------# |....| #|.......|# ------ #.........# --------- Prx the Evoker St:11 Dx:15 Co:13 In:18 Wi:9 Ch:11 Chaotic Dlvl:2 $:12 HP:15(15) Pw:20(23) AC:8 Xp:2 ``` Cependant, je commence à avoir faim... Très faim... Pas le choix, je dois manger. Il y a quelques cadavres à un endroit... Forcément qu'il y a des cadavres à ici, c'est en fait un piège : je me prends un gros rocher sur la tronche. Heureusement, j'avais enfilé un casque... Je tente de manger un cadavre, je n'ai rien d'autre... Beurk, c'est avarié. Ça me rend malade du coup, et je ne suis pas rassasié. 2 tours plus tard, je suis toujours malade, et je m'évanouis à cause de la faim... Et devinez quoi? Je meurs XD Leçon n°4 : un tas de cadavres, c'est sûrement un piège. ``` ---------- / \ / REST \ / IN \ / PEACE \ / \ | prx | | 12 Au | | poisoned by a | | rotted jackal | | corpse | | | | 2021 | *| * * * | * _________)/\\_//(\/(/\)/\//\/|_)_______ Goodbye prx the Wizard... You were poisoned in The Dungeons of Doom on dungeon level 2 with 201 points, and 12 pieces of gold, after 1152 moves. You were level 2 with a maximum of 15 hit points when you were poisoned. ``` ]]> NetHack -- Episode 3 https://si3t.ch/log/2021-03-18.txt 2021-03-18T21:07:51Z .|# ---.-- # ------# ######## -|----|---- #|..@.|# |....| # |....|# ####|.........| #|.....# |....| # |.....# #..........| #-....| |....| # |....| |.........| |....| |^.<.| ##-....-##### ----------- ------ |....| ------ ------ Prx the Hatamoto St:14 Dx:18 Co:18 In:9 Wi:8 Ch:8 Lawful Dlvl:1 $:8 HP:15(15) Pw:2(2) AC:3 Xp:1 ``` C'est parti pour le niveau 2. Il semble que mon chien ne m'ait pas suivi. Et j'ai beau remonter à l'étage au-dessus, je ne le trouve pas. J'ai même tenté d'utiliser le sifflet trouvé un peu plus tôt, mais la pauvre bête semble perdue :/ Au cours de l'exploration, je commence à avoir faim. Je porte une portion de tripes, alors j'en mange un bout : apparemment c'est très mauvais. C'est tellement mauvais que pendant plusieurs tours, je suis confus et délire un peu : les tripes, ça rend malade. Heuresement, ça finit pas passer, personne n'est venu m'attaquer pendant ma crise de vomi. Un renard m'attaque, mais je ne me laisse pas faire : tiens, prends ça espèce de sale roux! (j'ai une barbe rousse dans la vraie vie, alors je suis bien placé pour savoir que les roux ça peut être tenace. N'y voyez aucun roucisme :D). Et là, oh joie : ``` You kill the fox! Welcome to experience level 2. ``` L'ancien moi qui perdait dans la 1ere salle du donjon se sent tout fier :) Plus loin, je me retrouve coincé dans un piège à ours :s ``` #untrap You cannot deal with the bear trap while trapped in it! ``` Euh, ok, je fais comment alors ? Je tente de me déplacer encore et encore, et finalement : ``` You are caught in a bear trap. You finally wriggle free. ``` Ouf! Niveau 2 fini! ``` ----- ------------ ----------- |....#######|..........| |.........-# |...| #|..........| |<........|# --------- |...| #............# |..........# |.......| -|--- ---------.--# |.........|# |.......| ## ##### # |.........-#### |.......| # ## # -----.-----# #####........| # # # ## ##` |.......| ----------- # # # # ### --.------ |.........| # ## # # #### ## #-.....@...| # ###### # #### # # # ###|......>..| -.-------.----- # # ##### # # ----------- |.............| ######## # # ### # |.............| #---------------- ### ----.- # |..............#########|..............| ###-.....##### |.............| #|..............| ###|^...| |.............| #...............| #|....| --------------- |..............| ------ ---------------- Prx the Hatamoto St:14 Dx:18 Co:18 In:9 Wi:8 Ch:8 Lawful Dlvl:2 $:17 HP:22(22) Pw:6(6) AC:3 Xp:2 ``` Je peux aller au niveau 3. Cependant, quelque chose me titille : j'ai récupéré une potion et une baguette magique... Je tente ou pas? La dernière fois, je suis mort en testant un parchemin, je vais éviter pour l'instant... Au niveau 3, je découvre mon premier petit commerce ``` ------ |....| ------------ |....| |.?()]?!=?*| |.<..-### |.[=?(?%!!)| ------ # |.?)!%!%!%)| ###|@/%%(%%!%[| #-@!!!)(![%?| ------------ ``` J'ai 17 pièces d'or, je me demande quoi acheter... Déjà, je désactive l'autopickup (@) pour éviter d'avoir des dettes impayables et ne pas pouvoir partir. je me déplace dans le magasin, les prix apparaissent quand je suis sur un objet. Quand soudain, un mimic m'attaque et frappe aussitôt : ``` Wait! That's a giant mimic! The giant mimic hits! The giant mimic hits! ------ |....| ------------ |....| |.?(@m?!=?*| |.<..-### |.[=?(?%!!)| ------ # |.?)!%!%!%)| ###|./%%(%%!%[| #-@!!!)(![%?| ------------ Prx the Hatamoto St:14 Dx:18 Co:18 In:9 Wi:8 Ch:8 Lawful Dlvl:3 $:17 HP:1(22) Pw:6(6) AC:3 Xp:2 ``` Il ne me reste plus qu'1HP... Que faire? Boire une potion non identifiée? C'est très risqué. Tenter d'écrire "Elbereth" sur le sol? Si j'en ai le temps... Avant, je vais bêtement tenter de m'échapper... ``` You cannot escape from the giant mimic! ``` Bon, c'est clair au moins... Reste donc "Elbereth". C'est sans effet... Ça a marché au moins? Je tente de réécrire avec le doigt (j'avais écrit avec une gemme). ``` What do you want to write in the dust here? Elbereth The giant mimic hits! You die... Adjama gratefully inherits all your possessions. ``` Et m*%# Leçon n°3 : faire gaffe aux mimics "]" dans les magasins et ne pas s'en approcher. ``` ---------- / \ / REST \ / IN \ / PEACE \ / \ | prx | | 17 Au | | killed by a | | giant mimic | | | | | | 2021 | *| * * * | * _________)/\\_//(\/(/\)/\//\/|_)_______ Sayonara prx the Samurai... You died in The Dungeons of Doom on dungeon level 3 with 224 points, and 17 pieces of gold, after 1142 moves. You were level 2 with a maximum of 22 hit points when you died. ``` ]]> NetHack -- Épisode 2 https://si3t.ch/log/2021-03-11.txt 2021-03-11T21:07:51Z ". Cependant, certains couloirs sont des culs de sac. Normal? ``` ------- ------------ |......# |..........| |.....|## |..........-# #-.^...| # |..........|# -------- #|......#### ############-..........|# @d.....| #--.-|-- ## -------.----# |......| ### ##### ## ### # |......| # # #### # # # |...>..| # # ###### # # #.......| ## ## # ##### # #-------- # # # # ### ### # -.---|---- ############ ## # ------- # |....._..| ----------.-----# ## # ......|#######.........| #|..............|############## # |.<....## |.........####...............| #####--.------# |.....| |{.......| |..............| ##-........# ------- |........| ---------------- # |.......| ---------- ##|.......| ----|---- # Prx the Footpad St:16 Dx:18 Co:10 In:11 Wi:12 Ch:6 Chaotic Dlvl:1 $:11 HP:11(11) Pw:11(11) AC:7 Xp:1 ``` Au niveau 2, je découvre un coffre. Cool, je vais prendre ce qu'il y a dedans : de l'or, un parchemin, de la nourriture, et un bouquin. Lisons maintenant ce parchemin : c'est ainsi que dans crawl dungeon stone soup on peut en identifier facilement en début de partie : ``` As you read the scroll, it disappears. A lit field surrounds you! You feel a wrenching sensation. The jackal bites! The jackal bites! The jackal bites! ``` Mince, on dirait un sort de téléportation. ``` The jackal bites! The jackal bites! The jackal bites! ``` AÏe Aïe Aïe... ``` You die... ``` Vous l'aviez senti venir n'est-ce pas? Me voilà mort sans avoir pu faire quoi que ce soit, pas même riposter. Leçon n°2 : ne pas lire un parchemin non identifié : ils peuvent être méchants, même en début de partie. ``` ---------- / \ / REST \ / IN \ / PEACE \ / \ | prx | | 54 Au | | killed by a | | jackal | | | | | | 2021 | *| * * * | * _________)/\\_//(\/(/\)/\//\/|_)_______ Goodbye prx the Rogue... You died in The Dungeons of Doom on dungeon level 2 with 167 points, and 54 pieces of gold, after 578 moves. You were level 1 with a maximum of 11 hit points when you died. ``` ]]> NetHack -- Épisode 1 https://si3t.ch/log/2021-03-10.txt 2021-03-10T21:07:51Z https://www.nethack.org/ Site officiel => https://nethackwiki.com/wiki/NetHack Nethack Wiki => https://crawl.develz.org/ Dungeon Crawl Stone Soup Autant dire que l'aventure promet d'être longue. Voici l'épisode 1. ## Installation ``` $ doas pkg_add nethack ``` Je choisis la dernière version : nethack-3.6.6p0-no_x11. ## Lecture du guidebook En entrant "pkg_info -L nethack", je m'aperçois qu'il y a un fichier "Guidebook.txt" (/usr/local/share/doc/nethack-3.6.6/Guidebook.txt). Ça sera sans doute bien de le lire un jour. À première vue, il fait plus de 60 pages, donc bon... Il est disponible en ligne en mode html ou bien même en pdf : => https://nethack.org/v366/Guidebook.html => http://www.nethack.org/download/3.6.6/nethack-366-Guidebook.pdf Allez, je m'y mets, et noterai ci-dessous les trucs qui me paraissent important à retenir afin de m'y référer pour la suite, sachant qu'il y a toujours l'aide du jeu (?). Après tout, il y a pas mal de trucs qui ne me seront pas utiles : jouer si on est aveugle ou la liste de toutes les variables de configuration. * Ctrl-X détaille le status du perso (statistiques, objets équipes...) * / permet de détailler ce qui est à l'écran * ? : menu aide * q : boire une potion * #enhance : choisir quelle compétence améliorer lorsque le message "You fell more confident" apparaît. * s : chercher un passage secret ou détecter un piège. * 10s : chercher pendant 10 tours * m - action : se déplacer ou faire une action sans automatismes (ex : se déplacer sans prendre un objet, ou manger mais pas ce qui est à ses pieds) * e : manger * E : Écrire sur le sol. Écrire "Elbereth" repousse les monstres (pas les attaques à distance) * #sit : pour être assis. À quoi ça sert? * a : utiliser un objet * g - direction : mouvement automatique dans une direction * _ : voyage rapide à un endroit de la carte. On valide avec "." * < ou > : prendre un escalier * A : retirer un objet (armure...) ou T, ou R. * o ou c : ouvrir ou fermer une porte * S : sauver et quitter * #quit, Alt-q ou ctrl-c : quitter * d : lâcher un objet * t : lancer une pierre, une flèche... Q pour choisir quel objet sera lancé. * f : tirer avec l'arme de jet ce qui est dans le carquoi. * Ctrl-D : défoncer une porte * p : payer la liste de courses (les objets pris chez un machand). Pour vendre, il faut poser les objets chez le marchand. * W : porter une armure * w : porter une arme * X : combat à 2 mains * x : échanger d'arme si on en a 2 * z : utiliser une baguette magique * Z : invoquer un sort * #adjust : changer les lettres utilisées dans l'inventaire (ou Alt-a) * #annotate : mettre une note sur un niveau du donjon (ou Alt-A). Par exemple : monstre hyper dangereux, fuir! * #chat: parler à quelqu'un * #force : forcer une serrure * #pray : demander l'aide d'un dieu. Ne pas le faire trop souvent! * #ride : monter une créature * #wipe : s'essuyer la figure. Pourquoi??? * #loot : pour piller un coffre par exemple * Ctrl-P : afficher l'historique des messages * @ : désactive la prise automatique des objets au sol (autopickup) * #turn : se changer en mort-vivant. ## Première partie Allez, on en a assez, il faut se lancer. Je lance une première partie. Je laisse le jeu choisir un personnage pour moi. ``` name: prx Is this ok? [ynq] role: Knight race: human prx, lawful female human Knight gender: female alignment: lawful y + Yes; start game n - No; choose role again q - Quit (end) ``` Une chevalière humaine loyale ? C'est tout moi :). Let's go ! Me voici devant une mini carte, avec mon cheval "u", un chacal "d" et une cotte de mailles "[". J'ai utilisé "/" pour savoir ça ``` Salutations prx, welcome to NetHack! You are a lawful female human Knight. ----- .@u.| |..d| ..[. ---- Prx the Gallant St:14 Dx:9 Co:10 In:8 Wi:16 Ch:18 Lawful Dlvl:1 $:0 HP:16(16) Pw:3(3) AC:3 Xp:1 ``` Tiens, je vais attendre un peu avec "s", voir ce que font les autres. ``` The saddled pony hits the jackal. The jackal is killed! ``` Bravo petit poney :) Je me déplace vers le corps du chacal, et on me dit que ça me trouble un peu de porter ce cadavre... Tu m'étonnes. En plus, me voilà surchargé : ``` Your movements are slowed slightly because of your load. ----- .<..| |..@| ...[u ----- Prx the Gallant St:14 Dx:9 Co:10 In:8 Wi:16 Ch:18 Lawful Dlvl:1 $:0 HP:16(16) Pw:3(3) AC:3 Xp:1 Burdened ``` Je vais le reposer hein :), j'utilise pour ça "d". Pis je le mange tiens : ``` This jackal corpse tastes okay. ``` Hum, il faut aimer la viande crue :P Je tente de porter la cotte de maille, mais elle est finalement moins bien que l'autre, la première étant enchantée avec un bonus +1. J'ai du retirer (R) l'ancienne avant (logique). Tiens, je vais essayer de monter sur mon poney. Je tente une première fois et échoue lamentablement. Allez, un autre essai pour voir : ``` #ride In what direction? You slip while trying to get on the saddled pony. You die... ``` Je glisse? Sérieux, je suis chevalière, et je ne sais pas monter à cheval ??? :D Et en plus, j'en meurs ??? XD Je viens de réaliser la partie la plus courte et la plus ridicule de nethack! ``` ---------- / \ / REST \ / IN \ / PEACE \ / \ | prx | | 0 Au | | slipped while | | mounting a | | saddled pony | | | | 2021 | *| * * * | * _________)/\\_//(\/(/\)/\//\/|_)_______ Fare thee well prx the Knight... You died in The Dungeons of Doom on dungeon level 1 with 0 points, and 0 pieces of gold, after 52 moves. You were level 1 with a maximum of 16 hit points when you died. ``` Leçon n°1 : NE PAS MONTER SUR LE DOS D'UN PONEY. La prochaine partie s'annonce épique :D ]]> scratchterm - toujours un terminal sous la main https://si3t.ch/log/2020-11-07.txt 2020-11-07T21:07:51Z /pub/videos/scratchterm.mp4 Voici comment ça marche. Tout d'abord, on récupère les dimensions de l'écran après avoir définit le nom de notre outil : ``` name=scratchterm # screen size sw=$(/usr/X11R6/bin/xwininfo -root|sed '/Width/!d;s/.* //') sh=$(/usr/X11R6/bin/xwininfo -root|sed '/Height/!d;s/.* //') ``` Ensuite, on calcule mes dimensions du terminal, disons les 2/3 de l'écran : ``` # dimension # 2/3 of screen w=$(($sw*2/3)) h=$(($sh*2/3)) ``` Toutefois, pour préciser les dimensions d'un terminal, il faut donner le nombre de colonnes et de lignes, pas un nombre de pixels... Là j'ai pas mal galéré pour trouver quelque chose d'à peu près correct. Il semble qu'un caractère fasse environ 7 pixels de large et 15 pixels de haut... ``` # a char is approx 7x15 px columns=$(($w/7)) rows=$(($h/15)) ``` Ensuite, on calcule la position sur l'écran de la fenêtre , au centre. ``` # position x=$((($sw-$w)/2)) y=$((($sh-$h)/2)) ``` Ça nous donne cette géométrie : ``` geometry="${columns}x${rows}+${x}+${y}" ``` Ensuite, on va créer une session tmux spécialement pour notre scratchterm sauf si elle existe déjà. ``` session=$name tmux start-server tmux has-session -t $session || \ tmux new -d -s $session -n $name ``` Enfin, soit on affiche notre scratchterm, soit on le ferme. Pour savoir s'il est déjà ouvert, on peut récupérer l'id de toutes les fenêtrs ouvertes pour voir s'il y a notre scratchterm dans la liste. Si oui, on la xkill, sinon, on ouvre un terminal avec la bonne session tmux : ``` # show/hide scratchterm id_=$(xwininfo -root -children | grep "$name" | awk '{print $1}') if [ -n "$id_" ]; then # window exist, kill it xkill -id $id_ else xterm -T $name -name $name -class $name -geometry "${geometry}@c"\ -e tmux a -t $session & fi ``` Dans la version que j'utilise, le terminal est st avec le patch pour avoir de la transparence. => https://st.suckless.org st ``` st -A .9 -c $name -n $name -T $name -g "$geometry" -e tmux a -t $session ``` J'ai ce script associé à un raccourci Alt-x, et je dois dire que j'ai du mal à m'en passer. :) Le script peut se trouver ici : => https://si3t.ch/code/prxbins.tgz scratchterm dans l'archive prxbins.tgz ]]> Solidarité https://si3t.ch/log/2020-10-22.txt 2020-10-22T21:07:51Z Plus jamais de 20% ! Depuis pourtant, la voici le pourcentage de votants en France qui ont accordé leur confiance à la haine : * 2002 : 17,79% * 2007 : 10,44% * 2012 : 17,90% * 2017 : 21,30% puis 33,90% * 2022 : à vous de jouer... Ils peuvent changer de nom, s'appeler FN ou RN, Jean-Marie Marine ou Marion... : > ...nous sommes noirs, nous sommes blancs, nous sommes jaunes, et ensemble, nous sommes de la dynamite. Sources : * https://www.interieur.gouv.fr/Elections/Les-resultats * https://www.youtube.com/watch?v=CuZB9hOQ0DQ ]]> Choisir un gestionnaire de fichiers https://si3t.ch/log/2020-10-07.txt 2020-10-07T21:07:51Z https://www.3hg.fr/Isos/isotop/ isotop Voici donc le résultat de mes recherches non exhaustives sur OpenBSD -current en septembre 2020. ## Cahier des charges L'idéal pour moi serait : * Un gestionnaire avec peu de dépendances * léger * qui affiche des aperçus si possible * qui supporte les actions personnalisées (redimensionnement d'images, renommage en masse...) * encore à peu près maintenu. Ce n'est pas indispensable, après tout un outil qui marche bien et qui n'a pas besoin de nouvelles fonctionnalité n'a pas à voir de nouvelles publications. Mais c'est rassurant de savoir qu'un(e) développeur n'est pa sloin pour corriger une éventuelle faille. ## Les "gros" gestionnaires : Nautilus, Dolphin Je vais être honnête, je n'ai pas testé ces derniers. Ils sont trop dépéndants des environnements de bureau Gnome et KDE. ## Thunar Thunar est un excellent gestionnaire de fichiers. Il est rapide, léger, supporte les onglets, les aperçus et les actions personnalisées. Ces dernières sont très facilement configurables. => https://docs.xfce.org/xfce/thunar/start Thunar Toutefois, il requiert des dépendances à Xfce dont j'aimerais me passer. La preuve: ``` $ doas pkg_add thunar doas (prx@shaihulud.my.domain) password: quirks-3.439 signed on 2020-10-01T20:26:48Z thunar-1.8.15:gvfs-1.44.1p0: ok thunar-1.8.15:startup-notification-0.12p6: ok thunar-1.8.15:libwnck3-3.36.0: ok thunar-1.8.15:libxfce4util-4.14.0p0: ok thunar-1.8.15:xfconf-4.14.3: ok thunar-1.8.15:yelp-xsl-3.36.0: ok thunar-1.8.15:geoclue2-2.4.13: ok thunar-1.8.15:orc-0.4.29: ok thunar-1.8.15:gstreamer1-1.18.0: ok thunar-1.8.15:cdparanoia-3.a9.8p4: ok thunar-1.8.15:gstreamer1-plugins-base-1.18.0: ok thunar-1.8.15:enchant2-2.2.11: ok thunar-1.8.15:hyphen-2.8.8: ok thunar-1.8.15:woff2-1.0.2p0: ok thunar-1.8.15:webkitgtk4-2.30.1: ok thunar-1.8.15:yelp-3.36.0: ok thunar-1.8.15:amtk-5.0.2: ok thunar-1.8.15:gnome-devel-docs-3.32.1: ok thunar-1.8.15:devhelp-3.36.2: ok thunar-1.8.15:glade-3.36.0p0: ok thunar-1.8.15:libxfce4ui-4.14.1p0: ok thunar-1.8.15:garcon-0.6.4p0: ok thunar-1.8.15:p5-URI-1.76p0: ok thunar-1.8.15:exo-0.12.11: ok thunar-1.8.15:xfce4-panel-4.14.4: ok thunar-1.8.15: ok Running tags: ok ``` => https://pix.toile-libre.org/upload/original/1602078931.png Aperçu Thunar [IMG] (La capture d'écran est prise avec le thème d'icônes Tango que j'aime beaucoup :P). On voit par ailleurs qu'il ne sait pas gérer l'absence de certaines icônes... C'est un détail, mais ça m'énerve. Ce petit défaut esthétique ne retire pas les nombreuses qualités de ce gestionnaire. ## Pcmanfm Voici une excellent alternative à Thunar sans les dépendances à Xfce puisque supporté par l'environnement LXDE. Il supporte lui aussi dans une certaine mesure les actions personnalisées : il faut créer un fichier ".desktop" dans ~/.local/share/file-manager/actions. Toutefois, le site officiel semble peu à jour et je me demande où va le projet puisqu'il y a maintenant lxQT et pcmanfm-qt qui est développé (mais carrément moche actuellement). => https://wiki.lxde.org/fr/PCManFM officiel Ceci dit, ça fonctionne bien. Il a tout de même deux défauts majeurs sous OpenBSD : * Il n'est pas traduit en français. Ça ne me gêne pas, mais c'est embêtant pour isotop. * Le menu "applications" reste vide : il dépend des autres environnements de bureau. => https://pix.toile-libre.org/upload/original/1602079468.png pcmanfm [IMG] ## Rox-filer Voilà une bête de course. Je n'ai pas trouvé plus rapide. Il est possible de définir des actions personnalisées, et même si l'apparence a un peu vieilli, une fois bien configuré il est très pratique et à la limite joli. Seuls bémols : * Les raccourcis clavier par défaut sont déroutants * Pas d'onglets (mais osef) * Pas traduit * La progression lors d'une copie est peu précise * Il ne semble plus maintenu depuis des années et ça m'ennuie un peu... => https://pix.toile-libre.org/upload/original/1602079737.png rox-filer [IMG] ## Xfe : X File Explorer Voici mon préféré. Il est à la fois rapide, scriptable, indépendant, et toujours maintenu!!! Au look un peu rétro de prime abord, on peut facilement obtenur une interface agréable avec des aperçus. Il intègre des visualiseurs basiques bienvenus : visualiseur d'images xfi, un éditeur de texte xfw. On peut avoir une vue en panneaux ou classique : => https://pix.toile-libre.org/upload/original/1602080162.png xfe1 [IMG] => https://pix.toile-libre.org/upload/original/1602080107.png xfe2 [IMG] Il est aussi possible d'y intégrer des scripts pour le renommage/redimensionnement... en les déposant dans $HOME/.config/xfe/scripts. C'est clairement mon favori lorsque j'ai besoin d'un client graphique. ## mc, ranger, noice, nnn, rover : les clients en mode texte? Pour gérer les fichiers, le shell c'est très bien, mais il existe aussi des gestionnaires en console qui permettent de tout faire du bout des doigts et être très efficace. Le plus conne est sans doute Midnight Commander, donc je n'en parlerai pas ici. Je vais plutôt parler de ceux qui utilisent des raccourcis à la vi. Vient ensuite un de mes préférés : ranger, intégré dans la nakedeb (pub subtile ;)). Je l'ai utilisé longtemps, il est top, avec un visualiseur bien fichu. Mais il est en python, et si possible je cherche des alternatives plus rapides en C (choix très personnel et pas forcément recevable). => https://github.com/ranger/ranger ranger => https://arpinux.org/home/article78/nakedeb-01-beta-jouet-sameliore nakedeb => https://raw.githubusercontent.com/ranger/ranger-assets/master/screenshots/screenshot.png ranger [IMG] Puisque j'aime le C, je suis tombé sur noice. Pour le coup, j'ai utilisé ce dernier longtemps, il est très rapide, permet de se déplacer dans une hiérarchie avec efficacité. Il souffre toutefois de ne pas gérer la copie et déplacement des fichiers : c'est donc davantage un lanceur. => https://git.2f30.org/noice/ noice => https://pix.toile-libre.org/upload/original/1602081006.png noice [IMG] Vient ensuite le successeur de noice : nnn. Très intéressant, ce dernier ajoute des "vues" qui permettent d'avoir plusieurs dossiers d'ouverts en même temps. Il est bien fichu, il faut l'admettre, et peut être énormément configuré avec un tas de plugins. Je lui trouve tout de même un gros défaut : sa dépendanc eà xdg-open pour ouvrir des fichiers : c'est peu pratique quand on veut choisir les applications par défaut selon le type de fichier : il faut se manger du xdg-mime default app.desktop image.jpeg et çe pour tous les types mime... => https://github.com/jarun/nnn nnn Je termine donc par mon préféré que j'aurais aimé trouver plus tôt : rover. => https://lecram.github.io/p/rover/ rover Déjà, il s'installe en le compilant, mais ça prend 2 secondes : ``` git clone --depth=1 https://github.com/lecram/rover.git cd rover && make && make install PREFIX=$HOME ``` Il est coloré par défaut : => https://pix.toile-libre.org/upload/original/1602081406.png rover1 [IMG] On navigue avec "h/j/k/l". Jusque là, on n'est pas perdus. On peut éditer un fichier avec "e" ou juste le lire avec "espace". Pour chercher un fichier, on utiliser "/" puis on écrit sa recherche. Pour ouvrir un shell dans le dossier courant, il suffit d'appuyer sur "Entrée. Il dispose de plusieurs vues accessibles avec les nombres "1,2,3....". Mais ce qui est absolument génial, c'est qu'on peut copier/déplacer des fichiers. Tout d'abord, on les marque avec "m" : => https://pix.toile-libre.org/upload/original/1602081573.png rover2 [IMG] Ensuite, on change de dossier. Ici, pous la démonstration, je vais appuyer sur "2" pour ouvrir un nouveau contexte et me déplacer dans "/tmp". Je copie les fichiers précédemment marqués avec "C", une barre de progression s'affiche : => https://pix.toile-libre.org/upload/original/1602081644.png rover3 [IMG] Enfin, et ça c'est hyper fort, on peut ouvrir les fichiers avec la touche "o". Afin de pouvoir configurer quelle commande lancer selon l'extension, la FAQ donne un exemple. => https://github.com/lecram/rover/blob/master/FAQ.md FAQ Il faut ajouter export ROVER_OPEN="rover-open" dans $HOME/.profile puis céer le script rover-open à placer dans votre $PATH, donc /usr/local/bin par exemple. Chez moi, c'est $HOME/bin. Ce script prendra cette forme : ``` #! /bin/sh # Usage: # ./open.sh /path/to/file # get extension ext="$(echo .${1#*.} | tr '[:upper:]' '[:lower:]')" # lower extension case "${ext}" in *.htm|*.html) fmt="$BROWSER %s" ;; *.pdf|*.xps|*.cbz|*.epub) fmt="mupdf %s" ;; *.jpg|*.jpeg|*.png|*.gif|*.tiff) fmt="sxiv %s" ;; *.odt|*.odt|*.ods|*.od*|*.docx|*.doc|*.xls|*.xlsx) fmt="libreoffice %s" ;; *.mp4|*.avi|*.mpg|*.ogv|*.webm|*.mkv) fmt="ffplay %s" ;; *.ogg|*.flac|*.wav|*.mp3) fmt="ffplay %s" ;; *.[1-9]) fmt="man -l %s" ;; *.c|*.h|*.sh|*.lua|*.py|*.ml|*[Mm]akefile|*.md) fmt="$EDITOR %s" ;; *) fmt="xdg-open %s" esac exec sh -c "$(printf "$fmt" "\"$1\"")" ``` Il me suffit d'éditer ce petit script si je veux modifier/ajouter la façon dont mes fichiers seront ouverts. Comme vous le voyez, c'est xdg-open qui est appelé, mais seulement si je n'ai rien précisé d'autre. rover a été mis à jour le 2 juin 2020 donc semble toujours bien maintenu. Je vous invite à le tester, il est super :) => https://github.com/lecram/rover/commit/2ec364f923b60b8b1e68ffe4c705b82d9a487056= dernière mise à jour de rover ]]> Première fonction personnalisée dans dwm https://si3t.ch/log/2020-09-23.txt 2020-09-23T21:07:51Z nmaster = 1; arrange(selmon); } ``` Et ça fait le job :) Bon, j'avoue, je suis tellement habitué à ce gestionnaire de fenêtres que je n'ai plus grand chose à lui ajouter ou modifier. Ceci dit, je ne regrette pas une fois encore d'avoir appris le C, même pour une modification aussi ridicule. Pour ceux que ça intéresse, ma configuration dwm est là : dwm-config.h => https://si3t.ch/pub/dwm-config.h dwm-config.h => https://dwm.suckless.org dwm ]]>