Include <string.h> for strcmp prototype.
[kopensolaris-gnu/glibc.git] / misc / fstab.c
1 /* Copyright (C) 1995, 1996, 1997, 1998, 2000 Free Software Foundation, Inc.
2    This file is part of the GNU C Library.
3
4    The GNU C Library is free software; you can redistribute it and/or
5    modify it under the terms of the GNU Library General Public License as
6    published by the Free Software Foundation; either version 2 of the
7    License, or (at your option) any later version.
8
9    The GNU C Library is distributed in the hope that it will be useful,
10    but WITHOUT ANY WARRANTY; without even the implied warranty of
11    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12    Library General Public License for more details.
13
14    You should have received a copy of the GNU Library General Public
15    License along with the GNU C Library; see the file COPYING.LIB.  If not,
16    write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
17    Boston, MA 02111-1307, USA.  */
18
19 #include <fstab.h>
20 #include <mntent.h>
21 #include <stdio.h>
22 #include <stdlib.h>
23 #include <string.h>
24 #include <bits/libc-lock.h>
25
26 #define BUFFER_SIZE 0x1fc0
27
28 struct fstab_state
29 {
30   FILE *fs_fp;
31   char *fs_buffer;
32   struct mntent fs_mntres;
33   struct fstab fs_ret;
34 };
35
36 static struct fstab_state *fstab_init (int opt_rewind);
37 static struct mntent *fstab_fetch (struct fstab_state *state);
38 static struct fstab *fstab_convert (struct fstab_state *state);
39
40 static struct fstab_state fstab_state;
41
42
43 int
44 setfsent (void)
45 {
46   return fstab_init (1) != NULL;
47 }
48
49
50 struct fstab *
51 getfsent (void)
52 {
53   struct fstab_state *state;
54
55   state = fstab_init (0);
56   if (state == NULL)
57     return NULL;
58   if (fstab_fetch (state) == NULL)
59     return NULL;
60   return fstab_convert (state);
61 }
62
63
64 struct fstab *
65 getfsspec (name)
66      const char *name;
67 {
68   struct fstab_state *state;
69   struct mntent *m;
70
71   state = fstab_init (1);
72   if (state == NULL)
73     return NULL;
74   while ((m = fstab_fetch (state)) != NULL)
75     if (strcmp (m->mnt_fsname, name) == 0)
76       return fstab_convert (state);
77   return NULL;
78 }
79
80
81 struct fstab *
82 getfsfile (name)
83      const char *name;
84 {
85   struct fstab_state *state;
86   struct mntent *m;
87
88   state = fstab_init (1);
89   if (state == NULL)
90     return NULL;
91   while ((m = fstab_fetch (state)) != NULL)
92     if (strcmp (m->mnt_dir, name) == 0)
93       return fstab_convert (state);
94   return NULL;
95 }
96
97
98 void
99 endfsent ()
100 {
101   struct fstab_state *state;
102
103   state = &fstab_state;
104   if (state->fs_fp != NULL)
105     {
106       (void) __endmntent (state->fs_fp);
107       state->fs_fp = NULL;
108     }
109 }
110
111
112 static struct fstab_state *
113 fstab_init (int opt_rewind)
114 {
115   struct fstab_state *state;
116   char *buffer;
117   FILE *fp;
118
119   state = &fstab_state;
120
121   buffer = state->fs_buffer;
122   if (buffer == NULL)
123     {
124       buffer = (char *) malloc (BUFFER_SIZE);
125       if (buffer == NULL)
126         return NULL;
127       state->fs_buffer = buffer;
128     }
129
130   fp = state->fs_fp;
131   if (fp != NULL)
132     {
133       if (opt_rewind)
134         rewind (fp);
135     }
136   else
137     {
138       fp = __setmntent (_PATH_FSTAB, "r");
139       if (fp == NULL)
140         return NULL;
141       state->fs_fp = fp;
142     }
143
144   return state;
145 }
146
147
148 static struct mntent *
149 fstab_fetch (struct fstab_state *state)
150 {
151   return __getmntent_r (state->fs_fp, &state->fs_mntres,
152                         state->fs_buffer, BUFFER_SIZE);
153 }
154
155
156 static struct fstab *
157 fstab_convert (struct fstab_state *state)
158 {
159   struct mntent *m;
160   struct fstab *f;
161
162   m = &state->fs_mntres;
163   f = &state->fs_ret;
164
165   f->fs_spec = m->mnt_fsname;
166   f->fs_file = m->mnt_dir;
167   f->fs_vfstype = m->mnt_type;
168   f->fs_mntops = m->mnt_opts;
169   f->fs_type = (__hasmntopt (m, FSTAB_RW) ? FSTAB_RW :
170                 __hasmntopt (m, FSTAB_RQ) ? FSTAB_RQ :
171                 __hasmntopt (m, FSTAB_RO) ? FSTAB_RO :
172                 __hasmntopt (m, FSTAB_SW) ? FSTAB_SW :
173                 __hasmntopt (m, FSTAB_XX) ? FSTAB_XX :
174                 "??");
175   f->fs_freq = m->mnt_freq;
176   f->fs_passno = m->mnt_passno;
177   return f;
178 }
179
180
181 /* Make sure the memory is freed if the programs ends while in
182    memory-debugging mode and something actually was allocated.  */
183 static void
184 __attribute__ ((unused))
185 fstab_free (void)
186 {
187   char *buffer;
188
189   buffer = fstab_state.fs_buffer;
190   if (buffer != NULL)
191     free ((void *) buffer);
192 }
193
194 text_set_element (__libc_subfreeres, fstab_free);