]>
git.ipfire.org Git - thirdparty/util-linux.git/blob - mount/mntent.c
1 /* Private version of the libc *mntent() routines. */
2 /* Note slightly different prototypes. */
4 /* 1999-02-22 Arkadiusz Mi¶kiewicz <misiek@misiek.eu.org>
5 * - added Native Language Support
9 #include <string.h> /* for index */
10 #include <ctype.h> /* for isdigit */
12 #include "sundries.h" /* for xmalloc */
15 /* Unfortunately the classical Unix /etc/mtab and /etc/fstab
16 do not handle directory names containing spaces.
17 Here we mangle them, replacing a space by \040.
18 What do other Unices do? */
20 static unsigned char need_escaping
[] = { ' ', '\t', '\n', '\\' };
23 mangle(unsigned char *s
) {
28 ss
= sp
= xmalloc(4*n
+1);
30 for (n
= 0; n
< sizeof(need_escaping
); n
++) {
31 if (*s
== need_escaping
[n
]) {
33 *sp
++ = '0' + ((*s
& 0300) >> 6);
34 *sp
++ = '0' + ((*s
& 070) >> 3);
35 *sp
++ = '0' + (*s
& 07);
49 is_space_or_tab (char c
) {
50 return (c
== ' ' || c
== '\t');
54 skip_spaces(char *s
) {
55 while (is_space_or_tab(*s
))
61 skip_nonspaces(char *s
) {
62 while (*s
&& !is_space_or_tab(*s
))
67 #define isoctal(a) (((a) & ~7) == '0')
69 /* returns malloced pointer - no more strdup required */
74 ss
= skip_nonspaces(s
);
75 ret
= sp
= xmalloc(ss
-s
+1);
77 if (*s
== '\\' && isoctal(s
[1]) && isoctal(s
[2]) && isoctal(s
[3])) {
78 *sp
++ = 64*(s
[1] & 7) + 8*(s
[2] & 7) + (s
[3] & 7);
88 * fstat'ing the file and allocating a buffer holding all of it
89 * may be a bad idea: if the file is /proc/mounts, the stat
91 * (On the other hand, mangling and unmangling is meaningless
96 my_setmntent (const char *file
, char *mode
) {
97 mntFILE
*mfp
= xmalloc(sizeof(*mfp
));
99 mfp
->mntent_fp
= fopen (file
, mode
);
100 mfp
->mntent_file
= xstrdup(file
);
101 mfp
->mntent_errs
= (mfp
->mntent_fp
== NULL
);
102 mfp
->mntent_softerrs
= 0;
103 mfp
->mntent_lineno
= 0;
108 my_endmntent (mntFILE
*mfp
) {
111 fclose(mfp
->mntent_fp
);
112 if (mfp
->mntent_file
)
113 free(mfp
->mntent_file
);
120 my_addmntent (mntFILE
*mfp
, struct mntent
*mnt
) {
121 char *m1
, *m2
, *m3
, *m4
;
124 if (fseek (mfp
->mntent_fp
, 0, SEEK_END
))
125 return 1; /* failure */
127 m1
= mangle(mnt
->mnt_fsname
);
128 m2
= mangle(mnt
->mnt_dir
);
129 m3
= mangle(mnt
->mnt_type
);
130 m4
= mangle(mnt
->mnt_opts
);
132 res
= ((fprintf (mfp
->mntent_fp
, "%s %s %s %s %d %d\n",
133 m1
, m2
, m3
, m4
, mnt
->mnt_freq
, mnt
->mnt_passno
)
143 /* Read the next entry from the file fp. Stop reading at an incorrect entry. */
145 my_getmntent (mntFILE
*mfp
) {
146 static char buf
[4096];
147 static struct mntent me
;
151 if (mfp
->mntent_errs
|| mfp
->mntent_softerrs
>= ERR_MAX
)
154 /* read the next non-blank non-comment line */
156 if (fgets (buf
, sizeof(buf
), mfp
->mntent_fp
) == NULL
)
159 mfp
->mntent_lineno
++;
160 s
= index (buf
, '\n');
162 /* Missing final newline? Otherwise extremely */
163 /* long line - assume file was corrupted */
164 if (feof(mfp
->mntent_fp
)) {
165 fprintf(stderr
, _("[mntent]: warning: no final "
166 "newline at the end of %s\n"),
170 mfp
->mntent_errs
= 1;
175 if (--s
>= buf
&& *s
== '\r')
177 s
= skip_spaces(buf
);
178 } while (*s
== '\0' || *s
== '#');
180 me
.mnt_fsname
= unmangle(s
);
181 s
= skip_nonspaces(s
);
183 me
.mnt_dir
= unmangle(s
);
184 s
= skip_nonspaces(s
);
186 me
.mnt_type
= unmangle(s
);
187 s
= skip_nonspaces(s
);
189 me
.mnt_opts
= unmangle(s
);
190 s
= skip_nonspaces(s
);
194 me
.mnt_freq
= atoi(s
);
195 while(isdigit(*s
)) s
++;
198 if(*s
&& !is_space_or_tab(*s
))
203 me
.mnt_passno
= atoi(s
);
204 while(isdigit(*s
)) s
++;
207 if(*s
&& !is_space_or_tab(*s
))
210 /* allow more stuff, e.g. comments, on this line */
215 mfp
->mntent_softerrs
++;
216 fprintf(stderr
, _("[mntent]: line %d in %s is bad%s\n"),
217 mfp
->mntent_lineno
, mfp
->mntent_file
,
218 (mfp
->mntent_errs
|| mfp
->mntent_softerrs
>= ERR_MAX
) ?
219 _("; rest of file ignored") : "");