/*************************************************************************************************************************************/
/*                                                                                                                                   */
/*        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



Copyright © Jean-François COLONNA, 2019-2024.
Copyright © CMAP (Centre de Mathématiques APpliquées) UMR CNRS 7641 / École polytechnique, Institut Polytechnique de Paris, 2019-2024.