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