version 0.70
[irssistats] / irssistats.c
index d7e974d..4e637a5 100644 (file)
@@ -1,5 +1,5 @@
 /*
 /*
- * irssistats version 0.62
+ * irssistats version 0.70
  *
  * This tool generates IRC stats based on irssi logs.
  * Usage: irssistats [/path/to/file.conf]
  *
  * This tool generates IRC stats based on irssi logs.
  * Usage: irssistats [/path/to/file.conf]
@@ -20,7 +20,7 @@
  * You should have received a copy of the GNU General Public License
  * along with this program; if not, write to the Free Software
  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  * You should have received a copy of the GNU General Public License
  * along with this program; if not, write to the Free Software
  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
-*/
+ */
 
 
 #include <sys/types.h>
 
 
 #include <sys/types.h>
 #include <stdlib.h>
 #include <time.h>
 #include <string.h>
 #include <stdlib.h>
 #include <time.h>
 #include <string.h>
+#ifdef __WIN32__
+#define GLOBALCONF "irssistats.conf"
+#else
+#define GLOBALCONF "/etc/irssistats.conf"
 #include <regex.h>
 #include <regex.h>
+#endif
 
 /* Config */
 #define BASEUSERS 1000
 
 /* Config */
 #define BASEUSERS 1000
@@ -43,7 +48,7 @@
 #define MINWORDLENGTH 5
 
 /* irssistats */
 #define MINWORDLENGTH 5
 
 /* irssistats */
-#define VERSION "0.62"
+#define VERSION "0.70"
 #define URL "http://royale.zerezo.com/irssistats/"
 
 /* Counters */
 #define URL "http://royale.zerezo.com/irssistats/"
 
 /* Counters */
