~ubuntu-branches/ubuntu/wily/netkit-telnet-ssl/wily-proposed

« back to all changes in this revision

Viewing changes to .pc/545-track_scm.diff/telnetd/sys_term.c

  • Committer: Package Import Robot
  • Author(s): Mats Erik Andersson
  • Date: 2015-04-27 23:20:22 UTC
  • mfrom: (7.1.2 sid)
  • Revision ID: package-import@ubuntu.com-20150427232022-c2f04nl1gr4qyqom
Tags: 0.17.40+0.2-1
* Bring in package changes from experimental to unstable.
* Update to source version 0.17-40 of netkit-telnet.
  + debian/rules: Define and use the variable LDDEFS.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 * Copyright (c) 1989 Regents of the University of California.
 
3
 * All rights reserved.
 
4
 *
 
5
 * Redistribution and use in source and binary forms, with or without
 
6
 * modification, are permitted provided that the following conditions
 
7
 * are met:
 
8
 * 1. Redistributions of source code must retain the above copyright
 
9
 *    notice, this list of conditions and the following disclaimer.
 
10
 * 2. Redistributions in binary form must reproduce the above copyright
 
11
 *    notice, this list of conditions and the following disclaimer in the
 
12
 *    documentation and/or other materials provided with the distribution.
 
13
 * 3. All advertising materials mentioning features or use of this software
 
14
 *    must display the following acknowledgement:
 
15
 *      This product includes software developed by the University of
 
16
 *      California, Berkeley and its contributors.
 
17
 * 4. Neither the name of the University nor the names of its contributors
 
18
 *    may be used to endorse or promote products derived from this software
 
19
 *    without specific prior written permission.
 
20
 *
 
21
 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
 
22
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 
23
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 
24
 * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
 
25
 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 
26
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
 
27
 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 
28
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
 
29
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
 
30
 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 
31
 * SUCH DAMAGE.
 
32
 */
 
33
 
 
34
/*
 
35
 * From: @(#)sys_term.c 5.16 (Berkeley) 3/22/91
 
36
 */
 
37
char st_rcsid[] = 
 
38
  "$Id: sys_term.c,v 1.17 1999/12/17 14:28:47 dholland Exp $";
 
39
 
 
40
#include <utmp.h>
 
41
 
 
42
#include "telnetd.h"
 
43
#include "pathnames.h"
 
44
 
 
45
#if defined(__GLIBC__) && (__GLIBC__ >= 2)
 
46
/* mmm, nonstandard */
 
47
#include <pty.h>
 
48
#else
 
49
int openpty(int *, int *, char *, struct termios *, struct winsize *);
 
50
#endif
 
51
 
 
52
#define ARCH64 ((sizeof(void *)) == 8)
 
53
#define ARCH32 ((sizeof(void *)) == 4)
 
54
 
 
55
#if defined(AUTHENTICATE)
 
56
#include <libtelnet/auth.h>
 
57
#endif
 
58
 
 
59
static struct termios termbuf, termbuf2;        /* pty control structure */
 
60
 
 
61
#ifdef USE_SSL
 
62
#define DO_SHUTDOWN(x,y) \
 
63
                         if (debug) { \
 
64
                           fprintf(stderr,"Doing SSL_shutdown\n");\
 
65
                           fflush(stderr); \
 
66
                         } \
 
67
                         if (ssl_active_flag) \
 
68
                           SSL_shutdown(ssl_con); \
 
69
                         shutdown((x),(y))
 
70
#else
 
71
#define DO_SHUTDOWN(x,y) shutdown((x),(y))
 
72
#endif
 
73
 
 
74
/*static int cleanopen(char *line);*/
 
75
 
 
76
/*
 
77
 * init_termbuf()
 
78
 * copy_termbuf(cp)
 
79
 * set_termbuf()
 
80
 *
 
81
 * These three routines are used to get and set the "termbuf" structure
 
82
 * to and from the kernel.  init_termbuf() gets the current settings.
 
83
 * copy_termbuf() hands in a new "termbuf" to write to the kernel, and
 
84
 * set_termbuf() writes the structure into the kernel.
 
85
 */
 
86
 
 
87
void init_termbuf(void) {
 
88
    tcgetattr(pty, &termbuf);
 
89
    termbuf2 = termbuf;
 
90
}
 
