/*************************************************************************************************************************************/ /* */ /* E X E C U T I O N A D I S T A N C E D ' U N E C O M M A N D E : */ /* */ /* */ /* Nota : */ /* */ /* Tout ce qui suit a ete mis au point */ /* grace au programme 'v $xtc/remote.12$c'. */ /* */ /* */ /* ATTENTION : */ /* */ /* La commande distante est executee sous */ /* le "shell" de login qui est, en general, */ /* '$SH', ce qui fait que les variables */ /* d'environnement (telles '$DISPLAY', ou */ /* encore '$ROUGE,'...) qui sont utiles dans */ /* certaines commandes via 'Gval(...)' ne */ /* pas definies. Cela a, par exemple, des */ /* consequences dans '$xci/display$X' pour */ /* recuperer la palette de couleurs. Lorsque */ /* le "shell" de login est '$CSH', cela ne */ /* change pas grand chose car, en effet, le */ /* fichier '$FCshrc' n'est pas interprete a */ /* cause du test sur '$?prompt' qu'il contient */ /* ('v $FCshrc prompt'). */ /* */ /* */ /* Exemples : */ /* */ /* Voici six exemples tres differents d'utilisation */ /* de cette commande : */ /* */ /* 1-edition de l'environnement distant "de base" : */ /* */ /* $xcg/remote.01$X user=colonna machine=$LACT27 \ */ /* avertissement=FAUX \ */ /* STANDARD_IN=FAUX \ */ /* preliminaire="env" \ */ /* cat=FAUX */ /* */ /* */ /* 2-execution d'une commande de base ('date') : */ /* */ /* $xcg/remote.01$X user=colonna machine=$LACT27 \ */ /* avertissement=FAUX \ */ /* commande="date" \ */ /* cat=FAUX */ /* */ /* */ /* 3-recuperation de la variable '$bandeB' sur '$LACT27' : */ /* */ /* */ /* $xcg/remote.01$X user=colonna machine=$LACT27 \ */ /* avertissement=FAUX \ */ /* STANDARD_IN=FAUX \ */ /* preliminaire="prompt= ; export prompt ; TERM=$TERM ; export TERM" \ */ /* commande="$CSH -c set" \ */ /* cat=FAUX | \ */ /* $R "$K_TAB" "$K_BLANC" | \ */ /* $GRE "^bandeB " */ /* */ /* */ /* 4-sauvegarde sur '$LACT27' du contenu du directory */ /* courant sur la bande '/dev/mt/tps0d3nsv' : */ /* */ /* */ /* $FIN $Dcourant -type f -print \ */ /* | \ */ /* $CPI -oBv \ */ /* | \ */ /* $xcg/remote.01$X user=colonna machine=$LACT27 \ */ /* avertissement=FAUX \ */ /* STANDARD_IN=VRAI \ */ /* commande="$CA > /dev/mt/tps0d3nsv" \ */ /* cat=FAUX */ /* */ /* */ /* 5-verification de la qualite de l'operation */ /* de sauvegarde precedente : */ /* */ /* */ /* $xcg/remote.01$X user=colonna machine=$LACT27 \ */ /* avertissement=FAUX \ */ /* STANDARD_IN=FAUX \ */ /* commande="$CPI -iBt < /dev/mt/tps0d3nsv" \ */ /* cat=FAUX */ /* */ /* */ /* 6-affichage de l'image 'v $xiio/MIRE' sur l'ecran de '$LACT27' : */ /* */ /* */ /* $xci/acces$X A=$xiio/MIRE \ */ /* $formatI | \ */ /* $xcg/remote.01$X user=colonna machine=$LACT27 \ */ /* avertissement=FAUX \ */ /* preliminaire="DISPLAY=$X_LACT27;export DISPLAY" \ */ /* commande="commandes/images/display$X \ */ /* palette=palettes/cercle.35 \ */ /* substitution=L_SUBSTITUTION_02 \ */ /* $formatI" \ */ /* cat=VRAI */ /* */ /* */ /* Author of '$xcg/remote.01$K' : */ /* */ /* Jean-Francois COLONNA (LACTAMME, 1997??????????). */ /* */ /*************************************************************************************************************************************/ /*===================================================================================================================================*/ /*************************************************************************************************************************************/ /* */ /* I N T E R F A C E ' listG ' : */ /* */ /* */ /* :Debut_listG: */ /* :Fin_listG: */ /* */ /*************************************************************************************************************************************/ /*===================================================================================================================================*/ /*************************************************************************************************************************************/ /* */ /* D I R E C T I V E S S P E C I F I Q U E S D E C O M P I L A T I O N : */ /* */ /*************************************************************************************************************************************/ @define PRAGMA_CL_____PAS_DE_LIBRAIRIES_DYNAMIQUES /* Introduit le 20061114154814 (car tres utile dans '$xE'...). */ /*===================================================================================================================================*/ /*************************************************************************************************************************************/ /* */ /* F I C H I E R S D ' I N C L U D E S : */ /* */ /*************************************************************************************************************************************/ #include INCLUDES_MINI /*===================================================================================================================================*/ /*************************************************************************************************************************************/ /* */ /* P A R A M E T R E S : */ /* */ /*===================================================================================================================================*/ #define EDITER_LES_MESSAGES_D_AVERTISSEMENT \ VRAI \ /* Faut-il editer les messages de type 'PRINT_ATTENTION(...)' ('VRAI') ou pas ('FAUX') ? */ #define FAIRE_DU_PARALLELISME \ VRAI \ /* Faut-il lancer 'EMULATION_DE_STANDARD_IN' et 'EMULATION_DE_STANDARD_OUT' en parallele */ \ /* ('VRAI') ou en sequentiel ('FAUX') ? */ #define FAIRE_DE_LA_SIGNALISATION \ FAUX \ /* Faut-il lancer utiliser le "stream" de signalisation ('VRAI') ou pas ('FAUX') ? */ #define EMULER_STANDARD_IN \ FAUX \ /* Faut-il emuler 'STANDARD_IN' ('VRAI') ou pas ('FAUX') ? Le 20001121092205, cette */ \ /* option est passee de 'VRAI' a 'FAUX' parce qu'il semble que cela soit la meilleure */ \ /* chose ('v $Falias_fin_um_pa remote.01.X'). */ #define EMULER_STANDARD_OUT \ VRAI \ /* Faut-il emuler 'STANDARD_OUT' ('VRAI') ou pas ('FAUX') ? */ #define TAILLE_DU_BUFFER_D_EMULATION_DE_STANDARD_IN \ CENT_MILLE \ /* Taille du buffer d'emulation de 'STANDARD_IN'. */ #define TAILLE_DU_BUFFER_D_EMULATION_DE_STANDARD_OUT \ CENT_MILLE \ /* Taille du buffer d'emulation de 'STANDARD_OUT'. */ #define NOM_DE_LA_MACHINE_DISTANTE \ NOM_UNDEF_VIDE \ /* Definition de la machine distante. */ #define NOM_DE_L_UTILISATEUR_DISTANT \ NOM_UNDEF_VIDE #define MOT_DE_PASSE_DE_L_UTILISATEUR_DISTANT \ NOM_UNDEF_VIDE /* Definition de l'utilisateur distant. Ces initialisations forcent donc, en particulier, */ /* l'entree interactive du mot de passe. */ #define COMMANDE_PRELIMINAIRE_A_EXECUTER_A_DISTANCE \ C_VIDE \ /* Definition de la commande preliminaire a executer a distance (par exemple pour mettre */ \ /* en place des variables d'environnement comme '$DISPLAY'...). */ #define COMMANDE_A_EXECUTER_A_DISTANCE \ C_VIDE \ /* Definition de la commande a executer a distance. */ #define EXECUTER_UN_CAT_PRELIMINAIRE \ VRAI \ /* Doit-on executer un '$CA' avant la commande a executer a distance ('VRAI') ou pas */ \ /* ('FAUX'). Ceci permet de lutter contre au moins 2 problemes : */ \ /* */ \ /* 1-si l'on essaye d'executer une unique commande '$CA' a distance, on recupere le */ \ /* message d'erreur : */ \ /* */ \ /* UX:cat: ERROR: Input/output files '-' identical */ \ /* */ \ /* qui peut se comprendre car alors, le '$CA' voit un 'STANDARD_IN' et un 'STANDARD_OUT' */ \ /* identiques (le "stream"...). La solution est donc alors d'executer '$CA | $CA'. */ \ /* */ \ /* 2-dans le cas ou la commande distante est une commande recuperant la valeur de certains */ \ /* de ses arguments via un "pipe" d'entree (par exemple une commande de '$xci'), il y a */ \ /* un test de "pipe" absent qui est fait dans 'v $xiii/files$FON OPEN_READ'. Malheureusement */ \ /* dans le cas d'une execution via '$xcg/remote.01$K' la valeur de 'Fflags(STANDARD_IN)' */ \ /* est 'OPEN_READ_AND_WRITE' (sauf sur 'LACT29" ou l'on recupere 'OUIN(O_RDWR,O_TRUNC)') */ \ /* et non pas le 'OPEN_READ' espere. D'ou encore cette solution... */ /*===================================================================================================================================*/ /*************************************************************************************************************************************/ /* */ /* M A C R O S U T I L E S : */ /* */ /*************************************************************************************************************************************/ #define ENTREE_INTERACTIVE(nom_ou_mot_de_passe,nom_ou_mot_de_passe_pour_l_entree_interactive) \ COND(IFNE_chaine(nom_ou_mot_de_passe,nom_ou_mot_de_passe_pour_l_entree_interactive) \ ,nom_ou_mot_de_passe \ ,ADRESSE_NON_DEFINIE \ ) \ /* Afin de forcer l'entree du nom ou du mot de passe de l'utilisateur... */ #define EMULATION_DE_STANDARD_IN \ Bblock \ Test(IL_FAUT(emuler_STANDARD_IN)) \ Bblock \ DEFV(CHAR,INIT(POINTERc(buffer_d_emulation_de_STANDARD_IN) \ ,kMalo(taille_du_buffer_d_emulation_de_STANDARD_IN) \ ) \ ); \ /* Allocation de la memoire necessaire au buffer d'emulation de 'STANDARD_IN'. */ \ DEFV(Logical,INIT(iterer_sur_le_buffer_d_emulation_de_STANDARD_IN,VRAI)); \ /* Controle du buffer d'emulation du 'STANDARD_IN' distant. */ \ \ CALS(FPrme0("'stdin' de la commande distante :\n")); \ \ Tant(IL_FAUT(iterer_sur_le_buffer_d_emulation_de_STANDARD_IN)) \ Bblock \ DEFV(Int,INIT(longueur_courante_du_buffer_d_emulation_de_STANDARD_IN \ ,Read(STANDARD_IN \ ,buffer_d_emulation_de_STANDARD_IN \ ,taille_du_buffer_d_emulation_de_STANDARD_IN \ ) \ ) \ ); \ /* Recuperation des donnees a transmettre du 'STANDARD_IN' local au 'STANDARD_IN' distant. */ \ \ Test(IZGT(longueur_courante_du_buffer_d_emulation_de_STANDARD_IN)) \ Bblock \ CALS(Writ(stream_de_communication \ ,buffer_d_emulation_de_STANDARD_IN \ ,longueur_courante_du_buffer_d_emulation_de_STANDARD_IN \ ) \ ); \ /* Transfert du 'STANDARD_IN' a distance. */ \ Eblock \ ATes \ Bblock \ EGAL(iterer_sur_le_buffer_d_emulation_de_STANDARD_IN,FAUX); \ Eblock \ ETes \ Eblock \ ETan \ \ CALZ_FreDD(buffer_d_emulation_de_STANDARD_IN); \ /* Liberation de la memoire necessaire au buffer d'emulation de 'STANDARD_IN'. */ \ \ CALS(ShutdownStream(stream_de_communication,ShutdownStream_EMISSION)); \ /* Cet appel est destine a provoquer un "End of File" sur le 'STANDARD_IN' emule. */ \ Eblock \ ATes \ Bblock \ Eblock \ ETes \ Eblock \ /* Emulation du 'STANDARD_IN' distant. */ #define EMULATION_DE_STANDARD_OUT \ Bblock \ Test(IL_FAUT(emuler_STANDARD_OUT)) \ Bblock \ DEFV(CHAR,INIT(POINTERc(buffer_d_emulation_de_STANDARD_OUT) \ ,kMalo(taille_du_buffer_d_emulation_de_STANDARD_OUT) \ ) \ ); \ /* Allocation de la memoire necessaire au buffer d'emulation de 'STANDARD_OUT'. */ \ DEFV(Logical,INIT(iterer_sur_le_buffer_d_emulation_de_STANDARD_OUT,VRAI)); \ /* Controle du buffer d'emulation du 'STANDARD_OUT' distant. */ \ \ Tant(IL_FAUT(iterer_sur_le_buffer_d_emulation_de_STANDARD_OUT)) \ Bblock \ DEFV(Int,INIT(longueur_courante_du_buffer_d_emulation_de_STANDARD_OUT \ ,Read(stream_de_communication \ ,buffer_d_emulation_de_STANDARD_OUT \ ,taille_du_buffer_d_emulation_de_STANDARD_OUT \ ) \ ) \ ); \ /* Recuperation des donnees a transmettre du 'STANDARD_OUT' distant au 'STANDARD_OUT' local. */ \ \ Test(IZGT(longueur_courante_du_buffer_d_emulation_de_STANDARD_OUT)) \ Bblock \ CALS(Writ(STANDARD_OUT \ ,buffer_d_emulation_de_STANDARD_OUT \ ,longueur_courante_du_buffer_d_emulation_de_STANDARD_OUT \ ) \ ); \ /* Et sortie des resultats... */ \ Eblock \ ATes \ Bblock \ EGAL(iterer_sur_le_buffer_d_emulation_de_STANDARD_OUT,FAUX); \ Eblock \ ETes \ Eblock \ ETan \ \ CALZ_FreDD(buffer_d_emulation_de_STANDARD_OUT); \ /* Liberation de la memoire necessaire au buffer d'emulation de 'STANDARD_OUT'. */ \ \ CALS(ShutdownStream(stream_de_communication,ShutdownStream_RECEPTION)); \ /* Par symetrie avec 'STANDARD_IN'... */ \ Eblock \ ATes \ Bblock \ Eblock \ ETes \ Eblock \ /* Emulation du 'STANDARD_OUT' distant. */ #define FERMETURE_D_UN_STREAM(stream,identite) \ Bblock \ Test(PAS_D_ERREUR(Clos(stream))) \ Bblock \ Eblock \ ATes \ Bblock \ PRINT_ERREUR("le 'close(...)' d'un 'stream' s'est mal passe"); \ CAL1(Prer1("il s'agit de '%s'.\n",identite)); \ \ CODE_ERROR(ERREUR25); \ /* Introduit le 20000906101952 pour etre teste dans 'v $Falias_fin_um_pa status'. */ \ Eblock \ ETes \ Eblock \ /* Fermeture d'un stream. */ /*===================================================================================================================================*/ /*************************************************************************************************************************************/ /* */ /* E X E C U T I O N A D I S T A N C E D ' U N E C O M M A N D E : */ /* */ /*************************************************************************************************************************************/ BCommande(nombre_d_arguments,arguments) /*-----------------------------------------------------------------------------------------------------------------------------------*/ Bblock DEFV(Logical,INIT(editer_les_messages_d_avertissement,EDITER_LES_MESSAGES_D_AVERTISSEMENT)); /* Faut-il editer les messages de type 'PRINT_ATTENTION(...)' ('VRAI') ou pas ('FAUX') ? */ DEFV(Logical,INIT(faire_du_parallelisme,FAIRE_DU_PARALLELISME)); /* Faut-il lancer 'EMULATION_DE_STANDARD_IN' et 'EMULATION_DE_STANDARD_OUT' en parallele */ /* ('VRAI') ou en sequentiel ('FAUX') ? */ DEFV(Logical,INIT(faire_de_la_signalisation,FAIRE_DE_LA_SIGNALISATION)); /* Faut-il lancer utiliser le "stream" de signalisation ('VRAI') ou pas ('FAUX') ? */ DEFV(Logical,INIT(emuler_STANDARD_IN,EMULER_STANDARD_IN)); /* Faut-il emuler 'STANDARD_IN' ('VRAI') ou pas ('FAUX') ? Le 20001121092205, cette */ /* option est passee de 'VRAI' a 'FAUX' parce qu'il semble que cela soit la meilleure */ /* chose ('v $Falias_fin_um_pa remote.01.X'). */ DEFV(Logical,INIT(emuler_STANDARD_OUT,EMULER_STANDARD_OUT)); /* Faut-il emuler 'STANDARD_OUT' ('VRAI') ou pas ('FAUX') ? */ DEFV(Positive,INIT(taille_du_buffer_d_emulation_de_STANDARD_IN,TAILLE_DU_BUFFER_D_EMULATION_DE_STANDARD_IN)); /* Taille du buffer d'emulation de 'STANDARD_IN'. */ DEFV(Positive,INIT(taille_du_buffer_d_emulation_de_STANDARD_OUT,TAILLE_DU_BUFFER_D_EMULATION_DE_STANDARD_OUT)); /* Taille du buffer d'emulation de 'STANDARD_OUT'. */ DEFV(CHAR,INIC(POINTERc(nom_de_la_machine_distante),NOM_DE_LA_MACHINE_DISTANTE)); /* Definition de la machine distante. */ DEFV(CHAR,INIC(POINTERc(nom_de_l_utilisateur_distant),NOM_DE_L_UTILISATEUR_DISTANT)); DEFV(CHAR,INIC(POINTERc(mot_de_passe_de_l_utilisateur_distant),MOT_DE_PASSE_DE_L_UTILISATEUR_DISTANT)); /* Definition de l'utilisateur distant. Ces initialisations forcent donc, en particulier, */ /* l'entree interactive du mot de passe. */ DEFV(CHAR,INIC(POINTERc(commande_preliminaire_a_executer_a_distance),COMMANDE_PRELIMINAIRE_A_EXECUTER_A_DISTANCE)); /* Definition de la commande preliminaire a executer a distance (par exemple pour mettre */ /* en place des variables d'environnement comme '$DISPLAY'...). */ DEFV(CHAR,INIC(POINTERc(commande_a_executer_a_distance),COMMANDE_A_EXECUTER_A_DISTANCE)); /* Definition de la commande a executer a distance. */ DEFV(Logical,INIT(executer_un_cat_preliminaire,EXECUTER_UN_CAT_PRELIMINAIRE)); /* Doit-on executer un '$CA' avant la commande a executer a distance ('VRAI') ou pas */ /* ('FAUX'). Ceci permet de lutter contre au moins 2 problemes : */ /* */ /* 1-si l'on essaye d'executer une unique commande '$CA' a distance, on recupere le */ /* message d'erreur : */ /* */ /* UX:cat: ERROR: Input/output files '-' identical */ /* */ /* qui peut se comprendre car alors, le '$CA' voit un 'STANDARD_IN' et un 'STANDARD_OUT' */ /* identiques (le "stream"...). La solution est donc alors d'executer '$CA | $CA'. */ /* */ /* 2-dans le cas ou la commande distante est une commande recuperant la valeur de certains */ /* de ses arguments via un "pipe" d'entree (par exemple une commande de '$xci'), il y a */ /* un test de "pipe" absent qui est fait dans 'v $xiii/files$FON OPEN_READ'. Malheureusement */ /* dans le cas d'une execution via '$xcg/remote.01$K' la valeur de 'Fflags(STANDARD_IN)' */ /* est 'OPEN_READ_AND_WRITE' (sauf sur 'LACT29" ou l'on recupere 'OUIN(O_RDWR,O_TRUNC)') */ /* et non pas le 'OPEN_READ' espere. D'ou encore cette solution... */ DEFV(CHAR,INIT(buffer_de_signalisation,K_UNDEF)); /* Buffer de signalisation (actuellement inutilise...). */ /* buffer de signalisation. Celui est actuellement inutilise, mais on pourrait ecrire, par */ /* exemple : */ /* */ /* EGAL(buffer_de_signalisation,SIGKILL); */ /* CALS(Writ(stream_de_signalisation */ /* ,buffer_de_signalisation */ /* ,SIZE(buffer_de_signalisation) */ /* ) */ /* ); */ /* */ /* pour tuer la commande distante... */ DEFV(RemoteServeur,INIT(POINTERs(caracteristiques_du_serveur_exec_tcp),ADRESSE_NON_ENCORE_DEFINIE)); /* Destine a 'GetServeurByName(...)' pour caracteriser le service demande. */ /*..............................................................................................................................*/ GET_ARGUMENTS_(nombre_d_arguments ,BLOC(GET_ARGUMENT_L("editer=""e=""avertissement=""a=",editer_les_messages_d_avertissement); GET_ARGUMENT_L("parallelisme=""parallele=",faire_du_parallelisme); GET_ARGUMENT_L("signalisation=",faire_de_la_signalisation); GET_ARGUMENT_L("STANDARD_IN=",emuler_STANDARD_IN); GET_ARGUMENT_L("STANDARD_OUT=",emuler_STANDARD_OUT); GET_ARGUMENT_I("buffer_STANDARD_IN=""bIN=",taille_du_buffer_d_emulation_de_STANDARD_IN); GET_ARGUMENT_I("buffer_STANDARD_OUT=""bOUT=",taille_du_buffer_d_emulation_de_STANDARD_OUT); GET_ARGUMENT_C("machine=""m=""host=",nom_de_la_machine_distante); GET_ARGUMENT_C("utilisateur=""user=""login=",nom_de_l_utilisateur_distant); GET_ARGUMENT_C("password=""passwd=""mot_de_passe=",mot_de_passe_de_l_utilisateur_distant); GET_ARGUMENT_C("preliminaire=""p=",commande_preliminaire_a_executer_a_distance); GET_ARGUMENT_C("commande=""c=",commande_a_executer_a_distance); GET_ARGUMENT_L("cat=",executer_un_cat_preliminaire); ) ); Test(IL_FAUT(editer_les_messages_d_avertissement)) Bblock PRINT_ATTENTION("les variables d'environnement ne sont pas disponibles 'v $xcg/remote.01$K shell'"); PRINT_ATTENTION("des valeurs par defaut pour certaines variables d'environnement sont donc forcees"); /* En fait, ne sont forcees par defaut que les variables definies via 'GvarDefaut(...)' */ /* et 'GvalDefaut(...)' dans les differents fichiers '$DEF'. Pour celles qui sont definies */ /* par 'Gvar(...)' et 'Gval(...)', la valeur est "vide"... */ Eblock ATes Bblock Eblock ETes GetServeurByName(caracteristiques_du_serveur_exec_tcp,"exec","tcp"); /* Recherche du code du serveur "exec/tcp". */ Test(IFOU(IZEQ(UNDEF),IZNE(ADRESSE_NON_DEFINIE))) /* Afin de valider l'utilisation qui est faite de 'UNDEF' et de 'ADRESSE_NON_DEFINIE'... */ Bblock PRINT_ERREUR("l'utilisation des procedures de type 'RemoteCommande(...)' est incorrecte"); Eblock ATes Bblock Eblock ETes #ifndef BUG_SYSTEME_rexec_login_passwd_interactif Test(IZNE(caracteristiques_du_serveur_exec_tcp)) #Aifndef BUG_SYSTEME_rexec_login_passwd_interactif Test(IFET(IZNE(caracteristiques_du_serveur_exec_tcp) ,IFET(IFNE_chaine(nom_de_l_utilisateur_distant,NOM_DE_L_UTILISATEUR_DISTANT) ,IFNE_chaine(mot_de_passe_de_l_utilisateur_distant,MOT_DE_PASSE_DE_L_UTILISATEUR_DISTANT) ) ) ) #Eifndef BUG_SYSTEME_rexec_login_passwd_interactif Bblock DEFV(vrai_Int_de_base,INIT(stream_de_signalisation,COND(IL_FAUT(faire_de_la_signalisation),UNDEF,ADRESSE_NON_DEFINIE))); DEFV(vrai_Int_de_base,INIT(stream_de_communication,UNDEF)); /* Definition des deux "stream"s. */ CALS(RemoteCommande(stream_de_communication ,nom_de_la_machine_distante ,ASI1(caracteristiques_du_serveur_exec_tcp,s_port) ,ENTREE_INTERACTIVE(nom_de_l_utilisateur_distant,NOM_DE_L_UTILISATEUR_DISTANT) ,ENTREE_INTERACTIVE(mot_de_passe_de_l_utilisateur_distant,MOT_DE_PASSE_DE_L_UTILISATEUR_DISTANT) ,chain_Aconcaten3(commande_preliminaire_a_executer_a_distance ,COND(IFNE_chaine(commande_preliminaire_a_executer_a_distance,C_VIDE) ," ; " ,C_VIDE ) ,COND(IL_FAUT(executer_un_cat_preliminaire) ,chain_Aconcaten3(GvarDefaut("CA","cat") ," | " ,commande_a_executer_a_distance ) ,commande_a_executer_a_distance ) ) ,stream_de_signalisation ) ); /* Tentative d'etablissement de la liaison bidirectionnelle. On notera l'usage de */ /* 'ENTREE_INTERACTIVE(...)' car, en effet, il n'est pas possible d'initialiser les */ /* chaines 'nom_de_l_utilisateur_distant' et 'mot_de_passe_de_l_utilisateur_distant' */ /* avec 'ADRESSE_NON_ENCORE_DEFINIE', au retour de 'GET_ARGUMENT_C(...)' cette valeur */ /* etant ecrasee par 'C_VIDE'... */ Test(IZGT(stream_de_communication)) Bblock Test(IL_FAUT(faire_du_parallelisme)) Bblock /* Cas parallele ('EMULATION_DE_STANDARD_IN' et 'EMULATION_DE_STANDARD_OUT' en parallele) : */ DEFV(processus,processus_STANDARD_IN); /* Identificateur du processus fils d'emulation du 'STANDARD_IN' distant. On notera que */ /* j'ai d'abord utilise le symbole : */ /* */ /* identificateur_du_processus_d_emulation_de_STANDARD_IN */ /* */ /* puis : */ /* */ /* processus_d_emulation_de_STANDARD_IN */ /* */ /* mais malheureusement, l'expansion de l'un des 'Test(...)' de 'iPARALLELE(...)' donnait */ /* une ligne trop longue pour '$SE' et non decoupable par '$xcp/decoupage$K'... */ iPARALLELE(BLOC(Bblock /* Processus d'emission pour emuler 'STANDARD_IN' distant : */ EMULATION_DE_STANDARD_IN; Eblock ) ,processus_STANDARD_IN ); /* Processus de reception pour emuler 'STANDARD_OUT' distant : */ EMULATION_DE_STANDARD_OUT; Eblock ATes Bblock /* Cas sequentiel ('EMULATION_DE_STANDARD_IN' puis 'EMULATION_DE_STANDARD_OUT') : */ EMULATION_DE_STANDARD_IN; EMULATION_DE_STANDARD_OUT; Eblock ETes FERMETURE_D_UN_STREAM(stream_de_communication,"COMMUNICATION"); Test(IL_FAUT(faire_de_la_signalisation)) Bblock FERMETURE_D_UN_STREAM(stream_de_signalisation,"SIGNALISATION"); Eblock ATes Bblock Eblock ETes Eblock ATes Bblock PRINT_ERREUR("la communication n'a pu s'etablir"); CODE_ERROR(ERREUR25); /* Introduit le 20000906101952 pour etre teste dans 'v $Falias_fin_um_pa status'. */ Eblock ETes Eblock ATes Bblock PRINT_ERREUR("le service 'exec/tcp' n'existe pas"); #ifndef BUG_SYSTEME_rexec_login_passwd_interactif #Aifndef BUG_SYSTEME_rexec_login_passwd_interactif PRINT_ERREUR("ou bien il s'agit d'un SYSTEME ou 'login' et 'passwd' doivent etre donnes en argument de la commande"); #Eifndef BUG_SYSTEME_rexec_login_passwd_interactif CODE_ERROR(ERREUR25); /* Introduit le 20000906101952 pour etre teste dans 'v $Falias_fin_um_pa status'. */ Eblock ETes RETU_Commande; Eblock ECommande