#include "url.h"
#include "mime.h"
#include "sendmail.h"
+#include "base64.h"
char *login_cookie;
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) {
* 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);
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");
expand_template(ds, output, "login");
}
+static void act_reminder(cgi_sink *output,
+ dcgi_state *ds) {
+ const char *const username = cgi_get("username");
+
+ if(!username || !*username) {
+ cgi_set_option("error", "nousername");
+ expand_template(ds, output, "login");
+ return;
+ }
+ if(disorder_reminder(ds->g->client, username)) {
+ cgi_set_option("error", "reminderfailed");
+ expand_template(ds, output, "login");
+ return;
+ }
+ cgi_set_option("status", "reminded");
+ expand_template(ds, output, "login");
+}
static const struct action {
const char *name;
{ "random-disable", act_random_disable },
{ "random-enable", act_random_enable },
{ "register", act_register },
+ { "reminder", act_reminder },
{ "remove", act_remove },
{ "resume", act_resume },
{ "scratch", act_scratch },