diff -upN old/Makefile.in new/Makefile.in
--- old/Makefile.in	2009-05-06 00:48:39.000000000 +0530
+++ new/Makefile.in	2009-05-06 00:47:02.000000000 +0530
@@ -43,8 +43,8 @@ webalizer:	webalizer.o webalizer.h hasht
 		linklist.o linklist.h preserve.o preserve.h  \
                 dns_resolv.o dns_resolv.h parser.o parser.h  \
                 output.o output.h graphs.o graphs.h lang.h   \
-		webalizer_lang.h
-	$(CC) ${LDFLAGS} -o webalizer webalizer.o hashtab.o linklist.o preserve.o parser.o output.o dns_resolv.o graphs.o ${LIBS}
+		rssfeed.o rssfeed.h webalizer_lang.h
+	$(CC) ${LDFLAGS} -o webalizer webalizer.o hashtab.o linklist.o preserve.o parser.o output.o dns_resolv.o graphs.o rssfeed.o ${LIBS}
 	rm -f webazolver
 	@LN_S@ webalizer webazolver
 
@@ -75,6 +75,9 @@ dns_resolv.o:	dns_resolv.c dns_resolv.h
 graphs.o:	graphs.c graphs.h webalizer.h lang.h
 	$(CC) ${CFLAGS} ${DEFS} -c graphs.c
 
+rssfeed.o:	rssfeed.c rssfeed.h webalizer.h output.h hashtab.h
+	$(CC) ${CFLAGS} ${DEFS} -c rssfeed.c
+
 wcmgr:	wcmgr.o
 	$(CC) ${LDFLAGS} -o wcmgr wcmgr.o ${WCMGR_LIBS} 
 
diff -upN old/configure new/configure
--- old/configure	2009-05-06 00:48:39.000000000 +0530
+++ new/configure	2009-05-06 00:47:02.000000000 +0530
@@ -706,6 +706,8 @@ with_zlib
 with_db
 with_dblib
 enable_dns
+enable_skiphostid
+enable_rssfeed
 enable_bz2
 with_bz2
 with_bz2lib
@@ -1349,6 +1351,8 @@ Optional Features:
   --enable-static         Build as static executable       [default=no]
   --enable-debug          Compile with debugging code      [default=no]
   --enable-dns            Enable DNS/GeoDB lookup code     [default=yes]
+  --enable-skiphostid            Enable skip hostid code     [default=no]
+  --enable-rssfeed            Enable rssfeed code     [default=no]
   --enable-bz2            Enable BZip2 decompression code  [default=no]
   --enable-geoip          Enable GeoIP geolocation code    [default=no]
 
@@ -6103,6 +6107,30 @@ fi
   fi
 fi
 
+# Check whether --enable-skiphostid was given.
+if test "${enable_skiphostid+set}" = set; then
+  enableval=$enable_skiphostid; SKIP_HOSTID="yes"
+else
+  SKIP_HOSTID="no"
+fi
+
+
+if test "${SKIP_HOSTID}" = "yes"; then
+    OPTS="-DSKIP_HOSTID ${OPTS}"
+fi
+
+# Check whether --enable-rssfeed was given.
+if test "${enable_rssfeed+set}" = set; then
+  enableval=$enable_rssfeed; _RSSFEED="yes"
+else
+  _RSSFEED="no"
+fi
+
+
+if test "${_RSSFEED}" = "yes"; then
+    OPTS="-D_RSSFEED ${OPTS}"
+fi
+
 
 # Check whether --enable-bz2 was given.
 if test "${enable_bz2+set}" = set; then
diff -upN old/configure.in new/configure.in
--- old/configure.in	2009-05-06 00:48:39.000000000 +0530
+++ new/configure.in	2009-05-06 00:47:02.000000000 +0530
@@ -54,7 +54,7 @@ if test "$GCC" = "yes"; then
   if test "$ac_cv_c_char_unsigned" = "yes"; then
     CFLAGS="-fsigned-char ${CFLAGS}"
   fi
-
+ 
   AC_ARG_ENABLE(debug,
   [  --enable-debug          Compile with debugging code      [[default=no]]],
   CFLAGS="-g ${CFLAGS}")
@@ -191,6 +191,30 @@ if test "${USE_DNS}" = "yes"; then
   fi
 fi
 
+dnl ------------
+dnl whether to skip host id in parsing
+dnl ------------
+AC_ARG_ENABLE(skiphostid,
+  [  --enable-skiphostid            Enable skip hostid code     [[default=no]]],
+  SKIP_HOSTID="yes", SKIP_HOSTID="no")
+
+if test "${SKIP_HOSTID}" = "yes"; then
+  dnl define SKIP_HOSTID
+  OPTS="-DSKIP_HOSTID ${OPTS}"
+fi
+
+dnl ------------
+dnl enable/disable RSS Feed code
+dnl ------------
+AC_ARG_ENABLE(rssfeed,
+  [  --enable-rssfeed            Enable rssfeed code     [[default=no]]],
+  _RSSFEED="yes", _RSSFEED="no")
+
+if test "${_RSSFEED}" = "yes"; then
+  dnl define _RSSFEED
+  OPTS="-D_RSSFEED ${OPTS}"
+fi
+
 dnl ------------------------------------------
 dnl BZip2 code specific tests
 dnl ------------------------------------------
