c1e647a9a80f8ce54524abf7045525e561e1cec9
[openafs.git] / src / packaging / MacOS / afssettings.m
1 /*
2  * Copyright (c) 2003 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     {NULL, 0, 0, NULL}
56 };
57 Setting s_first[] = {
58     {@"All", AFS_SC_ALL, TypeNode, NULL},
59     {@"Darwin", AFS_SC_DARWIN, TypeNode, s_darwin},
60     {NULL, 0, 0, NULL}
61 };
62 Setting s_top = {NULL, -1, TypeNode, s_first};
63
64 int oid[CTL_MAXNAME] = {CTL_VFS};
65 NSString *path = @"/var/db/openafs/etc/config/settings.plist";
66
67 char *oidString(int *oid, int len);
68 void init(void);
69 void walk(id obj, Setting *s, int level);
70
71 void
72 init(void)
73 {
74     int oidmax[] = {CTL_VFS, VFS_GENERIC, VFS_MAXTYPENUM};
75     int oidvfs[] = {CTL_VFS, VFS_GENERIC, VFS_CONF, 0};
76     int max;
77     struct vfsconf conf;
78     size_t len;
79     int i;
80
81     len = sizeof(max);
82     if(sysctl(oidmax, 3, &max, &len, NULL, NULL) < 0)
83         err(1, "sysctl VFS_MAXTYPENUM");
84     for(i = max; --i >= 0; ) {
85         oidvfs[3] = i;
86         len = sizeof(conf);
87         if(sysctl(oidvfs, 4, &conf, &len, NULL, NULL) < 0)
88             continue;
89         if(strcmp("afs", conf.vfc_name) == 0) {
90             s_top.selector = conf.vfc_typenum;
91             break;
92         }
93     }
94     if(s_top.selector < 0)
95         errx(1, "AFS is not loaded");
96 }
97
98 char *
99 oidString(int *oid, int len)
100 {
101     static char buf[256];
102     char *cp = buf;
103
104     for(;;) {
105         sprintf(cp, "%d", *oid++);
106         if(--len <= 0)
107             break;
108         cp += strlen(cp);
109         *cp++ = '.';
110     }
111     return buf;
112 }
113
114 void
115 walk(id obj, Setting *s, int level)
116 {
117     Setting *child;
118     id newobj;
119     int intval;
120     const char *cp;
121     int level1 = level + 1;
122
123     oid[level] = s->selector;
124     switch(s->type) {
125       case TypeNode:
126         for(child = s->children; child->key; child++) {
127             if(child->type == TypeNode && !child->children)
128                 continue;
129             newobj = [obj objectForKey: child->key];
130             if(newobj)
131                 walk(newobj, child, level1);
132         }
133         break;
134       case TypeNum:
135         intval = [obj intValue];
136         if(sysctl(oid, level1, NULL, NULL, &intval, sizeof(intval)) < 0)
137             err(1, "sysctl %s => %d", oidString(oid, level1), intval);
138         break;
139       case TypeStr:
140         cp = [obj UTF8String];
141         if(sysctl(oid, level1, NULL, NULL, (void *)cp, strlen(cp)) < 0)
142             err(1, "sysctl %s => %s", oidString(oid, level1), cp);
143         break;
144     }
145 }
146
147 main()
148 {
149     NSData *plistData;
150     id plist;
151     NSString *error;
152     NSPropertyListFormat format;
153     NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];
154
155     init();
156     plistData = [NSData dataWithContentsOfFile: path];
157     if(plistData) {
158         plist = [NSPropertyListSerialization propertyListFromData: plistData
159           mutabilityOption: NSPropertyListImmutable
160           format: &format
161           errorDescription: &error
162         ];
163         if(plist)
164             walk(plist, &s_top, 1);
165         else
166             errx(1, "%s: %s", [path UTF8String], [error UTF8String]);
167     }
168
169     [pool release];
170     return 0;
171 }