summaryrefslogtreecommitdiffstats
path: root/rascontrol/rasmgr_utils_comm.cc
diff options
context:
space:
mode:
Diffstat (limited to 'rascontrol/rasmgr_utils_comm.cc')
-rw-r--r--rascontrol/rasmgr_utils_comm.cc359
1 files changed, 359 insertions, 0 deletions
diff --git a/rascontrol/rasmgr_utils_comm.cc b/rascontrol/rasmgr_utils_comm.cc
new file mode 100644
index 0000000..01b504c
--- /dev/null
+++ b/rascontrol/rasmgr_utils_comm.cc
@@ -0,0 +1,359 @@
+/*
+* This file is part of rasdaman community.
+*
+* Rasdaman community is free software: you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation, either version 3 of the License, or
+* (at your option) any later version.
+*
+* Rasdaman community is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with rasdaman community. If not, see <http://www.gnu.org/licenses/>.
+*
+* Copyright 2003, 2004, 2005, 2006, 2007, 2008, 2009 Peter Baumann /
+rasdaman GmbH.
+*
+* For more information please see <http://www.rasdaman.org>
+* or contact Peter Baumann via <baumann@rasdaman.com>.
+/
+/**
+ * SOURCE: rasmgr_utils_comm.cc
+ *
+ * MODULE: rascontrol
+ * CLASS: RasMgrClientComm, UserLogin
+ *
+ * PURPOSE:
+ * rasmgr-Client communication and login classes
+ *
+ * COMMENTS:
+ *
+ *
+*/
+
+// trace macros
+#include "debug-clt.hh"
+
+#include "globals.hh"
+
+#include "rasmgr_utils_comm.hh"
+#include "rascontrol.hh"
+
+
+RasMgrClientComm::RasMgrClientComm()
+ {
+ rasmgrSocket=-1;
+ userName[0]= EOS_CHAR;
+ encrPass[0]= EOS_CHAR;
+ rasmgrHost[0]= EOS_CHAR;
+ answerBody=answerMessage;
+ answerMessage[0]= EOS_CHAR;
+ }
+
+RasMgrClientComm::~RasMgrClientComm()
+ {
+ }
+void RasMgrClientComm::setRasMgrHost(const char *rasmgrHost, int rasmgrPort)
+ {
+ strcpy(this->rasmgrHost,rasmgrHost);
+ this->rasmgrPort=rasmgrPort;
+ }
+
+const char* RasMgrClientComm::getRasMgrHost()
+ { return rasmgrHost;
+ }
+
+void RasMgrClientComm::setUserIdentification(const char *userName, const char *encrPass)
+ {
+ strcpy(this->userName,userName);
+ strcpy(this->encrPass,encrPass);
+ }
+
+int RasMgrClientComm::openSocket()
+ {
+ ENTER("RasMgrClientComm::openSocket: enter." );
+
+ // if open already, close beforehand
+ if(rasmgrSocket!=-1)
+ {
+ TALK ("RasMgrClientComm::openSocket: socket was open, closing it." );
+ closeSocket();
+ }
+
+ struct protoent *getprotoptr = getprotoptr=getprotobyname("tcp"); // FIXME: what is this???
+ struct hostent *hostinfo = gethostbyname(rasmgrHost);
+
+ if(hostinfo==NULL)
+ {
+ TALK ("RasMgrClientComm::openSocket: leave. unknown host " << rasmgrHost );
+ return -1;
+ }
+
+ sockaddr_in internetAddress;
+ internetAddress.sin_family=AF_INET;
+ internetAddress.sin_port=htons(rasmgrPort);
+ internetAddress.sin_addr=*(struct in_addr*)hostinfo->h_addr;
+
+ rasmgrSocket=socket(PF_INET,SOCK_STREAM,getprotoptr->p_proto);
+
+ if(rasmgrSocket<0)
+ {
+ int tempErrno = errno;
+ TALK ("RasMgrClientComm::openSocket: leave. error opening socket: " << strerror(tempErrno ) );
+ return -1;
+ }
+
+ if(0>connect(rasmgrSocket,(struct sockaddr*)&internetAddress,sizeof(internetAddress)))
+ {
+ int tempErrno = errno;
+ TALK ("RasMgrClientComm::openSocket: leave. error connecting socket: " << strerror(tempErrno ) );
+ return -1;
+ }
+
+ LEAVE( "RasMgrClientComm::openSocket: leave. ok." );
+ return 0;
+ }
+
+void RasMgrClientComm::closeSocket()
+ {
+ ENTER( "RasMgrClientComm::closeSocket. enter." );
+ if(rasmgrSocket >0)
+ {
+ TALK( "RasMgrClientComm::closeSocket. closing, socket=" << rasmgrSocket );
+ close(rasmgrSocket);
+ rasmgrSocket=-1;
+ }
+ LEAVE( "RasMgrClientComm::closeSocket. leave." );
+ }
+
+int RasMgrClientComm::sendMessage(const char *message)
+ {
+ char request[MAXMSG];
+ int result = COMM_CONT; // was: 0, but this is same value
+
+ ENTER( "RasMgrClientComm::sendMessage: enter. message=" << message );
+
+ sprintf(request, "POST rascontrol HTTP/1.1\r\nAccept: text/plain\r\nUserAgent: rascontrol/2.0");
+ sprintf(request+strlen(request),"\r\nAuthorization: ras %s:%s",userName,encrPass);//"rasadmin","d293a15562d3e70b6fdc5ee452eaed40");
+ sprintf(request+strlen(request),"\r\nContent length: %d\r\n\r\n%s ",strlen(message)+1,message);
+
+ int reqLen=strlen(request)+1; // including final '\0'!!
+ if(writeWholeMessage(rasmgrSocket,request,reqLen)<reqLen)
+ { closeSocket(); // redundant, but ok as safety measure^
+ TALK( "RasMgrClientComm::sendMessage: cannot write, socket closed." );
+ result = COMM_ERR;
+ }
+
+ LEAVE( "RasMgrClientComm::sendMessage: leave. result=" << result );
+ return result;
+ }
+
+const char* RasMgrClientComm::readMessage()
+ {
+ ENTER( "RasMgrClientComm::readMessage: enter." );
+
+ if(readWholeMessage(rasmgrSocket,answerMessage,MAXMSGRASCONTROL)<0)
+ { closeSocket(); // redundant, but ok as safety measure^
+ TALK( "RasMgrClientComm::readMessage: cannot read message from rasmgr." );
+ answerBody=answerMessage;
+ answerMessage[0] = EOS_CHAR;
+ return NULL;
+ }
+
+ answerMessage[MAXMSGRASCONTROL-1]='\0';
+
+ answerBody=strstr(answerMessage,"\r\n\r\n");
+ if(answerBody)
+ { *answerBody=0;
+ answerBody+=4;
+ }
+ else
+ answerBody=answerMessage+strlen(answerMessage);
+
+ LEAVE( "RasMgrClientComm::readMessage: leave. answerBody=" << answerBody );
+ return answerBody;
+ }
+
+const char* RasMgrClientComm::getHeader()
+ {
+ return answerMessage;
+ }
+
+const char* RasMgrClientComm::getBody()
+ {
+ return answerBody;
+ }
+
+// bugfix: socket was not closed in case of send or receive error (was done in subroutines, dispersed)
+int RasMgrClientComm::sendMessageGetAnswer(const char *message, const char **responsePtr)
+ {
+ int result = COMM_CONT; // actually, in the end COMM_* from rasmgr_utils_comm.hh; COMM_CONT means OK
+ const char *rcvMsg = NULL; // message ptr delivered by readMessage()
+
+ ENTER( "RasMgrClientComm::sendMessageGetAnswer: enter. message=" << message );
+
+ TALK( "RasMgrClientComm::sendMessageGetAnswer: opening socket." );
+ result = openSocket(); // open socket to rasmgr
+ if ( result < 0 ) // open went wrong?
+ {
+ TALK( "RasMgrClientComm::sendMessageGetAnswer: cannot open socket." );
+ result = COMM_ERR;
+ }
+ else // we have a good socket, proceed
+ {
+ result = sendMessage(message); // send message to rasmgr, get a COMM_* answer
+ if ( result == COMM_CONT ) // "continue, no error"
+ rcvMsg = readMessage(); // receive result from rasmgr
+ result = ( result == COMM_CONT && rcvMsg != NULL) ? COMM_CONT : COMM_ERR;
+ // FIXME: should be refined
+ TALK( "RasMgrClientComm::sendMessageGetAnswer: closing socket." );
+ closeSocket(); // close socket again, in any case
+ // (due to current implementation, may have been closed before, no problem)
+ }
+
+ if (result == COMM_CONT && rcvMsg != NULL)
+ {
+ rcvMsg = stripBlanks( rcvMsg );
+ *responsePtr = rcvMsg;
+ }
+
+ LEAVE( "RasMgrClientComm::sendMessageGetAnswer: leave. result=" << result );
+ return result;
+ }
+
+// strip leading blanks from message string
+const char* RasMgrClientComm::stripBlanks(const char *r)
+ {
+ if (r==NULL)
+ return NULL;
+
+ const char *s = r;
+ while ( *s == ' ' || *s == '\t' )
+ s++;
+
+ return s;
+ }
+
+int RasMgrClientComm::writeWholeMessage(int socket,char *destBuffer,int buffSize)
+ {
+ ENTER( "RasMgrClientComm::writeWholeMessage: enter. socket=" << socket );
+
+ // we write the whole message, including the ending '\0', which is already in
+ // the buffSize provided by the caller
+ int totalLength=0;
+ int writeNow;
+ while(1)
+ {
+ writeNow = write(socket,destBuffer+totalLength,buffSize-totalLength);
+ if(writeNow == -1)
+ { if(errno == EINTR) continue; // read was interrupted by signal
+
+ LEAVE( "RasMgrClientComm::writeWholeMessage: leave. EINTR." );
+ return -1; // another error
+ }
+ totalLength+=writeNow;
+
+ if( totalLength==buffSize ) break; // THE END
+ }
+
+ LEAVE( "RasMgrClientComm::writeWholeMessage: leave. totalLength=" << totalLength );
+ return totalLength;
+ }
+
+int RasMgrClientComm::readWholeMessage(int socket,char *destBuffer,int buffSize)
+ {
+ ENTER( "RasMgrClientComm::readWholeMessage: enter. socket=" << socket );
+
+ // we read what is comming in until we encounter a '\0'
+ // this is our end-sign.
+ int totalLength=0;
+ int redNow;
+ while(1)
+ {
+ redNow = read(socket,destBuffer+totalLength,buffSize-totalLength);
+ if(redNow == -1)
+ { if(errno == EINTR) continue; // read was interrupted by signal
+
+ LEAVE( "RasMgrClientComm::readWholeMessage: leave. EINTR." );
+ return -1; // another error
+ }
+ totalLength+=redNow;
+
+ if(destBuffer[totalLength-1]==0) break; // THE END
+ }
+
+ LEAVE( "RasMgrClientComm::readWholeMessage: leave. totalLength=" << totalLength );
+ return totalLength;
+ }
+
+
+
+//################################################################################
+UserLogin::UserLogin()
+ {
+ userName[0]= EOS_CHAR;
+ encrPass[0]= EOS_CHAR;
+ }
+UserLogin::~UserLogin()
+ {
+ }
+int UserLogin::interactiveLogin()
+ {
+ std::cerr<<"Login name: ";
+ char *rasp=fgets(userName,99,stdin);
+ if(!rasp) return -1;
+ //strtok(userName,"\r\n"); //removes the ending \r\n
+
+ for(int i=0;userName[i];i++)
+ {
+ if(userName[i]==' ' || userName[i]=='\t' || userName[i]=='\r' || userName[i]=='\n')
+ { userName[i]=0;break;
+ }
+ }
+
+ char *plainPass=getpass(" Password: ");
+ messageDigest(plainPass,encrPass,"MD5");
+ for(int i=0;i<strlen(plainPass);i++) plainPass[i]=0;
+ std::cerr<<std::endl;
+
+ // cout<<"name="<<username<<" pass="<<encrPass<<endl;
+ return 0;
+ }
+int UserLogin::environmentLogin()
+ {
+ char *s=getenv("RASLOGIN");
+ if(s==NULL) return -1;
+ int i;
+
+ for(i=0;i<99 && *s!=':' && *s ;i++,s++)
+ {
+ userName[i]=*s;
+ }
+ userName[i]=0;
+
+ if(*s != ':') return -1;
+
+ s++;
+ strcpy(encrPass,s);
+ return 0;
+ }
+
+int UserLogin::quickLogin()
+ {
+ strcpy(userName,"rasadmin");
+ messageDigest("rasadmin",encrPass,"MD5");
+ return 0;
+ }
+
+const char *UserLogin::getUserName()
+ {
+ return userName;
+ }
+const char *UserLogin::getEncrPass()
+ {
+ return encrPass;
+ }
+