2 * Copyright (c) 2004 Scott Ullrich <GeekGod@GeekGod.com>
3 * Portions Copyright (c) 2004 Chris Pressey <cpressey@catseye.mine.nu>
5 * Copyright (c) 2004 The DragonFly Project.
8 * This code is derived from software contributed to The DragonFly Project
9 * by Scott Ullrich and Chris Pressey (see above for e-mail addresses).
11 * Redistribution and use in source and binary forms, with or without
12 * modification, are permitted provided that the following conditions
15 * 1. Redistributions of source code must retain the above copyright
16 * notice, this list of conditions and the following disclaimer.
18 * 2. Redistributions in binary form must reproduce the above copyright
19 * notice, this list of conditions and the following disclaimer in
20 * the documentation and/or other materials provided with the
23 * 3. Neither the name of The DragonFly Project nor the names of its
24 * contributors may be used to endorse or promote products derived
25 * from this software without specific, prior written permission.
27 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
28 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
29 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
30 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
31 * COPYRIGHT HOLDERS, CONTRIBUTORS OR VOICES IN THE AUTHOR'S HEAD
32 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY
33 * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
34 * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
35 * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
36 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
37 * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
38 * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
39 * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
40 * INCIDENTAL, SPECIAL, EXEMPLARY OR CONSEQUENTIAL DAMAGES (INCLUDING,
41 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
42 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
43 * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
44 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
45 * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
51 * CGI frontend for DFUI.
52 * $Id: dfuife_cgi.c,v 1.46 2005/03/09 22:55:55 cpressey Exp $
55 * With CAPS, this CGI only seems to work with thttpd (where user =
56 * the user that the DFUI backend is running as.) No luck with Apache.
59 #define SAVED_ENVIRONMENT "/tmp/cgicsave.env"
60 #define LINEMAX 1024 /* an arbitrary buffer size */
69 #include "dfui/dfui.h"
70 #include "dfui/dump.h"
75 #define DFUIFE_CSS "dfuife.css"
79 #define DFUIFE_CGI "dfuife.cgi"
83 #define DFUIFE_JS "dfuife.js"
86 static void signal_handler(int signo);
87 static void output_html_header(const char *title);
88 static void output_html_footer(void);
89 static void cl_progress_bar_begin(void);
90 static void create_html_from_dfui_form(const struct dfui_form *f);
91 static void create_html_from_dfui_form_single(const struct dfui_form *f);
92 static void create_html_from_dfui_form_multiple(const struct dfui_form *f);
93 static void cl_progress_bar_stop(void);
94 static void cl_progress_bar_update(int percent, const char *pbstatus);
95 static void convert_nl_to_br(const char *string_to_convert);
96 static int field_name_has_type(const char *arrayFieldName);
98 int headers_outputted = 0;
99 int last_progress_amount = -1;
100 int is_streaming_progress_bar = 0;
102 volatile sig_atomic_t caught_signal;
105 signal_handler(int signo)
107 caught_signal = signo;
111 output_html_header(const char *title)
116 if (headers_outputted == 1)
119 headers_outputted = 1;
121 setvbuf(cgiOut, NULL, _IONBF, 0);
124 tp = localtime(&now);
125 fprintf(cgiOut, "Cache-Control: no-cache\n");
126 fprintf(cgiOut, "Cache-Control: no-store\n");
127 fprintf(cgiOut, "Pragma: no-cache\n");
128 fprintf(cgiOut, "Content-type: text/html\n\n");
129 fprintf(cgiOut, "\n<?xml version='1.0' encoding='UTF-8'?>\n");
130 fprintf(cgiOut, "\n<!DOCTYPE html ");
131 fprintf(cgiOut, "PUBLIC '-//W3C//Dtd XHTML 1.0 Strict//EN'");
132 fprintf(cgiOut, " 'http://www.w3.org/tr/xhtml1/Dtd/xhtml1-strict.dtd'>\n");
133 fprintf(cgiOut, "\n<html xmlns='http://www.w3.org/1999/xhtml' xml:lang='en' lang='en'>\n");
134 fprintf(cgiOut, "\n<head>");
135 fprintf(cgiOut, "\n<meta http-equiv='Content-Type' content='text/html; charset=utf-8' />");
136 fprintf(cgiOut, "\n<title>%s</title>", title);
137 fprintf(cgiOut, "<link rel=\"stylesheet\" type=\"text/css\" href=\"" DFUIFE_CSS "\" /> \n ");
138 fprintf(cgiOut, "\n</head>");
139 fprintf(cgiOut, "\n<body onunload=\"if(loaded == 0) { event.returnValue = 'An install in progress.'; } \"> ");
140 fprintf(cgiOut, "\n<form name='dfuife' id='dfuife' method='post' action='" DFUIFE_CGI "'>\n");
142 /* javascript form helper functions */
143 fprintf(cgiOut, "\n<script type=\"text/javascript\" language=\"javascript\" src=\"" DFUIFE_JS "\">\n</script>\n");
145 fprintf(cgiOut, "\n<div class=\"main\">\n");
147 fprintf(cgiOut, "<div class=\"maintitle\">\n");
148 fprintf(cgiOut, " DragonFly Installer\n");
149 fprintf(cgiOut, "</div>\n");
151 fprintf(cgiOut, "<div class=\"title\">\n");
152 fprintf(cgiOut, " %s\n",title);
153 fprintf(cgiOut, "</div>\n");
157 output_html_footer(void)
159 fprintf(cgiOut, "\n</tbody>\n</table>\n");
160 fprintf(cgiOut, "\n</div>\n");
161 fprintf(cgiOut, "\n</div>\n");
162 fprintf(cgiOut, "\n</form>\n");
163 fprintf(cgiOut, "\n\n<script type=\"text/javascript\" language='javascript'>\nloaded = 1;\n</script>\n");
164 fprintf(cgiOut, "\n<p />");
165 fprintf(cgiOut, "\n</body>\n</html>\n");
169 create_html_from_dfui_form_single(const struct dfui_form *f)
171 struct dfui_action *a;
172 struct dfui_celldata *cd;
173 struct dfui_field *fi;
174 const char *field_id;
175 const char *field_name;
176 const char *field_descr;
177 const char *field_value;
178 const char *field_type;
179 const char *form_name;
180 const char *form_short_description;
181 struct dfui_option *o;
182 const char *help_text;
184 help_text = dfui_info_get_long_desc(dfui_form_get_info(f));
185 form_name = dfui_info_get_name(dfui_form_get_info(f));
186 form_short_description = dfui_info_get_short_desc(dfui_form_get_info(f));
188 output_html_header(form_name);
190 if (dfui_form_property_is(f, "monospaced", "true")) {
191 /* output the short description as-is */
192 fprintf(cgiOut, "<div class=\"monospaced\">\n");
193 fprintf(cgiOut, "<pre>%s</pre>", form_short_description);
195 /* output the short desc with newlines converted to <br> */
196 fprintf(cgiOut, "<div class=\"textbox\">\n");
197 convert_nl_to_br(form_short_description);
199 fprintf(cgiOut, "</div>");
201 fprintf(cgiOut, " <div class=\"mainform\">\n");
202 fprintf(cgiOut, " <table class=\"maintable\" id=\"mainness\">");
203 fprintf(cgiOut, " <tbody>\n");
206 fprintf(cgiOut, "\n<table width=\"100%%\" border=\"0\"><tr><td colspan=\"15\"><center>");
207 fprintf(cgiOut, "<div class=\"textbox\">\n");
208 if (dfui_form_property_is(f, "monospaced", "true")) {
209 fprintf(cgiOut, "<pre>");
211 /* ouput this text with newlines converted to <br> */
212 convert_nl_to_br(form_short_description);
213 if (dfui_form_property_is(f, "monospaced", "true")) {
214 fprintf(cgiOut, "</pre>");
216 fprintf(cgiOut, "</div>\n<center>\n");
219 if (dfui_form_is_extensible(f)) {
220 fprintf(cgiOut, "<input type='hidden' name='isextensible' value='isextensible'></input>\n");
224 * TODO: * get accurate colspan
225 * * size all columns in a grid pattern
228 help_text = dfui_info_get_long_desc(dfui_form_get_info(f));
230 for (fi = dfui_form_field_get_first(f); fi != NULL; fi = dfui_field_get_next(fi)) {
231 field_id = dfui_field_get_id(fi);
232 field_name = dfui_info_get_name(dfui_field_get_info(fi));
233 field_descr = dfui_info_get_short_desc(dfui_field_get_info(fi));
234 if (strlen(field_descr) < 3)
235 field_descr = field_name;
237 cd = dfui_dataset_celldata_find(dfui_form_dataset_get_first(f), dfui_field_get_id(fi));
238 field_value = dfui_celldata_get_value(cd);
239 field_type = "textbox";
240 if (dfui_field_property_is(fi, "control", "checkbox"))
241 field_type = "checkbox";
242 if (dfui_field_property_is(fi, "control", "button"))
243 field_type = "button";
244 if (dfui_field_property_is(fi, "control", "radio"))
245 field_type = "radio";
246 if (dfui_field_property_is(fi, "control", "checkbox")) {
247 fprintf(cgiOut, "<tr><td colspan=\"2\" align=middle><center>%s: "
248 "<input type='checkbox' name='%s' title='%s'"
250 field_name, field_id, field_descr,
251 strcmp(field_value, "Y") == 0 ? " CHECKED" : " ");
252 fprintf(cgiOut, "<input type='hidden' name='%s_type' value='checkbox'></input></td></tr>\n",
255 o = dfui_field_option_get_first(fi);
257 fprintf(cgiOut, "<tr><td align=right>%s:</td>"
258 "<td align=left><select name='%s' "
260 field_name, field_id, field_descr);
261 for (o = dfui_field_option_get_first(fi); o != NULL; o = dfui_option_get_next(o)) {
263 * Render this option as a choice
264 * in a drop-down list box.
266 fprintf(cgiOut, "<option value='%s'>%s</option>\n",
267 dfui_option_get_value(o), dfui_option_get_value(o));
269 fprintf(cgiOut, "</select>\n</td></tr>\n");
271 fprintf(cgiOut, "<tr><td align=right>%s:</td>"
272 "<td align='left'><input class='button' "
273 "type='%s' name='%s' value='%s' %s"
274 "title='%s'></input>\n",
276 dfui_field_property_is(fi, "obscured", "true") ?
277 "password" : "textbox",
278 field_id, field_value,
279 dfui_field_property_is(fi, "editable", "false") ?
280 " onFocus=\"this.blur();\" " : " ",
282 fprintf(cgiOut, "<input type='hidden' name='%s_type' value='%s'></input></td></tr>\n",
283 field_id, field_type);
287 fprintf(cgiOut, "\n<tr><td colspan=\"15\"> <br /><center>");
288 for (a = dfui_form_action_get_first(f); a != NULL; a = dfui_action_get_next(a)) {
289 const char *action_id, *action_name;
291 action_id = dfui_action_get_id(a);
292 action_name = dfui_info_get_name(dfui_action_get_info(a));
293 fprintf(cgiOut, "<input class='button' type='submit' name='%s' value='%s'></input> \n",
294 action_id, action_name);
295 fprintf(cgiOut, "<input type='hidden' name='%s_type' value='button'></input> \n",
297 if (dfui_form_property_is(f, "role", "menu")) {
298 fprintf(cgiOut, "<br /> <br />");
301 fprintf(cgiOut, "</center>");
302 fprintf(cgiOut, "</td></tr></table>");
304 if (strlen(help_text) > 0) {
305 fprintf(cgiOut, "<center><p><a href='#' onClick='javascript:alert(\"%s\");'>Help</a></p></center>", help_text);
308 output_html_footer();
312 create_html_from_dfui_form_multiple(const struct dfui_form *f)
314 struct dfui_action *a;
315 struct dfui_celldata *cd;
316 struct dfui_dataset *ds;
317 struct dfui_field *fi;
318 struct dfui_option *o;
319 const char *field_descr;
320 const char *field_name;
321 const char *field_value;
322 const char *field_type;
323 const char *form_name;
324 const char *form_short_description;
326 int field_counter_js = 0;
328 const char *help_text;
330 form_name = dfui_info_get_name(dfui_form_get_info(f));
331 form_short_description = dfui_info_get_short_desc(dfui_form_get_info(f));
333 output_html_header(form_name);
335 fprintf(cgiOut, " <div class=\"mainform\">\n");
336 fprintf(cgiOut, " <table width=\"100%%\" class=\"maintable\" id=\"mainness\">");
338 fprintf(cgiOut, " <tbody>\n<tr><td><center>");
340 fprintf(cgiOut, "\n<center>\n<table border=\"0\"><tr><td colspan=\"15\"><center>");
342 fprintf(cgiOut, "<input type='hidden' name='ismultiple' value='true'></input>\n");
344 if (dfui_form_is_extensible(f))
345 fprintf(cgiOut, "<input type='hidden' name='isextensible' value='isextensible'></input>\n");
347 if (dfui_form_property_is(f, "monospaced", "true")) {
348 fprintf(cgiOut, "<div class=\"monospaced\">\n");
349 fprintf(cgiOut, "<pre>%s</pre>", form_short_description);
351 /* output this text with newlines converted to <br> */
352 fprintf(cgiOut, "<div class=\"textbox\">\n");
353 convert_nl_to_br(form_short_description);
355 fprintf(cgiOut, "</div>\n<center>\n");
357 fprintf(cgiOut, "<p></p>\n<table width=\"100%%\" name=\"maintablearea\" id=\"maintablearea\"><tr>");
360 for (fi = dfui_form_field_get_first(f); fi != NULL; fi = dfui_field_get_next(fi)) {
361 field_descr = dfui_info_get_name(dfui_field_get_info(fi));
362 fprintf(cgiOut, "<td><b>%s</b></td>", field_descr);
363 fprintf(cgiOut, "\n<script type=\"text/javascript\" language='javascript'>\n");
364 field_name = dfui_field_get_id(fi);
365 fprintf(cgiOut, "rowname[%i] = \"%s\";\n", rows, field_name);
367 field_type = "textbox";
368 if (dfui_field_property_is(fi, "control", "checkbox"))
369 field_type = "checkbox";
370 if (dfui_field_property_is(fi, "control", "button"))
371 field_type = "button";
372 if (dfui_field_property_is(fi, "control", "textbox"))
373 field_type = "textbox";
374 if (dfui_field_property_is(fi, "control", "radio"))
375 field_type = "radio";
377 fprintf(cgiOut, "rowtype[%i] = \"%s\";\n", rows, field_type);
378 fprintf(cgiOut, "</script>\n");
379 fprintf(cgiOut, "<input type='hidden' name='%s_type' value='%s'></input>\n<p></p>\n",
380 field_name, field_type);
385 if (dfui_form_is_extensible(f))
386 fprintf(cgiOut, "\n<td>\n<input class='button' type=\"button\" "
387 "onclick=\"addRowTo('maintablearea')\" value=\"Add\">\n</td>\n");
389 fprintf(cgiOut, "\n</tr>\n<tr>");
392 for (ds = dfui_form_dataset_get_first(f); ds != NULL; ds = dfui_dataset_get_next(ds)) {
393 fprintf(cgiOut, "<tr>");
394 for (fi = dfui_form_field_get_first(f); fi != NULL; fi = dfui_field_get_next(fi)) {
395 cd = dfui_dataset_celldata_find(ds, dfui_field_get_id(fi));
396 field_name = dfui_field_get_id(fi);
397 field_value = dfui_celldata_get_value(cd);
398 field_descr = dfui_info_get_short_desc(dfui_field_get_info(fi));
400 if (dfui_field_property_is(fi, "control", "checkbox")) {
401 fprintf(cgiOut, "<td><center><input type='checkbox' name='%s-%d'%s></input>\n",
402 field_name, field_counter, strcmp(field_value, "Y") == 0 ? " CHECKED" : " ");
404 fprintf(cgiOut, "<input type='hidden' name='%s_row-%d' value='%d'></input><p></td>",
405 field_name, field_counter, field_counter);
407 o = dfui_field_option_get_first(fi);
409 fprintf(cgiOut, "<td><select name=\"%s-%d\">\n",
410 field_name, field_counter);
411 for (o = dfui_field_option_get_first(fi); o != NULL; o = dfui_option_get_next(o)) {
413 * Render this option as a choice
414 * in a drop-down list box.
416 fprintf(cgiOut, "<option value='%s'>%s</option>\n",
417 dfui_option_get_value(o), dfui_option_get_value(o));
419 fprintf(cgiOut, "</select>\n</td>");
421 fprintf(cgiOut, "<td><input class='button' type='%s' name='%s-%d' "
422 "value='%s' %s title='%s'></input>\n",
423 dfui_field_property_is(fi, "obscured","true") ?
424 "password" : "textbox",
425 field_name, field_counter,
427 dfui_field_property_is(fi, "editable", "false") ?
428 " onFocus=\"this.blur();\" " : " ",
431 fprintf(cgiOut, "<input type='hidden' name='%s_row-%d' value='%d'></input>\n<p />\n</td>",
432 field_name, field_counter, field_counter);
438 if (dfui_form_is_extensible(f))
439 fprintf(cgiOut, "\n<td>\n<input class='button' type='button' "
440 "value='Delete' onclick='removeRow(this)'>\n</td>\n");
442 fprintf(cgiOut, "\n</tr>");
444 fprintf(cgiOut, "</table><table>");
445 fprintf(cgiOut, "<tr><td>\n");
446 fprintf(cgiOut, "\n<script type=\"text/javascript\" language='javascript'>\n");
447 fprintf(cgiOut, "field_counter_js = %d;\n", field_counter_js);
448 fprintf(cgiOut, "rows = %d;\n", (field_counter-1));
449 fprintf(cgiOut, "totalrows = %d;\n", (rows-1));
450 fprintf(cgiOut, "</script>\n\n");
451 for (a = dfui_form_action_get_first(f); a != NULL; a = dfui_action_get_next(a)) {
452 field_name = dfui_action_get_id(a);
453 field_value = dfui_info_get_name(dfui_action_get_info(a));
454 fprintf(cgiOut, "\n<input class='button' type='submit' name='%s' value='%s'></input> \n", field_name, field_value);
455 fprintf(cgiOut, "\n<input type='hidden' name='%s_type' value='button'></input>\n", field_name);
456 if (dfui_form_property_is(f, "role", "menu"))
457 fprintf(cgiOut, "\n<br /> <br />");
459 fprintf(cgiOut, "</td></tr></table>\n");
461 help_text = dfui_info_get_long_desc(dfui_form_get_info(f));
463 if (strlen(help_text) > 0) {
464 fprintf(cgiOut, "<center><p><a href='#' onClick='javascript:alert(\"%s\");'>Help</a></p></center>", help_text);
467 output_html_footer();
471 create_html_from_dfui_form(const struct dfui_form *f)
473 if (dfui_form_is_multiple(f))
474 create_html_from_dfui_form_multiple(f);
476 create_html_from_dfui_form_single(f);
479 static struct dfui_response *
480 create_response_from_posted_data_single(const char *form_id)
482 struct dfui_dataset *ds;
483 struct dfui_response *r;
484 char **array, **arrayStep;
486 char arrayFieldName[80];
491 if (cgiFormEntries(&array) != cgiFormSuccess)
495 while (*arrayStep != NULL) {
496 snprintf(tmp, 29, "%s_type", *arrayStep);
497 cgiFormStringNoNewlines(tmp, field_type, 80);
498 if (cgiFormSubmitClicked(*arrayStep) == cgiFormSuccess &&
499 strcmp(field_type, "button") == 0) {
500 field_name = *arrayStep;
506 r = dfui_response_new(form_id, field_name);
508 /* Add the contents of all form inputs to r's dataset. */
509 ds = dfui_dataset_new();
512 output_html_header("DEBUG TURNED ON");
517 * TODO: revise this since it doesn't seem to include
520 while (*arrayStep != NULL) {
521 strncpy(arrayFieldName, *arrayStep, 30);
522 if (field_name_has_type(arrayFieldName)) {
526 /* copy cgi value to value var */
527 cgiFormStringNoNewlines(*arrayStep, value, 81);
528 /* we posted a extra hint about this field */
529 snprintf(tmp, 29, "%s_type", *arrayStep);
530 /* copy the hint type to observe what kind of field we have. */
531 cgiFormStringNoNewlines(tmp, field_type, 80);
532 /* if it's a checkbox: */
534 /* TODO: Check for _type at end of string */
535 if (strcmp(field_type, "checkbox") == 0) {
536 if (cgiFormCheckboxSingle(*arrayStep) ==
538 snprintf(value, 2, "Y");
540 fprintf(cgiOut, "Adding %s %s<P>",
541 arrayFieldName, value);
543 dfui_dataset_celldata_add(ds,
544 arrayFieldName, value);
546 snprintf(value, 2, "N");
548 fprintf(cgiOut, "Adding %s %s<P>",
549 arrayFieldName, value);
551 dfui_dataset_celldata_add(ds,
552 arrayFieldName, value);
555 /* if it's a textbox or a checkbox: */
556 if (strcmp(field_type, "textbox") == 0 ||
557 strcmp(field_type, "checkbox") == 0) {
559 fprintf(cgiOut, "Adding %s %s<P>",
560 arrayFieldName, value);
562 dfui_dataset_celldata_add(ds, arrayFieldName, value);
567 cgiStringArrayFree(array);
568 dfui_response_dataset_add(r, ds);
573 field_name_has_type(const char *arrayFieldName)
575 if (strstr(arrayFieldName, "_type") != NULL ||
576 strstr(arrayFieldName, "_row") != NULL) {
577 return(1); /* field is okay to post to backend. */
579 return(0); /* field is not okay to post to backend. */
583 static struct dfui_response *
584 create_response_from_posted_data_multiple(const char *form_id)
586 struct dfui_dataset *ds;
587 struct dfui_response *r;
588 char **array, **arrayStep;
590 char arrayFieldName[80];
594 int arrayFieldNumber;
597 int row = 0, found = 0;
600 cgiFormStringNoNewlines("ismultiple", tmp, 20);
601 if (strcmp(tmp, "true") == 0)
604 if (cgiFormEntries(&array) != cgiFormSuccess) {
609 while (*arrayStep != NULL) {
610 snprintf(tmp, 29, "%s_type", *arrayStep);
611 cgiFormStringNoNewlines(tmp, field_type, 80);
612 if (cgiFormSubmitClicked(*arrayStep) == cgiFormSuccess &&
613 strcmp(field_type, "button") == 0) {
614 field_name = *arrayStep;
620 r = dfui_response_new(form_id, field_name);
623 output_html_header("DEBUG TURNED ON");
627 * TODO: revise this since it doesn't seem to include
632 ds = dfui_dataset_new();
634 for (arrayStep = array; *arrayStep != NULL; arrayStep++) {
635 strncpy(arrayFieldName, *arrayStep, 30);
636 if (field_name_has_type(arrayFieldName)) {
639 /* copy cgi value to value var */
640 cgiFormStringNoNewlines(*arrayStep, value, 81);
641 /* walk arrayFieldName and remove -[0-1000] */
642 arrayFieldNumber = -1;
643 for (x = 0; x < strlen(arrayFieldName); x++) {
644 if (arrayFieldName[x] == '-') {
645 arrayFieldName[x] = '\0';
646 arrayFieldNumber = atoi(&arrayFieldName[x+1]);
651 fprintf(cgiOut, "HTML input name: %s, arrayFieldName: %s, "
652 "arrayFieldNumber: %d<p></p>",
653 *arrayStep, arrayFieldName, arrayFieldNumber);
657 * In any given iteration of this (inner) loop, we only care about
658 * one set of fields, the fields which have an arrayFieldNumber
659 * (that is, the bit after the hyphen) which is the same as 'row'.
660 * So, if it's different, try again; if it's the same, count it.
662 if (arrayFieldNumber != row || arrayFieldNumber == -1) {
667 /* we posted a extra hint about this field */
668 snprintf(tmp, 29, "%s_type", arrayFieldName);
669 /* copy the hint type to observe what kind of field we have. */
670 cgiFormStringNoNewlines(tmp, field_type, 80);
671 /* XXX temporarily override */
673 /* if it's a checkbox: */
674 if (strcmp(field_type, "checkbox") == 0) {
675 if (cgiFormCheckboxSingle(*arrayStep) ==
677 snprintf(value, 2, "Y");
679 fprintf(cgiOut, "Adding %s %s<P>",
680 arrayFieldName, value);
682 dfui_dataset_celldata_add(ds,
683 arrayFieldName, value);
685 snprintf(value, 2, "N");
687 fprintf(cgiOut, "Adding %s %s<P>",
688 arrayFieldName, value);
690 dfui_dataset_celldata_add(ds,
691 arrayFieldName, value);
694 /* if it's a textbox or a checkbox: */
695 if (strcmp(field_type, "textbox") == 0 ||
696 strcmp(field_type, "checkbox") == 0) {
698 fprintf(cgiOut, "Adding %s %s<P>",
699 arrayFieldName, value);
701 if (strcmp(arrayFieldName, "") != 0)
702 dfui_dataset_celldata_add(ds, arrayFieldName, value);
707 if (strcmp(arrayFieldName, "") != 0) {
708 cgiFormStringNoNewlines("isextensible", tmp, 80);
709 dfui_response_dataset_add(r, ds);
712 dfui_dataset_free(ds);
716 cgiStringArrayFree(array);
721 request_method_is(const char *method)
723 if (!strcasecmp(method, cgiRequestMethod))
732 struct dfui_connection *c;
734 struct dfui_progress *pr;
735 struct dfui_property *gp;
736 struct dfui_response *r;
741 char environmental_payload[256];
745 dfui_debug_file = fopen("/tmp/dfuife_cgi_debug.log", "a");
747 setvbuf(cgiOut, NULL, _IONBF, 0);
749 /* Deterimine if the user is setting the transport via a environmental variable */
751 snprintf(environmental_payload, 256, "%s", getenv("BSD_INSTALLER_TRANSPORT"));
752 if (strcmp(environmental_payload,"CAPS") == 0) {
753 c = dfui_connection_new(DFUI_TRANSPORT_CAPS, "test");
754 } else if (strcmp(environmental_payload,"NPIPE") == 0) {
755 c = dfui_connection_new(DFUI_TRANSPORT_NPIPE, "test");
756 } else if (strcmp(environmental_payload,"TCP") == 0) {
757 c = dfui_connection_new(DFUI_TRANSPORT_TCP, "9999");
759 c = dfui_connection_new(DFUI_TRANSPORT_TCP, "9999");
764 /* TODO: Additional error checking if we could not connect. */
766 if (request_method_is("POST")) {
769 if (cgiFormSubmitClicked("cancelinstal") == cgiFormSuccess) {
771 dfui_fe_progress_cancel(c);
773 cgiFormStringNoNewlines("form_id", form_id, 80);
774 cgiFormStringNoNewlines("ismultiple",tmp, 20);
775 if (strcmp(tmp, "true") == 0) {
776 r = create_response_from_posted_data_multiple(form_id);
778 r = create_response_from_posted_data_single(form_id);
780 dfui_fe_submit(c, r);
781 dfui_response_free(r);
785 dfui_fe_receive(c, &msgtype, &payload);
787 case DFUI_BE_MSG_PRESENT:
788 f = (struct dfui_form *)payload;
789 create_html_from_dfui_form(f);
793 case DFUI_BE_MSG_PROG_BEGIN:
795 signal(SIGPIPE, signal_handler);
796 pr = (struct dfui_progress *)payload;
797 is_streaming_progress_bar = dfui_progress_get_streaming(pr);
798 fprintf(cgiOut, "<script language=javascript>\n");
799 fprintf(cgiOut, "is_streaming_progress_bar = 1; \n");
800 fprintf(cgiOut, "</script>\n");
801 cl_progress_bar_begin();
802 dfui_progress_free(pr);
803 dfui_fe_progress_continue(c);
805 case DFUI_BE_MSG_PROG_UPDATE:
806 pr = (struct dfui_progress *)payload;
807 progress_amount = dfui_progress_get_amount(pr);
808 if (last_progress_amount != progress_amount)
809 cl_progress_bar_update(progress_amount, dfui_info_get_short_desc(dfui_progress_get_info(pr)));
810 dfui_progress_free(pr);
811 if (caught_signal != 0) {
812 dfui_fe_progress_cancel(c);
815 dfui_fe_progress_continue(c);
818 case DFUI_BE_MSG_PROG_END:
819 signal(SIGPIPE, SIG_DFL);
820 cl_progress_bar_stop();
821 dfui_fe_progress_continue(c);
824 case DFUI_BE_MSG_SET_GLOBAL:
825 gp = (struct dfui_property *)payload;
828 * Check for a change to the "lang" setting...
830 if (strcmp(dfui_property_get_name(gp), "lang") == 0) {
832 * TODO: call the appropriate gettext function.
836 dfui_fe_confirm_set_global(c);
837 dfui_property_free(gp);
839 case DFUI_BE_MSG_STOP:
840 /* end of cycle, return to opening screen. */
841 dfui_fe_confirm_stop(c);
842 cgiHeaderLocation("/");
849 dfui_fe_disconnect(c);
851 fclose(dfui_debug_file);
857 cl_progress_bar_stop(void)
859 fprintf(cgiOut, "\n<script type=\"text/javascript\" language='javascript'>\n");
860 fprintf(cgiOut, "document.progressbar.style.width='100%%';\n");
861 fprintf(cgiOut, "</script>\n");
862 fprintf(cgiOut, "\n\n<meta http-equiv='refresh' content='1;url=" DFUIFE_CGI "'>\n");
867 cl_progress_bar_begin(void)
872 if (is_streaming_progress_bar) {
879 output_html_header("Operation in progress, please wait...");
880 fprintf(cgiOut, "\n\n<p> </p>\n<center>\n\n");
881 fprintf(cgiOut, "<table height='40' border='1' bordercolor='black' width='400' bordercolordark='#000000' bordercolorlight='#000000' style='border-collapse: collapse' colspacing='2' cellpadding='2' cellspacing='2'><tr><td>");
882 fprintf(cgiOut, "\n<img border='0' src='dfly-pg.gif' width='280' height='43' name='progressbar' id='progressbar'>");
883 fprintf(cgiOut, "\n</td>\n</tr>\n</table>\n<br />\n<form>\n<center>\n<textarea rows='%d' onFocus=\"this.blur();\" cols='%d' name='pbstatus' id='pbstatus'>\n</textarea>", rows, cols);
884 fprintf(cgiOut, "\n<form method='post' action='" DFUIFE_CGI "'><p><input class='button' type='submit' name='cancelinstall' value='Cancel'></p>");
886 output_html_footer();
890 cl_progress_bar_update(int percent, const char *pbstatus)
892 fprintf(cgiOut, "\n\n<script type=\"text/javascript\" language='javascript'>\n");
893 fprintf(cgiOut, "document.progressbar.style.width='%d%%';\n", percent);
894 if (is_streaming_progress_bar) {
895 fprintf(cgiOut, "temp_streaming_text = document.forms[0].pbstatus.value;\n");
896 fprintf(cgiOut, "document.forms[0].pbstatus.value = temp_streaming_text + \"%s\\n\";\n", pbstatus);
898 fprintf(cgiOut, "document.forms[0].pbstatus.value='%s';\n", pbstatus);
900 fprintf(cgiOut, "</script>\n\n");
901 last_progress_amount = percent;
906 convert_nl_to_br(const char *string_to_convert)
910 for (x = 0; x < strlen(string_to_convert); x++) {
911 if (string_to_convert[x] == 10) { /* newline character */
912 fprintf(cgiOut, " <br />");
913 } else if (string_to_convert[x] == '>') {
914 fprintf(cgiOut, ">");
915 } else if (string_to_convert[x] == '<') {
916 fprintf(cgiOut, "<");
918 fprintf(cgiOut, "%c", string_to_convert[x]);