00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032 #ifdef HAVE_CONFIG_H
00033 #include "config.h"
00034 #endif
00035
00036 #ifdef HAVE_STDIO_H
00037 #include <stdio.h>
00038 #else
00039 #error need stdio.h
00040 #endif
00041
00042 #ifdef HAVE_STRING_H
00043 #include <string.h>
00044 #else
00045 #error need string.h
00046 #endif
00047
00048 #ifdef HAVE_MATH_H
00049 #include <math.h>
00050 #else
00051 #error need math.h
00052 #endif
00053
00054
00055 #include "Exception.h"
00056 #include "Source.h"
00057 #include "Sink.h"
00058 #include "Util.h"
00059 #include "IceCast2.h"
00060
00061
00062
00063
00064
00065
00066
00067
00068
00069
00070 static const char fileid[] = "$Id: IceCast2.cpp,v 1.11 2005/04/11 18:32:32 darkeye Exp $";
00071
00072
00073
00074
00075
00076 #define STRBUF_SIZE 32
00077
00078
00079
00080
00081
00082 static const char responseOK[] = "HTTP/1.0 200";
00083
00084
00085
00086
00087
00088
00089
00090
00091
00092
00093 void
00094 IceCast2 :: init ( StreamFormat format,
00095 const char * mountPoint,
00096 const char * description )
00097 throw ( Exception )
00098 {
00099 this->format = format;
00100 this->mountPoint = Util::strDup( mountPoint);
00101 this->description = description ? Util::strDup( description) : 0;
00102 }
00103
00104
00105
00106
00107
00108 void
00109 IceCast2 :: strip ( void ) throw ( Exception )
00110 {
00111 delete[] mountPoint;
00112 if ( description ) {
00113 delete[] description;
00114 }
00115 }
00116
00117
00118
00119
00120
00121 bool
00122 IceCast2 :: sendLogin ( void ) throw ( Exception )
00123 {
00124 Sink * sink = getSink();
00125 Source * source = getSocket();
00126 const char * str;
00127 char resp[STRBUF_SIZE];
00128 unsigned int len;
00129 unsigned int lenExpected;
00130
00131 if ( !source->isOpen() ) {
00132 return false;
00133 }
00134 if ( !sink->isOpen() ) {
00135 return false;
00136 }
00137
00138
00139
00140 str = "SOURCE /";
00141 sink->write( str, strlen( str));
00142 str = getMountPoint();
00143 sink->write( str, strlen( str));
00144 str = " HTTP/1.0";
00145 sink->write( str, strlen( str));
00146
00147
00148 str = "\nContent-type: ";
00149 sink->write( str, strlen( str));
00150 switch ( format ) {
00151 case mp3:
00152 str = "audio/mpeg";
00153 break;
00154
00155 case oggVorbis:
00156 str = "application/ogg";
00157 break;
00158
00159 default:
00160 throw Exception( __FILE__, __LINE__,
00161 "unsupported stream format", format);
00162 break;
00163 }
00164 sink->write( str, strlen( str));
00165
00166
00167 str = "\nAuthorization: Basic ";
00168 sink->write( str, strlen(str));
00169 {
00170
00171 char * source = "source:";
00172 const char * pwd = getPassword();
00173 char * tmp = new char[Util::strLen(source) +
00174 Util::strLen(pwd) + 1];
00175 Util::strCpy( tmp, source);
00176 Util::strCat( tmp, pwd);
00177 char * base64 = Util::base64Encode( tmp);
00178 delete[] tmp;
00179 sink->write( base64, strlen(base64));
00180 delete[] base64;
00181 }
00182
00183
00184 str = "\nUser-Agent: DarkIce/" VERSION " (http://darkice.sourceforge.net/)";
00185 sink->write( str, strlen( str));
00186
00187
00188 str = "\nice-bitrate: ";
00189 sink->write( str, strlen( str));
00190 if ( log10(getBitRate()) >= (STRBUF_SIZE-2) ) {
00191 throw Exception( __FILE__, __LINE__,
00192 "bitrate does not fit string buffer", getBitRate());
00193 }
00194 sprintf( resp, "%d", getBitRate());
00195 sink->write( resp, strlen( resp));
00196
00197 str = "\nice-public: ";
00198 sink->write( str, strlen( str));
00199 str = getIsPublic() ? "1" : "0";
00200 sink->write( str, strlen( str));
00201
00202 if ( getName() ) {
00203 str = "\nice-name: ";
00204 sink->write( str, strlen( str));
00205 str = getName();
00206 sink->write( str, strlen( str));
00207 }
00208
00209 if ( getDescription() ) {
00210 str = "\nice-description: ";
00211 sink->write( str, strlen( str));
00212 str = getDescription();
00213 sink->write( str, strlen( str));
00214 }
00215
00216 if ( getUrl() ) {
00217 str = "\nice-url: ";
00218 sink->write( str, strlen( str));
00219 str = getUrl();
00220 sink->write( str, strlen( str));
00221 }
00222
00223 if ( getGenre() ) {
00224 str = "\nice-genre: ";
00225 sink->write( str, strlen( str));
00226 str = getGenre();
00227 sink->write( str, strlen( str));
00228 }
00229
00230 str = "\n\n";
00231 sink->write( str, strlen( str));
00232 sink->flush();
00233
00234
00235 lenExpected = Util::strLen( responseOK);
00236 if ( (len = source->read( resp, STRBUF_SIZE-1)) < lenExpected ) {
00237 return false;
00238 }
00239 resp[lenExpected] = 0;
00240 if ( !Util::strEq( resp, responseOK) ) {
00241 return false;
00242 }
00243
00244
00245 while ( source->canRead( 0, 0) &&
00246 (len = source->read( resp, STRBUF_SIZE-1)) );
00247
00248 return true;
00249 }
00250
00251
00252
00253
00254
00255
00256
00257
00258
00259
00260
00261
00262
00263
00264
00265
00266
00267
00268
00269
00270
00271
00272
00273
00274
00275
00276
00277
00278
00279
00280
00281
00282
00283
00284
00285
00286
00287
00288
00289
00290
00291
00292
00293
00294
00295