/*******************************************************************
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
*******************************************************************/
/* lich.c : listes chainees pour creer les elements (url, ip, ip6 ) */
#include
#include
#include
#include
#include "lich.h"
/* variables globales */
static long LC_SIZE = (long)0;
static long LC_SIZEL = (long)0;
static struct elt * First=FIN; /* depart du chainage */
static pthread_mutex_t mut_Elt = PTHREAD_MUTEX_INITIALIZER;
long getLC_SIZE(void) { return LC_SIZE; }
long getLC_SIZEL(void) { return LC_SIZEL; }
struct elt ** getFirst(void) { return &First; }
pthread_mutex_t * getMutElt(void) { return &mut_Elt; }
struct elt * ajouteElt(char * n, int s)
{
void * M;
struct elt *e, **D;
long sizeMore;
int i,c;
/* creation de l'espace memoire de l'element */
if ((M = malloc(sizeof(struct elt))) == NULL) {
perror(Y(p00)); return FIN;
}
sizeMore = sizeof(struct elt);
e = (struct elt *)M;
/* creation de l'espace memoire de l'url */
if ((M = malloc(strlen(n)+1)) == NULL) {
perror(Y(p00)); return FIN;
}
e->url = (char *)M;
sizeMore += strlen(n)+1;
/* remplissage de l'element */
strcpy(e->url,n);
e->stat = s;
e->ip = VIDE;
e->ip6 = VIDE;
e->next = FIN;
for (i=0;ino[i] = 0;
/* boucle sur l'adresse du suivant */
D=&First;
pthread_mutex_lock(&mut_Elt);
while (*D != FIN) {
if ((c=strcmp((*D)->url,n)) > 0) { /* insertion avant */
e->next = *D;
break;
}
if (c == 0) { /* deja present */
pthread_mutex_unlock(&mut_Elt);
free(M);
free((void*)e);
return *D;
}
D = &((*D)->next);
}
*D = e;
LC_SIZE += sizeMore;
pthread_mutex_unlock(&mut_Elt);
return e;
}
static void ajouteLib(struct lib **Lib, char *l)
{
void * M;
struct lib *e,**D;
long sizeMore;
int c;
/* creation de l'espace memoire du libelle */
if ((M = malloc(sizeof(struct lib))) == NULL) {
perror(Y(p00)); return;
}
sizeMore = sizeof(struct lib);
e = (struct lib *)M;
/* creation de l'espace memoire du libelle */
if ((M = malloc(strlen(l)+1)) == NULL) {
perror(Y(p00)); return;
}
sizeMore += strlen(l)+1;
e->lib = (char *)M;
/* remplissage de l'element */
strcpy(e->lib,l);
e->next = VIDE;
D=Lib;
pthread_mutex_lock(&mut_Elt);
while (*D != VIDE) {
if ((c=strcmp((*D)->lib,l)) > 0) { /* insertion avant */
e->next = *D;
break;
}
if (c == 0) { /* deja present */
pthread_mutex_unlock(&mut_Elt);
free(M);
free((void*)e);
return;
}
D = &((*D)->next);
}
*D = e;
LC_SIZE += sizeMore;
pthread_mutex_unlock(&mut_Elt);
}
static void ajouteLibD(struct libd **Lib, char *l, char * l2) /*Libs:l2=NULL*/
{
void * M, *M2;
struct libd *e,**D;
long sizeMore;
int c;
/* creation de l'espace memoire du libelle */
if ((M = malloc(sizeof(struct libd))) == NULL) {
perror(Y(p00)); return;
}
sizeMore = sizeof(struct libd);
e = (struct libd *)M;
/* creation de l'espace memoire du libelle */
if ((M = malloc(strlen(l)+1)) == NULL) {
perror(Y(p00)); return;
}
sizeMore += strlen(l)+1;
e->lib = (char *)M;
if (l2 == NULL) e->lib2 = NULL;
else {
if ((M2 = malloc(strlen(l2)+1)) == NULL) {
perror(Y(p00)); return;
}
sizeMore += strlen(l2)+1;
e->lib2 = (char *)M2;
strcpy(e->lib2,l2);
}
/* remplissage de l'element */
strcpy(e->lib,l);
e->next = VIDD;
D=Lib;
pthread_mutex_lock(&mut_Elt);
while (*D != VIDD) {
if ((c=strcmp((*D)->lib,l)) > 0) { /* insertion avant */
e->next = *D;
break;
}
if (c == 0) { /* deja present */
pthread_mutex_unlock(&mut_Elt);
free(M);
if (l2 != NULL) free(M2);
free((void*)e);
return;
}
D = &((*D)->next);
}
*D = e;
if (l2==NULL) LC_SIZE += sizeMore;
else LC_SIZEL += sizeMore;
pthread_mutex_unlock(&mut_Elt);
}
void ajouteIp(struct elt *E, char *ip, int v6)
{
if (v6) ajouteLib(&(E->ip6), ip);
else ajouteLib(&(E->ip), ip);
}
struct elt * getNum(int n)
{
struct elt **D;
int i;
D=&First;
while (*D != FIN) {
for (i=0; i< ELT_NBN; i++) if ((*D)->no[i] == n) return *D;
D = &((*D)->next);
}
return FIN; /* pas trouve ! */
}
/* Listes Cidr, Cidr6, Allow et Deny */
static struct libd *Libs = VIDD;
static struct libd *Cidr = VIDD;
static struct libd *Cidr6 = VIDD;
static struct lib *Allow = VIDE;
static struct lib *Deny = VIDE;
void ajouteLibs(char * e, char * l) { ajouteLibD(&Libs, e, l); }
void ajouteCidr(char * u) { ajouteLibD(&Cidr,u,NULL); }
void ajouteCidr6(char * u) { ajouteLibD(&Cidr6,u,NULL); }
void ajouteAllow(char * u) { ajouteLib(&Allow,u); }
void ajouteDeny(char * u) { ajouteLib(&Deny,u); }
int estSousDomaine(char * u, char * d)
{
int t, tu;
char *su;
tu = strlen(u);
t = strlen(d);
if (tu < t) return 0;
su = u + tu - t;
if (strcmp(su,d) == 0) {
if (*d == '.') return 1;
if (su==u) return 1;
if (*(su-1)=='.') return 1;
}
return 0;
}
static int addLib2(struct libd **L, char * u, char *l)
{
struct libd **D;
void *M;
int ret=0;
D=L;
pthread_mutex_lock(&mut_Elt);
while (*D != VIDD) {
if (strcmp(u,(*D)->lib)==0) { ret = 1; break; }
D = &((*D)->next);
}
if (ret) {
if ((*D)->lib2 != NULL) free((*D)->lib2);
/* creation de l'espace memoire de lib2 */
if ((M = malloc(strlen(l)+1)) == NULL) perror(Y(p00));
else { /* remplissage de l'element */
(*D)->lib2 = (char *)M;
LC_SIZE += strlen(l)+1;
strcpy((*D)->lib2,l);
}
}
pthread_mutex_unlock(&mut_Elt);
return ret;
}
int addNameCidr(char * u, char *l) { return addLib2(&Cidr,u,l); }
int addNameCidr6(char * u, char *l) { return addLib2(&Cidr6,u,l); }
static char * getEntErr(char c)
{
static char E[8];
E[3]='s';
E[1]=c;
E[2]='%';
*E='?';
E[4]='\0';
return E;
}
static char * getLib2(struct libd **L, char * u, int Lock)
{
struct libd **D;
int ret=0;
D=L;
if (Lock) pthread_mutex_lock(&mut_Elt);
while (*D != VIDD) {
if (strcmp(u,(*D)->lib)==0) { ret = 1; break; }
D = &((*D)->next);
}
if (Lock) pthread_mutex_unlock(&mut_Elt);
if (ret) return (*D)->lib2;
if (Lock == 0) { /* pour l'instant seult libs */
fprintf(stderr,getEntErr('L'),u);
exit(129);
}
return NULL;
}
char * getNameCidr(char * u) { return getLib2(&Cidr,u,1); }
char * getNameCidr6(char * u) { return getLib2(&Cidr6,u,1); }
char * getLibelle(char * e) { return getLib2(&Libs,e,0); }
static int estDans(struct lib **L, char * u)
{
struct lib **D;
int ret=0;
D=L;
pthread_mutex_lock(&mut_Elt);
while (*D != VIDE) {
if (estSousDomaine(u,(*D)->lib)) { ret = 1; break; }
D = &((*D)->next);
}
pthread_mutex_unlock(&mut_Elt);
return ret;
}
int inAllow(char * u) { return estDans(&Allow,u); }
int inDeny(char * u) { return estDans(&Deny,u); }
void listeLib(struct lib **L)
{
struct lib **D;
D=L;
while (*D != VIDE) {
printf(Y(f49),(*D)->lib);
D = &((*D)->next);
}
}
void listeLibD(struct libd **L)
{
struct libd **D;
int i=0;
D=L;
while (*D != VIDD) {
printf(Y(f50),(*D)->lib,(*D)->lib2);
i++;
D = &((*D)->next);
}
printf(Y(f65),i);
}
static void listeLibD2(struct libd **L, char *s)
{
struct libd **D;
int i=0;
char *d;
D=L;
while (*D != VIDD) {
if (*s != '\0') {
if (strstr((*D)->lib,s) == NULL) {
if (strstr((*D)->lib2,s) == NULL) {
D = &((*D)->next); continue;
}
}
}
printf(Y(f66),(*D)->lib);
d = (*D)->lib2;
printf("\"");
while (*d != '\0') {
if (*d == '\n') printf("\\n");
else {
if (*d == '\r') printf("\\r");
else {
if (*d == '\t') printf("\\t");
else {
if (*d == '\e') printf("\\e");
else {
if (*d == '\\') printf("\\");
printf("%c",*d);
}
}
}
}
d++;
}
printf("\"\n");
i++;
D = &((*D)->next);
}
printf(Y(f65),i);
}
void listeAllow(void) { printf(Y(i13)); listeLib(&Allow); }
void listeDeny(void) { printf(Y(i14)); listeLib(&Deny); }
void listeLibs(char *s) { listeLibD2(&Libs,s); }