]> git.decadent.org.uk Git - ap-utils.git/blob - lib/file.c
e39d7d3431b3ca645dc812f53d2cd1614db15e95
[ap-utils.git] / lib / file.c
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     char *name;
42
43     struct APList * next;
44 };
45
46 void
47 _scroll_rows(struct APList *first, int begin, int end)
48 {
49     int i = 1;
50     struct APList *curr = first;
51     char message[56];
52
53     clear_main(3);
54
55     while (i++ < begin)
56         curr = curr->next;
57
58     i = 0;
59     while (end-- > begin) {
60         sprintf(message, "%5u  %15s   %s    %s", begin + i, curr->ip,
61             ap_types[curr->type], curr->name);
62         mvwaddstr(main_sub, 2 + i, 1, message);
63         i++;
64         curr = curr->next;
65     }
66     wrefresh(main_sub);
67 }
68
69 struct APList *parse_db_str(char *str)
70 {
71     struct APList *curr=NULL;
72     char *ip=NULL, *passwd=NULL, *name=NULL, mess[1024];
73     int i=0, pos=0, j=0;
74
75     while(str[i] != '\0') {
76         if(str[i] == ':') {
77             switch (pos) {
78                 case 0: 
79                     ip = (char *) malloc(j+1);
80                     memcpy(ip, mess, j+1);
81                     ip[j] = '\0';
82                     break;
83                 case 1:
84                     passwd = (char *) malloc(j+1);
85                     memcpy(passwd, mess, j+1);
86                     passwd[j] = '\0';
87                     break;
88                 case 2:
89                     name = (char *) malloc(j+1);
90                     memcpy(name, mess, j+1);
91                     name[j] = '\0';
92                     break;
93             }
94             i++;
95             j=0;
96             pos++;
97         } else
98             mess[j++] = str[i++];
99
100     }
101
102     mess[j]='\0';
103     if (pos==3 && ip && passwd && ((atmel410_filter && atoi(mess) == ATMEL410)
104         || !atmel410_filter)) {
105         curr = (struct APList *) malloc(sizeof(struct APList));
106         curr->type = atoi(mess);
107         curr->next = NULL;
108         curr->ip = (char *) malloc(strlen(ip) + 1);
109         strcpy(curr->ip, ip);
110         curr->passwd = (char *) malloc(strlen(passwd) + 1);
111         strcpy(curr->passwd, passwd);
112         curr->name = (char *) malloc(strlen(name) + 1);
113         strcpy(curr->name, name);
114     }
115         
116     if (ip)
117         free(ip);
118
119     if (passwd)
120         free(passwd);
121
122     if (name)
123         free(name);
124
125     return curr;
126 }
127
128 int get_opts()
129 {
130     extern char *community;
131     extern struct in_addr ap_ip;
132     extern int sockfd;
133         
134     char *home_dir, buf[1024], mess[64];
135     char message[50];
136     int c, fd, rval=0, pos;
137     signed int j, i, begin, end, record_num=0;
138     struct APList *first=NULL, *curr=NULL, *pmac; 
139     struct sockaddr_in client;
140
141
142     memset(&client, 0, sizeof client);
143     client.sin_family = AF_INET;
144     client.sin_port = INADDR_ANY;
145     client.sin_addr.s_addr = INADDR_ANY;
146
147     if ((home_dir = getenv("HOME")) == NULL)
148         return 0;
149
150     sprintf(buf, "%s/.ap-config", home_dir);
151     if ((fd = open(buf, O_RDONLY)) == -1)
152         return 0;
153
154     pos=0;
155     while((j = read(fd, buf, sizeof(buf))) > 0) 
156         for(i=0; i < j; i++) {
157             if (buf[i] == 0x0a) {
158                 mess[pos]='\0';
159                 if (first == NULL) {
160                     if ((first = parse_db_str(mess)) != NULL) {
161                         curr=first;
162                         record_num=1;
163                     }
164                 } else {
165                     if ((curr->next = parse_db_str(mess)) != NULL) {
166                         curr = curr->next;
167                         record_num++;
168                     }
169                 }
170                 pos=0;
171             } else      
172                 mess[pos++] = buf[i];
173
174         }
175
176     mess[pos]='\0';
177     if (first == NULL) {
178         if ((first = parse_db_str(mess)) != NULL) {
179             curr=first;
180             record_num=1;
181         }
182     } else {
183         if ((curr->next = parse_db_str(mess)) != NULL) 
184             curr = curr->next;
185
186         record_num++;
187     }
188
189     close(fd);
190     if (!record_num)
191         return 0;
192
193     mvwaddstr(main_sub, 0, 3,
194         _("NUM       IP ADDRESS   TYPE        NAME (in ~/.ap-config)"));
195     print_title(_("Choose an AP to connect to"));
196     begin = 1;
197     end = (MAX_LINES < record_num) ? MAX_LINES : record_num;
198     _scroll_rows(first, begin, end);
199     noecho();
200     print_help(_("1-9,C: connect; N: new; D: delete; W: save; Q: quit; arrows: scroll"));
201     while (1) {
202         switch (c = getch()) {
203             case 'q':
204             case 'Q':
205                 exit_program();
206
207             case 'n':
208             case 'N':
209                 goto quit;
210
211             case '0':
212             case '1':
213             case '2':
214             case '3':
215             case '4':
216             case '5':
217             case '6':
218             case '7':
219             case '8':
220             case '9':
221                 i = c - '0';
222                 if (record_num <= i || i <= 0)
223                     goto wrong_num;
224
225                 curr = first;
226                 while (--i > 0)
227                     curr = curr->next;
228
229                 inet_aton(curr->ip, &ap_ip);
230                 if (community)
231                     free(community);
232
233                 i = strlen(curr->passwd) + 1;
234                 community = (char *) malloc(i);
235                 strncpy(community, curr->passwd, i);
236                 ap_type = curr->type;
237                 rval=1;
238                 if (sockfd)
239                     close(sockfd);
240
241                 if ((sockfd = socket(AF_INET, SOCK_DGRAM, 0)) == -1)
242                     rval=0;
243
244                 if (bind(sockfd, (struct sockaddr *) &client, SIZE) == -1)
245                     rval=0;
246
247                 print_bottom(inet_ntoa(ap_ip));
248                 get_mib_details();
249                 goto quit;
250
251             case 'c':
252             case 'C':
253                 /* Nothing to connect */
254                 if (record_num == 1)
255                     continue;
256
257                 mvwaddstr(main_sub, 1, 1, _("Connect to AP num:"));
258                 get_value(message, 1, 20, 6, INT_STRING, 1, record_num - 1,
259                     NULL);
260                 i = atoi(message);
261                 curr = first;
262                 while (--i > 0)
263                     curr = curr->next;
264
265                 inet_aton(curr->ip, &ap_ip);
266                 if (community)
267                     free(community);
268
269                 i = strlen(curr->passwd) + 1;
270                 community = (char *) malloc(i);
271                 strncpy(community, curr->passwd, i);
272                 ap_type = curr->type;
273                 rval=1;
274                 if (sockfd)
275                     close(sockfd);
276
277                 if ((sockfd = socket(AF_INET, SOCK_DGRAM, 0)) == -1)
278                     rval=0;
279
280                 if (bind(sockfd, (struct sockaddr *) &client, SIZE) == -1)
281                     rval=0;
282
283                 print_bottom(inet_ntoa(ap_ip));
284                 get_mib_details();
285                 goto quit;
286
287             case 'd':
288             case 'D':
289                 /* Nothing to delete */
290                 if (record_num == 1)
291                     continue;
292
293                 mvwaddstr(main_sub, 1, 0, _("Delete num:"));
294                 get_value(message, 1, 15, 6, INT_STRING,
295                     1, (record_num == 1 ? 1 : record_num - 1), NULL);
296                 i = atoi(message);
297                 if (i == 1) {
298                     curr = first;
299                     first = first->next;
300                     free(curr);
301                 } else {
302                     curr = first;
303                     while (--i > 1)
304                         curr = curr->next;
305
306                     pmac = curr->next;
307                     curr->next = pmac->next;
308                     free(pmac);
309                 }
310                 record_num--;
311                 /* Clear incl. line with last AP record */
312                 if (record_num == 1) {
313                     clear_main_new(1, 3);
314                     continue;
315                 }
316
317                 begin = 1;
318                 end = (MAX_LINES < record_num) ? MAX_LINES : record_num;
319                 _scroll_rows(first, begin, end);
320 wrong_num:
321                 clear_main_new(1, 2);
322                 continue;
323
324             case KEY_DOWN:
325             case KEY_RIGHT:
326                 if (end < record_num) {
327                     begin++;
328                     end++;
329                     _scroll_rows(first, begin, end);
330                 }
331                 continue;
332
333             case KEY_UP:
334             case KEY_LEFT:
335                 if (begin > 1) {
336                     begin--;
337                     end--;
338                     _scroll_rows(first, begin, end);
339                 }
340                 continue;
341
342             case 'w':
343             case 'W':
344                 sprintf(buf, "%s/.ap-config", home_dir);
345                 if ((fd = creat(buf, 0600)) != -1) {
346                     curr=first;
347                     while (curr) {
348                         sprintf(buf, "%s:%s:%d\n", curr->ip, curr->passwd,
349                             curr->type);
350                         write(fd, buf, strlen(buf));
351                         curr = curr->next;
352                     }
353                     close(fd);
354                 }
355                 continue;
356
357         }
358     }
359 /*
360     print_help(ANY_KEY);
361     getch();
362 */  quit:
363     while ((curr = first)) {
364         first = curr->next;
365         free(curr->ip);
366         free(curr->passwd);
367         free(curr);
368     }
369     print_help("");
370     print_title("");
371     wclear(main_sub);
372     wrefresh(main_sub);
373     return rval;
374 }
375
376 void save_Stations(struct MacListStat *curr)
377 {
378     int fd;
379     char *home_dir;
380     char message[1024];
381     if ((home_dir = getenv("HOME"))) {
382         sprintf(message, "%s/ap-%s.stations", home_dir, ap_types[ap_type]);
383         if ((fd = creat(message, 0600)) != -1) {
384             while (curr) {
385                 sprintf(message, "%02X%02X%02X%02X%02X%02X\n",
386                     curr->addr[0] & 0xFF, curr->addr[1] & 0xFF,
387                     curr->addr[2] & 0xFF, curr->addr[3] & 0xFF,
388                     curr->addr[4] & 0xFF, curr->addr[5] & 0xFF);
389                 write(fd, message, 13);
390                 curr = curr->next;
391             }
392             close(fd);
393         }
394     }
395 }
396