4 * Implementation of the TclCurl extension that creates the curl namespace
5 * so that Tcl interpreters can access libcurl.
7 * Copyright (c) 2001-2011 Andres Garcia Garcia.
9 * See the file "license.terms" for information on usage and redistribution
10 * of this file, and for a DISCLAIMER OF ALL WARRANTIES.
16 #include <sys/types.h>
20 *----------------------------------------------------------------------
24 * This procedure initializes the package
27 * A standard Tcl result.
29 *----------------------------------------------------------------------
33 Tclcurl_Init (Tcl_Interp *interp) {
35 if(Tcl_InitStubs(interp,"8.1",0)==NULL) {
39 Tcl_CreateObjCommand (interp,"::curl::init",curlInitObjCmd,
40 (ClientData)NULL,(Tcl_CmdDeleteProc *)NULL);
41 Tcl_CreateObjCommand (interp,"::curl::version",curlVersion,
42 (ClientData)NULL,(Tcl_CmdDeleteProc *)NULL);
43 Tcl_CreateObjCommand (interp,"::curl::escape",curlEscape,
44 (ClientData)NULL,(Tcl_CmdDeleteProc *)NULL);
45 Tcl_CreateObjCommand (interp,"::curl::unescape",curlUnescape,
46 (ClientData)NULL,(Tcl_CmdDeleteProc *)NULL);
47 Tcl_CreateObjCommand (interp,"::curl::versioninfo",curlVersionInfo,
48 (ClientData)NULL,(Tcl_CmdDeleteProc *)NULL);
49 Tcl_CreateObjCommand (interp,"::curl::shareinit",curlShareInitObjCmd,
50 (ClientData)NULL,(Tcl_CmdDeleteProc *)NULL);
51 Tcl_CreateObjCommand (interp,"::curl::easystrerror", curlEasyStringError,
52 (ClientData)NULL,(Tcl_CmdDeleteProc *)NULL);
53 Tcl_CreateObjCommand (interp,"::curl::sharestrerror",curlShareStringError,
54 (ClientData)NULL,(Tcl_CmdDeleteProc *)NULL);
55 Tcl_CreateObjCommand (interp,"::curl::multistrerror",curlMultiStringError,
56 (ClientData)NULL,(Tcl_CmdDeleteProc *)NULL);
58 Tclcurl_MultiInit(interp);
60 Tcl_PkgProvide(interp,"TclCurl","7.22.0");
66 *----------------------------------------------------------------------
70 * Looks for the first free handle (curl1, curl2,...) and creates a
74 * A string with the name of the handle, don't forget to free it.
77 * See the user documentation.
79 *----------------------------------------------------------------------
83 curlCreateObjCmd (Tcl_Interp *interp,struct curlObjData *curlData) {
89 /* We try with curl1, if it already exists with curl2...*/
90 handleName=(char *)Tcl_Alloc(10);
92 sprintf(handleName,"curl%d",i);
93 if (!Tcl_GetCommandInfo(interp,handleName,&info)) {
94 cmdToken=Tcl_CreateObjCommand(interp,handleName,curlObjCmd,
96 (Tcl_CmdDeleteProc *)curlDeleteCmd);
100 curlData->token=cmdToken;
106 *----------------------------------------------------------------------
110 * This procedure is invoked to process the "curl::init" Tcl command.
111 * See the user documentation for details on what it does.
114 * A standard Tcl result.
117 * See the user documentation.
119 *----------------------------------------------------------------------
123 curlInitObjCmd (ClientData clientData, Tcl_Interp *interp,
124 int objc,Tcl_Obj *CONST objv[]) {
128 struct curlObjData *curlData;
131 curlData=(struct curlObjData *)Tcl_Alloc(sizeof(struct curlObjData));
132 if (curlData==NULL) {
133 resultPtr=Tcl_NewStringObj("Couldn't allocate memory",-1);
134 Tcl_SetObjResult(interp,resultPtr);
138 memset(curlData, 0, sizeof(struct curlObjData));
139 curlData->interp=interp;
141 curlHandle=curl_easy_init();
142 if (curlHandle==NULL) {
143 resultPtr=Tcl_NewStringObj("Couldn't open curl handle",-1);
144 Tcl_SetObjResult(interp,resultPtr);
148 handleName=curlCreateObjCmd(interp,curlData);
150 curlData->curl=curlHandle;
152 resultPtr=Tcl_NewStringObj(handleName,-1);
153 Tcl_SetObjResult(interp,resultPtr);
154 Tcl_Free(handleName);
160 *----------------------------------------------------------------------
164 * This procedure is invoked to process the "curl" commands.
165 * See the user documentation for details on what it does.
168 * A standard Tcl result.
171 * See the user documentation.
173 *----------------------------------------------------------------------
176 curlObjCmd (ClientData clientData, Tcl_Interp *interp,
177 int objc,Tcl_Obj *CONST objv[]) {
179 struct curlObjData *curlData=(struct curlObjData *)clientData;
180 CURL *curlHandle=curlData->curl;
184 Tcl_WrongNumArgs(interp,1,objv,"option arg ?arg?");
187 if (Tcl_GetIndexFromObj(interp, objv[1], commandTable, "option",
188 TCL_EXACT,&tableIndex)==TCL_ERROR) {
194 if (curlSetOptsTransfer(interp,curlData,objc,objv)==TCL_ERROR) {
199 /* fprintf(stdout,"Perform\n"); */
200 if (curlPerform(interp,curlHandle,curlData)) {
201 if (curlData->errorBuffer!=NULL) {
202 if (curlData->errorBufferKey==NULL) {
203 Tcl_SetVar(interp,curlData->errorBufferName,
204 curlData->errorBuffer,0);
206 Tcl_SetVar2(interp,curlData->errorBufferName,
207 curlData->errorBufferKey,
208 curlData->errorBuffer,0);
215 /* fprintf(stdout,"Getinfo\n"); */
216 if (Tcl_GetIndexFromObj(interp,objv[2],getInfoTable,
217 "getinfo option",TCL_EXACT,&tableIndex)==TCL_ERROR) {
220 if (curlGetInfo(interp,curlHandle,tableIndex)) {
225 /* fprintf(stdout,"Cleanup\n"); */
226 Tcl_DeleteCommandFromToken(interp,curlData->token);
229 /* fprintf(stdout,"Configure\n"); */
230 if (curlConfigTransfer(interp,curlData,objc,objv)==TCL_ERROR) {
235 /* fprintf(stdout,"DupHandle\n"); */
236 if (curlDupHandle(interp,curlData,objc,objv)==TCL_ERROR) {
241 /* fprintf(stdout,"Reset\n"); */
242 if (curlResetHandle(interp,curlData)==TCL_ERROR) {
247 /* fprintf(stdout,"Pause\n"); */
248 if (curl_easy_pause(curlData->curl,CURLPAUSE_ALL)==TCL_ERROR) {
254 /* fprintf(stdout,"Resume\n"); */
255 if (curl_easy_pause(curlData->curl,CURLPAUSE_CONT)==TCL_ERROR) {
264 *----------------------------------------------------------------------
268 * This procedure is invoked when curl handle is deleted.
271 * A standard Tcl result.
274 * Cleans the curl handle and frees the memory.
276 *----------------------------------------------------------------------
279 curlDeleteCmd(ClientData clientData) {
280 struct curlObjData *curlData=(struct curlObjData *)clientData;
281 CURL *curlHandle=curlData->curl;
283 curl_easy_cleanup(curlHandle);
284 curlFreeSpace(curlData);
286 Tcl_Free((char *)curlData);
292 *----------------------------------------------------------------------
296 * Invokes the libcurl function 'curl_easy_perform'
299 * interp: Pointer to the interpreter we are using.
300 * curlHandle: the curl handle for which the option is set.
301 * objc and objv: The usual in Tcl.
304 * Standard Tcl return codes.
305 *----------------------------------------------------------------------
308 curlPerform(Tcl_Interp *interp,CURL *curlHandle,
309 struct curlObjData *curlData) {
313 if (curlOpenFiles(interp,curlData)) {
316 if (curlSetPostData(interp,curlData)) {
319 exitCode=curl_easy_perform(curlHandle);
320 resultPtr=Tcl_NewIntObj(exitCode);
321 Tcl_SetObjResult(interp,resultPtr);
322 curlCloseFiles(curlData);
323 curlResetPostData(curlData);
324 if (curlData->bodyVarName) {
325 curlSetBodyVarName(interp,curlData);
327 if (curlData->command) {
328 Tcl_GlobalEval(interp,curlData->command);
334 *----------------------------------------------------------------------
336 * curlSetOptsTransfer --
338 * This procedure is invoked when the user invokes the 'setopt'
339 * command, it is used to set the 'curl' options
342 * interp: Pointer to the interpreter we are using.
343 * curlHandle: the curl handle for which the option is set.
344 * objc and objv: The usual in Tcl.
347 * A standard Tcl result.
348 *----------------------------------------------------------------------
351 curlSetOptsTransfer(Tcl_Interp *interp, struct curlObjData *curlData,
352 int objc, Tcl_Obj *CONST objv[]) {
356 if (Tcl_GetIndexFromObj(interp, objv[2], optionTable, "option",
357 TCL_EXACT, &tableIndex)==TCL_ERROR) {
361 return curlSetOpts(interp,curlData,objv[3],tableIndex);
365 *----------------------------------------------------------------------
367 * curlConfigTransfer --
369 * This procedure is invoked by the user command 'configure', it reads
370 * the options passed by the user to configure a transfer, and passes
371 * then, one by one to 'curlSetOpts'.
374 * interp: Pointer to the interpreter we are using.
375 * curlHandle: the curl handle for which the option is set.
376 * objc and objv: The usual in Tcl.
379 * A standard Tcl result.
380 *----------------------------------------------------------------------
383 curlConfigTransfer(Tcl_Interp *interp, struct curlObjData *curlData,
384 int objc, Tcl_Obj *CONST objv[]) {
392 for(i=2,j=3;i<objc;i=i+2,j=j+2) {
393 if (Tcl_GetIndexFromObj(interp, objv[i], configTable, "option",
394 TCL_EXACT, &tableIndex)==TCL_ERROR) {
398 snprintf(errorMsg,500,"Empty value for %s",configTable[tableIndex]);
399 resultPtr=Tcl_NewStringObj(errorMsg,-1);
400 Tcl_SetObjResult(interp,resultPtr);
403 if (curlSetOpts(interp,curlData,objv[j],tableIndex)==TCL_ERROR) {
411 *----------------------------------------------------------------------
415 * This procedure takes care of setting the transfer options.
418 * interp: Pointer to the interpreter we are using.
419 * curlHandle: the curl handle for which the option is set.
420 * objv: A pointer to the object where the data to set is stored.
421 * tableIndex: The index of the option in the options table.
424 * A standard Tcl result.
425 *----------------------------------------------------------------------
428 curlSetOpts(Tcl_Interp *interp, struct curlObjData *curlData,
429 Tcl_Obj *CONST objv,int tableIndex) {
432 CURL *curlHandle=curlData->curl;
435 Tcl_Obj *resultObjPtr;
439 CONST char *startPtr;
446 unsigned char *tmpUStr;
448 Tcl_Obj **httpPostData;
450 int curlTableIndex,formaddError,formArrayIndex;
451 struct formArrayStruct *newFormArray;
452 struct curl_forms *formArray;
453 int curlformBufferSize;
456 unsigned long int protocolMask;
460 if (SetoptChar(interp,curlHandle,CURLOPT_URL,
466 Tcl_Free(curlData->outFile);
467 curlData->outFile=curlstrdup(Tcl_GetString(objv));
468 if ((strcmp(curlData->outFile,""))&&(strcmp(curlData->outFile,"stdout"))) {
472 curl_easy_setopt(curlHandle,CURLOPT_WRITEDATA,stdout);
473 curlData->outFile=NULL;
475 curl_easy_setopt(curlHandle,CURLOPT_WRITEFUNCTION,NULL);
478 Tcl_Free(curlData->inFile);
479 curlData->inFile=curlstrdup(Tcl_GetString(objv));
480 if ((strcmp(curlData->inFile,""))&&(strcmp(curlData->inFile,"stdin"))) {
483 curl_easy_setopt(curlHandle,CURLOPT_READDATA,stdin);
485 curlData->inFile=NULL;
487 curl_easy_setopt(curlHandle,CURLOPT_READFUNCTION,NULL);
490 if (SetoptChar(interp,curlHandle,
491 CURLOPT_USERAGENT,tableIndex,objv)) {
496 if (SetoptChar(interp,curlHandle,CURLOPT_REFERER,tableIndex,objv)) {
501 if (SetoptInt(interp,curlHandle,CURLOPT_VERBOSE,tableIndex,objv)) {
506 if (SetoptInt(interp,curlHandle,CURLOPT_HEADER,tableIndex,objv)) {
511 if (SetoptInt(interp,curlHandle,CURLOPT_NOBODY,tableIndex,objv)) {
516 if (SetoptChar(interp,curlHandle,CURLOPT_PROXY,tableIndex,objv)) {
521 if (SetoptLong(interp,curlHandle,CURLOPT_PROXYPORT,tableIndex,
527 if (SetoptInt(interp,curlHandle,CURLOPT_HTTPPROXYTUNNEL,tableIndex,
533 if (SetoptInt(interp,curlHandle,CURLOPT_FAILONERROR,tableIndex,
539 if (SetoptLong(interp,curlHandle,CURLOPT_TIMEOUT,tableIndex,
545 if (SetoptLong(interp,curlHandle,CURLOPT_LOW_SPEED_LIMIT,tableIndex,
551 if (SetoptLong(interp,curlHandle,CURLOPT_LOW_SPEED_TIME,tableIndex,
557 if (SetoptLong(interp,curlHandle,CURLOPT_RESUME_FROM,tableIndex,
563 if (SetoptLong(interp,curlHandle,CURLOPT_INFILESIZE,tableIndex,
569 if (SetoptInt(interp,curlHandle,CURLOPT_UPLOAD,tableIndex,
576 if (SetoptInt(interp,curlHandle,CURLOPT_DIRLISTONLY,tableIndex,
583 if (SetoptInt(interp,curlHandle,CURLOPT_APPEND,tableIndex,
589 if (Tcl_GetIndexFromObj(interp, objv, netrcTable,
590 "netrc option",TCL_EXACT,&curlTableIndex)==TCL_ERROR) {
593 if (curl_easy_setopt(curlHandle,CURLOPT_NETRC,curlTableIndex)) {
594 curlErrorSetOpt(interp,configTable,tableIndex,netrcTable[curlTableIndex]);
599 if (SetoptInt(interp,curlHandle,CURLOPT_FOLLOWLOCATION,tableIndex,
605 if (SetoptInt(interp,curlHandle,CURLOPT_TRANSFERTEXT,tableIndex,
609 Tcl_GetIntFromObj(interp,objv,&curlData->transferText);
612 if (SetoptInt(interp,curlHandle,CURLOPT_PUT,tableIndex,objv)) {
616 case 24: /* The CURLOPT_MUTE option no longer does anything.*/
619 if (SetoptChar(interp,curlHandle,CURLOPT_USERPWD,tableIndex,objv)) {
624 if (SetoptChar(interp,curlHandle,CURLOPT_PROXYUSERPWD,tableIndex,objv)) {
629 if (SetoptChar(interp,curlHandle,CURLOPT_RANGE,tableIndex,objv)) {
634 tmpStr=curlstrdup(Tcl_GetString(objv));
635 regExp=Tcl_RegExpCompile(interp,"(.*)(?:\\()(.*)(?:\\))");
636 exitCode=Tcl_RegExpExec(interp,regExp,tmpStr,tmpStr);
639 Tcl_Free((char *)tmpStr);
644 curlData->errorBufferName=curlstrdup(tmpStr);
646 curlData->errorBuffer=NULL;
648 curlData->errorBufferKey=NULL;
651 Tcl_RegExpRange(regExp,1,&startPtr,&endPtr);
652 charLength=endPtr-startPtr;
653 curlData->errorBufferName=Tcl_Alloc(charLength+1);
654 strncpy(curlData->errorBufferName,startPtr,charLength);
655 curlData->errorBufferName[charLength]=0;
656 Tcl_RegExpRange(regExp,2,&startPtr,&endPtr);
657 charLength=endPtr-startPtr;
658 curlData->errorBufferKey=Tcl_Alloc(charLength+1);
659 strncpy(curlData->errorBufferKey,startPtr,charLength);
660 curlData->errorBufferKey[charLength]=0;
663 Tcl_Free((char *)tmpStr);
664 if (curlData->errorBufferName!=NULL) {
665 curlData->errorBuffer=Tcl_Alloc(CURL_ERROR_SIZE);
666 if (curl_easy_setopt(curlHandle,CURLOPT_ERRORBUFFER,
667 curlData->errorBuffer)) {
668 Tcl_Free((char *)curlData->errorBuffer);
669 curlData->errorBuffer=NULL;
673 Tcl_Free(curlData->errorBuffer);
677 if (SetoptLong(interp,curlHandle,CURLOPT_HTTPGET,tableIndex,
683 if (SetoptInt(interp,curlHandle,CURLOPT_POST,tableIndex,objv)) {
688 if (SetoptChar(interp,curlHandle,
689 CURLOPT_COPYPOSTFIELDS,tableIndex,objv)) {
694 if (SetoptChar(interp,curlHandle,
695 CURLOPT_FTPPORT,tableIndex,objv)) {
700 if (SetoptChar(interp,curlHandle,CURLOPT_COOKIE,tableIndex,objv)) {
705 if (SetoptChar(interp,curlHandle,CURLOPT_COOKIEFILE,tableIndex,objv)) {
710 if(SetoptsList(interp,&curlData->headerList,objv)) {
711 curlErrorSetOpt(interp,configTable,tableIndex,"Header list invalid");
714 if (curl_easy_setopt(curlHandle,CURLOPT_HTTPHEADER,curlData->headerList)) {
715 curl_slist_free_all(curlData->headerList);
716 curlData->headerList=NULL;
722 if (Tcl_ListObjGetElements(interp,objv,&k,&httpPostData)
727 newFormArray=(struct formArrayStruct *)Tcl_Alloc(sizeof(struct formArrayStruct));
728 formArray=(struct curl_forms *)Tcl_Alloc(k*(sizeof(struct curl_forms)));
731 newFormArray->next=curlData->formArray;
732 newFormArray->formArray=formArray;
733 newFormArray->formHeaderList=NULL;
735 for(i=0,j=0;i<k;i+=2,j+=1) {
736 if (Tcl_GetIndexFromObj(interp,httpPostData[i],curlFormTable,
737 "CURLFORM option",TCL_EXACT,&curlTableIndex)==TCL_ERROR) {
741 switch(curlTableIndex) {
743 /* fprintf(stdout,"Section name: %s\n",Tcl_GetString(httpPostData[i+1]));*/
744 formArray[formArrayIndex].option = CURLFORM_COPYNAME;
745 formArray[formArrayIndex].value = curlstrdup(Tcl_GetString(httpPostData[i+1]));
748 /* fprintf(stdout,"Section contents: %s\n",Tcl_GetString(httpPostData[i+1]));*/
749 tmpStr=Tcl_GetStringFromObj(httpPostData[i+1],&curlformBufferSize);
750 formArray[formArrayIndex].option = CURLFORM_COPYCONTENTS;
751 formArray[formArrayIndex].value = (char *)
752 memcpy(Tcl_Alloc(curlformBufferSize), tmpStr, curlformBufferSize);
755 formArray[formArrayIndex].option = CURLFORM_CONTENTSLENGTH;
756 contentslen=curlformBufferSize++;
757 formArray[formArrayIndex].value = (char *)contentslen;
760 /* fprintf(stdout,"File name %d: %s\n",formArrayIndex,Tcl_GetString(httpPostData[i+1]));*/
761 formArray[formArrayIndex].option = CURLFORM_FILE;
762 formArray[formArrayIndex].value = curlstrdup(Tcl_GetString(httpPostData[i+1]));
765 /* fprintf(stdout,"Data type: %s\n",Tcl_GetString(httpPostData[i+1]));*/
766 formArray[formArrayIndex].option = CURLFORM_CONTENTTYPE;
767 formArray[formArrayIndex].value = curlstrdup(Tcl_GetString(httpPostData[i+1]));
770 /* fprintf(stdout,"ContentHeader: %s\n",Tcl_GetString(httpPostData[i+1]));*/
771 formArray[formArrayIndex].option = CURLFORM_CONTENTHEADER;
772 if(SetoptsList(interp,&newFormArray->formHeaderList,httpPostData[i+1])) {
773 curlErrorSetOpt(interp,configTable,tableIndex,"Header list invalid");
777 formArray[formArrayIndex].value = (char *)newFormArray->formHeaderList;
780 /* fprintf(stdout,"FileName: %s\n",Tcl_GetString(httpPostData[i+1])); */
781 formArray[formArrayIndex].option = CURLFORM_FILENAME;
782 formArray[formArrayIndex].value = curlstrdup(Tcl_GetString(httpPostData[i+1]));
785 /* fprintf(stdout,"BufferName: %s\n",Tcl_GetString(httpPostData[i+1])); */
786 formArray[formArrayIndex].option = CURLFORM_BUFFER;
787 formArray[formArrayIndex].value = curlstrdup(Tcl_GetString(httpPostData[i+1]));
790 /* fprintf(stdout,"Buffer: %s\n",Tcl_GetString(httpPostData[i+1])); */
791 tmpUStr=Tcl_GetByteArrayFromObj
792 (httpPostData[i+1],&curlformBufferSize);
793 formArray[formArrayIndex].option = CURLFORM_BUFFERPTR;
794 formArray[formArrayIndex].value = (char *)
795 memcpy(Tcl_Alloc(curlformBufferSize), tmpUStr, curlformBufferSize);
797 formArray[formArrayIndex].option = CURLFORM_BUFFERLENGTH;
798 contentslen=curlformBufferSize;
799 formArray[formArrayIndex].value = (char *)contentslen;
802 /* fprintf(stdout,"FileName: %s\n",Tcl_GetString(httpPostData[i+1])); */
803 formArray[formArrayIndex].option = CURLFORM_FILECONTENT;
804 formArray[formArrayIndex].value = curlstrdup(Tcl_GetString(httpPostData[i+1]));
809 formArray[formArrayIndex].option=CURLFORM_END;
810 curlData->formArray=newFormArray;
812 if (0==formaddError) {
813 formaddError=curl_formadd(&(curlData->postListFirst)
814 ,&(curlData->postListLast), CURLFORM_ARRAY, formArray
817 if (formaddError!=CURL_FORMADD_OK) {
818 curlResetFormArray(formArray);
819 curlData->formArray=newFormArray->next;
820 Tcl_Free((char *)newFormArray);
821 tmpStr=Tcl_Alloc(10);
822 snprintf(tmpStr,10,"%d",formaddError);
823 resultObjPtr=Tcl_NewStringObj(tmpStr,-1);
824 Tcl_SetObjResult(interp,resultObjPtr);
831 if (SetoptChar(interp,curlHandle,CURLOPT_SSLCERT,tableIndex,objv)) {
836 if (SetoptChar(interp,curlHandle,CURLOPT_SSLCERTPASSWD,tableIndex,objv)) {
841 if (Tcl_GetIndexFromObj(interp, objv, sslversion,
842 "sslversion ",TCL_EXACT,&intNumber)==TCL_ERROR) {
847 longNumber=CURL_SSLVERSION_DEFAULT;
850 longNumber=CURL_SSLVERSION_TLSv1;
853 longNumber=CURL_SSLVERSION_SSLv2;
856 longNumber=CURL_SSLVERSION_SSLv3;
858 tmpObjPtr=Tcl_NewLongObj(longNumber);
859 if (SetoptLong(interp,curlHandle,CURLOPT_SSLVERSION,
860 tableIndex,tmpObjPtr)) {
865 if (SetoptInt(interp,curlHandle,CURLOPT_CRLF,tableIndex,objv)) {
870 if(SetoptsList(interp,&curlData->quote,objv)) {
871 curlErrorSetOpt(interp,configTable,tableIndex,"quote list invalid");
874 if (curl_easy_setopt(curlHandle,CURLOPT_QUOTE,curlData->quote)) {
875 curl_slist_free_all(curlData->quote);
876 curlData->quote=NULL;
882 if(SetoptsList(interp,&curlData->postquote,objv)) {
883 curlErrorSetOpt(interp,configTable,tableIndex,"postqoute invalid");
886 if (curl_easy_setopt(curlHandle,CURLOPT_POSTQUOTE,curlData->postquote)) {
887 curlErrorSetOpt(interp,configTable,tableIndex,"postqoute invalid");
888 curl_slist_free_all(curlData->postquote);
889 curlData->postquote=NULL;
895 Tcl_Free(curlData->headerFile);
896 curlData->headerFile=curlstrdup(Tcl_GetString(objv));
897 if ((strcmp(curlData->headerFile,""))&&(strcmp(curlData->headerFile,"stdout"))
898 &&(strcmp(curlData->headerFile,"stderr"))) {
899 curlData->headerFlag=1;
901 if ((strcmp(curlData->headerFile,"stdout"))) {
902 curl_easy_setopt(curlHandle,CURLOPT_HEADERDATA,stderr);
904 curl_easy_setopt(curlHandle,CURLOPT_HEADERDATA,stdout);
906 curlData->headerFlag=0;
907 curlData->headerFile=NULL;
911 if (Tcl_GetIndexFromObj(interp, objv, timeCond,
912 "time cond option",TCL_EXACT, &intNumber)==TCL_ERROR) {
916 longNumber=CURL_TIMECOND_IFMODSINCE;
918 longNumber=CURL_TIMECOND_IFUNMODSINCE;
920 if (curl_easy_setopt(curlHandle,CURLOPT_TIMECONDITION,longNumber)) {
925 if (SetoptLong(interp,curlHandle,CURLOPT_TIMEVALUE,tableIndex,
931 if (SetoptChar(interp,curlHandle,CURLOPT_CUSTOMREQUEST,tableIndex,objv)) {
936 Tcl_Free(curlData->stderrFile);
937 curlData->stderrFile=curlstrdup(Tcl_GetString(objv));
938 if ((strcmp(curlData->stderrFile,""))&&(strcmp(curlData->stderrFile,"stdout"))
939 &&(strcmp(curlData->stderrFile,"stderr"))) {
940 curlData->stderrFlag=1;
942 curlData->stderrFlag=0;
943 if (strcmp(curlData->stderrFile,"stdout")) {
944 curl_easy_setopt(curlHandle,CURLOPT_STDERR,stderr);
946 curl_easy_setopt(curlHandle,CURLOPT_STDERR,stdout);
948 curlData->stderrFile=NULL;
952 if (SetoptChar(interp,curlHandle,CURLOPT_INTERFACE,tableIndex,objv)) {
958 if (SetoptChar(interp,curlHandle,CURLOPT_KRBLEVEL,tableIndex,objv)) {
963 if (SetoptLong(interp,curlHandle,CURLOPT_SSL_VERIFYPEER,tableIndex,
969 if (SetoptChar(interp,curlHandle,CURLOPT_CAINFO,tableIndex,objv)) {
974 if (SetoptLong(interp,curlHandle,CURLOPT_FILETIME,tableIndex,
980 if (SetoptLong(interp,curlHandle,CURLOPT_MAXREDIRS,tableIndex,
986 if (SetoptLong(interp,curlHandle,CURLOPT_MAXCONNECTS,tableIndex,
992 curlErrorSetOpt(interp,configTable,tableIndex,"option is obsolete");
996 if (SetoptChar(interp,curlHandle,CURLOPT_RANDOM_FILE,tableIndex,objv)) {
1001 if (SetoptChar(interp,curlHandle,CURLOPT_EGDSOCKET,tableIndex,objv)) {
1006 if (SetoptLong(interp,curlHandle,CURLOPT_CONNECTTIMEOUT,
1012 if (SetoptLong(interp,curlHandle,CURLOPT_NOPROGRESS,
1018 if (curl_easy_setopt(curlHandle,CURLOPT_HEADERFUNCTION,
1019 curlHeaderReader)) {
1022 Tcl_Free(curlData->headerVar);
1023 curlData->headerVar=curlstrdup(Tcl_GetString(objv));
1024 if (curl_easy_setopt(curlHandle,CURLOPT_HEADERDATA,
1025 (FILE *)curlData)) {
1030 Tcl_Free(curlData->bodyVarName);
1031 curlData->bodyVarName=curlstrdup(Tcl_GetString(objv));
1032 if (curl_easy_setopt(curlHandle,CURLOPT_WRITEFUNCTION,
1036 if (curl_easy_setopt(curlHandle,CURLOPT_WRITEDATA,curlData)) {
1041 Tcl_Free(curlData->progressProc);
1042 curlData->progressProc=curlstrdup(Tcl_GetString(objv));
1043 if (strcmp(curlData->progressProc,"")) {
1044 if (curl_easy_setopt(curlHandle,CURLOPT_PROGRESSFUNCTION,
1045 curlProgressCallback)) {
1048 if (curl_easy_setopt(curlHandle,CURLOPT_PROGRESSDATA,
1053 if (curl_easy_setopt(curlHandle,CURLOPT_PROGRESSFUNCTION,NULL)) {
1059 if (curlData->cancelTransVarName) {
1060 Tcl_UnlinkVar(curlData->interp,curlData->cancelTransVarName);
1061 Tcl_Free(curlData->cancelTransVarName);
1063 curlData->cancelTransVarName=curlstrdup(Tcl_GetString(objv));
1064 Tcl_LinkVar(interp,curlData->cancelTransVarName,
1065 (char *)&(curlData->cancelTrans),TCL_LINK_INT);
1068 curlData->writeProc=curlstrdup(Tcl_GetString(objv));
1069 curlData->outFlag=0;
1070 if (curl_easy_setopt(curlHandle,CURLOPT_WRITEFUNCTION,
1071 curlWriteProcInvoke)) {
1072 curl_easy_setopt(curlHandle,CURLOPT_WRITEFUNCTION,NULL);
1075 if (curl_easy_setopt(curlHandle,CURLOPT_WRITEDATA,curlData)) {
1076 curl_easy_setopt(curlHandle,CURLOPT_WRITEFUNCTION,NULL);
1081 curlData->readProc=curlstrdup(Tcl_GetString(objv));
1083 if (strcmp(curlData->readProc,"")) {
1084 if (curl_easy_setopt(curlHandle,CURLOPT_READFUNCTION,
1085 curlReadProcInvoke)) {
1089 curl_easy_setopt(curlHandle,CURLOPT_READFUNCTION,NULL);
1092 if (curl_easy_setopt(curlHandle,CURLOPT_READDATA,curlData)) {
1097 if (SetoptLong(interp,curlHandle,CURLOPT_SSL_VERIFYHOST,
1103 if (SetoptChar(interp,curlHandle,CURLOPT_COOKIEJAR,tableIndex,objv)) {
1108 if (SetoptChar(interp,curlHandle,CURLOPT_SSL_CIPHER_LIST,tableIndex,objv)) {
1113 if (Tcl_GetIndexFromObj(interp, objv, httpVersionTable,
1114 "http version",TCL_EXACT,&tableIndex)==TCL_ERROR) {
1117 if (curl_easy_setopt(curlHandle,CURLOPT_HTTP_VERSION,
1119 tmpStr=curlstrdup(Tcl_GetString(objv));
1120 curlErrorSetOpt(interp,configTable,70,tmpStr);
1126 if (SetoptLong(interp,curlHandle,CURLOPT_FTP_USE_EPSV,
1132 if (SetoptChar(interp,curlHandle,CURLOPT_SSLCERTTYPE,tableIndex,objv)) {
1137 if (SetoptChar(interp,curlHandle,CURLOPT_SSLKEY,tableIndex,objv)) {
1142 if (SetoptChar(interp,curlHandle,CURLOPT_SSLKEYTYPE,tableIndex,objv)) {
1148 if (SetoptChar(interp,curlHandle,CURLOPT_KEYPASSWD,tableIndex,objv)) {
1153 if (SetoptChar(interp,curlHandle,CURLOPT_SSLENGINE,tableIndex,objv)) {
1158 if (SetoptLong(interp,curlHandle,CURLOPT_SSLENGINE_DEFAULT,tableIndex,objv)) {
1163 if(SetoptsList(interp,&curlData->prequote,objv)) {
1164 curlErrorSetOpt(interp,configTable,tableIndex,"pretqoute invalid");
1167 if (curl_easy_setopt(curlHandle,CURLOPT_PREQUOTE,curlData->prequote)) {
1168 curlErrorSetOpt(interp,configTable,tableIndex,"preqoute invalid");
1169 curl_slist_free_all(curlData->prequote);
1170 curlData->prequote=NULL;
1176 curlData->debugProc=curlstrdup(Tcl_GetString(objv));
1177 if (curl_easy_setopt(curlHandle,CURLOPT_DEBUGFUNCTION,
1178 curlDebugProcInvoke)) {
1181 if (curl_easy_setopt(curlHandle,CURLOPT_DEBUGDATA,curlData)) {
1186 if (SetoptLong(interp,curlHandle,CURLOPT_DNS_CACHE_TIMEOUT,
1192 if (SetoptLong(interp,curlHandle,CURLOPT_DNS_USE_GLOBAL_CACHE,
1198 if (SetoptLong(interp,curlHandle,CURLOPT_COOKIESESSION,
1204 if (SetoptChar(interp,curlHandle,CURLOPT_CAPATH,tableIndex,objv)) {
1209 if (SetoptLong(interp,curlHandle,CURLOPT_BUFFERSIZE,
1215 if (SetoptLong(interp,curlHandle,CURLOPT_NOSIGNAL,
1221 if (Tcl_GetIndexFromObj(interp, objv, encodingTable,
1222 "encoding",TCL_EXACT,&tableIndex)==TCL_ERROR) {
1225 if (tableIndex==2) {
1226 if (curl_easy_setopt(curlHandle,CURLOPT_ACCEPT_ENCODING,"")) {
1227 curlErrorSetOpt(interp,configTable,86,"all");
1231 if (SetoptChar(interp,curlHandle,CURLOPT_ACCEPT_ENCODING,86,objv)) {
1237 if (Tcl_GetIndexFromObj(interp, objv, proxyTypeTable,
1238 "proxy type",TCL_EXACT,&tableIndex)==TCL_ERROR) {
1241 switch(tableIndex) {
1243 curl_easy_setopt(curlHandle,CURLOPT_PROXYTYPE,
1247 curl_easy_setopt(curlHandle,CURLOPT_PROXYTYPE,
1248 CURLPROXY_HTTP_1_0);
1251 curl_easy_setopt(curlHandle,CURLOPT_PROXYTYPE,
1255 curl_easy_setopt(curlHandle,CURLOPT_PROXYTYPE,
1259 curl_easy_setopt(curlHandle,CURLOPT_PROXYTYPE,
1263 curl_easy_setopt(curlHandle,CURLOPT_PROXYTYPE,
1264 CURLPROXY_SOCKS5_HOSTNAME);
1268 if(SetoptsList(interp,&curlData->http200aliases,objv)) {
1269 curlErrorSetOpt(interp,configTable,tableIndex,"http200aliases invalid");
1272 if (curl_easy_setopt(curlHandle,CURLOPT_HTTP200ALIASES,curlData->http200aliases)) {
1273 curlErrorSetOpt(interp,configTable,tableIndex,"http200aliases invalid");
1274 curl_slist_free_all(curlData->http200aliases);
1275 curlData->http200aliases=NULL;
1281 if (SetoptInt(interp,curlHandle,CURLOPT_UNRESTRICTED_AUTH
1282 ,tableIndex,objv)) {
1287 if (SetoptLong(interp,curlHandle,CURLOPT_FTP_USE_EPRT,
1293 Tcl_Free(curlData->command);
1294 curlData->command=curlstrdup(Tcl_GetString(objv));
1297 if (Tcl_GetIndexFromObj(interp, objv, httpAuthMethods,
1298 "authentication method",TCL_EXACT,&intNumber)==TCL_ERROR) {
1301 curlData->anyAuthFlag=0;
1304 longNumber=CURLAUTH_BASIC;
1307 longNumber=CURLAUTH_DIGEST;
1310 longNumber=CURLAUTH_DIGEST_IE;
1313 longNumber=CURLAUTH_GSSNEGOTIATE;
1316 longNumber=CURLAUTH_NTLM;
1319 longNumber=CURLAUTH_ANY;
1320 curlData->anyAuthFlag=1;
1323 longNumber=CURLAUTH_ANYSAFE;
1326 longNumber=CURLAUTH_NTLM_WB;
1329 tmpObjPtr=Tcl_NewLongObj(longNumber);
1330 if (SetoptLong(interp,curlHandle,CURLOPT_HTTPAUTH
1331 ,tableIndex,tmpObjPtr)) {
1336 if (SetoptLong(interp,curlHandle,CURLOPT_FTP_CREATE_MISSING_DIRS,
1342 if (Tcl_GetIndexFromObj(interp, objv, httpAuthMethods,
1343 "authentication method",TCL_EXACT,&intNumber)==TCL_ERROR) {
1348 longNumber=CURLAUTH_BASIC;
1351 longNumber=CURLAUTH_DIGEST;
1354 longNumber=CURLAUTH_GSSNEGOTIATE;
1357 longNumber=CURLAUTH_NTLM;
1360 longNumber=CURLAUTH_ANYSAFE;
1364 longNumber=CURLAUTH_ANY;
1367 tmpObjPtr=Tcl_NewLongObj(longNumber);
1368 if (SetoptLong(interp,curlHandle,CURLOPT_PROXYAUTH
1369 ,tableIndex,tmpObjPtr)) {
1374 if (SetoptLong(interp,curlHandle,CURLOPT_FTP_RESPONSE_TIMEOUT,
1380 if (Tcl_GetIndexFromObj(interp, objv, ipresolve,
1381 "ip version",TCL_EXACT,&curlTableIndex)==TCL_ERROR) {
1384 switch(curlTableIndex) {
1386 longNumber=CURL_IPRESOLVE_WHATEVER;
1389 longNumber=CURL_IPRESOLVE_V4;
1392 longNumber=CURL_IPRESOLVE_V6;
1395 tmpObjPtr=Tcl_NewLongObj(longNumber);
1396 if (SetoptLong(interp,curlHandle,CURLOPT_IPRESOLVE
1397 ,tableIndex,tmpObjPtr)) {
1402 if (SetoptLong(interp,curlHandle,CURLOPT_MAXFILESIZE,
1408 if (SetoptChar(interp,curlHandle,CURLOPT_NETRC_FILE,tableIndex,objv)) {
1414 if (Tcl_GetIndexFromObj(interp, objv, ftpssl,
1415 "ftps method ",TCL_EXACT,&intNumber)==TCL_ERROR) {
1420 longNumber=CURLUSESSL_NONE;
1423 longNumber=CURLUSESSL_TRY;
1426 longNumber=CURLUSESSL_CONTROL;
1429 longNumber=CURLUSESSL_ALL;
1432 tmpObjPtr=Tcl_NewLongObj(longNumber);
1433 if (SetoptLong(interp,curlHandle,CURLOPT_USE_SSL,
1434 tableIndex,tmpObjPtr)) {
1439 if (SetoptSHandle(interp,curlHandle,CURLOPT_SHARE,
1445 if (SetoptLong(interp,curlHandle,CURLOPT_PORT,
1451 if (SetoptLong(interp,curlHandle,CURLOPT_TCP_NODELAY,
1457 if (SetoptLong(interp,curlHandle,CURLOPT_AUTOREFERER,
1463 curlErrorSetOpt(interp,configTable,tableIndex,"option is obsolete");
1467 curlErrorSetOpt(interp,configTable,tableIndex,"option is obsolete");
1471 curlErrorSetOpt(interp,configTable,tableIndex,"option is obsolete");
1475 curlErrorSetOpt(interp,configTable,tableIndex,"option is obsolete, check '-ftpport'");
1479 curlErrorSetOpt(interp,configTable,tableIndex,"option is obsolete, check '-ftpport'");
1483 curlErrorSetOpt(interp,configTable,tableIndex,"option is obsolete");
1487 curlErrorSetOpt(interp,configTable,tableIndex,"option is obsolete");
1491 if (Tcl_GetIndexFromObj(interp, objv, ftpsslauth,
1492 "ftpsslauth method ",TCL_EXACT,&intNumber)==TCL_ERROR) {
1497 longNumber=CURLFTPAUTH_DEFAULT;
1500 longNumber=CURLFTPAUTH_SSL;
1503 longNumber=CURLFTPAUTH_TLS;
1506 tmpObjPtr=Tcl_NewLongObj(longNumber);
1507 if (SetoptLong(interp,curlHandle,CURLOPT_FTPSSLAUTH,
1508 tableIndex,tmpObjPtr)) {
1513 curlErrorSetOpt(interp,configTable,tableIndex,"option is obsolete");
1517 curlErrorSetOpt(interp,configTable,tableIndex,"option is obsolete");
1521 if (SetoptChar(interp,curlHandle,CURLOPT_FTP_ACCOUNT,tableIndex,objv)) {
1526 if (SetoptLong(interp,curlHandle,CURLOPT_IGNORE_CONTENT_LENGTH,
1532 if (SetoptChar(interp,curlHandle,CURLOPT_COOKIELIST,tableIndex,objv)) {
1537 if (SetoptLong(interp,curlHandle,CURLOPT_FTP_SKIP_PASV_IP,
1543 if (Tcl_GetIndexFromObj(interp, objv, ftpfilemethod,
1544 "ftp file method ",TCL_EXACT,&intNumber)==TCL_ERROR) {
1550 longNumber=1; /* FTPFILE_MULTICWD */
1553 longNumber=2; /* FTPFILE_NOCWD */
1556 longNumber=3; /* FTPFILE_SINGLECWD */
1559 tmpObjPtr=Tcl_NewLongObj(longNumber);
1560 if (SetoptLong(interp,curlHandle,CURLOPT_FTP_FILEMETHOD,
1561 tableIndex,tmpObjPtr)) {
1566 if (SetoptLong(interp,curlHandle,CURLOPT_LOCALPORT,
1572 if (SetoptLong(interp,curlHandle,CURLOPT_LOCALPORTRANGE,
1578 if (SetoptCurlOffT(interp,curlHandle,CURLOPT_MAX_SEND_SPEED_LARGE,
1584 if (SetoptCurlOffT(interp,curlHandle,CURLOPT_MAX_RECV_SPEED_LARGE,
1590 if (SetoptChar(interp,curlHandle,
1591 CURLOPT_FTP_ALTERNATIVE_TO_USER,tableIndex,objv)) {
1596 if (SetoptLong(interp,curlHandle,CURLOPT_SSL_SESSIONID_CACHE,
1602 if (Tcl_GetIndexFromObj(interp, objv, sshauthtypes,
1603 "ssh auth type ",TCL_EXACT,&intNumber)==TCL_ERROR) {
1608 longNumber=CURLSSH_AUTH_PUBLICKEY;
1611 longNumber=CURLSSH_AUTH_PASSWORD;
1614 longNumber=CURLSSH_AUTH_HOST;
1617 longNumber=CURLSSH_AUTH_KEYBOARD;
1620 longNumber=CURLSSH_AUTH_ANY;
1623 tmpObjPtr=Tcl_NewLongObj(longNumber);
1624 if (SetoptLong(interp,curlHandle,CURLOPT_SSH_AUTH_TYPES,
1625 tableIndex,tmpObjPtr)) {
1630 if (SetoptChar(interp,curlHandle,CURLOPT_SSH_PUBLIC_KEYFILE,
1636 if (SetoptChar(interp,curlHandle,CURLOPT_SSH_PRIVATE_KEYFILE,
1642 if (SetoptLong(interp,curlHandle,CURLOPT_TIMEOUT_MS,
1648 if (SetoptLong(interp,curlHandle,CURLOPT_CONNECTTIMEOUT_MS,
1654 if (SetoptLong(interp,curlHandle,CURLOPT_HTTP_CONTENT_DECODING,
1660 if (SetoptLong(interp,curlHandle,CURLOPT_HTTP_TRANSFER_DECODING,
1665 /* 132 is together with case 50 */
1667 if (SetoptLong(interp,curlHandle,CURLOPT_NEW_FILE_PERMS,
1673 if (SetoptLong(interp,curlHandle,CURLOPT_NEW_DIRECTORY_PERMS,
1678 /* case 135 with 75, case 136 with 19, case 137 with 18 and case 138 with 99 */
1681 if (Tcl_GetIndexFromObj(interp, objv, postredir,
1682 "Postredir option ",TCL_EXACT,&intNumber)==TCL_ERROR) {
1687 longNumber=CURL_REDIR_POST_301;
1690 longNumber=CURL_REDIR_POST_302;
1693 longNumber=CURL_REDIR_POST_ALL;
1696 tmpObjPtr=Tcl_NewLongObj(longNumber);
1697 if (SetoptLong(interp,curlHandle,CURLOPT_POSTREDIR,
1698 tableIndex,tmpObjPtr)) {
1703 if (SetoptChar(interp,curlHandle,CURLOPT_SSH_HOST_PUBLIC_KEY_MD5,
1709 if (SetoptLong(interp,curlHandle,CURLOPT_PROXY_TRANSFER_MODE,
1715 if (SetoptChar(interp,curlHandle,CURLOPT_CRLFILE,
1721 if (SetoptChar(interp,curlHandle,CURLOPT_ISSUERCERT,
1727 if (SetoptLong(interp,curlHandle,CURLOPT_ADDRESS_SCOPE,
1733 if (SetoptLong(interp,curlHandle,CURLOPT_CERTINFO,
1738 /* case 146 is together with 139*/
1740 if (SetoptChar(interp,curlHandle,CURLOPT_USERNAME,
1746 if (SetoptChar(interp,curlHandle,CURLOPT_PASSWORD,
1752 if (SetoptChar(interp,curlHandle,CURLOPT_PROXYUSERNAME,
1758 if (SetoptChar(interp,curlHandle,CURLOPT_PROXYPASSWORD,
1764 if (SetoptLong(interp,curlHandle,CURLOPT_TFTP_BLKSIZE,
1770 if (SetoptChar(interp,curlHandle,CURLOPT_SOCKS5_GSSAPI_SERVICE,
1776 if (SetoptLong(interp,curlHandle,CURLOPT_SOCKS5_GSSAPI_NEC,
1783 if (Tcl_ListObjGetElements(interp,objv,&j,&protocols)==TCL_ERROR) {
1787 for (i=0,protocolMask=0;i<j;i++) {
1788 tmpStr=curlstrdup(Tcl_GetString(protocols[i]));
1789 if (Tcl_GetIndexFromObj(interp,protocols[i],protocolNames,
1790 "protocol",TCL_EXACT,&curlTableIndex)==TCL_ERROR) {
1793 switch(curlTableIndex) {
1794 case 0: /* http 1 */
1795 protocolMask|=CURLPROTO_HTTP;
1797 case 1: /* https 2 */
1798 protocolMask|=CURLPROTO_HTTPS;
1801 protocolMask|=CURLPROTO_FTP;
1803 case 3: /* ftps 8 */
1804 protocolMask|=CURLPROTO_FTPS;
1806 case 4: /* scp 16 */
1807 protocolMask|=CURLPROTO_SCP;
1809 case 5: /* sftp 32 */
1810 protocolMask|=CURLPROTO_SFTP;
1812 case 6: /* telnet 64 */
1813 protocolMask|=CURLPROTO_TELNET;
1815 case 7: /* ldap 128 */
1816 protocolMask|=CURLPROTO_LDAP;
1818 case 8: /* ldaps 256 */
1819 protocolMask|=CURLPROTO_LDAPS;
1821 case 9: /* dict 512 */
1822 protocolMask|=CURLPROTO_DICT;
1824 case 10: /* file 1024 */
1825 protocolMask|=CURLPROTO_FILE;
1827 case 11: /* tftp 2048 */
1828 protocolMask|=CURLPROTO_TFTP;
1830 case 12: /* imap 4096 */
1831 protocolMask|=CURLPROTO_IMAP;
1833 case 13: /* imaps */
1834 protocolMask|=CURLPROTO_IMAPS;
1837 protocolMask|=CURLPROTO_POP3;
1839 case 15: /* pop3s */
1840 protocolMask|=CURLPROTO_POP3S;
1843 protocolMask|=CURLPROTO_SMTP;
1845 case 17: /* smtps */
1846 protocolMask|=CURLPROTO_SMTPS;
1849 protocolMask|=CURLPROTO_RTSP;
1852 protocolMask|=CURLPROTO_RTMP;
1854 case 20: /* rtmpt */
1855 protocolMask|=CURLPROTO_RTMPT;
1857 case 21: /* rtmpe */
1858 protocolMask|=CURLPROTO_RTMPE;
1860 case 22: /* rtmpte */
1861 protocolMask|=CURLPROTO_RTMPTE;
1863 case 23: /* rtmps */
1864 protocolMask|=CURLPROTO_RTMPS;
1866 case 24: /* rtmpts */
1867 protocolMask|=CURLPROTO_RTMPTS;
1869 case 25: /* gopher */
1870 protocolMask|=CURLPROTO_GOPHER;
1872 case 26: /* all FFFF */
1873 protocolMask|=CURLPROTO_ALL;
1876 tmpObjPtr=Tcl_NewLongObj(protocolMask);
1877 if (tableIndex==154) {
1878 longNumber=CURLOPT_PROTOCOLS;
1880 longNumber=CURLOPT_REDIR_PROTOCOLS;
1882 if (SetoptLong(interp,curlHandle,longNumber,tableIndex,tmpObjPtr)) {
1887 if (Tcl_GetIndexFromObj(interp, objv, ftpsslccc,
1888 "Clear Command Channel option ",TCL_EXACT,&intNumber)==TCL_ERROR) {
1893 longNumber=CURLFTPSSL_CCC_NONE;
1896 longNumber=CURLFTPSSL_CCC_PASSIVE;
1899 longNumber=CURLFTPSSL_CCC_ACTIVE;
1902 tmpObjPtr=Tcl_NewLongObj(longNumber);
1903 if (SetoptLong(interp,curlHandle,CURLOPT_FTP_SSL_CCC,
1904 tableIndex,tmpObjPtr)) {
1909 if (SetoptChar(interp,curlHandle,CURLOPT_SSH_KNOWNHOSTS,
1915 if (curl_easy_setopt(curlHandle,CURLOPT_SSH_KEYFUNCTION,curlsshkeycallback)) {
1918 if (curl_easy_setopt(curlHandle,CURLOPT_SSH_KEYDATA,curlData)) {
1921 curlData->sshkeycallProc=curlstrdup(Tcl_GetString(objv));
1924 if (SetoptChar(interp,curlHandle,CURLOPT_MAIL_FROM,
1930 if(SetoptsList(interp,&curlData->mailrcpt,objv)) {
1931 curlErrorSetOpt(interp,configTable,tableIndex,"mailrcpt invalid");
1934 if (curl_easy_setopt(curlHandle,CURLOPT_MAIL_RCPT,curlData->mailrcpt)) {
1935 curlErrorSetOpt(interp,configTable,tableIndex,"mailrcpt invalid");
1936 curl_slist_free_all(curlData->mailrcpt);
1937 curlData->mailrcpt=NULL;
1943 if (SetoptLong(interp,curlHandle,CURLOPT_FTP_USE_PRET,
1949 if (SetoptLong(interp,curlHandle,CURLOPT_WILDCARDMATCH,
1955 curlData->chunkBgnProc=curlstrdup(Tcl_GetString(objv));
1956 if (strcmp(curlData->chunkBgnProc,"")) {
1957 if (curl_easy_setopt(curlHandle,CURLOPT_CHUNK_BGN_FUNCTION,
1958 curlChunkBgnProcInvoke)) {
1962 curl_easy_setopt(curlHandle,CURLOPT_CHUNK_BGN_FUNCTION,NULL);
1965 if (curl_easy_setopt(curlHandle,CURLOPT_CHUNK_DATA,curlData)) {
1970 curlData->chunkBgnVar=curlstrdup(Tcl_GetString(objv));
1971 if (!strcmp(curlData->chunkBgnVar,"")) {
1972 curlErrorSetOpt(interp,configTable,tableIndex,"invalid var name");
1977 curlData->chunkEndProc=curlstrdup(Tcl_GetString(objv));
1978 if (strcmp(curlData->chunkEndProc,"")) {
1979 if (curl_easy_setopt(curlHandle,CURLOPT_CHUNK_END_FUNCTION,
1980 curlChunkEndProcInvoke)) {
1984 curl_easy_setopt(curlHandle,CURLOPT_CHUNK_END_FUNCTION,NULL);
1989 curlData->fnmatchProc=curlstrdup(Tcl_GetString(objv));
1990 if (strcmp(curlData->fnmatchProc,"")) {
1991 if (curl_easy_setopt(curlHandle,CURLOPT_FNMATCH_FUNCTION,
1992 curlfnmatchProcInvoke)) {
1996 curl_easy_setopt(curlHandle,CURLOPT_FNMATCH_FUNCTION,NULL);
1999 if (curl_easy_setopt(curlHandle,CURLOPT_FNMATCH_DATA,curlData)) {
2004 if(SetoptsList(interp,&curlData->resolve,objv)) {
2005 curlErrorSetOpt(interp,configTable,tableIndex,"invalid list");
2008 if (curl_easy_setopt(curlHandle,CURLOPT_RESOLVE,curlData->resolve)) {
2009 curlErrorSetOpt(interp,configTable,tableIndex,"resolve list invalid");
2010 curl_slist_free_all(curlData->resolve);
2011 curlData->resolve=NULL;
2017 if (SetoptChar(interp,curlHandle,CURLOPT_TLSAUTH_USERNAME,
2023 if (SetoptChar(interp,curlHandle,CURLOPT_TLSAUTH_PASSWORD,
2029 if (Tcl_GetIndexFromObj(interp, objv, tlsauth,
2030 "TSL auth option ",TCL_EXACT,&intNumber)==TCL_ERROR) {
2035 longNumber=CURL_TLSAUTH_NONE;
2038 longNumber=CURL_TLSAUTH_SRP;
2040 tmpObjPtr=Tcl_NewLongObj(longNumber);
2041 if (SetoptLong(interp,curlHandle,CURLOPT_TLSAUTH_TYPE,
2042 tableIndex,tmpObjPtr)) {
2047 if (SetoptLong(interp,curlHandle,CURLOPT_TRANSFER_ENCODING,
2053 if (Tcl_GetIndexFromObj(interp, objv, gssapidelegation,
2054 "GSS API delegation option ",TCL_EXACT,&intNumber)==TCL_ERROR) {
2059 longNumber=CURLGSSAPI_DELEGATION_FLAG;
2062 longNumber=CURLGSSAPI_DELEGATION_POLICY_FLAG;
2064 tmpObjPtr=Tcl_NewLongObj(longNumber);
2065 if (SetoptLong(interp,curlHandle,CURLOPT_GSSAPI_DELEGATION,
2066 tableIndex,tmpObjPtr)) {
2071 if (SetoptChar(interp,curlHandle,CURLOPT_NOPROXY,
2077 if(SetoptsList(interp,&curlData->telnetoptions,objv)) {
2078 curlErrorSetOpt(interp,configTable,tableIndex,"invalid list");
2081 if (curl_easy_setopt(curlHandle,CURLOPT_TELNETOPTIONS,curlData->telnetoptions)) {
2082 curlErrorSetOpt(interp,configTable,tableIndex,"telnetoptions list invalid");
2083 curl_slist_free_all(curlData->telnetoptions);
2084 curlData->telnetoptions=NULL;
2094 *----------------------------------------------------------------------
2098 * Sets the curl options that require an int
2101 * interp: The interpreter we are working with.
2102 * curlHandle: and the curl handle
2103 * opt: the option to set
2104 * tclObj: The Tcl with the value for the option.
2107 * 0 if all went well.
2108 * 1 in case of error.
2109 *----------------------------------------------------------------------
2112 SetoptInt(Tcl_Interp *interp,CURL *curlHandle,CURLoption opt,
2113 int tableIndex,Tcl_Obj *tclObj) {
2117 if (Tcl_GetIntFromObj(interp,tclObj,&intNumber)) {
2118 parPtr=curlstrdup(Tcl_GetString(tclObj));
2119 curlErrorSetOpt(interp,configTable,tableIndex,parPtr);
2123 if (curl_easy_setopt(curlHandle,opt,intNumber)) {
2124 parPtr=curlstrdup(Tcl_GetString(tclObj));
2125 curlErrorSetOpt(interp,configTable,tableIndex,parPtr);
2133 *----------------------------------------------------------------------
2137 * Set the curl options that require a long
2140 * interp: The interpreter we are working with.
2141 * curlHandle: and the curl handle
2142 * opt: the option to set
2143 * tclObj: The Tcl with the value for the option.
2146 * 0 if all went well.
2147 * 1 in case of error.
2148 *----------------------------------------------------------------------
2151 SetoptLong(Tcl_Interp *interp,CURL *curlHandle,CURLoption opt,
2152 int tableIndex,Tcl_Obj *tclObj) {
2156 if (Tcl_GetLongFromObj(interp,tclObj,&longNumber)) {
2157 parPtr=curlstrdup(Tcl_GetString(tclObj));
2158 curlErrorSetOpt(interp,configTable,tableIndex,parPtr);
2162 if (curl_easy_setopt(curlHandle,opt,longNumber)) {
2163 parPtr=curlstrdup(Tcl_GetString(tclObj));
2164 curlErrorSetOpt(interp,configTable,tableIndex,parPtr);
2173 *----------------------------------------------------------------------
2175 * curlSetoptCurlOffT --
2177 * Set the curl options that require a curl_off_t, even if we really
2178 * use a long to do it. (Cutting and pasting at its worst)
2181 * interp: The interpreter we are working with.
2182 * curlHandle: and the curl handle
2183 * opt: the option to set
2184 * tclObj: The Tcl with the value for the option.
2187 * 0 if all went well.
2188 * 1 in case of error.
2189 *----------------------------------------------------------------------
2192 SetoptCurlOffT(Tcl_Interp *interp,CURL *curlHandle,CURLoption opt,
2193 int tableIndex,Tcl_Obj *tclObj) {
2197 if (Tcl_GetLongFromObj(interp,tclObj,&longNumber)) {
2198 parPtr=curlstrdup(Tcl_GetString(tclObj));
2199 curlErrorSetOpt(interp,configTable,tableIndex,parPtr);
2204 if (curl_easy_setopt(curlHandle,opt,(curl_off_t)longNumber)) {
2205 parPtr=curlstrdup(Tcl_GetString(tclObj));
2206 curlErrorSetOpt(interp,configTable,tableIndex,parPtr);
2216 *----------------------------------------------------------------------
2220 * Set the curl options that require a string
2223 * interp: The interpreter we are working with.
2224 * curlHandle: and the curl handle
2225 * opt: the option to set
2226 * tclObj: The Tcl with the value for the option.
2229 * 0 if all went well.
2230 * 1 in case of error.
2231 *----------------------------------------------------------------------
2234 SetoptChar(Tcl_Interp *interp,CURL *curlHandle,
2235 CURLoption opt,int tableIndex,Tcl_Obj *tclObj) {
2238 optionPtr=curlstrdup(Tcl_GetString(tclObj));
2239 if (curl_easy_setopt(curlHandle,opt,optionPtr)) {
2240 curlErrorSetOpt(interp,configTable,tableIndex,optionPtr);
2241 Tcl_Free(optionPtr);
2244 Tcl_Free(optionPtr);
2249 *----------------------------------------------------------------------
2253 * Set the curl options that require a share handle (there is only
2254 * one but you never know.
2257 * interp: The interpreter we are working with.
2258 * curlHandle: the curl handle
2259 * opt: the option to set
2260 * tclObj: The Tcl with the value for the option.
2263 * 0 if all went well.
2264 * 1 in case of error.
2265 *----------------------------------------------------------------------
2268 SetoptSHandle(Tcl_Interp *interp,CURL *curlHandle,
2269 CURLoption opt,int tableIndex,Tcl_Obj *tclObj) {
2272 Tcl_CmdInfo *infoPtr=(Tcl_CmdInfo *)Tcl_Alloc(sizeof(Tcl_CmdInfo));
2273 struct shcurlObjData *shandleDataPtr;
2275 shandleName=Tcl_GetString(tclObj);
2276 if (0==Tcl_GetCommandInfo(interp,shandleName,infoPtr)) {
2279 shandleDataPtr=(struct shcurlObjData *)(infoPtr->objClientData);
2280 Tcl_Free((char *)infoPtr);
2281 if (curl_easy_setopt(curlHandle,opt,shandleDataPtr->shandle)) {
2282 curlErrorSetOpt(interp,configTable,tableIndex,shandleName);
2289 *----------------------------------------------------------------------
2293 * Prepares a slist for future use.
2296 * slistPtr: Pointer to the slist to prepare.
2297 * objv: Tcl object with a list of the data.
2300 * 0 if all went well.
2301 * 1 in case of error.
2302 *----------------------------------------------------------------------
2305 SetoptsList(Tcl_Interp *interp,struct curl_slist **slistPtr,
2306 Tcl_Obj *CONST objv) {
2310 if (slistPtr!=NULL) {
2311 curl_slist_free_all(*slistPtr);
2315 if (Tcl_ListObjGetElements(interp,objv,&headerNumber,&headers)
2320 for (i=0;i<headerNumber;i++) {
2321 *slistPtr=curl_slist_append(*slistPtr,Tcl_GetString(headers[i]));
2322 if (slistPtr==NULL) {
2330 *----------------------------------------------------------------------
2332 * curlErrorSetOpt --
2334 * When an error happens when setting an option, this function
2335 * takes cares of reporting it
2338 * interp: Pointer to the interpreter we are using.
2339 * option: The index of the option in 'optionTable'
2340 * parPtr: String with the parameter we wanted to set the option to.
2341 *----------------------------------------------------------------------
2345 curlErrorSetOpt(Tcl_Interp *interp,CONST char **configTable, int option,
2346 CONST char *parPtr) {
2350 snprintf(errorMsg,500,"setting option %s: %s",configTable[option],parPtr);
2351 resultPtr=Tcl_NewStringObj(errorMsg,-1);
2352 Tcl_SetObjResult(interp,resultPtr);
2356 *----------------------------------------------------------------------
2360 * This is the function that will be invoked if the user wants to put
2361 * the headers into a variable
2364 * header: string with the header line.
2365 * size and nmemb: it so happens size * nmemb if the size of the
2367 * curlData: A pointer to the curlData structure for the transfer.
2370 * The number of bytes actually written or -1 in case of error, in
2371 * which case 'libcurl' will abort the transfer.
2372 *-----------------------------------------------------------------------
2375 curlHeaderReader(void *ptr,size_t size,size_t nmemb,FILE *curlDataPtr) {
2378 struct curlObjData *curlData=(struct curlObjData *)curlDataPtr;
2381 CONST char *startPtr;
2385 char *headerContent;
2388 int match,charLength;
2390 regExp=Tcl_RegExpCompile(curlData->interp,"(.*?)(?::\\s*)(.*?)(\\r*)(\\n)");
2391 match=Tcl_RegExpExec(curlData->interp,regExp,header,header);
2394 Tcl_RegExpRange(regExp,1,&startPtr,&endPtr);
2395 charLength=endPtr-startPtr;
2396 headerName=Tcl_Alloc(charLength+1);
2397 strncpy(headerName,startPtr,charLength);
2398 headerName[charLength]=0;
2400 Tcl_RegExpRange(regExp,2,&startPtr,&endPtr);
2401 charLength=endPtr-startPtr;
2402 headerContent=Tcl_Alloc(charLength+1);
2403 strncpy(headerContent,startPtr,charLength);
2404 headerContent[charLength]=0;
2405 /* There may be multiple 'Set-Cookie' headers, so we use a list */
2406 if (Tcl_StringCaseMatch(headerName,"Set-Cookie",1)) {
2407 Tcl_SetVar2(curlData->interp,curlData->headerVar,headerName, \
2408 headerContent,TCL_LIST_ELEMENT|TCL_APPEND_VALUE);
2410 Tcl_SetVar2(curlData->interp,curlData->headerVar,headerName,
2414 regExp=Tcl_RegExpCompile(curlData->interp,"(^(HTTP|http)[^\r]+)(\r*)(\n)");
2415 match=Tcl_RegExpExec(curlData->interp,regExp,header,header);
2417 Tcl_RegExpRange(regExp,1,&startPtr,&endPtr);
2418 charLength=endPtr-startPtr;
2419 httpStatus=Tcl_Alloc(charLength+1);
2420 strncpy(httpStatus,startPtr,charLength);
2421 httpStatus[charLength]=0;
2423 Tcl_SetVar2(curlData->interp,curlData->headerVar,"http",
2430 *----------------------------------------------------------------------
2434 * This is the function that will be invoked as a callback while
2435 * transferring the body of a request into a Tcl variable.
2437 * This function has been adapted from an example in libcurl's FAQ.
2440 * header: string with the header line.
2441 * size and nmemb: it so happens size * nmemb if the size of the
2443 * curlData: A pointer to the curlData structure for the transfer.
2446 * The number of bytes actually written or -1 in case of error, in
2447 * which case 'libcurl' will abort the transfer.
2448 *-----------------------------------------------------------------------
2451 curlBodyReader(void *ptr,size_t size,size_t nmemb,FILE *curlDataPtr) {
2453 register int realsize = size * nmemb;
2454 struct MemoryStruct *mem=&(((struct curlObjData *)curlDataPtr)->bodyVar);
2456 mem->memory = (char *)Tcl_Realloc(mem->memory,mem->size + realsize);
2458 memcpy(&(mem->memory[mem->size]), ptr, realsize);
2459 mem->size += realsize;
2465 *----------------------------------------------------------------------
2467 * curlProgressCallback --
2469 * This is the function that will be invoked as a callback during a
2472 * This function has been adapted from an example in libcurl's FAQ.
2475 * clientData: The curlData struct for the transfer.
2476 * dltotal: Total amount of bytes to download.
2477 * dlnow: Bytes downloaded so far.
2478 * ultotal: Total amount of bytes to upload.
2479 * ulnow: Bytes uploaded so far.
2482 * Returning a non-zero value will make 'libcurl' abort the transfer
2483 * and return 'CURLE_ABORTED_BY_CALLBACK'.
2484 *-----------------------------------------------------------------------
2487 curlProgressCallback(void *clientData,double dltotal,double dlnow,
2488 double ultotal,double ulnow) {
2490 struct curlObjData *curlData=(struct curlObjData *)clientData;
2491 Tcl_Obj *tclProcPtr;
2492 char tclCommand[300];
2494 snprintf(tclCommand,299,"%s %f %f %f %f",curlData->progressProc,dltotal,
2495 dlnow,ultotal,ulnow);
2496 tclProcPtr=Tcl_NewStringObj(tclCommand,-1);
2497 if (curlData->cancelTransVarName) {
2498 if (curlData->cancelTrans) {
2499 curlData->cancelTrans=0;
2503 if (Tcl_EvalObjEx(curlData->interp,tclProcPtr,TCL_EVAL_GLOBAL)!=TCL_OK) {
2510 *----------------------------------------------------------------------
2512 * curlWriteProcInvoke --
2514 * This is the function that will be invoked as a callback when the user
2515 * wants to invoke a Tcl procedure to write the recieved data.
2517 * This function has been adapted from an example in libcurl's FAQ.
2520 * ptr: A pointer to the data.
2521 * size and nmemb: it so happens size * nmemb if the size of the
2523 * curlData: A pointer to the curlData structure for the transfer.
2526 * The number of bytes actually written or -1 in case of error, in
2527 * which case 'libcurl' will abort the transfer.
2528 *-----------------------------------------------------------------------
2531 curlWriteProcInvoke(void *ptr,size_t size,size_t nmemb,FILE *curlDataPtr) {
2532 register int realsize = size * nmemb;
2533 struct curlObjData *curlData=(struct curlObjData *)curlDataPtr;
2536 objv[0]=Tcl_NewStringObj(curlData->writeProc,-1);
2537 objv[1]=Tcl_NewByteArrayObj(ptr,realsize);
2538 if (curlData->cancelTransVarName) {
2539 if (curlData->cancelTrans) {
2540 curlData->cancelTrans=0;
2544 if (Tcl_EvalObjv(curlData->interp,2,objv,TCL_EVAL_GLOBAL)!=TCL_OK) {
2551 *----------------------------------------------------------------------
2553 * curlReadProcInvoke --
2555 * This is the function that will be invoked as a callback when the user
2556 * wants to invoke a Tcl procedure to read the data to send.
2559 * header: string with the header line.
2560 * size and nmemb: it so happens size * nmemb if the size of the
2562 * curlData: A pointer to the curlData structure for the transfer.
2565 * The number of bytes actually read or CURL_READFUNC_ABORT in case
2566 * of error, in which case 'libcurl' will abort the transfer.
2567 *-----------------------------------------------------------------------
2570 curlReadProcInvoke(void *ptr,size_t size,size_t nmemb,FILE *curlDataPtr) {
2571 register int realsize = size * nmemb;
2572 struct curlObjData *curlData=(struct curlObjData *)curlDataPtr;
2573 Tcl_Obj *tclProcPtr;
2574 Tcl_Obj *readDataPtr;
2575 char tclCommand[300];
2576 unsigned char *readBytes;
2579 snprintf(tclCommand,300,"%s %d",curlData->readProc,realsize);
2580 tclProcPtr=Tcl_NewStringObj(tclCommand,-1);
2582 if (curlData->cancelTransVarName) {
2583 if (curlData->cancelTrans) {
2584 curlData->cancelTrans=0;
2585 return CURL_READFUNC_ABORT;
2588 if (Tcl_EvalObjEx(curlData->interp,tclProcPtr,TCL_EVAL_GLOBAL)!=TCL_OK) {
2589 return CURL_READFUNC_ABORT;
2591 readDataPtr=Tcl_GetObjResult(curlData->interp);
2592 readBytes=Tcl_GetByteArrayFromObj(readDataPtr,&sizeRead);
2593 memcpy(ptr,readBytes,sizeRead);
2599 *----------------------------------------------------------------------
2601 * curlChunkBgnProcInvoke --
2603 * This is the function that will be invoked as a callback when the user
2604 * wants to invoke a Tcl procedure to process every wildcard matching file
2605 * on a ftp transfer.
2608 * transfer_info: a curl_fileinfo structure about the file.
2609 * curlData: A pointer to the curlData structure for the transfer.
2610 * remains: number of chunks remaining.
2611 *-----------------------------------------------------------------------
2614 curlChunkBgnProcInvoke (const void *transfer_info, void *curlDataPtr, int remains) {
2615 struct curlObjData *curlData=(struct curlObjData *)curlDataPtr;
2616 Tcl_Obj *tclProcPtr;
2617 char tclCommand[300];
2619 const struct curl_fileinfo *fileinfoPtr=(const struct curl_fileinfo *)transfer_info;
2621 tclProcPtr=Tcl_NewStringObj(tclCommand,-1);
2623 if (curlData->chunkBgnVar==NULL) {
2624 curlData->chunkBgnVar=curlstrdup("fileData");
2627 Tcl_SetVar2(curlData->interp,curlData->chunkBgnVar,"filename",
2628 fileinfoPtr->filename,0);
2630 switch(fileinfoPtr->filetype) {
2632 Tcl_SetVar2(curlData->interp,curlData->chunkBgnVar,"filetype",
2636 Tcl_SetVar2(curlData->interp,curlData->chunkBgnVar,"filetype",
2640 Tcl_SetVar2(curlData->interp,curlData->chunkBgnVar,"filetype",
2644 Tcl_SetVar2(curlData->interp,curlData->chunkBgnVar,"filetype",
2648 Tcl_SetVar2(curlData->interp,curlData->chunkBgnVar,"filetype",
2652 Tcl_SetVar2(curlData->interp,curlData->chunkBgnVar,"filetype",
2656 Tcl_SetVar2(curlData->interp,curlData->chunkBgnVar,"filetype",
2660 Tcl_SetVar2(curlData->interp,curlData->chunkBgnVar,"filetype",
2664 Tcl_SetVar2(curlData->interp,curlData->chunkBgnVar,"filetype",
2669 Tcl_SetVar2Ex(curlData->interp,curlData->chunkBgnVar,"time",
2670 Tcl_NewLongObj(fileinfoPtr->time),0);
2672 Tcl_SetVar2Ex(curlData->interp,curlData->chunkBgnVar,"perm",
2673 Tcl_NewIntObj(fileinfoPtr->perm),0);
2675 Tcl_SetVar2Ex(curlData->interp,curlData->chunkBgnVar,"uid",
2676 Tcl_NewIntObj(fileinfoPtr->uid),0);
2677 Tcl_SetVar2Ex(curlData->interp,curlData->chunkBgnVar,"gid",
2678 Tcl_NewIntObj(fileinfoPtr->gid),0);
2679 Tcl_SetVar2Ex(curlData->interp,curlData->chunkBgnVar,"size",
2680 Tcl_NewLongObj(fileinfoPtr->size),0);
2681 Tcl_SetVar2Ex(curlData->interp,curlData->chunkBgnVar,"hardlinks",
2682 Tcl_NewIntObj(fileinfoPtr->hardlinks),0);
2683 Tcl_SetVar2Ex(curlData->interp,curlData->chunkBgnVar,"flags",
2684 Tcl_NewIntObj(fileinfoPtr->flags),0);
2686 snprintf(tclCommand,300,"%s %d",curlData->chunkBgnProc,remains);
2687 tclProcPtr=Tcl_NewStringObj(tclCommand,-1);
2689 if (Tcl_EvalObjEx(curlData->interp,tclProcPtr,TCL_EVAL_GLOBAL)!=TCL_OK) {
2690 return CURL_CHUNK_BGN_FUNC_FAIL;
2693 if (Tcl_GetIntFromObj(curlData->interp,Tcl_GetObjResult(curlData->interp),&i)!=TCL_OK) {
2694 return CURL_CHUNK_BGN_FUNC_FAIL;
2698 return CURL_CHUNK_BGN_FUNC_OK;
2700 return CURL_CHUNK_BGN_FUNC_SKIP;
2702 return CURL_CHUNK_BGN_FUNC_FAIL;
2706 *----------------------------------------------------------------------
2708 * curlChunkEndProcInvoke --
2710 * This is the function that will be invoked every time a file has
2711 * been downloaded or skipped, it does little more than called the
2715 * curlData: A pointer to the curlData structure for the transfer.
2718 *-----------------------------------------------------------------------
2721 curlChunkEndProcInvoke (void *curlDataPtr) {
2723 struct curlObjData *curlData=(struct curlObjData *)curlDataPtr;
2724 Tcl_Obj *tclProcPtr;
2725 char tclCommand[300];
2728 snprintf(tclCommand,300,"%s",curlData->chunkEndProc);
2729 tclProcPtr=Tcl_NewStringObj(tclCommand,-1);
2731 if (Tcl_EvalObjEx(curlData->interp,tclProcPtr,TCL_EVAL_GLOBAL)!=TCL_OK) {
2732 return CURL_CHUNK_END_FUNC_FAIL;
2735 if (Tcl_GetIntFromObj(curlData->interp,Tcl_GetObjResult(curlData->interp),&i)!=TCL_OK) {
2736 return CURL_CHUNK_END_FUNC_FAIL;
2739 return CURL_CHUNK_BGN_FUNC_FAIL;
2741 return CURL_CHUNK_END_FUNC_OK;
2745 *----------------------------------------------------------------------
2747 * curlfnmatchProcInvoke --
2749 * This is the function that will be invoked to tell whether a filename
2750 * matches a pattern when doing a 'wildcard' download. It invokes a Tcl
2751 * proc to do the actual work.
2754 * curlData: A pointer to the curlData structure for the transfer.
2755 * pattern: The pattern to match.
2756 * filename: The file name to be matched.
2757 *-----------------------------------------------------------------------
2759 int curlfnmatchProcInvoke(void *curlDataPtr, const char *pattern, const char *filename) {
2761 struct curlObjData *curlData=(struct curlObjData *)curlDataPtr;
2762 Tcl_Obj *tclProcPtr;
2763 char tclCommand[500];
2766 snprintf(tclCommand,500,"%s %s %s",curlData->fnmatchProc,pattern,filename);
2767 tclProcPtr=Tcl_NewStringObj(tclCommand,-1);
2769 if (Tcl_EvalObjEx(curlData->interp,tclProcPtr,TCL_EVAL_GLOBAL)!=TCL_OK) {
2770 return CURL_FNMATCHFUNC_FAIL;
2773 if (Tcl_GetIntFromObj(curlData->interp,Tcl_GetObjResult(curlData->interp),&i)!=TCL_OK) {
2774 return CURL_FNMATCHFUNC_FAIL;
2778 return CURL_FNMATCHFUNC_MATCH;
2780 return CURL_FNMATCHFUNC_NOMATCH;
2782 return CURL_FNMATCHFUNC_FAIL;
2786 *----------------------------------------------------------------------
2788 * curlshkeyextract --
2790 * Out of one of libcurl's ssh key struct, this function will return a
2791 * Tcl_Obj with a list, the first element is the type ok key, the second
2795 * interp: The interp need to deal with the objects.
2796 * key: a curl_khkey struct with the key.
2799 * The object with the list.
2800 *-----------------------------------------------------------------------
2803 curlsshkeyextract(Tcl_Interp *interp,const struct curl_khkey *key) {
2807 keyObjPtr=Tcl_NewListObj(0,(Tcl_Obj **)NULL);
2809 switch(key->keytype) {
2810 case CURLKHTYPE_RSA1:
2811 Tcl_ListObjAppendElement(interp,keyObjPtr,Tcl_NewStringObj("rsa1",-1));
2813 case CURLKHTYPE_RSA:
2814 Tcl_ListObjAppendElement(interp,keyObjPtr,Tcl_NewStringObj("rsa",-1));
2816 case CURLKHTYPE_DSS:
2817 Tcl_ListObjAppendElement(interp,keyObjPtr,Tcl_NewStringObj("dss",-1));
2820 Tcl_ListObjAppendElement(interp,keyObjPtr,Tcl_NewStringObj("unknnown",-1));
2823 Tcl_ListObjAppendElement(interp,keyObjPtr,Tcl_NewStringObj(key->key,-1));
2829 *----------------------------------------------------------------------
2831 * curlshkeycallback --
2833 * This is the function that will be invoked as a callback when the user
2834 * wants to invoke a Tcl procedure to decide about this new ssh host
2837 * curl: curl's easy handle for the connection.
2838 * knownkey: The key from the hosts_file.
2839 * foundkey: The key from the remote site.
2840 * match: What libcurl thinks about how they match
2841 * curlDataPtr: Points to the structure with all the TclCurl data
2842 * for the connection.
2845 * A libcurl return code so that libcurl knows what to do.
2846 *-----------------------------------------------------------------------
2849 curlsshkeycallback(CURL *curl ,const struct curl_khkey *knownkey,
2850 const struct curl_khkey *foundkey, enum curl_khmatch match,void *curlDataPtr) {
2852 struct curlObjData *tclcurlDataPtr=(struct curlObjData *)curlDataPtr;
2856 Tcl_Obj *returnObjPtr;
2860 interp=tclcurlDataPtr->interp;
2862 objv[0]=Tcl_NewStringObj(tclcurlDataPtr->sshkeycallProc,-1);
2863 objv[1]=curlsshkeyextract(interp,knownkey);
2864 objv[2]=curlsshkeyextract(interp,foundkey);
2867 case CURLKHMATCH_OK:
2868 objv[3]=Tcl_NewStringObj("match",-1);
2870 case CURLKHMATCH_MISMATCH:
2871 objv[3]=Tcl_NewStringObj("mismatch",-1);
2873 case CURLKHMATCH_MISSING:
2874 objv[3]=Tcl_NewStringObj("missing",-1);
2876 case CURLKHMATCH_LAST:
2877 objv[3]=Tcl_NewStringObj("error",-1);
2880 if (Tcl_EvalObjv(interp,4,objv,TCL_EVAL_GLOBAL)!=TCL_OK) {return CURLKHSTAT_REJECT;}
2882 returnObjPtr=Tcl_GetObjResult(interp);
2884 if (Tcl_GetIntFromObj(interp,returnObjPtr,&action)!=TCL_OK) {return CURLKHSTAT_REJECT;}
2888 return CURLKHSTAT_FINE_ADD_TO_FILE;
2890 return CURLKHSTAT_FINE;
2892 return CURLKHSTAT_REJECT;
2894 return CURLKHSTAT_DEFER;
2896 return CURLKHSTAT_REJECT;
2900 *----------------------------------------------------------------------
2902 * curlDebugProcInvoke --
2904 * This is the function that will be invoked as a callback when the user
2905 * wants to invoke a Tcl procedure to write the debug data produce by
2906 * the verbose option.
2909 * curlHandle: A pointer to the handle for the transfer.
2910 * infoType: Integer with the type of data.
2911 * dataPtr: the data passed to the procedure.
2912 * curlDataPtr: ointer to the curlData structure for the transfer.
2915 * The number of bytes actually written or -1 in case of error, in
2916 * which case 'libcurl' will abort the transfer.
2917 *-----------------------------------------------------------------------
2920 curlDebugProcInvoke(CURL *curlHandle, curl_infotype infoType,
2921 char * dataPtr, size_t size, void *curlDataPtr) {
2922 struct curlObjData *curlData=(struct curlObjData *)curlDataPtr;
2923 Tcl_Obj *tclProcPtr;
2925 char tclCommand[300];
2927 snprintf(tclCommand,300,"%s %d %d",curlData->debugProc,infoType,size);
2928 tclProcPtr=Tcl_NewStringObj(tclCommand,-1);
2930 objv[0]=Tcl_NewStringObj(curlData->debugProc,-1);
2931 objv[1]=Tcl_NewIntObj(infoType);
2932 objv[2]=Tcl_NewByteArrayObj((CONST unsigned char *)dataPtr,size);
2934 if (curlData->cancelTransVarName) {
2935 if (curlData->cancelTrans) {
2936 curlData->cancelTrans=0;
2941 Tcl_EvalObjv(curlData->interp,3,objv,TCL_EVAL_GLOBAL);
2947 *----------------------------------------------------------------------
2951 * Invokes the 'curl_easy_getinfo' function in libcurl.
2956 * 0 if all went well.
2957 * The CURLcode for the error.
2958 *----------------------------------------------------------------------
2961 curlGetInfo(Tcl_Interp *interp,CURL *curlHandle,int tableIndex) {
2964 double doubleNumber;
2965 struct curl_slist *slistPtr;
2966 struct curl_certinfo *certinfoPtr=NULL;
2971 Tcl_Obj *resultObjPtr;
2973 switch(tableIndex) {
2975 exitCode=curl_easy_getinfo(curlHandle,CURLINFO_EFFECTIVE_URL,&charPtr);
2979 resultObjPtr=Tcl_NewStringObj(charPtr,-1);
2980 Tcl_SetObjResult(interp,resultObjPtr);
2984 exitCode=curl_easy_getinfo(curlHandle,CURLINFO_RESPONSE_CODE,&longNumber);
2988 resultObjPtr=Tcl_NewLongObj(longNumber);
2989 Tcl_SetObjResult(interp,resultObjPtr);
2992 exitCode=curl_easy_getinfo(curlHandle,CURLINFO_FILETIME,&longNumber);
2996 resultObjPtr=Tcl_NewLongObj(longNumber);
2997 Tcl_SetObjResult(interp,resultObjPtr);
3000 exitCode=curl_easy_getinfo(curlHandle,CURLINFO_TOTAL_TIME,&doubleNumber);
3004 resultObjPtr=Tcl_NewDoubleObj(doubleNumber);
3005 Tcl_SetObjResult(interp,resultObjPtr);
3008 exitCode=curl_easy_getinfo(curlHandle,CURLINFO_NAMELOOKUP_TIME,
3013 resultObjPtr=Tcl_NewDoubleObj(doubleNumber);
3014 Tcl_SetObjResult(interp,resultObjPtr);
3017 exitCode=curl_easy_getinfo(curlHandle,CURLINFO_CONNECT_TIME,
3022 resultObjPtr=Tcl_NewDoubleObj(doubleNumber);
3023 Tcl_SetObjResult(interp,resultObjPtr);
3026 exitCode=curl_easy_getinfo(curlHandle,CURLINFO_PRETRANSFER_TIME,
3031 resultObjPtr=Tcl_NewDoubleObj(doubleNumber);
3032 Tcl_SetObjResult(interp,resultObjPtr);
3035 exitCode=curl_easy_getinfo(curlHandle,CURLINFO_SIZE_UPLOAD,
3040 resultObjPtr=Tcl_NewDoubleObj(doubleNumber);
3041 Tcl_SetObjResult(interp,resultObjPtr);
3044 exitCode=curl_easy_getinfo(curlHandle,CURLINFO_SIZE_DOWNLOAD,
3049 resultObjPtr=Tcl_NewDoubleObj(doubleNumber);
3050 Tcl_SetObjResult(interp,resultObjPtr);
3053 exitCode=curl_easy_getinfo(curlHandle,CURLINFO_SPEED_DOWNLOAD,
3058 resultObjPtr=Tcl_NewDoubleObj(doubleNumber);
3059 Tcl_SetObjResult(interp,resultObjPtr);
3062 exitCode=curl_easy_getinfo(curlHandle,CURLINFO_SPEED_UPLOAD,
3067 resultObjPtr=Tcl_NewDoubleObj(doubleNumber);
3068 Tcl_SetObjResult(interp,resultObjPtr);
3071 exitCode=curl_easy_getinfo(curlHandle,CURLINFO_HEADER_SIZE,
3076 resultObjPtr=Tcl_NewLongObj(longNumber);
3077 Tcl_SetObjResult(interp,resultObjPtr);
3080 exitCode=curl_easy_getinfo(curlHandle,CURLINFO_REQUEST_SIZE,
3085 resultObjPtr=Tcl_NewLongObj(longNumber);
3086 Tcl_SetObjResult(interp,resultObjPtr);
3089 exitCode=curl_easy_getinfo(curlHandle,CURLINFO_SSL_VERIFYRESULT,
3094 resultObjPtr=Tcl_NewLongObj(longNumber);
3095 Tcl_SetObjResult(interp,resultObjPtr);
3098 exitCode=curl_easy_getinfo(curlHandle,CURLINFO_CONTENT_LENGTH_DOWNLOAD,
3103 resultObjPtr=Tcl_NewDoubleObj(doubleNumber);
3104 Tcl_SetObjResult(interp,resultObjPtr);
3107 exitCode=curl_easy_getinfo(curlHandle,CURLINFO_CONTENT_LENGTH_UPLOAD,
3112 resultObjPtr=Tcl_NewDoubleObj(doubleNumber);
3113 Tcl_SetObjResult(interp,resultObjPtr);
3116 exitCode=curl_easy_getinfo(curlHandle,CURLINFO_STARTTRANSFER_TIME,&doubleNumber);
3120 resultObjPtr=Tcl_NewDoubleObj(doubleNumber);
3121 Tcl_SetObjResult(interp,resultObjPtr);
3124 exitCode=curl_easy_getinfo(curlHandle,CURLINFO_CONTENT_TYPE,&charPtr);
3128 resultObjPtr=Tcl_NewStringObj(charPtr,-1);
3129 Tcl_SetObjResult(interp,resultObjPtr);
3132 exitCode=curl_easy_getinfo(curlHandle,CURLINFO_REDIRECT_TIME,&doubleNumber);
3136 resultObjPtr=Tcl_NewDoubleObj(doubleNumber);
3137 Tcl_SetObjResult(interp,resultObjPtr);
3140 exitCode=curl_easy_getinfo(curlHandle,CURLINFO_REDIRECT_COUNT,&longNumber);
3144 resultObjPtr=Tcl_NewLongObj(longNumber);
3145 Tcl_SetObjResult(interp,resultObjPtr);
3149 if (tableIndex==21) {
3150 exitCode=curl_easy_getinfo(curlHandle,CURLINFO_HTTPAUTH_AVAIL,&longNumber);
3152 exitCode=curl_easy_getinfo(curlHandle,CURLINFO_PROXYAUTH_AVAIL,&longNumber);
3157 resultObjPtr=Tcl_NewListObj(0,(Tcl_Obj **)NULL);
3158 if (longNumber&CURLAUTH_BASIC) {
3159 Tcl_ListObjAppendElement(interp,resultObjPtr
3160 ,Tcl_NewStringObj("basic",-1));
3162 if (longNumber&CURLAUTH_DIGEST) {
3163 Tcl_ListObjAppendElement(interp,resultObjPtr
3164 ,Tcl_NewStringObj("digest",-1));
3166 if (longNumber&CURLAUTH_GSSNEGOTIATE) {
3167 Tcl_ListObjAppendElement(interp,resultObjPtr
3168 ,Tcl_NewStringObj("gssnegotiate",-1));
3170 if (longNumber&CURLAUTH_NTLM) {
3171 Tcl_ListObjAppendElement(interp,resultObjPtr
3172 ,Tcl_NewStringObj("NTLM",-1));
3174 Tcl_SetObjResult(interp,resultObjPtr);
3177 exitCode=curl_easy_getinfo(curlHandle,CURLINFO_OS_ERRNO,&longNumber);
3181 resultObjPtr=Tcl_NewLongObj(longNumber);
3182 Tcl_SetObjResult(interp,resultObjPtr);
3185 exitCode=curl_easy_getinfo(curlHandle,CURLINFO_NUM_CONNECTS,&longNumber);
3189 resultObjPtr=Tcl_NewLongObj(longNumber);
3190 Tcl_SetObjResult(interp,resultObjPtr);
3193 exitCode=curl_easy_getinfo \
3194 (curlHandle,CURLINFO_SSL_ENGINES,&slistPtr);
3198 resultObjPtr=Tcl_NewListObj(0,(Tcl_Obj **)NULL);
3199 while(slistPtr!=NULL) {
3200 Tcl_ListObjAppendElement(interp,resultObjPtr
3201 ,Tcl_NewStringObj(slistPtr->data,-1));
3202 slistPtr=slistPtr->next;
3204 curl_slist_free_all(slistPtr);
3205 Tcl_SetObjResult(interp,resultObjPtr);
3208 exitCode=curl_easy_getinfo \
3209 (curlHandle,CURLINFO_HTTP_CONNECTCODE,&longNumber);
3213 resultObjPtr=Tcl_NewLongObj(longNumber);
3214 Tcl_SetObjResult(interp,resultObjPtr);
3217 exitCode=curl_easy_getinfo \
3218 (curlHandle,CURLINFO_COOKIELIST,&slistPtr);
3222 resultObjPtr=Tcl_NewListObj(0,(Tcl_Obj **)NULL);
3223 while(slistPtr!=NULL) {
3224 Tcl_ListObjAppendElement(interp,resultObjPtr
3225 ,Tcl_NewStringObj(slistPtr->data,-1));
3226 slistPtr=slistPtr->next;
3228 curl_slist_free_all(slistPtr);
3229 Tcl_SetObjResult(interp,resultObjPtr);
3232 exitCode=curl_easy_getinfo(curlHandle,CURLINFO_FTP_ENTRY_PATH,&charPtr);
3236 resultObjPtr=Tcl_NewStringObj(charPtr,-1);
3237 Tcl_SetObjResult(interp,resultObjPtr);
3240 exitCode=curl_easy_getinfo(curlHandle,CURLINFO_REDIRECT_URL,&charPtr);
3244 resultObjPtr=Tcl_NewStringObj(charPtr,-1);
3245 Tcl_SetObjResult(interp,resultObjPtr);
3248 exitCode=curl_easy_getinfo(curlHandle,CURLINFO_PRIMARY_IP,&charPtr);
3252 resultObjPtr=Tcl_NewStringObj(charPtr,-1);
3253 Tcl_SetObjResult(interp,resultObjPtr);
3256 exitCode=curl_easy_getinfo(curlHandle,CURLINFO_APPCONNECT_TIME,&doubleNumber);
3260 resultObjPtr=Tcl_NewDoubleObj(doubleNumber);
3261 Tcl_SetObjResult(interp,resultObjPtr);
3264 exitCode=curl_easy_getinfo(curlHandle,CURLINFO_CERTINFO,certinfoPtr);
3268 charPtr=(char *)Tcl_Alloc(3);
3269 sprintf(charPtr,"%d",certinfoPtr->num_of_certs);
3270 resultObjPtr=Tcl_NewListObj(0,(Tcl_Obj **)NULL);
3271 Tcl_ListObjAppendElement(interp,resultObjPtr,Tcl_NewStringObj(charPtr,-1));
3273 for(i=0; i < certinfoPtr->num_of_certs; i++) {
3274 for(slistPtr = certinfoPtr->certinfo[i]; slistPtr; slistPtr=slistPtr->next) {
3275 Tcl_ListObjAppendElement(interp,resultObjPtr,Tcl_NewStringObj(slistPtr->data,-1));
3278 Tcl_SetObjResult(interp,resultObjPtr);
3281 exitCode=curl_easy_getinfo \
3282 (curlHandle,CURLINFO_CONDITION_UNMET,&longNumber);
3286 resultObjPtr=Tcl_NewLongObj(longNumber);
3287 Tcl_SetObjResult(interp,resultObjPtr);
3290 exitCode=curl_easy_getinfo \
3291 (curlHandle,CURLINFO_PRIMARY_PORT,&longNumber);
3295 resultObjPtr=Tcl_NewLongObj(longNumber);
3296 Tcl_SetObjResult(interp,resultObjPtr);
3299 exitCode=curl_easy_getinfo(curlHandle,CURLINFO_LOCAL_IP,&charPtr);
3303 resultObjPtr=Tcl_NewStringObj(charPtr,-1);
3304 Tcl_SetObjResult(interp,resultObjPtr);
3307 exitCode=curl_easy_getinfo \
3308 (curlHandle,CURLINFO_LOCAL_PORT,&longNumber);
3312 resultObjPtr=Tcl_NewLongObj(longNumber);
3313 Tcl_SetObjResult(interp,resultObjPtr);
3320 *----------------------------------------------------------------------
3324 * Frees the space taken by a curlObjData struct either because we are
3325 * deleting the handle or reseting it.
3328 * interp: Pointer to the interpreter we are using.
3329 * curlHandle: the curl handle for which the option is set.
3330 * objc and objv: The usual in Tcl.
3333 * A standard Tcl result.
3334 *----------------------------------------------------------------------
3337 curlFreeSpace(struct curlObjData *curlData) {
3339 curl_slist_free_all(curlData->headerList);
3340 curl_slist_free_all(curlData->quote);
3341 curl_slist_free_all(curlData->prequote);
3342 curl_slist_free_all(curlData->postquote);
3344 Tcl_Free(curlData->outFile);
3345 Tcl_Free(curlData->inFile);
3346 Tcl_Free(curlData->proxy);
3347 Tcl_Free(curlData->errorBuffer);
3348 Tcl_Free(curlData->errorBufferName);
3349 Tcl_Free(curlData->errorBufferKey);
3350 Tcl_Free(curlData->stderrFile);
3351 Tcl_Free(curlData->randomFile);
3352 Tcl_Free(curlData->headerVar);
3353 Tcl_Free(curlData->bodyVarName);
3354 if (curlData->bodyVar.memory) {
3355 Tcl_Free(curlData->bodyVar.memory);
3357 Tcl_Free(curlData->progressProc);
3358 if (curlData->cancelTransVarName) {
3359 Tcl_UnlinkVar(curlData->interp,curlData->cancelTransVarName);
3360 Tcl_Free(curlData->cancelTransVarName);
3362 Tcl_Free(curlData->writeProc);
3363 Tcl_Free(curlData->readProc);
3364 Tcl_Free(curlData->debugProc);
3365 curl_slist_free_all(curlData->http200aliases);
3366 Tcl_Free(curlData->sshkeycallProc);
3367 curl_slist_free_all(curlData->mailrcpt);
3368 Tcl_Free(curlData->chunkBgnProc);
3369 Tcl_Free(curlData->chunkBgnVar);
3370 Tcl_Free(curlData->chunkEndProc);
3371 Tcl_Free(curlData->fnmatchProc);
3372 curl_slist_free_all(curlData->resolve);
3373 curl_slist_free_all(curlData->telnetoptions);
3375 Tcl_Free(curlData->command);
3379 *----------------------------------------------------------------------
3383 * This function is invoked by the 'duphandle' command, it will
3384 * create a duplicate of the given handle.
3387 * The stantard parameters for Tcl commands
3390 * A standard Tcl result.
3393 * See the user documentation.
3395 *----------------------------------------------------------------------
3398 curlDupHandle(Tcl_Interp *interp, struct curlObjData *curlData,
3399 int objc, Tcl_Obj *CONST objv[]) {
3401 CURL *newCurlHandle;
3403 struct curlObjData *newCurlData;
3406 newCurlHandle=curl_easy_duphandle(curlData->curl);
3407 if (newCurlHandle==NULL) {
3408 result=Tcl_NewStringObj("Couldn't create new handle.",-1);
3409 Tcl_SetObjResult(interp,result);
3413 newCurlData=(struct curlObjData *)Tcl_Alloc(sizeof(struct curlObjData));
3415 curlCopyCurlData(curlData,newCurlData);
3417 handleName=curlCreateObjCmd(interp,newCurlData);
3419 newCurlData->curl=newCurlHandle;
3421 result=Tcl_NewStringObj(handleName,-1);
3422 Tcl_SetObjResult(interp,result);
3423 Tcl_Free(handleName);
3430 *----------------------------------------------------------------------
3432 * curlResetHandle --
3434 * This function is invoked by the 'reset' command, it reset all the
3435 * options in the handle to the state it had when 'init' was invoked.
3438 * The stantard parameters for Tcl commands
3441 * A standard Tcl result.
3444 * See the user documentation.
3446 *----------------------------------------------------------------------
3449 curlResetHandle(Tcl_Interp *interp, struct curlObjData *curlData) {
3450 struct curlObjData *tmpPtr=
3451 (struct curlObjData *)Tcl_Alloc(sizeof(struct curlObjData));
3453 tmpPtr->curl = curlData->curl;
3454 tmpPtr->token = curlData->token;
3455 tmpPtr->shareToken = curlData->shareToken;
3456 tmpPtr->interp = curlData->interp;
3458 curlFreeSpace(curlData);
3459 memset(curlData, 0, sizeof(struct curlObjData));
3461 curlData->curl = tmpPtr->curl;
3462 curlData->token = tmpPtr->token;
3463 curlData->shareToken = tmpPtr->shareToken;
3464 curlData->interp = tmpPtr->interp;
3466 curl_easy_reset(curlData->curl);
3468 Tcl_Free((char *)tmpPtr);
3475 *----------------------------------------------------------------------
3479 * This procedure is invoked to process the "curl::init" Tcl command.
3480 * See the user documentation for details on what it does.
3483 * The stantard parameters for Tcl commands
3486 * A standard Tcl result.
3489 * See the user documentation.
3491 *----------------------------------------------------------------------
3494 curlVersion (ClientData clientData, Tcl_Interp *interp,
3495 int objc,Tcl_Obj *CONST objv[]) {
3497 Tcl_Obj *versionPtr;
3498 char tclversion[200];
3500 sprintf(tclversion,"TclCurl Version %s (%s)",TclCurlVersion,
3502 versionPtr=Tcl_NewStringObj(tclversion,-1);
3503 Tcl_SetObjResult(interp,versionPtr);
3509 *----------------------------------------------------------------------
3513 * This function is invoked to process the "curl::escape" Tcl command.
3514 * See the user documentation for details on what it does.
3518 * The stantard parameters for Tcl commands
3521 * A standard Tcl result.
3524 * See the user documentation.
3526 *----------------------------------------------------------------------
3529 curlEscape(ClientData clientData, Tcl_Interp *interp,
3530 int objc,Tcl_Obj *CONST objv[]) {
3535 escapedStr=curl_easy_escape(NULL,Tcl_GetString(objv[1]),0);
3538 resultObj=Tcl_NewStringObj("curl::escape bad parameter",-1);
3539 Tcl_SetObjResult(interp,resultObj);
3542 resultObj=Tcl_NewStringObj(escapedStr,-1);
3543 Tcl_SetObjResult(interp,resultObj);
3544 curl_free(escapedStr);
3550 *----------------------------------------------------------------------
3554 * This function is invoked to process the "curl::Unescape" Tcl command.
3555 * See the user documentation for details on what it does.
3559 * The stantard parameters for Tcl commands
3562 * A standard Tcl result.
3565 * See the user documentation.
3567 *----------------------------------------------------------------------
3570 curlUnescape(ClientData clientData, Tcl_Interp *interp,
3571 int objc,Tcl_Obj *CONST objv[]) {
3576 unescapedStr=curl_easy_unescape(NULL,Tcl_GetString(objv[1]),0,NULL);
3578 resultObj=Tcl_NewStringObj("curl::unescape bad parameter",-1);
3579 Tcl_SetObjResult(interp,resultObj);
3582 resultObj=Tcl_NewStringObj(unescapedStr,-1);
3583 Tcl_SetObjResult(interp,resultObj);
3584 curl_free(unescapedStr);
3590 *----------------------------------------------------------------------
3592 * curlVersionInfo --
3594 * This function invokes 'curl_version_info' to query how 'libcurl' was
3598 * The standard parameters for Tcl commands, but nothing is used.
3601 * A standard Tcl result.
3604 * See the user documentation.
3606 *----------------------------------------------------------------------
3609 curlVersionInfo (ClientData clientData, Tcl_Interp *interp,
3610 int objc,Tcl_Obj *CONST objv[]) {
3614 curl_version_info_data *infoPtr;
3615 Tcl_Obj *resultObjPtr=NULL;
3619 resultObjPtr=Tcl_NewStringObj("usage: curl::versioninfo -option",-1);
3620 Tcl_SetObjResult(interp,resultObjPtr);
3624 if (Tcl_GetIndexFromObj(interp, objv[1], versionInfoTable, "option",
3625 TCL_EXACT,&tableIndex)==TCL_ERROR) {
3629 infoPtr=curl_version_info(CURLVERSION_NOW);
3631 switch(tableIndex) {
3633 resultObjPtr=Tcl_NewStringObj(infoPtr->version,-1);
3636 sprintf(tmp,"%X",infoPtr->version_num);
3637 resultObjPtr=Tcl_NewStringObj(tmp,-1);
3640 resultObjPtr=Tcl_NewStringObj(infoPtr->host,-1);
3643 resultObjPtr=Tcl_NewListObj(0,(Tcl_Obj **)NULL);
3644 if (infoPtr->features&CURL_VERSION_IPV6) {
3645 Tcl_ListObjAppendElement(interp,resultObjPtr
3646 ,Tcl_NewStringObj("IPV6",-1));
3648 if (infoPtr->features&CURL_VERSION_KERBEROS4) {
3649 Tcl_ListObjAppendElement(interp,resultObjPtr
3650 ,Tcl_NewStringObj("KERBEROS4",-1));
3652 if (infoPtr->features&CURL_VERSION_SSL) {
3653 Tcl_ListObjAppendElement(interp,resultObjPtr
3654 ,Tcl_NewStringObj("SSL",-1));
3656 if (infoPtr->features&CURL_VERSION_LIBZ) {
3657 Tcl_ListObjAppendElement(interp,resultObjPtr
3658 ,Tcl_NewStringObj("LIBZ",-1));
3660 if (infoPtr->features&CURL_VERSION_NTLM) {
3661 Tcl_ListObjAppendElement(interp,resultObjPtr
3662 ,Tcl_NewStringObj("NTLM",-1));
3664 if (infoPtr->features&CURL_VERSION_GSSNEGOTIATE) {
3665 Tcl_ListObjAppendElement(interp,resultObjPtr
3666 ,Tcl_NewStringObj("GSSNEGOTIATE",-1));
3668 if (infoPtr->features&CURL_VERSION_DEBUG) {
3669 Tcl_ListObjAppendElement(interp,resultObjPtr
3670 ,Tcl_NewStringObj("DEBUG",-1));
3672 if (infoPtr->features&CURL_VERSION_ASYNCHDNS) {
3673 Tcl_ListObjAppendElement(interp,resultObjPtr
3674 ,Tcl_NewStringObj("ASYNCHDNS",-1));
3676 if (infoPtr->features&CURL_VERSION_SPNEGO) {
3677 Tcl_ListObjAppendElement(interp,resultObjPtr
3678 ,Tcl_NewStringObj("SPNEGO",-1));
3680 if (infoPtr->features&CURL_VERSION_LARGEFILE) {
3681 Tcl_ListObjAppendElement(interp,resultObjPtr
3682 ,Tcl_NewStringObj("LARGEFILE",-1));
3684 if (infoPtr->features&CURL_VERSION_IDN) {
3685 Tcl_ListObjAppendElement(interp,resultObjPtr
3686 ,Tcl_NewStringObj("IDN",-1));
3688 if (infoPtr->features&CURL_VERSION_SSPI) {
3689 Tcl_ListObjAppendElement(interp,resultObjPtr
3690 ,Tcl_NewStringObj("SSPI",-1));
3693 if (infoPtr->features&CURL_VERSION_CONV) {
3694 Tcl_ListObjAppendElement(interp,resultObjPtr
3695 ,Tcl_NewStringObj("CONV",-1));
3698 resultObjPtr=Tcl_NewStringObj(infoPtr->ssl_version,-1);
3701 resultObjPtr=Tcl_NewLongObj(infoPtr->ssl_version_num);
3704 resultObjPtr=Tcl_NewStringObj(infoPtr->libz_version,-1);
3707 resultObjPtr=Tcl_NewListObj(0,(Tcl_Obj **)NULL);
3709 if (infoPtr->protocols[i]!=NULL) {
3710 Tcl_ListObjAppendElement(interp,resultObjPtr
3711 ,Tcl_NewStringObj(infoPtr->protocols[i],-1));
3718 Tcl_SetObjResult(interp,resultObjPtr);
3724 *----------------------------------------------------------------------
3726 * curlCopyCurlData --
3728 * This function copies the contents of a curlData struct into another.
3731 * curlDataOld: The original one.
3732 * curlDataNew: The new one
3735 * A standard Tcl result.
3738 * See the user documentation.
3740 *----------------------------------------------------------------------
3743 curlCopyCurlData (struct curlObjData *curlDataOld,
3744 struct curlObjData *curlDataNew) {
3746 /* This takes care of the int and long values */
3747 memcpy(curlDataNew, curlDataOld, sizeof(struct curlObjData));
3749 /* Some of the data doesn't get copied */
3751 curlDataNew->headerList=NULL;
3752 curlDataNew->quote=NULL;
3753 curlDataNew->prequote=NULL;
3754 curlDataNew->postquote=NULL;
3755 curlDataNew->formArray=NULL;
3756 curlDataNew->postListFirst=NULL;
3757 curlDataNew->postListLast=NULL;
3758 curlDataNew->formArray=NULL;
3759 curlDataNew->outHandle=NULL;
3760 curlDataNew->outFlag=0;
3761 curlDataNew->inHandle=NULL;
3762 curlDataNew->inFlag=0;
3763 curlDataNew->headerHandle=NULL;
3764 curlDataNew->headerFlag=0;
3765 curlDataNew->stderrHandle=NULL;
3766 curlDataNew->stderrFlag=0;
3767 curlDataNew->http200aliases=NULL;
3768 curlDataNew->mailrcpt=NULL;
3769 curlDataNew->resolve=NULL;
3770 curlDataNew->telnetoptions=NULL;
3772 /* The strings need a special treatment. */
3774 curlDataNew->outFile=curlstrdup(curlDataOld->outFile);
3775 curlDataNew->inFile=curlstrdup(curlDataOld->inFile);
3776 curlDataNew->proxy=curlstrdup(curlDataOld->proxy);
3777 curlDataNew->errorBuffer=curlstrdup(curlDataOld->errorBuffer);
3778 curlDataNew->errorBufferName=curlstrdup(curlDataOld->errorBufferName);
3779 curlDataNew->errorBufferKey=curlstrdup(curlDataOld->errorBufferKey);
3780 curlDataNew->headerFile=curlstrdup(curlDataOld->headerFile);
3781 curlDataNew->stderrFile=curlstrdup(curlDataOld->stderrFile);
3782 curlDataNew->randomFile=curlstrdup(curlDataOld->randomFile);
3783 curlDataNew->headerVar=curlstrdup(curlDataOld->headerVar);
3784 curlDataNew->bodyVarName=curlstrdup(curlDataOld->bodyVarName);
3785 curlDataNew->progressProc=curlstrdup(curlDataOld->progressProc);
3786 curlDataNew->cancelTransVarName=curlstrdup(curlDataOld->cancelTransVarName);
3787 curlDataNew->writeProc=curlstrdup(curlDataOld->writeProc);
3788 curlDataNew->readProc=curlstrdup(curlDataOld->readProc);
3789 curlDataNew->debugProc=curlstrdup(curlDataOld->debugProc);
3790 curlDataNew->command=curlstrdup(curlDataOld->command);
3791 curlDataNew->sshkeycallProc=curlstrdup(curlDataOld->sshkeycallProc);
3792 curlDataNew->chunkBgnProc=curlstrdup(curlDataOld->chunkBgnProc);
3793 curlDataNew->chunkBgnVar=curlstrdup(curlDataOld->chunkBgnVar);
3794 curlDataNew->chunkEndProc=curlstrdup(curlDataOld->chunkEndProc);
3795 curlDataNew->fnmatchProc=curlstrdup(curlDataOld->fnmatchProc);
3797 curlDataNew->bodyVar.memory=(char *)Tcl_Alloc(curlDataOld->bodyVar.size);
3798 memcpy(curlDataNew->bodyVar.memory,curlDataOld->bodyVar.memory
3799 ,curlDataOld->bodyVar.size);
3800 curlDataNew->bodyVar.size=curlDataOld->bodyVar.size;
3805 /*----------------------------------------------------------------------
3809 * Before doing a transfer with the easy interface or adding an easy
3810 * handle to a multi one, this function takes care of opening all
3811 * necessary files for the transfer.
3814 * curlData: The pointer to the struct with the transfer data.
3817 * '0' all went well, '1' in case of error.
3818 *----------------------------------------------------------------------
3821 curlOpenFiles(Tcl_Interp *interp,struct curlObjData *curlData) {
3823 if (curlData->outFlag) {
3824 if (curlOpenFile(interp,curlData->outFile,&(curlData->outHandle),1,
3825 curlData->transferText)) {
3828 curl_easy_setopt(curlData->curl,CURLOPT_WRITEDATA,curlData->outHandle);
3830 if (curlData->inFlag) {
3831 if (curlOpenFile(interp,curlData->inFile,&(curlData->inHandle),0,
3832 curlData->transferText)) {
3835 curl_easy_setopt(curlData->curl,CURLOPT_READDATA,curlData->inHandle);
3836 if (curlData->anyAuthFlag) {
3837 curl_easy_setopt(curlData->curl, CURLOPT_SEEKFUNCTION, curlseek);
3838 curl_easy_setopt(curlData->curl, CURLOPT_SEEKDATA, curlData->inHandle);
3841 if (curlData->headerFlag) {
3842 if (curlOpenFile(interp,curlData->headerFile,&(curlData->headerHandle),1,1)) {
3845 curl_easy_setopt(curlData->curl,CURLOPT_HEADERDATA,curlData->headerHandle);
3847 if (curlData->stderrFlag) {
3848 if (curlOpenFile(interp,curlData->stderrFile,&(curlData->stderrHandle),1,1)) {
3851 curl_easy_setopt(curlData->curl,CURLOPT_STDERR,curlData->stderrHandle);
3856 /*----------------------------------------------------------------------
3860 * Closes the files opened during a transfer.
3863 * curlData: The pointer to the struct with the transfer data.
3865 *----------------------------------------------------------------------
3868 curlCloseFiles(struct curlObjData *curlData) {
3869 if (curlData->outHandle!=NULL) {
3870 fclose(curlData->outHandle);
3871 curlData->outHandle=NULL;
3873 if (curlData->inHandle!=NULL) {
3874 fclose(curlData->inHandle);
3875 curlData->inHandle=NULL;
3877 if (curlData->headerHandle!=NULL) {
3878 fclose(curlData->headerHandle);
3879 curlData->headerHandle=NULL;
3881 if (curlData->stderrHandle!=NULL) {
3882 fclose(curlData->stderrHandle);
3883 curlData->stderrHandle=NULL;
3887 /*----------------------------------------------------------------------
3891 * Opens a file to be used during a transfer.
3894 * fileName: name of the file.
3895 * handle: the handle for the file
3896 * writing: '0' if reading, '1' if writing.
3897 * text: '0' if binary, '1' if text.
3900 * '0' all went well, '1' in case of error.
3901 *----------------------------------------------------------------------
3904 curlOpenFile(Tcl_Interp *interp,char *fileName, FILE **handle, int writing, int text) {
3905 Tcl_Obj *resultObjPtr;
3908 if (*handle!=NULL) {
3913 *handle=fopen(fileName,"w");
3915 *handle=fopen(fileName,"wb");
3919 *handle=fopen(fileName,"r");
3921 *handle=fopen(fileName,"rb");
3924 if (*handle==NULL) {
3925 snprintf(errorMsg,300,"Couldn't open file %s.",fileName);
3926 resultObjPtr=Tcl_NewStringObj(errorMsg,-1);
3927 Tcl_SetObjResult(interp,resultObjPtr);
3933 /*----------------------------------------------------------------------
3937 * When the user requests the 'any' auth, libcurl may need
3938 * to send the PUT/POST data more than once and thus may need to ask
3939 * the app to "rewind" the read data stream to start.
3941 *----------------------------------------------------------------------
3945 curlseek(void *instream, curl_off_t offset, int origin)
3947 if(-1 == fseek((FILE *)instream, 0, origin)) {
3948 return CURLIOE_FAILRESTART;
3953 /*----------------------------------------------------------------------
3955 * curlSetPostData --
3957 * In case there is going to be a post transfer, this function sets the
3958 * data that is going to be posted.
3961 * interp: Tcl interpreter we are using.
3962 * curlData: A pointer to the struct with the transfer data.
3965 * A standard Tcl result.
3966 *----------------------------------------------------------------------
3969 curlSetPostData(Tcl_Interp *interp,struct curlObjData *curlDataPtr) {
3970 Tcl_Obj *errorMsgObjPtr;
3972 if (curlDataPtr->postListFirst!=NULL) {
3973 if (curl_easy_setopt(curlDataPtr->curl,CURLOPT_HTTPPOST,curlDataPtr->postListFirst)) {
3974 curl_formfree(curlDataPtr->postListFirst);
3975 errorMsgObjPtr=Tcl_NewStringObj("Error setting the data to post",-1);
3976 Tcl_SetObjResult(interp,errorMsgObjPtr);
3983 /*----------------------------------------------------------------------
3985 * curlResetPostData --
3987 * After performing a transfer, this function is invoked to erease the
3991 * curlData: A pointer to the struct with the transfer data.
3992 *----------------------------------------------------------------------
3995 curlResetPostData(struct curlObjData *curlDataPtr) {
3996 struct formArrayStruct *tmpPtr;
3998 if (curlDataPtr->postListFirst) {
3999 curl_formfree(curlDataPtr->postListFirst);
4000 curlDataPtr->postListFirst=NULL;
4001 curlDataPtr->postListLast=NULL;
4002 curl_easy_setopt(curlDataPtr->curl,CURLOPT_HTTPPOST,NULL);
4004 while(curlDataPtr->formArray!=NULL) {
4005 if (curlDataPtr->formArray->formHeaderList!=NULL) {
4006 curl_slist_free_all(curlDataPtr->formArray->formHeaderList);
4007 curlDataPtr->formArray->formHeaderList=NULL;
4009 curlResetFormArray(curlDataPtr->formArray->formArray);
4010 tmpPtr=curlDataPtr->formArray->next;
4011 Tcl_Free((char *)curlDataPtr->formArray);
4012 curlDataPtr->formArray=tmpPtr;
4016 /*----------------------------------------------------------------------
4018 * curlResetFormArray --
4020 * Cleans the contents of the formArray, it is done after a transfer or
4021 * if 'curl_formadd' returns an error.
4024 * formArray: A pointer to the array to clean up.
4025 *----------------------------------------------------------------------
4028 curlResetFormArray(struct curl_forms *formArray) {
4031 for (i=0;formArray[i].option!=CURLFORM_END;i++) {
4032 switch (formArray[i].option) {
4033 case CURLFORM_COPYNAME:
4034 case CURLFORM_COPYCONTENTS:
4036 case CURLFORM_CONTENTTYPE:
4037 case CURLFORM_FILENAME:
4038 case CURLFORM_FILECONTENT:
4039 case CURLFORM_BUFFER:
4040 case CURLFORM_BUFFERPTR:
4041 Tcl_Free((char *)(formArray[i].value));
4047 Tcl_Free((char *)formArray);
4050 /*----------------------------------------------------------------------
4052 * curlSetBodyVarName --
4054 * After performing a transfer, this function is invoked to set the
4055 * body of the recieved transfer into a user defined Tcl variable.
4058 * interp: The Tcl interpreter we are using.
4059 * curlData: A pointer to the struct with the transfer data.
4060 *----------------------------------------------------------------------
4063 curlSetBodyVarName(Tcl_Interp *interp,struct curlObjData *curlDataPtr) {
4064 Tcl_Obj *bodyVarNameObjPtr, *bodyVarObjPtr;
4066 bodyVarNameObjPtr=Tcl_NewStringObj(curlDataPtr->bodyVarName,-1);
4067 bodyVarObjPtr=Tcl_NewByteArrayObj((unsigned char *)curlDataPtr->bodyVar.memory,
4068 curlDataPtr->bodyVar.size);
4070 Tcl_ObjSetVar2(interp,bodyVarNameObjPtr,(Tcl_Obj *)NULL,bodyVarObjPtr,0);
4072 Tcl_Free(curlDataPtr->bodyVar.memory);
4073 curlDataPtr->bodyVar.memory=NULL;
4074 curlDataPtr->bodyVar.size=0;
4077 /*----------------------------------------------------------------------
4080 * The same as strdup, but won't seg fault if the string to copy is NULL.
4083 * old: The original one.
4086 * Returns a pointer to the new string.
4087 *----------------------------------------------------------------------
4090 *curlstrdup (char *old) {
4096 tmpPtr=Tcl_Alloc(strlen(old)+1);
4103 *----------------------------------------------------------------------
4105 * curlShareInitObjCmd --
4107 * Looks for the first free share handle (scurl1, scurl2,...) and
4108 * creates a Tcl command for it.
4111 * A string with the name of the handle, don't forget to free it.
4114 * See the user documentation.
4116 *----------------------------------------------------------------------
4120 curlCreateShareObjCmd (Tcl_Interp *interp,struct shcurlObjData *shcurlData) {
4124 Tcl_Command cmdToken;
4126 /* We try with scurl1, if it already exists with scurl2...*/
4127 shandleName=(char *)Tcl_Alloc(10);
4129 sprintf(shandleName,"scurl%d",i);
4130 if (!Tcl_GetCommandInfo(interp,shandleName,&info)) {
4131 cmdToken=Tcl_CreateObjCommand(interp,shandleName,curlShareObjCmd,
4132 (ClientData)shcurlData,
4133 (Tcl_CmdDeleteProc *)curlCleanUpShareCmd);
4137 shcurlData->token=cmdToken;
4143 *----------------------------------------------------------------------
4145 * curlShareInitObjCmd --
4147 * This procedure is invoked to process the "curl::shareinit" Tcl command.
4148 * See the user documentation for details on what it does.
4151 * A standard Tcl result.
4154 * See the user documentation.
4156 *----------------------------------------------------------------------
4160 curlShareInitObjCmd (ClientData clientData, Tcl_Interp *interp,
4161 int objc,Tcl_Obj *CONST objv[]) {
4165 struct shcurlObjData *shcurlData;
4168 shcurlData=(struct shcurlObjData *)Tcl_Alloc(sizeof(struct shcurlObjData));
4169 if (shcurlData==NULL) {
4170 resultPtr=Tcl_NewStringObj("Couldn't allocate memory",-1);
4171 Tcl_SetObjResult(interp,resultPtr);
4175 memset(shcurlData, 0, sizeof(struct shcurlObjData));
4177 shcurlHandle=curl_share_init();
4178 if (shcurlHandle==NULL) {
4179 resultPtr=Tcl_NewStringObj("Couldn't create share handle",-1);
4180 Tcl_SetObjResult(interp,resultPtr);
4184 shandleName=curlCreateShareObjCmd(interp,shcurlData);
4186 shcurlData->shandle=shcurlHandle;
4188 resultPtr=Tcl_NewStringObj(shandleName,-1);
4189 Tcl_SetObjResult(interp,resultPtr);
4190 Tcl_Free(shandleName);
4193 curl_share_setopt(shcurlHandle, CURLSHOPT_LOCKFUNC, curlShareLockFunc);
4194 curl_share_setopt(shcurlHandle, CURLSHOPT_LOCKFUNC, curlShareUnLockFunc);
4202 *----------------------------------------------------------------------
4204 * curlShareLockFunc --
4206 * This will be the function invoked by libcurl when it wants to lock
4207 * some data for the share interface.
4210 * See the user documentation.
4212 *----------------------------------------------------------------------
4216 curlShareLockFunc (CURL *handle, curl_lock_data data, curl_lock_access access
4220 CURL_LOCK_DATA_COOKIE:
4221 Tcl_MutexLock(&cookieLock);
4224 Tcl_MutexLock(&dnsLock);
4226 CURL_LOCK_DATA_SSL_SESSION:
4227 Tcl_MutexLock(&sslLock);
4229 CURL_LOCK_DATA_CONNECT:
4230 Tcl_MutexLock(&connectLock);
4233 /* Prevent useless compile warnings */
4239 *----------------------------------------------------------------------
4241 * curlShareUnLockFunc --
4243 * This will be the function invoked by libcurl when it wants to unlock
4244 * the previously locked data.
4247 * See the user documentation.
4249 *----------------------------------------------------------------------
4252 curlShareUnLockFunc(CURL *handle, curl_lock_data data, void *userptr) {
4255 CURL_LOCK_DATA_COOKIE:
4256 Tcl_MutexUnlock(&cookieLock);
4259 Tcl_MutexUnlock(&dnsLock);
4261 CURL_LOCK_DATA_SSL_SESSION:
4262 Tcl_MutexUnlock(&sslLock);
4264 CURL_LOCK_DATA_CONNECT:
4265 Tcl_MutexUnlock(&connectLock);
4275 *----------------------------------------------------------------------
4277 * curlShareObjCmd --
4279 * This procedure is invoked to process the "share curl" commands.
4280 * See the user documentation for details on what it does.
4283 * A standard Tcl result.
4286 * See the user documentation.
4288 *----------------------------------------------------------------------
4291 curlShareObjCmd (ClientData clientData, Tcl_Interp *interp,
4292 int objc,Tcl_Obj *CONST objv[]) {
4294 struct shcurlObjData *shcurlData=(struct shcurlObjData *)clientData;
4295 CURLSH *shcurlHandle=shcurlData->shandle;
4296 int tableIndex, dataIndex;
4300 Tcl_WrongNumArgs(interp,1,objv,"option arg ?arg?");
4304 if (Tcl_GetIndexFromObj(interp, objv[1], shareCmd, "option",TCL_EXACT,&tableIndex)==TCL_ERROR) {
4308 switch(tableIndex) {
4311 if (Tcl_GetIndexFromObj(interp, objv[2], lockData,
4312 "data to lock ",TCL_EXACT,&dataIndex)==TCL_ERROR) {
4317 dataToLock=CURL_LOCK_DATA_COOKIE;
4320 dataToLock=CURL_LOCK_DATA_DNS;
4323 if (tableIndex==0) {
4324 curl_share_setopt(shcurlHandle, CURLSHOPT_SHARE, dataToLock);
4326 curl_share_setopt(shcurlHandle, CURLSHOPT_UNSHARE, dataToLock);
4330 Tcl_DeleteCommandFromToken(interp,shcurlData->token);
4337 *----------------------------------------------------------------------
4339 * curlCleanUpShareCmd --
4341 * This procedure is invoked when curl share handle is deleted.
4344 * A standard Tcl result.
4347 * Cleans the curl share handle and frees the memory.
4349 *----------------------------------------------------------------------
4352 curlCleanUpShareCmd(ClientData clientData) {
4353 struct shcurlObjData *shcurlData=(struct shcurlObjData *)clientData;
4354 CURLSH *shcurlHandle=shcurlData->shandle;
4356 curl_share_cleanup(shcurlHandle);
4357 Tcl_Free((char *)shcurlData);
4363 *----------------------------------------------------------------------
4365 * curlErrorStrings --
4367 * All the commands to return the error string from the error code have
4368 * this function in common.
4371 * '0': All went well.
4372 * '1': The error code didn't make sense.
4373 *----------------------------------------------------------------------
4376 curlErrorStrings (Tcl_Interp *interp, Tcl_Obj *CONST objv,int type) {
4382 if (Tcl_GetIntFromObj(interp,objv,&errorCode)) {
4383 snprintf(errorMsg,500,"Invalid error code: %s",Tcl_GetString(objv));
4384 resultPtr=Tcl_NewStringObj(errorMsg,-1);
4385 Tcl_SetObjResult(interp,resultPtr);
4390 resultPtr=Tcl_NewStringObj(curl_easy_strerror(errorCode),-1);
4393 resultPtr=Tcl_NewStringObj(curl_share_strerror(errorCode),-1);
4396 resultPtr=Tcl_NewStringObj(curl_multi_strerror(errorCode),-1);
4399 resultPtr=Tcl_NewStringObj("You're kidding,right?",-1);
4401 Tcl_SetObjResult(interp,resultPtr);
4407 *----------------------------------------------------------------------
4409 * curlEasyStringError --
4411 * This function is invoked to process the "curl::easystrerror" Tcl command.
4412 * It will return a string with an explanation of the error code given.
4415 * A standard Tcl result.
4418 * The interpreter will contain as a result the string with the error
4421 *----------------------------------------------------------------------
4424 curlEasyStringError (ClientData clientData, Tcl_Interp *interp,
4425 int objc,Tcl_Obj *CONST objv[]) {
4428 Tcl_WrongNumArgs(interp,1,objv,"errorCode");
4432 if (curlErrorStrings(interp,objv[1],0)) {
4439 *----------------------------------------------------------------------
4441 * curlShareStringError --
4443 * This function is invoked to process the "curl::sharestrerror" Tcl command.
4444 * It will return a string with an explanation of the error code given.
4447 * A standard Tcl result.
4450 * The interpreter will contain as a result the string with the error
4453 *----------------------------------------------------------------------
4456 curlShareStringError (ClientData clientData, Tcl_Interp *interp,
4457 int objc,Tcl_Obj *CONST objv[]) {
4460 Tcl_WrongNumArgs(interp,1,objv,"errorCode");
4464 if (curlErrorStrings(interp,objv[1],1)) {
4471 *----------------------------------------------------------------------
4473 * curlMultiStringError --
4475 * This function is invoked to process the "curl::multirerror" Tcl command.
4476 * It will return a string with an explanation of the error code given.
4479 * A standard Tcl result.
4482 * The interpreter will contain as a result the string with the error
4485 *----------------------------------------------------------------------
4488 curlMultiStringError (ClientData clientData, Tcl_Interp *interp,
4489 int objc,Tcl_Obj *CONST objv[]) {
4492 Tcl_WrongNumArgs(interp,1,objv,"errorCode");
4496 if (curlErrorStrings(interp,objv[1],2)) {