G:/ScriptBasic/source/extensions/curl/interface.c

Go to the documentation of this file.
00001 /* FILE: curlintrfc.c
00002 
00003 This file contains code the CURL interface
00004 
00005 --GNU LGPL
00006 This library is free software; you can redistribute it and/or
00007 modify it under the terms of the GNU Lesser General Public
00008 License as published by the Free Software Foundation; either
00009 version 2.1 of the License, or (at your option) any later version.
00010 
00011 This library is distributed in the hope that it will be useful,
00012 but WITHOUT ANY WARRANTY; without even the implied warranty of
00013 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00014 Lesser General Public License for more details.
00015 
00016 You should have received a copy of the GNU Lesser General Public
00017 License along with this library; if not, write to the Free Software
00018 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
00019 
00020 NTLIBS: libcurl.lib ws2_32.lib
00021 UXLIBS: -lcurl -lssl -lcrypto -ldl -lc
00022 
00023 */
00024 #include <stdio.h>
00025 #include <time.h>
00026 #include <curl/curl.h>
00027 #include "../../basext.h"
00028 
00097 /*
00098 Here you have to list all the CURL options that get char * parameter and are handles
00099 transparently passed to CURL.
00100 
00101 The macro is (re)defined
00102 - in the string parameter declaration,
00103 - initializing the parameters to NULL
00104 - during parameter setting
00105 - and release of memory when finish a curl handle.
00106 
00107 That helps you to maintain new options because this is the only place where the name of
00108 the new option is to be present.
00109 */
00110 #define STRING_OPTIONS \
00111 STRING_OPTION(PROXY)\
00112 STRING_OPTION(URL)\
00113 STRING_OPTION(USERPWD)\
00114 STRING_OPTION(PROXYUSERPWD)\
00115 STRING_OPTION(RANGE)\
00116 STRING_OPTION(REFERER)\
00117 STRING_OPTION(USERAGENT)\
00118 STRING_OPTION(FTPPORT)\
00119 STRING_OPTION(COOKIE)\
00120 STRING_OPTION(SSLCERT)\
00121 STRING_OPTION(SSLCERTPASSWD)\
00122 STRING_OPTION(COOKIEFILE)\
00123 STRING_OPTION(CUSTOMREQUEST)\
00124 STRING_OPTION(INTERFACE)\
00125 STRING_OPTION(KRB4LEVEL)\
00126 STRING_OPTION(WRITEINFO)\
00127 STRING_OPTION(CAINFO)\
00128 STRING_OPTION(RANDOM_FILE)\
00129 STRING_OPTION(EGDSOCKET)\
00130 
00131 typedef struct _CurlConnection {
00132   CURL          *myConnection;
00133   FILE          *fp;        /* file pointer to file where we read from or store the result             */
00134   FILE          *hfp;       /* header file pointer where the header is stored                          */
00135   char          errorbuffer[CURL_ERROR_SIZE];
00136                             /* buffer to store the error messages from the underlying CURL system      */
00137   int           fWasPerform;
00138   char          *pszBuffer; /* buffer to store the downloaded file when not saved to disk              */
00139   unsigned long cbBuffer;   /* characters in the buffer                                                */
00140   unsigned long dwBuffer;   /* allocated size of the buffer                                            */
00141   unsigned long dwStepBf;   /* increase step when fubber is full                                       */
00142   char          *pszInText; /* the text to upload                                                      */
00143   unsigned long dwInText;   /* the length of the text                                                  */
00144   unsigned long cbInText;   /* the number of characters already sent up                                */
00145 
00146   pSupportTable pSt;        /* this is needed to get back to the interpreter
00147                                environment in the function buffercollect                               */
00148 
00149 
00150 #define STRING_OPTION(X) char *psz##X;
00151 STRING_OPTIONS
00152 #undef STRING_OPTION
00153 
00154   char *pszPOSTFIELDS;
00155   struct _CurlConnection *next,*prev;
00156   struct curl_slist *pHeaderLines;
00157   struct curl_slist *pQuote;
00158   struct curl_slist *pPostQuote;
00159   struct HttpPost *firstitem, *lastitem;
00160   } CurlConnection,  *pCurlConnection;
00161 
00162 typedef struct _CurlClass {
00163   void *HandleArray;
00164   pCurlConnection pFirstConnection;
00165   } CurlClass,*pCurlClass;
00166 
00167 SUPPORT_MULTITHREAD
00168 
00169 besVERSION_NEGOTIATE
00170 
00171   return (int)INTERFACE_VERSION;
00172 
00173 besEND
00174 
00175 besSUB_SHUTDOWN
00176   curl_global_cleanup();
00177 besEND
00178 
00179 besSUB_START
00180   pCurlClass pCurl;
00181   /* This macro increments the thread counter used to help to keep this library in memory 
00182      even those times when the process is idle and no ScriptBasic threads are running. */
00183   INC_THREAD_COUNTER
00184   /* A process level initialization of the module should take place in this function because
00185      the call-back support functions are not accessible when the  function DllMan or _init is
00186      called. On the other hand it has to initialize only once.
00187   */
00188   INITLOCK /* lock the init mutex */
00189   if( iFirst ){ /* if it was not initialized yet*/
00190 
00191     curl_global_init(CURL_GLOBAL_ALL);
00192 
00193     iFirst = 0;/* successful initialization was done*/
00194     }
00195   INITUNLO /* unlock the init mutex */
00196 
00197   besMODULEPOINTER = besALLOC(sizeof(CurlClass));
00198   if( besMODULEPOINTER == NULL )return 0;
00199   pCurl = (pCurlClass)besMODULEPOINTER;
00200   pCurl->pFirstConnection = NULL;
00201   pCurl->HandleArray = NULL;
00202   return COMMAND_ERROR_SUCCESS;
00203 besEND
00204 
00205 besSUB_FINISH
00206   pCurlClass pCurl;
00207   pCurlConnection pCon;
00208 
00209   pCurl = (pCurlClass)besMODULEPOINTER;
00210   if( pCurl != NULL ){
00211     for( pCon = pCurl->pFirstConnection ; pCon ; pCon = pCon->next ){
00212       if( pCon->pHeaderLines ){
00213         curl_slist_free_all(pCon->pHeaderLines);
00214         pCon->pHeaderLines = NULL;
00215         }
00216       if( pCon->pQuote ){
00217         curl_slist_free_all(pCon->pQuote);
00218         pCon->pQuote = NULL;
00219         }
00220       if( pCon->pPostQuote ){
00221         curl_slist_free_all(pCon->pPostQuote);
00222         pCon->pQuote = NULL;
00223         }
00224       if( pCon->firstitem ){
00225         curl_formfree(pCon->firstitem);
00226         pCon->firstitem = pCon->lastitem = NULL;
00227         }
00228       curl_easy_cleanup(pCon->myConnection);
00229       }
00230     besHandleDestroyHandleArray(pCurl->HandleArray);
00231     }
00232   return 0;
00233 besEND
00234 
00235 #define GET_CURL_HANDLE \
00236   pCurl = (pCurlClass)besMODULEPOINTER;\
00237   Argument = besARGUMENT(1);\
00238   besDEREFERENCE(Argument);\
00239   if( ! Argument )return EX_ERROR_TOO_FEW_ARGUMENTS;\
00240   pCon = besHandleGetPointer(pCurl->HandleArray,besGETLONGVALUE(Argument));\
00241   if( pCon == NULL )return COMMAND_ERROR_ARGUMENT_RANGE;
00242 
00243 
00263 besFUNCTION(sb_curl_init)
00264   pCurlClass pCurl;
00265   pCurlConnection pCon;
00266   long res;
00267 
00268   pCurl = besMODULEPOINTER;
00269 
00270   /* allocate the space to store the new connection */
00271   pCon = besALLOC(sizeof(CurlConnection));
00272   if( pCon == NULL )return COMMAND_ERROR_MEMORY_LOW;
00273 
00274   /* get the connection */
00275   pCon->myConnection = curl_easy_init();
00276   if( pCon->myConnection == NULL ){
00277     besFREE(pCon);
00278     return COMMAND_ERROR_MEMORY_LOW;
00279     }
00280 
00281   pCon->fp           = NULL; /* no output file opened                                           */
00282   pCon->hfp          = NULL; /* no input file opened                                            */
00283   pCon->fWasPerform  = 0;    /* no perform was done yet (check before calling curl_easy_getinfo */
00284   pCon->pHeaderLines = NULL; /* no extra header lines                                           */
00285   pCon->pQuote       = NULL; /* no QUOTE commands for FTP                                       */
00286   pCon->pPostQuote   = NULL; /* no post QUOTE commands for FTP                                  */
00287   pCon->firstitem    = NULL; /* POST parameters first item                                      */
00288   pCon->lastitem     = NULL; /* POST parameters last item                                       */
00289 
00290   pCon->pszBuffer    = NULL; /* no buffer is allocated by default                               */
00291   pCon->dwBuffer     = 0;    /* as I said: no buffer is allocated by default                    */
00292   pCon->cbBuffer     = 0;    /* there is zero number of chars in the nonallocated buffer        */
00293   pCon->dwStepBf     = 0;    /* by default allocate space as bytes come                         */
00294   pCon->pszInText    = NULL; /* no text is stored for upload                                    */
00295   pCon->dwInText     = 0;    /* as I said: you know                                             */
00296   pCon->cbInText     = 0;    /* no bytes were sent from the nonexistent infile text             */
00297 
00298   pCon->pSt          = pSt;
00299 
00300 #define STRING_OPTION(X) pCon->psz##X = NULL;
00301 STRING_OPTIONS
00302 #undef STRING_OPTION
00303   pCon->pszPOSTFIELDS = NULL;
00304 
00305   memset(pCon->errorbuffer,0,CURL_ERROR_SIZE);
00306   res = curl_easy_setopt(pCon->myConnection, CURLOPT_ERRORBUFFER, pCon->errorbuffer);
00307   if( res )return 0x00081100+res;
00308 
00309   /* link the new connection tot he head of the list of connections */
00310   pCon->next               = pCurl->pFirstConnection;
00311   pCon->prev               = NULL;
00312   if( pCon->next )
00313     pCon->next->prev       = pCon;
00314   pCurl->pFirstConnection  = pCon;
00315 
00316   besALLOC_RETURN_LONG;
00317   LONGVALUE(besRETURNVALUE) = besHandleGetHandle(pCurl->HandleArray,pCon);
00318   return COMMAND_ERROR_SUCCESS;
00319 
00320 besEND
00321 
00322 static size_t buffersend(char *buffer, size_t size, size_t count, pCurlConnection pCon){
00323   unsigned long dwChunkSize;
00324 
00325   dwChunkSize = size*count;
00326   if( dwChunkSize > pCon->dwInText - pCon->cbInText )dwChunkSize = pCon->dwInText - pCon->cbInText;
00327   memcpy(buffer,pCon->pszInText,dwChunkSize);
00328   pCon->cbInText += dwChunkSize;
00329   return dwChunkSize;
00330   }
00331 
01226 besFUNCTION(sb_curl_option)
01227   pCurlClass pCurl;
01228   pCurlConnection pCon;
01229   VARIABLE Argument;
01230   char *pszOption;
01231   long value;
01232   long res;
01233   struct curl_slist *pNewList;
01234 
01235   GET_CURL_HANDLE
01236   /* get the option name */
01237   Argument = besARGUMENT(2);
01238   besDEREFERENCE(Argument);
01239   if( Argument == NULL )return COMMAND_ERROR_ARGUMENT_RANGE;
01240   Argument = besCONVERT2STRING(Argument);
01241 
01242 #define CHECK_OPTION(X) if( STRLEN(Argument) == strlen(#X) && memcmp(STRINGVALUE(Argument),#X,strlen(#X)) == 0 )
01243 
01244   CHECK_OPTION(FILE){
01245     Argument = besARGUMENT(3);
01246     besDEREFERENCE(Argument);
01247     if( Argument == NULL )return COMMAND_ERROR_ARGUMENT_RANGE;
01248     besCONVERT2ZCHAR(Argument,pszOption);
01249     if( pCon->fp )besFCLOSE(pCon->fp);
01250     pCon->fp = besFOPEN(pszOption,"wb");
01251     if( pCon->fp == NULL )return COMMAND_ERROR_FILE_CANNOT_BE_OPENED;
01252     res = curl_easy_setopt(pCon->myConnection,CURLOPT_FILE,pCon->fp);
01253     if( res == CURLE_OK )res = curl_easy_setopt(pCon->myConnection,CURLOPT_WRITEFUNCTION,pSt->fwrite);
01254     if( res == CURLE_OK ) return COMMAND_ERROR_SUCCESS;
01255     return 0x00081100+res;
01256     }
01257 
01258   CHECK_OPTION(HEADERFILE){
01259     Argument = besARGUMENT(3);
01260     besDEREFERENCE(Argument);
01261     if( Argument == NULL )return COMMAND_ERROR_ARGUMENT_RANGE;
01262     besCONVERT2ZCHAR(Argument,pszOption);
01263     if( pCon->hfp )besFCLOSE(pCon->hfp);
01264     pCon->hfp = besFOPEN(pszOption,"wb");
01265     if( pCon->hfp == NULL )return COMMAND_ERROR_FILE_CANNOT_BE_OPENED;
01266     res = curl_easy_setopt(pCon->myConnection,CURLOPT_WRITEHEADER,pCon->hfp);
01267     if( res == CURLE_OK )res = curl_easy_setopt(pCon->myConnection,CURLOPT_HEADERFUNCTION,pSt->fwrite);
01268     if( res == CURLE_OK ) return COMMAND_ERROR_SUCCESS;
01269     return 0x00081100+res;
01270     }
01271 
01272   CHECK_OPTION(INFILE){
01273     Argument = besARGUMENT(3);
01274     besDEREFERENCE(Argument);
01275     if( Argument == NULL )return COMMAND_ERROR_ARGUMENT_RANGE;
01276     besCONVERT2ZCHAR(Argument,pszOption);
01277     if( pCon->fp )besFCLOSE(pCon->fp);
01278     besFREE(pCon->pszInText);
01279 
01280     /* if there was any previous but not used string: do not loose memory! */
01281     pCon->pszInText = NULL;
01282     pCon->cbInText = 0;
01283     pCon->dwInText = 0;
01284 
01285     pCon->fp = besFOPEN(pszOption,"rb");
01286     if( pCon->fp == NULL )return COMMAND_ERROR_FILE_CANNOT_BE_OPENED;
01287     res = curl_easy_setopt(pCon->myConnection,CURLOPT_INFILE,pCon->fp);
01288     if( res == CURLE_OK )res = curl_easy_setopt(pCon->myConnection,CURLOPT_READFUNCTION,pSt->fread);
01289     if( res == CURLE_OK )res = curl_easy_setopt(pCon->myConnection,CURLOPT_INFILESIZE,besSIZE(pszOption));
01290     if( res == CURLE_OK ) return COMMAND_ERROR_SUCCESS;
01291     return 0x00081100+res;
01292     }
01293 
01294   CHECK_OPTION(INTEXT){
01295     Argument = besARGUMENT(3);
01296     besDEREFERENCE(Argument);
01297     if( Argument == NULL )return COMMAND_ERROR_ARGUMENT_RANGE;
01298     Argument = besCONVERT2STRING(Argument);
01299     if( pCon->fp )besFCLOSE(pCon->fp);
01300 
01301     /* if there was any previous but not used string: do not loose memory! */
01302     besFREE(pCon->pszInText);
01303     pCon->pszInText = NULL;
01304     pCon->cbInText = 0;
01305     pCon->dwInText = 0;
01306 
01307     pCon->pszInText = besALLOC(STRLEN(Argument));
01308     if( pCon->pszInText == NULL )return COMMAND_ERROR_MEMORY_LOW;
01309     pCon->dwInText = STRLEN(Argument);
01310     memcpy(pCon->pszInText,STRINGVALUE(Argument),pCon->dwInText);
01311     pCon->cbInText = 0;
01312     res = curl_easy_setopt(pCon->myConnection,CURLOPT_INFILE,pCon);
01313     if( res == CURLE_OK )res = curl_easy_setopt(pCon->myConnection,CURLOPT_READFUNCTION,buffersend);
01314     if( res == CURLE_OK )res = curl_easy_setopt(pCon->myConnection,CURLOPT_INFILESIZE,pCon->dwInText);
01315     if( res == CURLE_OK ) return COMMAND_ERROR_SUCCESS;
01316     return 0x00081100+res;
01317     }
01318 
01319   CHECK_OPTION(POSTFIELDS){
01320     Argument = besARGUMENT(3);
01321     besDEREFERENCE(Argument);
01322     if( Argument == NULL )return COMMAND_ERROR_ARGUMENT_RANGE;
01323     Argument = besCONVERT2STRING(Argument);
01324     pCon->pszPOSTFIELDS = besALLOC(STRLEN(Argument));
01325     if( pCon->pszPOSTFIELDS == NULL )return COMMAND_ERROR_MEMORY_LOW;
01326     memcpy(pCon->pszPOSTFIELDS,STRINGVALUE(Argument),STRLEN(Argument));
01327     res = curl_easy_setopt(pCon->myConnection,CURLOPT_POSTFIELDS,pCon->pszPOSTFIELDS);
01328     if( res == CURLE_OK )res = curl_easy_setopt(pCon->myConnection,CURLOPT_POSTFIELDSIZE,STRLEN(Argument));
01329     if( res == CURLE_OK ) return COMMAND_ERROR_SUCCESS;
01330     return 0x00081100+res;
01331     }
01332 
01333   CHECK_OPTION(CLOSEPOLICY){
01334     Argument = besARGUMENT(3);
01335     besDEREFERENCE(Argument);
01336     if( Argument == NULL )return COMMAND_ERROR_ARGUMENT_RANGE;
01337     Argument = besCONVERT2STRING(Argument);
01338     if( STRLEN(Argument) == 3 && memcmp(STRINGVALUE(Argument),"OLD",3) == 0 ){
01339       value = CURLCLOSEPOLICY_OLDEST;
01340       }else
01341     if( STRLEN(Argument) == 5 && memcmp(STRINGVALUE(Argument),"FRESH",5) == 0 ){
01342       value = CURLCLOSEPOLICY_LEAST_RECENTLY_USED;
01343       }else return COMMAND_ERROR_ARGUMENT_RANGE;
01344     res = curl_easy_setopt(pCon->myConnection,CURLOPT_CLOSEPOLICY,value);
01345     if( res == CURLE_OK ) return COMMAND_ERROR_SUCCESS;
01346     return 0x00081100+res;
01347     }
01348 
01349   CHECK_OPTION(TIMECONDITION){
01350     Argument = besARGUMENT(3);
01351     besDEREFERENCE(Argument);
01352     if( Argument == NULL )return COMMAND_ERROR_ARGUMENT_RANGE;
01353     Argument = besCONVERT2STRING(Argument);
01354     if( STRLEN(Argument) == 10 && memcmp(STRINGVALUE(Argument),"IFMODSINCE",10) == 0 ){
01355       value = TIMECOND_IFMODSINCE;
01356       }else
01357     if( STRLEN(Argument) == 12 && memcmp(STRINGVALUE(Argument),"IFUNMODSINCE",12) == 0 ){
01358       value = TIMECOND_IFUNMODSINCE;
01359       }else return COMMAND_ERROR_ARGUMENT_RANGE;
01360     res = curl_easy_setopt(pCon->myConnection,CURLOPT_TIMECONDITION,value);
01361     if( res == CURLE_OK ) return COMMAND_ERROR_SUCCESS;
01362     return 0x00081100+res;
01363     }
01364 
01365   CHECK_OPTION(HTTPHEADER){
01366     Argument = besARGUMENT(3);
01367     besDEREFERENCE(Argument);
01368     if( Argument == NULL )return COMMAND_ERROR_ARGUMENT_RANGE;
01369     besCONVERT2ZCHAR(Argument,pszOption);
01370     pNewList = curl_slist_append(pCon->pHeaderLines,pszOption);
01371     besFREE(pszOption);
01372     if( pNewList == NULL ){
01373       curl_slist_free_all(pCon->pHeaderLines);
01374       pCon->pHeaderLines = NULL;
01375       return COMMAND_ERROR_MEMORY_LOW;
01376       }
01377     pCon->pHeaderLines = pNewList;
01378     return COMMAND_ERROR_SUCCESS;
01379     }
01380 
01381   CHECK_OPTION(QUOTE){
01382     Argument = besARGUMENT(3);
01383     besDEREFERENCE(Argument);
01384     if( Argument == NULL )return COMMAND_ERROR_ARGUMENT_RANGE;
01385     besCONVERT2ZCHAR(Argument,pszOption);
01386     pNewList = curl_slist_append(pCon->pQuote,pszOption);
01387     besFREE(pszOption);
01388     if( pNewList == NULL ){
01389       curl_slist_free_all(pCon->pQuote);
01390       pCon->pQuote = NULL;
01391       return COMMAND_ERROR_MEMORY_LOW;
01392       }
01393     pCon->pQuote = pNewList;
01394     return COMMAND_ERROR_SUCCESS;
01395     }
01396 
01397   CHECK_OPTION(POSTQUOTE){
01398     Argument = besARGUMENT(3);
01399     besDEREFERENCE(Argument);
01400     if( Argument == NULL )return COMMAND_ERROR_ARGUMENT_RANGE;
01401     besCONVERT2ZCHAR(Argument,pszOption);
01402     pNewList = curl_slist_append(pCon->pPostQuote,pszOption);
01403     besFREE(pszOption);
01404     if( pNewList == NULL ){
01405       curl_slist_free_all(pCon->pPostQuote);
01406       pCon->pPostQuote = NULL;
01407       return COMMAND_ERROR_MEMORY_LOW;
01408       }
01409     pCon->pPostQuote = pNewList;
01410     return COMMAND_ERROR_SUCCESS;
01411     }
01412 
01413   /* delete all gathered HTTP header lines that may have remained from the previous network action */
01414   CHECK_OPTION(NOHTTPHEADER){
01415     curl_slist_free_all(pCon->pHeaderLines);
01416     pCon->pHeaderLines = NULL;
01417     return COMMAND_ERROR_SUCCESS;
01418     }
01419 
01420   /* delete all previously gathered FTP quote commands */
01421   CHECK_OPTION(NOQUOTE){
01422     curl_slist_free_all(pCon->pQuote);
01423     pCon->pQuote = NULL;
01424     return COMMAND_ERROR_SUCCESS;
01425     }
01426 
01427   /* delete all previously gathered FTP post quote commands */
01428   CHECK_OPTION(NOPOSTQUOTE){
01429     curl_slist_free_all(pCon->pPostQuote);
01430     pCon->pPostQuote = NULL;
01431     return COMMAND_ERROR_SUCCESS;
01432     }
01433 
01434   CHECK_OPTION(HTTPPOST){
01435     Argument = besARGUMENT(3);
01436     besDEREFERENCE(Argument);
01437     if( Argument == NULL )return COMMAND_ERROR_ARGUMENT_RANGE;
01438     besCONVERT2ZCHAR(Argument,pszOption);
01439     curl_formparse(pszOption,&(pCon->firstitem),&(pCon->lastitem));
01440     besFREE(pszOption);
01441     return COMMAND_ERROR_SUCCESS;
01442     }
01443 
01444   CHECK_OPTION(BUFFER_SIZE){
01445     value=0;
01446     if( besARGNR >= 3 ){
01447       Argument = besARGUMENT(3);
01448       besDEREFERENCE(Argument);
01449       value = besGETLONGVALUE(Argument);
01450       }
01451     pCon->dwStepBf = value;
01452     return COMMAND_ERROR_SUCCESS;
01453     }
01454 
01455 #define STRING_OPTION(X) \
01456   CHECK_OPTION(X){\
01457     Argument = besARGUMENT(3);\
01458     besDEREFERENCE(Argument);\
01459     if( Argument == NULL )return COMMAND_ERROR_ARGUMENT_RANGE;\
01460     if( pCon->psz##X )besFREE(pCon->psz##X);\
01461     besCONVERT2ZCHAR(Argument,pCon->psz##X);\
01462     res = curl_easy_setopt(pCon->myConnection,CURLOPT_##X,pCon->psz##X);\
01463     if( res == CURLE_OK ) return COMMAND_ERROR_SUCCESS;\
01464     return 0x00081100+res;\
01465     }
01466 STRING_OPTIONS
01467 #undef STRING_OPTION
01468 
01469 #define HANDLE_FLAG(X)\
01470   CHECK_OPTION(X){\
01471     value=1;\
01472     if( besARGNR >= 3 ){\
01473       Argument = besARGUMENT(3);\
01474       besDEREFERENCE(Argument);\
01475       value = besGETLONGVALUE(Argument);\
01476       }\
01477     res = curl_easy_setopt(pCon->myConnection,CURLOPT_##X,value);\
01478     if( res == CURLE_OK ) return COMMAND_ERROR_SUCCESS;\
01479     return 0x00081100+res;\
01480     }
01481 
01482 #define HANDLE_LONG(X)\
01483   CHECK_OPTION(X){\
01484     value=0;\
01485     if( besARGNR >= 3 ){\
01486       Argument = besARGUMENT(3);\
01487       besDEREFERENCE(Argument);\
01488       value = besGETLONGVALUE(Argument);\
01489       }\
01490     res = curl_easy_setopt(pCon->myConnection,CURLOPT_##X,value);\
01491     if( res == CURLE_OK ) return COMMAND_ERROR_SUCCESS;\
01492     return 0x00081100+res;\
01493     }
01494 
01495 HANDLE_FLAG(HTTPPROXYTUNNEL)
01496 HANDLE_FLAG(VERBOSE)
01497 HANDLE_FLAG(NOPROGRESS)
01498 HANDLE_FLAG(NOBODY)
01499 HANDLE_FLAG(FAILONERROR)
01500 HANDLE_FLAG(UPLOAD)
01501 HANDLE_FLAG(POST)
01502 HANDLE_FLAG(FTPLISTONLY)
01503 HANDLE_FLAG(FTPAPPEND)
01504 HANDLE_FLAG(NETRC)
01505 HANDLE_FLAG(FOLLOWLOCATION)
01506 HANDLE_FLAG(TRANSFERTEXT)
01507 HANDLE_FLAG(PUT)
01508 HANDLE_FLAG(HEADER)
01509 HANDLE_FLAG(SSL_VERIFYPEER)
01510 HANDLE_FLAG(FILETIME)
01511 HANDLE_FLAG(FRESH_CONNECT)
01512 HANDLE_FLAG(FORBID_REUSE)
01513 HANDLE_FLAG(HTTPGET)
01514 HANDLE_FLAG(CRLF)
01515 
01516 HANDLE_LONG(TIMEOUT)
01517 HANDLE_LONG(LOW_SPEED_LIMIT)
01518 HANDLE_LONG(LOW_SPEED_TIME)
01519 HANDLE_LONG(RESUME_FROM)
01520 HANDLE_LONG(SSLVERSION)
01521 HANDLE_LONG(TIMEVALUE)
01522 HANDLE_LONG(MAXREDIRS)
01523 HANDLE_LONG(MAXCONNECTS)
01524 HANDLE_LONG(CONNECTTIMEOUT)
01525 HANDLE_LONG(PROXYPORT)
01526 
01527   besCONVERT2ZCHAR(Argument,pszOption);
01528   sprintf(pCon->errorbuffer,"CURL Error in 'curl::option'. Unkown option \"%s\"",pszOption);
01529   besFREE(pszOption);
01530   return 0x00081001;
01531 besEND
01532 
01533 static size_t buffercollect(char *buffer,size_t size,size_t count,pCurlConnection pCon){
01534   long dwChunkSize;
01535   pSupportTable pSt;
01536   char *pszNewBuffer;
01537   unsigned long dwNewSize;
01538 
01539   /* set the pSt variable so we can easily use the bes macros */
01540   pSt = pCon->pSt;
01541 
01542   dwChunkSize = size*count;
01543 
01544   /* if the buffer can not store the new chunk then reallocate it */
01545   if( dwChunkSize+pCon->cbBuffer > pCon->dwBuffer ){
01546     dwNewSize = pCon->dwBuffer+pCon->dwStepBf;
01547     if( dwNewSize < dwChunkSize+pCon->cbBuffer )dwNewSize = dwChunkSize+pCon->cbBuffer;
01548     pszNewBuffer = besALLOC(dwNewSize);
01549     if( pszNewBuffer == NULL )return 0;
01550     pCon->dwBuffer = dwNewSize;
01551     /* copy the characters that were already read into the new buffer */
01552     memcpy(pszNewBuffer,pCon->pszBuffer,pCon->cbBuffer);
01553     besFREE(pCon->pszBuffer);
01554     pCon->pszBuffer = pszNewBuffer;
01555     }
01556 
01557   memcpy(pCon->pszBuffer+pCon->cbBuffer,buffer,dwChunkSize);
01558   pCon->cbBuffer += dwChunkSize;
01559   return dwChunkSize;
01560   }
01561 
01575 besFUNCTION(sb_curl_perform)
01576   pCurlClass pCurl;
01577   pCurlConnection pCon;
01578   VARIABLE Argument;
01579   int res;
01580 
01581   GET_CURL_HANDLE
01582 
01583   /* if there were header lines specified then apply them. */
01584   if( pCon->pHeaderLines ){
01585     curl_easy_setopt(pCon->myConnection,CURLOPT_HTTPHEADER,pCon->pHeaderLines);
01586     }
01587 
01588   if( pCon->pQuote ){
01589     curl_easy_setopt(pCon->myConnection,CURLOPT_QUOTE,pCon->pQuote);
01590     }
01591 
01592   if( pCon->pPostQuote ){
01593     curl_easy_setopt(pCon->myConnection,CURLOPT_POSTQUOTE,pCon->pPostQuote);
01594     }
01595 
01596   if( pCon->firstitem ){
01597     curl_easy_setopt(pCon->myConnection,CURLOPT_HTTPPOST,pCon->firstitem);
01598     }
01599 
01600   /* if there was no file specified for the download than we have to return the result as string */
01601   if( pCon->fp == NULL ){
01602     res = curl_easy_setopt(pCon->myConnection,CURLOPT_FILE,pCon);
01603     if( res == CURLE_OK )res = curl_easy_setopt(pCon->myConnection,CURLOPT_WRITEFUNCTION,buffercollect);
01604     }
01605 
01606   res = curl_easy_perform(pCon->myConnection);
01607 
01608   /* if there was no download file specified and there is some downloaded string then we have to return it */
01609   if( pCon->cbBuffer > 0 ){
01610     besALLOC_RETURN_STRING(pCon->cbBuffer);
01611     memcpy(STRINGVALUE(besRETURNVALUE),pCon->pszBuffer,STRLEN(besRETURNVALUE));
01612     besFREE(pCon->pszBuffer);
01613     pCon->pszBuffer = NULL;
01614     pCon->dwBuffer = 0;
01615     pCon->cbBuffer = 0;
01616     }
01617 
01618   if( pCon->pszInText ){
01619     besFREE(pCon->pszInText);
01620     pCon->pszInText = NULL;
01621     pCon->cbInText = 0;
01622     pCon->dwInText = 0;
01623     }
01624 
01625   if( res == CURLE_OK ){
01626     pCon->fWasPerform = 1;
01627     return COMMAND_ERROR_SUCCESS;
01628     }
01629 
01630   return 0x00081100+res;;
01631 
01632 besEND
01633 
01734 besFUNCTION(sb_curl_info)
01735   pCurlClass pCurl;
01736   pCurlConnection pCon;
01737   VARIABLE Argument;
01738   int res;
01739   char *pszOption;
01740   long lOption;
01741   double dOption;
01742 
01743   GET_CURL_HANDLE
01744 
01745   if(  ! pCon->fWasPerform ){
01746     sprintf(pCon->errorbuffer,"CURL Error: no successful curl::perform was called before curl::info");
01747     return 0x00081002;
01748     }
01749   /* get the option name */
01750   Argument = besARGUMENT(2);
01751   besDEREFERENCE(Argument);
01752   if( Argument == NULL )return COMMAND_ERROR_ARGUMENT_RANGE;
01753   Argument = besCONVERT2STRING(Argument);
01754 
01755 #define CHECK_INFOPT_SZ(X) if( STRLEN(Argument) == strlen(#X) && memcmp(STRINGVALUE(Argument),#X,strlen(#X)) == 0 ){\
01756     res = curl_easy_getinfo(pCon->myConnection,CURLINFO_##X,&pszOption);\
01757     besALLOC_RETURN_STRING(strlen(pszOption));\
01758     memcpy(STRINGVALUE(besRETURNVALUE),pszOption,STRLEN(besRETURNVALUE));\
01759     return COMMAND_ERROR_SUCCESS;\
01760     }
01761 #define CHECK_INFOPT_L(X) if( STRLEN(Argument) == strlen(#X) && memcmp(STRINGVALUE(Argument),#X,strlen(#X)) == 0 ){\
01762     res = curl_easy_getinfo(pCon->myConnection,CURLINFO_##X,&lOption);\
01763     besALLOC_RETURN_LONG;\
01764     LONGVALUE(besRETURNVALUE) = lOption;\
01765     return COMMAND_ERROR_SUCCESS;\
01766     }
01767 #define CHECK_INFOPT_D(X) if( STRLEN(Argument) == strlen(#X) && memcmp(STRINGVALUE(Argument),#X,strlen(#X)) == 0 ){\
01768     res = curl_easy_getinfo(pCon->myConnection,CURLINFO_##X,&dOption);\
01769     besALLOC_RETURN_DOUBLE;\
01770     DOUBLEVALUE(besRETURNVALUE) = dOption;\
01771     return COMMAND_ERROR_SUCCESS;\
01772     }
01773 
01774 CHECK_INFOPT_SZ(EFFECTIVE_URL)
01775 CHECK_INFOPT_L (HTTP_CODE)
01776 CHECK_INFOPT_L (FILETIME)
01777 CHECK_INFOPT_D (TOTAL_TIME)
01778 CHECK_INFOPT_D (NAMELOOKUP_TIME)
01779 CHECK_INFOPT_D (CONNECT_TIME)
01780 CHECK_INFOPT_D (PRETRANSFER_TIME)
01781 CHECK_INFOPT_D (SIZE_UPLOAD)
01782 CHECK_INFOPT_D (SIZE_DOWNLOAD)
01783 CHECK_INFOPT_D (SPEED_DOWNLOAD)
01784 CHECK_INFOPT_D (SPEED_UPLOAD)
01785 CHECK_INFOPT_L (HEADER_SIZE)
01786 CHECK_INFOPT_L (REQUEST_SIZE)
01787 CHECK_INFOPT_L (SSL_VERIFYRESULT)
01788 CHECK_INFOPT_D (CONTENT_LENGTH_DOWNLOAD)
01789 CHECK_INFOPT_D (CONTENT_LENGTH_UPLOAD)
01790 
01791   besCONVERT2ZCHAR(Argument,pszOption);
01792   sprintf(pCon->errorbuffer,"CURL Error in 'curl::info'. Unkown info type \"%s\"",pszOption);
01793   besFREE(pszOption);
01794   return 0x00081003;
01795 
01796 besEND
01797 
01817 besFUNCTION(sb_curl_finish)
01818   pCurlClass pCurl;
01819   pCurlConnection pCon;
01820   VARIABLE Argument;
01821 
01822   GET_CURL_HANDLE
01823 
01824   curl_easy_cleanup(pCon->myConnection);
01825 
01826   if( pCon->pHeaderLines ){
01827     curl_slist_free_all(pCon->pHeaderLines);
01828     pCon->pHeaderLines = NULL;
01829     }
01830 
01831   if( pCon->pQuote ){
01832     curl_slist_free_all(pCon->pQuote);
01833     pCon->pQuote = NULL;
01834     }
01835 
01836   if( pCon->pPostQuote ){
01837     curl_slist_free_all(pCon->pPostQuote);
01838     pCon->pPostQuote = NULL;
01839     }
01840 
01841   if( pCon->firstitem ){
01842     curl_formfree(pCon->firstitem);
01843     pCon->firstitem = pCon->lastitem = NULL;
01844     }
01845 
01846   if( pCon->fp )besFCLOSE(pCon->fp);
01847 
01848   /* unlink the handle from the list */
01849   if( pCon->prev )
01850     pCon->prev->next       = pCon->next;
01851   else
01852     pCurl->pFirstConnection = pCon->next;
01853 
01854   if( pCon->next )
01855     pCon->next->prev     = pCon->prev;
01856 
01857 #define STRING_OPTION(X) if( pCon->psz##X )besFREE(pCon->psz##X);
01858 STRING_OPTIONS
01859 #undef STRING_OPTION
01860   if( pCon->pszPOSTFIELDS )besFREE(pCon->pszPOSTFIELDS);
01861 
01862   /* free the connection hanlde structure */
01863   besFREE(pCon);
01864 
01865 besEND
01866 
01880 besFUNCTION(sb_curl_error)
01881   pCurlClass pCurl;
01882   pCurlConnection pCon;
01883   VARIABLE Argument;
01884 
01885   GET_CURL_HANDLE
01886 
01887   besALLOC_RETURN_STRING(strlen(pCon->errorbuffer));
01888   memcpy(STRINGVALUE(besRETURNVALUE),pCon->errorbuffer,STRLEN(besRETURNVALUE));
01889 besEND
01890 
01891 
01906 besFUNCTION(sb_curl_escape)
01907   VARIABLE Argument;
01908   char *s;
01909 
01910   Argument = besARGUMENT(1);
01911   besDEREFERENCE(Argument);
01912   /* undef argument returns undef */
01913   if( Argument == NULL )return COMMAND_ERROR_SUCCESS;
01914   Argument = besCONVERT2STRING(Argument);
01915   if( STRLEN(Argument) == 0 ){
01916     besALLOC_RETURN_STRING(1);
01917     STRLEN(besRETURNVALUE) = 0;
01918     }
01919   s = curl_escape(STRINGVALUE(Argument),STRLEN(Argument));
01920   if( s == NULL )return COMMAND_ERROR_MEMORY_LOW;
01921   besALLOC_RETURN_STRING(strlen(s));
01922   memcpy(STRINGVALUE(besRETURNVALUE),s,STRLEN(besRETURNVALUE));
01923   free(s);
01924 besEND
01925 
01957 besFUNCTION(sb_curl_unescape)
01958   VARIABLE Argument;
01959   char *s;
01960 
01961   Argument = besARGUMENT(1);
01962   besDEREFERENCE(Argument);
01963   /* undef argument returns undef */
01964   if( Argument == NULL )return COMMAND_ERROR_SUCCESS;
01965   Argument = besCONVERT2STRING(Argument);
01966   if( STRLEN(Argument) == 0 ){
01967     besALLOC_RETURN_STRING(1);
01968     STRLEN(besRETURNVALUE) = 0;
01969     }
01970   s = curl_unescape(STRINGVALUE(Argument),STRLEN(Argument));
01971   if( s == NULL )return COMMAND_ERROR_MEMORY_LOW;
01972   besALLOC_RETURN_STRING(strlen(s));
01973   memcpy(STRINGVALUE(besRETURNVALUE),s,STRLEN(besRETURNVALUE));
01974   free(s);
01975 besEND
01976 
02050 besFUNCTION(sb_curl_getdate)
02051   VARIABLE Argument;
02052   char *s;
02053   time_t t;
02054 
02055   Argument = besARGUMENT(1);
02056   besDEREFERENCE(Argument);
02057   besCONVERT2ZCHAR(Argument,s);
02058   t = time(&t);
02059   t = curl_getdate(s,&t);
02060   besALLOC_RETURN_LONG;
02061   LONGVALUE(besRETURNVALUE) = t;
02062 
02063 besEND
02064 
02079 besFUNCTION(sb_curl_version)
02080   char *s;
02081 
02082   s = curl_version();  
02083   besALLOC_RETURN_STRING(strlen(s));
02084   memcpy(STRINGVALUE(besRETURNVALUE),s,STRLEN(besRETURNVALUE));
02085 
02086 besEND
02087 
02088 besDLL_MAIN
02089 
02090 besSUB_PROCESS_START
02091   INIT_MULTITHREAD
02092   return 1;
02093 besEND
02094 
02095 besSUB_PROCESS_FINISH
02096   FINISH_MULTITHREAD
02097 besEND
02098 
02099 START_FUNCTION_TABLE(CURL_SLFST)
02100 
02101 EXPORT_MODULE_FUNCTION(shutmodu)
02102 EXPORT_MODULE_FUNCTION(bootmodu)
02103 EXPORT_MODULE_FUNCTION(versmodu)
02104 EXPORT_MODULE_FUNCTION(sb_curl_error)
02105 EXPORT_MODULE_FUNCTION(sb_curl_finish)
02106 EXPORT_MODULE_FUNCTION(sb_curl_option)
02107 EXPORT_MODULE_FUNCTION(sb_curl_perform)
02108 EXPORT_MODULE_FUNCTION(sb_curl_init)
02109 EXPORT_MODULE_FUNCTION(sb_curl_info)
02110 EXPORT_MODULE_FUNCTION(sb_curl_version)
02111 EXPORT_MODULE_FUNCTION(sb_curl_getdate)
02112 EXPORT_MODULE_FUNCTION(sb_curl_escape)
02113 EXPORT_MODULE_FUNCTION(sb_curl_unescape)
02114 EXPORT_MODULE_FUNCTION(_init)
02115 EXPORT_MODULE_FUNCTION(_fini)
02116 
02117 END_FUNCTION_TABLE

Generated on Sun Mar 12 23:56:28 2006 for ScriptBasic by  doxygen 1.4.6-NO