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

Subversion Repositories or1k

[/] [or1k/] [trunk/] [uclinux/] [userland/] [telnet/] [commands.c] - Blame information for rev 763

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 763 simons
/*
2
 * Copyright (c) 1988, 1990, 1993
3
 *      The Regents of the University of California.  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
#ifndef lint
35
static char sccsid[] = "@(#)commands.c  8.2 (Berkeley) 12/15/93";
36
#endif /* not lint */
37
 
38
#if     defined(unix)
39
#include <sys/param.h>
40
#if     defined(CRAY) || defined(sysV88)
41
#include <sys/types.h>
42
#endif
43
#include <sys/file.h>
44
#else
45
#include <sys/types.h>
46
#endif  /* defined(unix) */
47
#include <sys/socket.h>
48
#include <sys/wait.h>
49
#include <netinet/in.h>
50
#ifdef  CRAY
51
#include <fcntl.h>
52
#endif  /* CRAY */
53
 
54
#include <stdlib.h>
55
#include <string.h>
56
#include <signal.h>
57
#include <netdb.h>
58
#include <ctype.h>
59
#include <pwd.h>
60
#include <varargs.h>
61
#include <errno.h>
62
#ifdef __linux__
63
#include <unistd.h>
64
#endif
65
 
66
#include <arpa/telnet.h>
67
#include <arpa/inet.h>
68
 
69
#include "general.h"
70
 
71
#include "ring.h"
72
 
73
#include "externs.h"
74
#include "defines.h"
75
#include "types.h"
76
 
77
#if !defined(CRAY) && !defined(sysV88)
78
#include <netinet/in_systm.h>
79
# if (defined(vax) || defined(tahoe) || defined(hp300)) && !defined(ultrix)
80
# include <machine/endian.h>
81
# endif /* vax */
82
#endif /* !defined(CRAY) && !defined(sysV88) */
83
#include <netinet/ip.h>
84
 
85
 
86
#ifndef       MAXHOSTNAMELEN
87
#define       MAXHOSTNAMELEN 64
88
#endif        MAXHOSTNAMELEN
89
 
90
#if     defined(IPPROTO_IP) && defined(IP_TOS)
91
int tos = -1;
92
#endif  /* defined(IPPROTO_IP) && defined(IP_TOS) */
93
 
94
char    *hostname;
95
static char _hostname[MAXHOSTNAMELEN];
96
 
97
extern char *getenv();
98
 
99
extern int isprefix();
100
extern char **genget();
101
extern int Ambiguous();
102
 
103
static int call(int (*intrtn_t)(), ...);
104
 
105
typedef struct {
106
        char    *name;          /* command name */
107
        char    *help;          /* help string (NULL for no help) */
108
        int     (*handler)();   /* routine which executes command */
109
        int     needconnect;    /* Do we need to be connected to execute? */
110
} Command;
111
 
112
static char line[256];
113
static char saveline[256];
114
static int margc;
115
static char *margv[20];
116
 
117
#if     defined(SKEY)
118
#include <sys/wait.h>
119
#define PATH_SKEY       "/usr/bin/key"
120
    int
121
skey_calc(argc, argv)
122
        int argc;
123
        char **argv;
124
{
125
        int status;
126
 
127
        if(argc != 3) {
128
                printf("%s sequence challenge\n", argv[0]);
129
                return;
130
        }
131
 
132
        switch(fork()) {
133
        case 0:
134
                execv(PATH_SKEY, argv);
135
                exit (1);
136
        case -1:
137
                perror("fork");
138
                break;
139
        default:
140
                (void) wait(&status);
141
                if (WIFEXITED(status))
142
                        return (WEXITSTATUS(status));
143
                return (0);
144
        }
145
}
146
#endif
147
 
148
    static void
149
makeargv()
150
{
151
    register char *cp, *cp2, c;
152
    register char **argp = margv;
153
 
154
    margc = 0;
155
    cp = line;
156
    if (*cp == '!') {           /* Special case shell escape */
157
        strcpy(saveline, line); /* save for shell command */
158
        *argp++ = "!";          /* No room in string to get this */
159
        margc++;
160
        cp++;
161
    }
162
    while (c = *cp) {
163
        register int inquote = 0;
164
        while (isspace(c))
165
            c = *++cp;
166
        if (c == '\0')
167
            break;
168
        *argp++ = cp;
169
        margc += 1;
170
        for (cp2 = cp; c != '\0'; c = *++cp) {
171
            if (inquote) {
172
                if (c == inquote) {
173
                    inquote = 0;
174
                    continue;
175
                }
176
            } else {
177
                if (c == '\\') {
178
                    if ((c = *++cp) == '\0')
179
                        break;
180
                } else if (c == '"') {
181
                    inquote = '"';
182
                    continue;
183
                } else if (c == '\'') {
184
                    inquote = '\'';
185
                    continue;
186
                } else if (isspace(c))
187
                    break;
188
            }
189
            *cp2++ = c;
190
        }
191
        *cp2 = '\0';
192
        if (c == '\0')
193
            break;
194
        cp++;
195
    }
196
    *argp++ = 0;
197
}
198
 
199
/*
200
 * Make a character string into a number.
201
 *
202
 * Todo:  1.  Could take random integers (12, 0x12, 012, 0b1).
203
 */
204
 
205
        static
206
special(s)
207
        register char *s;
208
{
209
        register char c;
210
        char b;
211
 
212
        switch (*s) {
213
        case '^':
214
                b = *++s;
215
                if (b == '?') {
216
                    c = b | 0x40;               /* DEL */
217
                } else {
218
                    c = b & 0x1f;
219
                }
220
                break;
221
        default:
222
                c = *s;
223
                break;
224
        }
225
        return c;
226
}
227
 
228
/*
229
 * Construct a control character sequence
230
 * for a special character.
231
 */
232
        static char *
233
control(c)
234
        register cc_t c;
235
{
236
        static char buf[5];
237
        /*
238
         * The only way I could get the Sun 3.5 compiler
239
         * to shut up about
240
         *      if ((unsigned int)c >= 0x80)
241
         * was to assign "c" to an unsigned int variable...
242
         * Arggg....
243
         */
244
        register unsigned int uic = (unsigned int)c;
245
 
246
        if (uic == 0x7f)
247
                return ("^?");
248
        if (c == (cc_t)_POSIX_VDISABLE) {
249
                return "off";
250
        }
251
        if (uic >= 0x80) {
252
                buf[0] = '\\';
253
                buf[1] = ((c>>6)&07) + '0';
254
                buf[2] = ((c>>3)&07) + '0';
255
                buf[3] = (c&07) + '0';
256
                buf[4] = 0;
257
        } else if (uic >= 0x20) {
258
                buf[0] = c;
259
                buf[1] = 0;
260
        } else {
261
                buf[0] = '^';
262
                buf[1] = '@'+c;
263
                buf[2] = 0;
264
        }
265
        return (buf);
266
}
267
 
268
 
269
 
270
/*
271
 *      The following are data structures and routines for
272
 *      the "send" command.
273
 *
274
 */
275
 
276
struct sendlist {
277
    char        *name;          /* How user refers to it (case independent) */
278
    char        *help;          /* Help information (0 ==> no help) */
279
    int         needconnect;    /* Need to be connected */
280
    int         narg;           /* Number of arguments */
281
    int         (*handler)();   /* Routine to perform (for special ops) */
282
    int         nbyte;          /* Number of bytes to send this command */
283
    int         what;           /* Character to be sent (<0 ==> special) */
284
};
285
 
286
 
287
static int
288
        send_esc P((void)),
289
        send_help P((void)),
290
        send_docmd P((char *)),
291
        send_dontcmd P((char *)),
292
        send_willcmd P((char *)),
293
        send_wontcmd P((char *));
294
 
295
static struct sendlist Sendlist[] = {
296
    { "ao",     "Send Telnet Abort output",             1, 0, 0, 2, AO },
297
    { "ayt",    "Send Telnet 'Are You There'",          1, 0, 0, 2, AYT },
298
    { "brk",    "Send Telnet Break",                    1, 0, 0, 2, BREAK },
299
    { "break",  0,                                       1, 0, 0, 2, BREAK },
300
    { "ec",     "Send Telnet Erase Character",          1, 0, 0, 2, EC },
301
    { "el",     "Send Telnet Erase Line",               1, 0, 0, 2, EL },
302
    { "escape", "Send current escape character",        1, 0, send_esc, 1, 0 },
303
    { "ga",     "Send Telnet 'Go Ahead' sequence",      1, 0, 0, 2, GA },
304
    { "ip",     "Send Telnet Interrupt Process",        1, 0, 0, 2, IP },
305
    { "intp",   0,                                       1, 0, 0, 2, IP },
306
    { "interrupt", 0,                                    1, 0, 0, 2, IP },
307
    { "intr",   0,                                       1, 0, 0, 2, IP },
308
    { "nop",    "Send Telnet 'No operation'",           1, 0, 0, 2, NOP },
309
    { "eor",    "Send Telnet 'End of Record'",          1, 0, 0, 2, EOR },
310
    { "abort",  "Send Telnet 'Abort Process'",          1, 0, 0, 2, ABORT },
311
    { "susp",   "Send Telnet 'Suspend Process'",        1, 0, 0, 2, SUSP },
312
    { "eof",    "Send Telnet End of File Character",    1, 0, 0, 2, xEOF },
313
    { "synch",  "Perform Telnet 'Synch operation'",     1, 0, dosynch, 2, 0 },
314
    { "getstatus", "Send request for STATUS",           1, 0, get_status, 6, 0 },
315
    { "?",      "Display send options",                 0, 0, send_help, 0, 0 },
316
    { "help",   0,                                       0, 0, send_help, 0, 0 },
317
    { "do",     0,                                       0, 1, send_docmd, 3, 0 },
318
    { "dont",   0,                                       0, 1, send_dontcmd, 3, 0 },
319
    { "will",   0,                                       0, 1, send_willcmd, 3, 0 },
320
    { "wont",   0,                                       0, 1, send_wontcmd, 3, 0 },
321
    { 0 }
322
};
323
 
324
#define GETSEND(name) ((struct sendlist *) genget(name, (char **) Sendlist, \
325
                                sizeof(struct sendlist)))
326
    /*VARARGS*/
327
    static
328
bye(argc, argv)
329
    int  argc;          /* Number of arguments */
330
    char *argv[];       /* arguments */
331
{
332
    extern int resettermname;
333
 
334
    if (connected) {
335
        (void) shutdown(net, 2);
336
        printf("Connection closed.\n");
337
        (void) NetClose(net);
338
        connected = 0;
339
        resettermname = 1;
340
#if     defined(AUTHENTICATION)
341
        auth_encrypt_connect(connected);
342
#endif  /* defined(AUTHENTICATION) */
343
        /* reset options */
344
        tninit();
345
#if     defined(TN3270)
346
        SetIn3270();            /* Get out of 3270 mode */
347
#endif  /* defined(TN3270) */
348
    }
349
    if ((argc != 2) || (strcmp(argv[1], "fromquit") != 0)) {
350
#ifdef EMBED
351
        printf("ERROR: no longjmp()\n");
352
        exit(1);
353
#else
354
        longjmp(toplevel, 1);
355
#endif
356
        /* NOTREACHED */
357
    }
358
    return 1;                   /* Keep lint, etc., happy */
359
}
360
 
361
/*VARARGS*/
362
    void
363
quit()
364
{
365
        (void) call(bye, "bye", "fromquit", 0);
366
        Exit(0);
367
        /*NOTREACHED*/
368
}
369
 
370
 
371
    static int
372
sendcmd(argc, argv)
373
    int  argc;
374
    char **argv;
