⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 term.c

📁 tcpipstack源程序用于C51的TCP/IP协议栈,,C-C++,TCP/IP Stack
💻 C
📖 第 1 页 / 共 3 页
字号:
/*
 * usage: term [-s speed] [-l line] [-e escape-char] [-c callscript]
 *      defaults:
 *              speed:  38400 or 2400
 *              line :  /dev/tty2a
 *              escape: ~
 *                      escape char may be specified as three octal digits
 *
 *      term escapes:
 *              escape-. or escape-CTRLD        terminate
 *              escape-!                        escape to shell
 *              escape-#                        send break
 *              escape-escape                   send escape char
 */

#include <stdio.h>
#include <string.h>
#include <signal.h>
#include <fcntl.h>
#include <ctype.h>
#include <errno.h>
#include <malloc.h>
#include <setjmp.h>

#ifdef V7
# include <sgtty.h>
#else
# if defined(__linux__) || defined(HAVE_TERMIOS)
#  include <termios.h>
#  ifndef HAVE_TERMIOS
#   define HAVE_TERMIOS
#  endif
# else
#  include <termio.h>
# endif
# ifndef SYSV
#  define SYSV
# endif
#endif

#define XSCRIPT
#define XLOGFILE
#define XCHARXLATE

#ifdef B38400
#define SPEED B38400		/* default speed */
#else
#define SPEED B2400		/* default speed */
#endif

#define LINE    "/dev/ttyS0"    /* the default line  */
#define ESC     '~'             /* default esc char  */
#define EOT     '\004'          /* ^D */

#ifndef R_OK            /* access() modes */
#define R_OK 4
#define W_OK 2
#endif

char esc[2] = { ESC, '\0' };

extern void s_line();      /* set & save line characteristics   */
extern void r_line();      /* reset saved  line characteristics */

int wr_pid = 0;            /* writer process id */
int line_fd;               /* comm line file desc        */
int tty_fd;                /* console   file desc        */
char line_device[64];

#ifdef CHARXLATE
int Termtype = 2;
#else
int Termtype = 0;
#endif
int Bit_mask = 0xFF;	   /* Strip high bit from line */
int Parity = 0;		   /* Add parity to line */

#ifdef LOGFILE
FILE * lfile = 0;
char   logfname[64] = "tty/ttylog%d";
char   ltbuf[10240];
char * ltptr = 0;
#endif

#ifdef SCRIPT
int in_script = 0;
char script_name[128];
char script_args[128];
struct script_sv
{
   struct script_sv * next;
   FILE * scrfd;
   char script_args[128];
}
   * saved_sc = 0;

int verbose = 0;
#endif

int cleanup()
{
   int status;
   r_line();
   if( wr_pid ) kill(wr_pid, SIGTERM);
   wait(&status);
   uucp_unlock(line_device);
#ifdef LOGFILE
   if( lfile ) fclose(lfile);
   lfile = 0;
#endif
   if( wr_pid ) fprintf(stderr, "Disconnected\r\n");
   exit(0);
}

