a28abf343898791b415336d36ef67c4977063d5f
[nfs-utils.git] / support / nfs / rmtab.c
1 /*
2  * support/nfs/rmtab.c
3  *
4  * Handling for rmtab.
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 <stdlib.h>
15 #include <string.h>
16 #include <stdio.h>
17 #include <unistd.h>
18 #include <errno.h>
19 #include <signal.h>
20 #include "nfslib.h"
21
22 static FILE     *rmfp = NULL;
23
24 int
25 setrmtabent(char *type)
26 {
27         if (rmfp)
28                 fclose(rmfp);
29         rmfp = fsetrmtabent(_PATH_RMTAB, type);
30         return (rmfp != NULL);
31 }
32
33 FILE *
34 fsetrmtabent(char *fname, char *type)
35 {
36         int     readonly = !strcmp(type, "r");
37         FILE    *fp;
38
39         if (!fname)
40                 return NULL;
41         if ((fp = fopen(fname, type)) == NULL) {
42                 xlog(L_ERROR, "can't open %s for %sing", fname,
43                                 readonly ? "read" : "writ");
44                 return NULL;
45         }
46         return fp;
47 }
48
49 struct rmtabent *
50 getrmtabent(int log, long *pos)
51 {
52         return fgetrmtabent(rmfp, log, pos);
53 }
54
55 struct rmtabent *
56 fgetrmtabent(FILE *fp, int log, long *pos)
57 {
58         static struct rmtabent  re;
59         char    buf[2048], *count, *host, *path;
60
61         errno = 0;
62         if (!fp)
63                 return NULL;
64         do {
65                 if (pos)
66                         *pos = ftell (fp);
67                 if (fgets(buf, sizeof(buf)-1, fp) == NULL)
68                         return NULL;
69                 host = buf;
70                 if ((path = strchr(host, '\n')) != NULL)
71                         *path = '\0';
72                 if (!(path = strchr(host, ':'))) {
73                         if (log)
74                                 xlog(L_ERROR, "malformed entry in rmtab file");
75                         errno = EINVAL;
76                         return NULL;
77                 }
78                 *path++ = '\0';
79                 count = strchr(path, ':');
80                 if (count) {
81                         *count++ = '\0';
82                         re.r_count = strtol (count, NULL, 0);
83                 }
84                 else
85                         re.r_count = 1;
86         } while (0);
87         strncpy(re.r_client, host, sizeof (re.r_client) - 1);
88         re.r_client[sizeof (re.r_client) - 1] = '\0';
89         strncpy(re.r_path, path, sizeof (re.r_path) - 1);
90         re.r_path[sizeof (re.r_path) - 1] = '\0';
91         return &re;
92 }
93
94 void
95 putrmtabent(struct rmtabent *rep, long *pos)
96 {
97         fputrmtabent(rmfp, rep, pos);
98 }
99
100 void
101 fputrmtabent(FILE *fp, struct rmtabent *rep, long *pos)
102 {
103         if (!fp || (pos && fseek (fp, *pos, SEEK_SET) != 0))
104                 return;
105         fprintf(fp, "%s:%s:0x%.8x\n", rep->r_client, rep->r_path,
106                 rep->r_count);
107 }
108
109 void
110 endrmtabent(void)
111 {
112         fendrmtabent(rmfp);
113         rmfp = NULL;
114 }
115
116 void
117 fendrmtabent(FILE *fp)
118 {
119         if (fp) {
120                 static int have_new_cache = -1;
121                 if (have_new_cache == -1) /* check only once */
122                         have_new_cache = check_new_cache();
123
124                 if (!have_new_cache) {
125                         /*
126                          * If we are using the old caching interface: exportfs
127                          * uses the rmtab to determine what should be exported,
128                          * so it is important that it be up-to-date.
129                          *
130                          * If we are using the new caching interface: the rmtab
131                          * is ignored by exportfs and the fdatasync only serves
132                          * to slow us down.
133                          */
134                         fflush(fp);
135                         fdatasync(fileno(fp));
136                 }
137
138                 fclose(fp);
139         }
140 }
141
142 void
143 rewindrmtabent(void)
144 {
145         if (rmfp)
146                 rewind(rmfp);
147 }
148
149 void
150 frewindrmtabent(FILE *fp)
151 {
152         if (fp)
153                 rewind (fp);
154 }