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