@@ -412,6 +417,7 @@ char *keys[NBLANGUAGES][NBKEYS+1][2]= /* first key used for language name and ab
   },
   { /* Dutch language */
     /* contributed by Jeroen Ubbink <crasp@blackbyte.nl> */
   },
   { /* Dutch language */
     /* contributed by Jeroen Ubbink <crasp@blackbyte.nl> */
+    /* updated by Wouter HorrĂ© <wouter@ligezin.be> */
     { "Dutch",        "nl" },
     { "CHARSET",      "ISO-8859-1" },
     { "HEADER",       "Statistieken voor %s door %s" },
     { "Dutch",        "nl" },
     { "CHARSET",      "ISO-8859-1" },
     { "HEADER",       "Statistieken voor %s door %s" },
@@ -419,7 +425,7 @@ char *keys[NBLANGUAGES][NBKEYS+1][2]= /* first key used for language name and ab
     { "LASTDAYS",     "Statistieken van de laatste dagen" },
     { "TOPHOURS",     "Statistieken per uur" },
     { "TOPUSERS",     "Meest actieve mensen" },
     { "LASTDAYS",     "Statistieken van de laatste dagen" },
     { "TOPHOURS",     "Statistieken per uur" },
     { "TOPUSERS",     "Meest actieve mensen" },
-    { "OTHERS",       "Er zijn nog %d niet in de top..." },
+    { "OTHERS",       "Er zijn nog %d mensen die de top niet haalden..." },
     { "NBLINES",      "regels" },
     { "NICK",         "nick" },
     { "AVGLETTERS",   "letters/lijn" },
     { "NBLINES",      "regels" },
     { "NICK",         "nick" },
     { "AVGLETTERS",   "letters/lijn" },
@@ -438,7 +444,7 @@ char *keys[NBLANGUAGES][NBKEYS+1][2]= /* first key used for language name and ab
     { "BIGNUMBERS",   "Enkele grote aantallen..." },
     { "NUMBERS",      "numbers" },
     { "TIME",         "%d regels (%d dagen) verwerkt in %d seconden" },
     { "BIGNUMBERS",   "Enkele grote aantallen..." },
     { "NUMBERS",      "numbers" },
     { "TIME",         "%d regels (%d dagen) verwerkt in %d seconden" },
-    { "FOOTER",       "Statistieken gegenereert door" },
+    { "FOOTER",       "Statistieken gegenereerd door" },
     { "C_SMILE",      "is vaak vrolijk :)" },
     { "C_FROWN",      "is vaak droevig :(" },
     { "C_EXCLAM",     "schreeuwt veel !" },
     { "C_SMILE",      "is vaak vrolijk :)" },
     { "C_FROWN",      "is vaak droevig :(" },
     { "C_EXCLAM",     "schreeuwt veel !" },
@@ -556,9 +562,10 @@ char *L(char *key)
 int debug=1; /* 0 = none ; 1 = normal ; 2 = verbose */
 char channel[MAXLINELENGTH]="set_channel_in_config_file";
 char maintainer[MAXLINELENGTH]="set_maintainer_in_config_file";
 int debug=1; /* 0 = none ; 1 = normal ; 2 = verbose */
 char channel[MAXLINELENGTH]="set_channel_in_config_file";
 char maintainer[MAXLINELENGTH]="set_maintainer_in_config_file";
-char theme[MAXLINELENGTH]="default,blue,dark,grayscale,namour,pisg,zeduel,zerezo";
+char theme[MAXLINELENGTH]="default,biseau,blue,dark,damier,grayscale,namour,niflheim,pisg,zeduel,zerezo";
 int refresh_time=0; /* 0 = disabled */
 int w3c_link=1; /* 0 = disabled */
 int refresh_time=0; /* 0 = disabled */
 int w3c_link=1; /* 0 = disabled */
+int logo=1; /* 0 = disabled */
 char header[MAXLINELENGTH]="none";
 char footer[MAXLINELENGTH]="none";
 int totallines=0;
 char header[MAXLINELENGTH]="none";
 char footer[MAXLINELENGTH]="none";
 int totallines=0;
@@ -566,6 +573,7 @@ time_t debut;
 int top_words=1; /* 0 = disabled */
 int ranking=0; /* 0 = lines ; 1 = words ; 2 = letters */
 int quarter=0; /* 1 = enabled */
 int top_words=1; /* 0 = disabled */
 int ranking=0; /* 0 = lines ; 1 = words ; 2 = letters */
 int quarter=0; /* 1 = enabled */
+int photo_size=60;
 
 struct user
 {
 
 struct user
 {
@@ -576,6 +584,7 @@ struct user
   int hours[4];
   char quote[MAXQUOTELENGTH+1];
   int counters[NBCOUNTERS];
   int hours[4];
   char quote[MAXQUOTELENGTH+1];
   int counters[NBCOUNTERS];
+  char *photo;
   int temp;
 } *users;
 int nbusers=0;
   int temp;
 } *users;
 int nbusers=0;
@@ -729,6 +738,7 @@ int dichotomic(char *nick)
       strcpy(users[i].quote,users[i-1].quote);
       for (j=0;j<NBCOUNTERS;j++) users[i].counters[j]=users[i-1].counters[j];
       users[i].temp=users[i-1].temp;
       strcpy(users[i].quote,users[i-1].quote);
       for (j=0;j<NBCOUNTERS;j++) users[i].counters[j]=users[i-1].counters[j];
       users[i].temp=users[i-1].temp;
+      users[i].photo=users[i-1].photo;
     }
     strcpy(users[start].nick,nick);
     users[start].lines=0;
     }
     strcpy(users[start].nick,nick);
     users[start].lines=0;
@@ -738,6 +748,7 @@ int dichotomic(char *nick)
     users[start].quote[0]='\0';
     for (j=0;j<NBCOUNTERS;j++) users[start].counters[j]=0;
     users[start].temp=0;
     users[start].quote[0]='\0';
     for (j=0;j<NBCOUNTERS;j++) users[start].counters[j]=0;
     users[start].temp=0;
+    users[start].photo=NULL;
   }
   return(start);
 }
   }
   return(start);
 }