diff -upN old/hashtab.c new/hashtab.c
--- old/hashtab.c	2009-05-06 00:48:39.000000000 +0530
+++ new/hashtab.c	2009-05-06 00:47:02.000000000 +0530
@@ -329,9 +329,13 @@ UNODEPTR new_unode(char *str)
 /*********************************************/
 /* PUT_UNODE - insert/update URL node        */
 /*********************************************/
-
+#ifdef _RSSFEED
+int put_unode(char *str, int type, u_int64_t count, double xfer,
+              u_int64_t *ctr, u_int64_t entry, u_int64_t exit, UNODEPTR *htab, time_t timestamp)
+#else
 int put_unode(char *str, int type, u_int64_t count, double xfer,
               u_int64_t *ctr, u_int64_t entry, u_int64_t exit, UNODEPTR *htab)
+#endif
 {
    UNODEPTR cptr,nptr;
 
@@ -350,6 +354,9 @@ int put_unode(char *str, int type, u_int
          nptr->entry= entry;
          nptr->exit = exit;
          htab[hash(str)] = nptr;
+#ifdef _RSSFEED
+         nptr->timestamp = timestamp;
+#endif
          if (type!=OBJ_GRP) (*ctr)++;
       }
    }
@@ -365,6 +372,9 @@ int put_unode(char *str, int type, u_int
                /* found... bump counter */
                cptr->count+=count;
                cptr->xfer += xfer;
+#ifdef _RSSFEED
+               cptr->timestamp = timestamp;
+#endif
                return 0;
             }
          }
@@ -379,6 +389,9 @@ int put_unode(char *str, int type, u_int
          nptr->next = htab[hash(str)];
          nptr->entry= entry;
          nptr->exit = exit;
+#ifdef _RSSFEED
+         nptr->timestamp = timestamp;
+#endif
          htab[hash(str)]=nptr;
          if (type!=OBJ_GRP) (*ctr)++;
       }
diff -upN old/hashtab.h new/hashtab.h
--- old/hashtab.h	2009-05-06 00:48:39.000000000 +0530
+++ new/hashtab.h	2009-05-06 00:47:02.000000000 +0530
@@ -41,7 +41,12 @@ struct unode {  char *string;
            u_int64_t entry;                /* entry page counter           */
            u_int64_t exit;                 /* exit page counter            */
               double xfer;                 /* xfer size in bytes           */
-              struct unode *next; };       /* pointer to next node         */
+#ifdef _RSSFEED
+              time_t timestamp;            /* time stamp */
+#endif
+              struct unode *next;          /* pointer to next node         */
+            };
+
 
 struct rnode {  char *string;              /* referrer hash table struct   */
                  int flag;
@@ -79,8 +84,13 @@ extern DNODEPTR host_table[MAXHASH];
 
 extern int    put_hnode(char *, int, u_int64_t, u_int64_t, double,
                         u_int64_t *, u_int64_t, u_int64_t, char *, HNODEPTR *);
+#ifdef _RSSFEED
+extern int    put_unode(char *, int, u_int64_t, double, u_int64_t *,
+                        u_int64_t, u_int64_t, UNODEPTR *, time_t);
+#else
 extern int    put_unode(char *, int, u_int64_t, double, u_int64_t *,
                         u_int64_t, u_int64_t, UNODEPTR *);
+#endif
 extern int    put_inode(char *, int, u_int64_t, u_int64_t, double,
                         u_int64_t *, u_int64_t, u_int64_t, INODEPTR *);
 extern int    put_rnode(char *, int, u_int64_t, u_int64_t *, RNODEPTR *);
diff -upN old/output.c new/output.c
--- old/output.c	2009-05-06 00:48:39.000000000 +0530
+++ new/output.c	2009-05-06 00:47:02.000000000 +0530
@@ -65,6 +65,10 @@
 #include "graphs.h"
 #include "output.h"
 
+#ifdef _RSSFEED
+#include "rssfeed.h"
+#endif
+
 /* internal function prototypes */
 void    write_html_head(char *, FILE *);            /* head of html page   */
 void    write_html_tail(FILE *);                    /* tail of html page   */
@@ -289,6 +293,9 @@ int write_month_html()
    if (verbose>1)
       printf("%s %s %d\n",msg_gen_rpt, l_month[cur_month-1], cur_year); 
 
+#ifdef _RSSFEED
+   InitRssCounter();
+#endif
    /* fill in filenames */
    snprintf(html_fname,sizeof(html_fname),"usage_%04d%02d.%s",
             cur_year,cur_month,html_ext);
@@ -327,6 +334,10 @@ int write_month_html()
    /* first, open the file */
    if ( (out_fp=open_out_file(html_fname))==NULL ) return 1;
 
+#ifdef _RSSFEED
+   InitRssFiles(l_month[cur_month-1]);
+#endif
+
    snprintf(buffer,sizeof(buffer),"%s %d",l_month[cur_month-1],cur_year);
    write_html_head(buffer, out_fp);
    month_links();
@@ -464,6 +475,9 @@ int write_month_html()
 
    write_html_tail(out_fp);               /* finish up the HTML document    */
    fclose(out_fp);                        /* close the file                 */
+#ifdef _RSSFEED
+   CloseTopUrlRss();               	  /* close all rss feed file   */
+#endif   
    return (0);                            /* done...                        */
 }
 
