diff src/cfgparser.c @ 125:e413158cae13

Add ushare project files.
author naoyan@johnstown.minaminoshima.org
date Sun, 03 Oct 2010 11:35:19 +0900
parents
children 863ac6807ee3
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/cfgparser.c	Sun Oct 03 11:35:19 2010 +0900
@@ -0,0 +1,450 @@
+/*
+ * cfgparser.c : GeeXboX uShare config file parser.
+ * Originally developped for the GeeXboX project.
+ * Copyright (C) 2005-2007 Alexis Saettler <asbin@asbin.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <getopt.h>
+#include <stdbool.h>
+#include <limits.h>
+
+#include "config.h"
+#include "gettext.h"
+#include "cfgparser.h"
+#include "ushare.h"
+#include "trace.h"
+#include "osdep.h"
+
+#define USHARE_DIR_DELIM ","
+
+static bool
+ignore_line (const char *line)
+{
+  int i;
+  size_t len;
+
+  /* commented line */
+  if (line[0] == '#' )
+    return true;
+
+  len = strlen (line);
+
+  for (i = 0 ; i < (int) len ; i++ )
+    if (line[i] != ' ' && line[i] != '\t' && line[i] != '\n')
+      return false;
+
+  return true;
+}
+
+static char *
+strdup_trim (const char *s)
+{
+  size_t begin, end;
+  char *r = NULL;
+
+  if (!s)
+    return NULL;
+
+  end = strlen (s) - 1;
+
+  for (begin = 0 ; begin < end ; begin++)
+    if (s[begin] != ' ' && s[begin] != '\t' && s[begin] != '"')
+      break;
+
+  for (; begin < end ; end--)
+    if (s[end] != ' ' && s[end] != '\t' && s[end] != '"' && s[end] != '\n')
+      break;
+
+  r = strndup (s + begin, end - begin + 1);
+
+  return r;
+}
+
+static void
+ushare_set_name (struct ushare_t *ut, const char *name)
+{
+  if (!ut || !name)
+    return;
+
+  if (ut->name)
+  {
+    free (ut->name);
+    ut->name = NULL;
+  }
+
+  ut->name = strdup_trim (name);
+}
+
+static void
+ushare_set_interface (struct ushare_t *ut, const char *iface)
+{
+  if (!ut || !iface)
+    return;
+
+  if (ut->interface)
+  {
+    free (ut->interface);
+    ut->interface = NULL;
+  }
+
+  ut->interface = strdup_trim (iface);
+}
+
+static void
+ushare_add_contentdir (struct ushare_t *ut, const char *dir)
+{
+  if (!ut || !dir)
+    return;
+
+  ut->contentlist = content_add (ut->contentlist, dir);
+}
+
+static void
+ushare_set_cfg_file (struct ushare_t *ut, const char *file)
+{
+  if (!ut || !file)
+    return;
+
+  ut->cfg_file = strdup (file);
+}
+
+static void
+ushare_set_dir (struct ushare_t *ut, const char *dirlist)
+{
+  char *x = NULL, *token = NULL;
+  char *m_buffer = NULL, *buffer;
+
+  if (!ut || !dirlist)
+    return;
+
+  x = strdup_trim (dirlist);
+  if (x)
+  {
+    m_buffer = (char*) malloc (strlen (x) * sizeof (char));
+    if (m_buffer)
+    {
+      buffer = m_buffer;
+      token = strtok_r (x, USHARE_DIR_DELIM, &buffer);
+      while (token)
+      {
+        ushare_add_contentdir (ut, token);
+        token = strtok_r (NULL, USHARE_DIR_DELIM, &buffer);
+      }
+      free (m_buffer);
+    }
+    free (x);
+  }
+}
+
+static void
+ushare_set_port (struct ushare_t *ut, const char *port)
+{
+  if (!ut || !port)
+    return;
+
+  ut->port = atoi (port);
+  if (ut->port < 49152)
+  {
+    fprintf (stderr,
+             _("Warning: port doesn't fit IANA port assignements.\n"));
+
+    fprintf (stderr, _("Warning: Only Dynamic or Private Ports can be used "
+                       "(from 49152 through 65535)\n"));
+    ut->port = 0;
+  }
+}
+
+static void
+ushare_set_telnet_port (struct ushare_t *ut, const char *port)
+{
+  if (!ut || !port)
+    return;
+
+  ut->telnet_port = atoi (port);
+}
+
+static void
+ushare_use_web (struct ushare_t *ut, const char *val)
+{
+  if (!ut || !val)
+    return;
+
+  ut->use_presentation = (!strcmp (val, "yes")) ? true : false;
+}
+
+static void
+ushare_use_telnet (struct ushare_t *ut, const char *val)
+{
+  if (!ut || !val)
+    return;
+
+  ut->use_telnet = (!strcmp (val, "yes")) ? true : false;
+}
+
+static void
+ushare_use_xbox (struct ushare_t *ut, const char *val)
+{
+  if (!ut || !val)
+    return;
+
+  ut->xbox360 = (!strcmp (val, "yes")) ? true : false;
+}
+
+static void
+ushare_use_dlna (struct ushare_t *ut, const char *val)
+{
+  if (!ut || !val)
+    return;
+
+#ifdef HAVE_DLNA
+  ut->dlna_enabled = (!strcmp (val, "yes")) ? true : false;
+#endif /* HAVE_DLNA */
+}
+
+static void
+ushare_set_override_iconv_err (struct ushare_t *ut, const char *arg)
+{
+  if (!ut)
+    return;
+
+  ut->override_iconv_err = false;
+
+  if (!strcasecmp (arg, "yes")
+      || !strcasecmp (arg, "true")
+      || !strcmp (arg, "1"))
+    ut->override_iconv_err = true;
+}
+
+static u_configline_t configline[] = {
+  { USHARE_NAME,                 ushare_set_name                },
+  { USHARE_IFACE,                ushare_set_interface           },
+  { USHARE_PORT,                 ushare_set_port                },
+  { USHARE_TELNET_PORT,          ushare_set_telnet_port         },
+  { USHARE_DIR,                  ushare_set_dir                 },
+  { USHARE_OVERRIDE_ICONV_ERR,   ushare_set_override_iconv_err  },
+  { USHARE_ENABLE_WEB,           ushare_use_web                 },
+  { USHARE_ENABLE_TELNET,        ushare_use_telnet              },
+  { USHARE_ENABLE_XBOX,          ushare_use_xbox                },
+  { USHARE_ENABLE_DLNA,          ushare_use_dlna                },
+  { NULL,                        NULL                           },
+};
+
+static void
+parse_config_line (struct ushare_t *ut, const char *line,
+                   u_configline_t *configline)
+{
+  char *s = NULL;
+
+  s = strchr (line, '=');
+  if (s && s[1] != '\0')
+  {
+    int i;
+    for (i=0 ; configline[i].name ; i++)
+    {
+      if (!strncmp (line, configline[i].name, strlen (configline[i].name)))
+      {
+        configline[i].set_var (ut, s + 1);
+        break;
+      }
+    }
+  }
+}
+
+int
+parse_config_file (struct ushare_t *ut)
+{
+  char filename[PATH_MAX];
+  FILE *conffile;
+  char *line = NULL;
+  size_t size = 0;
+  ssize_t read;
+
+  if (!ut)
+    return -1;
+
+  if (!ut->cfg_file)
+    snprintf (filename, PATH_MAX, "%s/%s", SYSCONFDIR, USHARE_CONFIG_FILE); 
+  else
+    snprintf (filename, PATH_MAX, "%s", ut->cfg_file);
+
+  conffile = fopen (filename, "r");
+  if (!conffile)
+    return -1;
+
+  while ((read = getline (&line, &size, conffile)) != -1)
+  {
+    if (ignore_line (line))
+      continue;
+
+    if (line[read-1] == '\n')
+      line[read-1] = '\0';
+
+    while (line[0] == ' ' || line[0] == '\t')
+      line++;
+
+    parse_config_line (ut, line, configline);
+  }
+
+  fclose (conffile);
+
+  if (line)
+    free (line);
+
+  return 0;
+}
+
+inline static void
+display_usage (void)
+{
+  display_headers ();
+  printf ("\n");
+  printf (_("Usage: ushare [-n name] [-i interface] [-p port] [-c directory] [[-c directory]...]\n"));
+  printf (_("Options:\n"));
+  printf (_(" -n, --name=NAME\tSet UPnP Friendly Name (default is '%s')\n"),
+          DEFAULT_USHARE_NAME);
+  printf (_(" -i, --interface=IFACE\tUse IFACE Network Interface (default is '%s')\n"),
+          DEFAULT_USHARE_IFACE);
+  printf (_(" -f, --cfg=FILE\t\tConfig file to be used\n"));
+  printf (_(" -p, --port=PORT\tForces the HTTP server to run on PORT\n"));
+  printf (_(" -q, --telnet-port=PORT\tForces the TELNET server to run on PORT\n"));
+  printf (_(" -c, --content=DIR\tShare the content of DIR directory\n"));
+  printf (_(" -w, --no-web\t\tDisable the control web page (enabled by default)\n"));
+  printf (_(" -t, --no-telnet\tDisable the TELNET control (enabled by default)\n"));
+  printf (_(" -o, --override-iconv-err\tIf iconv fails parsing name, still add to media contents (hoping the renderer can handle it)\n"));
+  printf (_(" -v, --verbose\t\tSet verbose display\n"));
+  printf (_(" -x, --xbox\t\tUse XboX 360 compliant profile\n"));
+#ifdef HAVE_DLNA
+  printf (_(" -d, --dlna\t\tUse DLNA compliant profile (PlayStation3 needs this)\n"));
+#endif /* HAVE_DLNA */
+  printf (_(" -D, --daemon\t\tRun as a daemon\n"));
+  printf (_(" -V, --version\t\tDisplay the version of uShare and exit\n"));
+  printf (_(" -h, --help\t\tDisplay this help\n"));
+}
+
+int
+parse_command_line (struct ushare_t *ut, int argc, char **argv)
+{
+  int c, index;
+  char short_options[] = "VhvDowtxdn:i:p:q:c:f:";
+  struct option long_options [] = {
+    {"version", no_argument, 0, 'V' },
+    {"help", no_argument, 0, 'h' },
+    {"verbose", no_argument, 0, 'v' },
+    {"daemon", no_argument, 0, 'D' },
+    {"override-iconv-err", no_argument, 0, 'o' },
+    {"name", required_argument, 0, 'n' },
+    {"interface", required_argument, 0, 'i' },
+    {"port", required_argument, 0, 'p' },
+    {"telnet-port", required_argument, 0, 'q' },
+    {"content", required_argument, 0, 'c' },
+    {"no-web", no_argument, 0, 'w' },
+    {"no-telnet", no_argument, 0, 't' },
+    {"xbox", no_argument, 0, 'x' },
+#ifdef HAVE_DLNA
+    {"dlna", no_argument, 0, 'd' },
+#endif /* HAVE_DLNA */
+    {"cfg", required_argument, 0, 'f' },
+    {0, 0, 0, 0 }
+  };
+
+  /* command line argument processing */
+  while (true)
+  {
+    c = getopt_long (argc, argv, short_options, long_options, &index);
+
+    if (c == EOF)
+      break;
+
+    switch (c)
+    {
+    case 0:
+      /* opt = long_options[index].name; */
+      break;
+
+    case '?':
+    case 'h':
+      display_usage ();
+      return -1;
+
+    case 'V':
+      display_headers ();
+      return -1;
+
+    case 'v':
+      ut->verbose = true;
+      break;
+
+    case 'D':
+      ut->daemon = true;
+      break;
+
+    case 'o':
+      ut->override_iconv_err = true;
+      break;
+
+    case 'n':
+      ushare_set_name (ut, optarg);
+      break;
+
+    case 'i':
+      ushare_set_interface (ut, optarg);
+      break;
+
+    case 'p':
+      ushare_set_port (ut, optarg);
+      break;
+
+    case 'q':
+      ushare_set_telnet_port (ut, optarg);
+      break;
+
+    case 'c':
+      ushare_add_contentdir (ut, optarg);
+      break;
+
+    case 'w':
+      ut->use_presentation = false;
+      break;
+
+    case 't':
+      ut->use_telnet = false;
+      break;
+
+    case 'x':
+      ut->xbox360 = true;
+      break;
+
+#ifdef HAVE_DLNA
+    case 'd':
+      ut->dlna_enabled = true;
+      break;
+#endif /* HAVE_DLNA */
+      
+    case 'f':
+      ushare_set_cfg_file (ut, optarg);
+      break;
+
+    default:
+      break;
+    }
+  }
+
+  return 0;
+}