~ubuntu-branches/debian/sid/net-tools/sid

« back to all changes in this revision

Viewing changes to .pc/CVS-20051204-slttach.c_sync.patch/slattach.c

  • Committer: Package Import Robot
  • Author(s): Martín Ferrari
  • Date: 2015-09-07 01:54:07 UTC
  • mfrom: (1.1.1)
  • Revision ID: package-import@ubuntu.com-20150907015407-v2tfsgxayjd3iq4i
Tags: 1.60+git20150829.73cef8a-1
* After 14 years without an upstream release, I am producing a new package
  based on today's upstream repository.
  Closes: #391495, #486448, #323261, #260587, #545328, #511395.
* Remove many patches now merged upstream, delete unmaintainable and
  undocumented local changes, and update the rest.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/*
2
 
 * slattach     A program for handling dialup IP connecions.
3
 
 *              This program forces a TTY line to go into a special
4
 
 *              terminal line discipline, so that it can be used for
5
 
 *              network traffic instead of the regular terminal I/O.
6
 
 *
7
 
 * Usage:       slattach [-ehlmnqv] [ -k keepalive ] [ -o outfill ]
8
 
 *                      [-c cmd] [-s speed] [-p protocol] tty | -
9
 
 *
10
 
 * Version:     @(#)slattach.c  1.20  1999-05-29
11
 
 *
12
 
 * Author:      Fred N. van Kempen, <waltje@uWalt.NL.Mugnet.ORG>
13
 
 *              Copyright 1988-1993 MicroWalt Corporation
14
 
 *
15
 
 * Modified:
16
 
 *              Alan Cox, <A.Cox@swansea.ac.uk> , July 16 1994
17
 
 *              Miquel van Smoorenburg, <miquels@drinkel.ow.org>, October 1994
18
 
 *              George Shearer, <gshearer@one.net>, January 3, 1995
19
 
 *              Yossi Gottlieb, <yogo@math.tau.ac.il>, February 11, 1995
20
 
 *              Peter Tobias, <tobias@et-inf.fho-emden.de>, July 30 1995
21
 
 *              Bernd Eckenfels <net-tools@lina.inka.de>, May 29, 1999
22
 
 *                      added some more printf's for debug and NOBLOCK to open
23
 
 *                      this should be enough to support 2.2 ttyS-style locks
24
 
 *
25
 
 *              This program is free software; you can redistribute it
26
 
 *              and/or  modify it under  the terms of  the GNU General
27
 
 *              Public  License as  published  by  the  Free  Software
28
 
 *              Foundation;  either  version 2 of the License, or  (at
29
 
 *              your option) any later version.
30
 
 */
31
 
#include <sys/param.h>
32
 
#include <sys/types.h>
33
 
#include <sys/socket.h>
34
 
#include <sys/ioctl.h>
35
 
#include <sys/stat.h>
36
 
#include <stdio.h>
37
 
#include <ctype.h>
38
 
#include <errno.h>
39
 
#include <fcntl.h>
40
 
#include <limits.h>
41
 
#include <pwd.h>
42
 
#include <signal.h>
43
 
#include <stdlib.h>          
44
 
#include <string.h>
45
 
#include <unistd.h>
46
 
#include <getopt.h>
47
 
#include <linux/if_slip.h>
48
 
 
49
 
#if defined(__GLIBC__)
50
 
#if __GLIBC__ == 2 && __GLIBC_MINOR__ == 0
51
 
# include <termbits.h>
52
 
#else
53
 
# include <termios.h>
54
 
#endif
55
 
#endif
56
 
 
57
 
#include "pathnames.h"
58
 
#include "net-support.h"
59
 
#include "version.h"
60
 
#include "config.h"
61
 
#include "intl.h"
62
 
#include "util.h"
63
 
 
64
 
#ifndef _PATH_LOCKD
65
 
#define _PATH_LOCKD             "/var/lock"             /* lock files   */
66
 
#endif
67
 
#ifndef _UID_UUCP
68
 
#define _UID_UUCP               "uucp"                  /* owns locks   */
69
 
#endif
70
 
 
71
 
 
72
 
#define DEF_PROTO       "cslip"
73
 
 
74
 
 
75
 
const char *Release = RELEASE,
76
 
           *Version = "@(#) slattach 1.21 (1999-11-21)",
77
 
           *Signature = "net-tools, Fred N. van Kempen et al.";