@@ -1031,6 +1045,11 @@ void top_urls_table(int flag)
          case OBJ_GRP:  u_grp++;  break;
          case OBJ_HIDE: u_hid++;  break;
       }
+      
+#ifdef _RSSFEED
+      if (IsRssTopCountReached())
+         AddAsTopUrl((*pointer)->string, (*pointer)->timestamp, (*pointer)->flag);
+#endif
       pointer++;
    }
 
@@ -2907,4 +2926,3 @@ FILE *open_out_file(char *filename)
    }
    return out_fp;
 }
-
diff -upN old/parser.c new/parser.c
--- old/parser.c	2009-05-06 00:48:39.000000000 +0530
+++ new/parser.c	2009-05-06 00:47:02.000000000 +0530
@@ -335,6 +335,12 @@ int parse_record_clf(char *buffer)
    /* done with CLF record */
    if (cp1>=eob) return 1;
 
+#ifdef SKIP_HOSTID
+   cp1++; 
+   while ( (*cp1 != '\0') && (cp1 < eob) ) cp1++; /* skip host id */
+   if (cp1 < eob) cp1++;
+#endif
+
    while ( (*cp1 != '\0') && (*cp1 != '\n') && (cp1 < eob) ) cp1++;
    if (cp1 < eob) cp1++;
    /* get referrer if present */
diff -upN old/preserve.c new/preserve.c
--- old/preserve.c	2009-05-06 00:48:39.000000000 +0530
+++ new/preserve.c	2009-05-06 00:47:02.000000000 +0530
@@ -658,8 +658,13 @@ int restore_state()
          &t_unode.entry, &t_unode.exit);
 
       /* Good record, insert into hash table */
+#ifdef _RSSFEED
+      if (put_unode(tmp_buf,t_unode.flag,t_unode.count,
+         t_unode.xfer,&ul_bogus,t_unode.entry,t_unode.exit,um_htab, 0))
+#else
       if (put_unode(tmp_buf,t_unode.flag,t_unode.count,
          t_unode.xfer,&ul_bogus,t_unode.entry,t_unode.exit,um_htab))
