]> jfr.im git - irc/rqf/shadowircd.git/blobdiff - src/cache.c
Fix inconsistency between --sysconfdir and --with-confdir, deprecate --with-confdir.
[irc/rqf/shadowircd.git] / src / cache.c
index 0a23ebbcc9ef70777d0af03149d2a06be19e3979..04766b7448d04711719a21e1cf9253cb7b418c2c 100644 (file)
  * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
  * POSSIBILITY OF SUCH DAMAGE.
  *
- * $Id: cache.c 3436 2007-05-02 19:56:40Z jilles $
  */
 
 #include "stdinc.h"
 #include "ircd_defs.h"
 #include "common.h"
 #include "s_conf.h"
-#include "tools.h"
 #include "client.h"
-#include "memory.h"
-#include "balloc.h"
-#include "event.h"
 #include "hash.h"
 #include "cache.h"
-#include "sprintf_irc.h"
-
-static BlockHeap *cachefile_heap = NULL;
-static BlockHeap *cacheline_heap = NULL;
+#include "irc_dictionary.h"
+#include "numeric.h"
 
 struct cachefile *user_motd = NULL;
 struct cachefile *oper_motd = NULL;
-dlink_list links_cache_list;
+struct cacheline *emptyline = NULL;
+rb_dlink_list links_cache_list;
 char user_motd_changed[MAX_DATE_STRING];
 
+struct Dictionary *help_dict_oper = NULL;
+struct Dictionary *help_dict_user = NULL;
+
 /* init_cache()
  *
  * inputs      -
@@ -62,14 +59,47 @@ char user_motd_changed[MAX_DATE_STRING];
 void
 init_cache(void)
 {
-       cachefile_heap = BlockHeapCreate(sizeof(struct cachefile), CACHEFILE_HEAP_SIZE);
-       cacheline_heap = BlockHeapCreate(sizeof(struct cacheline), CACHELINE_HEAP_SIZE);
-
+       /* allocate the emptyline */
+       emptyline = rb_malloc(sizeof(struct cacheline));
+       emptyline->data[0] = ' ';
+       emptyline->data[1] = '\0';
        user_motd_changed[0] = '\0';
 
        user_motd = cache_file(MPATH, "ircd.motd", 0);
        oper_motd = cache_file(OPATH, "opers.motd", 0);
        memset(&links_cache_list, 0, sizeof(links_cache_list));
+
+       help_dict_oper = irc_dictionary_create(strcasecmp);
+       help_dict_user = irc_dictionary_create(strcasecmp);
+}
+
+/* 
+ * removes tabs from src, replaces with 8 spaces, and returns the length
+ * of the new string.  if the new string would be greater than destlen,
+ * it is truncated to destlen - 1
+ */
+static size_t
+untabify(char *dest, const char *src, size_t destlen)
+{
+       size_t x = 0, i;
+       const char *s = src;
+       char *d = dest;
+
+       while(*s != '\0' && x < destlen - 1)
+       {
+               if(*s == '\t')
+               {
+                       for(i = 0; i < 8 && x < destlen - 1; i++, x++, d++)
+                               *d = ' ';
+                       s++;
+               } else 
+               {
+                       *d++ = *s++;
+                       x++;
+               }
+       }
+       *d = '\0';
+       return x;
 }
 
 /* cache_file()
@@ -90,41 +120,33 @@ cache_file(const char *filename, const char *shortname, int flags)
        if((in = fopen(filename, "r")) == NULL)
                return NULL;
 
-       if(strcmp(shortname, "ircd.motd") == 0)
-       {
-               struct stat sb;
-               struct tm *local_tm;
-
-               if(fstat(fileno(in), &sb) < 0)
-                       return NULL;
 
-               local_tm = localtime(&sb.st_mtime);
+       cacheptr = rb_malloc(sizeof(struct cachefile));
 
-               if(local_tm != NULL)
-                       ircsnprintf(user_motd_changed, sizeof(user_motd_changed),
-                                "%d/%d/%d %d:%d",
-                                local_tm->tm_mday, local_tm->tm_mon + 1,
-                                1900 + local_tm->tm_year, local_tm->tm_hour,
-                                local_tm->tm_min);
-       }
-
-       cacheptr = BlockHeapAlloc(cachefile_heap);
-
-       strlcpy(cacheptr->name, shortname, sizeof(cacheptr->name));
+       rb_strlcpy(cacheptr->name, shortname, sizeof(cacheptr->name));
        cacheptr->flags = flags;
 
        /* cache the file... */
        while(fgets(line, sizeof(line), in) != NULL)
        {
-               if((p = strchr(line, '\n')) != NULL)
+               if((p = strpbrk(line, "\r\n")) != NULL)
                        *p = '\0';
 
-               lineptr = BlockHeapAlloc(cacheline_heap);
-               if(EmptyString(line))
-                       strlcpy(lineptr->data, " ", sizeof(lineptr->data));
+               if(!EmptyString(line))
+               {
+                       lineptr = rb_malloc(sizeof(struct cacheline));
+                       untabify(lineptr->data, line, sizeof(lineptr->data));
+                       rb_dlinkAddTail(lineptr, &lineptr->linenode, &cacheptr->contents);
+               }
                else
-                       strlcpy(lineptr->data, line, sizeof(lineptr->data));
-               dlinkAddTail(lineptr, &lineptr->linenode, &cacheptr->contents);
+                       rb_dlinkAddTailAlloc(emptyline, &cacheptr->contents);
+       }
+
+       if (0 == rb_dlink_list_length(&cacheptr->contents))
+       {
+               /* No contents. Don't cache it after all. */
+               rb_free(cacheptr);
+               cacheptr = NULL;
        }
 
        fclose(in);
