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