~peter-pearse/ubuntu/oneiric/x11-utils/prop001

« back to all changes in this revision

Viewing changes to luit/sys.c

  • Committer: Bazaar Package Importer
  • Author(s): Julien Cristau
  • Date: 2011-02-09 20:34:01 UTC
  • mfrom: (3.1.5 sid)
  • Revision ID: james.westby@ubuntu.com-20110209203401-43knowb75duvo9td
Tags: 7.6+1
* Remove David Nusinow and Brice Goglin from Uploaders.  Thanks for your
  work!
* Drop Pre-Depends on x11-common.
* Bump Standards-Version to 3.9.1.
* Upload to unstable.

Show diffs side-by-side

added added

removed removed

Lines of Context:
19
19
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
20
20
THE SOFTWARE.
21
21
*/
22
 
/* $XFree86: xc/programs/luit/sys.c,v 1.9 2003/08/17 20:39:58 dawes Exp $ */
 
22
 
 
23
#ifdef HAVE_CONFIG_H
 
24
# include "config.h"
 
25
#endif
23
26
 
24
27
#include <stdlib.h>
25
28
#include <string.h>
34
37
#include <signal.h>
35
38
#include <errno.h>
36
39
 
37
 
#ifdef HAVE_CONFIG_H
38
 
# include "config.h"
39
 
#endif
40
 
 
41
 
#ifdef HAVE_POLL
 
40
#ifdef HAVE_WORKING_POLL
 
41
#ifdef HAVE_POLL_H
 
42
#include <poll.h>
 
43
#else
42
44
#include <sys/poll.h>
 
45
#endif
43
46
#undef HAVE_SELECT
44
47
#endif
45
48
 
46
 
#ifdef HAVE_SYS_SELECT_H
47
 
# include <sys/select.h>
 
49
#ifdef HAVE_SELECT
 
50
#if !(defined(_MINIX) || defined(__BEOS__))
 
51
#define HAVE_WORKING_SELECT 1
 
52
#endif
 
53
#endif
 
54
 
 
55
#ifdef HAVE_WORKING_SELECT
 
56
#if defined(HAVE_SYS_SELECT_H) && defined(HAVE_SYS_TIME_SELECT)
 
57
#include <sys/select.h>
 
58
#endif
48
59
#endif
49
60
 
50
61
#ifdef HAVE_PTY_H
51
 
# include <pty.h>
 
62
#include <pty.h>
52
63
#endif
53
64
 
54
65
#ifdef HAVE_STROPTS_H
55
 
# include <stropts.h>
56
 
#endif
57
 
 
58
 
#ifdef HAVE_SYS_PARAM_H
59
 
# include <sys/param.h>
60
 
#endif
 
66
#include <stropts.h>
 
67
#endif
 
68
 
 
69
#ifdef HAVE_SYS_PARAM
 
70
#include <sys/param.h>
 
71
#endif
 
72
 
 
73
#ifdef HAVE_OPENPTY
 
74
#if defined(HAVE_UTIL_H)
 
75
#include <util.h>
 
76
#elif defined(HAVE_LIBUTIL_H)
 
77
#include <libutil.h>
 
78
#elif defined(HAVE_PTY_H)
 
79
#include <pty.h>
 
80
#endif
 
81
#endif /* HAVE_OPENPTY */
61
82
 
62
83
#include "sys.h"
63
84
 
 
85
#ifdef USE_IGNORE_RC
 
86
int ignore_unused;
 
87
#endif
 
88
 
 
89
#if defined(HAVE_OPENPTY)
 
90
static int opened_tty = -1;
 
91
#endif
 
92
 
64
93
static int saved_tio_valid = 0;
65
94
static struct termios saved_tio;
66
95
 
67
 
 
68
 