78
 
 
79
 
 
80
 
struct {
81
 
  const char    *speed;
82
 
  int   code;
83
 
} tty_speeds[] = {                      /* table of usable baud rates   */
84
 
  { "50",       B50     }, { "75",      B75     },      
85
 
  { "110",      B110    }, { "300",     B300    },
86
 
  { "600",      B600    }, { "1200",    B1200   },
87
 
  { "2400",     B2400   }, { "4800",    B4800   },
88
 
  { "9600",     B9600   },
89
 
#ifdef B14400
90
 
  { "14400",    B14400  },
91
 
#endif
92
 
#ifdef B19200
93
 
  { "19200",    B19200  },
94
 
#endif
95
 
#ifdef B38400
96
 
  { "38400",    B38400  },
97
 
#endif
98
 
#ifdef B57600
99
 
  { "57600",    B57600  },
100
 
#endif
101
 
#ifdef B115200
102
 
  { "115200",   B115200 },
103
 
#endif
104
 
  { NULL,       0       }
105
 
};
106
 
struct termios  tty_saved,              /* saved TTY device state       */
107
 
                tty_current;            /* current TTY device state     */
108
 
int             tty_sdisc,              /* saved TTY line discipline    */
109
 
                tty_ldisc,              /* current TTY line discipline  */
110
 
                tty_fd = -1;            /* TTY file descriptor          */
111
 
int             opt_c = 0;              /* "command" to run at exit     */
112
 
int             opt_e = 0;              /* "activate only" flag         */
113
 
int             opt_h = 0;              /* "hangup" on carrier loss     */
114
 
#ifdef SIOCSKEEPALIVE
115
 
int             opt_k = 0;              /* "keepalive" value            */
116
 
#endif
117
 
int             opt_l = 0;              /* "lock it" flag               */
118
 
int             opt_L = 0;              /* clocal flag                  */
119
 
int             opt_m = 0;              /* "set RAW mode" flag          */
120
 
int             opt_n = 0;              /* "set No Mesg" flag           */
121
 
#ifdef SIOCSOUTFILL
122
 
int             opt_o = 0;              /* "outfill" value              */
123
 
#endif
124
 
int             opt_q = 0;              /* "quiet" flag                 */
125
 
int             opt_d = 0;              /* debug flag                   */
126
 
int             opt_v = 0;              /* Verbose flag                 */
127
 
 
128
 
/* Disable any messages to the input channel of this process. */
129
 
static int
130
 
tty_nomesg(int fd)
131
 
{
132
 
  if (opt_n == 0) return(0);
133
 
  return(fchmod(fd, 0600));
134
 
}
135
 
 
136
 
/* Check for an existing lock file on our device */
137
 
static int
138
 
tty_already_locked(char *nam)
139
 
{
140
 
  int  i = 0, pid = 0;
141
 
  FILE *fd = (FILE *)0;
142
 
 
143
 
  /* Does the lock file on our device exist? */
144
 
  if ((fd = fopen(nam, "r")) == (FILE *)0)
145
 
    return(0); /* No, return perm to continue */
146
 
 
147
 
  /* Yes, the lock is there.  Now let's make sure */
148
 
  /* at least there's no active process that owns */
149
 
  /* that lock.                                   */
150
 
  i = fscanf(fd, "%d", &pid);
151
 
  (void) fclose(fd);
152
 
 
153
 
  if (i != 1) /* Lock file format's wrong! Kill't */
154
 
    return(0);
155
 
 
156
 
  /* We got the pid, check if the process's alive */
157
 
  if (kill(pid, 0) == 0)      /* it found process */
158
 
      return(1);          /* Yup, it's running... */
159
 
 
160
 
  /* Dead, we can proceed locking this device...  */
161
 
  return(0);
162
 
}
163
 
 
164
 
/* Lock or unlock a terminal line. */
165
 
static int
166
 
tty_lock(char *path, int mode)
167
 
