OpenCores
URL https://opencores.org/ocsvn/or1k/or1k/trunk

Subversion Repositories or1k

[/] [or1k/] [trunk/] [insight/] [expect/] [pty_unicos.c] - Blame information for rev 1765

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 578 markom
/* pty_unicos.c - routines to allocate ptys - for CRAY UNICOS 5.1 and 6.0 */
2
 
3
/*
4
 
5
Original by: Don Libes, NIST, 2/6/90
6
Hacked for Unicos 5.1 by: Frank Terhaar-Yonkers, US EPA,  1/10/91
7
Hacked for Unicos 6.0 by: Pete TerMaat, pete@willow.cray.com, 3/27/91
8
 
9
Design and implementation of this program was paid for by U.S. tax
10
dollars.  Therefore it is public domain.  However, the author and NIST
11
would appreciate credit if this program or parts of it are used.
12
 
13
*/
14
 
15
#include "expect_cf.h"
16
#include <stdio.h>
17
#include <signal.h>
18
 
19
#if defined(SIGCLD) && !defined(SIGCHLD)
20
#define SIGCHLD SIGCLD
21
#endif
22
 
23
#ifdef HAVE_UNISTD_H
24
#include <unistd.h>
25
#else
26
extern int fork(), execl(), wait();
27
#endif
28
#include <errno.h>
29
#include <sys/types.h>
30
#include <sys/stat.h>
31
#include <sys/ioctl.h>
32
#include <sys/file.h>
33
#ifdef HAVE_SYS_FCNTL_H
34
#  include <sys/fcntl.h>
35
#else
36
#  include <fcntl.h>
37
#endif
38
/*#if CRAY>=60*/
39
#if defined(HAVE_TERMIOS)
40
# include <sys/termios.h>
41
#else
42
# include <sys/termio.h>
43
/*#endif /* 60 */*/
44
#endif /* defined(HAVE_TERMIOS) */
45
#if CRAY>=70 && defined(_CRAY2)
46
#include <sys/session.h>
47
#endif /* 70 */
48
#include <sys/pty.h>
49
#include <pwd.h>
50
#include <utmp.h>
51
#include <signal.h>
52
#include "exp_tty_in.h"
53
#include "exp_rename.h"
54
 
55
#ifdef HAVE_SYSCONF_H
56
#include <sys/sysconfig.h>
57
#endif
58
 
59
void debuglog();
60
 
61
#ifndef TRUE
62
#define TRUE 1
63
#define FALSE 0
64
#endif
65
 
66
#ifndef MAXHOSTNAMELEN
67
#define MAXHOSTNAMELEN 64
68
#endif /* MAXHOSTNAMELEN */
69
 
70
static char     linep[] = "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0";
71
static char     linet[] = "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0";
72
static int      lowpty;
73
static int      highpty;
74
static int      realuid;
75
static int      realgid;
76
static int      *ptys;
77
static char myname[32];
78
static char hostname[MAXHOSTNAMELEN];
79
char *exp_pty_slave_name;
80
char *exp_pty_error;
81
 
82
static void
83
pty_stty(s,name)
84
char *s;                /* args to stty */
85
char *name;             /* name of pty */
86
{
87
#define MAX_ARGLIST 10240
88
        char buf[MAX_ARGLIST];  /* overkill is easier */
89
        RETSIGTYPE (*old)();    /* save old sigalarm handler */
90
 
91
#ifdef STTY_READS_STDOUT
92
        sprintf(buf,"/bin/stty %s > %s",s,name);
93
#else
94
        sprintf(buf,"/bin/stty %s < %s",s,name);
95
#endif
96
        old = signal(SIGCHLD, SIG_DFL);
97
        system(buf);
98
        signal(SIGCHLD, old);   /* restore signal handler */
99
}
100
 
101
int exp_dev_tty;        /* file descriptor to /dev/tty or -1 if none */
102
static int knew_dev_tty;/* true if we had our hands on /dev/tty at any time */
103
 
