2 * scr.c from Access Point SNMP Utils for Linux
3 * program input & screen related functions
5 * Copyright (c) 2002 Roman Festchook <roma at polesye dot net>
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License Version 2 from
9 * June 1991 as published by the Free Software Foundation.
11 * This program is distributed in the hope that it will be useful, but
12 * WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License along
17 * with this program; if not, write to the Free Software Foundation, Inc.,
18 * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
25 #include <sys/types.h>
31 extern WINDOW *main_sub, *win_for_help;
33 #define GEN_IV_MSG _("Invalid value. Press any key to continue.")
34 #define OOR_IV_MSG _("Value must be in range %u - %u. Press any key to continue.")
40 get_mac(char *mac, int row, int col)
42 char message[MAC_LEN+1], mess[MAC_LEN/MAC_BYTES+1];
45 get_value(message, row, col, MAC_LEN+1, HEX_STRING, 0, 0, NULL);
46 if (strlen(message) < 12) i = 255;
48 for (i = 0; i < MAC_BYTES; i++) {
49 mess[0] = message[2 * i];
50 mess[1] = message[2 * i + 1];
52 mac[i] = strtol(mess, NULL, 16);
59 get_ip(struct in_addr *ip, int row, int col, char *helpmsg)
61 char message[IP_LEN+1], *cp;
65 get_value(message, row, col, IP_LEN+1, ANY_STRING, 0, 0, NULL);
66 for (cp = message, dotc = 0; *cp && (cp = index(cp, '.')); cp++, dotc++);
67 if (dotc < 3 || !(inet_aton(message, ip))) {
69 print_helperr(GEN_IV_MSG);
78 get_mask(struct in_addr *ip, int row, int col, char *helpmsg)
80 int i, bit, hmask, trans_count = 0;
83 get_ip(ip, row, col, helpmsg);
84 hmask = ntohl(ip->s_addr);
85 bit = hmask & 0x00000001;
86 for (i = 1; i < 32; i++)
87 if (((hmask >> i) & 0x00000001) != bit) {
92 if (trans_count > 1) {
93 print_helperr(GEN_IV_MSG);
101 * This is the main input function for all cases when user needs to enter
102 * a visible string. It also performs syntax correctness checks
103 * as well as bounds checks if required.
105 * value ....... this should keep the value, entered by the user,
106 * in ascii string notation
108 * col ......... the begin coordinates, relative to the current window,
109 * at which the string entered by the user will appear
110 * len ......... maximum length of the entered string, including the
111 * tailing '\0' character. Negative value along with
112 * vt=ANY_STRING means that zero-length string is allowed.
113 * vt .......... desired input value type (types INT_STRING, HEX_STRING,
115 * minv, maxv .. min/max bounds in case of integer value input. Each can be
116 * of value 0-0xFFFFFFFF. If both are 0, it means no value bounds
117 * checking will be performed. Used only with vt=INT_STRING.
118 * helpmsg ..... pointer to string that will be printed after OOR_IV_MSG
119 * message if the entered integer value is out of range.
120 * If NULL, then no 'invalid value' and subsequent status line
121 * message will be printed, and whole input process will be
122 * repeated. Used only with vt=INT_STRING.
125 get_value(char *value, int row, int col, int len,
126 char vt, unsigned int minv, unsigned int maxv, char *helpmsg)
129 unsigned char c, acs;
130 char iv_msg[128], zerolen_perm = 0;
132 if (vt == ANY_STRING && len < 0) {
138 wattrset(main_sub, COLOR_PAIR(2));
140 wmove(main_sub, row, col);
141 for (i = 0; i < (unsigned int)len - 1; i++)
142 waddch(main_sub, ' ');
144 wmove(main_sub, row, col);
153 if (c >= '0' && c <= '9') acs = 1;
156 if ((c >= '0' && c <= '9') ||
157 (c >= 'a' && c <= 'f') ||
158 (c >= 'A' && c <= 'F')) acs = 1;
167 wmove(main_sub, row, col + i);
168 waddch(main_sub, ' ');
169 /* put backspace to move cursor back */
170 wechochar(main_sub, 0x08);
173 } else if (c == 0x0D) {
175 if (i > 0 || zerolen_perm)
178 } else if (c == 0x1B) {
181 } else if (acs && (i < (unsigned int)len - 1)) {
183 wechochar(main_sub, c);
189 if (vt == INT_STRING && (minv | maxv)) {
191 i = strtoul(value, (char **)NULL, 10);
192 if (i < minv || i > maxv || errno == ERANGE) {
194 snprintf(iv_msg, sizeof(iv_msg) - 1, OOR_IV_MSG, minv, maxv);
195 print_helperr(iv_msg);
199 goto get_value_again;
204 wattrset(main_sub, A_BOLD);
205 wmove(main_sub, row, col);
206 for (i = 0; i < (unsigned int)len - 1; i++)
207 waddch(main_sub, ' ');
208 mvwaddstr(main_sub, row, col, value);
209 wattrset(main_sub, A_NORMAL);
214 * Note: indeed we should use get_value() for this action, but for the moment,
215 * we'll settle with this one.
219 get_pass(char *value, int row, int col, int len)
223 wattrset(main_sub, COLOR_PAIR(2));
224 wmove(main_sub, row, col);
225 for (i = 0; i < len - 1; i++)
226 waddch(main_sub, ' ');
230 value[j] = mvwgetch(main_sub, row, col + j);
231 if (value[j] == 0x0A) /* NEWLINE */
233 if (value[j] == 0x1B) /* ESCAPE */
235 if (value[j] != 0x7F) { /* BACKSPACE */
237 mvwaddch(main_sub, row, col + j++, '*');
240 mvwaddch(main_sub, row, col + --j, ' ');
246 wattrset(main_sub, A_BOLD);
247 wmove(main_sub, row, col);
248 for (i = 0; i < len - 1; i++)
249 waddch(main_sub, ' ');
250 wmove(main_sub, row, col);
251 for (i = 0; i < j; i++)
252 waddch(main_sub, '*');
253 wattrset(main_sub, A_NORMAL);
258 yes_no(int brow, int bcol)
260 char *names[2] = { YES, NO };
262 return menu_choose(brow, bcol, names, 2) + 1;
266 on_off(int brow, int bcol)
268 char *names[2] = { ON, OFF };
270 return menu_choose(brow, bcol, names, 2) + 1;
273 int menu_choose(int brow, int bcol, char **names, unsigned int num)
275 unsigned short int c;
276 ITEM **menu_item = calloc(num, sizeof(ITEM)), **ip = menu_item;
278 unsigned int ncol = 2, i, nrow;
279 WINDOW *choose_menu, *sub_choose_menu;
280 extern WINDOW *main_sub;
282 for (i = 0; i < num; i++) {
283 *ip++ = new_item(names[i], "");
284 if (ncol < strlen(names[i]) + 3)
285 ncol = strlen(names[i]) + 3;
291 if (brow + 2 + nrow <= (unsigned int) LINES - 2)
292 choose_menu = newwin(nrow, ncol, brow + 2, bcol + MCOLS);
294 choose_menu = newwin(nrow, ncol, brow - nrow + 3, bcol + MCOLS);
295 sub_choose_menu = derwin(choose_menu, nrow - 2, ncol - 2, 1, 1);
296 attrset(COLOR_PAIR(1));
298 mvwaddch(choose_menu, 0, 0, ACS_ULCORNER);
299 mvwaddch(choose_menu, 0, ncol - 1, ACS_URCORNER);
300 mvwaddch(choose_menu, nrow - 1, 0, ACS_LLCORNER);
301 mvwaddch(choose_menu, nrow - 1, ncol - 1, ACS_LRCORNER);
302 for (i = 1; i < ncol - 1; i++) {
303 mvwaddch(choose_menu, 0, i, ACS_HLINE);
304 mvwaddch(choose_menu, nrow - 1, i, ACS_HLINE);
306 for (i = 1; i < nrow - 1; i++) {
307 mvwaddch(choose_menu, i, 0, ACS_VLINE);
308 mvwaddch(choose_menu, i, ncol - 1, ACS_VLINE);
310 wrefresh(choose_menu);
313 menu1 = new_menu(menu_item);
314 set_menu_win(menu1, choose_menu);
315 set_menu_sub(menu1, sub_choose_menu);
317 set_menu_opts(menu1, O_ONEVALUE);
321 wrefresh(sub_choose_menu);
328 menu_driver(menu1, REQ_NEXT_ITEM);
329 wrefresh(sub_choose_menu);
334 menu_driver(menu1, REQ_LAST_ITEM);
335 wrefresh(sub_choose_menu);
340 menu_driver(menu1, REQ_FIRST_ITEM);
341 wrefresh(sub_choose_menu);
346 menu_driver(menu1, REQ_PREV_ITEM);
347 wrefresh(sub_choose_menu);
350 i = item_index(current_item(menu1));
353 for (c = 0; c < nrow - 2; c++)
354 free_item(menu_item[c]);
355 delwin(sub_choose_menu);
366 * Reads key by either getch() (WAIT_FOREVER mode) or select()
367 * (WAIT_TIMEOUT mode). Returns -1 upon error, 0 for timeout, or
374 struct timeval timeout;
375 extern int wait_mode;
382 if (wait_mode == WAIT_TIMEOUT) {
384 * wait up to timeout until anything is avail. for reading
387 i = select(1, &rds, NULL, NULL, &timeout);
389 /* not timed out => anything avail. for reading in rds */
395 print_helperr(SELECT);
399 /* also happens: i = 0 => timeout => release */
401 } else { /* wait_mode = WAIT_FOREVER */
412 print_help (_("Y - Yes; Any other key - No (it's safer to answer No)"));
415 if (c == 'y' || c == 'Y')