]> git.saurik.com Git - apple/configd.git/blob - scutil.tproj/net_set.c
configd-130.tar.gz
[apple/configd.git] / scutil.tproj / net_set.c
1 /*
2 * Copyright (c) 2004 Apple Computer, Inc. All rights reserved.
3 *
4 * @APPLE_LICENSE_HEADER_START@
5 *
6 * This file contains Original Code and/or Modifications of Original Code
7 * as defined in and that are subject to the Apple Public Source License
8 * Version 2.0 (the 'License'). You may not use this file except in
9 * compliance with the License. Please obtain a copy of the License at
10 * http://www.opensource.apple.com/apsl/ and read it before using this
11 * file.
12 *
13 * The Original Code and all software distributed under the License are
14 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
15 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
16 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
17 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
18 * Please see the License for the specific language governing rights and
19 * limitations under the License.
20 *
21 * @APPLE_LICENSE_HEADER_END@
22 */
23
24 /*
25 * Modification History
26 *
27 * August 5, 2004 Allan Nathanson <ajn@apple.com>
28 * - initial revision
29 */
30
31
32 #include "scutil.h"
33 #include "net.h"
34 #include "net_set.h"
35 #include "net_service.h"
36
37
38 /* -------------------- */
39
40
41 static CFComparisonResult
42 _compare_sets(const void *val1, const void *val2, void *context)
43 {
44 CFStringRef id1;
45 CFStringRef id2;
46 CFStringRef name1;
47 CFStringRef name2;
48 SCNetworkSetRef s1 = (SCNetworkSetRef)val1;
49 SCNetworkSetRef s2 = (SCNetworkSetRef)val2;
50
51 name1 = SCNetworkSetGetName(s1);
52 name2 = SCNetworkSetGetName(s2);
53
54 if (name1 != NULL) {
55 if (name2 != NULL) {
56 return CFStringCompare(name1, name2, 0);
57 } else {
58 return kCFCompareLessThan;
59 }
60 }
61
62 if (name2 != NULL) {
63 return kCFCompareGreaterThan;
64 }
65
66 id1 = SCNetworkSetGetSetID(s1);
67 id2 = SCNetworkSetGetSetID(s2);
68 return CFStringCompare(id1, id2, 0);
69 }
70
71
72 static CFArrayRef
73 _copy_sets()
74 {
75 CFArrayRef sets;
76 CFMutableArrayRef sorted;
77
78 sets = SCNetworkSetCopyAll(prefs);
79 if (sets == NULL) {
80 SCPrint(TRUE, stdout, CFSTR("%s\n"), SCErrorString(SCError()));
81 return NULL;
82 }
83
84 sorted = CFArrayCreateMutableCopy(NULL, 0, sets);
85 CFArraySortValues(sorted,
86 CFRangeMake(0, CFArrayGetCount(sorted)),
87 _compare_sets,
88 NULL);
89
90 CFRelease(sets);
91 sets = CFArrayCreateCopy(NULL, sorted);
92 CFRelease(sorted);
93 return sets;
94 }
95
96
97 static SCNetworkSetRef
98 _find_set(char *match)
99 {
100 Boolean allowIndex = TRUE;
101 CFIndex i;
102 CFIndex n;
103 CFStringRef select_name = NULL;
104 SCNetworkSetRef selected = NULL;
105
106 if (sets == NULL) {
107 if (prefs == NULL) {
108 SCPrint(TRUE, stdout, CFSTR("network configuration not open\n"));
109 return NULL;
110 }
111
112 sets = _copy_sets();
113 if (sets == NULL) {
114 return NULL;
115 }
116
117 allowIndex = FALSE;
118 }
119
120 // try to select the set by its setID
121
122 select_name = CFStringCreateWithCString(NULL, match, kCFStringEncodingUTF8);
123
124 n = CFArrayGetCount(sets);
125 for (i = 0; i < n; i++) {
126 SCNetworkSetRef set;
127 CFStringRef setID;
128
129 set = CFArrayGetValueAtIndex(sets, i);
130 setID = SCNetworkSetGetSetID(set);
131 if (CFEqual(select_name, setID)) {
132 selected = set;
133 goto done;
134
135 }
136 }
137
138 // try to select the set by its name
139
140 for (i = 0; i < n; i++) {
141 SCNetworkSetRef set;
142 CFStringRef setName;
143
144 set = CFArrayGetValueAtIndex(sets, i);
145 setName = SCNetworkSetGetName(set);
146 if ((setName != NULL) &&
147 CFEqual(select_name, setName)) {
148 if (selected == NULL) {
149 selected = set;
150 } else {
151 // if multiple sets match
152 selected = NULL;
153 SCPrint(TRUE, stdout, CFSTR("multiple sets match\n"));
154 goto done;
155 }
156 }
157 }
158
159 if (selected != NULL) {
160 goto done;
161 }
162
163 // try to select the set by its name (case insensitive)
164
165 for (i = 0; i < n; i++) {
166 SCNetworkSetRef set;
167 CFStringRef setName;
168
169 set = CFArrayGetValueAtIndex(sets, i);
170 setName = SCNetworkSetGetName(set);
171 if ((setName != NULL) &&
172 CFStringCompare(select_name,
173 setName,
174 kCFCompareCaseInsensitive) == kCFCompareEqualTo) {
175 if (selected == NULL) {
176 selected = set;
177 } else {
178 // if multiple sets match
179 selected = NULL;
180 SCPrint(TRUE, stdout, CFSTR("multiple sets match\n"));
181 goto done;
182 }
183 }
184 }
185
186 if (selected != NULL) {
187 goto done;
188 }
189
190 // try to select the set by its index
191
192 if (allowIndex) {
193 char *end;
194 char *str = match;
195 long val;
196
197 errno = 0;
198 val = strtol(str, &end, 10);
199 if ((*str != '\0') && (*end == '\0') && (errno == 0)) {
200 if ((val > 0) && (val <= n)) {
201 selected = CFArrayGetValueAtIndex(sets, val - 1);
202 }
203 }
204 }
205
206 if (selected != NULL) {
207 goto done;
208 }
209
210 SCPrint(TRUE, stdout, CFSTR("no match, which set?\n"));
211
212 done :
213
214 if (select_name != NULL) CFRelease(select_name);
215 return selected;
216 }
217
218
219 /* -------------------- */
220
221
222 __private_extern__
223 void
224 create_set(int argc, char **argv)
225 {
226 SCNetworkSetRef set;
227 CFStringRef setName;
228
229 if (prefs == NULL) {
230 SCPrint(TRUE, stdout, CFSTR("network configuration not open\n"));
231 return;
232 }
233
234 set = SCNetworkSetCreate(prefs);
235 if (set == NULL) {
236 SCPrint(TRUE, stdout, CFSTR("%s\n"), SCErrorString(SCError()));
237 return;
238 }
239
240 if ((argc > 0) && (strlen(argv[0]) > 0)) {
241 Boolean ok;
242
243 setName = CFStringCreateWithCString(NULL, argv[0], kCFStringEncodingUTF8);
244 argv++;
245 argc--;
246
247 ok = SCNetworkSetSetName(set, setName);
248 CFRelease(setName);
249 if (!ok) {
250 SCPrint(TRUE, stdout, CFSTR("set not created: %s\n"), SCErrorString(SCError()));
251 (void) SCNetworkSetRemove(set);
252 CFRelease(set);
253 return;
254 }
255 }
256
257 net_changed = TRUE;
258
259 if (net_set != NULL) CFRelease(net_set);
260 net_set = set;
261
262 setName = SCNetworkSetGetName(set);
263 if (setName != NULL) {
264 SCPrint(TRUE, stdout,
265 CFSTR("set \"%@\" (%@) created and selected\n"),
266 setName,
267 SCNetworkSetGetSetID(set));
268 } else {
269 SCPrint(TRUE, stdout,
270 CFSTR("set ID \"%@\" created and selected\n"),
271 SCNetworkSetGetSetID(set));
272 }
273
274 if (net_service != NULL) {
275 CFRelease(net_service);
276 net_service = NULL;
277 SCPrint(TRUE, stdout, CFSTR("& no service selected\n"));
278 }
279
280 if (net_protocol != NULL) {
281 CFRelease(net_protocol);
282 net_protocol = NULL;
283 SCPrint(TRUE, stdout, CFSTR("& no protocol selected\n"));
284 }
285
286 if (net_interface != NULL) {
287 CFRelease(net_interface);
288 net_interface = NULL;
289 SCPrint(TRUE, stdout, CFSTR("& no interface selected\n"));
290 }
291
292 if (sets != NULL) {
293 CFRelease(sets);
294 sets = NULL;
295 }
296
297 return;
298 }
299
300
301 __private_extern__
302 void
303 remove_set(int argc, char **argv)
304 {
305 SCNetworkSetRef set = NULL;
306 CFStringRef setName;
307
308 if (argc == 1) {
309 set = _find_set(argv[0]);
310 } else {
311 if (net_set != NULL) {
312 set = net_set;
313 }
314 }
315
316 if (set == NULL) {
317 return;
318 }
319
320 CFRetain(set);
321
322 if (!SCNetworkSetRemove(set)) {
323 SCPrint(TRUE, stdout, CFSTR("%s\n"), SCErrorString(SCError()));
324 goto done;
325 }
326
327 net_changed = TRUE;
328
329 setName = SCNetworkSetGetName(set);
330 if (setName != NULL) {
331 SCPrint(TRUE, stdout, CFSTR("set \"%@\" removed\n"), setName);
332 } else {
333 SCPrint(TRUE, stdout,
334 CFSTR("set ID \"%@\" removed\n"),
335 SCNetworkSetGetSetID(set));
336 }
337
338 if (CFEqual(set, net_set)) {
339 if (net_service != NULL) {
340 CFRelease(net_service);
341 net_service = NULL;
342 SCPrint(TRUE, stdout, CFSTR("& no service selected\n"));
343 }
344
345 if (net_protocol != NULL) {
346 CFRelease(net_protocol);
347 net_protocol = NULL;
348 SCPrint(TRUE, stdout, CFSTR("& no protocol selected\n"));
349 }
350
351 if (net_interface != NULL) {
352 CFRelease(net_interface);
353 net_interface = NULL;
354 SCPrint(TRUE, stdout, CFSTR("& no interface selected\n"));
355 }
356 }
357
358 if (sets != NULL) {
359 CFRelease(sets);
360 sets = NULL;
361 }
362
363 done :
364
365 CFRelease(set);
366 return;
367 }
368
369
370 __private_extern__
371 void
372 select_set(int argc, char **argv)
373 {
374 SCNetworkSetRef set;
375 CFStringRef setName;
376
377 set = _find_set(argv[0]);
378
379 if (set == NULL) {
380 return;
381 }
382
383 if (net_set != NULL) CFRelease(net_set);
384 net_set = CFRetain(set);
385
386 setName = SCNetworkSetGetName(set);
387 if (setName != NULL) {
388 SCPrint(TRUE, stdout, CFSTR("set \"%@\" selected\n"), setName);
389 } else {
390 SCPrint(TRUE, stdout,
391 CFSTR("set ID \"%@\" selected\n"),
392 SCNetworkSetGetSetID(set));
393 }
394
395 if (net_service != NULL) {
396 CFRelease(net_service);
397 net_service = NULL;
398 SCPrint(TRUE, stdout, CFSTR("& no service selected\n"));
399 }
400
401 if (net_protocol != NULL) {
402 CFRelease(net_protocol);
403 net_protocol = NULL;
404 SCPrint(TRUE, stdout, CFSTR("& no protocol selected\n"));
405 }
406
407 if (net_interface != NULL) {
408 CFRelease(net_interface);
409 net_interface = NULL;
410 SCPrint(TRUE, stdout, CFSTR("& no interface selected\n"));
411 }
412
413 return;
414 }
415
416
417 __private_extern__
418 void
419 set_set(int argc, char **argv)
420 {
421 Boolean ok;
422
423 if (net_set == NULL) {
424 SCPrint(TRUE, stdout, CFSTR("set not selected\n"));
425 return;
426 }
427
428 if (argc < 1) {
429 SCPrint(TRUE, stdout, CFSTR("set what?\n"));
430 return;
431 }
432
433 while (argc > 0) {
434 char *command;
435
436 command = argv[0];
437 argv++;
438 argc--;
439
440 if (strcmp(command, "name") == 0) {
441 CFStringRef setName;
442
443 if (argc < 1) {
444 SCPrint(TRUE, stdout, CFSTR("name not specified\n"));
445 return;
446 }
447
448 setName = (strlen(argv[0]) > 0)
449 ? CFStringCreateWithCString(NULL, argv[0], kCFStringEncodingUTF8)
450 : NULL;
451 argv++;
452 argc--;
453
454 ok = SCNetworkSetSetName(net_set, setName);
455 if (setName != NULL) CFRelease(setName);
456 if (!ok) {
457 SCPrint(TRUE, stdout, CFSTR("%s\n"), SCErrorString(SCError()));
458 return;
459 }
460
461 net_changed = TRUE;
462
463 if (sets != NULL) {
464 /*
465 * since the (displayed) ordering may have changed, refresh sets
466 */
467 char *setID;
468
469 setID = _SC_cfstring_to_cstring(SCNetworkSetGetSetID(net_set),
470 NULL,
471 0,
472 kCFStringEncodingUTF8);
473
474 CFRelease(net_set);
475 net_set = NULL;
476
477 CFRelease(sets);
478 sets = NULL;
479
480 net_set = _find_set(setID);
481 if (net_set != NULL) {
482 CFRetain(net_set);
483 }
484
485 CFAllocatorDeallocate(NULL, setID);
486 }
487 } else {
488 SCPrint(TRUE, stdout, CFSTR("set what?\n"));
489 }
490 }
491
492 return;
493 }
494
495
496 __private_extern__
497 void
498 show_set(int argc, char **argv)
499 {
500 CFArrayRef services;
501 SCNetworkSetRef set = NULL;
502 CFStringRef setName;
503
504 if (argc == 1) {
505 set = _find_set(argv[0]);
506 } else {
507 if (net_set != NULL) {
508 set = net_set;
509 } else {
510 SCPrint(TRUE, stdout, CFSTR("set not selected\n"));
511 return;
512 }
513 }
514
515 if (set == NULL) {
516 return;
517 }
518
519 SCPrint(TRUE, stdout, CFSTR("set id = %@\n"), SCNetworkSetGetSetID(set));
520
521 setName = SCNetworkSetGetName(set);
522 SCPrint(TRUE, stdout, CFSTR("name = %@\n"),
523 (setName != NULL) ? setName : CFSTR(""));
524
525 services = SCNetworkSetCopyServices(set);
526 if (services != NULL) {
527 CFIndex i;
528 CFIndex n;
529 CFIndex nOrder = 0;
530 CFArrayRef order;
531 CFMutableArrayRef sorted = (CFMutableArrayRef)services;
532
533 order = SCNetworkSetGetServiceOrder(set);
534 if (order != NULL) {
535 nOrder = CFArrayGetCount(order);
536 }
537
538 n = CFArrayGetCount(services);
539 if (n > 1) {
540 sorted = CFArrayCreateMutableCopy(NULL, 0, services);
541 CFArraySortValues(sorted,
542 CFRangeMake(0, CFArrayGetCount(sorted)),
543 _compare_services,
544 (void *)order);
545 }
546
547 SCPrint(TRUE, stdout, CFSTR("services =\n"));
548
549 for (i = 0; i < n; i++) {
550 CFIndex orderIndex = kCFNotFound;
551 SCNetworkServiceRef service;
552 CFStringRef serviceName;
553 CFStringRef serviceID;
554
555 service = CFArrayGetValueAtIndex(sorted, i);
556 serviceID = SCNetworkServiceGetServiceID(service);
557 serviceName = SCNetworkServiceGetName(service);
558 if (serviceName == NULL) serviceName = CFSTR("");
559
560 if (order != NULL) {
561 orderIndex = CFArrayGetFirstIndexOfValue(order,
562 CFRangeMake(0, nOrder),
563 serviceID);
564 }
565 if (orderIndex != kCFNotFound) {
566 SCPrint(TRUE, stdout, CFSTR("%c%2d: %@%-*s (%@)\n"),
567 ((net_service != NULL) && CFEqual(service, net_service)) ? '>' : ' ',
568 orderIndex + 1,
569 serviceName,
570 30 - CFStringGetLength(serviceName),
571 " ",
572 serviceID);
573 } else {
574 SCPrint(TRUE, stdout, CFSTR("%c : %@%-*s (%@)\n"),
575 ((net_service != NULL) && CFEqual(service, net_service)) ? '>' : ' ',
576 serviceName,
577 30 - CFStringGetLength(serviceName),
578 " ",
579 serviceID);
580 }
581 }
582
583 CFRelease(services);
584
585 if (sorted != services) CFRelease(sorted);
586 }
587
588 if (_sc_debug) {
589 SCPrint(TRUE, stdout, CFSTR("\n%@\n"), set);
590 }
591
592 return;
593 }
594
595
596 __private_extern__
597 void
598 show_sets(int argc, char **argv)
599 {
600 SCNetworkSetRef current;
601 CFIndex i;
602 CFIndex n;
603
604 if (prefs == NULL) {
605 SCPrint(TRUE, stdout, CFSTR("network configuration not open\n"));
606 return;
607 }
608
609 if (sets == NULL) {
610 sets = _copy_sets();
611 if (sets == NULL) {
612 return;
613 }
614 }
615
616 current = SCNetworkSetCopyCurrent(prefs);
617
618 n = CFArrayGetCount(sets);
619 for (i = 0; i < n; i++) {
620 SCNetworkSetRef set;
621 CFStringRef setID;
622 CFStringRef setName;
623
624 set = CFArrayGetValueAtIndex(sets, i);
625 setID = SCNetworkSetGetSetID(set);
626 setName = SCNetworkSetGetName(set);
627 if (setName == NULL) setName = CFSTR("");
628
629 SCPrint(TRUE, stdout, CFSTR(" %c%c%2d: %@%-*s (%@)\n"),
630 ((current != NULL) && CFEqual(set, current)) ? '*' : ' ',
631 ((net_set != NULL) && CFEqual(set, net_set)) ? '>' : ' ',
632 i + 1,
633 setName,
634 30 - CFStringGetLength(setName),
635 " ",
636 setID);
637 }
638
639 if (current != NULL) CFRelease(current);
640
641 return;
642 }