SemiGlobals.hpp

00001 /*********************************************************************** 00002 * * 00003 * ViTooKi * 00004 * * 00005 * title: SemiGlobals.hpp (S H A R E D) * 00006 * * 00007 * * 00008 * * 00009 * ITEC institute of the University of Klagenfurt (Austria) * 00010 * http://www.itec.uni-klu.ac.at * 00011 * * 00012 * * 00013 * For more information visit the ViTooKi homepage: * 00014 * http://ViTooKi.sourceforge.net * 00015 * vitooki-user@lists.sourceforge.net * 00016 * vitooki-devel@lists.sourceforge.net * 00017 * * 00018 * This file is part of ViTooKi, a free video toolkit. * 00019 * ViTooKi is free software; you can redistribute it and/or * 00020 * modify it under the terms of the GNU General Public License * 00021 * as published by the Free Software Foundation; either version 2 * 00022 * of the License, or (at your option) any later version. * 00023 * * 00024 * This program is distributed in the hope that it will be useful, * 00025 * but WITHOUT ANY WARRANTY; without even the implied warranty of * 00026 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * 00027 * GNU General Public License for more details. * 00028 * * 00029 * You should have received a copy of the GNU General Public License * 00030 * along with this program; if not, write to the Free Software * 00031 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, * 00032 * MA 02111-1307, USA. * 00033 * * 00034 ***********************************************************************/ 00035 00036 /*********************************************************************** 00037 * * 00038 * REVISION HISTORY: * 00039 * * 00040 * * 00041 * * 00042 ***********************************************************************/ 00043 00044 /*********************************************************************** 00045 * Video Session Migration System, 2004 * 00046 * Author: Klaus Schoeffmann * 00047 ************************************************************************/ 00048 00049 00050 #ifndef __SemiGlobals_hpp__ 00051 #define __SemiGlobals_hpp__ 00052 00053 #include <string> 00054 #include <sstream> 00055 #include <fstream> 00056 #include <iostream> 00057 #include <vector> 00058 #include <map> 00059 #include <math.h> 00060 00061 #ifdef WIN32 00062 #include <winsock2.h> 00063 #else 00064 #include <sys/time.h> 00065 #include <unistd.h> 00066 #include <time.h> 00067 #include <sys/time.h> 00068 #include <sys/socket.h> 00069 #include <netdb.h> 00070 #include <netinet/in.h> 00071 #include <unistd.h> 00072 #include <arpa/inet.h> 00073 #endif 00074 00075 00076 using namespace std; 00077 00078 00080 #define DEFAULT_RTSPSERVER_PORT 554 00081 00082 #define READLINE_MAXLEN 160 00083 00084 #define CONFIGFILE_MAXLEN 5000 00085 00086 #define USERNAME_MAXLEN 30 00087 00088 #define PASSWORD_MAXLEN 30 00089 00091 #define RTSP_NONE 0 00092 00093 #define RTSP_OPTIONS 1 00094 00095 #define RTSP_DESCRIBE 2 00096 00097 #define RTSP_SETUP 3 00098 00099 #define RTSP_PLAY 4 00100 00101 #define RTSP_PAUSE 5 00102 00103 #define RTSP_TEARDOWN 6 00104 00105 #define RTSP_GETPARAMETER 7 00106 00107 #define RTSP_SETPARAMETER 8 00108 00110 #define STATE_INIT 0 00111 00112 #define STATE_RUNNING 1 00113 00114 #define STATE_PAUSED 2 00115 00116 #define STATE_CLOSED 3 00117 00119 #define ACTION_MIGRATE 1 00120 00121 #define ACTION_COPY 2 00122 00123 #define ACTION_CONTINUE 3 00124 00126 #define LINK_RTSP 1 00127 00128 #define LINK_QTE 2 00129 00130 #define LINK_SDP 3 00131 00133 #define PROXY_SLEEP_USECS 20; 00134 00135 typedef unsigned int uint; 00136 typedef unsigned long ulong; 00137 00138 00139 00147 namespace semifunc { 00153 inline int replaceStr(std::string &str, char* val, char* newval, bool all = false) 00154 { 00155 //TODO: use replace() function !!! 00156 uint pos = str.find(val); 00157 uint lengthDiff = 0; 00158 while (pos != std::string::npos) { 00159 str.replace(pos, strlen(val), newval); 00160 lengthDiff += (strlen(val)-strlen(newval)); 00161 pos = str.find(val); 00162 if (!all) break; 00163 } 00164 return lengthDiff; 00165 }; 00166 00173 inline void replaceStr(std::string &str, uint from, uint to, char *newval) 00174 { 00175 //TODO: use replace() function !!! 00176 str.replace(from, to-from, newval, strlen(newval)); 00177 } 00178 00180 template <class Ch> 00181 inline std::string toString(Ch arg) 00182 { 00183 std::ostringstream os; 00184 os << arg; 00185 return os.str(); 00186 } 00187 00189 inline char* newStrCpy(char *from, uint length = 0) 00190 { 00191 if (length == 0) length = strlen(from); 00192 00193 char *tmp = new char[length+1]; 00194 strncpy(tmp, from, length); 00195 tmp[length] = 0; 00196 return tmp; 00197 } 00198 00200 inline char* getHostname() 00201 { 00202 //find out IP-Address of this host 00203 char *address = new char[255]; 00204 char name[255]; 00205 if (gethostname(name, sizeof(name)) == 0) { 00206 hostent *host = gethostbyname(name); 00207 if (host == NULL) { 00208 cerr << "semifunc::getHostname(): binding specific IP-addr, though no DNS-hostname resolution possible...\n"; 00209 strcpy(address,name); 00210 } else 00211 strcpy(address,inet_ntoa(*(reinterpret_cast<in_addr*>(host->h_addr))) ); 00212 } else { 00213 cerr << "semifunc::getHostname(): cannot get hostname!!!\n"; 00214 return NULL; 00215 } 00216 00217 return address; 00218 } 00219 00220 00222 inline char* formatTime(ulong msecs) 00223 { 00224 ostringstream timeFormat; 00225 msecs /= 1000; 00226 00227 /*double secsD60 = ceil((double)msecs/(double)60); 00228 double secsD3600 = ceil((double)msecs/3600);*/ 00229 uint secsD60 = msecs/60; 00230 uint secsD3600 = msecs/3600; 00231 00232 00233 uint hour = (uint)secsD3600 % 24; 00234 uint minute = (uint)secsD60 % 60; 00235 uint second = msecs % 60; 00236 00237 if (hour < 10)timeFormat << "0" << hour << ":"; 00238 else timeFormat << hour << ":"; 00239 if (minute < 10)timeFormat << "0" << minute << ":"; 00240 else timeFormat << minute << ":"; 00241 if (second < 10)timeFormat << "0" << second; 00242 else timeFormat << second; 00243 00244 return (char*)(timeFormat.str().c_str()); 00245 } 00246 00248 inline char* formatTimeSecs(ulong secs) 00249 { 00250 ostringstream timeFormat; 00251 00252 double secsD60 = ceil((double)secs/(double)60); 00253 double secsD3600 = ceil((double)secs/3600); 00254 00255 uint hour = (uint)secsD3600 % 24; 00256 uint minute = (uint)secsD60 % 60; 00257 uint second = secs % 60; 00258 00259 if (hour < 10)timeFormat << "0" << hour << ":"; 00260 else timeFormat << hour << ":"; 00261 if (minute < 10)timeFormat << "0" << minute << ":"; 00262 else timeFormat << minute << ":"; 00263 if (second < 10)timeFormat << "0" << second; 00264 else timeFormat << second; 00265 00266 return (char*)(timeFormat.str().c_str()); 00267 } 00268 00270 inline char* convertToString(ulong msecs) 00271 { 00272 float fmsecs = (float)msecs/1000; 00273 char *smsecs = new char[15]; 00274 sprintf(smsecs, "%.3f000", fmsecs); 00275 return smsecs; 00276 } 00277 00278 00286 inline string createSDPFile(string name, string url, string relpath, string abspath) 00287 { 00288 string fname (abspath + name + ".sdp"); 00289 00290 ofstream ofile (fname.c_str(), ios::out | ios::trunc); 00291 if (ofile) 00292 { 00293 ofile << "v=0" << "\r\n"; 00294 ofile << "s=" << name << "\r\n"; 00295 ofile << "a=control:" << url <<"\r\n"; 00296 ofile.close(); 00297 } else { 00298 cerr << "no success!!!" << endl; 00299 } 00300 00301 return relpath + name + ".sdp"; 00302 } 00303 00304 }; 00305 00306 00307 00308 00316 class SemiDebug 00317 { 00319 ofstream outfile; 00322 vector<string> log; 00324 char *logfile; 00326 bool stdOutEnabled; 00328 bool shouldFlush; 00329 00330 public: 00332 SemiDebug(char *logfilename = NULL); 00334 ~SemiDebug(); 00335 00337 void enableStdOut(); 00339 void enableFlush(); 00342 void doFlush(); 00344 void writeLogfile(); 00346 void writeTimestamp(char *str); 00347 00348 00353 SemiDebug& operator << (unsigned int n); 00358 SemiDebug& operator << (int n); 00363 SemiDebug& operator << (long n); 00368 SemiDebug& operator << (unsigned long n); 00373 SemiDebug& operator << (float f); 00378 SemiDebug& operator << (double d); 00383 SemiDebug& operator << (char c); 00388 SemiDebug& operator << (char *str); 00393 SemiDebug& operator << (const char *str); 00398 SemiDebug& operator << (string &str); 00399 }; 00400 00401 00402 00403 00412 class Globals 00413 { 00415 static bool initialized; 00417 static map<char*,char*> config; 00419 static map<char*,char*> configDesc; 00420 00421 public: 00423 Globals () {}; 00425 static void initialize(); 00427 static string getCGIPath(); 00429 static char* getProxyComHost(); 00431 static int getProxyComPort(); 00433 static char *getConfigFilePath(); 00435 static char* getMoviesFileName(); 00437 static char* getAbsoluteImagesFilePath(); 00439 static char* getRelativeImagesFilePath(); 00441 static char* getMediaserverHttpHost(); 00443 static int getMediaserverHttpPort(); 00445 static char* getRelativeSDPFilePath(); 00447 static char* getAbsoluteSDPFilePath(); 00449 static uint getHoursToPreserveClosedSessions(); 00451 static uint getPRMaxWaitSecs(); 00452 00454 static SemiDebug sdebug; 00456 static bool loadConfiguration(char *filename); 00458 static void readConfigValues(char *buffer); 00460 static void loadDefaultConfiguration(); 00462 static void writeConfiguration(char *filename); 00464 static void showCurrentConfiguration(); 00465 }; 00466 00467 00474 namespace html { 00475 00479 inline string warning(string val) 00480 { 00481 string str = "<br><font class=\"warning\">WARNING: "; 00482 str.append(val); 00483 str.append("</font>"); 00484 00485 return str; 00486 } 00487 00488 00490 inline string getHTMLHeader() 00491 { 00492 string hdr = "Content-type: text/html\n\n" 00493 "<html><head><title>Videostream Migration System, (c) by KS 2004</title>" 00494 "<style type=\"text/css\">" 00495 "table.background {" 00496 " background-color:white;" 00497 " border-style:solid;" 00498 " border-width:1px;" 00499 " border-color:#000000;" 00500 " text-align:center;" 00501 "}" 00502 "body, td, .profileinfo, input, textarea, select, td {" 00503 " font-family: Verdana;" 00504 " font-size: 12px;" 00505 "}" 00506 "a, a:visited {" 00507 " color: #0000FF;" 00508 "}" 00509 "input, textarea, select {" 00510 " color: #002F68;" 00511 "}" 00512 "body {" 00513 " scrollbar-arrow-color: #253BC0;" 00514 " scrollbar-base-color: #B2C2D7;" 00515 " scrollbar-track-color: #D0D7E1;" 00516 " scrollbar-highlight-color: #002F68;" 00517 " scrollbar-3dlight-color: #D0D7E1;" 00518 " scrollbar-darkshadow-color: #D0D7E1;" 00519 " scrollbar-shadow-color: #002F68;" 00520 " background-color:#ECF1F7;" 00521 "}" 00522 "font.copyright {" 00523 " font-size:10px;" 00524 "}" 00525 "font.warning {" 00526 " color: #FF0000;" 00527 "}" 00528 "font.error {" 00529 " color: #FF0000;" 00530 " font-weight: bold;" 00531 "}" 00532 "td.menu {" 00533 " background-color: #EAEAEA;" 00534 "}" 00535 "td.copyright {" 00536 " background-color: #F7F7F7;" 00537 " border-top-style: solid;" 00538 " border-top-width: 1px;" 00539 " border-top-color: #000000;" 00540 "}" 00541 ".profileinfo {" 00542 " width:80%;" 00543 " background-color:#FFFFCC;" 00544 " border-style:solid;" 00545 " border-width:1px;" 00546 " border-color:#CCCCCC;" 00547 "}" 00548 ".moviehdr {" 00549 " font-size: 12px;" 00550 " background-color:#F7F7F7;" 00551 " color: #000000;" 00552 "}" 00553 ".moviedesc {" 00554 " color: #AAAAAA;" 00555 " font-style: italic;" 00556 "}" 00557 ".activeSessions {" 00558 " background-color:#F7F7F7;" 00559 " border-style:solid;" 00560 " border-width:1px;" 00561 " border-color:#FF0000;" 00562 "}" 00563 ".darkblueborder {" 00564 " scrollbar-arrow-color: #FFFFFF;" 00565 " scrollbar-base-color: #B2C2D7;" 00566 " scrollbar-track-color: #D0D7E1;" 00567 " scrollbar-highlight-color: #002F68;" 00568 " scrollbar-3dlight-color: #D0D7E1;" 00569 " scrollbar-darkshadow-color: #D0D7E1;" 00570 " scrollbar-shadow-color: #002F68;" 00571 " border-style:solid;" 00572 " border-color:#002F68;" 00573 " border-width:1px;" 00574 "}" 00575 "</style>" 00576 "<script language=\"JavaScript\">" 00577 " function submitFormInWindow(formname) {" 00578 " form = document.forms[formname];" 00579 " win = window.open(\"about:blank\", formname, \"width=300,height=200,resizeable=yes\");" 00580 " form.submit();" 00581 " }" 00582 "</script></head>" 00583 "<body><center>" 00584 "\n<h3>Session Migration System</h3><br>\n"; 00585 00586 //status=yes,dependend=yes,menubar=yes, resizeable=yes 00587 00588 return hdr; 00589 } 00590 00592 inline string getMenu(char *currMenu, uint pageSize) 00593 { 00594 ostringstream str; 00595 if (pageSize == 1) str << "\n<table style=\"width:240px;\" cellspacing=\"5\" class=\"background\"><tr>"; 00596 else if (pageSize == 2) str << "\n<table style=\"width:480px;\" cellspacing=\"5\" class=\"background\"><tr>"; 00597 else if (pageSize == 3) str << "\n<table style=\"width:640px;\" cellspacing=\"5\" class=\"background\"><tr>"; 00598 00599 str << "\n <td width=\"50%\" class=\"menu\"><a href=\"../index.html\">Home</a></td>"; 00600 00601 str << "\n <td width=\"50%\" class=\"menu\"><a href=\"javascript:document.forms['refreshForm'].submit();\">Refresh</td>"; 00602 00603 str << "\n</tr><tr><td align=\"center\" colspan=\"4\">"; 00604 00605 return str.str(); 00606 } 00607 00608 00610 inline string getHTMLFooter(string refreshForm = "") 00611 { 00612 //string ftr = "\n<tr><td colspan=\"4\"><br><br></td></tr>" 00613 string ftr = "\n<tr><td class=\"copyright\" colspan=\"4\">" 00614 "<font size=\"1\">Created by Klaus Sch&ouml;ffmann,<br>University of Klagenfurt - ITEC, 2004</font>" 00615 "</td></tr></table>" + refreshForm + 00616 "</center></body></html>"; 00617 00618 00619 return ftr; 00620 } 00621 00623 inline void createPageSizeForm(string formheader, uint pageSize) 00624 { 00625 cout << formheader; 00626 cout << "Page size:<br>" << endl; 00627 cout << "<input type=\"radio\" name=\"pagesize\" value=\"1\""; 00628 if (pageSize == 1) cout << " checked "; 00629 cout << " onClick=\"document.forms['frmPageSize'].submit();\">" << endl; 00630 cout << "small"; 00631 cout << "<input type=\"radio\" name=\"pagesize\" value=\"2\""; 00632 if (pageSize == 2) cout << " checked "; 00633 cout << " onClick=\"document.forms['frmPageSize'].submit();\">" << endl; 00634 cout << "medium"; 00635 cout << "<input type=\"radio\" name=\"pagesize\" value=\"3\""; 00636 if (pageSize == 3) cout << " checked "; 00637 cout << " onClick=\"document.forms['frmPageSize'].submit();\">" << endl; 00638 cout << "large</form>"; 00639 } 00640 00644 inline void createQTEForm(string name, string uri, uint width, uint height) 00645 { 00646 cout << "\n<form name=\"" << name << "\" action=\"embedded.cgi\" method=\"post\" target=\"" << name << "\">" << endl; 00647 cout << "<input type=\"hidden\" name=\"uri\" value=\"" << uri << "\">" << endl; 00648 cout << "<input type=\"hidden\" name=\"width\" value=\"" << width << "\">" << endl; 00649 cout << "<input type=\"hidden\" name=\"height\" value=\"" << height << "\">" << endl; 00650 cout << "</form>"; 00651 } 00652 00654 inline string error(string val) 00655 { 00656 string str = "<br><font class=\"error\"><br>ERROR: "; 00657 str.append(val); 00658 str.append("</font>"); 00659 str.append(getHTMLFooter()); 00660 00661 return str; 00662 } 00663 00664 }; 00665 00666 00667 #endif