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