91
 
 
92
#if defined(LINEMODE) && defined(TIOCPKT_IOCTL)
 
93
/*
 
94
 * ?
 
95
 */
 
96
void copy_termbuf(char *cp, int len) {
 
97
    if (len > sizeof(termbuf)) len = sizeof(termbuf);
 
98
    bcopy(cp, (char *)&termbuf, len);
 
99
    termbuf2 = termbuf;
 
100
}
 
101
#endif /* defined(LINEMODE) && defined(TIOCPKT_IOCTL) */
 
102
 
 
103
void set_termbuf(void) {
 
104
    if (memcmp(&termbuf, &termbuf2, sizeof(termbuf))) {
 
105
        tcsetattr(pty, TCSANOW, &termbuf);
 
106
    }
 
107
}
 
108
 
 
109
 
 
110
/*
 
111
 * spcset(func, valp, valpp)
 
112
 *
 
113
 * This function takes various special characters (func), and
 
114
 * sets *valp to the current value of that character, and
 
115
 * *valpp to point to where in the "termbuf" structure that
 
116
 * value is kept.
 
117
 *
 
118
 * It returns the SLC_ level of support for this function.
 
119
 */
 
120
 
 
121
 
 
122
int spcset(int func, cc_t *valp, cc_t **valpp) {
 
123
 
 
124
#define setval(a, b)    *valp = termbuf.c_cc[a]; \
 
125
                        *valpp = &termbuf.c_cc[a]; \
 
126
                        return(b);
 
127
#define defval(a) *valp = ((cc_t)a); *valpp = (cc_t *)0; return(SLC_DEFAULT);
 
128
 
 
129
    switch(func) {
 
130
    case SLC_EOF:
 
131
        setval(VEOF, SLC_VARIABLE);
 
132
    case SLC_EC:
 
133
        setval(VERASE, SLC_VARIABLE);
 
134
    case SLC_EL:
 
135
        setval(VKILL, SLC_VARIABLE);
 
136
    case SLC_IP:
 
137
        setval(VINTR, SLC_VARIABLE|SLC_FLUSHIN|SLC_FLUSHOUT);
 
138
    case SLC_ABORT:
 
139
        setval(VQUIT, SLC_VARIABLE|SLC_FLUSHIN|SLC_FLUSHOUT);
 
140
    case SLC_XON:
 
141
#ifdef VSTART
 
142
        setval(VSTART, SLC_VARIABLE);
 
143
#else
 
144
        defval(0x13);
 
145
#endif
 
146
    case SLC_XOFF:
 
147
#ifdef  VSTOP
 
148
        setval(VSTOP, SLC_VARIABLE);
 
149
#else
 
150
        defval(0x11);
 
151
#endif
 
152
    case SLC_EW:
 
153
#ifdef  VWERASE
 
154
        setval(VWERASE, SLC_VARIABLE);
 
155
#else
 
156
        defval(0);
 
157
#endif
 
158
    case SLC_RP:
 
159
#ifdef  VREPRINT
 
160
        setval(VREPRINT, SLC_VARIABLE);
 
161
#else
 
162
        defval(0);
 
163
#endif
 
164
    case SLC_LNEXT:
 
165
#ifdef  VLNEXT
 
166
        setval(VLNEXT, SLC_VARIABLE);
 
167
#else
 
168
        defval(0);
 
169
#endif
 
170
    case SLC_AO:
 
171
#if     !defined(VDISCARD) && defined(VFLUSHO)
 
172
# define VDISCARD VFLUSHO
 
173
#endif
 
174
#ifdef  VDISCARD
 
175
        setval(VDISCARD, SLC_VARIABLE|SLC_FLUSHOUT);
 
176
#else
 
177
        defval(0);
 
178
#endif
 
179
    case SLC_SUSP:
 
180
#ifdef  VSUSP
 
181
        setval(VSUSP, SLC_VARIABLE|SLC_FLUSHIN);
 
182
#else
 
183
        defval(0);
 
184
#endif
 
185
#ifdef  VEOL
 
186
    case SLC_FORW1:
 
187
        setval(VEOL, SLC_VARIABLE);
 
188
#endif
 
189
#ifdef  VEOL2
 
190
    case SLC_FORW2:
 
191
        setval(VEOL2, SLC_VARIABLE);
 
192
#endif
 
193
    case SLC_AYT:
 
194
#ifdef  VSTATUS
 
195
        setval(VSTATUS, SLC_VARIABLE);
 
196
#else
 
197
        defval(0);
 
198
#endif
 
199
        
 
200
    case SLC_BRK:
 
201
    case SLC_SYNCH:
 
202
    case SLC_EOR:
 
203
        defval(0);
 
204
        
 
205
    default:
 
206
        *valp = 0;
 
207
        *valpp = 0;
 
208
        return(SLC_NOSUPPORT);
 
209
    }
 
210
}
 
