Release bumped to "gts4".
[tac_plus.git] / utils.c
diff --git a/utils.c b/utils.c
index b597e70..43b50f3 100644 (file)
--- a/utils.c
+++ b/utils.c
@@ -1,4 +1,4 @@
-/* 
+/*
    Copyright (c) 1995-1998 by Cisco systems, Inc.
 
    Permission to use, copy, modify, and distribute this software for
    FITNESS FOR A PARTICULAR PURPOSE.
 */
 
-#include "tac_plus.h"
 
-#ifdef STDLIB_MALLOC
+#include "tac_plus.h"
 
-#include <stdlib.h>
+#include <stdlib.h>    /* malloc() can be found in <stdlib.h> OR <malloc.h> */
+#ifdef HAVE_MALLOC_H
+#include <malloc.h>
+#endif
+#include <string.h>
+#ifdef HAVE_FCNTL_H
+#include <fcntl.h>     /* for "struct flock" */
+#endif
+#include <errno.h>
+#ifdef HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+#ifdef HAVE_SYSLOG_H
+#include <syslog.h>
+#endif
+#ifdef HAVE_SYS_SYSLOG_H
+#include <sys/syslog.h>
+#endif
 
-#else /* !STDLIB_MALLOC */
+#include "utils.h"
+#include "report.h"
+#include "main.h"
 
-#include <malloc.h>
 
-#endif /* STDLIB_MALLOC */
+void *tac_malloc TAC_ARGS((int size));
 
-char *
+void *
 tac_malloc(size)
 int size;
 {
@@ -49,9 +66,11 @@ int size;
     return (p);
 }
 
-char *
+void *tac_realloc TAC_ARGS((void *ptr, int size));
+
+void *
 tac_realloc(ptr, size)
-char *ptr;
+void *ptr;
 int size;
 {
     char *p;
@@ -70,6 +89,9 @@ int size;
     return (p);
 }
 
+void tac_exit TAC_ARGS((int status)) G_GNUC_NORETURN;
+
+void
 tac_exit(status)
 int status;
 {
@@ -78,9 +100,11 @@ int status;
     exit(status);
 }
 
+char *tac_strdup TAC_ARGS((const char *p));
+
 char *
 tac_strdup(p)
-char *p;
+const char *p;
 {
     char *n = strdup(p);
 
@@ -91,6 +115,8 @@ char *p;
     return (n);
 }
 
+char *tac_make_string TAC_ARGS((u_char *p, int len));
+
 char *
 tac_make_string(p, len)
 u_char *p;
@@ -99,7 +125,7 @@ int len;
     char *string;
     int new_len = len;
 
-    /* 
+    /*
      * Add space for a null terminator if needed. Also, no telling
      * what various mallocs will do when asked for a length of zero.
      */
@@ -113,12 +139,16 @@ int len;
     return (string);
 }
 
-/* return a pointer to the end of substring in string, or NULL. Substring 
+/* return a pointer to the end of substring in string, or NULL. Substring
    must begin at start of string.
 */
-char *
+
+const char *tac_find_substring TAC_ARGS((const char *substring, const char *string));
+
+const char *
 tac_find_substring(substring, string)
