windows-64-bit-type-safety-20051105
[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 <afsconfig.h>
11 #include <afs/param.h>
12
13 RCSID
14     ("$Header$");
15
16 #include <afs/pthread_glock.h>
17 #include <afs/afsutil.h>
18 #include <sys/types.h>
19 #ifdef AFS_NT40_ENV
20 #include <winsock2.h>
21 #include <fcntl.h>
22 #include <io.h>
23 #else
24 #include <sys/file.h>
25 #include <sys/socket.h>
26 #include <netinet/in.h>
27 #include <netdb.h>
28 #endif
29 #include <stdio.h>
30 #include <errno.h>
31 #ifdef HAVE_STRING_H
32 #include <string.h>
33 #else
34 #ifdef HAVE_STRINGS_H
35 #include <strings.h>
36 #endif
37 #endif
38 #ifdef HAVE_FCNTL_H
39 #include <fcntl.h>
40 #endif
41 #ifdef HAVE_UNISTD_H
42 #include <unistd.h>
43 #endif
44 #include "cellconfig.h"
45 #include "keys.h"
46
47 /* write ThisCell and CellServDB containing exactly one cell's info specified
48     by acellInfo parm.   Useful only on the server (which describes only one cell).
49 */
50
51 static int
52 VerifyEntries(aci)
53      register struct afsconf_cell *aci;
54 {
55     register int i;
56     register struct hostent *th;
57
58     for (i = 0; i < aci->numServers; i++) {
59         if (aci->hostAddr[i].sin_addr.s_addr == 0) {
60             /* no address spec'd */
61             if (*(aci->hostName[i]) != 0) {
62                 th = gethostbyname(aci->hostName[i]);
63                 if (!th) {
64                     printf("Host %s not found in host database...\n",
65                            aci->hostName[i]);
66                     return AFSCONF_FAILURE;
67                 }
68                 memcpy(&aci->hostAddr[i].sin_addr, th->h_addr,
69                        sizeof(afs_int32));
70             }
71             /* otherwise we're deleting this entry */
72         } else {
73             /* address spec'd, perhaps no name known */
74             if (aci->hostName[i][0] != 0)
75                 continue;       /* name known too */
76             /* figure out name, if possible */
77             th = gethostbyaddr((char *)(&aci->hostAddr[i].sin_addr), 4,
78                                AF_INET);
79             if (!th) {
80                 strcpy(aci->hostName[i], "UNKNOWNHOST");
81             } else {
82                 strcpy(aci->hostName[i], th->h_name);
83             }
84         }
85     }
86     return 0;
87 }
88
89 /* Changed the interface to accept the afsconf_dir datastructure.
90    This is a handle to the internal cache that is maintained by the bosserver.
91    */
92
93 int
94 afsconf_SetCellInfo(adir, apath, acellInfo)
95      struct afsconf_dir *adir;
96      char *apath;
97      struct afsconf_cell *acellInfo;
98 {
99     afs_int32 code;
100
101     code = afsconf_SetExtendedCellInfo(adir, apath, acellInfo, NULL);
102     return code;
103 }
104
105 int
106 afsconf_SetExtendedCellInfo(adir, apath, acellInfo, clones)
107      struct afsconf_dir *adir;
108      char *apath;
109      struct afsconf_cell *acellInfo;
110      char clones[];
111 {
112     register afs_int32 code;
113     register int fd;
114     char tbuffer[1024];
115     register FILE *tf;
116     register afs_int32 i;
117
118     LOCK_GLOBAL_MUTEX;
119     /* write ThisCell file */
120     strcompose(tbuffer, 1024, apath, "/", AFSDIR_THISCELL_FILE, NULL);
121
122     fd = open(tbuffer, O_RDWR | O_CREAT | O_TRUNC, 0666);
123     if (fd < 0) {
124         UNLOCK_GLOBAL_MUTEX;
125         return errno;
126     }
127     i = (int)strlen(acellInfo->name);
128     code = write(fd, acellInfo->name, i);
129     if (code != i) {
130         UNLOCK_GLOBAL_MUTEX;
131         return AFSCONF_FAILURE;
132     }
133     if (close(fd) < 0) {
134         UNLOCK_GLOBAL_MUTEX;
135         return errno;
136     }
137
138     /* make sure we have both name and address for each host, looking up other
139      * if need be */
140     code = VerifyEntries(acellInfo);
141     if (code) {
142         UNLOCK_GLOBAL_MUTEX;
143         return code;
144     }
145
146     /* write CellServDB */
147     strcompose(tbuffer, 1024, apath, "/", AFSDIR_CELLSERVDB_FILE, NULL);
148     tf = fopen(tbuffer, "w");
149     if (!tf) {
150         UNLOCK_GLOBAL_MUTEX;
151         return AFSCONF_NOTFOUND;
152     }
153     fprintf(tf, ">%s    #Cell name\n", acellInfo->name);
154     for (i = 0; i < acellInfo->numServers; i++) {
155         code = acellInfo->hostAddr[i].sin_addr.s_addr;  /* net order */
156         if (code == 0)
157             continue;           /* delete request */
158         code = ntohl(code);     /* convert to host order */
159         if (clones && clones[i])
160             fprintf(tf, "[%d.%d.%d.%d]  #%s\n", (code >> 24) & 0xff,
161                     (code >> 16) & 0xff, (code >> 8) & 0xff, code & 0xff,
162                     acellInfo->hostName[i]);
163         else
164             fprintf(tf, "%d.%d.%d.%d    #%s\n", (code >> 24) & 0xff,
165                     (code >> 16) & 0xff, (code >> 8) & 0xff, code & 0xff,
166                     acellInfo->hostName[i]);
167     }
168     if (ferror(tf)) {
169         fclose(tf);
170         UNLOCK_GLOBAL_MUTEX;
171         return AFSCONF_FAILURE;
172     }
173     code = fclose(tf);
174
175     /* Reset the timestamp in the cache, so that
176      * the CellServDB is read into the cache next time.
177      * Resolves the lost update problem due to an inconsistent cache
178      */
179     if (adir)
180         adir->timeRead = 0;
181
182     UNLOCK_GLOBAL_MUTEX;
183     if (code == EOF)
184         return AFSCONF_FAILURE;
185     return 0;
186 }