3 Travail à réaliser
Vous devez réaliser un programme xdmcpquery prenant en paramètre
le nom de la machine abritant le gestionnaire de sessions à contacter.
Votre programme doit aussi accepter comme paramètre optionnel
le nom du display à gérer (e.g. gayant01:1).
Votre programme doit contacter le gestionnaire et dialoguer avec lui
jusqu'à ce que le gestionnaire prenne en charge le serveur X11 désigné.
3.1 Exercices autour de X11 et des gestionnaires de sessions
Lancez un sous-serveur X11 (commande Xnest) dans une fenêtre X11.
Faites en sorte que ce serveur soit considéré comme l'écran numéro 1
de votre machine. Vérifiez que vous pouvez lancer sur ce nouveau serveur des
applications X11 en provenance d'une autre machine (utilisez, par exemple,
l'application xeyes pour faire les tests). Relancez votre sous-serveur
en faisant en sorte qu'il soit géré par le gestionnaire de sessions d'une
autre machine Unix. Recommencez en lançant la requête au serveur sur
chouia puis sur servntapp1. Recommencez une de ces requêtes en
exécutant, dans une autre fenêtre, la commande xdmcpdump. À l'aide du
document xdmcp-doc.ps sur XDMCP, analysez le dialogue entre les machines.
3.2 Client en mode non connecté
Commencez par écrire un client créant une socket UDP locale et l'adresse
de la socket à contacter (i.e. la socket du gestionnaire de sessions).
La socket et l'adresse de socket doivent être créées à partir des
noms passés en paramètre du programme. Il faudra donc une routine
de résolution de noms en adresses IP. Envoyez un paquet vide au gestionnaire
de sessions. Vérifiez avec le renifleur que le paquet apparaît bien sur
le réseau.
3.3 Envoi du paquet Query
La bibliothèque libXdmcp.a et le fichier d'inclusion Xdmcp.h
contiennent des outils permettant de construire et de déchiffrer des
paquets XDCMP. Il faut commencer par créer des zones de travail avec
la fonction suivante :
/** Allocate an XDMCP buffer **/
XdmcpBufferPtr allocXDMCPBuffer(void){
XdmcpBufferPtr buffer=(XdmcpBufferPtr)calloc(sizeof(XdmcpBuffer),1);
buffer->data=(BYTE *)calloc(MAX_BUFFER,sizeof(BYTE));
buffer->size=MAX_BUFFER;
return buffer;
}
Ensuite il faut allouer une structure XdmcpHeader, la remplir, puis
l'écrire dans la zone de travail en utilisant XdmcpWriteHeader.
Vous pouvez alors ajouter les différents champs du paquet en utilisant
les fonctions XdmcpWriteCARD16, XdmcpWriteCARD32,
XdmcpWriteARRAY8 et XdmcpWriteARRAYofARRAY8.
Après l'envoi du paquet, la zone de travail peut être libérée
via la fonction :
/** Free an XDMCP buffer **/
void freeXDMCPBuffer(XdmcpBufferPtr buffer){
if(buffer->data!=NULL) free(buffer->data);
free(buffer);
}
Utilisez ces outils pour construire et envoyer le premier paquet Query
du dialogue. La liste des authentication peut être vide.
Vérifiez avec le renifleur que le paquet est bien constitué et que
le serveur xdm répond.
3.4 Serveur en mode non connecté
Il faut maintenant recevoir la réponse du gestionnaire de sessions. Utilisez
les fonctions système select et recvfrom pour construire
une procédure de récupération des messages en provenance du
gestionnaire xdm. Construisez aussi une procédure pour vérifier
que le paquet reçu en réponse du Query est bien un paquet
Willing (utilisez les fonctions XdmcpReadXX). Vous devez
afficher les informations directement lisibles par un être humain
qui se trouvent dans le paquet Willing.
3.5 Paquets Request, Accept et Manage
Perfectionnez votre programme en ajoutant les procédures pour
-
Envoyer le paquet Request (le protocole TCP/IP est codé 0,
l'adresse correspondante est l'adresse IP de la machine tournant
le serveur X11 et le champ authorization name peut être
fixé à MIT-MAGIC-COOKIE-1).
- Recevoir le paquet Accept (la procédure doit retourner
le numéro de session présent dans le paquet, elle doit aussi
afficher la valeur du champ authorization data en hexadécimal).
- Envoyer le paquet Manage (utilisez la classe de display
MIT-unspecified).
Testez votre programme en lui demandant de faire prendre en charge votre
Xnest par le gestionnaire kdm de weppes.
3.6 Tiens, il y en a qui arrivent jusque là ?!
Ajoutez du code pour prendre en compte les divers paquets d'erreur
qui peuvent survenir (Unwilling, Decline, Refuse et
Failed). Utilisez les paquets KeepAlive et Alive pour
indiquer la fin de la session courante.