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 |
40 | struct entry { |
41 | const char *path; |
42 | const char *sort; |
43 | const char *display; |
44 | }; |
45 | |
460b9539 |
46 | static 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 | |
54 | static 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 |
66 | static 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 | |
75 | static 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 |
85 | struct trackinfo_state { |
86 | dcgi_state *ds; |
87 | const struct queue_entry *q; |
88 | long length; |
89 | time_t when; |
90 | }; |
91 | |
460b9539 |
92 | struct result { |
93 | char *track; |
94 | const char *sort; |
95 | }; |
96 | |
97 | static 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 |
106 | static 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 |
121 | static 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 |
133 | static 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 | |
164 | static 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 | /* |
173 | Local Variables: |
174 | c-basic-offset:2 |
175 | comment-column:40 |
176 | fill-column:79 |
177 | End: |
178 | */ |