diff options
Diffstat (limited to 'src/gns/gnunet-bcd.c')
-rw-r--r-- | src/gns/gnunet-bcd.c | 677 |
1 files changed, 0 insertions, 677 deletions
diff --git a/src/gns/gnunet-bcd.c b/src/gns/gnunet-bcd.c deleted file mode 100644 index 60fe25945..000000000 --- a/src/gns/gnunet-bcd.c +++ /dev/null | |||
@@ -1,677 +0,0 @@ | |||
1 | /* | ||
2 | This file is part of GNUnet. | ||
3 | Copyright (C) 2013 GNUnet e.V. | ||
4 | |||
5 | GNUnet is free software: you can redistribute it and/or modify it | ||
6 | under the terms of the GNU Affero General Public License as published | ||
7 | by the Free Software Foundation, either version 3 of the License, | ||
8 | or (at your option) any later version. | ||
9 | |||
10 | GNUnet is distributed in the hope that it will be useful, but | ||
11 | WITHOUT ANY WARRANTY; without even the implied warranty of | ||
12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
13 | Affero General Public License for more details. | ||
14 | |||
15 | You should have received a copy of the GNU Affero General Public License | ||
16 | along with this program. If not, see <http://www.gnu.org/licenses/>. | ||
17 | |||
18 | SPDX-License-Identifier: AGPL3.0-or-later | ||
19 | */ | ||
20 | |||
21 | /** | ||
22 | * @file gns/gnunet-bcd.c | ||
23 | * @author Christian Grothoff | ||
24 | * @brief HTTP server to create GNS business cards | ||
25 | */ | ||
26 | |||
27 | #include "platform.h" | ||
28 | #include <microhttpd.h> | ||
29 | #include "gnunet_util_lib.h" | ||
30 | #include "gnunet_identity_service.h" | ||
31 | #include "gnunet_mhd_compat.h" | ||
32 | |||
33 | struct StaticResource | ||
34 | { | ||
35 | /** | ||
36 | * Handle to file on disk. | ||
37 | */ | ||
38 | struct GNUNET_DISK_FileHandle *handle; | ||
39 | |||
40 | /** | ||
41 | * Size in bytes of the file. | ||
42 | */ | ||
43 | uint64_t size; | ||
44 | |||
45 | /** | ||
46 | * Cached response object to send to clients. | ||
47 | */ | ||
48 | struct MHD_Response *response; | ||
49 | }; | ||
50 | |||
51 | struct ParameterMap | ||
52 | { | ||
53 | /** | ||
54 | * Name of the parameter from the request. | ||
55 | */ | ||
56 | char *name; | ||
57 | |||
58 | /** | ||
59 | * Name of the definition in the TeX output. | ||
60 | */ | ||
61 | char *definition; | ||
62 | }; | ||
63 | |||
64 | /** | ||
65 | * Handle to the HTTP server as provided by libmicrohttpd | ||
66 | */ | ||
67 | static struct MHD_Daemon *httpd = NULL; | ||
68 | |||
69 | /** | ||
70 | * Our primary task for the HTTPD. | ||
71 | */ | ||
72 | static struct GNUNET_SCHEDULER_Task *httpd_task = NULL; | ||
73 | |||
74 | /** | ||
75 | * Index file resource (simple result). | ||
76 | */ | ||
77 | static struct StaticResource *index_simple = NULL; | ||
78 | |||
79 | /** | ||
80 | * Index file resource (full result). | ||
81 | */ | ||
82 | static struct StaticResource *index_full = NULL; | ||
83 | |||
84 | /** | ||
85 | * Error: invalid gns key. | ||
86 | */ | ||
87 | static struct StaticResource *key_error = NULL; | ||
88 | |||
89 | /** | ||
90 | * Error: 404 | ||
91 | */ | ||
92 | static struct StaticResource *notfound_error = NULL; | ||
93 | |||
94 | /** | ||
95 | * Errors after receiving the form data. | ||
96 | */ | ||
97 | static struct StaticResource *internal_error = NULL; | ||
98 | |||
99 | /** | ||
100 | * Other errors. | ||
101 | */ | ||
102 | static struct StaticResource *forbidden_error = NULL; | ||
103 | |||
104 | /** | ||
105 | * Full path to the TeX template file (simple result) | ||
106 | */ | ||
107 | static char *tex_file_simple = NULL; | ||
108 | |||
109 | /** | ||
110 | * Full path to the TeX template file (full result) | ||
111 | */ | ||
112 | static char *tex_file_full = NULL; | ||
113 | |||
114 | /** | ||
115 | * Full path to the TeX template file (PNG result) | ||
116 | */ | ||
117 | static char *tex_file_png = NULL; | ||
118 | |||
119 | /** | ||
120 | * Used as a sort of singleton to send exactly one 100 CONTINUE per request. | ||
121 | */ | ||
122 | static int continue_100 = 100; | ||
123 | |||
124 | /** | ||
125 | * Map of names with TeX definitions, used during PDF generation. | ||
126 | */ | ||
127 | static const struct ParameterMap pmap[] = { | ||
128 | {"prefix", "prefix"}, | ||
129 | {"name", "name"}, | ||
130 | {"suffix", "suffix"}, | ||
131 | {"street", "street"}, | ||
132 | {"city", "city"}, | ||
133 | {"phone", "phone"}, | ||
134 | {"fax", "fax"}, | ||
135 | {"email", "email"}, | ||
136 | {"homepage", "homepage"}, | ||
137 | {"org", "organization"}, | ||
138 | {"department", "department"}, | ||
139 | {"subdepartment", "subdepartment"}, | ||
140 | {"jobtitle", "jobtitle"}, | ||
141 | {NULL, NULL}, | ||
142 | }; | ||
143 | |||
144 | /** | ||
145 | * Port number. | ||
146 | */ | ||
147 | static uint16_t port = 8888; | ||
148 | |||
149 | /** | ||
150 | * Task ran at shutdown to clean up everything. | ||
151 | * | ||
152 | * @param cls unused | ||
153 | */ | ||
154 | static void | ||
155 | do_shutdown (void *cls) | ||
156 | { | ||
157 | /* We cheat a bit here: the file descriptor is implicitly closed by MHD, so | ||
158 | calling `GNUNET_DISK_file_close' would generate a spurious warning message | ||
159 | in the log. Since that function does nothing but close the descriptor and | ||
160 | free the allocated memory, After destroying the response all that's left to | ||
161 | do is call `GNUNET_free'. */ | ||
162 | if (NULL != index_simple) | ||
163 | { | ||
164 | MHD_destroy_response (index_simple->response); | ||
165 | GNUNET_free (index_simple->handle); | ||
166 | GNUNET_free (index_simple); | ||
167 | } | ||
168 | if (NULL != index_full) | ||
169 | { | ||
170 | MHD_destroy_response (index_full->response); | ||
171 | GNUNET_free (index_full->handle); | ||
172 | GNUNET_free (index_full); | ||
173 | } | ||
174 | if (NULL != key_error) | ||
175 | { | ||
176 | MHD_destroy_response (key_error->response); | ||
177 | GNUNET_free (key_error->handle); | ||
178 | GNUNET_free (key_error); | ||
179 | } | ||
180 | if (NULL != notfound_error) | ||
181 | { | ||
182 | MHD_destroy_response (notfound_error->response); | ||
183 | GNUNET_free (notfound_error->handle); | ||
184 | GNUNET_free (notfound_error); | ||
185 | } | ||
186 | if (NULL != internal_error) | ||
187 | { | ||
188 | MHD_destroy_response (internal_error->response); | ||
189 | GNUNET_free (internal_error->handle); | ||
190 | GNUNET_free (internal_error); | ||
191 | } | ||
192 | if (NULL != forbidden_error) | ||
193 | { | ||
194 | MHD_destroy_response (forbidden_error->response); | ||
195 | GNUNET_free (forbidden_error->handle); | ||
196 | GNUNET_free (forbidden_error); | ||
197 | } | ||
198 | |||
199 | if (NULL != httpd_task) | ||
200 | { | ||
201 | GNUNET_SCHEDULER_cancel (httpd_task); | ||
202 | } | ||
203 | if (NULL != httpd) | ||
204 | { | ||
205 | MHD_stop_daemon (httpd); | ||
206 | } | ||
207 | } | ||
208 | |||
209 | /** | ||
210 | * Called when the HTTP server has some pending operations. | ||
211 | * | ||
212 | * @param cls unused | ||
213 | */ | ||
214 | static void | ||
215 | do_httpd (void *cls); | ||
216 | |||
217 | /** | ||
218 | * Schedule a task to run MHD. | ||
219 | */ | ||
220 | static void | ||
221 | run_httpd (void) | ||
222 | { | ||
223 | fd_set rs; | ||
224 | fd_set ws; | ||
225 | fd_set es; | ||
226 | |||
227 | struct GNUNET_NETWORK_FDSet *grs = GNUNET_NETWORK_fdset_create (); | ||
228 | struct GNUNET_NETWORK_FDSet *gws = GNUNET_NETWORK_fdset_create (); | ||
229 | struct GNUNET_NETWORK_FDSet *ges = GNUNET_NETWORK_fdset_create (); | ||
230 | |||
231 | FD_ZERO (&rs); | ||
232 | FD_ZERO (&ws); | ||
233 | FD_ZERO (&es); | ||
234 | |||
235 | int max = -1; | ||
236 | GNUNET_assert (MHD_YES == MHD_get_fdset (httpd, &rs, &ws, &es, &max)); | ||
237 | |||
238 | unsigned MHD_LONG_LONG timeout = 0; | ||
239 | struct GNUNET_TIME_Relative gtime = GNUNET_TIME_UNIT_FOREVER_REL; | ||
240 | if (MHD_YES == MHD_get_timeout (httpd, &timeout)) | ||
241 | { | ||
242 | gtime = GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_MILLISECONDS, | ||
243 | timeout); | ||
244 | } | ||
245 | |||
246 | GNUNET_NETWORK_fdset_copy_native (grs, &rs, max + 1); | ||
247 | GNUNET_NETWORK_fdset_copy_native (gws, &ws, max + 1); | ||
248 | GNUNET_NETWORK_fdset_copy_native (ges, &es, max + 1); | ||
249 | |||
250 | httpd_task = GNUNET_SCHEDULER_add_select (GNUNET_SCHEDULER_PRIORITY_HIGH, | ||
251 | gtime, | ||
252 | grs, | ||
253 | gws, | ||
254 | &do_httpd, | ||
255 | NULL); | ||
256 | GNUNET_NETWORK_fdset_destroy (grs); | ||
257 | GNUNET_NETWORK_fdset_destroy (gws); | ||
258 | GNUNET_NETWORK_fdset_destroy (ges); | ||
259 | } | ||
260 | |||
261 | /** | ||
262 | * Called when the HTTP server has some pending operations. | ||
263 | * | ||
264 | * @param cls unused | ||
265 | */ | ||
266 | static void | ||
267 | do_httpd (void *cls) | ||
268 | { | ||
269 | httpd_task = NULL; | ||
270 | MHD_run (httpd); | ||
271 | run_httpd (); | ||
272 | } | ||
273 | |||
274 | /** | ||
275 | * Send a response back to a connected client. | ||
276 | * | ||
277 | * @param cls unused | ||
278 | * @param connection the connection with the client | ||
279 | * @param url the requested address | ||
280 | * @param method the HTTP method used | ||
281 | * @param version the protocol version (including the "HTTP/" part) | ||
282 | * @param upload_data data sent with a POST request | ||
283 | * @param upload_data_size length in bytes of the POST data | ||
284 | * @param ptr used to pass data between request handling phases | ||
285 | * @return MHD_NO on error | ||
286 | */ | ||
287 | static MHD_RESULT | ||
288 | create_response (void *cls, | ||
289 | struct MHD_Connection *connection, | ||
290 | const char *url, | ||
291 | const char *method, | ||
292 | const char *version, | ||
293 | const char *upload_data, | ||
294 | size_t *upload_data_size, | ||
295 | void **ptr) | ||
296 | { | ||
297 | (void) cls; | ||
298 | (void) version; | ||
299 | (void) upload_data; | ||
300 | (void) upload_data_size; | ||
301 | |||
302 | bool isget = (0 == strcmp (method, MHD_HTTP_METHOD_GET)); | ||
303 | bool ishead = (0 == strcmp (method, MHD_HTTP_METHOD_HEAD)); | ||
304 | |||
305 | if (!isget && !ishead) | ||
306 | { | ||
307 | return MHD_queue_response (connection, | ||
308 | MHD_HTTP_NOT_IMPLEMENTED, | ||
309 | forbidden_error->response); | ||
310 | } | ||
311 | |||
312 | if (ishead) | ||
313 | { | ||
314 | /* Dedicated branch in case we want to provide a different result for some | ||
315 | reason (e.g. a non-web browser application using the web UI) */ | ||
316 | return MHD_queue_response (connection, | ||
317 | MHD_HTTP_OK, | ||
318 | index_simple->response); | ||
319 | } | ||
320 | |||
321 | /* Send a 100 CONTINUE response to tell clients that the result of the | ||
322 | request might take some time */ | ||
323 | if (NULL == *ptr) | ||
324 | { | ||
325 | *ptr = &continue_100; | ||
326 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Sending 100 CONTINUE\n"); | ||
327 | return MHD_YES; | ||
328 | } | ||
329 | |||
330 | if (0 == strcmp ("/", url)) | ||
331 | { | ||
332 | return MHD_queue_response (connection, | ||
333 | MHD_HTTP_OK, | ||
334 | index_simple->response); | ||
335 | } | ||
336 | |||
337 | if (0 == strcmp ("/full", url)) | ||
338 | { | ||
339 | return MHD_queue_response (connection, | ||
340 | MHD_HTTP_OK, | ||
341 | index_full->response); | ||
342 | } | ||
343 | |||
344 | bool isfull = (0 == strcmp ("/submit/full", url)); | ||
345 | bool issimple = (0 == strcmp ("/submit/simple", url)); | ||
346 | |||
347 | if (!isfull && !issimple) | ||
348 | { | ||
349 | return MHD_queue_response (connection, | ||
350 | MHD_HTTP_NOT_FOUND, | ||
351 | notfound_error->response); | ||
352 | } | ||
353 | |||
354 | const char *gpgfp = MHD_lookup_connection_value (connection, | ||
355 | MHD_GET_ARGUMENT_KIND, | ||
356 | "gpgfingerprint"); | ||
357 | const char *gnsnick = MHD_lookup_connection_value (connection, | ||
358 | MHD_GET_ARGUMENT_KIND, | ||
359 | "gnsnick"); | ||
360 | const char *gnskey = MHD_lookup_connection_value (connection, | ||
361 | MHD_GET_ARGUMENT_KIND, | ||
362 | "gnskey"); | ||
363 | const char *qrpng = MHD_lookup_connection_value (connection, | ||
364 | MHD_GET_ARGUMENT_KIND, | ||
365 | "gnspng"); | ||
366 | |||
367 | struct GNUNET_IDENTITY_PublicKey pk; | ||
368 | if (NULL == gnskey | ||
369 | || GNUNET_OK != GNUNET_IDENTITY_public_key_from_string (gnskey, &pk)) | ||
370 | { | ||
371 | return MHD_queue_response (connection, | ||
372 | MHD_HTTP_BAD_REQUEST, | ||
373 | key_error->response); | ||
374 | } | ||
375 | |||
376 | char *tmpd = GNUNET_DISK_mkdtemp (gnskey); | ||
377 | if (NULL == tmpd) | ||
378 | { | ||
379 | GNUNET_log_strerror_file (GNUNET_ERROR_TYPE_ERROR, "mktemp", gnskey); | ||
380 | return MHD_queue_response (connection, | ||
381 | MHD_HTTP_INTERNAL_SERVER_ERROR, | ||
382 | internal_error->response); | ||
383 | } | ||
384 | |||
385 | char *defpath = NULL; | ||
386 | GNUNET_asprintf (&defpath, "%s%s%s", tmpd, DIR_SEPARATOR_STR, "def.tex"); | ||
387 | |||
388 | FILE *deffile = fopen (defpath, "w"); | ||
389 | if (NULL == deffile) | ||
390 | { | ||
391 | GNUNET_log_strerror_file (GNUNET_ERROR_TYPE_ERROR, "open", defpath); | ||
392 | GNUNET_free (defpath); | ||
393 | GNUNET_DISK_directory_remove (tmpd); | ||
394 | GNUNET_free (tmpd); | ||
395 | return MHD_queue_response (connection, | ||
396 | MHD_HTTP_INTERNAL_SERVER_ERROR, | ||
397 | internal_error->response); | ||
398 | } | ||
399 | |||
400 | GNUNET_free (defpath); | ||
401 | |||
402 | for (size_t i=0; NULL!=pmap[i].name; ++i) | ||
403 | { | ||
404 | const char *value = MHD_lookup_connection_value (connection, | ||
405 | MHD_GET_ARGUMENT_KIND, | ||
406 | pmap[i].name); | ||
407 | fprintf (deffile, | ||
408 | "\\def\\%s{%s}\n", | ||
409 | pmap[i].definition, | ||
410 | (NULL == value) ? "" : value); | ||
411 | } | ||
412 | |||
413 | if (NULL != gpgfp) | ||
414 | { | ||
415 | size_t len = strlen (gpgfp); | ||
416 | char *line1 = GNUNET_strndup (gpgfp, len/2); | ||
417 | char *line2 = GNUNET_strdup (&gpgfp[len/2]); | ||
418 | fprintf (deffile, | ||
419 | "\\def\\gpglineone{%s}\n\\def\\gpglinetwo{%s}\n", | ||
420 | line1, | ||
421 | line2); | ||
422 | GNUNET_free (line1); | ||
423 | GNUNET_free (line2); | ||
424 | } | ||
425 | |||
426 | fprintf (deffile, | ||
427 | "\\def\\gns{%s/%s}\n", | ||
428 | gnskey, | ||
429 | (NULL == gnsnick) ? "" : gnsnick); | ||
430 | |||
431 | fclose (deffile); | ||
432 | |||
433 | char *command = NULL; | ||
434 | GNUNET_asprintf (&command, | ||
435 | "cd %s; cp %s gns-bcd.tex; " | ||
436 | "pdflatex %s gns-bcd.tex >/dev/null 2>&1", | ||
437 | tmpd, | ||
438 | (isfull) ? tex_file_full : | ||
439 | ((NULL == qrpng) ? tex_file_simple : tex_file_png), | ||
440 | (NULL == qrpng) ? "" : "-shell-escape"); | ||
441 | |||
442 | int ret = system (command); | ||
443 | |||
444 | GNUNET_free (command); | ||
445 | |||
446 | if (WIFSIGNALED (ret) || 0 != WEXITSTATUS (ret)) | ||
447 | { | ||
448 | GNUNET_log_strerror_file (GNUNET_ERROR_TYPE_ERROR, "system", command); | ||
449 | } | ||
450 | |||
451 | GNUNET_asprintf (&defpath, | ||
452 | "%s%s%s", | ||
453 | tmpd, | ||
454 | DIR_SEPARATOR_STR, | ||
455 | (NULL == qrpng) ? "gns-bcd.pdf" : "gns-bcd.png"); | ||
456 | |||
457 | int pdf = open (defpath, O_RDONLY); | ||
458 | if (-1 == pdf) | ||
459 | { | ||
460 | GNUNET_log_strerror_file (GNUNET_ERROR_TYPE_ERROR, "open", defpath); | ||
461 | GNUNET_free (defpath); | ||
462 | GNUNET_DISK_directory_remove (tmpd); | ||
463 | GNUNET_free (tmpd); | ||
464 | return MHD_queue_response (connection, | ||
465 | MHD_HTTP_INTERNAL_SERVER_ERROR, | ||
466 | internal_error->response); | ||
467 | } | ||
468 | |||
469 | struct stat statret; | ||
470 | GNUNET_break (0 == stat (defpath, &statret)); | ||
471 | |||
472 | GNUNET_free (defpath); | ||
473 | |||
474 | struct MHD_Response *pdfrs = | ||
475 | MHD_create_response_from_fd ((size_t) statret.st_size, pdf); | ||
476 | if (NULL == pdfrs) | ||
477 | { | ||
478 | GNUNET_break (0); | ||
479 | GNUNET_break (0 == close (pdf)); | ||
480 | GNUNET_DISK_directory_remove (tmpd); | ||
481 | GNUNET_free (tmpd); | ||
482 | return MHD_queue_response (connection, | ||
483 | MHD_HTTP_INTERNAL_SERVER_ERROR, | ||
484 | internal_error->response); | ||
485 | } | ||
486 | |||
487 | MHD_add_response_header (pdfrs, | ||
488 | MHD_HTTP_HEADER_CONTENT_TYPE, | ||
489 | (NULL == qrpng) ? "application/pdf" : "image/png"); | ||
490 | MHD_add_response_header (pdfrs, | ||
491 | MHD_HTTP_HEADER_CONTENT_DISPOSITION, | ||
492 | (NULL == qrpng) ? | ||
493 | "attachment; filename=\"gns-business-card.pdf\"" : | ||
494 | "attachment; filename=\"gns-qr-code.png\""); | ||
495 | MHD_RESULT r = MHD_queue_response (connection, MHD_HTTP_OK, pdfrs); | ||
496 | |||
497 | MHD_destroy_response (pdfrs); | ||
498 | GNUNET_DISK_directory_remove (tmpd); | ||
499 | GNUNET_free (tmpd); | ||
500 | |||
501 | return r; | ||
502 | } | ||
503 | |||
504 | /** | ||
505 | * Open a file on disk and generate a response for it. | ||
506 | * | ||
507 | * @param name name of the file to open | ||
508 | * @param basedir directory where the file is located | ||
509 | * @return NULL on error | ||
510 | */ | ||
511 | static struct StaticResource * | ||
512 | open_static_resource (const char *name, const char *basedir) | ||
513 | { | ||
514 | char *fullname = NULL; | ||
515 | GNUNET_asprintf (&fullname, "%s%s%s", basedir, DIR_SEPARATOR_STR, name); | ||
516 | |||
517 | struct GNUNET_DISK_FileHandle *f = | ||
518 | GNUNET_DISK_file_open (fullname, | ||
519 | GNUNET_DISK_OPEN_READ, | ||
520 | GNUNET_DISK_PERM_NONE); | ||
521 | |||
522 | GNUNET_free (fullname); | ||
523 | |||
524 | if (NULL == f) | ||
525 | { | ||
526 | return NULL; | ||
527 | } | ||
528 | |||
529 | off_t size = 0; | ||
530 | if (GNUNET_SYSERR == GNUNET_DISK_file_handle_size (f, &size)) | ||
531 | { | ||
532 | GNUNET_DISK_file_close (f); | ||
533 | return NULL; | ||
534 | } | ||
535 | |||
536 | struct MHD_Response *response = MHD_create_response_from_fd64 (size, f->fd); | ||
537 | |||
538 | if (NULL == response) | ||
539 | { | ||
540 | GNUNET_DISK_file_close (f); | ||
541 | return NULL; | ||
542 | } | ||
543 | |||
544 | struct StaticResource *res = GNUNET_new (struct StaticResource); | ||
545 | res->handle = f; | ||
546 | res->size = (uint64_t) size; | ||
547 | res->response = response; | ||
548 | |||
549 | return res; | ||
550 | } | ||
551 | |||
552 | /** | ||
553 | * Main function that will be run. | ||
554 | * | ||
555 | * @param cls closure | ||
556 | * @param args remaining command-line arguments | ||
557 | * @param cfgfile name of the configuration file used (for saving, can be NULL!) | ||
558 | * @param c configuration | ||
559 | */ | ||
560 | static void | ||
561 | run (void *cls, | ||
562 | char *const *args, | ||
563 | const char *cfgfile, | ||
564 | const struct GNUNET_CONFIGURATION_Handle *c) | ||
565 | { | ||
566 | (void) cls; | ||
567 | (void) args; | ||
568 | (void) cfgfile; | ||
569 | |||
570 | if (0 == port) | ||
571 | { | ||
572 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, | ||
573 | _ ("Invalid port number %u\n"), | ||
574 | port); | ||
575 | GNUNET_SCHEDULER_shutdown (); | ||
576 | return; | ||
577 | } | ||
578 | |||
579 | GNUNET_SCHEDULER_add_shutdown (&do_shutdown, NULL); | ||
580 | |||
581 | char *datadir = GNUNET_OS_installation_get_path (GNUNET_OS_IPK_DATADIR); | ||
582 | GNUNET_assert (NULL != datadir); | ||
583 | |||
584 | GNUNET_asprintf (&tex_file_full, | ||
585 | "%s%s%s", | ||
586 | datadir, | ||
587 | DIR_SEPARATOR_STR, | ||
588 | "gns-bcd.tex"); | ||
589 | GNUNET_asprintf (&tex_file_simple, | ||
590 | "%s%s%s", | ||
591 | datadir, | ||
592 | DIR_SEPARATOR_STR, | ||
593 | "gns-bcd-simple.tex"); | ||
594 | GNUNET_asprintf(&tex_file_png, | ||
595 | "%s%s%s", | ||
596 | datadir, | ||
597 | DIR_SEPARATOR_STR, | ||
598 | "gns-bcd-png.tex"); | ||
599 | |||
600 | index_simple = open_static_resource ("gns-bcd-simple.html", datadir); | ||
601 | index_full = open_static_resource ("gns-bcd.html", datadir); | ||
602 | key_error = open_static_resource ("gns-bcd-invalid-key.html", datadir); | ||
603 | notfound_error = open_static_resource ("gns-bcd-not-found.html", datadir); | ||
604 | internal_error = open_static_resource ("gns-bcd-internal-error.html", datadir); | ||
605 | forbidden_error = open_static_resource ("gns-bcd-forbidden.html", datadir); | ||
606 | |||
607 | GNUNET_free (datadir); | ||
608 | |||
609 | if ((NULL == index_simple) || (NULL == index_full) | ||
610 | || (NULL == key_error) || (NULL == notfound_error) | ||
611 | || (NULL == internal_error) || (NULL == forbidden_error)) | ||
612 | { | ||
613 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, | ||
614 | _ ("Unable to set up the daemon\n")); | ||
615 | GNUNET_SCHEDULER_shutdown (); | ||
616 | return; | ||
617 | } | ||
618 | |||
619 | int flags = MHD_USE_DUAL_STACK | MHD_USE_DEBUG | MHD_ALLOW_SUSPEND_RESUME; | ||
620 | do | ||
621 | { | ||
622 | httpd = MHD_start_daemon (flags, | ||
623 | port, | ||
624 | NULL, NULL, | ||
625 | &create_response, NULL, | ||
626 | MHD_OPTION_CONNECTION_LIMIT, 512, | ||
627 | MHD_OPTION_PER_IP_CONNECTION_LIMIT, 2, | ||
628 | MHD_OPTION_CONNECTION_TIMEOUT, 60, | ||
629 | MHD_OPTION_CONNECTION_MEMORY_LIMIT, 16 * 1024, | ||
630 | MHD_OPTION_END); | ||
631 | flags = MHD_USE_DEBUG; | ||
632 | } while (NULL == httpd && flags != MHD_USE_DEBUG); | ||
633 | |||
634 | if (NULL == httpd) | ||
635 | { | ||
636 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, | ||
637 | _ ("Failed to start HTTP server\n")); | ||
638 | GNUNET_SCHEDULER_shutdown (); | ||
639 | return; | ||
640 | } | ||
641 | |||
642 | run_httpd (); | ||
643 | } | ||
644 | |||
645 | /** | ||
646 | * The main function for gnunet-gns. | ||
647 | * | ||
648 | * @param argc number of arguments from the command line | ||
649 | * @param argv command line arguments | ||
650 | * @return 0 ok, 1 on error | ||
651 | */ | ||
652 | int | ||
653 | main (int argc, char *const *argv) | ||
654 | { | ||
655 | struct GNUNET_GETOPT_CommandLineOption options[] = { | ||
656 | GNUNET_GETOPT_option_uint16 ( | ||
657 | 'p', | ||
658 | "port", | ||
659 | "PORT", | ||
660 | gettext_noop ("Run HTTP server on port PORT (default is 8888)"), | ||
661 | &port), | ||
662 | GNUNET_GETOPT_OPTION_END, | ||
663 | }; | ||
664 | |||
665 | return ((GNUNET_OK == | ||
666 | GNUNET_PROGRAM_run (argc, | ||
667 | argv, | ||
668 | "gnunet-bcd", | ||
669 | _ ("GNUnet HTTP server to create business cards"), | ||
670 | options, | ||
671 | &run, | ||
672 | NULL)) | ||
673 | ? 0 | ||
674 | : 1); | ||
675 | } | ||
676 | |||
677 | /* end of gnunet-bcd.c */ | ||