Précédent | Sommaire | Index | Suivant
Makefile
générés automatiquementssh.c
Note du traducteur : bien entendu, le mot « hacker » est à prendre ici au sens de bidouilleur passionné, qui s'intéresse au fonctionnement interne des choses afin de contribuer à leur amélioration, et non au sens largement utilisé, mais néanmoins incorrect, de pirate informatique. Si vous êtes venu sur cette page avec l'espoir d'y trouver des explications sur la façon d'utiliser PuTTY pour pénétrer illégalement dans un système informatique, vous pouvez passer votre chemin et aller jouer ailleurs.
La présente annexe recense un certain nombre de principes de conception qui s'appliquent au code source de PuTTY. Si vous prévoyez de nous envoyer des contributions sous forme de code source en vue de leur inclusion dans le logiciel, vous devriez commencer par lire ce qui suit.
Bien que la version Windows de PuTTY soit la plus connue de toutes, PuTTY et les outils qui vont avec ne sont plus des applications spécifiquement Windows. Il existe une version fonctionnelle de PuTTY pour Unix, et une version Mac est en cours de réalisation. D'autres versions, pour d'autres plateformes, feront peut-être leur apparition un jour, ou pas.
C'est pourquoi mettre du code spécifiquement Windows dans les modules qui constituent le cœur même de PuTTY, tels que ssh.c
, n'est pas acceptable. Nous nous sommes donné du mal pour retirer tout ce qui est spécifique à Windows des modules principaux, et pour le déplacer dans des modules spécifiquement Windows. Ajouter de grandes quantiés de code spécifiquement Windows à des endroits du source qui devraient rester portables est un excellent moyen pour que nous refusions de prendre en compte une modification qui nous serait proposée.
Dans le code source de PuTTY, on trouve d'une part des modules spécifiques à telle ou telle plateforme, et d'autre part des modules génériques, qui sont communs à l'ensemble des plateformes. Les modules spécifiques à la version Unix se trouvent tous dans le sous-répertoire unix
. Ceux qui sont spécifiquement Mac sont dans le sous-répertoire mac
et, bien entendu, les modules spécifiquement liés à Windows se trouvent dans le sous-répertoire windows
.
Tous les modules qui figurent dans le répertoire principal du code source - notamment la totalité du code source pour les différents backends - sont génériques, communs à toutes les plateformes. Nous voulons que cela reste ainsi.
Cela signifie également que vous devriez vous en tenir à ce que vous garantit le C ANSI / ISO ( c'est à dire le standard d'origine, C89/C90, pas le C99 ). Essayez de ne pas faire de suppositions quant à la taille précise des types de base tels que int
et long int
. N'utilisez pas de transtypages de pointeurs pour effectuer des opérations dont le résultat dépend de l'ordre des bits à l'intérieur des octets ou des mots ( vous savez, la différence entre petit-boutiste et grand-boutiste ), et ainsi de suite.
Il y a toutefois un ou deux aspects de la portabilité du C ANSI dont nous n'avons que faire. En particulier, PuTTY est destiné à être compilé sur des architectures 32 bits ou plus, donc on peut sans risque considérer que le type int
fait au moins 32 bits, et non juste les 16 bits que vous garantit le C ANSI. De même, nous tablons sur le fait que l'encodage des caractères à l'exécution se fait sur un surensemble des caractères ASCII imprimables, bien que nous ne fassions aucune pré-supposition sur les valeurs numériques des caractères de contrôle, en particulier les caractères '\n'
et '\r'
).
PuTTY n'est pas, contrairement à ce que l'on pourrait penser, avant tout un client SSH auquel quelques autres fonctionnalités ont été rajoutées de bric et de broc, à la McGyver. Au contraire, PuTTY est un client générique, de type VT, qui supporte plusieurs « backends », et l'un d'entre eux se trouve être plus gros, plus populaire et plus utile que les autres ( en l'occurrence, le backend SSH, bien sûr ). Toute fonctionnalité supplémentaire qui peut s'avérer intéressante à tous les backends doit donc précisément être mise en commun : l'implémenter sans raison particulière dans le backend SSH constituerait une erreur de conception. À titre d'exemple, nous avons ainsi reçu plusieurs propositions de modifications du code source de PuTTY visant à ajouter le support de proxy grâce à des modifications dans ssh.c
. De toute évidence, c'est une erreur que de procéder ainsi : ce genre de modification a sa place dans le fichier network.h
, de façon à ce qu'elle bénéficie équitablement à tous les backends. Et c'est d'ailleurs là que nous l'avons mise, en fin de compte, après qu'un autre contributeur nous ait envoyé un meilleur patch.
Le reste de PuTTY devrait, dans la mesure du possible, s'efforcer d'ignorer toute spécificité de tel ou tel backend. Pour supporter une fonctionnalité qui n'est disponible que dans un seul protocole réseau, par exemple, l'interface du backend devrait être étendue de telle manière que n'importe quel backend capable de fournir cette fonctionnalité puisse le faire. S'il s'avère, dans la pratique, qu'il n'y a qu'un seul backend qui se trouve être concerné, alors tant mieux, mais il ne faut pas faire en sorte qu'une autre portion de code, qui n'a rien à voir, se retrouve dépendante de ces modifications.
Certains portages de PuTTY - notamment la version Mac, qui est en cours de réalisation - sont contraints par le système d'exploitation de s'exécuter comme un processus unique, bien qu'ils puissent avoir à gérer des sessions multiples.
C'est pourquoi les parties de PuTTY qui sont indépendantes de la plateforme n'utilisent jamais de variables globales pour entreposer des données propres à chaque session. Les quelques variables globales utilisées ici et là sont tolérées parce qu'elles ne sont pas propres à une session en particulier : flags
, par exemple, définit des propriétés dont on s'attend à qu'elles s'appliquent de la même façon à toutes les sessions gérées par un seul et même processus PuTTY. L'état du nombre aléatoire dans sshrand.c
, ou la liste de timers dans timing.c
, s'appliquent de la même manière à toutes les sessions, et ainsi de suite. Mais la plupart des données étant spécifiques à une session particulière, elles sont stockées dans des structures de données allouées dynamiquement, et des pointeurs sur ces structures de données sont échangés entre les fonctions.
Le code spécifique à une plateforme donnée peut le cas échéant aller à l'encontre de ce principe. Le code Windows, pour des raisons historiques, stocke la majorité de ses données sous forme de variables globales. Ce n'est pas un problème, parce sous Windows, nous savons qu'il y a une seule session par processus PuTTY. Cela dit, les modifications apportées au code commun à toutes les plateformes devraient éviter de recourir à des variables globales, à moins qu'elles ne soient effectivement communes à plusieurs sessions.
PuTTY est entièrement écrit en C, pas en C++.
Nous avons fait certains efforts pour faciliter la compilation de notre code avec un compilateur C++ : en particulier, nos macros snew
, snewn
et sresize
convertissent explicitement les valeurs de retour de malloc
et de realloc
dans le type cible ( cela présente des avantages, au niveau de la vérification de type, y compris en C : en effet, on ne peut jamais allouer par accident une zone mémoire de taille incorrecte pour le type pointeur auquel on l'affecte, et la compatibilité avec le C++, bien qu'intéressante, n'est en fait vraiment qu'un effet secondaire ).
Nous tenons à ce que PuTTY reste écrit exclusivement en C, au moins dans les parties indépendantes de la plateforme et dans les portages actuels. Les propositions de modifications qui changent les makefiles pour que la compilation se fasse comme si PuTTY était écrit en C++, et qui commencent à utiliser des classes, ne seront pas acceptées. De la même manière, nous désapprouvons particulièrement l'utilisation des commentaires commençant par deux barres obliques, façon C++, au moins pour l'instant. Peut-être que lorsque C99 sera d'un usage suffisament répandu, nous serons plus indulgents.
La seule exception que nous acceptions à cette règle est la suivante : un portage de PuTTY vers une nouvelle plateforme peut utiliser un autre langage que le C si cet autre langage est nécessaire pour coder sur cette plateforme. Par exemple, si votre PDA favori a une interface graphique avec une API écrite en C++, alors il n'y a pas moyen d'écrire une version de PuTTY pour ce PDA sans utiliser le C++. Dans ce cas, OK, allez-y et codez en C++, mais uniquement dans le sous-répertoire qui contient le code spécifique à cette plateforme. Si vos modifications ont pour conséquence que les versions Unix ou Windows doivent être compilées avec un compilateur C++, alors nous ne les accepterons pas.
PuTTY est une application réseau, et une application liée à la sécurité. Dites-vous bien que votre code sera tôt ou tard confronté à des données incorrectes, malformées, etc., volontairement envoyées par des attaquants qui essayent de trouver une faille, pour faire des choses qu'ils ne doivent pas faire, et pour s'octroyer des droits qu'ils ne doivent pas avoir. Alors efforcez-vous de programmer de telle façon que votre code ne soit pas une source de trous de sécurité.
En particulier, efforcez-vous de ne pas utiliser des buffers de taille fixe pour stocker des données de taille variable, ou dont la taille n'est pas connue d'avance, comme les chaînes de caractères reçues de la machine distante, ou tapées au clavier par l'utilisateur. Nous mettons à votre disposition des fonctions telles que dupcat
et dupprintf
, qui allouent dynamiquement des buffers de la bonne taille pour les chaînes de caractères qu'elles construisent. Servez-vous en autant que possible.
La version Windows de PuTTY peut actuellement être compilée avec n'importe lequel des quatre compilateurs Windows suivants : MS Visual C, le compilateur C téléchargeable gratuitement de Borland, le compilateur MinGW32
, que vous pouvez trouver dans les outils GNU et dans Cygwin, et enfin lcc-win32
.
C'est une caractéristique réellement utile de PuTTY, parce que cela signifie que les gens qui veulent contribuer au codage n'ont pas besoin, pour cela, d'avoir un compilateur particulier. D'un côté, ils ne sont pas obligés de sortir le chéquier pour s'acheter MSVC s'ils ne l'ont pas encore, et d'un autre côté, s'ils l'ont déjà, ils peuvent l'utiliser, plutôt que de se prendre la tête à vouloir installer gcc
en parallèle de MSVC. Ils peuvent utiliser le compilateur de leur choix s'ils en ont déjà un, ou installer le moins cher et le plus facile à utiliser qui soit, s'ils n'en ont pas déjà un.
C'est pourquoi nous ne voulons pas que PuTTY devienne dépendant du compilateur que vous utilisez. Utiliser les extensions GNU au langage C, par exemple, risquerait de mettre à mal cette caractéristique bien utile et, d'une façon plus réaliste, dépendre d'une fonction de bibliothèque spécifiquement Microsoft fournie par la bibliothèque C de MSVC ( comme _snprintf
, par exemple ) serait une erreur, parce que cette fonction n'est pas disponible dans les autres compilateurs. Toutes les fonctions fournies dans les DLL Windows officielles, au titre de l'API Windows, peuvent être utilisées sans problème, de même que tout ce qui est défini dans la bibliothèque C standard, parce que tout cela doit normalement être utilisable quel que soit l'environnement de développement. En revanche, aussi bien ce qui est fourni dans des bibliothèques non standard que les extensions au langage propres à un compilateur particulier, n'est pas autorisé.
( _snprintf
, en particulier, ne devrait pas être utile puisque nous fournissons la fonction dupprintf
: voir à ce sujet la section D.5 ).
L'indépendance vis à vis du compilateur doit bien entendu s'appliquer à toutes les plates-formes, pas seulement à Windows.
PuTTY est tout petit, en comparaison de beaucoup d'autres applications Windows. Et il est facile à installer : il ne dépend d'aucune DLL, d'aucune autre application, d'aucun service pack, d'aucune mise à jour système. Il se présente sous la forme d'un seul exécutable. Vous l'installez où vous voulez, et vous le lancez. C'est aussi simple que cela.
Nous tenons à garder ces deux caractéristiques ( la petite taille et la facilité d'installation ) autant que faire se peut. C'est pourquoi les propositions de modifications du code qui entraîneraient une dépendance critique vis à vis de telle ou telle DLL, ou qui augmenteraient de façon importante la taille du programme, ont de bonnes chances d'être refusées immédiatement, surtout si c'est pour ajouter une fonctionnalité utile pour seulement une petite minorité d'utilisateurs.
Nous avons plus ou moins l'intention de faire un jour le nécessaire pour qu'il soit possible de rajouter à PuTTY des fonctionnalités - potentiellement volumineuses en termes de nombre de lignes de code ou de taille du code objet - à l'aide de plug-ins ( pardon, de greffons ) sous forme de DLL. L'important, cependant, c'est que ces DLL soient optionnelles. Si PuTTY n'arrive pas à les trouver lorsqu'il démarre, il faudra qu'il puisse démarrer quand même, sans problème, simplement en ne fournissant pas les fonctionnalités supplémentaires implémentées dans ces DLL non trouvées. Un jour, peut-être, une installation complète de PuTTY comprendra dix ou vingt petits de ces petits plug-ins sous forme de DLL. Cela donnera un processus d'installation moins simple qu'actuellement, bien sûr, mais si la simplicité d'installation est ce qui compte le plus pour vous, vous pourrez toujours n'installer que l'exécutable principal de PuTTY, avec seulement les DLLs dont vous aurez besoin, ou aucune d'entre elles, et tout devra fonctionner impeccablement.
Dépendre de code externe placé dans des DLL est une chose que nous aimerions éviter autant que faire se peut ( encore que, dans certains cas, comme pour les mécanismes complexes d'authentification SSH, ce soit peut-être inévitable ). Et si cela ne peut vraiment pas être évité, il est important de conserver le même principe de fonctionnement dégradé « en douceur » : si une certaine DLL n'est pas disponible, PuTTY ne doit surtout pas planter. Au contraire, il doit continuer à fonctionner, simplement en ne fournissant pas la fonction correspondant à cette DLL.
PuTTY et les outils associés, ou tout du moins la grande majorité d'entre eux, s'exécutent dans un seul thread.
Cela signifie que si vous concevez un nouveau mécanisme interne au logiciel, il n'y a pas besoin de recourir à des verrous pour s'assurer que ce nouveau mécanisme ne risquera pas d'être appelé par deux threads différents à un instant donné. La seule façon d'appeler du code de façon ré-entrante est par appel récursif.
Cela dit, la gestion du réseau, dans la version Windows de PuTTY, est principalement le résultat de messages Windows provenant de WSAAsyncSelect ()
. Donc si vous appelez MessageBox ()
assez profondément dans une routine quelconque de gestion d'événement réseau, il faut que vous sachiez que votre code risque d'être ré-entré si jamais un événement réseau survient et qu'il est transmis à notre procédure de fenêtre par la boucle de messages de MessageBox ()
.
De même, les programmes « frontaux », tel que le programme Plink, notamment, qui accompagne la version Windows de PuTTY, peuvent utiliser plusieurs threads s'ils le souhaitent. Cela dit, Plink exerce un contrôle très strict de ses threads auxiliaires, et ne les utilise pour ainsi dire que comme un select ()
. Le code situé hors du fichier windows/winplink.c
n'est quasiment appelé que depuis le thread principal. Les autres threads ne sont là que pour gérer les accès aux fichiers, qui sont potentiellement bloquants, et ils envoient des messages au thread principal lorsqu'il y a du vrai travail à faire. Cela ne remet pas en cause la portabilité du code source, parce que de toute façon, il y a certaines parties de windows/winplink.c
qui doivent être adaptées à l'occasion du portage vers d'autres plates-formes.
Une conséquence importante de cela est que PuTTY n'a qu'un seul thread, dans lequel il fait tout. Ce « tout » peut inclure le fait de gérer plus d'une session de login ( cf. section D.3 ), de gérer de multiples canaux de données au sein d'une session SSH, de répondre à des événements liés à l'interface graphique même lorsque rien ne se passe au niveau réseau, et de répondre à des demandes réseau émanant de la machine distante ( comme la répétition de l'échange de clés ) alors même que le programme est occupé à traiter des interactions utilisateur complexes telles que la boîte de dialogue de re-configuration. Tout cela signifie que quasiment aucune partie du code de PuTTY ne doit prendre le risque de bloquer le fonctionnement du programme, sans quoi cela peut causer des problèmes en cascade dans d'autres parties du programme.
Dans quasiment tous les cas, PuTTY envoie les frappes de touches à la machine distante. Même les séquences de touches bizarres dont vous pensez que ce devrait être des raccourcis qui contrôlent le fonctionnement de PuTTY. Même Alt-F4 ou Alt-Espace, par exemple. Si une séquence de touches possède une séquence d'échappement bien définie qu'il pourrait être utile d'envoyer à la machine distante, alors il faut le faire, ou à tout le moins faire en sorte qu'il soit possible de configurer le programme pour qu'il le fasse.
Prendre une séquence de touches et en faire de façon inconditionnelle un raccourci clavier pour contrôler le fonctionnement de PuTTY est presque toujours une erreur de conception. S'il y a réellement, vraiment, besoin d'un raccourci clavier, alors essayez de trouver une séquence de touches qui n'est pas déjà utilisée dans les versions déjà existantes de PuTTY ( soit une qui n'envoie rien à la machine distante, soit une qui envoie la même chose qu'une autre combinaison de touches ). Et même comme ça, dites-vous bien qu'il est possible qu'un jour, il y ait besoin de cette combinaison de touches pour envoyer quelque chose à la machine distante, alors assurez-vous qu'il y a un autre moyen d'invoquer la fonctionnalité correspondante de PuTTY.
Ce n'est pas sans raison si PuTTY a plein de petits panneaux de configuration au lieu d'en avoir seulement quelques uns de plus grande taille : tout le monde n'a pas la chance d'avoir un écran de 1600×1200, tout simplement. 640×480 est une résolution utilisable sous Windows, même si elle est très très limitée ( d'ailleurs c'est la résolution quand on démarre Windows en mode sans échec ). Voilà pourquoi nous choisissons de continuer à l'utiliser.
C'est pour cela que la boîte de dialogue de configuration de PuTTY et la fenêtre de contrôle de PuTTYgen sont maintenues suffisamment petites pour rentrer confortablement dans un écran de 640×480. Si vous ajoutez des boutons, des cases à cocher, etc., à l'un de ces panneaux de configuration, et que par suite, il vous semble nécessaire d'agrandir la taille globale de la fenêtre, alors ne le faites pas, ne changez pas cette taille globale. Répartissez plutôt ces boutons et cases supplémentaires sur d'autres panneaux de configuration.
Makefile
générés automatiquementPuTTY est destiné à pouvoir être compilé sur de nombreux plateformes, et avec de nombreux compilateurs différents. Tant et si bien qu'il est inenvisageable de vouloir maintenir un seul fichier Makefile
qui serait capable de gérer tous les cas possibles, et qu'il serait tout aussi « prise de tête » de vouloir maintenir un ensemble de fichiers Makefile
, à raison d'un pour chacun des environnements de compilation.
C'est pourquoi nous avons déplacé le problème d'un cran : dans l'archive qui regroupe tous les codes source de PuTTY se trouve un fichier nommé Recipe
, qui indique quels fichiers source sont nécessaires pour produire tel ou tel binaire. Il y a aussi un script nommé mkfiles.pl
, qui lit le fichier Recipe
, et qui écrit les véritables fichiers Makefile
. Le script lit également tous les fichiers sources, et analyse leurs dépendances vis à vis de fichiers d'en-tête, et cela nous procure un avantage supplémentaire : cela nous permet de disposer d'informations correctes au sujet des dépendances, y compris dans des environnements où il est difficile de mettre en place une phase de make depend
automatisée.
Vous ne devriez jamais modifier directement aucun des fichiers Makefile
de PuTTY. Ils ne sont pas entreposés dans notre système de gestion de versions. Au lieu de cela, ils sont générés automatiquement par le script mkfiles.pl
à partir du fichier Recipe
.
Si vous avez besoin d'ajouter un nouveau fichier objet à un binaire en particulier, la bonne façon de faire consiste à modifier le fichier Recipe
, puis à relancer le script mkfiles.pl
. Cela provoquera l'ajout du nouveau fichier objet à chacun des outils qui en ont besoin, sur chacune des plateformes où il présente un intérêt, dans chacun des fichiers Makefile
où sa présence a un sens, et cela mettra d'équerre toutes les informations de dépendances.
Nous envoyer un patch qui modifie l'un des fichiers Makefile
, ce serait perdre votre temps, puisqu'il faudrait qu'on fasse la modification correspondante dans le fichier Recipe
. Et nous envoyer un patch qui modifie tous les fichiers Makefile
s, sans exception, ce serait juste une perte de temps plus grande encore, et une perte de votre temps à vous, aussi !
Il y a un commentaire qui dit cela au début de chaque fichier Makefile
de l'archive qui contient les sources de PuTTY, mais il semblerait que de nombreuses personnes passent devant ce commentaire sans le voir, et c'est pourquoi il n'est pas inutile de le redire ici.
ssh.c
De grandes parties du code de ssh.c
sont structurées à l'aide d'un ensemble de macros qui mettent en œuvre le concept de « coroutines » en C, de Donald KNUTH ( ou du moins quelque chose qui y ressemble ).
Pour faire bref, disons que la raison d'être de ces macros est de permettre qu'une fonction puisse appeler crReturn ()
pour revenir à son appelant, et que la fois suivante, lorsque cette fonction est appelée à nouveau, l'exécution reprenne juste après cette instruction crReturn
.
Cela veut dire que toute variable locale ( automatique ) déclarée dans une telle fonction sera corrompue lors de l'appel de crReturn
. Si vous avez besoin d'une variable persistante, qui doive « survivre » au delà de l'appel de crReturn
, il faut en faire un champ de l'une des structures d'état persistentes : soit les structures d'état locales s
ou st
dans chaque fonction, soit la structure ssh
, qui s'étend à l'ensemble du backend.
Veuillez vous reporter à http://www.chiark.greenend.org.uk/~sgtatham/coroutines.html
pour des informations plus complètes au sujet de ces macros, de ce à quoi elles servent, et de comment elles fonctionnent.
Le système de compilation de PuTTY est très simple, et repose sur le modèle suivant, toutes plateformes confondues :
Par conséquent, si vous avez besoin d'introduire des modifications dans un module particulier, qui n'est disponible que dans certains binaires ( par exemple, un mécanisme d'authentification, basé sur un proxy faisant appel au chiffrement, qui doit être laissé à l'écart de PuTTYtel pour que celui-ci puisse continuer à être utilisé dans les juridictions qui interdisent le cryptage des communications ), alors la mauvaise façon de s'y prendre consiste à mettre des directives de compilation #ifdef
un peu partout dans proxy.c
( par exemple ). En effet, cela imposerait deux compilations séparées du fichier proxy.c
: une en vue de son utilisation dans PuTTY, et une autre pour l'utiliser dans PuTTYtel. Et cela nécessiterait une refonte importante de toute l'architecture de génération des Makefile
( voir à ce sujet la section D.11 ). Ne faites pas cela, à moins que vous ne soyez prêt à assurer cette refonte vous-même, et que vous puissiez garantir qu'elle restera toujours valable, qu'elle sera applicable à toute plateforme sur laquelle nous pourrions vouloir faire tourner PuTTY et les outils qui vont avec !
La bonne façon de procéder, pour introduire une modification comme celle-ci, consiste à placer le nouveau code dans un fichier source séparé et, si nécessaire, à mettre en place un second nouveau fichier source, qui définisse le même ensemble de fonctions, mais sous forme de « stubs », c'est à dire de coquilles vides qui ne fournissent pas la fonctionnalité en question. Le module dont le comportement a besoin de pouvoir varier d'un cas à l'autre ( proxy.c
, dans cet exemple ) peut dès lors appeler les fonctions ainsi définies dans les deux modules, et cela fournira la nouvelle fonctionnalité, ou pas, selon celui de vos nouveaux modules avec lequel il sera lié.
Bien entendu, les fichiers objets ne sont jamais partagés entre les différentes plateformes. Il est donc permis d'utiliser des directives #ifdef
pour choisir entre les plateformes. C'es le cas, par exemple, dans puttyps.h
, pour choisir quels fichiers d'en-tête spécifiques à la plateforme il y a lieu d'incorporer dans le binaire final, et aussi dans misc.c
( le système de diagnostic mémoire style « Démineur » spécifique aux versions Windows ). Cela dit, il vaut mieux utiliser cela avec parcimonie, voire même l'éviter, dans la mesure du possible.
Le code actuel de PuTTY n'est sans doute pas strictement conforme à tous les principes énoncés ci-dessus. Il se peut qu'il y ait ici ou là quelques lignes de code spécifiques à SSH dans ce qui devrait normalement être indépendant du « backend » ( cf. [NdT] ci-dessous ), autrement dit des rouages internes, ou bien une dépendance occasionnelle vis à vis d'une fonction de bibliothèque X non standard, sous Unix.
Ce n'est pas une raison pour outrepasser les règles. Il nous arrive de les outrepasser nous-mêmes, mais cela ne nous satisfait pas, et nous accepterions volontiers des correctifs qui résoudraient les problèmes existants. Merci de nous aider à améliorer notre code, pas à l'empirer !
[NdT] : j'ai laissé le mot « backend » tel quel dans la traduction, non par paresse, mais parce que je ne suis pas arrivé à lui trouver un équivalent français qui me satisfasse. Ce n'est pas faute d'avoir cherché, mais les définitions que j'ai trouvées soit n'expliquaient rien, soit ne s'appliquaient pas au contexte, et donc n'aidaient pas à la compréhension.
Si vous souhaitez faire part aux auteurs de PuTTY de votre avis sur ce manuel, ou sur les outils PuTTY eux-mêmes,
veuillez vous reporter à la page "Feedback"
( merci de leur écrire exclusivement en anglais ). Si vos remarques portent sur la traduction, merci de
vous adresser directement au traducteur, et non à l'équipe de
développement.