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

📄 vmcp.c

📁 控制语音Modem的程序
💻 C
📖 第 1 页 / 共 2 页
字号:
/*----------------------------------------------------------------------*//* vmcp		Voice Modem Control Program.				*//*		A little program to send commands to the modem		*//*		with special features for voice modems.			*//*									*//* Version	0.6.1		Jul 14 1999				*//*									*//* Author:	Niccolo Rigacci <fd131@cleveland.freenet.edu>		*//*									*//* Copyright (C) 1996-1999 Niccolo Rigacci				*//*									*//* 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.					*//*									*//* This program is distributed in the hope that it will be useful,	*//* but WITHOUT ANY WARRANTY; without even the implied warranty of	*//* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the	*//* GNU General Public License for more details.				*//* 									*//* You should have received a copy of the GNU General Public License	*//* along with this program; if not, write to the Free Software		*//* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.		*//*----------------------------------------------------------------------*/#include <stdio.h>#include <stdlib.h>#include <errno.h>#include <fcntl.h>#include <getopt.h>#include <signal.h>#include <string.h>#include <linux/termios.h>#include <unistd.h>#include <sys/file.h>#include <sys/stat.h>#include <sys/types.h>#include <sys/time.h> /*----------------------------------------------------------------------*//* Macro definitions/*----------------------------------------------------------------------*//* DLE			Escape char for voice mode.			*//* BREAK_KEY		Break key for -k switch.			*//* MAX_LEN_FNAME	Max len for filename strings.			*//* TEMP_DIR		Where to put the lock file.			*//* DEVS_DIR		Where modem devices are.			*//* DFLT_DEV		Default modem device.				*//* DEV_NULL		Black-hole file.				*//* HDB_LCK_FORMAT	Format string for printing PID in HDB lockfile.	*//* HDB_LCK_LEN		Len of HDB lockfile.				*/#define TRUE		1#define FALSE		0#define DLE		16#define BREAK_KEY	27#define MAX_LEN_FNAME	255#define TEMP_DIR	"/tmp/"#define DEVS_DIR	"/dev/"#define DFLT_DEV	"ttyS0"#define DEV_NULL	"/dev/null"#define HDB_LCK_FORMAT	"%10d\n"#define HDB_LCK_LEN	11#define EXIT_OK		0#define EXIT_TIMEOUT	100#define EXIT_KEYPRESS	101#define ERR_MEMORY	150#define ERR_SYNTAX	151#define ERR_DEVICE	152#define ERR_OPEN	153#define ERR_WRITE	154#define ERR_CLOSE	155#define ERR_LOCK	156#define ERR_IOCTL	157#define ERR_LCKFILE	158#define ERR_BAUDRATE	159#define ERR_SIGNAL	200/*----------------------------------------------------------------------*//* Function prototypes/*----------------------------------------------------------------------*/int out_chr(int c);int out_esc(int c);void no_response(int i);void end_on_signal(int i);void fatal(int exit_code);char *strdupcvt(char *str);void safeprint(char *msg, char *str);void port_reset(int fd);/*----------------------------------------------------------------------*//* Global variables/*----------------------------------------------------------------------*/struct termios ts;			/* Saved stdin line settings	*/int debug = FALSE;			/* Be verbose			*/int timeout = 5;			/* Seconds to wait		*/int break_on_key = FALSE;		/* Return on keypress		*/int escaping_dle = FALSE;		/* Handle escaping of DLE	*/int make_lock_file = FALSE;		/* Must create lock file	*/int made_lock_file = FALSE;		/* Lock file created		*/int changed_std_input = FALSE;		/* Std input settings changed	*/int quit_on_eof = FALSE;		/* Return on end of input file	*/int skip_out_string = FALSE;		/* Do not output the -W string	*/FILE *inp_fp;				/* Input file pointer		*/FILE *out_fp;				/* Output file pointer		*/FILE *esc_fp;				/* Escape file pointer		*/unsigned char *lckfname = NULL;		/* Name of the lock file	*/unsigned char *command = NULL;		/* Command to send		*/unsigned char *out_string = NULL;	/* String to wait		*/unsigned char *esc_string = NULL;	/* Escape chars to wait		*/int out_len;				/* Len of out_string		*/int out_pos = 0;			/* Index to scan out_string	*/int ok_exit_code;			/* Exit code if OK (0 - 99)	*/long baud_rate;				/* Baud rate of serial line	*//*----------------------------------------------------------------------*//* Main program/*----------------------------------------------------------------------*/int main(int argc, char **argv)   {   int i, c, fd, opt;   int eof_inp = TRUE;   int finito = FALSE;   int reset_port = FALSE;   int previous_dle = FALSE;   int sent_one_dle = FALSE;   unsigned char pid_buf[HDB_LCK_LEN + 1];   unsigned char filename[MAX_LEN_FNAME + 1];   unsigned char *inp_file, *out_file, *esc_file;   unsigned char *device;   unsigned char buf;   struct termios new_ts;   fd_set rfds;   pid_t pid;   /* Set default values for some strings. */   inp_file = out_file = esc_file = DEV_NULL;   device = DFLT_DEV;   /* Process command line arguments */   while ((opt = getopt(argc, argv, "c:d:eghi:kl:o:qs:t:w:W:x:z:")) != -1)      {      switch (opt)         {         case 'e':            escaping_dle = TRUE; break;         case 'g':            debug = TRUE; break;         case 'k':            break_on_key = TRUE; break;         case 'q':            quit_on_eof = TRUE; break;         case 'c':            if ((command = strdupcvt(optarg)) == NULL) fatal(ERR_MEMORY);            break;         case 'd':            if ((device = strdup(optarg)) == NULL) fatal(ERR_MEMORY);            break;         case 'h':            fprintf(stderr, "Voice Modem Control Program\n");            fprintf(stderr, "Usage: %s [OPTION]...\n", argv[0]);            fprintf(stderr, "\t-c command\n\t-d device\n\t-e\n\t-g\n\t-h\n");            fprintf(stderr, "\t-i in_file\n\t-k\n\t-l lockfile\n");            fprintf(stderr, "\t-o out_file\n\t-q\n\t-s esc_file\n");            fprintf(stderr, "\t-t sec\n\t-w waitstring\n\t-W skipstring\n");            fprintf(stderr, "\t-x esc_string\n\t-z baudrate\n");            exit(0);            break;         case 'i':            if ((inp_file = strdup(optarg)) == NULL) fatal(ERR_MEMORY);            eof_inp = FALSE;            break;         case 'l':            if ((lckfname = strdup(optarg)) == NULL) fatal(ERR_MEMORY);            make_lock_file = TRUE; break;         case 'o':            if ((out_file = strdup(optarg)) == NULL) fatal(ERR_MEMORY);            break;         case 's':            if ((esc_file = strdup(optarg)) == NULL) fatal(ERR_MEMORY);            break;         case 't':            timeout = atoi(optarg); break;         case 'W':            skip_out_string = TRUE;         case 'w':            if ((out_string = strdupcvt(optarg)) == NULL) fatal(ERR_MEMORY);            out_len = strlen(out_string);            break;         case 'x':            if ((esc_string = strdup(optarg)) == NULL) fatal(ERR_MEMORY);            break;         case 'z':            baud_rate = atol(optarg);            reset_port = TRUE;            break;         default:            fprintf(stderr, "Try `vmcp -h' for help.\n");            fatal(ERR_SYNTAX);            break;         }      }   /* Set standard input line settings in non-canonical mode:	*/   /* no line buffering, no echo, no wait.			*/   if (break_on_key)      {      /* Get standard input (file descriptor 0) line settings. */      if (ioctl(0, TCGETS, &ts) != 0) fatal(ERR_IOCTL);      new_ts = ts;      new_ts.c_lflag &= ~ICANON;      new_ts.c_lflag &= ~ECHO;      new_ts.c_cc[VTIME] = 0;      new_ts.c_cc[VMIN] = 0;      if (ioctl(0, TCSETS, &new_ts) != 0) fatal(ERR_IOCTL);      changed_std_input = TRUE;      }   /* Set the timeout alarm. */   if (timeout != 0)      {      signal(SIGALRM, no_response);      alarm(timeout);      }   /* Set some signal handling functions. */   signal(SIGHUP, end_on_signal);   signal(SIGINT, end_on_signal);   signal(SIGQUIT, end_on_signal);   signal(SIGTERM, end_on_signal);   /* Open communication file device. */   sprintf(filename, "%s%s", DEVS_DIR, device);   if ((fd = open(filename, O_RDWR | O_NONBLOCK)) == -1) fatal(ERR_DEVICE);   if (flock(fd, LOCK_EX | LOCK_NB) != 0) fatal(ERR_LOCK);   if (reset_port)      {      if (debug) fprintf(stderr, "Resetting the serial line\n");      port_reset(fd);      }   /* Create lock file if required. Use HDB lockfile format:	*/   /* ten byte ASCII decimal number, with a trailing newline.	*/   if (make_lock_file)      {      pid = getpid();      sprintf(pid_buf, HDB_LCK_FORMAT, pid);      sprintf(filename, "%sTMP..%d", TEMP_DIR, pid);      /* Create a temp lock file and write PID to it. */      if ((i = creat(filename, 0644)) == -1) fatal(ERR_LCKFILE);      if (write(i, pid_buf, HDB_LCK_LEN) != HDB_LCK_LEN) fatal(ERR_LCKFILE);      if (close(i) != 0) fatal(ERR_LCKFILE);      /* Change name to the lock file. */      if (link(filename, lckfname) == 0) made_lock_file = TRUE;      unlink (filename);      if (!made_lock_file) fatal(ERR_LCKFILE);      }   /* Write command to communication file device. */   /* NOTE: no check is made for EAGAIN error, we */   /* suppose command string to be small enough   */   /* to fit entirely in the output buffer.       */   if (command != NULL)      {      /* Just paranoia: US-Robotic requires a pause	*/      /* of 1 ms before "AT" commands, we do 2 ms.	*/      if (strncmp(command, "AT", 2) == 0 || strncmp(command, "at", 2) == 0)         {         struct timeval tv;         tv.tv_sec = 0;         tv.tv_usec = 2000;         select(0, NULL, NULL, NULL, &tv);         }      if (debug) safeprint("Sending", command);      i = strlen(command);      if (write(fd, command, i) != i) fatal(ERR_WRITE);      }   else      if (debug && (out_string != NULL))         if (skip_out_string)            safeprint("Skipping", out_string);         else            safeprint("Waiting for", out_string);   /* Open input, output and escape files. */   if ((inp_fp = fopen(inp_file, "rb")) == NULL) fatal(ERR_OPEN);   if ((out_fp = fopen(out_file, "wb")) == NULL) fatal(ERR_OPEN);   if ((esc_fp = fopen(esc_file, "wb")) == NULL) fatal(ERR_OPEN);   /* Main loop to send input file to communication device's input */   /* and to capture output to output file. If escaping of DLE     */   /* char is enabled, escaped chars are sent to escape file.      */   while (!finito)      {      /* If "-i file" has more characters to send, do one. */      if (!eof_inp)         {         /* Write a char from "-i file" to device, escape DLE if required. */         if ((c = fgetc(inp_fp)) == EOF)            {            eof_inp = TRUE;            finito = quit_on_eof;            }         else            {            buf = (unsigned char)c;            if (write(fd, &buf, 1) == 1)               { /* No error, check for DLE escaping. */               if (buf == DLE && escaping_dle && !sent_one_dle)

⌨️ 快捷键说明

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