Autogen update
[nfs-utils.git] / support / export / xtab.c
1 /*
2  * support/export/xtab.c
3  *
4  * Interface to the xtab file.
5  *
6  * Copyright (C) 1995, 1996 Olaf Kirch <okir@monad.swb.de>
7  */
8
9 #ifdef HAVE_CONFIG_H
10 #include <config.h>
11 #endif
12
13 #include <sys/fcntl.h>
14 #include <unistd.h>
15 #include <stdlib.h>
16 #include <string.h>
17 #include "xmalloc.h"
18 #include "nfslib.h"
19 #include "exportfs.h"
20 #include "xio.h"
21 #include "xlog.h"
22
23 static void cond_rename(char *newfile, char *oldfile);
24
25 static int
26 xtab_read(char *xtab, int is_export)
27 {
28     /* is_export == 0  => reading /proc/fs/nfs/exports - we know these things are exported to kernel
29      * is_export == 1  => reading /var/lib/nfs/etab - these things are allowed to be exported
30      * is_export == 2  => reading /var/lib/nfs/xtab - these things might be known to kernel
31      */
32         struct exportent        *xp;
33         nfs_export              *exp;
34         int                     lockid;
35
36         if ((lockid = xflock(xtab, "r")) < 0)
37                 return 0;
38         setexportent(xtab, "r");
39         while ((xp = getexportent(is_export==0, 0)) != NULL) {
40                 if (!(exp = export_lookup(xp->e_hostname, xp->e_path, is_export != 1)) &&
41                     !(exp = export_create(xp, is_export!=1))) {
42                         continue;
43                 }
44                 switch (is_export) {
45                 case 0:
46                         exp->m_exported = 1;
47                         break;
48                 case 1:
49                         exp->m_xtabent = 1;
50                         exp->m_mayexport = 1;
51                         break;
52                 case 2:
53                         exp->m_exported = -1;/* may be exported */
54                         break;
55                 }
56         }
57         endexportent();
58         xfunlock(lockid);
59
60         return 0;
61 }
62
63 int
64 xtab_mount_read(void)
65 {
66         int fd;
67         if ((fd=open(_PATH_PROC_EXPORTS, O_RDONLY))>=0) {
68                 close(fd);
69                 return xtab_read(_PATH_PROC_EXPORTS, 0);
70         } else if ((fd=open(_PATH_PROC_EXPORTS_ALT, O_RDONLY) >= 0)) {
71                 close(fd);
72                 return xtab_read(_PATH_PROC_EXPORTS_ALT, 0);
73         } else
74                 return xtab_read(_PATH_XTAB, 2);
75 }
76
77 int
78 xtab_export_read(void)
79 {
80         return xtab_read(_PATH_ETAB, 1);
81 }
82
83 static int
84 xtab_write(char *xtab, char *xtabtmp, int is_export)
85 {
86         struct exportent        xe;
87         nfs_export              *exp;
88         int                     lockid, i;
89
90         if ((lockid = xflock(xtab, "w")) < 0) {
91                 xlog(L_ERROR, "can't lock %s for writing", xtab);
92                 return 0;
93         }
94         setexportent(xtabtmp, "w");
95
96         for (i = 0; i < MCL_MAXTYPES; i++) {
97                 for (exp = exportlist[i]; exp; exp = exp->m_next) {
98                         if (is_export && !exp->m_xtabent)
99                                 continue;
100                         if (!is_export && ! exp->m_exported)
101                                 continue;
102
103                         /* write out the export entry using the FQDN */
104                         xe = exp->m_export;
105                         strncpy(xe.e_hostname,
106                                 exp->m_client->m_hostname,
107                                 sizeof (xe.e_hostname) - 1);
108                         xe.e_hostname[sizeof (xe.e_hostname) - 1] = '\0';
109                         putexportent(&xe);
110                 }
111         }
112         endexportent();
113
114         cond_rename(xtabtmp, xtab);
115
116         xfunlock(lockid);
117
118         return 1;
119 }
120
121 int
122 xtab_export_write()
123 {
124         return xtab_write(_PATH_ETAB, _PATH_ETABTMP, 1);
125 }
126
127 int
128 xtab_mount_write()
129 {
130         return xtab_write(_PATH_XTAB, _PATH_XTABTMP, 0);
131 }
132
133 void
134 xtab_append(nfs_export *exp)
135 {
136         struct exportent xe;
137         int             lockid;
138
139         if ((lockid = xflock(_PATH_XTAB, "w")) < 0)
140                 return;
141         setexportent(_PATH_XTAB, "a");
142         xe = exp->m_export;
143         strncpy(xe.e_hostname, exp->m_client->m_hostname,
144                sizeof (xe.e_hostname) - 1);
145         xe.e_hostname[sizeof (xe.e_hostname) - 1] = '\0';
146         putexportent(&xe);
147         endexportent();
148         xfunlock(lockid);
149         exp->m_xtabent = 1;
150 }
151
152 /*
153  * rename newfile onto oldfile unless
154  * they are identical
155  */
156 static void cond_rename(char *newfile, char *oldfile)
157 {
158         int nfd, ofd;
159         char nbuf[4096], obuf[4096];
160         int ncnt, ocnt;
161
162         nfd = open(newfile, 0);
163         if (nfd < 0)
164                 return;
165         ofd = open(oldfile, 0);
166         if (ofd < 0) {
167                 close(nfd);
168                 rename(newfile, oldfile);
169                 return;
170         }
171
172         do {
173                 ncnt = read(nfd, nbuf, sizeof(nbuf));
174                 if (ncnt < 0)
175                         break;
176                 ocnt = read(ofd, obuf, sizeof(obuf));
177                 if (ocnt < 0)
178                         break;
179                 if (ncnt != ocnt)
180                         break;
181                 if (ncnt == 0) {
182                         close(nfd);
183                         close(ofd);
184                         unlink(newfile);
185                         return;
186                 }
187         } while (memcmp(obuf, nbuf, ncnt) == 0);
188
189         /* some mis-match */
190         close(nfd);
191         close(ofd);
192         rename(newfile, oldfile);
193         return;
194 }