chiark / gitweb /
Empty back= should be treated as if absent
[disorder] / server / dcgi.c
CommitLineData
460b9539 1
2#include <stdio.h>
3#include <errno.h>
4#include <sys/types.h>
5#include <sys/socket.h>
6#include <stddef.h>
7#include <stdlib.h>
8#include <time.h>
9#include <unistd.h>
10#include <string.h>
11#include <sys/wait.h>
12#include <pcre.h>
13#include <assert.h>
14
15#include "client.h"
16#include "mem.h"
17#include "vector.h"
18#include "sink.h"
9faa7a88 19#include "server-cgi.h"
460b9539 20#include "log.h"
21#include "configuration.h"
22#include "table.h"
23#include "queue.h"
24#include "plugin.h"
25#include "split.h"
460b9539 26#include "wstat.h"
27#include "kvp.h"
28#include "syscalls.h"
29#include "printf.h"
30#include "regsub.h"
31#include "defs.h"
32#include "trackname.h"
61507e3c 33#include "charset.h"
938d8157 34#include "dcgi.h"
36bde473 35#include "url.h"
36#include "mime.h"
bb6ae3fb 37#include "sendmail.h"
f902253a 38#include "base64.h"
460b9539 39
460b9539 40struct entry {
41 const char *path;
42 const char *sort;
43 const char *display;
44};
45
460b9539 46static int compare_entry(const void *a, const void *b) {
47 const struct entry *ea = a, *eb = b;
48
49 return compare_tracks(ea->sort, eb->sort,
50 ea->display, eb->display,
51 ea->path, eb->path);
52}
53
54static const char *front_url(void) {
55 char *url;
56 const char *mgmt;
57
58 /* preserve management interface visibility */
59 if((mgmt = cgi_get("mgmt")) && !strcmp(mgmt, "true")) {
60 byte_xasprintf(&url, "%s?mgmt=true", config->url);
61 return url;
62 }
63 return config->url;
64}
65
7f66f58b 66static void redirect(struct sink *output) {
67 const char *back;
68
69 back = cgi_get("back");
70 cgi_header(output, "Location", back && *back ? back : front_url());
71 header_cookie(output);
72 cgi_body(output);
fdf98378 73}
74
75static void expand_template(dcgi_state *ds, cgi_sink *output,
76 const char *action) {
77 cgi_header(output->sink, "Content-Type", "text/html");
7f66f58b 78 header_cookie(output->sink);
fdf98378 79 cgi_body(output->sink);
80 expand(output, action, ds);
81}
82
460b9539 83/* expansions *****************************************************************/
84
460b9539 85struct trackinfo_state {
86 dcgi_state *ds;
87 const struct queue_entry *q;
88 long length;
89 time_t when;
90};
91
460b9539 92struct result {
93 char *track;
94 const char *sort;
95};
96
97static int compare_result(const void *a, const void *b) {
98 const struct result *ra = a, *rb = b;
99 int c;
100
101 if(!(c = strcmp(ra->sort, rb->sort)))
102 c = strcmp(ra->track, rb->track);
103 return c;
104}
105
460b9539 106static void exp_stats(int attribute((unused)) nargs,
107 char attribute((unused)) **args,
108 cgi_sink *output,
109 void *u) {
110 dcgi_state *ds = u;
111 char **v;
112
113 cgi_opentag(output->sink, "pre", "class", "stats", (char *)0);
114 if(!disorder_stats(ds->g->client, &v, 0)) {
115 while(*v)
116 cgi_output(output, "%s\n", *v++);
117 }
118 cgi_closetag(output->sink, "pre");
119}
120
460b9539 121static char *expandarg(const char *arg, dcgi_state *ds) {
122 struct dynstr d;
123 cgi_sink output;
124
125 dynstr_init(&d);
126 output.quote = 0;
127 output.sink = sink_dynstr(&d);
128 expandstring(&output, arg, ds);
129 dynstr_terminate(&d);
130 return d.vec;
131}
132
460b9539 133static void exp_navigate(int attribute((unused)) nargs,
134 char **args,
135 cgi_sink *output,
136 void *u) {
137 dcgi_state *ds = u;
138 dcgi_state substate;
139 const char *path = expandarg(args[0], ds);
140 const char *ptr;
141 int dirlen;
142
143 if(*path) {
144 memset(&substate, 0, sizeof substate);
145 substate.g = ds->g;
146 ptr = path + 1; /* skip root */
147 dirlen = 0;
148 substate.nav_path = path;
149 substate.first = 1;
150 while(*ptr) {
151 while(*ptr && *ptr != '/')
152 ++ptr;
153 substate.last = !*ptr;
154 substate.nav_len = ptr - path;
155 substate.nav_dirlen = dirlen;
156 expandstring(output, args[1], &substate);
157 dirlen = substate.nav_len;
158 if(*ptr) ++ptr;
159 substate.first = 0;
160 }
161 }
162}
163
164static void exp_fullname(int attribute((unused)) nargs,
165 char attribute((unused)) **args,
166 cgi_sink *output,
167 void *u) {
168 dcgi_state *ds = u;
169 cgi_output(output, "%.*s", ds->nav_len, ds->nav_path);
170}
171
460b9539 172/*
173Local Variables:
174c-basic-offset:2
175comment-column:40
176fill-column:79
177End:
178*/