]> CyberLeo.Net >> Repos - SourceForge/eyefi-config.git/blob - eyefi-unix.c
more portability improvements
[SourceForge/eyefi-config.git] / eyefi-unix.c
1 /*
2  * eyefi-unix.c
3  *
4  * Copyright (C) 2008 Dave Hansen <dave@sr71.net>
5  *
6  * This software may be redistributed and/or modified under the terms of
7  * the GNU General Public License ("GPL") version 2 as published by the
8  * Free Software Foundation.
9  */
10
11 #include "eyefi-config.h"
12
13 void print_pascal_string(struct pascal_string *str)
14 {
15         int i;
16         for (i = 0; i < str->length; i++)
17                 printf("%c", str->value[i]);
18 }
19
20 void print_mac(struct mac_address *mac)
21 {
22         int i;
23         for (i=0; i < MAC_BYTES-1; i++) {
24                 printf("%02x:", mac->mac[i]);
25         }
26         printf("%02x\n", mac->mac[i]);
27 }
28
29
30 void print_card_mac(void)
31 {
32         debug_printf(2, "%s()\n", __func__);
33         struct mac_address *mac;
34
35         card_info_cmd(MAC_ADDRESS);
36         mac = eyefi_response();
37         assert(mac->length == MAC_BYTES);
38         printf("card mac address: ");
39         print_mac(mac);
40 }
41
42 void print_card_firmware_info(void)
43 {
44         struct card_firmware_info *info = fetch_card_firmware_info();
45         printf("card firmware (len: %d): '", info->info.length);
46         print_pascal_string(&info->info);
47         printf("'\n");
48 }
49
50 void print_card_key(void)
51 {
52         debug_printf(2, "%s()\n", __func__);
53         struct card_info_rsp_key *foo = fetch_card_key();
54         printf("card key (len: %d): '", foo->key.length);
55         print_pascal_string(&foo->key);
56         printf("'\n");
57 }
58
59 void scan_print_nets(void)
60 {
61         int i;
62
63         debug_printf(2, "%s()\n", __func__);
64         struct scanned_net_list *scanned = scan_nets();
65         if (scanned->nr == 0) {
66                 printf("unable to detect any wireless networks\n");
67                 return;
68         }
69         printf("Scanned wireless networks:\n");
70         for (i=0; i < scanned->nr; i++) {
71                 struct scanned_net *net = &scanned->nets[i];
72                 printf("'%s' type(%d): %s, strength: %d\n", net->essid,
73                                 net->type,
74                                 net_type_name(net->type),
75                                 net->strength);
76         }
77 }
78
79 void print_configured_nets(void)
80 {
81         int ret;
82         int i;
83         struct configured_net_list *configured = fetch_configured_nets();
84
85         debug_printf(2, "%s()\n", __func__);
86         ret = issue_noarg_command('l');
87         if (ret) {
88                 printf("error issuing print networks command: %d\n", ret);
89                 return;
90         }
91         configured = eyefi_response();
92         if (configured->nr == 0) {
93                 printf("No wireless networks configured on card\n");
94                 return;
95         }
96         printf("configured wireless networks:\n");
97         for (i=0; i < configured->nr; i++) {
98                 struct configured_net *net = &configured->nets[i];
99                 printf("'%s'\n", net->essid);
100         }
101 }
102
103 int try_connection_to(char *essid, char *wpa_ascii)
104 {
105         int i;
106         int ret = -1;
107
108         char *type = net_type_name(WPA);
109         if (!wpa_ascii)
110                 type = net_type_name(UNSECURED);
111         eyefi_printf("trying to connect to %s network: '%s'", type, essid);
112         if (wpa_ascii)
113                 eyefi_printf(" with passphrase: '%s'", wpa_ascii);
114         fflush(NULL);
115
116         // test network
117         network_action('t', essid, wpa_ascii);
118         u8 last_rsp = -1;
119
120         char rsp = '\0';
121         for (i=0; i < 200; i++) {
122                 struct byte_response *r;
123                 issue_noarg_command('s');
124                 r = eyefi_response();
125                 rsp = r->response;
126                 char *state = net_test_state_name(rsp);
127                 if (rsp == last_rsp) {
128                         eyefi_printf(".");
129                         fflush(NULL);;
130                 } else {
131                         if (rsp)
132                                 eyefi_printf("\nTesting connecion to '%s' (%d): %s", essid, rsp, state);
133                         last_rsp = rsp;
134                 }
135                 
136                 if (!strcmp("success", state)) {
137                         ret = 0;
138                         break;
139                 }
140                 if (!strcmp("not scanning", state))
141                         break;
142                 if (!strcmp("unknown", state))
143                         break;
144         }
145         eyefi_printf("\n");
146         if (!ret) {
147                 eyefi_printf("Succeeded connecting to: '%s'\n", essid);
148         } else {
149                 eyefi_printf("Unable to connect to: '%s' (final state: %d/'%s')\n", essid,
150                                 rsp, net_test_state_name(rsp));
151         }
152         return ret;
153 }
154
155 int print_log(void)
156 {
157         int i;
158         char *resbuf = malloc(EYEFI_BUF_SIZE*4);
159         int total_bytes;
160
161         total_bytes = get_log_into(resbuf);
162         if (total_bytes < 0) {
163                 debug_printf(1, "%s() error: %d\n", __func__, total_bytes);
164                 return total_bytes;
165         }
166         // The last byte *should* be a null, and the 
167         // official software does not print it.
168         for (i = 0; i < total_bytes-1; i++) {
169                 char c = resbuf[i];
170                 // the official software converts UNIX to DOS-style
171                 // line breaks, so we'll do the same
172                 if (c == '\n')
173                         printf("%c", '\r');
174                 printf("%c", c);
175         }
176         printf("\n");
177         // just some simple sanity checking to make sure what
178         // we are fetching looks valid
179         /* needs to be rethought for the new aligned logs
180         int null_bytes_left = 20;
181         if (resbuf[log_end] != 0) {
182                 debug_printf(2, "error: unexpected last byte (%ld/0x%lx) of log: %02x\n",
183                                 log_end, log_end, resbuf[log_end]);
184                 for (i=0; i<log_size; i++) {
185                         if (resbuf[i])
186                                 continue;
187                         if (null_bytes_left <= 0)
188                                 continue;
189                         null_bytes_left--;
190                         debug_printf(2, "null byte %d\n", i);
191                 }
192         }
193         */
194         return 0;
195 }
196
197 void open_error(char *file, int ret)
198 {
199         fprintf(stderr, "unable to open '%s' (%d)\n", file, ret);
200         fprintf(stderr, "Is the Eye-Fi card inserted and mounted at: %s ?\n", locate_eyefi_mount());
201         fprintf(stderr, "Do you have write permissions to it?\n");
202         fprintf(stderr, "debug information:\n");
203         if (eyefi_debug_level > 0)
204                 system("cat /proc/mounts >&2");
205         if (eyefi_debug_level > 1)
206                 perror("bad open");
207         exit(1);
208 }
209
210 void usage(void)
211 {
212         printf("Usage:\n");
213         printf("  eyefitest [OPTIONS]\n");
214         printf("  -a ESSID      add network (implies test unless --force)\n");
215         printf("  -t ESSID      test network\n");
216         printf("  -p KEY        set WPA key for add/test\n");
217         printf("  -r ESSID      remove network\n");
218         printf("  -s            scan for networks\n");
219         printf("  -c            list configured networks\n");
220         printf("  -b            reboot card\n");
221         printf("  -f            print information about card firmware\n");
222         printf("  -d level      set debugging level (default: 1)\n");
223         printf("  -k            print card unique key\n");
224         printf("  -l            dump card log\n");
225         printf("  -m            print card mac\n");
226         exit(4);
227 }
228
229 int main(int argc, char **argv)
230 {
231         if (argc == 1)
232                 usage();
233
234         debug_printf(3, "%s starting...\n", argv[0]);
235         
236         //static int passed_wep = 0;
237         //static int passed_wpa = 0;
238         static int force = 0;
239         static struct option long_options[] = {
240                 //{"wep", 'x', &passed_wep, 1},
241                 //{"wpa", 'y', &passed_wpa, 1},
242                 {"force", 0, &force, 1},
243                 {"help", 'h', NULL, 1},
244         };
245
246         int option_index;
247         char c;
248         char *essid = NULL;
249         char *passwd = NULL;
250         char network_action = 0;
251         debug_printf(3, "about to parse arguments\n");
252         while ((c = getopt_long_only(argc, argv, "a:bcd:kflmp:r:st:z",
253                         &long_options[0], &option_index)) != -1) {
254                 debug_printf(3, "argument: '%c' %d optarg: '%s'\n", c, c, optarg);
255                 switch (c) {
256                 case 0:
257                         // was a long argument
258                         break;
259                 case 'a':
260                 case 't':
261                 case 'r':
262                         essid = optarg;
263                         network_action = c;
264                         break;
265                 case 'b':
266                         reboot_card();
267                         break;
268                 case 'c':
269                         print_configured_nets();
270                         break;
271                 case 'd':
272                         eyefi_debug_level = atoi(optarg);
273                         fprintf(stderr, "set debug level to: %d\n", eyefi_debug_level);
274                         break;
275                 case 'f':
276                         print_card_firmware_info();
277                         break;
278                 case 'k':
279                         print_card_key();
280                         break;
281                 case 'l':
282                         print_log();
283                         break;
284                 case 'm':
285                         print_card_mac();
286                         break;
287                 case 'p':
288                         passwd = optarg;
289                         break;
290                 case 's':
291                         scan_print_nets();
292                         break;
293                 case 'z': {
294                                   extern void testit0(void);
295                         testit0();
296                           }
297                         break;
298                 case 'h':
299                 default:
300                         usage();
301                         break;
302                 }
303         }
304         debug_printf(3, "after arguments essid: '%s' passwd: '%s'\n", essid, passwd);
305         if (network_action && essid) {
306                 int ret = 0;
307                 init_card();
308                 switch (network_action) {
309                 case 't':
310                         ret = try_connection_to(essid, passwd);
311                         break;
312                 case 'a':
313                         if (!force) {
314                                 ret = try_connection_to(essid, passwd);
315                         } else {
316                                 debug_printf(1, "forced: skipping network test\n");
317                         }
318                         if (ret) {
319                                 printf("Error connecting to network '%s', not adding.\n", essid);
320                                 printf("use --force to override\n");
321                                 break;
322                         }
323                         add_network(essid, passwd);
324                         break;
325                 case 'r':
326                         remove_network(essid);
327                         break;
328                 }
329         }
330         return 0;
331 }
332
333