Bring head revision up to date with cabal (try #3)
[oweals/tinc.git] / src / conf.c
index 35ca4d78160da58db39a8c35c1f4e7bb9c11b765..442e3960086b91be24b965357c46327d9ff6d133 100644 (file)
     along with this program; if not, write to the Free Software
     Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 
-    $Id: conf.c,v 1.9 2000/05/30 11:18:12 zarq Exp $
+    $Id: conf.c,v 1.10 2000/10/18 20:12:08 zarq Exp $
 */
 
 
-#include "config.h"
-
 #include <ctype.h>
 #include <errno.h>
 #include <netdb.h>
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
+#include <syslog.h>
 
 #include <xalloc.h>
 
 #include "conf.h"
 #include "netutl.h" /* for strtoip */
+#include <utils.h> /* for cp */
 
+#include "config.h"
+#include "connlist.h"
 #include "system.h"
 
-config_t *config;
+config_t *config = NULL;
 int debug_lvl = 0;
 int timeout = 0; /* seconds before timeout */
+char *confbase = NULL;           /* directory in which all config files are */
+char *netname = NULL;            /* name of the vpn network */
 
-typedef struct internal_config_t {
-  char *name;
-  enum which_t which;
-  int argtype;
-} internal_config_t;
+/* Will be set if HUP signal is received. It will be processed when it is safe. */
+int sighup = 0;
 
 /*
   These are all the possible configurable values
 */
 static internal_config_t hazahaza[] = {
-  { "AllowConnect", allowconnect,   TYPE_BOOL },   /* Is not used anywhere. Remove? */
-  { "ConnectTo",    upstreamip,     TYPE_IP },
-  { "ConnectPort",  upstreamport,   TYPE_INT },
-  { "ListenPort",   listenport,     TYPE_INT },
-  { "MyOwnVPNIP",   myvpnip,        TYPE_IP },
-  { "MyVirtualIP",  myvpnip,        TYPE_IP },   /* an alias */
-  { "Passphrases",  passphrasesdir, TYPE_NAME },
+/* Main configuration file keywords */
+  { "Name",         tincname,       TYPE_NAME },
+  { "ConnectTo",    connectto,      TYPE_NAME },
   { "PingTimeout",  pingtimeout,    TYPE_INT },
   { "TapDevice",    tapdevice,      TYPE_NAME },
+  { "TapSubnet",    tapsubnet,      TYPE_IP },
+  { "PrivateKey",   privatekey,     TYPE_NAME },
   { "KeyExpire",    keyexpire,      TYPE_INT },
-  { "VpnMask",      vpnmask,        TYPE_IP },
   { "Hostnames",    resolve_dns,    TYPE_BOOL },
+  { "Interface",    interface,      TYPE_NAME },
+  { "InterfaceIP",  interfaceip,    TYPE_IP },
+/* Host configuration file keywords */
+  { "Address",      address,        TYPE_NAME },
+  { "Port",         port,           TYPE_INT },
+  { "PublicKey",    publickey,      TYPE_NAME },
+  { "Subnet",       subnet,         TYPE_NAME },
+  { "RestrictHosts", restricthosts, TYPE_BOOL },
+  { "RestrictSubnets", restrictsubnets, TYPE_BOOL },
+  { "RestrictAddress", restrictaddress, TYPE_BOOL },
+  { "RestrictPort", restrictport,   TYPE_BOOL },
+  { "IndirectData", indirectdata,   TYPE_BOOL },
+  { "TCPonly",      tcponly,        TYPE_BOOL },
   { NULL, 0, 0 }
 };
 
@@ -74,12 +85,12 @@ static internal_config_t hazahaza[] = {
 config_t *
 add_config_val(config_t **cfg, int argtype, char *val)
 {
-  config_t *p;
+  config_t *p, *r;
   char *q;
-
+cp
   p = (config_t*)xmalloc(sizeof(*p));
   p->data.val = 0;
-  
+
   switch(argtype)
     {
     case TYPE_INT:
@@ -103,45 +114,56 @@ add_config_val(config_t **cfg, int argtype, char *val)
        p->data.val = 0;
     }
 
+  p->argtype = argtype;
+
   if(p->data.val)
     {
       p->next = *cfg;
       *cfg = p;
+cp
       return p;
     }
-
-  free(p);
-  return NULL;
+  else
+    {
+      free(p);
+cp
+      return NULL;
+    }
 }
 
 /*
-  Get variable from a section in a configfile. returns -1 on failure.
+  Parse a configuration file and put the results in the configuration tree
+  starting at *base.
 */
-int
-readconfig(const char *fname, FILE *fp)
+int read_config_file(config_t **base, const char *fname)
 {
-  char *line, *temp_buf;
+  int err = -1;
+  FILE *fp;
+  char line[MAXBUFSIZE];       /* There really should not be any line longer than this... */
   char *p, *q;
   int i, lineno = 0;
   config_t *cfg;
+cp
+  if((fp = fopen (fname, "r")) == NULL)
+    {
+      return -1;
+    }
 
-  line = (char *)xmalloc(80 * sizeof(char));
-  temp_buf = (char *)xmalloc(80 * sizeof(char));
-       
   for(;;)
     {
-      if(fgets(line, 80, fp) == NULL)
-       return 0;
+      if(fgets(line, MAXBUFSIZE, fp) == NULL)
+        {
+          err = 0;
+          break;
+        }
+        
+      lineno++;
 
-      while(!index(line, '\n'))
+      if(!index(line, '\n'))
         {
-         fgets(temp_buf, (strlen(line)+1) * 80, fp);
-         if(!temp_buf)
-           break;
-         strcat(line, temp_buf);
-         line = (char *)xrealloc(line, (strlen(line)+1) * sizeof(char));
+          syslog(LOG_ERR, _("Line %d too long while reading config file %s"), lineno, fname);
+          break;
         }        
-      lineno++;
 
       if((p = strtok(line, "\t\n\r =")) == NULL)
        continue; /* no tokens on this line */
@@ -155,66 +177,92 @@ readconfig(const char *fname, FILE *fp)
 
       if(!hazahaza[i].name)
        {
-         fprintf(stderr, _("%s: %d: Invalid variable name `%s'.\n"),
-                 fname, lineno, p);
-         return -1;
+         syslog(LOG_ERR, _("Invalid variable name on line %d while reading config file %s"),
+                 lineno, fname);
+          break;
        }
 
       if(((q = strtok(NULL, "\t\n\r =")) == NULL) || q[0] == '#')
        {
-         fprintf(stderr, _("%s: %d: No value given for `%s'.\n"),
-                 fname, lineno, hazahaza[i].name);
-         return -1;
+         fprintf(stderr, _("No value for variable on line %d while reading config file %s"),
+                 lineno, fname);
+         break;
        }
 
-      cfg = add_config_val(&config, hazahaza[i].argtype, q);
+      cfg = add_config_val(base, hazahaza[i].argtype, q);
       if(cfg == NULL)
        {
-         fprintf(stderr, _("%s: %d: Invalid value `%s' for variable `%s'.\n"),
-                 fname, lineno, q, hazahaza[i].name);
-         return -1;
+         fprintf(stderr, _("Invalid value for variable on line %d while reading config file %s"),
+                 lineno, fname);
+         break;
        }
 
       cfg->which = hazahaza[i].which;
       if(!config)
        config = cfg;
     }
-}
-
-/*
-  wrapper function for readconfig
-*/
-int
-read_config_file(const char *fname)
-{
-  FILE *fp;
-
-  if((fp = fopen (fname, "r")) == NULL)
-    {
-      fprintf(stderr, _("Could not open %s: %s\n"), fname, sys_errlist[errno]);
-      return 1;
-    }
-
-  if(readconfig(fname, fp))
-    return -1;
 
   fclose (fp);
+cp
+  return err;
+}
 
-  return 0;
+int read_server_config()
+{
+  char *fname;
+  int x;
+cp
+  asprintf(&fname, "%s/tinc.conf", confbase);
+  x = read_config_file(&config, fname);
+  free(fname);
+cp
+  return x;  
 }
 
 /*
   Look up the value of the config option type
 */
-const config_t *
-get_config_val(which_t type)
+const config_t *get_config_val(config_t *p, which_t type)
 {
-  config_t *p;
+cp
+  for(; p != NULL; p = p->next)
+    if(p->which == type)
+      break;
+cp
+  return p;
+}
 
-  for(p = config; p != NULL; p = p->next)
+/*
+  Support for multiple config lines.
+  Index is used to get a specific value, 0 being the first, 1 the second etc.
+*/
+const config_t *get_next_config_val(config_t *p, which_t type, int index)
+{
+cp  
+  for(; p != NULL; p = p->next)
     if(p->which == type)
-      return p;
+      if(--index < 0)
+        break;
+cp  
+  return p;
+}
 
-  /* Not found */
-  return NULL;
+/*
+  Remove the complete configuration tree.
+*/
+void clear_config(config_t **base)
+{
+  config_t *p, *next;
+cp
+  for(p = *base; p != NULL; p = next)
+    {
+      next = p->next;
+      if(p->data.ptr && (p->argtype == TYPE_NAME))
+        {
+          free(p->data.ptr);
+        }
+      free(p);
+    }
+  *base = NULL;
+cp
 }