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 Lesser General Public
6    License as published by the Free Software Foundation; either
7    version 2.1 of the 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    Lesser General Public License for more details.
13 
14    You should have received a copy of the GNU Lesser General Public
15    License along with the GNU C Library; if not, write to the Free
16    Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
17    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 #include <libc-symbols.h>
26 
27 #define BUFFER_SIZE 0x1fc0
28 
29 struct fstab_state
30 {
31   FILE *fs_fp;
32   char *fs_buffer;
33   struct mntent fs_mntres;
34   struct fstab fs_ret;
35 };
36 
37 static struct fstab_state *fstab_init (int opt_rewind);
38 static struct mntent *fstab_fetch (struct fstab_state *state);
39 static struct fstab *fstab_convert (struct fstab_state *state);
40 
41 static struct fstab_state fstab_state;
42 
43 
44 int
setfsent(void)45 setfsent (void)
46 {
47   return fstab_init (1) != NULL;
48 }
49 
50 
51 struct fstab *
getfsent(void)52 getfsent (void)
53 {
54   struct fstab_state *state;
55 
56   state = fstab_init (0);
57   if (state == NULL)
58     return NULL;
59   if (fstab_fetch (state) == NULL)
60     return NULL;
61   return fstab_convert (state);
62 }
63 
64 
65 struct fstab *
getfsspec(name)66 getfsspec (name)
67      const char *name;
68 {
69   struct fstab_state *state;
70   struct mntent *m;
71 
72   state = fstab_init (1);
73   if (state == NULL)
74     return NULL;
75   while ((m = fstab_fetch (state)) != NULL)
76     if (strcmp (m->mnt_fsname, name) == 0)
77       return fstab_convert (state);
78   return NULL;
79 }
80 
81 
82 struct fstab *
getfsfile(name)83 getfsfile (name)
84      const char *name;
85 {
86   struct fstab_state *state;
87   struct mntent *m;
88 
89   state = fstab_init (1);
90   if (state == NULL)
91     return NULL;
92   while ((m = fstab_fetch (state)) != NULL)
93     if (strcmp (m->mnt_dir, name) == 0)
94       return fstab_convert (state);
95   return NULL;
96 }
97 
98 
99 void
endfsent()100 endfsent ()
101 {
102   struct fstab_state *state;
103 
104   state = &fstab_state;
105   if (state->fs_fp != NULL)
106     {
107       (void) __endmntent (state->fs_fp);
108       state->fs_fp = NULL;
109     }
110 }
111 
112 
113 static struct fstab_state *
fstab_init(int opt_rewind)114 fstab_init (int opt_rewind)
115 {
116   struct fstab_state *state;
117   char *buffer;
118   FILE *fp;
119 
120   state = &fstab_state;
121 
122   buffer = state->fs_buffer;
123   if (buffer == NULL)
124     {
125       buffer = (char *) malloc (BUFFER_SIZE);
126       if (buffer == NULL)
127 	return NULL;
128       state->fs_buffer = buffer;
129     }
130 
131   fp = state->fs_fp;
132   if (fp != NULL)
133     {
134       if (opt_rewind)
135 	rewind (fp);
136     }
137   else
138     {
139       fp = __setmntent (_PATH_FSTAB, "r");
140       if (fp == NULL)
141 	return NULL;
142       state->fs_fp = fp;
143     }
144 
145   return state;
146 }
147 
148 
149 static struct mntent *
fstab_fetch(struct fstab_state * state)150 fstab_fetch (struct fstab_state *state)
151 {
152   return __getmntent_r (state->fs_fp, &state->fs_mntres,
153 			state->fs_buffer, BUFFER_SIZE);
154 }
155 
156 
157 static struct fstab *
fstab_convert(struct fstab_state * state)158 fstab_convert (struct fstab_state *state)
159 {
160   struct mntent *m;
161   struct fstab *f;
162 
163   m = &state->fs_mntres;
164   f = &state->fs_ret;
165 
166   f->fs_spec = m->mnt_fsname;
167   f->fs_file = m->mnt_dir;
168   f->fs_vfstype = m->mnt_type;
169   f->fs_mntops = m->mnt_opts;
170   f->fs_type = (__hasmntopt (m, FSTAB_RW) ? FSTAB_RW :
171 		__hasmntopt (m, FSTAB_RQ) ? FSTAB_RQ :
172 		__hasmntopt (m, FSTAB_RO) ? FSTAB_RO :
173 		__hasmntopt (m, FSTAB_SW) ? FSTAB_SW :
174 		__hasmntopt (m, FSTAB_XX) ? FSTAB_XX :
175 		"??");
176   f->fs_freq = m->mnt_freq;
177   f->fs_passno = m->mnt_passno;
178   return f;
179 }
180 
181 
182 /* Make sure the memory is freed if the programs ends while in
183    memory-debugging mode and something actually was allocated.  */
184 static void
185 __attribute__ ((unused))
fstab_free(void)186 fstab_free (void)
187 {
188   char *buffer;
189 
190   buffer = fstab_state.fs_buffer;
191   if (buffer != NULL)
192     free ((void *) buffer);
193 }
194 
195 text_set_element (__libc_subfreeres, fstab_free);
196