/* * support/nfs/xio.c * * Simple I/O functions for the parsing of /etc/exports and /etc/nfsclients. * * Copyright (C) 1995, 1996 Olaf Kirch */ #ifdef HAVE_CONFIG_H #include #endif #include #include #include #include #include #include #include #include #include "xmalloc.h" #include "xlog.h" #include "xio.h" XFILE * xfopen(char *fname, char *type) { XFILE *xfp; FILE *fp; if (!(fp = fopen(fname, type))) return NULL; xfp = (XFILE *) xmalloc(sizeof(*xfp)); xfp->x_fp = fp; xfp->x_line = 1; return xfp; } void xfclose(XFILE *xfp) { fclose(xfp->x_fp); xfree(xfp); } int xflock(char *fname, char *type) { int readonly = !strcmp(type, "r"); struct flock fl = { readonly? F_RDLCK : F_WRLCK, SEEK_SET, 0, 0, 0 }; int fd; if (readonly) fd = open(fname, (O_RDONLY|O_CREAT), 0600); else fd = open(fname, (O_RDWR|O_CREAT), 0600); if (fd < 0) { xlog(L_WARNING, "could not open %s for locking: errno %d (%s)", fname, errno, strerror(errno)); return -1; } if (fcntl(fd, F_SETLKW, &fl) < 0) { xlog(L_WARNING, "failed to lock %s: errno %d (%s)", fname, errno, strerror(errno)); close(fd); fd = -1; } return fd; } void xfunlock(int fd) { close(fd); } #define isoctal(x) (isdigit(x) && ((x)<'8')) int xgettok(XFILE *xfp, char sepa, char *tok, int len) { int i = 0; int c = 0; int quoted=0; while (i < len && (c = xgetc(xfp)) != EOF && (quoted || (c != sepa && !isspace(c)))) { if (c == '"') { quoted = !quoted; continue; } tok[i++] = c; if (i >= 4 && tok[i-4] == '\\' && isoctal(tok[i-3]) && isoctal(tok[i-2]) && isoctal(tok[i-1]) && ((tok[i]=0), (c = strtol(tok+i-3,NULL, 8)) < 256)) { i -= 4; tok[i++] = c; } } if (c == '\n') xungetc(c, xfp); if (!i) return 0; if (i >= len || (sepa && c != sepa)) return -1; tok[i] = '\0'; return 1; } int xgetc(XFILE *xfp) { int c = getc(xfp->x_fp); if (c == EOF) return c; if (c == '\\') { if ((c = getc(xfp->x_fp)) != '\n') { ungetc(c, xfp->x_fp); return '\\'; } xfp->x_line++; while ((c = getc(xfp->x_fp)) == ' ' || c == '\t'); ungetc(c, xfp->x_fp); return ' '; } if (c == '\n') xfp->x_line++; return c; } void xungetc(int c, XFILE *xfp) { if (c == EOF) return; ungetc(c, xfp->x_fp); if (c == '\n') xfp->x_line--; } void xskip(XFILE *xfp, char *str) { int c; while ((c = xgetc(xfp)) != EOF) { if (c == '#') c = xskipcomment(xfp); if (strchr(str, c) == NULL) break; } xungetc(c, xfp); } char xskipcomment(XFILE *xfp) { int c; while ((c = getc(xfp->x_fp)) != EOF && c != '\n'); return c; }