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