Initial IBM OpenAFS 1.0 tree
[openafs.git] / src / WINNT / afsd / cm_config.c
1 /* 
2  * Copyright (C) 1998, 1989 Transarc Corporation - All rights reserved
3  *
4  * (C) COPYRIGHT IBM CORPORATION 1987, 1988
5  * LICENSED MATERIALS - PROPERTY OF IBM
6  *
7  *
8  */
9
10 #include <afs/param.h>
11 #include <afs/stds.h>
12
13 #include <windows.h>
14 #include <winsock2.h>
15 #include <stdlib.h>
16 #include <stdio.h>
17 #include <string.h>
18
19 #include "cm_config.h"
20
21 char AFSConfigKeyName[] =
22         "SYSTEM\\CurrentControlSet\\Services\\TransarcAFSDaemon\\Parameters";
23
24 static long cm_ParsePair(char *lineBufferp, char *leftp, char *rightp)
25 {
26         char *tp;
27         char tc;
28         int sawEquals;
29         int sawBracket;
30         
31         sawEquals = 0;
32         sawBracket = 0;
33         for(tp = lineBufferp; *tp; tp++) {
34                 tc = *tp;
35
36                 if (sawBracket) {
37                         if (tc == ']')
38                                 sawBracket = 0;
39                         continue;
40                 }
41
42                 /* comment or line end */
43                 if (tc == '#' || tc == '\r' || tc == '\n') break;
44
45                 /* square bracket comment -- look for closing delim
46                 if (tc == '[') {sawBracket = 1; continue;}
47
48                 /* space or tab */
49                 if (tc == ' ' || tc == '\t') continue;
50
51                 if (tc == '=') {
52                         sawEquals = 1;
53                         continue;
54                 }
55                 
56                 /* now we have a real character, put it in the appropriate bucket */
57                 if (sawEquals == 0) {
58                         *leftp++ = tc;
59                 }
60                 else {
61                         *rightp++ = tc;
62                 }
63         }
64
65         /* null terminate the strings */
66         *leftp = 0;
67         *rightp = 0;
68
69         return 0;       /* and return success */
70 }
71
72 /* search for a cell, and either return an error code if we don't find it,
73  * or return 0 if we do, in which case we also fill in the addresses in
74  * the cellp field.
75  *
76  * new feature:  we can handle abbreviations and are insensitive to case.
77  * If the caller wants the "real" cell name, it puts a non-null pointer in
78  * newCellNamep.  Anomaly:  if cellNamep is ambiguous, we may modify
79  * newCellNamep but return an error code.
80  */
81 long cm_SearchCellFile(char *cellNamep, char *newCellNamep,
82         cm_configProc_t *procp, void *rockp)
83 {
84         char wdir[256];
85         int tlen;
86         FILE *tfilep, *bestp, *tempp;
87         char *tp;
88         char lineBuffer[256];
89         struct hostent *thp;
90         char *valuep;
91         struct sockaddr_in vlSockAddr;
92         int inRightCell;
93         int foundCell;
94         long code;
95         int tracking = 1, partial = 0;
96
97         foundCell = 0;
98
99         code = GetWindowsDirectory(wdir, sizeof(wdir));
100         if (code == 0 || code > sizeof(wdir)) return -1;
101         
102         /* add trailing backslash, if required */
103         tlen = strlen(wdir);
104         if (wdir[tlen-1] != '\\') strcat(wdir, "\\");
105
106         strcat(wdir, "afsdcell.ini");
107         
108         tfilep = fopen(wdir, "r");
109         if (!tfilep) return -2;
110         bestp = fopen(wdir, "r");
111         
112         /* have we seen the cell line for the guy we're looking for? */
113         inRightCell = 0;
114         while (1) {
115                 tp = fgets(lineBuffer, sizeof(lineBuffer), tfilep);
116                 if (tracking)
117                         (void) fgets(lineBuffer, sizeof(lineBuffer), bestp);
118                 if (tp == NULL) {
119                         if (feof(tfilep)) {
120                                 /* hit EOF */
121                                 if (partial) {
122                                         /*
123                                          * found partial match earlier;
124                                          * now go back to it
125                                          */
126                                         tempp = bestp;
127                                         bestp = tfilep;
128                                         tfilep = tempp;
129                                         inRightCell = 1;
130                                         partial = 0;
131                                         continue;
132                                 }
133                                 else {
134                                         fclose(tfilep);
135                                         fclose(bestp);
136                                         return (foundCell? 0 : -3);
137                                 }
138                         }
139                 }
140                 
141                 /* turn trailing cr or lf into null */
142                 tp = strchr(lineBuffer, '\r');
143                 if (tp) *tp = 0;
144                 tp = strchr(lineBuffer, '\n');
145                 if (tp) *tp = 0;
146                 
147                 /* skip blank lines */
148                 if (lineBuffer[0] == 0) continue;
149
150                 if (lineBuffer[0] == '>') {
151                         /* trim off at white space or '#' chars */
152                         tp = strchr(lineBuffer, ' ');
153                         if (tp) *tp = 0;
154                         tp = strchr(lineBuffer, '\t');
155                         if (tp) *tp = 0;
156                         tp = strchr(lineBuffer, '#');
157                         if (tp) *tp = 0;
158
159                         /* now see if this is the right cell */
160                         if (stricmp(lineBuffer+1, cellNamep) == 0) {
161                                 /* found the cell we're looking for */
162                                 if (newCellNamep)
163                                         strcpy(newCellNamep, lineBuffer+1);
164                                 inRightCell = 1;
165                                 tracking = 0;
166                         }
167                         else if (strnicmp(lineBuffer+1, cellNamep,
168                                           strlen(cellNamep)) == 0) {
169                                 /* partial match */
170                                 if (partial) {  /* ambiguous */
171                                         fclose(tfilep);
172                                         fclose(bestp);
173                                         return -5;
174                                 }
175                                 if (newCellNamep)
176                                         strcpy(newCellNamep, lineBuffer+1);
177                                 inRightCell = 0;
178                                 tracking = 0;
179                                 partial = 1;
180                         }
181                         else inRightCell = 0;
182                 }
183                 else {
184                         valuep = strchr(lineBuffer, '#');
185                         if (valuep == NULL) {
186                                 fclose(tfilep);
187                                 fclose(bestp);
188                                 return -4;
189                         }
190                         valuep++;       /* skip the "#" */
191                         valuep += strspn(valuep, "      "); /* skip SP & TAB */
192                         if (inRightCell) {
193                                 /* add the server to the VLDB list */
194                                 thp = gethostbyname(valuep);
195                                 if (thp) {
196                                         memcpy(&vlSockAddr.sin_addr.s_addr, thp->h_addr,
197                                                 sizeof(long));
198                                         vlSockAddr.sin_family = AF_INET;
199                                         /* sin_port supplied by connection code */
200                                         if (procp)
201                                                 (*procp)(rockp, &vlSockAddr, valuep);
202                                         foundCell = 1;
203                                 }
204                         }
205                 }       /* a vldb line */
206         }               /* while loop processing all lines */
207 }
208
209 /* look up the root cell's name in the Registry */
210 long cm_GetRootCellName(char *cellNamep)
211 {
212         DWORD code, dummyLen;
213         HKEY parmKey;
214
215         code = RegOpenKeyEx(HKEY_LOCAL_MACHINE, AFSConfigKeyName,
216                                 0, KEY_QUERY_VALUE, &parmKey);
217         if (code != ERROR_SUCCESS)
218                 return -1;
219
220         dummyLen = 256;
221         code = RegQueryValueEx(parmKey, "Cell", NULL, NULL,
222                                 cellNamep, &dummyLen);
223         RegCloseKey (parmKey);
224         if (code != ERROR_SUCCESS)
225                 return -1;
226
227         return 0;
228 }
229
230 cm_configFile_t *cm_CommonOpen(char *namep, char *rwp)
231 {
232         char wdir[256];
233         long code;
234         long tlen;
235         FILE *tfilep;
236
237         code = GetWindowsDirectory(wdir, sizeof(wdir));
238         if (code == 0 || code > sizeof(wdir)) return NULL;
239         
240         /* add trailing backslash, if required */
241         tlen = strlen(wdir);
242         if (wdir[tlen-1] != '\\') strcat(wdir, "\\");
243
244         strcat(wdir, namep);
245         
246         tfilep = fopen(wdir, rwp);
247
248         return ((cm_configFile_t *) tfilep);        
249 }
250
251 long cm_WriteConfigString(char *labelp, char *valuep)
252 {
253         DWORD code, dummyDisp;
254         HKEY parmKey;
255
256         code = RegCreateKeyEx(HKEY_LOCAL_MACHINE, AFSConfigKeyName,
257                                 0, "container", 0, KEY_SET_VALUE, NULL,
258                                 &parmKey, &dummyDisp);
259         if (code != ERROR_SUCCESS)
260                 return -1;
261
262         code = RegSetValueEx(parmKey, labelp, 0, REG_SZ,
263                              valuep, strlen(valuep) + 1);
264         RegCloseKey (parmKey);
265         if (code != ERROR_SUCCESS)
266                 return -1;
267
268         return 0;
269 }
270
271 long cm_WriteConfigInt(char *labelp, long value)
272 {
273         DWORD code, dummyDisp;
274         HKEY parmKey;
275
276         code = RegCreateKeyEx(HKEY_LOCAL_MACHINE, AFSConfigKeyName,
277                                 0, "container", 0, KEY_SET_VALUE, NULL,
278                                 &parmKey, &dummyDisp);
279         if (code != ERROR_SUCCESS)
280                 return -1;
281
282         code = RegSetValueEx(parmKey, labelp, 0, REG_DWORD,
283                              &value, sizeof(value));
284         RegCloseKey (parmKey);
285         if (code != ERROR_SUCCESS)
286                 return -1;
287
288         return 0;
289 }
290
291 cm_configFile_t *cm_OpenCellFile(void)
292 {
293         cm_configFile_t *cfp;
294
295         cfp = cm_CommonOpen("afsdcel2.ini", "w");
296         return cfp;
297 }
298
299 long cm_AppendPrunedCellList(cm_configFile_t *ofp, char *cellNamep)
300 {
301         cm_configFile_t *tfilep;        /* input file */
302         char *tp;
303         char lineBuffer[256];
304         char *valuep;
305         int inRightCell;
306         int foundCell;
307
308         tfilep = cm_CommonOpen("afsdcell.ini", "r");
309         if (!tfilep) return -1;
310
311         foundCell = 0;
312
313         /* have we seen the cell line for the guy we're looking for? */
314         inRightCell = 0;
315         while (1) {
316                 tp = fgets(lineBuffer, sizeof(lineBuffer), (FILE *)tfilep);
317                 if (tp == NULL) {
318                         if (feof((FILE *)tfilep)) {
319                                 /* hit EOF */
320                                 fclose((FILE *)tfilep);
321                                 return 0;
322                         }
323                 }
324                 
325                 /* turn trailing cr or lf into null */
326                 tp = strchr(lineBuffer, '\r');
327                 if (tp) *tp = 0;
328                 tp = strchr(lineBuffer, '\n');
329                 if (tp) *tp = 0;
330                 
331                 /* skip blank lines */
332                 if (lineBuffer[0] == 0) {
333                         fprintf((FILE *)ofp, "%s\n", lineBuffer);
334                         continue;
335                 }
336
337                 if (lineBuffer[0] == '>') {
338                         /* trim off at white space or '#' chars */
339                         tp = strchr(lineBuffer, ' ');
340                         if (tp) *tp = 0;
341                         tp = strchr(lineBuffer, '\t');
342                         if (tp) *tp = 0;
343                         tp = strchr(lineBuffer, '#');
344                         if (tp) *tp = 0;
345
346                         /* now see if this is the right cell */
347                         if (strcmp(lineBuffer+1, cellNamep) == 0) {
348                                 /* found the cell we're looking for */
349                                 inRightCell = 1;
350                         }
351                         else {
352                                 inRightCell = 0;
353                                 fprintf((FILE *)ofp, "%s\n", lineBuffer);
354                         }
355                 }
356                 else {
357                         valuep = strchr(lineBuffer, '#');
358                         if (valuep == NULL) return -2;
359                         valuep++;       /* skip the "#" */
360                         if (!inRightCell) {
361                                 fprintf((FILE *)ofp, "%s\n", lineBuffer);
362                         }
363                 }       /* a vldb line */
364         }               /* while loop processing all lines */
365 }
366
367 long cm_AppendNewCell(cm_configFile_t *filep, char *cellNamep)
368 {
369         fprintf((FILE *)filep, ">%s\n", cellNamep);
370         return 0;
371 }
372
373 long cm_AppendNewCellLine(cm_configFile_t *filep, char *linep)
374 {
375         fprintf((FILE *)filep, "%s\n", linep);
376         return 0;
377 }
378
379 extern long cm_CloseCellFile(cm_configFile_t *filep)
380 {
381         char wdir[256];
382         char sdir[256];
383         long code;
384         long closeCode;
385         int tlen;
386
387         closeCode = fclose((FILE *)filep);
388
389         code = GetWindowsDirectory(wdir, sizeof(wdir));
390         if (code == 0 || code > sizeof(wdir)) return -1;
391         
392         /* add trailing backslash, if required */
393         tlen = strlen(wdir);
394         if (wdir[tlen-1] != '\\') strcat(wdir, "\\");
395         strcpy(sdir, wdir);
396
397         if (closeCode != 0) {
398                 /* something went wrong, preserve original database */
399                 strcat(wdir, "afsdcel2.ini");
400                 unlink(wdir);
401                 return closeCode;
402         }
403
404         strcat(wdir, "afsdcell.ini");
405         strcat(sdir, "afsdcel2.ini");   /* new file */
406         
407         unlink(wdir);                   /* delete old file */
408         
409         code = rename(sdir, wdir);      /* do the rename */
410         
411         if (code) code = errno;
412         
413         return code;
414 }