Initial revision
[nfs-utils.git] / utils / mountd / rmtab.c
1 /*
2  * utils/mountd/rmtab.c
3  *
4  * Manage the rmtab file for mountd.
5  *
6  * Copyright (C) 1995, 1996 Olaf Kirch <okir@monad.swb.de>
7  */
8
9 #include "config.h"
10
11 #include <sys/stat.h>
12 #include <netinet/in.h>
13 #include <arpa/inet.h>
14 #include <netdb.h>
15 #include "xmalloc.h"
16 #include "misc.h"
17 #include "exportfs.h"
18 #include "xio.h"
19 #include "mountd.h"
20
21 void
22 mountlist_add(nfs_export *exp, const char *path)
23 {
24         struct rmtabent xe;
25         struct rmtabent *rep;
26         int             lockid;
27
28         if ((lockid = xflock(_PATH_RMTAB, "a")) < 0)
29                 return;
30         setrmtabent("r");
31         while ((rep = getrmtabent(1)) != NULL) {
32                 if (strcmp (rep->r_client,
33                             exp->m_client->m_hostname) == 0
34                     && strcmp(rep->r_path, path) == 0) {
35                         endrmtabent();
36                         xfunlock(lockid);
37                         return;
38                 }
39         }
40         endrmtabent();
41         strncpy(xe.r_client, exp->m_client->m_hostname,
42                 sizeof (xe.r_client) - 1);
43         xe.r_client [sizeof (xe.r_client) - 1] = '\0';
44         strncpy(xe.r_path, path, sizeof (xe.r_path) - 1);
45         xe.r_path [sizeof (xe.r_path) - 1] = '\0';
46         if (setrmtabent("a")) {
47                 putrmtabent(&xe);
48                 endrmtabent();
49         }
50         xfunlock(lockid);
51 }
52
53 void
54 mountlist_del(nfs_export *exp, const char *path)
55 {
56         struct rmtabent *rep;
57         FILE            *fp;
58         char            *hname = exp->m_client->m_hostname;
59         int             lockid;
60
61         if ((lockid = xflock(_PATH_RMTAB, "w")) < 0)
62                 return;
63         if (!setrmtabent("r")) {
64                 xfunlock(lockid);
65                 return;
66         }
67         if (!(fp = fsetrmtabent(_PATH_RMTABTMP, "w"))) {
68                 endrmtabent();
69                 xfunlock(lockid);
70                 return;
71         }
72         while ((rep = getrmtabent(1)) != NULL) {
73                 if (strcmp (rep->r_client, hname)
74                     || strcmp(rep->r_path, path))
75                         fputrmtabent(fp, rep);
76         }
77         if (rename(_PATH_RMTABTMP, _PATH_RMTAB) < 0) {
78                 xlog(L_ERROR, "couldn't rename %s to %s",
79                                 _PATH_RMTABTMP, _PATH_RMTAB);
80         }
81         endrmtabent();  /* close & unlink */
82         fendrmtabent(fp);
83         xfunlock(lockid);
84 }
85
86 void
87 mountlist_del_all(struct sockaddr_in *sin)
88 {
89         struct in_addr  addr = sin->sin_addr;
90         struct hostent  *hp;
91         struct rmtabent *rep;
92         nfs_export      *exp;
93         FILE            *fp;
94         int             lockid;
95
96         if ((lockid = xflock(_PATH_RMTAB, "w")) < 0)
97                 return;
98         if (!(hp = gethostbyaddr((char *)&addr, sizeof(addr), AF_INET))) {
99                 xlog(L_ERROR, "can't get hostname of %s", inet_ntoa(addr));
100                 xfunlock(lockid);
101                 return;
102         }
103         else
104                 hp = hostent_dup (hp);
105
106         if (!setrmtabent("r")) {
107                 xfunlock(lockid);
108                 free (hp);
109                 return;
110         }
111         if (!(fp = fsetrmtabent(_PATH_RMTABTMP, "w"))) {
112                 endrmtabent();
113                 xfunlock(lockid);
114                 free (hp);
115                 return;
116         }
117         while ((rep = getrmtabent(1)) != NULL) {
118                 if (strcmp(rep->r_client, hp->h_name) == 0 &&
119                     (exp = auth_authenticate("umountall", sin, rep->r_path))) {
120                         export_reset(exp);
121                         continue;
122                 }
123                 fputrmtabent(fp, rep);
124         }
125         if (rename(_PATH_RMTABTMP, _PATH_RMTAB) < 0) {
126                 xlog(L_ERROR, "couldn't rename %s to %s",
127                                 _PATH_RMTABTMP, _PATH_RMTAB);
128         }
129         endrmtabent();  /* close & unlink */
130         fendrmtabent(fp);
131         xfunlock(lockid);
132         free (hp);
133 }
134
135 mountlist
136 mountlist_list(void)
137 {
138         static mountlist        mlist = NULL;
139         static time_t           last_mtime = 0;
140         mountlist               m;
141         struct rmtabent         *rep;
142         struct stat             stb;
143         int                     lockid;
144
145         if ((lockid = xflock(_PATH_RMTAB, "r")) < 0)
146                 return NULL;
147         if (stat(_PATH_RMTAB, &stb) < 0) {
148                 xlog(L_ERROR, "can't stat %s", _PATH_RMTAB);
149                 return NULL;
150         }
151         if (stb.st_mtime != last_mtime) {
152                 while (mlist) {
153                         mlist = (m = mlist)->ml_next;
154                         xfree(m->ml_hostname);
155                         xfree(m->ml_directory);
156                         xfree(m);
157                 }
158                 last_mtime = stb.st_mtime;
159
160                 setrmtabent("r");
161                 while ((rep = getrmtabent(1)) != NULL) {
162                         m = (mountlist) xmalloc(sizeof(*m));
163                         m->ml_hostname = xstrdup(rep->r_client);
164                         m->ml_directory = xstrdup(rep->r_path);
165                         m->ml_next = mlist;
166                         mlist = m;
167                 }
168                 endrmtabent();
169         }
170         xfunlock(lockid);
171
172         return mlist;
173 }