+#endif
       {
          if (verbose)
          /* Error adding URL node, skipping ... */
diff -upN old/rssfeed.c new/rssfeed.c
--- old/rssfeed.c	1970-01-01 05:30:00.000000000 +0530
+++ new/rssfeed.c	2009-05-06 00:47:02.000000000 +0530
@@ -0,0 +1,548 @@
+#include "rssfeed.h"
+#define MAX_RSSFEED_COUNT   50
+#define MAX_BLOCK 10000
+
+char    *rssIncludeUrlExts[MAX_RSSFEED_COUNT];
+char    *rssExcludeUrls[MAX_RSSFEED_COUNT];
+char    *rssFileName[MAX_RSSFEED_COUNT];
+char    *rssHeaderFile[MAX_RSSFEED_COUNT];
+char    *rssUrlRootFolders[MAX_RSSFEED_COUNT];
+char	*rssFooter[MAX_RSSFEED_COUNT];
+time_t  rssStartDate[MAX_RSSFEED_COUNT];
+time_t  rssEndDate[MAX_RSSFEED_COUNT];
+
+int     rssFilePopulated[MAX_RSSFEED_COUNT];
+
+int     rssTopUrlCount[MAX_RSSFEED_COUNT];
+int     rssTopUrlCounter[MAX_RSSFEED_COUNT];
+
+char    *rssUrlDownloadTimeout=NULL;
+char    *rssDateRange = NULL;
+      
+
+int     nRssFileName=0;
+int     nRssHeaderFile=0;
+int     nRsstopUrlCount=0;
+int     nRssIncludeUrlExts=0;
+int     nRssUrlRootFolders=0;
+int     nRssExcludeUrls=0;
+int     rssFeedCount=0;
+int     nRssDateRange=0;
+int 	nRssFooter=0;
+
+FILE     **rssFile_fp = NULL;
+
+void CloseTopUrlRss()
+{
+  int nRss=0;
+  for(; nRss < rssFeedCount; nRss++)
+  { 
+    fprintf(rssFile_fp[nRss], rssFooter[nRss]);
+    fclose(rssFile_fp[nRss]);
+  }
+}
+long GetFileLength ( FILE * fp)
+{
+  int pos = ftell(fp);
+  fseek ( fp, 0L, SEEK_END);
+  long len = ftell (fp);
+  fseek ( fp, pos, SEEK_SET);
+  return (len);
+}
+void InitRssCounter()
+{
+   int nRss=0;
+   for(; nRss < rssFeedCount; nRss++)
+   {
+      rssTopUrlCounter[nRss] = 0; 
+   }
+}
+int ParseTitle(char *buffer, int *titlePos, int *titleSize)
+{
+  char *temp=NULL, *temp1=NULL;
+  
+  temp = strstr(buffer, "<title>");
+  if (temp)
+    temp1 = strstr(temp, "</title>");
+  else
+    return 0;
+  
+  if (temp && temp1)
+  {
+    temp = temp + strlen("<title>");
+    *titleSize = temp1 - temp;
+    *titlePos = temp - buffer;
+  }
+  else
+    return 0;
+  
+  return 1;
+}
+
+int ParseDescription(char *buffer, int *descPos, int *descSize)
+{
+  char *temp=NULL;
+  char *temp1=NULL;
+  
+  if (!buffer)
+    return 0;
+  
+  char *buf = buffer;
+      
+  while (temp = strstr(buffer, "<meta "))
+  {
+    temp += strlen("<meta ");
+    while (isspace(*temp)) temp ++;
+      
+    if (strstr(temp, "name") == temp)
+    {
+      temp += strlen("name");
+      while (isspace(*temp)) temp ++;
+      if (*temp == '=')
+      {
+        temp ++;
+        while (isspace(*temp)) temp ++;
+        if (*temp == '"' || *temp == '\'') 
+          temp ++;
+        
+        if (strstr(temp, "description") == temp)
+        {
+          temp = strstr(temp, "content");
+          temp += strlen("content");
+          while (isspace(*temp)) temp ++;
+          if (*temp == '=')
+          {
+            temp ++;          
+            
+            while (isspace(*temp)) temp ++;
+            
+            if (*temp == '"' || *temp == '\'') 
+              temp ++;
+            
+            char *temp1 = strstr(temp, "\"");
+  
+            if (temp1)
+            {
+              *descSize = temp1 - temp;
+              *descPos = temp - buf;
+              return 1;
+            }
+            else
+              return 0;
+          }
+          else
+            return 0;
+        }
+      }
+      else 
+        return 0;
+      
+    }
+    
+    buffer = temp;
+  }
+  
+  return 0;
+     
+}
+
+int ParseTitleAndDesc(char *fileName, char *url, char **title, char **desc)
+{
+  char *buffer = malloc(MAX_BLOCK + 1);
+  if (buffer == NULL)
+    return 0;
+  
+  buffer[MAX_BLOCK] = 0;
+  
+  FILE *fstream = fopen(fileName, "r");
+  if (fstream == NULL)
+    return 0;
+  
+  if (GetFileLength(fstream) == 0)
+  {
+    if (verbose)
+    {
+      printf("Failed to download the url: %s%s\n", hname, url);
+    }
+  }
+  else
+  {
+    int loop = 0;
+    while(fread (buffer + loop*MAX_BLOCK, sizeof(char), MAX_BLOCK, fstream))
+    {
+      char *strHead = strstr(buffer, "</head>");
+      
+      if (strHead != NULL)
+      {
+        break;
+      }
+      else
+      {
+        loop ++;
+        buffer = realloc(buffer, MAX_BLOCK*(loop+1));
+        buffer[MAX_BLOCK*(loop+1)] = 0;
+      }    
+    }
+      
+    char *buf = strdup(buffer);  
+    int i=0;
+    while(buf[i] = tolower(buf[i])) i++;
+    
+    int titlePos = 0;
+    int descPos = 0;
+    
+    int titleSize=0, descSize=0;
+    if (ParseTitle(buf, &titlePos, &titleSize))
+    {
+      *title = malloc(titleSize + 1);
+      strncpy(*title, buffer + titlePos, titleSize);
+      (*title)[titleSize] = 0;
+    }
+  
+    if (ParseDescription(buf, &descPos, &descSize))
+    {
+      *desc = malloc(descSize + 1);
+      strncpy(*desc, buffer + descPos, descSize);
+      (*desc)[descSize] = 0;
+    }
+  }
+  
+  fclose(fstream);
+  
+  return 1;
+}
+
+int IsUrlExtIncluded(int nRss, char *url)
+{
+  extern char    *rssIncludeUrlExts[];
+  if (!rssIncludeUrlExts[nRss])
+    return 1;
+  
+  char noext[]="noext";
+  char *temp = strrchr(url, '/');
+  
+  if (temp)
+    temp = strchr (temp, '.');
+  
+  if (!temp)
+    temp = noext;
+  
+  return (NULL != strstr(rssIncludeUrlExts[nRss], temp));
+}
+
+int IsUrlExcluded(int nRss, char *url)
+{
+  int ret = 0;
+  extern char    *rssExcludeUrls[];
+  
+  if (rssExcludeUrls[nRss] && *rssExcludeUrls[nRss])
+  {
+    char *rssExcludedUrls = strdup(rssExcludeUrls[nRss]);
+    char *token = strtok(rssExcludedUrls, ";");
+    while (token)
+    {
+      if (strstr(url, token))
+      {
+        ret = 1;
+        break;
+      }      
+      token = strtok( NULL, ";");
+    }
+    
+    if (rssExcludedUrls)
+    {
+      free(rssExcludedUrls);
+      rssExcludedUrls = NULL;
+    }
+  }
+    
+  return ret;
+}
+
+int IsUrlUnderRssRoot(int nRss, char *url)
+{
+  extern char    *rssUrlRootFolders[];
+  
+  if (rssUrlRootFolders[nRss])
+  {
+    char *rssRootFolder = strdup(rssUrlRootFolders[nRss]);
+    char *token = strtok(rssRootFolder, ";");
+    while (token)
+    {
+      if (strstr(url, token) == url)
+      {
+        return 1;
+      }      
+      token = strtok( NULL, ";");
+    }
+    
+    free (rssRootFolder);
+    rssRootFolder = NULL;
+  }
+  
+  return 0;
+}
+int IsWithinTheDateRange(int nRss, time_t timestamp)
+{
+  if(rssStartDate[nRss] == 0 || rssEndDate[nRss] == 0 || (rssStartDate[nRss] <= timestamp && rssEndDate[nRss] >= timestamp))
+    return 1;
+  else 
+    return 0;
+}
+int IsRssTopCountReached()
+{
+  int nRss=0;
+  int bRssFeedCountNotReached = 0;
+  for(nRss=0; nRss < rssFeedCount; nRss++)
+  {  
+     if (rssTopUrlCounter[nRss] < rssTopUrlCount[nRss])
+     {
+	bRssFeedCountNotReached = 1;
+	break;
+     }
+  }
+  return bRssFeedCountNotReached;
+}
+void AddAsTopUrl(char *url, time_t timestamp, int flag)
+{
+  int *rssAddUrlFlag = (int *)malloc(sizeof(int)*rssFeedCount);
+  int parseUrl=0;
+  
+  int nRss=0;
+  for(nRss=0; nRss < rssFeedCount; nRss++)
+  {
+    rssAddUrlFlag[nRss] = (rssTopUrlCounter[nRss] < rssTopUrlCount[nRss] && 
+                          IsUrlExtIncluded(nRss, url) && 
+                          !IsUrlExcluded(nRss, url) &&
+                          IsUrlUnderRssRoot(nRss, url) && 
+                          IsWithinTheDateRange(nRss, timestamp));
+    
+    if (rssAddUrlFlag[nRss])
+      parseUrl = 1;
+  }
+  
+  char *title=NULL;
+  char *desc=NULL;
+  if (parseUrl)
+  {
+    char fullyQualifiedUrl[2048];
+    strcpy(fullyQualifiedUrl, hname);
+    strncat(fullyQualifiedUrl, url, sizeof(fullyQualifiedUrl) - strlen(fullyQualifiedUrl));
+
+    if (flag != OBJ_HIDE)
+    {
+      char wgetCmd[2048];
+      char tempFile[] = ".temp.txt";
+      
+      strcpy(wgetCmd, "wget -q --save-header -O ");
+      strcat(wgetCmd, tempFile);
+      strcat(wgetCmd, " --tries=1 --timeout=");
+      
+      strcat(wgetCmd, rssUrlDownloadTimeout ? rssUrlDownloadTimeout : "0");
+      
+      if (use_https)  
+        strcat(wgetCmd, " https://");
+      else
+        strcat(wgetCmd, " http://");
+      
+      strncat(wgetCmd, fullyQualifiedUrl, sizeof(wgetCmd) - strlen(wgetCmd));
+      
+      if (verbose)
+      {
+        fprintf(stderr, "Downloading page: %s\n", fullyQualifiedUrl);
+      }
+      
+      system(wgetCmd);
+      
+      if (!ParseTitleAndDesc(tempFile, url, &title, &desc))
+      {
+        if (verbose)
+          fprintf(stderr, "failed to create Rss feed for top urls");
+      }
+    }
+        
+    for(nRss=0; nRss < rssFeedCount; nRss++)
+    {
+      if (rssAddUrlFlag[nRss])
+      {
+        rssTopUrlCounter[nRss] ++;
+        rssFilePopulated[nRss] = 1;
+		fprintf(rssFile_fp[nRss], "<item>\n\t<title>%s</title>\n\t<link>http://%s%s</link>\n\t<description>%s</description>\n\t<guid isPermaLink=\"true\">http://%s%s</guid>\n</item>", title?title:fullyQualifiedUrl, hname, url, desc?desc:"", hname, url);
+      }
+    }
+  }
+  
+  if (rssAddUrlFlag)
+  {
+    free (rssAddUrlFlag);
+    rssAddUrlFlag = NULL;
+  }
+}
+    
+FILE *OpenAndInitializeRssFile(char *rssOutFilename, char *rssHeaderFile)
+{
+  FILE *rss_fp=NULL;
+
+  if ( (rss_fp=fopen(rssOutFilename,"w")) == NULL)
+  {
+    if (verbose)
+      fprintf(stderr,"%s %s!\n",msg_no_open,rssOutFilename);
+    
+    return NULL;
+  }
+  
+  FILE *rssTemplate_fp = fopen(rssHeaderFile,"r");
+  if (rssTemplate_fp == NULL)
+  {
+    fclose(rss_fp);
+    rss_fp = NULL;
+    if (verbose)
+        fprintf(stderr,"%s %s!\n",msg_no_open,rssHeaderFile);
+  }
+  else
+  {
+    long templateFileLen = GetFileLength(rssTemplate_fp);
+    if (templateFileLen > 0)
+    { 
+	char *buffer = malloc(templateFileLen + 1);
+	fread (buffer, sizeof(char), templateFileLen, rssTemplate_fp);
+	buffer[templateFileLen] = 0;
+	
+	fprintf(rss_fp, buffer);
+	
+	free (buffer);
+	buffer = NULL;
+    }
+    else 
+    {
+	fclose(rss_fp);
+	rss_fp = NULL;
+	if (verbose)
+	{
+	    fprintf(stderr,"Invalid file: %s!\n", rssHeaderFile);
+	}
+    }
+  }
+  
+  return rss_fp;
+}
+void ParseRssDateRange (char *rssEndDateAndDuration, time_t *startDate, time_t *endDate)
+{
+  int duration = 0;
+  
+  if(!strncasecmp(rssEndDateAndDuration, "none", strlen("none")))
+  {
+    *startDate = *endDate = 0;
+    return;
+  }
+      
+  if (!strncasecmp(rssEndDateAndDuration, "today", strlen("today")))
+  {
+    int endDateOffset = 0;
+    char *temp=strstr(rssEndDateAndDuration,",");
+    if (temp)
+    {
+      *temp = ' ';
+      temp = strstr(rssEndDateAndDuration,"-");
+      if (temp)
+      {
+        *temp = ' ';
+        sscanf(rssEndDateAndDuration, "%*s%d%d", &endDateOffset, &duration);
+      }
+      else
+      {
+        sscanf(rssEndDateAndDuration, "%*s%d", &duration);
+      }
+    }
+    
+    *endDate = time(NULL);
+    *endDate -= endDateOffset*86400; //24*60*60  
+  }
+  else
+  {
+    int year=0, month=0, day=0;
+    char *temp = NULL;
+    temp = rssEndDateAndDuration;
+    while(temp = strstr(temp, "/"))
+    {
+      *temp = ' ';
+    }
+    
+    if (temp = strstr(rssEndDateAndDuration, ","))
+      *temp = ' ';
+    
+    sscanf(rssEndDateAndDuration, "%d %d %d %d", &month, &day, &year, &duration);
+    
+    struct tm timeinfo;
+    memset(&timeinfo, 0, sizeof(timeinfo));
+    timeinfo.tm_year =  year - 1900;
+    timeinfo.tm_mon = month - 1;
+    timeinfo.tm_mday = day;
+    timeinfo.tm_hour = 23;
+    timeinfo.tm_min = 59;
+    timeinfo.tm_sec = 59;
+    
+    *endDate = mktime(&timeinfo);
+  }
+  
+  *endDate += 86400;
+  *endDate -= (*endDate % 86400);
+  *endDate -= 1;
+      
+  *startDate = *endDate - (duration-1)*86400; //24*60*60
+  *startDate -= (*startDate % 86400);
+
+}
+int InitRssFiles(char *month)
+{
+   // open RSS file and write the header content   
+   rssFile_fp = (FILE **)malloc(sizeof(FILE *)*rssFeedCount);
+   int nRss = 0;
+   for(; nRss < rssFeedCount; nRss++)
+   {
+     char rssTopUrlFileNameForMonth[260];
+     strcpy(rssTopUrlFileNameForMonth, rssFileName[nRss]);
+     
+     if (rssFilePopulated[nRss])
+     {
+       strcat(rssTopUrlFileNameForMonth, ".");
+       strcat(rssTopUrlFileNameForMonth, month);
+     }
+     
+     if ( (rssFile_fp[nRss]=OpenAndInitializeRssFile(rssTopUrlFileNameForMonth, rssHeaderFile[nRss]))==NULL ) 
+     {
+       if (verbose)
+         fprintf(stderr, "Failed to create file %s", rssFileName[nRss]);
+       return 1;
+     }
+   }
+   return 0;
+}
+int ValidateRssFeedInputs()
+{
+   if (nRssFileName != nRssHeaderFile ||
+       nRssHeaderFile != nRsstopUrlCount ||
+       nRsstopUrlCount != nRssIncludeUrlExts ||
+       nRssIncludeUrlExts != nRssExcludeUrls ||
+       nRssIncludeUrlExts != nRssUrlRootFolders || 
+       nRssUrlRootFolders != nRssDateRange ||
+       nRssDateRange != nRssFooter)
+   {
+     if (verbose)
+     {
+       fprintf(stderr,"One of the required field to generate RSS feed is missing in config file. The following gives the count of different RSS settings found in config file:\n");
+       fprintf(stderr,"RssFileName=%d\n", nRssFileName);
+       fprintf(stderr,"RssHeaderFile=%d\n", nRssHeaderFile);
+       fprintf(stderr,"RsstopUrlCount=%d\n", nRsstopUrlCount);
+       fprintf(stderr,"RssIncludeUrlExts=%d\n", nRssIncludeUrlExts);
+       fprintf(stderr,"RssExcludeUrls=%d\n", nRssExcludeUrls);
+       fprintf(stderr,"RssUrlRootFolders=%d\n", nRssUrlRootFolders);
+       fprintf(stderr,"RssEndDateAndDuration=%d\n", nRssDateRange);
+       fprintf(stderr,"RssFooter=%d\n", nRssFooter);
+     }
+     return 1;
+   }
+      
+   rssFeedCount = nRssFileName;
+   return 0;
+}
diff -upN old/rssfeed.h new/rssfeed.h
--- old/rssfeed.h	1970-01-01 05:30:00.000000000 +0530
+++ new/rssfeed.h	2009-05-06 00:47:02.000000000 +0530
@@ -0,0 +1,47 @@
+#include <stdio.h>
+#include <time.h>
+#include <stdlib.h>
+
+#define MAXHASH  2048                  /* Size of our hash tables          */
+#include "hashtab.h"
+
+extern char    *rssIncludeUrlExts[];
+extern char    *rssExcludeUrls[];
+extern char    *rssFileName[];
+extern char    *rssHeaderFile[];
+extern char    *rssUrlRootFolders[];
+extern char    *rssFooter[];
+extern time_t  rssStartDate[];
+extern time_t  rssEndDate[];
+
+extern int     rssFilePopulated[];
+
+extern int     rssTopUrlCount[];
+extern int     rssTopUrlCounter[];
+
+extern char    *rssUrlDownloadTimeout;
+extern char    *rssDateRange;
+      
+
+extern int     nRssFileName;
+extern int     nRssHeaderFile;
+extern int     nRsstopUrlCount;
+extern int     nRssIncludeUrlExts;
+extern int     nRssUrlRootFolders;
+extern int     nRssExcludeUrls;
+extern int     nRssDateRange;
+extern int     nRssFooter;
+extern int     rssFeedCount;
+
+extern FILE     **rssFile_fp;
+
+// from webalizer.h
+extern int     verbose      ;                 /* 2=verbose,1=err, 0=none  */ 
+extern char    *hname       ;                 /* hostname for reports     */
+extern int     use_https    ;                 /* use 'https://' on URLs   */
+
+// from lang.h
+extern char *msg_no_open ;
+
+void ParseRssDateRange (char *, time_t *, time_t *);
+FILE  *OpenAndInitializeRssFile(char *, char *);
diff -upN old/webalizer.c new/webalizer.c
--- old/webalizer.c	2009-05-06 00:48:39.000000000 +0530
+++ new/webalizer.c	2009-05-06 00:47:02.000000000 +0530
@@ -91,6 +91,9 @@ int bz2_rewind(void **, char *, char *);
 #include "dns_resolv.h"
 #endif
 
+#ifdef _RSSFEED
+#include "rssfeed.h"
+#endif
 /* internal function prototypes */
 
 void    clear_month();                              /* clear monthly stuff */
@@ -106,7 +109,6 @@ void    agent_mangle(char *);
 char    *our_gzgets(void *, char *, int);           /* our gzgets          */
 int     stricmp(char *, char *);                    /* case ins. compare   */
 int     isipaddr(char *);                           /* is IP address test  */
-
 /*********************************************/
 /* GLOBAL VARIABLES                          */
 /*********************************************/
@@ -753,6 +755,19 @@ int main(int argc, char *argv[])
             continue;                   /* and ignore this record           */
          }
 
