]> git.zerfleddert.de Git - rigol/blob - rigold.c
export reset functionality
[rigol] / rigold.c
1 #include <sys/types.h>
2 #include <sys/socket.h>
3 #include <arpa/inet.h>
4 #include <stdio.h>
5 #include <stdlib.h>
6 #include <string.h>
7 #include <strings.h>
8 #include <unistd.h>
9 #include <signal.h>
10
11 #include "scope.h"
12 #include "commands.h"
13
14 #define TIMEOUT 4
15
16 static int send_binary(int s, char *buf, int len)
17 {
18 int ret;
19
20 while(len > 0) {
21 ret = write(s, buf, len);
22 if (ret == -1) {
23 perror("write");
24 return ret;
25 }
26 buf += ret;
27 len -= ret;
28 }
29
30 return 0;
31 }
32
33 static int send_text(int s, char *buf)
34 {
35 return send_binary(s, buf, strlen(buf));
36 }
37
38 static void serve_index(int s, struct scope *sc, char *param)
39 {
40 send_text(s, "HTTP/1.0 200 OK\n");
41 send_text(s, "Content-type: text/html\n\n");
42 send_text(s, "<html><head><title>");
43 send_text(s, scope_idn(sc));
44 send_text(s, "</title></head><body bgcolor=\"#ffffff\" text=\"#000000\">\n");
45 send_text(s, "<img src=\"/cgi-bin/lcd\" height=\"234\" width=\"320\">\n");
46 send_text(s, "<br>\n");
47 send_text(s, "<form method=\"get\" action=\"\">\n");
48 send_text(s, "<input type=\"text\" name=\"cmd\" value=\"");
49 if (param) {
50 if (strncmp(param, "cmd=", 4) == 0)
51 param += 4;
52
53 send_text(s, param);
54 }
55 send_text(s, "\">\n");
56 send_text(s, "<input type=\"submit\">\n");
57 send_text(s, "</form>\n");
58 if (param) {
59 unsigned char buf[1024*1024];
60 int res;
61
62 claimscope(sc);
63 if (strchr (param, '?')) {
64 res = sendscpi(sc, param, buf, sizeof(buf));
65 send_text(s, "<pre>< ");
66 send_text(s, param);
67 send_text(s, "\n> ");
68 send_binary(s, (char*)buf, res);
69 send_text(s, "</pre>\n");
70 } else {
71 sendscpi(sc, param, NULL, 0);
72 }
73 releasescope(sc);
74 }
75 send_text(s, "</body></html>\n");
76 }
77
78 static void serve_lcd(int s, struct scope *sc)
79 {
80 char buf[256];
81 int imglen;
82 unsigned char *png;
83
84 claimscope(sc);
85 png = get_lcd(sc, &imglen, 0);
86 releasescope(sc);
87
88 if (png == NULL)
89 return;
90
91
92 send_text(s, "HTTP/1.0 200 OK\n");
93 send_text(s, "Content-type: image/png\n");
94 snprintf(buf, sizeof(buf), "Content-length: %u\n\n", imglen);
95 send_text(s, buf);
96 send_binary(s, (char*)png, imglen);
97 free(png);
98 }
99
100 static void serve_404(int s)
101 {
102 send_text(s, "HTTP/1.0 404 Not found\n");
103 send_text(s, "Content-type: text/html\n\n");
104 send_text(s, "<html><head><title>404</title></head>");
105 send_text(s, "<body bgcolor=\"#ffffff\" text=\"#000000\">\n");
106 send_text(s, "<h1>404</h1>");
107 send_text(s, "</body></html>\n");
108 }
109
110 int is_eor(char *buf)
111 {
112 int eor = 0;
113
114 /* This does not completely work, when the request is split
115 in multiple packets... */
116 if (strstr(buf, "\x0d\x0a\x0d\x0a")) {
117 eor = 1;
118 } else if (strstr(buf, "\x0a\x0a")) {
119 eor = 1;
120 } else if (strcmp(buf, "\x0d\x0a") == 0) {
121 eor = 1;
122 } else if (strcmp(buf, "\x0a") == 0) {
123 eor = 1;
124 }
125
126 return eor;
127 }
128
129
130 static void parse_request(int s, struct scope *sc)
131 {
132 int ret;
133 int eor;
134 char buf[4096];
135 char file[4096];
136 const char delim[] = " \t\x0d\x0a";
137 char *saveptr;
138 char *token;
139 char *param = NULL;
140
141 alarm(TIMEOUT);
142 ret=read(s, buf, sizeof(buf)-1);
143 if (ret == -1) {
144 perror("read");
145 return;
146 }
147 buf[ret] = 0;
148
149 eor = is_eor(buf);
150
151 token = strtok_r(buf, delim, &saveptr);
152 if (token == NULL)
153 return;
154 /* TODO: Only GET... */
155 token = strtok_r(NULL, delim, &saveptr);
156 if (token == NULL)
157 return;
158 bzero(&file, sizeof(file));
159 strncpy(file, token, sizeof(file)-1);
160
161 while (!eor) {
162 alarm(TIMEOUT);
163 ret=read(s, buf, sizeof(buf)-1);
164 if (ret == -1) {
165 perror("read");
166 return;
167 }
168 buf[ret] = 0;
169 eor = is_eor(buf);
170 }
171 alarm(0);
172
173 param = strchr(file, '?');
174 if (param) {
175 *param = 0;
176 param++;
177
178 while ((token = strchr(param, '%')) != NULL) {
179 char buf[3];
180
181 if (strlen(token+1) < 2)
182 break;
183
184 strncpy(buf, token+1, 3);
185 buf[2] = 0;
186
187 *token = (char)strtoul(buf, NULL, 16);
188 memmove(token+1, token+3, strlen(token)-2);
189
190 }
191 }
192
193 if (strcmp("/", file) == 0) {
194 serve_index(s, sc, param);
195 } else if (strcmp("/cgi-bin/lcd", file) == 0) {
196 serve_lcd(s, sc);
197 } else {
198 serve_404(s);
199 }
200 }
201
202 void sighandler(int sig)
203 {
204 switch(sig) {
205 case SIGPIPE:
206 break;
207 case SIGALRM:
208 default:
209 printf("Signal %d received\n", sig);
210 break;
211 }
212 }
213
214 int main(int argc, char **argv)
215 {
216 struct sigaction act;
217 int sock, csock;
218 int opt;
219 socklen_t slen;
220 struct scope *sc;
221 struct sockaddr_in sin, clientsin;
222 unsigned short port = 8088;
223
224 sc = initscope();
225 if (sc == NULL) {
226 printf("Scope not found!\n");
227 exit(EXIT_FAILURE);
228 }
229
230 bzero(&act, sizeof(act));
231 act.sa_handler = sighandler;
232 act.sa_flags = SA_RESTART;
233 if (sigaction(SIGPIPE, &act, NULL) == -1) {
234 perror("sigaction");
235 exit(EXIT_FAILURE);
236 }
237
238 bzero(&act, sizeof(act));
239 act.sa_handler = sighandler;
240 if (sigaction(SIGALRM, &act, NULL) == -1) {
241 perror("sigaction");
242 exit(EXIT_FAILURE);
243 }
244
245 if ((sock = socket(AF_INET, SOCK_STREAM, 0)) == -1) {
246 perror("socket");
247 exit(EXIT_FAILURE);
248 }
249
250 if (argc == 2) {
251 port=atoi(argv[1]);
252 }
253
254 bzero(&sin, sizeof(sin));
255 sin.sin_addr.s_addr=htonl(INADDR_ANY);
256 sin.sin_family=AF_INET;
257 sin.sin_port=htons(port);
258
259 opt = 1;
260 setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, &opt,sizeof(opt));
261
262 if (bind(sock, (struct sockaddr*)&sin, sizeof(sin)) == -1) {
263 perror("bind");
264 exit(EXIT_FAILURE);
265 }
266
267 listen(sock, 32);
268 printf("Listening on Port %u\n", port);
269
270 while(1) {
271 bzero(&clientsin, sizeof(clientsin));
272 slen = sizeof(clientsin);
273 if ((csock = accept(sock, (struct sockaddr*)&clientsin, &slen)) == -1) {
274 perror("accept");
275 }
276
277 parse_request(csock, sc);
278
279 close(csock);
280 }
281
282 closescope(sc);
283 return 0;
284 }
Impressum, Datenschutz