00001 // ----------------------------------------------------------------------^ 00002 // Copyright (C) 2004 -- 2011, Giorgio Calderone 00003 // (mailto: <gcalderone@ifc.inaf.it>) 00004 // 00005 // This file is part of MCS. 00006 // 00007 // MCS is free software; you can redistribute it and/or modify 00008 // it under the terms of the GNU General Public License as published by 00009 // the Free Software Foundation; either version 2 of the License, or 00010 // (at your option) any later version. 00011 // 00012 // MCS is distributed in the hope that it will be useful, 00013 // but WITHOUT ANY WARRANTY; without even the implied warranty of 00014 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00015 // GNU General Public License for more details. 00016 // 00017 // You should have received a copy of the GNU General Public License 00018 // along with MCS; if not, write to the Free Software 00019 // Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 00020 // 00021 // ----------------------------------------------------------------------$ 00022 00023 00024 00032 #ifndef DEF_MCS_HH 00033 #define DEF_MCS_HH 00034 00035 00036 //The symbol COMPILING_MCS is defined when we are compiling the MCS library 00037 #undef COMPILING_MCS 00038 #ifdef HAVE_CONFIG_H 00039 //We are compiling the MCS library 00040 #define COMPILING_MCS 00041 #else 00042 //We are compiling a MCS-based program 00043 #endif //HAVE_CONFIG_H 00044 00045 00046 00047 //We need the following includes only when compiling the MCS library 00048 #ifdef COMPILING_MCS 00049 //-------------------------------------------------------------------- 00050 //System's library include 00051 00052 //Portability with old libc 00053 // LN 00054 #ifndef __APPLE__ 00055 #include <wait.h> 00056 #endif 00057 00058 #include <sys/stat.h> 00059 #include <math.h> 00060 #include <stdint.h> 00061 #include <stdarg.h> 00062 #include <dirent.h> 00063 #include <pthread.h> 00064 #include <errno.h> 00065 #include <arpa/inet.h> 00066 #include <net/if.h> 00067 #include <sys/ioctl.h> 00068 #include <sys/time.h> 00069 #include <sys/types.h> 00070 #include <sys/socket.h> 00071 #include <netdb.h> 00072 #include <fcntl.h> 00073 00074 //Portability with old libc 00075 #include <unistd.h> 00076 00077 #include <fstream> 00078 #endif //COMPILING_MCS 00079 00080 00081 //The following include is necessary for some network related type 00082 #include <netinet/in.h> 00083 00084 00085 //The following includes are probably needed by user programs, so we 00086 //include them here instead of in the "COMPILING_MCS" section. 00087 #include <string> 00088 #include <iostream> 00089 #include <vector> 00090 using namespace std; 00091 00092 //#include <stdlib.h> 00093 #include <cstdlib> 00094 00095 00096 00097 00098 00099 //-------------------------------------------------------------------- 00100 //MCS configuration file. 00101 #include "mcs_config.h" 00102 00103 00104 00105 #if ENABLE_MYSQL 00106 //-------------------------------------------------------------------- 00107 //MySQL include, this will be needed by user programs until the 00108 //"mysql_stmt_param_metadata" function is available. 00109 #include <mysql.h> 00110 #define MYSQL_SOCK NULL 00111 00112 #else 00113 //If MySQL facilities are disabled we need the following declaration to 00114 //compile correctly. 00115 #define MYSQL_BIND char 00116 #define my_bool bool 00117 00118 //This has been copied from MySQL's include file mysql_time.h 00119 typedef struct st_mysql_time 00120 { 00121 unsigned int year, month, day, hour, minute, second; 00122 } MYSQL_TIME; 00123 #endif //ENABLE_MYSQL 00124 00125 00126 00127 //OpenSSL include 00128 #ifdef HAVE_OPENSSL_SSL_H 00129 #include <openssl/ssl.h> 00130 #include <openssl/err.h> 00131 #endif //HAVE_OPENSSL_SSL_H 00132 00133 00134 00135 #ifdef COMPILING_MCS 00136 00137 //-------------------------------------------------------------------- 00138 //PCRE include 00139 #include <pcrecpp.h> 00140 #endif //COMPILING_MCS 00141 00142 00152 namespace mcs 00153 { 00154 00155 00156 00157 //-------------------------------------------------------------------- 00158 //MCS constants 00159 00161 #define MCS_DEFAULT_PORT 6523 00162 00163 00170 #define MCS_DEFAULTCHUNKSIZE 16384 00171 00172 00174 #define MCS_DEFAULT_MAX_USERS 100 00175 00176 00178 #define MCS_DEFAULT_CLIENT_TIMEOUT 10 * 60 * 1000 00179 // min sec msec 00180 00182 #define MCS_COMMBUFSIZE 1024 00183 00184 00185 00186 #define MCS_SSLCERT "mcscert.pem" 00187 #define MCS_SSLPRIV "mcspkey.pem" 00188 00189 //Grants constants 00190 #define MCS_GRANT_NO_GRANTS 0 00191 #define MCS_GRANT_LOGIN 1 00192 #define MCS_GRANT_SQL_SCRIPTS 2 00193 #define MCS_GRANT_SCRIPTS 4 00194 #define MCS_GRANT_QUERY 8 00195 #define MCS_GRANT_BATCH 16 00196 #define MCS_GRANT_GET 32 00197 #define MCS_GRANT_PUT 64 00198 #define MCS_GRANT_SYS 128 00199 #define MCS_GRANT_ADMIN 256 00200 #define MCS_GRANT_ALL 511 00201 00202 00204 #define MCS_BANNER "\nMy Customizable Server (MCS) ver. " PACKAGE_VERSION "\n" 00205 00206 00207 #define MCS_MISSING_COPY_CONSTRUCTOR(CLASS) \ 00208 CLASS(const CLASS&); 00209 00210 00211 #define MCS_MISSING_ASSIGNMENT_OPERATOR(CLASS) \ 00212 CLASS& operator=(const CLASS&); 00213 00214 00218 enum BufferFreeOnDestroy 00219 { 00220 AUTO_FREE, 00221 DONT_FREE 00222 }; 00223 00224 00225 00229 enum ThrowExceptions 00230 { 00231 DONT_THROW, 00232 THROW 00233 }; 00234 00235 00236 00237 00238 //-------------------------------------------------------------------- 00239 //Protocol Specification: 00240 00242 #define MCS_PRE "#" 00243 00245 #define MCS_SEP "|" 00246 00248 #define MCS_PROMPT_OK MCS_PRE "0--" 00249 00251 #define MCS_PROMPT_WARN MCS_PRE "0W-" 00252 00254 #define MCS_PROMPT_ERROR MCS_PRE "0E-" 00255 00256 00257 //Protocol messages and numeric identifiers 00258 #include <mcsmsg.hh> 00259 00260 //Protocol commands: (help lines MUST ends on column 93) 00261 00263 #define MCS_CMD_NOP "NOP" 00264 #define MCS_CMD_NOP_HELP "No operation (dummy) command." 00265 00266 00268 #define MCS_CMD_CLIENT_INFO "CLINFO" 00269 #define MCS_CMD_CLIENT_INFO_HELP "Return all client informations." 00270 00271 00273 #define MCS_CMD_USERNAME "USR" 00274 #define MCS_CMD_USERNAME_HELP "Supply user name.\n" \ 00275 "USR <user_name>" 00276 00278 #define MCS_CMD_PASSWORD "PWD" 00279 #define MCS_CMD_PASSWORD_HELP "Supply password.\n" \ 00280 "PWD <password>" 00281 00283 #define MCS_CMD_DBNAME "DBN" 00284 #define MCS_CMD_DBNAME_HELP "Supply application (database) name.\n" \ 00285 "DBN <application_name>" 00286 00287 00289 #define MCS_CMD_DBCONNECT "CON" 00290 #define MCS_CMD_DBCONNECT_HELP "Finalize the authentication process and log in.\n" \ 00291 "CON" 00292 00294 #define MCS_CMD_CLOSECLIENT "BYE" 00295 #define MCS_CMD_CLOSECLIENT_HELP "Close the session.\n" \ 00296 "BYE" 00297 00299 #define MCS_CMD_CID "CID" 00300 #define MCS_CMD_CID_HELP "Retrieve the Client identifier.\n" \ 00301 "CID" 00302 00303 00304 00309 #define MCS_CMD_RECORD "FETCH" 00310 #define MCS_CMD_RECORD_HELP "Retrieve the record at a specified position, or at\n" \ 00311 "current position (if none is specified) of the last\n" \ 00312 "query executed.\n" \ 00313 "FETCH [position]" 00314 00315 00316 #if ENABLE_MYSQL 00317 //Commands for DB access 00318 00320 #define MCS_CMD_QUERY "QRY" 00321 #define MCS_CMD_QUERY_HELP "Execute queries on the database.\n" \ 00322 "QRY <SQL query>" 00323 00325 #define MCS_CMD_SENDQUERYRES "QRES" 00326 #define MCS_CMD_SENDQUERYRES_HELP "Retrieve a file with an ASCII dump of the entire set\n" \ 00327 "of records returned by the last query." \ 00328 "QRES" 00329 00330 00332 #define MCS_CMD_TABLELIST "TLIST" 00333 #define MCS_CMD_TABLELIST_HELP "Retrieve the list of tables actually present in the\n" \ 00334 "database.\n" \ 00335 "TLIST" 00336 00338 #define MCS_CMD_TABLEINFO "TINFO" 00339 #define MCS_CMD_TABLEINFO_HELP "Retrieve information about a table.\n" \ 00340 "TINFO" 00341 #endif //ENABLE_MYSQL 00342 00343 00344 00345 00346 //Options (to be used with "-" like in a shell command) 00347 00348 00350 #define MCS_OPT_SAVEQUERYFITS "sqfits" 00351 #define MCS_OPT_SAVEQUERYFITS_HELP "Save query result in FITS format.\n " \ 00352 "-sqfits" 00353 00355 #define MCS_OPT_SAVEQUERYASCII "sqascii" 00356 #define MCS_OPT_SAVEQUERYASCII_HELP "Save query result in ASCII format.\n" \ 00357 "-sqascii" 00358 00359 00361 #define MCS_OPT_FORCE "force" 00362 #define MCS_OPT_FORCE_HELP "Continue execution of commands even if an error\n" \ 00363 "occurred.\n" \ 00364 "-force" 00365 00367 #define MCS_OPT_ALL_ERRORS "werr" 00368 #define MCS_OPT_ALL_ERRORS_HELP "Turns all warning into errors, so that a warning can\n" \ 00369 "stop the execution.\n" \ 00370 "-werr" 00371 00373 #define MCS_OPT_LOOP "loop" 00374 #define MCS_OPT_LOOP_HELP "Put a copy of thr recevied Data object in the \n" \ 00375 "\"send\" vector.\n" \ 00376 "-loop" 00377 00379 #define MCS_OPT_HELP "help" 00380 00381 00383 #define MCS_CMD_EXEC "EXEC" 00384 #define MCS_CMD_EXEC_HELP "Execute an external program, SQL or batch file.\n" \ 00385 "EXEC <alias> [[PAR1] [PAR2] ...]" 00386 00388 #define MCS_CMD_GET "GET" 00389 #define MCS_CMD_GET_HELP "Download a file from the work directory.\n" \ 00390 "GET <filename>" 00391 00393 #define MCS_CMD_PUT "PUT" 00394 #define MCS_CMD_PUT_HELP "Upload a file to the work directory.\n" \ 00395 "PUT <filename> <size>" 00396 00398 #define MCS_CMD_GETDATA "GDATA" 00399 #define MCS_CMD_GETDATA_HELP "Download Data objects.\n" \ 00400 "GDATA <position>" 00401 00403 #define MCS_CMD_PUTDATA "PDATA" 00404 #define MCS_CMD_PUTDATA_HELP "Upload Data objects.\n" \ 00405 "PDATA <size>" 00406 00407 00408 00409 00410 00411 //-------------------------------------------------------------------- 00412 //MCS enumerations 00413 00443 enum RetValue { 00444 OK, 00445 WARN, 00446 ERROR, 00447 FATAL 00448 }; 00449 00450 00451 #include "mcstypes.hh" 00452 00453 00454 //-------------------------------------------------------------------- 00455 //MCS macro facilities 00456 00458 #define csz c_str() 00459 00460 00462 #define my_mempcpy(D, S, N) ((void *) ((char *) memcpy (D, S, N) + (N))) 00463 00464 00465 00466 00467 //-------------------------------------------------------------------- 00468 //MCS utilities functions 00469 00471 #define MCS_SUBST_QUOTE_WITH 1 00472 00474 #define MCS_SUBST_LEADING 4 00475 00477 #define MCS_SUBST_TRAILING 8 00478 00487 string subst(string s, string what, string with, int op = 0); 00488 00489 00491 string trim(string s); 00492 00494 string chomp(string s); 00495 00497 string remTabs(string s); 00498 00500 string remLeading(string& s, const char* p); 00501 00503 string remTrailing(string& s, const char* p); 00504 00512 vector<string> split(string s, string sep = " "); 00513 00515 int extractCode(const char* msg); 00516 00525 bool File_Dir_Exist(string fn, unsigned int& size); 00526 00528 string itos(int i); 00529 00530 00540 int stoi(string s); 00541 00552 int stoi(string s, int errval); 00553 00554 00556 string btos(bool b); 00557 00559 string vtos(vector<string> vec); 00560 00562 string dtos(double f); 00563 00565 string Pwd(); 00566 00568 string hexDump(const void* buf, unsigned int size); 00569 00570 00571 #define MCS_MKDIR_UMASK 0 00572 #define MCS_MKDIR_PROTECT S_IRUSR | S_IWUSR | S_IXUSR 00573 00575 bool mkDir(string path, mode_t perm = 0, enum ThrowExceptions throwexc = THROW); 00576 00577 00579 mode_t read_umask(); 00580 00582 bool rmDir(string path, enum ThrowExceptions throwexc = THROW); 00583 00584 class Record; 00585 00587 void ls2Record(string fn, Record& v); 00588 00590 string Types2Str(Types type, bool isunsigned); 00591 00593 bool VarLenType(Types type); 00594 00596 bool IntType(Types type); 00597 00599 bool FloatType(Types type); 00600 00612 int copy(char* OLDNAME, char* NEWNAME); 00613 00627 int move(char* OLDNAME, char* NEWNAME); 00628 00629 00630 #if ENABLE_MYSQL 00632 string MYSQL2Str(enum_field_types type); 00633 00634 00642 bool MYSQL2Types(enum_field_types mtype, Types& type); 00643 00651 bool Types2MYSQL(Types& type, enum_field_types& mtype); 00652 00660 string Types2MYSQLStr(Types& type, bool isunsigned); 00661 00662 #endif //ENABLE_MYSQL 00663 00664 00665 #if ENABLE_CFITSIO 00666 00673 bool FITS2Types(int fits, Types& dbt, bool& isunsigned); 00674 00682 bool Types2FITS(Types dbt, bool isunsigned, int& fits); 00683 00691 bool Types2S_FITS(Types dbt, int len, bool isunsigned, string& fits); 00692 00693 00695 string fitsError(int status); 00696 #endif //ENABLE_CFITSIO 00697 00698 00699 00700 //-------------------------------------------------------------------- 00702 #define MCS_VMSG_SIZE 1000 00703 00786 class Event 00787 { 00788 private: 00790 string latFile; 00791 00793 int latLine; 00794 00796 char buf[MCS_COMMBUFSIZE]; 00797 00799 string lmsg; 00800 00802 int lcode; 00803 00805 int lsubcode; 00806 00808 RetValue ltype; 00809 00810 friend class UserThread; 00811 00813 static const char* vmsg[MCS_VMSG_SIZE]; 00814 00816 static void init_vmsg(); 00817 00819 static bool flInitialized; 00820 00821 void init(string atFile, unsigned int atLine, RetValue type, int code); 00822 00823 public: 00825 static void (*custom_init_vmsg) (const char* vmsg[MCS_VMSG_SIZE]); 00826 00840 Event(string atFile, unsigned int atLine, RetValue type, int code, 00841 string s1 = "", string s2 = "", string s3 = ""); 00842 00850 Event(string atFile, unsigned int atLine, RetValue type, int code, 00851 string s1, int i1); 00852 00860 Event(string atFile, unsigned int atLine, RetValue type, int code, 00861 int i1, string s1 = ""); 00862 00863 00871 Event(string atFile, unsigned int atLine, RetValue type, int code, 00872 int i1, int i2); 00873 00875 ~Event(); 00876 00878 string msg(); 00879 00881 string where(); 00882 00884 int code(); 00885 00887 int subcode(); 00888 00909 Event& subcode(int subcode); 00910 00913 string codemsg(); 00914 00916 string file(); 00917 00919 unsigned int line(); 00920 00922 RetValue type(); 00923 00925 static string static_vmsg(unsigned int i); 00926 }; 00927 00928 00930 #define MCS_OK(A, rest...) mcs::Event(__FILE__, __LINE__, mcs::OK, A, ## rest) 00931 00933 #define MCS_WARN(A, rest...) mcs::Event(__FILE__, __LINE__, mcs::WARN, A, ## rest) 00934 00936 #define MCS_ERROR(A, rest...) mcs::Event(__FILE__, __LINE__, mcs::ERROR, A, ## rest) 00937 00939 #define MCS_FATAL(A, rest...) mcs::Event(__FILE__, __LINE__, mcs::FATAL, A, ## rest) 00940 00942 #define MCS_(TYPE, rest...) mcs::Event(__FILE__, __LINE__, TYPE , ## rest) 00943 00944 00945 #ifndef DOXYGEN_SKIP 00946 //-------------------------------------------------------------------- 00947 //MCS macro facilities for debug, see also the Debug class 00948 #ifndef NOARGS 00949 #define NOARGS 00950 #endif //NOARGS 00951 00952 #define MCS_DEBUG_ALLOC 00953 #define MCS_DEBUG_SETUP(A, B) 00954 #define MCS_DEBUG(A) 00955 #define MCS_DEBUG_ENTER(A) 00956 #define MCS_DEBUG_LEAVE(A) 00957 00958 #if ENABLE_DEBUG 00959 #undef MCS_DEBUG_ALLOC 00960 #undef MCS_DEBUG_SETUP 00961 #undef MCS_DEBUG 00962 #undef MCS_DEBUG_ENTER 00963 #undef MCS_DEBUG_LEAVE 00964 00965 #define MCS_DEBUG_ALLOC Debug _debug_ 00966 #define MCS_DEBUG_SETUP(A, B) _debug_.setDebug(B, this, A) 00967 #define MCS_DEBUG(A) if (_debug_.getDebugFlag()) { cout << _debug_.debug(__FILE__, __LINE__, __FUNCTION__) << A << endl; } 00968 #define MCS_DEBUG_ENTER(A) MCS_DEBUG("-> " A); 00969 #define MCS_DEBUG_LEAVE(A) MCS_DEBUG("<- " A); 00970 00971 #define MCS_DEBUG_NTHR 100 00972 00973 class Debug 00974 { 00975 private: 00976 bool active; 00977 string className; 00978 void* pThis; 00979 00980 static pthread_t thrs[MCS_DEBUG_NTHR]; 00981 static bool thrmap[MCS_DEBUG_NTHR]; 00982 static int dummy; 00983 static int init(); 00984 00985 public: 00986 Debug(); 00987 ~Debug(); 00988 00989 string debug(const char* file, int line, const char* function); 00990 00991 void setDebug(string className, void* pthis = 0, bool active = false); 00992 void setDebug(); 00993 bool getDebugFlag(); 00994 }; 00995 #endif //ENABLE_DEBUG 00996 #endif //DOXYGEN_SKIP 00997 00998 00999 01000 01001 01002 01067 class Buffer { 01068 private: 01070 char* buf; 01071 01073 unsigned int bufsize; 01074 01076 enum BufferFreeOnDestroy freebuffer; 01077 01079 bool extbuffer; 01080 01082 bool select; 01083 01085 unsigned int wstart; 01086 01088 unsigned int wlen; 01089 01090 public: 01097 Buffer(enum BufferFreeOnDestroy freeBuffer = AUTO_FREE); 01098 01105 Buffer(void* extbuf, unsigned int size, 01106 enum BufferFreeOnDestroy freeBuffer = DONT_FREE); 01107 01114 MCS_MISSING_COPY_CONSTRUCTOR(Buffer); 01115 01116 01123 MCS_MISSING_ASSIGNMENT_OPERATOR(Buffer); 01124 01126 ~Buffer(); 01127 01128 01129 void set(void* extbuf, unsigned int size, enum BufferFreeOnDestroy freeBuffer); 01130 01131 01143 Buffer& operator()(unsigned int start, unsigned int len); 01144 01145 01154 Buffer& operator()(unsigned int len); 01155 01156 01165 Buffer& operator<<(const void* extbuf); 01166 01167 Buffer& operator<<(istream& stream); 01168 01178 Buffer& operator>>(void* extbuf); 01179 01180 Buffer& operator>>(ostream& stream); 01181 01182 operator void*() const { return buf; } 01183 01184 01186 char* operator[](unsigned int pos); 01187 01188 01196 void free(); 01197 01198 01214 void resize(unsigned int size); 01215 01217 unsigned int size(); 01218 }; 01219 01220 01221 01222 01223 01224 01225 01226 01227 01228 01229 01230 01231 01232 01233 01234 01235 01236 01237 #define MCS_SERIAL_UNKNOWN 0 01238 #define MCS_SERIAL_BUFFER 1 01239 #define MCS_SERIAL_FILENAME 2 01240 01241 //-------------------------------------------------------------------- 01242 //MCS Serializable class 01262 class Serializable 01263 { 01264 private: 01265 MCS_DEBUG_ALLOC; 01266 01268 char* buf; 01269 01271 unsigned int maxChunksize; 01272 01274 unsigned int lsize; 01275 01277 string filename; 01278 01280 int type; 01281 01283 char* from; 01284 01289 bool freeAfterUse; 01290 01292 ifstream* stream; 01293 01299 void init(int type, unsigned int lmaxChunksize); 01300 01301 char* userdata; //To be used with virtual_nextChunk 01302 01303 bool firstTime; //To be used with virtual_nextChunk 01304 01316 virtual char* nextChunk_unknown(char* userdata, char* buf, 01317 unsigned int& chunksize, bool firstTime); 01318 01319 virtual char* serialize_unknown(); 01320 01321 virtual bool serialize_buffer(char*& from, unsigned int& size); 01322 01323 virtual string serialize_filename(); 01324 01325 void serialize(); 01326 01327 void serialize_end(); 01328 01329 public: 01336 MCS_MISSING_COPY_CONSTRUCTOR(Serializable); 01337 01338 01345 MCS_MISSING_ASSIGNMENT_OPERATOR(Serializable); 01346 01353 Serializable(unsigned int lmaxChunksize = MCS_DEFAULTCHUNKSIZE); 01354 01355 01364 Serializable(void* from, unsigned int size, bool freeAfterUse, 01365 unsigned int lmaxChunksize = MCS_DEFAULTCHUNKSIZE); 01366 01367 01375 Serializable(string filename, unsigned int lmaxChunksize = MCS_DEFAULTCHUNKSIZE); 01376 01377 Serializable(int type, unsigned int lmaxChunksize = MCS_DEFAULTCHUNKSIZE); 01378 01382 virtual ~Serializable(); 01383 01384 01385 // /*! 01386 // \brief Fills a buffer with next chunk to be sent. 01387 // 01388 // \param chunksize Upon exit contains the size of the chunk. 01389 // \return Address of the buffer containing the chunk, or NULL if there are 01390 // no more data. 01391 // */ 01392 // char* fillBuffer(unsigned int& chunksize); 01393 01394 void* nextChunk(unsigned int& chunksize); 01395 01396 void* getEntireBuffer(unsigned int& size); 01397 01399 unsigned int maxChunkSize(); 01400 01401 01402 // /*! 01403 // \brief Reinitialize internal data. 01404 // 01405 // Reinitialize internal data, so that next call to fillBuffer() will read 01406 // data from the beginning of the buffer or the file. If type = 01407 // SERIAL_UNKNOWN the next call to fillBuffer will have firstTime = 01408 // true. 01409 // */ 01410 // void abort(); 01411 01412 01413 // /*! 01414 // \brief Tells if the object is in use. 01415 // 01416 // If a call to fillBuffer() has already be done, and data are not yet 01417 // finished this will return true. Otherwise return false. 01418 // */ 01419 // bool inUse(); 01420 01421 01429 bool knowSize(); 01430 01435 unsigned int nChunk(); 01436 01437 01442 unsigned int size(); 01443 }; 01444 01445 01446 01447 01448 01449 01450 01451 //-------------------------------------------------------------------- 01459 class NetInterface 01460 { 01461 protected: 01462 unsigned int lindex; 01463 01464 int req(int ioctl_num, struct ifreq *ifr); 01465 int getflags(); 01466 bool isup(); 01467 void str_sockaddr(struct sockaddr* sa); 01468 void str_sockaddr_in(struct sockaddr_in* sin); 01469 01471 vector<string> names; 01472 01473 public: 01488 NetInterface(string name = "lo"); 01489 01491 ~NetInterface(); 01492 01499 MCS_MISSING_COPY_CONSTRUCTOR(NetInterface); 01500 01506 MCS_MISSING_ASSIGNMENT_OPERATOR(NetInterface); 01507 01518 string name(int index = -1); 01519 01521 unsigned int index(); 01522 01524 unsigned int count(); 01525 01536 string ipaddress(int index = -1); 01537 }; 01538 01539 01540 01541 01542 01543 01544 01545 //-------------------------------------------------------------------- 01553 class HostInfo 01554 { 01555 protected: 01556 struct sockaddr_in sin; 01557 string host; 01558 string ipaddr; 01559 void populate_sockaddr_in(); 01560 01561 public: 01568 MCS_MISSING_COPY_CONSTRUCTOR(HostInfo); 01569 01575 MCS_MISSING_ASSIGNMENT_OPERATOR(HostInfo); 01576 01587 HostInfo(string host); 01588 01594 HostInfo(int sockfd); 01595 01597 ~HostInfo(); 01598 01600 string hostname(); 01601 01603 string ipaddress(); 01604 }; 01605 01606 01607 01608 01609 01610 01611 //-------------------------------------------------------------------- 01627 class Socket : public HostInfo 01628 { 01629 private: 01630 MCS_DEBUG_ALLOC; 01631 01633 int sockfd; 01634 01636 fd_set fds; 01637 01638 #ifdef HAVE_OPENSSL_SSL_H 01640 SSL_CTX* ssl_ctx; 01641 01643 SSL *ssl; 01644 01646 BIO *sbio; 01647 01648 void initialize_ssl_bio(string keyfile); 01649 #endif //HAVE_OPENSSL_SSL_H 01650 01652 unsigned short int port; 01653 01655 bool use_ssl; 01656 01658 struct timeval readto; 01659 01661 struct timeval writeto; 01662 01677 int socketToHost(unsigned short port); 01678 01679 01693 void sendChunk(void* buf, unsigned int size); 01694 01695 01711 unsigned int recvChunk(void* buf, unsigned int size); 01712 01718 unsigned int recvChunk(Buffer* buf); 01719 01720 protected: 01738 bool chkSend(enum ThrowExceptions throwexc = THROW); 01739 01740 01764 bool chkRecv(bool chkDataAvailable = false, enum ThrowExceptions throwexc = THROW); 01765 01766 01767 01768 01769 public: 01776 MCS_MISSING_COPY_CONSTRUCTOR(Socket); 01777 01783 MCS_MISSING_ASSIGNMENT_OPERATOR(Socket); 01784 01799 Socket(string host, unsigned short int port=0, 01800 unsigned int readTimeout = 1000, 01801 unsigned int writeTimeout = 1000, 01802 bool ssl = false); 01803 01804 01818 Socket(int sockfd, 01819 unsigned int readTimeout = 1000, 01820 unsigned int writeTimeout = 1000, 01821 void* ssl_ctx = NULL); 01822 01823 01830 ~Socket(); 01831 01833 void Close(); 01834 01841 static void set_struct_timeval(unsigned int millisec, struct timeval* time); 01842 01843 01858 unsigned int read(void* buf, unsigned int count); 01859 01860 01874 unsigned int write(void* buf, unsigned int count); 01875 01876 01887 string getline(); 01888 01889 01900 void print(string s); 01901 01902 01910 void sendData(Serializable* from); 01911 01912 01932 unsigned int recvData(char** buffer, unsigned int maxsize); 01933 01934 01944 unsigned int recvData(string filename); 01945 01954 unsigned int recvData(int filedes); 01955 01964 unsigned int recvData(ofstream& stream); 01965 }; 01966 01967 01968 01969 01970 01971 01972 //-------------------------------------------------------------------- 01981 class ServerSocket : public NetInterface 01982 { 01983 private: 01985 int sockfd; 01986 01988 bool use_ssl; 01989 01990 #ifdef HAVE_OPENSSL_SSL_H 01992 SSL_CTX* ssl_ctx; 01993 #endif //HAVE_OPENSSL_SSL_H 01994 01995 public: 02002 MCS_MISSING_COPY_CONSTRUCTOR(ServerSocket); 02003 02010 MCS_MISSING_ASSIGNMENT_OPERATOR(ServerSocket); 02011 02025 ServerSocket(string interface, unsigned short int port, 02026 bool use_ssl = false, string sslcert = "", string sslpriv = ""); 02027 02029 ~ServerSocket(); 02030 02043 bool acceptConnection(int& newsock, unsigned int millisec); 02044 02045 void* getSSLContext(); 02046 }; 02047 02048 02049 02050 02051 02052 //-------------------------------------------------------------------- 02153 class Synchro 02154 { 02155 private: 02156 MCS_DEBUG_ALLOC; 02157 02159 struct _pthread_cleanup_buffer _buf; 02160 02162 pthread_mutex_t mutex; 02163 02165 pthread_mutexattr_t attr; 02166 02168 int Count; 02169 02171 bool isActive; 02172 02173 public: 02180 MCS_MISSING_COPY_CONSTRUCTOR(Synchro); 02181 02188 MCS_MISSING_ASSIGNMENT_OPERATOR(Synchro); 02189 02199 Synchro(); 02200 02204 ~Synchro(); 02205 02216 void synchronize(bool setactive); 02217 02219 #define MCS_SYNCHRO_LOCK 1 02220 02222 #define MCS_SYNCHRO_TRY_LOCK 2 02223 02226 #define MCS_SYNCHRO_TRY_TIMED 3 02227 02261 bool enter(int op = MCS_SYNCHRO_LOCK, unsigned int timeout = 0); 02262 02265 bool tryenter(unsigned int timeout = 0); 02266 02268 int count(); 02269 02279 int leave(); 02280 02281 #ifdef ENABLE_CLEANUP_HANDLERS 02282 02290 static void CH_leave(void* This); 02291 #endif //ENABLE_CLEANUP_HANDLERS 02292 02294 // \brief Waits until some other thread locks and unlocks the same 02295 // Synchro object. 02296 // 02297 // The mutex MUST be locked before using wait() (with enter()) and unlocked 02298 // after this method returns (with leave()). 02299 // 02300 // When this method is called it immediately unlock the mutex, so 02301 // that another thread can lock it. 02302 // 02303 // If it return true then another thread has locked and unlocked the same 02304 // Synchro object, if it returns false a timeout occurred before other 02305 // threads can lock and unlock the mutex. in any case the mutex is now locked 02306 // by the current thread, so you have to unlock it with leave(). 02307 // 02308 // An example follows: 02309 // \code 02310 // ... 02311 // enter(); 02312 // bool b = wait(1000); //Leaving the critical section and wait 02313 // //for someone else to lock and unlock the 02314 // //same Synchro object, or a timeout of 1 02315 // //second occur. 02316 // 02317 // if (b) { //Another thread entered and leave a critical section 02318 // ... //Do some work 02319 // } 02320 // else { //A timeout occurred 02321 // ... 02322 // } 02323 // leave(); 02324 // \endcode 02325 // 02326 // \param timeout Timeout in millisecond. 02327 // \return False if a timeout or an interrupt occurred, true otherwise. 02328 //*/ 02330 }; 02331 02332 02335 #define MCS_CRITICAL_SECTION_BEGIN enter(); try { 02336 02337 02340 #define MCS_CRITICAL_SECTION_END } catch(Event e) { leave(); throw e; } leave(); 02341 02342 #define MCS_CRITICAL_SECTION_END_RETURN(What...) \ 02343 leave(); return What; } \ 02344 catch(Event e) { leave(); throw e; } 02345 02346 02353 #define MCS_CRITICAL_SECTION(BLOCK...) \ 02354 MCS_CRITICAL_SECTION_BEGIN \ 02355 BLOCK; \ 02356 MCS_CRITICAL_SECTION_END 02357 02358 02359 02360 02361 02362 02363 02364 //-------------------------------------------------------------------- 02366 #define MCS_STATE_CREATED 1 02367 02369 #define MCS_STATE_RUNNING 2 02370 02373 #define MCS_STATE_TERMINATING 3 02374 02376 #define MCS_STATE_END 4 02377 02378 02442 class Thread 02443 { 02444 private: 02445 MCS_DEBUG_ALLOC; 02446 02448 Thread* lparent; 02449 02451 pthread_t lthrID; 02452 02454 int lid; 02455 02457 int lstate; 02458 02459 //Synchronization for lstate variable. 02460 Synchro syn_lstate; 02461 02468 static void cleanup_Handler(void* This); 02469 02475 static void* RunThread(void* args); 02476 02478 bool checkTerminating(); 02479 02481 bool detached; 02482 02485 bool selfDelete; 02486 02487 protected: 02511 virtual void notify(int id, Thread* ref); 02512 02513 02524 virtual void initial(); 02525 02526 02542 virtual void final(); 02543 02544 02554 virtual void run(); 02555 02559 void set_cancel_state(bool cancel); 02560 02564 void test_cancel(); 02565 02567 Event* lerror; 02568 02569 public: 02571 Event* error(); 02572 02579 MCS_MISSING_COPY_CONSTRUCTOR(Thread); 02580 02587 MCS_MISSING_ASSIGNMENT_OPERATOR(Thread); 02588 02599 Thread(int id = 0, Thread* parent = NULL); 02600 02612 virtual ~Thread(); 02613 02625 void start(); 02626 02627 02642 void startDetached(bool selfDelete = false); 02643 02644 02654 void stop(); 02655 02664 int id(); 02665 02669 Thread* parent(); 02670 02671 02683 int state(); 02684 }; 02685 02686 02687 02688 template<class BASE> 02689 class ThreadSpecificData 02690 { 02691 private: 02692 pthread_key_t key; 02693 int ltag; 02694 02695 static void generic_destructor(void* p) 02696 { delete ((BASE*) p); } 02697 02698 void (*destructor)(void*); 02699 02700 public: 02701 ThreadSpecificData(void (*ext_destructor)(void*) = NULL) 02702 { 02703 destructor = generic_destructor; 02704 if (ext_destructor) 02705 destructor = ext_destructor; 02706 02707 pthread_key_create(&key, destructor); 02708 } 02709 02710 ~ThreadSpecificData() 02711 { pthread_key_delete(key); } 02712 02713 void clear() 02714 { 02715 void* p = getp(); 02716 if (p) 02717 (destructor)(p); 02718 02719 pthread_setspecific(key, NULL); 02720 } 02721 02722 void init(BASE* p = NULL, int tag = 0) 02723 { 02724 clear(); 02725 02726 if (! p) 02727 p = new BASE(); 02728 02729 pthread_setspecific(key, p); 02730 ltag = tag; 02731 } 02732 02733 int tag() 02734 { return ltag; } 02735 02736 BASE* operator->() const 02737 { return ((BASE*) pthread_getspecific(key)); } 02738 02739 BASE* getp() 02740 { return ((BASE*) pthread_getspecific(key)); } 02741 }; 02742 02743 02744 02745 02746 02747 class ThreadFunc : public Thread 02748 { 02749 private: 02750 int (*start_routine1)(void*); 02751 Event* (*start_routine2)(void*); 02752 void* arg; 02753 int ret; 02754 02755 void run(); 02756 02757 public: 02759 ThreadFunc(int (*start_routine)(void*), void* arg); 02760 ThreadFunc(Event* (*start_routine)(void*), void* arg); 02761 02762 int retcode(); 02763 }; 02764 02765 02772 void sleep_ms(unsigned int millisec); 02773 02774 02775 02782 enum TimeMode { 02783 UTC, 02784 LOCAL 02785 }; 02786 02787 02788 02789 02790 02791 time_t my_timelocal(struct tm* tm); 02792 02793 02794 02795 02814 class DateTime { 02815 02816 private: 02818 time_t time; 02819 02821 enum TimeMode timemode; 02822 02824 MYSQL_TIME* mysql; 02825 02838 static const char* parseTime(const char* s, struct tm* tm); 02839 02840 02842 void to_MYSQL_TIME(); 02843 02844 02852 time_t getTime() const; 02853 02854 02855 public: 02857 DateTime(); 02858 02866 void setMysqlBuffer(MYSQL_TIME* mysql); 02867 02882 void setTimeMode(enum TimeMode tm); 02883 02884 02886 void now(); 02887 02888 02890 void settval(time_t t); 02891 02893 DateTime& operator=(time_t t) 02894 { settval(t); return *this; } 02895 02896 02900 void setsval(string s); 02901 02903 DateTime& operator=(string s) 02904 { setsval(s); return *this; } 02905 02921 void settmval(struct tm& ltm); 02922 02924 DateTime& operator=(struct tm& ltm) 02925 { settmval(ltm); return *this; } 02926 02927 02929 time_t tval() const; 02930 02932 operator time_t() const 02933 { return tval(); } 02934 02935 02937 struct tm tmval() const; 02938 02940 operator struct tm() const 02941 { return tmval(); } 02942 02944 string sval() const; 02945 02947 operator string() const 02948 { return sval(); } 02949 }; 02950 02951 02952 02953 #define MCS_ID_UNKNOWN -1 02954 #define MCS_ID_LOCAL -2 02955 #define MCS_ID_CLIENT -3 02956 02957 02958 // Another wide use of the Data class is to to set/retrieve data of 02959 // prepared statement executions on the database. The Query class has 02960 // two fundamental methods that returns address of Data objects: 02961 // param() (to input data on prepared statement) and field() (to 02962 // retrieve data from an executed query on the database. 02963 02964 02965 02966 //Max number of dimensions in a Data multi-dimensional array. Note 02967 //that this number influences the declaration and implementation of 02968 //Data::array and Data::operator=. 02969 #define MCS_DATA_NDIM 15 02970 02971 02972 02973 //-------------------------------------------------------------------- 03041 class Data : public Serializable 03042 { 03043 private: 03044 MCS_DEBUG_ALLOC; 03045 03046 void reallocBuffer(); 03047 03048 #if ENABLE_MYSQL 03050 MYSQL_BIND* lbind; 03051 #endif 03052 03054 Types ltype; 03055 03057 string lname; 03058 03060 unsigned int lflags; 03061 03064 unsigned short int lmaxlength; 03065 03070 unsigned long llength; 03071 03073 bool lisunsigned; 03074 03076 my_bool lisnull; 03077 03079 bool lautoincr; 03080 03082 unsigned char tag; 03083 03085 char* buf; 03086 03088 unsigned int bufsize; 03089 03091 static const char* dtfmt; 03092 03094 static const char* dafmt; 03095 03097 static const char* tmfmt; 03098 03100 static const char* ifmt; 03101 03103 static const char* lfmt; 03104 03106 static const char* ffmt; 03107 03109 static const char* dfmt; 03110 03111 DateTime dt; 03112 03113 03115 void init(MYSQL_BIND* bind, Types type, const char* name="", 03116 unsigned short int maxLength=0, bool isunsigned=false, 03117 unsigned int flags = 0); 03118 03120 //void MySQL_TIME_2_time_t(MYSQL_TIME* mtime, time_t* t); 03121 // 03123 //void time_t_2_MySQL_TIME(time_t* t, MYSQL_TIME* mtime); 03124 03142 bool serialize_buffer(char*& from, unsigned int& size); 03143 03145 int id_source; 03146 03148 int id_dest; 03149 03155 unsigned char ldimspec; 03156 03158 unsigned short int ldim[MCS_DATA_NDIM]; 03159 03161 unsigned short int mult[MCS_DATA_NDIM]; 03162 03164 unsigned int arrsize; 03165 03167 unsigned int arrpos; 03168 03169 public: 03171 unsigned int objSize(); 03172 03173 03175 Data(); 03176 03178 Data(const Data& from); 03179 03180 03196 Data(Types type, unsigned short int maxLength = 0, 03197 bool isunsigned = false, string dimSpec = ""); 03198 03199 03222 Data(MYSQL_BIND* bind = NULL, Types type = STRING, 03223 const char* name="", unsigned short int maxLength=0, 03224 bool isunsigned=false, unsigned int flags = 0, 03225 unsigned char tag = 0); 03226 03227 03234 Data(int v, unsigned char tag = 0); 03235 03242 Data(long long int v, unsigned char tag = 0); 03243 03250 Data(double v, unsigned char tag = 0); 03251 03260 Data(string v, unsigned char tag = 0); 03261 03268 Data(struct tm v, unsigned char tag = 0); 03269 03276 Data(time_t v, unsigned char tag = 0); 03277 03289 Data(void* lbuf, unsigned int size, unsigned char tag = 0); 03290 03291 03299 Data(void* lbuf); 03300 03302 ~Data(); 03303 03310 void emptyName(); 03311 03312 03314 string name(); 03315 03316 //Set the name of the object. 03317 void setName(string name); 03318 03320 //unsigned int flags(); 03321 03323 Types type(); 03324 03326 unsigned short int maxLength(); 03327 03329 unsigned short int length(); 03330 03332 bool isUnsigned(); 03333 03335 bool isNull(); 03336 03338 bool isAutoIncrement(); 03339 03341 void* buffer() const; 03342 03349 int ival() const; 03350 03357 unsigned int uival() const; 03358 03365 long long int lval() const; 03366 03373 unsigned long long int ulval() const; 03374 03381 float fval() const; 03382 03389 double dval() const; 03390 03397 string sval(bool addWhiteSpaces = false) const; 03398 03410 int cval(char* c, int maxlength) const; 03411 03415 time_t tval() const; 03416 03424 void tval(struct tm* t) const; 03425 03426 03427 void* pval() const; 03428 03429 void setpval(void* p); 03430 03431 03433 void setNull(bool null = true); 03434 03436 void setival(int v); 03437 03439 void setuival(unsigned int v); 03440 03442 void setlval(long long int v); 03443 03445 void setulval(unsigned long long int v); 03446 03448 void setdval(double v); 03449 03451 void setcval(const char* v); 03452 03454 void setsval(string v); 03455 03457 void setblob(void* lbuf, unsigned int size); 03458 03460 void settimeval(struct tm v); 03461 03463 void settimeval(time_t v); 03464 03466 void settimenow(); 03467 03468 void setTimeMode(enum TimeMode tm); 03469 03470 //Wrapper to setsval(int). 03471 //void setval(string v); 03472 03473 //Wrapper to setival(int). 03474 //void setval(int v); 03475 03476 //Wrapper to setdval(int). 03477 //void setval(double v); 03478 03479 //Wrapper to setcval(int). 03480 //void setval(const char* v); 03481 03508 void resize(string dimSpec); 03509 03521 void resizeVaryingDim(unsigned short int newsize); 03522 03528 unsigned short int dim(int d); 03529 03530 03531 //How many dimensions, 0 means scalar value 03532 03539 unsigned int howManyDim(); 03540 03550 unsigned int varyingDim(); 03551 03557 unsigned int arraySize(); 03558 03559 03566 unsigned int array(unsigned short int i1 = 0, 03567 unsigned short int i2 = 0, 03568 unsigned short int i3 = 0, 03569 unsigned short int i4 = 0, 03570 unsigned short int i5 = 0, 03571 unsigned short int i6 = 0, 03572 unsigned short int i7 = 0, 03573 unsigned short int i8 = 0, 03574 unsigned short int i9 = 0, 03575 unsigned short int i10 = 0, 03576 unsigned short int i11 = 0, 03577 unsigned short int i12 = 0, 03578 unsigned short int i13 = 0, 03579 unsigned short int i14 = 0, 03580 unsigned short int i15 = 0); 03581 03585 Data& operator()(const int i1 = 0, 03586 const int i2 = 0, 03587 const int i3 = 0, 03588 const int i4 = 0, 03589 const int i5 = 0, 03590 const int i6 = 0, 03591 const int i7 = 0, 03592 const int i8 = 0, 03593 const int i9 = 0, 03594 const int i10 = 0, 03595 const int i11 = 0, 03596 const int i12 = 0, 03597 const int i13 = 0, 03598 const int i14 = 0, 03599 const int i15 = 0); 03600 03602 Data& operator=(const int v) 03603 { setival(v); return *this; } 03604 03606 Data& operator=(const unsigned int v) 03607 { setuival(v); return *this; } 03608 03610 Data& operator=(const long long int v) 03611 { setlval(v); return *this; } 03612 03614 Data& operator=(const unsigned long long int v) 03615 { setulval(v); return *this; } 03616 03618 Data& operator=(const double v) 03619 { setdval(v); return *this; } 03620 03622 Data& operator=(const char* v) 03623 { setsval(v); return *this; } 03624 03626 Data& operator=(const string v) 03627 { setsval(v); return *this; } 03628 03630 Data& operator=(const struct tm v) 03631 { settimeval(v); return *this; } 03632 03634 Data& operator=(const time_t v) 03635 { settimeval(v); return *this; } 03636 03638 operator const int () const { return ival (); } 03639 03641 operator const unsigned int () const { return uival (); } 03642 03644 operator const long long int () const { return lval (); } 03645 03647 operator const unsigned long long int () const { return ulval (); } 03648 03650 operator const float () const { return dval (); } 03651 03653 operator const double () const { return dval (); } 03654 03656 operator const char* () const { return (char*) pval(); } 03657 03659 operator const string () const { return sval (); } 03660 03662 operator const struct tm () const { struct tm v; tval(&v); return v; } 03663 03665 operator const time_t () const { return tval (); } 03666 03667 03679 Data& operator=(Data& d); 03680 03682 //static void default_struct_tm(struct tm* t); 03683 03699 static void parseTime(string s, struct tm* ts); 03700 03715 static long long int MinValue(Types ltype, bool flunsigned); 03716 03729 static long long int MaxValue(Types ltype, bool flunsigned); 03730 03732 string print(); 03733 03735 void setTag(unsigned char tag); 03736 03738 unsigned char getTag(); 03739 03740 int getSourceID(); 03741 int getDestID(); 03742 void setSourceID(int id); 03743 void setDestID(int id); 03744 }; 03745 03746 03747 03749 #define DYNAMIC_ARRAY_DEFAULT_STEP 10 03750 03751 03752 03761 template<class BASE> 03762 class Dynamic_Array : public Synchro { 03763 private: 03765 BASE** arr; 03766 03768 int step_alloc; 03769 03771 int lcount; 03772 03780 void check_allocation(int count); 03781 03782 protected: 03783 Dynamic_Array<BASE>& array; 03784 03785 public: 03791 Dynamic_Array(bool synchro); 03792 03799 MCS_MISSING_COPY_CONSTRUCTOR(Dynamic_Array); 03800 03801 03803 Dynamic_Array& operator=(Dynamic_Array& from); 03804 03805 03807 ~Dynamic_Array(); 03808 03814 int count(); 03815 03826 bool ready(); 03827 03857 void push(BASE* d); 03858 03868 void push(BASE& d); 03869 03882 BASE pop(int pos = 0); 03883 03913 BASE& operator[](int pos); 03914 03928 BASE peek(int pos); 03929 03935 void clear(); 03936 }; 03937 03938 03939 //Methods implementation of template classes must be in the header file 03940 template<class BASE> 03941 void mcs::Dynamic_Array<BASE>::check_allocation(int count) { 03942 unsigned int size; 03943 static int max_size = Data::MaxValue(SMALL, true); 03944 03945 if (count >= max_size) 03946 throw MCS_ERROR(MSG_INDEX_OUT_RANGE, count, max_size); 03947 03948 if (count > (step_alloc * DYNAMIC_ARRAY_DEFAULT_STEP)) { 03949 step_alloc++; 03950 size = sizeof(BASE*) * step_alloc * DYNAMIC_ARRAY_DEFAULT_STEP; 03951 03952 if (step_alloc == 1) //First allocation 03953 arr = (BASE**) malloc(size); 03954 else 03955 arr = (BASE**) realloc(arr, size); 03956 } 03957 } 03958 03959 03960 template<class BASE> 03961 mcs::Dynamic_Array<BASE>::Dynamic_Array(bool synchro) : 03962 Synchro(), array(*this) 03963 { 03964 synchronize(synchro); 03965 lcount = 0; 03966 step_alloc = 0; 03967 arr = NULL; 03968 } 03969 03970 03971 template<class BASE> 03972 mcs::Dynamic_Array<BASE>::~Dynamic_Array() { 03973 clear(); 03974 } 03975 03976 03977 03978 template<class BASE> 03979 mcs::Dynamic_Array<BASE>& 03980 mcs::Dynamic_Array<BASE>::operator=(Dynamic_Array<BASE>& from) { 03981 int i; 03982 03983 clear(); 03984 for (i=0; i<from.count(); i++) 03985 push(from[i]); 03986 03987 return *this; 03988 } 03989 03990 03991 template<class BASE> 03992 void mcs::Dynamic_Array<BASE>::push(BASE* d) { 03993 MCS_CRITICAL_SECTION_BEGIN; 03994 03995 check_allocation(lcount + 1); 03996 arr[lcount++] = d; 03997 03998 MCS_CRITICAL_SECTION_END; 03999 } 04000 04001 04002 template<class BASE> 04003 void mcs::Dynamic_Array<BASE>::push(BASE& d) { 04004 MCS_CRITICAL_SECTION_BEGIN; 04005 04006 check_allocation(lcount + 1); 04007 arr[lcount++] = new BASE(d); 04008 04009 MCS_CRITICAL_SECTION_END; 04010 } 04011 04012 04013 04014 //#define EVENT_IS_THROWN(INSTR...) 04015 //try { INSTR;} catch(Event e) { leave(); throw; } 04016 //{ bool _EVENT_IS_THROWN 04017 04018 04019 04020 template<class BASE> 04021 BASE mcs::Dynamic_Array<BASE>::pop(int pos) { 04022 int i; 04023 04024 MCS_CRITICAL_SECTION_BEGIN; 04025 04026 BASE d = BASE(operator[](pos)); 04027 04028 if (pos < lcount) { 04029 delete arr[pos]; 04030 04031 lcount--; 04032 for (i=pos; i<lcount; i++) 04033 arr[i] = arr[i+1]; 04034 } 04035 04036 MCS_CRITICAL_SECTION_END_RETURN(d); 04037 } 04038 04039 04040 template<class BASE> 04041 BASE& mcs::Dynamic_Array<BASE>::operator[](int pos) { 04042 if (pos < 0) 04043 pos += lcount; 04044 04045 if (pos < 0) 04046 throw MCS_ERROR(MSG_INVALID_POSITION, pos); 04047 04048 if (pos >= lcount) 04049 throw MCS_ERROR(MSG_INDEX_OUT_RANGE, pos, lcount); 04050 04051 return *(arr[pos]); 04052 } 04053 04054 04055 template<class BASE> 04056 BASE mcs::Dynamic_Array<BASE>::peek(int pos) 04057 { 04058 MCS_CRITICAL_SECTION_BEGIN; 04059 04060 BASE d = operator[](pos); 04061 04062 MCS_CRITICAL_SECTION_END_RETURN(d); 04063 } 04064 04065 04066 template<class BASE> 04067 int mcs::Dynamic_Array<BASE>::count() { 04068 return lcount; 04069 } 04070 04071 04072 template<class BASE> 04073 bool mcs::Dynamic_Array<BASE>::ready() { 04074 return (bool) (lcount > 0); 04075 } 04076 04077 04078 template<class BASE> 04079 void mcs::Dynamic_Array<BASE>::clear() { 04080 int i; 04081 04082 MCS_CRITICAL_SECTION_BEGIN; 04083 04084 for (i=0; i<lcount; i++) 04085 delete arr[i]; 04086 04087 if (arr) { 04088 free(arr); 04089 arr = NULL; 04090 } 04091 04092 lcount = 0; 04093 step_alloc = 0; 04094 04095 MCS_CRITICAL_SECTION_END; 04096 } 04097 04098 04099 04100 04102 //#define MCS_VECTOR_MOVE_TO_END -1 04103 04119 class Record : public Serializable, public Synchro 04120 { 04121 private: 04122 MCS_DEBUG_ALLOC; 04123 04125 Dynamic_Array<Data> array; 04126 04128 Dynamic_Array<int> lmap; 04129 04131 string smap; 04132 04151 bool serialize_buffer(char*& from, unsigned int& size); 04152 04153 04154 04155 public: 04157 Record(Record& from); 04158 04160 Record& operator=(Record& from); 04161 04168 void emptyName(); 04169 04173 void setNull(); 04174 04175 04177 Record(bool synchro = false); 04178 04179 04188 Record(void* lbuf, bool synchro = false); 04189 04190 04198 ~Record(); 04199 04201 int count(); 04202 04204 void addField(Data* d); 04205 04207 void addField(Data& d); 04208 04217 void addField(string s, char tag = 0); 04218 04227 void addField(int i, char tag = 0); 04228 04237 void addField(long long int i, char tag = 0); 04238 04247 void addField(double f, char tag = 0); 04248 04249 Data pop(int x = 0); 04250 04267 int posWhoseNameIs(string name , enum ThrowExceptions throwexc = THROW); 04268 04269 04312 void setFieldMap(string s = ""); 04313 04315 void setFieldMap(Record& rec); 04316 04317 void clear(); 04318 04319 04333 Data& operator[](string name); 04334 04335 Data& operator[](int pos); 04336 04338 Data field(string name); 04339 04340 Data field(int pos); 04341 04342 04344 unsigned int objSize(); 04345 04347 string asString(string sep = "\t"); 04348 string asStringNames(string sep = "\t"); 04349 string asStringTypes(string sep = "\t"); 04350 04351 04353 // \brief Move element in the Record from one position to another. 04354 // 04355 // Both indexes must be allowed ones, and "from" must be less than 04356 // "to". All elements after "from" will be shifted one position 04357 // towards the exit of the queue. This is a thread safe method. 04358 // 04359 // \param from Source position; 04360 // \param to Destination position. 04361 // 04362 // \exception ERROR MSG_INDEX_OUT_RANGE. 04363 // */ 04364 //void move(int from, int to); 04365 }; 04366 04367 04368 04369 04370 04371 04372 04373 04374 04375 04376 04386 #define MCS_RS_ACCUM 1 04387 04388 04398 #define MCS_RS_USEMETAREC 2 04399 04406 #define MCS_RS_KNOW_NROWS 4 04407 04415 #define MCS_RS_RANDOM 8 04416 04417 04429 #define MCS_RS_INSERT 16 04430 04431 04432 04433 04459 class RecordSet { 04460 private: 04462 short int lid; 04463 04465 unsigned char code; 04466 04468 bool lknow_nrows; 04469 04471 unsigned int lnrows; 04472 04474 bool laccum; 04475 04477 bool lrandom; 04478 04480 bool lusemetarec; 04481 04483 bool lfetch; 04484 04486 bool linsert; 04487 04489 unsigned int lpos; 04490 04492 unsigned int current; 04493 04495 Record lmetarec; 04496 04498 bool leof; 04499 04501 Dynamic_Array<Record> rs; 04502 04515 virtual Record* newRecord(); 04516 04517 //Clear the entire Record set and the lmetarec object. 04518 void clear(); 04519 04528 bool internal_fetch(unsigned int newpos); 04529 04530 04531 protected: 04556 void init(unsigned char code, unsigned int nrows = 0, Record* meta = NULL, 04557 short int id = 0); 04558 04560 void startFetch(); 04561 04587 virtual bool fetch(unsigned int newpos, bool random); 04588 04590 virtual void hk_dump(string fn); 04591 04592 04593 public: 04600 MCS_MISSING_COPY_CONSTRUCTOR(RecordSet); 04601 04608 MCS_MISSING_ASSIGNMENT_OPERATOR(RecordSet); 04609 04616 RecordSet(); 04617 04619 virtual ~RecordSet(); 04620 04621 04622 04632 void setFieldMap(string s = ""); 04633 04634 04645 void insert(Record* rec); 04646 04657 void insert(Record& rec); 04658 04659 04668 bool setFirst(); 04669 04679 bool setLast(); 04680 04689 bool setNext(); 04690 04699 bool setPrev(); 04700 04718 bool setWhere(int i, string equalTo); 04719 04737 bool setWhere(int field, int equalTo); 04738 04755 bool setPos(unsigned int i); 04756 04757 void dump(string fn); 04758 04759 bool know_nRows(); 04760 unsigned int nRows(); 04761 04763 int nFields(); 04764 04765 unsigned int pos(); 04766 bool eof(); 04767 bool alwaysSameStructure(); 04768 04769 Record& rec(); 04770 Record& metarec(); 04771 04772 Record* prepRecToSend(); 04773 }; 04774 04775 04776 04777 04778 04779 //-------------------------------------------------------------------- 04792 class Conf 04793 { 04794 private: 04796 string filename; 04797 04799 vector<string> sections; 04800 04802 vector<string> keys; 04803 04805 vector<string> values; 04806 04808 vector<string> comments; 04809 04818 int index(string section, string key); 04819 04820 Data lastval; 04821 04822 public: 04829 MCS_MISSING_COPY_CONSTRUCTOR(Conf); 04830 04837 MCS_MISSING_ASSIGNMENT_OPERATOR(Conf); 04838 04844 Conf(string filename = ""); 04845 04847 ~Conf(); 04848 04849 void open(string filename); 04850 04863 bool search(string section, string key, enum ThrowExceptions throwexc = DONT_THROW); 04864 04866 04881 Data& val(string section = "", string key = ""); 04882 04896 string sval(string section, string key); 04897 04912 string sval(string section, string key, string defval); 04913 04914 04915 04929 int ival(string section, string key); 04930 04945 int ival(string section, string key, int defval); 04946 04947 04961 long long int lval(string section, string key); 04962 04977 long long int lval(string section, string key, int defval); 04978 04979 04994 void setval(string section, string key, string val, string comment = ""); 04995 05011 void setval(string section, string key, long long int val, string comment = ""); 05026 void setval(string section, string key, int val, string comment = ""); 05027 05042 void setval(string section, string key, Data* val, string comment = ""); 05043 05044 05055 void save(string filename = ""); 05056 }; 05057 05058 05059 05060 05061 05062 05063 05064 //-------------------------------------------------------------------- 05066 #define MCS_CMD_MAX_TOKENS 100 05067 05134 class CommandParser { 05135 private: 05136 MCS_DEBUG_ALLOC; 05137 05139 string origcmdline; 05140 05142 string lcmd; 05143 05145 vector<string> tokens; 05146 05154 vector<string> rest; 05155 05157 vector<string> args; 05158 05160 vector<string> opts; 05161 05163 vector<string> optargs; 05164 05166 Data* md_args[MCS_CMD_MAX_TOKENS]; 05167 05169 Data* md_optargs[MCS_CMD_MAX_TOKENS]; 05170 05177 static string clean(string c); 05178 05180 void clearArgs(); 05181 05182 public: 05189 MCS_MISSING_COPY_CONSTRUCTOR(CommandParser); 05190 05197 MCS_MISSING_ASSIGNMENT_OPERATOR(CommandParser); 05198 05200 CommandParser(); 05201 05203 ~CommandParser(); 05204 05206 int tokenc(); 05207 05220 string token(int i); 05221 05236 string line_afterToken(int i); 05237 05238 05254 Data& arg(int i); 05255 05257 string sarg(int i); 05258 05259 05261 int argc(); 05262 05263 05279 string opt(int i); 05280 05282 int optc(); 05283 05284 05304 Data& optarg(int i); 05305 05307 void parseCmd(string c); 05308 05310 void parseCmd(int argc, char* argv[]); 05311 05312 05313 05315 string cline(); 05316 05318 string cmd(); 05319 05321 string allargs(); 05322 05324 bool cmpCmd(string cmd); 05325 05327 bool givenOpt(string opt); 05328 05330 bool givenOpt(string opt, int& i); 05331 05332 05349 vector<string> replPars_onFile(string fn); 05350 05351 05364 string replPars(string str); 05365 }; 05366 05367 05368 05369 05370 05371 05372 #if ENABLE_MYSQL 05373 //-------------------------------------------------------------------- 05381 class DBConn 05382 { 05383 private: 05384 MCS_DEBUG_ALLOC; 05385 05387 MYSQL* lconn; 05388 05390 bool lconnInitialized; 05391 05393 bool lconnOpened; 05394 05396 string luser; 05397 05399 string lpass; 05400 05402 string ldb ; 05403 05405 string lhost; 05406 05407 friend class Query; 05408 05409 public: 05416 MCS_MISSING_COPY_CONSTRUCTOR(DBConn); 05417 05424 MCS_MISSING_ASSIGNMENT_OPERATOR(DBConn); 05425 05427 DBConn(); 05428 05430 ~DBConn(); 05431 05446 void connect(string user, string pass, string db, string host=""); 05447 05449 void close(); 05450 05452 bool isOpen(); 05453 05455 unsigned long id(); 05456 05471 DBConn* newDBConn(); 05472 }; 05473 05474 05475 05476 05477 05478 05479 //-------------------------------------------------------------------- 05493 class Query : public RecordSet 05494 { 05495 private: 05496 MCS_DEBUG_ALLOC; 05497 05499 DBConn* ldbc; 05500 05502 bool lhandleNewDBConn; 05503 05505 MYSQL* lconn; 05506 05508 bool gotStmtInitialized; 05509 05511 bool gotResult; 05512 05514 unsigned int laffectedRows; 05515 05517 long long int lastid; 05518 05523 Record lparam; 05524 05525 05543 vector<string> printResultSet(unsigned int& nrows, 05544 unsigned int& nfields, 05545 MYSQL_RES* res = NULL); 05546 05551 MYSQL_STMT* lstmt; 05552 05557 MYSQL_BIND* lbparam; 05558 05559 int nlparam; 05560 05561 05563 MYSQL_BIND* lbrec; 05564 05565 bool fetch(unsigned int newpos, bool random); 05566 05567 Record* myrec; 05568 05569 Record* newRecord(); 05570 05571 /* 05572 IMPORTANT NOTE: lbparam and lparam are protected because the Table class 05573 needs them to bind parameters. Anyway this should be automatically done 05574 via mysql_stmt_param_metadata, but it is not yet implemented. When this 05575 routine will became available this two variables will become private, so 05576 users should use the method "param" wherever possible. 05577 */ 05578 05584 void bind(); 05585 05586 string SQL; 05587 05588 void parseFieldList(int op, string& fields, string& values, int& autoIncr); 05589 05590 05591 public: 05598 MCS_MISSING_COPY_CONSTRUCTOR(Query); 05599 05606 MCS_MISSING_ASSIGNMENT_OPERATOR(Query); 05607 05622 Query(DBConn* lconn, bool call_newDBConn = false); 05623 05630 ~Query(); 05631 05638 void query(string SQL, bool StoreResult = false); 05639 05640 05681 vector<string> simpleQuery(string SQL, 05682 unsigned int& nrows, unsigned int& nfields); 05683 05684 05686 vector<string> simpleQuery(string SQL); 05687 05688 05709 void prepare(string SQL=""); 05710 05711 #define MCS_PAB_INSERT 1 05712 #define MCS_PAB_UPDATE 2 05713 #define MCS_PAB_REPLACE 3 05714 05715 05756 void prepare_with_parameters(int op, string fields, string table, 05757 string where=""); 05758 05759 05771 void prepare_with_parameters(int op, char** fields, int nfields, 05772 string table, string where=""); 05773 05774 05782 unsigned int nAffectedRows(); 05783 05784 05786 Record& param(); 05787 05789 // \brief Returns the current record set. 05790 //*/ 05791 //DBRecordSet* result(); 05792 05811 Data& lookup(string field, string table, string where = ""); 05812 05813 05844 void execute(bool StoreResult = false); 05845 05846 05847 bool gotRecordSet(); 05848 05849 05851 void close(); 05852 05853 05860 void readTableList(); 05861 05863 vector<string>tableList; 05864 05876 vector<string> tableInfo(string tbl); 05877 05878 05880 vector<string> ExecutionDetails(string pre = ""); 05881 05882 05902 void customFillBuffer(char* buf, unsigned int& chunksize, bool firstTime); 05903 05910 void Result2Ascii(string fn); 05911 05921 long long int last_id(); 05922 }; 05923 05924 05925 05926 05927 05928 05929 05930 //-------------------------------------------------------------------- 05948 class Table : public Query 05949 { 05950 private: 05951 MCS_DEBUG_ALLOC; 05952 05954 string ltable; 05955 05957 string lfieldkey; 05958 05960 unsigned int posfieldkey; 05961 05963 Record newrec; 05964 05965 void insert_or_update(int op); 05966 05967 public: 05974 MCS_MISSING_COPY_CONSTRUCTOR(Table); 05975 05982 MCS_MISSING_ASSIGNMENT_OPERATOR(Table); 05983 05991 Table(DBConn* db, string table, string fieldkey); 05992 05994 ~Table(); 05995 05997 void loadTable(); 05998 06002 Record& newRec(); 06003 06009 void insert(); 06010 06016 void replace(); 06017 06018 06025 void update(); 06026 }; 06027 #endif 06028 06029 06030 06031 06032 06033 //Forward declaration 06034 class Env; 06035 class Server; 06036 06037 06038 06039 //-------------------------------------------------------------------- 06046 class BaseThread : public Thread { 06047 private: 06048 MCS_DEBUG_ALLOC; 06049 06051 char tID[4]; 06052 06053 protected: 06061 RetValue Log(Event e); 06062 06064 static Env* env; 06065 06066 public: 06073 MCS_MISSING_COPY_CONSTRUCTOR(BaseThread); 06074 06081 MCS_MISSING_ASSIGNMENT_OPERATOR(BaseThread); 06082 06091 BaseThread(Thread* parent, int lID); 06092 06101 BaseThread(Thread* parent, const char *ltID); 06102 06104 ~BaseThread(); 06105 06107 const char *tid(); 06108 06109 06129 static int fileType(string fn); 06130 06144 int chkExt(string& s); 06145 06184 static int spawn(string fn, string pars, 06185 string wpath = ".", 06186 string thrID = "x", 06187 string user = "x", 06188 string pass = "x", 06189 string dbname = "x", 06190 string fout = "out", 06191 string ferr = "err"); 06192 }; 06193 06194 06195 06196 06197 06198 //-------------------------------------------------------------------- 06200 #define MCS_FT_UNKNOWN 0 06201 06203 #define MCS_FT_BATCH 1 06204 06206 #define MCS_FT_SQL 2 06207 06209 #define MCS_FT_SCRIPT 3 06210 06212 #define MCS_FT_BIN 4 06213 06214 06215 06222 class ClientInfo : public Record 06223 { 06224 public: 06226 Data& id(); 06227 06229 Data& ipaddress(); 06230 06232 Data& hostname(); 06233 06235 Data& timeConnetcted(); 06236 06238 Data& username(); 06239 06241 Data& lastCommand(); 06242 06244 Data& timeLastCommand(); 06245 06247 Data& commandExecuted(); 06248 06250 Data& logged(); 06251 06252 public: 06254 ClientInfo(); 06255 }; 06256 06257 06258 06259 06260 06261 06262 06316 class UserThread : public BaseThread { 06317 private: 06318 MCS_DEBUG_ALLOC; 06319 06321 int csocket; 06322 06324 ClientInfo linfo; 06325 06326 RecordSet* rs; 06327 06328 bool deleters; 06329 06330 Synchro syn; 06331 06332 protected: 06334 Socket* sock; 06335 06337 int luserid; 06338 06340 int batchlevel; 06341 06343 bool loginok; 06344 06346 int grants; 06347 06349 string fnout; 06350 06352 string fnerr; 06353 06355 string user; 06356 06358 string pass; 06359 06361 string dbname; 06362 06364 string dbhost; 06365 06366 #if ENABLE_MYSQL 06368 DBConn db; 06369 06371 Query* query; 06372 #endif 06373 06374 void setActiveRS(RecordSet* rs, bool delWhenFinished = true); 06375 06386 string wpath(string fn = ""); 06387 06388 06399 RetValue sendStrings(string str); 06400 06401 06408 RetValue Send(Event e, bool log = true); 06409 06415 RetValue Send(Data& data); 06416 06422 RetValue Send(Record& vec); 06423 06432 RetValue Send(string filename, string path); 06433 06441 RetValue Send(vector<string> vec); 06442 06443 06444 #if ENABLE_MYSQL 06445 06457 RetValue sendQueryRes(); 06458 #endif 06459 06460 06475 void prompt(RetValue ret); 06476 06477 06486 void run(); 06487 06488 06502 virtual RetValue hk_connect(); 06503 06504 06523 virtual RetValue hk_auth(int& grants, bool& loginok); 06524 06525 06543 virtual RetValue hk_exec(CommandParser* cmd, bool& cmd_executed); 06544 06545 06558 virtual void hk_postexec(CommandParser* cmd, RetValue ret); 06559 06560 06569 virtual void hk_disconnect(); 06570 06571 06594 RetValue exec(string cmd, string pars = ""); 06595 06596 06601 Server* parent(); 06602 06603 06605 void send2OtherThread(Data& d, int destid); 06606 06607 public: 06614 MCS_MISSING_COPY_CONSTRUCTOR(UserThread); 06615 06622 MCS_MISSING_ASSIGNMENT_OPERATOR(UserThread); 06623 06633 UserThread(Thread* parent, int lID, int newsock); 06634 06636 ~UserThread(); 06637 06639 ClientInfo& info(); 06640 06658 void wakeUpClient(Event* e = NULL); 06659 06661 Record send; 06662 06664 Record recv; 06665 06667 string userName(); 06668 06669 int userID(); 06670 }; 06671 06672 06673 06674 06675 // ------------------------------------------------------------------- 06692 class LocalThread : public BaseThread 06693 { 06694 private: 06695 MCS_DEBUG_ALLOC; 06696 06705 virtual void run(); 06706 06707 06708 protected: 06709 UserThread** client; 06710 06712 UserThread** serverClients(); 06713 06722 void dataDispatcher(); 06723 06741 bool userID2clientID(int userid, int* cid); 06742 06743 06744 public: 06751 MCS_MISSING_COPY_CONSTRUCTOR(LocalThread); 06752 06759 MCS_MISSING_ASSIGNMENT_OPERATOR(LocalThread); 06760 06770 LocalThread(Thread* parent); 06771 06772 06774 ~LocalThread(); 06775 06776 06791 virtual void hk_log(UserThread* p, Event e); 06792 06794 Record recv; 06795 }; 06796 06797 06798 06799 06800 06801 06802 //-------------------------------------------------------------------- 06820 class Env { 06821 private: 06822 #if ENABLE_MYSQL 06823 DBConn db; 06824 #endif //ENABLE_MYSQL 06825 06827 void chkTree(); 06828 06832 void LoadConf(); 06833 06837 void DumpConf(); 06838 06839 06840 public: 06849 Env(string app = "mcs", string inipath = "mcs.conf"); 06850 06857 MCS_MISSING_COPY_CONSTRUCTOR(Env); 06858 06865 MCS_MISSING_ASSIGNMENT_OPERATOR(Env); 06866 06868 ~Env(); 06869 06870 //Pointer to the LocalThread (or derived) object; 06871 LocalThread* local; 06872 06874 Conf* cnf; 06875 06877 string appname; 06878 06880 string appvers; 06881 06883 string path; 06884 06886 string inipath; 06887 06889 string localhost; 06890 06892 string interface; 06893 06895 int port; 06896 06898 //bool server_running; 06899 06901 Server* server; 06902 06904 int max_users; 06905 06907 bool cl_local_kills_mcs; 06908 06910 bool cl_have_db; 06911 06913 bool cl_custom_auth; 06914 06916 bool cl_logfile; 06917 06919 bool cl_work; 06920 06922 bool cl_work_cid; 06923 06925 bool cl_logstdout; 06926 06928 bool cl_createlocal; 06929 06931 bool cl_restartlocal; 06932 06934 bool cl_clean_logout; 06935 06937 bool cl_read_grants; 06938 06940 bool cl_autoexec; 06941 06943 bool cl_use_ssl; 06944 06946 string sslcert; 06947 06949 string sslpriv; 06950 06952 ofstream* flog; 06953 06955 string db_user; 06956 06958 string db_pass; 06959 06961 string db_name; 06962 06964 string db_host; 06965 06967 unsigned int timeout; 06968 06970 int cl_chunksize; 06971 06973 void* ssl_ctx; 06974 }; 06975 06976 06977 06978 06979 06980 06981 06982 06983 06984 06985 06986 06987 06988 06989 //-------------------------------------------------------------------- 07123 class Server : public BaseThread 07124 { 07125 private: 07126 MCS_DEBUG_ALLOC; 07127 07129 UserThread** pClient; 07130 07131 friend class LocalThread; //To give access to pClient 07132 07141 void run(); 07142 07145 int find_free_id(); 07146 07147 protected: 07156 void notify(int id, Thread* ref); 07157 07159 void newClient(int newsock); 07160 07163 //void freeClient(int i); 07164 07166 void killAllClients(); 07167 07183 virtual void hk_newClient(int i); 07184 07186 void killClient(int i); 07187 07188 07195 virtual UserThread* newUserThread(int lID, int newsock); 07196 07203 virtual LocalThread* newLocalThread(); 07204 07205 public: 07212 MCS_MISSING_COPY_CONSTRUCTOR(Server); 07213 07220 MCS_MISSING_ASSIGNMENT_OPERATOR(Server); 07221 07228 Server(Env* lenv); 07229 07231 ~Server(); 07232 07240 RecordSet* getAll_ClientInfo(); 07241 07243 void (*cb_log) (UserThread* p, Event e); 07244 07246 RetValue (*cb_connect) (); 07247 07249 RetValue (*cb_auth) (int&, bool&); 07250 07252 RetValue (*cb_exec) (CommandParser*, bool&_executed); 07253 07255 void (*cb_postexec) (CommandParser*, RetValue); 07256 07258 void (*cb_disconnect) (); 07259 07261 void (*cbwa_log) (); 07262 07264 void (*cbwa_connect) (); 07265 07267 void (*cbwa_auth) (); 07268 07270 void (*cbwa_exec) (); 07271 07273 void (*cbwa_postexec) (); 07274 07276 void (*cb_newClient) (int i); 07277 07279 Record dispatch; 07280 }; 07281 07282 07283 07284 07334 Env* mcsStart(string appname, string inipath = "", 07335 Server* (*cb_newServer)(Env*) = NULL); 07336 07337 07367 //void mcsWait(Env* env); 07368 07369 07370 #define MCS_CUSTOM_USER(CLASS) \ 07371 class CLASS : public mcs::UserThread \ 07372 { \ 07373 public: \ 07374 CLASS(mcs::Thread* p, int id, int sock) : \ 07375 UserThread(p, id, sock) {} \ 07376 ~CLASS() {} 07377 #define MCS_CUSTOM_USER_END(CLASS) }; 07378 07379 07380 #define MCS_CUSTOM_LOCAL(CLASS) \ 07381 class CLASS : public mcs::LocalThread \ 07382 { \ 07383 public: \ 07384 CLASS(mcs::Thread* p) : \ 07385 LocalThread(p) {} \ 07386 ~CLASS() {} 07387 #define MCS_CUSTOM_LOCAL_END(CLASS) }; 07388 07389 07403 #define MCS_CUSTOM_SERVER(CLIENT, LOCAL) \ 07404 mcs::Server* newCustomServer(mcs::Env* env); \ 07405 \ 07406 class mcsCustomServer : public mcs::Server \ 07407 { \ 07408 private: \ 07409 mcs::UserThread* newUserThread(int id, int sock) { \ 07410 return new CLIENT(this, id, sock); \ 07411 } \ 07412 \ 07413 mcs::LocalThread* newLocalThread() { \ 07414 return new LOCAL(this); \ 07415 } \ 07416 \ 07417 public: \ 07418 mcsCustomServer(mcs::Env* lenv): Server(lenv) {} \ 07419 \ 07420 ~mcsCustomServer() {} \ 07421 }; \ 07422 \ 07423 mcs::Server* newCustomServer(Env* env) \ 07424 { return new mcsCustomServer(env); } \ 07425 \ 07426 mcs::Env* mcsCustomStart(string appname, string inipath = "") \ 07427 { return mcsStart(appname, inipath, &newCustomServer); } 07428 07429 07430 07431 07432 //-------------------------------------------------------------------- 07496 class Client : public Socket, public RecordSet 07497 { 07498 protected: 07500 string lpath; 07501 07503 bool connected; 07504 07506 void clearRecords(); 07507 07508 bool writetofile; 07509 07510 int fileDescriptor; 07511 07512 bool fetch(unsigned int newpos, bool random); 07513 07514 Record* lrecord; 07515 07516 //Server side Client Identificator. 07517 int lcid; 07518 07519 //Server side chunk size. 07520 int lchunksize; 07521 07522 public: 07529 MCS_MISSING_COPY_CONSTRUCTOR(Client); 07530 07537 MCS_MISSING_ASSIGNMENT_OPERATOR(Client); 07538 07539 07544 Record code; 07545 07550 Record msg; 07551 07556 Record out; 07557 07559 Record recv; 07560 07562 Record aux; 07563 07575 Client(string path, string server, int port=MCS_DEFAULT_PORT, 07576 bool synchro = false, bool SSL = false, 07577 unsigned int timeout = MCS_DEFAULT_CLIENT_TIMEOUT); 07578 07580 virtual ~Client(); 07581 07582 07595 bool login(string user, string pass, string db = ""); 07596 07604 bool exec(string cmd, Data* data = NULL); 07605 07606 void writeToFile(int des); 07607 07608 #define MCS_CLIENT_ERROR 1 07609 #define MCS_CLIENT_DATA 2 07610 #define MCS_CLIENT_FILE 3 07611 #define MCS_CLIENT_DISCONNECT 4 07612 virtual void event(int op, Data d, int code = 0); 07613 07615 bool isConnected(); 07616 07618 int cid(); 07619 07621 int chunksize(); 07622 }; 07623 07624 07625 07652 class Pipe { 07653 private: 07655 static Synchro synchro; 07656 07658 static int filecount; 07659 07661 string pipefn; 07662 07664 int pipefd[2]; 07665 07673 bool flcreated; 07674 07676 bool named; 07677 07678 public: 07680 Pipe(); 07681 07683 ~Pipe(); 07684 07687 bool isReady(); 07688 07691 string filename(); 07692 07693 07701 bool consumerHasGone(); 07702 07703 07706 void create(); 07707 07709 string createNamed(); 07710 07714 int openRead(); 07715 07719 int openWrite(); 07720 07725 void closeRead(); 07726 07731 void closeWrite(); 07732 }; 07733 07734 07735 07736 07737 07738 07745 class URLReader : Pipe 07746 { 07747 private: 07749 static bool fl_curl_global_init; 07750 07752 string lurl; 07753 07755 bool local; 07756 07757 static size_t cb_write(void *ptr, size_t size, size_t nmemb, void *This); 07758 07759 ThreadFunc* thr; 07760 static int thread_run(void* p); 07761 void thread_fetch(); 07762 07763 protected: 07771 virtual unsigned int Write(void *ptr, unsigned int size, unsigned int nmemb); 07772 07773 void flush(); 07774 07775 public: 07777 URLReader(); 07778 07780 virtual ~URLReader(); 07781 07783 int OpenAsFD(string url); 07784 07786 const char* OpenAsFifo(string url); 07787 07788 void Download(string url, string fn); 07789 07790 07794 int Read(char* buf, int maxlen); 07795 07806 void Close(); 07807 07808 string url(); 07809 07810 //Event* thread_error(); 07811 07812 static bool chkLocal(string& url); 07813 }; 07814 07815 07816 07817 07818 #if ENABLE_CFITSIO 07819 07825 class FITSReader: public RecordSet 07826 { 07827 private: 07828 void* fptr; 07829 long int nrows; 07830 int ncols; 07831 bool local; 07832 int nhdu; 07833 bool fetch(unsigned int newpos, bool random); 07834 07835 Buffer memfile; 07836 void* memfilep; 07837 size_t memfilesize; 07838 07839 public: 07840 FITSReader(); 07841 ~FITSReader(); 07842 07843 void open(Buffer& buf); 07844 void open(string fn); 07845 void close(); 07846 07847 Record header; 07848 Record header_comments; 07849 07850 void selectHDU(int hdunum); 07851 bool selectNextHDU(); 07852 07853 void selectHDU(string name, int extver = 0); 07854 int currentHDU(); 07855 int HDUCount(); 07856 07857 bool ffile_is_compressed(string fn); 07858 }; 07859 07860 07867 class FITSWriter: public Record 07868 { 07869 private: 07870 void* fptr; 07871 07872 public: 07873 FITSWriter(); 07874 ~FITSWriter(); 07875 07876 void open(string fn, bool compressed = false); 07877 void close(); 07878 07879 void newKeyword(string key, string value, string comment = ""); 07880 void newBinTable(Record& meta, string name = ""); 07881 void newAsciiTable(int nfields, string name = ""); 07882 void newImage(Types bitpix, unsigned int naxis, unsigned int naxes, 07883 void* buf, string name = ""); 07884 07885 //The "buf" parameter is used only to write a image HDU. 07886 void write(void* buf); 07887 }; 07888 #endif //ENABLE_CFITSIO 07889 07890 07891 //class FileReader : public RecordSet 07892 //{ 07893 //private: 07894 // URLReader input; 07895 // int fd; 07896 // 07897 // Record master; 07898 // string sep; 07899 // string eor; 07900 // 07901 // Buffer buf; 07902 // 07903 // bool fetch(unsigned int newpos, bool random); 07904 // 07905 //public: 07906 // FileReader(); 07907 // ~FileReader(); 07908 // 07909 // void open(string url); 07910 // void close(); 07911 // 07912 // void setMaster(Record& rec); 07913 // void setMaster(Record& rec, string sep); 07914 // void setMaster(Record& rec, string sep, string eor); 07915 //}; 07916 07917 07918 07919 #define MCS_B64_DEF_LINE 72 07920 #define MCS_B64_MIN_LINE 4 07921 07922 #define MCS_B64_ENCODE 0 07923 #define MCS_B64_DECODE 1 07924 #define MCS_B64_DECODEINPLACE 2 07925 07931 class B64_Codec { 07932 private: 07933 /* 07934 ** Translation Table as described in RFC1113 07935 */ 07936 static const char* cb64; 07937 07938 /* 07939 ** Translation Table to decode (created by author) 07940 */ 07941 static const char* cd64; 07942 07944 char* bufAllocated; 07945 07947 unsigned int bufsize; 07948 07950 void requireSpace(unsigned int Length); 07951 07953 void freeBuffer(); 07954 07956 char* buf_out; 07957 07959 unsigned int bufused; 07960 07962 char* pin; 07963 07965 char* pout; 07966 07968 char* EOIB; 07969 07971 unsigned int linesize; 07972 07974 unsigned int blocksout; 07975 07976 unsigned char precData[4]; 07977 int precDataCount; 07978 07980 bool eob(); 07981 07983 unsigned char readData(); 07984 07986 void writeData(unsigned char d); 07987 07989 void encodeblock(unsigned char in[3], unsigned char out[4], int len); 07990 07992 void decodeblock(unsigned char in[4], unsigned char out[3]); 07993 07994 public: 07995 07997 B64_Codec(); 07998 08000 ~B64_Codec(); 08001 08002 //DO NOT SET par_buf_out = buf_in (sigsegv) 08003 08014 unsigned int encode(char* buf_in, int Length, char* par_buf_out = NULL, 08015 unsigned int linesize = MCS_B64_DEF_LINE); 08016 08017 //Decode may happen also in the same buffer (set par_buf_out = 08018 //buf_in). 08019 08030 unsigned int decode(char* buf_in, int Length, char* par_buf_out = NULL); 08031 08032 char* buffer(); 08033 unsigned int bufUsed(); 08034 }; 08035 08036 08037 08038 #define MCS_SELECT_READ 0 08039 #define MCS_SELECT_WRITE 1 08040 08041 08042 int Select(int fd, unsigned int sec_timeout, unsigned int usec_timeout, int op); 08043 int Select(int fd[], int nfd, unsigned int sec_timeout, unsigned int usec_timeout, int op); 08044 08045 08046 08047 } //Namespace mcs 08048 #endif //DEF_MCS_HH
![]() |
MCS (My Customizable Server) ver. 0.3.3-alpha3
|