1 /* $OpenBSD: filesys-os.c,v 1.10 2009/10/27 23:59:42 deraadt Exp $ */ 2 3 /* 4 * Copyright (c) 1983 Regents of the University of California. 5 * All rights reserved. 6 * 7 * Redistribution and use in source and binary forms, with or without 8 * modification, are permitted provided that the following conditions 9 * are met: 10 * 1. Redistributions of source code must retain the above copyright 11 * notice, this list of conditions and the following disclaimer. 12 * 2. Redistributions in binary form must reproduce the above copyright 13 * notice, this list of conditions and the following disclaimer in the 14 * documentation and/or other materials provided with the distribution. 15 * 3. Neither the name of the University nor the names of its contributors 16 * may be used to endorse or promote products derived from this software 17 * without specific prior written permission. 18 * 19 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 20 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 21 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 22 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 23 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 24 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 25 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 26 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 27 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 28 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 29 * SUCH DAMAGE. 30 */ 31 32 #include "defs.h" 33 34 /* 35 * OS specific file system routines 36 */ 37 38 #if FSI_TYPE == FSI_GETFSSTAT 39 static struct statfs *mnt = NULL; 40 #endif /* FSI_GETFSSTAT */ 41 42 #if FSI_TYPE == FSI_MNTCTL 43 static struct vmount *mnt = NULL; 44 #endif /* FSI_MNTCTL */ 45 46 #if (FSI_TYPE == FSI_MNTCTL) || (FSI_TYPE == FSI_GETFSSTAT) 47 static char *mntbuf = NULL; 48 static int entries_left; 49 #endif /* FSI_MNTCTL || FSI_GETFSSTAT */ 50 51 #if FSI_TYPE == FSI_MNTCTL 52 /* 53 * AIX version of setmountent() 54 */ 55 FILE * 56 setmountent(const char *file, const char *mode) 57 { 58 ulong size; 59 60 if (mntbuf) 61 (void) free(mntbuf); 62 63 mntctl(MCTL_QUERY, sizeof(size), &size); 64 mntbuf = (char *) xmalloc(size); 65 66 entries_left = mntctl(MCTL_QUERY, size, mntbuf); 67 if (!entries_left) 68 return(NULL); 69 70 mnt = (struct vmount *)mntbuf; 71 return((FILE *) 1); 72 } 73 #endif /* FSI_MNTCTL */ 74 75 #if FSI_TYPE == FSI_GETFSSTAT 76 /* 77 * getfsstat() version of get mount info routines. 78 */ 79 FILE * 80 setmountent(const char *file, const char *mode) 81 { 82 long size; 83 84 if (mntbuf) 85 (void) free(mntbuf); 86 87 size = getfsstat(NULL, 0, MNT_WAIT); 88 if (size == -1) 89 return (NULL); 90 size *= sizeof(struct statfs); 91 mntbuf = (char *) xmalloc(size); 92 93 entries_left = getfsstat((struct statfs *)mntbuf, size, MNT_WAIT); 94 if (entries_left == -1) 95 return(NULL); 96 97 mnt = (struct statfs *) mntbuf; 98 99 return((FILE *) 1); 100 } 101 #endif /* FSI_GETFSSTAT */ 102 103 #if FSI_TYPE == FSI_MNTCTL 104 /* 105 * AIX version of getmountent() 106 */ 107 /* 108 * Iterate over mount entries 109 */ 110 mntent_t * 111 getmountent(FILE *fptr) 112 { 113 static mntent_t mntstruct; 114 115 if (!entries_left) 116 return((mntent_t*)0); 117 118 bzero((char *) &mntstruct, sizeof(mntstruct)); 119 120 if (mnt->vmt_flags & MNT_READONLY) 121 mntstruct.me_flags |= MEFLAG_READONLY; 122 123 mntstruct.me_path = vmt2dataptr(mnt, VMT_STUB); 124 switch ((ulong)(struct vmount*)mnt->vmt_gfstype) { 125 case MNT_NFS: 126 mntstruct.me_type = METYPE_NFS; 127 break; 128 default: 129 mntstruct.me_type = METYPE_OTHER; 130 break; 131 } 132 133 mnt = (struct vmount*)((mnt->vmt_length)+(char *)mnt); 134 entries_left--; 135 136 return(&mntstruct); 137 } 138 #endif /* FSI_MNTCTL */ 139 140 #if FSI_TYPE == FSI_GETFSSTAT 141 /* 142 * getfsstat() version of getmountent() 143 */ 144 mntent_t * 145 getmountent(FILE *fptr) 146 { 147 static mntent_t mntstruct; 148 static char remote_dev[MAXHOSTNAMELEN+MAXPATHLEN+1]; 149 150 if (!entries_left) 151 return((mntent_t*)0); 152 153 bzero((char *) &mntstruct, sizeof(mntstruct)); 154 155 #if defined(MNT_RDONLY) 156 if (mnt->f_flags & MNT_RDONLY) 157 mntstruct.me_flags |= MEFLAG_READONLY; 158 #endif 159 #if defined(M_RDONLY) 160 if (mnt->f_flags & M_RDONLY) 161 mntstruct.me_flags |= MEFLAG_READONLY; 162 #endif 163 164 #ifdef HAVE_FSTYPENAME 165 if (strcmp(mnt->f_fstypename, "nfs") == 0) 166 #else 167 if (mnt->f_type == MOUNT_NFS) 168 #endif /* HAVE_FSTYPENAME */ 169 { 170 strlcpy(remote_dev, mnt->f_mntfromname, sizeof(remote_dev)); 171 mntstruct.me_path = remote_dev; 172 mntstruct.me_type = METYPE_NFS; 173 } else { 174 mntstruct.me_path = mnt->f_mntonname; 175 mntstruct.me_type = METYPE_OTHER; 176 } 177 178 mnt++; 179 entries_left--; 180 181 return(&mntstruct); 182 } 183 #endif 184 185 #if (FSI_TYPE == FSI_MNTCTL) || (FSI_TYPE == FSI_GETFSSTAT) 186 /* 187 * Done with iterations 188 */ 189 void 190 endmountent(FILE *fptr) 191 { 192 mnt = NULL; 193 194 if (mntbuf) { 195 (void) free(mntbuf); 196 mntbuf = NULL; 197 } 198 } 199 #endif /* FSI_MNTCTL || FSI_GETFSSTAT */ 200 201 #if FSI_TYPE == FSI_GETMNTENT2 202 /* 203 * Prepare to iterate over mounted filesystem list 204 */ 205 FILE * 206 setmountent(const char *file, const char *mode) 207 { 208 return(fopen(file, mode)); 209 } 210 211 /* 212 * Done with iteration 213 */ 214 void 215 endmountent(FILE *fptr) 216 { 217 fclose(fptr); 218 } 219 220 /* 221 * Iterate over mount entries 222 */ 223 mntent_t * 224 getmountent(FILE *fptr) 225 { 226 static mntent_t me; 227 static struct mnttab mntent; 228 229 bzero((char *)&me, sizeof(mntent_t)); 230 231 #if defined(UNICOS) 232 if (getmntent(fptr, &mntent) != NULL) { 233 #else 234 if (getmntent(fptr, &mntent) != -1) { 235 #endif 236 me.me_path = mntent.mnt_mountp; 237 me.me_type = mntent.mnt_fstype; 238 if (mntent.mnt_mntopts && hasmntopt(&mntent, MNTOPT_RO)) 239 me.me_flags |= MEFLAG_READONLY; 240 241 #if defined(MNTTYPE_IGNORE) 242 if (strcmp(mntent.mnt_fstype, MNTTYPE_IGNORE) == 0) 243 me.me_flags |= MEFLAG_IGNORE; 244 #endif /* MNTTYPE_IGNORE */ 245 #if defined(MNTTYPE_SWAP) 246 if (strcmp(mntent.mnt_fstype, MNTTYPE_SWAP) == 0) 247 me.me_flags |= MEFLAG_IGNORE; 248 #endif /* MNTTYPE_SWAP */ 249 250 return(&me); 251 } else 252 return(NULL); 253 } 254 #endif /* FSI_GETMNTNET2 */ 255 256 #if FSI_TYPE == FSI_GETMNTENT 257 /* 258 * Prepare to iterate over mounted filesystem list 259 */ 260 FILE * 261 setmountent(const char *file, const char *mode) 262 { 263 return(setmntent(file, mode)); 264 } 265 266 /* 267 * Done with iteration 268 */ 269 void 270 endmountent(FILE *fptr) 271 { 272 endmntent(fptr); 273 } 274 275 /* 276 * Iterate over mount entries 277 */ 278 mntent_t * 279 getmountent(FILE *fptr) 280 { 281 static mntent_t me; 282 struct mntent *mntent; 283 284 bzero((char *)&me, sizeof(mntent_t)); 285 286 if ((mntent = getmntent(fptr)) != NULL) { 287 me.me_path = mntent->mnt_dir; 288 me.me_type = mntent->mnt_type; 289 if (mntent->mnt_opts && hasmntopt(mntent, MNTOPT_RO)) 290 me.me_flags |= MEFLAG_READONLY; 291 292 #if defined(MNTTYPE_IGNORE) 293 if (strcmp(mntent->mnt_type, MNTTYPE_IGNORE) == 0) 294 me.me_flags |= MEFLAG_IGNORE; 295 #endif /* MNTTYPE_IGNORE */ 296 #if defined(MNTTYPE_SWAP) 297 if (strcmp(mntent->mnt_type, MNTTYPE_SWAP) == 0) 298 me.me_flags |= MEFLAG_IGNORE; 299 #endif /* MNTTYPE_SWAP */ 300 301 return(&me); 302 } else 303 return(NULL); 304 } 305 #endif /* FSI_GETMNTNET */ 306 307 #if FSI_TYPE == FSI_GETMNT 308 /* 309 * getmnt() interface (Ultrix) 310 */ 311 312 #include <sys/fs_types.h> 313 314 static int startmounts = 0; 315 316 FILE * 317 setmountent(const char *file, const char *mode) 318 { 319 startmounts = 0; 320 return((FILE *) 1); 321 } 322 323 void 324 endmountent(FILE *fptr) 325 { 326 /* NOOP */ 327 } 328 329 /* 330 * Iterate over mounted filesystems using getmnt() 331 */ 332 mntent_t * 333 getmountent(FILE *fptr) 334 { 335 struct fs_data fs_data; 336 static mntent_t me; 337 338 if (getmnt(&startmounts, &fs_data, sizeof(fs_data), NOSTAT_MANY, 339 NULL) <= 0) 340 return(NULL); 341 342 bzero((char *)&me, sizeof(mntent_t)); 343 me.me_path = fs_data.fd_path; 344 if (fs_data.fd_fstype == GT_NFS) 345 me.me_type = METYPE_NFS; 346 else 347 me.me_type = METYPE_OTHER; 348 349 if (fs_data.fd_flags & M_RONLY) 350 me.me_flags |= MEFLAG_READONLY; 351 352 return(&me); 353 } 354 #endif /* FSI_GETMNT */ 355 356 /* 357 * Make a new (copy) of a mntent structure. 358 */ 359 mntent_t * 360 newmountent(const mntent_t *old) 361 { 362 mntent_t *new; 363 364 if (!old) 365 return(NULL); 366 367 new = (mntent_t *) xcalloc(1, sizeof(mntent_t)); 368 new->me_path = xstrdup(old->me_path); 369 new->me_type = xstrdup(old->me_type); 370 new->me_flags = old->me_flags; 371 372 return(new); 373 } 374