211
 
 
212
/*
 
213
 * getpty()
 
214
 *
 
215
 * Allocate a pty.  As a side effect, the external character
 
216
 * array "line" contains the name of the slave side.
 
217
 *
 
218
 * Returns the file descriptor of the opened pty.
 
219
 */
 
220
const char *line;
 
221
 
 
222
static int ptyslavefd=-1;
 
223
 
 
224
int getpty(void) {
 
225
    int masterfd;
 
226
 
 
227
    if (openpty(&masterfd, &ptyslavefd, NULL, NULL, NULL)) {
 
228
        return -1;
 
229
    }
 
230
    line = ttyname(ptyslavefd);
 
231
    return masterfd;
 
232
}
 
233
 
 
234
#ifdef  LINEMODE
 
235
/*
 
236
 * tty_flowmode()       Find out if flow control is enabled or disabled.
 
237
 * tty_linemode()       Find out if linemode (external processing) is enabled.
 
238
 * tty_setlinemod(on)   Turn on/off linemode.
 
239
 * tty_isecho()         Find out if echoing is turned on.
 
240
 * tty_setecho(on)      Enable/disable character echoing.
 
241
 * tty_israw()          Find out if terminal is in RAW mode.
 
242
 * tty_binaryin(on)     Turn on/off BINARY on input.
 
243
 * tty_binaryout(on)    Turn on/off BINARY on output.
 
244
 * tty_isediting()      Find out if line editing is enabled.
 
245
 * tty_istrapsig()      Find out if signal trapping is enabled.
 
246
 * tty_setedit(on)      Turn on/off line editing.
 
247
 * tty_setsig(on)       Turn on/off signal trapping.
 
248
 * tty_issofttab()      Find out if tab expansion is enabled.
 
249
 * tty_setsofttab(on)   Turn on/off soft tab expansion.
 
250
 * tty_islitecho()      Find out if typed control chars are echoed literally
 
251
 * tty_setlitecho()     Turn on/off literal echo of control chars
 
252
 * tty_tspeed(val)      Set transmit speed to val.
 
253
 * tty_rspeed(val)      Set receive speed to val.
 
254
 */
 
255
 
 
256
int tty_flowmode(void) {
 
257
    return (termbuf.c_iflag & IXON ? 1 : 0);
 
258
}
 
259
 
 
260
int tty_linemode(void) {
 
261
    return (termbuf.c_lflag & EXTPROC);
 
262
}
 
263
 
 
264
void tty_setlinemode(int on) {
 
265
#ifdef TIOCEXT
 
266
    set_termbuf();
 
267
    ioctl(pty, TIOCEXT, (char *)&on);
 
268
    init_termbuf();
 
269
#else   /* !TIOCEXT */
 
270
# ifdef EXTPROC
 
271
    if (on) termbuf.c_lflag |= EXTPROC;
 
272
    else termbuf.c_lflag &= ~EXTPROC;
 
273
# endif
 
274
#endif  /* TIOCEXT */
 
275
}
 
276
 
 
277
int tty_isecho(void) {
 
278
    return (termbuf.c_lflag & ECHO);
 
279
}
 
280
#endif  /* LINEMODE */
 
281
 
 
282
void tty_setecho(int on) {
 
283
    if (on) termbuf.c_lflag |= ECHO;
 
284
    else termbuf.c_lflag &= ~ECHO;
 
285
}
 
286
 
 
287
#if defined(LINEMODE) && defined(KLUDGELINEMODE)
 
288
int tty_israw(void) {
 
289
    return(!(termbuf.c_lflag & ICANON));
 
290
}
 
291
#endif  /* defined(LINEMODE) && defined(KLUDGELINEMODE) */
 
