Compare commits
No commits in common. "0ad7108d5aa0191ff5a078d993d9614d677afd2e" and "97f9196db681bba6674410917d728a35201e1cec" have entirely different histories.
0ad7108d5a
...
97f9196db6
3
.gitignore
vendored
3
.gitignore
vendored
@ -24,6 +24,3 @@ code/no-op
|
||||
code/get-signal
|
||||
code/fifo-tx
|
||||
code/fifo-rx
|
||||
code/plugiciel.so
|
||||
code/appelant
|
||||
|
||||
|
@ -350,8 +350,7 @@ Il y a plein d'autres exemples de code en C, sur des sujets
|
||||
divers comme Open Sound Control (page \pageref{chap:OSC}) ou
|
||||
libsndfile (page \pageref{chap:son}).
|
||||
Et pour les gens du système~:
|
||||
l'utilisation des signaux (page \pageref{get-signal}),
|
||||
le chargement dynamique (page \pageref{ex_dlopen}.
|
||||
l'utilisation des signaux (page \pageref{get-signal}).
|
||||
|
||||
|
||||
% ---------------------------------------------------------
|
||||
|
18
chap/IPC.tex
18
chap/IPC.tex
@ -96,8 +96,6 @@ Ce marqueur temporel sera obtenu par l'appel à
|
||||
pour tenter d'avoir une précision
|
||||
significative.
|
||||
|
||||
% ----------------------------------------------------------------
|
||||
|
||||
\subsection{Émetteur}
|
||||
|
||||
Son role est simple~: il met le timestamp dans l'enveloppe, et
|
||||
@ -105,11 +103,6 @@ la poste vers l'adresse qu'on lui passe sur la ligne de commande.
|
||||
|
||||
\lstinputlisting[language=c]{code/fifo-tx.c}
|
||||
|
||||
Vous remarquerez que nous nettoyons le message avant utilisation
|
||||
avec un \texttt{memset(3)}, une étape trop souvent oubliée.
|
||||
|
||||
% ----------------------------------------------------------------
|
||||
|
||||
\subsection{Récepteur}
|
||||
|
||||
Pour faire simple, le récepteur des messages va passer l'intégralité
|
||||
@ -122,12 +115,7 @@ Sauf que ça n'est pas tout à fait ça.
|
||||
\lstinputlisting[language=c]{code/fifo-rx.c}
|
||||
|
||||
J'avoue ne pas avoir encore bien capté le deuxième argument
|
||||
de mkfifo, mais la lecture de
|
||||
\texttt{fifo(7)} et de \texttt{pipe(7)} peut être
|
||||
utile pour comprendre\footnote{modulo les références circulaires.}
|
||||
la chose\dots
|
||||
|
||||
% ----------------------------------------------------------------
|
||||
de mkfifo\dots
|
||||
|
||||
\subsection{Timestamp} \index{timestamp}
|
||||
|
||||
@ -148,8 +136,6 @@ the system time). If you need a monotonically increasing clock, see
|
||||
clock\_gettime(2).
|
||||
\end{quote}
|
||||
|
||||
% ----------------------------------------------------------------
|
||||
|
||||
\subsection{Message}
|
||||
|
||||
Pour des raisons pas si évidente que ça, les messages transmis
|
||||
@ -160,8 +146,6 @@ une structure (page ???) contenant les données à transmettre.
|
||||
|
||||
C'est rudimentaire, mais ça fera l'affaire pour claquer un Bonaldi.
|
||||
|
||||
% ----------------------------------------------------------------
|
||||
|
||||
% ================================================================
|
||||
|
||||
|
||||
|
@ -1,7 +0,0 @@
|
||||
|
||||
# Les chapitres
|
||||
|
||||
Le label d'un chapitre est de la forme
|
||||
`chap:filename`.
|
||||
|
||||
|
@ -1,21 +0,0 @@
|
||||
\chapter{Buzybox}
|
||||
\label{chap:buzybox}
|
||||
\index{buzybox}
|
||||
|
||||
Buzybox est un peu le couteau suisse des systèmes Unix minimalistes,
|
||||
tels que ceux que l'on peut trouver dans des routeurs WiFi
|
||||
(OpenWrt\index{OpenWrt}, par exemple. Cf page \pageref{chap:openwrt}),
|
||||
ou des systèmes embarqués de toutes natures.
|
||||
|
||||
%
|
||||
% https://opensource.com/article/21/8/what-busybox
|
||||
%
|
||||
\begin{quote}
|
||||
BusyBox is an open source (GPL) project providing simple implementations
|
||||
of nearly \textbf{400} common commands, including ls, mv, ln, mkdir, more, ps,
|
||||
gzip, bzip2, tar, and grep. It also contains a version of the programming
|
||||
language awk, the stream editor sed, the filesystem checker fsck, the
|
||||
rpm and dpkg package managers, and of course, a shell (sh) that provides
|
||||
easy access to all of these commands.
|
||||
\end{quote}
|
||||
|
@ -1,30 +0,0 @@
|
||||
\chapter{CD \& DVD}
|
||||
\label{chap:cd-dvd}
|
||||
\index{cdrom} \index{dvd}
|
||||
|
||||
Vous allez bien dire : « Encore un truc de vieux\dots ».
|
||||
Oui, peut-être, mais il y a quand même pas mal d'usages
|
||||
assez cools pour ces technologies du passé. Nous allons
|
||||
en explorer quelques uns.
|
||||
|
||||
|
||||
% --------------------------------------------------------
|
||||
|
||||
\section{CD Audio}
|
||||
|
||||
\subsection {Riping}
|
||||
|
||||
Le \textsl{ripage} est l'action d'extraire les pistes d'un
|
||||
ce audion pour les convertir en fichier numérique audio.
|
||||
|
||||
\subsection {Mastering}
|
||||
|
||||
% --------------------------------------------------------
|
||||
|
||||
\section{DVD}
|
||||
|
||||
% --------------------------------------------------------
|
||||
|
||||
|
||||
% --------------------------------------------------------
|
||||
|
@ -7,23 +7,17 @@
|
||||
|
||||
En fait, nous allons plutôt parler de \textbf{ncurses} qui est
|
||||
l'implémentation actuelle de l'ancêtre \texttt{curses}. Voic ce
|
||||
qu'en dit une page de man~:
|
||||
qu'en dit une page de man :
|
||||
|
||||
\begin{quote}
|
||||
The ncurses library routines give the user a terminal-independent
|
||||
method of updating character screens with reasonable optimization.
|
||||
This implementation is ``new curses'' (ncurses) and is the approved
|
||||
replacement for 4.4BSD classic curses, which ha been discontinued.
|
||||
replacement for 4.4BSD classic curses, which has been discontinued.
|
||||
\end{quote}
|
||||
|
||||
Plus concrètement, Curses est un moyen optimisé de gestion des
|
||||
écrans textes (Rappellez-vous notre ami le \textsc{Minitel}) afin
|
||||
de créer des interfaces 'full-screen'. Vous pouvez adresser
|
||||
chaque cellule de votre écran (la case où l'on peut mettre
|
||||
un caractère) pour y écrire quelque chose, en gérant des
|
||||
attributs tels que gras ou souligné.
|
||||
|
||||
\section{Premier exemple}
|
||||
\section{premier exemple}
|
||||
|
||||
Bien entendu, nous commencerons par l'ECM traditionnel de rigueur.
|
||||
|
||||
@ -34,35 +28,12 @@ interne de ncurses, et à régler l'interaction clavier/écran.
|
||||
|
||||
Ensuite, avec \texttt{mvaddstr}, nous écrivons le texte passé
|
||||
en paramètre à une position fixée ligne,colonne
|
||||
dans un écran virtuel (qui n'existe qu'en mémoire)
|
||||
qui sera ensuite transféré dans l'écran réel (celui qui est affiché)
|
||||
dans un écran virtuel
|
||||
qui sera ensuite transféré dans l'écran réel
|
||||
par le \texttt{refresh()}.
|
||||
|
||||
Dans ma grande mansuétude, je n'aurais pas l'audace de vous montrer
|
||||
une capture d'écran, puisque je me permet de supposer que vous
|
||||
avez pris le temps de compiler l'exemple, et de voir par vous même
|
||||
ce que ça donne.
|
||||
|
||||
\section{Bell and whistles}
|
||||
|
||||
Voici comment centrer sur la ligne du haut
|
||||
un texte écrit en \textbf{gras} grace à l'attribut
|
||||
\texttt{A\_BOLD} :
|
||||
|
||||
\begin{verbatim}
|
||||
attron(A_BOLD);
|
||||
mvaddstr(0, (COLS / 2) - (strlen(text) / 2), text);
|
||||
attroff(A_BOLD);
|
||||
\end{verbatim}
|
||||
|
||||
Il existe tout un tas d'autres attributs:
|
||||
\texttt{A\_UNDERLINE} pour le soulignement ou
|
||||
\texttt{A\_BLINK} pour clignoter, par exemple.
|
||||
La liste complète est dans le man~: \texttt{attr(3NCURSES)},
|
||||
avec plein
|
||||
de fonctions spécialisées dans le traitement des attributs.
|
||||
|
||||
\section{Astuces}
|
||||
\section{astuces}
|
||||
|
||||
Dans une boucle interactive, on va utiliser \texttt{getch()}, qui va
|
||||
bloquer tant qu'on n'a pas tapé sur une touche. Mais que faire si
|
||||
|
@ -8,22 +8,12 @@ Gnuplot - an interactive plotting program
|
||||
|
||||
There is an on-line demo collection at http://gnuplot.info/demo
|
||||
|
||||
\begin{verbatim}
|
||||
gnuplot> splot "cam.indoor" using 2:4:3, "cam.indoor" using 5:7:6
|
||||
\end{verbatim}
|
||||
|
||||
% -------------------------------------------------------------------
|
||||
|
||||
\section{Exemple : le phytotron}
|
||||
\index{phytotron}
|
||||
|
||||
Un exemple réel, issu d'un projet d'élevage d'algues
|
||||
bio-luminescentes dans un frigo bricolé.
|
||||
|
||||
Le fichier des données contient cinq champs séparés par des blancs.
|
||||
Le premier est
|
||||
un \textsl{timestamp} exprimé en secondes depuis l'\textsl{epoch},
|
||||
et les quatre suivants sont des températures en degrés Celsius.
|
||||
|
||||
\begin{verbatim}
|
||||
#!/bin/bash
|
||||
@ -58,10 +48,6 @@ __EOC__
|
||||
display ${IMAGE} &
|
||||
\end{verbatim}
|
||||
|
||||
\textsf{Bon, un de ces jours, il faudrait que je ressorte des archives
|
||||
l'enregistrement d'un été dans le dd2, pour que vous puissiez voir
|
||||
le résulate de ce script en « pour de vrai ».}
|
||||
|
||||
% -------------------------------------------------------------------
|
||||
|
||||
\section{Questions}
|
||||
|
@ -1,7 +1,5 @@
|
||||
\chapter{Graphisme}
|
||||
|
||||
Quelques notes en vrac.
|
||||
|
||||
% ------------------------------------------------
|
||||
|
||||
\section{Flydraw}\index{Flydraw}
|
||||
@ -19,53 +17,6 @@ GIF, JPEG, or PNG\index{PNG} files.
|
||||
\textbf{Persistence Of Vision} est un logiciel de raytracing qui
|
||||
existe depuis plus de trente ans.
|
||||
|
||||
\subsection{Caméra}
|
||||
|
||||
Vous avez des problèmes pour caler les mouvement de la caméra ?
|
||||
Vous avez deux trajectoires (mal) calculées pour la
|
||||
\texttt{location} et le \texttt{look\_at}, et rien ne tombe
|
||||
en face de l'objectif ? Voici une approche de solution.
|
||||
|
||||
La première étape est l'enregistrerement des paramètres de la caméra
|
||||
lors du calcul de la séquence~:
|
||||
|
||||
\begin{verbatim}
|
||||
#if (0 = clock)
|
||||
#fopen CL "cam.log" create
|
||||
#else
|
||||
#fopen CL "cam.log" append
|
||||
#end
|
||||
#write (CL, clock, " ", CamX, " ", CamY, " ", CamZ,
|
||||
" ", LatX, " ", LatY, " ", LatZ,"\n")
|
||||
#fclose CL
|
||||
\end{verbatim}
|
||||
|
||||
Et la seconde, l'exploitation des données~:
|
||||
|
||||
\begin{verbatim}
|
||||
#!/bin/bash
|
||||
|
||||
FILE="cam.log"
|
||||
TMPF="/dev/shm/cam.data"
|
||||
IMAGE="graphe.png"
|
||||
|
||||
tail -360 $FILE | sort -n > $TMPF
|
||||
|
||||
gnuplot << __EOC__
|
||||
set term png size 720,720
|
||||
set output "${IMAGE}"
|
||||
set ytics 2
|
||||
set xtics 2
|
||||
set grid front
|
||||
set title "Rush Camera"
|
||||
plot "$TMPF" using 2:4 title "Cam", \
|
||||
"$TMPF" using 5:7 title "Lat" with dots
|
||||
__EOC__
|
||||
|
||||
display "${IMAGE}" &
|
||||
\end{verbatim}
|
||||
|
||||
|
||||
% ------------------------------------------------
|
||||
|
||||
% ------------------------------------------------
|
||||
|
@ -1,11 +0,0 @@
|
||||
\chapter{OpenWrt}
|
||||
\label{chap:openwrt}
|
||||
\index{openwrt}
|
||||
|
||||
\begin{verbatim}
|
||||
TP Ling
|
||||
AC 1750
|
||||
Archer C7
|
||||
\end{verbatim}
|
||||
|
||||
|
@ -1,26 +1,9 @@
|
||||
\chapter{Plugins}
|
||||
\index{plugin}
|
||||
|
||||
% ------------------------------------
|
||||
\texttt{dlopen}\index{dlopen}
|
||||
|
||||
Le concept de bibliothèque partagée
|
||||
(\textsl{shared library} en anglais est apparu, du moins
|
||||
dans le monde Unix, avec \textsl{SunOS 4}, en 1989.
|
||||
Mais il est probable que ce concept existait déja dans
|
||||
d'autres mondes, peut-être avec \textsl{AmigaOS} ou
|
||||
\textsl{VAX/VMS}\index{VMS}\dots
|
||||
|
||||
Et c'est en partie sur ce concept qu'est basé le premier
|
||||
mécanisme que nous allon découvrir~:
|
||||
\texttt{dlopen} et sa petite famille.
|
||||
|
||||
% ------------------------------------
|
||||
|
||||
\section{Mécanique}
|
||||
|
||||
\index{dlopen}
|
||||
|
||||
\texttt{dlclose, dlopen, dlmopen - open and close a shared object}
|
||||
dlclose, dlopen, dlmopen - open and close a shared object
|
||||
|
||||
\begin{quote}
|
||||
The function dlopen() loads the dynamic shared object (shared library)
|
||||
@ -30,58 +13,9 @@ functions in the dlopen API, such as dlsym(3), dladdr(3), dlinfo(3),
|
||||
and dlclose().
|
||||
\end{quote}
|
||||
|
||||
% ------------------------------------
|
||||
|
||||
\section{Un exemple ?}
|
||||
\label{ex_dlopen}
|
||||
|
||||
Comme d'habitude, je vais proposer un exemple un peu artificiel,
|
||||
mais qui, de part sa simplicité, illustrera clairement
|
||||
les concepts de base. Partons du principe que nous avons
|
||||
un tableau de quatre nombres flottants, et que nous souhaitons
|
||||
proposer un affichage de ce tableau modifiable à volonté.
|
||||
|
||||
Nous allons donc écrire notre fonction personnelle d'affichage
|
||||
dans un fichier \textsc{.c} indépendant (le plugiciel) et qui
|
||||
sera chargé dynamiquement au \textsl{run-time} par le logiciel
|
||||
principal (l'appelant).
|
||||
|
||||
\subsection{Le plugiciel}
|
||||
|
||||
C'est ici que nous trouverons le code actif de l'exemple,
|
||||
l'utilité de notre \textsl{usecase} reste à déterminer par nos
|
||||
lecteurs, à titre d'exercice.
|
||||
|
||||
\lstinputlisting[language=c]{code/plugiciel.c}
|
||||
|
||||
On peut difficelement faire plus simple pour une première
|
||||
approche, mais attendez la suite.
|
||||
|
||||
\subsection{L'appelant}
|
||||
|
||||
|
||||
|
||||
\lstinputlisting[language=c]{code/appelant.c}
|
||||
|
||||
Ah, les choses se corsent un peu, il y a un pointeur bien
|
||||
tortueux à déchiffrer. Il était temps.
|
||||
|
||||
\texttt{void (*funcname)(const char*, const float *);}
|
||||
|
||||
\subsection{Le run}
|
||||
|
||||
\begin{verbatim}
|
||||
tth@fubar:~/Documents/TetaTricks/code$ make plugin
|
||||
gcc -Wall -shared -fPIC plugiciel.c -o plugiciel.so
|
||||
gcc -Wall appelant.c -ldl -o appelant
|
||||
tth@fubar:~/Documents/TetaTricks/code$ ./appelant
|
||||
rgb * a = : 6.685000 8.320000 1.570795
|
||||
tth@fubar:~/Documents/TetaTricks/code$
|
||||
\end{verbatim}
|
||||
|
||||
% ------------------------------------
|
||||
|
||||
\section{Autres langages}
|
||||
XXX\index{XXX}
|
||||
|
||||
|
||||
|
||||
|
@ -19,13 +19,11 @@ arguments: arguments.c Makefile
|
||||
no-op: no-op.c Makefile
|
||||
gcc -Wall $< -o $@
|
||||
|
||||
#------------- IPC -----------------------
|
||||
#------------- IPC
|
||||
|
||||
get-signal: get-signal.c Makefile
|
||||
gcc -Wall $< -o $@
|
||||
|
||||
fifo: fifo-rx fifo-tx
|
||||
|
||||
dtime.o: dtime.c my-fifo.h Makefile
|
||||
gcc -Wall -c $<
|
||||
|
||||
@ -35,13 +33,3 @@ fifo-tx: fifo-tx.c my-fifo.h dtime.o Makefile
|
||||
fifo-rx: fifo-rx.c my-fifo.h dtime.o Makefile
|
||||
gcc -Wall $< dtime.o -o $@
|
||||
|
||||
#------------- PLUGIN --------------------
|
||||
|
||||
plugin: plugiciel.so appelant
|
||||
|
||||
plugiciel.so: plugiciel.c plugiciel.h Makefile
|
||||
gcc -Wall -shared -fPIC $< -o $@
|
||||
|
||||
appelant: appelant.c plugiciel.h Makefile
|
||||
gcc -Wall $< -ldl -o $@
|
||||
|
||||
|
@ -1,31 +0,0 @@
|
||||
/* appelant.c */
|
||||
|
||||
#include <stdio.h>
|
||||
#include <dlfcn.h>
|
||||
|
||||
void affichage(char *titre, float vals[4]);
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
void *handle;
|
||||
float values[4];
|
||||
|
||||
void (*funcname)(const char*, const float *);
|
||||
|
||||
handle = dlopen("./plugiciel.so", RTLD_LAZY);
|
||||
if (!handle) {
|
||||
/* fail to load the library */
|
||||
fprintf(stderr, "Error: %s\n", dlerror());
|
||||
return 1;
|
||||
}
|
||||
|
||||
*(void**)(&funcname) = dlsym(handle, "affichage");
|
||||
|
||||
values[0] = 13.37; values[1] = 16.64;
|
||||
values[2] = 3.14159; values[3] = 0.5;
|
||||
funcname("rgb * a =", values);
|
||||
|
||||
dlclose(handle);
|
||||
|
||||
return 0;
|
||||
}
|
@ -1,6 +1,6 @@
|
||||
#include <stddef.h>
|
||||
#include <sys/time.h>
|
||||
#include "my-fifo.h"
|
||||
|
||||
double dtime(void)
|
||||
{
|
||||
struct timeval tv;
|
||||
|
@ -5,10 +5,8 @@ int main(int argc, char *argv[])
|
||||
{
|
||||
int key;
|
||||
|
||||
if (2 != argc) {
|
||||
fputs("need an argument\n", stderr);
|
||||
exit(1);
|
||||
}
|
||||
if (2 != argc) exit(1);
|
||||
|
||||
initscr(); /* first initialization */
|
||||
cbreak(); /* no line buffering */
|
||||
noecho(); /* be silent on input */
|
||||
@ -16,9 +14,11 @@ keypad(stdscr, TRUE); /* acces touches curseur */
|
||||
|
||||
mvaddstr(10, 3, argv[1]);
|
||||
refresh();
|
||||
|
||||
key = getch();
|
||||
|
||||
endwin();
|
||||
printf("code touche %d 0x%X\n", key, key);
|
||||
printf("code touche %d\n", key);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -13,12 +13,9 @@ int fifo;
|
||||
Message message;
|
||||
double localTS;
|
||||
|
||||
if (argc!=2) {
|
||||
fprintf(stderr, "%s need a fifo name\n", argv[0]);
|
||||
exit(1);
|
||||
}
|
||||
fifo = mkfifo(argv[1], O_RDONLY|O_CREAT);
|
||||
if (-1==fifo) {
|
||||
if (argc!=2) exit(1);
|
||||
fifo = mkfifo(argv[1], 0400);
|
||||
if (fifo) {
|
||||
perror("mkfifo fail");
|
||||
exit(2);
|
||||
}
|
||||
|
@ -1,7 +1,6 @@
|
||||
/*** named pipe --- transmiter ***/
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
#include <fcntl.h>
|
||||
#include "my-fifo.h"
|
||||
@ -16,7 +15,6 @@ if (-1==(fifo = open(argv[1], O_WRONLY))) {
|
||||
perror("open fifo for wr");
|
||||
exit(1);
|
||||
}
|
||||
memset(&message, 0, sizeof(Message));
|
||||
message.pid = getpid();
|
||||
message.timestamp = dtime();
|
||||
write(fifo, &message, sizeof(Message));
|
||||
|
@ -1,11 +0,0 @@
|
||||
/* plugiciel.c */
|
||||
|
||||
#include <stdio.h>
|
||||
#include "plugiciel.h"
|
||||
|
||||
void affichage(char *titre, float vals[4])
|
||||
{
|
||||
printf("%s : %f %f %f\n", titre,
|
||||
vals[0]*vals[3], vals[1]*vals[3],
|
||||
vals[2]*vals[3]);
|
||||
}
|
@ -1 +0,0 @@
|
||||
void affichage(char *titre, float vals[4]);
|
25
main.tex
25
main.tex
@ -90,7 +90,7 @@ en ligne sur le site du Tetalab. Your mileage may vary\dots
|
||||
% peut-être trouver un ordre des chapitres plus logique ?
|
||||
%
|
||||
|
||||
% \input{chap/boot}
|
||||
\input{chap/boot}
|
||||
\input{chap/shell}
|
||||
% \input{chap/editeurs}
|
||||
\input{chap/manpages}
|
||||
@ -108,22 +108,21 @@ en ligne sur le site du Tetalab. Your mileage may vary\dots
|
||||
\input{chap/video}
|
||||
\input{chap/graphisme}
|
||||
\input{chap/gnuplot}
|
||||
% \input{chap/print}
|
||||
\input{chap/print}
|
||||
\input{chap/webcam}
|
||||
% \input{chap/SCSI}
|
||||
\input{chap/X11}
|
||||
% \input{chap/manpages}
|
||||
% \input{chap/Fortran}
|
||||
% \input{chap/GMP}
|
||||
\input{chap/manpages}
|
||||
\input{chap/Fortran}
|
||||
\input{chap/GMP}
|
||||
\input{chap/Python}
|
||||
\input{chap/dino}
|
||||
\input{chap/cd-dvd}
|
||||
\input{chap/C}
|
||||
\input{chap/C.tex}
|
||||
\input{chap/textes}
|
||||
% \input{chap/MINITEL}
|
||||
% \input{chap/Raspberry}
|
||||
\input{chap/MINITEL}
|
||||
\input{chap/Raspberry}
|
||||
\input{chap/Fedora}
|
||||
% \input{chap/IPv6}
|
||||
\input{chap/IPv6}
|
||||
\input{chap/threads}
|
||||
\input{chap/IPC}
|
||||
\input{chap/dosbox}
|
||||
@ -132,10 +131,9 @@ en ligne sur le site du Tetalab. Your mileage may vary\dots
|
||||
\input{chap/plugins}
|
||||
\input{chap/Bonjour}
|
||||
\input{chap/debug}
|
||||
\input{chap/buzybox}
|
||||
\input{chap/gif89a}
|
||||
\input{chap/IRC}
|
||||
% \input{chap/SCCS} % nouveau 18 mars 2021
|
||||
\input{chap/SCCS} % nouveau 18 mars 2021
|
||||
\input{chap/Usenet}
|
||||
\input{chap/DNS}
|
||||
\input{chap/ssh}
|
||||
@ -143,9 +141,8 @@ en ligne sur le site du Tetalab. Your mileage may vary\dots
|
||||
\input{chap/gadgets}
|
||||
% \input{chap/slang}
|
||||
\input{chap/curses}
|
||||
\input{chap/openwrt}
|
||||
\input{chap/WiFi}
|
||||
% \input{chap/GIT}
|
||||
\input{chap/GIT}
|
||||
\input{chap/divers}
|
||||
% \input{chap/peer2peer}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user