#ifdef HAVE_POLL
69
96
int
70
97
waitForOutput(int fd)
71
98
{
 
99
    int ret = 0;
 
100
 
 
101
#if defined(HAVE_WORKING_POLL)
72
102
    struct pollfd pfd[1];
73
103
    int rc;
74
104
 
77
107
    pfd[0].revents = 0;
78
108
 
79
109
    rc = poll(pfd, 1, -1);
80
 
    if(rc < 0)
81
 
        return -1;
82
 
 
83
 
    if(pfd[0].revents & POLLOUT)
84
 
        return 1;
85
 
 
86
 
    return 0;
 
110
    if (rc < 0)
 
111
        ret = -1;
 
112
    else if (pfd[0].revents & (POLLOUT | POLLERR | POLLHUP))
 
113
        ret = 1;
 
114
 
 
115
#elif defined(HAVE_WORKING_SELECT)
 
116
    fd_set fds;
 
117
    int rc;
 
118
 
 
119
    FD_ZERO(&fds);
 
120
    FD_SET(fd, &fds);
 
121
    rc = select(FD_SETSIZE, NULL, &fds, NULL, NULL);
 
122
    if (rc < 0)
 
123
        ret = -1;
 
124
    else if (FD_ISSET(fd, &fds))
 
125
        ret = 1;
 
126
 
 
127
#else
 
128
    ret = 1;
 
129
#endif
 
130
 
 
131
    return ret;
87
132
}
88
133
 
89
134
int
90
135
waitForInput(int fd1, int fd2)
91
136
{
 
137
    int ret = 0;
 
138
 
 
139
#if defined(HAVE_WORKING_POLL)
92
140
    struct pollfd pfd[2];
93
 
    int ret, rc;
 
141
    int rc;
94
142
 
95
143
    pfd[0].fd = fd1;
96
144
    pfd[1].fd = fd2;
98
146
    pfd[0].revents = pfd[1].revents = 0;
99
147
 
100
148
    rc = poll(pfd, 2, -1);
101
 
    if(rc < 0)
102
 
        return -1;
103
 
 
104
 
    ret = 0;
105
 
    if(pfd[0].revents & (POLLIN | POLLERR | POLLHUP))
106
 
        ret |= 1;
107
 
    if(pfd[1].revents & (POLLIN | POLLERR | POLLHUP))
108
 
        ret |= 2;
109
 
    return ret;
110
 
}
111
 
#endif
112
 
 
113
 
#ifdef HAVE_SELECT
114
 
int
115
 
waitForOutput(int fd)
116
 
{
 
149
    if (rc < 0) {
 
150
        ret = -1;
 
151
    } else {
 
152
        if (pfd[0].revents & (POLLIN | POLLERR | POLLHUP))
 
153
            ret |= 1;
 
154
        if (pfd[1].revents & (POLLIN | POLLERR | POLLHUP))
 
155
            ret |= 2;
 
156
    }
 
157
 
 
158
#elif defined(HAVE_WORKING_SELECT)
117
159
    fd_set fds;
118
160
    int rc;
119
161
 
120
162
    FD_ZERO(&fds);
121
 
    FD_SET(fd, &fds);
122
 
    rc = select(FD_SETSIZE, NULL, &fds, NULL, NULL);
123
 
    if(rc < 0)
124
 
        return -1;
125
 
 
126
 
    if(FD_ISSET(fd, &fds))
127
 
        return 1;
128
 
 
129
 
    return 0;
130
 
}
131
 
 
132
 
int
133
 
waitForInput(int fd1, int fd2)
134
 
{
135
 
    fd_set fds;
136
 
    int ret, rc;
137
 
 
138
 
    FD_ZERO(&fds);
139
163
    FD_SET(fd1, &fds);
140
164
    FD_SET(fd2, &fds);
141
165
    rc = select(FD_SETSIZE, &fds, NULL, NULL, NULL);
142
 
    if(rc < 0)
143
 
        return -1;
 
166
    if (rc < 0) {
 
167
        ret = -1;
 
168
    } else {
 
169
        if (FD_ISSET(fd1, &fds))
 
170
            ret |= 1;
 
171
        if (FD_ISSET(fd2, &fds))
 
172
            ret |= 2;
 
173
    }
 
174
#else
 
175
    ret = (1 | 2);
 
176
#endif
144
177
 
145
 
    ret = 0;
146
 
    if(FD_ISSET(fd1, &fds))
147
 
        ret |= 1;
148
 
    if(FD_ISSET(fd2, &fds))
149
 
        ret |= 2;
150
178
    return ret;
151
179
}
152
 