292
 
 
293
void tty_binaryin(int on) {
 
294
    if (on) {
 
295
        termbuf.c_iflag &= ~ISTRIP;
 
296
    }
 
297
    else {
 
298
        termbuf.c_iflag |= ISTRIP;
 
299
    }
 
300
}
 
301
 
 
302
void tty_binaryout(int on) {
 
303
    if (on) {
 
304
        termbuf.c_cflag &= ~(CSIZE|PARENB);
 
305
        termbuf.c_cflag |= CS8;
 
306
        termbuf.c_oflag &= ~OPOST;
 
307
    } 
 
308
    else {
 
309
        termbuf.c_cflag &= ~CSIZE;
 
310
        termbuf.c_cflag |= CS7|PARENB;
 
311
        termbuf.c_oflag |= OPOST;
 
312
    }
 
313
}
 
314
 
 
315
int tty_isbinaryin(void) {
 
316
    return (!(termbuf.c_iflag & ISTRIP));
 
317
}
 
318
 
 
319
int tty_isbinaryout(void) {
 
320
    return (!(termbuf.c_oflag&OPOST));
 
321
}
 
322
 
 
323
#ifdef  LINEMODE
 
324
int tty_isediting(void) {
 
325
    return(termbuf.c_lflag & ICANON);
 
326
}
 
327
 
 
328
int tty_istrapsig(void) {
 
329
    return(termbuf.c_lflag & ISIG);
 
330
}
 
331
 
 
332
void tty_setedit(int on) {
 
333
    if (on) termbuf.c_lflag |= ICANON;
 
334
    else termbuf.c_lflag &= ~ICANON;
 
335
}
 
336
 
 
337
void tty_setsig(int on) {
 
338
    if (on) termbuf.c_lflag |= ISIG;
 
339
    else termbuf.c_lflag &= ~ISIG;
 
340
}
 
341
#endif  /* LINEMODE */
 
342
 
 
343
int tty_issofttab(void) {
 
344
#ifdef OXTABS
 
345
    return (termbuf.c_oflag & OXTABS);
 
346
#endif
 
347
#ifdef TABDLY
 
348
    return ((termbuf.c_oflag & TABDLY) == TAB3);
 
349
#endif
 
350
}
 
351
 
 
352
void tty_setsofttab(int on) {
 
353
    if (on) {
 
354
#ifdef  OXTABS
 
355
        termbuf.c_oflag |= OXTABS;
 
356
#endif
 
357
#ifdef  TABDLY
 
358
        termbuf.c_oflag &= ~TABDLY;
 
359
        termbuf.c_oflag |= TAB3;
 
360
#endif
 
361
    } 
 
362
    else {
 
363
#ifdef  OXTABS
 
364
        termbuf.c_oflag &= ~OXTABS;
 
365
#endif
 
366
#ifdef  TABDLY
 
367
        termbuf.c_oflag &= ~TABDLY;
 
368
        termbuf.c_oflag |= TAB0;
 
369
#endif
 
370
    }
 
371
}
 
372
 
 
373
int tty_islitecho(void) {
 
374
    return (!(termbuf.c_lflag & ECHOCTL));
 
375
}
 
376
 
 
377
void tty_setlitecho(int on) {
 
378
    if (on) termbuf.c_lflag &= ~ECHOCTL;
 
379
    else termbuf.c_lflag |= ECHOCTL;
 
380
}
 
381
 
 
382
int tty_iscrnl(void) {
 
383
    return (termbuf.c_iflag & ICRNL);
 
384
}
 
385
 
 
386
/*
 
387
 * A table of available terminal speeds
 
388
 */
 
389
struct termspeeds {
 
390
        int     speed;
 
391
        int     value;
 
392
} termspeeds[] = {
 
393
        { 0,     B0 },    { 50,    B50 },   { 75,    B75 },
 
394
        { 110,   B110 },  { 134,   B134 },  { 150,   B150 },
 
395
        { 200,   B200 },  { 300,   B300 },  { 600,   B600 },
 
396
        { 1200,  B1200 }, { 1800,  B1800 }, { 2400,  B2400 },
 
397
        { 4800,  B4800 }, { 9600,  B9600 }, { 19200, B9600 },
 
398
        { 38400, B9600 }, { -1,    B9600 }
 
399
};
 
