handle SIGPIPE
[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 static int send_binary(int s, char *buf, int len)
15 {
16 int ret;
17
18 while(len > 0) {
19 ret = write(s, buf, len);
20 if (ret == -1) {
21 perror("write");
22 return ret;
23 }
24 buf += ret;
25 len -= ret;
26 }
27
28 return 0;
29 }
30
31 static int send_text(int s, char *buf)
32 {
33 return send_binary(s, buf, strlen(buf));
34 }
35
36 static void serve_index(int s, struct scope *sc)
37 {
38 send_text(s, "HTTP/1.0 200 OK");
39 send_text(s, "Content-type: text/html\n\n");
40 send_text(s, "<html><head><title>");
41 send_text(s, scope_idn(sc));
42 send_text(s, "</title></head><body bgcolor=\"#ffffff\" text=\"#000000\">\n");
43 send_text(s, "<img src=\"/lcd.png\" height=\"234\" width=\"320\">\n");
44 send_text(s, "</body></html>\n");
45 }
46
47 static void serve_lcd(int s, struct scope *sc)
48 {
49 char buf[256];
50 int imglen;
51 unsigned char *png;
52
53 claimscope(sc);
54 png = get_lcd(sc, &imglen, 0);
55 releasescope(sc);
56
57 if (png == NULL)
58 return;
59
60
61 send_text(s, "HTTP/1.0 200 OK");
62 send_text(s, "Content-type: image/png\n");
63 snprintf(buf, sizeof(buf), "Content-length: %u\n\n", imglen);
64 send_text(s, buf);
65 send_binary(s, (char*)png, imglen);
66 free(png);
67 }
68
69 static void parse_request(int s, struct scope *sc)
70 {
71 int ret;
72 char buf[1024];
73 char file[1024];
74 const char delim[] = " \t\x0d\x0a";
75 const char crlf[] = "\x0d\x0a";
76 char *saveptr;
77 char *token;
78
79 ret=read(s, buf, sizeof(buf)-1);
80 if (ret == -1) {
81 perror("read");
82 return;
83 }
84 buf[ret] = 0;
85
86 token = strtok_r(buf, delim, &saveptr);
87 if (token == NULL)
88 return;
89 /* TODO: Only GET... */
90 token = strtok_r(NULL, delim, &saveptr);
91 if (token == NULL)
92 return;
93 bzero(&file, sizeof(file));
94 strncpy(file, token, sizeof(file)-1);
95
96 do {
97 token = strtok_r(NULL, crlf, &saveptr);
98 /* TODO: FIXME */
99 #if 0
100 if (token == NULL) {
101 ret=read(s, buf, sizeof(buf)-1);
102 if (ret == -1) {
103 perror("read");
104 return;
105 }
106 buf[ret] = 0;
107 token = strtok_r(buf, crlf, &saveptr);
108 }
109 #endif
110 } while(token != NULL);
111
112 if (strcmp("/", file) == 0) {
113 serve_index(s, sc);
114 } else if (strcmp("/lcd.png", file) == 0) {
115 serve_lcd(s, sc);
116 }
117 }
118
119 void sighandler(int sig)
120 {
121 printf("Signal %d received\n", sig);
122 }
123
124 int main(int argc, char **argv)
125 {
126 struct sigaction act;
127 int sock, csock;
128 int opt;
129 socklen_t slen;
130 struct scope *sc;
131 struct sockaddr_in sin, clientsin;
132 unsigned short port = 8088;
133
134 sc = initscope();
135 if (sc == NULL) {
136 printf("Scope not found!\n");
137 exit(EXIT_FAILURE);
138 }
139
140 bzero(&act, sizeof(act));
141 act.sa_handler = sighandler;
142 act.sa_flags = SA_RESTART;
143 if (sigaction(SIGPIPE, &act, NULL) == -1) {
144 perror("sigaction");
145 exit(EXIT_FAILURE);
146 }
147
148 if ((sock = socket(AF_INET, SOCK_STREAM, 0)) == -1) {
149 perror("socket");
150 exit(EXIT_FAILURE);
151 }
152
153 if (argc == 2) {
154 port=atoi(argv[1]);
155 }
156
157 bzero(&sin, sizeof(sin));
158 sin.sin_addr.s_addr=htonl(INADDR_ANY);
159 sin.sin_family=AF_INET;
160 sin.sin_port=htons(port);
161
162 opt = 1;
163 setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, &opt,sizeof(opt));
164
165 if (bind(sock, (struct sockaddr*)&sin, sizeof(sin)) == -1) {
166 perror("bind");
167 exit(EXIT_FAILURE);
168 }
169
170 listen(sock, 32);
171 printf("Listening on Port %u\n", port);
172
173 while(1) {
174 bzero(&clientsin, sizeof(clientsin));
175 slen = sizeof(clientsin);
176 if ((csock = accept(sock, (struct sockaddr*)&clientsin, &slen)) == -1) {
177 perror("accept");
178 }
179
180 parse_request(csock, sc);
181
182 close(csock);
183 }
184
185 closescope(sc);
186 return 0;
187 }
Impressum, Datenschutz