Vegastrike 0.5.1 rc1  1.0
Original sources for Vegastrike Evolved
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
respawning_soundserver.cpp
Go to the documentation of this file.
1 #include <stdlib.h>
2 #include <stdio.h>
3 #include <sys/types.h>
4 #include <sys/wait.h>
5 #include <string>
6 
7 #include <vector>
8 
9 #include <fcntl.h>
10 #include <unistd.h>
11 #include "inet.h"
12 #include "inet_file.h"
13 #include "lin_time.h"
14 #include <sys/types.h>
15 #include <pwd.h>
16 using std::string;
17 //assumes null termination;
18 float fadein = 0;
19 float fadeout = 0;
20 float volume = 1;
21 bool scanChar( string s, char c, float &val )
22 {
23  char cc[2] = {c, 0};
24  string::size_type loc;
25  bool anyvalid = false;
26  while ( ( loc = s.find( cc ) ) != string::npos ) {
27  bool valid = (loc == 0);
28  if (!valid && loc > 0)
29  valid = ( (s[loc-1] == '\n') || (s[loc-1] == '\r') );
30  s = s.substr( loc+1 );
31  if (valid) {
32  sscanf( s.c_str(), "%f", &val );
33  anyvalid = true;
34  }
35  }
36  return anyvalid;
37 }
38 bool quit = false;
39 void ScanOptions( char *buf, int ammt )
40 {
41  string bleh( buf, ammt );
42  scanChar( bleh, 'i', fadein );
43  scanChar( bleh, 'I', fadein );
44  scanChar( bleh, 'O', fadeout );
45  scanChar( bleh, 'o', fadeout );
46  scanChar( bleh, 'v', volume );
47  scanChar( bleh, 'V', volume );
48  float test;
49  quit = scanChar( bleh, 't', test ) || scanChar( bleh, 'T', test );
50 }
51 bool ForwardBytes( int fd, int mysocket_write, char buf[65536] )
52 {
53  if ( INET_BytesToRead( fd ) ) {
54  int ammt = INET_Recv( fd, buf, 65535 );
55  if (ammt == 0 || ammt == -1)
56  return false;
57  buf[ammt] = 0;
58  fNET_Write( mysocket_write, ammt, buf );
59  ScanOptions( buf, ammt );
60  }
61  return true;
62 }
63 bool ForwardFileBytes( int mysocket_read, int fd )
64 {
65  char c;
66  if ( 1 == read( mysocket_read, &c, 1 ) ) {
67  printf( "recved bytes %c %d", c, (int) c );
68  int famt = INET_Write( fd, 1, &c );
69  if (famt != 1)
70  return false;
71  }
72  return true;
73 }
74 
75 bool current_client_dead( pid_t p )
76 {
77  int status = 0;
78  if ( !waitpid( p, &status, WNOHANG ) )
79  return false;
80  return true;
81 }
82 void changehome( bool, bool );
83 pid_t F0rkProcess( int close_this_socket, int &write, int &read )
84 {
85  char writer_str[65536];
86  writer_str[0] = 0;
87  char reader_str[65536];
88  reader_str[0] = 0;
89  {
90  char pwd[32768];
91  pwd[32766] = pwd[32767] = 0;
92  char reader[] = "myreadsocketXXXXXX";
93  char writer[] = "mywritsocketXXXXXX";
94  changehome( true, true );
95  write = mkstemp( writer );
96  int tmpread = mkstemp( reader );
97  getcwd( pwd, 32766 );
98  changehome( false, false );
99  strcat( pwd, "/" );
100  strcpy( writer_str, pwd );
101  strcpy( reader_str, pwd );
102  strcat( writer_str, writer );
103  strcat( reader_str, reader );
104  read = open( reader_str, O_RDONLY|O_SHLOCK|O_TRUNC, 0xffffffff );
105  close( tmpread );
106  }
107  pid_t retval = fork();
108  if (retval) {
109  char mystr[8192];
110  sprintf( mystr, "i%f\r\no%f\r\nv%f\r\n", fadein, fadeout, volume );
111  fNET_Write( write, strlen( mystr ), mystr ); //don't write null
112  return retval;
113  }
114  close( read );
115  close( write );
116  close( close_this_socket );
117  execlp( "./soundserver.child", "./soundserver.child", writer_str, reader_str, NULL );
118  //trashed!
119 }
120 int main( int argc, char **argv )
121 {
122  char buf[65536];
123  INET_startup();
124  int fd = -1;
125  int mysocket_read = -1;
126  int mysocket_write = -1;
127  for (int i = 0; i < 10 && fd == -1; i++) {
128  int port = 4364;
129  if (argc > 1) port = atoi( argv[1] );
130  fd = INET_AcceptFrom( port, "localhost" );
131  }
132  if (fd == -1)
133  return 1;
134  bool done = false;
135  while (!done && !quit) {
136  pid_t mypid = F0rkProcess( fd, mysocket_write, mysocket_read );
137  while ( (!done) && ( !current_client_dead( mypid ) ) ) {
138  done = !ForwardBytes( fd, mysocket_write, buf );
139  if (!done)
140  done = !ForwardFileBytes( mysocket_read, fd );
141  micro_sleep( 50000 );
142  }
143  char c = 'e';
144  INET_Write( fd, 1, &c );
145  }
146  INET_cleanup();
147  return 0;
148 }
149 
150 void changehome( bool to, bool linuxhome = true )
151 {
152  static std::vector< std::string >paths;
153  if (to) {
154  char mycurpath[8192];
155  getcwd( mycurpath, 8191 );
156  mycurpath[8191] = '\0';
157  paths.push_back( mycurpath );
158 #ifndef _WIN32
159  if (linuxhome) {
160  struct passwd *pwent;
161  pwent = getpwuid( getuid() );
162  chdir( pwent->pw_dir );
163  }
164 #endif
165  mkdir( ".vegastrike", 0xffffffff );
166  chdir( ".vegastrike" );
167  } else if ( !paths.empty() ) {
168  chdir( paths.back().c_str() );
169  paths.pop_back();
170  }
171 }
172