400
 
 
401
void tty_tspeed(int val) {
 
402
    struct termspeeds *tp;
 
403
    for (tp = termspeeds; (tp->speed != -1) && (val > tp->speed); tp++);
 
404
    cfsetospeed(&termbuf, tp->value);
 
405
}
 
406
 
 
407
void tty_rspeed(int val) {
 
408
    struct termspeeds *tp;
 
409
    for (tp = termspeeds; (tp->speed != -1) && (val > tp->speed); tp++);
 
410
    cfsetispeed(&termbuf, tp->value);
 
411
}
 
412
 
 
413
/*
 
414
 * getptyslave()
 
415
 *
 
416
 * Open the slave side of the pty, and do any initialization
 
417
 * that is necessary.  The return value is a file descriptor
 
418
 * for the slave side.
 
419
 */
 
420
#ifdef  TIOCGWINSZ
 
421
extern int def_row, def_col;
 
422
#endif
 
423
extern int def_tspeed, def_rspeed;
 
424
 
 
425
static int getptyslave(void) {
 
426
#if 0
 
427
    register int t = -1;
 
428
 
 
429
# ifdef LINEMODE
 
430
    int waslm;
 
431
# endif
 
432
# ifdef TIOCGWINSZ
 
433
    struct winsize ws;
 
434
# endif
 
435
    /*
 
436
     * Opening the slave side may cause initilization of the
 
437
     * kernel tty structure.  We need remember the state of
 
438
     *  if linemode was turned on
 
439
     *  terminal window size
 
440
     *  terminal speed
 
441
     * so that we can re-set them if we need to.
 
442
     */
 
443
# ifdef LINEMODE
 
444
    waslm = tty_linemode();
 
445
# endif
 
446
 
 
447
 
 
448
    /*
 
449
     * Make sure that we don't have a controlling tty, and
 
450
     * that we are the session (process group) leader.
 
451
     */
 
452
    t = open(_PATH_TTY, O_RDWR);
 
453
    if (t >= 0) {
 
454
        ioctl(t, TIOCNOTTY, (char *)0);
 
455
        close(t);
 
456
    }
 
457
 
 
458
    t = cleanopen(line);
 
459
    if (t < 0) fatalperror(net, line);
 
460
#endif /* 0 */
 
461
 
 
462
    struct winsize ws;
 
463
    int t = ptyslavefd;
 
464
 
 
465
    /*
 
466
     * set up the tty modes as we like them to be.
 
467
     */
 
468
    init_termbuf();
 
469
# ifdef TIOCGWINSZ
 
470
    if (def_row || def_col) {
 
471
        bzero((char *)&ws, sizeof(ws));
 
472
        ws.ws_col = def_col;
 
473
        ws.ws_row = def_row;
 
474
        ioctl(t, TIOCSWINSZ, (char *)&ws);
 
475
    }
 
476
# endif
 
477
 
 
478
    /*
 
479
     * Settings for all other termios/termio based
 
480
     * systems, other than 4.4BSD.  In 4.4BSD the
 
481
     * kernel does the initial terminal setup.
 
482
     *
 
483
     * XXX what about linux?
 
484
     */
 
485
#  ifndef       OXTABS
 
486
#   define OXTABS       0
 
487
#  endif
 
488
    termbuf.c_lflag |= ECHO;
 
489
    termbuf.c_oflag |= OPOST|ONLCR|OXTABS;
 
490
    termbuf.c_iflag |= ICRNL;
 
491
    termbuf.c_iflag &= ~IXOFF;
 
492
 
 
493
    tty_rspeed((def_rspeed > 0) ? def_rspeed : 9600);
 
494
    tty_tspeed((def_tspeed > 0) ? def_tspeed : 9600);
 
495
# ifdef LINEMODE
 
496
    if (waslm) tty_setlinemode(1);
 
497
# endif /* LINEMODE */
 
498
 
 
499
    /*
 
500
     * Set the tty modes, and make this our controlling tty.
 
501
     */
 
502
    set_termbuf();
 
503
    if (login_tty(t) == -1) fatalperror(net, "login_tty");
 
504
 
 
505
    if (net > 2) close(net);
 
506
    if (pty > 2) close(pty);
 
507
    return t;
 
508
}
 
509
 
 
510
#if 0
 
511
#ifndef O_NOCTTY
 
512
#define O_NOCTTY        0
 
513
#endif
 
