2000-05-31 H.J. Lu <hjl@lucon.org>
[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         long            pos;
28
29         if ((lockid = xflock(_PATH_RMTAB, "a")) < 0)
30                 return;
31         setrmtabent("r+");
32         while ((rep = getrmtabent(1, &pos)) != NULL) {
33                 if (strcmp (rep->r_client,
34                             exp->m_client->m_hostname) == 0
35                     && strcmp(rep->r_path, path) == 0) {
36                         rep->r_count++;
37                         putrmtabent(rep, &pos);
38                         endrmtabent();
39                         xfunlock(lockid);
40                         return;
41                 }
42         }
43         endrmtabent();
44         strncpy(xe.r_client, exp->m_client->m_hostname,
45                 sizeof (xe.r_client) - 1);
46         xe.r_client [sizeof (xe.r_client) - 1] = '\0';
47         strncpy(xe.r_path, path, sizeof (xe.r_path) - 1);
48         xe.r_path [sizeof (xe.r_path) - 1] = '\0';
49         xe.r_count = 1;
50         if (setrmtabent("a")) {
51                 putrmtabent(&xe, NULL);
52                 endrmtabent();
53         }
54         xfunlock(lockid);
55 }
56
57 void
58 mountlist_del(nfs_export *exp, const char *path)
59 {
60         struct rmtabent *rep;
61         FILE            *fp;
62         char            *hname = exp->m_client->m_hostname;
63         int             lockid;
64         int             match;
65
66         if ((lockid = xflock(_PATH_RMTAB, "w")) < 0)
67                 return;
68         if (!setrmtabent("r")) {
69                 xfunlock(lockid);
70                 return;
71         }
72         if (!(fp = fsetrmtabent(_PATH_RMTABTMP, "w"))) {
73                 endrmtabent();
74                 xfunlock(lockid);
75                 return;
76         }
77         while ((rep = getrmtabent(1, NULL)) != NULL) {
78                 match = !strcmp (rep->r_client, hname)
79                         && !strcmp(rep->r_path, path);
80                 if (match)
81                         rep->r_count--;
82                 if (!match || rep->r_count)
83                         fputrmtabent(fp, rep, NULL);
84         }
85         if (rename(_PATH_RMTABTMP, _PATH_RMTAB) < 0) {
86                 xlog(L_ERROR, "couldn't rename %s to %s",
87                                 _PATH_RMTABTMP, _PATH_RMTAB);
88         }
89         endrmtabent();  /* close & unlink */
90         fendrmtabent(fp);
91         xfunlock(lockid);
92 }
93
94 void
95 mountlist_del_all(struct sockaddr_in *sin)
96 {
97         struct in_addr  addr = sin->sin_addr;
98         struct hostent  *hp;
99         struct rmtabent *rep;
100         nfs_export      *exp;
101         FILE            *fp;
102         int             lockid;
103
104         if ((lockid = xflock(_PATH_RMTAB, "w")) < 0)
105                 return;
106         if (!(hp = gethostbyaddr((char *)&addr, sizeof(addr), AF_INET))) {
107                 xlog(L_ERROR, "can't get hostname of %s", inet_ntoa(addr));
108                 xfunlock(lockid);
109                 return;
110         }
111         else
112                 hp = hostent_dup (hp);
113
114         if (!setrmtabent("r")) {
115                 xfunlock(lockid);
116                 free (hp);
117                 return;
118         }
119         if (!(fp = fsetrmtabent(_PATH_RMTABTMP, "w"))) {
120                 endrmtabent();
121                 xfunlock(lockid);
122                 free (hp);
123                 return;
124         }
125         while ((rep = getrmtabent(1, NULL)) != NULL) {
126                 if (strcmp(rep->r_client, hp->h_name) == 0 &&
127                     (exp = auth_authenticate("umountall", sin, rep->r_path))) {
128                         export_reset(exp);
129                         continue;
130                 }
131                 fputrmtabent(fp, rep, NULL);
132         }
133         if (rename(_PATH_RMTABTMP, _PATH_RMTAB) < 0) {
134                 xlog(L_ERROR, "couldn't rename %s to %s",
135                                 _PATH_RMTABTMP, _PATH_RMTAB);
136         }
137         endrmtabent();  /* close & unlink */
138         fendrmtabent(fp);
139         xfunlock(lockid);
140         free (hp);
141 }
142
143 mountlist
144 mountlist_list(void)
145 {
146         static mountlist        mlist = NULL;
147         static time_t           last_mtime = 0;
148         mountlist               m;
149         struct rmtabent         *rep;
150         struct stat             stb;
151         int                     lockid;
152
153         if ((lockid = xflock(_PATH_RMTAB, "r")) < 0)
154                 return NULL;
155         if (stat(_PATH_RMTAB, &stb) < 0) {
156                 xlog(L_ERROR, "can't stat %s", _PATH_RMTAB);
157                 return NULL;
158         }
159         if (stb.st_mtime != last_mtime) {
160                 while (mlist) {
161                         mlist = (m = mlist)->ml_next;
162                         xfree(m->ml_hostname);
163                         xfree(m->ml_directory);
164                         xfree(m);
165                 }
166                 last_mtime = stb.st_mtime;
167
168                 setrmtabent("r");
169                 while ((rep = getrmtabent(1, NULL)) != NULL) {
170                         m = (mountlist) xmalloc(sizeof(*m));
171                         m->ml_hostname = xstrdup(rep->r_client);
172                         m->ml_directory = xstrdup(rep->r_path);
173                         m->ml_next = mlist;
174                         mlist = m;
175                 }
176                 endrmtabent();
177         }
178         xfunlock(lockid);
179
180         return mlist;
181 }