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