home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
PC World Komputer 1995 November
/
PCWK1195.iso
/
esker
/
emul.1
/
EMUL.ARC
/
RTUNPLUS.C
< prev
next >
Wrap
Text File
|
1992-09-25
|
28KB
|
1,109 lines
/*------------------------------------------------------------------------------
rtunplus.c Version 6.00
------------------------------------------------------------------------------*/
#define NO 0
#define YES 1
#define DIRECT 0
#define DIRECTPTR 1
#define DIRENT 3
#ifdef SYSIII
#define USE_OPENDIR NO
#define DIRSTRUCT DIRECT
#define DIR_H <sys/dir.h>
#else
#ifdef XENIX
#define USE_OPENDIR YES
#define DIRSTRUCT DIRECTPTR
#define DIR_H <sys/ndir.h>
#else
#ifdef SYSV
#define USE_OPENDIR NO
#define DIRSTRUCT DIRECT
#define DIR_H <sys/dir.h>
#else
#ifdef LSX
#define USE_OPENDIR YES
#define DIRSTRUCT DIRECTPTR
#define DIR_H <sys/dir.h>
#else
#define USE_OPENDIR YES
#define DIRSTRUCT DIRENT
#define DIR_H <dirent.h>
#endif
#endif
#endif
#endif
#include <stdio.h>
#include <ctype.h>
#include <sys/types.h>
#ifdef SYSIII
#define O_RDONLY 0
#define O_WRONLY 1
#include <sgtty.h>
#else
#include <fcntl.h>
#include <string.h>
#include <termio.h>
#endif
#include <signal.h>
#include <sys/stat.h>
#include DIR_H
#ifdef SYSIII
char *strchr(s,car)
char *s,car;
{ for(;*s;s++) if(*s == car) return(s);
if(car == '\0') return(s);
return((char*)0);
}
char *strrchr(s,car)
char *s,car;
{ char *p;
for(p=s;*p;p++);
for(p;p!=s;p--) if(*p == car) return(p);
return((char*)0);
}
#endif
#define maxtrame SZTRAME+4
#define MAXDATA 0x7e
#define MAXTRAME MAXDATA+4
#define XOR SZTRAME
#define LONG SZTRAME+2
#define flag_transc MAXDATA
#define in_ascii(a) ((0x20<=a)&&(a<flag_transc))
unsigned char SZTRAME=MAXDATA;
#define STX 002
#define ETX 003
#define ACK 006
#define NAK 025
#define EOT 004
#define ESC 033
#define push_path(a) pile_path[i_pile_path++]=a
#define push_pf(a) pile_pf[i_pile_pf++]=a;
#define pop_path() pile_path[--i_pile_path]
#define pop_pf() pile_pf[--i_pile_pf]
#define fin_dir() (i_pile_path==0)
#if(USE_OPENDIR == YES)
DIR *pile_pf[200] ;
#else
static int pile_pf[200];
#endif
static char *pile_path[200];
static int i_pile_path=0;
static int i_pile_pf=0;
static int dir_flag = -1;
#if(USE_OPENDIR == YES)
DIR *pf_cour ;
#else
static int pf_cour;
#endif
static char *path_cour;
static char masq_cour[80];
static char TMOUT[] ={"\002\007\003"};
static char OK[] ={"\002\006\003"};
static char NONOK[] ={"\002\025\003"};
static char FIN[] ={"\002\004\003"};
static char INTER[] ={"\002\033\003"};
static int INTERRUPT;
static unsigned int TIME_OUT;
extern char *malloc();
extern void free();
extern unsigned int alarm();
extern long lseek();
#define DEBUG 0
#define DBG(f,v) if(DEBUG) fprintf(stderr,f,v)
/*------------------------------hexabin----------------------------------
Convertion hexa --> binaire
-------------------------------------------------------------------------*/
unsigned char hexabin(car)
unsigned char car;
{ if(isdigit(car)) car -= '0';
else car -= 'a'- 10;
return(car);
}
/*------------------------------isrepert--------------------------------------
tester si path est un repertoire
renvoi 1 si c'en est un
0 sinon
----------------------------------------------------------------------------*/
isrepert(path)
char *path;
{ struct stat status;
if(stat(path,&status)==-1) return(0);
if((status.st_mode&S_IFMT)!=S_IFDIR) return(0);
return(1);
}
/*------------------------------decompose-------------------------------------
decomposerle chemin d'acces et le nom de fichier
path : path a decomposer
au retour chemin : chemin d'acces termine par /
fic : nom de fichier
renvoi 0 si path est un repertoire
1 si path designe un fichier
2 si fic est un nouveau nom
-1 sinon
----------------------------------------------------------------------------*/
decompose(path,chemin,fic)
char *path,*chemin,*fic;
{ char *p;
struct stat status;
strcpy(chemin,"./");
*fic='\0';
if(path==NULL) return(0);
if(*path=='\0') return(0);
if(isrepert(path))
{ strcpy(chemin,path);
if(path[strlen(path)-1]!='/') strcat(chemin,"/");
return(0);
}
if((p=strrchr(path,'/'))==NULL) strcpy(fic,path);
else
{ strcpy(fic,++p);
*p='\0';
strcpy(chemin,path);
if(!isrepert(chemin)) return(-1);
}
if(stat(path,&status)==-1) return(2);
return(1);
}
/*-----------------------------findsdir---------------------------------------
chercher le prochain sous repertoire du repertoire pere
a l'appel pf : l'entree repertoire ouvert
pere : nom du repertoire
renvoi NULL s'il n'y en a pas
nom de sous repertoire trouve sinon
----------------------------------------------------------------------------*/
static char *findsdir(pf,pere)
#if(USE_OPENDIR == YES)
DIR *pf;
#else
int pf;
#endif
char *pere;
{ char path[256],buf[256],*p;
struct stat status;
#if(DIRSTRUCT == DIRENT)
struct dirent *B;
#else
#if(DIRSTRUCT == DIRECTPTR)
struct direct *B;
#else
#if(DIRSTRUCT == DIRECT)
struct direct B;
#endif
#endif
#endif
#if(USE_OPENDIR == YES)
while (B=readdir(pf))
{ if(B->d_ino==0) continue;
strcpy(buf,B->d_name);
#else
buf[DIRSIZ] = '\0';
while(read(pf,&B,sizeof(B)))
{ if(B.d_ino==0) continue;
strncpy(buf,B.d_name,DIRSIZ);
#endif
if(!strcmp(buf,".")) continue;
if(!strcmp(buf,"..")) continue;
sprintf(path,"%s%s",pere,buf);
if(stat(path,&status)==-1) continue;
if((status.st_mode&S_IFMT)!=S_IFDIR) continue;
if((p=malloc((unsigned)strlen(path)+2))==NULL) return(NULL);
sprintf(p,"%s/",path);
return(p);
}
return(NULL);
}
/*------------------------------firstdir--------------------------------------
initialiser l'environnement de recherche de sous repertoires
a l'appel dir = repertoire termine par /
flag = 0 recherche recurssive des sous repertoires
> 0 sans recherche de sous repertoire
renvoi NULL si dir n'est pas un repertoire ou
si autorisation de consultation n'est pas permise
nom du repertoire
----------------------------------------------------------------------------*/
char *firstdir(dir,flag)
char *dir,flag;
{
enddir();
if(!isrepert(dir)) return(NULL);
if(access(dir,05)==-1) return(NULL);
#if(USE_OPENDIR == YES)
if(!(pf_cour=opendir(dir))) return(NULL) ;
#else
if((pf_cour=open(dir,O_RDONLY))==-1) return(NULL);
#endif
if((path_cour=malloc((unsigned)strlen(dir)+1))==NULL) return(NULL);
strcpy(path_cour,dir);
i_pile_pf=0;
i_pile_path=0;
dir_flag=flag;
return(path_cour);
}
/*------------------------------nextdir---------------------------------------
chercher le prochain sous repertoire
renvoi NULL s'il n'y en a plus ou
si le recherche n'est pas autorisee
nom du sous repertoire trouve
----------------------------------------------------------------------------*/
char *nextdir()
{ char *dir;
#if(USE_OPENDIR == YES)
DIR *pf ;
#else
int pf;
#endif
if(dir_flag>0) free(path_cour);
if(dir_flag!=0) return(NULL);
while((dir=findsdir(pf_cour,path_cour))!=NULL)
{ if(access(dir,05)==-1) continue;
#if(USE_OPENDIR == YES)
if(!(pf=opendir(dir))) continue ;
#else
if((pf=open(dir,O_RDONLY))==-1) continue;
#endif
push_path(path_cour);
push_pf(pf_cour);
path_cour=dir;
pf_cour=pf;
return(dir);
}
#if(USE_OPENDIR == YES)
closedir(pf_cour) ;
#else
close(pf_cour);
#endif
free(path_cour);
if(fin_dir())
{ dir_flag = -1;
return(NULL);
}
pf_cour=pop_pf();
path_cour=pop_path();
return(nextdir());
}
/*------------------------------enddir----------------------------------------
terminer le recherche de sous repertoire si l'on ne desire pas
aller jusqu'au bout
----------------------------------------------------------------------------*/
enddir()
{ while(!fin_dir())
{
#if(USE_OPENDIR == YES)
closedir(pop_pf()) ;
#else
close(pop_pf());
#endif
free(pop_path());
}
dir_flag = -1;
}
/*------------------------------nextfic---------------------------------------
chercher le prochain fichier
au retour name : nom du fichier trouve
renvoi -1 s'il n'y en a plus
taille du fichier en octet sinon
----------------------------------------------------------------------------*/
long nextfic(name)
char *name;
{ struct stat status;
char path[256],buf[256];
#if(DIRSTRUCT == DIRENT)
struct dirent *B;
#else
#if(DIRSTRUCT == DIRECTPTR)
struct direct *B;
#else
#if(DIRSTRUCT == DIRECT)
struct direct B;
#endif
#endif
#endif
if(dir_flag==-1) return(-1);
#if(USE_OPENDIR == YES)
while(B=readdir(pf_cour))
{ if(B->d_ino==0) continue;
strcpy(buf,B->d_name);
#else
buf[DIRSIZ] = '\0';
while(read(pf_cour,&B,sizeof(B))==sizeof(B))
{ if(B.d_ino==0) continue;
strncpy(buf,B.d_name,DIRSIZ);
#endif
sprintf(path,"%s%s",path_cour,buf);
if(stat(path,&status)==-1) continue;
if((status.st_mode&S_IFMT)!=S_IFREG) continue;
if(masque(buf,masq_cour))
{ strcpy(name,buf);
return(status.st_size);
}
}
#if(USE_OPENDIR == YES)
rewinddir(pf_cour) ;
#else
lseek(pf_cour,0L,0);
#endif
return(-1);
}
/*------------------------------firstfic--------------------------------------
chercher le premier fichier (firstdir ou nextdir a ete appelle)
a l'appel masq : caracteres generiques
au retour name : nom du fichier trouve
renvoi -1 s'il n'y en a pas
taille du fichier en octet sinon
----------------------------------------------------------------------------*/
long firstfic(masq,name)
char *masq,*name;
{ if(dir_flag==-1) return(-1);
strcpy(masq_cour,masq);
#if(USE_OPENDIR == YES)
rewinddir(pf_cour) ;
#else
lseek(pf_cour,0L,0);
#endif
return(nextfic(name));
}
/*------------------------------masque----------------------------------------
renvoi 1 si chaine conforme aux carracteres generiques forme
0 sinon
----------------------------------------------------------------------------*/
masque(chaine,forme)
char *chaine,*forme;
{ int i=0,j=0;
while((i<strlen(chaine))&&(j<strlen(forme)))
{ if(forme[j]=='*')
{ if(++j>=strlen(forme)) return(1);
for(;i<strlen(chaine);i++)
{ if(masque(&chaine[i],&forme[j])) return(1);
}
return(0);
}
if((chaine[i]!=forme[j])&&('?'!=forme[j])) return(0);
i++; j++;
}
if(j==strlen(forme))
{ if(i>=strlen(chaine)) return(1);
else return(0);
}
else
{ for(;j<strlen(forme);j++)
{ if(forme[j]!='*') return(0);
}
return(1);
}
}
/*------------------------------ignorer---------------------------------------
tester si nom contien un masque
renvoi 1 si nom contien un masque ou est une chaine vide ou NULL
0 sinon
----------------------------------------------------------------------------*/
ignorer(nom)
char *nom;
{ if(nom==NULL) return(1);
if(*nom=='\0') return(1);
if(strrchr(nom,'?')!=NULL) return(1);
if(strrchr(nom,'*')!=NULL) return(1);
return(0);
}
/*------------------------------converpath------------------------------------
convertir DOS path notation en UNIX notation
----------------------------------------------------------------------------*/
converpath(path)
char *path;
{ char *p;
while((p=strchr(path,'\\'))!=NULL) *p='/';
}
/*------------------------------creatdir--------------------------------------
creer repetoire dir
renvoi 1 si creation reussite
0 sinon
----------------------------------------------------------------------------*/
creatdir(dir)
char *dir;
{ char ref[80],pere[80],*pt;
#ifdef SYSIII
sprintf(ref,"mkdir %s",dir);
return(!system(ref));
#else
#ifndef XENIX
return(!mkdir(dir,0777)) ;
#else
pt=strrchr(dir,'/');
if(!pt) strcpy(pere,".");
else
{ if(pt==dir) strcpy(pere,"/");
else
{ strncpy(pere,dir,pt-dir);
pere[pt-dir]='\0';
}
}
if(access(pere,03))
{ DBG("Acces interdit a %s\n",pere);
return(0);
}
if(mknod(dir,S_IFDIR+0777,0))
{ DBG("Creation %s impossible\n",dir);
return(0);
}
if(chown(dir,getuid(),getgid()))
{ unlink(dir);
DBG("Chgt de proprietaire impossible\n","");
return(0);
}
sprintf(ref,"%s/.",dir);
if(link(dir,ref))
{ unlink(dir);
DBG("Creation du lien . impossible\n","");
return(0);
}
sprintf(ref,"%s/..",dir);
if(link(pere,ref))
{ sprintf(ref,"%s/.",dir);
unlink(ref);
unlink(dir);
DBG("Creation du lien .. impossible\n","");
return(0);
}
return(1);
#endif
#endif
}
/*------------------------------RTUNPLUS----------------------------------------
Usage : RTUNPLUS [temps_alarme]
Fonction : transfert de fichiers
execution de commandes UNIX
----------------------------------------------------------------------------*/
main(argc,argv)
int argc;
char **argv;
{ unsigned char buf[60];
int ret=0;
TIME_OUT= argc>1 ? atoi(argv[1]) : 10;
DBG("Lancement de RTUNPLUS %d\n",TIME_OUT);
ini_las();
INTERRUPT=0;
if(!lire_action(2,buf,1))
{ fin_las();
DBG("erreur de transmission 1\n","");
exit(1);
}
if(buf[0]!=STX)
{ fin_las();
DBG("erreur de trame\n","");
exit(2);
}
if(!lire_action(1,buf,0))
{ fin_las();
DBG("erreur de transmission 2\n","");
exit(3);
}
if(buf[0]=='E')
{ DBG("Emission %s\n",&buf[2]);
DBG("Transcodage %c\n",buf[1]);
ret=strlen((char *)buf)+1;
if(buf[ret]=='t')
SZTRAME=(hexabin(buf[ret+1])<<4)+hexabin(buf[ret+2]);
DBG("Trame %d\n",SZTRAME);
ret=emission((char *)&buf[2],(char )buf[1]);
}
else if(buf[0]=='R')
{ DBG("Reception %s\n",&buf[2]);
DBG("Transcodage %c\n",buf[1]);
ret=strlen((char *)buf)+1;
if(buf[ret]=='t')
SZTRAME=(hexabin(buf[ret+1])<<4)+hexabin(buf[ret+2]);
DBG("Trame %d\n",SZTRAME);
ret=reception((char *)&buf[2],(char )buf[1]);
}
else if(buf[0]=='X')
{ DBG("Execution %s\n",&buf[1]);
ret=execution((char *)&buf[1]);
}
else if(buf[0]=='T')
{ DBG("Test rlogin\n","");
ret=1;
}
else
{ DBG("commande inconnue [%s]\n",buf);
}
if(ret)
{ DBG("RTUNPLUS termine ...\n","");
}
else DBG("RTUNPLUS echoue ...\n","");
fin_las();
return(!ret);
}
/*------------------------------emission--------------------------------------
emission de fichiers
renvoi : 1 si emission reussite
0 sinon
----------------------------------------------------------------------------*/
emission(nom,trcode)
char *nom,trcode;
{ int p,i,j,flag,l_racine;
long l;
char chemin[80],buf[80],fic[80],masq[80],*dir;
if((flag=decompose(nom,chemin,masq))==-1)
{ DBG("Chemin d'acces %s incorrect !",chemin);
write(1,NONOK,3);
return(0);
}
if((dir=firstdir(chemin,flag))==NULL)
{ DBG("Consultation de %s n'es pas permise !\n",chemin);
write(1,NONOK,3);
return(0);
}
if(*masq=='\0') strcpy(masq,"*");
if((flag==2)&&((l=firstfic(masq,fic))==-1))
{ DBG("Fichier source %s non trouve !\n",masq);
write(1,NONOK,3);
enddir();
return(0);
}
if(!ecr_action((unsigned char *)&OK[1],1))
{ enddir();
DBG("Pas de reponse\n","");
return(0);
}
l_racine=strlen(dir);
do
{ if((l=firstfic(masq,fic))!=-1)
do
{ sprintf(buf,"%s%s",dir,fic);
if(access(buf,04)==-1)
{ DBG("Ouverture de fichier source %s non autorisee !\n",buf);
if(!ecr_action((unsigned char *)&NONOK[1],1))
{ enddir();
return(0);
}
continue;
}
if((p=open(buf,O_RDONLY))==-1)
{ DBG("Ouverture de fichier source %s impossible !\n",buf);
if(!ecr_action((unsigned char *)&NONOK[1],1))
{ enddir();
return(0);
}
continue;
}
i=strlen(fic)+1;
sprintf(buf,"F%s %ld",fic,l);
j=strlen(buf);
buf[i]='\0';
if(!ecr_action((unsigned char *)buf,j))
{ close(p);
DBG("Ouverture de fichier destination %s impossible !\n",fic);
if(INTERRUPT)
{ enddir();
return(0);
}
continue;
}
DBG("Emission de %s en cours ...\n",fic);
if(!sortie_fic(p,trcode))
{ DBG("Erreur de transmission !\n","");
}
else DBG("Emission de %s termine\n",fic);
close(p);
}while(((l=nextfic(fic))!=-1)&&(!INTERRUPT));
while(((dir=nextdir())!=NULL)&&(!INTERRUPT))
{ sprintf(buf,"D%s",&dir[l_racine]);
if(!ecr_action((unsigned char *)buf,strlen(buf)))
{ DBG("Creation de repertoire DOS %s refusee !\n",buf);
}
else
{ DBG("Creation de repertoire DOS %s\n",buf);
break;
}
}
}while((dir!=NULL)&&(!INTERRUPT));
if(!INTERRUPT)
{ write(1,FIN,3);
return(1);
}
enddir();
return(0);
}
/*------------------------------reception-------------------------------------
reception de fichiers
renvoi : 1 si reception reussite
0 sinon
----------------------------------------------------------------------------*/
reception(nom,trcode)
char *nom,trcode;
{ char buf[80],chemin[80],fic[80],fich[30],pere[80];
int p,ignor;
converpath(nom);
if(decompose(nom,pere,fich)==-1)
{ DBG("Chemin d'acces %s incorrect !",chemin);
write(1,NONOK,3);
return(0);
}
ignor=ignorer(fich);
strcpy(chemin,pere);
if(!lire_action(1,(unsigned char *)fic,0)) return(0);
while((fic[0]!=EOT)&&(!INTERRUPT))
{ if(fic[0]=='D')
{ converpath(&fic[1]);
sprintf(chemin,"%s%s",pere,&fic[1]);
if(!isrepert(chemin))
{ strcpy(buf,chemin);
buf[strlen(buf)-1]='\0';
if(!creatdir(buf))
{ DBG("Creation du repertoire %s refusee!\n",chemin);
lire_action(0,(unsigned char *)fic,0);
continue;
}
DBG("Creation du repertoire %s\n",chemin);
}
lire_action(1,(unsigned char *)fic,0);
continue;
}
if(fic[0]!='F')
{ DBG("Nom de fichier destination non recu!\n","");
if(!lire_action(0,(unsigned char *)fic,0))
return(0);
continue;
}
strcpy(buf,chemin);
if(ignor) strcat(buf,&fic[1]);
else strcat(buf,fich);
if(access(buf,0)==-1)
{ if(access(chemin,03)==-1)
{ DBG("Creation de fichier destination %s impossible !\n",buf);
if(!lire_action(0,(unsigned char *)fic,0))
return(0);
continue;
}
#ifdef SYSIII
if((p=creat(buf,0777))==-1)
#else
if((p=open(buf,O_WRONLY|O_CREAT,0777))==-1)
#endif
{ DBG("Creation de fichier destination %s impossible !\n",buf);
if(!lire_action(0,(unsigned char *)fic,0))
return(0);
continue;
}
}
else
{ if(access(buf,04)==-1)
{ DBG("Ouverture de fichier destination %s impossible !\n",buf);
if(!lire_action(0,(unsigned char *)fic,0))
return(0);
continue;
}
#ifdef SYSIII
unlink(buf);
if((p=creat(buf,0777))==-1)
#else
if((p=open(buf,O_WRONLY|O_TRUNC))==-1)
#endif
{ DBG("Ouverture de fichier destination %s impossible !\n",buf);
if(!lire_action(0,(unsigned char *)fic,0))
return(0);
continue;
}
}
DBG("Reception de %s en cours ...\n",buf);
if(!entree_fic(p,trcode))
{ DBG("Erreur de transmission !\n","");
}
else DBG("Reception de %s terminee\n",buf);
close(p);
chown(buf,getuid(),getgid());
if(INTERRUPT) return(0);
if(!lire_action(1,(unsigned char *)fic,0)) return(0);
}
return(1);
}
/*------------------------------execution-------------------------------------
execution de commande UNIX
renvoi : 1 si reception reussite
0 sinon
----------------------------------------------------------------------------*/
execution(cmd)
char *cmd;
{ char fin[20],i=0;
if(!lire_action(1,(unsigned char *)fin,0)) return(0);
fin_las();
strcat(cmd,"\n");
write(1,cmd,(unsigned )strlen(cmd));
system(cmd);
write(1,&i,1);
ini_las();
write(1,fin,(unsigned )strlen(fin));
return(1);
}
/*------------------------------sortie_fic------------------------------------
emettre un fichier vers le port serie
p : pointeur du fichier a emettre
trcode : 1 si avec transcodage
0 sinon
renvoi 1 si emission reussite
0 sinon
----------------------------------------------------------------------------*/
sortie_fic(p,trcode)
int p,trcode;
{ unsigned char sz,c[MAXTRAME];
unsigned char formertrame();
do
{ sz=formertrame(p,c,SZTRAME,trcode);
if(!ecr_trame(c)) return(0);
}while(sz==SZTRAME);
return(1);
}
/*------------------------------entree_fic------------------------------------
recevoir un fichier depuis le port serie
p : pointeur du fichier a recevoir
trcode : 1 si avec transcodage
0 sinon
renvoi 1 si reception reussite
0 sinon
----------------------------------------------------------------------------*/
entree_fic(p,trcode)
int p;
char trcode;
{ int i,j;
unsigned char ok,c[MAXTRAME+1],tmout,len;
do
{ ok=1;
for(j=0,tmout=0;j<10;j++)
{ if(!lire_action(ok,c,(int )maxtrame))
{ if(INTERRUPT==1)
{ if(tmout==2) return(0);
tmout++;
ok = 0xff;
continue;
}
if(INTERRUPT==2) return(0);
tmout=0;
ok=0;
continue;
}
len=(hexabin(c[LONG])<<4)+hexabin(c[LONG+1]);
ok=(hexabin(c[XOR])<<4)+hexabin(c[XOR+1]);
for(i=0;i<SZTRAME;i++) ok^=c[i];
if(!(ok=!ok))
{ tmout=0;
continue;
}
i=(trcode=='1') ? transcode(c,len) : len;
write(p,(char *)c,(unsigned )i);
break;
}
if(j==10) return(0);
}while(len==SZTRAME);
return(1);
}
/*------------------------------formertrame-----------------------------------
former un trame de longueur size
p : fichier source
trame : trame a former
size : longueur de trame demande
trcode : 1 si transcodage
0 sinon
renvoi longueur de trame effectif
----------------------------------------------------------------------------*/
unsigned char formertrame(p,trame,size,trcode)
int p;
char trcode;
unsigned char *trame,size;
{ int len,i,j,encours;
unsigned char buf[MAXDATA],xor;
if(trcode=='0') size=read(p,(char *)trame,size);
else
{ len=read(p,(char *)buf,size);
for(i=j=encours=0;(j<size)&&(i<len);j++)
{ if(in_ascii(buf[i]))
{ if(encours)
{ trame[j]=flag_transc;
encours=0;
}
else trame[j]=buf[i++];
}
else
{ if(!encours)
{ trame[j]=flag_transc;
encours=1;
}
else sprintf((char *)&trame[j++],"%02x",buf[i++]);
}
}
if(j>size)
{ trame[size-1]=flag_transc;
i--;
}
else size=j;
if((i-=len)<0) lseek(p,(long )i,1);
}
for(i=size;i<SZTRAME;i++) trame[i]=ETX;
for(i=xor=0;i<SZTRAME;i++) xor^=trame[i];
sprintf((char *)trame+XOR,"%02x%02x",xor,size);
return(size);
}
/*------------------------------transcode-------------------------------------
transcoder la trame
trame : trame a transcoder
size : longueur de trame a transcoder
renvoi longueur de la trame transcode
----------------------------------------------------------------------------*/
transcode(trame,size)
unsigned char *trame,size;
{ int i,j,encours;
unsigned char input[MAXDATA];
for(i=0;i<size;i++) input[i]=trame[i];
for(i=j=encours=0;i<size;i++)
{ if(input[i]==flag_transc) encours=!encours;
else if(!encours) trame[j++]=input[i];
else
{ trame[j++]=(hexabin(input[i])<<4)+hexabin(input[i+1]);
i++;
}
}
return(j);
}
/*------------------------------ecr_trame-------------------------------------
emettre un trame vers le port serie
trame : trame a emettre
renvoi 1 si emission reussite
0 sinon
----------------------------------------------------------------------------*/
ecr_trame(trame)
unsigned char *trame;
{ int j,tmout;
for(j=tmout=0;j<10;j++)
{ if(ecr_action(trame,(int )maxtrame)) break;
if(INTERRUPT==2) return(0);
if(INTERRUPT==1)
{ if(tmout) return(0);
tmout=1;
}
else tmout=0;
}
return((j<10)&&(!INTERRUPT));
}
/*------------------------------ecr_action------------------------------------
emettre une chaine de caracteres precedee de STX suivie de ETX
vers le port serie et lire la reponse de TUN
action : chaine a emettre
l : longueur de la chaine
renvoi 1 si emission reussite
0 sinon
----------------------------------------------------------------------------*/
ecr_action(action,l)
int l;
unsigned char *action;
{ char c[4];
int i,alrmint();
INTERRUPT=0;
signal(SIGALRM,alrmint);
write(1,OK,1);
write(1,(char *)action,(unsigned )l);
write(1,&OK[2],1);
alarm(TIME_OUT+2);
for(i=0;(i<3)&&(!INTERRUPT);i+=read(0,c+i,(unsigned )(3-i)));
#ifdef SYSIII
for(i=0;i<3;i++) c[i] &= 0x7f;
#endif
alarm(0);
c[3]='\0';
if(!strcmp(c,INTER)) INTERRUPT=2;
if(INTERRUPT) return(0);
return(!strcmp(c,OK));
}
/*------------------------------lire_action-----------------------------------
recevoir une chaine de caracteres precedee de STX suivie de ETX
depuis le port serie avant d'envoyer une reponse a TUN
ok : 1 si l'envoi d'un OK
0 si l'envoi d'un NONOK
sinon rien
l : >0 lire l caracteres
sinon lire jusqu'a la rencontre de STX
action : chaine recue
renvoi 1 si reception reussite
0 sinon
----------------------------------------------------------------------------*/
lire_action(ok,action,l)
int l;
unsigned char ok,*action;
{ int i;
char stx,etx;
int alrmint();
INTERRUPT=0;
signal(SIGALRM,alrmint);
if(ok==1) write(1,OK,3);
else if(ok==0) write(1,NONOK,3);
else if(ok==0xff) write(1,TMOUT,3);
alarm(TIME_OUT);
do
{ while((!read(0,&stx,1))&&(!INTERRUPT));
}while((stx!=STX)&&(!INTERRUPT));
if(INTERRUPT)
{ alarm(0);
return(0);
}
#ifdef SYSIII
stx &= 0x7f;
#endif
if(l<=0)
{ for(i=etx=0;(etx!=ETX)&&(!INTERRUPT);i++)
{ while((!read(0,&etx,1))&&(!INTERRUPT));
#ifdef SYSIII
etx &= 0x7f;
#endif
action[i]=etx;
}
action[--i]='\0';
}
else
{ for(i=0;(i<=l)&&(!INTERRUPT);
i+=read(0,(char *)action+i,(unsigned )(l+1-i)));
#ifdef SYSIII
for(i=0;i<=l;i++) action[i] &= 0x7f;
#endif
etx = action[l];
}
alarm(0);
if(etx!=ETX) return(0);
if((i==1)&&(action[0]==ESC)) INTERRUPT=2;
return(!INTERRUPT);
}
#ifdef SYSIII
static struct sgttyb sv1_las,
sv2_las;
/*------------------------------ini_las---------------------------------------
initialisation de la ligne asynchrone
----------------------------------------------------------------------------*/
ini_las()
{ struct sgttyb B;
ioctl(0,TIOCGETP,(char*)&B) ;
ioctl(0,TIOCGETP,(char*)&sv1_las) ;
B.sg_flags |= RAW;
B.sg_flags &= ~ECHO;
ioctl(0,TIOCSETN,&B) ;
ioctl(1,TIOCGETP,(char*)&B) ;
ioctl(1,TIOCGETP,(char*)&sv2_las) ;
B.sg_flags |= RAW;
B.sg_flags &= ~ECHO;
ioctl(1,TIOCSETN,&B);
}
/*------------------------------fin_las---------------------------------------
reinitialisation de la ligne asynchrone
----------------------------------------------------------------------------*/
fin_las()
{ ioctl(1,TIOCSETN,&sv2_las) ;
ioctl(0,TIOCSETN,&sv1_las) ;
}
#else
static struct termio sv_las;
/*------------------------------ini_las---------------------------------------
initialisation de la ligne asynchrone
----------------------------------------------------------------------------*/
ini_las()
{ struct termio B;
ioctl(0,TCGETA,&B);
ioctl(0,TCGETA,&sv_las);
B.c_iflag&=~ICRNL; B.c_iflag&=~IXON;
B.c_iflag&=~IXOFF; B.c_oflag&=~OPOST;
B.c_lflag&=~ICANON; B.c_lflag&=~ISIG;
B.c_lflag&=~ECHO; B.c_cc[VMIN]=1;
B.c_lflag&=~ECHOE; B.c_lflag&=~ECHOK;
B.c_lflag&=~ECHONL; B.c_iflag&=~ISTRIP;
B.c_line=0;
B.c_iflag&=~BRKINT;
ioctl(0,TCSETA,&B);
}
/*------------------------------fin_las---------------------------------------
reinitialisation de la ligne asynchrone
----------------------------------------------------------------------------*/
fin_las()
{ ioctl(0,TCSETAW,&sv_las);
}
#endif
/*------------------------------alrmint---------------------------------------
fonction d'alarme
----------------------------------------------------------------------------*/
alrmint()
{ DBG("\nTimeout\n","");
INTERRUPT=1;
}