home *** CD-ROM | disk | FTP | other *** search
/ PC World Komputer 1995 November / PCWK1195.iso / esker / emul.1 / EMUL.ARC / RTUNPLUS.C < prev    next >
Text File  |  1992-09-25  |  28KB  |  1,109 lines

  1. /*------------------------------------------------------------------------------
  2.     rtunplus.c    Version 6.00
  3. ------------------------------------------------------------------------------*/
  4. #define    NO        0
  5. #define    YES        1
  6. #define    DIRECT        0
  7. #define DIRECTPTR    1
  8. #define    DIRENT        3
  9.  
  10. #ifdef    SYSIII
  11. #define    USE_OPENDIR    NO
  12. #define    DIRSTRUCT    DIRECT
  13. #define    DIR_H    <sys/dir.h>
  14. #else
  15.  
  16. #ifdef    XENIX
  17. #define    USE_OPENDIR    YES
  18. #define    DIRSTRUCT    DIRECTPTR
  19. #define    DIR_H    <sys/ndir.h>
  20. #else
  21.  
  22. #ifdef    SYSV
  23. #define    USE_OPENDIR    NO
  24. #define    DIRSTRUCT    DIRECT
  25. #define    DIR_H    <sys/dir.h>
  26. #else
  27.  
  28. #ifdef    LSX
  29. #define    USE_OPENDIR    YES
  30. #define    DIRSTRUCT    DIRECTPTR
  31. #define    DIR_H    <sys/dir.h>
  32. #else
  33.  
  34. #define    USE_OPENDIR    YES
  35. #define    DIRSTRUCT    DIRENT
  36. #define    DIR_H    <dirent.h>
  37. #endif
  38. #endif
  39. #endif
  40. #endif
  41.  
  42. #include <stdio.h>
  43. #include <ctype.h>
  44. #include <sys/types.h>
  45. #ifdef    SYSIII
  46. #define    O_RDONLY 0
  47. #define    O_WRONLY 1
  48. #include <sgtty.h>
  49. #else
  50. #include <fcntl.h>
  51. #include <string.h>
  52. #include <termio.h>
  53. #endif
  54. #include <signal.h>
  55. #include <sys/stat.h>
  56.  
  57. #include DIR_H
  58.  
  59. #ifdef SYSIII
  60. char    *strchr(s,car)
  61. char    *s,car;
  62.  
  63. {    for(;*s;s++)    if(*s == car)    return(s);
  64.     if(car == '\0')    return(s);
  65.     return((char*)0);
  66. }
  67.  
  68. char    *strrchr(s,car)
  69. char    *s,car;
  70.  
  71. {    char    *p;
  72.  
  73.     for(p=s;*p;p++);
  74.     for(p;p!=s;p--)    if(*p == car)    return(p);
  75.     return((char*)0);
  76. }
  77. #endif
  78.  
  79. #define    maxtrame        SZTRAME+4
  80. #define    MAXDATA        0x7e
  81. #define    MAXTRAME        MAXDATA+4
  82. #define    XOR        SZTRAME
  83. #define    LONG        SZTRAME+2
  84. #define    flag_transc    MAXDATA
  85. #define    in_ascii(a)    ((0x20<=a)&&(a<flag_transc))
  86.  
  87. unsigned char    SZTRAME=MAXDATA;
  88.  
  89. #define    STX    002
  90. #define    ETX    003
  91. #define    ACK    006
  92. #define    NAK    025
  93. #define    EOT    004
  94. #define    ESC    033
  95.  
  96. #define    push_path(a)    pile_path[i_pile_path++]=a
  97. #define    push_pf(a)    pile_pf[i_pile_pf++]=a;
  98. #define    pop_path()    pile_path[--i_pile_path]
  99. #define    pop_pf()    pile_pf[--i_pile_pf]
  100. #define    fin_dir()    (i_pile_path==0)
  101.  
  102. #if(USE_OPENDIR == YES)
  103. DIR    *pile_pf[200] ;
  104. #else
  105. static    int    pile_pf[200];
  106. #endif
  107.  
  108. static    char    *pile_path[200];
  109. static    int    i_pile_path=0;
  110. static    int    i_pile_pf=0;
  111. static    int    dir_flag = -1;
  112. #if(USE_OPENDIR == YES)
  113. DIR    *pf_cour ;
  114. #else
  115. static    int    pf_cour;
  116. #endif
  117. static    char    *path_cour;
  118. static    char    masq_cour[80];
  119.  
  120. static    char    TMOUT[]    ={"\002\007\003"};
  121. static    char    OK[]    ={"\002\006\003"};
  122. static    char    NONOK[]    ={"\002\025\003"};
  123. static    char    FIN[]    ={"\002\004\003"};
  124. static    char    INTER[] ={"\002\033\003"};
  125. static    int    INTERRUPT;
  126. static    unsigned    int    TIME_OUT;
  127.  
  128. extern    char    *malloc();
  129. extern    void    free();
  130. extern    unsigned int    alarm();
  131. extern  long    lseek();
  132.  
  133. #define    DEBUG    0
  134. #define    DBG(f,v)    if(DEBUG) fprintf(stderr,f,v)
  135.  
  136. /*------------------------------hexabin----------------------------------
  137. Convertion hexa --> binaire
  138. -------------------------------------------------------------------------*/
  139. unsigned char    hexabin(car)
  140. unsigned char    car;
  141. {    if(isdigit(car))    car -= '0';
  142.     else            car -= 'a'- 10;
  143.     return(car);
  144. }
  145.  
  146. /*------------------------------isrepert--------------------------------------
  147.     tester si path est un repertoire
  148.     renvoi    1 si c'en est un
  149.         0 sinon
  150. ----------------------------------------------------------------------------*/
  151. isrepert(path)
  152. char    *path;
  153. {    struct    stat    status;
  154.  
  155.     if(stat(path,&status)==-1)    return(0);
  156.     if((status.st_mode&S_IFMT)!=S_IFDIR)    return(0);
  157.     return(1);
  158. }
  159.  
  160. /*------------------------------decompose-------------------------------------
  161.         decomposerle chemin d'acces et le nom de fichier
  162.             path    : path a decomposer
  163.     au retour    chemin    : chemin d'acces termine par /
  164.             fic    : nom de fichier
  165.     renvoi        0  si path est un repertoire
  166.             1  si path designe un fichier
  167.             2  si fic est un nouveau nom
  168.             -1 sinon
  169. ----------------------------------------------------------------------------*/
  170. decompose(path,chemin,fic)
  171. char    *path,*chemin,*fic;
  172. {       char    *p;
  173.     struct    stat    status;
  174.  
  175.     strcpy(chemin,"./");
  176.     *fic='\0';
  177.     if(path==NULL)    return(0);
  178.     if(*path=='\0')    return(0);
  179.     if(isrepert(path))
  180.     {    strcpy(chemin,path);
  181.         if(path[strlen(path)-1]!='/')    strcat(chemin,"/");
  182.         return(0);
  183.     }
  184.     if((p=strrchr(path,'/'))==NULL)    strcpy(fic,path);
  185.     else
  186.     {    strcpy(fic,++p);
  187.         *p='\0';
  188.         strcpy(chemin,path);
  189.         if(!isrepert(chemin))    return(-1);
  190.     }
  191.         if(stat(path,&status)==-1)    return(2);
  192.     return(1);
  193. }
  194.  
  195. /*-----------------------------findsdir---------------------------------------
  196.     chercher le prochain sous repertoire du repertoire pere
  197.     a l'appel    pf    : l'entree repertoire ouvert
  198.             pere    : nom du repertoire
  199.     renvoi        NULL s'il n'y en a pas
  200.                         nom de sous repertoire trouve sinon
  201. ----------------------------------------------------------------------------*/
  202. static    char    *findsdir(pf,pere)
  203. #if(USE_OPENDIR == YES)
  204. DIR    *pf;
  205. #else
  206. int    pf;
  207. #endif
  208. char    *pere;
  209. {    char    path[256],buf[256],*p;
  210.     struct    stat    status;
  211.  
  212. #if(DIRSTRUCT == DIRENT)
  213.     struct    dirent    *B;
  214. #else
  215. #if(DIRSTRUCT == DIRECTPTR)
  216.     struct    direct    *B;
  217. #else
  218. #if(DIRSTRUCT == DIRECT)
  219.     struct    direct    B;
  220. #endif
  221. #endif
  222. #endif
  223.  
  224. #if(USE_OPENDIR == YES)
  225.     while (B=readdir(pf))
  226.     {    if(B->d_ino==0)    continue;
  227.         strcpy(buf,B->d_name);
  228. #else
  229.     buf[DIRSIZ] = '\0';
  230.     while(read(pf,&B,sizeof(B)))
  231.     {    if(B.d_ino==0)    continue;
  232.         strncpy(buf,B.d_name,DIRSIZ);
  233. #endif
  234.         if(!strcmp(buf,"."))    continue;
  235.         if(!strcmp(buf,".."))    continue;
  236.         sprintf(path,"%s%s",pere,buf);
  237.         if(stat(path,&status)==-1)    continue;
  238.         if((status.st_mode&S_IFMT)!=S_IFDIR)    continue;
  239.         if((p=malloc((unsigned)strlen(path)+2))==NULL)    return(NULL);
  240.         sprintf(p,"%s/",path);
  241.         return(p);
  242.     }
  243.     return(NULL);
  244. }
  245.  
  246. /*------------------------------firstdir--------------------------------------
  247.         initialiser l'environnement de recherche de sous repertoires
  248.     a l'appel    dir  = repertoire termine par /
  249.             flag = 0 recherche recurssive des sous repertoires
  250.                  > 0 sans recherche de sous repertoire
  251.     renvoi    NULL si dir n'est pas un repertoire ou
  252.              si autorisation de consultation n'est pas permise
  253.         nom du repertoire
  254. ----------------------------------------------------------------------------*/
  255. char    *firstdir(dir,flag)
  256. char    *dir,flag;
  257. {
  258.     enddir();
  259.     if(!isrepert(dir))    return(NULL);
  260.     if(access(dir,05)==-1)    return(NULL);
  261. #if(USE_OPENDIR == YES)
  262.     if(!(pf_cour=opendir(dir)))    return(NULL) ;
  263. #else
  264.     if((pf_cour=open(dir,O_RDONLY))==-1)    return(NULL);
  265. #endif
  266.     if((path_cour=malloc((unsigned)strlen(dir)+1))==NULL)    return(NULL);
  267.     strcpy(path_cour,dir);
  268.     i_pile_pf=0;
  269.     i_pile_path=0;
  270.     dir_flag=flag;
  271.     return(path_cour);
  272. }
  273.  
  274. /*------------------------------nextdir---------------------------------------
  275.         chercher le prochain sous repertoire
  276.     renvoi    NULL s'il n'y en a plus ou
  277.              si le recherche n'est pas autorisee
  278.         nom du sous repertoire trouve
  279. ----------------------------------------------------------------------------*/
  280. char    *nextdir()
  281. {    char    *dir;
  282. #if(USE_OPENDIR == YES)
  283.     DIR    *pf ;
  284. #else
  285.     int    pf;
  286. #endif
  287.  
  288.     if(dir_flag>0)    free(path_cour);
  289.     if(dir_flag!=0)    return(NULL);
  290.     while((dir=findsdir(pf_cour,path_cour))!=NULL)
  291.     {       if(access(dir,05)==-1)    continue;
  292. #if(USE_OPENDIR == YES)
  293.         if(!(pf=opendir(dir)))    continue ;
  294. #else
  295.         if((pf=open(dir,O_RDONLY))==-1)    continue;
  296. #endif
  297.         push_path(path_cour);
  298.         push_pf(pf_cour);
  299.             path_cour=dir;
  300.         pf_cour=pf;
  301.         return(dir);
  302.     }
  303. #if(USE_OPENDIR == YES)
  304.     closedir(pf_cour) ;
  305. #else
  306.     close(pf_cour);
  307. #endif
  308.     free(path_cour);
  309.     if(fin_dir())
  310.     {    dir_flag = -1;
  311.         return(NULL);
  312.     }
  313.     pf_cour=pop_pf();
  314.     path_cour=pop_path();
  315.     return(nextdir());
  316. }
  317.  
  318. /*------------------------------enddir----------------------------------------
  319.         terminer le recherche de sous repertoire si l'on ne desire pas
  320.     aller jusqu'au bout
  321. ----------------------------------------------------------------------------*/
  322. enddir()
  323. {       while(!fin_dir())
  324.     {
  325. #if(USE_OPENDIR == YES)
  326.         closedir(pop_pf()) ;
  327. #else
  328.         close(pop_pf());
  329. #endif
  330.         free(pop_path());
  331.     }
  332.     dir_flag = -1;
  333. }
  334.  
  335. /*------------------------------nextfic---------------------------------------
  336.     chercher le prochain fichier
  337.     au retour    name    : nom du fichier trouve
  338.     renvoi        -1 s'il n'y en a plus
  339.             taille du fichier en octet sinon
  340. ----------------------------------------------------------------------------*/
  341. long    nextfic(name)
  342. char    *name;
  343. {    struct    stat    status;
  344.     char    path[256],buf[256];
  345.  
  346. #if(DIRSTRUCT == DIRENT)
  347.     struct    dirent    *B;
  348. #else
  349. #if(DIRSTRUCT == DIRECTPTR)
  350.     struct    direct    *B;
  351. #else
  352. #if(DIRSTRUCT == DIRECT)
  353.     struct    direct    B;
  354. #endif
  355. #endif
  356. #endif
  357.  
  358.     if(dir_flag==-1)    return(-1);
  359. #if(USE_OPENDIR == YES)
  360.     while(B=readdir(pf_cour))
  361.     {    if(B->d_ino==0)    continue;
  362.         strcpy(buf,B->d_name);
  363. #else
  364.  
  365.     buf[DIRSIZ] = '\0';
  366.     while(read(pf_cour,&B,sizeof(B))==sizeof(B))
  367.     {    if(B.d_ino==0)    continue;
  368.         strncpy(buf,B.d_name,DIRSIZ);
  369. #endif
  370.         sprintf(path,"%s%s",path_cour,buf);
  371.         if(stat(path,&status)==-1)    continue;
  372.         if((status.st_mode&S_IFMT)!=S_IFREG)    continue;
  373.         if(masque(buf,masq_cour))
  374.         {    strcpy(name,buf);
  375.             return(status.st_size);
  376.         }
  377.     }
  378. #if(USE_OPENDIR == YES)
  379.     rewinddir(pf_cour) ;
  380. #else
  381.     lseek(pf_cour,0L,0);
  382. #endif
  383.     return(-1);
  384. }
  385.  
  386. /*------------------------------firstfic--------------------------------------
  387.     chercher le premier fichier (firstdir ou nextdir a ete appelle)
  388.     a l'appel    masq    : caracteres generiques
  389.     au retour    name    : nom du fichier trouve
  390.     renvoi        -1 s'il n'y en a pas
  391.             taille du fichier en octet sinon
  392. ----------------------------------------------------------------------------*/
  393. long    firstfic(masq,name)
  394. char    *masq,*name;
  395. {    if(dir_flag==-1)    return(-1);
  396.     strcpy(masq_cour,masq);
  397. #if(USE_OPENDIR == YES)
  398.     rewinddir(pf_cour) ;
  399. #else
  400.     lseek(pf_cour,0L,0);
  401. #endif
  402.     return(nextfic(name));
  403. }
  404.  
  405. /*------------------------------masque----------------------------------------
  406.     renvoi    1 si chaine conforme aux carracteres generiques forme
  407.         0 sinon
  408. ----------------------------------------------------------------------------*/
  409. masque(chaine,forme)
  410. char    *chaine,*forme;
  411. {    int    i=0,j=0;
  412.  
  413.     while((i<strlen(chaine))&&(j<strlen(forme)))
  414.     {    if(forme[j]=='*')
  415.         {    if(++j>=strlen(forme))    return(1);
  416.             for(;i<strlen(chaine);i++)
  417.             {    if(masque(&chaine[i],&forme[j])) return(1);
  418.             }
  419.             return(0);
  420.         }
  421.         if((chaine[i]!=forme[j])&&('?'!=forme[j]))    return(0);
  422.         i++;    j++;
  423.     }
  424.     if(j==strlen(forme))
  425.     {    if(i>=strlen(chaine))    return(1);
  426.         else    return(0);
  427.     }
  428.     else
  429.     {    for(;j<strlen(forme);j++)
  430.         {    if(forme[j]!='*')    return(0);
  431.         }
  432.         return(1);
  433.     }
  434. }
  435.  
  436. /*------------------------------ignorer---------------------------------------
  437.     tester si nom contien un masque
  438.     renvoi    1 si nom contien un masque ou est une chaine vide ou NULL
  439.         0 sinon
  440. ----------------------------------------------------------------------------*/
  441. ignorer(nom)
  442. char    *nom;
  443. {    if(nom==NULL)            return(1);
  444.     if(*nom=='\0')            return(1);
  445.     if(strrchr(nom,'?')!=NULL)    return(1);
  446.     if(strrchr(nom,'*')!=NULL)    return(1);
  447.     return(0);
  448. }
  449.  
  450. /*------------------------------converpath------------------------------------
  451.     convertir DOS path notation en UNIX notation
  452. ----------------------------------------------------------------------------*/
  453. converpath(path)
  454. char    *path;
  455. {    char    *p;
  456.  
  457.     while((p=strchr(path,'\\'))!=NULL)    *p='/';
  458. }
  459.  
  460. /*------------------------------creatdir--------------------------------------
  461.     creer repetoire dir
  462.     renvoi    1 si creation reussite
  463.         0 sinon
  464. ----------------------------------------------------------------------------*/
  465. creatdir(dir)
  466. char    *dir;
  467. {    char    ref[80],pere[80],*pt;
  468.  
  469. #ifdef    SYSIII
  470.     sprintf(ref,"mkdir %s",dir);
  471.     return(!system(ref));
  472. #else
  473. #ifndef XENIX
  474.     return(!mkdir(dir,0777)) ;
  475. #else
  476.     pt=strrchr(dir,'/');
  477.     if(!pt)    strcpy(pere,".");
  478.     else
  479.     {    if(pt==dir)    strcpy(pere,"/");
  480.         else
  481.         {    strncpy(pere,dir,pt-dir);
  482.             pere[pt-dir]='\0';
  483.         }
  484.     }
  485.     if(access(pere,03))
  486.     {    DBG("Acces interdit a %s\n",pere);
  487.         return(0);
  488.     }
  489.     if(mknod(dir,S_IFDIR+0777,0))
  490.     {    DBG("Creation %s impossible\n",dir);
  491.         return(0);
  492.     }
  493.     if(chown(dir,getuid(),getgid()))
  494.     {    unlink(dir);
  495.         DBG("Chgt de proprietaire impossible\n","");
  496.         return(0);
  497.     }
  498.     sprintf(ref,"%s/.",dir);
  499.     if(link(dir,ref))
  500.     {    unlink(dir);
  501.         DBG("Creation du lien . impossible\n","");
  502.         return(0);
  503.     }
  504.     sprintf(ref,"%s/..",dir);
  505.     if(link(pere,ref))
  506.     {    sprintf(ref,"%s/.",dir);
  507.         unlink(ref);
  508.         unlink(dir);
  509.         DBG("Creation du lien .. impossible\n","");
  510.         return(0);
  511.     }
  512.     return(1);
  513. #endif
  514. #endif
  515. }
  516.  
  517. /*------------------------------RTUNPLUS----------------------------------------
  518.         Usage     : RTUNPLUS [temps_alarme]
  519.     Fonction : transfert de fichiers
  520.            execution de commandes UNIX
  521.  
  522. ----------------------------------------------------------------------------*/
  523. main(argc,argv)
  524. int    argc;
  525. char    **argv;
  526. {    unsigned char    buf[60];
  527.     int    ret=0;
  528.  
  529.     TIME_OUT= argc>1 ? atoi(argv[1]) : 10;
  530.     DBG("Lancement de RTUNPLUS %d\n",TIME_OUT);
  531.     ini_las();
  532.     INTERRUPT=0;
  533.     if(!lire_action(2,buf,1))
  534.     {    fin_las();
  535.         DBG("erreur de transmission 1\n","");
  536.         exit(1);
  537.     }
  538.     if(buf[0]!=STX)
  539.     {    fin_las();
  540.         DBG("erreur de trame\n","");
  541.         exit(2);
  542.     }
  543.         if(!lire_action(1,buf,0))
  544.         {    fin_las();
  545.         DBG("erreur de transmission 2\n","");
  546.         exit(3);
  547.     }
  548.     if(buf[0]=='E')
  549.     {    DBG("Emission %s\n",&buf[2]);
  550.         DBG("Transcodage %c\n",buf[1]);
  551.         ret=strlen((char *)buf)+1;
  552.         if(buf[ret]=='t')
  553.             SZTRAME=(hexabin(buf[ret+1])<<4)+hexabin(buf[ret+2]);
  554.         DBG("Trame %d\n",SZTRAME);
  555.         ret=emission((char *)&buf[2],(char )buf[1]);
  556.     }
  557.     else if(buf[0]=='R')
  558.     {    DBG("Reception %s\n",&buf[2]);
  559.         DBG("Transcodage %c\n",buf[1]);
  560.         ret=strlen((char *)buf)+1;
  561.         if(buf[ret]=='t')
  562.             SZTRAME=(hexabin(buf[ret+1])<<4)+hexabin(buf[ret+2]);
  563.         DBG("Trame %d\n",SZTRAME);
  564.         ret=reception((char *)&buf[2],(char )buf[1]);
  565.     }
  566.     else if(buf[0]=='X')
  567.     {    DBG("Execution %s\n",&buf[1]);
  568.         ret=execution((char *)&buf[1]);
  569.     }
  570.     else if(buf[0]=='T')
  571.     {    DBG("Test rlogin\n","");
  572.         ret=1;
  573.     }
  574.     else
  575.     {    DBG("commande inconnue [%s]\n",buf);
  576.     }
  577.     if(ret)
  578.     {    DBG("RTUNPLUS termine ...\n","");
  579.     }
  580.     else    DBG("RTUNPLUS echoue ...\n","");
  581.     fin_las();
  582.     return(!ret);
  583. }
  584.  
  585. /*------------------------------emission--------------------------------------
  586.     emission de fichiers
  587.         renvoi    : 1 si emission reussite
  588.           0 sinon
  589. ----------------------------------------------------------------------------*/
  590. emission(nom,trcode)
  591. char    *nom,trcode;
  592. {    int    p,i,j,flag,l_racine;
  593.     long    l;
  594.     char    chemin[80],buf[80],fic[80],masq[80],*dir;
  595.  
  596.     if((flag=decompose(nom,chemin,masq))==-1)
  597.     {    DBG("Chemin d'acces %s incorrect !",chemin);
  598.         write(1,NONOK,3);
  599.         return(0);
  600.     }
  601.     if((dir=firstdir(chemin,flag))==NULL)
  602.     {    DBG("Consultation de %s n'es pas permise !\n",chemin);
  603.         write(1,NONOK,3);
  604.         return(0);
  605.     }
  606.     if(*masq=='\0')    strcpy(masq,"*");
  607.         if((flag==2)&&((l=firstfic(masq,fic))==-1))
  608.     {    DBG("Fichier source %s non trouve !\n",masq);
  609.         write(1,NONOK,3);
  610.         enddir();
  611.         return(0);
  612.     }
  613.     if(!ecr_action((unsigned char *)&OK[1],1))
  614.     {    enddir();
  615.         DBG("Pas de reponse\n","");
  616.         return(0);
  617.     }
  618.     l_racine=strlen(dir);
  619.     do
  620.     {       if((l=firstfic(masq,fic))!=-1)
  621.         do
  622.         {       sprintf(buf,"%s%s",dir,fic);
  623.             if(access(buf,04)==-1)
  624.             {    DBG("Ouverture de fichier source %s non autorisee !\n",buf);
  625.                 if(!ecr_action((unsigned char *)&NONOK[1],1))
  626.                 {    enddir();
  627.                     return(0);
  628.                 }
  629.                 continue;
  630.             }
  631.             if((p=open(buf,O_RDONLY))==-1)
  632.             {    DBG("Ouverture de fichier source %s impossible !\n",buf);
  633.                 if(!ecr_action((unsigned char *)&NONOK[1],1))
  634.                 {    enddir();
  635.                     return(0);
  636.                 }
  637.                 continue;
  638.             }
  639.             i=strlen(fic)+1;
  640.             sprintf(buf,"F%s %ld",fic,l);
  641.             j=strlen(buf);
  642.             buf[i]='\0';
  643.             if(!ecr_action((unsigned char *)buf,j))
  644.             {    close(p);
  645.                 DBG("Ouverture de fichier destination %s impossible !\n",fic);
  646.                 if(INTERRUPT)
  647.                 {    enddir();
  648.                     return(0);
  649.                 }
  650.                 continue;
  651.             }
  652.             DBG("Emission de %s en cours ...\n",fic);
  653.             if(!sortie_fic(p,trcode))
  654.             {    DBG("Erreur de transmission !\n","");
  655.             }
  656.             else    DBG("Emission de %s termine\n",fic);
  657.             close(p);
  658.                 }while(((l=nextfic(fic))!=-1)&&(!INTERRUPT));
  659.         while(((dir=nextdir())!=NULL)&&(!INTERRUPT))
  660.         {    sprintf(buf,"D%s",&dir[l_racine]);
  661.                         if(!ecr_action((unsigned char *)buf,strlen(buf)))
  662.             {    DBG("Creation de repertoire DOS %s refusee !\n",buf);
  663.             }
  664.             else
  665.             {    DBG("Creation de repertoire DOS %s\n",buf);
  666.                 break;
  667.             }
  668.         }
  669.     }while((dir!=NULL)&&(!INTERRUPT));
  670.     if(!INTERRUPT)
  671.     {    write(1,FIN,3);
  672.         return(1);
  673.     }
  674.     enddir();
  675.     return(0);
  676. }
  677.  
  678. /*------------------------------reception-------------------------------------
  679.     reception de fichiers
  680.         renvoi    : 1 si reception reussite
  681.           0 sinon
  682. ----------------------------------------------------------------------------*/
  683. reception(nom,trcode)
  684. char    *nom,trcode;
  685. {    char    buf[80],chemin[80],fic[80],fich[30],pere[80];
  686.     int    p,ignor;
  687.  
  688.     converpath(nom);
  689.     if(decompose(nom,pere,fich)==-1)
  690.     {    DBG("Chemin d'acces %s incorrect !",chemin);
  691.         write(1,NONOK,3);
  692.         return(0);
  693.     }
  694.     ignor=ignorer(fich);
  695.     strcpy(chemin,pere);
  696.     if(!lire_action(1,(unsigned char *)fic,0))    return(0);
  697.     while((fic[0]!=EOT)&&(!INTERRUPT))
  698.     {       if(fic[0]=='D')
  699.         {       converpath(&fic[1]);
  700.             sprintf(chemin,"%s%s",pere,&fic[1]);
  701.             if(!isrepert(chemin))
  702.             {       strcpy(buf,chemin);
  703.                 buf[strlen(buf)-1]='\0';
  704.                 if(!creatdir(buf))
  705.                 {    DBG("Creation du repertoire %s refusee!\n",chemin);
  706.                     lire_action(0,(unsigned char *)fic,0);
  707.                     continue;
  708.                 }
  709.                 DBG("Creation du repertoire %s\n",chemin);
  710.             }
  711.             lire_action(1,(unsigned char *)fic,0);
  712.             continue;
  713.         }
  714.         if(fic[0]!='F')
  715.         {    DBG("Nom de fichier destination non recu!\n","");
  716.             if(!lire_action(0,(unsigned char *)fic,0))
  717.                 return(0);
  718.             continue;
  719.         }
  720.         strcpy(buf,chemin);
  721.         if(ignor)    strcat(buf,&fic[1]);
  722.         else        strcat(buf,fich);
  723.         if(access(buf,0)==-1)
  724.              {       if(access(chemin,03)==-1)
  725.             {    DBG("Creation de fichier destination %s impossible !\n",buf);
  726.                 if(!lire_action(0,(unsigned char *)fic,0))    
  727.                     return(0);
  728.                 continue;
  729.             }
  730. #ifdef    SYSIII
  731.             if((p=creat(buf,0777))==-1)
  732. #else
  733.             if((p=open(buf,O_WRONLY|O_CREAT,0777))==-1)
  734. #endif
  735.             {    DBG("Creation de fichier destination %s impossible !\n",buf);
  736.                 if(!lire_action(0,(unsigned char *)fic,0))
  737.                     return(0);
  738.                 continue;
  739.             }
  740.         }
  741.         else
  742.         {    if(access(buf,04)==-1)
  743.             {    DBG("Ouverture de fichier destination %s impossible !\n",buf);
  744.                 if(!lire_action(0,(unsigned char *)fic,0))
  745.                     return(0);
  746.                 continue;
  747.             }
  748. #ifdef    SYSIII
  749.             unlink(buf);
  750.             if((p=creat(buf,0777))==-1)
  751. #else
  752.  
  753.                  if((p=open(buf,O_WRONLY|O_TRUNC))==-1)
  754. #endif
  755.             {    DBG("Ouverture de fichier destination %s impossible !\n",buf);
  756.                 if(!lire_action(0,(unsigned char *)fic,0))
  757.                     return(0);
  758.                 continue;
  759.             }
  760.         }
  761.         DBG("Reception de %s en cours ...\n",buf);
  762.         if(!entree_fic(p,trcode))
  763.         {    DBG("Erreur de transmission !\n","");
  764.         }
  765.         else    DBG("Reception de %s terminee\n",buf);
  766.         close(p);
  767.         chown(buf,getuid(),getgid());
  768.         if(INTERRUPT)    return(0);
  769.         if(!lire_action(1,(unsigned char *)fic,0))    return(0);
  770.     }
  771.     return(1);
  772. }
  773.  
  774. /*------------------------------execution-------------------------------------
  775.     execution de commande UNIX
  776.         renvoi    : 1 si reception reussite
  777.           0 sinon
  778. ----------------------------------------------------------------------------*/
  779. execution(cmd)
  780. char    *cmd;
  781. {    char    fin[20],i=0;
  782.  
  783.     if(!lire_action(1,(unsigned char *)fin,0))    return(0);
  784.     fin_las();
  785.     strcat(cmd,"\n");
  786.     write(1,cmd,(unsigned )strlen(cmd));
  787.     system(cmd);
  788.     write(1,&i,1);
  789.     ini_las();
  790.     write(1,fin,(unsigned )strlen(fin));
  791.     return(1);
  792. }
  793.  
  794. /*------------------------------sortie_fic------------------------------------
  795.     emettre un fichier vers le port serie
  796.         p    : pointeur du fichier a emettre
  797.         trcode    : 1 si avec transcodage
  798.               0 sinon
  799.     renvoi    1 si emission reussite
  800.         0 sinon
  801. ----------------------------------------------------------------------------*/
  802. sortie_fic(p,trcode)
  803. int    p,trcode;
  804. {    unsigned char    sz,c[MAXTRAME];
  805.     unsigned char    formertrame();
  806.  
  807.     do
  808.     {    sz=formertrame(p,c,SZTRAME,trcode);
  809.         if(!ecr_trame(c))    return(0);
  810.     }while(sz==SZTRAME);
  811.     return(1);
  812. }
  813.  
  814. /*------------------------------entree_fic------------------------------------
  815.     recevoir un fichier depuis le port serie
  816.         p    : pointeur du fichier a recevoir
  817.         trcode    : 1 si avec transcodage
  818.               0 sinon
  819.     renvoi    1 si reception reussite
  820.         0 sinon
  821. ----------------------------------------------------------------------------*/
  822. entree_fic(p,trcode)
  823. int    p;
  824. char    trcode;
  825. {    int    i,j;
  826.     unsigned char    ok,c[MAXTRAME+1],tmout,len;
  827.  
  828.     do
  829.     {       ok=1;
  830.         for(j=0,tmout=0;j<10;j++)
  831.         {    if(!lire_action(ok,c,(int )maxtrame))
  832.             {    if(INTERRUPT==1)
  833.                 {    if(tmout==2)    return(0);
  834.                     tmout++;
  835.                     ok = 0xff;
  836.                     continue;
  837.                 }
  838.                 if(INTERRUPT==2)    return(0);
  839.                 tmout=0;
  840.                 ok=0;
  841.                 continue;
  842.             }
  843.             len=(hexabin(c[LONG])<<4)+hexabin(c[LONG+1]);
  844.             ok=(hexabin(c[XOR])<<4)+hexabin(c[XOR+1]);
  845.             for(i=0;i<SZTRAME;i++)    ok^=c[i];
  846.             if(!(ok=!ok))
  847.             {    tmout=0;
  848.                 continue;
  849.             }
  850.             i=(trcode=='1') ? transcode(c,len) : len;
  851.             write(p,(char *)c,(unsigned )i);
  852.             break;
  853.         }
  854.         if(j==10)    return(0);
  855.     }while(len==SZTRAME);
  856.     return(1);
  857. }
  858.  
  859. /*------------------------------formertrame-----------------------------------
  860.     former un trame de longueur size
  861.     p    : fichier source
  862.     trame    : trame a former
  863.     size    : longueur de trame demande
  864.     trcode    : 1 si transcodage
  865.           0 sinon
  866.     renvoi    longueur de trame effectif
  867. ----------------------------------------------------------------------------*/
  868. unsigned char    formertrame(p,trame,size,trcode)
  869. int    p;
  870. char    trcode;
  871. unsigned char    *trame,size;
  872. {    int    len,i,j,encours;
  873.     unsigned char    buf[MAXDATA],xor;
  874.  
  875.     if(trcode=='0')    size=read(p,(char *)trame,size);
  876.     else
  877.     {    len=read(p,(char *)buf,size);
  878.         for(i=j=encours=0;(j<size)&&(i<len);j++)
  879.         {    if(in_ascii(buf[i]))
  880.             {    if(encours)
  881.                 {    trame[j]=flag_transc;
  882.                     encours=0;
  883.                 }
  884.                 else    trame[j]=buf[i++];
  885.                     }
  886.             else
  887.             {    if(!encours)
  888.                 {    trame[j]=flag_transc;
  889.                     encours=1;
  890.                 }
  891.                 else    sprintf((char *)&trame[j++],"%02x",buf[i++]);
  892.             }
  893.         }
  894.         if(j>size)
  895.         {    trame[size-1]=flag_transc;
  896.             i--;
  897.         }
  898.         else    size=j;
  899.         if((i-=len)<0)    lseek(p,(long )i,1);
  900.     }
  901.     for(i=size;i<SZTRAME;i++)    trame[i]=ETX;
  902.     for(i=xor=0;i<SZTRAME;i++)    xor^=trame[i];
  903.     sprintf((char *)trame+XOR,"%02x%02x",xor,size);
  904.     return(size);
  905. }
  906.  
  907. /*------------------------------transcode-------------------------------------
  908.     transcoder la trame
  909.         trame    : trame a transcoder
  910.         size    : longueur de trame a transcoder
  911.     renvoi    longueur de la trame transcode
  912. ----------------------------------------------------------------------------*/
  913. transcode(trame,size)
  914. unsigned char    *trame,size;
  915. {    int    i,j,encours;
  916.     unsigned char    input[MAXDATA];
  917.  
  918.     for(i=0;i<size;i++)    input[i]=trame[i];
  919.     for(i=j=encours=0;i<size;i++)
  920.     {    if(input[i]==flag_transc)    encours=!encours;
  921.         else if(!encours)    trame[j++]=input[i];
  922.         else
  923.         {    trame[j++]=(hexabin(input[i])<<4)+hexabin(input[i+1]);
  924.             i++;    
  925.         }
  926.     }
  927.     return(j);
  928. }
  929.  
  930. /*------------------------------ecr_trame-------------------------------------
  931.     emettre un trame vers le port serie
  932.         trame : trame a emettre
  933.     renvoi    1 si emission reussite
  934.         0 sinon
  935. ----------------------------------------------------------------------------*/
  936. ecr_trame(trame)
  937. unsigned char    *trame;
  938. {    int    j,tmout;
  939.  
  940.     for(j=tmout=0;j<10;j++)
  941.     {    if(ecr_action(trame,(int )maxtrame))    break;
  942.         if(INTERRUPT==2)    return(0);
  943.         if(INTERRUPT==1)
  944.         {    if(tmout)    return(0);
  945.             tmout=1;
  946.         }
  947.         else    tmout=0;
  948.     }
  949.     return((j<10)&&(!INTERRUPT));
  950. }
  951.  
  952. /*------------------------------ecr_action------------------------------------
  953.     emettre une chaine de caracteres precedee de STX suivie de ETX
  954.         vers le port serie et lire la reponse de TUN
  955.         action : chaine a emettre
  956.         l      : longueur de la chaine
  957.     renvoi    1 si emission reussite
  958.         0 sinon
  959. ----------------------------------------------------------------------------*/
  960. ecr_action(action,l)
  961. int        l;
  962. unsigned char    *action;
  963. {    char    c[4];
  964.     int    i,alrmint();
  965.  
  966.     INTERRUPT=0;
  967.     signal(SIGALRM,alrmint);
  968.     write(1,OK,1);
  969.     write(1,(char *)action,(unsigned )l);
  970.     write(1,&OK[2],1);
  971.     alarm(TIME_OUT+2);
  972.     for(i=0;(i<3)&&(!INTERRUPT);i+=read(0,c+i,(unsigned )(3-i)));
  973. #ifdef    SYSIII
  974.     for(i=0;i<3;i++)    c[i] &= 0x7f;
  975. #endif
  976.     alarm(0);
  977.     c[3]='\0';
  978.     if(!strcmp(c,INTER))    INTERRUPT=2;
  979.     if(INTERRUPT)    return(0);
  980.     return(!strcmp(c,OK));
  981. }
  982.  
  983. /*------------------------------lire_action-----------------------------------
  984.     recevoir une chaine de caracteres precedee de STX suivie de ETX
  985.         depuis le port serie avant d'envoyer une reponse a TUN
  986.         ok     : 1 si l'envoi d'un OK
  987.              0 si l'envoi d'un NONOK
  988.              sinon rien
  989.         l      : >0 lire l caracteres
  990.              sinon lire jusqu'a la rencontre de STX
  991.         action : chaine recue
  992.     renvoi    1 si reception reussite
  993.         0 sinon
  994. ----------------------------------------------------------------------------*/
  995. lire_action(ok,action,l)
  996. int        l;
  997. unsigned char    ok,*action;
  998. {    int    i;
  999.     char    stx,etx;
  1000.     int    alrmint();
  1001.  
  1002.     INTERRUPT=0;
  1003.     signal(SIGALRM,alrmint);
  1004.     if(ok==1)    write(1,OK,3);
  1005.     else if(ok==0)    write(1,NONOK,3);
  1006.     else if(ok==0xff)    write(1,TMOUT,3);
  1007.     alarm(TIME_OUT);
  1008.     do
  1009.     {    while((!read(0,&stx,1))&&(!INTERRUPT));
  1010.     }while((stx!=STX)&&(!INTERRUPT));
  1011.     if(INTERRUPT)
  1012.     {    alarm(0);
  1013.         return(0);
  1014.     }
  1015. #ifdef    SYSIII
  1016.     stx &= 0x7f;
  1017. #endif
  1018.     if(l<=0)
  1019.     {    for(i=etx=0;(etx!=ETX)&&(!INTERRUPT);i++)
  1020.         {    while((!read(0,&etx,1))&&(!INTERRUPT));
  1021. #ifdef    SYSIII
  1022.             etx &= 0x7f;
  1023. #endif
  1024.             action[i]=etx;
  1025.         }
  1026.         action[--i]='\0';
  1027.     }
  1028.     else
  1029.     {    for(i=0;(i<=l)&&(!INTERRUPT);
  1030.             i+=read(0,(char *)action+i,(unsigned )(l+1-i)));
  1031. #ifdef    SYSIII
  1032.         for(i=0;i<=l;i++)    action[i] &= 0x7f;
  1033. #endif
  1034.         etx = action[l];
  1035.     }
  1036.     alarm(0);
  1037.     if(etx!=ETX)    return(0);
  1038.     if((i==1)&&(action[0]==ESC))    INTERRUPT=2;
  1039.     return(!INTERRUPT);
  1040. }
  1041.  
  1042. #ifdef    SYSIII
  1043. static    struct    sgttyb    sv1_las,
  1044.             sv2_las;
  1045. /*------------------------------ini_las---------------------------------------
  1046.     initialisation de la ligne asynchrone
  1047. ----------------------------------------------------------------------------*/
  1048. ini_las()
  1049. {    struct    sgttyb    B;
  1050.  
  1051.     ioctl(0,TIOCGETP,(char*)&B) ;
  1052.     ioctl(0,TIOCGETP,(char*)&sv1_las) ;
  1053.     B.sg_flags  |= RAW;
  1054.     B.sg_flags &= ~ECHO;
  1055.     ioctl(0,TIOCSETN,&B) ;
  1056.  
  1057.     ioctl(1,TIOCGETP,(char*)&B) ;
  1058.     ioctl(1,TIOCGETP,(char*)&sv2_las) ;
  1059.     B.sg_flags  |= RAW;
  1060.     B.sg_flags &= ~ECHO;
  1061.     ioctl(1,TIOCSETN,&B);
  1062. }
  1063.  
  1064. /*------------------------------fin_las---------------------------------------
  1065.     reinitialisation de la ligne asynchrone
  1066. ----------------------------------------------------------------------------*/
  1067. fin_las()
  1068. {    ioctl(1,TIOCSETN,&sv2_las) ;
  1069.     ioctl(0,TIOCSETN,&sv1_las) ;
  1070. }
  1071.  
  1072. #else
  1073. static    struct    termio    sv_las;
  1074. /*------------------------------ini_las---------------------------------------
  1075.     initialisation de la ligne asynchrone
  1076. ----------------------------------------------------------------------------*/
  1077. ini_las()
  1078. {    struct    termio    B;
  1079.  
  1080.     ioctl(0,TCGETA,&B);
  1081.     ioctl(0,TCGETA,&sv_las);
  1082.     B.c_iflag&=~ICRNL;    B.c_iflag&=~IXON;
  1083.     B.c_iflag&=~IXOFF;    B.c_oflag&=~OPOST;
  1084.     B.c_lflag&=~ICANON;    B.c_lflag&=~ISIG;
  1085.     B.c_lflag&=~ECHO;    B.c_cc[VMIN]=1;
  1086.     B.c_lflag&=~ECHOE;    B.c_lflag&=~ECHOK;
  1087.     B.c_lflag&=~ECHONL;    B.c_iflag&=~ISTRIP;
  1088.     B.c_line=0;
  1089.     B.c_iflag&=~BRKINT;
  1090.     ioctl(0,TCSETA,&B);
  1091. }
  1092.  
  1093. /*------------------------------fin_las---------------------------------------
  1094.     reinitialisation de la ligne asynchrone
  1095. ----------------------------------------------------------------------------*/
  1096. fin_las()
  1097. {    ioctl(0,TCSETAW,&sv_las);
  1098. }
  1099. #endif
  1100.  
  1101. /*------------------------------alrmint---------------------------------------
  1102.     fonction d'alarme
  1103. ----------------------------------------------------------------------------*/
  1104. alrmint()
  1105. {    DBG("\nTimeout\n","");
  1106.     INTERRUPT=1;
  1107. }
  1108.  
  1109.