6 * Copyright (C) 1995, 1996 Olaf Kirch <okir@monad.swb.de>
13 #include <sys/fcntl.h>
23 * Colons in incoming IPv6 presentation addresses have to
24 * replaced with another character, since rmtab already
25 * uses colons to delineate fields.
27 * Use a printable character, but one that would never be
28 * found in a presentation address or domain name
30 #define IPV6_COLON ';'
32 #define LINELEN (2048)
34 static FILE *rmfp = NULL;
37 setrmtabent(char *type)
41 rmfp = fsetrmtabent(_PATH_RMTAB, type);
42 return (rmfp != NULL);
46 fsetrmtabent(char *fname, char *type)
48 int readonly = !strcmp(type, "r");
53 if ((fp = fopen(fname, type)) == NULL) {
54 xlog(L_ERROR, "can't open %s for %sing", fname,
55 readonly ? "read" : "writ");
62 getrmtabent(int log, long *pos)
64 return fgetrmtabent(rmfp, log, pos);
68 fgetrmtabent(FILE *fp, int log, long *pos)
70 static struct rmtabent re;
71 char *count, *host, *path, *c;
72 static char buf[LINELEN];
80 if (fgets(buf, sizeof(buf)-1, fp) == NULL)
83 if ((path = strchr(host, '\n')) != NULL)
85 if (!(path = strchr(host, ':'))) {
87 xlog(L_ERROR, "malformed entry in rmtab file");
92 count = strchr(path, ':');
95 re.r_count = strtol (count, NULL, 0);
101 strncpy(re.r_client, host, sizeof (re.r_client) - 1);
102 re.r_client[sizeof (re.r_client) - 1] = '\0';
103 for (c = re.r_client; *c != '\0'; c++)
104 if (*c == IPV6_COLON)
107 strncpy(re.r_path, path, sizeof (re.r_path) - 1);
108 re.r_path[sizeof (re.r_path) - 1] = '\0';
114 putrmtabent(struct rmtabent *rep, long *pos)
116 fputrmtabent(rmfp, rep, pos);
120 fputrmtabent(FILE *fp, struct rmtabent *rep, long *pos)
122 static char buf[LINELEN];
125 if (!fp || (pos && fseek (fp, *pos, SEEK_SET) != 0))
129 * To avoid confusing the token parser in fgetrmtabent(),
130 * convert colons in incoming IPv6 presentation addresses
133 if (strlen(rep->r_client) > sizeof(buf)) {
134 xlog(L_ERROR, "client name too large");
137 strncpy(buf, rep->r_client, sizeof(buf));
138 for (c = buf; *c != '\0'; c++)
142 (void)fprintf(fp, "%s:%s:0x%.8x\n", buf, rep->r_path, rep->r_count);
153 fendrmtabent(FILE *fp)
156 static int have_new_cache = -1;
157 if (have_new_cache == -1) /* check only once */
158 have_new_cache = check_new_cache();
160 if (!have_new_cache) {
162 * If we are using the old caching interface: exportfs
163 * uses the rmtab to determine what should be exported,
164 * so it is important that it be up-to-date.
166 * If we are using the new caching interface: the rmtab
167 * is ignored by exportfs and the fdatasync only serves
171 fdatasync(fileno(fp));
186 frewindrmtabent(FILE *fp)