xpp: allow XTALK_OPTIONS from a file
authorOron Peled <oron.peled@xorcom.com>
Mon, 22 Dec 2014 18:32:33 +0000 (20:32 +0200)
committerTzafrir Cohen <tzafrir.cohen@xorcom.com>
Thu, 5 Nov 2015 16:05:44 +0000 (18:05 +0200)
* The file is defined as XTALK_OPTIONS_FILE (/etc/dahdi/xpp.conf):
  - Lines beginning with '#' are skipped.
  - Line beginning with "XTALK_OPTIONS" are used.
  - Anything after whitespaces (with optional "=" characters) is part
    of the value.

* An environment variable named "XTALK_OPTIONS" may override file contents.

Signed-off-by: Oron Peled <oron.peled@xorcom.com>
Signed-off-by: Tzafrir Cohen <tzafrir.cohen@xorcom.com>

xpp/xtalk/Makefile.am
xpp/xtalk/xusb_common.c

index f719627..3cbdaa2 100644 (file)
@@ -1,5 +1,11 @@
 VISIBILITY_DEFS                = -DXTALK_DLL -DXTALK_DLL_EXPORTS
-COMMON_CFLAGS          = -Wall -Wno-unknown-pragmas -Werror $(VISIBILITY_DEFS) $(CFLAG_VISIBILITY)
+COMMON_CFLAGS          = \
+               -Wall \
+               -Wno-unknown-pragmas \
+               -Werror \
+               $(VISIBILITY_DEFS) \
+               $(CFLAG_VISIBILITY)
+
 AM_CFLAGS              = $(COMMON_CFLAGS)
 
 
@@ -35,7 +41,13 @@ dist_noinst_HEADERS  = \
 
 man_MANS               = xtalk_send.8
 
-libxtalk_la_CFLAGS     = $(COMMON_CFLAGS) -I$(srcdir)/include -I$(srcdir) $(USB_CFLAGS)
+libxtalk_la_CFLAGS     = \
+               $(COMMON_CFLAGS) \
+               -I$(srcdir)/include \
+               -I$(srcdir) \
+               $(USB_CFLAGS) \
+               -DXTALK_OPTIONS_FILE=\"/etc/dahdi/xpp.conf\"
+
 libxtalk_la_LDFLAGS    = #
 libxtalk_la_LIBADD     = $(USB_LIBS)
 libxtalk_la_SOURCES    = \
index 125f735..e5d4bbd 100644 (file)
@@ -1,5 +1,6 @@
 #define        _GNU_SOURCE     /* for memrchr() */
 #include <assert.h>
+#include <ctype.h>
 #include <errno.h>
 #include <stdarg.h>
 #include <stdlib.h>
@@ -360,16 +361,66 @@ int xtalk_option_use_clear_halt(void)
        return use_clear_halt;
 }
 
+static void chomp(char *buf)
+{
+       char *p;
+       int len;
+
+       if (!buf)
+               return;
+       len = strlen(buf);
+       for (p = buf + len - 1; p >= buf && isspace(*p); p--)
+               *p = '\0';
+}
+
+static const char *OPTION_VAR = "XTALK_OPTIONS";
+
+/* Caller should free the returned string if it is not NULL */
+static char *read_options(const char *fname)
+{
+       FILE *fp;
+       char buf[BUFSIZ];
+       char *p;
+       char *ret_buf;
+
+       fp = fopen(fname, "r");
+       if (!fp) {
+               DBG("Failed opening '$fname': %s\n", strerror(errno));
+               return NULL;
+       }
+       while (fgets(buf, sizeof(buf), fp) != NULL) {
+               chomp(buf);
+               if (buf[0] == '\0' || buf[0] == '#')
+                       continue;
+               if (strncmp(buf, OPTION_VAR, strlen(OPTION_VAR)) != 0)
+                       continue;
+               /* fprintf(stderr, "INPUT> '%s'\n", p); */
+               p = buf + strlen(OPTION_VAR);
+               while (*p && (isspace(*p) || *p == '='))
+                       p++;
+               ret_buf = malloc(sizeof(buf));
+               strcpy(ret_buf, p); /* Cannot overflow */
+               return ret_buf;
+       }
+       fclose(fp);
+       return NULL;
+}
+
 int xtalk_parse_options(void)
 {
        char *xtalk_options;
        char *saveptr;
        char *token;
        int ret;
+       int free_options = 0;
 
        xtalk_options = getenv("XTALK_OPTIONS");
-       if (!xtalk_options)
-               return 0;
+       if (!xtalk_options) {
+               xtalk_options = read_options(XTALK_OPTIONS_FILE);
+               if (!xtalk_options)
+                       return 0;
+               free_options = 1;
+       }
        token = strtok_r(xtalk_options, " \t", &saveptr);
        while (token) {
                ret = xtalk_one_option(token);
@@ -377,5 +428,7 @@ int xtalk_parse_options(void)
                        return ret;
                token = strtok_r(NULL, " \t", &saveptr);
        }
+       if (free_options)
+               free(xtalk_options);
        return 0;
 }