~ubuntu-branches/ubuntu/wily/splitvt/wily

« back to all changes in this revision

Viewing changes to .pc/old.changes.patch/misc.c

  • Committer: Bazaar Package Importer
  • Author(s): Mònica Ramírez Arceda
  • Date: 2011-02-13 00:21:26 UTC
  • Revision ID: james.westby@ubuntu.com-20110213002126-dl9ggx3zwvpu0awj
Tags: 1.6.6-8
* Adopt the package. (Closes: #489450)
* Switch to quilt format: add old.changes.patch.
* Tidy up debian/copyright: organize it in sections, add copyright
  notice, add GPL version and add myself as a Debian mantainer.
* Manpage:
  - Change - by \- to use minus sign instead of hyphen in manpage 
    (fix.man.minus.sign.patch).
  - Add .TB macro (fix.man.macro.not.defined.patch).
* Override lintian warning (setgid-binary): splitvt needs write 
  access to /var/run/utmp file.
* Add debian/install, debian/docs, debian/examples and
  debian/splitvt.manpages in order to minimize debian/rules.
* Update debian/rules to use overrides of dh_*.
* Delete Homepage field in debian/control and debian/watch: 
  upstream site doesn't exist any more.
* Bump to Standards-Version 3.9.1. No changes required.
* Add Vcs-Git, Vcs-Browser fields in debian/control.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/* Miscellaneous system dependent routines for splitsh */
 
2
 
 
3
#include        <sys/types.h>
 
4
#include        <sys/stat.h>
 
5
#include        <fcntl.h>
 
6
#include        <stdio.h>
 
7
#include        <stdlib.h>
 
8
#include        <string.h>
 
9
#include        <signal.h>
 
10
 
 
11
 
 
12
#ifdef HAVE_TERMIO_H
 
13
#include        <termio.h>
 
14
#else
 
15
#include        <sys/ioctl.h>
 
16
#endif  /* HAVE_TERMIO_H */
 
17
 
 
18
#ifdef HAVE_BSDTTY_H
 
19
#include        <sys/bsdtty.h>
 
20
#ifndef TIOCNOTTY
 
21
#define TIOCNOTTY       _IO('t', 113)   /* HP-UX void tty definition */
 
22
#endif
 
23
#endif /* HAVE_BSDTTY_H */
 
24
 
 
25
#ifdef NEED_INET_H
 
26
/*#define STTY_HACK*/
 
27
#endif
 
28
 
 
29
/*
 
30
 * Initialize a pty, fork a command running under it, and then 
 
31
 * return the master file descriptor
 
32
 */
 
33
 
 
34
extern int WU_lines, WL_lines, W_columns;       /* From vt100.c */
 
35
 
 
36
#define UPPER   0               /* Upper window definition */
 
37
#define LOWER   1               /* Lower window definition */
 
38
 
 
39
int pty_open(argv, childpid, win)
 
40
char *argv[];
 
41
int *childpid;
 
42
int win;                /* 0 for upper, 1 for lower */
 
43
{
 
44
 
 
45
        void dropctty(), pty_setwin();
 
46
        int get_master_pty(), get_slave_pty();
 
47
        char *get_ttyname(), *myputenv();
 
48
 
 
49
        char LINES[12], COLUMNS[12], SPLITVT[24];
 
50
        int returnfd, slave_fd;
 
51
 
 
52
        /* Get the master pty file descriptor */
 
53
        if ( (returnfd=get_master_pty()) < 0 )
 
54
                return(-1);
 
55
 
 
56
        /* Fork and go! */
 
57
        if ( ((*childpid)=fork()) < 0 )
 
58
                return(-1);
 
59
        else if ( (*childpid) == 0 )
 
60
        {
 
61
                dropctty();     /* Lose controlling tty */
 
62
 
 
63
                if ( (slave_fd=get_slave_pty()) < 0 )
 
64
                {
 
65
                        perror("Can't open slave tty");
 
66
                        exit(128);
 
67
                }
 
68
                close(0); close(1); close(2);
 
69
                dup(slave_fd); dup(slave_fd); dup(slave_fd);
 
70
                close(slave_fd); close(returnfd);
 
71
 
 
72
                /* Reattatch the new tty as the controlling terminal */
 
73
                /* Under old UNIX, just opening the new tty after
 
74
                   losing the controlling tty is good enough.
 
75
                   Under newer Unices, it requires an ioctl().  */
 
76
#ifdef TIOCSCTTY
 
77
                (void) ioctl(0, TIOCSCTTY, 0);
 
78
#endif
 
79
 
 
80
                /* Set the lines and columns on the new tty */
 
81
#ifdef TIOCGWINSZ       /* We don't want to set the environment if possible */
 
82
                pty_setwin(0, win);
 
83
#else
 
84
                if ( win == UPPER )
 
85
                        sprintf(LINES, "LINES=%d", WU_lines);
 
86
                else
 
87
                        sprintf(LINES, "LINES=%d", WL_lines);
 
88
                myputenv(LINES);
 
89
                sprintf(COLUMNS, "COLUMNS=%d", W_columns);
 
90
                myputenv(COLUMNS);
 
91
#endif /* TIOCGWINSZ */
 
92
                /* Set the SPLITVT environment variable for shell scripts */
 
93
                if ( win == UPPER )
 
94
                        sprintf(SPLITVT, "SPLITVT=upper");
 
95
                else
 
96
                        sprintf(SPLITVT, "SPLITVT=lower");
 
97
                myputenv(SPLITVT);
 
98
                myputenv("TERM=vt100"); /* Put the new TERM in the env. */
 
99
 
 
100
#ifdef SIGTSTP
 
101
                signal(SIGTSTP, SIG_IGN);
 
102
#endif
 
103
#ifdef STTY_HACK
 
104
                system("stty sane echo echoe intr '^C' erase '^H'");
 
105
#else
 
106
                (void) tty_reset(0);
 
107
#endif
 
108
                /* "touch" the tty so 'w' reports proper idle times */
 
109
                (void) utime(get_ttyname(), NULL);
 
110
 
 
111
                /* Set our uid to our real uid if necessary */
 
112
                (void) setuid(getuid());
 
113
                        
 
114
                /* Run the requested program, with possible leading dash. */
 
115
                execvp(((*argv[0] == '-') ? argv[0]+1 : argv[0]), argv);
 
116
                perror(argv[0]);
 
117
                exit(255);
 
118
        }
 
119
        return(returnfd);
 
120
}
 
121
 
 
122
 
 
123
 
 
124
/*
 
125
 * Pseudo-terminal routines for Unix System V Release 3.2 and BSD4.2-3
 
126
 */
 
127
 
 
128
 
 
129
extern int errno;
 
130
int master_fd;
 
131
 
 
132
char tty_name[64]={'\0'};
 
133
char pty_name[64]={'\0'};
 
134
 
 
135
char *get_ttyname()
 
136
{
 
137
        if ( tty_name[0] )
 
138
                return(tty_name);
 
139
        return(NULL);
 
140
}
 
141
 
 
142
#ifdef IRIX     /* IRIX System V for SGI machines */
 
143
 
 
144
extern char *_getpty();
 
145
 
 
146
int get_master_pty()
 
147
{
 
148
 
 
149
        char    *ttyptr;
 
150
 
 
151
        ttyptr=_getpty(&master_fd, O_RDWR, 0600, 0);
 
152
        if ( ttyptr == NULL || strlen(ttyptr)+1 > sizeof(tty_name) )
 
153
                return(-1);
 
154
        else
 
155
                strcpy(tty_name, ttyptr);
 
156
 
 
157
        return(master_fd);
 
158
}
 
159
 
 
160
/*
 
161
 * Open the slave half of a pseudo-terminal.
 
162
 */
 
163
 
 
164
int get_slave_pty()
 
165
{
 
166
        int     slave_fd;
 
167
        char    *slavename;
 
168
 
 
169
        slavename=tty_name;
 
170
 
 
171
        if (slavename == NULL) {
 
172
                close(master_fd);
 
173
                return(-1);
 
174
        }
 
175
 
 
176
        if ( (slave_fd=open(slavename, O_RDWR)) < 0 )   /* open the slave */
 
177
        {
 
178
                close(master_fd);
 
179
                return(-1);
 
180
        }
 
181
 
 
182
        return(slave_fd);
 
183
}
 
184
#else /* ! IRIX */
 
185
 
 
186
 
 
187
#if defined(SOLARIS) || defined(linux)          /* System V.4 pty routines from W. Richard Stevens */
 
188
 
 
189
#ifdef SOLARIS
 
190
#include <stropts.h>
 
191
#endif
 
192
 
 
193
#define DEV_CLONE       "/dev/ptmx"
 
194
 
 
195
extern char *ptsname();
 
196
 
 
197
int get_master_pty()
 
198
{
 
199
 
 
200
        char    *ttyptr;
 
201
 
 
202
        if ( (master_fd=open(DEV_CLONE, O_RDWR)) < 0 )
 
203
                return(-1);
 
204
 
 
205
        if ( grantpt(master_fd) < 0 )   /* grant access to slave */
 
206
        {
 
207
                close(master_fd);
 
208
#ifdef DEBUG
 
209
                perror("grantpt()");
 
210
#endif
 
211
                return(-1);
 
212
        }
 
213
 
 
214
        if ( unlockpt(master_fd) < 0 )  /* clear slave's lock flag */
 
215
        {
 
216
                close(master_fd);
 
217
                return(-1);
 
218
        }
 
219
 
 
220
        ttyptr=ptsname(master_fd);
 
221
        if ( ttyptr == NULL || strlen(ttyptr)+1 > sizeof(tty_name) )
 
222
        {
 
223
                close(master_fd);
 
224
                return(-1);
 
225
        }
 
226
        else
 
227
                strcpy(tty_name, ttyptr);
 
228
 
 
229
        return(master_fd);
 
230
}
 
231
 
 
232
/*
 
233
 * Open the slave half of a pseudo-terminal.
 
234
 */
 
235
 
 
236
int get_slave_pty()
 
237
{
 
238
        int     slave_fd;
 
239
        char    *slavename;
 
240
 
 
241
        slavename=tty_name;
 
242
 
 
243
        if ( (slave_fd=open(slavename, O_RDWR)) < 0 )   /* open the slave */
 
244
        {
 
245
                close(master_fd);
 
246
                return(-1);
 
247
        }
 
248
 
 
249
#ifdef SOLARIS
 
250
        if ( ioctl(slave_fd, I_PUSH, "ptem") < 0 )
 
251
        {
 
252
                close(master_fd);
 
253
                close(slave_fd);
 
254
                return(-1);
 
255
        }
 
256
 
 
257
        if ( ioctl(slave_fd, I_PUSH, "ldterm") < 0 )
 
258
        {
 
259
                close(master_fd);
 
260
                close(slave_fd);
 
261
                return(-1);
 
262
        }
 
263
 
 
264
        if ( ioctl(slave_fd, I_PUSH, "ttcompat") < 0 )
 
265
        {
 
266
                close(master_fd);
 
267
                close(slave_fd);
 
268
                return(-1);
 
269
        }
 
270
#endif
 
271
 
 
272
        return(slave_fd);
 
273
}
 
274
 
 
275
#else   /* BSD, Sun/OS, AIX, ULTRIX, HP-UX, AT&T SYSV */
 
276
 
 
277
#include        <setjmp.h>
 
278
 
 
279
#ifndef X_OK
 
280
#define R_OK    4       /* Test for Read permission */
 
281
#define W_OK    2       /* Test for Write permission */
 
282
#define X_OK    1       /* Test for eXecute permission */
 
283
#endif  /* X_OK */
 
284
 
 
285
jmp_buf next;
 
286
 
 
287
void trynext()
 
288
{
 
289
        longjmp(next, 2);
 
290
}
 
291
 
 
292
 
 
293
int get_master_pty()
 
294
{
 
295
        int i, master_fd;
 
296
        char *ptr;
 
297
        struct stat statbuff;
 
298
#ifdef PTYCHAR
 
299
        static char ptychar[]=PTYCHAR;                  /* X */ 
 
300
        static char hexdigit[]=HEXDIGIT;                /* Y */
 
301
#else
 
302
        static char ptychar[]="pqrstuvwxyzPQRST";       /* X */ 
 
303
        static char hexdigit[]="0123456789abcdef";      /* Y */
 
304
#endif
 
305
 
 
306
        for (ptr=ptychar; *ptr != 0; ptr++)
 
307
        {
 
308
                strcpy(pty_name, "/dev/ptyXY");
 
309
                pty_name[8]=(*ptr);  /* X */
 
310
                pty_name[9]='0';   /* Y */
 
311
 
 
312
                if ( stat(pty_name, &statbuff) < 0 )
 
313
                        break;
 
314
#ifdef OLDDEBUG
 
315
                fprintf(stderr, "statted.\n");
 
316
#endif
 
317
                i=(-1);         /* Initialize i */
 
318
 
 
319
                /* Set a time limit for the open */
 
320
                if ( setjmp(next) == -1 )
 
321
                        return(-1);
 
322
                signal(SIGALRM, trynext);
 
323
 
 
324
                for ( ++i; hexdigit[i]; ++i)
 
325
                {
 
326
                        pty_name[5]='p';
 
327
                        pty_name[9]=hexdigit[i];
 
328
 
 
329
                        alarm(2);       /* Set an open timeout */
 
330
 
 
331
                        if ( (master_fd=open(pty_name, O_RDWR)) >= 0 )
 
332
                        {
 
333
                                alarm(0);       /* Reset the alarm */
 
334
 
 
335
                                pty_name[5]='t';
 
336
                                sprintf(tty_name, "%s", pty_name);
 
337
#ifdef OLDDEBUG
 
338
                                fprintf(stderr, "tty: %s\n", tty_name);
 
339
#endif
 
340
                                if ( access(tty_name, R_OK|W_OK) == 0 ) {
 
341
                                        signal(SIGALRM, SIG_DFL);
 
342
                                        return (master_fd);
 
343
                                } else {
 
344
                                        pty_name[5]='p';
 
345
                                        (void) close(master_fd);
 
346
                                }
 
347
                        }
 
348
                        /* reset the alarm */
 
349
                        alarm(0);
 
350
                }
 
351
        }
 
352
        return(-1);
 
353
}
 
354
 
 
355
 
 
356
/* Open the slave half of a pseudo-terminal. */
 
357
 
 
358
int get_slave_pty()
 
359
{
 
360
        int slave_fd;
 
361
 
 
362
        if ( (slave_fd=open(tty_name, O_RDWR)) < 0 )
 
363
        {
 
364
                close(master_fd);
 
365
                return(-1);
 
366
        }
 
367
        return(slave_fd);
 
368
}
 
369
 
 
370
#endif  /* if linux or SOLARIS */
 
371
#endif  /* if IRIX */
 
372
 
 
373
 
 
374
/* These are the binary data functions that I am using instead of 
 
375
   bcopy() and bzero(), written by Richard A. O'Keefe.
 
376
     Thanks!
 
377
*/
 
378
 
 
379
void d_copy(src, dst, len)
 
380
    register char *src, *dst;
 
381
    register int len;
 
382
    {
 
383
        while (--len >= 0) *dst++ = *src++;
 
384
    }
 
385
 
 
386
void d_zero(dst, len)
 
387
    register char *dst;
 
388
    register int len;
 
389
    {
 
390
        while (--len >= 0) *dst++ = 0;
 
391
    }
 
392
 
 
393
 
 
394
 
 
395
/* Here are the Terminal manipulation routines...  */
 
396
 
 
397
 
 
398
/* Code to disassociate from my tty. Yay! :) */
 
399
 
 
400
void dropctty()
 
401
{
 
402
        int fd;
 
403
 
 
404
#if defined(_POSIX_SOURCE) || defined(SOLARIS) || \
 
405
                                defined(__386BSD__) || defined(__FreeBSD__)
 
406
        setsid();               /* The POSIX solution is simple. :) */
 
407
#else
 
408
#ifdef TIOCNOTTY  /* We want to get HP-UX, BSD, and Sun/OS here */
 
409
        setpgrp(0, 0);
 
410
 
 
411
#ifndef CIBAUD   /* Sun/OS doesn't need to do TIOCNOTTY.  */
 
412
        if ( (fd=open("/dev/tty", O_RDWR)) > (-1) ) 
 
413
        {
 
414
                if (ioctl(fd, TIOCNOTTY, 0) < 0)
 
415
                {
 
416
                        perror("ioctl TIOCNOTTY error");
 
417
                        fprintf(stderr, "\r");
 
418
                }
 
419
                close(fd);
 
420
        }
 
421
#endif /* CIBAUD */
 
422
#else /*  SYSV  */
 
423
        setpgrp();
 
424
#endif /* TIOCNOTTY */
 
425
#endif /* _POSIX_SOURCE */
 
426
}
 
427
 
 
428
 
 
429
#ifdef HAVE_TERMIO_H
 
430
 
 
431
/* Get the modes of the controlling tty and save them.  Saves
 
432
   ttymodes in tty_mode and returns -1 if ioctl fails. */
 
433
 
 
434
struct termio tty_mode;  /* Save tty mode here */
 
435
static int tty_init=0;
 
436
 
 
437
int tty_getmode(fd)
 
438
int fd;
 
439
{
 
440
        d_zero((char *)&tty_mode, sizeof(struct termio));
 
441
        tty_init=1;     /* Flag: we have initialized the tty_mode struct */
 
442
 
 
443
        if ( ! isatty(fd) )
 
444
                return(0);
 
445
 
 
446
#ifdef OLDDEBUG
 
447
        fprintf(stderr, "Getting tty modes for tty_mode.\r\n");
 
448
#endif
 
449
 
 
450
        if (ioctl(fd, TCGETA, (char *) &tty_mode) < 0)
 
451
        {
 
452
#ifdef DEBUG
 
453
                perror("tty_getmode(): ioctl error");
 
454
#endif
 
455
                return(-1);  
 
456
        }
 
457
 
 
458
        return(0);
 
459
}
 
460
 
 
461
 
 
462
/* Set a tty to a sane mode */
 
463
 
 
464
int tty_sane(fd)
 
465
int fd;
 
466
{
 
467
        struct termio temp_mode;
 
468
 
 
469
        if ( ! isatty(fd) )
 
470
                return(0);
 
471
 
 
472
        if ( ! tty_init )
 
473
        {
 
474
                if (ioctl(fd, TCGETA, (char *) &tty_mode) < 0)
 
475
                        return(-1);  
 
476
        }
 
477
 
 
478
#ifdef SEVEN_BIT
 
479
        temp_mode.c_iflag=(tty_mode.c_iflag|(BRKINT|IGNPAR|ISTRIP|ICRNL|IXON));
 
480
        temp_mode.c_oflag=(tty_mode.c_oflag|(OPOST|ONLCR));
 
481
#else
 
482
        temp_mode.c_iflag=(tty_mode.c_iflag|(BRKINT|IGNPAR|ICRNL|IXON));
 
483
        temp_mode.c_cflag=(tty_mode.c_cflag|(CS8|CREAD));
 
484
#endif
 
485
        temp_mode.c_lflag=(tty_mode.c_lflag|(ISIG|ICANON|ECHO|ECHOE|ECHOK));
 
486
        temp_mode.c_cflag=(tty_mode.c_cflag|(CS7|PARENB|CREAD));
 
487
        temp_mode.c_cc[VERASE]=('H'^64);
 
488
        temp_mode.c_cc[VKILL]=('U'^64);
 
489
        temp_mode.c_cc[VQUIT]=('\\'^64);
 
490
        temp_mode.c_cc[VINTR]=('C'^64);
 
491
        temp_mode.c_cc[VEOF]=('D'^64);
 
492
        
 
493
        /* TCSETAW is important for letting tty input drain. */
 
494
        if ( ioctl(fd, TCSETAW, (char *)&temp_mode) < 0 )
 
495
        {
 
496
#ifdef DEBUG
 
497
                perror("Can't set tty modes");
 
498
#endif
 
499
                return(-1);
 
500
        }
 
501
 
 
502
        return(0);
 
503
}
 
504
 
 
505
 
 
506
/* Set a terminal in raw mode */
 
507
 
 
508
int tty_raw(fd)
 
509
int fd;     /* of tty device */
 
510
{
 
511
        struct termio temp_mode;
 
512
 
 
513
        if ( ! tty_init )
 
514
                return(-1);
 
515
 
 
516
        if ( ! isatty(fd) )
 
517
                return(0);
 
518
 
 
519
        if ( ioctl(fd, TCGETA, (char *)&temp_mode) < 0 )
 
520
                return(-1);
 
521
 
 
522
#ifdef SEVEN_BIT
 
523
        temp_mode.c_iflag=(IGNBRK | ISTRIP);    /* turn off all input control */
 
524
#else
 
525
        temp_mode.c_iflag=(IGNBRK);             /* turn off all input control */
 
526
#endif
 
527
        temp_mode.c_oflag &= ~(OLCUC | ONLCR | OCRNL | ONLRET);
 
528
                                        /* disable output post-processing */
 
529
        temp_mode.c_lflag = 0;
 
530
        temp_mode.c_cc[VMIN]=1;         /* 1 or more chars satisfy read */
 
531
        temp_mode.c_cc[VTIME]=0;        /* 10'ths of seconds between chars */
 
532
 
 
533
        /* TCSETAW is important for letting tty input drain. */
 
534
        if (ioctl(fd, TCSETAW, (char *) &temp_mode) < 0)
 
535
                return(-1);
 
536
        return(0);
 
537
}
 
538
 
 
539
 
 
540
/* Restore terminal's mode to whatever it was on the most
 
541
   recent call to the tty_getmode() function. */
 
542
 
 
543
int tty_reset(fd)
 
544
int fd;
 
545
{
 
546
        if ( ! tty_init )
 
547
                return(-1);
 
548
 
 
549
        if ( ! isatty(fd) )
 
550
                return(0);
 
551
 
 
552
        /* TCSETAW is important for letting tty input drain. */
 
553
        if (ioctl(fd, TCSETAW, (char *) &tty_mode) < 0)
 
554
                return(-1);
 
555
        return(0);
 
556
}
 
557
 
 
558
#else  /* no /usr/include/termio.h */
 
559
#ifdef NEED_COMPAT_H            /* FreeBSD needs this */
 
560
#include <sys/ioctl_compat.h>
 
561
#endif /* NEED_COMPAT_H */
 
562
 
 
563
/* Set a tty to a sane mode */
 
564
 
 
565
int tty_sane(fd)
 
566
int fd;
 
567
{
 
568
        struct sgttyb temp_mode;
 
569
 
 
570
        if ( ! isatty(fd) )
 
571
                return(0);
 
572
 
 
573
        if (ioctl(fd, TIOCGETP, (char *) &temp_mode) < 0)
 
574
                return(-1);
 
575
 
 
576
        temp_mode.sg_flags|=ECHO;
 
577
        
 
578
        if (ioctl(fd, TIOCSETP, (char *) &temp_mode) < 0)
 
579
                return(-1);
 
580
 
 
581
        return(0);
 
582
}
 
583
 
 
584
 
 
585
 
 
586
/* Get the modes of the controlling tty and save them.  Saves
 
587
   ttymodes in tty_mode and returns 1 if ioctl fails. */
 
588
 
 
589
static struct sgttyb    tty_mode;       /* save tty mode here */
 
590
 
 
591
int tty_getmode(fd)
 
592
int fd;
 
593
{
 
594
        if ( ! isatty(fd) )
 
595
                return(0);
 
596
 
 
597
        if (ioctl(fd, TIOCGETP, (char *) &tty_mode) < 0)
 
598
                return(-1);
 
599
 
 
600
        return(0);
 
601
}
 
602
 
 
603
/*
 
604
 * Put a terminal device into RAW mode with ECHO off.
 
605
 * Before doing so we first save the terminal's current mode,
 
606
 * assuming the caller will call the tty_reset() function
 
607
 * (also in this file) when it's done with raw mode.
 
608
 */
 
609
 
 
610
int tty_raw(fd)
 
611
int     fd;             /* of terminal device */
 
612
{
 
613
        struct sgttyb   temp_mode;
 
614
 
 
615
        if ( ! isatty(fd) )
 
616
                return(0);
 
617
 
 
618
        temp_mode = tty_mode;
 
619
 
 
620
        temp_mode.sg_flags |= RAW;      /* turn RAW mode on */
 
621
        temp_mode.sg_flags &= ~ECHO;    /* turn ECHO off */
 
622
        if (ioctl(fd, TIOCSETP, (char *) &temp_mode) < 0)
 
623
                return(-1);
 
624
 
 
625
        return(0);
 
626
}
 
627
 
 
628
/*
 
629
 * Restore a terminal's mode to whatever it was on the most
 
630
 * recent call to the tty_getmode() function above.
 
631
 */
 
632
 
 
633
int tty_reset(fd)
 
634
int     fd;             /* of terminal device */
 
635
{
 
636
        if ( ! isatty(fd) )
 
637
                return(0);
 
638
 
 
639
        if (ioctl(fd, TIOCSETP, (char *) &tty_mode) < 0)
 
640
                return(-1);
 
641
 
 
642
        return(0);
 
643
}
 
644
#endif /* HAVE_TERMIO_H */
 
645
 
 
646
 
 
647
/* Set the pty window size to the size of the virtual window */
 
648
 
 
649
#ifdef TIOCSWINSZ
 
650
 
 
651
static struct /* winsize */ {
 
652
                unsigned short  ws_row;         /* rows, in characters */
 
653
                unsigned short  ws_col;         /* columns, in characters */
 
654
                unsigned short  ws_xpixel;      /* horizontal size - not used */
 
655
                unsigned short  ws_ypixel;      /* vertical size - not used */
 
656
        } mywinz;
 
657
 
 
658
void pty_setwin(fd, win)
 
659
int fd;                 /* The pty file descriptor */
 
660
int win;                /* 0 for upper, 1 for lower window */
 
661
{
 
662
        if ( win == UPPER )
 
663
                mywinz.ws_row=WU_lines;
 
664
        else
 
665
                mywinz.ws_row=WL_lines;
 
666
        mywinz.ws_col=W_columns;
 
667
        mywinz.ws_xpixel=0;
 
668
        mywinz.ws_ypixel=0;
 
669
        (void) ioctl(fd, TIOCSWINSZ, &mywinz);
 
670
}
 
671
 
 
672
#else
 
673
void pty_setwin(fd, win)
 
674
int fd;
 
675
int win;
 
676
{
 
677
        /* Bogus routine */
 
678
}
 
679
#endif /* TIOCSWINSZ */
 
680
 
 
681
/*
 
682
 * Write "n" bytes to a descriptor.
 
683
 * Use in place of write() when fd is a stream socket.
 
684
 */
 
685
 
 
686
int writen(fd, ptr, nbytes)
 
687
register int    fd;
 
688
register char   *ptr;
 
689
register int    nbytes;
 
690
{
 
691
        int     nleft, nwritten;
 
692
 
 
693
        nleft = nbytes;
 
694
        while (nleft > 0) {
 
695
                nwritten = write(fd, ptr, nleft);
 
696
                if (nwritten <= 0)
 
697
                        return(nwritten);               /* error */
 
698
 
 
699
                nleft -= nwritten;
 
700
                ptr   += nwritten;
 
701
        }
 
702
        return(nbytes - nleft);
 
703
}
 
704
 
 
705
 
 
706
/* 
 
707
   A function to put strings in the environment using malloc(). 
 
708
   Returns a pointer to the environment string or NULL if malloc() fails.
 
709
 */
 
710
 
 
711
char *myputenv(string)
 
712
char *string;
 
713
{
 
714
        extern char **environ;  /* The process environment strings */
 
715
 
 
716
        char *newptr, **envptr;
 
717
        char *tmptr, temp[BUFSIZ];
 
718
        int   distance, n=0;
 
719
 
 
720
        for ( distance=0; ((*(string+distance)) && 
 
721
                          ((*(string+distance)) != '=')); ++distance );
 
722
        if ( ! (*(string+distance)) )
 
723
                return(NULL);
 
724
        else
 
725
                ++distance;
 
726
                                                                
 
727
        if ( (newptr=(char *)malloc(strlen(string)+1)) == NULL )
 
728
                return(NULL);
 
729
        else
 
730
                strcpy(newptr, string);
 
731
 
 
732
        for ( envptr=environ; *envptr; ++envptr, ++n ) {
 
733
                if ( strncmp(*envptr, string, distance) == 0 ) {
 
734
                        *envptr=newptr;
 
735
                        return(newptr);
 
736
                }
 
737
        }
 
738
 
 
739
        *envptr=newptr;
 
740
        ++envptr;
 
741
        *envptr=NULL;
 
742
        
 
743
        return(newptr);
 
744
}
 
745
 
 
746
 
 
747
/* * * * * * * Routines to parse a line into an array of tokens * * * * * * */
 
748
 
 
749
static int istoken(c, tokens)
 
750
char c;
 
751
char *tokens;
 
752
{
 
753
        while ( *tokens ) {
 
754
                if ( c == *(tokens++) )
 
755
                        return(1);
 
756
        }
 
757
        return(0);
 
758
}
 
759
 
 
760
/* This version of tokenize is destructive to the line it parses. */
 
761
 
 
762
void tokenize(array, size, line, tokens)
 
763
char *array[];
 
764
int size;
 
765
char *line;
 
766
char *tokens;
 
767
{
 
768
        char *head, *ptr;
 
769
        int i=0;
 
770
 
 
771
        for ( head=line; *line && i < size-2; ) {
 
772
                if ( istoken(*line, tokens) ) {
 
773
                        *(line++)='\0';
 
774
                        array[i++]=head;
 
775
                        while ( istoken(*line, tokens) )
 
776
                                ++line;
 
777
                        head=line;
 
778
                } else
 
779
                        ++line;
 
780
        }
 
781
        array[i++]=head;
 
782
        array[i]=NULL;
 
783
}
 
784
 
 
785
 
 
786
/* Return the pathname of the command, or NULL if it's not in our PATH */
 
787
/* Warning: We use a static buffer that is overwritten at each invocation. */
 
788
 
 
789
char *pathsearch(command, secure)
 
790
char *command;
 
791
int secure;
 
792
{
 
793
#ifndef S_IFREG
 
794
#define S_IFREG 0100000
 
795
#endif
 
796
        char *path, *newpath, *paths[256];
 
797
        static char buffer[1024];
 
798
        int i;
 
799
        struct stat sb;
 
800
 
 
801
        if ( (path=(char *)getenv("PATH")) == NULL )
 
802
                return(NULL);
 
803
        if ( (newpath=(char *)malloc(strlen(path)+1)) == NULL )
 
804
                return(NULL);
 
805
        strcpy(newpath, path);
 
806
 
 
807
        tokenize(paths, 256, newpath, ":");
 
808
        for ( i=0; paths[i]; ++i ) {
 
809
                if ( secure && paths[i][0] != '/' ) {
 
810
                        /* Only allow full pathnames */
 
811
                        continue;
 
812
                }
 
813
 
 
814
                /* Make sure the file exists */
 
815
                sprintf(buffer, "%s/%s", paths[i], command);
 
816
                if ( stat(buffer, &sb) != 0 )
 
817
                        continue;
 
818
 
 
819
                /* Make sure it's a regular file */
 
820
                if ( (sb.st_mode & S_IFREG) != S_IFREG )
 
821
                        continue;
 
822
 
 
823
                /* Now make sure we can execute it */
 
824
                if ( sb.st_uid == getuid() ) {
 
825
                        /* User execute permission? */
 
826
                        if ( sb.st_mode & 0100 )
 
827
                                break;
 
828
                } else if ( sb.st_gid == getgid() ) {
 
829
                        /* Group execute permission? */
 
830
                        if ( sb.st_mode & 0010 )
 
831
                                break;
 
832
                } else {
 
833
                        /* Other execute permission? */
 
834
                        if ( sb.st_mode & 0001 )
 
835
                                break;
 
836
                }
 
837
        }
 
838
        (void) free(newpath);
 
839
 
 
840
        if ( paths[i] == NULL )
 
841
                return(NULL);
 
842
        else
 
843
                return(buffer);
 
844
}
 
845
 
 
846
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ 
 
847
 
 
848
/* Safe version of popen() and pclose(), they reset the uid and gid. */
 
849
 
 
850
FILE *safe_popen(command, type)
 
851
char *command;
 
852
char *type;
 
853
{
 
854
        char *argv[4];
 
855
        int pipe_fds[2];
 
856
        int rw, child;
 
857
 
 
858
        if ( strcmp(type, "r") == 0 )
 
859
                rw=0;   /* READ access for parent */
 
860
        else if ( strcmp(type, "w") == 0 )
 
861
                rw=1;   /* WRITE access for parent */
 
862
        else
 
863
                return(NULL);   /* Unsupported type */
 
864
 
 
865
        if ( pipe(pipe_fds) < 0 ) {
 
866
                return(NULL);
 
867
        }
 
868
 
 
869
        switch(fork()) {
 
870
                case 0:  /* Child runs here */
 
871
                        /* Reassign file descriptors */
 
872
                        if ( rw == 0 ) {
 
873
                                close(1); dup(pipe_fds[1]); close(0);
 
874
                        } else {
 
875
                                close(0); dup(pipe_fds[0]); close(1);
 
876
                        }
 
877
                        close(pipe_fds[0]); close(pipe_fds[1]); 
 
878
 
 
879
                        /* Set our uid to our real uid if necessary */
 
880
                        (void) setuid(getuid());
 
881
                        
 
882
                        /* Run the requested program */
 
883
                        argv[0]="/bin/sh";
 
884
                        argv[1]="-c";
 
885
                        argv[2]=command;
 
886
                        argv[3]=NULL;
 
887
                        execvp(argv[0], argv);
 
888
                        fprintf(stderr, "Can't execute %s: ", argv[0]);
 
889
                        perror("");
 
890
                        exit(255);
 
891
 
 
892
                case -1: /* fork() error */
 
893
                        close(pipe_fds[0]);
 
894
                        close(pipe_fds[1]);
 
895
                        return(NULL);
 
896
                        break;
 
897
 
 
898
                default: /* Parent runs */
 
899
                        break;
 
900
        }
 
901
        if ( rw == 0 ) 
 
902
                close(pipe_fds[1]);
 
903
        else
 
904
                close(pipe_fds[0]);
 
905
        return(fdopen(pipe_fds[rw], type));
 
906
}
 
907
 
 
908
int safe_pclose(pipefp)
 
909
FILE *pipefp;
 
910
{
 
911
        int status;
 
912
 
 
913
        /* Close the pipe */
 
914
        fclose(pipefp);
 
915
 
 
916
        /* Wait for the child to terminate */
 
917
        wait(&status);
 
918
        return(status);
 
919
}