diff --git a/cgirig/CGILib.cpp b/cgirig/CGILib.cpp new file mode 100644 index 000000000..a2dcd7be1 --- /dev/null +++ b/cgirig/CGILib.cpp @@ -0,0 +1,128 @@ +//////////////////////////////////////////////////////////////////////////////// +// +// File: +// CGILib.cpp +// Package: +// CGILib +// Author: +// Ignacio A. Macías +// Description: +// Body of the methods defined in "CGILib.h". +// Tested: GCC 2.7.2 +// Tested: MS Visual C++ 4.0 +// Support: +// Please contact if you've any problem. +// Version: +// v1.0 Nov 4 1996 - Main algorithms. +// +//////////////////////////////////////////////////////////////////////////////// + +# include +# include +# include + +# include "CGILib.h" + +//////////////////////////////////////////////////////////////////////////////// + +void CGIParser::parse() throw (CGIException) +{ +type = getEnv("REQUEST_METHOD"); + +if (!type.length()) + throw CGIException("Invalid request method"); + +if (type == "POST") + // Must read data from cin. + { + string conLen(getEnv("CONTENT_LENGTH")); + // EOF is not present. Need the length of the data. + if (!conLen.length()) + throw CGIException("Invalid content length"); + + int length = atoi(conLen.c_str()); + char *buffer = new char[length + 1]; + + if (length > 0) + { + cin.read(buffer,length); + if (cin.bad()) + throw CGIException("Error reading in POST"); + } + buffer[length] = 0; + // Mark the end of the string. + text = buffer; + // Preserve. + delete buffer; + } +else + if (type == "GET") + text = getEnv("QUERY_STRING"); + // The data is obtained from the environment. + else + throw CGIException("Unknown Request Method"); + +size_t ini, end, equ; + +if (text.find_first_of("&=",0) == string::npos) + type = "ISINDEX"; + // ISINDEX queries do not have pairs name-value. +else + // Parses & decodes the string in pairs name-value. + // ONLY standard requests are handled properly. + for ( ini = 0, end = string::npos - 1 ; end != string::npos ; ini = end + 1) + { + end = text.find_first_of('&',ini); + equ = text.find_first_of('=',ini); + data[decode(text.substr(ini, equ - ini))] + = decode(text.substr(equ + 1, end - equ - 1)); + } + +text = decode(text); + // Decodes the global text. +} + +//------------------------------------------------------------------------------ + +// Translates the urlencoded string. + +string CGIParser::decode(const string &cod) const +{ +string dec = cod; + // Buffer. +register unsigned int get; + // Origin index. +register unsigned int set; + // Target index. + +for (get = 0, set = 0 ; get < dec.length() ; set++, get++) + if (dec[get] == '+') + dec[set] = ' '; + // Pluses in spaces. + else + if (dec[get] == '%') + { + dec[set] = hexToChar(dec[get + 1], dec[get + 2]); + get += 2; + } + // Hex values in their represented char. + else + dec[set] = dec[get]; +dec.resize(set); + // Cut the rest of the buffer. +return dec; +} + +//------------------------------------------------------------------------------ + +// Translates a two-char hex representation in his corresponding value. + +char CGIParser::hexToChar(char c1, char c2) const +{ +c1 = tolower(c1); +c2 = tolower(c2); + // Some browsers/servers send uppercase values. +return ((c2 < 'a')? c2 - '0' : c2 - 'a' + 10) + + ((c1 < 'a')? c1 - '0' : c1 - 'a' + 10) * 16; +} + diff --git a/cgirig/CGILib.h b/cgirig/CGILib.h new file mode 100644 index 000000000..26a4a900f --- /dev/null +++ b/cgirig/CGILib.h @@ -0,0 +1,131 @@ +//////////////////////////////////////////////////////////////////////////////// +// +// File: +// CGILib.h +// Package: +// CGILib +// Author: +// Ignacio A. Macías +// Description: +// File header of the CGILib utils. For a description of the use +// of the CGILib library, please browse the "CGILib.html" file. +// Tested: GCC 2.7.2 +// Tested: MS Visual C++ 4.0 +// Support: +// Please contact if you've any problem. +// Version: +// v1.0 Nov 4 1996 - Main algorithms. +// +//////////////////////////////////////////////////////////////////////////////// + +# ifndef CGILIB_H +# define CGILIB_H + +# include + +# include + +typedef less order; + // MSVC++ 4.0 can't handle a direct mapping. +typedef map CGIData; + // CGIData is a STL map which associates the names + // of the form inputs with the user selected values. + +//////////////////////////////////////////////////////////////////////////////// + +// This exception is throwed by the CGILib on any error condition. The text +// contains the description of the problem. + +class CGIException + { + string text; + public: + CGIException(const char *cstr); + string getText() const; + }; + +//////////////////////////////////////////////////////////////////////////////// + +// This is the main class. When called the "parse()" method, the cgi data +// received from the http server is analyzed and is ready for handling with the +// observer functions. + +class CGIParser + { + private: + string text; + // Source text obtained from the server. + string type; + // Type of transaction: "GET", "POST" or "ISINDEX". + CGIData data; + // Map which associates names and values. + public: + void parse() throw (CGIException); + // Parses and decodes the CGI transaction. + string getText() const; + // Returns the transaction's complete text. + string getType() const; + // Returns the type of transaction. See above. + CGIData getData() const; + // Returns the parsed data; + string getEnv(const char *var) const; + // Receives the name of an environment variable and + // returns her value as a string. If the variable is + // not defined, an empty string is defined. + private: + string decode(const string &str) const; + // Decodes the form text. + char hexToChar(char c1, char c2) const; + // Obtains hte char represented by the hex. value c1c2. + }; + +//////////////////////////////////////////////////////////////////////////////// + +// Constructor of the global exception. Receives the text describing the error. + +inline CGIException::CGIException(const char *cstr) + : text(cstr) +{ +} + +//------------------------------------------------------------------------------ + +// Obtains the text of the exception catched. + +inline string CGIException::getText() const +{ +return text; +} + +//////////////////////////////////////////////////////////////////////////////// + +inline string CGIParser::getText() const +{ +return text; +} + +//------------------------------------------------------------------------------ + +inline string CGIParser::getType() const +{ +return type; +} + +//------------------------------------------------------------------------------ + +inline CGIData CGIParser::getData() const +{ +return data; +} + +//------------------------------------------------------------------------------ + +inline string CGIParser::getEnv(const char *var) const +{ +char *aux = getenv(var); +return (aux)? string(aux) : string(); +} + +//////////////////////////////////////////////////////////////////////////////// + +# endif diff --git a/cgirig/RpcRigClient.cpp b/cgirig/RpcRigClient.cpp new file mode 100644 index 000000000..6c4723012 --- /dev/null +++ b/cgirig/RpcRigClient.cpp @@ -0,0 +1,52 @@ +#include "RpcRigClient.h" + +RpcRigClient::RpcRigClient( const char* hostname ) { + + pClient = clnt_create( hostname, RIGPROG, RIGVERS, "udp" ); +}; + + +RpcRigClient::~RpcRigClient() { + + if( pClient ) clnt_destroy( pClient ); +}; + + +const rig_model_t RpcRigClient::getModel() const { + + rig_model_t result = 0; + if( pClient ) { + model_x* pResult = getmodel_1( pClient ); + if( pResult ) { + result = *pResult; + }; + }; + + return result; +}; + + +const freq_t RpcRigClient::getFrequency() const { + + freq_t result = 0; + if( pClient ) { + freq_res* pResult = getfreq_1( RIG_VFO1, pClient ); + if( pResult ) { + result = pResult->freq_res_u.freq.f1; + }; + }; + + return result; +}; + + +void RpcRigClient::setFrequency( const freq_t freq ) { + + if( pClient ) { + freq_arg f; + f.vfo = RIG_VFO1; + f.freq.f1 = freq; + f.freq.f2 = 0; + setfreq_1( f, pClient ); + }; +}; diff --git a/cgirig/RpcRigClient.h b/cgirig/RpcRigClient.h new file mode 100644 index 000000000..21bb18893 --- /dev/null +++ b/cgirig/RpcRigClient.h @@ -0,0 +1,19 @@ +#ifndef __RPCRIGCLIENT_H__ +#define __RPCRIGCLIENT_H__ + +#include "hamlib/rig.h" +#include "rpcrig.h" + +class RpcRigClient { +public: + RpcRigClient( const char* hostname ); + virtual ~RpcRigClient(); + const rig_model_t getModel() const; + const freq_t getFrequency() const; + void setFrequency( const freq_t freq ); + +private: + CLIENT* pClient; +}; + +#endif // __RPCRIGCLIENT_H__ diff --git a/cgirig/cgirig.cpp b/cgirig/cgirig.cpp new file mode 100644 index 000000000..43ef2178d --- /dev/null +++ b/cgirig/cgirig.cpp @@ -0,0 +1,30 @@ +#include "RpcRigClient.h" +#include "stdio.h" +#include "CGILib.h" + +main( int argv, char** argc ) +{ + freq_t freq = 0; + RpcRigClient rig( "localhost" ); + + CGIParser parser; + parser.parse(); + CGIData data = parser.getData(); + + if( data["freq"] != string( "" ) ) + { + freq = atoi( data["freq"].c_str() ); + rig.setFrequency( freq ); + }; + + freq = rig.getFrequency(); + + printf( "Content-type: text/html\r\n\r\n" ); + printf( "hamlib cgirig" ); + printf( "
\n" ); + printf( "The frequency is " ); + printf( " Hz \n", freq ); + printf( "\n" ); + printf( "
\n" ); + printf( "" ); +}