375
{
376
    int count;          /* how many bytes we are going to need to send */
377
    int i;
378
    int question = 0;    /* was at least one argument a question */
379
    struct sendlist *s; /* pointer to current command */
380
    int success = 0;
381
    int needconnect = 0;
382
 
383
    if (argc < 2) {
384
        printf("need at least one argument for 'send' command\n");
385
        printf("'send ?' for help\n");
386
        return 0;
387
    }
388
    /*
389
     * First, validate all the send arguments.
390
     * In addition, we see how much space we are going to need, and
391
     * whether or not we will be doing a "SYNCH" operation (which
392
     * flushes the network queue).
393
     */
394
    count = 0;
395
    for (i = 1; i < argc; i++) {
396
        s = GETSEND(argv[i]);
397
        if (s == 0) {
398
            printf("Unknown send argument '%s'\n'send ?' for help.\n",
399
                        argv[i]);
400
            return 0;
401
        } else if (Ambiguous(s)) {
402
            printf("Ambiguous send argument '%s'\n'send ?' for help.\n",
403
                        argv[i]);
404
            return 0;
405
        }
406
        if (i + s->narg >= argc) {
407
            fprintf(stderr,
408
            "Need %d argument%s to 'send %s' command.  'send %s ?' for help.\n",
409
                s->narg, s->narg == 1 ? "" : "s", s->name, s->name);
410
            return 0;
411
        }
412
        count += s->nbyte;
413
        if (s->handler == send_help) {
414
            send_help();
415
            return 0;
416
        }
417
 
418
        i += s->narg;
419
        needconnect += s->needconnect;
420
    }
421
    if (!connected && needconnect) {
422
        printf("?Need to be connected first.\n");
423
        printf("'send ?' for help\n");
424
        return 0;
425
    }
426
    /* Now, do we have enough room? */
427
    if (NETROOM() < count) {
428
        printf("There is not enough room in the buffer TO the network\n");
429
        printf("to process your request.  Nothing will be done.\n");
430
        printf("('send synch' will throw away most data in the network\n");
431
        printf("buffer, if this might help.)\n");
432
        return 0;
433
    }
434
    /* OK, they are all OK, now go through again and actually send */
435
    count = 0;
436
    for (i = 1; i < argc; i++) {
437
        if ((s = GETSEND(argv[i])) == 0) {
438
            fprintf(stderr, "Telnet 'send' error - argument disappeared!\n");
439
            (void) quit();
440
            /*NOTREACHED*/
441
        }
442
        if (s->handler) {
443
            count++;
444
            success += (*s->handler)((s->narg > 0) ? argv[i+1] : 0,
445
                                  (s->narg > 1) ? argv[i+2] : 0);
446
            i += s->narg;
447
        } else {
448
            NET2ADD(IAC, s->what);
449
            printoption("SENT", IAC, s->what);
450
        }
451
    }
452
    return (count == success);
453
}
454
 
455
    static int
456
send_esc()
457
{
458
    NETADD(escape);
459
    return 1;
460
}
461
 
462
    int
463
send_tncmd(func, cmd, name)
464
    void        (*func)();
465
    char        *cmd, *name;
466
{
467
    char **cpp;
468
    extern char *telopts[];
469
    register int val = 0;
470
 
471
    if (isprefix(name, "help") || isprefix(name, "?")) {
472
        register int col, len;
473
 
474
        printf("Usage: send %s <value|option>\n", cmd);
475
        printf("\"value\" must be from 0 to 255\n");
476
        printf("Valid options are:\n\t");
477
 
478
        col = 8;
479
        for (cpp = telopts; *cpp; cpp++) {
480
            len = strlen(*cpp) + 3;
481
            if (col + len > 65) {
482
                printf("\n\t");
483
                col = 8;
484
            }
485
            printf(" \"%s\"", *cpp);
486
            col += len;
487
        }
488
        printf("\n");
489
        return 0;
490
    }
491
    cpp = (char **)genget(name, telopts, sizeof(char *));
492
    if (Ambiguous(cpp)) {
493
        fprintf(stderr,"'%s': ambiguous argument ('send %s ?' for help).\n",
494
                                        name, cmd);
495
        return 0;
496
    }
497
    if (cpp) {
498
        val = cpp - telopts;
499
    } else {
500
        register char *cp = name;
501
 
502
        while (*cp >= '0' && *cp <= '9') {
503
            val *= 10;
504
            val += *cp - '0';
505
            cp++;
506
        }
507
        if (*cp != 0) {
508
            fprintf(stderr, "'%s': unknown argument ('send %s ?' for help).\n",
509
                                        name, cmd);
510
            return 0;
511
        } else if (val < 0 || val > 255) {
512
            fprintf(stderr, "'%s': bad value ('send %s ?' for help).\n",
513
                                        name, cmd);
514
            return 0;
515
        }
516
    }
517
    if (!connected) {
518
        printf("?Need to be connected first.\n");
519
        return 0;
520
    }
521
    (*func)(val, 1);
522
    return 1;
523
}
524
 
525
    static int
526
send_docmd(name)
527
    char *name;
528
{
529
    return(send_tncmd(send_do, "do", name));
530
}
531
 
532
    static int
533
send_dontcmd(name)
534
    char *name;
535
{
536
    return(send_tncmd(send_dont, "dont", name));
537
}
538
    static int
539
send_willcmd(name)
540
    char *name;
541
{
542
    return(send_tncmd(send_will, "will", name));
543
}
544
    static int
545
send_wontcmd(name)
546
    char *name;
547
{
548
    return(send_tncmd(send_wont, "wont", name));
549
}
550
 
551
    static int
552
send_help()
553
{
554
    struct sendlist *s; /* pointer to current command */
555
    for (s = Sendlist; s->name; s++) {
556
        if (s->help)
557
            printf("%-15s %s\n", s->name, s->help);
558
    }
559
    return(0);
560
}
561
 
562
/*
563
 * The following are the routines and data structures referred
564
 * to by the arguments to the "toggle" command.
565
 */
566
 
567
    static int
568
lclchars()
569
{
570
    donelclchars = 1;
571
    return 1;
572
}
573
 
574
    static int
575
togdebug()
576
{
577
#ifndef NOT43
578
    if (net > 0 &&
579
        (SetSockOpt(net, SOL_SOCKET, SO_DEBUG, debug)) < 0) {
580
            perror("setsockopt (SO_DEBUG)");
581
    }
582
#else   /* NOT43 */
583
    if (debug) {
584
        if (net > 0 && SetSockOpt(net, SOL_SOCKET, SO_DEBUG, 1) < 0)
585
            perror("setsockopt (SO_DEBUG)");
586
    } else
587
        printf("Cannot turn off socket debugging\n");
588
#endif  /* NOT43 */
589
    return 1;
590
}
591
 
592
 
593
    static int
594
togcrlf()
595
{
596
    if (crlf) {
597
        printf("Will send carriage returns as telnet <CR><LF>.\n");
598
    } else {
599
        printf("Will send carriage returns as telnet <CR><NUL>.\n");
600
    }
601
    return 1;
602
}
603
 
604
int binmode;
605
 
606
    static int
607
togbinary(val)
608
    int val;
609
{
610
    donebinarytoggle = 1;
611
 
612
    if (val >= 0) {
613
        binmode = val;
614
    } else {
615
        if (my_want_state_is_will(TELOPT_BINARY) &&
616
                                my_want_state_is_do(TELOPT_BINARY)) {
617
            binmode = 1;
618
        } else if (my_want_state_is_wont(TELOPT_BINARY) &&
619
                                my_want_state_is_dont(TELOPT_BINARY)) {
620
            binmode = 0;
621
        }
622
        val = binmode ? 0 : 1;
623
    }
624
 
625
    if (val == 1) {
626
        if (my_want_state_is_will(TELOPT_BINARY) &&
627
                                        my_want_state_is_do(TELOPT_BINARY)) {
628
            printf("Already operating in binary mode with remote host.\n");
629
        } else {
630
            printf("Negotiating binary mode with remote host.\n");
631
            tel_enter_binary(3);
632
        }
633
    } else {
634
        if (my_want_state_is_wont(TELOPT_BINARY) &&
635
                                        my_want_state_is_dont(TELOPT_BINARY)) {
636
            printf("Already in network ascii mode with remote host.\n");
637
        } else {
638
            printf("Negotiating network ascii mode with remote host.\n");
639
            tel_leave_binary(3);
640
        }
641
    }
642
    return 1;
643
}
644
 
645
    static int
646
togrbinary(val)
647
    int val;
648
{
649
    donebinarytoggle = 1;
650
 
651
    if (val == -1)
652
        val = my_want_state_is_do(TELOPT_BINARY) ? 0 : 1;
653
 
654
    if (val == 1) {
655
        if (my_want_state_is_do(TELOPT_BINARY)) {
656
            printf("Already receiving in binary mode.\n");
657
        } else {
658
            printf("Negotiating binary mode on input.\n");
659
            tel_enter_binary(1);
660
        }
661
    } else {
662
        if (my_want_state_is_dont(TELOPT_BINARY)) {
663
            printf("Already receiving in network ascii mode.\n");
664
        } else {
665
            printf("Negotiating network ascii mode on input.\n");
666
            tel_leave_binary(1);
667
        }
668
    }
669
    return 1;
670
}
671
 
672
    static int
673
togxbinary(val)
674
    int val;
675
{
676
    donebinarytoggle = 1;
677
 
678
    if (val == -1)
679
        val = my_want_state_is_will(TELOPT_BINARY) ? 0 : 1;
680
 
681
    if (val == 1) {
682
        if (my_want_state_is_will(TELOPT_BINARY)) {
683
            printf("Already transmitting in binary mode.\n");
684
        } else {
685
            printf("Negotiating binary mode on output.\n");
686
            tel_enter_binary(2);
687
        }
688
    } else {
689
        if (my_want_state_is_wont(TELOPT_BINARY)) {
690
            printf("Already transmitting in network ascii mode.\n");
691
        } else {
692
            printf("Negotiating network ascii mode on output.\n");
693
            tel_leave_binary(2);
694
        }
695
    }
696
    return 1;
697
}
698
 
699
 
700
static int togglehelp P((void));
701
#if     defined(AUTHENTICATION)
702
extern int auth_togdebug P((int));
703
#endif
704
 
705
struct togglelist {
706
    char        *name;          /* name of toggle */
707
    char        *help;          /* help message */
708
    int         (*handler)();   /* routine to do actual setting */
709
    int         *variable;
710
    char        *actionexplanation;
711
};
712
 
