#define EXPORT_DEFAULT_FLAGS \
(NFSEXP_ASYNC|NFSEXP_READONLY|NFSEXP_ROOTSQUASH|NFSEXP_GATHERED_WRITES)
+static char *efname = NULL;
static XFILE *efp = NULL;
static int first;
static int *squids = NULL, nsquids = 0,
if (!(efp = xfopen(fname, type)))
xlog(L_ERROR, "can't open %s for %sing",
fname, strcmp(type, "r")? "writ" : "read");
+ efname = strdup(fname);
first = 1;
}
if (ok == 0)
exp[0] = '\0';
if ((opt = strchr(exp, '(')) != NULL) {
+ if (opt == exp)
+ xlog(L_WARNING, "No host name given with %s %s, suggest *%s to avoid warning", ee.e_path, exp, exp);
*opt++ = '\0';
if (!(sp = strchr(opt, ')')) || sp[1] != '\0') {
syntaxerr("bad option list");
*sp = '\0';
if (parseopts(opt, &ee) < 0)
return NULL;
+ } else {
+ xlog(L_WARNING, "No options for %s %s: suggest %s() to avoid warning", ee.e_path, exp, exp);
}
if (strlen(exp) >= sizeof(ee.e_hostname)) {
syntaxerr("client name too long");
{
FILE *fp;
int *id, i;
+ char *esc=ep->e_path;
if (!efp)
return;
fp = efp->x_fp;
- fprintf(fp, "%s\t%s(", ep->e_path, ep->e_hostname);
+ for (i=0; esc[i]; i++)
+ if (iscntrl(esc[i]) || esc[i] == '"' || esc[i] == '\\'|| isspace(esc[i]))
+ fprintf(fp, "\\%03o", esc[i]);
+ else
+ fprintf(fp, "%c", esc[i]);
+
+ fprintf(fp, "\t%s(", ep->e_hostname);
fprintf(fp, "%s,", (ep->e_flags & NFSEXP_READONLY)? "ro" : "rw");
fprintf(fp, "%ssync,", (ep->e_flags & NFSEXP_ASYNC)? "a" : "");
fprintf(fp, "%swdelay,", (ep->e_flags & NFSEXP_GATHERED_WRITES)?
"" : "no_");
+ fprintf(fp, "%shide,", (ep->e_flags & NFSEXP_CROSSMNT)?
+ "no" : "");
fprintf(fp, "%ssecure,", (ep->e_flags & NFSEXP_INSECURE_PORT)?
"in" : "");
fprintf(fp, "%sroot_squash,", (ep->e_flags & NFSEXP_ROOTSQUASH)?
"" : "no_");
fprintf(fp, "%sall_squash,", (ep->e_flags & NFSEXP_ALLSQUASH)?
"" : "no_");
+ fprintf(fp, "%ssubtree_check,", (ep->e_flags & NFSEXP_NOSUBTREECHECK)?
+ "no_" : "");
+ fprintf(fp, "%ssecure_locks,", (ep->e_flags & NFSEXP_NOAUTHNLM)?
+ "in" : "");
fprintf(fp, "mapping=");
switch (ep->e_maptype) {
if (efp)
xfclose(efp);
efp = NULL;
+ if (efname)
+ free(efname);
+ efname = NULL;
freesquash();
}
}
/*
- * Parse option string pointed to by s and set mount options accordingly.
+ * Parse option string pointed to by cp and set mount options accordingly.
*/
static int
parseopts(char *cp, struct exportent *ep)
{
- char *opt;
squids = ep->e_squids; nsquids = ep->e_nsquids;
sqgids = ep->e_sqgids; nsqgids = ep->e_nsqgids;
while (isblank(*cp))
cp++;
while (*cp) {
- opt = cp;
+ char *opt = strdup(cp);
+ char *optstart = cp;
while (*cp && *cp != ',')
cp++;
- if (*cp)
- *cp++ = '\0';
+ if (*cp) {
+ opt[cp-optstart] = '\0';
+ cp++;
+ }
/* process keyword */
if (strcmp(opt, "ro") == 0)
ep->e_flags &= ~NFSEXP_ASYNC;
else if (!strcmp(opt, "async"))
ep->e_flags |= NFSEXP_ASYNC;
+ else if (!strcmp(opt, "nohide"))
+ ep->e_flags |= NFSEXP_CROSSMNT;
+ else if (!strcmp(opt, "hide"))
+ ep->e_flags &= ~NFSEXP_CROSSMNT;
+ else if (!strcmp(opt, "crossmnt")) /* old style */
+ ep->e_flags |= NFSEXP_CROSSMNT;
+ else if (!strcmp(opt, "nocrossmnt")) /* old style */
+ ep->e_flags &= ~NFSEXP_CROSSMNT;
else if (!strcmp(opt, "wdelay"))
ep->e_flags |= NFSEXP_GATHERED_WRITES;
else if (!strcmp(opt, "no_wdelay"))
ep->e_flags |= NFSEXP_ALLSQUASH;
else if (strcmp(opt, "no_all_squash") == 0)
ep->e_flags &= ~NFSEXP_ALLSQUASH;
+ else if (strcmp(opt, "subtree_check") == 0)
+ ep->e_flags &= ~NFSEXP_NOSUBTREECHECK;
+ else if (strcmp(opt, "no_subtree_check") == 0)
+ ep->e_flags |= NFSEXP_NOSUBTREECHECK;
+ else if (strcmp(opt, "auth_nlm") == 0)
+ ep->e_flags &= ~NFSEXP_NOAUTHNLM;
+ else if (strcmp(opt, "no_auth_nlm") == 0)
+ ep->e_flags |= NFSEXP_NOAUTHNLM;
+ else if (strcmp(opt, "secure_locks") == 0)
+ ep->e_flags &= ~NFSEXP_NOAUTHNLM;
+ else if (strcmp(opt, "insecure_locks") == 0)
+ ep->e_flags |= NFSEXP_NOAUTHNLM;
else if (strncmp(opt, "mapping=", 8) == 0)
ep->e_maptype = parsemaptype(opt+8);
else if (strcmp(opt, "map_identity") == 0) /* old style */
else if (strncmp(opt, "anongid=", 8) == 0)
ep->e_anongid = atoi(opt+8);
else if (strncmp(opt, "squash_uids=", 12) == 0) {
- if (parsesquash(opt+12, &squids, &nsquids, &cp) < 0)
+ if (parsesquash(opt+12, &squids, &nsquids, &cp) < 0) {
+ free(opt);
return -1;
+ }
} else if (strncmp(opt, "squash_gids=", 12) == 0) {
- if (parsesquash(opt+12, &sqgids, &nsqgids, &cp) < 0)
+ if (parsesquash(opt+12, &sqgids, &nsqgids, &cp) < 0) {
+ free(opt);
return -1;
+ }
} else {
- xlog(L_ERROR,
- "Unknown keyword \"%s\" in export file\n",
- opt);
+ xlog(L_ERROR, "%s:%d: unknown keyword \"%s\"\n",
+ efname, efp->x_line, opt);
ep->e_flags |= NFSEXP_ALLSQUASH | NFSEXP_READONLY;
+ free(opt);
return -1;
}
+ free(opt);
while (isblank(*cp))
cp++;
}
cp++;
} while(1);
- if (*cp == ',') *ep = cp+1;
-
+ if (**ep == ',') (*ep)++;
+
*lenp = len;
*idp = id;
return 1;
xskip(efp, " \t");
if ((ok = xgettok(efp, 0, exp, len)) < 0)
- xlog(L_ERROR, "error parsing export entry");
+ xlog(L_ERROR, "%s:%d: syntax error",
+ efname, efp->x_line);
return ok;
}
static void
syntaxerr(char *msg)
{
- xlog(L_ERROR, "syntax error in exports file (line %d): %s",
- efp->x_line, msg);
+ xlog(L_ERROR, "%s:%d: syntax error: %s",
+ efname, efp->x_line, msg);
}