* misc/mntent_r.c: Allow spaces and tabs in entry names by
	encoding these characters.
This commit is contained in:
Ulrich Drepper 1999-07-26 01:16:48 +00:00
parent 722c33bbb6
commit b0b422e85d
2 changed files with 114 additions and 12 deletions

View File

@ -1,5 +1,8 @@
1999-07-25 Ulrich Drepper <drepper@cygnus.com>
* misc/mntent_r.c: Allow spaces and tabs in entry names by
encoding these characters.
* string/bits/string2.h: Fix aliasing problems.
* sysdeps/i386/i486/bits/string.h: Likewise.
* sysdeps/i386/bits/string.h: Likewise.

View File

@ -1,5 +1,5 @@
/* Utilities for reading/writing fstab, mtab, etc.
Copyright (C) 1995, 1996, 1997, 1998 Free Software Foundation, Inc.
Copyright (C) 1995, 1996, 1997, 1998, 1999 Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
@ -48,12 +48,50 @@ __endmntent (FILE *stream)
weak_alias (__endmntent, endmntent)
/* Since the values in a line are separated by spaces, a name cannot
contain a space. Therefore some programs encode spaces in names
by the strings "\040". We undo the encoding when reading an entry.
The decoding happens in place. */
static char *
decode_name (char *buf)
{
char *rp = buf;
char *wp = buf;
do
if (rp[0] == '\\' && rp[1] == '0' && rp[2] == '4' && rp[3] == '0')
{
/* \040 is a SPACE. */
*wp++ = ' ';
rp += 3;
}
else if (rp[0] == '\\' && rp[1] == '0' && rp[2] == '1' && rp[3] == '2')
{
/* \012 is a TAB. */
*wp++ = '\t';
rp += 3;
}
else if (rp[0] == '\\' && rp[1] == '\\')
{
/* We have to escape \\ to be able to represent all characters. */
*wp++ = '\\';
rp += 1;
}
else
*wp++ = *rp;
while (*rp++ != '\0');
return buf;
}
/* Read one mount table entry from STREAM. Returns a pointer to storage
reused on the next call, or null for EOF or error (use feof/ferror to
check). */
struct mntent *
__getmntent_r (FILE *stream, struct mntent *mp, char *buffer, int bufsiz)
{
char *cp;
char *head;
flockfile (stream);
@ -81,18 +119,23 @@ __getmntent_r (FILE *stream, struct mntent *mp, char *buffer, int bufsiz)
head = buffer + strspn (buffer, " \t");
/* skip empty lines and comment lines: */
} while (head[0] == '\0' || head[0] == '#');
}
while (head[0] == '\0' || head[0] == '#');
mp->mnt_fsname = __strsep (&head, " \t") ?: (char *) "";
cp = __strsep (&head, " \t");
mp->mnt_fsname = cp != NULL ? decode_name (cp) : (char *) "";
if (head)
head += strspn (head, " \t");
mp->mnt_dir = __strsep (&head, " \t") ?: (char *) "";
cp = __strsep (&head, " \t");
mp->mnt_dir = cp != NULL ? decode_name (cp) : (char *) "";
if (head)
head += strspn (head, " \t");
mp->mnt_type = __strsep (&head, " \t") ?: (char *) "";
cp = __strsep (&head, " \t");
mp->mnt_type = cp != NULL ? decode_name (cp) : (char *) "";
if (head)
head += strspn (head, " \t");
mp->mnt_opts = __strsep (&head, " \t") ?: (char *) "";
cp = __strsep (&head, " \t");
mp->mnt_opts = cp != NULL ? decode_name (cp) : (char *) "";
switch (head ? sscanf (head, " %d %d ", &mp->mnt_freq, &mp->mnt_passno) : 0)
{
case 0:
@ -107,21 +150,77 @@ __getmntent_r (FILE *stream, struct mntent *mp, char *buffer, int bufsiz)
}
weak_alias (__getmntent_r, getmntent_r)
/* We have to use an encoding for names if they contain spaces or tabs.
To be able to represent all characters we also have to escape the
backslash itself. This "function" must be a macro since we use
`alloca'. */
#define encode_name(name) \
do { \
const char *rp = name; \
\
while (*rp != '\0') \
if (*rp == ' ' || *rp == '\t' || *rp == '\\') \
break; \
\
if (*rp != '\0') \
{ \
/* In the worst case the length of the string can increase to \
founr times the current length. */ \
char *wp = (char *) alloca (strlen (name) * 4 + 1); \
\
rp = name; \
do \
if (*rp == ' ') \
{ \
*wp++ = '\\'; \
*wp++ = '0'; \
*wp++ = '4'; \
*wp++ = '0'; \
} \
else if (*rp == '\t') \
{ \
*wp++ = '\\'; \
*wp++ = '0'; \
*wp++ = '1'; \
*wp++ = '2'; \
} \
else if (*rp == '\\') \
{ \
*wp++ = '\\'; \
*wp++ = '\\'; \
} \
else \
*wp++ = *rp; \
while (*rp++ != '\0'); \
\
name = wp; \
} \
} while (0)
/* Write the mount table entry described by MNT to STREAM.
Return zero on success, nonzero on failure. */
int
__addmntent (FILE *stream, const struct mntent *mnt)
{
struct mntent mntcopy = *mnt;
if (fseek (stream, 0, SEEK_END))
return 1;
/* Encode spaces and tabs in the names. */
encode_name (mntcopy.mnt_fsname);
encode_name (mntcopy.mnt_dir);
encode_name (mntcopy.mnt_type);
encode_name (mntcopy.mnt_opts);
return (fprintf (stream, "%s %s %s %s %d %d\n",
mnt->mnt_fsname,
mnt->mnt_dir,
mnt->mnt_type,
mnt->mnt_opts,
mnt->mnt_freq,
mnt->mnt_passno)
mntcopy.mnt_fsname,
mntcopy.mnt_dir,
mntcopy.mnt_type,
mntcopy.mnt_opts,
mntcopy.mnt_freq,
mntcopy.mnt_passno)
< 0 ? 1 : 0);
}
weak_alias (__addmntent, addmntent)