#endif
153
 
 
154
 
#ifndef HAVE_POLL
155
 
#ifndef HAVE_SELECT
156
 
/* Busy looping implementation */
157
 
int
158
 
waitForOutput(int fd)
159
 
{
160
 
    return 1;
161
 
}
162
 
 
163
 
int
164
 
waitForInput(int fd1, int fd2)
165
 
{
166
 
    return 1|2;
167
 
}
168
 
#endif
169
 
#endif
170
 
 
171
180
 
172
181
int
173
182
setWindowSize(int sfd, int dfd)
175
184
#ifdef TIOCGWINSZ
176
185
    int rc;
177
186
    struct winsize ws;
178
 
    rc = ioctl(sfd, TIOCGWINSZ, (char*)&ws);
179
 
    if(rc < 0)
180
 
        return -1;
181
 
    rc = ioctl(dfd, TIOCSWINSZ, (char*)&ws);
182
 
    if(rc < 0)
183
 
        return -1;
 
187
    rc = ioctl(sfd, TIOCGWINSZ, (char *) &ws);
 
188
    if (rc < 0)
 
189
        return -1;
 
190
    rc = ioctl(dfd, TIOCSWINSZ, (char *) &ws);
 
191
    if (rc < 0)
 
192
        return -1;
184
193
#endif
185
194
    return 0;
186
195
}
187
196
 
188
197
int
189
 
installHandler(int signum, void (*handler)(int))
 
198
installHandler(int signum, void (*handler) (int))
190
199
{
191
200
    struct sigaction sa;
192
201
    sigset_t ss;
208
217
    int rc;
209
218
 
210
219
    rc = tcgetattr(sfd, &tio);
211
 
    if(rc < 0)
212
 
        return -1;
 
220
    if (rc < 0)
 
221
        return -1;
213
222
 
214
223
    rc = tcsetattr(dfd, TCSAFLUSH, &tio);
215
 
    if(rc < 0)
216
 
        return -1;
 
224
    if (rc < 0)
 
225
        return -1;
217
226
 
218
227
    return 0;
219
228
}
223
232
{
224
233
    int rc;
225
234
    rc = tcgetattr(0, &saved_tio);
226
 
    if(rc >= 0)
227
 
        saved_tio_valid = 1;
 
235
    if (rc >= 0)
 
236
        saved_tio_valid = 1;
228
237
    return rc;
229
238
}
230
239
 
231
240
int
232
241
restoreTermios(void)
233
242
{
234
 
    if(!saved_tio_valid)
235
 
        return -1;
 
243
    if (!saved_tio_valid)
 
244
        return -1;
236
245
    return tcsetattr(0, TCSAFLUSH, &saved_tio);
237
246
}
238
247
 
242
251
    struct termios tio;
243
252
    int rc;
244
253
 
245
 
    if(!saved_tio_valid)
246
 
        saveTermios();
 
254
    if (!saved_tio_valid)
 
255
        saveTermios();
247
256
    rc = tcgetattr(0, &tio);
248
 
    if(rc < 0)
249
 
        return rc;
250
 
    tio.c_lflag &= ~(ECHO|ICANON|ISIG);
251
 
    tio.c_iflag &= ~(ICRNL|IXOFF|IXON|ISTRIP);
 
257
    if (rc < 0)
 
258
        return rc;
 
259
    tio.c_lflag &= (unsigned) ~(ECHO | ICANON | ISIG);
 
260
    tio.c_iflag &= (unsigned) ~(ICRNL | IXOFF | IXON | ISTRIP);
