macos prefpane fat binary arch selection correction
[openafs.git] / src / platform / DARWIN / afssettings.m
1 /*
2  * Copyright (c) 2003, 2006 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 #import <Foundation/Foundation.h>
24 #import <stdio.h>
25 #import <err.h>
26 #import <sys/types.h>
27 #import <sys/mount.h>
28 #import <sys/sysctl.h>
29 #import <afs/sysctl.h>
30
31 enum Type {
32     TypeNode = 0,
33     TypeNum,
34     TypeStr
35 };
36
37 typedef struct _setting {
38     NSString *key;
39     int selector;
40     enum Type type;
41     struct _setting *children;
42 } Setting;
43
44 Setting s_darwin_all[] = {
45     {@"RealModes", AFS_SC_DARWIN_ALL_REALMODES, TypeNum, NULL},
46     {NULL, 0, 0, NULL}
47 };
48 Setting s_darwin[] = {
49     {@"All", AFS_SC_DARWIN_ALL, TypeNode, s_darwin_all},
50     {@"Darwin12", AFS_SC_DARWIN_12, TypeNode, NULL},
51     {@"Darwin13", AFS_SC_DARWIN_13, TypeNode, NULL},
52     {@"Darwin14", AFS_SC_DARWIN_14, TypeNode, NULL},
53     {@"Darwin60", AFS_SC_DARWIN_60, TypeNode, NULL},
54     {@"Darwin70", AFS_SC_DARWIN_70, TypeNode, NULL},
55     {@"Darwin80", AFS_SC_DARWIN_80, TypeNode, NULL},
56     {@"Darwin90", AFS_SC_DARWIN_90, TypeNode, NULL},
57     {NULL, 0, 0, NULL}
58 };
59 Setting s_first[] = {
60     {@"All", AFS_SC_ALL, TypeNode, NULL},
61     {@"Darwin", AFS_SC_DARWIN, TypeNode, s_darwin},
62     {NULL, 0, 0, NULL}
63 };
64 Setting s_top = {NULL, -1, TypeNode, s_first};
65
66 int oid[CTL_MAXNAME] = {CTL_VFS};
67 NSString *path = @"/var/db/openafs/etc/config/settings.plist";
68
69 char *oidString(int *oid, int len);
70 void init(void);
71 void walk(id obj, Setting *s, int level);
72
73 void
74 init(void)
75 {
76     int oidmax[] = {CTL_VFS, VFS_GENERIC, VFS_MAXTYPENUM};
77     int oidvfs[] = {CTL_VFS, VFS_GENERIC, VFS_CONF, 0};
78     int max;
79     struct vfsconf conf;
80     size_t len;
81     int i;
82
83     len = sizeof(max);
84     if(sysctl(oidmax, 3, &max, &len, NULL, 0) < 0)
85         err(1, "sysctl VFS_MAXTYPENUM");
86     for(i = max; --i >= 0; ) {
87         oidvfs[3] = i;
88         len = sizeof(conf);
89         if(sysctl(oidvfs, 4, &conf, &len, NULL, 0) < 0)
90             continue;
91         if(strcmp("afs", conf.vfc_name) == 0) {
92             s_top.selector = conf.vfc_typenum;
93             break;
94         }
95     }
96     if(s_top.selector < 0)
97         errx(1, "AFS is not loaded");
98 }
99
100 char *
101 oidString(int *oid, int len)
102 {
103     static char buf[256];
104     char *cp = buf;
105
106     for(;;) {
107         sprintf(cp, "%d", *oid++);
108         if(--len <= 0)
109             break;
110         cp += strlen(cp);
111         *cp++ = '.';
112     }
113     return buf;
114 }
115
116 void
117 walk(id obj, Setting *s, int level)
118 {
119     Setting *child;
120     id newobj;
121     int intval;
122     const char *cp;
123     int level1 = level + 1;
124
125     oid[level] = s->selector;
126     switch(s->type) {
127       case TypeNode:
128         for(child = s->children; child->key; child++) {
129             if(child->type == TypeNode && !child->children)
130                 continue;
131             newobj = [obj objectForKey: child->key];
132             if(newobj)
133                 walk(newobj, child, level1);
134         }
135         break;
136       case TypeNum:
137         intval = [obj intValue];
138         if(sysctl(oid, level1, NULL, NULL, &intval, sizeof(intval)) < 0)
139             err(1, "sysctl %s => %d", oidString(oid, level1), intval);
140         break;
141       case TypeStr:
142         cp = [obj UTF8String];
143         if(sysctl(oid, level1, NULL, NULL, (void *)cp, strlen(cp)) < 0)
144             err(1, "sysctl %s => %s", oidString(oid, level1), cp);
145         break;
146     }
147 }
148
149 int
150 main(int argc, char **argv)
151 {
152     NSData *plistData;
153     id plist;
154     NSString *error;
155     NSPropertyListFormat format;
156     NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];
157
158     init();
159     plistData = [NSData dataWithContentsOfFile: path];
160     if(plistData) {
161         plist = [NSPropertyListSerialization propertyListFromData: plistData
162           mutabilityOption: NSPropertyListImmutable
163           format: &format
164           errorDescription: &error
165         ];
166         if(plist)
167             walk(plist, &s_top, 1);
168         else
169             errx(1, "%s: %s", [path UTF8String], [error UTF8String]);
170     }
171
172     [pool release];
173     return 0;
174 }