Fixed binary search: no more infinite loops when vendor is unknown.
[tangerine.git] / workbench / devs / networks / prism2 / SetPrism2Defaults.c
blob4d1a05adf9a816f7a889886f0d6594aab6ad9aa4
1 /*
3 Author: Neil Cafferkey
4 Copyright (C) 2004,2005 Neil Cafferkey
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2 of the License, or
9 (at your option) any later version.
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 GNU
14 General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with this program; if not, write to the Free Software
18 Foundation, Inc., 59 Temple Place - Suite 330, Boston,
19 MA 02111-1307, USA.
24 #include <exec/memory.h>
25 #include <dos/dos.h>
26 #include <utility/utility.h>
28 #include <proto/exec.h>
29 #include <proto/dos.h>
30 #include <proto/utility.h>
32 #include "wireless.h"
35 #ifndef UPINT
36 #ifdef __AROS__
37 typedef IPTR UPINT;
38 typedef SIPTR PINT;
39 #else
40 typedef ULONG UPINT;
41 typedef LONG PINT;
42 #endif
43 #endif
45 #define UTILITY_VERSION 39
46 #define DOS_VERSION 36
48 #ifndef __AROS__
49 IMPORT struct ExecBase *AbsExecBase;
50 #endif
52 struct ExecBase *SysBase;
53 struct DosLibrary *DOSBase;
54 struct UtilityBase *UtilityBase;
56 static UPINT ParseHexString(TEXT *str, UBYTE *buffer, UPINT buffer_size);
57 static UPINT StrLen(const TEXT *s);
59 const TEXT template[] =
60 "SSID/K,KEY/K,TEXTKEY/K,NOKEY/S,MANAGED/S,ADHOC/S,CHANNEL/K/N";
61 const TEXT version_string[] = "$VER: SetPrism2Defaults 1.2 (23.7.2005)";
62 const TEXT dos_name[] = DOSNAME;
63 const TEXT utility_name[] = UTILITYNAME;
64 const TEXT options_name[] = "Prism 2 options";
65 static const struct TagItem tag_list_template[] =
67 {P2OPT_SSID, 0},
68 {P2OPT_WEPKey, 0},
69 {P2OPT_Encryption, S2ENC_NONE},
70 {P2OPT_PortType, S2PORT_MANAGED},
71 {P2OPT_Channel, 0},
72 {TAG_END, 0}
74 static const struct TagItem name_tag_list[] =
76 {ANO_NameSpace, TRUE}, /* Work-around for old MorphOS bug */
77 {TAG_END, 0}
81 LONG Main(VOID)
83 struct RDArgs *read_args;
84 LONG error = 0, result = RETURN_OK;
85 UBYTE key_buffer[IEEE802_11_WEP128LEN];
86 struct
88 TEXT *ssid;
89 TEXT *key;
90 TEXT *textkey;
91 PINT nokey;
92 PINT managed;
93 PINT adhoc;
94 PINT *channel;
96 args = {NULL, NULL, NULL, FALSE, FALSE, FALSE, NULL};
97 struct NamedObject *options;
98 struct TagItem *tag_list, *tag_item;
99 TEXT *ssid;
100 UPINT length;
101 struct WEPKey *key;
102 UWORD key_option_count = 0;
104 /* Open libraries */
106 #ifdef __mc68000
107 SysBase = AbsExecBase;
108 #endif
109 DOSBase = (struct DosLibrary *)OpenLibrary(dos_name, DOS_VERSION);
110 if(DOSBase == NULL)
111 return RETURN_FAIL;
112 UtilityBase =
113 (struct UtilityBase *)OpenLibrary(utility_name, UTILITY_VERSION);
115 if(UtilityBase == NULL)
116 error = IoErr();
118 /* Parse arguments */
120 read_args = ReadArgs(template, (PINT *)&args, NULL);
121 if(read_args == NULL)
122 error = IoErr();
123 else
125 if(args.key != NULL)
126 key_option_count++;
127 if(args.textkey != NULL)
128 key_option_count++;
129 if(args.nokey)
130 key_option_count++;
131 if(key_option_count > 1 || args.managed && args.adhoc)
132 error = ERROR_TOO_MANY_ARGS;
135 /* Get pre-existing options object or create a new one */
137 if(error == 0)
139 options = FindNamedObject(NULL, options_name, NULL);
141 if(options == NULL)
143 options = AllocNamedObjectA(options_name, name_tag_list);
144 if(options != NULL)
146 if(AddNamedObject(NULL, options))
148 tag_list = CloneTagItems(tag_list_template);
149 if(tag_list != NULL)
151 options->no_Object = tag_list;
152 ssid = AllocMem(IEEE802_11_MAXIDLEN,
153 MEMF_PUBLIC | MEMF_CLEAR);
154 if(ssid == NULL)
155 error = IoErr();
156 key = AllocMem(sizeof(struct WEPKey),
157 MEMF_PUBLIC | MEMF_CLEAR);
158 if(key == NULL)
159 error = IoErr();
160 if(error == 0)
162 key->length = IEEE802_11_WEP64LEN;
163 tag_item = FindTagItem(P2OPT_SSID, tag_list);
164 tag_item->ti_Data = (UPINT)ssid;
165 tag_item = FindTagItem(P2OPT_WEPKey, tag_list);
166 tag_item->ti_Data = (UPINT)key;
169 else
170 error = IoErr();
172 else
174 error = IoErr();
175 FreeNamedObject(options);
178 else
179 error = IoErr();
183 /* Set new options */
185 if(error == 0)
187 tag_list = (APTR)options->no_Object;
189 if(args.ssid != NULL)
191 tag_item = FindTagItem(P2OPT_SSID, tag_list);
192 length = StrLen(args.ssid);
193 if(length <= IEEE802_11_MAXIDLEN)
194 CopyMem(args.ssid, (APTR)tag_item->ti_Data, length);
195 else
196 error = IoErr();
199 if(args.key != NULL)
201 tag_item = FindTagItem(P2OPT_WEPKey, tag_list);
202 length =
203 ParseHexString(args.key, key_buffer, IEEE802_11_WEP128LEN);
204 if(length == 0)
205 error = ERROR_BAD_NUMBER;
206 else if(length != IEEE802_11_WEP64LEN &&
207 length != IEEE802_11_WEP128LEN)
208 error = ERROR_BAD_NUMBER;
209 else
211 key = (APTR)tag_item->ti_Data;
212 key->length = length;
213 CopyMem(key_buffer, key->key, length);
217 if(args.textkey != NULL)
219 tag_item = FindTagItem(P2OPT_WEPKey, tag_list);
220 length = StrLen(args.textkey);
221 if(length == 0)
222 error = ERROR_INVALID_COMPONENT_NAME;
223 else if(length != IEEE802_11_WEP64LEN &&
224 length != IEEE802_11_WEP128LEN)
225 error = ERROR_INVALID_COMPONENT_NAME;
226 else
228 key = (APTR)tag_item->ti_Data;
229 key->length = length;
230 CopyMem(args.textkey, key->key, length);
235 if(error == 0)
237 tag_item = FindTagItem(P2OPT_Encryption, tag_list);
238 if(args.key != NULL || args.textkey != NULL)
239 tag_item->ti_Data = S2ENC_WEP;
240 else if(args.nokey)
241 tag_item->ti_Data = S2ENC_NONE;
243 tag_item = FindTagItem(P2OPT_PortType, tag_list);
244 if(args.managed)
245 tag_item->ti_Data = S2PORT_MANAGED;
246 else if(args.adhoc)
247 tag_item->ti_Data = S2PORT_ADHOC;
249 if(args.channel != NULL)
251 tag_item = FindTagItem(P2OPT_Channel, tag_list);
252 if(*args.channel >= 3 && *args.channel <= 14)
253 tag_item->ti_Data = *args.channel;
254 else
255 error = ERROR_BAD_NUMBER;
259 FreeArgs(read_args);
261 /* Print error message */
263 #ifdef USE_HACKS
264 SetIoErr(error);
265 #endif
266 PrintFault(error, NULL);
268 if(error != 0)
269 result = RETURN_FAIL;
271 /* Close libraries and exit */
273 CloseLibrary((struct Library *)UtilityBase);
274 CloseLibrary((struct Library *)DOSBase);
276 return result;
281 static UPINT ParseHexString(TEXT *str, UBYTE *buffer, UPINT buffer_size)
283 BOOL success = TRUE;
284 UBYTE n = 0, *end;
285 TEXT ch;
286 UPINT i = 0;
288 end = buffer + buffer_size;
289 while((ch = *str++) != '\0' && buffer < end)
291 n <<= 4;
293 ch = ToUpper(ch);
294 if(ch != '-' && ch != ':' && ch != ' ')
296 if(ch >= '0' && ch <= '9')
297 n |= ch - '0';
298 else if(ch >= 'A' && ch <= 'F')
299 n |= ch - 'A' + 10;
300 else
301 success = FALSE;
303 if((++i & 0x1) == 0)
305 *buffer++ = n;
306 n = 0;
311 if((i & 0x1) != 0)
312 success = FALSE;
314 if(!success)
315 i = 0;
317 return i >> 1;
322 static UPINT StrLen(const TEXT *s)
324 const TEXT *p;
326 for(p = s; *p != '\0'; p++);
327 return p - s;