104
#ifdef TIOCGWINSZ
105
static struct winsize winsize = {0, 0};
106
#endif
107
#if defined(TIOCGSIZE) && !defined(TIOCGWINSZ)
108
static struct ttysize winsize = {0, 0};
109
#endif
110
 
111
/*struct        termio exp_tty_original;*/
112
exp_tty exp_tty_original;
113
 
114
#define GET_TTYTYPE     0
115
#define SET_TTYTYPE     1
116
static void
117
ttytype(request,fd,ttycopy,ttyinit,s)
118
int request;
119
int fd;
120
                /* following are used only if request == SET_TTYTYPE */
121
int ttycopy;    /* true/false, copy from /dev/tty */
122
int ttyinit;    /* if true, initialize to sane state */
123
char *s;        /* stty args, used only if request == SET_TTYTYPE */
124
{
125
        if (request == GET_TTYTYPE) {
126
                if (-1 == ioctl(fd, TCGETA, (char *)&exp_tty_original)) {
127
                        knew_dev_tty = FALSE;
128
                        exp_dev_tty = -1;
129
                }
130
#ifdef TIOCGWINSZ
131
                ioctl(fd,TIOCGWINSZ,&winsize);
132
#endif
133
#if defined(TIOCGSIZE) && !defined(TIOCGWINSZ)
134
                ioctl(fd,TIOCGSIZE,&winsize);
135
#endif
136
        } else {        /* type == SET_TTYTYPE */
137
                if (ttycopy && knew_dev_tty) {
138
                        (void) ioctl(fd, TCSETA, (char *)&exp_tty_current);
139
#ifdef TIOCSWINSZ
140
                        ioctl(fd,TIOCSWINSZ,&winsize);
141
#endif
142
#if defined(TIOCSSIZE) && !defined(TIOCSWINSZ)
143
                        ioctl(fd,TIOCGSIZE,&winsize);
144
#endif
145
                }
146
 
147
                if (ttyinit) {
148
                        /* overlay parms originally supplied by Makefile */
149
                        pty_stty(DFLT_STTY,linet);
150
                }
151
 
152
                /* lastly, give user chance to override any terminal parms */
153
                if (s) {
154
                        pty_stty(s,linet);
155
                }
156
        }
157
}
158
 
159
void
160
exp_init_pty()
161
{
162
        int npty;
163
        char *myline;
164
 
165
        lowpty=0;
166
#ifdef _SC_CRAY_NPTY
167
        highpty=sysconf(_SC_CRAY_NPTY);
168
#else
169
        highpty=128;
170
#endif /* _SC_CRAY_NPTY */
171
 
172
        ptys = (int *) malloc(sizeof(int)*(highpty+1));
173
        if (ptys == NULL) {
174
                fprintf(stderr,"exp_init_pty:  couldn't allocate pty array\n");
175
                exit(1);
176
        }
177
        for (npty = lowpty;npty <= highpty;npty++)
178
                ptys[npty] = 0;
179
 
180
        realuid=getuid();       /* get REAL uid */
181
        realgid=getgid();       /* get REAL uid */
182
 
183
        exp_dev_tty = open("/dev/tty",O_RDWR);
184
        knew_dev_tty = (exp_dev_tty != -1);
185
        if (knew_dev_tty) ttytype(GET_TTYTYPE,exp_dev_tty,0,0,(char *)0);
186
 
187
        /*
188
         * Acquire (as root) current user name and host.
189
         */
190
        (void) cuserid(myname);
191
        (void) gethostname(hostname,sizeof(hostname));
192
 
193
        /*
194
         * Set the real and effective userids to root using 'setuid'.  Then
195
         * set the real and effective userids to the actual user using
196
         * 'setreuid'.  This allows using 'seteuid' to go back and forth from
197
         * root and the actual userid.  Don't ask me why it works.
198
         */
199
        setuid(0);
200
        setreuid(realuid,realuid);
201
}
202
 
