chiark / gitweb /
Almost compiles, will not work though
authorRichard Kettlewell <rjk@greenend.org.uk>
Sat, 10 May 2008 13:50:28 +0000 (14:50 +0100)
committerRichard Kettlewell <rjk@greenend.org.uk>
Sat, 10 May 2008 13:50:28 +0000 (14:50 +0100)
12 files changed:
lib/cgi.h
lib/macros-builtin.c
lib/macros.h
server/Makefile.am
server/actions.c
server/actions.h [new file with mode: 0644]
server/cgimain.c
server/lookup.c
server/lookup.h
server/macros-disorder.c
server/macros-disorder.h
server/options.c

index a26ee14..ec60482 100644 (file)
--- a/lib/cgi.h
+++ b/lib/cgi.h
@@ -28,7 +28,7 @@ struct sink;
 
 void cgi_init(void);
 const char *cgi_get(const char *name);
-void cgi_set(const char *name, const char *value)
+void cgi_set(const char *name, const char *value);
 char *cgi_sgmlquote(const char *src);
 void cgi_attr(struct sink *output, const char *name, const char *value);
 void cgi_opentag(struct sink *output, const char *name, ...);
index 0859695..551acbd 100644 (file)
@@ -61,7 +61,7 @@ const char *mx_bool2str(int n) {
 }
 
 /** @brief Write a boolean result */
