]> sourceware.org Git - glibc.git/blame - misc/mntent_r.c
Update.
[glibc.git] / misc / mntent_r.c
CommitLineData
845dcb57 1/* Utilities for reading/writing fstab, mtab, etc.
2706ee38 2 Copyright (C) 1995-2000, 2001 Free Software Foundation, Inc.
df4ef2ab 3 This file is part of the GNU C Library.
845dcb57 4
df4ef2ab 5 The GNU C Library is free software; you can redistribute it and/or
41bdb6e2
AJ
6 modify it under the terms of the GNU Lesser General Public
7 License as published by the Free Software Foundation; either
8 version 2.1 of the License, or (at your option) any later version.
845dcb57 9
df4ef2ab
UD
10 The GNU C Library is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
41bdb6e2 13 Lesser General Public License for more details.
845dcb57 14
41bdb6e2
AJ
15 You should have received a copy of the GNU Lesser General Public
16 License along with the GNU C Library; if not, write to the Free
17 Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
18 02111-1307 USA. */
845dcb57 19
53308042 20#include <alloca.h>
845dcb57
UD
21#include <mntent.h>
22#include <stdio.h>
2706ee38 23#include <stdio_ext.h>
845dcb57
UD
24#include <string.h>
25#include <sys/types.h>
26
50304ef0
UD
27#ifdef USE_IN_LIBIO
28# define flockfile(s) _IO_flockfile (s)
29# define funlockfile(s) _IO_funlockfile (s)
30#endif
31
845dcb57
UD
32/* Prepare to begin reading and/or writing mount table entries from the
33 beginning of FILE. MODE is as for `fopen'. */
34FILE *
35__setmntent (const char *file, const char *mode)
36{
2706ee38
UD
37 FILE *result = fopen (file, mode);
38
39 if (result != NULL)
40 /* We do the locking ourselves. */
b4c4f776 41 __fsetlocking (result, FSETLOCKING_BYCALLER);
2706ee38
UD
42
43 return result;
845dcb57
UD
44}
45weak_alias (__setmntent, setmntent)
46
47
48/* Close a stream opened with `setmntent'. */
49int
50__endmntent (FILE *stream)
51{
52 if (stream) /* SunOS 4.x allows for NULL stream */
53 fclose (stream);
54 return 1; /* SunOS 4.x says to always return 1 */
55}
56weak_alias (__endmntent, endmntent)
57
58
b0b422e8
UD
59/* Since the values in a line are separated by spaces, a name cannot
60 contain a space. Therefore some programs encode spaces in names
61 by the strings "\040". We undo the encoding when reading an entry.
62 The decoding happens in place. */
63static char *
64decode_name (char *buf)
65{
66 char *rp = buf;
67 char *wp = buf;
68
69 do
70 if (rp[0] == '\\' && rp[1] == '0' && rp[2] == '4' && rp[3] == '0')
71 {
72 /* \040 is a SPACE. */
73 *wp++ = ' ';
74 rp += 3;
75 }
76 else if (rp[0] == '\\' && rp[1] == '0' && rp[2] == '1' && rp[3] == '2')
77 {
78 /* \012 is a TAB. */
79 *wp++ = '\t';
80 rp += 3;
81 }
82 else if (rp[0] == '\\' && rp[1] == '\\')
83 {
84 /* We have to escape \\ to be able to represent all characters. */
85 *wp++ = '\\';
86 rp += 1;
87 }
88 else
89 *wp++ = *rp;
90 while (*rp++ != '\0');
91
92 return buf;
93}
94
95
845dcb57
UD
96/* Read one mount table entry from STREAM. Returns a pointer to storage
97 reused on the next call, or null for EOF or error (use feof/ferror to
98 check). */
99struct mntent *
100__getmntent_r (FILE *stream, struct mntent *mp, char *buffer, int bufsiz)
101{
b0b422e8 102 char *cp;
845dcb57
UD
103 char *head;
104
71412a8c 105 flockfile (stream);
845dcb57
UD
106 do
107 {
108 char *end_ptr;
109
71412a8c 110 if (fgets_unlocked (buffer, bufsiz, stream) == NULL)
4bae5567
UD
111 {
112 funlockfile (stream);
113 return NULL;
114 }
845dcb57
UD
115
116 end_ptr = strchr (buffer, '\n');
117 if (end_ptr != NULL) /* chop newline */
118 *end_ptr = '\0';
119 else
120 {
121 /* Not the whole line was read. Do it now but forget it. */
122 char tmp[1024];
71412a8c 123 while (fgets_unlocked (tmp, sizeof tmp, stream) != NULL)
845dcb57
UD
124 if (strchr (tmp, '\n') != NULL)
125 break;
126 }
127
128 head = buffer + strspn (buffer, " \t");
129 /* skip empty lines and comment lines: */
b0b422e8
UD
130 }
131 while (head[0] == '\0' || head[0] == '#');
845dcb57 132
b0b422e8
UD
133 cp = __strsep (&head, " \t");
134 mp->mnt_fsname = cp != NULL ? decode_name (cp) : (char *) "";
845dcb57
UD
135 if (head)
136 head += strspn (head, " \t");
b0b422e8
UD
137 cp = __strsep (&head, " \t");
138 mp->mnt_dir = cp != NULL ? decode_name (cp) : (char *) "";
845dcb57
UD
139 if (head)
140 head += strspn (head, " \t");
b0b422e8
UD
141 cp = __strsep (&head, " \t");
142 mp->mnt_type = cp != NULL ? decode_name (cp) : (char *) "";
845dcb57
UD
143 if (head)
144 head += strspn (head, " \t");
b0b422e8
UD
145 cp = __strsep (&head, " \t");
146 mp->mnt_opts = cp != NULL ? decode_name (cp) : (char *) "";
845dcb57
UD
147 switch (head ? sscanf (head, " %d %d ", &mp->mnt_freq, &mp->mnt_passno) : 0)
148 {
149 case 0:
150 mp->mnt_freq = 0;
151 case 1:
152 mp->mnt_passno = 0;
153 case 2:
49f3a758 154 break;
845dcb57 155 }
71412a8c 156 funlockfile (stream);
845dcb57
UD
157
158 return mp;
159}
160weak_alias (__getmntent_r, getmntent_r)
161
b0b422e8
UD
162
163/* We have to use an encoding for names if they contain spaces or tabs.
164 To be able to represent all characters we also have to escape the
165 backslash itself. This "function" must be a macro since we use
166 `alloca'. */
167#define encode_name(name) \
168 do { \
169 const char *rp = name; \
170 \
171 while (*rp != '\0') \
172 if (*rp == ' ' || *rp == '\t' || *rp == '\\') \
173 break; \
63f7cb44
UD
174 else \
175 ++rp; \
b0b422e8
UD
176 \
177 if (*rp != '\0') \
178 { \
179 /* In the worst case the length of the string can increase to \
180 founr times the current length. */ \
63f7cb44 181 char *wp; \
b0b422e8
UD
182 \
183 rp = name; \
63f7cb44
UD
184 name = wp = (char *) alloca (strlen (name) * 4 + 1); \
185 \
b0b422e8
UD
186 do \
187 if (*rp == ' ') \
188 { \
189 *wp++ = '\\'; \
190 *wp++ = '0'; \
191 *wp++ = '4'; \
192 *wp++ = '0'; \
193 } \
194 else if (*rp == '\t') \
195 { \
196 *wp++ = '\\'; \
197 *wp++ = '0'; \
198 *wp++ = '1'; \
199 *wp++ = '2'; \
200 } \
201 else if (*rp == '\\') \
202 { \
203 *wp++ = '\\'; \
204 *wp++ = '\\'; \
205 } \
206 else \
207 *wp++ = *rp; \
208 while (*rp++ != '\0'); \
b0b422e8
UD
209 } \
210 } while (0)
211
212
845dcb57
UD
213/* Write the mount table entry described by MNT to STREAM.
214 Return zero on success, nonzero on failure. */
215int
216__addmntent (FILE *stream, const struct mntent *mnt)
217{
b0b422e8 218 struct mntent mntcopy = *mnt;
845dcb57
UD
219 if (fseek (stream, 0, SEEK_END))
220 return 1;
221
b0b422e8
UD
222 /* Encode spaces and tabs in the names. */
223 encode_name (mntcopy.mnt_fsname);
224 encode_name (mntcopy.mnt_dir);
225 encode_name (mntcopy.mnt_type);
226 encode_name (mntcopy.mnt_opts);
227
845dcb57 228 return (fprintf (stream, "%s %s %s %s %d %d\n",
b0b422e8
UD
229 mntcopy.mnt_fsname,
230 mntcopy.mnt_dir,
231 mntcopy.mnt_type,
232 mntcopy.mnt_opts,
233 mntcopy.mnt_freq,
234 mntcopy.mnt_passno)
845dcb57
UD
235 < 0 ? 1 : 0);
236}
237weak_alias (__addmntent, addmntent)
238
239
240/* Search MNT->mnt_opts for an option matching OPT.
241 Returns the address of the substring, or null if none found. */
242char *
243__hasmntopt (const struct mntent *mnt, const char *opt)
244{
245 const size_t optlen = strlen (opt);
246 char *rest = mnt->mnt_opts, *p;
247
248 while ((p = strstr (rest, opt)) != NULL)
249 {
6796bc80
UD
250 if (p == rest
251 || (p[-1] == ','
252 && (p[optlen] == '\0' ||
253 p[optlen] == '=' ||
254 p[optlen] == ',')))
845dcb57
UD
255 return p;
256
257 rest = strchr (rest, ',');
df4ef2ab
UD
258 if (rest == NULL)
259 break;
260 ++rest;
845dcb57
UD
261 }
262
263 return NULL;
264}
265weak_alias (__hasmntopt, hasmntopt)
This page took 0.170832 seconds and 5 git commands to generate.