+#ifdef _RSSFEED
+         // Calculate time
+         struct tm timeinfo;
+         memset(&timeinfo, 0, sizeof(timeinfo));
+         timeinfo.tm_year =  rec_year - 1900;
+         timeinfo.tm_mon = rec_month - 1;
+         timeinfo.tm_mday = rec_day;
+         timeinfo.tm_hour = rec_hour;
+         timeinfo.tm_min = rec_min;
+         timeinfo.tm_sec = rec_sec;
+                      
+         log_rec.timestamp = mktime(&timeinfo);
+#endif
          /*********************************************/
          /* GOOD RECORD, CHECK INCREMENTAL/TIMESTAMPS */
          /*********************************************/
@@ -1201,8 +1216,13 @@ int main(int argc, char *argv[])
              (log_rec.resp_code==RC_PARTIALCONTENT))
          {
             /* URL hash table */
+#ifdef _RSSFEED
+            if (put_unode(log_rec.url,OBJ_REG,(u_int64_t)1,
+                log_rec.xfer_size,&t_url,(u_int64_t)0,(u_int64_t)0,um_htab,log_rec.timestamp))
+#else
             if (put_unode(log_rec.url,OBJ_REG,(u_int64_t)1,
                 log_rec.xfer_size,&t_url,(u_int64_t)0,(u_int64_t)0,um_htab))
+#endif
             {
                if (verbose)
                /* Error adding URL node, skipping ... */
@@ -1296,8 +1316,13 @@ int main(int argc, char *argv[])
          /* URL Grouping */
          if ( (cp1=isinglist(group_urls,log_rec.url))!=NULL)
          {
+#ifdef _RSSFEED
+            if (put_unode(cp1,OBJ_GRP,(u_int64_t)1,log_rec.xfer_size,
+                &ul_bogus,(u_int64_t)0,(u_int64_t)0,um_htab,log_rec.timestamp))
+#else
             if (put_unode(cp1,OBJ_GRP,(u_int64_t)1,log_rec.xfer_size,
                 &ul_bogus,(u_int64_t)0,(u_int64_t)0,um_htab))
+#endif
             {
                if (verbose)
                /* Error adding URL node, skipping ... */
@@ -1629,6 +1654,18 @@ void get_config(char *fname)
                      "CountryFlags",      /* show country flags? (0-no) 118 */
                      "FlagDir",           /* directory w/flag images    119 */
                      "SearchCaseI"        /* srch str case insensitive  120 */
+#ifdef _RSSFEED
+		     ,	
+                     "RssFileName",       /* rss feed filename          121 */
+                     "RssHeaderFile",      /* rss template filename    122 */
+                     "RssTopUrlCount",    /* count of top urls for rss  123 */
+                     "RssIncludeUrlExts", /* extenstion to be included  124*/
+                     "RssExcludeUrls",    /* urls to be excluded        125*/
+                     "RssUrlRootFolders", /* root folders rss urls      126*/
+                     "RssEndDateAndDuration",/* access date range for rss 127*/
+		     "RssFooter",	    /* RSS feed footer 		128*/
+                     "RssUrlDownloadTimeout" /* url download timeout to fetch title & desc 129*/
+#endif
                    };
 
    FILE *fp;
@@ -1863,8 +1900,30 @@ void get_config(char *fname)
         case 119: use_flags=1; flag_dir=save_opt(value); break; /* FlagDir  */
         case 120: searchcasei=
                     (tolower(value[0])=='n')?0:1;  break; /* SearchCaseI    */
+#ifdef _RSSFEED
+        case 121: rssFileName[nRssFileName ++]=save_opt(value); break;
+        case 122: rssHeaderFile[nRssHeaderFile ++]=save_opt(value); break;
+        case 123: rssTopUrlCount[nRsstopUrlCount ++]=atoi(value); break;
+        case 124: rssIncludeUrlExts[nRssIncludeUrlExts ++]=save_opt(value); break;
+        case 125: rssExcludeUrls[nRssExcludeUrls ++]=save_opt(value); break;
+        case 126: rssUrlRootFolders[nRssUrlRootFolders ++]=save_opt(value); break;
+        case 127: rssDateRange = save_opt(value);
+                 if (rssDateRange)
+                 {
+                    ParseRssDateRange(rssDateRange, &rssStartDate[nRssDateRange], &rssEndDate[nRssDateRange]); 
+                    nRssDateRange ++; 
+                    free(rssDateRange);rssDateRange = NULL;
+                 }
+                 break;
+	case 128: rssFooter[nRssFooter ++] = save_opt(value);break;
+        case 129: rssUrlDownloadTimeout = save_opt(value); break;
+#endif
       }
    }
+#ifdef _RSSFEED
+   ValidateRssFeedInputs();	
+#endif
+   
    fclose(fp);
 }
 