-char *substring, *string;
+const char *substring;
+const char *string;
 {
     int len;
 
@@ -131,7 +161,7 @@ char *substring, *string;
     if (len > (int) strlen(string)) {
        return(NULL);
     }
-       
+
     if (strncmp(substring, string, len)) {
        /* no match */
        return(NULL);
@@ -169,11 +199,11 @@ bcopy(s1, s2, len)
     while (--n);
 }
 
-int 
+int
 bcmp(s1,s2,n)
     char *s1,*s2;
     int n;
-{     
+{
     while (n-- > 0) {
        if (*s1++ != *s2++) {
            return(1);
@@ -187,9 +217,11 @@ bcmp(s1,s2,n)
    acquiring the lock. The lock disappears when we close the file.
 
    Note that if the locked file is on an NFS-mounted partition, you
-   are at the mercy of SUN's lockd, which is probably a bad idea 
+   are at the mercy of SUN's lockd, which is probably a bad idea
 */
 
+int tac_lockfd TAC_ARGS((char *filename, int lockfd));
+
 int
 tac_lockfd (filename, lockfd)
 char *filename;
@@ -216,7 +248,7 @@ int lockfd;
                sleep(1);
                continue;
            } else {
-               syslog(LOG_ERR, "fcntl lock error status %d on %s %d %s", 
+               syslog(LOG_ERR, "fcntl lock error status %d on %s %d %s",
                       status, filename, lockfd, sys_errlist[errno]);
                return(0);
            }
@@ -226,7 +258,7 @@ int lockfd;
     }
 
     if (errno != 0) {
-       syslog(LOG_ERR, "Cannot lock %s fd %d in %d tries %s", 
+       syslog(LOG_ERR, "Cannot lock %s fd %d in %d tries %s",
               filename, lockfd, tries+1, sys_errlist[errno]);
 
        /* who is hogging this lock */
@@ -248,9 +280,9 @@ int lockfd;
 
        if (debug & DEBUG_LOCK_FLAG) {
            syslog(LOG_ERR, "Lock on %s is being held by sys=%u pid=%d",
-                  filename, 
+                  filename,
 #ifdef HAS_FLOCK_SYSID
-                  flock.l_sysid, 
+                  flock.l_sysid,
 #else
                   0,
 #endif
@@ -260,7 +292,7 @@ int lockfd;
     }
 
     if (debug & DEBUG_LOCK_FLAG) {
-       syslog(LOG_ERR, "Successfully locked %s fd %d after %d tries", 
+       syslog(LOG_ERR, "Successfully locked %s fd %d after %d tries",
               filename, lockfd, tries+1);
     }
     return(1);
@@ -270,10 +302,11 @@ int lockfd;
    releasing a lock. The lock dies when we close the file.
 
    Note that if the locked file is on an NFS-mounted partition, you
-   are at the mercy of SUN's lockd, which is probably a bad idea 
+   are at the mercy of SUN's lockd, which is probably a bad idea
 */
 
-int
+#if 0 /* unused */
+static int
 tac_unlockfd (filename,lockfd)
 char *filename;
 int lockfd;
@@ -292,14 +325,195 @@ int lockfd;
 
     status = fcntl(lockfd, F_UNLCK, &flock);
     if (status == -1) {
-       syslog(LOG_ERR, "fcntl unlock error status %d on %s %d %s", 
+       syslog(LOG_ERR, "fcntl unlock error status %d on %s %d %s",
               status, filename, lockfd, sys_errlist[errno]);
        return(1);
     }
 
     if (debug & DEBUG_LOCK_FLAG) {
-       syslog(LOG_ERR, "Successfully unlocked %s fd %d", 
+       syslog(LOG_ERR, "Successfully unlocked %s fd %d",
               filename, lockfd);
     }
     return(0);
 }
+#endif /* unused */
+
+/* Management of bidirectional lists.
+*/
+
+#ifdef TAC_LIST_PARANOIA
+
+static void tac_list_check_magic TAC_ARGS((const struct tac_list *list));
+
+static void
+tac_list_check_magic(list)
+const struct tac_list *list;
+{
+   if (list->_magic != TAC_LIST_MAGIC)
+       report(LOG_ERR, "MAGIC fail for tac_list");
+}
+
+static void tac_list_node_check_magic TAC_ARGS((const struct tac_list_node *node));
+
+static void
+tac_list_node_check_magic(node)
+const struct tac_list_node *node;
+{
+   if (node->_magic != TAC_LIST_NODE_MAGIC)
+       report(LOG_ERR, "MAGIC fail for tac_list_node");
+}
+#else /* TAC_LIST_PARANOIA */
+
+#define tac_list_check_magic(list)
+#define tac_list_node_check_magic(node)
+
+#endif /* TAC_LIST_PARANOIA */
+
+
+void tac_list_init TAC_ARGS((struct tac_list *list));
+
+void
+tac_list_init(list)
+struct tac_list *list;
+{
+#ifdef TAC_LIST_PARANOIA
+    list->_magic = TAC_LIST_MAGIC;
+#endif
+    list->_head = NULL;
+    list->_tail = NULL;
+
+    tac_list_check_magic(list);
+}
+
+void tac_list_node_init TAC_ARGS((struct tac_list_node *node));
+
+void
+tac_list_node_init(node)
+struct tac_list_node *node;
+{
+#ifdef TAC_LIST_PARANOIA
+    node->_magic = TAC_LIST_NODE_MAGIC;
+#endif
+    node->_list = NULL;
+
+    tac_list_node_check_magic(node);
+}
+
+struct tac_list *tac_list_node_get_list TAC_ARGS((struct tac_list_node *node));
+
+struct tac_list *
+tac_list_node_get_list(node)
+struct tac_list_node *node;
+{
+    tac_list_node_check_magic(node);
+
+    return (node->_list);
+}
+
+struct tac_list_node *tac_list_first_node TAC_ARGS((struct tac_list *list));
+
+struct tac_list_node *
+tac_list_first_node(list)
+struct tac_list *list;
+{
+    tac_list_check_magic(list);
+
+    return (list->_head);
+}
+
+#if 0 /* unused */
+struct tac_list_node *tac_list_last_node TAC_ARGS((struct tac_list *list));
+
+struct tac_list_node *
+tac_list_last_node(list)
+struct tac_list *list;
+{
+    tac_list_check_magic(list);
+
+    return (list->_tail);
+}
+#endif /* unused */
+
+void tac_list_addhead TAC_ARGS((struct tac_list *list, struct tac_list_node *node));
+
+void
+tac_list_addhead(list, node)
+struct tac_list *list;
+struct tac_list_node *node;
+{
+    tac_list_check_magic(list);
+    tac_list_node_check_magic(node);
+
+    if ((node->_next = list->_head))
+       node->_next->_prev = node;
+    list->_head = node;
+    node->_prev = NULL;
+    if (!list->_tail)
+       list->_tail = node;
+    node->_list = list;
+}
+
+void tac_list_addtail TAC_ARGS((struct tac_list *list, struct tac_list_node *node));
+
+void
+tac_list_addtail(list, node)
+struct tac_list *list;
+struct tac_list_node *node;
+{
+    tac_list_check_magic(list);
+    tac_list_node_check_magic(node);
+
+    if ((node->_prev = list->_tail))
+       node->_prev->_next = node;
+    list->_tail = node;
+    node->_next = NULL;
+    if (!list->_head)
+       list->_head = node;
+    node->_list = list;
+}
+
+struct tac_list_node *tac_list_node_next TAC_ARGS((struct tac_list_node *node));
+
+struct tac_list_node *
+tac_list_node_next(node)
+struct tac_list_node *node;
+{
+    tac_list_node_check_magic(node);
+
+    return (node->_next);
+}
+    
+#if 0 /* unused */
+struct tac_list_node *tac_list_node_prev TAC_ARGS((struct tac_list_node *node));
+
+struct tac_list_node *
+tac_list_node_prev(node)
+struct tac_list_node *node;
+{
+    tac_list_node_check_magic(node);
+
+    return (node->_prev);
+}
+#endif /* unused */
+
+void tac_list_node_remove TAC_ARGS((struct tac_list_node *node));
+
+void
+tac_list_node_remove(node)
+struct tac_list_node *node;
+{
+    tac_list_node_check_magic(node);
+    tac_list_check_magic(node->_list);
+
+    if (node->_next)
+       node->_next->_prev = node->_prev;
+    else
+       node->_list->_tail = node->_prev;
+
+    if (node->_prev)
+       node->_prev->_next = node->_next;
+    else
+       node->_list->_head = node->_next;
+
+    node->_list = NULL;
+}