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