/*******************************************************************
Copyright (C) 2011-2024 Patrick H. E. Foubet - S.E.R.I.A.N.E.
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or any
later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see
*******************************************************************/
/*
############################################################
# Projet Kouglof 2 de l'Ecole du Logiciel Libre d'Ivry : #
############################################################
octave.c : outil pour scanner l'interface reseau afin d'analyser les sites
auxquels les applications veulent se connecter.
A utiliser avec le fichier auth1.txt pour stopper les connexions non voulues
Tous les details sur le site :
https://e2li.org -> menu : Projet Prosecco.
*/
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#define Version "1.00"
#define F_GETPIPE_SZ 1032
#define F_SETPIPE_SZ 1031
static int RUN=1, REQ=0, ENDT=0, REPR=0, p1[2],Trace=0;
static pid_t pid;
static char * NPROG, *IFACE=NULL;
#define DELAYR 20 /* delai avant relance auto */
void interup (int S)
{
if (S==SIGINT) {
write(p1[1],"\n",1);
REQ=1; return;
}
if (S==SIGCHLD) {
if (waitpid(pid,NULL,WNOHANG) == pid) {
ENDT=1;
write(p1[1],"\n",1);
}
return;
}
fprintf(stderr,"Reçu signal %d !!??\n",S);
}
/* ### les niveaux de trace */
#define TMIN 0
#define TMAX 3
#define T1 Trace > 0
#define T2 Trace > 1
#define T3 Trace > 2
/* #### les fonctions adresses IPv4 */
int isIPv4(char *a)
{
struct in_addr S;
int r;
if ((r = inet_pton(AF_INET,a, (void *)&S)) <= 0) return 0;
return 1;
}
int isCidr(char*r)
{
char buf[20], *sn;
int n;
if (strlen(r)>18) return 0;
strcpy(buf,r);
if ((sn=strstr(buf,"/")) == NULL) return 0;
*sn = '\0';
if (!isIPv4(buf)) return 0;
n = atoi(sn+1);
if (n>32) return 0;
return n;
}
int isSousRes(char*r, char *a)
{
struct in_addr Sa, Sr, Sm;
int n, m1,m2,m3,m4, m;
char buf[20],smasq[16],*sn;
if (!isCidr(r)) return 0;
if (!isIPv4(a)) return 0;
strcpy(buf,r);
if ((sn=strstr(buf,"/")) == NULL) return 0;
*sn = '\0';
n = atoi(sn+1);
/* calcul du masq */
m=n;
if (m>7) { m1=255; m-=8;
} else { m1=0;
while (m>=0) m1 |= 0x80 >> --m;
}
if (m>7) { m2=255; m-=8;
} else { m2=0;
while (m>=0) m2 |= 0x80 >> --m;
}
if (m>7) { m3=255; m-=8;
} else { m3=0;
while (m>=0) m3 |= 0x80 >> --m;
}
if (m>7) { m4=255; m-=8;
} else { m4=0;
while (m>=0) m4 |= 0x80 >> --m;
}
sprintf(smasq,"%d.%d.%d.%d",m1,m2,m3,m4);
inet_pton(AF_INET,smasq, (void *)&Sm);
inet_pton(AF_INET,a, (void *)&Sa);
inet_pton(AF_INET,buf, (void *)&Sr);
if ((Sr.s_addr & Sm.s_addr) == (Sa.s_addr & Sm.s_addr)) return 1;
return 0;
}
/* #### gestion dynamique des CIDR */
#define NBC 100 /* nb de CIDR */
char* Tcidr[NBC];
int iC=0;
int bloqueIP(char*);
int addCidr(char * c)
{
int i=iC;
if (i==NBC) return i;
Tcidr[i] = (char*)malloc(strlen(c)+1);
strcpy(Tcidr[i],c);
iC++;
bloqueIP(c);
return i;
}
void delCidr(char * c)
{
int i;
for (i=0; i 0) Tcidr[i] = Tcidr[iC];
return;
}
}
int isAddrInCidr(char * a, int M)
{
int i;
for(i=0;i 0) {
if (!litligne(line)) {
if (T1) printf("T1: Erreur param. = %s\n",line);
}
}
free(line);
fclose(fd);
validCidr();
if (T1) listCidr();
}
/* ### gestion dynamique des elts */
#define NBT 1000 /* nb d'elts */
int Tno[NBT];
int Trv[NBT];
char* Turl[NBT];
int iT=0, NbElt=0, MaxElt=0;
int addElt(int n, char * u)
{
int i=iT;
if (i == NBT) return i;
Tno[i]=n;
Trv[i]=0;
Turl[i] = (char*)malloc(strlen(u)+1);
strcpy(Turl[i],u);
iT++;
NbElt++;
if (NbElt > MaxElt) MaxElt=NbElt;
return i;
}
int isElt(int n)
{
int i;
for (i=0; i=iT) return;
if (T3) printf("T3: Del %d : %s \n",Tno[i],Turl[i]);
iT--;
if (iT == i) return;
if (iT > 0) {
Tno[i] = Tno[iT];
Turl[i] = Turl[iT];
Trv[i] = Trv[iT];
}
return;
}
void delElt(int n)
{
int i;
for (i=0; i0) { printf("%d : %s (%d)\n",Tno[i], Turl[i], Trv[i]);
n++;
}
break;
default:
for (i=0; i/dev/null 2>&1",comm);
return comsh(b);
}
/* ### fct de MAJ iptables */
static char * IPT = "iptables";
static char * IP6T = "ip6tables";
static char * MYCH = "valide4";
static char * OUTP = "OUTPUT";
static char * MNO = "REJECT";
static char * MOK = "ACCEPT";
int initIPT(void)
{
int i=0;
char b[90];
if (REPR) return 0;
sprintf(b,"%s -F",IPT);
i += exeCom(b);
sprintf(b,"%s -F",IP6T);
i += exeCom(b);
sprintf(b,"%s -L %s -n",IPT,MYCH);
if (exeCom(b)) {
sprintf(b,"%s -N %s",IPT,MYCH);
i += exeCom(b);
}
sprintf(b,"%s -A %s -j %s",IPT,OUTP,MYCH);
i += exeCom(b);
return i;
}
int isPresentIP(char * comm, char * ip, char * chain)
{
char buf[100];
sprintf(buf,"%s -L %s -n|grep %s",comm,chain,ip);
if (exeCom(buf) == 0) return 1;
return 0;
}
int retireChain(char * comm, char * ip, char * chain, char * jump)
{
char buf[100];
sprintf(buf,"%s -D %s -d %s -j %s",comm,chain, ip, jump);
return exeCom(buf);
}
int ajouteChain(char * comm, char * ip, char * chain, char * jump)
{
char buf[100];
sprintf(buf,"%s -A %s -d %s -j %s",comm,chain, ip, jump);
return exeCom(buf);
}
int bloqueIP(char* ip)
{
if (isAddrInCidr(ip,0)) return 0;
if (isPresentIP(IPT,ip,OUTP)) return 0;
return ajouteChain(IPT,ip,OUTP,MNO);
}
int debloqueIP(char* ip, char * url)
{
if (url != NULL) syslog(LOG_INFO,"%s=%s ACCEPT",url,ip);
return ajouteChain(IPT,ip,MYCH,MOK);
}
int rebloqueIP(char* ip)
{
return retireChain(IPT,ip,MYCH,MOK);
}
void dropIP(char * l)
{
char *s,*d=l;
while ((s=strstr(d, "A ")) != NULL) {
s+=2;
if ((d=strstr(s+2, ",")) == NULL) break;
*d = '\0';
d++;
bloqueIP(s);
}
bloqueIP(s);
}
int verifIPOk(char * l, char * url)
{
char *s,*d=l;
while ((s=strstr(d, "A ")) != NULL) {
s+=2;
if ((d=strstr(s+2, ",")) == NULL) break;
*d = '\0';
d++;
if (isPresentIP(IPT,s,MYCH)) continue;
if (isAddrInCidr(s,1)) debloqueIP(s,url);
}
if (isPresentIP(IPT,s,MYCH)) return 1;
if (isAddrInCidr(s,1)) return(debloqueIP(s,url));
return 1;
}
int dropIP6(char * l)
{
char *s,*d=l;
while ((s=strstr(d, "A ")) != NULL) {
s+=2;
if ((d=strstr(s+2, ",")) == NULL) break;
*d = '\0';
d++;
if (isPresentIP(IP6T,s,OUTP)) continue;
ajouteChain(IP6T,s,OUTP,MNO);
}
if (isPresentIP(IP6T,s,OUTP)) return 1;
ajouteChain(IP6T,s,OUTP,MNO);
return 1;
}
/* tache de commande et periodiques */
#define t0 (time_t)0
time_t tim1=t0;
void tachePer1(void) /* vide les elts toutes les 30 secondes */
{
static time_t tim0=t0, tw;
int i, v;
tw = time(NULL);
if ((tw - tim0) < 30) {
if (T3) printf ("T3: tache1 passe %s",ctime(&tw));
return;
}
if (T3) printf ("T3: tache1 exec %s",ctime(&tw));
tim1 = time(NULL);
v = (tim1 - tim0) / 30;
if (tim0 != t0) {
for (i=iT-1; i>=0; i--) {
if ((Trv[i]&0x6) == 6) delIElt(i); // IPv4 + IPV6
else { Trv[i] += 8*v;
if (Trv[i] > 80) delIElt(i); // On laisse 5 min.
}
}
}
tim0 = time(NULL);
return;
}
void ajoutParam(char * ficp, char * param)
{
FILE * fw;
fw = fopen(ficp,"a");
fwrite(param,strlen(param),1,fw);
fwrite("\n",1,1,fw);
fclose(fw);
}
static int NBin=0, NBout=0;
void prInOut(void)
{
printf(" %d messages DNS: %d requetes, %d reponses.\n",NBout+NBin,NBout,NBin);
}
int printQ(char * q)
{
char *rep=NULL;
size_t lr = 0;
int n;
while (1) {
printf("Voulez-vous %s ?\n Taper O (OUI) ou N (NON) :\n",q);
if ((n = getline(&rep, &lr, stdin)) != 2) continue;
if (*rep == 'O') return 1;
if (*rep == 'N') return 0;
}
}
void pr_encours(void)
{
printf(" ...\r"); fflush(stdout);
}
#define SUNIC "|sort|uniq"
#define CHLOG "/var/log/user.log"
#define CHLOGREP "/var/log/user.log|grep "
#define CUT6 "|cut -d' ' -f6"
#define CUT7S "|cut -d' ' -f7-"
#define FHISTO ".octave_history"
#define AWK5 "|awk '{ print $5}'"
#define AWK4 "|awk '{ print $4}'"
#define DREJ "^REJECT "
void * fct_com(void * p)
{
int REQ=1;
char *cmd = NULL, *fauth, com[100];
int n2;
pid_t pid;
fauth = (char*)p;
pid = getpid();
read_history(FHISTO);
if (REPR) comsh("reset");
while (REQ) {
if (kill(pid,SIGUSR1) < 0) { /* verif processus acquisition */
ENDT=1;
write(p1[1],"\n",1);
}
free(cmd);
cmd = readline("O-> ");
if ((n2 = strlen(cmd)) > 0) {
write(p1[1],"\n",1);
add_history(cmd);
switch (*cmd) {
case '+' :
if (*(cmd+1) != '\0') {
if (litligne(cmd+1)) { /* ajout au fichier fauth */
if (debloqueIP(cmd+1,NULL)) printf("Element non valable !\n");
else {
if (printQ("ajouter au fichier parametres"))
ajoutParam(fauth,cmd+1);
listeAllow();
}
} else printf("Erreur ajout param. !\n");
} else listeAllow();
break;
case '-' :
if (*(cmd+1) != '\0') {
if (litligne(cmd)) { /* ajout au fichier fauth */
if (rebloqueIP(cmd+1)) printf("Element non valable !\n");
else {
if (printQ("ajouter au fichier parametres"))
ajoutParam(fauth,cmd);
listeDeny();
}
} else printf("Erreur ajout param. !\n");
} else listeDeny();
break;
case 'l' :
listElt(cmd[1]);
printf(" %s Utilise %d elts/%d : %.2f%% (Max. %d)!\n",ctime(&tim1),iT,
NBT, (float)(iT*100)/(float)NBT, MaxElt);
prInOut();
break;
case 't' :
if (*(cmd+1) != '\0') {
if ((cmd[1] == '+') || (cmd[1] == '-')) {
if ((cmd[1] == '+') && (Trace < TMAX)) Trace++;
else {
if ((cmd[1] == '-') && (Trace > TMIN)) Trace--;
else printf("Erreur: niveau dans [%d, %d].\n",TMIN,TMAX);
}
} else printf("Erreur: Utiliser t+ ou t- !\n");
}
printf(" Trace niveau %d\n",Trace);
break;
case 'a' :
if (*(cmd+1) != '\0') printf("ignore %s\n",cmd+1);
sprintf(com,"grep '%s\\[%d\\]%s' %s%s%s",NPROG,pid,".* ok",
CHLOG,CUT6,SUNIC);
comsh(com);
break;
case 'i' :
if (*(cmd+1) != '\0') printf("ignore %s\n",cmd+1);
sprintf(com,"grep '%s\\[%d\\]%s' %s%s%s",NPROG,pid,".* DENY",
CHLOG,CUT6,SUNIC);
comsh(com);
break;
case 'e' :
if (*(cmd+1) != '\0') printf("ignore %s\n",cmd+1);
sprintf(com,"grep '%s\\[%d\\]%s' %s%s%s",NPROG,pid,".* ACCEPT",
CHLOG,CUT6,SUNIC);
comsh(com);
break;
case 'E' :
if (*(cmd+1) != '\0') printf("ignore %s\n",cmd+1);
sprintf(com,"grep '%s\\[%d\\]%s' %s",NPROG,pid,".*ERR: ",CHLOG);
comsh(com);
break;
case 'L' :
if (*(cmd+1) != '\0') printf("ignore %s\n",cmd+1);
sprintf(com,"grep '%s\\[%d\\]' %s%s",NPROG,pid,
CHLOGREP,"-v 'Re[pq]. '");
comsh(com);
break;
case 'T' :
if (*(cmd+1) != '\0')
sprintf(com,"grep '%s\\[%d\\].*%s' %s%s",NPROG,pid,cmd+1,
CHLOGREP," 'Re[pq]. '");
else
sprintf(com,"grep '%s\\[%d\\]' %s%s",NPROG,pid,
CHLOGREP," 'Re[pq]. '");
comsh(com);
prInOut();
break;
case '>' :
if (*(cmd+1) != '\0') printf("ignore %s\n",cmd+1);
sprintf(com,"grep '%s\\[%d\\]' %s%s%s%s",NPROG,pid,
CHLOGREP," 'Req. '",CUT7S,SUNIC);
comsh(com);
prInOut();
break;
case '<' :
if (*(cmd+1) != '\0') printf("ignore %s\n",cmd+1);
sprintf(com,"grep '%s\\[%d\\]' %s%s%s%s",NPROG,pid,
CHLOGREP," 'Rep. '",CUT7S,SUNIC);
comsh(com);
prInOut();
break;
case 'r' :
if (*(cmd+1) != '\0') printf("ignore %s\n",cmd+1);
sprintf(com,"%s -L|grep %s%s%s",IPT,DREJ,AWK5,SUNIC);
pr_encours();
comsh(com);
break;
case 'R' :
if (*(cmd+1) != '\0') printf("ignore %s\n",cmd+1);
sprintf(com,"%s -L|grep %s%s%s",IP6T,DREJ,AWK4,SUNIC);
pr_encours();
comsh(com);
break;
case 'S' :
if (*(cmd+1) != '\0') printf("ignore %s\n",cmd+1);
RUN = 0;
REQ = 0;
write(p1[1],"\n",1);
break;
case 'V' :
if (*(cmd+1) != '\0') printf("ignore %s\n",cmd+1);
printf("Version %s\n",Version);
prInOut();
break;
case ' ' :
if (*(cmd+1) != '\0') comsh(cmd+1);
break;
default :
printf("+url\t: Allow (autoriser une Url)\n");
printf("-url\t: Deny (interdire une Url)\n");
printf("a\t: Autorisations suivant analyse\n");
printf("i\t: Interdictions suivant analyse\n");
printf("e\t: Exceptions suivant analyse\n");
printf("E\t: Liste des erreurs\n");
printf("l[+|-]\t: Liste des elements dynamiques\n");
printf("L\t: Logs du systeme\n");
printf("r\t: Rejets actifs IPv4 (dure plusieurs sec.)\n");
printf("R\t: Rejets actifs IPv6 (dure plusieurs sec.)\n");
printf("S\t: Stopper\n");
printf("t+|-\t: Niveau de trace : 0 (off) => 3\n");
printf("T[mot]\t: Traces des demandes/reponses contenant mot\n");
printf(">\t: Traces des demandes triees\n");
printf("<\t: Traces des reponses triees\n");
printf("V\t: Version\n");
break;
}
}
}
write_history(FHISTO);
free(cmd);
/* fin dialogue */
pthread_exit(NULL);
}
void getIface(void)
{
FILE * fd;
char *line = NULL, *s, *w;
size_t ll = 0;
int n;
if ((fd = fopen("/proc/net/route","r")) == NULL) {
perror("route"); return;
}
while ((n = getline(&line, &ll, fd)) > 0) {
if ((s=strstr(line,"00000000"))==NULL) continue;
w=line;
while ((*w != ' ') && (*w != '\t')) w++;
*w = '\0';
w++;
while ((*w == ' ') || (*w == '\t')) w++;
if (s==w) { /* ok */
IFACE = (char*)malloc(strlen(line)+1);
strcpy(IFACE,line);
break;
}
}
free(line);
fclose(fd);
}
#define Vie (ie >= 0)
int main(int N, char * P[])
{
pthread_t thid;
FILE * fp;
char *analyse="tcpdump", *line = NULL, *cmd = NULL, *s1, *s2, *refU;
char *fauth = "auth1.txt", *strR = "-R", *Pars, strPID[8], **NP;
size_t ll = 0, lc = 0;
ssize_t n,n2;
int Inter=0, LogC=0, i, ie, np=0, opt;
if ((NPROG = strrchr(P[0],(int)'/')) == NULL) NPROG=P[0];
else NPROG++;
sprintf(strPID,"%d",getpid());
/* verif. options */
while ((opt = getopt(N, P, "ilp:R:t")) != -1) {
switch (opt) {
case 'i':
Inter = 1;
break;
case 'l':
LogC = 1;
break;
case 't':
Trace = TMIN+1;
break;
case 'p':
fauth = optarg;
break;
case 'R':
REPR=1;
np = atoi(optarg);
break;
default: /* '?' */
fprintf(stderr, "Utilisation: %s [options]\nAvec les options :\n", NPROG);
fprintf(stderr, "\t-i : mode interactif,\n");
fprintf(stderr, "\t-l : log des requetes,\n");
fprintf(stderr, "\t-p fichier : nom du fichier parametres (%s par defaut),\n",fauth);
fprintf(stderr, "\t-t : avec trace.\n");
return 1;
}
}
if ((REPR) && (np != getpid())) {
fprintf(stderr,"Erreur reprise %d\n", np);
return 1;
}
if (optind < N) {
fprintf(stderr,"Parametre inconnu : %s\n", P[optind]);
return 1;
}
getIface();
if (REPR) {
while (IFACE==NULL) { sleep(1); getIface(); }
} else {
if (IFACE == NULL) {
fprintf(stderr,"Interface reseau absente !\n");
return 9;
}
}
printf("%s %s sur %s\n", NPROG, Version, IFACE);
/* verif privilege root */
if ((getuid() > 0) && (geteuid() > 0)) {
fprintf(stderr,"A executer sous root !\n");
return 2;
}
if (T1) printf("T1: Fichier parametres = %s\n",fauth);
signal(SIGUSR1,SIG_IGN);
if (pipe(p1) < 0) {
perror("pipe"); return 3;
}
openlog(NULL,LOG_PID,0);
/* on lance le fils : */
if ((pid = fork()) < 0) {
perror("fork"); return 4;
}
if (pid == 0) {
signal(SIGINT,SIG_IGN);
close(0);
close(p1[0]);
dup2(p1[1],1); /* stdout dans p1 */
dup2(p1[1],2); /* idem stderr */
setsid();
execlp(analyse,analyse,"-tn","-i",IFACE,"port","53",NULL);
perror("execl");
return 5;
}
if (Inter) signal(SIGINT,SIG_IGN);
else signal(SIGINT,interup);
if ((np=initIPT())!=0) {
if (T1) printf("Erreur initIPT %d !!??\n",np);
syslog(LOG_WARNING, "ERR: Erreur initIPT %d !!??\n",np);
}
/* lecture des listes */
lectliste(fauth);
if (T1) recaplistes();
sleep(1); /* attend le fils en place */
if (kill(pid,SIGUSR1) < 0) return 6;
signal(SIGCHLD,interup);
/*
fcntl(p1[0], F_SETFL, O_NONBLOCK);
flag0 = fcntl(0, F_GETFL, O_NONBLOCK);
fcntl(0, F_SETFL, O_NONBLOCK);
*/
/* on analyse la sortie de p1 */
if ((fp = fdopen(p1[0],"r")) == NULL) {
perror("fdopen"); return 7;
}
fcntl(p1[0], F_SETPIPE_SZ,1048576);
if (T1) printf("Depart %s %s PIDF:%d !\n",NPROG, strPID,pid);
if (T1) printf("Capacite pipe : %ld bytes\n", (long)fcntl(p1[0], F_GETPIPE_SZ));
np=0;
/* lancement du thread */
if (Inter) {
if (pthread_create(&thid,NULL,fct_com,(void*)fauth) != 0) {
fprintf(stderr,"Erreur pthread_create !\n"); return 9;
}
}
while (RUN) {
tachePer1();
if ((n = getline(&line, &ll, fp)) > 0) {
if (ENDT) {
printf("Erreur : plus de tache d'analyse !\n"); break;
}
if (RUN == 0) break;
if ((n==1) && (*line=='\n')) continue;
if (np==0) { np++;
if (REPR) syslog(LOG_INFO,"Reprise de l'analyse !");
else syslog(LOG_INFO,"Debut de l'analyse !");
}
/* analyse */
if ((s1=strstr(line, " > ")) == NULL) continue;
if (strncmp(s1-3,".53",3) == 0) { /* REPONSE */
if ((s2=strstr(s1+3, ":")) == NULL) continue;
NBin++;
*s2 = '\0';
s1 = s2 -1;
while (*s1 != '.') s1--;
np = atoi(s1+1);
if ((ie = isElt(np)) == -1) { /* Elt OK ou ABSENT ! */
ie = isElt(-np);
s1 = s2+1;
if ((s2=strstr(s1, " A ")) != NULL) { /* IPv4 */
s2++;
s1 = strrchr(s2,(int)' ');
*s1 = '\0';
if (LogC) syslog(LOG_INFO,"Rep. %d %s",np,s2);
if Vie {
markElt(ie,4); refU = Turl[ie];
} else {
if (T1) printf("Elt %d non trouve !!??\n",np);
syslog(LOG_WARNING,"ERR: Elt %d non trouve !!??\n",np);
refU = NULL;
}
if (!verifIPOk(s2, refU))
if Vie syslog(LOG_INFO,"Deblocage IP4 %s",refU);
} else {
if ((s2=strstr(s1, " AAAA ")) != NULL) { /* IPv6 */
s2++;
s1 = strrchr(s2,(int)' ');
*s1 = '\0';
if (LogC) syslog(LOG_INFO,"Rep. %d %s",np,s2);
if Vie markElt(ie,2);
dropIP6(s2);
} else {
if Vie markElt(ie,1);
}
}
continue;
}
s1 = s2+1;
if ((s2=strstr(s1, " A ")) == NULL) {
if ((s2=strstr(s1, " AAAA ")) == NULL) {
markElt(ie,1);
} else { /* traitement IPv6 */
s2++;
if (LogC) syslog(LOG_INFO,"Rep. %d %s",np,s2);
s1 = strrchr(s2,(int)' ');
*s1 = '\0';
if (markElt(ie,2)) dropIP6(s2);
}
continue;
}
/* IPv4 REJECT */
s2++;
s1 = strrchr(s2,(int)' ');
*s1 = '\0';
if (LogC) syslog(LOG_INFO,"Rep. %d %s",np,s2);
syslog(LOG_INFO,"%s DENY",Turl[ie]);
if (markElt(ie,4)) dropIP(s2);
} else { /* DEMANDE */
NBout++;
*s1 = '\0';
s2 = s1 +1;
while (*s1 != '.') s1--;
np = atoi(s1+1);
if ((s1=strstr(s2, " A? ")) == NULL) continue;
s1 += 4;
s2 = s1 +1;
while (*s2 != ' ') s2++;
*(s2-1) = '\0'; /* on supprime le '.' */
if (LogC) syslog(LOG_INFO,"Req. %d %s",np,s1);
if (strstr(s1, ".") == NULL) { /* il doit en rester 1 */
if (T1) printf("Ignore : %d %s !\n",np,s1);
syslog(LOG_WARNING,"ERR: Ignore %d %s !\n",np,s1);
continue;
}
if (!isDeny(s1)) { // V2 ! On enregistre le OK en NEGATIF
if (isElt(-np) < 0) {
addElt(-np,s1);
syslog(LOG_INFO,"%s ok",s1);
}
continue;
}
if (isElt(np) < 0) {
i=addElt(np,s1);
if (T3) printf("T3: addElt %d %d/%d\n",NbElt,i,NBT);
}
}
}
if (REQ) {
printf("Taper votre commande : H pour help !\n");
if ((n2 = getline(&cmd, &lc, stdin)) > 0) {
switch (*cmd) {
case 'C' :
REQ = 0;
break;
case 'L' :
listElt(cmd[1]);
printf(" %s Utilise %d elts/%d : %.2f%% (Max. %d)!\n",
ctime(&tim1),iT,NBT,(float)(iT*100)/(float)NBT,MaxElt);
break;
case 'S' :
RUN = 0;
REQ = 0;
break;
default :
printf("C\t: continuer\n");
printf("L\t: liste des elts\n");
printf("S\t: stopper\n");
break;
}
}
}
}
syslog(LOG_INFO,"Fin de l'analyse !");
free(line);
free(cmd);
kill(pid,SIGTERM);
close(p1[0]);
close(p1[1]);
closelog();
if (ENDT) { /* relance auto */
comsh("reset");
if (T1) printf("Relance auto %s dans %d sec. ...\n",strPID, DELAYR);
sleep(DELAYR); /* attend N s */
NP = (char**)malloc((sizeof(Pars))*(N+3));
for (i=0;i