{
168
 
  static char saved_path[PATH_MAX];
169
 
  static int saved_lock = 0;
170
 
  struct passwd *pw;
171
 
  int fd;
172
 
  char apid[16];
173
 
 
174
 
  /* We do not lock standard input. */
175
 
  if ((opt_l == 0) || ((path == NULL) && (saved_lock == 0))) return(0);
176
 
 
177
 
  if (mode == 1) {      /* lock */
178
 
        sprintf(saved_path, "%s/LCK..%s", _PATH_LOCKD, path);
179
 
        if (tty_already_locked(saved_path)) {
180
 
                fprintf(stderr, _("slattach: /dev/%s already locked!\n"), path);
181
 
                return(-1);
182
 
        }
183
 
        if ((fd = creat(saved_path, 0644)) < 0) {
184
 
                if (errno != EEXIST)
185
 
                        if (opt_q == 0) fprintf(stderr,
186
 
                                _("slattach: tty_lock: (%s): %s\n"),
187
 
                                        saved_path, strerror(errno));
188
 
                return(-1);
189
 
        }
190
 
        sprintf(apid, "%10d\n", getpid());
191
 
        if (write(fd, apid, strlen(apid)) != strlen(apid)) {
192
 
                fprintf(stderr, _("slattach: cannot write PID file\n"));
193
 
                close(fd);
194
 
                unlink(saved_path);
195
 
                return(-1);
196
 
        }
197
 
 
198
 
        (void) close(fd);
199
 
 
200
 
        /* Make sure UUCP owns the lockfile.  Required by some packages. */
201
 
        if ((pw = getpwnam(_UID_UUCP)) == NULL) {
202
 
                if (opt_q == 0) fprintf(stderr, _("slattach: tty_lock: UUCP user %s unknown!\n"),
203
 
                                        _UID_UUCP);
204
 
                return(0);      /* keep the lock anyway */
205
 
        }
206
 
        (void) chown(saved_path, pw->pw_uid, pw->pw_gid);
207
 
        saved_lock = 1;
208
 
  } else {      /* unlock */
209
 
        if (saved_lock != 1) return(0);
210
 
        if (unlink(saved_path) < 0) {
211
 
                if (opt_q == 0) fprintf(stderr,
212
 
                        "slattach: tty_unlock: (%s): %s\n", saved_path,
213
 
                                                        strerror(errno));
214
 
                return(-1);
215
 
        }
216
 
        saved_lock = 0;
217
 
  }
218
 
 
219
 
  return(0);
220
 
}
221
 
 
222
 
 
223
 
/* Find a serial speed code in the table. */
224
 
static int
225
 
tty_find_speed(const char *speed)
226
 
{
227
 
  int i;
228
 
 
229
 
  i = 0;
230
 
  while (tty_speeds[i].speed != NULL) {
231
 
        if (!strcmp(tty_speeds[i].speed, speed)) return(tty_speeds[i].code);
232
 
        i++;
233
 
  }
234
 
  return(-EINVAL);
235
 
}
236
 
 
237
 
 
238
 
/* Set the number of stop bits. */
239
 
static int
240
 
tty_set_stopbits(struct termios *tty, char *stopbits)
241
 
{
242
 
  if (opt_d) printf("slattach: tty_set_stopbits: %c\n", *stopbits);
243
 
  switch(*stopbits) {
244
 
        case '1':
245
 
                tty->c_cflag &= ~CSTOPB;
246
 
                break;
247
 
 
248
 
        case '2':
249
 
                tty->c_cflag |= CSTOPB;
250
 
                break;
251
 
 
252
 
        default:
253
 
                return(-EINVAL);
254
 
  }
255
 
  return(0);
256
 
}
257
 
 
258
 
 
259
 
/* Set the number of data bits. */
260
 
static int
261
 
tty_set_databits(struct termios *tty, char *databits)
262
 
{
263
 
  if (opt_d) printf("slattach: tty_set_databits: %c\n", *databits);
264
 
  tty->c_cflag &= ~CSIZE;
265
 
  switch(*databits) {
266
 
        case '5':
267
 
                tty->c_cflag |= CS5;
268
 
                break;
269
 
 
270
 
        case '6':
271
 
                tty->c_cflag |= CS6;
272
 
                break;
273
 
 
274
 
        case '7':
275
 
                tty->c_cflag |= CS7;
276
 
                break;
277
 
 
278
 
        case '8':
279
 
                tty->c_cflag |= CS8;
280
 
                break;
281
 
 
282
 
        default:
283
 
                return(-EINVAL);
284
 
  }
285
 
  return(0);
286
 
}
287
 
 
288
 
 
289
 
/* Set the type of parity encoding. */
290
 
static int
291
 
tty_set_parity(struct termios *tty, char *parity)
292
 
