📄 main.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 + -