@@ -758,8 +769,19 @@ void parse_log(char *logfile)
   while (fgets(line,MAXLINELENGTH,fic)!=NULL)
   {
     /* remove \n */
   while (fgets(line,MAXLINELENGTH,fic)!=NULL)
   {
     /* remove \n */
-    for (i=0;line[i]!=0;i++);
-    if (i>=MAXLINELENGTH-1) { fprintf(stderr,"line %d is too long\n",totallines); exit(1); }
+    for (i=0;line[i]!=0 && i<MAXLINELENGTH-1;i++);
+    if (i>=MAXLINELENGTH-1) { 
+      if(debug){
+        fprintf(stderr,"line %d is too long, skipping\n",totallines+1); 
+      }
+      continue; 
+    }
+    if (i<8) {
+      if(debug) {
+        fprintf(stderr, "line %d is too short to be valid, skipping\n",totallines+1);
+      }
+      continue;
+    }
     line[i-1]='\0';
     pos=0;
     totallines++;
     line[i-1]='\0';
     pos=0;
     totallines++;
@@ -783,7 +805,13 @@ void parse_log(char *logfile)
     }
     else if (strncmp("-!-",&line[6],3)==0) /* 00:00 -!- Nick something... */
     {
     }
     else if (strncmp("-!-",&line[6],3)==0) /* 00:00 -!- Nick something... */
     {
-      for (i=10;line[i]!=' ';i++);
+      for (i=10;line[i]!=' ' && i <= 10 + MAXNICKLENGTH;i++);
+      if(i > 10 + MAXNICKLENGTH) {
+        if(debug) {
+          fprintf(stderr,"nick on line %d is too long, skipping line\n",totallines); 
+        }
+        continue;
+      }
       line[i]='\0';
       nick=&line[10];
       message=&line[i+1];
       line[i]='\0';
       nick=&line[10];
       message=&line[i+1];
@@ -828,14 +856,26 @@ void parse_log(char *logfile)
       hour=atoi(line);
       if (line[7]=='*') /* 00:00  * Nick the message */
       {
       hour=atoi(line);
       if (line[7]=='*') /* 00:00  * Nick the message */
       {
-        for (i=9;line[i]!=' ';i++);
+        for (i=9;line[i]!=' ' && i <= 9 + MAXNICKLENGTH;i++);
+        if(i > 9 + MAXNICKLENGTH) {
+          if(debug) {
+            fprintf(stderr,"nick on line %d is too long, skipping line\n",totallines); 
+          }
+          continue; 
+        }
         nick=&line[9];
         message=&line[i+1];
       }
       else if (line[7]=='>') /* 00:00 <>>>?Nick<<<> the personal message */
                              /* 00:00 <>>?Nick<<> the personal message */
       {
         nick=&line[9];
         message=&line[i+1];
       }
       else if (line[7]=='>') /* 00:00 <>>>?Nick<<<> the personal message */
                              /* 00:00 <>>?Nick<<> the personal message */
       {
-        for (i=10;line[i]!='<';i++);
+        for (i=10;line[i]!='<' && i <= 10 + MAXNICKLENGTH;i++);
+         if(i > 10 + MAXNICKLENGTH) { 
+          if(debug) {
+            fprintf(stderr,"nick on line %d is too long, skipping line\n",totallines); 
+          }
+          continue; 
+        }
         nick=&line[10];
         if (line[9]=='>') nick++;
         message=&line[i+5];
         nick=&line[10];
         if (line[9]=='>') nick++;
         message=&line[i+5];
@@ -853,7 +893,13 @@ void parse_log(char *logfile)
             nickstart = 7;
         }
           
             nickstart = 7;
         }
           
-        for (i=nickstart;line[i]!='>';i++);
+        for (i=nickstart;line[i]!='>' && i <= nickstart + MAXNICKLENGTH;i++);
+        if(i > nickstart + MAXNICKLENGTH) { 
+          if(debug) {
+            fprintf(stderr,"nick on line %d is too long, skipping line\n",totallines); 
+          }
+          continue; 
+        }
         nick=&line[nickstart];
         message=&line[i+2];
       }
         nick=&line[nickstart];
         message=&line[i+2];
       }
@@ -913,6 +959,7 @@ void parse_log(char *logfile)
   if (debug) printf(" done\n");
 }
 
   if (debug) printf(" done\n");
 }
 
+#ifndef __WIN32__
 void parse_nick(char *nickfile)
 {
   FILE *fic;
 void parse_nick(char *nickfile)
 {
   FILE *fic;
@@ -958,6 +1005,24 @@ void parse_nick(char *nickfile)
   for (j=0;j<4;j++) users[i].hours[j]=-1;
   for (j=0;j<NBCOUNTERS;j++) users[i].counters[j]=-1;
 }
   for (j=0;j<4;j++) users[i].hours[j]=-1;
   for (j=0;j<NBCOUNTERS;j++) users[i].counters[j]=-1;
 }
