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

📄 main.c

📁 Modem通讯程序包
💻 C
字号:
/* * $Id: main.c,v 1.14 1998/02/17 09:53:06 mdejonge Exp $ * *   $Source: /home/mdejonge/CVS/projects/modem/modemcontrol/main.c,v $ * $Revision: 1.14 $ *    Author: Merijn de Jonge *     Email: mdejonge@wins.uva.nl *  *   *  * This file is part of the modem communication package. * Copyright (C) 1996-1998  Merijn de Jonge *  * 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. *  *  */#ifdef HAVE_CONFIG_H#include <config.h>#endif#include <stdio.h>#include <fcntl.h>#include <errno.h>#include <unistd.h>#include <stdlib.h>#include <modem_defs.h>#ifdef HAS_GETOPT_H#include <getopt.h>#endifextern char* optarg;#include <signal.h>#include <string.h>#include <libui/libui.h>#include <libphonebook/libphonebook.h>#include <libtty/libtty.h>#include <libmclient/libmclient.h>#include <libtcpip/libtcpip.h>#include <libport/libport.h>#include "jobc.h"#define USAGE_MSG \  "modemcontrol (" ## VERSION ## ")\n"\  "usage:\n" \  "      modemcontrol [-toolkitoption ...] [-option ...] cmd\n" \  "\n" \  "where options include:\n"\  "     -e name      dial phone number from phone books entry name\n" \  "     -h           print out this message\n"\  "     -q           don't prompt for phone number when -e option\n"\  "                  is also given\n"\  "     -r           automatically redial when line is busy\n" \  "     -v           displays version information\n"\  "\n" \  "     cmd         command to execute after modem is connected\n"\  "\n"  #define VERSION_MSG \   "modemcontrol version " ## VERSION ## "\n"   static int modemDevice;static int ptyMasterDev;static int auto_retry = 0;static int auto_dial = 0;/* Is X interface already started */static int interface = 0;static int connected = 0;static char* localProgName = NULL;static char* phonenumber = NULL;static char* connectedTo = NULL;static char* opt_string = "e:hqrv";static void initStart( int argc, char* argv[] );static void initSetNumber( char* name );static void initSetProgram( char* program );static void getNumberStart();static void getNumberCancel();static void getNumberDone( char* number );static void dialStart();static void dialRetry();static void dialCancel();static void dialTimeout();static void dialDo();static void dialDone( char* );static void statusStart( char* );static void signalHandler( int sig );static void errorFromServer( protType, void*, size_t );static void readFromServer( protType, void*, size_t );static void replyFromServer( protType, void*, size_t );static void usage();static void version();static void modemcontrolExit();/*  * Signal handler * Catch SIGPIPE */static void signalHandler( int sig ){   switch( sig )   {      case SIGPIPE:         error( " \nBroken pipe,\n \nServer may have closed connection.\n" );         exit( 1 );         break;      case SIGINT:         exit( 1 );         break;    }}/* * Error handler */static void modemcontrolError( const char* msg ){   /* Use interface when possible to display error */   if( interface )      errorDialogPopup( (char*)msg );   else      fprintf( stderr, "ERROR: %s\n", msg );}/*  * Initialization  * Handle command line options */static void initStart( int argc, char* argv[] ){   int c;   while( 1 )   {      c = getopt( argc, argv, opt_string );      if( c == -1 )         break;      switch( c )      {         case 'e' :            /* use phonebook entry optarg */            initSetNumber( optarg );            break;         case 'h' :            usage();            exit( 0 );         case 'q' :            /* Start dialing when -e entry is also specified */            auto_dial = 1;            break;         case 'r' :            /* Auto retry dialing */            auto_retry = 1;            break;         case 'v' :            version();            exit( 0 );         default:            exit( 1 );            break;      }   }   if( argc == 1 )   {      usage();      exit( 1 );   }   initSetProgram( argv[ argc - 1] );}/*  * Dial number defined in phonebook entry name */static void initSetNumber( char* name ){   phonebook_entry entry;   phonebook* book;   int result;   book = phonebookOpen( PHONEBOOK );   if( book == NULL )      return;   result = phonebookGetEntryByName( book, &entry, name );   if( result )   {      /* Get number from phonebook entry */      if( entry.number != NULL )      {         phonenumber = strdup( entry.number );         connectedTo = name;      }   }   phonebookClose( book );}/*  * set program to execute when connected to program */static void initSetProgram( char* program ){   localProgName = strdup( program );}/* * Get phonenumber from user  */static void getNumberStart(){   dialDialogInfoRec info;   /* Set values in info rec */   info.number         = phonenumber;   info.cancelCallback = getNumberCancel;   info.dialCallback   = getNumberDone;   /* initialise dialog */   dialDialogInit( &info );   /* popup the dialog */   dialDialogPopup();   return;}/* * Cancel pressed  */static void getNumberCancel(){   exit( 0 );}/* * User entered number to dial  */static void getNumberDone( char* number ){   dialingDialogInfoRec info;   /* Set data in info rec */   info.number          = number;   info.timeout         = 60;   info.cancelCallback  = dialCancel;   info.timeoutCallback = dialTimeout;   info.retryCallback   = dialRetry;   /* initialise dialog */   dialingDialogInit( &info );   /* popup dialog */   dialingDialogPopup();   free( phonenumber );   phonenumber = strdup( number );   /* start dialing */   dialStart();}static void dialStart(){   dialDo();}/* * Retry button pressed */static void dialRetry(){   modemClientHangup();   /* restart dialing */   dialingDialogReset();   dialStart( phonenumber );}/* * cancel button pressed */static void dialCancel(){   modemClientHangup();   /* popdown the dialog */   dialingDialogPopdown();   /* start all over again */   getNumberStart();}/* * timed out  */static void dialTimeout(){   modemClientHangup();   /* time out */   errorDialogPopup( "Timeout" );         /* popdown the dialog */   dialingDialogPopdown();   /* start all over again */   getNumberStart( phonenumber );}/* * dial  */static void dialDo(){   modemClientDial( phonenumber );}/* * We are connected, */static void dialDone( char* bps ){   dialingDialogPopdown();/* Fire up the status dialog */   statusStart( bps );}/* * Read callback routine */static int doRead( int fd ){   static char buf[protBufSize];   int bytes = 0;   if( fd == modemDevice )   {      bytes = modemClientRead();      if( bytes < 0 )      {         FAIL( "modemClientRead" );         exit( 1 );      }      /* EOF */      if( bytes == 0 )         exit( 0 );   }   if( fd == ptyMasterDev )   {      /* read from pseudo terminal */      TEMP_FAILURE_RETRY( bytes, read( ptyMasterDev, buf, sizeof( buf ) ) );      if( bytes < 0 )      {         FAIL( "read pty" );         exit( 1 );      }      /* EOF */      if( bytes == 0 )         exit( 0 );      /* write to modem */      bytes = modemClientWrite( buf, bytes );      if( bytes == 0 )         exit( 0 );      if( bytes < 0 )      {         FAIL( "modemClientWrite" );         exit( 1 );      }   }   return bytes; }/* * Disconnect */static void disconnect(){   exit( 0 );}/* * Callback routine that returns the time we're connected */static time_t getTime(){   static time_t start;   static int firstTime = 1;   if( firstTime )   {      firstTime = 0;      time( &start );      return difftime( start, start );   }   else   {      time_t now;      time( &now );      return difftime( now, start );   }}/* * Popup the status dialog */static void statusStart( char* bps ){   statusDialogInfoRec info;   char ptySlaveDevName[20];   /*     * Remove inputhandler because input is handled by    * the status dialog.    */   interfaceRemoveInput( modemDevice );          /* Create pseudo terminal */   ptyMasterDev = openPtyMaster( ptySlaveDevName );   if( ptyMasterDev < 0 )   {      FAIL( "openPty" );      exit( 1 );   }   /* start new job that uses the modem */   jobControlNewJob( localProgName, ptySlaveDevName );   /* Set data in info rec */   info.fd1 = modemDevice;   info.fd2 = ptyMasterDev;   info.readCallback = doRead;   info.disconnectCallback = disconnect;   info.timeCallback = getTime;   info.connectSpeed = bps;    if( connectedTo != NULL )      info.connectedTo = connectedTo;   else      info.connectedTo  = phonenumber;      /* initialise dialog */   statusDialogInit( &info );   /* popup the dialog */   statusDialogPopup();}/* * Exit routine  */static void modemcontrolExit(){   static int busy = 0;   if( busy )      return;   busy++;   /* Kill all jobs */   jobControlKillJobs();   /* close pseudo terminal */   close( ptyMasterDev );   /* Close socket connection */   shutdown( modemDevice, 2 );      fprintf(stderr, "Bye\n" );}static void errorFromServer( protType type, void* data, size_t length ){   interfaceRemoveInput( modemDevice );      if( length > 0 )      error( (char*) data );   exit( 1 );}static void replyFromServer( protType type, void* data, size_t length ){   switch( protSubTypeOf( type ) )   {      case MDM_CONNECT:         dialDone( data );         connected = 1;         break;      case MDM_BUSY:         if( auto_retry )         {            dialingDialogReset();            dialStart( phonenumber );         }         else         {            dialingDialogPopdown();            errorDialogPopup( "Line is busy" );            getNumberStart( phonenumber );         }         break;      case MDM_NO_CARIER:         error( "No carrier." );         exit( 1 );      case MDM_NO_DIALTONE:         error( "No dial tone." );         exit( 1 );      case MDM_ERROR:         error( "Modem error." );         exit( 1 );      case MDM_NO_ANSWER:         error( "No answer." );         exit( 1 );      default:         error( "Unknown reply from modem server." );         exit( 1 );   }}static void readFromServer( protType type, void* data, size_t length ){   int bytes;   if( !connected )      return;   /* write to pseudo terminal */   TEMP_FAILURE_RETRY( bytes, write( ptyMasterDev, data, length ) );   if( bytes < 0 )   {      FAIL( "write pty" );      exit( 1 );   }   if( bytes == 0 )      exit( 0 );}static void usage(){   fprintf( stderr, USAGE_MSG );}static void version(){   fprintf( stdout, VERSION_MSG );}void main( int argc, char* argv[] ){   struct sigaction act;   char* modemd_server;      /*     * When environment variable "MODEM_SERVER" is set, it will    * be used to address the modem server. Otherwise the default    * address MODEM_SERVER will be used.    */   modemd_server = getenv( "MODEM_SERVER" );   if( modemd_server == NULL )      modemd_server = MODEM_SERVER;   /* Install exit routine */   atexit( modemcontrolExit );   /* set error handler */   setErrorFunc( modemcontrolError );   modemClientSetHandler( MODEM_DATA,  readFromServer );   modemClientSetHandler( MODEM_CMD_REPLY, replyFromServer );   modemClientSetHandler( MODEM_ERROR, errorFromServer );   /* Install signal handler */   sigemptyset( &act.sa_mask );   act.sa_handler = signalHandler;#ifdef SA_RESTART   act.sa_flags   = SA_RESTART;#endif   sigaction( SIGPIPE, &act, NULL );      sigaction( SIGINT, &act, NULL );      /* Initialise interface */   interfaceCreate( &argc, argv, "Modemcontrol" );   /* Handle command line options */   initStart( argc, argv );   /* Connect to server */   modemDevice = modemClientConnect( modemd_server );   if( modemDevice == -1 )   {      error( "No modems available" );      exit( 1 );   }   interfaceSetInput( modemDevice, protReceive );   /* Create dialogs */   dialDialogCreate();   dialingDialogCreate();   statusDialogCreate();   /* Initialise jobcontrol */   jobControlInit();   if( auto_dial == 1 && phonenumber != NULL )      getNumberDone( strdup( phonenumber ) );   else   /* Get phonenumber to dial */      getNumberStart();   interface = 1;   /* Start interface */   interfaceRun();}/* * EOF modemcontrol/main.c */

⌨️ 快捷键说明

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