/* * CDDL HEADER START * * The contents of this file are subject to the terms of the * Common Development and Distribution License, Version 1.0 only * (the "License"). You may not use this file except in compliance * with the License. * * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE * or http://www.opensolaris.org/os/licensing. * See the License for the specific language governing permissions * and limitations under the License. * * When distributing Covered Code, include this CDDL HEADER in each * file and include the License file at usr/src/OPENSOLARIS.LICENSE. * If applicable, add the following below this CDDL HEADER, with the * fields enclosed by brackets "[]" replaced with your own identifying * information: Portions Copyright [yyyy] [name of copyright owner] * * CDDL HEADER END */ /* * Copyright 1995 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ #pragma ident "%Z%%M% %I% %E% SMI" /* * Exported file system table manager. Reads/writes "/etc/xtab". */ #include #include #include #include extern char *strtok(); extern char *strcpy(); #define LINESIZE 4096 static char *TMPFILE = "/tmp/xtabXXXXXX"; static char *skipwhite(char *); static char *skipnonwhite(char *); FILE * setexportent(void) { FILE *f; int fd; /* * Create the tab file if it does not exist already */ if (access(TABFILE, F_OK) < 0) { fd = open(TABFILE, O_CREAT, 0644); close(fd); } if (access(TABFILE, W_OK) == 0) { f = fopen(TABFILE, "r+"); } else { f = fopen(TABFILE, "r"); } if (f == NULL) { return (NULL); } if (flock(fileno(f), LOCK_EX) < 0) { (void)fclose(f); return (NULL); } return (f); } void endexportent(FILE *f) { (void) fclose(f); } struct exportent * getexportent(FILE *f) { static char *line = NULL; static struct exportent xent; int len; char *p; if (line == NULL) { line = (char *)malloc(LINESIZE + 1); } if (fgets(line, LINESIZE, f) == NULL) { return (NULL); } len = strlen(line); if (line[len-1] == '\n') { line[len-1] = 0; } xent.xent_dirname = line; xent.xent_options = NULL; p = skipnonwhite(line); if (*p == 0) { return (&xent); } *p++ = 0; p = skipwhite(p); if (*p == 0) { return (&xent); } if (*p == '-') { p++; } xent.xent_options = p; return (&xent); } int remexportent(FILE *f, char *dirname) { char buf[LINESIZE]; FILE *f2; int len; char *fname; int fd; long pos; long rempos; int remlen; int res; fname = (char *) malloc(strlen(TMPFILE) + 1); pos = ftell(f); rempos = 0; remlen = 0; (void)strcpy(fname, TMPFILE); fd = mkstemp(fname); if (fd < 0) { return (-1); } if (unlink(fname) < 0) { (void)close(fd); return (-1); } f2 = fdopen(fd, "r+"); if (f2 == NULL) { (void)close(fd); return (-1); } len = strlen(dirname); rewind(f); while (fgets(buf, sizeof(buf), f)) { if (strncmp(buf, dirname, len) != 0 || ! isspace((unsigned char)buf[len])) { if (fputs(buf, f2) <= 0) { (void)fclose(f2); return (-1); } } else { remlen = strlen(buf); rempos = ftell(f) - remlen; } } rewind(f); if (ftruncate(fileno(f), 0L) < 0) { (void)fclose(f2); return (-1); } rewind(f2); while (fgets(buf, sizeof(buf), f2)) { if (fputs(buf, f) <= 0) { (void)fclose(f2); return (-1); } } (void)fclose(f2); if (remlen == 0) { /* nothing removed */ (void) fseek(f, pos, L_SET); res = -1; } else if (pos <= rempos) { res = fseek(f, pos, L_SET); } else if (pos > rempos + remlen) { res = fseek(f, pos - remlen, L_SET); } else { res = fseek(f, rempos, L_SET); } return (res < 0 ? -1 : 0); } int addexportent(FILE *f, char *dirname, char *options) { long pos; pos = ftell(f); if (fseek(f, 0L, L_XTND) >= 0 && fprintf(f, "%s", dirname) > 0 && (options == NULL || fprintf(f, " -%s", options) > 0) && fprintf(f, "\n") > 0 && fseek(f, pos, L_SET) >= 0) { return (0); } return (-1); } char * getexportopt(struct exportent *xent, char *opt) { static char *tokenbuf = NULL; char *lp; char *tok; int len; if (tokenbuf == NULL) { tokenbuf = (char *)malloc(LINESIZE); } if (xent->xent_options == NULL) { return (NULL); } (void)strcpy(tokenbuf, xent->xent_options); lp = tokenbuf; len = strlen(opt); while ((tok = strtok(lp, ",")) != NULL) { lp = NULL; if (strncmp(opt, tok, len) == 0) { if (tok[len] == '=') { return (&tok[len + 1]); } else if (tok[len] == 0) { return (""); } } } return (NULL); } #define iswhite(c) ((c) == ' ' || c == '\t') static char * skipwhite(char *str) { while (*str && iswhite(*str)) { str++; } return (str); } static char * skipnonwhite(char *str) { while (*str && ! iswhite(*str)) { str++; } return (str); }