Commit 59307314 authored by Ulrich Sibiller's avatar Ulrich Sibiller

update all files with NX relevant changes to libX11 1.3.4

parent a053df0a
...@@ -23,28 +23,27 @@ used in advertising or otherwise to promote the sale, use or other dealings ...@@ -23,28 +23,27 @@ used in advertising or otherwise to promote the sale, use or other dealings
in this Software without prior written authorization from The Open Group. in this Software without prior written authorization from The Open Group.
*/ */
/* $XFree86$ */
#ifdef HAVE_CONFIG_H #ifdef HAVE_CONFIG_H
#include <config.h> #include <config.h>
#endif #endif
#include "Xlibint.h" #include "Xlibint.h"
/* /*
* Check existing events in queue to find if any match. If so, return. * Check existing events in queue to find if any match. If so, return.
* If not, flush buffer and see if any more events are readable. If one * If not, flush buffer and see if any more events are readable. If one
* matches, return. If all else fails, tell the user no events found. * matches, return. If all else fails, tell the user no events found.
*/ */
Bool XCheckIfEvent (dpy, event, predicate, arg) Bool XCheckIfEvent (
register Display *dpy; register Display *dpy,
register XEvent *event, /* XEvent to be filled in. */
Bool (*predicate)( Bool (*predicate)(
Display* /* display */, Display* /* display */,
XEvent* /* event */, XEvent* /* event */,
char* /* arg */ char* /* arg */
); /* function to call */ ), /* function to call */
register XEvent *event; /* XEvent to be filled in. */ char *arg)
char *arg;
{ {
register _XQEvent *prev, *qelt; register _XQEvent *prev, *qelt;
unsigned long qe_serial = 0; unsigned long qe_serial = 0;
...@@ -60,6 +59,7 @@ Bool XCheckIfEvent (dpy, event, predicate, arg) ...@@ -60,6 +59,7 @@ Bool XCheckIfEvent (dpy, event, predicate, arg)
&& (*predicate)(dpy, &qelt->event, arg)) { && (*predicate)(dpy, &qelt->event, arg)) {
*event = qelt->event; *event = qelt->event;
_XDeq(dpy, prev, qelt); _XDeq(dpy, prev, qelt);
_XStoreEventCookie(dpy, event);
UnlockDisplay(dpy); UnlockDisplay(dpy);
return True; return True;
} }
...@@ -90,15 +90,16 @@ Bool XCheckIfEvent (dpy, event, predicate, arg) ...@@ -90,15 +90,16 @@ Bool XCheckIfEvent (dpy, event, predicate, arg)
* events. * events.
*/ */
Bool XCheckIfEventNoFlush (dpy, event, predicate, arg) Bool XCheckIfEventNoFlush (
register Display *dpy; register Display *dpy,
register XEvent *event, /* XEvent to be filled in. */
Bool (*predicate)( Bool (*predicate)(
Display* /* display */, Display* /* display */,
XEvent* /* event */, XEvent* /* event */,
char* /* arg */ char* /* arg */
); /* function to call */ ), /* function to call */
register XEvent *event; /* XEvent to be filled in. */ char *arg)
char *arg;
{ {
register _XQEvent *prev, *qelt; register _XQEvent *prev, *qelt;
unsigned long qe_serial = 0; unsigned long qe_serial = 0;
...@@ -114,6 +115,7 @@ Bool XCheckIfEventNoFlush (dpy, event, predicate, arg) ...@@ -114,6 +115,7 @@ Bool XCheckIfEventNoFlush (dpy, event, predicate, arg)
&& (*predicate)(dpy, &qelt->event, arg)) { && (*predicate)(dpy, &qelt->event, arg)) {
*event = qelt->event; *event = qelt->event;
_XDeq(dpy, prev, qelt); _XDeq(dpy, prev, qelt);
_XStoreEventCookie(dpy, event);
UnlockDisplay(dpy); UnlockDisplay(dpy);
return True; return True;
} }
......
...@@ -29,25 +29,25 @@ in this Software without prior written authorization from The Open Group. ...@@ -29,25 +29,25 @@ in this Software without prior written authorization from The Open Group.
#endif #endif
#include "Xlibint.h" #include "Xlibint.h"
/* /*
* Flush output and (wait for and) return the next event matching the * Flush output and (wait for and) return the next event matching the
* predicate in the queue. * predicate in the queue.
*/ */
int int
XIfEvent (dpy, event, predicate, arg) XIfEvent (
register Display *dpy; register Display *dpy,
register XEvent *event,
Bool (*predicate)( Bool (*predicate)(
Display* /* display */, Display* /* display */,
XEvent* /* event */, XEvent* /* event */,
char* /* arg */ char* /* arg */
); /* function to call */ ), /* function to call */
register XEvent *event; char *arg)
char *arg;
{ {
register _XQEvent *qelt, *prev; register _XQEvent *qelt, *prev;
unsigned long qe_serial = 0; unsigned long qe_serial = 0;
LockDisplay(dpy); LockDisplay(dpy);
prev = NULL; prev = NULL;
while (1) { while (1) {
...@@ -58,6 +58,7 @@ XIfEvent (dpy, event, predicate, arg) ...@@ -58,6 +58,7 @@ XIfEvent (dpy, event, predicate, arg)
&& (*predicate)(dpy, &qelt->event, arg)) { && (*predicate)(dpy, &qelt->event, arg)) {
*event = qelt->event; *event = qelt->event;
_XDeq(dpy, prev, qelt); _XDeq(dpy, prev, qelt);
_XStoreEventCookie(dpy, event);
UnlockDisplay(dpy); UnlockDisplay(dpy);
return 0; return 0;
} }
......
...@@ -34,28 +34,32 @@ extern long const _Xevent_to_mask[]; ...@@ -34,28 +34,32 @@ extern long const _Xevent_to_mask[];
#define AllButtons (Button1MotionMask|Button2MotionMask|Button3MotionMask|\ #define AllButtons (Button1MotionMask|Button2MotionMask|Button3MotionMask|\
Button4MotionMask|Button5MotionMask) Button4MotionMask|Button5MotionMask)
/* /*
* return the next event in the queue matching one of the events in the mask. * return the next event in the queue matching one of the events in the mask.
* If no event, flush output, and wait until match succeeds. * If no event, flush output, and wait until match succeeds.
* Events earlier in the queue are not discarded. * Events earlier in the queue are not discarded.
*/ */
int int
XMaskEvent (dpy, mask, event) XMaskEvent (
register Display *dpy; register Display *dpy,
long mask; /* Selected event mask. */ long mask, /* Selected event mask. */
register XEvent *event; /* XEvent to be filled in. */ register XEvent *event) /* XEvent to be filled in. */
{ {
register _XQEvent *prev, *qelt; register _XQEvent *prev, *qelt;
unsigned long qe_serial = 0; unsigned long qe_serial = 0;
LockDisplay(dpy); LockDisplay(dpy);
/* Delete unclaimed cookies */
_XFreeEventCookies(dpy);
prev = NULL; prev = NULL;
while (1) { while (1) {
for (qelt = prev ? prev->next : dpy->head; for (qelt = prev ? prev->next : dpy->head;
qelt; qelt;
prev = qelt, qelt = qelt->next) { prev = qelt, qelt = qelt->next) {
if ((qelt->event.type < LASTEvent) && if ((qelt->event.type < GenericEvent) &&
(_Xevent_to_mask[qelt->event.type] & mask) && (_Xevent_to_mask[qelt->event.type] & mask) &&
((qelt->event.type != MotionNotify) || ((qelt->event.type != MotionNotify) ||
(mask & AllPointers) || (mask & AllPointers) ||
......
...@@ -29,20 +29,23 @@ in this Software without prior written authorization from The Open Group. ...@@ -29,20 +29,23 @@ in this Software without prior written authorization from The Open Group.
#endif #endif
#include "Xlibint.h" #include "Xlibint.h"
/* /*
* Return next event in queue, or if none, flush output and wait for * Return next event in queue, or if none, flush output and wait for
* events. * events.
*/ */
int int
XNextEvent (dpy, event) XNextEvent (
register Display *dpy; register Display *dpy,
register XEvent *event; register XEvent *event)
{ {
register _XQEvent *qelt; register _XQEvent *qelt;
LockDisplay(dpy); LockDisplay(dpy);
/* Delete unclaimed cookies */
_XFreeEventCookies(dpy);
if (dpy->head == NULL) if (dpy->head == NULL)
_XReadEvents(dpy); _XReadEvents(dpy);
#ifdef NX_TRANS_SOCKET #ifdef NX_TRANS_SOCKET
...@@ -54,6 +57,7 @@ XNextEvent (dpy, event) ...@@ -54,6 +57,7 @@ XNextEvent (dpy, event)
qelt = dpy->head; qelt = dpy->head;
*event = qelt->event; *event = qelt->event;
_XDeq(dpy, NULL, qelt); _XDeq(dpy, NULL, qelt);
_XStoreEventCookie(dpy, event);
UnlockDisplay(dpy); UnlockDisplay(dpy);
return 0; return 0;
} }
......
...@@ -29,17 +29,18 @@ in this Software without prior written authorization from The Open Group. ...@@ -29,17 +29,18 @@ in this Software without prior written authorization from The Open Group.
#endif #endif
#include "Xlibint.h" #include "Xlibint.h"
/* /*
* Return the next event in the queue, * Return the next event in the queue,
* BUT do not remove it from the queue. * BUT do not remove it from the queue.
* If none found, flush and wait until there is an event to peek. * If none found, flush and wait until there is an event to peek.
*/ */
int int
XPeekEvent (dpy, event) XPeekEvent (
register Display *dpy; register Display *dpy,
register XEvent *event; register XEvent *event)
{ {
XEvent copy;
LockDisplay(dpy); LockDisplay(dpy);
if (dpy->head == NULL) if (dpy->head == NULL)
_XReadEvents(dpy); _XReadEvents(dpy);
...@@ -47,9 +48,13 @@ XPeekEvent (dpy, event) ...@@ -47,9 +48,13 @@ XPeekEvent (dpy, event)
if (_XGetIOError(dpy)) { if (_XGetIOError(dpy)) {
UnlockDisplay(dpy); UnlockDisplay(dpy);
return 1; return 1;
} }
#endif #endif
*event = (dpy->head)->event; *event = (dpy->head)->event;
if (_XCopyEventCookie(dpy, &event->xcookie, &copy.xcookie)) {
_XStoreEventCookie(dpy, &copy);
*event = copy;
}
UnlockDisplay(dpy); UnlockDisplay(dpy);
return 1; return 1;
} }
......
...@@ -36,15 +36,15 @@ in this Software without prior written authorization from The Open Group. ...@@ -36,15 +36,15 @@ in this Software without prior written authorization from The Open Group.
*/ */
int int
XPeekIfEvent (dpy, event, predicate, arg) XPeekIfEvent (
register Display *dpy; register Display *dpy,
register XEvent *event; register XEvent *event,
Bool (*predicate)( Bool (*predicate)(
Display* /* display */, Display* /* display */,
XEvent* /* event */, XEvent* /* event */,
char* /* arg */ char* /* arg */
); ),
char *arg; char *arg)
{ {
register _XQEvent *prev, *qelt; register _XQEvent *prev, *qelt;
unsigned long qe_serial = 0; unsigned long qe_serial = 0;
...@@ -57,7 +57,12 @@ XPeekIfEvent (dpy, event, predicate, arg) ...@@ -57,7 +57,12 @@ XPeekIfEvent (dpy, event, predicate, arg)
prev = qelt, qelt = qelt->next) { prev = qelt, qelt = qelt->next) {
if(qelt->qserial_num > qe_serial if(qelt->qserial_num > qe_serial
&& (*predicate)(dpy, &qelt->event, arg)) { && (*predicate)(dpy, &qelt->event, arg)) {
XEvent copy;
*event = qelt->event; *event = qelt->event;
if (_XCopyEventCookie(dpy, &event->xcookie, &copy.xcookie)) {
_XStoreEventCookie(dpy, &copy);
*event = copy;
}
UnlockDisplay(dpy); UnlockDisplay(dpy);
return 0; return 0;
} }
......
...@@ -33,9 +33,9 @@ in this Software without prior written authorization from The Open Group. ...@@ -33,9 +33,9 @@ in this Software without prior written authorization from The Open Group.
/* Read in pending events if needed and return the number of queued events. */ /* Read in pending events if needed and return the number of queued events. */
int XEventsQueued (dpy, mode) int XEventsQueued (
register Display *dpy; register Display *dpy,
int mode; int mode)
{ {
int ret_val; int ret_val;
#if defined(NX_TRANS_SOCKET) && defined(NX_TRANS_TEST) #if defined(NX_TRANS_SOCKET) && defined(NX_TRANS_TEST)
...@@ -54,8 +54,7 @@ int XEventsQueued (dpy, mode) ...@@ -54,8 +54,7 @@ int XEventsQueued (dpy, mode)
return ret_val; return ret_val;
} }
int XPending (dpy) int XPending (register Display *dpy)
register Display *dpy;
{ {
int ret_val; int ret_val;
LockDisplay(dpy); LockDisplay(dpy);
......
...@@ -34,7 +34,7 @@ extern long const _Xevent_to_mask[]; ...@@ -34,7 +34,7 @@ extern long const _Xevent_to_mask[];
#define AllButtons (Button1MotionMask|Button2MotionMask|Button3MotionMask|\ #define AllButtons (Button1MotionMask|Button2MotionMask|Button3MotionMask|\
Button4MotionMask|Button5MotionMask) Button4MotionMask|Button5MotionMask)
/* /*
* Return the next event in the queue * Return the next event in the queue
* for the given window matching one of the events in the mask. * for the given window matching one of the events in the mask.
* Events earlier in the queue are not discarded. * Events earlier in the queue are not discarded.
...@@ -43,23 +43,27 @@ extern long const _Xevent_to_mask[]; ...@@ -43,23 +43,27 @@ extern long const _Xevent_to_mask[];
*/ */
int int
XWindowEvent (dpy, w, mask, event) XWindowEvent (
register Display *dpy; register Display *dpy,
Window w; /* Selected window. */ Window w, /* Selected window. */
long mask; /* Selected event mask. */ long mask, /* Selected event mask. */
register XEvent *event; /* XEvent to be filled in. */ register XEvent *event) /* XEvent to be filled in. */
{ {
register _XQEvent *prev, *qelt; register _XQEvent *prev, *qelt;
unsigned long qe_serial = 0; unsigned long qe_serial = 0;
LockDisplay(dpy); LockDisplay(dpy);
/* Delete unclaimed cookies */
_XFreeEventCookies(dpy);
prev = NULL; prev = NULL;
while (1) { while (1) {
for (qelt = prev ? prev->next : dpy->head; for (qelt = prev ? prev->next : dpy->head;
qelt; qelt;
prev = qelt, qelt = qelt->next) { prev = qelt, qelt = qelt->next) {
if ((qelt->event.xany.window == w) && if ((qelt->event.xany.window == w) &&
(qelt->event.type < LASTEvent) && (qelt->event.type < GenericEvent) &&
(_Xevent_to_mask[qelt->event.type] & mask) && (_Xevent_to_mask[qelt->event.type] & mask) &&
((qelt->event.type != MotionNotify) || ((qelt->event.type != MotionNotify) ||
(mask & AllPointers) || (mask & AllPointers) ||
......
...@@ -59,12 +59,12 @@ from The Open Group. ...@@ -59,12 +59,12 @@ from The Open Group.
/*ARGSUSED*/ /*ARGSUSED*/
Bool Bool
_XAsyncErrorHandler(dpy, rep, buf, len, data) _XAsyncErrorHandler(
register Display *dpy; register Display *dpy,
register xReply *rep; register xReply *rep,
char *buf; char *buf,
int len; int len,
XPointer data; XPointer data)
{ {
register _XAsyncErrorState *state; register _XAsyncErrorState *state;
...@@ -87,9 +87,9 @@ _XAsyncErrorHandler(dpy, rep, buf, len, data) ...@@ -87,9 +87,9 @@ _XAsyncErrorHandler(dpy, rep, buf, len, data)
return False; return False;
} }
void _XDeqAsyncHandler(dpy, handler) void _XDeqAsyncHandler(
Display *dpy; Display *dpy,
register _XAsyncHandler *handler; register _XAsyncHandler *handler)
{ {
register _XAsyncHandler **prev; register _XAsyncHandler **prev;
register _XAsyncHandler *async; register _XAsyncHandler *async;
...@@ -103,14 +103,14 @@ void _XDeqAsyncHandler(dpy, handler) ...@@ -103,14 +103,14 @@ void _XDeqAsyncHandler(dpy, handler)
} }
char * char *
_XGetAsyncReply(dpy, replbuf, rep, buf, len, extra, discard) _XGetAsyncReply(
register Display *dpy; register Display *dpy,
register char *replbuf; /* data is read into this buffer */ register char *replbuf, /* data is read into this buffer */
register xReply *rep; /* value passed to calling handler */ register xReply *rep, /* value passed to calling handler */
char *buf; /* value passed to calling handler */ char *buf, /* value passed to calling handler */
int len; /* value passed to calling handler */ int len, /* value passed to calling handler */
int extra; /* extra words to read, ala _XReply */ int extra, /* extra words to read, ala _XReply */
Bool discard; /* discard after extra?, ala _XReply */ Bool discard) /* discard after extra?, ala _XReply */
{ {
if (extra == 0) { if (extra == 0) {
if (discard && (rep->generic.length << 2) > len) if (discard && (rep->generic.length << 2) > len)
...@@ -125,6 +125,11 @@ _XGetAsyncReply(dpy, replbuf, rep, buf, len, extra, discard) ...@@ -125,6 +125,11 @@ _XGetAsyncReply(dpy, replbuf, rep, buf, len, extra, discard)
_XRead(dpy, replbuf + len, size - len); _XRead(dpy, replbuf + len, size - len);
buf = replbuf; buf = replbuf;
len = size; len = size;
#ifdef MUSTCOPY
} else {
memcpy(replbuf, buf, size);
buf = replbuf;
#endif
} }
if (discard && rep->generic.length > extra && if (discard && rep->generic.length > extra &&
...@@ -133,9 +138,9 @@ _XGetAsyncReply(dpy, replbuf, rep, buf, len, extra, discard) ...@@ -133,9 +138,9 @@ _XGetAsyncReply(dpy, replbuf, rep, buf, len, extra, discard)
return buf; return buf;
} }
/* /*
*if we get here, then extra > rep->generic.length--meaning we *if we get here, then extra > rep->generic.length--meaning we
* read a reply that's shorter than we expected. This is an * read a reply that's shorter than we expected. This is an
* error, but we still need to figure out how to handle it... * error, but we still need to figure out how to handle it...
*/ */
if ((rep->generic.length << 2) > len) if ((rep->generic.length << 2) > len)
...@@ -153,15 +158,15 @@ _XGetAsyncReply(dpy, replbuf, rep, buf, len, extra, discard) ...@@ -153,15 +158,15 @@ _XGetAsyncReply(dpy, replbuf, rep, buf, len, extra, discard)
} }
void void
_XGetAsyncData(dpy, data, buf, len, skip, datalen, discardtotal) _XGetAsyncData(
Display *dpy; Display *dpy,
char *data; /* data is read into this buffer */ char *data, /* data is read into this buffer */
char *buf; /* value passed to calling handler */ char *buf, /* value passed to calling handler */
int len; /* value passed to calling handler */ int len, /* value passed to calling handler */
int skip; /* number of bytes already read in previous int skip, /* number of bytes already read in previous
_XGetAsyncReply or _XGetAsyncData calls */ _XGetAsyncReply or _XGetAsyncData calls */
int datalen; /* size of data buffer in bytes */ int datalen, /* size of data buffer in bytes */
int discardtotal; /* min. bytes to consume (after skip) */ int discardtotal) /* min. bytes to consume (after skip) */
{ {
buf += skip; buf += skip;
len -= skip; len -= skip;
......
/* Copyright (C) 2008 Jamey Sharp, Josh Triplett
* This file is licensed under the MIT license. See the file COPYING.
*
* As Xlibint.h has long become effectively public API, this header exists
* for new private functions that nothing outside of libX11 should call.
*/
#ifndef XPRIVATE_H
#define XPRIVATE_H
extern void _XIDHandler(Display *dpy);
extern void _XSeqSyncFunction(Display *dpy);
extern void _XSetPrivSyncFunction(Display *dpy);
extern void _XSetSeqSyncFunction(Display *dpy);
#ifdef XTHREADS
#if defined(XTHREADS_WARN) || defined(XTHREADS_FILE_LINE)
#define InternalLockDisplay(d,wskip) if ((d)->lock) \
(*(d)->lock->internal_lock_display)(d,wskip,__FILE__,__LINE__)
#else
#define InternalLockDisplay(d,wskip) if ((d)->lock) \
(*(d)->lock->internal_lock_display)(d,wskip)
#endif
#else /* XTHREADS else */
#define InternalLockDisplay(d,wskip)
#endif /* XTHREADS else */
#endif /* XPRIVATE_H */
...@@ -13,7 +13,7 @@ ...@@ -13,7 +13,7 @@
* software without specific, written prior permission. * software without specific, written prior permission.
* *
* IBM DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING * IBM DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
* ALL IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS, AND * ALL IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS, AND
* NONINFRINGEMENT OF THIRD PARTY RIGHTS, IN NO EVENT SHALL * NONINFRINGEMENT OF THIRD PARTY RIGHTS, IN NO EVENT SHALL
* IBM BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR * IBM BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
* ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, * ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
...@@ -32,11 +32,7 @@ ...@@ -32,11 +32,7 @@
#include "Xlibint.h" #include "Xlibint.h"
#include "XlcPubI.h" #include "XlcPubI.h"
#include <nx-X11/Xos.h> #include <nx-X11/Xos.h>
#if 0 #include <unistd.h>
#include <unistd.h> /* in theory delivers getresuid/gid prototypes,
* in practice only the Linux syscall wrapper is there. */
#endif
/************************************************************************/ /************************************************************************/
...@@ -221,7 +217,7 @@ _XlcParsePath( ...@@ -221,7 +217,7 @@ _XlcParsePath(
#define XLOCALEDIR "/usr/lib/X11/locale" #define XLOCALEDIR "/usr/lib/X11/locale"
#endif #endif
static void void
xlocaledir( xlocaledir(
char *buf, char *buf,
int buf_len) int buf_len)
...@@ -268,7 +264,7 @@ xlocaledir( ...@@ -268,7 +264,7 @@ xlocaledir(
priv = 0; priv = 0;
} else { } else {
if (seteuid(oldeuid) == -1) { if (seteuid(oldeuid) == -1) {
/* XXX ouch, coudn't get back to original uid /* XXX ouch, coudn't get back to original uid
what can we do ??? */ what can we do ??? */
_exit(127); _exit(127);
} }
...@@ -299,6 +295,84 @@ xlocaledir( ...@@ -299,6 +295,84 @@ xlocaledir(
buf[buf_len-1] = '\0'; buf[buf_len-1] = '\0';
} }
static void
xlocalelibdir(
char *buf,
int buf_len)
{
char *p = buf;
int len = 0;
#ifndef NO_XLOCALEDIR
char *dir;
int priv = 1;
dir = getenv("XLOCALELIBDIR");
if (dir) {
#ifndef WIN32
/*
* Only use the user-supplied path if the process isn't priviledged.
*/
if (getuid() == geteuid() && getgid() == getegid()) {
#if defined(HASSETUGID)
priv = issetugid();
#elif defined(HASGETRESUID)
{
uid_t ruid, euid, suid;
gid_t rgid, egid, sgid;
if ((getresuid(&ruid, &euid, &suid) == 0) &&
(getresgid(&rgid, &egid, &sgid) == 0))
priv = (euid != suid) || (egid != sgid);
}
#else
/*
* If there are saved ID's the process might still be priviledged
* even though the above test succeeded. If issetugid() and
* getresgid() aren't available, test this by trying to set
* euid to 0.
*
* Note: this only protects setuid-root clients. It doesn't
* protect other setuid or any setgid clients. If this tradeoff
* isn't acceptable, set DisableXLocaleDirEnv to YES in host.def.
*/
unsigned int oldeuid;
oldeuid = geteuid();
if (seteuid(0) != 0) {
priv = 0;
} else {
if (seteuid(oldeuid) == -1) {
/* XXX ouch, coudn't get back to original uid
what can we do ??? */
_exit(127);
}
priv = 1;
}
#endif
}
#else
priv = 0;
#endif
if (!priv) {
len = strlen(dir);
strncpy(p, dir, buf_len);
if (len < buf_len) {
p[len++] = LC_PATHDELIM;
p += len;
}
}
}
#endif /* NO_XLOCALEDIR */
if (len < buf_len)
#ifndef __UNIXOS2__
strncpy(p, XLOCALELIBDIR, buf_len - len);
#else
strncpy(p,__XOS2RedirRoot(XLOCALELIBDIR), buf_len - len);
#endif
buf[buf_len-1] = '\0';
}
/* Mapping direction */ /* Mapping direction */
typedef enum { typedef enum {
LtoR, /* Map first field to second field */ LtoR, /* Map first field to second field */
...@@ -387,11 +461,11 @@ normalize_lcname (const char *name) ...@@ -387,11 +461,11 @@ normalize_lcname (const char *name)
{ {
char *p, *ret; char *p, *ret;
const char *tmp = name; const char *tmp = name;
p = ret = Xmalloc(strlen(name) + 1); p = ret = Xmalloc(strlen(name) + 1);
if (!p) if (!p)
return NULL; return NULL;
if (tmp) { if (tmp) {
while (*tmp && *tmp != '.' && *tmp != '@') while (*tmp && *tmp != '.' && *tmp != '@')
*p++ = *tmp++; *p++ = *tmp++;
...@@ -428,7 +502,10 @@ _XlcFileName( ...@@ -428,7 +502,10 @@ _XlcFileName(
siname = XLC_PUBLIC(lcd, siname); siname = XLC_PUBLIC(lcd, siname);
lowercase(cat, category); if (category)
lowercase(cat, category);
else
cat[0] = '\0';
xlocaledir(dir,XLC_BUFSIZE); xlocaledir(dir,XLC_BUFSIZE);
n = _XlcParsePath(dir, args, NUM_LOCALEDIR); n = _XlcParsePath(dir, args, NUM_LOCALEDIR);
for (i = 0; i < n; ++i) { for (i = 0; i < n; ++i) {
...@@ -483,7 +560,7 @@ _XlcResolveLocaleName( ...@@ -483,7 +560,7 @@ _XlcResolveLocaleName(
xlocaledir (dir, PATH_MAX); xlocaledir (dir, PATH_MAX);
n = _XlcParsePath(dir, args, NUM_LOCALEDIR); n = _XlcParsePath(dir, args, NUM_LOCALEDIR);
for (i = 0; i < n; ++i) { for (i = 0; i < n; ++i) {
if ((2 + (args[i] ? strlen (args[i]) : 0) + if ((2 + (args[i] ? strlen (args[i]) : 0) +
strlen (locale_alias)) < PATH_MAX) { strlen (locale_alias)) < PATH_MAX) {
sprintf (buf, "%s/%s", args[i], locale_alias); sprintf (buf, "%s/%s", args[i], locale_alias);
name = resolve_name (lc_name, buf, LtoR); name = resolve_name (lc_name, buf, LtoR);
...@@ -515,7 +592,7 @@ _XlcResolveLocaleName( ...@@ -515,7 +592,7 @@ _XlcResolveLocaleName(
return 1; return 1;
} }
/* /*
* pub->siname is in the format <lang>_<terr>.<codeset>, typical would * pub->siname is in the format <lang>_<terr>.<codeset>, typical would
* be "en_US.ISO8859-1", "en_US.utf8", "ru_RU.KOI-8", or ja_JP.SJIS, * be "en_US.ISO8859-1", "en_US.utf8", "ru_RU.KOI-8", or ja_JP.SJIS,
* although it could be ja.SJIS too. * although it could be ja.SJIS too.
...@@ -551,9 +628,7 @@ _XlcResolveLocaleName( ...@@ -551,9 +628,7 @@ _XlcResolveLocaleName(
/************************************************************************/ /************************************************************************/
int int
_XlcResolveI18NPath(buf, buf_len) _XlcResolveI18NPath(char *buf, int buf_len)
char *buf;
int buf_len;
{ {
if (buf != NULL) { if (buf != NULL) {
xlocaledir(buf, buf_len); xlocaledir(buf, buf_len);
...@@ -562,10 +637,7 @@ _XlcResolveI18NPath(buf, buf_len) ...@@ -562,10 +637,7 @@ _XlcResolveI18NPath(buf, buf_len)
} }
char * char *
_XlcLocaleDirName(dir_name, dir_len, lc_name) _XlcLocaleDirName(char *dir_name, size_t dir_len, char *lc_name)
char *dir_name;
size_t dir_len;
char *lc_name;
{ {
char dir[PATH_MAX], buf[PATH_MAX], *name = NULL; char dir[PATH_MAX], buf[PATH_MAX], *name = NULL;
int i, n; int i, n;
...@@ -574,12 +646,121 @@ _XlcLocaleDirName(dir_name, dir_len, lc_name) ...@@ -574,12 +646,121 @@ _XlcLocaleDirName(dir_name, dir_len, lc_name)
char *target_name = (char*)0; char *target_name = (char*)0;
char *target_dir = (char*)0; char *target_dir = (char*)0;
char *nlc_name = NULL; char *nlc_name = NULL;
static char* last_dir_name = 0;
static size_t last_dir_len = 0;
static char* last_lc_name = 0;
if (last_lc_name != 0 && strcmp (last_lc_name, lc_name) == 0
&& dir_len >= last_dir_len) {
strcpy (dir_name, last_dir_name);
return dir_name;
}
xlocaledir (dir, PATH_MAX); xlocaledir (dir, PATH_MAX);
n = _XlcParsePath(dir, args, 256); n = _XlcParsePath(dir, args, 256);
for (i = 0; i < n; ++i) { for (i = 0; i < n; ++i) {
if ((2 + (args[i] ? strlen(args[i]) : 0) + if ((2 + (args[i] ? strlen(args[i]) : 0) +
strlen(locale_alias)) < PATH_MAX) {
sprintf (buf, "%s/%s", args[i], locale_alias);
name = resolve_name(lc_name, buf, LtoR);
if (!name) {
if (!nlc_name)
nlc_name = normalize_lcname(lc_name);
if (nlc_name)
name = resolve_name (nlc_name, buf, LtoR);
}
}
/* If name is not an alias, use lc_name for locale.dir search */
if (name == NULL)
name = lc_name;
/* look at locale.dir */
target_dir = args[i];
if (!target_dir) {
/* something wrong */
if (name != lc_name)
Xfree(name);
continue;
}
if ((1 + (target_dir ? strlen (target_dir) : 0) +
strlen("locale.dir")) < PATH_MAX) {
sprintf(buf, "%s/locale.dir", target_dir);
target_name = resolve_name(name, buf, RtoL);
}
if (name != lc_name)
Xfree(name);
if (target_name != NULL) {
char *p = 0;
if ((p = strstr(target_name, "/XLC_LOCALE"))) {
*p = '\0';
break;
}
Xfree(target_name);
target_name = NULL;
}
name = NULL;
}
if (nlc_name) Xfree(nlc_name);
if (target_name == NULL) {
/* vendor locale name == Xlocale name, no expansion of alias */
target_dir = args[0];
target_name = lc_name;
}
/* snprintf(dir_name, dir_len, "%s/%", target_dir, target_name); */
strncpy(dir_name, target_dir, dir_len - 1);
if (strlen(target_dir) >= dir_len - 1) {
dir_name[dir_len - 1] = '\0';
} else {
strcat(dir_name, "/");
strncat(dir_name, target_name, dir_len - strlen(dir_name) - 1);
if (strlen(target_name) >= dir_len - strlen(dir_name) - 1)
dir_name[dir_len - 1] = '\0';
}
if (target_name != lc_name)
Xfree(target_name);
if (last_dir_name != 0)
Xfree (last_dir_name);
if (last_lc_name != 0)
Xfree (last_lc_name);
last_dir_len = strlen (dir_name) + 1;
last_dir_name = Xmalloc (last_dir_len);
strcpy (last_dir_name, dir_name);
last_lc_name = Xmalloc (strlen (lc_name) + 1);
strcpy (last_lc_name, lc_name);
return dir_name;
}
char *
_XlcLocaleLibDirName(char *dir_name, size_t dir_len, char *lc_name)
{
char dir[PATH_MAX], buf[PATH_MAX], *name = NULL;
int i, n;
char *args[NUM_LOCALEDIR];
static char locale_alias[] = LOCALE_ALIAS;
char *target_name = (char*)0;
char *target_dir = (char*)0;
char *nlc_name = NULL;
static char* last_dir_name = 0;
static size_t last_dir_len = 0;
static char* last_lc_name = 0;
if (last_lc_name != 0 && strcmp (last_lc_name, lc_name) == 0
&& dir_len >= last_dir_len) {
strcpy (dir_name, last_dir_name);
return dir_name;
}
xlocalelibdir (dir, PATH_MAX);
n = _XlcParsePath(dir, args, 256);
for (i = 0; i < n; ++i) {
if ((2 + (args[i] ? strlen(args[i]) : 0) +
strlen(locale_alias)) < PATH_MAX) { strlen(locale_alias)) < PATH_MAX) {
sprintf (buf, "%s/%s", args[i], locale_alias); sprintf (buf, "%s/%s", args[i], locale_alias);
name = resolve_name(lc_name, buf, LtoR); name = resolve_name(lc_name, buf, LtoR);
...@@ -590,13 +771,13 @@ _XlcLocaleDirName(dir_name, dir_len, lc_name) ...@@ -590,13 +771,13 @@ _XlcLocaleDirName(dir_name, dir_len, lc_name)
name = resolve_name (nlc_name, buf, LtoR); name = resolve_name (nlc_name, buf, LtoR);
} }
} }
/* If name is not an alias, use lc_name for locale.dir search */ /* If name is not an alias, use lc_name for locale.dir search */
if (name == NULL) if (name == NULL)
name = lc_name; name = lc_name;
/* look at locale.dir */ /* look at locale.dir */
target_dir = args[i]; target_dir = args[i];
if (!target_dir) { if (!target_dir) {
/* something wrong */ /* something wrong */
...@@ -636,10 +817,21 @@ _XlcLocaleDirName(dir_name, dir_len, lc_name) ...@@ -636,10 +817,21 @@ _XlcLocaleDirName(dir_name, dir_len, lc_name)
} else { } else {
strcat(dir_name, "/"); strcat(dir_name, "/");
strncat(dir_name, target_name, dir_len - strlen(dir_name) - 1); strncat(dir_name, target_name, dir_len - strlen(dir_name) - 1);
if (strlen(target_name) >= dir_len - strlen(dir_name) - 1) if (strlen(target_name) >= dir_len - strlen(dir_name) - 1)
dir_name[dir_len - 1] = '\0'; dir_name[dir_len - 1] = '\0';
} }
if (target_name != lc_name) if (target_name != lc_name)
Xfree(target_name); Xfree(target_name);
if (last_dir_name != 0)
Xfree (last_dir_name);
if (last_lc_name != 0)
Xfree (last_lc_name);
last_dir_len = strlen (dir_name) + 1;
last_dir_name = Xmalloc (last_dir_len);
strcpy (last_dir_name, dir_name);
last_lc_name = Xmalloc (strlen (lc_name) + 1);
strcpy (last_lc_name, lc_name);
return dir_name; return dir_name;
} }
/*
Copyright (c) 2007-2009, Troy D. Hanson
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef UTLIST_H
#define UTLIST_H
#define UTLIST_VERSION 1.7
/* From: http://uthash.sourceforge.net/utlist.html */
/*
* This file contains macros to manipulate singly and doubly-linked lists.
*
* 1. LL_ macros: singly-linked lists.
* 2. DL_ macros: doubly-linked lists.
* 3. CDL_ macros: circular doubly-linked lists.
*
* To use singly-linked lists, your structure must have a "next" pointer.
* To use doubly-linked lists, your structure must "prev" and "next" pointers.
* Either way, the pointer to the head of the list must be initialized to NULL.
*
* ----------------.EXAMPLE -------------------------
* struct item {
* int id;
* struct item *prev, *next;
* }
*
* struct item *list = NULL:
*
* int main() {
* struct item *item;
* ... allocate and populate item ...
* DL_APPEND(list, item);
* }
* --------------------------------------------------
*
* For doubly-linked lists, the append and delete macros are O(1)
* For singly-linked lists, append and delete are O(n) but prepend is O(1)
* The sort macro is O(n log(n)) for all types of single/double/circular lists.
*/
/******************************************************************************
* doubly linked list macros (non-circular) *
*****************************************************************************/
#define DL_PREPEND(head,add) \
do { \
(add)->next = head; \
if (head) { \
(add)->prev = (head)->prev; \
(head)->prev = (add); \
} else { \
(add)->prev = (add); \
} \
(head) = (add); \
} while (0)
#define DL_APPEND(head,add) \
do { \
if (head) { \
(add)->prev = (head)->prev; \
(head)->prev->next = (add); \
(head)->prev = (add); \
(add)->next = NULL; \
} else { \
(head)=(add); \
(head)->prev = (head); \
(head)->next = NULL; \
} \
} while (0);
#define DL_DELETE(head,del) \
do { \
if ((del)->prev == (del)) { \
(head)=NULL; \
} else if ((del)==(head)) { \
(del)->next->prev = (del)->prev; \
(head) = (del)->next; \
} else { \
(del)->prev->next = (del)->next; \
if ((del)->next) { \
(del)->next->prev = (del)->prev; \
} else { \
(head)->prev = (del)->prev; \
} \
} \
} while (0);
#define DL_FOREACH(head,el) \
for(el=head;el;el=el->next)
#define DL_FOREACH_SAFE(head,el,tmp) \
for(el=head,tmp=el->next;el;el=tmp,tmp=(el) ? (el->next) : NULL)
#endif /* UTLIST_H */
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment