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