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