ubik-clone-support-20010212
[openafs.git] / src / auth / writeconfig.c
1 /*
2  * Copyright 2000, International Business Machines Corporation and others.
3  * All Rights Reserved.
4  * 
5  * This software has been released under the terms of the IBM Public
6  * License.  For details, see the LICENSE file in the top-level source
7  * directory or online at http://www.openafs.org/dl/license10.html
8  */
9
10 #include <afs/param.h>
11 #include <afs/pthread_glock.h>
12 #include <afs/afsutil.h>
13 #include <sys/types.h>
14 #ifdef AFS_SUN5_ENV 
15 #include <fcntl.h>
16 #endif
17 #ifdef AFS_NT40_ENV
18 #include <winsock2.h>
19 #include <fcntl.h>
20 #include <io.h>
21 #else
22 #include <sys/file.h>
23 #include <sys/socket.h>
24 #include <netinet/in.h>
25 #include <netdb.h>
26 #endif
27 #include <stdio.h>
28 #include <errno.h>
29 #include "cellconfig.h"
30 #include "keys.h"
31
32 /* write ThisCell and CellServDB containing exactly one cell's info specified
33     by acellInfo parm.   Useful only on the server (which describes only one cell).
34 */
35
36 static VerifyEntries(aci)
37 register struct afsconf_cell *aci; {
38     register int i;
39     register struct hostent *th;
40     
41     for(i=0;i<aci->numServers;i++) {
42         if (aci->hostAddr[i].sin_addr.s_addr == 0) {
43             /* no address spec'd */
44             if (*(aci->hostName[i]) != 0) {
45                 th = gethostbyname(aci->hostName[i]);
46                 if (!th) {
47                         printf("Host %s not found in host database...\n", aci->hostName[i]);
48                         return AFSCONF_FAILURE;
49                 }
50                 bcopy(th->h_addr, &aci->hostAddr[i].sin_addr, sizeof(afs_int32));
51             }
52             /* otherwise we're deleting this entry */
53         }
54         else {
55             /* address spec'd, perhaps no name known */
56             if (aci->hostName[i][0] != 0) continue; /* name known too */
57             /* figure out name, if possible */
58             th = gethostbyaddr((char *)(&aci->hostAddr[i].sin_addr), 4, AF_INET);
59             if (!th) {
60                 strcpy(aci->hostName[i], "UNKNOWNHOST");
61             }
62             else {
63                 strcpy(aci->hostName[i], th->h_name);
64             }
65         }
66     }
67     return 0;
68 }
69
70 /* Changed the interface to accept the afsconf_dir datastructure.
71    This is a handle to the internal cache that is maintained by the bosserver.
72    */
73    
74 afsconf_SetCellInfo(adir, apath, acellInfo)
75 struct afsconf_dir *adir;
76 char *apath;
77 struct afsconf_cell *acellInfo; 
78 {
79     afs_int32 code;
80
81     code = afsconf_SetExtendedCellInfo(adir, apath, acellInfo, (char *)0);
82     return code;
83 }
84    
85 afsconf_SetExtendedCellInfo(adir, apath, acellInfo, clones)
86     struct afsconf_dir *adir;
87     char *apath;
88     struct afsconf_cell *acellInfo; 
89     char clones[];
90 {
91     register afs_int32 code;
92     register int fd;
93     char tbuffer[1024];
94     register FILE *tf;
95     register afs_int32 i;
96     
97     LOCK_GLOBAL_MUTEX
98     /* write ThisCell file */
99     strcompose(tbuffer, 1024, apath, "/", AFSDIR_THISCELL_FILE, NULL);
100
101     fd = open(tbuffer, O_RDWR | O_CREAT | O_TRUNC, 0666);
102     if (fd < 0) {
103         UNLOCK_GLOBAL_MUTEX
104         return errno;
105     }
106     i = strlen(acellInfo->name);
107     code = write(fd, acellInfo->name, i);
108     if (code != i) {
109         UNLOCK_GLOBAL_MUTEX
110         return AFSCONF_FAILURE;
111     }
112     if (close(fd) < 0) {
113         UNLOCK_GLOBAL_MUTEX
114         return errno;
115     }
116     
117     /* make sure we have both name and address for each host, looking up other
118         if need be */
119     code = VerifyEntries(acellInfo);
120     if (code) {
121         UNLOCK_GLOBAL_MUTEX
122         return code;
123     }
124
125     /* write CellServDB */
126     strcompose(tbuffer, 1024, apath, "/", AFSDIR_CELLSERVDB_FILE, NULL);
127     tf = fopen(tbuffer, "w");
128     if (!tf) {
129         UNLOCK_GLOBAL_MUTEX
130         return AFSCONF_NOTFOUND;
131     }
132     fprintf(tf, ">%s    #Cell name\n", acellInfo->name);
133     for(i=0;i < acellInfo->numServers; i++) {
134         code = acellInfo->hostAddr[i].sin_addr.s_addr;  /* net order */
135         if (code == 0) continue;    /* delete request */
136         code = ntohl(code);     /* convert to host order */
137         if (clones && clones[i])
138             fprintf(tf, "[%d.%d.%d.%d]  #%s\n", (code>>24) & 0xff, (code>>16)&0xff, (code>>8)&0xff, code&0xff, acellInfo->hostName[i]);
139         else
140            fprintf(tf, "%d.%d.%d.%d    #%s\n", (code>>24) & 0xff, (code>>16)&0xff, (code>>8)&0xff, code&0xff, acellInfo->hostName[i]);
141     }
142     if (ferror(tf)) {
143         fclose(tf);
144         UNLOCK_GLOBAL_MUTEX
145         return AFSCONF_FAILURE;
146     }
147     code = fclose(tf);
148
149     /* Reset the timestamp in the cache, so that
150        the CellServDB is read into the cache next time.
151        Resolves the lost update problem due to an inconsistent cache
152        */
153     if (adir) adir->timeRead = 0;
154
155     UNLOCK_GLOBAL_MUTEX
156     if (code == EOF) return AFSCONF_FAILURE;
157     return 0;
158 }