203
/* returns fd of master end of pseudotty */
204
int
205
getptymaster()
206
{
207
        struct stat sb;
208
        int master;
209
        int npty;
210
 
211
        exp_pty_error = 0;
212
 
213
        debuglog("getptymaster:  lowpty=%d  highpty=%d\n",lowpty,highpty);
214
        for (npty = lowpty; npty <= highpty; npty++) {
215
                if (seteuid(0) == -1) {          /* we need to be root! */
216
                        debuglog("getptymaster:  seteuid root errno=%d\n",
217
                                errno);
218
                }
219
                (void) sprintf(linep, "/dev/pty/%03d", npty);
220
                master = open(linep, O_RDWR);
221
 
222
                if (master < 0) {
223
                        debuglog("getptymaster:  open linep=%s errno=%d\n",
224
                                linep,errno);
225
                        continue;
226
                }
227
 
228
                (void) sprintf(linet, "/dev/ttyp%03d", npty);
229
                if(stat(linet, &sb) < 0) {
230
                        debuglog("getptymaster:  stat linet=%s errno=%d\n",
231
                                linet,errno);
232
                        (void) close(master);
233
                        continue;
234
                }
235
                if (sb.st_uid || sb.st_gid || sb.st_mode != 0600) {
236
                        if (chown(linet, realuid, realgid) == -1) {
237
                                debuglog("getptymaster:  chown linet=%s errno=%d\n",
238
                                        linet,errno);
239
                        }
240
                        if (chmod(linet, 0600) == -1) {
241
                                debuglog("getptymaster:  chmod linet=%s errno=%d\n",
242
                                        linet,errno);
243
                        }
244
                        (void)close(master);
245
                        master = open(linep, 2);
246
                        if (master < 0) {
247
                                debuglog("getptymaster:  reopen linep=%s errno=%d\n",
248
                                        linep,errno);
249
                                continue;
250
                        }
251
                }
252
                if (seteuid(realuid) == -1) {   /* back to who we are! */
253
                        debuglog("getptymaster:  seteuid user errno=%d\n",
254
                                errno);
255
                }
256
                if (access(linet, R_OK|W_OK) != 0) {
257
                        debuglog("getptymaster:  access linet=%s errno=%d\n",
258
                                linet,errno);
259
                        (void) close(master);
260
                        continue;
261
                }
262
                debuglog("getptymaster:  allocated %s\n",linet);
263
                ptys[npty] = -1;
264
                exp_pty_slave_name = linet;
265
                return(master);
266
        }
267
        if (seteuid(realuid) == -1) {           /* back to who we are! */
268
                debuglog("getptymaster:  seteuid user errno=%d\n",errno);
269
        }
270
        return(-1);
271
}
272
 
273
/* see comment in pty_termios.c */
274
/*ARGSUSED*/
275
void
276
exp_slave_control(master,control)
277
int master;
278
int control;
279
{
280
}
281
 
282
int
283
getptyslave(ttycopy,ttyinit,stty_args)
284
int ttycopy;
285
int ttyinit;
286
char *stty_args;
287
{
288
        int slave;
289
 
290
        if (0 > (slave = open(linet, O_RDWR))) {
291
                debuglog("getptyslave:  open linet=%s errno=%d\n",linet,errno);
292
                return(-1);
293
        }
294
 
295
        /* sanity check - if slave not 0, skip rest of this and return */
296
        /* to what will later be detected as an error in caller */
297
        if (0 != slave) {
298
                debuglog("getptyslave:  slave fd not 0\n");
299
                 return(slave);
300
        }
301
 
302
        if (0 == slave) {
303
                /* if opened in a new process, slave will be 0 (and */
304
                /* ultimately, 1 and 2 as well) */
305
 
306
                /* duplicate 0 onto 1 and 2 to prepare for stty */
307
                fcntl(0,F_DUPFD,1);
308
                fcntl(0,F_DUPFD,2);
309
        }
310
 
311
        ttytype(SET_TTYTYPE,slave,ttycopy,ttyinit,stty_args);
312
        return(slave);
313
}
314
 
