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];
46 while (strlen(message) != 12)
47 get_value(message, row, col, MAC_LEN+1, HEX_STRING, 0, 0, NULL);
49 for (i = 0; i < MAC_BYTES; i++) {
50 mess[0] = message[2 * i];
51 mess[1] = message[2 * i + 1];
53 mac[i] = strtol(mess, NULL, 16);
60 get_ip(struct in_addr *ip, int row, int col, char *helpmsg)
62 char message[IP_LEN+1], *cp;
66 get_value(message, row, col, IP_LEN+1, ANY_STRING, 0, 0, NULL);
67 for (cp = message, dotc = 0; *cp && (cp = index(cp, '.')); cp++, dotc++);
68 if (dotc < 3 || !(inet_aton(message, ip))) {
70 print_helperr(GEN_IV_MSG);
79 get_mask(struct in_addr *ip, int row, int col, char *helpmsg)
81 int i, bit, hmask, trans_count = 0;
84 get_ip(ip, row, col, helpmsg);
85 hmask = ntohl(ip->s_addr);
86 bit = hmask & 0x00000001;
87 for (i = 1; i < 32; i++)
88 if (((hmask >> i) & 0x00000001) != bit) {
93 if (trans_count > 1) {
94 print_helperr(GEN_IV_MSG);
102 * This is the main input function for all cases when user needs to enter
103 * a visible string. It also performs syntax correctness checks
104 * as well as bounds checks if required.
106 * value ....... this should keep the value, entered by the user,
107 * in ascii string notation
109 * col ......... the begin coordinates, relative to the current window,
110 * at which the string entered by the user will appear
111 * len ......... maximum length of the entered string, including the
112 * tailing '\0' character. Negative value along with
113 * vt=ANY_STRING means that zero-length string is allowed.
114 * vt .......... desired input value type (types INT_STRING, HEX_STRING,
116 * minv, maxv .. min/max bounds in case of integer value input. Each can be
117 * of value 0-0xFFFFFFFF. If both are 0, it means no value bounds
118 * checking will be performed. Used only with vt=INT_STRING.
119 * helpmsg ..... pointer to string that will be printed after OOR_IV_MSG
120 * message if the entered integer value is out of range.
121 * If NULL, then no 'invalid value' and subsequent status line
122 * message will be printed, and whole input process will be
123 * repeated. Used only with vt=INT_STRING.
126 get_value(char *value, int row, int col, int len,
127 char vt, unsigned int minv, unsigned int maxv, char *helpmsg)
130 unsigned char c, acs;
131 char iv_msg[128], zerolen_perm = 0;
133 if (vt == ANY_STRING && len < 0) {
139 wattrset(main_sub, COLOR_PAIR(12));
141 wmove(main_sub, row, col);
142 for (i = 0; i < (unsigned int)len - 1; i++)
143 waddch(main_sub, ' ');
145 wmove(main_sub, row, col);
154 if (c >= '0' && c <= '9') acs = 1;
157 if ((c >= '0' && c <= '9') ||
158 (c >= 'a' && c <= 'f') ||
159 (c >= 'A' && c <= 'F')) acs = 1;
168 wmove(main_sub, row, col + i);
169 waddch(main_sub, ' ');
170 wmove(main_sub, row, col + i);
174 } else if (c == 0x0D) {
176 if (i > 0 || zerolen_perm)
179 } else if (c == 0x1B) {
182 } else if (acs && (i < (unsigned int)len - 1)) {
184 wechochar(main_sub, c);
190 if (vt == INT_STRING && (minv | maxv)) {
192 i = strtoul(value, (char **)NULL, 10);
193 if (i < minv || i > maxv || errno == ERANGE) {
195 snprintf(iv_msg, sizeof(iv_msg) - 1, OOR_IV_MSG, minv, maxv);
196 print_helperr(iv_msg);
200 goto get_value_again;
205 wattrset(main_sub, A_BOLD);
206 wmove(main_sub, row, col);
207 for (i = 0; i < (unsigned int)len - 1; i++)
208 waddch(main_sub, ' ');
209 mvwaddstr(main_sub, row, col, value);
210 wattrset(main_sub, A_NORMAL);
215 * Note: indeed we should use get_value() for this action, but for the moment,
216 * we'll settle with this one.
220 get_pass(char *value, int row, int col, int len)
224 wattrset(main_sub, COLOR_PAIR(12));
225 wmove(main_sub, row, col);
226 for (i = 0; i < len - 1; i++)
227 waddch(main_sub, ' ');
231 value[j] = mvwgetch(main_sub, row, col + j);
232 if (value[j] == 0x0A) /* NEWLINE */
234 if (value[j] == 0x1B) /* ESCAPE */
236 if (value[j] != 0x7F) { /* BACKSPACE */
238 mvwaddch(main_sub, row, col + j++, '*');
241 mvwaddch(main_sub, row, col + --j, ' ');
247 wattrset(main_sub, A_BOLD);
248 wmove(main_sub, row, col);
249 for (i = 0; i < len - 1; i++)
250 waddch(main_sub, ' ');
251 wmove(main_sub, row, col);
252 for (i = 0; i < j; i++)
253 waddch(main_sub, '*');
254 wattrset(main_sub, A_NORMAL);
259 yes_no(int brow, int bcol)
261 char *names[2] = { YES, NO };
263 return menu_choose(brow, bcol, names, 2) + 1;
267 on_off(int brow, int bcol)
269 char *names[2] = { ON, OFF };
271 return menu_choose(brow, bcol, names, 2) + 1;
274 int menu_choose(int brow, int bcol, char **names, unsigned int num)
276 unsigned short int c;
277 ITEM **menu_item = calloc(num, sizeof(ITEM)), **ip = menu_item;
279 unsigned int ncol = 2, i, nrow;
280 WINDOW *choose_menu, *sub_choose_menu;
281 extern WINDOW *main_sub;
283 for (i = 0; i < num; i++) {
284 *ip++ = new_item(names[i], "");
285 if (ncol < strlen(names[i]) + 3)
286 ncol = strlen(names[i]) + 3;
292 if (brow + 2 + nrow <= (unsigned int) LINES - 2)
293 choose_menu = newwin(nrow, ncol, brow + 2, bcol + MCOLS);
295 choose_menu = newwin(nrow, ncol, brow - nrow + 3, bcol + MCOLS);
296 sub_choose_menu = derwin(choose_menu, nrow - 2, ncol - 2, 1, 1);
297 attrset(COLOR_PAIR(11));
299 mvwaddch(choose_menu, 0, 0, ACS_ULCORNER);
300 mvwaddch(choose_menu, 0, ncol - 1, ACS_URCORNER);
301 mvwaddch(choose_menu, nrow - 1, 0, ACS_LLCORNER);
302 mvwaddch(choose_menu, nrow - 1, ncol - 1, ACS_LRCORNER);
303 for (i = 1; i < ncol - 1; i++) {
304 mvwaddch(choose_menu, 0, i, ACS_HLINE);
305 mvwaddch(choose_menu, nrow - 1, i, ACS_HLINE);
307 for (i = 1; i < nrow - 1; i++) {
308 mvwaddch(choose_menu, i, 0, ACS_VLINE);
309 mvwaddch(choose_menu, i, ncol - 1, ACS_VLINE);
311 wrefresh(choose_menu);
314 menu1 = new_menu(menu_item);
315 set_menu_win(menu1, choose_menu);
316 set_menu_sub(menu1, sub_choose_menu);
318 set_menu_opts(menu1, O_ONEVALUE);
322 wrefresh(sub_choose_menu);
329 menu_driver(menu1, REQ_NEXT_ITEM);
330 wrefresh(sub_choose_menu);
335 menu_driver(menu1, REQ_LAST_ITEM);
336 wrefresh(sub_choose_menu);
341 menu_driver(menu1, REQ_FIRST_ITEM);
342 wrefresh(sub_choose_menu);
347 menu_driver(menu1, REQ_PREV_ITEM);
348 wrefresh(sub_choose_menu);
351 i = item_index(current_item(menu1));
354 for (c = 0; c < nrow - 2; c++)
355 free_item(menu_item[c]);
356 delwin(sub_choose_menu);
367 * Reads key by either getch() (WAIT_FOREVER mode) or select()
368 * (WAIT_TIMEOUT mode). Returns -1 upon error, 0 for timeout, or
375 struct timeval timeout;
376 extern int wait_mode;
383 if (wait_mode == WAIT_TIMEOUT) {
385 * wait up to timeout until anything is avail. for reading
388 i = select(1, &rds, NULL, NULL, &timeout);
390 /* not timed out => anything avail. for reading in rds */
396 print_helperr(ERR_SELECT);
400 /* also happens: i = 0 => timeout => release */
402 } else { /* wait_mode = WAIT_FOREVER */
413 print_help (_("Y - Yes; Any other key - No (it's safer to answer No)"));
416 if (c == 'y' || c == 'Y')