252
261
#ifdef ONLCR
253
 
    tio.c_oflag &= ~ONLCR;
 
262
    tio.c_oflag &= (unsigned) ~ONLCR;
254
263
#endif
255
264
#ifdef OCRNL
256
 
    tio.c_oflag &= ~OCRNL;
 
265
    tio.c_oflag &= (unsigned) ~OCRNL;
257
266
#endif
258
267
#ifdef ONOCR
259
 
    tio.c_oflag &= ~ONOCR;
 
268
    tio.c_oflag &= (unsigned) ~ONOCR;
260
269
#endif
261
270
 
262
271
#ifdef VMIN
264
273
    tio.c_cc[VTIME] = 0;
265
274
#endif
266
275
    rc = tcsetattr(0, TCSAFLUSH, &tio);
267
 
    if(rc < 0)
268
 
        return rc;
 
276
    if (rc < 0)
 
277
        return rc;
269
278
    return 0;
270
279
}
271
280
 
272
 
 
273
281
char *
274
282
my_basename(char *path)
275
283
{
276
284
    char *p;
277
285
 
278
286
    p = strrchr(path, '/');
279
 
    if(!p)
280
 
        p = path;
 
287
    if (!p)
 
288
        p = path;
281
289
    else
282
 
        p++;
 
290
        p++;
283
291
    return p;
284
292
}
285
293
 
