| /* Copyright (C) 1995, 1996, 1997, 1998, 2000, 2008 |
| Free Software Foundation, Inc. |
| This file is part of the GNU C Library. |
| |
| The GNU C Library is free software; you can redistribute it and/or |
| modify it under the terms of the GNU Lesser General Public |
| License as published by the Free Software Foundation; either |
| version 2.1 of the License, or (at your option) any later version. |
| |
| The GNU C Library is distributed in the hope that it will be useful, |
| but WITHOUT ANY WARRANTY; without even the implied warranty of |
| MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
| Lesser General Public License for more details. |
| |
| You should have received a copy of the GNU Lesser General Public |
| License along with the GNU C Library; if not, write to the Free |
| Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA |
| 02111-1307 USA. */ |
| |
| #include <fstab.h> |
| #include <mntent.h> |
| #include <stdio.h> |
| #include <stdlib.h> |
| #include <string.h> |
| #include <bits/libc-lock.h> |
| |
| #define BUFFER_SIZE 0x1fc0 |
| |
| struct fstab_state |
| { |
| FILE *fs_fp; |
| char *fs_buffer; |
| struct mntent fs_mntres; |
| struct fstab fs_ret; |
| }; |
| |
| static struct fstab_state *fstab_init (int opt_rewind); |
| static struct mntent *fstab_fetch (struct fstab_state *state); |
| static struct fstab *fstab_convert (struct fstab_state *state); |
| |
| static struct fstab_state fstab_state; |
| |
| |
| int |
| setfsent (void) |
| { |
| return fstab_init (1) != NULL; |
| } |
| |
| |
| struct fstab * |
| getfsent (void) |
| { |
| struct fstab_state *state; |
| |
| state = fstab_init (0); |
| if (state == NULL) |
| return NULL; |
| if (fstab_fetch (state) == NULL) |
| return NULL; |
| return fstab_convert (state); |
| } |
| |
| |
| struct fstab * |
| getfsspec (name) |
| const char *name; |
| { |
| struct fstab_state *state; |
| struct mntent *m; |
| |
| state = fstab_init (1); |
| if (state == NULL) |
| return NULL; |
| while ((m = fstab_fetch (state)) != NULL) |
| if (strcmp (m->mnt_fsname, name) == 0) |
| return fstab_convert (state); |
| return NULL; |
| } |
| |
| |
| struct fstab * |
| getfsfile (name) |
| const char *name; |
| { |
| struct fstab_state *state; |
| struct mntent *m; |
| |
| state = fstab_init (1); |
| if (state == NULL) |
| return NULL; |
| while ((m = fstab_fetch (state)) != NULL) |
| if (strcmp (m->mnt_dir, name) == 0) |
| return fstab_convert (state); |
| return NULL; |
| } |
| |
| |
| void |
| endfsent () |
| { |
| struct fstab_state *state; |
| |
| state = &fstab_state; |
| if (state->fs_fp != NULL) |
| { |
| (void) __endmntent (state->fs_fp); |
| state->fs_fp = NULL; |
| } |
| } |
| |
| |
| static struct fstab_state * |
| fstab_init (int opt_rewind) |
| { |
| struct fstab_state *state; |
| char *buffer; |
| FILE *fp; |
| |
| state = &fstab_state; |
| |
| buffer = state->fs_buffer; |
| if (buffer == NULL) |
| { |
| buffer = (char *) malloc (BUFFER_SIZE); |
| if (buffer == NULL) |
| return NULL; |
| state->fs_buffer = buffer; |
| } |
| |
| fp = state->fs_fp; |
| if (fp != NULL) |
| { |
| if (opt_rewind) |
| rewind (fp); |
| } |
| else |
| { |
| fp = __setmntent (_PATH_FSTAB, "r"); |
| if (fp == NULL) |
| return NULL; |
| state->fs_fp = fp; |
| } |
| |
| return state; |
| } |
| |
| |
| static struct mntent * |
| fstab_fetch (struct fstab_state *state) |
| { |
| return __getmntent_r (state->fs_fp, &state->fs_mntres, |
| state->fs_buffer, BUFFER_SIZE); |
| } |
| |
| |
| static struct fstab * |
| fstab_convert (struct fstab_state *state) |
| { |
| struct mntent *m; |
| struct fstab *f; |
| |
| m = &state->fs_mntres; |
| f = &state->fs_ret; |
| |
| f->fs_spec = m->mnt_fsname; |
| f->fs_file = m->mnt_dir; |
| f->fs_vfstype = m->mnt_type; |
| f->fs_mntops = m->mnt_opts; |
| f->fs_type = (__hasmntopt (m, FSTAB_RW) ? FSTAB_RW : |
| __hasmntopt (m, FSTAB_RQ) ? FSTAB_RQ : |
| __hasmntopt (m, FSTAB_RO) ? FSTAB_RO : |
| __hasmntopt (m, FSTAB_SW) ? FSTAB_SW : |
| __hasmntopt (m, FSTAB_XX) ? FSTAB_XX : |
| "??"); |
| f->fs_freq = m->mnt_freq; |
| f->fs_passno = m->mnt_passno; |
| return f; |
| } |
| |
| |
| /* Make sure the memory is freed if the programs ends while in |
| memory-debugging mode and something actually was allocated. */ |
| libc_freeres_fn (fstab_free) |
| { |
| char *buffer; |
| |
| buffer = fstab_state.fs_buffer; |
| free ((void *) buffer); |
| } |