parse_command.cc
上传用户:psq1974
上传日期:2007-01-06
资源大小:1195k
文件大小:6k
源码类别:

mpeg/mp3

开发平台:

C/C++

  1. /* Copyright (C) 1998, 1999 State University of New York at Stony Brook
  2.    Author: Andrew V. Shuvalov ( andrew@ecsl.cs.sunysb.edu )
  3.    Software license is located in file "COPYING"
  4. */
  5. #include <stdio.h>
  6. #include <errno.h>
  7. #if HAVE_UNISTD_H
  8. #include <unistd.h>
  9. #endif
  10. #include <stdlib.h>
  11. #include <sys/types.h> 
  12. #include <sys/stat.h>
  13. #include <fcntl.h> 
  14. #include "sockaddr.h"
  15. #include "vpusher.h"
  16. #include "../../client/src/play_commands.h"
  17. //#define DEBUG
  18. void Appl::parse_command( const char *cmd, const Sockaddr &addr )
  19. {
  20.   const static int maxCommandLength = 100;
  21.   istrstream input( cmd );
  22.   string command;
  23.   command.resize( maxCommandLength );
  24.   // first line contains only the command
  25.   input.getline( ( char *)command.data(), maxCommandLength );
  26.   trim_string( command );
  27.   
  28.   // find the handler
  29.   commandsMapT::iterator it = commandsMap.find( command );
  30.   if( it == commandsMap.end() ) // sorry
  31.     {
  32.       log( 1, "Unknown command: %s", cmd );
  33. #     ifdef DEBUG
  34.       log( 1, "known commands:" );
  35.       for( it = commandsMap.begin(); it != commandsMap.end(); it++ )
  36. log( 3, "%s", (*it).first.c_str() );
  37. #     endif
  38.       return;
  39.     }
  40.   log( 3, "command: %s", cmd );
  41.   
  42.   // i'm sorry, guys, it's c++. Sometimes it looks very strange :-)
  43.   (this->*(*it).second)( input, addr );
  44. }
  45. void Appl::play_impl( istrstream &input, const Sockaddr &addr )
  46. {
  47.   cout << "play" << endl;
  48.   
  49.   if( users.find( addr ) != users.end() ) { // old user, delete old job
  50.     RemoteUser &user = *users[ addr ];
  51.     user.cleanup_jobs( inusedBuffers );
  52.   }
  53.   else {
  54.     users[ addr ] = new RemoteUser( addr );    // new
  55.     cout << "new user, addr " << addr << endl;
  56.   }
  57.   RemoteUser &user = *users[ addr ];
  58.   assert( user.jobs.empty() );
  59.   // read remote port to push data to
  60.   int remoteportnum;
  61.   string s;
  62.   s.resize( 100 );
  63.   input.getline( (char *) s.c_str(), 100 );
  64.   sscanf( s.c_str(), "%d", &remoteportnum );
  65.   // read time from where to play
  66.   s.resize( 100 );
  67.   input.getline( (char *) s.c_str(), 100 );
  68.   cout << "time to start" << s.c_str() << endl;
  69.   struct tm firstt;
  70.   STRTOTIME( s.c_str(), firstt );
  71.   bool firstFile = true;
  72.   while( input ) 
  73.     {
  74.       // add new job
  75.       JobElem newJob( user, input, firstFile, firstt );
  76.       firstFile = false;
  77.       if( !newJob.valid() ) // error
  78. break;
  79.       user.jobs.push( newJob );
  80.     }
  81.   // reset this user sequence number
  82.   user.sequence = 0;
  83.   // create output socket and
  84.   user.outputSocket = socket( PF_INET, SOCK_DGRAM, 0 );
  85.   if( -1 == user.outputSocket )
  86.     {
  87.       perror( "socket " );
  88.       return;
  89.     }
  90.   // connect to port number, that we got as argument
  91.   struct sockaddr_in saddr;
  92.   saddr.sin_family = AF_INET;
  93.   saddr.sin_port = htons( remoteportnum );
  94.   saddr.sin_addr = user.socketAddr.addr.sin_addr;
  95.   if( -1 == connect( user.outputSocket, 
  96.      (struct sockaddr *) &saddr, sizeof( saddr )))
  97.     {
  98.       perror( "connect " );
  99.       return;
  100.     }
  101.   // first load event
  102.   Event le( Event::load );
  103.   le.userSocketAddr = user.socketAddr;
  104.   le.when.now();
  105.   eventQueue.push( le );
  106.   // and just after first send event
  107.   Event se( Event::send );
  108.   se.userSocketAddr = user.socketAddr;
  109.   se.when = le.when;
  110.   se.when.tv_usec() += 100;
  111.   eventQueue.push( se );
  112.   log( 1, "play to user identified as %s, destination port %d, job size %d",
  113.        user.socketAddr.get_description().c_str(), remoteportnum, 
  114.        user.jobs.size() );
  115. }
  116. void Appl::stop_impl( istrstream &input, const Sockaddr &addr )
  117. {
  118.   if( users.find( addr ) == users.end() ) 
  119.     {
  120.       // nothing to do
  121.       return;
  122.     }
  123.   RemoteUser &user = *users[ addr ];
  124.   user.cleanup_jobs( inusedBuffers );
  125. }
  126. void Appl::setfilename_impl( istrstream &input, const Sockaddr &addr )
  127. {
  128.   // the filename
  129.   videoFileName.resize( MAX_PATH );
  130.   input.getline( (char *) videoFileName.c_str(), MAX_PATH );
  131.   videoFileName.resize( strlen( videoFileName.c_str() ) + 1 );
  132.   // open the file
  133.   if( videoFileHandle != -1 )
  134.     close( videoFileHandle );
  135.   log( 1, "Open new filename %s", videoFileName.c_str() );
  136.   videoFileHandle = open( videoFileName.c_str(),
  137.   O_WRONLY | O_CREAT | O_TRUNC, 0660 );
  138.   if( videoFileHandle == -1 )
  139.     {
  140.       // first reason: path do not exists
  141.       int pos = 0;
  142.       while( true )
  143. {
  144.   // from the next character
  145.   pos = videoFileName.find( '/', pos + 1 );
  146.   if( pos == -1 )
  147.     break;
  148.   string path = videoFileName.substr( 0, pos );
  149.   path.reserve( path.length() + 1 );
  150.   //   vvv   is that really needed?  vvv
  151.   *(char*)( path.c_str() + path.length() ) = ''; 
  152.   if( -1 == mkdir( path.c_str(), 0770 ))
  153.     {
  154.       // if mkdir fails that's fine, directory may exists
  155.       log( 2, "can't create dir %s, %s", path.c_str(),
  156.    sys_errlist[ errno ] );
  157.     }
  158. }
  159.       // the try to open again...
  160.       videoFileHandle = 
  161. open( videoFileName.c_str(),O_WRONLY | O_CREAT | O_TRUNC, 0660 );
  162.     }
  163.   if( videoFileHandle == -1 )
  164.     {
  165.       log( 0, "can't open new file, %s", sys_errlist[ errno ] );
  166.       perror( "open" );
  167.       videoFileHandle = -1;
  168.       return;
  169.     }
  170. }
  171. void Appl::stoprecording_impl( istrstream &cmd, const Sockaddr &addr )
  172. {
  173.   if( videoFileHandle != -1 )
  174.     close( videoFileHandle );
  175.   videoFileHandle = -1;
  176.   videoFileName = "";
  177. }
  178. void Appl::accept_stream_impl( istrstream &input, const Sockaddr &addr )
  179. {
  180.   // no parameters - push server should know the port number from environment
  181.   bindAcceptWaitSocket();
  182. }
  183. void Appl::add_broadcast_destination_impl
  184. ( istrstream &input, const Sockaddr &addr )
  185. {
  186.   // get the IP address or host name
  187.   string s_addr;
  188.   s_addr.resize( 100 );
  189.   input.getline( (char *) s_addr.c_str(), 100 );
  190.   trim_string( s_addr );
  191.   // and the port number
  192.   string s_port;
  193.   s_port.resize( 10 );
  194.   input.getline( (char *) s_port.c_str(), 10 );
  195.   trim_string( s_port );
  196.   int portnum = 0;
  197.   sscanf( s_port.c_str(), "%d", &portnum );
  198.   if( !portnum )
  199.     return;
  200.   Sockaddr broadcast_dest_addr( s_addr, portnum );
  201.   // add broadcast to user: this is special user, which broadcasts
  202.   if( broadcast_user == NULL )
  203.     {
  204.       log( 0, "Strong error: broadcast_user is zero" );
  205.       return;
  206.     }
  207.   broadcast_user->add_broadcast_channel( broadcast_dest_addr );
  208. }
  209. void Appl::trim_string( string &s )
  210. {
  211.   char ch;
  212.   int pos;
  213.   s.c_str();
  214.   for( pos = 0, ch = s[0]; ch == ' ' || ch == 't'; pos ++ )
  215.     ch = s[pos];
  216.   if( pos > 0 )
  217.     {
  218.       s = s.substr( pos );
  219.     }
  220.   for( pos = s.length() - 1, ch = s[pos]; ch == ' ' || ch == 't'; pos -- )
  221.     ch = s[pos];
  222.   s.resize( strlen( s.c_str() ));
  223.   if( pos < s.length() - 1 )
  224.     {
  225.       s = s.substr( 0, pos );
  226.     }
  227.   s.c_str();
  228. }