288
296
{
289
297
    int rc;
290
298
    struct stat s;
291
 
    int uid = getuid(), gid = getgid();
292
299
 
293
300
    rc = stat(line, &s);
294
 
    if(rc < 0)
295
 
        return -1;
296
 
    if(s.st_uid != uid || s.st_gid != gid) {
297
 
        rc = chown(line, getuid(), getgid());
298
 
        if(rc < 0) {
299
 
            fprintf(stderr, 
300
 
                    "Warning: could not change ownership of tty -- "
301
 
                    "pty is insecure!\n");
302
 
            return 0;
303
 
        }
 
301
    if (rc < 0)
 
302
        return -1;
 
303
    if (s.st_uid != getuid() || s.st_gid != getgid()) {
 
304
        rc = chown(line, getuid(), getgid());
 
305
        if (rc < 0) {
 
306
            fprintf(stderr,
 
307
                    "Warning: could not change ownership of tty -- "
 
308
                    "pty is insecure!\n");
 
309
            return 0;
 
310
        }
304
311
    }
305
 
    if((s.st_mode & 0777) != (S_IRUSR | S_IWUSR | S_IWGRP)) {
306
 
        rc = chmod(line, S_IRUSR | S_IWUSR | S_IWGRP);
307
 
        if (rc < 0) {
308
 
            fprintf(stderr,
309
 
                    "Warning: could not change permissions of tty -- "
310
 
                    "pty is insecure!\n");
311
 
            return 0;
312
 
        }
 
312
    if ((s.st_mode & 0777) != (S_IRUSR | S_IWUSR | S_IWGRP)) {
 
313
        rc = chmod(line, S_IRUSR | S_IWUSR | S_IWGRP);
 
314
        if (rc < 0) {
 
315
            fprintf(stderr,
 
316
                    "Warning: could not change permissions of tty -- "
 
317
                    "pty is insecure!\n");
 
318
            return 0;
 
319
        }
313
320
    }
314
321
    return 1;
315
322
}
319
326
{
320
327
    char name[12], *line = NULL;
321
328
    int pty = -1;
322
 
    char *name1 = "pqrstuvwxyzPQRST", 
323
 
        *name2 = "0123456789abcdefghijklmnopqrstuv";
324
 
    char *p1, *p2;
 
329
    const char *name1 = "pqrstuvwxyzPQRST";
 
330
    char buffer[80];
 
331
    char *name2 = strcpy(buffer, "0123456789abcdefghijklmnopqrstuv");
 
332
    const char *p1;
 
333
    char *p2;
325
334
 
326
 
#ifdef HAVE_GRANTPT
327
 
    char *temp_line;
 
335
#if defined(HAVE_GRANTPT)
328
336
    int rc;
329
337
 
330
 
#ifdef __APPLE__
331
 
    pty = posix_openpt(O_RDWR);
332
 
#else
333
338
    pty = open("/dev/ptmx", O_RDWR);
334
 
#endif
335
 
 
336
 
    if(pty < 0)
337
 
        goto bsd;
 
339
    if (pty < 0)
 
340
        goto bsd;
338
341
 
339
342
    rc = grantpt(pty);
340
 
    if(rc < 0) {
341
 
        close(pty);
342
 
        goto bsd;
 
343
    if (rc < 0) {
 
344
        close(pty);
 
345
        goto bsd;
343
346
    }
344
347
 
345
348
    rc = unlockpt(pty);
346
 
    if(rc < 0) {
347
 
        close(pty);
348
 
        goto bsd;
349
 
    }
350
 
 
351
 
    temp_line = ptsname(pty);
352
 
    if(!temp_line) {
353
 
        close(pty);
354
 
        goto bsd;
355
 
    }
356
 
    line = strdup(temp_line);
357
 
    if(!line) {
358
 
        close(pty);
359
 
        return -1;
360
 
    }
361
 
 
362
 
    fix_pty_perms(line);
363
 
 
364
 
    *pty_return = pty;
365
 
    *line_return = line;
366
 
    return 0;
367
 
 
368
 
  bsd:
369
 
#endif /* HAVE_GRANTPT */
 
349
    if (rc < 0) {
 
350
        close(pty);
 
351
        goto bsd;
 
352
    }
 
353
 
 
354
    line = strmalloc(ptsname(pty));
 
355
    if (!line) {
 
356
        close(pty);
 
357
        goto bsd;
 
358
    }
 
359
 
 
360
    fix_pty_perms(line);
 
361
 
 
362
    *pty_return = pty;
 
363
    *line_return = line;
 
364
    return 0;
 
365
 
 
366
  bsd:
 
367
#elif defined(HAVE_OPENPTY)
 
368
    int rc;
 
369
    char ttydev[80];            /* OpenBSD says at least 16 bytes */
 
370
 
 
371
    rc = openpty(&pty, &opened_tty, ttydev, NULL, NULL);
 
372
    if (rc < 0) {
 
373
        close(pty);
 
374
        goto bsd;
 
375
    }
 
376
    line = strmalloc(ttydev);
 
377
    if (!line) {
 
378
        close(pty);
 
379
        goto bsd;
 
380
    }
 
381
 
 
382
    fix_pty_perms(line);
 
383
 
 
384
    *pty_return = pty;
 
385
    *line_return = line;
 
386
    return 0;
 
387
 
 
388
  bsd:
 
389
#endif /* HAVE_GRANTPT, etc */
370
390
 
371
391
    strcpy(name, "/dev/pty??");
372
 
    for(p1 = name1; *p1; p1++) {
373
 
        name[8] = *p1;
374
 
        for(p2 = name2; *p2; p2++) {
375
 
            name[9] = *p2;
376
 
            pty = open(name, O_RDWR);
377
 
            if(pty >= 0)
378
 
                goto found;
379
 
            /* Systems derived from 4.4BSD differ in their pty names,
380
 
               so ENOENT doesn't necessarily imply we're done. */
381
 
            continue;
382
 
        }
 
392
    for (p1 = name1; *p1; p1++) {
 
393
        name[8] = *p1;
 
394
        for (p2 = name2; *p2; p2++) {
 
395
            name[9] = *p2;
 
396
            pty = open(name, O_RDWR);
 
397
            if (pty >= 0)
 
398
                goto found;
 
399
            /* Systems derived from 4.4BSD differ in their pty names,
 
400
               so ENOENT doesn't necessarily imply we're done. */
 
401
            continue;
 
402
        }
383
403
    }
384
404
 
385
405
    goto bail;
386
406
 
387
407
  found:
388
 
    line = strdup(name);
389
 
    if(!line)
390
 
        goto bail;
391
 
    line[5] = 't';
392
 
    fix_pty_perms(line);
393
 
    *pty_return = pty;
394
 
    *line_return = line;
395
 
    return 0;
 
408
    if ((line = strmalloc(name)) != 0) {
 
409
        line[5] = 't';
 
410
        fix_pty_perms(line);
 
411
        *pty_return = pty;
 
412
        *line_return = line;
 
413
        return 0;
 
414
    }
396
415
 
397
416
  bail:
398
 
    if(pty >= 0)
399
 
        close(pty);
400
 
    if(line)
401
 
        free(line);
 
417
    if (pty >= 0)
 
418
        close(pty);
 
419
    if (line)
 
420
        free(line);
402
421
    return -1;
403
422
}
404
423
 
408
427
    int rc;
409
428
    int tty = -1;
410
429
 
411
 
#if !defined(O_NOCTTY) || !defined(TIOCSCTTY)
412
 
    /* e.g. Cygwin has a working O_NOCTTY but no TIOCSCTTY, so the tty
413
 
       must be opened as controlling */
414
 
    tty = open(line, O_RDWR);
415
 
#else
416
 
    /* The TIOCSCTTY ioctl below will fail if the process already has a
417
 
       controlling tty (even if the current controlling tty is the same
418
 
       as the tty you want to make controlling).  So we need to open
419
 
       the tty with O_NOCTTY to make sure this doesn't happen. */
420
 
    tty = open(line, O_RDWR | O_NOCTTY);
421
 
#endif
422
 
 
423
 
    if(tty < 0)
424
 
        goto bail;
 
430
    tty = open(line, O_RDWR
 
431
#if defined(TIOCSCTTY) && defined(O_NOCTTY)
 
432
    /*
 
433
     * Do not make this our controlling terminal, yet just in case it fails
 
434
     * in some intermediate state.  But do not add this flag if we haven't
 
435
     * the corresponding ioctl.
 
436
     */
 
437
               | O_NOCTTY
 
438
#endif
 
439
        );
 
440
 
 
441
    if (tty < 0)
 
442
        goto bail;
 
443
 
 
444
#if defined(HAVE_OPENPTY)
 
445
    if (opened_tty >= 0) {
 
446
        close(opened_tty);
 
447
        opened_tty = -1;
 
448
    }
 
449
#endif
425
450
 
426
451
#ifdef TIOCSCTTY
427
 
    rc = ioctl(tty, TIOCSCTTY, (char *)0);
428
 
    if(rc < 0) {
429
 
        goto bail;
 
452
    /*
 
453
     * Now that we've successfully opened the terminal, make it the controlling
 
454
     * terminal.  This call works only if the process does not already have a
 
455
     * controlling terminal.
 
456
     *
 
457
     * Cygwin as of 2009/10/12 lacks this call, but has O_NOCTTY.
 
458
     */
 
459
    rc = ioctl(tty, TIOCSCTTY, (char *) 0);
 
460
    if (rc < 0) {
 
461
        goto bail;
430
462
    }
431
463
#endif
432
464
 
433
 
#if defined(SVR4) || defined(__SVR4)
 
465
#if defined(I_PUSH) && (defined(SVR4) || defined(__SVR4))
434
466
    rc = ioctl(tty, I_PUSH, "ptem");
435
 
    if(rc < 0)
436
 
        goto bail;
 
467
    if (rc < 0)
 
468
        goto bail;
437
469
 
438
470
    rc = ioctl(tty, I_PUSH, "ldterm");
439
 
    if(rc < 0)
440
 
        goto bail;
 
471
    if (rc < 0)
 
472
        goto bail;
441
473
 
442
474
    rc = ioctl(tty, I_PUSH, "ttcompat");
443
 
    if(rc < 0)
444
 
        goto bail;
 
475
    if (rc < 0)
 
476
        goto bail;
445
477
#endif
446
478
 
447
479
    return tty;
448
480
 
449
481
  bail:
450
 
    if(tty >= 0)
451
 
        close(tty);
 
482
    if (tty >= 0)
 
483
        close(tty);
452
484
    return -1;
453
485
}
454
486
 
455
487
/* Post-4.4 BSD systems have POSIX semantics (_POSIX_SAVED_IDS
456
488
   or not, depending on the version).  4.3BSD and Minix do not have
457
489
   saved IDs at all, so there's no issue. */
 
490
int
 
491
droppriv(void)
 
492
{
 
493
    int rc;
458
494
#if (defined(BSD) && !defined(_POSIX_SAVED_IDS)) || defined(_MINIX)
459
 
int
460
 
droppriv(void)
461
 
{
462
 
    int rc;
463
495
    rc = setuid(getuid());
464
 
    if(rc < 0)
465
 
        return rc;
466
 
    return setgid(getgid());
467
 
}
 
496
    if (rc >= 0) {
 
497
        rc = setgid(getgid());
 
498
    }
468
499
#elif defined(_POSIX_SAVED_IDS)
469
 
int
470
 
droppriv(void)
471
 
{
472
 
    int uid = getuid();
473
 
    int euid = geteuid();
474
 
    int gid = getgid();
475
 
    int egid = getegid();
476
 
    int rc;
477
 
 
478
 
    if((uid != euid || gid != egid) && euid != 0) {
479
 
        errno = ENOSYS;
480
 
        return -1;
481
 
    }
482
 
    rc = setuid(uid);
483
 
    if(rc < 0)
484
 
        return rc;
485
 
    return setgid(gid);
486
 
}
487
 
#else
488
 
int
489
 
droppriv(void)
490
 
{
491
 
    int uid = getuid();
492
 
    int euid = geteuid();
493
 
    int gid = getgid();
494
 
    int egid = getegid();
495
 
 
496
 
    if(uid != euid || gid != egid) {
497
 
        errno = ENOSYS;
498
 
        return -1;
499
 
    }
500
 
    return 0;
501
 
}
502
 
#endif    
 
500
    uid_t uid = getuid();
 
501
    uid_t euid = geteuid();
 
502
    gid_t gid = getgid();
 
503
    gid_t egid = getegid();
 
504
 
 
505
    if ((uid != euid || gid != egid) && euid != 0) {
 
506
        errno = ENOSYS;
 
507
        rc = -1;
 
508
    } else {
 
509
        rc = setuid(uid);
 
510
        if (rc >= 0)
 
511
            rc = setgid(gid);
 
512
    }
 
513
#else
 
514
    uid_t uid = getuid();
 
515
    uid_t euid = geteuid();
 
516
    gid_t gid = getgid();
 
517
    gid_t egid = getegid();
 
518
 
 
519
    if (uid != euid || gid != egid) {
 
520
        errno = ENOSYS;
 
521
        rc = -1;
 
522
    } else {
 
523
        rc = 0;
 
524
    }
 
525
#endif
 
526
    return rc;
 
527
}
 
528
 
 
529
char *
 
530
strmalloc(const char *value)
 
531
{
 
532
    char *result = 0;
 
533
 
 
534
    if (value != 0) {
 
535
#ifdef HAVE_STRDUP
 
536
        result = strdup(value);
 
537
#else
 
538
        result = malloc(strlen(value) + 1);
 
539
        if (result != 0)
 
540
            strcpy(result, value);
 
541
#endif
 
542
    }
 
543
    return result;
 
544
}
 
545
 
 
546
#ifdef NO_LEAKS
 
547
void
 
548
ExitProgram(int code)
 
549
{
 
550
    luit_leaks();
 
551
    iso2022_leaks();
 
552
    charset_leaks();
 
553
    exit(code);
 
554
}
 
555
#endif