slattach.c
来自「Linux下网络相关工具源代码。」· C语言 代码 · 共 724 行 · 第 1/2 页
C
724 行
/* * slattach A program for handling dialup IP connecions. * This program forces a TTY line to go into a special * terminal line discipline, so that it can be used for * network traffic instead of the regular terminal I/O. * * Usage: slattach [-ehlmnqv] [ -k keepalive ] [ -o outfill ] * [-c cmd] [-s speed] [-p protocol] tty | - * * Version: @(#)slattach.c 1.1.30 03/01/95 * * Author: Fred N. van Kempen, <waltje@uWalt.NL.Mugnet.ORG> * Copyright 1988-1993 MicroWalt Corporation * * Modified: * Alan Cox, <A.Cox@swansea.ac.uk> , July 16 1994 * Miquel van Smoorenburg, <miquels@drinkel.ow.org>, October 1994 * George Shearer, <gshearer@one.net>, January 3, 1995 * Yossi Gottlieb, <yogo@math.tau.ac.il>, February 11, 1995 * Peter Tobias, <tobias@et-inf.fho-emden.de>, July 30 1995 * * This program is free software; you can redistribute it * and/or modify it under the terms of the GNU General * Public License as published by the Free Software * Foundation; either version 2 of the License, or (at * your option) any later version. */#include <sys/types.h>#include <sys/socket.h>#include <sys/ioctl.h>#include <sys/stat.h>#include <stdio.h>#include <ctype.h>#include <errno.h>#include <fcntl.h>#include <limits.h>#include <pwd.h>#include <signal.h>#include <stdlib.h> #include <string.h>#include <unistd.h>#include <getopt.h>#include <linux/if_slip.h>#if defined(__GLIBC__)#if __GLIBC__ == 2 && __GLIBC_MINOR__ == 0# include <termbits.h>#else# include <termios.h>#endif#endif#include "pathnames.h"#include "net-support.h"#include "version.h"#include "config.h"#include "intl.h"#ifndef _PATH_LOCKD#define _PATH_LOCKD "/var/lock" /* lock files */#endif#ifndef _UID_UUCP#define _UID_UUCP "uucp" /* owns locks */#endif#define DEF_PROTO "cslip"char *Release = RELEASE, *Version = "@(#) slattach 1.1.91 (12-Feb-95)", *Signature = "Fred N. van Kempen et al.";struct { char *speed; int code;} tty_speeds[] = { /* table of usable baud rates */ { "50", B50 }, { "75", B75 }, { "110", B110 }, { "300", B300 }, { "600", B600 }, { "1200", B1200 }, { "2400", B2400 }, { "4800", B4800 }, { "9600", B9600 },#ifdef B14400 { "14400", B14400 },#endif#ifdef B19200 { "19200", B19200 },#endif#ifdef B38400 { "38400", B38400 },#endif#ifdef B57600 { "57600", B57600 },#endif#ifdef B115200 { "115200", B115200 },#endif { NULL, 0 }};struct termios tty_saved, /* saved TTY device state */ tty_current; /* current TTY device state */int tty_sdisc, /* saved TTY line discipline */ tty_ldisc, /* current TTY line discipline */ tty_fd = -1; /* TTY file descriptor */int opt_c = 0; /* "command" to run at exit */int opt_e = 0; /* "activate only" flag */int opt_h = 0; /* "hangup" on carrier loss */#ifdef SIOCSKEEPALIVEint opt_k = 0; /* "keepalive" value */#endifint opt_l = 0; /* "lock it" flag */int opt_L = 0; /* clocal flag */int opt_m = 0; /* "set RAW mode" flag */int opt_n = 0; /* "set No Mesg" flag */#ifdef SIOCSOUTFILLint opt_o = 0; /* "outfill" value */#endifint opt_q = 0; /* "quiet" flag */int opt_d = 0; /* debug flag */int opt_v = 0; /* Verbose flag *//* Disable any messages to the input channel of this process. */static inttty_nomesg(int fd){ if (opt_n == 0) return(0); return(fchmod(fd, 0600));}/* Check for an existing lock file on our device */static inttty_already_locked(char *nam){ int i = 0, pid = 0; FILE *fd = (FILE *)0; /* Does the lock file on our device exist? */ if ((fd = fopen(nam, "r")) == (FILE *)0) return(0); /* No, return perm to continue */ /* Yes, the lock is there. Now let's make sure */ /* at least there's no active process that owns */ /* that lock. */ i = fscanf(fd, "%d", &pid); (void) fclose(fd); if (i != 1) /* Lock file format's wrong! Kill't */ return(0); /* We got the pid, check if the process's alive */ if (kill(pid, 0) == 0) /* it found process */ return(1); /* Yup, it's running... */ /* Dead, we can proceed locking this device... */ return(0);}/* Lock or unlock a terminal line. */static inttty_lock(char *path, int mode){ static char saved_path[PATH_MAX]; static int saved_lock = 0; struct passwd *pw; int fd; char apid[16]; /* We do not lock standard input. */ if ((opt_l == 0) || ((path == NULL) && (saved_lock == 0))) return(0); if (mode == 1) { /* lock */ sprintf(saved_path, "%s/LCK..%s", _PATH_LOCKD, path); if (tty_already_locked(saved_path)) { fprintf(stderr, _("slattach: /dev/%s already locked!\n"), path); return(-1); } if ((fd = creat(saved_path, 0644)) < 0) { if (errno != EEXIST) if (opt_q == 0) fprintf(stderr, _("slattach: tty_lock: (%s): %s\n"), saved_path, strerror(errno)); return(-1); } sprintf(apid, "%10d\n", getpid()); if (write(fd, apid, strlen(apid)) != strlen(apid)) { fprintf(stderr, _("slattach: cannot write PID file\n")); close(fd); unlink(saved_path); return(-1); } (void) close(fd); /* Make sure UUCP owns the lockfile. Required by some packages. */ if ((pw = getpwnam(_UID_UUCP)) == NULL) { if (opt_q == 0) fprintf(stderr, _("slattach: tty_lock: UUCP user %s unknown!\n"), _UID_UUCP); return(0); /* keep the lock anyway */ } (void) chown(saved_path, pw->pw_uid, pw->pw_gid); saved_lock = 1; } else { /* unlock */ if (saved_lock != 1) return(0); if (unlink(saved_path) < 0) { if (opt_q == 0) fprintf(stderr, "slattach: tty_unlock: (%s): %s\n", saved_path, strerror(errno)); return(-1); } saved_lock = 0; } return(0);}/* Find a serial speed code in the table. */static inttty_find_speed(char *speed){ int i; i = 0; while (tty_speeds[i].speed != NULL) { if (!strcmp(tty_speeds[i].speed, speed)) return(tty_speeds[i].code); i++; } return(-EINVAL);}/* Set the number of stop bits. */static inttty_set_stopbits(struct termios *tty, char *stopbits){ if (opt_d) printf("slattach: tty_set_stopbits: %c\n", *stopbits); switch(*stopbits) { case '1': tty->c_cflag &= ~CSTOPB; break; case '2': tty->c_cflag |= CSTOPB; break; default: return(-EINVAL); } return(0);}/* Set the number of data bits. */static inttty_set_databits(struct termios *tty, char *databits){ if (opt_d) printf("slattach: tty_set_databits: %c\n", *databits); tty->c_cflag &= ~CSIZE; switch(*databits) { case '5': tty->c_cflag |= CS5; break; case '6': tty->c_cflag |= CS6; break; case '7': tty->c_cflag |= CS7; break; case '8': tty->c_cflag |= CS8; break; default: return(-EINVAL); } return(0);}/* Set the type of parity encoding. */static inttty_set_parity(struct termios *tty, char *parity){ if (opt_d) printf("slattach: tty_set_parity: %c\n", *parity); switch(toupper(*parity)) { case 'N': tty->c_cflag &= ~(PARENB | PARODD); break; case 'O': tty->c_cflag &= ~(PARENB | PARODD); tty->c_cflag |= (PARENB | PARODD); break; case 'E': tty->c_cflag &= ~(PARENB | PARODD); tty->c_cflag |= (PARENB); break; default: return(-EINVAL); } return(0);}/* Set the line speed of a terminal line. */static inttty_set_speed(struct termios *tty, char *speed){ int code; if (opt_d) printf("slattach: tty_set_speed: %s\n", speed); if ((code = tty_find_speed(speed)) < 0) return(code); tty->c_cflag &= ~CBAUD; tty->c_cflag |= code; return(0);}/* Put a terminal line in a transparent state. */static inttty_set_raw(struct termios *tty){ int i; int speed; for(i = 0; i < NCCS; i++) tty->c_cc[i] = '\0'; /* no spec chr */ tty->c_cc[VMIN] = 1; tty->c_cc[VTIME] = 0; tty->c_iflag = (IGNBRK | IGNPAR); /* input flags */ tty->c_oflag = (0); /* output flags */ tty->c_lflag = (0); /* local flags */ speed = (tty->c_cflag & CBAUD); /* save current speed */ tty->c_cflag = (CRTSCTS | HUPCL | CREAD); /* UART flags */ if (opt_L) tty->c_cflag |= CLOCAL; tty->c_cflag |= speed; /* restore speed */ return(0);}/* Fetch the state of a terminal. */static inttty_get_state(struct termios *tty){ if (ioctl(tty_fd, TCGETS, tty) < 0) { if (opt_q == 0) fprintf(stderr, "slattach: tty_get_state: %s\n", strerror(errno)); return(-errno); } return(0);}/* Set the state of a terminal. */static int
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?