mcs.hh

Go to the documentation of this file.
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

mcslogo

MCS (My Customizable Server) ver. 0.3.3-alpha3
Documentation generated on Thu Mar 22 13:22:23 UTC 2012