514
/*
 
515
 * Open the specified slave side of the pty,
 
516
 * making sure that we have a clean tty.
 
517
 */
 
518
static int cleanopen(char *lyne) {
 
519
    register int t;
 
520
 
 
521
    /*
 
522
     * Make sure that other people can't open the
 
523
     * slave side of the connection.
 
524
     */
 
525
    chown(lyne, 0, 0);
 
526
    chmod(lyne, 0600);
 
527
 
 
528
#ifndef NO_REVOKE
 
529
    revoke(lyne);
 
530
#endif
 
531
 
 
532
    t = open(lyne, O_RDWR|O_NOCTTY);
 
533
    if (t < 0) return(-1);
 
534
 
 
535
    /*
 
536
     * Hangup anybody else using this ttyp, then reopen it for
 
537
     * ourselves.
 
538
     */
 
539
# if !defined(__linux__)
 
540
    /* this looks buggy to me, our ctty is really a pty at this point */
 
541
    signal(SIGHUP, SIG_IGN);
 
542
    vhangup();
 
543
    signal(SIGHUP, SIG_DFL);
 
544
    t = open(lyne, O_RDWR|O_NOCTTY);
 
545
    if (t < 0) return(-1);
 
546
# endif
 
547
    return(t);
 
548
}
 
549
#endif /* 0 */
 
550
 
 
551
int login_tty(int t) {
 
552
    if (setsid() < 0) fatalperror(net, "setsid()");
 
553
    if (ioctl(t, TIOCSCTTY, (char *)0) < 0) {
 
554
        fatalperror(net, "ioctl(sctty)");
 
555
    }
 
556
    if (t != 0) dup2(t, 0);
 
557
    if (t != 1) dup2(t, 1);
 
558
    if (t != 2) dup2(t, 2);
 
559
    if (t > 2) close(t);
 
560
    return 0;
 
561
}
 
562
 
 
563
/*
 
564
 * startslave(host)
 
565
 *
 
566
 * Given a hostname, do whatever
 
567
 * is necessary to startup the login process on the slave side of the pty.
 
568
 */
 
569
 
 
570
/* ARGSUSED */
 
571
void startslave(const char *host, int autologin, char *autoname) {
 
572
    int i;
 
573
 
 
574
#if defined(AUTHENTICATE)
 
575
    if (!autoname || !autoname[0]) autologin = 0;
 
576
    if (autologin < auth_level) {
 
577
        fatal(net, "Authorization failed");
 
578
        exit(1);
 
579
    }
 
580
#endif
 
581
 
 
582
    i = fork();
 
583
    if (i < 0) fatalperror(net, "fork");
 
584
    if (i) {
 
585
        /* parent */
 
586
        signal(SIGHUP,SIG_IGN);
 
587
        close(ptyslavefd);
 
588
    } 
 
589
    else {
 
590
        /* child */
 
591
        signal(SIGHUP,SIG_IGN);
 
592
        getptyslave();
 
593
        start_login(host, autologin, autoname);
 
594
        /*NOTREACHED*/
 
595
    }
 
596
}
 
597
 
 
598
char *envinit[3];
 
599
 
 
600
void init_env(void) {
 
601
    char **envp;
 
602
    envp = envinit;
 
603
    if ((*envp = getenv("TZ"))!=NULL)
 
604
        *envp++ -= 3;
 
605
    *envp = 0;
 
606
    environ = envinit;
 
607
}
 
608
 
 
609
/*
 
610
 * start_login(host)
 
611
 *
 
612
 * Assuming that we are now running as a child processes, this
 
613
 * function will turn us into the login process.
 
614
 */
 
615
 
 
616
struct argv_stuff {
 
617
   const char **argv;
 
618
   int argc;
 
619
   int argmax;
 
620
};
 
621
 
 
622
static void addarg(struct argv_stuff *, const char *);
 
623
static void initarg(struct argv_stuff *);
 
