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

📄 service.c

📁 Modem通讯程序包
💻 C
📖 第 1 页 / 共 2 页
字号:
/* * $Id: service.c,v 1.30 1998/02/17 09:53:20 mdejonge Exp $ * *   $Source: /home/mdejonge/CVS/projects/modem/modemd/service.c,v $ * $Revision: 1.30 $ *    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 <time.h>#include <sys/types.h>#include <sys/ioctl.h>#if HAVE_SYS_WAIT_H#include <sys/wait.h>#endif#include <unistd.h>#include <errno.h>#include <stdio.h>#include <signal.h>#include <stdlib.h>#include <string.h>#include <setjmp.h>#include <libtty/libtty.h>#include <libtcpip/libtcpip.h>#include <libport/libport.h>#ifndef WEXITSTATUS#define WEXITSTATUS(stat_val) ((unsigned)(stat_val) >> 8 )#endif#ifndef WIFEXITED#define WIFEXITED(stat_val) (((stat_val) & 256) == 0 )#endif/* for connectStr and speedStr */#define USE_MODEM_REPLY#include <libmodem/libmodem.h>#include <libconf/libconf.h>#include <liberror/liberror.h>#include <libprotocol/libprotocol.h>#include <modem_defs.h>#include "log.h"#include "syscmd.h"#include "configuration.h"static void serviceSignalHandler( int );static void serviceExit( void );static void serviceModem2Client( void );static void serviceClient2Modem( protType, void*, size_t );static void serviceMainLoop( void );static void serviceCommandHandler( protType, void*, size_t );static void serviceSetup( const char*, const char*, int );static void serviceErrorFunc( const char* err );static void serviceDial( const char* );static void serviceHangup();static char serviceReadModem( void /*int, void*, size_t */);static int  serviceCheckNumber( void );struct{   int    modem;            /* Modem device */   int    allocated;        /* 0/1: no modem has/has not been alocated */   int    client;           /* Socket */   int    connected;        /* 0=not connected, 1=connected */   char*  remoteHost;       /* Name of host connected to us */   char*  remoteUser;       /* Name of user connected to us */   char*  localHost;        /* Name of host server is running on */   char*  number;           /* Phone number to dial */   time_t connected_since;  /* Time the modem connection started */} Data;static char buf[protBufSize];static jmp_buf saved_env;/* * Fork and start handling client on remote host */void handle_client( int sock, const char* host, const char* uName ){   /* Setup the service and start the event loop */   serviceSetup( host, uName, sock );   serviceMainLoop();}/* * Allocate and initialize modem device. * Save information about connection and do some other stuff. */static void serviceSetup( const char* host, const char* uName, int socket ){   char tmp[40];   struct sigaction act;   int    result;      /* Asure clean exit */   atexit( serviceExit );      /* Start new session and become session leader */   if( setsid() == -1 )   {      FAIL( "setsid" );      exit( 1 );   }   /* Save remoteHost, remoteUser and local hostname */   gethostname( tmp, sizeof tmp );   Data.localHost  = strdup( tmp );   Data.remoteHost = strdup( host );   Data.remoteUser = strdup( uName );   /* no modem allocated yet */   Data.allocated = 0;    /* Initial value for modem file desc */   Data.modem = -1;   /* Start in disconnected state */   Data.connected = 0;   /* Save fdesc of client */   Data.client = socket;      /* Allocate new modem device defined in MODEM_CONFIG_FILE and in    * configuration file as: modem_config_file. Modem device becomes    * our controlling terminal.    */   Data.modem = ttyOpen( get_modem_config_file() );   if( Data.modem == -1 )   {      if( protRequestConfirm( Data.client, PROT_REQUEST_FAILED ) < 0 )      {         FAIL( "protRequestConfirm" );         exit( 1 );      }      exit( 0 );   }#if defined(TIOCSTTY) && !defined(CIBAUD)         /*          * 4.3+BSD way to acquire controlling terminal          * !CIBAUD to avoid doing this under SunOS          * from Advanced Pogramming in the UNIX Environment          */         if( ioctl( Data.modem, TIOCSCTTY, NULL ) < 0 )         {            FAIL( "ioctl(TIOCSCTTY)" );            exit( 1 );         }#endif   /*     * Initialize and reset modem using configuration file    * MODEM_CONFIG_FILE or modem_config_file in configuration file    */   if( mdm_init( Data.modem, ttyDev(), get_modem_config_file() ) == -1 )   {      result =protRequestConfirm( Data.client, PROT_REQUEST_FAILED );      if( result < 0 )      {         FAIL( "protRequestConfirm" );         exit( 1 );      }      if( result == 0 )         exit( 0 );      FAIL( "modem init" );      exit( 1 );   }   /*     * Install protocol handlers for PROT_DATA and    * PROT_COMMAND events.    */   protSetHandler( PROT_DATA,    serviceClient2Modem );   protSetHandler( PROT_COMMAND, serviceCommandHandler );   sigemptyset( &act.sa_mask );   act.sa_handler = serviceSignalHandler;#ifdef SA_RESTART   act.sa_flags   = SA_RESTART;#endif   sigaction( SIGQUIT, &act, NULL );   sigaction( SIGTERM, &act, NULL );   sigaction( SIGHUP,  &act, NULL );   sigaction( SIGPIPE, &act, NULL );   /* Install correct error handler */   setErrorFunc( serviceErrorFunc );   Data.allocated = 1;   /* Write log message to access logfile */   fprintf( ACCESS_LOG, "%s[%s] Connect from: \"%s@%s\"\n",      timeStamp(),      Data.localHost,      Data.remoteUser,      Data.remoteHost );   fflush( ACCESS_LOG );   /* Modem allocated, we're now ready to serve our client */   result = protRequestConfirm( Data.client, PROT_REQUEST_OK );   if( result < 0 )   {      FAIL( "protRequestConfirm" );      exit( 1 );   }   if( result == 0 )      exit( 0 );}/* * Main eventhandler of service  */static void serviceMainLoop(){   int retval;   struct timeval timeout;   fd_set fds;   while( 1 )   {      /* Save state for non-local jump in serviceReadModem */      if( setjmp( saved_env ) == 1 )         /* Non-local jump: start over again */         continue;      /* Setup for select */      FD_ZERO( &fds );      FD_SET( Data.client, &fds );      /*        * Only add modem device to descriptor        * list when we are connected.       */      if( Data.connected )         FD_SET( Data.modem, &fds );            /* client timeout in minutes, not seconds */      timeout.tv_sec = CLIENT_TIMEOUT * 60;      timeout.tv_usec = 0;      TEMP_FAILURE_RETRY( retval,                           select( FD_SETSIZE, &fds, NULL, NULL, &timeout ) );      if( retval < 0 )      {         FAIL( "select" );         exit( 1 );      }      /*       * Timeout.       * User is not connected and didn't do anything for        * CLIENT_TIMEOUT seconds. Free modem resources and       * exit.       */      if( retval == 0 )      {         if( !Data.connected )         {            error( "you didn't do anything, bye" );            exit( 1 );         }         continue;      }      /*        * Data arrived from client. Let protocol       * routines handle this.       */      if( FD_ISSET( Data.client, &fds ) )      {         retval = protReceive( Data.client );         /* EOF reached, client has closed connection */         if( retval == 0 )         {            exit( 0 );         }         if( retval < 0 )         {            FAIL( "protReceive" );            exit( 1 );         }      }      /* Data arrived from modem */      if( FD_ISSET( Data.modem, &fds ) )         serviceModem2Client();   }}/* * Read data from modem and send it to client */static void serviceModem2Client(){   int bytes;   /* Read data from modem */   bytes = modemRead( Data.modem, buf, sizeof buf );   if( bytes < 0 )   {      FAIL( "modemRead" );      exit( 1 );   }   if( bytes == 0 )      exit( 0 );   /* Send data as PROT_DATA to client */   bytes = protSend( PROT_DATA, Data.client, buf, bytes );   /* EOF */   if( bytes == 0 )      exit( 0 );         if( bytes < 0 )   {      FAIL( "protSend" );      exit( 1 );   }}/*  * Protocol handler for PROT_DATA. * Just send the data to the modem. */static void serviceClient2Modem( protType type, void* data, size_t length ){   int bytes;   /* Only send to modem when we are connected */   if( !Data.connected )      return;   /* Send the data to modem */   bytes = modemWrite( Data.modem, data, length );   if( bytes < 0 )   {      FAIL( "modemWrite" );      exit( 1 );   }   if( bytes == 0 )      exit( 0 );}/* * Error handler * All errors are send as PROT_ERROR messages to client. */static void serviceErrorFunc( const char* err ){   int result;   struct sigaction saved;   struct sigaction act;   /*     * A SIGPIPE will normally terminate the program. We do not want    * the program to terminate without having sent the error message.    * We therefore ignore the signal. Writing the message when the

⌨️ 快捷键说明

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