]> git.saurik.com Git - apple/configd.git/blob - scutil.tproj/net.c
c28dd55341a72da8c38ff4a7423dceded7bf2fc8
[apple/configd.git] / scutil.tproj / net.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 "commands.h"
34 #include "net.h"
35 #include "net_interface.h"
36 #include "net_protocol.h"
37 #include "net_service.h"
38 #include "net_set.h"
39
40 #include <unistd.h>
41
42
43 __private_extern__ Boolean net_changed = FALSE;
44
45 __private_extern__ CFMutableArrayRef new_interfaces = NULL;
46
47 __private_extern__ CFArrayRef interfaces = NULL;
48 __private_extern__ CFArrayRef services = NULL;
49 __private_extern__ CFArrayRef protocols = NULL;
50 __private_extern__ CFArrayRef sets = NULL;
51
52 __private_extern__ SCNetworkInterfaceRef net_interface = NULL;
53 __private_extern__ SCNetworkServiceRef net_service = NULL;
54 __private_extern__ SCNetworkProtocolRef net_protocol = NULL;
55 __private_extern__ SCNetworkSetRef net_set = NULL;
56
57 __private_extern__ CFNumberRef CFNumberRef_0 = NULL;
58 __private_extern__ CFNumberRef CFNumberRef_1 = NULL;
59
60
61 /* -------------------- */
62
63
64 __private_extern__
65 CFNumberRef
66 _copy_number(const char *arg)
67 {
68 int val;
69
70 if (sscanf(arg, "%d", &val) != 1) {
71 return NULL;
72 }
73
74 return CFNumberCreate(NULL, kCFNumberIntType, &val);
75 }
76
77
78 /* -------------------- */
79
80
81 __private_extern__
82 CFIndex
83 _find_option(const char *option, optionsRef options, const int nOptions)
84 {
85 CFIndex i;
86
87 for (i = 0; i < nOptions; i++) {
88 if (strcasecmp(option, options[i].option) == 0) {
89 return i;
90 }
91 }
92
93 return kCFNotFound;
94 }
95
96
97 __private_extern__
98 CFIndex
99 _find_selection(CFStringRef choice, selections choices[], unsigned int *flags)
100 {
101 CFIndex i;
102
103 i = 0;
104 while (choices[i].selection != NULL) {
105 if (CFStringCompare(choice,
106 choices[i].selection,
107 kCFCompareCaseInsensitive) == kCFCompareEqualTo) {
108 if (flags != NULL) {
109 *flags = choices[i].flags;
110 }
111 return i;
112 }
113 i++;
114 }
115
116 return kCFNotFound;
117 }
118
119
120 __private_extern__
121 Boolean
122 _process_options(optionsRef options, int nOptions, int argc, char **argv, CFMutableDictionaryRef newConfiguration)
123 {
124 while (argc > 0) {
125 CFIndex optionIndex = kCFNotFound;
126
127 optionIndex = _find_option(argv[0], options, nOptions);
128 if (optionIndex == kCFNotFound) {
129 SCPrint(TRUE, stdout, CFSTR("set what?\n"));
130 return FALSE;
131 }
132 argv++;
133 argc--;
134
135 switch (options[optionIndex].type) {
136 case isOther :
137 // all option processing is managed by the "handler"
138 break;
139 case isHelp :
140 SCPrint(TRUE, stdout, CFSTR("%s\n"), options[optionIndex].info);
141 return FALSE;
142 case isChooseOne : {
143 CFStringRef choice;
144 selections *choices = (selections *)options[optionIndex].info;
145 unsigned int flags;
146 CFIndex i;
147
148 if (argc < 1) {
149 SCPrint(TRUE, stdout,
150 CFSTR("%s not specified\n"),
151 options[optionIndex].description != NULL ? options[optionIndex].description : "selection");
152 return FALSE;
153 }
154
155 choice = CFStringCreateWithCString(NULL, argv[0], kCFStringEncodingUTF8);
156 i = _find_selection(choice, choices, &flags);
157 CFRelease(choice);
158
159 if (i != kCFNotFound) {
160 if (choices[i].flags & selectionNotAvailable) {
161 SCPrint(TRUE, stdout,
162 CFSTR("cannot select %s\n"),
163 options[optionIndex].description != NULL ? options[optionIndex].description : "selection");
164 return FALSE;
165 }
166
167 CFDictionarySetValue(newConfiguration,
168 *(options[optionIndex].key),
169 *(choices[i].key));
170 } else {
171 SCPrint(TRUE, stdout,
172 CFSTR("invalid %s\n"),
173 options[optionIndex].description != NULL ? options[optionIndex].description : "selection");
174 return FALSE;
175 }
176
177 argv++;
178 argc--;
179 break;
180 }
181 case isChooseMultiple :
182 if (argc < 1) {
183 SCPrint(TRUE, stdout,
184 CFSTR("%s(s) not specified\n"),
185 options[optionIndex].description != NULL ? options[optionIndex].description : "selection");
186 return FALSE;
187 }
188
189 if (strlen(argv[0]) > 0) {
190 CFIndex i;
191 CFIndex n;
192 CFMutableArrayRef chosen;
193 CFStringRef str;
194 CFArrayRef str_array;
195
196 str = CFStringCreateWithCString(NULL, argv[0], kCFStringEncodingUTF8);
197 str_array = CFStringCreateArrayBySeparatingStrings(NULL, str, CFSTR(","));
198 CFRelease(str);
199
200 chosen = CFArrayCreateMutable(NULL, 0, &kCFTypeArrayCallBacks);
201
202 n = CFArrayGetCount(str_array);
203 for (i = 0; i < n; i++) {
204 CFStringRef choice;
205 selections *choices = (selections *)options[optionIndex].info;
206 unsigned int flags;
207 CFIndex j;
208
209 choice = CFArrayGetValueAtIndex(str_array, i);
210 j = _find_selection(choice, choices, &flags);
211
212 if (j != kCFNotFound) {
213 if (choices[j].flags & selectionNotAvailable) {
214 SCPrint(TRUE, stdout,
215 CFSTR("cannot select %s\n"),
216 options[optionIndex].description != NULL ? options[optionIndex].description : "selection");
217 CFArrayRemoveAllValues(chosen);
218 break;
219 }
220
221 CFArrayAppendValue(chosen, *(choices[j].key));
222 } else {
223 SCPrint(TRUE, stdout,
224 CFSTR("invalid %s\n"),
225 options[optionIndex].description != NULL ? options[optionIndex].description : "selection");
226 CFArrayRemoveAllValues(chosen);
227 break;
228 }
229 }
230 CFRelease(str_array);
231
232 if (CFArrayGetCount(chosen) > 0) {
233 CFDictionarySetValue(newConfiguration, *(options[optionIndex].key), chosen);
234 } else {
235 CFDictionaryRemoveValue(newConfiguration, *(options[optionIndex].key));
236 }
237 CFRelease(chosen);
238 } else {
239 CFDictionaryRemoveValue(newConfiguration, *(options[optionIndex].key));
240 }
241
242 argv++;
243 argc--;
244 break;
245 case isBoolean :
246 if (argc < 1) {
247 SCPrint(TRUE, stdout,
248 CFSTR("%s not specified\n"),
249 options[optionIndex].description != NULL ? options[optionIndex].description : "enable/disable");
250 return FALSE;
251 }
252
253 if ((strcasecmp(argv[0], "disable") == 0) ||
254 (strcasecmp(argv[0], "0" ) == 0)) {
255 CFDictionarySetValue(newConfiguration, *(options[optionIndex].key), CFNumberRef_0);
256 } else if ((strcasecmp(argv[0], "enable") == 0) ||
257 (strcasecmp(argv[0], "1" ) == 0)) {
258 CFDictionarySetValue(newConfiguration, *(options[optionIndex].key), CFNumberRef_1);
259 } else {
260 SCPrint(TRUE, stdout, CFSTR("invalid value\n"));
261 return FALSE;
262 }
263
264 argv++;
265 argc--;
266 break;
267 case isNumber :
268 if (argc < 1) {
269 SCPrint(TRUE, stdout,
270 CFSTR("%s not specified\n"),
271 options[optionIndex].description != NULL ? options[optionIndex].description : "value");
272 return FALSE;
273 }
274
275 if (strlen(argv[0]) > 0) {
276 CFNumberRef num;
277
278 num = _copy_number(argv[0]);
279 if (num != NULL) {
280 CFDictionarySetValue(newConfiguration, *(options[optionIndex].key), num);
281 CFRelease(num);
282 } else {
283 SCPrint(TRUE, stdout, CFSTR("invalid value\n"));
284 return FALSE;
285 }
286 } else {
287 CFDictionaryRemoveValue(newConfiguration, *(options[optionIndex].key));
288 }
289
290 argv++;
291 argc--;
292 break;
293 case isString :
294 if (argc < 1) {
295 SCPrint(TRUE, stdout,
296 CFSTR("%s not specified\n"),
297 options[optionIndex].description != NULL ? options[optionIndex].description : "value");
298 return FALSE;
299 }
300
301 if (strlen(argv[0]) > 0) {
302 CFStringRef str;
303
304 str = CFStringCreateWithCString(NULL, argv[0], kCFStringEncodingUTF8);
305 CFDictionarySetValue(newConfiguration, *(options[optionIndex].key), str);
306 CFRelease(str);
307 } else {
308 CFDictionaryRemoveValue(newConfiguration, *(options[optionIndex].key));
309 }
310
311 argv++;
312 argc--;
313 break;
314 case isStringArray :
315 if (argc < 1) {
316 SCPrint(TRUE, stdout,
317 CFSTR("%s(s) not specified\n"),
318 options[optionIndex].description != NULL ? options[optionIndex].description : "value");
319 return FALSE;
320 }
321
322 if (strlen(argv[0]) > 0) {
323 CFStringRef str;
324 CFArrayRef str_array;
325
326 str = CFStringCreateWithCString(NULL, argv[0], kCFStringEncodingUTF8);
327 str_array = CFStringCreateArrayBySeparatingStrings(NULL, str, CFSTR(","));
328 CFRelease(str);
329
330 CFDictionarySetValue(newConfiguration, *(options[optionIndex].key), str_array);
331 CFRelease(str_array);
332 } else {
333 CFDictionaryRemoveValue(newConfiguration, *(options[optionIndex].key));
334 }
335
336 argv++;
337 argc--;
338 break;
339 }
340
341 if (options[optionIndex].handler != NULL) {
342 CFStringRef key;
343 int nArgs;
344
345 key = options[optionIndex].key != NULL ? *(options[optionIndex].key) : NULL;
346 nArgs = (*options[optionIndex].handler)(key,
347 options[optionIndex].description,
348 options[optionIndex].info,
349 argc,
350 argv,
351 newConfiguration);
352 if (nArgs < 0) {
353 return FALSE;
354 }
355
356 argv += nArgs;
357 argc -= nArgs;
358 }
359 }
360
361 return TRUE;
362 }
363
364
365 /* -------------------- */
366
367
368 #define N_QUICK 32
369
370 __private_extern__
371 void
372 _show_entity(CFDictionaryRef entity, CFStringRef prefix)
373 {
374 CFArrayRef array;
375 const void * keys_q[N_QUICK];
376 const void ** keys = keys_q;
377 CFIndex i;
378 CFIndex n;
379 CFMutableArrayRef sorted;
380
381 n = CFDictionaryGetCount(entity);
382 if (n > (CFIndex)(sizeof(keys_q) / sizeof(CFTypeRef))) {
383 keys = CFAllocatorAllocate(NULL, n * sizeof(CFTypeRef), 0);
384 }
385 CFDictionaryGetKeysAndValues(entity, keys, NULL);
386
387 array = CFArrayCreate(NULL, keys, n, &kCFTypeArrayCallBacks);
388 sorted = CFArrayCreateMutableCopy(NULL, n, array);
389 if (n > 1) {
390 CFArraySortValues(sorted,
391 CFRangeMake(0, n),
392 (CFComparatorFunction)CFStringCompare,
393 NULL);
394 }
395
396 for (i = 0; i < n; i++) {
397 CFStringRef key;
398 CFTypeRef value;
399
400 key = CFArrayGetValueAtIndex(sorted, i);
401 value = CFDictionaryGetValue(entity, key);
402 if (isA_CFArray(value)) {
403 CFStringRef str;
404
405 str = CFStringCreateByCombiningStrings(NULL, value, CFSTR(", "));
406 SCPrint(TRUE, stdout, CFSTR("%@ %@ = (%@)\n"), prefix, key, str);
407 CFRelease(str);
408 } else {
409 SCPrint(TRUE, stdout, CFSTR("%@ %@ = %@\n"), prefix, key, value);
410 }
411 }
412
413 CFRelease(sorted);
414 CFRelease(array);
415 if (keys != keys_q) {
416 CFAllocatorDeallocate(NULL, keys);
417 }
418
419 return;
420 }
421
422
423 /* -------------------- */
424
425
426 static Boolean
427 commitRequired(int argc, char **argv, const char *command)
428 {
429 if (net_changed) {
430 if ((currentInput != NULL) &&
431 isatty(fileno(currentInput->fp)) &&
432 ((argc < 1) || (strcmp(argv[0], "!") != 0))
433 ) {
434 SCPrint(TRUE, stdout,
435 CFSTR("configuration changes have not been committed\n"
436 "use \"commit\" to save changes"));
437 if (command != NULL) {
438 SCPrint(TRUE, stdout,
439 CFSTR(" or \"%s !\" to abandon changes"),
440 command);
441 }
442 SCPrint(TRUE, stdout, CFSTR("\n"));
443 return TRUE;
444 }
445
446 SCPrint(TRUE, stdout, CFSTR("configuration changes abandoned\n"));
447 }
448
449 return FALSE;
450 }
451
452
453 __private_extern__
454 void
455 do_net_init()
456 {
457 int one = 1;
458 int zero = 0;
459
460 CFNumberRef_0 = CFNumberCreate(NULL, kCFNumberIntType, &zero);
461 CFNumberRef_1 = CFNumberCreate(NULL, kCFNumberIntType, &one);
462
463 return;
464 }
465
466
467 __private_extern__
468 void
469 do_net_open(int argc, char **argv)
470 {
471 CFStringRef prefsID = NULL;
472
473 if (prefs != NULL) {
474 if (commitRequired(argc, argv, "close")) {
475 return;
476 }
477 do_net_close(0, NULL);
478 }
479
480 if (argc > 0) {
481 prefsID = CFStringCreateWithCString(NULL, argv[0], kCFStringEncodingUTF8);
482 }
483
484 prefs = SCPreferencesCreate(NULL, CFSTR("scutil --net"), prefsID);
485 if (prefsID != NULL) CFRelease(prefsID);
486
487 if (prefs == NULL) {
488 SCPrint(TRUE, stdout, CFSTR("%s\n"), SCErrorString(SCError()));
489 return;
490 }
491
492 net_changed = FALSE;
493
494 net_set = SCNetworkSetCopyCurrent(prefs);
495 if (net_set != NULL) {
496 CFStringRef setName;
497
498 setName = SCNetworkSetGetName(net_set);
499 if (setName != NULL) {
500 SCPrint(TRUE, stdout, CFSTR("set \"%@\" selected\n"), setName);
501 } else {
502 SCPrint(TRUE, stdout,
503 CFSTR("set ID \"%@\" selected\n"),
504 SCNetworkSetGetSetID(net_set));
505 }
506 }
507
508 return;
509 }
510
511
512 __private_extern__
513 void
514 do_net_commit(int argc, char **argv)
515 {
516 if (!SCPreferencesCommitChanges(prefs)) {
517 SCPrint(TRUE, stdout, CFSTR("%s\n"), SCErrorString(SCError()));
518 return;
519 }
520
521 net_changed = FALSE;
522
523 return;
524 }
525
526
527 __private_extern__
528 void
529 do_net_apply(int argc, char **argv)
530 {
531 if (!SCPreferencesApplyChanges(prefs)) {
532 SCPrint(TRUE, stdout, CFSTR("%s\n"), SCErrorString(SCError()));
533 }
534 return;
535 }
536
537
538 __private_extern__
539 void
540 do_net_close(int argc, char **argv)
541 {
542 if (commitRequired(argc, argv, "close")) {
543 return;
544 }
545
546 if (net_interface != NULL) {
547 CFRelease(net_interface);
548 net_interface = NULL;
549 }
550
551 if (net_service != NULL) {
552 CFRelease(net_service);
553 net_service = NULL;
554 }
555
556 if (net_protocol != NULL) {
557 CFRelease(net_protocol);
558 net_protocol = NULL;
559 }
560
561 if (net_set != NULL) {
562 CFRelease(net_set);
563 net_set = NULL;
564 }
565
566 if (interfaces != NULL) {
567 CFRelease(interfaces);
568 interfaces = NULL;
569 }
570
571 if (services != NULL) {
572 CFRelease(services);
573 services = NULL;
574 }
575
576 if (protocols != NULL) {
577 CFRelease(protocols);
578 protocols = NULL;
579 }
580
581 if (sets != NULL) {
582 CFRelease(sets);
583 sets = NULL;
584 }
585
586 if (new_interfaces != NULL) {
587 CFRelease(new_interfaces);
588 new_interfaces = NULL;
589 }
590
591 if (prefs != NULL) {
592 CFRelease(prefs);
593 prefs = NULL;
594 }
595
596 net_changed = FALSE;
597
598 return;
599 }
600
601
602 __private_extern__
603 void
604 do_net_quit(int argc, char **argv)
605 {
606 if (commitRequired(argc, argv, "quit")) {
607 return;
608 }
609
610 termRequested = TRUE;
611 return;
612 }
613
614
615 /* -------------------- */
616
617
618 typedef void (*net_func) (int argc, char **argv);
619
620 static const struct {
621 char *key;
622 net_func create;
623 net_func disable;
624 net_func enable;
625 net_func select;
626 net_func set;
627 net_func show;
628 net_func remove;
629 } net_keys[] = {
630
631 { "interfaces", NULL , NULL , NULL ,
632 NULL , NULL , show_interfaces ,
633 NULL },
634
635 { "interface", create_interface, NULL , NULL ,
636 select_interface, set_interface , show_interface ,
637 NULL },
638
639 { "services", NULL , NULL , NULL ,
640 NULL , NULL , show_services ,
641 NULL },
642
643 { "service", create_service , disable_service , enable_service ,
644 select_service , set_service , show_service ,
645 remove_service },
646
647 { "protocols", NULL , NULL , NULL ,
648 NULL , NULL , show_protocols ,
649 NULL },
650
651 { "protocol", create_protocol , disable_protocol, enable_protocol ,
652 select_protocol , set_protocol , show_protocol ,
653 remove_protocol },
654
655 { "sets", NULL , NULL , NULL ,
656 NULL , NULL , show_sets ,
657 NULL },
658
659 { "set", create_set , NULL , NULL ,
660 select_set , set_set , show_set ,
661 remove_set }
662
663 };
664 #define N_NET_KEYS (sizeof(net_keys) / sizeof(net_keys[0]))
665
666
667 static int
668 findNetKey(char *key)
669 {
670 int i;
671
672 for (i = 0; i < (int)N_NET_KEYS; i++) {
673 if (strcmp(key, net_keys[i].key) == 0) {
674 return i;
675 }
676 }
677
678 return -1;
679 }
680
681
682 /* -------------------- */
683
684
685 __private_extern__
686 void
687 do_net_create(int argc, char **argv)
688 {
689 char *key;
690 int i;
691
692 key = argv[0];
693 argv++;
694 argc--;
695
696 i = findNetKey(key);
697 if (i < 0) {
698 SCPrint(TRUE, stderr, CFSTR("create what?\n"));
699 return;
700 }
701
702 if (*net_keys[i].create == NULL) {
703 SCPrint(TRUE, stderr, CFSTR("create what?\n"));
704 }
705
706 (*net_keys[i].create)(argc, argv);
707 return;
708 }
709
710
711 __private_extern__
712 void
713 do_net_disable(int argc, char **argv)
714 {
715 char *key;
716 int i;
717
718 key = argv[0];
719 argv++;
720 argc--;
721
722 i = findNetKey(key);
723 if (i < 0) {
724 SCPrint(TRUE, stderr, CFSTR("disable what?\n"));
725 return;
726 }
727
728 if (*net_keys[i].disable == NULL) {
729 SCPrint(TRUE, stderr, CFSTR("disable what?\n"));
730 }
731
732 (*net_keys[i].disable)(argc, argv);
733 return;
734 }
735
736
737 __private_extern__
738 void
739 do_net_enable(int argc, char **argv)
740 {
741 char *key;
742 int i;
743
744 key = argv[0];
745 argv++;
746 argc--;
747
748 i = findNetKey(key);
749 if (i < 0) {
750 SCPrint(TRUE, stderr, CFSTR("enable what?\n"));
751 return;
752 }
753
754 if (*net_keys[i].enable == NULL) {
755 SCPrint(TRUE, stderr, CFSTR("enable what?\n"));
756 }
757
758 (*net_keys[i].enable)(argc, argv);
759 return;
760 }
761
762
763 __private_extern__
764 void
765 do_net_remove(int argc, char **argv)
766 {
767 char *key;
768 int i;
769
770 key = argv[0];
771 argv++;
772 argc--;
773
774 i = findNetKey(key);
775 if (i < 0) {
776 SCPrint(TRUE, stderr, CFSTR("remove what?\n"));
777 return;
778 }
779
780 if (*net_keys[i].remove == NULL) {
781 SCPrint(TRUE, stderr, CFSTR("remove what?\n"));
782 }
783
784 (*net_keys[i].remove)(argc, argv);
785 return;
786 }
787
788
789 __private_extern__
790 void
791 do_net_select(int argc, char **argv)
792 {
793 char *key;
794 int i;
795
796 key = argv[0];
797 argv++;
798 argc--;
799
800 i = findNetKey(key);
801 if (i < 0) {
802 SCPrint(TRUE, stderr, CFSTR("select what?\n"));
803 return;
804 }
805
806 if (*net_keys[i].select == NULL) {
807 SCPrint(TRUE, stderr, CFSTR("select what?\n"));
808 }
809
810 (*net_keys[i].select)(argc, argv);
811 return;
812 }
813
814
815 __private_extern__
816 void
817 do_net_set(int argc, char **argv)
818 {
819 char *key;
820 int i;
821
822 key = argv[0];
823 argv++;
824 argc--;
825
826 i = findNetKey(key);
827 if (i < 0) {
828 SCPrint(TRUE, stderr, CFSTR("set what?\n"));
829 return;
830 }
831
832 (*net_keys[i].set)(argc, argv);
833 return;
834 }
835
836
837 __private_extern__
838 void
839 do_net_show(int argc, char **argv)
840 {
841 char *key;
842 int i;
843
844 key = argv[0];
845 argv++;
846 argc--;
847
848 i = findNetKey(key);
849 if (i < 0) {
850 SCPrint(TRUE, stderr, CFSTR("show what?\n"));
851 return;
852 }
853
854 (*net_keys[i].show)(argc, argv);
855 return;
856 }
857
858
859 #include "SCPreferencesInternal.h"
860 #include <fcntl.h>
861 #include <unistd.h>
862 __private_extern__
863 void
864 do_net_snapshot(int argc, char **argv)
865 {
866 if (prefs == NULL) {
867 SCPrint(TRUE, stdout, CFSTR("network configuration not open\n"));
868 return;
869 }
870
871 if (prefs != NULL) {
872 SCPreferencesPrivateRef prefsPrivate = (SCPreferencesPrivateRef)prefs;
873
874 if (prefsPrivate->prefs != NULL) {
875 int fd;
876 static int n_snapshot = 0;
877 char *path;
878 CFDataRef xmlData;
879
880 asprintf(&path, "/tmp/prefs_snapshot_%d", n_snapshot++);
881 fd = open(path, O_WRONLY|O_CREAT|O_TRUNC, 0644);
882 free(path);
883
884 xmlData = CFPropertyListCreateXMLData(NULL, prefsPrivate->prefs);
885 if (xmlData != NULL) {
886 (void) write(fd, CFDataGetBytePtr(xmlData), CFDataGetLength(xmlData));
887 CFRelease(xmlData);
888 } else {
889 SCLog(TRUE, LOG_ERR, CFSTR("CFPropertyListCreateXMLData() failed"));
890 }
891
892 (void) close(fd);
893 } else {
894 SCPrint(TRUE, stdout, CFSTR("prefs have not been accessed\n"));
895 }
896 }
897
898 return;
899 }