1 /*
2  *      file.c from Access Point SNMP Utils for Linux
3  * file accessing functions
4  *
5  * Copyright (c) 2002 Roman Festchook <roma at polesye dot net>
6  *
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.
10  *
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.
15  *
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
19  *
20  */
21 #include <sys/wait.h>
22 #include <unistd.h>
23 #include <stdlib.h>
24 #include <fcntl.h>
25 #include <signal.h>
26 #include <string.h>
27 #include <sys/types.h>
28 #include "ap-utils.h"
29 #include "ap-curses.h"
30 
31 extern WINDOW *main_sub, *win_for_help, *main_win;
32 extern char *ap_types[];
33 extern short ap_type;
34 extern int atmel410_filter;
35 #define MAX_LINES LINES-6
36 
37 struct APList {
38        char *ip;
39        char *passwd;
40        int  type;
41        struct APList * next;
42 };
43 
44 void
_scroll_rows(struct APList * first,int begin,int end)45 _scroll_rows(struct APList *first, int begin, int end)
46 {
47     int i = 1;
48     struct APList *curr = first;
49     char message[50];
50 
51     clear_main(3);
52 
53     while (i++ < begin)
54         curr = curr->next;
55         i = 0;
56     while (end-- > begin) {
57          sprintf(message, "%5u  %15s   %s", begin + i, curr->ip, ap_types[curr->type]);
58 	mvwaddstr(main_sub, 2 + i, 1, message);
59     	i++;
60     	curr = curr->next;
61     }
62     wrefresh(main_sub);
63 }
64 
parse_db_str(char * str)65 struct APList *parse_db_str(char *str)
66 {
67 	struct APList *curr=NULL;
68 	char *ip=NULL, *passwd=NULL, mess[1024];
69 	int i=0, pos=0, j=0;
70 
71 	while(str[i] != '\0') {
72 		if(str[i] == ':') {
73 			switch (pos) {
74 			case 0:
75 				ip = (char *) malloc(j+1);
76 				memcpy(ip, mess, j+1);
77 				ip[j] = '\0';
78 				break;
79 			case 1:
80                                 passwd = (char *) malloc(j+1);
81                                 memcpy(passwd, mess, j+1);
82                                 passwd[j] = '\0';
83 				break;
84 			}
85 			i++;
86 			j=0;
87 			pos++;
88 
89 		}
90 		else
91 			mess[j++] = str[i++];
92 	}
93 
94 	mess[j]='\0';
95 	if (pos==2 && ip && passwd && ((atmel410_filter && atoi(mess)== ATMEL410) || !atmel410_filter)) {
96             	    curr = (struct APList *) malloc(sizeof(struct APList));
97             	    curr->type = atoi(mess);
98             	    curr->next = NULL;
99             	    curr->ip = (char *) malloc(strlen(ip)+1);
100 	    	    strcpy(curr->ip, ip);
101 		    curr->passwd = (char *) malloc(strlen(passwd)+1);
102             	    strcpy(curr->passwd, passwd);
103 	}
104 
105 	if(passwd)
106 		free(passwd);
107 	if(ip)
108 		free(ip);
109 
110 	return curr;
111 }
112 
113 
get_opts()114 int get_opts()
115 {
116         extern char *community;
117 	extern struct in_addr ap_ip;
118 	extern int sockfd;
119 
120 	char *home_dir, buf[1024], mess[64];
121 	int c;
122     	int fd, rval=0, pos;
123     	signed int j, i, begin, end, record_num=0;
124 	char message[50];
125 	struct APList *first=NULL, *curr=NULL, *pmac;
126     struct sockaddr_in client;
127 
128     memset(&client, 0, sizeof client);
129     client.sin_family = AF_INET;
130     client.sin_port = INADDR_ANY;
131     client.sin_addr.s_addr = INADDR_ANY;
132 
133 
134    if ((home_dir = getenv("HOME")) == NULL)
135 	return 0;
136     sprintf(buf, "%s/.ap-config", home_dir);
137     if ((fd = open(buf, O_RDONLY)) == -1)
138 	return 0;
139     pos=0;
140  while((j = read(fd, buf, sizeof(buf)))>0)
141     for(i=0; i < j; i++) {
142 	if (buf[i] == 0x0a){
143 		mess[pos]='\0';
144             	if (first == NULL) {
145               		if ((first = parse_db_str(mess))!=NULL) {
146 				curr=first;
147 				record_num=1;
148 			}
149             	} else {
150                    if ((curr->next = parse_db_str(mess)) != NULL) {
151                    	curr = curr->next;
152 		   	record_num++;
153 		}
154             	}
155 		pos=0;
156 	} else
157 		mess[pos++] = buf[i];
158     }
159 
160 	 mess[pos]='\0';
161       	if (first == NULL) {
162        		if ((first = parse_db_str(mess))!=NULL) {
163 			curr=first;
164 			record_num=1;
165 		}
166         } else {
167                 if ((curr->next = parse_db_str(mess)) != NULL)
168                    	curr = curr->next;
169 		   	record_num++;
170         }
171 
172     close(fd);
173 	if(!record_num)
174 		return 0;
175 
176     mvwaddstr(main_sub, 0, 3, _("NUM       IP ADDRESS   TYPE"));
177 	print_title(_("Choose an AP to connect to"));
178     begin = 1;
179     end = (MAX_LINES < record_num) ? MAX_LINES : record_num;
180     _scroll_rows(first, begin, end);
181    noecho();
182 	print_help(_("1-9,C: connect; N: new; D: delete; W: save; Q: quit; arrows: scroll"));
183         while (1) {
184 	        switch (c = getch()) {
185 		        case 'q':
186 		        case 'Q':
187 				exit_program();
188 			case 'n':
189 			case 'N':
190 				goto quit;
191 		        case '0':
192 		        case '1':
193 		        case '2':
194 		        case '3':
195 		        case '4':
196 		        case '5':
197 		        case '6':
198 		        case '7':
199 		        case '8':
200 		        case '9':
201 			        i = c - '0';
202 			        if (record_num <= i || i <= 0)
203 					goto wrong_num;
204 		                curr = first;
205 			        while (--i > 0)
206 					curr = curr->next;
207 				inet_aton(curr->ip, &ap_ip);
208 				if (community)
209 		    			free(community);
210 				i = strlen(curr->passwd) + 1;
211 				community = (char *) malloc(i);
212 				strncpy(community, curr->passwd, i);
213 				ap_type = curr->type;
214 				rval=1;
215 				if (sockfd)
216 					close(sockfd);
217     				if ((sockfd = socket(AF_INET, SOCK_DGRAM, 0)) == -1)
218 					rval=0;
219 				if (bind(sockfd, (struct sockaddr *) &client, SIZE) == -1)
220 					rval=0;
221 				print_bottom(inet_ntoa(ap_ip));
222 				goto quit;
223 		        case 'c':
224 		        case 'C':
225 				mvwaddstr(main_sub, 1, 1, _("Connect to AP num:"));
226 			        get_value(message, 1, 20, 6, INT_STRING,
227 				    1, record_num - 1, NULL);
228 			        i = atoi(message);
229 		                curr = first;
230 			        while (--i > 0)
231 					curr = curr->next;
232 				inet_aton(curr->ip, &ap_ip);
233 				if (community)
234 		    			free(community);
235 				i = strlen(curr->passwd) + 1;
236 				community = (char *) malloc(i);
237 				strncpy(community, curr->passwd, i);
238 				ap_type = curr->type;
239 				rval=1;
240 				if (sockfd)
241 					close(sockfd);
242     				if ((sockfd = socket(AF_INET, SOCK_DGRAM, 0)) == -1)
243 					rval=0;
244 				if (bind(sockfd, (struct sockaddr *) &client, SIZE) == -1)
245 					rval=0;
246 				print_bottom(inet_ntoa(ap_ip));
247 				goto quit;
248  		        case 'd':
249 		        case 'D':
250 				mvwaddstr(main_sub, 1, 0, _("Delete num:"));
251 			        get_value(message, 1, 15, 6, INT_STRING,
252 				    1, record_num - 1, NULL);
253 			        i = atoi(message);
254 			        if (i == 1) {
255 			                curr = first;
256 					first = first->next;
257 					free(curr);
258 				} else {
259 				        curr = first;
260 				        while (--i > 1)
261 				           curr = curr->next;
262 				           pmac = curr->next;
263 				           curr->next = pmac->next;
264 				           free(pmac);
265 				}
266 				record_num--;
267 				begin = 1;
268 				end = (MAX_LINES < record_num) ? MAX_LINES : record_num;
269 				_scroll_rows(first, begin, end);
270 			   wrong_num:
271 			         clear_main_new(1, 2);
272 		            continue;
273         case KEY_DOWN:
274         case KEY_RIGHT:
275             if (end < record_num) {
276                 begin++;
277                 end++;
278                 _scroll_rows(first, begin, end);
279             }
280 
281             continue;
282         case KEY_UP:
283         case KEY_LEFT:
284             if (begin > 1) {
285 	                begin--;
286 	                end--;
287 	                _scroll_rows(first, begin, end);
288 	            }
289             continue;
290 
291 	case 'w':
292 	case 'W':
293 		sprintf(buf, "%s/.ap-config", home_dir);
294         	if ((fd = creat(buf, 0600)) != -1) {
295 		curr=first;
296             	while (curr) {
297                     	sprintf(buf, "%s:%s:%d\n", curr->ip, curr->passwd, curr->type);
298                 	write(fd, buf, strlen(buf));
299                 	curr = curr->next;
300             		}
301             	close(fd);
302         	}
303 	        continue;
304 	}
305 }
306 /*
307     print_help(ANY_KEY);
308     getch();
309 */  quit:
310     while ((curr = first)) {
311 	     first = curr->next;
312 	     free(curr->ip);
313 	     free(curr->passwd);
314 	     free(curr);
315 	}
316 	print_help("");
317 	print_title("");
318 	wclear(main_sub);
319 	wrefresh(main_sub);
320 	return rval;
321 }
322 
save_Stations(struct MacListStat * curr)323 void save_Stations(struct MacListStat *curr)
324 {
325     int fd;
326     char *home_dir;
327     char message[1024];
328     if ((home_dir = getenv("HOME"))) {
329 	sprintf(message, "%s/ap-%s.stations", home_dir,
330 		ap_types[ap_type]);
331 	if ((fd = creat(message, 0600)) != -1) {
332 	    while (curr) {
333 		sprintf(message, "%02X%02X%02X%02X%02X%02X\n",
334 			curr->addr[0] & 0xFF, curr->addr[1] & 0xFF,
335 			curr->addr[2] & 0xFF, curr->addr[3] & 0xFF,
336 			curr->addr[4] & 0xFF, curr->addr[5] & 0xFF);
337 		write(fd, message, 13);
338 		curr = curr->next;
339 	    }
340 	    close(fd);
341 	}
342     }
343 }
344 
345