@@ -135,20 +157,20 @@ void
 cache_links(void *unused)
 {
        struct Client *target_p;
-       dlink_node *ptr;
-       dlink_node *next_ptr;
+       rb_dlink_node *ptr;
+       rb_dlink_node *next_ptr;
        char *links_line;
 
-       DLINK_FOREACH_SAFE(ptr, next_ptr, links_cache_list.head)
+       RB_DLINK_FOREACH_SAFE(ptr, next_ptr, links_cache_list.head)
        {
-               MyFree(ptr->data);
-               free_dlink_node(ptr);
+               rb_free(ptr->data);
+               rb_free_rb_dlink_node(ptr);
        }
 
        links_cache_list.head = links_cache_list.tail = NULL;
        links_cache_list.length = 0;
 
-       DLINK_FOREACH(ptr, global_serv_list.head)
+       RB_DLINK_FOREACH(ptr, global_serv_list.head)
        {
                target_p = ptr->data;
 
@@ -158,13 +180,13 @@ cache_links(void *unused)
                        continue;
 
                /* if the below is ever modified, change LINKSLINELEN */
-               links_line = MyMalloc(LINKSLINELEN);
-               ircsnprintf(links_line, LINKSLINELEN, "%s %s :1 %s",
+               links_line = rb_malloc(LINKSLINELEN);
+               rb_snprintf(links_line, LINKSLINELEN, "%s %s :1 %s",
                           target_p->name, me.name, 
                           target_p->info[0] ? target_p->info : 
                            "(Unknown Location)");
 
-               dlinkAddTailAlloc(links_line, &links_cache_list);
+               rb_dlinkAddTailAlloc(links_line, &links_cache_list);
        }
 }
 
@@ -177,25 +199,27 @@ cache_links(void *unused)
 void
 free_cachefile(struct cachefile *cacheptr)
 {
-       dlink_node *ptr;
-       dlink_node *next_ptr;
+       rb_dlink_node *ptr;
+       rb_dlink_node *next_ptr;
 
        if(cacheptr == NULL)
                return;
 
-       DLINK_FOREACH_SAFE(ptr, next_ptr, cacheptr->contents.head)
+       RB_DLINK_FOREACH_SAFE(ptr, next_ptr, cacheptr->contents.head)
        {
-               BlockHeapFree(cacheline_heap, ptr->data);
+               if(ptr->data != emptyline)
+                       rb_free(ptr->data);
        }
 
-       BlockHeapFree(cachefile_heap, cacheptr);
+       rb_free(cacheptr);
 }
 
 /* load_help()
  *
  * inputs      -
  * outputs     -
- * side effects - contents of help directories are loaded.
+ * side effects - old help cache deleted
+ *             - contents of help directories are loaded.
  */
 void
 load_help(void)
@@ -204,12 +228,23 @@ load_help(void)
        struct dirent *ldirent= NULL;
        char filename[MAXPATHLEN];
        struct cachefile *cacheptr;
+       struct DictionaryIter iter;
 
 #if defined(S_ISLNK) && defined(HAVE_LSTAT)
        struct stat sb;
 #endif
 
-       /* opers must be done first */
+       DICTIONARY_FOREACH(cacheptr, &iter, help_dict_oper)
+       {
+               irc_dictionary_delete(help_dict_oper, cacheptr->name);
+               free_cachefile(cacheptr);
+       }
+       DICTIONARY_FOREACH(cacheptr, &iter, help_dict_user)
+       {
+               irc_dictionary_delete(help_dict_user, cacheptr->name);
+               free_cachefile(cacheptr);
+       }
+
        helpfile_dir = opendir(HPATH);
 
        if(helpfile_dir == NULL)
@@ -217,9 +252,11 @@ load_help(void)
 
        while((ldirent = readdir(helpfile_dir)) != NULL)
        {
-               ircsnprintf(filename, sizeof(filename), "%s/%s", HPATH, ldirent->d_name);
+               if(ldirent->d_name[0] == '.')
+                       continue;
+               rb_snprintf(filename, sizeof(filename), "%s/%s", HPATH, ldirent->d_name);
                cacheptr = cache_file(filename, ldirent->d_name, HELP_OPER);
-               add_to_help_hash(cacheptr->name, cacheptr);
+               irc_dictionary_add(help_dict_oper, cacheptr->name, cacheptr);
        }
 
        closedir(helpfile_dir);
@@ -230,7 +267,9 @@ load_help(void)
 
        while((ldirent = readdir(helpfile_dir)) != NULL)
        {
-               ircsnprintf(filename, sizeof(filename), "%s/%s", UHPATH, ldirent->d_name);
+               if(ldirent->d_name[0] == '.')
+                       continue;
+               rb_snprintf(filename, sizeof(filename), "%s/%s", UHPATH, ldirent->d_name);
 
 #if defined(S_ISLNK) && defined(HAVE_LSTAT)
                if(lstat(filename, &sb) < 0)
@@ -241,7 +280,7 @@ load_help(void)
                 */
                if(S_ISLNK(sb.st_mode))
                {
-                       cacheptr = hash_find_help(ldirent->d_name, HELP_OPER);
+                       cacheptr = irc_dictionary_retrieve(help_dict_oper, ldirent->d_name);
 
                        if(cacheptr != NULL)
                        {
@@ -252,7 +291,7 @@ load_help(void)
 #endif
 
                cacheptr = cache_file(filename, ldirent->d_name, HELP_USER);
-               add_to_help_hash(cacheptr->name, cacheptr);
+               irc_dictionary_add(help_dict_user, cacheptr->name, cacheptr);
        }
 
        closedir(helpfile_dir);
@@ -268,11 +307,10 @@ void
 send_user_motd(struct Client *source_p)
 {
        struct cacheline *lineptr;
-       dlink_node *ptr;
+       rb_dlink_node *ptr;
        const char *myname = get_id(&me, source_p);
        const char *nick = get_id(source_p, source_p);
-
-       if(user_motd == NULL || dlink_list_length(&user_motd->contents) == 0)
+       if(user_motd == NULL || rb_dlink_list_length(&user_motd->contents) == 0)
        {
                sendto_one(source_p, form_str(ERR_NOMOTD), myname, nick);
                return;
@@ -280,7 +318,7 @@ send_user_motd(struct Client *source_p)
 
        sendto_one(source_p, form_str(RPL_MOTDSTART), myname, nick, me.name);
 
-       DLINK_FOREACH(ptr, user_motd->contents.head)
+       RB_DLINK_FOREACH(ptr, user_motd->contents.head)
        {
                lineptr = ptr->data;
                sendto_one(source_p, form_str(RPL_MOTD), myname, nick, lineptr->data);
@@ -289,6 +327,30 @@ send_user_motd(struct Client *source_p)
        sendto_one(source_p, form_str(RPL_ENDOFMOTD), myname, nick);
 }
 
+void
+cache_user_motd(void)
+{
+       struct stat sb;
+       struct tm *local_tm;
+       
+       if(stat(MPATH, &sb) == 0) 
+       {
+               local_tm = localtime(&sb.st_mtime);
+
+               if(local_tm != NULL) 
+               {
+                       rb_snprintf(user_motd_changed, sizeof(user_motd_changed),
+                                "%d/%d/%d %d:%d",
+                                local_tm->tm_mday, local_tm->tm_mon + 1,
+                                1900 + local_tm->tm_year, local_tm->tm_hour,
+                                local_tm->tm_min);
+               }
+       } 
+       free_cachefile(user_motd);
+       user_motd = cache_file(MPATH, "ircd.motd", 0);
+}
+
+
 /* send_oper_motd()
  *
  * inputs      - client to send motd to
@@ -299,15 +361,15 @@ void
 send_oper_motd(struct Client *source_p)
 {
        struct cacheline *lineptr;
-       dlink_node *ptr;
+       rb_dlink_node *ptr;
 
-       if(oper_motd == NULL || dlink_list_length(&oper_motd->contents) == 0)
+       if(oper_motd == NULL || rb_dlink_list_length(&oper_motd->contents) == 0)
                return;
 
        sendto_one(source_p, form_str(RPL_OMOTDSTART), 
                   me.name, source_p->name);
 
-       DLINK_FOREACH(ptr, oper_motd->contents.head)
+       RB_DLINK_FOREACH(ptr, oper_motd->contents.head)
        {
                lineptr = ptr->data;
                sendto_one(source_p, form_str(RPL_OMOTD),
@@ -317,4 +379,3 @@ send_oper_motd(struct Client *source_p)
        sendto_one(source_p, form_str(RPL_ENDOFOMOTD), 
                   me.name, source_p->name);
 }
-