Update.
* misc/mntent_r.c: Allow spaces and tabs in entry names by encoding these characters.
This commit is contained in:
parent
722c33bbb6
commit
b0b422e85d
|
@ -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.
|
||||
|
|
123
misc/mntent_r.c
123
misc/mntent_r.c
|
@ -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)
|
||||
|
|
Loading…
Reference in New Issue