chiark / gitweb /
Further macro tests
[disorder] / server / dcgi.c
index 81b6943aecbac6aeb7f40cd5277ec9234678609d..16a5a6cb6c9698994f6a5d97995b9e679fb1fadd 100644 (file)
@@ -57,6 +57,7 @@
 #include "url.h"
 #include "mime.h"
 #include "sendmail.h"
+#include "base64.h"
 
 char *login_cookie;
 
@@ -73,15 +74,23 @@ struct entry {
   const char *display;
 };
 
+static const char nonce_base64_table[] =
+  "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-/*";
+
 static const char *nonce(void) {
-  static unsigned long count;
-  char *s;
+  static uint32_t count;
+
+  struct ndata {
+    uint16_t count;
+    uint16_t pid;
+    uint32_t when;
+  } nd;
 
-  byte_xasprintf(&s, "%lx%lx%lx",
-          (unsigned long)time(0),
-          (unsigned long)getpid(),
-          count++);
-  return s;
+  nd.count = count++;
+  nd.pid = (uint32_t)getpid();
+  nd.when = (uint32_t)time(0);
+  return generic_to_base64((void *)&nd, sizeof nd,
+                          nonce_base64_table);
 }
 
 static int compare_entry(const void *a, const void *b) {
@@ -124,6 +133,12 @@ static void header_cookie(struct sink *output) {
      * cause the browser to expose the cookie to other CGI programs on the same
      * web server. */
     dynstr_append_string(d, ";Version=1;Path=");
+    /* Formally we are supposed to quote the path, since it invariably has a
+     * slash in it.  However Safari does not parse quoted paths correctly, so
+     * this won't work.  Fortunately nothing else seems to care about proper
+     * quoting of paths, so in practice we get with it.  (See also
+     * parse_cookie() where we are liberal about cookie paths on the way back
+     * in.) */
     dynstr_append_string(d, u.path);
   }
   dynstr_terminate(d);
@@ -411,8 +426,18 @@ static void process_prefs(dcgi_state *ds, int numfile) {
       disorder_unset(ds->g->client, file, "pick_at_random");
     else
       disorder_set(ds->g->client, file, "pick_at_random", "0");
-    if((value = numbered_arg("tags", numfile)))
-      disorder_set(ds->g->client, file, "tags", value);
+    if((value = numbered_arg("tags", numfile))) {
+      if(!*value)
+       disorder_unset(ds->g->client, file, "tags");
+      else
+       disorder_set(ds->g->client, file, "tags", value);
+    }
+    if((value = numbered_arg("weight", numfile))) {
+      if(!*value || !strcmp(value, "90000"))
+       disorder_unset(ds->g->client, file, "weight");
+      else
+       disorder_set(ds->g->client, file, "weight", value);
+    }
   } else if((name = cgi_get("name"))) {
     /* Raw preferences.  Not well supported in the templates at the moment. */
     value = cgi_get("value");
@@ -1735,6 +1760,17 @@ static void exp_image(int attribute((unused)) nargs,
     cgi_output(output, "/disorder/%s", imagestem);
 }
 
+static void exp_define(int attribute((unused)) nargs,
+                      char **args,
+                      cgi_sink attribute((unused)) *output,
+                      void attribute((unused)) *u) {
+  const char *n = args[0], *a = args[1], *v = args[2];
+  int nas;
+  char **as = split(a, &nas, 0, 0, 0);
+
+  cgi_define(n, nas, as, v);
+}
+
 static const struct cgi_expansion expansions[] = {
   { "#", 0, INT_MAX, EXP_MAGIC, exp_comment },
   { "action", 0, 0, 0, exp_action },
@@ -1742,6 +1778,7 @@ static const struct cgi_expansion expansions[] = {
   { "arg", 1, 1, 0, exp_arg },
   { "basename", 0, 1, 0, exp_basename },
   { "choose", 2, 2, EXP_MAGIC, exp_choose },
+  { "define", 3, 3, EXP_MAGIC, exp_define },
   { "dirname", 0, 1, 0, exp_dirname },
   { "enabled", 0, 0, 0, exp_enabled },
   { "eq", 2, 2, 0, exp_eq },