624
 
 
625
void start_login(const char *host, int autologin, const char *name) {
 
626
    struct argv_stuff avs;
 
627
    char *const *argvfoo;
 
628
    (void)autologin;
 
629
 
 
630
    initarg(&avs);
 
631
 
 
632
    /*
 
633
     * -h : pass on name of host.
 
634
     *          WARNING:  -h is accepted by login if and only if
 
635
     *                  getuid() == 0.
 
636
     * -p : don't clobber the environment (so terminal type stays set).
 
637
     *
 
638
     * -f : force this login, he has already been authenticated
 
639
     */
 
640
    addarg(&avs, loginprg);
 
641
    addarg(&avs, "-h");
 
642
    addarg(&avs, host);
 
643
#if !defined(NO_LOGIN_P)
 
644
    addarg(&avs, "-p");
 
645
#endif
 
646
#ifdef BFTPDAEMON
 
647
    /*
 
648
     * Are we working as the bftp daemon?  If so, then ask login
 
649
     * to start bftp instead of shell.
 
650
     */
 
651
    if (bftpd) {
 
652
        addarg(&avs, "-e");
 
653
        addarg(&avs, BFTPPATH);
 
654
    } 
 
655
    else
 
656
#endif
 
657
    {
 
658
#if defined (SecurID)
 
659
        /*
 
660
         * don't worry about the -f that might get sent.
 
661
         * A -s is supposed to override it anyhow.
 
662
         */
 
663
        if (require_SecurID) addarg(&avs, "-s");
 
664
#endif
 
665
        if (*name=='-') {
 
666
            syslog(LOG_ERR, "Attempt to login with an option!");
 
667
            name = "";
 
668
        }
 
669
#if defined (AUTHENTICATE)
 
670
        if (auth_level >= 0 && autologin == AUTH_VALID) {
 
671
# if !defined(NO_LOGIN_F)
 
672
            addarg(&avs, "-f");
 
673
# endif
 
674
            addarg(&avs, name);
 
675
        } 
 
676
        else
 
677
#endif
 
678
        {
 
679
            if (getenv("USER")) {
 
680
                addarg(&avs, getenv("USER"));
 
681
                if (*getenv("USER") == '-') {
 
682
                    write(1,"I don't hear you!\r\n",19);
 
683
                    syslog(LOG_ERR,"Attempt to login with an option!");
 
684
                    exit(1);
 
685
                }
 
686
            }
 
687
        }
 
688
    }
 
689
    closelog();
 
690
    /* execv() should really take char const* const *, but it can't */ 
 
691
    /*argvfoo = argv*/;
 
692
    memcpy(&argvfoo, &avs.argv, sizeof(argvfoo));
 
693
    execv(loginprg, argvfoo);
 
694
 
 
695
    openlog("telnetd", LOG_PID | LOG_ODELAY, LOG_DAEMON);
 
696
    syslog(LOG_ERR, "%s: %m\n", loginprg);
 
697
    closelog();
 
698
    fatalperror(net, loginprg);
 
699
}
 
700
 
 
701
static void initarg(struct argv_stuff *avs) {
 
702
   /*
 
703
    * 10 entries and a null
 
704
    */
 
705
   avs->argmax = 11;
 
706
   avs->argv = malloc(sizeof(avs->argv[0]) * avs->argmax);
 
707
   if (avs->argv == NULL) {
 
708
      fprintf(stderr, "Out of memory\n");
 
709
      exit(1);
 
710
   }
 
711
   avs->argc = 0;
 
712
   avs->argv[0] = NULL;
 
713
}
 
714
 
 
715
static void addarg(struct argv_stuff *avs, const char *val) {
 
716
   if (avs->argc>=avs->argmax-1) {
 
717
       avs->argmax += 10;
 
718
       avs->argv = realloc(avs->argv, sizeof(avs->argv[0])*avs->argmax);
 
719
       if (avs->argv == NULL) {
 
720
          fprintf(stderr, "Out of memory\n");
 
721
          exit(1);
 
722
       }
 
723
   }
 
724
 
 
725
   avs->argv[avs->argc++] = val;
 
726
   avs->argv[avs->argc] = NULL;
 
727
}
 
728
 
 
729
/*
 
730
 * cleanup()
 
731
 *
 
732
 * This is the routine to call when we are all through, to
 
733
 * clean up anything that needs to be cleaned up.
 
734
 */
 
735
void cleanup(int sig) {
 
736
    const char *p;
 
737
    (void)sig;
 
738
 
 
739
    p = line + sizeof("/dev/") - 1;
 
740
    if (logout(p)) logwtmp(p, "", "");
 
741
    shutdown(net, 2);
 
742
    exit(0);
 
743
}