{
293
 
  if (opt_d) printf("slattach: tty_set_parity: %c\n", *parity);
294
 
  switch(toupper(*parity)) {
295
 
        case 'N':
296
 
                tty->c_cflag &= ~(PARENB | PARODD);
297
 
                break;  
298
 
 
299
 
        case 'O':
300
 
                tty->c_cflag &= ~(PARENB | PARODD);
301
 
                tty->c_cflag |= (PARENB | PARODD);
302
 
                break;
303
 
 
304
 
        case 'E':
305
 
                tty->c_cflag &= ~(PARENB | PARODD);
306
 
                tty->c_cflag |= (PARENB);
307
 
                break;
308
 
 
309
 
        default:
310
 
                return(-EINVAL);
311
 
  }
312
 
  return(0);
313
 
}
314
 
 
315
 
 
316
 
/* Set the line speed of a terminal line. */
317
 
static int
318
 
tty_set_speed(struct termios *tty, const char *speed)
319
 
{
320
 
  int code;
321
 
 
322
 
  if (opt_d) printf("slattach: tty_set_speed: %s\n", speed);
323
 
  if ((code = tty_find_speed(speed)) < 0) return(code);
324
 
  tty->c_cflag &= ~CBAUD;
325
 
  tty->c_cflag |= code;
326
 
  return(0);
327
 
}
328
 
 
329
 
 
330
 
/* Put a terminal line in a transparent state. */
331
 
static int
332
 
tty_set_raw(struct termios *tty)
333
 
{
334
 
  int i;
335
 
  int speed;
336
 
 
337
 
  for(i = 0; i < NCCS; i++)
338
 
                tty->c_cc[i] = '\0';            /* no spec chr          */
339
 
  tty->c_cc[VMIN] = 1;
340
 
  tty->c_cc[VTIME] = 0;
341
 
  tty->c_iflag = (IGNBRK | IGNPAR);             /* input flags          */
342
 
  tty->c_oflag = (0);                           /* output flags         */
343
 
  tty->c_lflag = (0);                           /* local flags          */
344
 
  speed = (tty->c_cflag & CBAUD);               /* save current speed   */
345
 
  tty->c_cflag = (CRTSCTS | HUPCL | CREAD);     /* UART flags           */
346
 
  if (opt_L) 
347
 
        tty->c_cflag |= CLOCAL;
348
 
  tty->c_cflag |= speed;                        /* restore speed        */
349
 
  return(0);
350
 
}
351
 
 
352
 
 
353
 
/* Fetch the state of a terminal. */
354
 
static int
355
 
tty_get_state(struct termios *tty)
356
 
{
357
 
  if (ioctl(tty_fd, TCGETS, tty) < 0) {
358
 
        if (opt_q == 0) fprintf(stderr,
359
 
                "slattach: tty_get_state: %s\n", strerror(errno));
360
 
        return(-errno);
361
 
  }
362
 
  return(0);
363
 
}
364
 
 
365
 
 
366
 
/* Set the state of a terminal. */
367
 
static int
368
 
tty_set_state(struct termios *tty)
369
 
{
370
 
  if (ioctl(tty_fd, TCSETS, tty) < 0) {
371
 
        if (opt_q == 0) fprintf(stderr,
372
 
                "slattach: tty_set_state: %s\n", strerror(errno));
373
 
        return(-errno);
374
 
  }
375
 
  return(0);
376
 
}
377
 
 
378
 
 
379
 
/* Get the line discipline of a terminal line. */
380
 
static int
381
 
tty_get_disc(int *disc)
382
 
{
383
 
  if (ioctl(tty_fd, TIOCGETD, disc) < 0) {
384
 
        if (opt_q == 0) fprintf(stderr,
385
 
                "slattach: tty_get_disc: %s\n", strerror(errno));
386
 
        return(-errno);
387
 
  }
388
 
  return(0);
389
 
}
390
 
 
391
 
 
392
 
/* Set the line discipline of a terminal line. */
393
 
static int
394
 
tty_set_disc(int disc)
395
 
{
396
 
  if (disc == -1) disc = tty_sdisc;
397
 
 
398
 
  if (ioctl(tty_fd, TIOCSETD, &disc) < 0) {
399
 
        if (opt_q == 0) fprintf(stderr,
400
 
                "slattach: tty_set_disc(%d, %d): %s\n", tty_fd,
401
 
                        disc, strerror(errno));
402
 
        return(-errno);
403
 
  }
404
 
  return(0);
405
 
}
406
 
 
407
 
 
408
 