@@ -1999,7 +2058,6 @@ char *cur_time()
 
    return timestamp;
 }
-
 /*********************************************/
 /* ISPAGE - determine if an HTML page or not */
 /*********************************************/
diff -upN old/webalizer.h new/webalizer.h
--- old/webalizer.h	2009-05-06 00:48:39.000000000 +0530
+++ new/webalizer.h	2009-05-06 00:47:02.000000000 +0530
@@ -17,8 +17,8 @@
 #define MAXHOST  128                   /* Max hostname buffer size         */
 #define MAXURL   4096                  /* Max HTTP request/URL field size  */
 #define MAXURLH  512                   /* Max URL field size in htab       */
-#define MAXREF   1024                  /* Max referrer field size          */
-#define MAXREFH  256                   /* Max referrer field size in htab  */
+#define MAXREF   4096                  /* Max referrer field size          */
+#define MAXREFH  512                  /* Max referrer field size in htab  */
 #define MAXAGENT 128                   /* Max user agent field size        */
 #define MAXCTRY  48                    /* Max country name size            */
 #define MAXSRCH  256                   /* Max size of search string buffer */
@@ -151,6 +151,9 @@ typedef struct country_code *CLISTPTR;
 /* log record structure */
 struct  log_struct  {  char   hostname[MAXHOST];  /* hostname             */
                        char   datetime[29];       /* raw timestamp        */
+#ifdef _RSSFEED
+                     time_t   timestamp;           /* timestamp            */
+#endif
                        char   url[MAXURL];        /* raw request field    */
                         int   resp_code;          /* response code        */
                   u_int64_t   xfer_size;          /* xfer size in bytes   */