void main(argc, argv)
int argc;
char **argv;
{
   int done, status;
   int speed = SPEED;
   extern char *optarg;
   extern int optind;
   extern int getopt(), conv_speed(), conv_esc(), access();
   extern open_timeout();

   strcpy(line_device, LINE);
   while((status = getopt(argc, argv,"s:l:e:rdm7pv")) != EOF)
   {
      switch(status)
      {
      case 's':
         if((speed = conv_speed(optarg)) == EOF)
         {
            fprintf(stderr,"%s: invalid speed\n", optarg);
            exit(1);
         }
         break;
      case 'l':
         strncpy(line_device, optarg, sizeof(line_device));
         if(access(line_device, R_OK|W_OK) == -1)
         {
            perror(optarg);
            exit(2);
         }
         break;

      case 'e': esc[0] = conv_esc(optarg); break;
      case 'p': Parity = 1; /* FALL */
      case '7': Bit_mask = 0x7F; break;
      case 'd': Termtype = 1; break;
#ifdef CHARXLATE
      case 'r': Termtype = 0; break;
#endif
#ifdef SCRIPT
      case 'v': verbose++; break;
#endif
      default:
         fprintf(stderr,
             "usage: %s [-s speed] [-l line] [-e escape-char]\n", *argv);
         exit(3);
      }
   }
   if( optind < argc )
   {
#ifdef SCRIPT
      strcpy(script_name, argv[optind]);
      strcat(script_name, ".sct");
      if(access(script_name, R_OK) == -1)
      {
         strcpy(script_name, "sct/");
         strcat(script_name, argv[optind]);
         strcat(script_name, ".sct");
         if(access(script_name, R_OK) == -1)
         {
	    fprintf(stderr, "Cannot open '%s.sct'\n", argv[optind]);
	    exit(4);
	 }
      }
      strcpy(script_name, argv[optind]);
      in_script = 1;
      for(optind++, script_args[0] = '\0'; optind<argc; optind++)
      {
	 if(*script_args) strcat(script_args, " ");
	 strcat(script_args, argv[optind]);
      }
#else
      fprintf(stderr,
             "usage: %s [-s speed] [-l line] [-e escape-char]\n", *argv);
      exit(3);
#endif
   }

   if( !uucp_check(line_device) )
   {
      fprintf(stderr, "Device in use\n");
      exit(1);
   }

   signal(SIGALRM, open_timeout);
   alarm(5);
   if((line_fd = open(line_device, O_RDWR)) < 0)
   {
      perror(line_device);
      exit(4);
   }
   alarm(0);
   signal(SIGALRM, SIG_DFL);

   tty_fd = fileno(stdin);

   signal(SIGINT, SIG_IGN);
   signal(SIGQUIT, SIG_IGN);
   signal(SIGTERM, SIG_IGN);

   s_line(speed);

   signal(SIGTERM, cleanup);

#ifdef SCRIPT
   if( in_script )
      fprintf(stderr, "Running script\r\n");
   else
#endif
      fprintf(stderr, "Connected\r\n");

   signal(SIGCHLD, cleanup);
   fork_writer(); /* launch writer process */
   read_tty();
   cleanup();
}

open_timeout()
{
   fprintf(stderr, "Cannot open port -- No carrier\n");
   cleanup();
}

#ifdef LOGFILE
open_logfile()
{
   char file[150];
   char file2[160];
   char file3[160];
   char *p;
   int  lnumber;
   FILE * fd;
   if( lfile ) return;
   if( strchr(logfname, '%') == 0 )
   {
      strcpy(file, logfname);
      lfile = fopen(file, "a");
      if( lfile == 0 ) return;
   }
   else
   {
      strcpy(file, logfname);
      p = strchr(file, '%');
      while(*p) { if(*p == 'd') { *p='s'; break; } else p++; }
      sprintf(file3, file, "cnt");
      lnumber=1;
      fd = fopen(file3, "r");
      if(fd) { fscanf(fd, "%d", &lnumber); fclose(fd); }
      for(;;lnumber++)
      {
         sprintf(file, logfname, lnumber);
         strcpy(file2, file);
         strcat(file2, ".Z");
         if( access(file, 0) != -1 || access(file2, 0) != -1 )
         {
            if( lnumber>=1000 )
            {
               lfile = 0;
               break;;
            }
            continue;
         }
         lfile = fopen(file, "w");
         fd = fopen(file3, "w");
         if(fd) { fprintf(fd, "%d\n", lnumber+1); fclose(fd); }
         break;
      }
   }
   if( lfile )
      fprintf(stderr, "Logfile %s\r\n", file);
   else
      fprintf(stderr, "Cannot open Logfile %s\r\n", file);
   if( ltptr && ltbuf != ltptr )
   {
      fwrite(ltbuf, 1, ltptr-ltbuf, lfile);
      ltptr = 0;
   }
}
#endif

typedef struct
{
   char *str;
   int  spd;
} vspeeds;

static vspeeds valid_speeds[] = 
{
   { "110",  B110  },
   { "300",  B300  },
   { "1200", B1200 },
   { "2400", B2400 },
   { "4800", B4800 },
   { "9600", B9600 },
#ifdef B19200
   { "19200", B19200 },
#endif
#ifdef B38400
   { "38400", B38400 },
#endif
#ifdef B57600
   { "57600", B57600 },
#endif
#ifdef B115200
   { "115200", B115200 },
#endif
   { (char *)0, 0 }
};

/*
 * given a desired speed string, if valid return its Bspeed value
 * else EOF
 */