/* Fetch the name of the network interface attached to this terminal. */
409
 
static int
410
 
tty_get_name(char *name)
411
 
{
412
 
  if (ioctl(tty_fd, SIOCGIFNAME, name) < 0) {
413
 
        if (opt_q == 0) 
414
 
            perror("tty_get_name");
415
 
        return(-errno);
416
 
  }
417
 
  return(0);
418
 
}
419
 
 
420
 
 
421
 
/* Hangup the line. */
422
 
static int
423
 
tty_hangup(void)
424
 
{
425
 
  struct termios tty;
426
 
 
427
 
  tty = tty_current;
428
 
  (void) tty_set_speed(&tty, "0");
429
 
  if (tty_set_state(&tty) < 0) {
430
 
        if (opt_q == 0) fprintf(stderr, _("slattach: tty_hangup(DROP): %s\n"), strerror(errno));
431
 
        return(-errno);
432
 
  }
433
 
 
434
 
  (void) sleep(1);
435
 
 
436
 
  if (tty_set_state(&tty_current) < 0) {
437
 
        if (opt_q == 0) fprintf(stderr, _("slattach: tty_hangup(RAISE): %s\n"), strerror(errno));
438
 
        return(-errno);
439
 
  }
440
 
  return(0);
441
 
}
442
 
 
443
 
 
444
 
/* Close down a terminal line. */
445
 
static int
446
 
tty_close(void)
447
 
{
448
 
  (void) tty_set_disc(tty_sdisc);
449
 
  (void) tty_hangup();
450
 
  (void) tty_lock(NULL, 0);
451
 
  return(0);
452
 
}
453
 
 
454
 
 
455
 
/* Open and initialize a terminal line. */
456
 
static int
457
 
tty_open(char *name, const char *speed)
458
 
{
459
 
  char pathbuf[PATH_MAX];
460
 
  register char *path_open, *path_lock;
461
 
  int fd;
462
 
 
463
 
  /* Try opening the TTY device. */
464
 
  if (name != NULL) {
465
 
        if (name[0] != '/') {
466
 
                if (strlen(name + 6) > sizeof(pathbuf)) {
467
 
                        if (opt_q == 0) fprintf(stderr, 
468
 
                                _("slattach: tty name too long\n"));
469
 
                        return (-1);
470
 
                }
471
 
                sprintf(pathbuf, "/dev/%s", name);
472
 
                path_open = pathbuf;
473
 
                path_lock = name;
474
 
        } else if (!strncmp(name, "/dev/", 5)) {
475
 
                path_open = name;
476
 
                path_lock = name + 5;
477
 
        } else {
478
 
                path_open = name;
479
 
                path_lock = name;
480
 
        }
481
 
        if (opt_d) printf("slattach: tty_open: looking for lock\n");
482
 
        if (tty_lock(path_lock, 1)) return(-1); /* can we lock the device? */
483
 
        if (opt_d) printf("slattach: tty_open: trying to open %s\n", path_open);
484
 
        if ((fd = open(path_open, O_RDWR|O_NDELAY)) < 0) {
485
 
                if (opt_q == 0) fprintf(stderr,
486
 
                        "slattach: tty_open(%s, RW): %s\n",
487
 
                                        path_open, strerror(errno));
488
 
                return(-errno);
489
 
        }
490
 
        tty_fd = fd;
491
 
        if (opt_d) printf("slattach: tty_open: %s (fd=%d) ", path_open, fd);
492
 
  } else {
493
 
        tty_fd = 0;
494
 
  }
495
 
 
496
 
  /* Fetch the current state of the terminal. */
497
 
  if (tty_get_state(&tty_saved) < 0) {
498
 
        if (opt_q == 0) fprintf(stderr, _("slattach: tty_open: cannot get current state!\n"));
499
 
        return(-errno);
500
 
  }
501
 
  tty_current = tty_saved;
502
 
 
503
 
  /* Fetch the current line discipline of this terminal. */
504
 
  if (tty_get_disc(&tty_sdisc) < 0) {
505
 
        if (opt_q == 0) fprintf(stderr, _("slattach: tty_open: cannot get current line disc!\n"));
506
 
        return(-errno);
507
 
  } 
508
 
  tty_ldisc = tty_sdisc;
509
 
 
510
 
  /* Put this terminal line in a 8-bit transparent mode. */
511
 
  if (opt_m == 0) {
512
 
        if (tty_set_raw(&tty_current) < 0) {
513
 
                if (opt_q == 0) fprintf(stderr, _("slattach: tty_open: cannot set RAW mode!\n"));
514
 
                return(-errno);
515
 
        }
516
 
 
517
 
        /* Set the default speed if we need to. */
518
 
        if (speed != NULL) {
519
 
                if (tty_set_speed(&tty_current, speed) != 0) {
520
 
                        if (opt_q == 0) fprintf(stderr, _("slattach: tty_open: cannot set %s bps!\n"),
521
 
                                                speed);
522
 
                        return(-errno);
523
 
                }
524
 
        }
525
 
 
526
 
        /* Set up a completely 8-bit clean line. */
527
 
        if (tty_set_databits(&tty_current, "8") ||
528
 
            tty_set_stopbits(&tty_current, "1") ||
529
 
            tty_set_parity(&tty_current, "N")) {
530
 
                if (opt_q == 0) fprintf(stderr, _("slattach: tty_open: cannot set 8N1 mode!\n"));
531
 
                return(-errno);
532
 
        }
533
 
 
534
 
        /* Set the new line mode. */
535
 
        if ((fd = tty_set_state(&tty_current)) < 0) return(fd);
536
 
  }
537
 
 
538
 
  /* OK, line is open.  Do we need to "silence" it? */
539
 
  (void) tty_nomesg(tty_fd);
540
 
 
541
 
  return(0);
542
 
}
543
 
 
544
 
 
545
 
/* Catch any signals. */
546
 
static void
547
 
sig_catch(int sig)
548
 
{
549
 
/*  (void) signal(sig, sig_catch); */
550
 
  tty_close();
551
 
  exit(0);
552
 
}
553
 
 
554
 
 
555
 
static void
556
 
usage(void)
557
 
{
558
 
  char *usage_msg = "Usage: slattach [-ehlLmnqv] "
559
 
#ifdef SIOCSKEEPALIVE
560
 
          "[-k keepalive] "
561
 
#endif
562
 
#ifdef SIOCSOUTFILL
563
 
          "[-o outfill] "
564
 
#endif
565
 
          "[-c cmd] [-s speed] [-p protocol] tty | -\n"
566
 
          "       slattach -V | --version\n";
567
 
 
568
 
  fprintf(stderr, usage_msg);
569
 
  exit(1);
570
 
}
571
 
 
572
 
 
573
 
static void 
574
 
version(void)
575
 
{
576
 
    printf("%s\n%s\n%s\n", Release, Version, Signature);
577
 
    exit(E_VERSION);
578
 
}
579
 
 
580
 
 
581
 
int
582
 
main(int argc, char *argv[])
583
 
{
584
 
  char path_buf[128];
585
 
  char *path_dev;
586
 
  char buff[128];
587
 
  const char *speed = NULL;
588
 
  const char *proto = DEF_PROTO;
589
 
  const char *extcmd = NULL;
590
 
  int s;
591
 
  static struct option longopts[] = {
592
 
    { "version", 0, NULL, 'V' },
593
 
    { NULL, 0, NULL, 0 }
594
 
  };
595
 
 
596
 
  strcpy(path_buf, "");
597
 
  path_dev = path_buf;
598
 
 
599
 
  /* Scan command line for any arguments. */
600
 
  opterr = 0;
601
 
  while ((s = getopt_long(argc, argv, "c:ehlLmnp:qs:vdVk:o:", longopts, NULL)) != EOF) switch(s) {
602
 
        case 'c':
603
 
                extcmd = optarg;
604
 
                break;
605
 
 
606
 
        case 'e':
607
 
                opt_e = 1 - opt_e;
608
 
                break;
609
 
 
610
 
        case 'h':
611
 
                opt_h = 1 - opt_h;
612
 
                break;
613
 
 
614
 
#ifdef SIOCSKEEPALIVE
615
 
        case 'k':
616
 
                opt_k = atoi(optarg);
617
 
                break;
618
 
#endif
619
 
 
620
 
        case 'L':
621
 
                opt_L = 1 - opt_L;
622
 
                break;
623
 
 
624
 
        case 'l':
625
 
                opt_l = 1 - opt_l;
626
 
                break;
627
 
 
628
 
        case 'm':
629
 
                opt_m = 1 - opt_m;
630
 
                break;
631
 
 
632
 
        case 'n':
633
 
                opt_n = 1 - opt_n;
634
 
                break;
635
 
 
636
 
#ifdef SIOCSOUTFILL
637
 
        case 'o':
638
 
                opt_o = atoi(optarg);
639
 
                break;
640
 
#endif
641
 
 
642
 
        case 'p':
643
 
                proto = optarg;
644
 
                break;
645
 
 
646
 
        case 'q':
647
 
                opt_q = 1 - opt_q;
648
 
                break;
649
 
 
650
 
        case 's':
651
 
                speed = optarg;
652
 
                break;
653
 
 
654
 
        case 'd':
655
 
                opt_d = 1 - opt_d;
656
 
                break;
657
 
 
658
 
        case 'v':
659
 
                opt_v = 1 - opt_v;
660
 
                break;
661
 
 
662
 
        case 'V':
663
 
                version();
664
 
                /*NOTREACHED*/
665
 
 
666
 
        default:
667
 
                usage();
668
 
                /*NOTREACHED*/
669
 
  }
670
 
  
671
 
  if (setvbuf(stdout,0,_IOLBF,0)) {
672
 
        if (opt_q == 0) fprintf(stderr, _("slattach: setvbuf(stdout,0,_IOLBF,0) : %s\n"),
673
 
                                strerror(errno));
674
 
        exit(1);
675
 
  }
676
 
 
677
 
  activate_init();
678
 
 
679
 
  if (!strcmp(proto, "tty"))
680
 
       opt_m++;
681
 
 
682
 
  /* Is a terminal given? */
683
 
  if (optind != (argc - 1)) usage();
684
 
  safe_strncpy(path_buf, argv[optind], sizeof(path_buf));
685
 
  if (!strcmp(path_buf, "-")) {
686
 
        opt_e = 1;
687
 
        path_dev = NULL;
688
 
        if (tty_open(NULL, speed) < 0) { return(3); }
689
 
  } else {
690
 
        path_dev = path_buf;
691
 
        if (tty_open(path_dev, speed) < 0) { return(3); }
692
 
  }
693
 
 
694
 
  /* Start the correct protocol. */
695
 
  if (!strcmp(proto, "tty")) {
696
 
        tty_sdisc = N_TTY;
697
 
        tty_close();
698
 
        return(0);
699
 
  }
700
 
  if (activate_ld(proto, tty_fd))
701
 
        return(1);
702
 
  if ((opt_v == 1) || (opt_d == 1)) {
703
 
        if (tty_get_name(buff)) { return(3); }
704
 
        printf(_("%s started"), proto);
705
 
        if (path_dev != NULL) printf(_(" on %s"), path_dev);
706
 
        printf(_(" interface %s\n"), buff);
707
 
  }
708
 
 
709
 
  /* Configure keepalive and outfill. */
710
 
#ifdef SIOCSKEEPALIVE
711
 
  if (opt_k && (ioctl(tty_fd, SIOCSKEEPALIVE, &opt_k) < 0))
712
 
          fprintf(stderr, "slattach: ioctl(SIOCSKEEPALIVE): %s\n", strerror(errno));
713
 
#endif
714
 
#ifdef SIOCSOUTFILL
715
 
  if (opt_o && (ioctl(tty_fd, SIOCSOUTFILL, &opt_o) < 0))
716
 
          fprintf(stderr, "slattach: ioctl(SIOCSOUTFILL): %s\n", strerror(errno));
717
 
#endif
718
 
 
719
 
  (void) signal(SIGHUP, sig_catch);
720
 
  (void) signal(SIGINT, sig_catch);
721
 
  (void) signal(SIGQUIT, sig_catch);
722
 
  (void) signal(SIGTERM, sig_catch);
723
 
 
724
 
  /* Wait until we get killed if hanging on a terminal. */
725
 
  if (opt_e == 0) {
726
 
        while(1) {
727
 
                if(opt_h == 1) { /* hangup on carrier loss */
728
 
                        int n = 0;
729
 
 
730
 
                        ioctl(tty_fd, TIOCMGET, &n);
731
 
                        if(!(n & TIOCM_CAR))
732
 
                                break;
733
 
                        sleep(15);
734
 
                }
735
 
                else
736
 
                        sleep(60);
737
 
        };
738
 
 
739
 
        tty_close();
740
 
        if(extcmd)      /* external command on exit */
741
 
                system(extcmd);
742
 
  }
743
 
  exit(0);
744
 
}