713
static struct togglelist Togglelist[] = {
714
    { "autoflush",
715
        "flushing of output when sending interrupt characters",
716
            0,
717
                &autoflush,
718
                    "flush output when sending interrupt characters" },
719
    { "autosynch",
720
        "automatic sending of interrupt characters in urgent mode",
721
            0,
722
                &autosynch,
723
                    "send interrupt characters in urgent mode" },
724
#if     defined(AUTHENTICATION)
725
    { "autologin",
726
        "automatic sending of login and/or authentication info",
727
            0,
728
                &autologin,
729
                    "send login name and/or authentication information" },
730
    { "authdebug",
731
        "Toggle authentication debugging",
732
            auth_togdebug,
733
                0,
734
                     "print authentication debugging information" },
735
#endif
736
    { "skiprc",
737
        "don't read ~/.telnetrc file",
738
            0,
739
                &skiprc,
740
                    "skip reading of ~/.telnetrc file" },
741
    { "binary",
742
        "sending and receiving of binary data",
743
            togbinary,
744
                0,
745
 
746
    { "inbinary",
747
        "receiving of binary data",
748
            togrbinary,
749
                0,
750
 
751
    { "outbinary",
752
        "sending of binary data",
753
            togxbinary,
754
                0,
755
 
756
    { "crlf",
757
        "sending carriage returns as telnet <CR><LF>",
758
            togcrlf,
759
                &crlf,
760
 
761
    { "crmod",
762
        "mapping of received carriage returns",
763
            0,
764
                &crmod,
765
                    "map carriage return on output" },
766
    { "localchars",
767
        "local recognition of certain control characters",
768
            lclchars,
769
                &localchars,
770
                    "recognize certain control characters" },
771
    { " ", "", 0 },              /* empty line */
772
#if     defined(unix) && defined(TN3270)
773
    { "apitrace",
774
        "(debugging) toggle tracing of API transactions",
775
            0,
776
                &apitrace,
777
                    "trace API transactions" },
778
    { "cursesdata",
779
        "(debugging) toggle printing of hexadecimal curses data",
780
            0,
781
                &cursesdata,
782
                    "print hexadecimal representation of curses data" },
783
#endif  /* defined(unix) && defined(TN3270) */
784
    { "debug",
785
        "debugging",
786
            togdebug,
787
                &debug,
788
                    "turn on socket level debugging" },
789
    { "netdata",
790
        "printing of hexadecimal network data (debugging)",
791
            0,
792
                &netdata,
793
                    "print hexadecimal representation of network traffic" },
794
    { "prettydump",
795
        "output of \"netdata\" to user readable format (debugging)",
796
            0,
797
                &prettydump,
798
                    "print user readable output for \"netdata\"" },
799
    { "options",
800
        "viewing of options processing (debugging)",
801
            0,
802
                &showoptions,
803
                    "show option processing" },
804
#if     defined(unix)
805
    { "termdata",
806
        "(debugging) toggle printing of hexadecimal terminal data",
807
            0,
808
                &termdata,
809
                    "print hexadecimal representation of terminal traffic" },
810
#endif  /* defined(unix) */
811
    { "?",
812
        0,
813
            togglehelp },
814
    { "help",
815
        0,
816
            togglehelp },
817
    { 0 }
818
};
819
 
820
    static int
821
togglehelp()
822
{
823
    struct togglelist *c;
824
 
825
    for (c = Togglelist; c->name; c++) {
826
        if (c->help) {
827
            if (*c->help)
828
                printf("%-15s toggle %s\n", c->name, c->help);
829
            else
830
                printf("\n");
831
        }
832
    }
833
    printf("\n");
834
    printf("%-15s %s\n", "?", "display help information");
835
    return 0;
836
}
837
 
838
    static void
839
settogglehelp(set)
840
    int set;
841
{
842
    struct togglelist *c;
843
 
844
    for (c = Togglelist; c->name; c++) {
845
        if (c->help) {
846
            if (*c->help)
847
                printf("%-15s %s %s\n", c->name, set ? "enable" : "disable",
848
                                                c->help);
849
            else
850
                printf("\n");
851
        }
852
    }
853
}
854
 
855
#define GETTOGGLE(name) (struct togglelist *) \
856
                genget(name, (char **) Togglelist, sizeof(struct togglelist))
857
 
858
    static int
859
toggle(argc, argv)
860
    int  argc;
861
    char *argv[];
862
{
863
    int retval = 1;
864
    char *name;
865
    struct togglelist *c;
866
 
867
    if (argc < 2) {
868
        fprintf(stderr,
869
            "Need an argument to 'toggle' command.  'toggle ?' for help.\n");
870
        return 0;
871
    }
872
    argc--;
873
    argv++;
874
    while (argc--) {
875
        name = *argv++;
876
        c = GETTOGGLE(name);
877
        if (Ambiguous(c)) {
878
            fprintf(stderr, "'%s': ambiguous argument ('toggle ?' for help).\n",
879
                                        name);
880
            return 0;
881
        } else if (c == 0) {
882
            fprintf(stderr, "'%s': unknown argument ('toggle ?' for help).\n",
883
                                        name);
884
            return 0;
885
        } else {
886
            if (c->variable) {
887
                *c->variable = !*c->variable;           /* invert it */
888
                if (c->actionexplanation) {
889
                    printf("%s %s.\n", *c->variable? "Will" : "Won't",
890
                                                        c->actionexplanation);
891
                }
892
            }
893
            if (c->handler) {
894
                retval &= (*c->handler)(-1);
895
            }
896
        }
897
    }
898
    return retval;
899
}
900
 
901
/*
902
 * The following perform the "set" command.
903
 */
904
 
905
struct setlist {
906
    char *name;                         /* name */
907
    char *help;                         /* help information */
908
    void (*handler)();
909
    cc_t *charp;                        /* where it is located at */
910
};
911
 
912
static struct setlist Setlist[] = {
913
#ifdef  KLUDGELINEMODE
914
    { "echo",   "character to toggle local echoing on/off", 0, &echoc },
915
#endif
916
    { "escape", "character to escape back to telnet command mode", 0, &escape },
917
    { "rlogin", "rlogin escape character", 0, &rlogin },
918
    { "tracefile", "file to write trace information to", SetNetTrace, (cc_t *)NetTraceFile},
919
    { " ", "" },
920
    { " ", "The following need 'localchars' to be toggled true", 0, 0 },
921
    { "flushoutput", "character to cause an Abort Output", 0, termFlushCharp },
922
    { "interrupt", "character to cause an Interrupt Process", 0, termIntCharp },
923
    { "quit",   "character to cause an Abort process", 0, termQuitCharp },
924
    { "eof",    "character to cause an EOF ", 0, termEofCharp },
925
    { " ", "" },
926
    { " ", "The following are for local editing in linemode", 0, 0 },
927
    { "erase",  "character to use to erase a character", 0, termEraseCharp },
928
    { "kill",   "character to use to erase a line", 0, termKillCharp },
929
    { "lnext",  "character to use for literal next", 0, termLiteralNextCharp },
930
    { "susp",   "character to cause a Suspend Process", 0, termSuspCharp },
931
    { "reprint", "character to use for line reprint", 0, termRprntCharp },
932
    { "worderase", "character to use to erase a word", 0, termWerasCharp },
933
    { "start",  "character to use for XON", 0, termStartCharp },
934
    { "stop",   "character to use for XOFF", 0, termStopCharp },
935
    { "forw1",  "alternate end of line character", 0, termForw1Charp },
936
    { "forw2",  "alternate end of line character", 0, termForw2Charp },
937
    { "ayt",    "alternate AYT character", 0, termAytCharp },
938
    { 0 }
939
};
940
 
941
#if     defined(CRAY) && !defined(__STDC__)
942
/* Work around compiler bug in pcc 4.1.5 */
943
    void
944
_setlist_init()
945
{
946
#ifndef KLUDGELINEMODE
947
#define N 5
948
#else
949
#define N 6
950
#endif
951
        Setlist[N+0].charp = &termFlushChar;
952
        Setlist[N+1].charp = &termIntChar;
953
        Setlist[N+2].charp = &termQuitChar;
954
        Setlist[N+3].charp = &termEofChar;
955
        Setlist[N+6].charp = &termEraseChar;
956
        Setlist[N+7].charp = &termKillChar;
957
        Setlist[N+8].charp = &termLiteralNextChar;
958
        Setlist[N+9].charp = &termSuspChar;
959
        Setlist[N+10].charp = &termRprntChar;
960
        Setlist[N+11].charp = &termWerasChar;
961
        Setlist[N+12].charp = &termStartChar;
962
        Setlist[N+13].charp = &termStopChar;
963
        Setlist[N+14].charp = &termForw1Char;
964
        Setlist[N+15].charp = &termForw2Char;
965
        Setlist[N+16].charp = &termAytChar;
966
#undef  N
967
}
968
#endif  /* defined(CRAY) && !defined(__STDC__) */
969
 
970
    static struct setlist *
971
getset(name)
972
    char *name;
973
{
974
    return (struct setlist *)
975
                genget(name, (char **) Setlist, sizeof(struct setlist));
976
}
977
 
978
    void
979
set_escape_char(s)
980
    char *s;
981
{
982
        if (rlogin != _POSIX_VDISABLE) {
983
                rlogin = (s && *s) ? special(s) : _POSIX_VDISABLE;
984
                printf("Telnet rlogin escape character is '%s'.\n",
985
                                        control(rlogin));
986
        } else {
987
                escape = (s && *s) ? special(s) : _POSIX_VDISABLE;
988
                printf("Telnet escape character is '%s'.\n", control(escape));
989
        }
990
}
991
 
992
    static int
993
setcmd(argc, argv)
994
    int  argc;
995
    char *argv[];
996
{
997
    int value;
998
    struct setlist *ct;
999
    struct togglelist *c;
1000
 
1001
    if (argc < 2 || argc > 3) {
1002
        printf("Format is 'set Name Value'\n'set ?' for help.\n");
1003
        return 0;
1004
    }
1005
    if ((argc == 2) && (isprefix(argv[1], "?") || isprefix(argv[1], "help"))) {
1006
        for (ct = Setlist; ct->name; ct++)
1007
            printf("%-15s %s\n", ct->name, ct->help);
1008
        printf("\n");
1009
        settogglehelp(1);
1010
        printf("%-15s %s\n", "?", "display help information");
1011
        return 0;
1012
    }
1013
 
1014
    ct = getset(argv[1]);
1015
    if (ct == 0) {
1016
        c = GETTOGGLE(argv[1]);
1017
        if (c == 0) {
1018
            fprintf(stderr, "'%s': unknown argument ('set ?' for help).\n",
1019
                        argv[1]);
1020
            return 0;
1021
        } else if (Ambiguous(c)) {
1022
            fprintf(stderr, "'%s': ambiguous argument ('set ?' for help).\n",
1023
                        argv[1]);
1024
            return 0;
1025
        }
1026
        if (c->variable) {
1027
            if ((argc == 2) || (strcmp("on", argv[2]) == 0))
1028
                *c->variable = 1;
1029
            else if (strcmp("off", argv[2]) == 0)
1030
                *c->variable = 0;
1031
            else {
1032
                printf("Format is 'set togglename [on|off]'\n'set ?' for help.\n");
1033
                return 0;
1034
            }
1035
            if (c->actionexplanation) {
1036
                printf("%s %s.\n", *c->variable? "Will" : "Won't",
1037
                                                        c->actionexplanation);
1038
            }
1039
        }
1040
        if (c->handler)
1041
            (*c->handler)(1);
1042
    } else if (argc != 3) {
1043
        printf("Format is 'set Name Value'\n'set ?' for help.\n");
1044
        return 0;
1045
    } else if (Ambiguous(ct)) {
1046
        fprintf(stderr, "'%s': ambiguous argument ('set ?' for help).\n",
1047
                        argv[1]);
1048
        return 0;
1049
    } else if (ct->handler) {
1050
        (*ct->handler)(argv[2]);
1051
        printf("%s set to \"%s\".\n", ct->name, (char *)ct->charp);
1052
    } else {
1053
        if (strcmp("off", argv[2])) {
1054
            value = special(argv[2]);
1055
        } else {
1056
            value = _POSIX_VDISABLE;
1057
        }
1058
        *(ct->charp) = (cc_t)value;
1059
        printf("%s character is '%s'.\n", ct->name, control(*(ct->charp)));
1060
    }
1061
    slc_check();
1062
    return 1;
1063
}
1064
 
1065
    static int
1066
unsetcmd(argc, argv)
1067
    int  argc;
1068
    char *argv[];
1069
{
1070
    struct setlist *ct;
1071
    struct togglelist *c;
1072
    register char *name;
1073
 
1074
    if (argc < 2) {
1075
        fprintf(stderr,
1076
            "Need an argument to 'unset' command.  'unset ?' for help.\n");
1077
        return 0;
1078
    }
1079
    if (isprefix(argv[1], "?") || isprefix(argv[1], "help")) {
1080
        for (ct = Setlist; ct->name; ct++)
1081
            printf("%-15s %s\n", ct->name, ct->help);
1082
        printf("\n");
1083
        settogglehelp(0);
1084
        printf("%-15s %s\n", "?", "display help information");
1085
        return 0;
1086
    }
1087
 
1088
    argc--;
1089
    argv++;
1090
    while (argc--) {
1091
        name = *argv++;
1092
        ct = getset(name);
1093
        if (ct == 0) {
1094
            c = GETTOGGLE(name);
1095
            if (c == 0) {
1096
                fprintf(stderr, "'%s': unknown argument ('unset ?' for help).\n",
1097
                        name);
1098
                return 0;
1099
            } else if (Ambiguous(c)) {
1100
                fprintf(stderr, "'%s': ambiguous argument ('unset ?' for help).\n",
1101
                        name);
1102
                return 0;
1103
            }
1104
            if (c->variable) {
1105
                *c->variable = 0;
1106
                if (c->actionexplanation) {
1107
                    printf("%s %s.\n", *c->variable? "Will" : "Won't",
1108
                                                        c->actionexplanation);
1109
                }
1110
            }
1111
            if (c->handler)
1112
                (*c->handler)(0);
1113
        } else if (Ambiguous(ct)) {
1114
            fprintf(stderr, "'%s': ambiguous argument ('unset ?' for help).\n",
1115
                        name);
1116
            return 0;
1117
        } else if (ct->handler) {
1118
            (*ct->handler)(0);
1119
            printf("%s reset to \"%s\".\n", ct->name, (char *)ct->charp);
1120
        } else {
1121
            *(ct->charp) = _POSIX_VDISABLE;
1122
            printf("%s character is '%s'.\n", ct->name, control(*(ct->charp)));
1123
        }
1124
    }
1125
    return 1;
1126
}
1127
 
1128
/*
1129
 * The following are the data structures and routines for the
1130
 * 'mode' command.
1131
 */
1132
#ifdef  KLUDGELINEMODE
1133
extern int kludgelinemode;
1134
 
1135
    static int
1136
dokludgemode()
1137
{
1138
    kludgelinemode = 1;
1139
    send_wont(TELOPT_LINEMODE, 1);
1140
    send_dont(TELOPT_SGA, 1);
1141
    send_dont(TELOPT_ECHO, 1);
1142
}
1143
#endif
1144
 
1145
    static int
1146
dolinemode()
1147
{
1148
#ifdef  KLUDGELINEMODE
1149
    if (kludgelinemode)
1150
        send_dont(TELOPT_SGA, 1);
1151
#endif
1152
    send_will(TELOPT_LINEMODE, 1);
1153
    send_dont(TELOPT_ECHO, 1);
1154
    return 1;
1155
}
1156
 
1157
    static int
1158
docharmode()
1159
{
1160
#ifdef  KLUDGELINEMODE
1161
    if (kludgelinemode)
1162
        send_do(TELOPT_SGA, 1);
1163
    else
1164
#endif
1165
    send_wont(TELOPT_LINEMODE, 1);
1166
    send_do(TELOPT_ECHO, 1);
1167
    return 1;
1168
}
1169
 
1170
    static int
1171
dolmmode(bit, on)
1172
    int bit, on;
1173
{
1174
    unsigned char c;
1175
    extern int linemode;
1176
 
1177
    if (my_want_state_is_wont(TELOPT_LINEMODE)) {
1178
        printf("?Need to have LINEMODE option enabled first.\n");
1179
        printf("'mode ?' for help.\n");
1180
        return 0;
1181
    }
1182
 
1183
    if (on)
1184
        c = (linemode | bit);
1185
    else
1186
        c = (linemode & ~bit);
1187
    lm_mode(&c, 1, 1);
1188
    return 1;
1189
}
1190
 
1191
    int
1192
setmode(bit)
1193
{
1194
    return dolmmode(bit, 1);
1195
}
1196
 
1197
    int
1198
clearmode(bit)
1199
{
1200
    return dolmmode(bit, 0);
1201
}
1202
 
1203
struct modelist {
1204
        char    *name;          /* command name */
1205
        char    *help;          /* help string */
1206
        int     (*handler)();   /* routine which executes command */
1207
        int     needconnect;    /* Do we need to be connected to execute? */
1208
        int     arg1;
1209
};
1210
 
1211
extern int modehelp();
1212
 
1213
static struct modelist ModeList[] = {
1214
    { "character", "Disable LINEMODE option",   docharmode, 1 },
1215
#ifdef  KLUDGELINEMODE
1216
    { "",       "(or disable obsolete line-by-line mode)", 0 },
1217
#endif
1218
    { "line",   "Enable LINEMODE option",       dolinemode, 1 },
1219
#ifdef  KLUDGELINEMODE
1220
    { "",       "(or enable obsolete line-by-line mode)", 0 },
1221
#endif
1222
    { "", "", 0 },
1223
    { "",       "These require the LINEMODE option to be enabled", 0 },
1224
    { "isig",   "Enable signal trapping",       setmode, 1, MODE_TRAPSIG },
1225
    { "+isig",  0,                               setmode, 1, MODE_TRAPSIG },
1226
    { "-isig",  "Disable signal trapping",      clearmode, 1, MODE_TRAPSIG },
1227
    { "edit",   "Enable character editing",     setmode, 1, MODE_EDIT },
1228
    { "+edit",  0,                               setmode, 1, MODE_EDIT },
1229
    { "-edit",  "Disable character editing",    clearmode, 1, MODE_EDIT },
1230
    { "softtabs", "Enable tab expansion",       setmode, 1, MODE_SOFT_TAB },
1231
    { "+softtabs", 0,                            setmode, 1, MODE_SOFT_TAB },
1232
    { "-softtabs", "Disable character editing", clearmode, 1, MODE_SOFT_TAB },
1233
    { "litecho", "Enable literal character echo", setmode, 1, MODE_LIT_ECHO },
1234
    { "+litecho", 0,                             setmode, 1, MODE_LIT_ECHO },
1235
    { "-litecho", "Disable literal character echo", clearmode, 1, MODE_LIT_ECHO },
1236
    { "help",   0,                               modehelp, 0 },
1237
#ifdef  KLUDGELINEMODE
1238
    { "kludgeline", 0,                           dokludgemode, 1 },
1239
#endif
1240
    { "", "", 0 },
1241
    { "?",      "Print help information",       modehelp, 0 },
1242
    { 0 },
1243
};
1244
 
1245
 
1246
    int
1247
modehelp()
1248
{
1249
    struct modelist *mt;
1250
 
1251
    printf("format is:  'mode Mode', where 'Mode' is one of:\n\n");
1252
    for (mt = ModeList; mt->name; mt++) {
1253
        if (mt->help) {
1254
            if (*mt->help)
1255
                printf("%-15s %s\n", mt->name, mt->help);
1256
            else
1257
                printf("\n");
1258
        }
1259
    }
1260
    return 0;
1261
}
1262
 
1263
#define GETMODECMD(name) (struct modelist *) \
1264
                genget(name, (char **) ModeList, sizeof(struct modelist))
1265
 
1266
    static int
1267
modecmd(argc, argv)
1268
    int  argc;
1269
    char *argv[];
1270
{
1271
    struct modelist *mt;
1272
 
1273
    if (argc != 2) {
1274
        printf("'mode' command requires an argument\n");
1275
        printf("'mode ?' for help.\n");
1276
    } else if ((mt = GETMODECMD(argv[1])) == 0) {
1277
        fprintf(stderr, "Unknown mode '%s' ('mode ?' for help).\n", argv[1]);
1278
    } else if (Ambiguous(mt)) {
1279
        fprintf(stderr, "Ambiguous mode '%s' ('mode ?' for help).\n", argv[1]);
1280
    } else if (mt->needconnect && !connected) {
1281
        printf("?Need to be connected first.\n");
1282
        printf("'mode ?' for help.\n");
1283
    } else if (mt->handler) {
1284
        return (*mt->handler)(mt->arg1);
1285
    }
1286
    return 0;
1287
}
1288
 
1289
/*
1290
 * The following data structures and routines implement the
1291
 * "display" command.
1292
 */
1293
 
1294
    static int
1295
display(argc, argv)
1296
    int  argc;
1297
    char *argv[];
1298
{
1299
    struct togglelist *tl;
1300
    struct setlist *sl;
1301
 
1302
#define dotog(tl)       if (tl->variable && tl->actionexplanation) { \
1303
                            if (*tl->variable) { \
1304
                                printf("will"); \
1305
                            } else { \
1306
                                printf("won't"); \
1307
                            } \
1308
                            printf(" %s.\n", tl->actionexplanation); \
1309
                        }
1310
 
1311
#define doset(sl)   if (sl->name && *sl->name != ' ') { \
1312
                        if (sl->handler == 0) \
1313
                            printf("%-15s [%s]\n", sl->name, control(*sl->charp)); \
1314
                        else \
1315
                            printf("%-15s \"%s\"\n", sl->name, (char *)sl->charp); \
1316
                    }
1317
 
1318
    if (argc == 1) {
1319
        for (tl = Togglelist; tl->name; tl++) {
1320
            dotog(tl);
1321
        }
1322
        printf("\n");
1323
        for (sl = Setlist; sl->name; sl++) {
1324
            doset(sl);
1325
        }
1326
    } else {
1327
        int i;
1328
 
1329
        for (i = 1; i < argc; i++) {
1330
            sl = getset(argv[i]);
1331
            tl = GETTOGGLE(argv[i]);
1332
            if (Ambiguous(sl) || Ambiguous(tl)) {
1333
                printf("?Ambiguous argument '%s'.\n", argv[i]);
1334
                return 0;
1335
            } else if (!sl && !tl) {
1336
                printf("?Unknown argument '%s'.\n", argv[i]);
1337
                return 0;
1338
            } else {
1339
                if (tl) {
1340
                    dotog(tl);
1341
                }
1342
                if (sl) {
1343
                    doset(sl);
1344
                }
1345
            }
1346
        }
1347
    }
1348
/*@*/optionstatus();
1349
    return 1;
1350
#undef  doset
1351
#undef  dotog
1352
}
1353
 
1354
/*
1355
 * The following are the data structures, and many of the routines,
1356
 * relating to command processing.
1357
 */
1358
 
1359
/*
1360
 * Set the escape character.
1361
 */
1362
        static int
1363
setescape(argc, argv)
1364
        int argc;
1365
        char *argv[];
1366
{
1367
        register char *arg;
1368
        char buf[50];
1369
 
1370
        printf(
1371
            "Deprecated usage - please use 'set escape%s%s' in the future.\n",
1372
                                (argc > 2)? " ":"", (argc > 2)? argv[1]: "");
1373
        if (argc > 2)
1374
                arg = argv[1];
1375
        else {
1376
                printf("new escape character: ");
1377
                (void) fgets(buf, sizeof(buf), stdin);
1378
                arg = buf;
1379
        }
1380
        if (arg[0] != '\0')
1381
                escape = arg[0];
1382
        if (!In3270) {
1383
                printf("Escape character is '%s'.\n", control(escape));
1384
        }
1385
        (void) fflush(stdout);
1386
        return 1;
1387
}
1388
 
1389
    /*VARARGS*/
1390
    static int
1391
togcrmod()
1392
{
1393
    crmod = !crmod;
1394
    printf("Deprecated usage - please use 'toggle crmod' in the future.\n");
1395
    printf("%s map carriage return on output.\n", crmod ? "Will" : "Won't");
1396
    (void) fflush(stdout);
1397
    return 1;
1398
}
1399
 
1400
    /*VARARGS*/
1401
    int
1402
suspend()
1403
{
1404
#ifdef  SIGTSTP
1405
    setcommandmode();
1406
    {
1407
        long oldrows, oldcols, newrows, newcols, err;
1408
 
1409
        err = (TerminalWindowSize(&oldrows, &oldcols) == 0) ? 1 : 0;
1410
        (void) kill(0, SIGTSTP);
1411
        /*
1412
         * If we didn't get the window size before the SUSPEND, but we
1413
         * can get them now (???), then send the NAWS to make sure that
1414
         * we are set up for the right window size.
1415
         */
1416
        if (TerminalWindowSize(&newrows, &newcols) && connected &&
1417
            (err || ((oldrows != newrows) || (oldcols != newcols)))) {
1418
                sendnaws();
1419
        }
1420
    }
1421
    /* reget parameters in case they were changed */
1422
    TerminalSaveState();
1423
    setconnmode(0);
1424
#else
1425
    printf("Suspend is not supported.  Try the '!' command instead\n");
1426
#endif
1427
    return 1;
1428
}
1429
 
1430
#if     !defined(TN3270)
1431
    /*ARGSUSED*/
1432
    int
1433
shell(argc, argv)
1434
    int argc;
1435
    char *argv[];
1436
{
1437
    long oldrows, oldcols, newrows, newcols, err;
1438
 
1439
    setcommandmode();
1440
 
1441
    err = (TerminalWindowSize(&oldrows, &oldcols) == 0) ? 1 : 0;
1442
    switch(vfork()) {
1443
    case -1:
1444
        perror("Fork failed\n");
1445
        break;
1446
 
1447
    case 0:
1448
        {
1449
            /*
1450
             * Fire up the shell in the child.
1451
             */
1452
            register char *shellp, *shellname;
1453
            extern char *rindex();
1454
 
1455
            shellp = getenv("SHELL");
1456
            if (shellp == NULL)
1457
                shellp = "/bin/sh";
1458
            if ((shellname = rindex(shellp, '/')) == 0)
1459
                shellname = shellp;
1460
            else
1461
                shellname++;
1462
            if (argc > 1)
1463
                execl(shellp, shellname, "-c", &saveline[1], 0);
1464
            else
1465
                execl(shellp, shellname, 0);
1466
            perror("Execl");
1467
            _exit(1);
1468
        }
1469
    default:
1470
            (void)wait((int *)0);        /* Wait for the shell to complete */
1471
 
1472
            if (TerminalWindowSize(&newrows, &newcols) && connected &&
1473
                (err || ((oldrows != newrows) || (oldcols != newcols)))) {
1474
                    sendnaws();
1475
            }
1476
            break;
1477
    }
1478
    return 1;
1479
}
1480
#else   /* !defined(TN3270) */
1481
extern int shell();
1482
#endif  /* !defined(TN3270) */
1483
 
1484
/*VARARGS*/
1485
        int
1486
logout()
1487
{
1488
        send_do(TELOPT_LOGOUT, 1);
1489
        (void) netflush();
1490
        return 1;
1491
}
1492
 
1493
 
1494
/*
1495
 * The SLC command.
1496
 */
1497
 
1498
struct slclist {
1499
        char    *name;
1500
        char    *help;
1501
        void    (*handler)();
1502
        int     arg;
1503
};
1504
 
1505
static void slc_help();
1506
 
1507
struct slclist SlcList[] = {
1508
    { "export", "Use local special character definitions",
1509
                                                slc_mode_export,        0 },
1510
    { "import", "Use remote special character definitions",
1511
                                                slc_mode_import,        1 },
1512
    { "check",  "Verify remote special character definitions",
1513
                                                slc_mode_import,        0 },
1514
    { "help",   0,                               slc_help,               0 },
1515
    { "?",      "Print help information",       slc_help,               0 },
1516
    { 0 },
1517
};
1518
 
1519
    static void
1520
slc_help()
1521
{
1522
    struct slclist *c;
1523
 
1524
    for (c = SlcList; c->name; c++) {
1525
        if (c->help) {
1526
            if (*c->help)
1527
                printf("%-15s %s\n", c->name, c->help);
1528
            else
1529
                printf("\n");
1530
        }
1531
    }
1532
}
1533
 
1534
    static struct slclist *
1535
getslc(name)
1536
    char *name;
1537
{
1538
    return (struct slclist *)
1539
                genget(name, (char **) SlcList, sizeof(struct slclist));
1540
}
1541
 
1542
    static
1543
slccmd(argc, argv)
1544
    int  argc;
1545
    char *argv[];
1546
{
1547
    struct slclist *c;
1548
 
1549
    if (argc != 2) {
1550
        fprintf(stderr,
1551
            "Need an argument to 'slc' command.  'slc ?' for help.\n");
1552
        return 0;
1553
    }
1554
    c = getslc(argv[1]);
1555
    if (c == 0) {
1556
        fprintf(stderr, "'%s': unknown argument ('slc ?' for help).\n",
1557
                                argv[1]);
1558
        return 0;
1559
    }
1560
    if (Ambiguous(c)) {
1561
        fprintf(stderr, "'%s': ambiguous argument ('slc ?' for help).\n",
1562
                                argv[1]);
1563
        return 0;
1564
    }
1565
    (*c->handler)(c->arg);
1566
    slcstate();
1567
    return 1;
1568
}
1569
 
1570
/*
1571
 * The ENVIRON command.
1572
 */
1573
 
1574
struct envlist {
1575
        char    *name;
1576
        char    *help;
1577
        void    (*handler)();
1578
        int     narg;
1579
};
1580
 
1581
extern struct env_lst *
1582
        env_define P((unsigned char *, unsigned char *));
1583
extern void
1584
        env_undefine P((unsigned char *)),
1585
        env_export P((unsigned char *)),
1586
        env_unexport P((unsigned char *)),
1587
        env_send P((unsigned char *)),
1588
#if defined(OLD_ENVIRON) && defined(ENV_HACK)
1589
        env_varval P((unsigned char *)),
1590
#endif
1591
        env_list P((void));
1592
static void
1593
        env_help P((void));
1594
 
1595
struct envlist EnvList[] = {
1596
    { "define", "Define an environment variable",
1597
                                                (void (*)())env_define, 2 },
1598
    { "undefine", "Undefine an environment variable",
1599
                                                env_undefine,   1 },
1600
    { "export", "Mark an environment variable for automatic export",
1601
                                                env_export,     1 },
1602
    { "unexport", "Don't mark an environment variable for automatic export",
1603
                                                env_unexport,   1 },
1604
    { "send",   "Send an environment variable", env_send,       1 },
1605
    { "list",   "List the current environment variables",
1606
                                                env_list,       0 },
1607
#if defined(OLD_ENVIRON) && defined(ENV_HACK)
1608
    { "varval", "Reverse VAR and VALUE (auto, right, wrong, status)",
1609
                                                env_varval,    1 },
1610
#endif
1611
    { "help",   0,                               env_help,               0 },
1612
    { "?",      "Print help information",       env_help,               0 },
1613
    { 0 },
1614
};
1615
 
1616
    static void
1617
env_help()
1618
{
1619
    struct envlist *c;
1620
 
1621
    for (c = EnvList; c->name; c++) {
1622
        if (c->help) {
1623
            if (*c->help)
1624
                printf("%-15s %s\n", c->name, c->help);
1625
            else
1626
                printf("\n");
1627
        }
1628
    }
1629
}
1630
 
1631
    static struct envlist *
1632
getenvcmd(name)
1633
    char *name;
1634
{
1635
    return (struct envlist *)
1636
                genget(name, (char **) EnvList, sizeof(struct envlist));
1637
}
1638
 
1639
env_cmd(argc, argv)
1640
    int  argc;
1641
    char *argv[];
1642
{
1643
    struct envlist *c;
1644
 
1645
    if (argc < 2) {
1646
        fprintf(stderr,
1647
            "Need an argument to 'environ' command.  'environ ?' for help.\n");
1648
        return 0;
1649
    }
1650
    c = getenvcmd(argv[1]);
1651
    if (c == 0) {
1652
        fprintf(stderr, "'%s': unknown argument ('environ ?' for help).\n",
1653
                                argv[1]);
1654
        return 0;
1655
    }
1656
    if (Ambiguous(c)) {
1657
        fprintf(stderr, "'%s': ambiguous argument ('environ ?' for help).\n",
1658
                                argv[1]);
1659
        return 0;
1660
    }
1661
    if (c->narg + 2 != argc) {
1662
        fprintf(stderr,
1663
            "Need %s%d argument%s to 'environ %s' command.  'environ ?' for help.\n",
1664
                c->narg < argc + 2 ? "only " : "",
1665
                c->narg, c->narg == 1 ? "" : "s", c->name);
1666
        return 0;
1667
    }
1668
    (*c->handler)(argv[2], argv[3]);
1669
    return 1;
1670
}
1671
 
1672
struct env_lst {
1673
        struct env_lst *next;   /* pointer to next structure */
1674
        struct env_lst *prev;   /* pointer to previous structure */
1675
        unsigned char *var;     /* pointer to variable name */
1676
        unsigned char *value;   /* pointer to variable value */
1677
        int export;             /* 1 -> export with default list of variables */
1678
        int welldefined;        /* A well defined variable */
1679
};
1680
 
1681
struct env_lst envlisthead;
1682
 
1683
        struct env_lst *
1684
env_find(var)
1685
        unsigned char *var;
1686
{
1687
        register struct env_lst *ep;
1688
 
1689
        for (ep = envlisthead.next; ep; ep = ep->next) {
1690
                if (strcmp((char *)ep->var, (char *)var) == 0)
1691
                        return(ep);
1692
        }
1693
        return(NULL);
1694
}
1695
 
1696
        void
1697
env_init()
1698
{
1699
        extern char **environ;
1700
        register char **epp, *cp;
1701
        register struct env_lst *ep;
1702
        extern char *index();
1703
 
1704
        for (epp = environ; *epp; epp++) {
1705
                if (cp = index(*epp, '=')) {
1706
                        *cp = '\0';
1707
                        ep = env_define((unsigned char *)*epp,
1708
                                        (unsigned char *)cp+1);
1709
                        ep->export = 0;
1710
                        *cp = '=';
1711
                }
1712
        }
1713
        /*
1714
         * Special case for DISPLAY variable.  If it is ":0.0" or
1715
         * "unix:0.0", we have to get rid of "unix" and insert our
1716
         * hostname.
1717
         */
1718
        if ((ep = env_find("DISPLAY"))
1719
            && ((*ep->value == ':')
1720
                || (strncmp((char *)ep->value, "unix:", 5) == 0))) {
1721
                char hbuf[256+1];
1722
                char *cp2 = index((char *)ep->value, ':');
1723
 
1724
                gethostname(hbuf, 256);
1725
                hbuf[256] = '\0';
1726
                cp = (char *)malloc(strlen(hbuf) + strlen(cp2) + 1);
1727
                sprintf((char *)cp, "%s%s", hbuf, cp2);
1728
                free(ep->value);
1729
                ep->value = (unsigned char *)cp;
1730
        }
1731
        /*
1732
         * If USER is not defined, but LOGNAME is, then add
1733
         * USER with the value from LOGNAME.  By default, we
1734
         * don't export the USER variable.
1735
         */
1736
        if ((env_find("USER") == NULL) && (ep = env_find("LOGNAME"))) {
1737
                env_define((unsigned char *)"USER", ep->value);
1738
                env_unexport((unsigned char *)"USER");
1739
        }
1740
        env_export((unsigned char *)"DISPLAY");
1741
        env_export((unsigned char *)"PRINTER");
1742
}
1743
 
1744
        struct env_lst *
1745
env_define(var, value)
1746
        unsigned char *var, *value;
1747
{
1748
        register struct env_lst *ep;
1749
 
1750
        if (ep = env_find(var)) {
1751
                if (ep->var)
1752
                        free(ep->var);
1753
                if (ep->value)
1754
                        free(ep->value);
1755
        } else {
1756
                ep = (struct env_lst *)malloc(sizeof(struct env_lst));
1757
                ep->next = envlisthead.next;
1758
                envlisthead.next = ep;
1759
                ep->prev = &envlisthead;
1760
                if (ep->next)
1761
                        ep->next->prev = ep;
1762
        }
1763
        ep->welldefined = opt_welldefined(var);
1764
        ep->export = 1;
1765
        ep->var = (unsigned char *)strdup((char *)var);
1766
        ep->value = (unsigned char *)strdup((char *)value);
1767
        return(ep);
1768
}
1769
 
1770
        void
1771
env_undefine(var)
1772
        unsigned char *var;
1773
{
1774
        register struct env_lst *ep;
1775
 
1776
        if (ep = env_find(var)) {
1777
                ep->prev->next = ep->next;
1778
                if (ep->next)
1779
                        ep->next->prev = ep->prev;
1780
                if (ep->var)
1781
                        free(ep->var);
1782
                if (ep->value)
1783
                        free(ep->value);
1784
                free(ep);
1785
        }
1786
}
1787
 
1788
        void
1789
env_export(var)
1790
        unsigned char *var;
1791
{
1792
        register struct env_lst *ep;
1793
 
1794
        if (ep = env_find(var))
1795
                ep->export = 1;
1796
}
1797
 
1798
        void
1799
env_unexport(var)
1800
        unsigned char *var;
1801
{
1802
        register struct env_lst *ep;
1803
 
1804
        if (ep = env_find(var))
1805
                ep->export = 0;
1806
}
1807
 
1808
        void
1809
env_send(var)
1810
        unsigned char *var;
1811
{
1812
        register struct env_lst *ep;
1813
 
1814
        if (my_state_is_wont(TELOPT_NEW_ENVIRON)
1815
#ifdef  OLD_ENVIRON
1816
            && my_state_is_wont(TELOPT_OLD_ENVIRON)
1817
#endif
1818
                ) {
1819
                fprintf(stderr,
1820
                    "Cannot send '%s': Telnet ENVIRON option not enabled\n",
1821
                                                                        var);
1822
                return;
1823
        }
1824
        ep = env_find(var);
1825
        if (ep == 0) {
1826
                fprintf(stderr, "Cannot send '%s': variable not defined\n",
1827
                                                                        var);
1828
                return;
1829
        }
1830
        env_opt_start_info();
1831
        env_opt_add(ep->var);
1832
        env_opt_end(0);
1833
}
1834
 
1835
        void
1836
env_list()
1837
{
1838
        register struct env_lst *ep;
1839
 
1840
        for (ep = envlisthead.next; ep; ep = ep->next) {
1841
                printf("%c %-20s %s\n", ep->export ? '*' : ' ',
1842
                                        ep->var, ep->value);
1843
        }
1844
}
1845
 
1846
        unsigned char *
1847
env_default(init, welldefined)
1848
        int init;
1849
{
1850
        static struct env_lst *nep = NULL;
1851
 
1852
        if (init) {
1853
                nep = &envlisthead;
1854
                return;
1855
        }
1856
        if (nep) {
1857
                while (nep = nep->next) {
1858
                        if (nep->export && (nep->welldefined == welldefined))
1859
                                return(nep->var);
1860
                }
1861
        }
1862
        return(NULL);
1863
}
1864
 
1865
        unsigned char *
1866
env_getvalue(var)
1867
        unsigned char *var;
1868
{
1869
        register struct env_lst *ep;
1870
 
1871
        if (ep = env_find(var))
1872
                return(ep->value);
1873
        return(NULL);
1874
}
1875
 
1876
#if defined(OLD_ENVIRON) && defined(ENV_HACK)
1877
        void
1878
env_varval(what)
1879
        unsigned char *what;
1880
{
1881
        extern int old_env_var, old_env_value, env_auto;
1882
        int len = strlen((char *)what);
1883
 
1884
        if (len == 0)
1885
                goto unknown;
1886
 
1887
        if (strncasecmp((char *)what, "status", len) == 0) {
1888
                if (env_auto)
1889
                        printf("%s%s", "VAR and VALUE are/will be ",
1890
                                        "determined automatically\n");
1891
                if (old_env_var == OLD_ENV_VAR)
1892
                        printf("VAR and VALUE set to correct definitions\n");
1893
                else
1894
                        printf("VAR and VALUE definitions are reversed\n");
1895
        } else if (strncasecmp((char *)what, "auto", len) == 0) {
1896
                env_auto = 1;
1897
                old_env_var = OLD_ENV_VALUE;
1898
                old_env_value = OLD_ENV_VAR;
1899
        } else if (strncasecmp((char *)what, "right", len) == 0) {
1900
                env_auto = 0;
1901
                old_env_var = OLD_ENV_VAR;
1902
                old_env_value = OLD_ENV_VALUE;
1903
        } else if (strncasecmp((char *)what, "wrong", len) == 0) {
1904
                env_auto = 0;
1905
                old_env_var = OLD_ENV_VALUE;
1906
                old_env_value = OLD_ENV_VAR;
1907
        } else {
1908
unknown:
1909
                printf("Unknown \"varval\" command. (\"auto\", \"right\", \"wrong\", \"status\")\n");
1910
        }
1911
}
1912
#endif
1913
 
1914
#if     defined(AUTHENTICATION)
1915
/*
1916
 * The AUTHENTICATE command.
1917
 */
1918
 
1919
struct authlist {
1920
        char    *name;
1921
        char    *help;
1922
        int     (*handler)();
1923
        int     narg;
1924
};
1925
 
1926
extern int
1927
        auth_enable P((int)),
1928
        auth_disable P((int)),
1929
        auth_status P((void));
1930
static int
1931
        auth_help P((void));
1932
 
1933
struct authlist AuthList[] = {
1934
    { "status", "Display current status of authentication information",
1935
                                                auth_status,    0 },
1936
    { "disable", "Disable an authentication type ('auth disable ?' for more)",
1937
                                                auth_disable,   1 },
1938
    { "enable", "Enable an authentication type ('auth enable ?' for more)",
1939
                                                auth_enable,    1 },
1940
    { "help",   0,                               auth_help,              0 },
1941
    { "?",      "Print help information",       auth_help,              0 },
1942
    { 0 },
1943
};
1944
 
1945
    static int
1946
auth_help()
1947
{
1948
    struct authlist *c;
1949
 
1950
    for (c = AuthList; c->name; c++) {
1951
        if (c->help) {
1952
            if (*c->help)
1953
                printf("%-15s %s\n", c->name, c->help);
1954
            else
1955
                printf("\n");
1956
        }
1957
    }
1958
    return 0;
1959
}
1960
 
1961
auth_cmd(argc, argv)
1962
    int  argc;
1963
    char *argv[];
1964
{
1965
    struct authlist *c;
1966
 
1967
    c = (struct authlist *)
1968
                genget(argv[1], (char **) AuthList, sizeof(struct authlist));
1969
    if (c == 0) {
1970
        fprintf(stderr, "'%s': unknown argument ('auth ?' for help).\n",
1971
                                argv[1]);
1972
        return 0;
1973
    }
1974
    if (Ambiguous(c)) {
1975
        fprintf(stderr, "'%s': ambiguous argument ('auth ?' for help).\n",
1976
                                argv[1]);
1977
        return 0;
1978
    }
1979
    if (c->narg + 2 != argc) {
1980
        fprintf(stderr,
1981
            "Need %s%d argument%s to 'auth %s' command.  'auth ?' for help.\n",
1982
                c->narg < argc + 2 ? "only " : "",
1983
                c->narg, c->narg == 1 ? "" : "s", c->name);
1984
        return 0;
1985
    }
1986
    return((*c->handler)(argv[2], argv[3]));
1987
}
1988
#endif
1989
 
1990
 
1991
#if     defined(unix) && defined(TN3270)
1992
    static void
1993
filestuff(fd)
1994
    int fd;
1995
{
1996
    int res;
1997
 
1998
#ifdef  F_GETOWN
1999
    setconnmode(0);
2000
    res = fcntl(fd, F_GETOWN, 0);
2001
    setcommandmode();
2002
 
2003
    if (res == -1) {
2004
        perror("fcntl");
2005
        return;
2006
    }
2007
    printf("\tOwner is %d.\n", res);
2008
#endif
2009
 
2010
    setconnmode(0);
2011
    res = fcntl(fd, F_GETFL, 0);
2012
    setcommandmode();
2013
 
2014
    if (res == -1) {
2015
        perror("fcntl");
2016
        return;
2017
    }
2018
#ifdef notdef
2019
    printf("\tFlags are 0x%x: %s\n", res, decodeflags(res));
2020
#endif
2021
}
2022
#endif /* defined(unix) && defined(TN3270) */
2023
 
2024
/*
2025
 * Print status about the connection.
2026
 */
2027
    /*ARGSUSED*/
2028
    static
2029
status(argc, argv)
2030
    int  argc;
2031
    char *argv[];
2032
{
2033
    if (connected) {
2034
        printf("Connected to %s.\n", hostname);
2035
        if ((argc < 2) || strcmp(argv[1], "notmuch")) {
2036
            int mode = getconnmode();
2037
 
2038
            if (my_want_state_is_will(TELOPT_LINEMODE)) {
2039
                printf("Operating with LINEMODE option\n");
2040
                printf("%s line editing\n", (mode&MODE_EDIT) ? "Local" : "No");
2041
                printf("%s catching of signals\n",
2042
                                        (mode&MODE_TRAPSIG) ? "Local" : "No");
2043
                slcstate();
2044
#ifdef  KLUDGELINEMODE
2045
            } else if (kludgelinemode && my_want_state_is_dont(TELOPT_SGA)) {
2046
                printf("Operating in obsolete linemode\n");
2047
#endif
2048
            } else {
2049
                printf("Operating in single character mode\n");
2050
                if (localchars)
2051
                    printf("Catching signals locally\n");
2052
            }
2053
            printf("%s character echo\n", (mode&MODE_ECHO) ? "Local" : "Remote");
2054
            if (my_want_state_is_will(TELOPT_LFLOW))
2055
                printf("%s flow control\n", (mode&MODE_FLOW) ? "Local" : "No");
2056
        }
2057
    } else {
2058
        printf("No connection.\n");
2059
    }
2060
#   if !defined(TN3270)
2061
    printf("Escape character is '%s'.\n", control(escape));
2062
    (void) fflush(stdout);
2063
#   else /* !defined(TN3270) */
2064
    if ((!In3270) && ((argc < 2) || strcmp(argv[1], "notmuch"))) {
2065
        printf("Escape character is '%s'.\n", control(escape));
2066
    }
2067
#   if defined(unix)
2068
    if ((argc >= 2) && !strcmp(argv[1], "everything")) {
2069
        printf("SIGIO received %d time%s.\n",
2070
                                sigiocount, (sigiocount == 1)? "":"s");
2071
        if (In3270) {
2072
            printf("Process ID %d, process group %d.\n",
2073
                                            getpid(), getpgrp(getpid()));
2074
            printf("Terminal input:\n");
2075
            filestuff(tin);
2076
            printf("Terminal output:\n");
2077
            filestuff(tout);
2078
            printf("Network socket:\n");
2079
            filestuff(net);
2080
        }
2081
    }
2082
    if (In3270 && transcom) {
2083
       printf("Transparent mode command is '%s'.\n", transcom);
2084
    }
2085
#   endif /* defined(unix) */
2086
    (void) fflush(stdout);
2087
    if (In3270) {
2088
        return 0;
2089
    }
2090
#   endif /* defined(TN3270) */
2091
    return 1;
2092
}
2093
 
2094
#ifdef  SIGINFO
2095
/*
2096
 * Function that gets called when SIGINFO is received.
2097
 */
2098
ayt_status()
2099
{
2100
    (void) call(status, "status", "notmuch", 0);
2101
}
2102
#endif
2103
 
2104
int
2105
tn(argc, argv)
2106
    int argc;
2107
    char *argv[];
2108
{
2109
    register struct hostent *host = 0;
2110
    struct sockaddr_in sin;
2111
    struct servent *sp = 0;
2112
    unsigned long temp;
2113
#if     defined(IP_OPTIONS) && defined(IPPROTO_IP)
2114
    char *srp = 0, *strrchr();
2115
    unsigned long sourceroute(), srlen;
2116
#endif
2117
    char *cmd, *hostp = 0, *portp = 0, *user = 0;
2118
 
2119
    /* clear the socket address prior to use */
2120
    bzero((char *)&sin, sizeof(sin));
2121
 
2122
    if (connected) {
2123
        printf("?Already connected to %s\n", hostname);
2124
        setuid(getuid());
2125
        return 0;
2126
    }
2127
    if (argc < 2) {
2128
        (void) strcpy(line, "open ");
2129
        printf("(to) ");
2130
        (void) fgets(&line[strlen(line)], sizeof(line) - strlen(line), stdin);
2131
        makeargv();
2132
        argc = margc;
2133
        argv = margv;
2134
    }
2135
    cmd = *argv;
2136
    --argc; ++argv;
2137
    while (argc) {
2138
        if (isprefix(*argv, "help") || isprefix(*argv, "?"))
2139
            goto usage;
2140
        if (strcmp(*argv, "-l") == 0) {
2141
            --argc; ++argv;
2142
            if (argc == 0)
2143
                goto usage;
2144
            user = *argv++;
2145
            --argc;
2146
            continue;
2147
        }
2148
        if (strcmp(*argv, "-a") == 0) {
2149
            --argc; ++argv;
2150
            autologin = 1;
2151
            continue;
2152
        }
2153
        if (hostp == 0) {
2154
            hostp = *argv++;
2155
            --argc;
2156
            continue;
2157
        }
2158
        if (portp == 0) {
2159
            portp = *argv++;
2160
            --argc;
2161
            continue;
2162
        }
2163
    usage:
2164
        printf("usage: telnet [-l user] [-a] host-name [port]\n");
2165
        setuid(getuid());
2166
        return 0;
2167
    }
2168
    if (hostp == 0)
2169
        goto usage;
2170
 
2171
#if     defined(IP_OPTIONS) && defined(IPPROTO_IP)
2172
    if (hostp[0] == '@' || hostp[0] == '!') {
2173
        if ((hostname = strrchr(hostp, ':')) == NULL)
2174
            hostname = strrchr(hostp, '@');
2175
        hostname++;
2176
        srp = 0;
2177
        temp = sourceroute(hostp, &srp, &srlen);
2178
        if (temp == 0) {
2179
#ifdef EMBED
2180
            printf("ERROR: srp=%x\n", srp);
2181
            printf("ERROR: srp=%s\n", srp);
2182
#else
2183
            herror(srp);
2184
#endif
2185
            setuid(getuid());
2186
            return 0;
2187
        } else if (temp == -1) {
2188
            printf("Bad source route option: %s\n", hostp);
2189
            setuid(getuid());
2190
            return 0;
2191
        } else {
2192
            sin.sin_addr.s_addr = temp;
2193
            sin.sin_family = AF_INET;
2194
        }
2195
    } else {
2196
#endif
2197
        temp = inet_addr(hostp);
2198
        if (temp != INADDR_NONE) {
2199
            sin.sin_addr.s_addr = temp;
2200
            sin.sin_family = AF_INET;
2201
            if (doaddrlookup)
2202
                host = gethostbyaddr((char *)&temp, sizeof(temp), AF_INET);
2203
            if (host)
2204
                (void) strncpy(_hostname, host->h_name, sizeof(_hostname));
2205
            else
2206
                (void) strncpy(_hostname, hostp, sizeof(_hostname));
2207
            _hostname[sizeof(_hostname)-1] = '\0';
2208
            hostname = _hostname;
2209
        } else {
2210
            host = gethostbyname(hostp);
2211
            if (host) {
2212
                sin.sin_family = host->h_addrtype;
2213
#if     defined(h_addr)         /* In 4.3, this is a #define */
2214
                memmove((caddr_t)&sin.sin_addr,
2215
                                host->h_addr_list[0],
2216
                                MIN(host->h_length, sizeof(sin.sin_addr)));
2217
#else   /* defined(h_addr) */
2218
                memmove((caddr_t)&sin.sin_addr, host->h_addr,
2219
                                MIN(host->h_length, sizeof(sin.sin_addr)));
2220
#endif  /* defined(h_addr) */
2221
                strncpy(_hostname, host->h_name, sizeof(_hostname));
2222
                _hostname[sizeof(_hostname)-1] = '\0';
2223
                hostname = _hostname;
2224
            } else {
2225
#ifdef EMBED
2226
                printf("ERROR: hostp=%x\n", hostp);
2227
                printf("ERROR: hostp=%s\n", hostp);
2228
#else
2229
                herror(hostp);
2230
#endif
2231
                setuid(getuid());
2232
                return 0;
2233
            }
2234
        }
2235
#if     defined(IP_OPTIONS) && defined(IPPROTO_IP)
2236
    }
2237
#endif
2238
    if (portp) {
2239
        if (*portp == '-') {
2240
            portp++;
2241
            telnetport = 1;
2242
        } else
2243
            telnetport = 0;
2244
        sin.sin_port = atoi(portp);
2245
        if (sin.sin_port == 0) {
2246
            sp = getservbyname(portp, "tcp");
2247
            if (sp)
2248
                sin.sin_port = sp->s_port;
2249
            else {
2250
                printf("%s: bad port number\n", portp);
2251
                setuid(getuid());
2252
                return 0;
2253
            }
2254
        } else {
2255
#if     !defined(htons)
2256
            u_short htons P((unsigned short));
2257
#endif  /* !defined(htons) */
2258
            sin.sin_port = htons(sin.sin_port);
2259
        }
2260
    } else {
2261
        if (sp == 0) {
2262
            sp = getservbyname("telnet", "tcp");
2263
            if (sp == 0) {
2264
                fprintf(stderr, "telnet: tcp/telnet: unknown service\n");
2265
                setuid(getuid());
2266
                return 0;
2267
            }
2268
            sin.sin_port = sp->s_port;
2269
        }
2270
        telnetport = 1;
2271
    }
2272
    printf("Trying %s(%d)...\n", inet_ntoa(sin.sin_addr), sin.sin_port);
2273
    do {
2274
        net = socket(AF_INET, SOCK_STREAM, 0);
2275
        setuid(getuid());
2276
        if (net < 0) {
2277
            perror("telnet: socket");
2278
            return 0;
2279
        }
2280
#if     defined(IP_OPTIONS) && defined(IPPROTO_IP)
2281
        if (srp && setsockopt(net, IPPROTO_IP, IP_OPTIONS, (char *)srp, srlen) < 0)
2282
                perror("setsockopt (IP_OPTIONS)");
2283
#endif
2284
#if     defined(IPPROTO_IP) && defined(IP_TOS)
2285
        {
2286
# if    defined(HAS_GETTOS)
2287
            struct tosent *tp;
2288
            if (tos < 0 && (tp = gettosbyname("telnet", "tcp")))
2289
                tos = tp->t_tos;
2290
# endif
2291
            if (tos < 0)
2292
                tos = IPTOS_LOWDELAY;
2293
            if (tos
2294
                && (setsockopt(net, IPPROTO_IP, IP_TOS,
2295
                    (char *)&tos, sizeof(int)) < 0)
2296
                && (errno != ENOPROTOOPT))
2297
                    perror("telnet: setsockopt (IP_TOS) (ignored)");
2298
        }
2299
#endif  /* defined(IPPROTO_IP) && defined(IP_TOS) */
2300
 
2301
        if (debug && SetSockOpt(net, SOL_SOCKET, SO_DEBUG, 1) < 0) {
2302
                perror("setsockopt (SO_DEBUG)");
2303
        }
2304
 
2305
        if (connect(net, (struct sockaddr *)&sin, sizeof (sin)) < 0) {
2306
#if     defined(h_addr)         /* In 4.3, this is a #define */
2307
            if (host && host->h_addr_list[1]) {
2308
                int oerrno = errno;
2309
 
2310
                fprintf(stderr, "telnet: connect to address %s: ",
2311
                                                inet_ntoa(sin.sin_addr));
2312
                errno = oerrno;
2313
                perror((char *)0);
2314
                host->h_addr_list++;
2315
                memcpy((caddr_t)&sin.sin_addr, host->h_addr_list[0],
2316
                                MIN(host->h_length, sizeof(sin.sin_addr)));
2317
                (void) NetClose(net);
2318
                continue;
2319
            }
2320
#endif  /* defined(h_addr) */
2321
            perror("telnet: Unable to connect to remote host");
2322
            return 0;
2323
        }
2324
        connected++;
2325
#if     defined(AUTHENTICATION)
2326
        auth_encrypt_connect(connected);
2327
#endif  /* defined(AUTHENTICATION) */
2328
    } while (connected == 0);
2329
    cmdrc(hostp, hostname);
2330
    if (autologin && user == NULL) {
2331
        struct passwd *pw;
2332
 
2333
        user = getenv("USER");
2334
        if (user == NULL ||
2335
            (pw = getpwnam(user)) && pw->pw_uid != getuid()) {
2336
                if (pw = getpwuid(getuid()))
2337
                        user = pw->pw_name;
2338
                else
2339
                        user = NULL;
2340
        }
2341
    }
2342
    if (user) {
2343
        env_define((unsigned char *)"USER", (unsigned char *)user);
2344
        env_export((unsigned char *)"USER");
2345
    }
2346
    (void) call(status, "status", "notmuch", 0);
2347
#ifndef EMBED
2348
    if (setjmp(peerdied) == 0)
2349
#endif
2350
        telnet(user);
2351
    (void) NetClose(net);
2352
    ExitString("Connection closed by foreign host.\n",1);
2353
    /*NOTREACHED*/
2354
}
2355
 
2356
#define HELPINDENT (sizeof ("connect"))
2357
 
2358
static char
2359
        openhelp[] =    "connect to a site",
2360
        closehelp[] =   "close current connection",
2361
        logouthelp[] =  "forcibly logout remote user and close the connection",
2362
        quithelp[] =    "exit telnet",
2363
        statushelp[] =  "print status information",
2364
        helphelp[] =    "print help information",
2365
        sendhelp[] =    "transmit special characters ('send ?' for more)",
2366
        sethelp[] =     "set operating parameters ('set ?' for more)",
2367
        unsethelp[] =   "unset operating parameters ('unset ?' for more)",
2368
        togglestring[] ="toggle operating parameters ('toggle ?' for more)",
2369
        slchelp[] =     "change state of special charaters ('slc ?' for more)",
2370
        displayhelp[] = "display operating parameters",
2371
#if     defined(TN3270) && defined(unix)
2372
        transcomhelp[] = "specify Unix command for transparent mode pipe",
2373
#endif  /* defined(TN3270) && defined(unix) */
2374
#if     defined(AUTHENTICATION)
2375
        authhelp[] =    "turn on (off) authentication ('auth ?' for more)",
2376
#endif
2377
#if     defined(unix)
2378
        zhelp[] =       "suspend telnet",
2379
#endif  /* defined(unix) */
2380
#if     defined(SKEY)
2381
        skeyhelp[] =    "compute response to s/key challenge",
2382
#endif
2383
        shellhelp[] =   "invoke a subshell",
2384
        envhelp[] =     "change environment variables ('environ ?' for more)",
2385
        modestring[] = "try to enter line or character mode ('mode ?' for more)";
2386
 
2387
static int      help();
2388
 
2389
static Command cmdtab[] = {
2390
        { "close",      closehelp,      bye,            1 },
2391
        { "logout",     logouthelp,     logout,         1 },
2392
        { "display",    displayhelp,    display,        0 },
2393
        { "mode",       modestring,     modecmd,        0 },
2394
        { "telnet",     openhelp,       tn,             0 },
2395
        { "open",       openhelp,       tn,             0 },
2396
        { "quit",       quithelp,       quit,           0 },
2397
        { "send",       sendhelp,       sendcmd,        0 },
2398
        { "set",        sethelp,        setcmd,         0 },
2399
        { "unset",      unsethelp,      unsetcmd,       0 },
2400
        { "status",     statushelp,     status,         0 },
2401
        { "toggle",     togglestring,   toggle,         0 },
2402
        { "slc",        slchelp,        slccmd,         0 },
2403
#if     defined(TN3270) && defined(unix)
2404
        { "transcom",   transcomhelp,   settranscom,    0 },
2405
#endif  /* defined(TN3270) && defined(unix) */
2406
#if     defined(AUTHENTICATION)
2407
        { "auth",       authhelp,       auth_cmd,       0 },
2408
#endif
2409
#if     defined(unix)
2410
        { "z",          zhelp,          suspend,        0 },
2411
#endif  /* defined(unix) */
2412
#if     defined(TN3270)
2413
        { "!",          shellhelp,      shell,          1 },
2414
#else
2415
        { "!",          shellhelp,      shell,          0 },
2416
#endif
2417
        { "environ",    envhelp,        env_cmd,        0 },
2418
        { "?",          helphelp,       help,           0 },
2419
#if     defined(SKEY)
2420
        { "skey",       skeyhelp,       skey_calc,      0 },
2421
#endif          
2422
 
2423
};
2424
 
2425
static char     crmodhelp[] =   "deprecated command -- use 'toggle crmod' instead";
2426
static char     escapehelp[] =  "deprecated command -- use 'set escape' instead";
2427
 
2428
static Command cmdtab2[] = {
2429
        { "help",       0,               help,           0 },
2430
        { "escape",     escapehelp,     setescape,      0 },
2431
        { "crmod",      crmodhelp,      togcrmod,       0 },
2432
 
2433
};
2434
 
2435
 
2436
/*
2437
 * Call routine with argc, argv set from args (terminated by 0).
2438
 */
2439
 
2440
    /*VARARGS1*/
2441
    static
2442
/*call(va_alist)
2443
    va_dcl
2444
*/
2445
int call(intrtn_t)
2446
    int (*intrtn_t)();
2447
{
2448
    va_list ap;
2449
    typedef int (*intrtn_t)();
2450
    intrtn_t routine;
2451
    char *args[100];
2452
    int argno = 0;
2453
 
2454
    va_start(ap);
2455
    routine = (va_arg(ap, intrtn_t));
2456
    while ((args[argno++] = va_arg(ap, char *)) != 0) {
2457
        ;
2458
    }
2459
    va_end(ap);
2460
    return (*routine)(argno-1, args);
2461
}
2462
 
2463
 
2464
    static Command *
2465
getcmd(name)
2466
    char *name;
2467
{
2468
    Command *cm;
2469
 
2470
    if (cm = (Command *) genget(name, (char **) cmdtab, sizeof(Command)))
2471
        return cm;
2472
    return (Command *) genget(name, (char **) cmdtab2, sizeof(Command));
2473
}
2474
 
2475
    void
2476
command(top, tbuf, cnt)
2477
    int top;
2478
    char *tbuf;
2479
    int cnt;
2480
{
2481
    register Command *c;
2482
 
2483
    setcommandmode();
2484
    if (!top) {
2485
        putchar('\n');
2486
#if     defined(unix)
2487
    } else {
2488
        (void) signal(SIGINT, SIG_DFL);
2489
        (void) signal(SIGQUIT, SIG_DFL);
2490
#endif  /* defined(unix) */
2491
    }
2492
    for (;;) {
2493
        if (rlogin == _POSIX_VDISABLE)
2494
                printf("%s> ", prompt);
2495
        if (tbuf) {
2496
            register char *cp;
2497
            cp = line;
2498
            while (cnt > 0 && (*cp++ = *tbuf++) != '\n')
2499
                cnt--;
2500
            tbuf = 0;
2501
            if (cp == line || *--cp != '\n' || cp == line)
2502
                goto getline;
2503
            *cp = '\0';
2504
            if (rlogin == _POSIX_VDISABLE)
2505
                printf("%s\n", line);
2506
        } else {
2507
        getline:
2508
            if (rlogin != _POSIX_VDISABLE)
2509
                printf("%s> ", prompt);
2510
            if (fgets(line, sizeof(line), stdin) == NULL) {
2511
                if (feof(stdin) || ferror(stdin)) {
2512
                    (void) quit();
2513
                    /*NOTREACHED*/
2514
                }
2515
                break;
2516
            }
2517
        }
2518
        if (line[0] == 0)
2519
            break;
2520
        makeargv();
2521
        if (margv[0] == 0) {
2522
            break;
2523
        }
2524
        c = getcmd(margv[0]);
2525
        if (Ambiguous(c)) {
2526
            printf("?Ambiguous command\n");
2527
            continue;
2528
        }
2529
        if (c == 0) {
2530
            printf("?Invalid command\n");
2531
            continue;
2532
        }
2533
        if (c->needconnect && !connected) {
2534
            printf("?Need to be connected first.\n");
2535
            continue;
2536
        }
2537
        if ((*c->handler)(margc, margv)) {
2538
            break;
2539
        }
2540
    }
2541
    if (!top) {
2542
        if (!connected) {
2543
#ifdef EMBED
2544
            printf("ERROR: no longjmp()\n");
2545
            exit(1);
2546
#else
2547
            longjmp(toplevel, 1);
2548
#endif
2549
            /*NOTREACHED*/
2550
        }
2551
#if     defined(TN3270)
2552
        if (shell_active == 0) {
2553
            setconnmode(0);
2554
        }
2555
#else   /* defined(TN3270) */
2556
        setconnmode(0);
2557
#endif  /* defined(TN3270) */
2558
    }
2559
}
2560
 
2561
/*
2562
 * Help command.
2563
 */
2564
        static
2565
help(argc, argv)
2566
        int argc;
2567
        char *argv[];
2568
{
2569
        register Command *c;
2570
 
2571
        if (argc == 1) {
2572
                printf("Commands may be abbreviated.  Commands are:\n\n");
2573
                for (c = cmdtab; c->name; c++)
2574
                        if (c->help) {
2575
                                printf("%-*s\t%s\n", HELPINDENT, c->name,
2576
                                                                    c->help);
2577
                        }
2578
                return 0;
2579
        }
2580
        while (--argc > 0) {
2581
                register char *arg;
2582
                arg = *++argv;
2583
                c = getcmd(arg);
2584
                if (Ambiguous(c))
2585
                        printf("?Ambiguous help command %s\n", arg);
2586
                else if (c == (Command *)0)
2587
                        printf("?Invalid help command %s\n", arg);
2588
                else
2589
                        printf("%s\n", c->help);
2590
        }
2591
        return 0;
2592
}
2593
 
2594
static char *rcname = 0;
2595
static char rcbuf[128];
2596
 
2597
        void
2598
cmdrc(m1, m2)
2599
        char *m1, *m2;
2600
{
2601
    register Command *c;
2602
    FILE *rcfile;
2603
    int gotmachine = 0;
2604
    int l1 = strlen(m1);
2605
    int l2 = strlen(m2);
2606
    char m1save[64];
2607
 
2608
    if (skiprc)
2609
        return;
2610
 
2611
    strcpy(m1save, m1);
2612
    m1 = m1save;
2613
 
2614
    if (rcname == 0) {
2615
        rcname = getenv("HOME");
2616
        if (rcname && (strlen(rcname) + 10) < sizeof(rcbuf))
2617
            strcpy(rcbuf, rcname);
2618
        else
2619
            rcbuf[0] = '\0';
2620
        strcat(rcbuf, "/.telnetrc");
2621
        rcname = rcbuf;
2622
    }
2623
 
2624
    if ((rcfile = fopen(rcname, "r")) == 0) {
2625
        return;
2626
    }
2627
 
2628
    for (;;) {
2629
        if (fgets(line, sizeof(line), rcfile) == NULL)
2630
            break;
2631
        if (line[0] == 0)
2632
            break;
2633
        if (line[0] == '#')
2634
            continue;
2635
        if (gotmachine) {
2636
            if (!isspace(line[0]))
2637
                gotmachine = 0;
2638
        }
2639
        if (gotmachine == 0) {
2640
            if (isspace(line[0]))
2641
                continue;
2642
            if (strncasecmp(line, m1, l1) == 0)
2643
                strncpy(line, &line[l1], sizeof(line) - l1);
2644
            else if (strncasecmp(line, m2, l2) == 0)
2645
                strncpy(line, &line[l2], sizeof(line) - l2);
2646
            else if (strncasecmp(line, "DEFAULT", 7) == 0)
2647
                strncpy(line, &line[7], sizeof(line) - 7);
2648
            else
2649
                continue;
2650
            if (line[0] != ' ' && line[0] != '\t' && line[0] != '\n')
2651
                continue;
2652
            gotmachine = 1;
2653
        }
2654
        makeargv();
2655
        if (margv[0] == 0)
2656
            continue;
2657
        c = getcmd(margv[0]);
2658
        if (Ambiguous(c)) {
2659
            printf("?Ambiguous command: %s\n", margv[0]);
2660
            continue;
2661
        }
2662
        if (c == 0) {
2663
            printf("?Invalid command: %s\n", margv[0]);
2664
            continue;
2665
        }
2666
        /*
2667
         * This should never happen...
2668
         */
2669
        if (c->needconnect && !connected) {
2670
            printf("?Need to be connected first for %s.\n", margv[0]);
2671
            continue;
2672
        }
2673
        (*c->handler)(margc, margv);
2674
    }
2675
    fclose(rcfile);
2676
}
2677
 
2678
#if     defined(IP_OPTIONS) && defined(IPPROTO_IP)
2679
 
2680
/*
2681
 * Source route is handed in as
2682
 *      [!]@hop1@hop2...[@|:]dst
2683
 * If the leading ! is present, it is a
2684
 * strict source route, otherwise it is
2685
 * assmed to be a loose source route.
2686
 *
2687
 * We fill in the source route option as
2688
 *      hop1,hop2,hop3...dest
2689
 * and return a pointer to hop1, which will
2690
 * be the address to connect() to.
2691
 *
2692
 * Arguments:
2693
 *      arg:    pointer to route list to decipher
2694
 *
2695
 *      cpp:    If *cpp is not equal to NULL, this is a
2696
 *              pointer to a pointer to a character array
2697
 *              that should be filled in with the option.
2698
 *
2699
 *      lenp:   pointer to an integer that contains the
2700
 *              length of *cpp if *cpp != NULL.
2701
 *
2702
 * Return values:
2703
 *
2704
 *      Returns the address of the host to connect to.  If the
2705
 *      return value is -1, there was a syntax error in the
2706
 *      option, either unknown characters, or too many hosts.
2707
 *      If the return value is 0, one of the hostnames in the
2708
 *      path is unknown, and *cpp is set to point to the bad
2709
 *      hostname.
2710
 *
2711
 *      *cpp:   If *cpp was equal to NULL, it will be filled
2712
 *              in with a pointer to our static area that has
2713
 *              the option filled in.  This will be 32bit aligned.
2714
 *
2715
 *      *lenp:  This will be filled in with how long the option
2716
 *              pointed to by *cpp is.
2717
 *
2718
 */
2719
        unsigned long
2720
sourceroute(arg, cpp, lenp)
2721
        char    *arg;
2722
        char    **cpp;
2723
        int     *lenp;
2724
{
2725
        static char lsr[44];
2726
#ifdef  sysV88
2727
        static IOPTN ipopt;
2728
#endif
2729
        char *cp, *cp2, *lsrp, *lsrep;
2730
        register int tmp;
2731
        struct in_addr sin_addr;
2732
        register struct hostent *host = 0;
2733
        register char c;
2734
 
2735
        /*
2736
         * Verify the arguments, and make sure we have
2737
         * at least 7 bytes for the option.
2738
         */
2739
        if (cpp == NULL || lenp == NULL)
2740
                return((unsigned long)-1);
2741
        if (*cpp != NULL && *lenp < 7)
2742
                return((unsigned long)-1);
2743
        /*
2744
         * Decide whether we have a buffer passed to us,
2745
         * or if we need to use our own static buffer.
2746
         */
2747
        if (*cpp) {
2748
                lsrp = *cpp;
2749
                lsrep = lsrp + *lenp;
2750
        } else {
2751
                *cpp = lsrp = lsr;
2752
                lsrep = lsrp + 44;
2753
        }
2754
 
2755
        cp = arg;
2756
 
2757
        /*
2758
         * Next, decide whether we have a loose source
2759
         * route or a strict source route, and fill in
2760
         * the begining of the option.
2761
         */
2762
#ifndef sysV88
2763
        if (*cp == '!') {
2764
                cp++;
2765
                *lsrp++ = IPOPT_SSRR;
2766
        } else
2767
                *lsrp++ = IPOPT_LSRR;
2768
#else
2769
        if (*cp == '!') {
2770
                cp++;
2771
                ipopt.io_type = IPOPT_SSRR;
2772
        } else
2773
                ipopt.io_type = IPOPT_LSRR;
2774
#endif
2775
 
2776
        if (*cp != '@')
2777
                return((unsigned long)-1);
2778
 
2779
#ifndef sysV88
2780
        lsrp++;         /* skip over length, we'll fill it in later */
2781
        *lsrp++ = 4;
2782
#endif
2783
 
2784
        cp++;
2785
 
2786
        sin_addr.s_addr = 0;
2787
 
2788
        for (c = 0;;) {
2789
                if (c == ':')
2790
                        cp2 = 0;
2791
                else for (cp2 = cp; c = *cp2; cp2++) {
2792
                        if (c == ',') {
2793
                                *cp2++ = '\0';
2794
                                if (*cp2 == '@')
2795
                                        cp2++;
2796
                        } else if (c == '@') {
2797
                                *cp2++ = '\0';
2798
                        } else if (c == ':') {
2799
                                *cp2++ = '\0';
2800
                        } else
2801
                                continue;
2802
                        break;
2803
                }
2804
                if (!c)
2805
                        cp2 = 0;
2806
 
2807
                if ((tmp = inet_addr(cp)) != -1) {
2808
                        sin_addr.s_addr = tmp;
2809
                } else if (host = gethostbyname(cp)) {
2810
#if     defined(h_addr)
2811
                        memcpy((caddr_t)&sin_addr, host->h_addr_list[0],
2812
                                        MIN(host->h_length,sizeof(sin_addr)));
2813
#else
2814
                        memcpy((caddr_t)&sin_addr, host->h_addr,
2815
                                        MIN(host->h_length,sizeof(sin_addr)));
2816
#endif
2817
                } else {
2818
                        *cpp = cp;
2819
                        return(0);
2820
                }
2821
                memcpy(lsrp, (char *)&sin_addr, 4);
2822
                lsrp += 4;
2823
                if (cp2)
2824
                        cp = cp2;
2825
                else
2826
                        break;
2827
                /*
2828
                 * Check to make sure there is space for next address
2829
                 */
2830
                if (lsrp + 4 > lsrep)
2831
                        return((unsigned long)-1);
2832
        }
2833
#ifndef sysV88
2834
        if ((*(*cpp+IPOPT_OLEN) = lsrp - *cpp) <= 7) {
2835
                *cpp = 0;
2836
                *lenp = 0;
2837
                return((unsigned long)-1);
2838
        }
2839
        *lsrp++ = IPOPT_NOP; /* 32 bit word align it */
2840
        *lenp = lsrp - *cpp;
2841
#else
2842
        ipopt.io_len = lsrp - *cpp;
2843
        if (ipopt.io_len <= 5) {                /* Is 3 better ? */
2844
                *cpp = 0;
2845
                *lenp = 0;
2846
                return((unsigned long)-1);
2847
        }
2848
        *lenp = sizeof(ipopt);
2849
        *cpp = (char *) &ipopt;
2850
#endif
2851
        return(sin_addr.s_addr);
2852
}
2853
#endif

powered by: WebSVN 2.1.0

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