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

📄 service.c

📁 Modem通讯程序包
💻 C
📖 第 1 页 / 共 2 页
字号:
    * connection has been closed by the remote site will now result    * in an error, in which case we send the message to stderr.    */   sigaction( SIGPIPE, NULL, &saved );   sigaction( SIGPIPE, NULL, &act );       act.sa_handler = SIG_IGN;   sigaction( SIGPIPE, &act, NULL );   /* Send message to client (inc. terminating '\0') */   result = protSend( PROT_ERROR, Data.client, err, strlen( err ) + 1 );   /*     * Send to remote site failed. Perhaps remote site has closed    * connection we send the error message to stderr instead.    */   if( result <= 0 )   {      fprintf( stderr, "%s\n", err );   }   /* Restore SIGPIPE */   sigaction( SIGPIPE, &saved, NULL );}   /* * Protocol handler for PROT_COMMAND * According to the subtype of the protocol message, * dial a number or hangup the modem */static void serviceCommandHandler( protType type, void* data, size_t length ){   switch( protSubTypeOf( type ) )   {      case MDM_DIAL:          /* Dial a number; data contains number */         serviceDial( data );         break;      case MDM_HANGUP:         /* Hangup the modem */         serviceHangup();         break;      case MDM_EXIT:         /* Quit */         exit( 0 );            }}static void serviceSignalHandler( int sig ){   switch( sig )   {      case SIGPIPE:         exit( 0 );      case SIGQUIT:      case SIGTERM:         exit( 1 );      case SIGHUP:         /* Modem hangup */         /* No more writes to modem device */         Data.modem = -1;         /* Inform user */         error( "Modem disconnected, exiting!" );         exit( 0 );   }}/* * Exit routine */static void serviceExit(){   static int exiting = 0;   /*     * In error situations, it can happen that    * this routine gets called recursively. So    * we need a sort of semaphore to assure that    * serviceHangup and mdm_reset are called just     * once.    */   if( exiting == 0 )   {      /* Set semaphore */      exiting++;      /* Hangup the modem */      if( Data.connected )         serviceHangup();          /* Only do the following when a modem was allocated */      if( Data.allocated == 1 )      {         /*          * Write a message to the acces log indicating the disconnection          * of the client. When no modem was allocated we forget this user          */         fprintf( ACCESS_LOG, "%s[%s] Disconnect from: \"%s@%s\"\n",            timeStamp(),            Data.localHost,              Data.remoteUser,             Data.remoteHost );         fflush( ACCESS_LOG );      }            /* Reset modem device and terminal unless Data.modem is invalid        * after SIGHUP has been received.       */      if( Data.modem != -1 )      {         /* Reset the modem */         mdm_reset( Data.modem );                  ttyReset();         ttyHangup();      }            /* Close and unlock modem device */      ttyClose();      shutdown( Data.client, 2 );      if( close( Data.client ) == -1 )      {         FAIL( "close" );         exit( 1 );      }      closeLog();      }}/* * This routine checks whether a user/host is allowed  * to dial a number. * The routine executes a program (VERIFY_NUMBER or as defined in * configuration file as verify_number) that * actually does the check. * * The program is executed with the following arguments: * * argv:       0              1            2         3 *       VERIFY_NUMBER   remoteUser   remoteHost   number * * where VERIFY_NUMBER is the name of the program. * The program should return 0 when the user has permission * to dial the number and 1 otherwise. * * Function return: *   1   The user does not have permission to dial the number, *   0   The user does have permission. * */static int serviceCheckNumber( void ){   int retval;   /*     * Execute VERIFY_NUMBER script    */   retval = sys_cmd( get_verify_number(),                     Data.remoteUser,                     Data.remoteHost,                     Data.number,                     NULL );   if( retval == -1 )   {      FAIL1( "sys_cmd", get_verify_number() );      exit( 1 );   }   /* Abnormal termination */   if( !WIFEXITED( retval ) )      exit( 1 );   if( WIFEXITED( retval ) )      return  WEXITSTATUS( retval );   return 1;}   /*  * This routine dials a phonenumber. */static void serviceDial( const char* number ){   int result;   /* If already connected, first disconnect */   if( Data.connected )      serviceHangup();   /* Save number to dial */   Data.number = strdup( number );   /* Check if user has permission to dial the number */   if( serviceCheckNumber() == 1)   {      error( "No permission to dial %s", number );      exit( 1 );   }   /* Dial the number */   mdm_dial( Data.modem, number );   /* Wait on any reply from the modem */   result = matchText( connectStr, MATCH_ALL, serviceReadModem );   switch( result )   {       /* CONNECT */      case 0:          /* Save current time */            time( &Data.connected_since );         /* We're connected now */         Data.connected = 1;         /* We are connected, get connectspeed from modem */         result = matchText( speedStr, MATCH_ALL, serviceReadModem );         /* Send speed as PROT_REPLY to client */         result = protSend( PROT_REPLY | MDM_CONNECT, Data.client,                      speedStr[result],                      strlen( speedStr[result] ) + 1 );         /* Result is evalutated below */         break;      /* NO CARRIER */      case 1:         result =             protSend( PROT_REPLY | MDM_NO_CARIER, Data.client, NULL, 0 );         /* Result is evalutated below */         break;      /* NO DIALTONE */      case 2:         result =             protSend( PROT_REPLY | MDM_NO_DIALTONE, Data.client, NULL, 0 );         /* Result is evalutated below */         break;      /* ERROR */      case 3:         result =             protSend( PROT_REPLY | MDM_ERROR, Data.client, NULL, 0 );         /* Result is evalutated below */         break;      /* NO ANSWER */      case 4:         result =            protSend( PROT_REPLY | MDM_NO_ANSWER, Data.client, NULL, 0 );         /* Result is evalutated below */         break;      /* BUSY */      case 5:         result =             protSend( PROT_REPLY | MDM_BUSY, Data.client, NULL, 0 );         /* Result is evalutated below */         break;      default:         error( "UNKNOWN result: %d", result );         exit( 1 );   }   /* result value of protSend is evaluated here */   /* EOF */   if( result == 0 )      exit( 0 );   /* Error */   if( result < 0 )   {      FAIL( "protSend" );      exit( 1 );   }}/* * Hangup the modem and write a log message to * ACCOUNT_LOG * The log message is as follows: * * remoteUser@remoteHost,modemDevice,number,localHost,[startTime],[endTime] * */static void serviceHangup(){   char       buf[100];   struct tm* tm;   /* Hangup modem deice, unless Data.modem is invalid after    * SIGHUP has been received.    */   if( Data.modem != -1 )      mdm_hangup( Data.modem );   /* No log message when not connected */   if( !Data.connected )      return;   tm = localtime( &Data.connected_since );   strftime( buf, sizeof(buf), "[%c]", tm );   fprintf( ACCOUNT_LOG, "%s@%s,%s,%s,%s,%s,%s\n",      Data.remoteUser,      Data.remoteHost,      ttyDev(),      Data.number,      Data.localHost,      buf,      timeStamp()      );   fflush( ACCOUNT_LOG );   /* We're not connected anymore */   Data.connected = 0;}/* * Function that reads a character from modem. * This function is used by matchText * * This function will be interrupted when data from * the client arrives. In that case, the function  * longjumps to the loop in serviceMainLoop(). *  * By doing so, the process does not block when waiting * for input from the modem. * */static char serviceReadModem(){   int retval;   char c;   fd_set fds;   /* Make set of descriptors */   FD_ZERO( &fds );   FD_SET( Data.modem,  &fds );   FD_SET( Data.client, &fds );   /* Wait on input on any of the descriptors in fds */   TEMP_FAILURE_RETRY( retval,                      select( FD_SETSIZE, &fds, NULL, NULL, NULL ) );   if( retval == -1 )   {      FAIL( "select" );      exit( 1 );   }   /* Input arrived from client, longjump tp serviceMainLoop() */   if( FD_ISSET( Data.client, &fds ) )   {      longjmp( saved_env, 1 );   }   /*     * Data ready from modem, we can no savely     * read that data and return.    */   TEMP_FAILURE_RETRY( retval, read( Data.modem, &c, 1 ) );   if( retval < 0 )   {      FAIL( "read" );      exit( 1 );   }   if( retval == 0 )   {      exit( 0 );   }   /* Send data as PROT_DATA to client */   retval = protSend( PROT_DATA, Data.client, &c, 1 );   if( retval == 0 )      exit( 0 );   if( retval < 0 )   {      FAIL( "protSend" );      exit( 1 );   }   return c;}/* * EOF modemd/service.c */

⌨️ 快捷键说明

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