IRIX: Move src/sgistuff to platform/IRIX
[openafs.git] / src / platform / DARWIN / afssettings.m
1 /*
2  * Copyright (c) 1992, 1993, 1994
3  *      The Regents of the University of California.  All rights reserved.
4  *
5  * This code is derived from software donated to Berkeley by
6  * Jan-Simon Pendry.
7  *
8  * Redistribution and use in source and binary forms, with or without
9  * modification, are permitted provided that the following conditions
10  * are met:
11  * 1. Redistributions of source code must retain the above copyright
12  *    notice, this list of conditions and the following disclaimer.
13  * 2. Redistributions in binary form must reproduce the above copyright
14  *    notice, this list of conditions and the following disclaimer in the
15  *    documentation and/or other materials provided with the distribution.
16  * 3. All advertising materials mentioning features or use of this software
17  *    must display the following acknowledgement:
18  *      This product includes software developed by the University of
19  *      California, Berkeley and its contributors.
20  * 4. Neither the name of the University nor the names of its contributors
21  *    may be used to endorse or promote products derived from this software
22  *    without specific prior written permission.
23  *
24  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
25  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
26  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
27  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
28  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
29  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
30  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
31  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
32  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
33  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
34  * SUCH DAMAGE.
35  */
36
37 #include <stdio.h>
38 #include <sys/types.h>
39 #include <sys/mount.h>
40 #include <sys/sysctl.h>
41 #include <ctype.h>
42
43 #include <afs/sysctl.h>
44
45 #include <CoreFoundation/CFString.h>
46 #include <Foundation/Foundation.h>
47
48 enum Type {
49     Node = 0,
50     LeafNum,
51     LeafStr
52 };
53
54 typedef struct oidsetting {
55     NSString *key;
56     int selector;
57     enum Type type;
58     struct oidsetting *children;
59 } Setting;
60
61 int
62 mygetvfsbyname(const char *fsname, struct vfsconf *vfcp, Setting *s, int myoid[])
63 {
64     int maxtypenum, cnt;
65     size_t buflen;
66     
67     myoid[0] = CTL_VFS;
68     myoid[1] = VFS_GENERIC;
69     myoid[2] = VFS_MAXTYPENUM;
70     buflen = 4;
71     if (sysctl(myoid, 3, &maxtypenum, &buflen, (void *)0, (size_t)0) < 0)
72     {
73         return (-1);
74     }
75     myoid[2] = VFS_CONF;
76     buflen = sizeof * vfcp;
77     for (cnt = 0; cnt < maxtypenum; cnt++)
78     {
79         myoid[3] = cnt;
80         if (sysctl(myoid, 4, vfcp, &buflen, (void *)0, (size_t)0) < 0)
81         {
82             if (errno != EOPNOTSUPP && errno != ENOENT && errno != ENOTSUP)
83             {
84                 return (-1);
85             }
86             continue;
87         }
88         if (!strcmp(fsname, vfcp->vfc_name))
89         {
90             s->selector = vfcp->vfc_typenum;
91             return (0);
92         }
93     }
94     errno = ENOENT;
95     return (-1);
96 }
97
98 void
99 oiderror(int *oid, int oidlen, enum Type type, void *obj)
100 {
101     fprintf(stderr, "sysctl ");
102     while (1) {
103         fprintf(stderr, "%d", *oid++);
104         if(--oidlen <= 0)
105             break;
106         fprintf(stderr, "%c", '.');
107     }
108     fprintf(stderr, " => ");
109     if (type == LeafNum)
110         fprintf(stderr, "%d\n", *(int *)obj);
111     else
112         fprintf(stderr, "%s\n", (char *)obj);
113
114     return;
115 }
116
117 void
118 recurse(id obj, Setting *s, int level, int myoid[])
119 {
120     Setting *child;
121     id newobj;
122     int intval;
123     const char *cp;
124
125     myoid[level] = s->selector;
126     switch(s->type) {
127     case Node:
128         for(child = s->children; child->key; child++) {
129             if(child->type == Node && !child->children)
130                 continue;
131             newobj = [obj objectForKey: child->key];
132             if(newobj)
133               recurse(newobj, child, level+1, myoid);
134         }
135         break;
136     case LeafNum:
137         intval = [obj intValue];
138         if(sysctl(myoid, level+1, NULL, NULL, &intval, sizeof(intval)) < 0)
139             oiderror(myoid, level+1, s->type, &intval);
140         break;
141     case LeafStr:
142         cp = [obj UTF8String];
143         if(sysctl(myoid, level+1, NULL, NULL, (void *)cp, strlen(cp)) < 0)
144             oiderror(myoid, level+1, s->type, &cp);
145         break;
146     }
147 }
148
149 Setting sysctl_darwin_all[] = {
150     {@"RealModes", AFS_SC_DARWIN_ALL_REALMODES, LeafNum, NULL},
151     {@"FSEvents", AFS_SC_DARWIN_ALL_FSEVENTS, LeafNum, NULL},
152     {@"Bulkstat", AFS_SC_DARWIN_ALL_BULKSTAT, LeafNum, NULL},
153     {NULL, 0, 0, NULL}
154 };
155 Setting sysctl_darwin[] = {
156     {@"All", AFS_SC_DARWIN_ALL, Node, sysctl_darwin_all},
157     {@"Darwin60", AFS_SC_DARWIN_60, Node, NULL},
158     {@"Darwin70", AFS_SC_DARWIN_70, Node, NULL},
159     {@"Darwin80", AFS_SC_DARWIN_80, Node, NULL},
160     {@"Darwin90", AFS_SC_DARWIN_90, Node, NULL},
161     {@"Darwin100", AFS_SC_DARWIN_100, Node, NULL},
162     {NULL, 0, 0, NULL}
163 };
164 Setting sysctl_first[] = {
165     {@"All", AFS_SC_ALL, Node, NULL},
166     {@"Darwin", AFS_SC_DARWIN, Node, sysctl_darwin},
167     {NULL, 0, 0, NULL}
168 };
169 Setting sysctl_top = {NULL, -1, Node, sysctl_first};
170
171 int
172 main(int argc, char **argv)
173 {
174     struct vfsconf vfcp;
175     NSData *plistData;
176     id plist;
177     NSString *error;
178     NSAutoreleasePool * nspool = [[NSAutoreleasePool alloc] init];
179     NSString *plistpath = @"/var/db/openafs/etc/config/settings.plist";
180     int oid[CTL_MAXNAME] = {CTL_VFS};
181
182     if (mygetvfsbyname("afs", &vfcp, &sysctl_top, oid) != 0)
183         exit(-1);
184     plistData = [NSData dataWithContentsOfFile: plistpath];
185     if(plistData) {
186         plist = [NSPropertyListSerialization propertyListFromData: plistData
187                                              mutabilityOption: NSPropertyListImmutable
188                                              format: NULL
189                                              errorDescription: &error
190             ];
191         if (!plist) {
192             NSLog(@"Error reading plist from file '%s', error = '%s'", [plistpath UTF8String], [error UTF8String]);
193             [nspool release];
194             return -1;
195         }
196
197         recurse(plist, &sysctl_top, 1, oid);
198     }
199     [nspool release];
200     return 0;
201 }