Home | History | Annotate | Download | only in common
      1 /*
      2  * CDDL HEADER START
      3  *
      4  * The contents of this file are subject to the terms of the
      5  * Common Development and Distribution License, Version 1.0 only
      6  * (the "License").  You may not use this file except in compliance
      7  * with the License.
      8  *
      9  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
     10  * or http://www.opensolaris.org/os/licensing.
     11  * See the License for the specific language governing permissions
     12  * and limitations under the License.
     13  *
     14  * When distributing Covered Code, include this CDDL HEADER in each
     15  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
     16  * If applicable, add the following below this CDDL HEADER, with the
     17  * fields enclosed by brackets "[]" replaced with your own identifying
     18  * information: Portions Copyright [yyyy] [name of copyright owner]
     19  *
     20  * CDDL HEADER END
     21  */
     22 
     23 /*
     24  * Copyright 1995 Sun Microsystems, Inc.  All rights reserved.
     25  * Use is subject to license terms.
     26  */
     27 
     28 #pragma ident	"%Z%%M%	%I%	%E% SMI"
     29 
     30 /*
     31  * Exported file system table manager. Reads/writes "/etc/xtab".
     32  */
     33 
     34 #include <stdio.h>
     35 #include <exportent.h>
     36 #include <sys/file.h>
     37 #include <ctype.h>
     38 
     39 extern char *strtok();
     40 extern char *strcpy();
     41 
     42 #define LINESIZE 4096
     43 
     44 static char *TMPFILE = "/tmp/xtabXXXXXX";
     45 
     46 static char *skipwhite(char *);
     47 static char *skipnonwhite(char *);
     48 
     49 FILE *
     50 setexportent(void)
     51 {
     52 	FILE *f;
     53 	int fd;
     54 
     55 	/*
     56 	 * Create the tab file if it does not exist already
     57 	 */
     58 	if (access(TABFILE, F_OK) < 0) {
     59 		fd = open(TABFILE, O_CREAT, 0644);
     60 		close(fd);
     61 	}
     62 	if (access(TABFILE, W_OK) == 0) {
     63 		f = fopen(TABFILE, "r+");
     64 	} else {
     65 		f = fopen(TABFILE, "r");
     66 	}
     67 	if (f == NULL) {
     68 	   	return (NULL);
     69 	}
     70 	if (flock(fileno(f), LOCK_EX) < 0) {
     71 		(void)fclose(f);
     72 		return (NULL);
     73 	}
     74 	return (f);
     75 }
     76 
     77 
     78 void
     79 endexportent(FILE *f)
     80 {
     81 	(void) fclose(f);
     82 }
     83 
     84 
     85 struct exportent *
     86 getexportent(FILE *f)
     87 {
     88 	static char *line = NULL;
     89 	static struct exportent xent;
     90 	int len;
     91 	char *p;
     92 
     93 	if (line == NULL) {
     94 		line = (char *)malloc(LINESIZE + 1);
     95 	}
     96 	if (fgets(line, LINESIZE, f) == NULL) {
     97 		return (NULL);
     98 	}
     99 	len = strlen(line);
    100 	if (line[len-1] == '\n') {
    101 		line[len-1] = 0;
    102 	}
    103 	xent.xent_dirname = line;
    104 	xent.xent_options = NULL;
    105 	p = skipnonwhite(line);
    106 	if (*p == 0) {
    107 		return (&xent);
    108 	}
    109 	*p++ = 0;
    110 	p = skipwhite(p);
    111 	if (*p == 0) {
    112 		return (&xent);
    113 	}
    114 	if (*p == '-') {
    115 		p++;
    116 	}
    117 	xent.xent_options = p;
    118 	return (&xent);
    119 }
    120 
    121 int
    122 remexportent(FILE *f, char *dirname)
    123 {
    124 	char buf[LINESIZE];
    125 	FILE *f2;
    126 	int len;
    127 	char *fname;
    128 	int fd;
    129 	long pos;
    130 	long rempos;
    131 	int remlen;
    132 	int res;
    133 
    134 	fname = (char *) malloc(strlen(TMPFILE) + 1);
    135 	pos = ftell(f);
    136 	rempos = 0;
    137 	remlen = 0;
    138 	(void)strcpy(fname, TMPFILE);
    139  	fd = mkstemp(fname);
    140 	if (fd < 0) {
    141 		return (-1);
    142 	}
    143 	if (unlink(fname) < 0) {
    144 		(void)close(fd);
    145 		return (-1);
    146 	}
    147 	f2 = fdopen(fd, "r+");
    148 	if (f2 == NULL) {
    149 		(void)close(fd);
    150 		return (-1);
    151 	}
    152 	len = strlen(dirname);
    153 	rewind(f);
    154 	while (fgets(buf, sizeof(buf), f)) {
    155 		if (strncmp(buf, dirname,
    156 		    len) != 0 || ! isspace((unsigned char)buf[len])) {
    157 			if (fputs(buf, f2) <= 0) {
    158 				(void)fclose(f2);
    159 				return (-1);
    160 			}
    161 		} else {
    162 			remlen = strlen(buf);
    163 			rempos = ftell(f) - remlen;
    164 		}
    165 	}
    166 	rewind(f);
    167 	if (ftruncate(fileno(f), 0L) < 0) {
    168 		(void)fclose(f2);
    169 		return (-1);
    170 	}
    171 	rewind(f2);
    172 	while (fgets(buf, sizeof(buf), f2)) {
    173 		if (fputs(buf, f) <= 0) {
    174 			(void)fclose(f2);
    175 			return (-1);
    176 		}
    177 	}
    178 	(void)fclose(f2);
    179 	if (remlen == 0) {
    180 		/* nothing removed */
    181 		(void) fseek(f, pos, L_SET);
    182 		res = -1;
    183 	} else if (pos <= rempos) {
    184 		res = fseek(f, pos, L_SET);
    185 	} else if (pos > rempos + remlen) {
    186 		res = fseek(f, pos - remlen, L_SET);
    187 	} else {
    188 		res = fseek(f, rempos, L_SET);
    189 	}
    190 	return (res < 0 ? -1 : 0);
    191 }
    192 
    193 int
    194 addexportent(FILE *f, char *dirname, char *options)
    195 {
    196 	long pos;
    197 
    198 	pos = ftell(f);
    199 	if (fseek(f, 0L, L_XTND) >= 0 &&
    200 	    fprintf(f, "%s", dirname) > 0 &&
    201 	    (options == NULL || fprintf(f, " -%s", options) > 0) &&
    202 	    fprintf(f, "\n") > 0 &&
    203 	    fseek(f, pos, L_SET) >= 0) {
    204 		return (0);
    205 	}
    206 	return (-1);
    207 }
    208 
    209 
    210 char *
    211 getexportopt(struct exportent *xent, char *opt)
    212 {
    213 	static char *tokenbuf = NULL;
    214 	char *lp;
    215 	char *tok;
    216 	int len;
    217 
    218 	if (tokenbuf == NULL) {
    219 		tokenbuf = (char *)malloc(LINESIZE);
    220 	}
    221 	if (xent->xent_options == NULL) {
    222 		return (NULL);
    223 	}
    224 	(void)strcpy(tokenbuf, xent->xent_options);
    225 	lp = tokenbuf;
    226 	len = strlen(opt);
    227 	while ((tok = strtok(lp, ",")) != NULL) {
    228 		lp = NULL;
    229 		if (strncmp(opt, tok, len) == 0) {
    230 			if (tok[len] == '=') {
    231 				return (&tok[len + 1]);
    232 			} else if (tok[len] == 0) {
    233 				return ("");
    234 			}
    235 		}
    236 	}
    237 	return (NULL);
    238 }
    239 
    240 
    241 #define iswhite(c) 	((c) == ' ' || c == '\t')
    242 
    243 static char *
    244 skipwhite(char *str)
    245 {
    246 	while (*str && iswhite(*str)) {
    247 		str++;
    248 	}
    249 	return (str);
    250 }
    251 
    252 static char *
    253 skipnonwhite(char *str)
    254 {
    255 	while (*str && ! iswhite(*str)) {
    256 		str++;
    257 	}
    258 	return (str);
    259 }
    260