315
setptyutmp()
316
{
317
        struct utmp utmp;
318
 
319
        if (seteuid(0) == -1) {          /* Need to be root */
320
                debuglog("setptyutmp:  setuid root errno=%d\n",errno);
321
                return(-1);
322
        }
323
        (void) time(&utmp.ut_time);
324
        utmp.ut_type = USER_PROCESS;
325
        utmp.ut_pid = getpid();
326
        strncpy(utmp.ut_user,myname,sizeof(utmp.ut_user));
327
        strncpy(utmp.ut_host,hostname,sizeof(utmp.ut_host));
328
        strncpy(utmp.ut_line,linet+5,sizeof(utmp.ut_line));
329
        strncpy(utmp.ut_id,linet+8,sizeof(utmp.ut_id));
330
        if (pututline(&utmp) == NULL) {
331
                debuglog("setptyutmp:  pututline failed\n");
332
        }
333
        endutent();
334
        if (seteuid(realuid) == -1)
335
                debuglog("setptyutmp:  seteuid user errno=%d\n",errno);
336
        return(0);
337
}
338
 
339
setptypid(pid)
340
int pid;
341
{
342
        int npty;
343
 
344
        for (npty = lowpty; npty <= highpty; npty++) {
345
                if (ptys[npty] < 0) {
346
                        debuglog("setptypid:  ttyp%03d pid=%d\n",npty,pid);
347
                        ptys[npty] = pid;
348
                        break;
349
                }
350
        }
351
}
352
 
353
ttyp_reset()
354
{
355
        int npty;
356
 
357
        if (seteuid(0) == -1) {          /* we need to be root! */
358
                debuglog("ttyp_reset:  seteuid root errno=%d\n",errno);
359
        }
360
        for (npty = lowpty; npty <= highpty; npty++) {
361
                if (ptys[npty] <= 0)
362
                        continue;
363
 
364
                (void) sprintf(linet, "/dev/ttyp%03d", npty);
365
                debuglog("ttyp_reset:  resetting %s, killing %d\n",
366
                        linet,ptys[npty]);
367
                if (chown(linet,0,0) == -1) {
368
                        debuglog("ttyp_reset: chown %s errno=%d\n",linet,errno);
369
                }
370
                if (chmod(linet, 0666) == -1) {
371
                        debuglog("ttyp_reset: chmod %s errno=%d\n",linet,errno);
372
                }
373
                resetptyutmp();
374
                if (kill(ptys[npty],SIGKILL) == -1) {
375
                        debuglog("ttyp_reset:  kill pid=%d errno=%d\n",
376
                                ptys[npty],errno);
377
                }
378
        }
379
        if (seteuid(realuid) == -1) {   /* Back to who we really are */
380
                debuglog("ttyp_reset:  seteuid user errno=%d\n",errno);
381
        }
382
}
383
 
384
void
385
exp_pty_exit()
386
{
387
        ttyp_reset();
388
}
389
 
390
resetptyutmp()
391
{
392
        struct utmp utmp;
393
 
394
        (void) setutent ();
395
        /* set up entry to search for */
396
        (void) strncpy(utmp.ut_id, linet + strlen(linet) - 4,
397
                 sizeof (utmp.ut_id));
398
        utmp.ut_type = USER_PROCESS;
399
 
400
        /* position to entry in utmp file */
401
        if(getutid(&utmp) == NULL) {
402
                debuglog("resetptyutmp:  no utmp entry for %s\n",linet);
403
                return(-1);     /* no utmp entry for this line ??? */
404
        }
405
 
406
        /* set up the new entry */
407
        strncpy(utmp.ut_name,"",sizeof(utmp.ut_name));
408
        strncpy(utmp.ut_host,"",sizeof(utmp.ut_host));
409
        time(&utmp.ut_time);
410
        utmp.ut_type = DEAD_PROCESS;
411
        utmp.ut_exit.e_exit = 0;
412
 
413
        /* write out the entry */
414
        pututline(&utmp);
415
 
416
        /* close the file */
417
        (void) endutent();
418
        return(0);
419
}

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.