]> git.decadent.org.uk Git - ap-utils.git/blob - lib/file.c
415cfcc64f3f84ed0c7b06fef996d1cbdd8b3ca1
[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
30 extern WINDOW *main_sub, *win_for_help, *main_win;
31 extern char *ap_types[], *ap_vendorexts[][3];
32 extern short ap_type, ap_vendorext;
33 extern struct in_addr ap_ip;
34 extern int atmel410_filter;
35
36 #define MAX_LINES LINES-6
37
38 struct APList {
39     char *ip;
40     char *passwd;
41     int type;
42     int vendorext;
43     char *label;
44
45     struct APList * next;
46 };
47
48 void
49 _scroll_rows(struct APList *first, int begin, int end)
50 {
51     int i = 1;
52     struct APList *curr = first;
53     char message[80];
54
55     clear_main(3);
56
57     while (i++ < begin)
58         curr = curr->next;
59
60     i = 0;
61     while (end-- > begin) {
62         sprintf(message, "  %3u  %-15s  %-10s  %-8s  %-16s", begin + i,
63             curr->ip, ap_types[curr->type],
64             ap_vendorexts[curr->type][curr->vendorext], curr->label);
65         mvwaddstr(main_sub, 2 + i, 0, message);
66         i++;
67         curr = curr->next;
68     }
69     wrefresh(main_sub);
70 }
71
72 struct APList *parse_db_str(char *str)
73 {
74     struct APList *curr=NULL;
75     char *ip=NULL, *passwd=NULL, *label=NULL, *aptype=NULL, mess[1024];
76     int i=0, pos=0, j=0;
77
78     while(str[i] != '\0') {
79         if(str[i] == ':') {
80             switch (pos) {
81                 case 0: 
82                     ip = (char *) malloc(j+1);
83                     memcpy(ip, mess, j+1);
84                     ip[j] = '\0';
85                     break;
86                 case 1:
87                     passwd = (char *) malloc(j+1);
88                     memcpy(passwd, mess, j+1);
89                     passwd[j] = '\0';
90                     break;
91                 case 2:
92                     label = (char *) malloc(j+1);
93                     memcpy(label, mess, j+1);
94                     label[j > 16 ? 16 : j] = '\0';
95                     break;
96                 case 3:
97                     aptype = (char *) malloc(j+1);
98                     memcpy(aptype, mess, j+1);
99                     aptype[j] = '\0';
100                     break;
101             }
102             i++;
103             j=0;
104             pos++;
105         } else
106             mess[j++] = str[i++];
107
108     }
109
110     mess[j]='\0';
111     if (pos==4 && ip && passwd && ((atmel410_filter && atoi(aptype) == ATMEL410)
112         || !atmel410_filter)) {
113         curr = (struct APList *) malloc(sizeof(struct APList));
114         curr->type = atoi(aptype);
115         curr->vendorext = atoi(mess);
116         curr->next = NULL;
117         curr->ip = (char *) malloc(strlen(ip) + 1);
118         strcpy(curr->ip, ip);
119         curr->passwd = (char *) malloc(strlen(passwd) + 1);
120         strcpy(curr->passwd, passwd);
121         curr->label = (char *) malloc(strlen(label) + 1);
122         strcpy(curr->label, label);
123     }
124
125     if (ip)
126         free(ip);
127
128     if (passwd)
129         free(passwd);
130
131     if (label)
132         free(label);
133
134     if (aptype)
135         free(aptype);
136
137     return curr;
138 }
139
140 int get_opts()
141 {
142     extern char *community;
143     extern struct in_addr ap_ip;
144
145     char *home_dir, buf[1024], mess[64];
146     char message[50];
147     int c, fd, rval = 0, pos;
148     signed int j, i, begin, end, record_num = 0;
149     struct APList *first = NULL, *curr = NULL, *pmac; 
150
151
152     if ((home_dir = getenv("HOME")) == NULL)
153         return 0;
154
155     sprintf(buf, "%s/.ap-config", home_dir);
156     if ((fd = open(buf, O_RDONLY)) == -1)
157         return 0;
158
159     pos=0;
160     while((j = read(fd, buf, sizeof(buf))) > 0) 
161         for(i=0; i < j; i++) {
162             if (buf[i] == 0x0a) {
163                 mess[pos]='\0';
164                 if (first == NULL) {
165                     if ((first = parse_db_str(mess)) != NULL) {
166                         curr = first;
167                         record_num = 1;
168                     }
169                 } else {
170                     if ((curr->next = parse_db_str(mess)) != NULL) {
171                         curr = curr->next;
172                         record_num++;
173                     }
174                 }
175                 pos=0;
176             } else      
177                 mess[pos++] = buf[i];
178
179         }
180
181     mess[pos]='\0';
182     if (first == NULL) {
183         if ((first = parse_db_str(mess)) != NULL) {
184             curr = first;
185             record_num = 1;
186         }
187     } else {
188         if ((curr->next = parse_db_str(mess)) != NULL) 
189             curr = curr->next;
190
191         record_num++;
192     }
193
194     close(fd);
195     if (!record_num)
196         return 0;
197
198     mvwaddstr(main_sub, 0, 2,
199         _("NUM  IP ADDRESS       MIB TYPE    MIB EXT.  LABEL"));
200     print_top(NULL, _("Choose an AP to connect to"));
201     begin = 1;
202     end = (MAX_LINES < record_num) ? MAX_LINES : record_num;
203     _scroll_rows(first, begin, end);
204     noecho();
205     while (1) {
206         print_help(_("1-9,C: connect; N: new; D: delete; W: save; Q: quit; arrows: scroll"));
207         switch (c = getch()) {
208             case 'q':
209             case 'Q':
210                 exit_program();
211
212             case 'n':
213             case 'N':
214                 goto quit;
215
216             case '0':
217             case '1':
218             case '2':
219             case '3':
220             case '4':
221             case '5':
222             case '6':
223             case '7':
224             case '8':
225             case '9':
226                 i = c - '0';
227                 if (record_num <= i || i <= 0)
228                     goto wrong_num;
229
230                 curr = first;
231                 while (--i > 0)
232                     curr = curr->next;
233
234                 inet_aton(curr->ip, &ap_ip);
235                 if (community)
236                     free(community);
237
238                 i = strlen(curr->passwd) + 1;
239                 community = (char *) malloc(i);
240                 strncpy(community, curr->passwd, i);
241                 ap_type = curr->type;
242                 ap_vendorext = curr->vendorext;
243
244                 rval = 1;
245                 if (reopen_sockfd() == -1)
246                     rval = 0;
247
248                 print_bottom(inet_ntoa(ap_ip));
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                 ap_vendorext = curr->vendorext;
274
275                 rval = 1;
276                 if (reopen_sockfd() == -1)
277                     rval = 0;
278
279                 print_bottom(inet_ntoa(ap_ip));
280                 goto quit;
281
282             case 'd':
283             case 'D':
284                 /* Nothing to delete */
285                 if (record_num == 1)
286                     continue;
287
288                 mvwaddstr(main_sub, 1, 0, _("Delete num:"));
289                 get_value(message, 1, 15, 6, INT_STRING,
290                     1, (record_num == 1 ? 1 : record_num - 1), NULL);
291                 i = atoi(message);
292                 if (i == 1) {
293                     curr = first;
294                     first = first->next;
295                     free(curr->ip);
296                     free(curr->passwd);
297                     free(curr->label);
298                     free(curr);
299                 } else {
300                     curr = first;
301                     while (--i > 1)
302                         curr = curr->next;
303
304                     pmac = curr->next;
305                     curr->next = pmac->next;
306                     free(pmac->ip);
307                     free(pmac->passwd);
308                     free(pmac->label);
309                     free(pmac);
310                 }
311                 record_num--;
312                 /* Clear incl. line with last AP record */
313                 if (record_num == 1) {
314                     clear_main_new(1, 3);
315                     continue;
316                 }
317
318                 begin = 1;
319                 end = (MAX_LINES < record_num) ? MAX_LINES : record_num;
320                 _scroll_rows(first, begin, end);
321 wrong_num:
322                 clear_main_new(1, 2);
323                 continue;
324
325             case KEY_DOWN:
326             case KEY_RIGHT:
327                 if (end < record_num) {
328                     begin++;
329                     end++;
330                     _scroll_rows(first, begin, end);
331                 }
332                 continue;
333
334             case KEY_UP:
335             case KEY_LEFT:
336                 if (begin > 1) {
337                     begin--;
338                     end--;
339                     _scroll_rows(first, begin, end);
340                 }
341                 continue;
342
343             case KEY_NPAGE:
344                 if (end < record_num) {
345                     end = (end + (MAX_LINES) - 1 < record_num) ?
346                         end + (MAX_LINES) - 1 : record_num;
347                     begin = (end - (MAX_LINES) + 1 > 0) ?
348                         end - (MAX_LINES) + 1 : 1;
349                     _scroll_rows(first, begin, end);
350                 }
351                 continue;
352
353             case KEY_PPAGE:
354                 if (begin > 1) {
355                     begin = (begin - (MAX_LINES) + 1 > 0) ?
356                         begin - (MAX_LINES) + 1 : 1;
357                     end = (begin + (MAX_LINES) - 1 < record_num) ?
358                         begin + (MAX_LINES) - 1 : record_num;
359                     _scroll_rows(first, begin, end);
360                 }
361                 continue;
362
363             case KEY_END:
364                 if (end < record_num) {
365                     begin = (record_num > MAX_LINES) ? record_num + 1 - (MAX_LINES) : 1;
366                     end = record_num;
367                     _scroll_rows(first, begin, end);
368                 }
369                 continue;
370
371             case KEY_HOME:
372                 if (begin > 1) {
373                     begin = 1;
374                     end = (record_num > MAX_LINES) ? MAX_LINES : record_num;
375                     _scroll_rows(first, begin, end);
376                 }
377                 continue;
378
379             case 'w':
380             case 'W':
381                 sprintf(buf, "%s/.ap-config", home_dir);
382                 if ((fd = creat(buf, 0600)) != -1) {
383                     curr=first;
384                     while (curr) {
385                         sprintf(buf, "%s:%s:%s:%d:%d\n", curr->ip, curr->passwd,
386                             curr->label,curr->type, curr->vendorext);
387                         write(fd, buf, strlen(buf));
388                         curr = curr->next;
389                     }
390                     close(fd);
391                     print_help(DONE_WRITING_APCONF);
392                 } else
393                     print_helperr(ERR_WRITING_APCONF);
394
395                 getch();
396                 continue;
397         }
398     }
399 /*
400     print_help(ANY_KEY);
401     getch();
402 */  quit:
403     while ((curr = first)) {
404         first = curr->next;
405         free(curr->ip);
406         free(curr->passwd);
407         free(curr->label);
408         free(curr);
409     }
410     print_help("");
411     print_top(NULL, NULL);
412     wclear(main_sub);
413     wrefresh(main_sub);
414     return rval;
415 }
416
417 void save_Stations(struct MacListStat *curr)
418 {
419     int fd, err_f = 0;
420     char *home_dir;
421     char message[1024];
422     if ((home_dir = getenv("HOME"))) {
423         sprintf(message, "%s/ap-%s-%s-%s.stations", home_dir, inet_ntoa(ap_ip),
424             ap_types[ap_type],ap_vendorexts[ap_type][ap_vendorext]);
425         if ((fd = creat(message, 0600)) != -1) {
426             while (curr) {
427                 sprintf(message, "%02X%02X%02X%02X%02X%02X\n",
428                     curr->addr[0] & 0xFF, curr->addr[1] & 0xFF,
429                     curr->addr[2] & 0xFF, curr->addr[3] & 0xFF,
430                     curr->addr[4] & 0xFF, curr->addr[5] & 0xFF);
431                 write(fd, message, 13);
432                 curr = curr->next;
433             }
434             close(fd);
435         } else {
436             err_f = 1;
437         }
438     } else {
439         err_f = 1;
440     }
441     if (err_f)
442         print_helperr(_("Unable to write stations file. Press any key."));
443     else
444         print_help(_("Stations file succesfully written. Press any key."));
445     getch();
446     print_help("");
447 }
448