+#endif
+
+void parse_photo(char *photofile)
+{
+  FILE *fic;
+  char line[MAXLINELENGTH];
+  int user;
+  
+  if ((fic=fopen(photofile,"rt"))==NULL) { fprintf(stderr,"can't open photo file \"%s\"\n",photofile); exit(1); }
+  while (fscanf(fic,"%s",line)==1)
+  {
+    user=dichotomic(line);
+    fscanf(fic,"%s",line);
+    users[user].photo=malloc(strlen(line)+1);
+    strcpy(users[user].photo,line);
+  }
+  fclose(fic);
+}
 
 void gen_xhtml(char *xhtmlfile)
 {
 
 void gen_xhtml(char *xhtmlfile)
 {
@@ -967,6 +1032,9 @@ void gen_xhtml(char *xhtmlfile)
   int user,max,temp;
   char line[MAXLINELENGTH];
   char *subtheme;
   int user,max,temp;
   char line[MAXLINELENGTH];
   char *subtheme;
+  int photos=0;
+  
+  for (i=0;i<nbusers;i++) if (users[i].photo!=NULL) photos=1;
   
   if ((fic=fopen(xhtmlfile,"wt"))==NULL) { fprintf(stderr,"can't open xhtml file \"%s\"\n",xhtmlfile); exit(1); }
   
   
   if ((fic=fopen(xhtmlfile,"wt"))==NULL) { fprintf(stderr,"can't open xhtml file \"%s\"\n",xhtmlfile); exit(1); }
   
@@ -1044,13 +1112,15 @@ void gen_xhtml(char *xhtmlfile)
   switch (ranking)
   {
     case 0:
   switch (ranking)
   {
     case 0:
-      fprintf(fic,"<table>\n<tr><th></th><th>%s</th><th>%s</th><th>%s</th><th colspan=\"2\">%s</th><th>%s</th></tr>\n",L("NICK"),L("NBLINES"),L("HOURS"),L("AVGLETTERS"),L("QUOTE"));
+      fprintf(fic,"<table>\n<tr><th></th><th>%s</th><th>%s</th><th>%s</th><th colspan=\"2\">%s</th><th>%s</th>\n",L("NICK"),L("NBLINES"),L("HOURS"),L("AVGLETTERS"),L("QUOTE"));
       break;
     default:
       /* "letters" and "words" ranking are not yet translated so we use the generic word "rank" ... */
       break;
     default:
       /* "letters" and "words" ranking are not yet translated so we use the generic word "rank" ... */
-      fprintf(fic,"<table>\n<tr><th></th><th>%s</th><th>%s</th><th>%s</th><th colspan=\"2\">%s</th><th>%s</th></tr>\n",L("NICK"),"rank",L("HOURS"),L("AVGLETTERS"),L("QUOTE"));
+      fprintf(fic,"<table>\n<tr><th></th><th>%s</th><th>%s</th><th>%s</th><th colspan=\"2\">%s</th><th>%s</th>\n",L("NICK"),"rank",L("HOURS"),L("AVGLETTERS"),L("QUOTE"));
       break;
   }
       break;
   }
+  if (photos) fprintf(fic,"<th></th>");
+  fprintf(fic,"</tr>");
   for (i=1;i<=NBUSERS;i++)
   {
     user=-1;
   for (i=1;i<=NBUSERS;i++)
   {
     user=-1;
@@ -1084,7 +1154,15 @@ void gen_xhtml(char *xhtmlfile)
       for (j=0;j<4;j++) if (users[user].hours[j]!=0) fprintf(fic,"<div class=\"h%d\" style=\"width:%dpx\"></div>",j+1,100*users[user].hours[j]/users[user].lines);
       fprintf(fic,"</td><td>%d</td><td><div class=\"hm\" style=\"width:%dpx\"></div></td><td>\"",users[user].lines!=0?users[user].letters/users[user].lines:0,users[user].lines!=0?users[user].letters/users[user].lines:0);
       printhtml(fic,users[user].quote);
       for (j=0;j<4;j++) if (users[user].hours[j]!=0) fprintf(fic,"<div class=\"h%d\" style=\"width:%dpx\"></div>",j+1,100*users[user].hours[j]/users[user].lines);
       fprintf(fic,"</td><td>%d</td><td><div class=\"hm\" style=\"width:%dpx\"></div></td><td>\"",users[user].lines!=0?users[user].letters/users[user].lines:0,users[user].lines!=0?users[user].letters/users[user].lines:0);
       printhtml(fic,users[user].quote);
-      fprintf(fic,"\"</td></tr>\n");
+      fprintf(fic,"\"</td>");
+      if (photos && users[user].photo!=NULL)
+      {
+        if (photo_size)
+          fprintf(fic,"<td class=\"tdphoto\"><a href=\"%s\"><img src=\"%s\" class=\"imgphoto\" width=\"%d\" height=\"%d\" alt=\"\" style=\"border: 0\" /></a></td>",users[user].photo,users[user].photo,photo_size,photo_size);
+        else
+          fprintf(fic,"<td class=\"tdphoto\"><img src=\"%s\" class=\"imgphoto\" alt=\"\" /></td>",users[user].photo,users[user].photo);
+      }
+      fprintf(fic,"</tr>\n");
       users[user].lines=-1;
       users[user].words=-1;
       users[user].letters=-1;
       users[user].lines=-1;
       users[user].words=-1;
       users[user].letters=-1;
@@ -1180,10 +1258,15 @@ void gen_xhtml(char *xhtmlfile)
     fprintf(fic,"<p>\n<a href=\"http://validator.w3.org/check/referer\"><img src=\"valid-xhtml10.png\" height=\"31\" width=\"88\" alt=\"Valid XHTML 1.0!\" /></a>\n");
     fprintf(fic,"<a href=\"http://jigsaw.w3.org/css-validator/check/referer\"><img src=\"valid-css.png\" height=\"31\" width=\"88\" alt=\"Valid CSS!\" /></a>\n</p>\n");
   }
     fprintf(fic,"<p>\n<a href=\"http://validator.w3.org/check/referer\"><img src=\"valid-xhtml10.png\" height=\"31\" width=\"88\" alt=\"Valid XHTML 1.0!\" /></a>\n");
     fprintf(fic,"<a href=\"http://jigsaw.w3.org/css-validator/check/referer\"><img src=\"valid-css.png\" height=\"31\" width=\"88\" alt=\"Valid CSS!\" /></a>\n</p>\n");
   }
-  fprintf(fic,"</div>\n\n</div>");
-  if (strcmp("none",header)==0)
+  fprintf(fic,"</div>\n\n");
+  
+  /* logo*/
+  if (logo) fprintf(fic,"<div class=\"logo\"></div>\n\n");
+  
+  /* end */
+  if (strcmp("none",footer)==0)
   {
   {
-    fprintf(fic,"\n\n</body>\n\n</html>\n");
+    fprintf(fic,"</div>\n\n</body>\n\n</html>\n");
   }
   else
   {
   }
   else
   {
@@ -1197,6 +1280,17 @@ void gen_xhtml(char *xhtmlfile)
 
 void parse_config(char *configfile)
 {
 
 void parse_config(char *configfile)
 {
+  void expand(char *path)
+  {
+    char temp[MAXLINELENGTH];
+    if (*path=='~')
+    {
+      snprintf(temp,MAXLINELENGTH-1,"%s%s",getenv("HOME"),path+1);
+      temp[MAXLINELENGTH-1]='\0';
+      strcpy(path,temp);
+    }
+  }
+  
   FILE *fic;
   char line[MAXLINELENGTH];
   char keyword[MAXLINELENGTH];
   FILE *fic;
   char line[MAXLINELENGTH];
   char keyword[MAXLINELENGTH];
@@ -1214,11 +1308,12 @@ void parse_config(char *configfile)
   }
   else
   {
   }
   else
   {
-    sprintf(line,"%s/.irssistats",getenv("HOME"));
+    snprintf(line,MAXLINELENGTH-1,"%s/.irssistats",getenv("HOME"));
+    line[MAXLINELENGTH-1]='\0';
     if ((fic=fopen(line,"rt"))==NULL)
     if ((fic=fopen(line,"rt"))==NULL)
-      if ((fic=fopen("/etc/irssistats.conf","rt"))==NULL)
+      if ((fic=fopen(GLOBALCONF,"rt"))==NULL)
       {
       {
-        fprintf(stderr,"can't find config file : \"%s\" nor \"/etc/irssistats.conf\"\n",line);
+        fprintf(stderr,"can't find config file : \"%s\" nor \"" GLOBALCONF "\"\n",line);
         fprintf(stderr,"please give the path to the config file in argument\n");
         exit(1);
       }
         fprintf(stderr,"please give the path to the config file in argument\n");
         exit(1);
       }
@@ -1284,6 +1379,13 @@ void parse_config(char *configfile)
       }
       else
       
       }
       else
       
+      if (strcmp("photo_size",keyword)==0)
+      {
+        photo_size=atoi(value);
+        if (debug==2) fprintf(stderr,"setting photo_size to \"%d\"\n",photo_size);
+      }
+      else
+      
       if (strcmp("w3c_link",keyword)==0)
       {
         if (debug==2) fprintf(stderr,"setting w3c_link to \"%s\"\n",value);
       if (strcmp("w3c_link",keyword)==0)
       {
         if (debug==2) fprintf(stderr,"setting w3c_link to \"%s\"\n",value);
@@ -1293,8 +1395,18 @@ void parse_config(char *configfile)
       }
       else
       
       }
       else
       
+      if (strcmp("logo",keyword)==0)
+      {
+        if (debug==2) fprintf(stderr,"setting logo to \"%s\"\n",value);
+        if (strcmp("no",value)==0) logo=0;
+        else if (strcmp("yes",value)==0) logo=1;
+        else { fprintf(stderr,"unknown value for \"logo\" option, must be \"yes\" or \"no\"\n"); exit(1); }
+      }
+      else
+      
       if (strcmp("header",keyword)==0)
       {
       if (strcmp("header",keyword)==0)
       {
+        expand(value);
         if (debug==2) fprintf(stderr,"setting header to \"%s\"\n",value);
         strcpy(header,value);
       }
         if (debug==2) fprintf(stderr,"setting header to \"%s\"\n",value);
         strcpy(header,value);
       }
@@ -1302,6 +1414,7 @@ void parse_config(char *configfile)
       
       if (strcmp("footer",keyword)==0)
       {
       
       if (strcmp("footer",keyword)==0)
       {
+        expand(value);
         if (debug==2) fprintf(stderr,"setting footer to \"%s\"\n",value);
         strcpy(footer,value);
       }
         if (debug==2) fprintf(stderr,"setting footer to \"%s\"\n",value);
         strcpy(footer,value);
       }
@@ -1309,6 +1422,7 @@ void parse_config(char *configfile)
       
       if (strcmp("input",keyword)==0)
       {
       
       if (strcmp("input",keyword)==0)
       {
+        expand(value);
         if (debug==2) fprintf(stderr,"parsing log file \"%s\"\n",value);
         parse_log(value);
       }
         if (debug==2) fprintf(stderr,"parsing log file \"%s\"\n",value);
         parse_log(value);
       }
@@ -1316,13 +1430,27 @@ void parse_config(char *configfile)
       
       if (strcmp("nickfile",keyword)==0)
       {
       
       if (strcmp("nickfile",keyword)==0)
       {
+        expand(value);
         if (debug==2) fprintf(stderr,"nick alias using file \"%s\"\n",value);
         if (debug==2) fprintf(stderr,"nick alias using file \"%s\"\n",value);
+#ifdef __WIN32__
+        fprintf(stderr,"no support for nickfile in WIN32 version\n");
+#else
         parse_nick(value);
         parse_nick(value);
+#endif
+      }
+      else
+      
+      if (strcmp("photofile",keyword)==0)
+      {
+        expand(value);
+        if (debug==2) fprintf(stderr,"parsing photo file \"%s\"\n",value);
+        parse_photo(value);
       }
       else
       
       if (strcmp("output",keyword)==0)
       {
       }
       else
       
       if (strcmp("output",keyword)==0)
       {
+        expand(value);
         if (debug==2) fprintf(stderr,"generating xhtml file \"%s\"\n",value);
         bestwords(words,0);
         gen_xhtml(value);
         if (debug==2) fprintf(stderr,"generating xhtml file \"%s\"\n",value);
         bestwords(words,0);
         gen_xhtml(value);
@@ -1338,6 +1466,11 @@ void parse_config(char *configfile)
         for (i=0;i<NBWORDS;i++) topwords[i].nb=0;
         totallines=0;
         debut=time(NULL);
         for (i=0;i<NBWORDS;i++) topwords[i].nb=0;
         totallines=0;
         debut=time(NULL);
+        for (i=0;i<nbusers;i++)
+        {
+          free(users[i].photo);
+          users[i].photo=NULL;
+        }
       }
       else
       
       }
       else