-static int mx_bool_result(struct sink *output, int result) {
+int mx_bool_result(struct sink *output, int result) {
   if(sink_writes(output, mx_bool2str(result)) < 0)
     return -1;
   else
index a311102..772873c 100644 (file)
@@ -125,6 +125,7 @@ const struct mx_node *mx_rewritel(const struct mx_node *m,
 
 int mx_str2bool(const char *s);
 const char *mx_bool2str(int n);
+int mx_bool_result(struct sink *output, int result);
 
 #endif /* MACROS_H */
 
index 49d2d86..6b2c683 100644 (file)
@@ -100,9 +100,9 @@ disorder_dbupgrade_LDADD=$(LIBOBJS) ../lib/libdisorder.a \
        $(LIBDB) $(LIBGC) $(LIBPCRE) $(LIBICONV) $(LIBGCRYPT)
 disorder_dbupgrade_DEPENDENCIES=../lib/libdisorder.a
 
-disorder_cgi_SOURCES=dcgi.c dcgi.h                     \
-       api.c api-client.c api-client.h                 \
-       cgi.c server-cgi.h cgimain.c exports.c
+disorder_cgi_SOURCES=macros-disorder.c macros-disorder.h lookup.c      \
+       lookup.h options.c options.h actions.c actions.h api.c          \
+       api-client.c api-client.h cgimain.c exports.c
 disorder_cgi_LDADD=../lib/libdisorder.a \
        $(LIBPCRE) $(LIBGCRYPT) $(LIBDL) $(LIBDB)
 disorder_cgi_LDFLAGS=-export-dynamic
index 2332754..341f881 100644 (file)
 #include <config.h>
 #include "types.h"
 
+#include <string.h>
+#include <stdio.h>
+#include <errno.h>
+#include <time.h>
+#include <ctype.h>
+#include <stddef.h>
+
+#include "hash.h"
+#include "table.h"
+#include "client.h"
+#include "rights.h"
+#include "mem.h"
+#include "sink.h"
+#include "vector.h"
+#include "printf.h"
 #include "actions.h"
-#include "lookups.h"
+#include "lookup.h"
+#include "url.h"
+#include "configuration.h"
+#include "cgi.h"
+#include "log.h"
+#include "queue.h"
+#include "macros.h"
+#include "macros-disorder.h"
 
 /** @brief Login cookie */
 char *login_cookie;
@@ -66,7 +88,7 @@ static char *cookie(void) {
 static void redirect(const char *url) {
   /* By default use the 'back' argument */
   if(!url)
-    url = cgi_get("back")
+    url = cgi_get("back");
   if(url) {
     if(!strncmp(url, "http", 4))
       /* If the target is not a full URL assume it's the action */
@@ -87,8 +109,9 @@ static void act_playing(void) {
   long length;
   time_t now, fin;
   char *url;
+  const char *action;
 
-  lookups(DC_PLAYING|DC_QUEUE|DC_ENABLED|DC_RANDOM_ENABLED);
+  lookup(DC_PLAYING|DC_QUEUE|DC_ENABLED|DC_RANDOM_ENABLED);
   if(playing
      && playing->state == playing_started /* i.e. not paused */
      && !disorder_length(client, playing->track, &length)
@@ -171,9 +194,9 @@ void disorder_cgi_expand(const char *name) {
   for(p = name; *p && isalnum((unsigned char)*p); ++p)
     ;
   if(*p)
-    fatal(0, "invalid action name '%s'", action);
-  byte_xasprintf((char **)&p, "%s.tmpl", action);
-  if(mx_expand_file(p, sink_stdio(stdout), 0) == -1
+    fatal(0, "invalid action name '%s'", name);
+  byte_xasprintf((char **)&p, "%s.tmpl", name);
+  if(mx_expand_file(p, sink_stdio("stdout", stdout), 0) == -1
      || fflush(stdout) < 0)
     fatal(errno, "error writing to stdout");
 }
@@ -185,7 +208,6 @@ void disorder_cgi_expand(const char *name) {
  */
 void disorder_cgi_action(const char *action) {
   int n;
-  char *s;
 
   /* Consult CGI args if caller had no view */
   if(!action)
@@ -226,16 +248,16 @@ void disorder_cgi_error(const char *msg, ...) {
 }
 
 /** @brief Log in as the current user or guest if none */
-void disorder_cgi_login(dcgi_state *ds, struct sink *output) {
+void disorder_cgi_login(void) {
   /* Junk old data */
-  disorder_macros_reset();
+  lookup_reset();
   /* Reconnect */
   if(disorder_connect_cookie(client, login_cookie)) {
     disorder_cgi_error("Cannot connect to server");
     exit(0);
   }
   /* If there was a cookie but it went bad, we forget it */
-  if(login_cookie && !strcmp(disorder_user(>client), "guest"))
+  if(login_cookie && !strcmp(disorder_user(client), "guest"))
     login_cookie = 0;
 }
 
diff --git a/server/actions.h b/server/actions.h
new file mode 100644 (file)
index 0000000..5b58161
--- /dev/null
@@ -0,0 +1,39 @@
+/*
+ * This file is part of DisOrder.
+ * Copyright (C) 2004-2008 Richard Kettlewell
+ *
+ * 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
+ * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+ * USA
+ */
+#ifndef ACTIONS_H
+#define ACTIONS_H
+
+extern char *login_cookie;
+
+void disorder_cgi_expand(const char *name);
+void disorder_cgi_action(const char *action);
+void disorder_cgi_error(const char *msg, ...);
+void disorder_cgi_login(void);
+
+#endif /* ACTIONS_H */
+
+/*
+Local Variables:
+c-basic-offset:2
+comment-column:40
+fill-column:79
+indent-tabs-mode:nil
+End:
+*/
index 77764c0..695fb70 100644 (file)
@@ -35,7 +35,7 @@
 
 #include "client.h"
 #include "sink.h"
-#include "server-cgi.h"
+#include "hash.h"
 #include "mem.h"
 #include "log.h"
 #include "configuration.h"
 #include "api-client.h"
 #include "mime.h"
 #include "printf.h"
-#include "dcgi.h"
 #include "url.h"
-
 #include "macros.h"
 #include "macros-disorder.h"
+#include "cgi.h"
+#include "actions.h"
+#include "defs.h"
 
 /** @brief Return true if @p a is better than @p b
  *
@@ -77,9 +78,6 @@ static int better_cookie(const struct cookie *a, const struct cookie *b) {
 
 int main(int argc, char **argv) {
   const char *cookie_env, *conf;
-  dcgi_global g;
-  dcgi_state s;
-  cgi_sink output;
   int n, best_cookie;
   struct cookiedata cd;
 
@@ -95,7 +93,7 @@ int main(int argc, char **argv) {
     printf("<p>Sorry, PATH_INFO not supported.</p>\n");
     exit(0);
   }
-  cgi_parse();
+  cgi_init();
   /* We allow various things to be overridden from the environment.  This is
    * intended for debugging and is not a documented feature. */
   if((conf = getenv("DISORDER_CONFIG")))
@@ -108,9 +106,6 @@ int main(int argc, char **argv) {
    * necessary but it shouldn't be necessary in ordinary installations. */
   if(!config->url)
     config->url = infer_url();
-  memset(&g, 0, sizeof g);
-  memset(&s, 0, sizeof s);
-  output = sink_stdio("stdout", stdout);
   /* See if there's a cookie */
   cookie_env = getenv("HTTP_COOKIE");
   if(cookie_env) {
@@ -140,12 +135,13 @@ int main(int argc, char **argv) {
   mx_search_path(pkgconfdir);
   mx_search_path(pkgdatadir);
   /* Never cache anythging */
-  cgi_header(output->sink, "Cache-Control", "no-cache");
+  if(printf("Cache-Control: no-cache\n") < 0)
+    fatal(errno, "error writing to stdout");
   /* Create the initial connection, trying the cookie if we found a suitable
    * one. */
-  disorder_cgi_login(&s, &output);
+  disorder_cgi_login();
   /* The main program... */
-  disorder_cgi(&output, &s);
+  disorder_cgi_action(NULL);
   /* In practice if a write fails that probably means the web server went away,
    * but we log it anyway. */
   if(fclose(stdout) < 0)
index 235a7d2..4005238 100644 (file)
 #include <config.h>
 #include "types.h"
 
+#include <stdio.h>
+#include <string.h>
+
+#include "queue.h"
 #include "sink.h"
 #include "client.h"
+#include "rights.h"
 #include "lookup.h"
 #include "cgi.h"
 
@@ -62,11 +67,11 @@ int enabled;
 int random_enabled;
 
 /** @brief Fetch cachable data */
-static void lookup(unsigned want) {
+void lookup(unsigned want) {
   unsigned need = want ^ (flags & want);
   struct queue_entry *r, *rnext;
   const char *dir, *re;
-  char *rights;
+  char *rights_string;
 
   if(!client || !need)
     return;
@@ -106,8 +111,8 @@ static void lookup(unsigned want) {
   if(need & DC_RIGHTS) {
     rights = RIGHT_READ;       /* fail-safe */
     if(!disorder_userinfo(client, disorder_user(client),
-                          "rights", &rights))
-      parse_rights(rights, &rights, 1);
+                          "rights", &rights_string))
+      parse_rights(rights_string, &rights, 1);
   }
   if(need & DC_ENABLED)
     disorder_enabled(client, &enabled);
@@ -117,6 +122,17 @@ static void lookup(unsigned want) {
   flags |= need;
 }
 
+void lookup_reset(void) {
+  /* Junk the old connection if there is one */
+  if(client)
+    disorder_close(client);
+  /* Create a new connection */
+  client = disorder_new(0);
+  /* Forget everything we knew */
+  flags = 0;
+}
+
+
 /*
 Local Variables:
 c-basic-offset:2
index 0ab7355..1e48455 100644 (file)
@@ -58,6 +58,9 @@ extern rights_type rights;
 extern int enabled;
 extern int random_enabled;
 
+void lookup(unsigned want);
+void lookup_reset(void);
+
 #endif /* LOOKUP_H */
 
 /*
index cc79657..90c1392 100644 (file)
 #include <config.h>
 #include "types.h"
 
+#include <stdio.h>
+#include <stdarg.h>
+#include <string.h>
+#include <time.h>
+
+#include "kvp.h"
+#include "queue.h"
+#include "rights.h"
 #include "sink.h"
 #include "client.h"
 #include "cgi.h"
+#include "hash.h"
+#include "macros.h"
 #include "macros-disorder.h"
-#include "lookups.h"
+#include "lookup.h"
+#include "printf.h"
+#include "defs.h"
+#include "configuration.h"
+#include "trackname.h"
 
 /** @brief For error template */
 char *error_string;
@@ -37,17 +51,18 @@ char *error_string;
 static struct queue_entry *findtrack(const char *id) {
   struct queue_entry *q;
 
-  lookups(DC_PLAYING);
+  lookup(DC_PLAYING);
   if(playing && !strcmp(playing->id, id))
     return playing;
-  lookups(DC_QUEUE);
+  lookup(DC_QUEUE);
   for(q = queue; q; q = q->next)
     if(!strcmp(q->id, id))
       return q;
-  lookups(DC_RECENT);
+  lookup(DC_RECENT);
   for(q = recent; q; q = q->next)
     if(!strcmp(q->id, id))
       return q;
+  return NULL;
 }
 
 /** @brief Return @p i as a string */
@@ -74,7 +89,7 @@ static int exp_server_version(int attribute((unused)) nargs,
       v = "(cannot get version)";
   } else
     v = "(server not running)";
-  return sink_write(output, cgi_sgmlquote(v)) < 0 ? -1 : 0;
+  return sink_writes(output, cgi_sgmlquote(v)) < 0 ? -1 : 0;
 }
 
 /* @version
@@ -85,8 +100,8 @@ static int exp_version(int attribute((unused)) nargs,
                       char attribute((unused)) **args,
                       struct sink *output,
                       void attribute((unused)) *u) {
-  return sink_write(output,
-                   cgi_sgmlquote(disorder_short_version_string)) < 0 ? -1 : 0;
+  return sink_writes(output,
+                     cgi_sgmlquote(disorder_short_version_string)) < 0 ? -1 : 0;
 }
 
 /* @url
@@ -97,8 +112,8 @@ static int exp_url(int attribute((unused)) nargs,
                   char attribute((unused)) **args,
                   struct sink *output,
                   void attribute((unused)) *u) {
-  return sink_write(output,
-                   cgi_sgmlquote(config->url)) < 0 ? -1 : 0;
+  return sink_writes(output,
+                     cgi_sgmlquote(config->url)) < 0 ? -1 : 0;
 }
 
 /* @arg{NAME}
@@ -112,8 +127,8 @@ static int exp_arg(int attribute((unused)) nargs,
                   void attribute((unused)) *u) {
   const char *s = cgi_get(args[0]);
   if(s)
-    return sink_write(output,
-                     cgi_sgmlquote(s)) < 0 ? -1 : 0;
+    return sink_writes(output,
+                       cgi_sgmlquote(s)) < 0 ? -1 : 0;
   else
     return 0;
 }
@@ -127,10 +142,10 @@ static int exp_user(int attribute((unused)) nargs,
                    char attribute((unused)) **args,
                    struct sink *output,
                    void attribute((unused)) *u) {
-  const char *u;
+  const char *user;
   
-  if(client && (u = disorder_user(client)))
-    return sink_write(output, cgi_sgmlquote(u)) < 0 ? -1 : 0;
+  if(client && (user = disorder_user(client)))
+    return sink_writes(output, cgi_sgmlquote(user)) < 0 ? -1 : 0;
   return 0;
 }
 
@@ -163,10 +178,11 @@ static int exp_part(int nargs,
       return 0;
   }
   if(client
-     && !disorder_get(client, &s, track,
-                      !strcmp(context, "short") ? "display" : context,
-                      part))
-    return sink_write(output, cgi_sgmlquote(s)) < 0 ? -1 : 0;
+     && !disorder_part(client, &s,
+                       track,
+                       !strcmp(context, "short") ? "display" : context,
+                       part))
+    return sink_writes(output, cgi_sgmlquote(s)) < 0 ? -1 : 0;
   return 0;
 }
 
@@ -179,7 +195,7 @@ static int exp_quote(int attribute((unused)) nargs,
                      char **args,
                      struct sink *output,
                      void attribute((unused)) *u) {
-  return sink_write(output, cgi_sgmlquote(args[0])) < 0 ? -1 : 0;
+  return sink_writes(output, cgi_sgmlquote(args[0])) < 0 ? -1 : 0;
 }
 
 /* @who{ID}
@@ -194,7 +210,7 @@ static int exp_who(int attribute((unused)) nargs,
   struct queue_entry *q = findtrack(args[0]);
 
   if(q && q->submitter)
-    return sink_write(output, cgi_sgmlquote(q->submitter)) < 0 ? -1 : 0;
+    return sink_writes(output, cgi_sgmlquote(q->submitter)) < 0 ? -1 : 0;
   return 0;
 }
 
@@ -232,7 +248,7 @@ static int exp_when(int attribute((unused)) nargs,
     if(w)
       return sink_printf(output, "%d:%02d", w->tm_hour, w->tm_min) < 0 ? -1 : 0;
   }
-  return sink_write(output, "&nbsp;") < 0 ? -1 : 0;
+  return sink_writes(output, "&nbsp;") < 0 ? -1 : 0;
 }
 
 /* @length{ID|TRACK}
@@ -256,7 +272,7 @@ static int exp_length(int attribute((unused)) nargs,
     /* Track identified by queue ID */
     if(!(q = findtrack(args[0])))
       return 0;
-    if(q->state == play_start || q->state == playing_paused)
+    if(q->state == playing_started || q->state == playing_paused)
       if(sink_printf(output, "%ld:%02ld/", q->sofar / 60, q->sofar % 60) < 0)
         return -1;
     name = q->track;
@@ -264,7 +280,7 @@ static int exp_length(int attribute((unused)) nargs,
   if(client && disorder_length(client, name, &length))
     return sink_printf(output, "%ld:%02ld",
                        length / 60, length % 60) < 0 ? -1 : 0;
-  return sink_write(output, "&nbsp;") < 0 ? -1 : 0;
+  return sink_writes(output, "&nbsp;") < 0 ? -1 : 0;
 }
 
 /* @removable{ID}
@@ -319,16 +335,17 @@ static int exp_movable(int attribute((unused)) nargs,
 static int exp_playing(int nargs,
                        const struct mx_node **args,
                        struct sink *output,
-                       void attribute((unused)) *u) {
+                       void *u) {
   lookup(DC_PLAYING);
   if(!playing)
     return 0;
   if(!nargs)
-    return sink_write(output, playing->id) < 0 ? -1 : 0;
-  return mx_rewritel(args[0],
-                     "id", playing->id,
-                     "track", playing->track,
-                     (char *)0);
+    return sink_writes(output, playing->id) < 0 ? -1 : 0;
+  return mx_expand(mx_rewritel(args[0],
+                               "id", playing->id,
+                               "track", playing->track,
+                               (char *)0),
+                   output, u);
 }
 
 /* @queue{TEMPLATE}
@@ -344,20 +361,21 @@ static int exp_playing(int nargs,
 static int exp_queue(int attribute((unused)) nargs,
                      const struct mx_node **args,
                      struct sink *output,
-                     void attribute((unused)) *u) {
+                     void *u) {
   struct queue_entry *q;
   int rc, i;
   
   lookup(DC_QUEUE);
   for(q = queue, i = 0; q; q = q->next, ++i)
-    if((rc = mx_rewritel(args[0],
-                         "id", q->id,
-                         "track", q->track,
-                         "index", make_index(i),
-                         "parity", i % 2 ? "odd" : "even",
-                         "first", q == queue ? "true" : "false",
-                         "last", q->next ? "false" : "true",
-                         (char *)0)))
+    if((rc = mx_expand(mx_rewritel(args[0],
+                                   "id", q->id,
+                                   "track", q->track,
+                                   "index", make_index(i),
+                                   "parity", i % 2 ? "odd" : "even",
+                                   "first", q == queue ? "true" : "false",
+                                   "last", q->next ? "false" : "true",
+                                   (char *)0),
+                       output, u)))
       return rc;
   return 0;
 }
@@ -376,20 +394,21 @@ static int exp_queue(int attribute((unused)) nargs,
 static int exp_recent(int attribute((unused)) nargs,
                       const struct mx_node **args,
                       struct sink *output,
-                      void attribute((unused)) *u) {
+                      void *u) {
   struct queue_entry *q;
   int rc, i;
   
   lookup(DC_RECENT);
   for(q = recent, i = 0; q; q = q->next, ++i)
-    if((rc = mx_rewritel(args[0],
-                         "id", q->id,
-                         "track", q->track,
-                         "index", make_index(i),
-                         "parity", i % 2 ? "odd" : "even",
-                         "first", q == recent ? "true" : "false",
-                         "last", q->next ? "false" : "true",
-                         (char *)0)))
+    if((rc = mx_expand(mx_rewritel(args[0],
+                                   "id", q->id,
+                                   "track", q->track,
+                                   "index", make_index(i),
+                                   "parity", i % 2 ? "odd" : "even",
+                                   "first", q == recent ? "true" : "false",
+                                   "last", q->next ? "false" : "true",
+                                   (char *)0),
+                       output, u)))
       return rc;
   return 0;
 }
@@ -410,20 +429,20 @@ static int exp_recent(int attribute((unused)) nargs,
 static int exp_new(int attribute((unused)) nargs,
                    const struct mx_node **args,
                    struct sink *output,
-                   void attribute((unused)) *u) {
-  struct queue_entry *q;
+                   void *u) {
   int rc, i;
   
   lookup(DC_NEW);
   /* TODO perhaps we should generate an ID value for tracks in the new list */
   for(i = 0; i < nnew; ++i)
-    if((rc = mx_rewritel(args[0],
-                         "track", new[i],
-                         "index", make_index(i),
-                         "parity", i % 2 ? "odd" : "even",
-                         "first", i == 0 ? "true" : "false",
-                         "last", i == nnew - 1 ? "false" : "true",
-                         (char *)0)))
+    if((rc = mx_expand(mx_rewritel(args[0],
+                                   "track", new[i],
+                                   "index", make_index(i),
+                                   "parity", i % 2 ? "odd" : "even",
+                                   "first", i == 0 ? "true" : "false",
+                                   "last", i == nnew - 1 ? "false" : "true",
+                                   (char *)0),
+                       output, u)))
       return rc;
   return 0;
 }
@@ -438,9 +457,9 @@ static int exp_volume(int attribute((unused)) nargs,
                       struct sink *output,
                       void attribute((unused)) *u) {
   lookup(DC_VOLUME);
-  return sink_write(output, "%d",
-                    !strcmp(args[0], "left")
-                            ? volume_left : volume_right) < 0 ? -1 : 0;
+  return sink_printf(output, "%d",
+                     !strcmp(args[0], "left")
+                         ? volume_left : volume_right) < 0 ? -1 : 0;
 }
 
 /* @isplaying
@@ -504,7 +523,8 @@ static int exp_pref(int attribute((unused)) nargs,
   char *value;
 
   if(client && !disorder_get(client, args[0], args[1], &value))
-    return sink_write(output, cgi_sgmlquote(value)) < 0 ? -1 : 0;
+    return sink_writes(output, cgi_sgmlquote(value)) < 0 ? -1 : 0;
+  return 0;
 }
 
 /* @prefs{TRACK}{TEMPLATE}
@@ -523,7 +543,7 @@ static int exp_pref(int attribute((unused)) nargs,
 static int exp_prefs(int attribute((unused)) nargs,
                      const struct mx_node **args,
                      struct sink *output,
-                     void attribute((unused)) *u) {
+                     void *u) {
   int rc, i;
   struct kvp *k, *head;
   char *track;
@@ -533,14 +553,15 @@ static int exp_prefs(int attribute((unused)) nargs,
   if(!client || disorder_prefs(client, track, &head))
     return 0;
   for(k = head, i = 0; k; k = k->next, ++i)
-    if((rc = mx_rewritel(args[1],
-                         "index", make_index(i),
-                         "parity", i % 2 ? "odd" : "even",
-                         "name", k->name,
-                         "value", k->value,
-                         "first", k == head ? "true" : "false",
-                         "last", k->next ? "false" : "true",
-                         (char *)0)))
+    if((rc = mx_expand(mx_rewritel(args[1],
+                                   "index", make_index(i),
+                                   "parity", i % 2 ? "odd" : "even",
+                                   "name", k->name,
+                                   "value", k->value,
+                                   "first", k == head ? "true" : "false",
+                                   "last", k->next ? "false" : "true",
+                                   (char *)0),
+                       output, u)))
       return rc;
   return 0;
 }
@@ -556,8 +577,8 @@ static int exp_transform(int nargs,
                          struct sink *output,
                          void attribute((unused)) *u) {
   const char *t = trackname_transform(args[1], args[0],
-                                      (nargs > 2 ? args[2] : "display")));
-  return sink_write(output, cgi_sgmlquote(t)) < 0 ? -1 : 0;
+                                      (nargs > 2 ? args[2] : "display"));
+  return sink_writes(output, cgi_sgmlquote(t)) < 0 ? -1 : 0;
 }
 
 /* @enabled@
@@ -579,10 +600,10 @@ static int exp_enabled(int attribute((unused)) nargs,
  *
  * Expands to "true" if random play is enabled, otherwise "false".
  */
-static int exp_enabled(int attribute((unused)) nargs,
-                       char attribute((unused)) **args,
-                       struct sink *output,
-                       void attribute((unused)) *u) {
+static int exp_random_enabled(int attribute((unused)) nargs,
+                              char attribute((unused)) **args,
+                              struct sink *output,
+                              void attribute((unused)) *u) {
   int enabled = 0;
 
   if(client)
@@ -608,11 +629,11 @@ static int exp_trackstate(int attribute((unused)) nargs,
     return 0;
   lookup(DC_PLAYING);
   if(playing && !strcmp(track, playing->track))
-    return sink_write(output, "playing") < 0 ? -1 : 0;
+    return sink_writes(output, "playing") < 0 ? -1 : 0;
   lookup(DC_QUEUE);
   for(q = queue; q; q = q->next)
     if(!strcmp(track, q->track))
-      return sink_write(output, "queued") < 0 ? -1 : 0;
+      return sink_writes(output, "queued") < 0 ? -1 : 0;
   return 0;
 }
 
@@ -626,7 +647,7 @@ static int exp_thisurl(int attribute((unused)) nargs,
                        char attribute((unused)) **args,
                        struct sink *output,
                        void attribute((unused)) *u) {
-  return cgi_thisurl(config->url);
+  return sink_writes(output, cgi_thisurl(config->url)) < 0 ? -1 : 0;
 }
 
 /* @resolve{TRACK}
@@ -641,7 +662,7 @@ static int exp_resolve(int attribute((unused)) nargs,
   char *r;
 
   if(client && !disorder_resolve(client, &r, args[0]))
-    return sink_write(output, r) < 0 ? -1 : 0;
+    return sink_writes(output, r) < 0 ? -1 : 0;
   return 0;
 }
 
@@ -669,7 +690,7 @@ static int exp_state(int attribute((unused)) nargs,
   struct queue_entry *q = findtrack(args[0]);
 
   if(q)
-    return sink_write(output, playing_states[q->state]) < 0 ? -1 : 0;
+    return sink_writes(output, playing_states[q->state]) < 0 ? -1 : 0;
   return 0;
 }
 
@@ -687,14 +708,15 @@ static int exp_state(int attribute((unused)) nargs,
 static int exp_right(int nargs,
                      const struct mx_node **args,
                      struct sink *output,
-                     void attribute((unused)) *u) {
+                     void *u) {
   char *right;
   rights_type r;
+  int rc;
 
   if(!client)
     return 0;
   lookup(DC_RIGHTS);
-  if((rc = mx_expandstr(args[0], &rightname, u, "argument #0 (RIGHT)")))
+  if((rc = mx_expandstr(args[0], &right, u, "argument #0 (RIGHT)")))
     return rc;
   if(parse_rights(right, &r, 1/*report*/))
     return 0;
@@ -703,9 +725,9 @@ static int exp_right(int nargs,
     return mx_bool_result(output, !!(r & rights));
   /* Multiple argument form */
   if(r & rights)
-    return mx_expandl(args[1], (char *)0);
+    return mx_expand(args[1], output, u);
   if(nargs == 3)
-    return mx_expandl(args[2], (char *)0);
+    return mx_expand(args[2], output, u);
   return 0;
 }
 
@@ -720,7 +742,7 @@ static int exp_userinfo(int attribute((unused)) nargs,
   char *v;
 
   if(client && !disorder_userinfo(client, disorder_user(client), args[0], &v))
-    return sink_write(output, v) < 0 ? -1 : 0;
+    return sink_writes(output, v) < 0 ? -1 : 0;
   return 0;
 }
 
@@ -732,56 +754,45 @@ static int exp_error(int attribute((unused)) nargs,
                      char attribute((unused)) **args,
                      struct sink *output,
                      void attribute((unused)) *u) {
-  return sink_write(output, cgi_sgmlquote(error_string)) < 0 ? -1 : 0;
+  return sink_writes(output, cgi_sgmlquote(error_string)) < 0 ? -1 : 0;
 }
 
-/* @userinfo{PROPERTY}@
- *
 /** @brief Register DisOrder-specific expansions */
 void register_disorder_expansions(void) {
-  mx_register(exp_arg, 1, 1, "arg");
-  mx_register(exp_enabled, 0, 0, "enabled");
-  mx_register(exp_error, 0, 0, "error");
-  mx_register(exp_isnew, 0, 0, "isnew");
-  mx_register(exp_isplaying, 0, 0, "isplaying");
-  mx_register(exp_isqueue, 0, 0, "isplaying");
-  mx_register(exp_isrecent, 0, 0, "isrecent");
-  mx_register(exp_length, 1, 1, "length");
-  mx_register(exp_movable, 1, 1, "movable");
-  mx_register(exp_part, 2, 3, "part");
-  mx_register(exp_pref, 2, 2, "pref");
-  mx_register(exp_quote, 1, 1, "quote");
-  mx_register(exp_random_enabled, 0, 0, "random-enabled");
-  mx_register(exp_removable, 1, 1, "removable");
-  mx_register(exp_resolve, 1, 1, "resolve");
-  mx_register(exp_right, 1, 3, "right");
-  mx_register(exp_server_version, 0, 0, "server-version");
-  mx_register(exp_state, 1, 1, "state");
-  mx_register(exp_thisurl, 0, 0, "thisurl");
-  mx_register(exp_trackstate, 1, 1, "trackstate");
-  mx_register(exp_transform, 2, 3, "transform");
-  mx_register(exp_url, 0, 0, "url");
-  mx_register(exp_user, 0, 0, "user");
-  mx_register(exp_userinfo, 1, 1, "userinfo");
-  mx_register(exp_version, 0, 0, "version");
-  mx_register(exp_volume, 1, 1, "volume");
-  mx_register(exp_when, 1, 1, "when");
-  mx_register(exp_who, 1, 1, "who");
-  mx_register_magic(exp_new, 1, 1, "new");
-  mx_register_magic(exp_playing, 0, 1, "playing");
-  mx_register_magic(exp_prefs, 2, 2, "prefs");
-  mx_register_magic(exp_queue, 1, 1, "queue");
-  mx_register_magic(exp_recent, 1, 1, "recent");
-}
-
-void disorder_macros_reset(void) {
-  /* Junk the old connection if there is one */
-  if(client)
-    disorder_close(client);
-  /* Create a new connection */
-  client = disorder_new(0);
-  /* Forget everything we knew */
-  flags = 0;
+  mx_register("arg", 1, 1, exp_arg);
+  mx_register("enabled", 0, 0, exp_enabled);
+  mx_register("error", 0, 0, exp_error);
+  mx_register("isnew", 0, 0, exp_isnew);
+  mx_register("isplaying", 0, 0, exp_isplaying);
+  mx_register("isplaying", 0, 0, exp_isqueue);
+  mx_register("isrecent", 0, 0, exp_isrecent);
+  mx_register("length", 1, 1, exp_length);
+  mx_register("movable", 1, 1, exp_movable);
+  mx_register("part", 2, 3, exp_part);
+  mx_register("paused", 0, 0, exp_paused);
+  mx_register("pref", 2, 2, exp_pref);
+  mx_register("quote", 1, 1, exp_quote);
+  mx_register("random-enabled", 0, 0, exp_random_enabled);
+  mx_register("removable", 1, 1, exp_removable);
+  mx_register("resolve", 1, 1, exp_resolve);
+  mx_register("server-version", 0, 0, exp_server_version);
+  mx_register("state", 1, 1, exp_state);
+  mx_register("thisurl", 0, 0, exp_thisurl);
+  mx_register("trackstate", 1, 1, exp_trackstate);
+  mx_register("transform", 2, 3, exp_transform);
+  mx_register("url", 0, 0, exp_url);
+  mx_register("user", 0, 0, exp_user);
+  mx_register("userinfo", 1, 1, exp_userinfo);
+  mx_register("version", 0, 0, exp_version);
+  mx_register("volume", 1, 1, exp_volume);
+  mx_register("when", 1, 1, exp_when);
+  mx_register("who", 1, 1, exp_who);
+  mx_register_magic("new", 1, 1, exp_new);
+  mx_register_magic("playing", 0, 1, exp_playing);
+  mx_register_magic("prefs", 2, 2, exp_prefs);
+  mx_register_magic("queue", 1, 1, exp_queue);
+  mx_register_magic("recent", 1, 1, exp_recent);
+  mx_register_magic("right", 1, 3, exp_right);
 }
 
 /*
index 371e0f0..1dc8ba3 100644 (file)
@@ -28,33 +28,6 @@ extern disorder_client *client;
 extern char *error_string;
 void register_disorder_expansions(void);
 
-#define DC_QUEUE 0x0001
-#define DC_PLAYING 0x0002
-#define DC_RECENT 0x0004
-#define DC_VOLUME 0x0008
-#define DC_DIRS 0x0010
-#define DC_FILES 0x0020
-#define DC_NEW 0x0040
-#define DC_RIGHTS 0x0080
-
-static struct queue_entry *queue;
-static struct queue_entry *playing;
-static struct queue_entry *recent;
-
-static int volume_left;
-static int volume_right;
-
-static char **files;
-static int nfiles;
-
-static char **dirs;
-static int ndirs;
-
-static char **new;
-static int nnew;
-
-static rights_type rights;
-
 #endif /* MACROS_DISORDER_H */
 
 /*
index 88fc9bf..e3cf7b8 100644 (file)
@@ -25,6 +25,9 @@
 #include "types.h"
 
 #include <stdio.h>
+#include <stddef.h>
+#include <errno.h>
+#include <string.h>
 
 #include "mem.h"
 #include "hash.h"
 #include "options.h"
 #include "split.h"
 #include "table.h"
+#include "log.h"
+#include "inputline.h"
+#include "printf.h"
 
 struct column {
   int ncolumns;
   char **columns;
 };
 
+struct read_options_state {
+  const char *name;
+  int line;
+};
+
 static hash *labels;
 static hash *columns;
 
+static void option__readfile(const char *name);
+
 static void option__label(int attribute((unused)) nvec,
                         char **vec) {
   option_set(vec[0], vec[1]);
@@ -65,9 +78,9 @@ static struct option {
   int minargs, maxargs;
   void (*handler)(int nvec, char **vec);
 } options[] = {
-  { "columns", 1, INT_MAX, option_columns },
-  { "include", 1, 1, option_include },
-  { "label", 2, 2, option_label },
+  { "columns", 1, INT_MAX, option__columns },
+  { "include", 1, 1, option__include },
+  { "label", 2, 2, option__label },
 };
 
 static void option__split_error(const char *msg,
@@ -79,11 +92,9 @@ static void option__split_error(const char *msg,
 
 static void option__readfile(const char *name) {
   int n, i;
-  int fd;
   FILE *fp;
   char **vec, *buffer;
   struct read_options_state cs;
-  const char *path;
 
   if(!(cs.name = mx_find(name)))
     return;