int conv_speed(s)
register char *s;
{
   register vspeeds *p = &valid_speeds[0];

   if(*s == 0) return EOF;

   for(; p->str != (char *)0; p++)
      if(strncmp(s, p->str, strlen(s)) == 0)
         return p->spd;
   return EOF;
}

/*
 * convert given string to char
 *      string maybe a char, or octal digits
 */
int conv_esc(s)
register char *s;
{
   register int val = 0;

   if(!isdigit(*s))
      return *s; /* ! octal */

   /* convert octal digs */
   do
   {
      if(*s > '7' || *s < '0')
      {
         fprintf(stderr,"escape char must be character/octal digits\n");
         exit(4);
      }
      val = (val << 3) + (*s++ - '0');
   } while(isdigit(*s));

   return val;
}

/*-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-*/

#ifdef V7
/* This is Version 7 unix code it should work on any unix machine */
/* If you believe that you'll believe anything :-) */

struct sgttyb tty_save, line_save, tty;
int tty_mode = -1;
int got_line = 0;

void s_line(speed)
{
   set_mode(2);
   if(!got_line)
   {
      got_line = 1;
      ioctl(line_fd, TIOCGETP, &line_save);
   }
   tty = line_save;
   tty.sg_ospeed  = speed;      /* Set new speed */
   tty.sg_ispeed  = speed;      /* Set new speed */
   tty.sg_flags  |= RAW;
   tty.sg_flags  &= ~ECHO;
   /* Parity doesn't appear to work with Xenix tty.sg_flags |= EVENP; */
   /* So xmit parity is done in software */
   ioctl(line_fd, TIOCSETP, &tty);
}

void r_line()
{
   set_mode(0);
   if(!got_line) return;
   ioctl(line_fd, TIOCSETP, &line_save);
}

set_mode(which)
int which;
{
    if( tty_mode == -1 )
    {
       if(ioctl(tty_fd, TIOCGETP, &tty))
       {
	   perror("Unable to sense terminal");
	   exit(1);
       }
       tty_save = tty;
       tty_mode = 0;
    }

    tty = tty_save;
    switch(which)
    {
    default: /* Normal cooked */
	    which = 0;
	    break;
    case 1: /* CBREAK */
            tty.sg_flags &= ~ECHO;
            tty.sg_flags |= CBREAK; /* Allow break & cr/nl mapping */
	    break;
    case 2: /* RAW */
            tty.sg_flags &= ~ECHO;
            tty.sg_flags |= RAW;
            break;
    }
    if(ioctl(tty_fd, TIOCSETP, &tty))
    {
	perror("Unable to change terminal mode");
    }
    else tty_mode = which;
}
#endif
/*-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-*/
#ifdef SYSV
/* This is System V unix code */

#ifdef HAVE_TERMIOS
struct termios tty_save, line_save, tty;
#else
struct termio tty_save, line_save, tty;
#endif
static int tty_mode = -1;
int got_line = 0;

void s_line(speed)
int speed;
{
   set_mode(2);
   if(!got_line)
   {
      got_line = 1;
#ifndef HAVE_TERMIOS
      ioctl(line_fd, TCGETA, &line_save);
#else
      tcgetattr(line_fd, &line_save);
#endif
   }
   tty = line_save;

   tty.c_iflag &= ~(IXON|IXANY|IXOFF|ISTRIP|INLCR|ICRNL|IGNCR|IUCLC);
   tty.c_oflag &= ~(OLCUC|ONLCR|OCRNL|ONOCR|ONLRET);
   tty.c_cflag &= ~(CBAUD|PARENB);
   tty.c_lflag &= ~(ICANON|ECHO|ECHOE|ECHONL|ISIG);

   tty.c_iflag |= IXOFF;	/* X/Y modem will clear this */
   tty.c_cflag |= (speed);

   tty.c_cc[VTIME] = 0;
   tty.c_cc[VMIN]  = 1;

#ifndef HAVE_TERMIOS
   ioctl(line_fd, TCSETA, &tty);
#else
   tcsetattr(line_fd, TCSANOW, &tty);
#endif
}

void r_line()
{
   set_mode(0);
   if(!got_line) return;
#ifndef HAVE_TERMIOS
   ioctl(line_fd, TCSETA, &line_save);
#else
   tcsetattr(line_fd, TCSANOW, &line_save);
#endif
}

set_mode(which)

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -