Get rid of PATH_MAX and MAXPATHLEN

There could be no upper limit on the length of a path according
to POSIX, therefore these macros may not be defined at all on
some systems (such as GNU Hurd).

Signed-off-by: Arnaud Fontaine <arnau@debian.org>
Reviewed-by: Peter Harris <pharris@opentext.com>
This commit is contained in:
Arnaud Fontaine 2010-04-30 14:47:16 +02:00
parent d068572173
commit a546d00091
2 changed files with 83 additions and 16 deletions

View File

@ -89,8 +89,7 @@ static int authname_match(enum auth_protos kind, char *name, size_t namelen)
#define SIN6_ADDR(s) (&((struct sockaddr_in6 *)s)->sin6_addr) #define SIN6_ADDR(s) (&((struct sockaddr_in6 *)s)->sin6_addr)
static Xauth *get_authptr(struct sockaddr *sockname, unsigned int socknamelen, static Xauth *get_authptr(struct sockaddr *sockname, int display)
int display)
{ {
char *addr = 0; char *addr = 0;
int addrlen = 0; int addrlen = 0;
@ -243,13 +242,55 @@ static int compute_auth(xcb_auth_info_t *info, Xauth *authptr, struct sockaddr *
return 0; /* Unknown authorization type */ return 0; /* Unknown authorization type */
} }
/* `sockaddr_un.sun_path' typical size usually ranges between 92 and 108 */
#define INITIAL_SOCKNAME_SLACK 108
/* Return a dynamically allocated socket address structure according
to the value returned by either getpeername() or getsockname()
(according to POSIX, applications should not assume a particular
length for `sockaddr_un.sun_path') */
static struct sockaddr *get_peer_sock_name(int (*socket_func)(int,
struct sockaddr *,
socklen_t *),
int fd)
{
socklen_t socknamelen = sizeof(struct sockaddr) + INITIAL_SOCKNAME_SLACK;
socklen_t actual_socknamelen = socknamelen;
struct sockaddr *sockname = malloc(socknamelen), *new_sockname = NULL;
if (sockname == NULL)
return NULL;
/* Both getpeername() and getsockname() truncates sockname if
there is not enough space and set the required length in
actual_socknamelen */
if (socket_func(fd, sockname, &actual_socknamelen) == -1)
goto sock_or_realloc_error;
if (actual_socknamelen > socknamelen)
{
socknamelen = actual_socknamelen;
if ((new_sockname = realloc(sockname, actual_socknamelen)) == NULL ||
socket_func(fd, new_sockname, &actual_socknamelen) == -1 ||
actual_socknamelen > socknamelen)
goto sock_or_realloc_error;
sockname = new_sockname;
}
return sockname;
sock_or_realloc_error:
free(sockname);
return NULL;
}
int _xcb_get_auth_info(int fd, xcb_auth_info_t *info, int display) int _xcb_get_auth_info(int fd, xcb_auth_info_t *info, int display)
{ {
/* code adapted from Xlib/ConnDis.c, xtrans/Xtranssocket.c, /* code adapted from Xlib/ConnDis.c, xtrans/Xtranssocket.c,
xtrans/Xtransutils.c */ xtrans/Xtransutils.c */
char sockbuf[sizeof(struct sockaddr) + MAXPATHLEN]; struct sockaddr *sockname = NULL;
unsigned int socknamelen = sizeof(sockbuf); /* need extra space */
struct sockaddr *sockname = (struct sockaddr *) &sockbuf;
int gotsockname = 0; int gotsockname = 0;
Xauth *authptr = 0; Xauth *authptr = 0;
int ret = 1; int ret = 1;
@ -258,24 +299,30 @@ int _xcb_get_auth_info(int fd, xcb_auth_info_t *info, int display)
* for UNIX Domain Sockets, but this is irrelevant, * for UNIX Domain Sockets, but this is irrelevant,
* since compute_auth() ignores the peer name in this * since compute_auth() ignores the peer name in this
* case anyway.*/ * case anyway.*/
if (getpeername(fd, sockname, &socknamelen) == -1) if ((sockname = get_peer_sock_name(getpeername, fd)) == NULL)
{ {
if (getsockname(fd, sockname, &socknamelen) == -1) if ((sockname = get_peer_sock_name(getsockname, fd)) == NULL)
return 0; /* can only authenticate sockets */ return 0; /* can only authenticate sockets */
if (sockname->sa_family != AF_UNIX) if (sockname->sa_family != AF_UNIX)
{
free(sockname);
return 0; /* except for AF_UNIX, sockets should have peernames */ return 0; /* except for AF_UNIX, sockets should have peernames */
}
gotsockname = 1; gotsockname = 1;
} }
authptr = get_authptr(sockname, socknamelen, display); authptr = get_authptr(sockname, display);
if (authptr == 0) if (authptr == 0)
{
free(sockname);
return 0; /* cannot find good auth data */ return 0; /* cannot find good auth data */
}
info->namelen = memdup(&info->name, authptr->name, authptr->name_length); info->namelen = memdup(&info->name, authptr->name, authptr->name_length);
if (!info->namelen) if (!info->namelen)
goto no_auth; /* out of memory */ goto no_auth; /* out of memory */
if (!gotsockname && getsockname(fd, sockname, &socknamelen) == -1) if (!gotsockname && (sockname = get_peer_sock_name(getsockname, fd)) == NULL)
{ {
free(info->name); free(info->name);
goto no_auth; /* can only authenticate sockets */ goto no_auth; /* can only authenticate sockets */
@ -288,10 +335,15 @@ int _xcb_get_auth_info(int fd, xcb_auth_info_t *info, int display)
goto no_auth; /* cannot build auth record */ goto no_auth; /* cannot build auth record */
} }
free(sockname);
sockname = NULL;
XauDisposeAuth(authptr); XauDisposeAuth(authptr);
return ret; return ret;
no_auth: no_auth:
free(sockname);
info->name = 0; info->name = 0;
info->namelen = 0; info->namelen = 0;
XauDisposeAuth(authptr); XauDisposeAuth(authptr);

View File

@ -145,8 +145,9 @@ static int _xcb_open(char *host, char *protocol, const int display)
#endif #endif
static const char unix_base[] = "/tmp/.X11-unix/X"; static const char unix_base[] = "/tmp/.X11-unix/X";
const char *base = unix_base; const char *base = unix_base;
char file[PATH_MAX + 1]; size_t filelen;
int filelen; char *file = NULL;
int actual_filelen;
if(*host) if(*host)
{ {
@ -181,24 +182,38 @@ static int _xcb_open(char *host, char *protocol, const int display)
#endif #endif
} }
filelen = strlen(base) + 1 + sizeof(display) * 3 + 1;
file = malloc(filelen);
if(file == NULL)
return -1;
/* display specifies Unix socket */ /* display specifies Unix socket */
#ifdef HAVE_LAUNCHD #ifdef HAVE_LAUNCHD
if(base == host) if(base == host)
filelen = snprintf(file, sizeof(file), "%s:%d", base, display); actual_filelen = snprintf(file, filelen, "%s:%d", base, display);
else else
#endif #endif
filelen = snprintf(file, sizeof(file), "%s%d", base, display); actual_filelen = snprintf(file, filelen, "%s%d", base, display);
if(filelen < 0) if(actual_filelen < 0)
{
free(file);
return -1; return -1;
}
/* snprintf may truncate the file */ /* snprintf may truncate the file */
filelen = MIN(filelen, sizeof(file) - 1); filelen = MIN(actual_filelen, filelen - 1);
#ifdef HAVE_ABSTRACT_SOCKETS #ifdef HAVE_ABSTRACT_SOCKETS
fd = _xcb_open_abstract(protocol, file, filelen); fd = _xcb_open_abstract(protocol, file, filelen);
if (fd >= 0 || (errno != ENOENT && errno != ECONNREFUSED)) if (fd >= 0 || (errno != ENOENT && errno != ECONNREFUSED))
{
free(file);
return fd; return fd;
}
#endif #endif
return _xcb_open_unix(protocol, file); fd = _xcb_open_unix(protocol, file);
free(file);
return fd;
} }
static int _xcb_socket(int family, int type, int proto) static int _xcb_socket(int family, int type, int proto)