/* * Recursive function responsible to create fields, position them and setting * the modifiable fields. All of this from a service dictionary. * To keep the cursor from moving on signal, a string is affected to mark each * field. This is used by repos_cursor(). * @param longest_key_len The longest length for a label * @param pos The index in main_fields[] * @param jobj The service dictionary * @param is_obj_modifiable Use to set the whole object as modifiable (usefull * for IPv4.Configuration for example) * @param obj_str The string representing the "hash" of a surrounding object */ static void render_fields_from_jobj(int longest_key_len, int *pos, struct json_object *jobj, bool is_obj_modifiable, const char *obj_str) { bool is_autoconnect = false, is_modifiable = false; struct userptr_data *data; json_object_object_foreach(jobj, key, val) { main_fields[*pos] = render_label(longest_key_len, key); assert(main_fields[*pos] != NULL); (*pos)++; is_modifiable = string_ends_with_configuration(key); is_modifiable |= is_obj_modifiable; if (json_object_get_type(val) == json_type_object) { move_field(main_fields[(*pos)-1], ++cur_y, cur_x); cur_y++; render_fields_from_jobj(longest_key_len, pos, val, is_modifiable, key); is_modifiable = false; } else { // insert the page delimiter if (cur_y >= win_body_lines-4) { cur_y = 1; set_new_page(main_fields[(*pos)-1], TRUE); move_field(main_fields[(*pos)-1], cur_y, cur_x); nb_pages++; } main_fields[*pos] = render_field(longest_key_len, val); assert(main_fields[*pos] != NULL); is_autoconnect = strcmp(key, key_serv_autoconnect) == 0; if (is_modifiable || is_autoconnect) { field_opts_on(main_fields[*pos], O_EDIT); field_opts_off(main_fields[*pos], O_BLANK); set_field_back(main_fields[*pos], A_UNDERLINE); } else field_opts_off(main_fields[*pos], O_EDIT); // Specific operations on fields config_fields_type(*pos, is_autoconnect, obj_str, key); field_opts_on(main_fields[*pos], O_NULLOK); data = malloc(sizeof(struct userptr_data)); data->dbus_name = strdup(get_str_key()); data->pretty_name = NULL; set_field_userptr(main_fields[*pos], data); (*pos)++; } cur_y++; }
static void demo_forms(void) { WINDOW *w; FORM *form; FIELD *f[100]; /* FIXME memset to zero */ int finished = 0, c; unsigned n = 0; int pg; WINDOW *also; #ifdef NCURSES_MOUSE_VERSION mousemask(ALL_MOUSE_EVENTS, (mmask_t *) 0); #endif help_edit_field(); MvAddStr(4, 57, "Forms Entry Test"); show_insert_mode(TRUE); refresh(); /* describe the form */ memset(f, 0, sizeof(f)); for (pg = 0; pg < 4; ++pg) { char label[80]; sprintf(label, "Sample Form Page %d", pg + 1); f[n++] = make_label(0, 15, label); set_new_page(f[n - 1], TRUE); switch (pg) { default: f[n++] = make_label(2, 0, "Last Name"); f[n++] = make_field(3, 0, 1, 18); set_field_type(f[n - 1], TYPE_ALPHA, 1); f[n++] = make_label(2, 20, "First Name"); f[n++] = make_field(3, 20, 1, 12); set_field_type(f[n - 1], TYPE_ALPHA, 1); f[n++] = make_label(2, 34, "Middle Name"); f[n++] = make_field(3, 34, 1, 12); set_field_type(f[n - 1], TYPE_ALPHA, 1); break; case 1: f[n++] = make_label(2, 0, "Last Name"); f[n++] = make_field(3, 0, 1, 18); set_field_type(f[n - 1], TYPE_ALPHA, 1); f[n++] = make_label(2, 20, "First Name"); f[n++] = make_field(3, 20, 1, 12); set_field_type(f[n - 1], TYPE_ALPHA, 1); f[n++] = make_label(2, 34, "MI"); f[n++] = make_field(3, 34, 1, 1); set_field_pad(f[n - 1], '?'); set_field_type(f[n - 1], TYPE_ALPHA, 1); break; case 2: f[n++] = make_label(2, 0, "Host Name"); f[n++] = make_field(3, 0, 1, 18); set_field_type(f[n - 1], TYPE_ALNUM, 1); #ifdef NCURSES_VERSION f[n++] = make_label(2, 20, "IP Address"); f[n++] = make_field(3, 20, 1, 12); set_field_type(f[n - 1], TYPE_IPV4, 1); #endif break; case 3: f[n++] = make_label(2, 0, "Four digits"); f[n++] = make_field(3, 0, 1, 18); set_field_type(f[n - 1], TYPE_INTEGER, 4, 0, 0); f[n++] = make_label(2, 20, "Numeric"); f[n++] = make_field(3, 20, 1, 12); set_field_type(f[n - 1], TYPE_NUMERIC, 3, -10000.0, 100000000.0); break; } f[n++] = make_label(5, 0, "Comments"); f[n++] = make_field(6, 0, 4, 46); set_field_buffer(f[n - 1], 0, "HELLO\nWORLD!"); set_field_buffer(f[n - 1], 1, "Hello\nWorld!"); } f[n] = (FIELD *) 0; if ((form = new_form(f)) != 0) { display_form(form); w = form_win(form); also = newwin(getmaxy(stdscr) - getmaxy(w), COLS, getmaxy(w), 0); show_current_field(also, form); while (!finished) { switch (edit_field(form, &c)) { case E_OK: break; case E_UNKNOWN_COMMAND: finished = my_form_driver(form, c); break; default: beep(); break; } show_current_field(also, form); } erase_form(form); free_form(form); } for (c = 0; f[c] != 0; c++) { void *ptr = field_userptr(f[c]); free(ptr); free_field(f[c]); } noraw(); nl(); #ifdef NCURSES_MOUSE_VERSION mousemask(0, (mmask_t *) 0); #endif }
int configure_step(int height, int width) { FIELD * field[6]; FORM *form; int ch, page = 0; int error = 0; char emsg[64]; url_t u, ua; field[0] = new_field(1, width - 20, 8, 10, 0, 0); field[1] = new_field(1, width - 20, 8, 10, 0, 0); field[2] = new_field(1, (width - 20) / 2, 8, 22, 0, 0); field[3] = new_field(1, (width - 20) / 2, 10, 22, 0, 0); field[4] = new_field(1, width - 20, 8, 10, 0, 0); field[5] = NULL; set_field_back(field[0], A_UNDERLINE); field_opts_off(field[0], O_AUTOSKIP); set_field_back(field[1], A_UNDERLINE); field_opts_off(field[1], O_AUTOSKIP); set_field_back(field[2], A_UNDERLINE); field_opts_off(field[2], O_AUTOSKIP); set_field_back(field[3], A_UNDERLINE); field_opts_off(field[3], O_AUTOSKIP); field_opts_off(field[3], O_PUBLIC); //agent password field_opts_off(field[4], O_AUTOSKIP); set_field_back(field[4], A_UNDERLINE); set_new_page(field[1], TRUE); set_new_page(field[2], TRUE); set_new_page(field[4], TRUE); form = new_form(field); clear(); post_form(form); refresh(); step(0, height, width); refresh(); while ((ch = getch()) != KEY_F(4)) { menu_continue: switch (ch) { case KEY_F(2): page--; if (page < 0) { page = 0; } else { form_driver(form, REQ_PREV_PAGE); step(page, height, width); } break; case KEY_F(3): //validation error = 0; emsg[0] = '\0'; form_driver(form, REQ_VALIDATION); switch (page) { case 0://openam url validate { strcpy(openam_url, field_buffer(field[0], 0)); am_trim(openam_url); u = URL(openam_url); if (u.error == 0) { if (validate_am_host(&u) != 0) { error = 1; sprintf(emsg, "Error validating OpenAM URL"); } } else { error = 1; sprintf(emsg, "Invalid URL value"); } } break; case 1://agent url strcpy(agent_url, field_buffer(field[1], 0)); am_trim(agent_url); ua = URL(agent_url); if (ua.error != 0) { error = 1; sprintf(emsg, "Invalid URL value"); } break; case 2://agent user/pass snprintf(agent_id, sizeof (agent_id), "%s", field_buffer(field[2], 0)); snprintf(agent_pass, sizeof (agent_pass), "%s", field_buffer(field[3], 0)); am_trim(agent_id); am_trim(agent_pass); if (agent_id == NULL || agent_id[0] == '\0' || agent_pass == NULL || agent_pass[0] == '\0') { error = 1; sprintf(emsg, "Values must not be empty"); } else { if (u.error == 0) { if (validate_agent(&u, agent_id, agent_pass) != 0) { error = 1; sprintf(emsg, PROFILE_NOT_FOUND); } } else { error = 1; sprintf(emsg, "Invalid OpenAM URL value"); } } break; case 3://web container path { char *t = NULL; strcpy(web_conf_path, field_buffer(field[4], 0)); am_trim(web_conf_path); if (web_conf_path == NULL || web_conf_path[0] == '\0') { error = 1; sprintf(emsg, "Value must not be empty"); } else { asprintf(&t, "%s/libvmod_am.so", web_conf_path); if (am_whitespace(web_conf_path) > 0) { LOG("configure_step() error - path to Varnish modules directory must not contain spaces %s", web_conf_path); error = 1; sprintf(emsg, "Error reading Varnish modules directory"); } else if (am_file_writeable(web_conf_path) == 0) { LOG("configure_step() error - vmod directory is not accessible %s", web_conf_path); error = 1; sprintf(emsg, "Error opening Varnish modules directory"); } else if (am_file_exists(t) == 1) { LOG("configure_step() vmod directory already contains agent library %s", t); error = 1; sprintf(emsg, "This Varnish instance is already configured"); } am_free(t); } } break; } if (error == 0) { move(13, 10); clrtoeol(); page++; if (page > 3) { goto cfg_done; } form_driver(form, REQ_NEXT_PAGE); step(page, height, width); } else { move(13, 10); clrtoeol(); attron(A_BOLD); attron(COLOR_PAIR(1)); mvprintw(13, 10, emsg); attroff(COLOR_PAIR(1)); attroff(A_BOLD); form_driver(form, REQ_END_LINE); } break; case 0x08: case 0x7f: case KEY_DC: case KEY_BACKSPACE: form_driver(form, REQ_DEL_PREV); form_driver(form, REQ_CLR_EOF); break; case KEY_DOWN: case 10://ENTER case 9://TAB if ((ch == 9 || ch == 10) && (page == 0 || page == 1 || page == 3)) { /*allow enter to accept-validate single-line form fields*/ ch = KEY_F(3); refresh(); goto menu_continue; } form_driver(form, REQ_NEXT_FIELD); form_driver(form, REQ_END_LINE); break; case KEY_UP: form_driver(form, REQ_PREV_FIELD); form_driver(form, REQ_END_LINE); break; default: form_driver(form, ch); break; } refresh(); } cfg_done: unpost_form(form); free_form(form); free_field(field[0]); free_field(field[1]); free_field(field[2]); free_field(field[3]); clear(); refresh(); if (page > 3) { curs_set(0); create_varnish_instance(ua); step(-1, height, width); while ((ch = getch()) != KEY_F(4)) { } curs_set(1); clear(); } return ch; }