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(32);
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 (curlData->outFlag) {
469 if (curlData->outHandle!=NULL) {
470 fclose(curlData->outHandle);
471 curlData->outHandle=NULL;
474 if ((strcmp(curlData->outFile,""))&&(strcmp(curlData->outFile,"stdout"))) {
478 curl_easy_setopt(curlHandle,CURLOPT_WRITEDATA,stdout);
479 curlData->outFile=NULL;
481 curl_easy_setopt(curlHandle,CURLOPT_WRITEFUNCTION,NULL);
484 Tcl_Free(curlData->inFile);
485 curlData->inFile=curlstrdup(Tcl_GetString(objv));
486 if (curlData->inFlag) {
487 if (curlData->inHandle!=NULL) {
488 fclose(curlData->inHandle);
489 curlData->inHandle=NULL;
492 if ((strcmp(curlData->inFile,""))&&(strcmp(curlData->inFile,"stdin"))) {
495 curl_easy_setopt(curlHandle,CURLOPT_READDATA,stdin);
497 curlData->inFile=NULL;
499 curl_easy_setopt(curlHandle,CURLOPT_READFUNCTION,NULL);
502 if (SetoptChar(interp,curlHandle,
503 CURLOPT_USERAGENT,tableIndex,objv)) {
508 if (SetoptChar(interp,curlHandle,CURLOPT_REFERER,tableIndex,objv)) {
513 if (SetoptInt(interp,curlHandle,CURLOPT_VERBOSE,tableIndex,objv)) {
518 if (SetoptInt(interp,curlHandle,CURLOPT_HEADER,tableIndex,objv)) {
523 if (SetoptInt(interp,curlHandle,CURLOPT_NOBODY,tableIndex,objv)) {
528 if (SetoptChar(interp,curlHandle,CURLOPT_PROXY,tableIndex,objv)) {
533 if (SetoptLong(interp,curlHandle,CURLOPT_PROXYPORT,tableIndex,
539 if (SetoptInt(interp,curlHandle,CURLOPT_HTTPPROXYTUNNEL,tableIndex,
545 if (SetoptInt(interp,curlHandle,CURLOPT_FAILONERROR,tableIndex,
551 if (SetoptLong(interp,curlHandle,CURLOPT_TIMEOUT,tableIndex,
557 if (SetoptLong(interp,curlHandle,CURLOPT_LOW_SPEED_LIMIT,tableIndex,
563 if (SetoptLong(interp,curlHandle,CURLOPT_LOW_SPEED_TIME,tableIndex,
569 if (SetoptLong(interp,curlHandle,CURLOPT_RESUME_FROM,tableIndex,
575 if (SetoptLong(interp,curlHandle,CURLOPT_INFILESIZE,tableIndex,
581 if (SetoptInt(interp,curlHandle,CURLOPT_UPLOAD,tableIndex,
588 if (SetoptInt(interp,curlHandle,CURLOPT_DIRLISTONLY,tableIndex,
595 if (SetoptInt(interp,curlHandle,CURLOPT_APPEND,tableIndex,
601 if (Tcl_GetIndexFromObj(interp, objv, netrcTable,
602 "netrc option",TCL_EXACT,&curlTableIndex)==TCL_ERROR) {
605 if (curl_easy_setopt(curlHandle,CURLOPT_NETRC,curlTableIndex)) {
606 curlErrorSetOpt(interp,configTable,tableIndex,netrcTable[curlTableIndex]);
611 if (SetoptInt(interp,curlHandle,CURLOPT_FOLLOWLOCATION,tableIndex,
617 if (SetoptInt(interp,curlHandle,CURLOPT_TRANSFERTEXT,tableIndex,
621 Tcl_GetIntFromObj(interp,objv,&curlData->transferText);
624 if (SetoptInt(interp,curlHandle,CURLOPT_PUT,tableIndex,objv)) {
628 case 24: /* The CURLOPT_MUTE option no longer does anything.*/
631 if (SetoptChar(interp,curlHandle,CURLOPT_USERPWD,tableIndex,objv)) {
636 if (SetoptChar(interp,curlHandle,CURLOPT_PROXYUSERPWD,tableIndex,objv)) {
641 if (SetoptChar(interp,curlHandle,CURLOPT_RANGE,tableIndex,objv)) {
646 tmpStr=curlstrdup(Tcl_GetString(objv));
647 regExp=Tcl_RegExpCompile(interp,"(.*)(?:\\()(.*)(?:\\))");
648 exitCode=Tcl_RegExpExec(interp,regExp,tmpStr,tmpStr);
651 Tcl_Free((char *)tmpStr);
656 curlData->errorBufferName=curlstrdup(tmpStr);
658 curlData->errorBuffer=NULL;
660 curlData->errorBufferKey=NULL;
663 Tcl_RegExpRange(regExp,1,&startPtr,&endPtr);
664 charLength=endPtr-startPtr;
665 curlData->errorBufferName=Tcl_Alloc(charLength+1);
666 strncpy(curlData->errorBufferName,startPtr,charLength);
667 curlData->errorBufferName[charLength]=0;
668 Tcl_RegExpRange(regExp,2,&startPtr,&endPtr);
669 charLength=endPtr-startPtr;
670 curlData->errorBufferKey=Tcl_Alloc(charLength+1);
671 strncpy(curlData->errorBufferKey,startPtr,charLength);
672 curlData->errorBufferKey[charLength]=0;
675 Tcl_Free((char *)tmpStr);
676 if (curlData->errorBufferName!=NULL) {
677 curlData->errorBuffer=Tcl_Alloc(CURL_ERROR_SIZE);
678 if (curl_easy_setopt(curlHandle,CURLOPT_ERRORBUFFER,
679 curlData->errorBuffer)) {
680 Tcl_Free((char *)curlData->errorBuffer);
681 curlData->errorBuffer=NULL;
685 Tcl_Free(curlData->errorBuffer);
689 if (SetoptLong(interp,curlHandle,CURLOPT_HTTPGET,tableIndex,
695 if (SetoptInt(interp,curlHandle,CURLOPT_POST,tableIndex,objv)) {
700 if (SetoptChar(interp,curlHandle,
701 CURLOPT_COPYPOSTFIELDS,tableIndex,objv)) {
706 if (SetoptChar(interp,curlHandle,
707 CURLOPT_FTPPORT,tableIndex,objv)) {
712 if (SetoptChar(interp,curlHandle,CURLOPT_COOKIE,tableIndex,objv)) {
717 if (SetoptChar(interp,curlHandle,CURLOPT_COOKIEFILE,tableIndex,objv)) {
722 if(SetoptsList(interp,&curlData->headerList,objv)) {
723 curlErrorSetOpt(interp,configTable,tableIndex,"Header list invalid");
726 if (curl_easy_setopt(curlHandle,CURLOPT_HTTPHEADER,curlData->headerList)) {
727 curl_slist_free_all(curlData->headerList);
728 curlData->headerList=NULL;
734 if (Tcl_ListObjGetElements(interp,objv,&k,&httpPostData)
739 newFormArray=(struct formArrayStruct *)Tcl_Alloc(sizeof(struct formArrayStruct));
740 formArray=(struct curl_forms *)Tcl_Alloc(k*(sizeof(struct curl_forms)));
743 newFormArray->next=curlData->formArray;
744 newFormArray->formArray=formArray;
745 newFormArray->formHeaderList=NULL;
747 for(i=0,j=0;i<k;i+=2,j+=1) {
748 if (Tcl_GetIndexFromObj(interp,httpPostData[i],curlFormTable,
749 "CURLFORM option",TCL_EXACT,&curlTableIndex)==TCL_ERROR) {
753 switch(curlTableIndex) {
755 /* fprintf(stdout,"Section name: %s\n",Tcl_GetString(httpPostData[i+1]));*/
756 formArray[formArrayIndex].option = CURLFORM_COPYNAME;
757 formArray[formArrayIndex].value = curlstrdup(Tcl_GetString(httpPostData[i+1]));
760 /* fprintf(stdout,"Section contents: %s\n",Tcl_GetString(httpPostData[i+1]));*/
761 tmpStr=Tcl_GetStringFromObj(httpPostData[i+1],&curlformBufferSize);
762 formArray[formArrayIndex].option = CURLFORM_COPYCONTENTS;
764 formArray[formArrayIndex].value = Tcl_Alloc((curlformBufferSize > 0) ? curlformBufferSize : 1);
765 if (curlformBufferSize > 0) {
766 memcpy((char *)formArray[formArrayIndex].value,tmpStr,curlformBufferSize);
768 memset((char *)formArray[formArrayIndex].value,0,1);
772 formArray[formArrayIndex].option = CURLFORM_CONTENTSLENGTH;
773 contentslen=curlformBufferSize++;
774 formArray[formArrayIndex].value = (char *)contentslen;
777 /* fprintf(stdout,"File name %d: %s\n",formArrayIndex,Tcl_GetString(httpPostData[i+1]));*/
778 formArray[formArrayIndex].option = CURLFORM_FILE;
779 formArray[formArrayIndex].value = curlstrdup(Tcl_GetString(httpPostData[i+1]));
782 /* fprintf(stdout,"Data type: %s\n",Tcl_GetString(httpPostData[i+1]));*/
783 formArray[formArrayIndex].option = CURLFORM_CONTENTTYPE;
784 formArray[formArrayIndex].value = curlstrdup(Tcl_GetString(httpPostData[i+1]));
787 /* fprintf(stdout,"ContentHeader: %s\n",Tcl_GetString(httpPostData[i+1]));*/
788 formArray[formArrayIndex].option = CURLFORM_CONTENTHEADER;
789 if(SetoptsList(interp,&newFormArray->formHeaderList,httpPostData[i+1])) {
790 curlErrorSetOpt(interp,configTable,tableIndex,"Header list invalid");
794 formArray[formArrayIndex].value = (char *)newFormArray->formHeaderList;
797 /* fprintf(stdout,"FileName: %s\n",Tcl_GetString(httpPostData[i+1])); */
798 formArray[formArrayIndex].option = CURLFORM_FILENAME;
799 formArray[formArrayIndex].value = curlstrdup(Tcl_GetString(httpPostData[i+1]));
802 /* fprintf(stdout,"BufferName: %s\n",Tcl_GetString(httpPostData[i+1])); */
803 formArray[formArrayIndex].option = CURLFORM_BUFFER;
804 formArray[formArrayIndex].value = curlstrdup(Tcl_GetString(httpPostData[i+1]));
807 /* fprintf(stdout,"Buffer: %s\n",Tcl_GetString(httpPostData[i+1])); */
808 tmpUStr=Tcl_GetByteArrayFromObj
809 (httpPostData[i+1],&curlformBufferSize);
810 formArray[formArrayIndex].option = CURLFORM_BUFFERPTR;
811 formArray[formArrayIndex].value = (char *)
812 memcpy(Tcl_Alloc(curlformBufferSize), tmpUStr, curlformBufferSize);
814 formArray[formArrayIndex].option = CURLFORM_BUFFERLENGTH;
815 contentslen=curlformBufferSize;
816 formArray[formArrayIndex].value = (char *)contentslen;
819 /* fprintf(stdout,"FileName: %s\n",Tcl_GetString(httpPostData[i+1])); */
820 formArray[formArrayIndex].option = CURLFORM_FILECONTENT;
821 formArray[formArrayIndex].value = curlstrdup(Tcl_GetString(httpPostData[i+1]));
826 formArray[formArrayIndex].option=CURLFORM_END;
827 curlData->formArray=newFormArray;
829 if (0==formaddError) {
830 formaddError=curl_formadd(&(curlData->postListFirst)
831 ,&(curlData->postListLast), CURLFORM_ARRAY, formArray
834 if (formaddError!=CURL_FORMADD_OK) {
835 curlResetFormArray(formArray);
836 curlData->formArray=newFormArray->next;
837 Tcl_Free((char *)newFormArray);
838 tmpStr=Tcl_Alloc(10);
839 snprintf(tmpStr,10,"%d",formaddError);
840 resultObjPtr=Tcl_NewStringObj(tmpStr,-1);
841 Tcl_SetObjResult(interp,resultObjPtr);
848 if (SetoptChar(interp,curlHandle,CURLOPT_SSLCERT,tableIndex,objv)) {
853 if (SetoptChar(interp,curlHandle,CURLOPT_SSLCERTPASSWD,tableIndex,objv)) {
858 if (Tcl_GetIndexFromObj(interp, objv, sslversion,
859 "sslversion ",TCL_EXACT,&intNumber)==TCL_ERROR) {
864 longNumber=CURL_SSLVERSION_DEFAULT;
867 longNumber=CURL_SSLVERSION_TLSv1;
870 longNumber=CURL_SSLVERSION_SSLv2;
873 longNumber=CURL_SSLVERSION_SSLv3;
876 longNumber=CURL_SSLVERSION_TLSv1_0;
879 longNumber=CURL_SSLVERSION_TLSv1_1;
882 longNumber=CURL_SSLVERSION_TLSv1_2;
884 tmpObjPtr=Tcl_NewLongObj(longNumber);
885 if (SetoptLong(interp,curlHandle,CURLOPT_SSLVERSION,
886 tableIndex,tmpObjPtr)) {
891 if (SetoptInt(interp,curlHandle,CURLOPT_CRLF,tableIndex,objv)) {
896 if(SetoptsList(interp,&curlData->quote,objv)) {
897 curlErrorSetOpt(interp,configTable,tableIndex,"quote list invalid");
900 if (curl_easy_setopt(curlHandle,CURLOPT_QUOTE,curlData->quote)) {
901 curl_slist_free_all(curlData->quote);
902 curlData->quote=NULL;
908 if(SetoptsList(interp,&curlData->postquote,objv)) {
909 curlErrorSetOpt(interp,configTable,tableIndex,"postqoute invalid");
912 if (curl_easy_setopt(curlHandle,CURLOPT_POSTQUOTE,curlData->postquote)) {
913 curlErrorSetOpt(interp,configTable,tableIndex,"postqoute invalid");
914 curl_slist_free_all(curlData->postquote);
915 curlData->postquote=NULL;
921 Tcl_Free(curlData->headerFile);
922 curlData->headerFile=curlstrdup(Tcl_GetString(objv));
923 if (curlData->headerFlag) {
924 if (curlData->headerHandle!=NULL) {
925 fclose(curlData->headerHandle);
926 curlData->headerHandle=NULL;
928 curl_easy_setopt(curlHandle,CURLOPT_HEADERDATA,NULL);
930 if ((strcmp(curlData->headerFile,""))&&(strcmp(curlData->headerFile,"stdout"))
931 &&(strcmp(curlData->headerFile,"stderr"))) {
932 curlData->headerFlag=1;
934 if ((strcmp(curlData->headerFile,"stdout"))) {
935 curl_easy_setopt(curlHandle,CURLOPT_HEADERDATA,stderr);
937 curl_easy_setopt(curlHandle,CURLOPT_HEADERDATA,stdout);
939 curlData->headerFlag=0;
940 curlData->headerFile=NULL;
944 if (Tcl_GetIndexFromObj(interp, objv, timeCond,
945 "time cond option",TCL_EXACT, &intNumber)==TCL_ERROR) {
949 longNumber=CURL_TIMECOND_IFMODSINCE;
951 longNumber=CURL_TIMECOND_IFUNMODSINCE;
953 if (curl_easy_setopt(curlHandle,CURLOPT_TIMECONDITION,longNumber)) {
958 if (SetoptLong(interp,curlHandle,CURLOPT_TIMEVALUE,tableIndex,
964 if (SetoptChar(interp,curlHandle,CURLOPT_CUSTOMREQUEST,tableIndex,objv)) {
969 Tcl_Free(curlData->stderrFile);
970 curlData->stderrFile=curlstrdup(Tcl_GetString(objv));
971 if ((strcmp(curlData->stderrFile,""))&&(strcmp(curlData->stderrFile,"stdout"))
972 &&(strcmp(curlData->stderrFile,"stderr"))) {
973 curlData->stderrFlag=1;
975 curlData->stderrFlag=0;
976 if (strcmp(curlData->stderrFile,"stdout")) {
977 curl_easy_setopt(curlHandle,CURLOPT_STDERR,stderr);
979 curl_easy_setopt(curlHandle,CURLOPT_STDERR,stdout);
981 curlData->stderrFile=NULL;
985 if (SetoptChar(interp,curlHandle,CURLOPT_INTERFACE,tableIndex,objv)) {
991 if (SetoptChar(interp,curlHandle,CURLOPT_KRBLEVEL,tableIndex,objv)) {
996 if (SetoptLong(interp,curlHandle,CURLOPT_SSL_VERIFYPEER,tableIndex,
1002 if (SetoptChar(interp,curlHandle,CURLOPT_CAINFO,tableIndex,objv)) {
1007 if (SetoptLong(interp,curlHandle,CURLOPT_FILETIME,tableIndex,
1013 if (SetoptLong(interp,curlHandle,CURLOPT_MAXREDIRS,tableIndex,
1019 if (SetoptLong(interp,curlHandle,CURLOPT_MAXCONNECTS,tableIndex,
1025 curlErrorSetOpt(interp,configTable,tableIndex,"option is obsolete");
1029 if (SetoptChar(interp,curlHandle,CURLOPT_RANDOM_FILE,tableIndex,objv)) {
1034 if (SetoptChar(interp,curlHandle,CURLOPT_EGDSOCKET,tableIndex,objv)) {
1039 if (SetoptLong(interp,curlHandle,CURLOPT_CONNECTTIMEOUT,
1045 if (SetoptLong(interp,curlHandle,CURLOPT_NOPROGRESS,
1051 if (curlData->headerFlag) {
1052 if (curlData->headerHandle!=NULL) {
1053 fclose(curlData->headerHandle);
1054 curlData->headerHandle=NULL;
1056 curl_easy_setopt(curlHandle,CURLOPT_HEADERDATA,NULL);
1057 curlData->headerFlag=0;
1059 if (curl_easy_setopt(curlHandle,CURLOPT_HEADERFUNCTION,
1060 curlHeaderReader)) {
1063 Tcl_Free(curlData->headerVar);
1064 curlData->headerVar=curlstrdup(Tcl_GetString(objv));
1065 if (curl_easy_setopt(curlHandle,CURLOPT_HEADERDATA,
1066 (FILE *)curlData)) {
1071 Tcl_Free(curlData->bodyVarName);
1072 curlData->bodyVarName=curlstrdup(Tcl_GetString(objv));
1073 if (curlData->outFlag) {
1074 if (curlData->outHandle!=NULL) {
1075 fclose(curlData->outHandle);
1076 curlData->outHandle=NULL;
1078 curl_easy_setopt(curlHandle,CURLOPT_WRITEDATA,NULL);
1080 curlData->outFlag=0;
1081 if (curl_easy_setopt(curlHandle,CURLOPT_WRITEFUNCTION,
1085 if (curl_easy_setopt(curlHandle,CURLOPT_WRITEDATA,curlData)) {
1090 Tcl_Free(curlData->progressProc);
1091 curlData->progressProc=curlstrdup(Tcl_GetString(objv));
1092 if (strcmp(curlData->progressProc,"")) {
1093 if (curl_easy_setopt(curlHandle,CURLOPT_PROGRESSFUNCTION,
1094 curlProgressCallback)) {
1097 if (curl_easy_setopt(curlHandle,CURLOPT_PROGRESSDATA,
1102 if (curl_easy_setopt(curlHandle,CURLOPT_PROGRESSFUNCTION,NULL)) {
1108 if (curlData->cancelTransVarName) {
1109 Tcl_UnlinkVar(curlData->interp,curlData->cancelTransVarName);
1110 Tcl_Free(curlData->cancelTransVarName);
1112 curlData->cancelTransVarName=curlstrdup(Tcl_GetString(objv));
1113 Tcl_LinkVar(interp,curlData->cancelTransVarName,
1114 (char *)&(curlData->cancelTrans),TCL_LINK_INT);
1117 curlData->writeProc=curlstrdup(Tcl_GetString(objv));
1118 if (curlData->outFlag) {
1119 if (curlData->outHandle!=NULL) {
1120 fclose(curlData->outHandle);
1121 curlData->outHandle=NULL;
1123 curl_easy_setopt(curlHandle,CURLOPT_WRITEDATA,NULL);
1125 curlData->outFlag=0;
1126 if (curl_easy_setopt(curlHandle,CURLOPT_WRITEFUNCTION,
1127 curlWriteProcInvoke)) {
1128 curl_easy_setopt(curlHandle,CURLOPT_WRITEFUNCTION,NULL);
1131 if (curl_easy_setopt(curlHandle,CURLOPT_WRITEDATA,curlData)) {
1132 curl_easy_setopt(curlHandle,CURLOPT_WRITEFUNCTION,NULL);
1137 curlData->readProc=curlstrdup(Tcl_GetString(objv));
1138 if (curlData->inFlag) {
1139 if (curlData->inHandle!=NULL) {
1140 fclose(curlData->inHandle);
1141 curlData->inHandle=NULL;
1143 curl_easy_setopt(curlHandle,CURLOPT_READDATA,NULL);
1146 if (strcmp(curlData->readProc,"")) {
1147 if (curl_easy_setopt(curlHandle,CURLOPT_READFUNCTION,
1148 curlReadProcInvoke)) {
1152 curl_easy_setopt(curlHandle,CURLOPT_READFUNCTION,NULL);
1155 if (curl_easy_setopt(curlHandle,CURLOPT_READDATA,curlData)) {
1160 if (SetoptLong(interp,curlHandle,CURLOPT_SSL_VERIFYHOST,
1166 if (SetoptChar(interp,curlHandle,CURLOPT_COOKIEJAR,tableIndex,objv)) {
1171 if (SetoptChar(interp,curlHandle,CURLOPT_SSL_CIPHER_LIST,tableIndex,objv)) {
1176 if (Tcl_GetIndexFromObj(interp, objv, httpVersionTable,
1177 "http version",TCL_EXACT,&tableIndex)==TCL_ERROR) {
1180 if (curl_easy_setopt(curlHandle,CURLOPT_HTTP_VERSION,
1182 tmpStr=curlstrdup(Tcl_GetString(objv));
1183 curlErrorSetOpt(interp,configTable,70,tmpStr);
1189 if (SetoptLong(interp,curlHandle,CURLOPT_FTP_USE_EPSV,
1195 if (SetoptChar(interp,curlHandle,CURLOPT_SSLCERTTYPE,tableIndex,objv)) {
1200 if (SetoptChar(interp,curlHandle,CURLOPT_SSLKEY,tableIndex,objv)) {
1205 if (SetoptChar(interp,curlHandle,CURLOPT_SSLKEYTYPE,tableIndex,objv)) {
1211 if (SetoptChar(interp,curlHandle,CURLOPT_KEYPASSWD,tableIndex,objv)) {
1216 if (SetoptChar(interp,curlHandle,CURLOPT_SSLENGINE,tableIndex,objv)) {
1221 if (SetoptLong(interp,curlHandle,CURLOPT_SSLENGINE_DEFAULT,tableIndex,objv)) {
1226 if(SetoptsList(interp,&curlData->prequote,objv)) {
1227 curlErrorSetOpt(interp,configTable,tableIndex,"pretqoute invalid");
1230 if (curl_easy_setopt(curlHandle,CURLOPT_PREQUOTE,curlData->prequote)) {
1231 curlErrorSetOpt(interp,configTable,tableIndex,"preqoute invalid");
1232 curl_slist_free_all(curlData->prequote);
1233 curlData->prequote=NULL;
1239 curlData->debugProc=curlstrdup(Tcl_GetString(objv));
1240 if (curl_easy_setopt(curlHandle,CURLOPT_DEBUGFUNCTION,
1241 curlDebugProcInvoke)) {
1244 if (curl_easy_setopt(curlHandle,CURLOPT_DEBUGDATA,curlData)) {
1249 if (SetoptLong(interp,curlHandle,CURLOPT_DNS_CACHE_TIMEOUT,
1255 if (SetoptLong(interp,curlHandle,CURLOPT_DNS_USE_GLOBAL_CACHE,
1261 if (SetoptLong(interp,curlHandle,CURLOPT_COOKIESESSION,
1267 if (SetoptChar(interp,curlHandle,CURLOPT_CAPATH,tableIndex,objv)) {
1272 if (SetoptLong(interp,curlHandle,CURLOPT_BUFFERSIZE,
1278 if (SetoptLong(interp,curlHandle,CURLOPT_NOSIGNAL,
1284 if (Tcl_GetIndexFromObj(interp, objv, encodingTable,
1285 "encoding",TCL_EXACT,&tableIndex)==TCL_ERROR) {
1288 if (tableIndex==2) {
1289 if (curl_easy_setopt(curlHandle,CURLOPT_ACCEPT_ENCODING,"")) {
1290 curlErrorSetOpt(interp,configTable,86,"all");
1294 if (SetoptChar(interp,curlHandle,CURLOPT_ACCEPT_ENCODING,86,objv)) {
1300 if (Tcl_GetIndexFromObj(interp, objv, proxyTypeTable,
1301 "proxy type",TCL_EXACT,&tableIndex)==TCL_ERROR) {
1304 switch(tableIndex) {
1306 curl_easy_setopt(curlHandle,CURLOPT_PROXYTYPE,
1310 curl_easy_setopt(curlHandle,CURLOPT_PROXYTYPE,
1311 CURLPROXY_HTTP_1_0);
1314 curl_easy_setopt(curlHandle,CURLOPT_PROXYTYPE,
1318 curl_easy_setopt(curlHandle,CURLOPT_PROXYTYPE,
1322 curl_easy_setopt(curlHandle,CURLOPT_PROXYTYPE,
1326 curl_easy_setopt(curlHandle,CURLOPT_PROXYTYPE,
1327 CURLPROXY_SOCKS5_HOSTNAME);
1331 if(SetoptsList(interp,&curlData->http200aliases,objv)) {
1332 curlErrorSetOpt(interp,configTable,tableIndex,"http200aliases invalid");
1335 if (curl_easy_setopt(curlHandle,CURLOPT_HTTP200ALIASES,curlData->http200aliases)) {
1336 curlErrorSetOpt(interp,configTable,tableIndex,"http200aliases invalid");
1337 curl_slist_free_all(curlData->http200aliases);
1338 curlData->http200aliases=NULL;
1344 if (SetoptInt(interp,curlHandle,CURLOPT_UNRESTRICTED_AUTH
1345 ,tableIndex,objv)) {
1350 if (SetoptLong(interp,curlHandle,CURLOPT_FTP_USE_EPRT,
1356 Tcl_Free(curlData->command);
1357 curlData->command=curlstrdup(Tcl_GetString(objv));
1360 if (Tcl_GetIndexFromObj(interp, objv, httpAuthMethods,
1361 "authentication method",TCL_EXACT,&intNumber)==TCL_ERROR) {
1364 curlData->anyAuthFlag=0;
1367 longNumber=CURLAUTH_BASIC;
1370 longNumber=CURLAUTH_DIGEST;
1373 longNumber=CURLAUTH_DIGEST_IE;
1376 longNumber=CURLAUTH_GSSNEGOTIATE;
1379 longNumber=CURLAUTH_NTLM;
1382 longNumber=CURLAUTH_ANY;
1383 curlData->anyAuthFlag=1;
1386 longNumber=CURLAUTH_ANYSAFE;
1389 longNumber=CURLAUTH_NTLM_WB;
1392 tmpObjPtr=Tcl_NewLongObj(longNumber);
1393 if (SetoptLong(interp,curlHandle,CURLOPT_HTTPAUTH
1394 ,tableIndex,tmpObjPtr)) {
1399 if (SetoptLong(interp,curlHandle,CURLOPT_FTP_CREATE_MISSING_DIRS,
1405 if (Tcl_GetIndexFromObj(interp, objv, httpAuthMethods,
1406 "authentication method",TCL_EXACT,&intNumber)==TCL_ERROR) {
1411 longNumber=CURLAUTH_BASIC;
1414 longNumber=CURLAUTH_DIGEST;
1417 longNumber=CURLAUTH_GSSNEGOTIATE;
1420 longNumber=CURLAUTH_NTLM;
1423 longNumber=CURLAUTH_ANYSAFE;
1427 longNumber=CURLAUTH_ANY;
1430 tmpObjPtr=Tcl_NewLongObj(longNumber);
1431 if (SetoptLong(interp,curlHandle,CURLOPT_PROXYAUTH
1432 ,tableIndex,tmpObjPtr)) {
1437 if (SetoptLong(interp,curlHandle,CURLOPT_FTP_RESPONSE_TIMEOUT,
1443 if (Tcl_GetIndexFromObj(interp, objv, ipresolve,
1444 "ip version",TCL_EXACT,&curlTableIndex)==TCL_ERROR) {
1447 switch(curlTableIndex) {
1449 longNumber=CURL_IPRESOLVE_WHATEVER;
1452 longNumber=CURL_IPRESOLVE_V4;
1455 longNumber=CURL_IPRESOLVE_V6;
1458 tmpObjPtr=Tcl_NewLongObj(longNumber);
1459 if (SetoptLong(interp,curlHandle,CURLOPT_IPRESOLVE
1460 ,tableIndex,tmpObjPtr)) {
1465 if (SetoptLong(interp,curlHandle,CURLOPT_MAXFILESIZE,
1471 if (SetoptChar(interp,curlHandle,CURLOPT_NETRC_FILE,tableIndex,objv)) {
1477 if (Tcl_GetIndexFromObj(interp, objv, ftpssl,
1478 "ftps method ",TCL_EXACT,&intNumber)==TCL_ERROR) {
1483 longNumber=CURLUSESSL_NONE;
1486 longNumber=CURLUSESSL_TRY;
1489 longNumber=CURLUSESSL_CONTROL;
1492 longNumber=CURLUSESSL_ALL;
1495 tmpObjPtr=Tcl_NewLongObj(longNumber);
1496 if (SetoptLong(interp,curlHandle,CURLOPT_USE_SSL,
1497 tableIndex,tmpObjPtr)) {
1502 if (SetoptSHandle(interp,curlHandle,CURLOPT_SHARE,
1508 if (SetoptLong(interp,curlHandle,CURLOPT_PORT,
1514 if (SetoptLong(interp,curlHandle,CURLOPT_TCP_NODELAY,
1520 if (SetoptLong(interp,curlHandle,CURLOPT_AUTOREFERER,
1526 curlErrorSetOpt(interp,configTable,tableIndex,"option is obsolete");
1530 curlErrorSetOpt(interp,configTable,tableIndex,"option is obsolete");
1534 curlErrorSetOpt(interp,configTable,tableIndex,"option is obsolete");
1538 curlErrorSetOpt(interp,configTable,tableIndex,"option is obsolete, check '-ftpport'");
1542 curlErrorSetOpt(interp,configTable,tableIndex,"option is obsolete, check '-ftpport'");
1546 curlErrorSetOpt(interp,configTable,tableIndex,"option is obsolete");
1550 curlErrorSetOpt(interp,configTable,tableIndex,"option is obsolete");
1554 if (Tcl_GetIndexFromObj(interp, objv, ftpsslauth,
1555 "ftpsslauth method ",TCL_EXACT,&intNumber)==TCL_ERROR) {
1560 longNumber=CURLFTPAUTH_DEFAULT;
1563 longNumber=CURLFTPAUTH_SSL;
1566 longNumber=CURLFTPAUTH_TLS;
1569 tmpObjPtr=Tcl_NewLongObj(longNumber);
1570 if (SetoptLong(interp,curlHandle,CURLOPT_FTPSSLAUTH,
1571 tableIndex,tmpObjPtr)) {
1576 curlErrorSetOpt(interp,configTable,tableIndex,"option is obsolete");
1580 curlErrorSetOpt(interp,configTable,tableIndex,"option is obsolete");
1584 if (SetoptChar(interp,curlHandle,CURLOPT_FTP_ACCOUNT,tableIndex,objv)) {
1589 if (SetoptLong(interp,curlHandle,CURLOPT_IGNORE_CONTENT_LENGTH,
1595 if (SetoptChar(interp,curlHandle,CURLOPT_COOKIELIST,tableIndex,objv)) {
1600 if (SetoptLong(interp,curlHandle,CURLOPT_FTP_SKIP_PASV_IP,
1606 if (Tcl_GetIndexFromObj(interp, objv, ftpfilemethod,
1607 "ftp file method ",TCL_EXACT,&intNumber)==TCL_ERROR) {
1613 longNumber=1; /* FTPFILE_MULTICWD */
1616 longNumber=2; /* FTPFILE_NOCWD */
1619 longNumber=3; /* FTPFILE_SINGLECWD */
1622 tmpObjPtr=Tcl_NewLongObj(longNumber);
1623 if (SetoptLong(interp,curlHandle,CURLOPT_FTP_FILEMETHOD,
1624 tableIndex,tmpObjPtr)) {
1629 if (SetoptLong(interp,curlHandle,CURLOPT_LOCALPORT,
1635 if (SetoptLong(interp,curlHandle,CURLOPT_LOCALPORTRANGE,
1641 if (SetoptCurlOffT(interp,curlHandle,CURLOPT_MAX_SEND_SPEED_LARGE,
1647 if (SetoptCurlOffT(interp,curlHandle,CURLOPT_MAX_RECV_SPEED_LARGE,
1653 if (SetoptChar(interp,curlHandle,
1654 CURLOPT_FTP_ALTERNATIVE_TO_USER,tableIndex,objv)) {
1659 if (SetoptLong(interp,curlHandle,CURLOPT_SSL_SESSIONID_CACHE,
1665 if (Tcl_GetIndexFromObj(interp, objv, sshauthtypes,
1666 "ssh auth type ",TCL_EXACT,&intNumber)==TCL_ERROR) {
1671 longNumber=CURLSSH_AUTH_PUBLICKEY;
1674 longNumber=CURLSSH_AUTH_PASSWORD;
1677 longNumber=CURLSSH_AUTH_HOST;
1680 longNumber=CURLSSH_AUTH_KEYBOARD;
1683 longNumber=CURLSSH_AUTH_ANY;
1686 tmpObjPtr=Tcl_NewLongObj(longNumber);
1687 if (SetoptLong(interp,curlHandle,CURLOPT_SSH_AUTH_TYPES,
1688 tableIndex,tmpObjPtr)) {
1693 if (SetoptChar(interp,curlHandle,CURLOPT_SSH_PUBLIC_KEYFILE,
1699 if (SetoptChar(interp,curlHandle,CURLOPT_SSH_PRIVATE_KEYFILE,
1705 if (SetoptLong(interp,curlHandle,CURLOPT_TIMEOUT_MS,
1711 if (SetoptLong(interp,curlHandle,CURLOPT_CONNECTTIMEOUT_MS,
1717 if (SetoptLong(interp,curlHandle,CURLOPT_HTTP_CONTENT_DECODING,
1723 if (SetoptLong(interp,curlHandle,CURLOPT_HTTP_TRANSFER_DECODING,
1728 /* 132 is together with case 50 */
1730 if (SetoptLong(interp,curlHandle,CURLOPT_NEW_FILE_PERMS,
1736 if (SetoptLong(interp,curlHandle,CURLOPT_NEW_DIRECTORY_PERMS,
1741 /* case 135 with 75, case 136 with 19, case 137 with 18 and case 138 with 99 */
1744 if (Tcl_GetIndexFromObj(interp, objv, postredir,
1745 "Postredir option ",TCL_EXACT,&intNumber)==TCL_ERROR) {
1750 longNumber=CURL_REDIR_POST_301;
1753 longNumber=CURL_REDIR_POST_302;
1756 longNumber=CURL_REDIR_POST_ALL;
1759 tmpObjPtr=Tcl_NewLongObj(longNumber);
1760 if (SetoptLong(interp,curlHandle,CURLOPT_POSTREDIR,
1761 tableIndex,tmpObjPtr)) {
1766 if (SetoptChar(interp,curlHandle,CURLOPT_SSH_HOST_PUBLIC_KEY_MD5,
1772 if (SetoptLong(interp,curlHandle,CURLOPT_PROXY_TRANSFER_MODE,
1778 if (SetoptChar(interp,curlHandle,CURLOPT_CRLFILE,
1784 if (SetoptChar(interp,curlHandle,CURLOPT_ISSUERCERT,
1790 if (SetoptLong(interp,curlHandle,CURLOPT_ADDRESS_SCOPE,
1796 if (SetoptLong(interp,curlHandle,CURLOPT_CERTINFO,
1801 /* case 146 is together with 139*/
1803 if (SetoptChar(interp,curlHandle,CURLOPT_USERNAME,
1809 if (SetoptChar(interp,curlHandle,CURLOPT_PASSWORD,
1815 if (SetoptChar(interp,curlHandle,CURLOPT_PROXYUSERNAME,
1821 if (SetoptChar(interp,curlHandle,CURLOPT_PROXYPASSWORD,
1827 if (SetoptLong(interp,curlHandle,CURLOPT_TFTP_BLKSIZE,
1833 if (SetoptChar(interp,curlHandle,CURLOPT_SOCKS5_GSSAPI_SERVICE,
1839 if (SetoptLong(interp,curlHandle,CURLOPT_SOCKS5_GSSAPI_NEC,
1846 if (Tcl_ListObjGetElements(interp,objv,&j,&protocols)==TCL_ERROR) {
1850 for (i=0,protocolMask=0;i<j;i++) {
1851 tmpStr=curlstrdup(Tcl_GetString(protocols[i]));
1852 if (Tcl_GetIndexFromObj(interp,protocols[i],protocolNames,
1853 "protocol",TCL_EXACT,&curlTableIndex)==TCL_ERROR) {
1856 switch(curlTableIndex) {
1857 case 0: /* http 1 */
1858 protocolMask|=CURLPROTO_HTTP;
1860 case 1: /* https 2 */
1861 protocolMask|=CURLPROTO_HTTPS;
1864 protocolMask|=CURLPROTO_FTP;
1866 case 3: /* ftps 8 */
1867 protocolMask|=CURLPROTO_FTPS;
1869 case 4: /* scp 16 */
1870 protocolMask|=CURLPROTO_SCP;
1872 case 5: /* sftp 32 */
1873 protocolMask|=CURLPROTO_SFTP;
1875 case 6: /* telnet 64 */
1876 protocolMask|=CURLPROTO_TELNET;
1878 case 7: /* ldap 128 */
1879 protocolMask|=CURLPROTO_LDAP;
1881 case 8: /* ldaps 256 */
1882 protocolMask|=CURLPROTO_LDAPS;
1884 case 9: /* dict 512 */
1885 protocolMask|=CURLPROTO_DICT;
1887 case 10: /* file 1024 */
1888 protocolMask|=CURLPROTO_FILE;
1890 case 11: /* tftp 2048 */
1891 protocolMask|=CURLPROTO_TFTP;
1893 case 12: /* imap 4096 */
1894 protocolMask|=CURLPROTO_IMAP;
1896 case 13: /* imaps */
1897 protocolMask|=CURLPROTO_IMAPS;
1900 protocolMask|=CURLPROTO_POP3;
1902 case 15: /* pop3s */
1903 protocolMask|=CURLPROTO_POP3S;
1906 protocolMask|=CURLPROTO_SMTP;
1908 case 17: /* smtps */
1909 protocolMask|=CURLPROTO_SMTPS;
1912 protocolMask|=CURLPROTO_RTSP;
1915 protocolMask|=CURLPROTO_RTMP;
1917 case 20: /* rtmpt */
1918 protocolMask|=CURLPROTO_RTMPT;
1920 case 21: /* rtmpe */
1921 protocolMask|=CURLPROTO_RTMPE;
1923 case 22: /* rtmpte */
1924 protocolMask|=CURLPROTO_RTMPTE;
1926 case 23: /* rtmps */
1927 protocolMask|=CURLPROTO_RTMPS;
1929 case 24: /* rtmpts */
1930 protocolMask|=CURLPROTO_RTMPTS;
1932 case 25: /* gopher */
1933 protocolMask|=CURLPROTO_GOPHER;
1935 case 26: /* all FFFF */
1936 protocolMask|=CURLPROTO_ALL;
1939 tmpObjPtr=Tcl_NewLongObj(protocolMask);
1940 if (tableIndex==154) {
1941 longNumber=CURLOPT_PROTOCOLS;
1943 longNumber=CURLOPT_REDIR_PROTOCOLS;
1945 if (SetoptLong(interp,curlHandle,longNumber,tableIndex,tmpObjPtr)) {
1950 if (Tcl_GetIndexFromObj(interp, objv, ftpsslccc,
1951 "Clear Command Channel option ",TCL_EXACT,&intNumber)==TCL_ERROR) {
1956 longNumber=CURLFTPSSL_CCC_NONE;
1959 longNumber=CURLFTPSSL_CCC_PASSIVE;
1962 longNumber=CURLFTPSSL_CCC_ACTIVE;
1965 tmpObjPtr=Tcl_NewLongObj(longNumber);
1966 if (SetoptLong(interp,curlHandle,CURLOPT_FTP_SSL_CCC,
1967 tableIndex,tmpObjPtr)) {
1972 if (SetoptChar(interp,curlHandle,CURLOPT_SSH_KNOWNHOSTS,
1978 if (curl_easy_setopt(curlHandle,CURLOPT_SSH_KEYFUNCTION,curlsshkeycallback)) {
1981 if (curl_easy_setopt(curlHandle,CURLOPT_SSH_KEYDATA,curlData)) {
1984 curlData->sshkeycallProc=curlstrdup(Tcl_GetString(objv));
1987 if (SetoptChar(interp,curlHandle,CURLOPT_MAIL_FROM,
1993 if(SetoptsList(interp,&curlData->mailrcpt,objv)) {
1994 curlErrorSetOpt(interp,configTable,tableIndex,"mailrcpt invalid");
1997 if (curl_easy_setopt(curlHandle,CURLOPT_MAIL_RCPT,curlData->mailrcpt)) {
1998 curlErrorSetOpt(interp,configTable,tableIndex,"mailrcpt invalid");
1999 curl_slist_free_all(curlData->mailrcpt);
2000 curlData->mailrcpt=NULL;
2006 if (SetoptLong(interp,curlHandle,CURLOPT_FTP_USE_PRET,
2012 if (SetoptLong(interp,curlHandle,CURLOPT_WILDCARDMATCH,
2018 curlData->chunkBgnProc=curlstrdup(Tcl_GetString(objv));
2019 if (strcmp(curlData->chunkBgnProc,"")) {
2020 if (curl_easy_setopt(curlHandle,CURLOPT_CHUNK_BGN_FUNCTION,
2021 curlChunkBgnProcInvoke)) {
2025 curl_easy_setopt(curlHandle,CURLOPT_CHUNK_BGN_FUNCTION,NULL);
2028 if (curl_easy_setopt(curlHandle,CURLOPT_CHUNK_DATA,curlData)) {
2033 curlData->chunkBgnVar=curlstrdup(Tcl_GetString(objv));
2034 if (!strcmp(curlData->chunkBgnVar,"")) {
2035 curlErrorSetOpt(interp,configTable,tableIndex,"invalid var name");
2040 curlData->chunkEndProc=curlstrdup(Tcl_GetString(objv));
2041 if (strcmp(curlData->chunkEndProc,"")) {
2042 if (curl_easy_setopt(curlHandle,CURLOPT_CHUNK_END_FUNCTION,
2043 curlChunkEndProcInvoke)) {
2047 curl_easy_setopt(curlHandle,CURLOPT_CHUNK_END_FUNCTION,NULL);
2052 curlData->fnmatchProc=curlstrdup(Tcl_GetString(objv));
2053 if (strcmp(curlData->fnmatchProc,"")) {
2054 if (curl_easy_setopt(curlHandle,CURLOPT_FNMATCH_FUNCTION,
2055 curlfnmatchProcInvoke)) {
2059 curl_easy_setopt(curlHandle,CURLOPT_FNMATCH_FUNCTION,NULL);
2062 if (curl_easy_setopt(curlHandle,CURLOPT_FNMATCH_DATA,curlData)) {
2067 if(SetoptsList(interp,&curlData->resolve,objv)) {
2068 curlErrorSetOpt(interp,configTable,tableIndex,"invalid list");
2071 if (curl_easy_setopt(curlHandle,CURLOPT_RESOLVE,curlData->resolve)) {
2072 curlErrorSetOpt(interp,configTable,tableIndex,"resolve list invalid");
2073 curl_slist_free_all(curlData->resolve);
2074 curlData->resolve=NULL;
2080 if (SetoptChar(interp,curlHandle,CURLOPT_TLSAUTH_USERNAME,
2086 if (SetoptChar(interp,curlHandle,CURLOPT_TLSAUTH_PASSWORD,
2092 if (Tcl_GetIndexFromObj(interp, objv, tlsauth,
2093 "TSL auth option ",TCL_EXACT,&intNumber)==TCL_ERROR) {
2098 longNumber=CURL_TLSAUTH_NONE;
2101 longNumber=CURL_TLSAUTH_SRP;
2103 tmpObjPtr=Tcl_NewLongObj(longNumber);
2104 if (SetoptLong(interp,curlHandle,CURLOPT_TLSAUTH_TYPE,
2105 tableIndex,tmpObjPtr)) {
2110 if (SetoptLong(interp,curlHandle,CURLOPT_TRANSFER_ENCODING,
2116 if (Tcl_GetIndexFromObj(interp, objv, gssapidelegation,
2117 "GSS API delegation option ",TCL_EXACT,&intNumber)==TCL_ERROR) {
2122 longNumber=CURLGSSAPI_DELEGATION_FLAG;
2125 longNumber=CURLGSSAPI_DELEGATION_POLICY_FLAG;
2127 tmpObjPtr=Tcl_NewLongObj(longNumber);
2128 if (SetoptLong(interp,curlHandle,CURLOPT_GSSAPI_DELEGATION,
2129 tableIndex,tmpObjPtr)) {
2134 if (SetoptChar(interp,curlHandle,CURLOPT_NOPROXY,
2140 if(SetoptsList(interp,&curlData->telnetoptions,objv)) {
2141 curlErrorSetOpt(interp,configTable,tableIndex,"invalid list");
2144 if (curl_easy_setopt(curlHandle,CURLOPT_TELNETOPTIONS,curlData->telnetoptions)) {
2145 curlErrorSetOpt(interp,configTable,tableIndex,"telnetoptions list invalid");
2146 curl_slist_free_all(curlData->telnetoptions);
2147 curlData->telnetoptions=NULL;
2157 *----------------------------------------------------------------------
2161 * Sets the curl options that require an int
2164 * interp: The interpreter we are working with.
2165 * curlHandle: and the curl handle
2166 * opt: the option to set
2167 * tclObj: The Tcl with the value for the option.
2170 * 0 if all went well.
2171 * 1 in case of error.
2172 *----------------------------------------------------------------------
2175 SetoptInt(Tcl_Interp *interp,CURL *curlHandle,CURLoption opt,
2176 int tableIndex,Tcl_Obj *tclObj) {
2180 if (Tcl_GetIntFromObj(interp,tclObj,&intNumber)) {
2181 parPtr=curlstrdup(Tcl_GetString(tclObj));
2182 curlErrorSetOpt(interp,configTable,tableIndex,parPtr);
2186 if (curl_easy_setopt(curlHandle,opt,intNumber)) {
2187 parPtr=curlstrdup(Tcl_GetString(tclObj));
2188 curlErrorSetOpt(interp,configTable,tableIndex,parPtr);
2196 *----------------------------------------------------------------------
2200 * Set the curl options that require a long
2203 * interp: The interpreter we are working with.
2204 * curlHandle: and the curl handle
2205 * opt: the option to set
2206 * tclObj: The Tcl with the value for the option.
2209 * 0 if all went well.
2210 * 1 in case of error.
2211 *----------------------------------------------------------------------
2214 SetoptLong(Tcl_Interp *interp,CURL *curlHandle,CURLoption opt,
2215 int tableIndex,Tcl_Obj *tclObj) {
2219 if (Tcl_GetLongFromObj(interp,tclObj,&longNumber)) {
2220 parPtr=curlstrdup(Tcl_GetString(tclObj));
2221 curlErrorSetOpt(interp,configTable,tableIndex,parPtr);
2225 if (curl_easy_setopt(curlHandle,opt,longNumber)) {
2226 parPtr=curlstrdup(Tcl_GetString(tclObj));
2227 curlErrorSetOpt(interp,configTable,tableIndex,parPtr);
2236 *----------------------------------------------------------------------
2238 * curlSetoptCurlOffT --
2240 * Set the curl options that require a curl_off_t, even if we really
2241 * use a long to do it. (Cutting and pasting at its worst)
2244 * interp: The interpreter we are working with.
2245 * curlHandle: and the curl handle
2246 * opt: the option to set
2247 * tclObj: The Tcl with the value for the option.
2250 * 0 if all went well.
2251 * 1 in case of error.
2252 *----------------------------------------------------------------------
2255 SetoptCurlOffT(Tcl_Interp *interp,CURL *curlHandle,CURLoption opt,
2256 int tableIndex,Tcl_Obj *tclObj) {
2260 if (Tcl_GetLongFromObj(interp,tclObj,&longNumber)) {
2261 parPtr=curlstrdup(Tcl_GetString(tclObj));
2262 curlErrorSetOpt(interp,configTable,tableIndex,parPtr);
2267 if (curl_easy_setopt(curlHandle,opt,(curl_off_t)longNumber)) {
2268 parPtr=curlstrdup(Tcl_GetString(tclObj));
2269 curlErrorSetOpt(interp,configTable,tableIndex,parPtr);
2279 *----------------------------------------------------------------------
2283 * Set the curl options that require a string
2286 * interp: The interpreter we are working with.
2287 * curlHandle: and the curl handle
2288 * opt: the option to set
2289 * tclObj: The Tcl with the value for the option.
2292 * 0 if all went well.
2293 * 1 in case of error.
2294 *----------------------------------------------------------------------
2297 SetoptChar(Tcl_Interp *interp,CURL *curlHandle,
2298 CURLoption opt,int tableIndex,Tcl_Obj *tclObj) {
2301 optionPtr=curlstrdup(Tcl_GetString(tclObj));
2302 if (curl_easy_setopt(curlHandle,opt,optionPtr)) {
2303 curlErrorSetOpt(interp,configTable,tableIndex,optionPtr);
2304 Tcl_Free(optionPtr);
2307 Tcl_Free(optionPtr);
2312 *----------------------------------------------------------------------
2316 * Set the curl options that require a share handle (there is only
2317 * one but you never know.
2320 * interp: The interpreter we are working with.
2321 * curlHandle: the curl handle
2322 * opt: the option to set
2323 * tclObj: The Tcl with the value for the option.
2326 * 0 if all went well.
2327 * 1 in case of error.
2328 *----------------------------------------------------------------------
2331 SetoptSHandle(Tcl_Interp *interp,CURL *curlHandle,
2332 CURLoption opt,int tableIndex,Tcl_Obj *tclObj) {
2335 Tcl_CmdInfo *infoPtr=(Tcl_CmdInfo *)Tcl_Alloc(sizeof(Tcl_CmdInfo));
2336 struct shcurlObjData *shandleDataPtr;
2338 shandleName=Tcl_GetString(tclObj);
2339 if (0==Tcl_GetCommandInfo(interp,shandleName,infoPtr)) {
2342 shandleDataPtr=(struct shcurlObjData *)(infoPtr->objClientData);
2343 Tcl_Free((char *)infoPtr);
2344 if (curl_easy_setopt(curlHandle,opt,shandleDataPtr->shandle)) {
2345 curlErrorSetOpt(interp,configTable,tableIndex,shandleName);
2352 *----------------------------------------------------------------------
2356 * Prepares a slist for future use.
2359 * slistPtr: Pointer to the slist to prepare.
2360 * objv: Tcl object with a list of the data.
2363 * 0 if all went well.
2364 * 1 in case of error.
2365 *----------------------------------------------------------------------
2368 SetoptsList(Tcl_Interp *interp,struct curl_slist **slistPtr,
2369 Tcl_Obj *CONST objv) {
2373 if (slistPtr!=NULL) {
2374 curl_slist_free_all(*slistPtr);
2378 if (Tcl_ListObjGetElements(interp,objv,&headerNumber,&headers)
2383 for (i=0;i<headerNumber;i++) {
2384 *slistPtr=curl_slist_append(*slistPtr,Tcl_GetString(headers[i]));
2385 if (slistPtr==NULL) {
2393 *----------------------------------------------------------------------
2395 * curlErrorSetOpt --
2397 * When an error happens when setting an option, this function
2398 * takes cares of reporting it
2401 * interp: Pointer to the interpreter we are using.
2402 * option: The index of the option in 'optionTable'
2403 * parPtr: String with the parameter we wanted to set the option to.
2404 *----------------------------------------------------------------------
2408 curlErrorSetOpt(Tcl_Interp *interp,CONST char **configTable, int option,
2409 CONST char *parPtr) {
2413 snprintf(errorMsg,500,"setting option %s: %s",configTable[option],parPtr);
2414 resultPtr=Tcl_NewStringObj(errorMsg,-1);
2415 Tcl_SetObjResult(interp,resultPtr);
2419 *----------------------------------------------------------------------
2423 * This is the function that will be invoked if the user wants to put
2424 * the headers into a variable
2427 * header: string with the header line.
2428 * size and nmemb: it so happens size * nmemb if the size of the
2430 * curlData: A pointer to the curlData structure for the transfer.
2433 * The number of bytes actually written or -1 in case of error, in
2434 * which case 'libcurl' will abort the transfer.
2435 *-----------------------------------------------------------------------
2438 curlHeaderReader(void *ptr,size_t size,size_t nmemb,FILE *curlDataPtr) {
2441 struct curlObjData *curlData=(struct curlObjData *)curlDataPtr;
2444 CONST char *startPtr;
2448 char *headerContent;
2451 int match,charLength;
2453 regExp=Tcl_RegExpCompile(curlData->interp,"(.*?)(?::\\s*)(.*?)(\\r*)(\\n)");
2454 match=Tcl_RegExpExec(curlData->interp,regExp,header,header);
2457 Tcl_RegExpRange(regExp,1,&startPtr,&endPtr);
2458 charLength=endPtr-startPtr;
2459 headerName=Tcl_Alloc(charLength+1);
2460 strncpy(headerName,startPtr,charLength);
2461 headerName[charLength]=0;
2463 Tcl_RegExpRange(regExp,2,&startPtr,&endPtr);
2464 charLength=endPtr-startPtr;
2465 headerContent=Tcl_Alloc(charLength+1);
2466 strncpy(headerContent,startPtr,charLength);
2467 headerContent[charLength]=0;
2468 /* There may be multiple 'Set-Cookie' headers, so we use a list */
2469 if (Tcl_StringCaseMatch(headerName,"Set-Cookie",1)) {
2470 Tcl_SetVar2(curlData->interp,curlData->headerVar,headerName,
2471 headerContent,TCL_LIST_ELEMENT|TCL_APPEND_VALUE);
2473 Tcl_SetVar2(curlData->interp,curlData->headerVar,headerName,
2476 Tcl_Free(headerContent);
2477 Tcl_Free(headerName);
2479 regExp=Tcl_RegExpCompile(curlData->interp,"(^(HTTP|http)[^\r]+)(\r*)(\n)");
2480 match=Tcl_RegExpExec(curlData->interp,regExp,header,header);
2482 Tcl_RegExpRange(regExp,1,&startPtr,&endPtr);
2483 charLength=endPtr-startPtr;
2484 httpStatus=Tcl_Alloc(charLength+1);
2485 strncpy(httpStatus,startPtr,charLength);
2486 httpStatus[charLength]=0;
2488 Tcl_SetVar2(curlData->interp,curlData->headerVar,"http",
2490 Tcl_Free(httpStatus);
2496 *----------------------------------------------------------------------
2500 * This is the function that will be invoked as a callback while
2501 * transferring the body of a request into a Tcl variable.
2503 * This function has been adapted from an example in libcurl's FAQ.
2506 * header: string with the header line.
2507 * size and nmemb: it so happens size * nmemb if the size of the
2509 * curlData: A pointer to the curlData structure for the transfer.
2512 * The number of bytes actually written or -1 in case of error, in
2513 * which case 'libcurl' will abort the transfer.
2514 *-----------------------------------------------------------------------
2517 curlBodyReader(void *ptr,size_t size,size_t nmemb,FILE *curlDataPtr) {
2519 register int realsize = size * nmemb;
2520 struct MemoryStruct *mem=&(((struct curlObjData *)curlDataPtr)->bodyVar);
2522 mem->memory = (char *)Tcl_Realloc(mem->memory,mem->size + realsize);
2524 memcpy(&(mem->memory[mem->size]), ptr, realsize);
2525 mem->size += realsize;
2531 *----------------------------------------------------------------------
2533 * curlProgressCallback --
2535 * This is the function that will be invoked as a callback during a
2538 * This function has been adapted from an example in libcurl's FAQ.
2541 * clientData: The curlData struct for the transfer.
2542 * dltotal: Total amount of bytes to download.
2543 * dlnow: Bytes downloaded so far.
2544 * ultotal: Total amount of bytes to upload.
2545 * ulnow: Bytes uploaded so far.
2548 * Returning a non-zero value will make 'libcurl' abort the transfer
2549 * and return 'CURLE_ABORTED_BY_CALLBACK'.
2550 *-----------------------------------------------------------------------
2553 curlProgressCallback(void *clientData,double dltotal,double dlnow,
2554 double ultotal,double ulnow) {
2556 struct curlObjData *curlData=(struct curlObjData *)clientData;
2557 Tcl_Obj *tclProcPtr;
2558 char tclCommand[300];
2560 snprintf(tclCommand,299,"%s %f %f %f %f",curlData->progressProc,dltotal,
2561 dlnow,ultotal,ulnow);
2562 tclProcPtr=Tcl_NewStringObj(tclCommand,-1);
2563 if (curlData->cancelTransVarName) {
2564 if (curlData->cancelTrans) {
2565 curlData->cancelTrans=0;
2569 if (Tcl_EvalObjEx(curlData->interp,tclProcPtr,TCL_EVAL_GLOBAL)!=TCL_OK) {
2576 *----------------------------------------------------------------------
2578 * curlWriteProcInvoke --
2580 * This is the function that will be invoked as a callback when the user
2581 * wants to invoke a Tcl procedure to write the recieved data.
2583 * This function has been adapted from an example in libcurl's FAQ.
2586 * ptr: A pointer to the data.
2587 * size and nmemb: it so happens size * nmemb if the size of the
2589 * curlData: A pointer to the curlData structure for the transfer.
2592 * The number of bytes actually written or -1 in case of error, in
2593 * which case 'libcurl' will abort the transfer.
2594 *-----------------------------------------------------------------------
2597 curlWriteProcInvoke(void *ptr,size_t size,size_t nmemb,FILE *curlDataPtr) {
2598 register int realsize = size * nmemb;
2599 struct curlObjData *curlData=(struct curlObjData *)curlDataPtr;
2602 objv[0]=Tcl_NewStringObj(curlData->writeProc,-1);
2603 objv[1]=Tcl_NewByteArrayObj(ptr,realsize);
2604 if (curlData->cancelTransVarName) {
2605 if (curlData->cancelTrans) {
2606 curlData->cancelTrans=0;
2610 if (Tcl_EvalObjv(curlData->interp,2,objv,TCL_EVAL_GLOBAL)!=TCL_OK) {
2617 *----------------------------------------------------------------------
2619 * curlReadProcInvoke --
2621 * This is the function that will be invoked as a callback when the user
2622 * wants to invoke a Tcl procedure to read the data to send.
2625 * header: string with the header line.
2626 * size and nmemb: it so happens size * nmemb if the size of the
2628 * curlData: A pointer to the curlData structure for the transfer.
2631 * The number of bytes actually read or CURL_READFUNC_ABORT in case
2632 * of error, in which case 'libcurl' will abort the transfer.
2633 *-----------------------------------------------------------------------
2636 curlReadProcInvoke(void *ptr,size_t size,size_t nmemb,FILE *curlDataPtr) {
2637 register int realsize = size * nmemb;
2638 struct curlObjData *curlData=(struct curlObjData *)curlDataPtr;
2639 Tcl_Obj *tclProcPtr;
2640 Tcl_Obj *readDataPtr;
2641 char tclCommand[300];
2642 unsigned char *readBytes;
2645 snprintf(tclCommand,300,"%s %d",curlData->readProc,realsize);
2646 tclProcPtr=Tcl_NewStringObj(tclCommand,-1);
2648 if (curlData->cancelTransVarName) {
2649 if (curlData->cancelTrans) {
2650 curlData->cancelTrans=0;
2651 return CURL_READFUNC_ABORT;
2654 if (Tcl_EvalObjEx(curlData->interp,tclProcPtr,TCL_EVAL_GLOBAL)!=TCL_OK) {
2655 return CURL_READFUNC_ABORT;
2657 readDataPtr=Tcl_GetObjResult(curlData->interp);
2658 readBytes=Tcl_GetByteArrayFromObj(readDataPtr,&sizeRead);
2659 memcpy(ptr,readBytes,sizeRead);
2665 *----------------------------------------------------------------------
2667 * curlChunkBgnProcInvoke --
2669 * This is the function that will be invoked as a callback when the user
2670 * wants to invoke a Tcl procedure to process every wildcard matching file
2671 * on a ftp transfer.
2674 * transfer_info: a curl_fileinfo structure about the file.
2675 * curlData: A pointer to the curlData structure for the transfer.
2676 * remains: number of chunks remaining.
2677 *-----------------------------------------------------------------------
2680 curlChunkBgnProcInvoke (const void *transfer_info, void *curlDataPtr, int remains) {
2681 struct curlObjData *curlData=(struct curlObjData *)curlDataPtr;
2682 Tcl_Obj *tclProcPtr;
2683 char tclCommand[300];
2685 const struct curl_fileinfo *fileinfoPtr=(const struct curl_fileinfo *)transfer_info;
2687 tclProcPtr=Tcl_NewStringObj(tclCommand,-1);
2689 if (curlData->chunkBgnVar==NULL) {
2690 curlData->chunkBgnVar=curlstrdup("fileData");
2693 Tcl_SetVar2(curlData->interp,curlData->chunkBgnVar,"filename",
2694 fileinfoPtr->filename,0);
2696 switch(fileinfoPtr->filetype) {
2698 Tcl_SetVar2(curlData->interp,curlData->chunkBgnVar,"filetype",
2702 Tcl_SetVar2(curlData->interp,curlData->chunkBgnVar,"filetype",
2706 Tcl_SetVar2(curlData->interp,curlData->chunkBgnVar,"filetype",
2710 Tcl_SetVar2(curlData->interp,curlData->chunkBgnVar,"filetype",
2714 Tcl_SetVar2(curlData->interp,curlData->chunkBgnVar,"filetype",
2718 Tcl_SetVar2(curlData->interp,curlData->chunkBgnVar,"filetype",
2722 Tcl_SetVar2(curlData->interp,curlData->chunkBgnVar,"filetype",
2726 Tcl_SetVar2(curlData->interp,curlData->chunkBgnVar,"filetype",
2730 Tcl_SetVar2(curlData->interp,curlData->chunkBgnVar,"filetype",
2735 Tcl_SetVar2Ex(curlData->interp,curlData->chunkBgnVar,"time",
2736 Tcl_NewLongObj(fileinfoPtr->time),0);
2738 Tcl_SetVar2Ex(curlData->interp,curlData->chunkBgnVar,"perm",
2739 Tcl_NewIntObj(fileinfoPtr->perm),0);
2741 Tcl_SetVar2Ex(curlData->interp,curlData->chunkBgnVar,"uid",
2742 Tcl_NewIntObj(fileinfoPtr->uid),0);
2743 Tcl_SetVar2Ex(curlData->interp,curlData->chunkBgnVar,"gid",
2744 Tcl_NewIntObj(fileinfoPtr->gid),0);
2745 Tcl_SetVar2Ex(curlData->interp,curlData->chunkBgnVar,"size",
2746 Tcl_NewLongObj(fileinfoPtr->size),0);
2747 Tcl_SetVar2Ex(curlData->interp,curlData->chunkBgnVar,"hardlinks",
2748 Tcl_NewIntObj(fileinfoPtr->hardlinks),0);
2749 Tcl_SetVar2Ex(curlData->interp,curlData->chunkBgnVar,"flags",
2750 Tcl_NewIntObj(fileinfoPtr->flags),0);
2752 snprintf(tclCommand,300,"%s %d",curlData->chunkBgnProc,remains);
2753 tclProcPtr=Tcl_NewStringObj(tclCommand,-1);
2755 if (Tcl_EvalObjEx(curlData->interp,tclProcPtr,TCL_EVAL_GLOBAL)!=TCL_OK) {
2756 return CURL_CHUNK_BGN_FUNC_FAIL;
2759 if (Tcl_GetIntFromObj(curlData->interp,Tcl_GetObjResult(curlData->interp),&i)!=TCL_OK) {
2760 return CURL_CHUNK_BGN_FUNC_FAIL;
2764 return CURL_CHUNK_BGN_FUNC_OK;
2766 return CURL_CHUNK_BGN_FUNC_SKIP;
2768 return CURL_CHUNK_BGN_FUNC_FAIL;
2772 *----------------------------------------------------------------------
2774 * curlChunkEndProcInvoke --
2776 * This is the function that will be invoked every time a file has
2777 * been downloaded or skipped, it does little more than called the
2781 * curlData: A pointer to the curlData structure for the transfer.
2784 *-----------------------------------------------------------------------
2787 curlChunkEndProcInvoke (void *curlDataPtr) {
2789 struct curlObjData *curlData=(struct curlObjData *)curlDataPtr;
2790 Tcl_Obj *tclProcPtr;
2791 char tclCommand[300];
2794 snprintf(tclCommand,300,"%s",curlData->chunkEndProc);
2795 tclProcPtr=Tcl_NewStringObj(tclCommand,-1);
2797 if (Tcl_EvalObjEx(curlData->interp,tclProcPtr,TCL_EVAL_GLOBAL)!=TCL_OK) {
2798 return CURL_CHUNK_END_FUNC_FAIL;
2801 if (Tcl_GetIntFromObj(curlData->interp,Tcl_GetObjResult(curlData->interp),&i)!=TCL_OK) {
2802 return CURL_CHUNK_END_FUNC_FAIL;
2805 return CURL_CHUNK_BGN_FUNC_FAIL;
2807 return CURL_CHUNK_END_FUNC_OK;
2811 *----------------------------------------------------------------------
2813 * curlfnmatchProcInvoke --
2815 * This is the function that will be invoked to tell whether a filename
2816 * matches a pattern when doing a 'wildcard' download. It invokes a Tcl
2817 * proc to do the actual work.
2820 * curlData: A pointer to the curlData structure for the transfer.
2821 * pattern: The pattern to match.
2822 * filename: The file name to be matched.
2823 *-----------------------------------------------------------------------
2825 int curlfnmatchProcInvoke(void *curlDataPtr, const char *pattern, const char *filename) {
2827 struct curlObjData *curlData=(struct curlObjData *)curlDataPtr;
2828 Tcl_Obj *tclProcPtr;
2829 char tclCommand[500];
2832 snprintf(tclCommand,500,"%s %s %s",curlData->fnmatchProc,pattern,filename);
2833 tclProcPtr=Tcl_NewStringObj(tclCommand,-1);
2835 if (Tcl_EvalObjEx(curlData->interp,tclProcPtr,TCL_EVAL_GLOBAL)!=TCL_OK) {
2836 return CURL_FNMATCHFUNC_FAIL;
2839 if (Tcl_GetIntFromObj(curlData->interp,Tcl_GetObjResult(curlData->interp),&i)!=TCL_OK) {
2840 return CURL_FNMATCHFUNC_FAIL;
2844 return CURL_FNMATCHFUNC_MATCH;
2846 return CURL_FNMATCHFUNC_NOMATCH;
2848 return CURL_FNMATCHFUNC_FAIL;
2852 *----------------------------------------------------------------------
2854 * curlshkeyextract --
2856 * Out of one of libcurl's ssh key struct, this function will return a
2857 * Tcl_Obj with a list, the first element is the type ok key, the second
2861 * interp: The interp need to deal with the objects.
2862 * key: a curl_khkey struct with the key.
2865 * The object with the list.
2866 *-----------------------------------------------------------------------
2869 curlsshkeyextract(Tcl_Interp *interp,const struct curl_khkey *key) {
2873 keyObjPtr=Tcl_NewListObj(0,(Tcl_Obj **)NULL);
2875 switch(key->keytype) {
2876 case CURLKHTYPE_RSA1:
2877 Tcl_ListObjAppendElement(interp,keyObjPtr,Tcl_NewStringObj("rsa1",-1));
2879 case CURLKHTYPE_RSA:
2880 Tcl_ListObjAppendElement(interp,keyObjPtr,Tcl_NewStringObj("rsa",-1));
2882 case CURLKHTYPE_DSS:
2883 Tcl_ListObjAppendElement(interp,keyObjPtr,Tcl_NewStringObj("dss",-1));
2886 Tcl_ListObjAppendElement(interp,keyObjPtr,Tcl_NewStringObj("unknnown",-1));
2889 Tcl_ListObjAppendElement(interp,keyObjPtr,Tcl_NewStringObj(key->key,-1));
2895 *----------------------------------------------------------------------
2897 * curlshkeycallback --
2899 * This is the function that will be invoked as a callback when the user
2900 * wants to invoke a Tcl procedure to decide about this new ssh host
2903 * curl: curl's easy handle for the connection.
2904 * knownkey: The key from the hosts_file.
2905 * foundkey: The key from the remote site.
2906 * match: What libcurl thinks about how they match
2907 * curlDataPtr: Points to the structure with all the TclCurl data
2908 * for the connection.
2911 * A libcurl return code so that libcurl knows what to do.
2912 *-----------------------------------------------------------------------
2915 curlsshkeycallback(CURL *curl ,const struct curl_khkey *knownkey,
2916 const struct curl_khkey *foundkey, enum curl_khmatch match,void *curlDataPtr) {
2918 struct curlObjData *tclcurlDataPtr=(struct curlObjData *)curlDataPtr;
2922 Tcl_Obj *returnObjPtr;
2926 interp=tclcurlDataPtr->interp;
2928 objv[0]=Tcl_NewStringObj(tclcurlDataPtr->sshkeycallProc,-1);
2929 objv[1]=curlsshkeyextract(interp,knownkey);
2930 objv[2]=curlsshkeyextract(interp,foundkey);
2933 case CURLKHMATCH_OK:
2934 objv[3]=Tcl_NewStringObj("match",-1);
2936 case CURLKHMATCH_MISMATCH:
2937 objv[3]=Tcl_NewStringObj("mismatch",-1);
2939 case CURLKHMATCH_MISSING:
2940 objv[3]=Tcl_NewStringObj("missing",-1);
2942 case CURLKHMATCH_LAST:
2943 objv[3]=Tcl_NewStringObj("error",-1);
2946 if (Tcl_EvalObjv(interp,4,objv,TCL_EVAL_GLOBAL)!=TCL_OK) {return CURLKHSTAT_REJECT;}
2948 returnObjPtr=Tcl_GetObjResult(interp);
2950 if (Tcl_GetIntFromObj(interp,returnObjPtr,&action)!=TCL_OK) {return CURLKHSTAT_REJECT;}
2954 return CURLKHSTAT_FINE_ADD_TO_FILE;
2956 return CURLKHSTAT_FINE;
2958 return CURLKHSTAT_REJECT;
2960 return CURLKHSTAT_DEFER;
2962 return CURLKHSTAT_REJECT;
2966 *----------------------------------------------------------------------
2968 * curlDebugProcInvoke --
2970 * This is the function that will be invoked as a callback when the user
2971 * wants to invoke a Tcl procedure to write the debug data produce by
2972 * the verbose option.
2975 * curlHandle: A pointer to the handle for the transfer.
2976 * infoType: Integer with the type of data.
2977 * dataPtr: the data passed to the procedure.
2978 * curlDataPtr: ointer to the curlData structure for the transfer.
2981 * The number of bytes actually written or -1 in case of error, in
2982 * which case 'libcurl' will abort the transfer.
2983 *-----------------------------------------------------------------------
2986 curlDebugProcInvoke(CURL *curlHandle, curl_infotype infoType,
2987 char * dataPtr, size_t size, void *curlDataPtr) {
2988 struct curlObjData *curlData=(struct curlObjData *)curlDataPtr;
2989 Tcl_Obj *tclProcPtr;
2991 char tclCommand[300];
2993 snprintf(tclCommand,300,"%s %d %d",curlData->debugProc,infoType,size);
2994 tclProcPtr=Tcl_NewStringObj(tclCommand,-1);
2996 objv[0]=Tcl_NewStringObj(curlData->debugProc,-1);
2997 objv[1]=Tcl_NewIntObj(infoType);
2998 objv[2]=Tcl_NewByteArrayObj((CONST unsigned char *)dataPtr,size);
3000 if (curlData->cancelTransVarName) {
3001 if (curlData->cancelTrans) {
3002 curlData->cancelTrans=0;
3007 Tcl_EvalObjv(curlData->interp,3,objv,TCL_EVAL_GLOBAL);
3013 *----------------------------------------------------------------------
3017 * Invokes the 'curl_easy_getinfo' function in libcurl.
3022 * 0 if all went well.
3023 * The CURLcode for the error.
3024 *----------------------------------------------------------------------
3027 curlGetInfo(Tcl_Interp *interp,CURL *curlHandle,int tableIndex) {
3030 double doubleNumber;
3031 struct curl_slist *slistPtr;
3032 struct curl_certinfo *certinfoPtr=NULL;
3037 Tcl_Obj *resultObjPtr;
3039 switch(tableIndex) {
3041 exitCode=curl_easy_getinfo(curlHandle,CURLINFO_EFFECTIVE_URL,&charPtr);
3045 resultObjPtr=Tcl_NewStringObj(charPtr,-1);
3046 Tcl_SetObjResult(interp,resultObjPtr);
3050 exitCode=curl_easy_getinfo(curlHandle,CURLINFO_RESPONSE_CODE,&longNumber);
3054 resultObjPtr=Tcl_NewLongObj(longNumber);
3055 Tcl_SetObjResult(interp,resultObjPtr);
3058 exitCode=curl_easy_getinfo(curlHandle,CURLINFO_FILETIME,&longNumber);
3062 resultObjPtr=Tcl_NewLongObj(longNumber);
3063 Tcl_SetObjResult(interp,resultObjPtr);
3066 exitCode=curl_easy_getinfo(curlHandle,CURLINFO_TOTAL_TIME,&doubleNumber);
3070 resultObjPtr=Tcl_NewDoubleObj(doubleNumber);
3071 Tcl_SetObjResult(interp,resultObjPtr);
3074 exitCode=curl_easy_getinfo(curlHandle,CURLINFO_NAMELOOKUP_TIME,
3079 resultObjPtr=Tcl_NewDoubleObj(doubleNumber);
3080 Tcl_SetObjResult(interp,resultObjPtr);
3083 exitCode=curl_easy_getinfo(curlHandle,CURLINFO_CONNECT_TIME,
3088 resultObjPtr=Tcl_NewDoubleObj(doubleNumber);
3089 Tcl_SetObjResult(interp,resultObjPtr);
3092 exitCode=curl_easy_getinfo(curlHandle,CURLINFO_PRETRANSFER_TIME,
3097 resultObjPtr=Tcl_NewDoubleObj(doubleNumber);
3098 Tcl_SetObjResult(interp,resultObjPtr);
3101 exitCode=curl_easy_getinfo(curlHandle,CURLINFO_SIZE_UPLOAD,
3106 resultObjPtr=Tcl_NewDoubleObj(doubleNumber);
3107 Tcl_SetObjResult(interp,resultObjPtr);
3110 exitCode=curl_easy_getinfo(curlHandle,CURLINFO_SIZE_DOWNLOAD,
3115 resultObjPtr=Tcl_NewDoubleObj(doubleNumber);
3116 Tcl_SetObjResult(interp,resultObjPtr);
3119 exitCode=curl_easy_getinfo(curlHandle,CURLINFO_SPEED_DOWNLOAD,
3124 resultObjPtr=Tcl_NewDoubleObj(doubleNumber);
3125 Tcl_SetObjResult(interp,resultObjPtr);
3128 exitCode=curl_easy_getinfo(curlHandle,CURLINFO_SPEED_UPLOAD,
3133 resultObjPtr=Tcl_NewDoubleObj(doubleNumber);
3134 Tcl_SetObjResult(interp,resultObjPtr);
3137 exitCode=curl_easy_getinfo(curlHandle,CURLINFO_HEADER_SIZE,
3142 resultObjPtr=Tcl_NewLongObj(longNumber);
3143 Tcl_SetObjResult(interp,resultObjPtr);
3146 exitCode=curl_easy_getinfo(curlHandle,CURLINFO_REQUEST_SIZE,
3151 resultObjPtr=Tcl_NewLongObj(longNumber);
3152 Tcl_SetObjResult(interp,resultObjPtr);
3155 exitCode=curl_easy_getinfo(curlHandle,CURLINFO_SSL_VERIFYRESULT,
3160 resultObjPtr=Tcl_NewLongObj(longNumber);
3161 Tcl_SetObjResult(interp,resultObjPtr);
3164 exitCode=curl_easy_getinfo(curlHandle,CURLINFO_CONTENT_LENGTH_DOWNLOAD,
3169 resultObjPtr=Tcl_NewDoubleObj(doubleNumber);
3170 Tcl_SetObjResult(interp,resultObjPtr);
3173 exitCode=curl_easy_getinfo(curlHandle,CURLINFO_CONTENT_LENGTH_UPLOAD,
3178 resultObjPtr=Tcl_NewDoubleObj(doubleNumber);
3179 Tcl_SetObjResult(interp,resultObjPtr);
3182 exitCode=curl_easy_getinfo(curlHandle,CURLINFO_STARTTRANSFER_TIME,&doubleNumber);
3186 resultObjPtr=Tcl_NewDoubleObj(doubleNumber);
3187 Tcl_SetObjResult(interp,resultObjPtr);
3190 exitCode=curl_easy_getinfo(curlHandle,CURLINFO_CONTENT_TYPE,&charPtr);
3194 resultObjPtr=Tcl_NewStringObj(charPtr,-1);
3195 Tcl_SetObjResult(interp,resultObjPtr);
3198 exitCode=curl_easy_getinfo(curlHandle,CURLINFO_REDIRECT_TIME,&doubleNumber);
3202 resultObjPtr=Tcl_NewDoubleObj(doubleNumber);
3203 Tcl_SetObjResult(interp,resultObjPtr);
3206 exitCode=curl_easy_getinfo(curlHandle,CURLINFO_REDIRECT_COUNT,&longNumber);
3210 resultObjPtr=Tcl_NewLongObj(longNumber);
3211 Tcl_SetObjResult(interp,resultObjPtr);
3215 if (tableIndex==21) {
3216 exitCode=curl_easy_getinfo(curlHandle,CURLINFO_HTTPAUTH_AVAIL,&longNumber);
3218 exitCode=curl_easy_getinfo(curlHandle,CURLINFO_PROXYAUTH_AVAIL,&longNumber);
3223 resultObjPtr=Tcl_NewListObj(0,(Tcl_Obj **)NULL);
3224 if (longNumber&CURLAUTH_BASIC) {
3225 Tcl_ListObjAppendElement(interp,resultObjPtr
3226 ,Tcl_NewStringObj("basic",-1));
3228 if (longNumber&CURLAUTH_DIGEST) {
3229 Tcl_ListObjAppendElement(interp,resultObjPtr
3230 ,Tcl_NewStringObj("digest",-1));
3232 if (longNumber&CURLAUTH_GSSNEGOTIATE) {
3233 Tcl_ListObjAppendElement(interp,resultObjPtr
3234 ,Tcl_NewStringObj("gssnegotiate",-1));
3236 if (longNumber&CURLAUTH_NTLM) {
3237 Tcl_ListObjAppendElement(interp,resultObjPtr
3238 ,Tcl_NewStringObj("NTLM",-1));
3240 Tcl_SetObjResult(interp,resultObjPtr);
3243 exitCode=curl_easy_getinfo(curlHandle,CURLINFO_OS_ERRNO,&longNumber);
3247 resultObjPtr=Tcl_NewLongObj(longNumber);
3248 Tcl_SetObjResult(interp,resultObjPtr);
3251 exitCode=curl_easy_getinfo(curlHandle,CURLINFO_NUM_CONNECTS,&longNumber);
3255 resultObjPtr=Tcl_NewLongObj(longNumber);
3256 Tcl_SetObjResult(interp,resultObjPtr);
3259 exitCode=curl_easy_getinfo \
3260 (curlHandle,CURLINFO_SSL_ENGINES,&slistPtr);
3264 resultObjPtr=Tcl_NewListObj(0,(Tcl_Obj **)NULL);
3265 while(slistPtr!=NULL) {
3266 Tcl_ListObjAppendElement(interp,resultObjPtr
3267 ,Tcl_NewStringObj(slistPtr->data,-1));
3268 slistPtr=slistPtr->next;
3270 curl_slist_free_all(slistPtr);
3271 Tcl_SetObjResult(interp,resultObjPtr);
3274 exitCode=curl_easy_getinfo \
3275 (curlHandle,CURLINFO_HTTP_CONNECTCODE,&longNumber);
3279 resultObjPtr=Tcl_NewLongObj(longNumber);
3280 Tcl_SetObjResult(interp,resultObjPtr);
3283 exitCode=curl_easy_getinfo \
3284 (curlHandle,CURLINFO_COOKIELIST,&slistPtr);
3288 resultObjPtr=Tcl_NewListObj(0,(Tcl_Obj **)NULL);
3289 while(slistPtr!=NULL) {
3290 Tcl_ListObjAppendElement(interp,resultObjPtr
3291 ,Tcl_NewStringObj(slistPtr->data,-1));
3292 slistPtr=slistPtr->next;
3294 curl_slist_free_all(slistPtr);
3295 Tcl_SetObjResult(interp,resultObjPtr);
3298 exitCode=curl_easy_getinfo(curlHandle,CURLINFO_FTP_ENTRY_PATH,&charPtr);
3302 resultObjPtr=Tcl_NewStringObj(charPtr,-1);
3303 Tcl_SetObjResult(interp,resultObjPtr);
3306 exitCode=curl_easy_getinfo(curlHandle,CURLINFO_REDIRECT_URL,&charPtr);
3310 resultObjPtr=Tcl_NewStringObj(charPtr,-1);
3311 Tcl_SetObjResult(interp,resultObjPtr);
3314 exitCode=curl_easy_getinfo(curlHandle,CURLINFO_PRIMARY_IP,&charPtr);
3318 resultObjPtr=Tcl_NewStringObj(charPtr,-1);
3319 Tcl_SetObjResult(interp,resultObjPtr);
3322 exitCode=curl_easy_getinfo(curlHandle,CURLINFO_APPCONNECT_TIME,&doubleNumber);
3326 resultObjPtr=Tcl_NewDoubleObj(doubleNumber);
3327 Tcl_SetObjResult(interp,resultObjPtr);
3330 exitCode=curl_easy_getinfo(curlHandle,CURLINFO_CERTINFO,certinfoPtr);
3334 charPtr=(char *)Tcl_Alloc(3);
3335 sprintf(charPtr,"%d",certinfoPtr->num_of_certs);
3336 resultObjPtr=Tcl_NewListObj(0,(Tcl_Obj **)NULL);
3337 Tcl_ListObjAppendElement(interp,resultObjPtr,Tcl_NewStringObj(charPtr,-1));
3339 for(i=0; i < certinfoPtr->num_of_certs; i++) {
3340 for(slistPtr = certinfoPtr->certinfo[i]; slistPtr; slistPtr=slistPtr->next) {
3341 Tcl_ListObjAppendElement(interp,resultObjPtr,Tcl_NewStringObj(slistPtr->data,-1));
3344 Tcl_SetObjResult(interp,resultObjPtr);
3347 exitCode=curl_easy_getinfo \
3348 (curlHandle,CURLINFO_CONDITION_UNMET,&longNumber);
3352 resultObjPtr=Tcl_NewLongObj(longNumber);
3353 Tcl_SetObjResult(interp,resultObjPtr);
3356 exitCode=curl_easy_getinfo \
3357 (curlHandle,CURLINFO_PRIMARY_PORT,&longNumber);
3361 resultObjPtr=Tcl_NewLongObj(longNumber);
3362 Tcl_SetObjResult(interp,resultObjPtr);
3365 exitCode=curl_easy_getinfo(curlHandle,CURLINFO_LOCAL_IP,&charPtr);
3369 resultObjPtr=Tcl_NewStringObj(charPtr,-1);
3370 Tcl_SetObjResult(interp,resultObjPtr);
3373 exitCode=curl_easy_getinfo \
3374 (curlHandle,CURLINFO_LOCAL_PORT,&longNumber);
3378 resultObjPtr=Tcl_NewLongObj(longNumber);
3379 Tcl_SetObjResult(interp,resultObjPtr);
3386 *----------------------------------------------------------------------
3390 * Frees the space taken by a curlObjData struct either because we are
3391 * deleting the handle or reseting it.
3394 * interp: Pointer to the interpreter we are using.
3395 * curlHandle: the curl handle for which the option is set.
3396 * objc and objv: The usual in Tcl.
3399 * A standard Tcl result.
3400 *----------------------------------------------------------------------
3403 curlFreeSpace(struct curlObjData *curlData) {
3405 curl_slist_free_all(curlData->headerList);
3406 curl_slist_free_all(curlData->quote);
3407 curl_slist_free_all(curlData->prequote);
3408 curl_slist_free_all(curlData->postquote);
3410 Tcl_Free(curlData->outFile);
3411 Tcl_Free(curlData->inFile);
3412 Tcl_Free(curlData->proxy);
3413 Tcl_Free(curlData->errorBuffer);
3414 Tcl_Free(curlData->errorBufferName);
3415 Tcl_Free(curlData->errorBufferKey);
3416 Tcl_Free(curlData->stderrFile);
3417 Tcl_Free(curlData->randomFile);
3418 Tcl_Free(curlData->headerVar);
3419 Tcl_Free(curlData->bodyVarName);
3420 if (curlData->bodyVar.memory) {
3421 Tcl_Free(curlData->bodyVar.memory);
3423 Tcl_Free(curlData->progressProc);
3424 if (curlData->cancelTransVarName) {
3425 Tcl_UnlinkVar(curlData->interp,curlData->cancelTransVarName);
3426 Tcl_Free(curlData->cancelTransVarName);
3428 Tcl_Free(curlData->writeProc);
3429 Tcl_Free(curlData->readProc);
3430 Tcl_Free(curlData->debugProc);
3431 curl_slist_free_all(curlData->http200aliases);
3432 Tcl_Free(curlData->sshkeycallProc);
3433 curl_slist_free_all(curlData->mailrcpt);
3434 Tcl_Free(curlData->chunkBgnProc);
3435 Tcl_Free(curlData->chunkBgnVar);
3436 Tcl_Free(curlData->chunkEndProc);
3437 Tcl_Free(curlData->fnmatchProc);
3438 curl_slist_free_all(curlData->resolve);
3439 curl_slist_free_all(curlData->telnetoptions);
3441 Tcl_Free(curlData->command);
3445 *----------------------------------------------------------------------
3449 * This function is invoked by the 'duphandle' command, it will
3450 * create a duplicate of the given handle.
3453 * The stantard parameters for Tcl commands
3456 * A standard Tcl result.
3459 * See the user documentation.
3461 *----------------------------------------------------------------------
3464 curlDupHandle(Tcl_Interp *interp, struct curlObjData *curlData,
3465 int objc, Tcl_Obj *CONST objv[]) {
3467 CURL *newCurlHandle;
3469 struct curlObjData *newCurlData;
3472 newCurlHandle=curl_easy_duphandle(curlData->curl);
3473 if (newCurlHandle==NULL) {
3474 result=Tcl_NewStringObj("Couldn't create new handle.",-1);
3475 Tcl_SetObjResult(interp,result);
3479 newCurlData=(struct curlObjData *)Tcl_Alloc(sizeof(struct curlObjData));
3481 curlCopyCurlData(curlData,newCurlData);
3483 handleName=curlCreateObjCmd(interp,newCurlData);
3485 newCurlData->curl=newCurlHandle;
3487 result=Tcl_NewStringObj(handleName,-1);
3488 Tcl_SetObjResult(interp,result);
3489 Tcl_Free(handleName);
3496 *----------------------------------------------------------------------
3498 * curlResetHandle --
3500 * This function is invoked by the 'reset' command, it reset all the
3501 * options in the handle to the state it had when 'init' was invoked.
3504 * The stantard parameters for Tcl commands
3507 * A standard Tcl result.
3510 * See the user documentation.
3512 *----------------------------------------------------------------------
3515 curlResetHandle(Tcl_Interp *interp, struct curlObjData *curlData) {
3516 struct curlObjData *tmpPtr=
3517 (struct curlObjData *)Tcl_Alloc(sizeof(struct curlObjData));
3519 tmpPtr->curl = curlData->curl;
3520 tmpPtr->token = curlData->token;
3521 tmpPtr->shareToken = curlData->shareToken;
3522 tmpPtr->interp = curlData->interp;
3524 curlFreeSpace(curlData);
3525 memset(curlData, 0, sizeof(struct curlObjData));
3527 curlData->curl = tmpPtr->curl;
3528 curlData->token = tmpPtr->token;
3529 curlData->shareToken = tmpPtr->shareToken;
3530 curlData->interp = tmpPtr->interp;
3532 curl_easy_reset(curlData->curl);
3534 Tcl_Free((char *)tmpPtr);
3541 *----------------------------------------------------------------------
3545 * This procedure is invoked to process the "curl::init" Tcl command.
3546 * See the user documentation for details on what it does.
3549 * The stantard parameters for Tcl commands
3552 * A standard Tcl result.
3555 * See the user documentation.
3557 *----------------------------------------------------------------------
3560 curlVersion (ClientData clientData, Tcl_Interp *interp,
3561 int objc,Tcl_Obj *CONST objv[]) {
3563 Tcl_Obj *versionPtr;
3564 char tclversion[200];
3566 sprintf(tclversion,"TclCurl Version %s (%s)",TclCurlVersion,
3568 versionPtr=Tcl_NewStringObj(tclversion,-1);
3569 Tcl_SetObjResult(interp,versionPtr);
3575 *----------------------------------------------------------------------
3579 * This function is invoked to process the "curl::escape" Tcl command.
3580 * See the user documentation for details on what it does.
3584 * The stantard parameters for Tcl commands
3587 * A standard Tcl result.
3590 * See the user documentation.
3592 *----------------------------------------------------------------------
3595 curlEscape(ClientData clientData, Tcl_Interp *interp,
3596 int objc,Tcl_Obj *CONST objv[]) {
3601 escapedStr=curl_easy_escape(NULL,Tcl_GetString(objv[1]),0);
3604 resultObj=Tcl_NewStringObj("curl::escape bad parameter",-1);
3605 Tcl_SetObjResult(interp,resultObj);
3608 resultObj=Tcl_NewStringObj(escapedStr,-1);
3609 Tcl_SetObjResult(interp,resultObj);
3610 curl_free(escapedStr);
3616 *----------------------------------------------------------------------
3620 * This function is invoked to process the "curl::Unescape" Tcl command.
3621 * See the user documentation for details on what it does.
3625 * The stantard parameters for Tcl commands
3628 * A standard Tcl result.
3631 * See the user documentation.
3633 *----------------------------------------------------------------------
3636 curlUnescape(ClientData clientData, Tcl_Interp *interp,
3637 int objc,Tcl_Obj *CONST objv[]) {
3642 unescapedStr=curl_easy_unescape(NULL,Tcl_GetString(objv[1]),0,NULL);
3644 resultObj=Tcl_NewStringObj("curl::unescape bad parameter",-1);
3645 Tcl_SetObjResult(interp,resultObj);
3648 resultObj=Tcl_NewStringObj(unescapedStr,-1);
3649 Tcl_SetObjResult(interp,resultObj);
3650 curl_free(unescapedStr);
3656 *----------------------------------------------------------------------
3658 * curlVersionInfo --
3660 * This function invokes 'curl_version_info' to query how 'libcurl' was
3664 * The standard parameters for Tcl commands, but nothing is used.
3667 * A standard Tcl result.
3670 * See the user documentation.
3672 *----------------------------------------------------------------------
3675 curlVersionInfo (ClientData clientData, Tcl_Interp *interp,
3676 int objc,Tcl_Obj *CONST objv[]) {
3680 curl_version_info_data *infoPtr;
3681 Tcl_Obj *resultObjPtr=NULL;
3685 resultObjPtr=Tcl_NewStringObj("usage: curl::versioninfo -option",-1);
3686 Tcl_SetObjResult(interp,resultObjPtr);
3690 if (Tcl_GetIndexFromObj(interp, objv[1], versionInfoTable, "option",
3691 TCL_EXACT,&tableIndex)==TCL_ERROR) {
3695 infoPtr=curl_version_info(CURLVERSION_NOW);
3697 switch(tableIndex) {
3699 resultObjPtr=Tcl_NewStringObj(infoPtr->version,-1);
3702 sprintf(tmp,"%X",infoPtr->version_num);
3703 resultObjPtr=Tcl_NewStringObj(tmp,-1);
3706 resultObjPtr=Tcl_NewStringObj(infoPtr->host,-1);
3709 resultObjPtr=Tcl_NewListObj(0,(Tcl_Obj **)NULL);
3710 if (infoPtr->features&CURL_VERSION_IPV6) {
3711 Tcl_ListObjAppendElement(interp,resultObjPtr
3712 ,Tcl_NewStringObj("IPV6",-1));
3714 if (infoPtr->features&CURL_VERSION_KERBEROS4) {
3715 Tcl_ListObjAppendElement(interp,resultObjPtr
3716 ,Tcl_NewStringObj("KERBEROS4",-1));
3718 if (infoPtr->features&CURL_VERSION_SSL) {
3719 Tcl_ListObjAppendElement(interp,resultObjPtr
3720 ,Tcl_NewStringObj("SSL",-1));
3722 if (infoPtr->features&CURL_VERSION_LIBZ) {
3723 Tcl_ListObjAppendElement(interp,resultObjPtr
3724 ,Tcl_NewStringObj("LIBZ",-1));
3726 if (infoPtr->features&CURL_VERSION_NTLM) {
3727 Tcl_ListObjAppendElement(interp,resultObjPtr
3728 ,Tcl_NewStringObj("NTLM",-1));
3730 if (infoPtr->features&CURL_VERSION_GSSNEGOTIATE) {
3731 Tcl_ListObjAppendElement(interp,resultObjPtr
3732 ,Tcl_NewStringObj("GSSNEGOTIATE",-1));
3734 if (infoPtr->features&CURL_VERSION_DEBUG) {
3735 Tcl_ListObjAppendElement(interp,resultObjPtr
3736 ,Tcl_NewStringObj("DEBUG",-1));
3738 if (infoPtr->features&CURL_VERSION_ASYNCHDNS) {
3739 Tcl_ListObjAppendElement(interp,resultObjPtr
3740 ,Tcl_NewStringObj("ASYNCHDNS",-1));
3742 if (infoPtr->features&CURL_VERSION_SPNEGO) {
3743 Tcl_ListObjAppendElement(interp,resultObjPtr
3744 ,Tcl_NewStringObj("SPNEGO",-1));
3746 if (infoPtr->features&CURL_VERSION_LARGEFILE) {
3747 Tcl_ListObjAppendElement(interp,resultObjPtr
3748 ,Tcl_NewStringObj("LARGEFILE",-1));
3750 if (infoPtr->features&CURL_VERSION_IDN) {
3751 Tcl_ListObjAppendElement(interp,resultObjPtr
3752 ,Tcl_NewStringObj("IDN",-1));
3754 if (infoPtr->features&CURL_VERSION_SSPI) {
3755 Tcl_ListObjAppendElement(interp,resultObjPtr
3756 ,Tcl_NewStringObj("SSPI",-1));
3759 if (infoPtr->features&CURL_VERSION_CONV) {
3760 Tcl_ListObjAppendElement(interp,resultObjPtr
3761 ,Tcl_NewStringObj("CONV",-1));
3764 resultObjPtr=Tcl_NewStringObj(infoPtr->ssl_version,-1);
3767 resultObjPtr=Tcl_NewLongObj(infoPtr->ssl_version_num);
3770 resultObjPtr=Tcl_NewStringObj(infoPtr->libz_version,-1);
3773 resultObjPtr=Tcl_NewListObj(0,(Tcl_Obj **)NULL);
3775 if (infoPtr->protocols[i]!=NULL) {
3776 Tcl_ListObjAppendElement(interp,resultObjPtr
3777 ,Tcl_NewStringObj(infoPtr->protocols[i],-1));
3784 Tcl_SetObjResult(interp,resultObjPtr);
3790 *----------------------------------------------------------------------
3792 * curlCopyCurlData --
3794 * This function copies the contents of a curlData struct into another.
3797 * curlDataOld: The original one.
3798 * curlDataNew: The new one
3801 * A standard Tcl result.
3804 * See the user documentation.
3806 *----------------------------------------------------------------------
3809 curlCopyCurlData (struct curlObjData *curlDataOld,
3810 struct curlObjData *curlDataNew) {
3812 /* This takes care of the int and long values */
3813 memcpy(curlDataNew, curlDataOld, sizeof(struct curlObjData));
3815 /* Some of the data doesn't get copied */
3817 curlDataNew->headerList=NULL;
3818 curlDataNew->quote=NULL;
3819 curlDataNew->prequote=NULL;
3820 curlDataNew->postquote=NULL;
3821 curlDataNew->formArray=NULL;
3822 curlDataNew->postListFirst=NULL;
3823 curlDataNew->postListLast=NULL;
3824 curlDataNew->formArray=NULL;
3825 curlDataNew->outHandle=NULL;
3826 curlDataNew->outFlag=0;
3827 curlDataNew->inHandle=NULL;
3828 curlDataNew->inFlag=0;
3829 curlDataNew->headerHandle=NULL;
3830 curlDataNew->headerFlag=0;
3831 curlDataNew->stderrHandle=NULL;
3832 curlDataNew->stderrFlag=0;
3833 curlDataNew->http200aliases=NULL;
3834 curlDataNew->mailrcpt=NULL;
3835 curlDataNew->resolve=NULL;
3836 curlDataNew->telnetoptions=NULL;
3838 /* The strings need a special treatment. */
3840 curlDataNew->outFile=curlstrdup(curlDataOld->outFile);
3841 curlDataNew->inFile=curlstrdup(curlDataOld->inFile);
3842 curlDataNew->proxy=curlstrdup(curlDataOld->proxy);
3843 curlDataNew->errorBuffer=curlstrdup(curlDataOld->errorBuffer);
3844 curlDataNew->errorBufferName=curlstrdup(curlDataOld->errorBufferName);
3845 curlDataNew->errorBufferKey=curlstrdup(curlDataOld->errorBufferKey);
3846 curlDataNew->headerFile=curlstrdup(curlDataOld->headerFile);
3847 curlDataNew->stderrFile=curlstrdup(curlDataOld->stderrFile);
3848 curlDataNew->randomFile=curlstrdup(curlDataOld->randomFile);
3849 curlDataNew->headerVar=curlstrdup(curlDataOld->headerVar);
3850 curlDataNew->bodyVarName=curlstrdup(curlDataOld->bodyVarName);
3851 curlDataNew->progressProc=curlstrdup(curlDataOld->progressProc);
3852 curlDataNew->cancelTransVarName=curlstrdup(curlDataOld->cancelTransVarName);
3853 curlDataNew->writeProc=curlstrdup(curlDataOld->writeProc);
3854 curlDataNew->readProc=curlstrdup(curlDataOld->readProc);
3855 curlDataNew->debugProc=curlstrdup(curlDataOld->debugProc);
3856 curlDataNew->command=curlstrdup(curlDataOld->command);
3857 curlDataNew->sshkeycallProc=curlstrdup(curlDataOld->sshkeycallProc);
3858 curlDataNew->chunkBgnProc=curlstrdup(curlDataOld->chunkBgnProc);
3859 curlDataNew->chunkBgnVar=curlstrdup(curlDataOld->chunkBgnVar);
3860 curlDataNew->chunkEndProc=curlstrdup(curlDataOld->chunkEndProc);
3861 curlDataNew->fnmatchProc=curlstrdup(curlDataOld->fnmatchProc);
3863 curlDataNew->bodyVar.memory=(char *)Tcl_Alloc(curlDataOld->bodyVar.size);
3864 memcpy(curlDataNew->bodyVar.memory,curlDataOld->bodyVar.memory
3865 ,curlDataOld->bodyVar.size);
3866 curlDataNew->bodyVar.size=curlDataOld->bodyVar.size;
3871 /*----------------------------------------------------------------------
3875 * Before doing a transfer with the easy interface or adding an easy
3876 * handle to a multi one, this function takes care of opening all
3877 * necessary files for the transfer.
3880 * curlData: The pointer to the struct with the transfer data.
3883 * '0' all went well, '1' in case of error.
3884 *----------------------------------------------------------------------
3887 curlOpenFiles(Tcl_Interp *interp,struct curlObjData *curlData) {
3889 if (curlData->outFlag) {
3890 if (curlOpenFile(interp,curlData->outFile,&(curlData->outHandle),1,
3891 curlData->transferText)) {
3894 curl_easy_setopt(curlData->curl,CURLOPT_WRITEDATA,curlData->outHandle);
3896 if (curlData->inFlag) {
3897 if (curlOpenFile(interp,curlData->inFile,&(curlData->inHandle),0,
3898 curlData->transferText)) {
3901 curl_easy_setopt(curlData->curl,CURLOPT_READDATA,curlData->inHandle);
3902 if (curlData->anyAuthFlag) {
3903 curl_easy_setopt(curlData->curl, CURLOPT_SEEKFUNCTION, curlseek);
3904 curl_easy_setopt(curlData->curl, CURLOPT_SEEKDATA, curlData->inHandle);
3907 if (curlData->headerFlag) {
3908 if (curlOpenFile(interp,curlData->headerFile,&(curlData->headerHandle),1,1)) {
3911 curl_easy_setopt(curlData->curl,CURLOPT_HEADERDATA,curlData->headerHandle);
3913 if (curlData->stderrFlag) {
3914 if (curlOpenFile(interp,curlData->stderrFile,&(curlData->stderrHandle),1,1)) {
3917 curl_easy_setopt(curlData->curl,CURLOPT_STDERR,curlData->stderrHandle);
3922 /*----------------------------------------------------------------------
3926 * Closes the files opened during a transfer.
3929 * curlData: The pointer to the struct with the transfer data.
3931 *----------------------------------------------------------------------
3934 curlCloseFiles(struct curlObjData *curlData) {
3935 if (curlData->outHandle!=NULL) {
3936 fclose(curlData->outHandle);
3937 curlData->outHandle=NULL;
3939 if (curlData->inHandle!=NULL) {
3940 fclose(curlData->inHandle);
3941 curlData->inHandle=NULL;
3943 if (curlData->headerHandle!=NULL) {
3944 fclose(curlData->headerHandle);
3945 curlData->headerHandle=NULL;
3947 if (curlData->stderrHandle!=NULL) {
3948 fclose(curlData->stderrHandle);
3949 curlData->stderrHandle=NULL;
3953 /*----------------------------------------------------------------------
3957 * Opens a file to be used during a transfer.
3960 * fileName: name of the file.
3961 * handle: the handle for the file
3962 * writing: '0' if reading, '1' if writing.
3963 * text: '0' if binary, '1' if text.
3966 * '0' all went well, '1' in case of error.
3967 *----------------------------------------------------------------------
3970 curlOpenFile(Tcl_Interp *interp,char *fileName, FILE **handle, int writing, int text) {
3971 Tcl_Obj *resultObjPtr;
3974 if (*handle!=NULL) {
3979 *handle=fopen(fileName,"w");
3981 *handle=fopen(fileName,"wb");
3985 *handle=fopen(fileName,"r");
3987 *handle=fopen(fileName,"rb");
3990 if (*handle==NULL) {
3991 snprintf(errorMsg,300,"Couldn't open file %s.",fileName);
3992 resultObjPtr=Tcl_NewStringObj(errorMsg,-1);
3993 Tcl_SetObjResult(interp,resultObjPtr);
3999 /*----------------------------------------------------------------------
4003 * When the user requests the 'any' auth, libcurl may need
4004 * to send the PUT/POST data more than once and thus may need to ask
4005 * the app to "rewind" the read data stream to start.
4007 *----------------------------------------------------------------------
4011 curlseek(void *instream, curl_off_t offset, int origin)
4013 if(-1 == fseek((FILE *)instream, 0, origin)) {
4014 return CURLIOE_FAILRESTART;
4019 /*----------------------------------------------------------------------
4021 * curlSetPostData --
4023 * In case there is going to be a post transfer, this function sets the
4024 * data that is going to be posted.
4027 * interp: Tcl interpreter we are using.
4028 * curlData: A pointer to the struct with the transfer data.
4031 * A standard Tcl result.
4032 *----------------------------------------------------------------------
4035 curlSetPostData(Tcl_Interp *interp,struct curlObjData *curlDataPtr) {
4036 Tcl_Obj *errorMsgObjPtr;
4038 if (curlDataPtr->postListFirst!=NULL) {
4039 if (curl_easy_setopt(curlDataPtr->curl,CURLOPT_HTTPPOST,curlDataPtr->postListFirst)) {
4040 curl_formfree(curlDataPtr->postListFirst);
4041 errorMsgObjPtr=Tcl_NewStringObj("Error setting the data to post",-1);
4042 Tcl_SetObjResult(interp,errorMsgObjPtr);
4049 /*----------------------------------------------------------------------
4051 * curlResetPostData --
4053 * After performing a transfer, this function is invoked to erease the
4057 * curlData: A pointer to the struct with the transfer data.
4058 *----------------------------------------------------------------------
4061 curlResetPostData(struct curlObjData *curlDataPtr) {
4062 struct formArrayStruct *tmpPtr;
4064 if (curlDataPtr->postListFirst) {
4065 curl_formfree(curlDataPtr->postListFirst);
4066 curlDataPtr->postListFirst=NULL;
4067 curlDataPtr->postListLast=NULL;
4068 curl_easy_setopt(curlDataPtr->curl,CURLOPT_HTTPPOST,NULL);
4070 while(curlDataPtr->formArray!=NULL) {
4071 if (curlDataPtr->formArray->formHeaderList!=NULL) {
4072 curl_slist_free_all(curlDataPtr->formArray->formHeaderList);
4073 curlDataPtr->formArray->formHeaderList=NULL;
4075 curlResetFormArray(curlDataPtr->formArray->formArray);
4076 tmpPtr=curlDataPtr->formArray->next;
4077 Tcl_Free((char *)curlDataPtr->formArray);
4078 curlDataPtr->formArray=tmpPtr;
4082 /*----------------------------------------------------------------------
4084 * curlResetFormArray --
4086 * Cleans the contents of the formArray, it is done after a transfer or
4087 * if 'curl_formadd' returns an error.
4090 * formArray: A pointer to the array to clean up.
4091 *----------------------------------------------------------------------
4094 curlResetFormArray(struct curl_forms *formArray) {
4097 for (i=0;formArray[i].option!=CURLFORM_END;i++) {
4098 switch (formArray[i].option) {
4099 case CURLFORM_COPYNAME:
4100 case CURLFORM_COPYCONTENTS:
4102 case CURLFORM_CONTENTTYPE:
4103 case CURLFORM_FILENAME:
4104 case CURLFORM_FILECONTENT:
4105 case CURLFORM_BUFFER:
4106 case CURLFORM_BUFFERPTR:
4107 Tcl_Free((char *)(formArray[i].value));
4113 Tcl_Free((char *)formArray);
4116 /*----------------------------------------------------------------------
4118 * curlSetBodyVarName --
4120 * After performing a transfer, this function is invoked to set the
4121 * body of the recieved transfer into a user defined Tcl variable.
4124 * interp: The Tcl interpreter we are using.
4125 * curlData: A pointer to the struct with the transfer data.
4126 *----------------------------------------------------------------------
4129 curlSetBodyVarName(Tcl_Interp *interp,struct curlObjData *curlDataPtr) {
4130 Tcl_Obj *bodyVarNameObjPtr, *bodyVarObjPtr;
4132 bodyVarNameObjPtr=Tcl_NewStringObj(curlDataPtr->bodyVarName,-1);
4133 bodyVarObjPtr=Tcl_NewByteArrayObj((unsigned char *)curlDataPtr->bodyVar.memory,
4134 curlDataPtr->bodyVar.size);
4136 Tcl_ObjSetVar2(interp,bodyVarNameObjPtr,(Tcl_Obj *)NULL,bodyVarObjPtr,0);
4138 Tcl_Free(curlDataPtr->bodyVar.memory);
4139 curlDataPtr->bodyVar.memory=NULL;
4140 curlDataPtr->bodyVar.size=0;
4143 /*----------------------------------------------------------------------
4146 * The same as strdup, but won't seg fault if the string to copy is NULL.
4149 * old: The original one.
4152 * Returns a pointer to the new string.
4153 *----------------------------------------------------------------------
4156 *curlstrdup (char *old) {
4162 tmpPtr=Tcl_Alloc(strlen(old)+1);
4169 *----------------------------------------------------------------------
4171 * curlShareInitObjCmd --
4173 * Looks for the first free share handle (scurl1, scurl2,...) and
4174 * creates a Tcl command for it.
4177 * A string with the name of the handle, don't forget to free it.
4180 * See the user documentation.
4182 *----------------------------------------------------------------------
4186 curlCreateShareObjCmd (Tcl_Interp *interp,struct shcurlObjData *shcurlData) {
4190 Tcl_Command cmdToken;
4192 /* We try with scurl1, if it already exists with scurl2...*/
4193 shandleName=(char *)Tcl_Alloc(32);
4195 sprintf(shandleName,"scurl%d",i);
4196 if (!Tcl_GetCommandInfo(interp,shandleName,&info)) {
4197 cmdToken=Tcl_CreateObjCommand(interp,shandleName,curlShareObjCmd,
4198 (ClientData)shcurlData,
4199 (Tcl_CmdDeleteProc *)curlCleanUpShareCmd);
4203 shcurlData->token=cmdToken;
4209 *----------------------------------------------------------------------
4211 * curlShareInitObjCmd --
4213 * This procedure is invoked to process the "curl::shareinit" Tcl command.
4214 * See the user documentation for details on what it does.
4217 * A standard Tcl result.
4220 * See the user documentation.
4222 *----------------------------------------------------------------------
4226 curlShareInitObjCmd (ClientData clientData, Tcl_Interp *interp,
4227 int objc,Tcl_Obj *CONST objv[]) {
4231 struct shcurlObjData *shcurlData;
4234 shcurlData=(struct shcurlObjData *)Tcl_Alloc(sizeof(struct shcurlObjData));
4235 if (shcurlData==NULL) {
4236 resultPtr=Tcl_NewStringObj("Couldn't allocate memory",-1);
4237 Tcl_SetObjResult(interp,resultPtr);
4241 memset(shcurlData, 0, sizeof(struct shcurlObjData));
4243 shcurlHandle=curl_share_init();
4244 if (shcurlHandle==NULL) {
4245 resultPtr=Tcl_NewStringObj("Couldn't create share handle",-1);
4246 Tcl_SetObjResult(interp,resultPtr);
4250 shandleName=curlCreateShareObjCmd(interp,shcurlData);
4252 shcurlData->shandle=shcurlHandle;
4254 resultPtr=Tcl_NewStringObj(shandleName,-1);
4255 Tcl_SetObjResult(interp,resultPtr);
4256 Tcl_Free(shandleName);
4259 curl_share_setopt(shcurlHandle, CURLSHOPT_LOCKFUNC, curlShareLockFunc);
4260 curl_share_setopt(shcurlHandle, CURLSHOPT_LOCKFUNC, curlShareUnLockFunc);
4268 *----------------------------------------------------------------------
4270 * curlShareLockFunc --
4272 * This will be the function invoked by libcurl when it wants to lock
4273 * some data for the share interface.
4276 * See the user documentation.
4278 *----------------------------------------------------------------------
4282 curlShareLockFunc (CURL *handle, curl_lock_data data, curl_lock_access access
4286 CURL_LOCK_DATA_COOKIE:
4287 Tcl_MutexLock(&cookieLock);
4290 Tcl_MutexLock(&dnsLock);
4292 CURL_LOCK_DATA_SSL_SESSION:
4293 Tcl_MutexLock(&sslLock);
4295 CURL_LOCK_DATA_CONNECT:
4296 Tcl_MutexLock(&connectLock);
4299 /* Prevent useless compile warnings */
4305 *----------------------------------------------------------------------
4307 * curlShareUnLockFunc --
4309 * This will be the function invoked by libcurl when it wants to unlock
4310 * the previously locked data.
4313 * See the user documentation.
4315 *----------------------------------------------------------------------
4318 curlShareUnLockFunc(CURL *handle, curl_lock_data data, void *userptr) {
4321 CURL_LOCK_DATA_COOKIE:
4322 Tcl_MutexUnlock(&cookieLock);
4325 Tcl_MutexUnlock(&dnsLock);
4327 CURL_LOCK_DATA_SSL_SESSION:
4328 Tcl_MutexUnlock(&sslLock);
4330 CURL_LOCK_DATA_CONNECT:
4331 Tcl_MutexUnlock(&connectLock);
4341 *----------------------------------------------------------------------
4343 * curlShareObjCmd --
4345 * This procedure is invoked to process the "share curl" commands.
4346 * See the user documentation for details on what it does.
4349 * A standard Tcl result.
4352 * See the user documentation.
4354 *----------------------------------------------------------------------
4357 curlShareObjCmd (ClientData clientData, Tcl_Interp *interp,
4358 int objc,Tcl_Obj *CONST objv[]) {
4360 struct shcurlObjData *shcurlData=(struct shcurlObjData *)clientData;
4361 CURLSH *shcurlHandle=shcurlData->shandle;
4362 int tableIndex, dataIndex;
4366 Tcl_WrongNumArgs(interp,1,objv,"option arg ?arg?");
4370 if (Tcl_GetIndexFromObj(interp, objv[1], shareCmd, "option",TCL_EXACT,&tableIndex)==TCL_ERROR) {
4374 switch(tableIndex) {
4377 if (Tcl_GetIndexFromObj(interp, objv[2], lockData,
4378 "data to lock ",TCL_EXACT,&dataIndex)==TCL_ERROR) {
4383 dataToLock=CURL_LOCK_DATA_COOKIE;
4386 dataToLock=CURL_LOCK_DATA_DNS;
4389 if (tableIndex==0) {
4390 curl_share_setopt(shcurlHandle, CURLSHOPT_SHARE, dataToLock);
4392 curl_share_setopt(shcurlHandle, CURLSHOPT_UNSHARE, dataToLock);
4396 Tcl_DeleteCommandFromToken(interp,shcurlData->token);
4403 *----------------------------------------------------------------------
4405 * curlCleanUpShareCmd --
4407 * This procedure is invoked when curl share handle is deleted.
4410 * A standard Tcl result.
4413 * Cleans the curl share handle and frees the memory.
4415 *----------------------------------------------------------------------
4418 curlCleanUpShareCmd(ClientData clientData) {
4419 struct shcurlObjData *shcurlData=(struct shcurlObjData *)clientData;
4420 CURLSH *shcurlHandle=shcurlData->shandle;
4422 curl_share_cleanup(shcurlHandle);
4423 Tcl_Free((char *)shcurlData);
4429 *----------------------------------------------------------------------
4431 * curlErrorStrings --
4433 * All the commands to return the error string from the error code have
4434 * this function in common.
4437 * '0': All went well.
4438 * '1': The error code didn't make sense.
4439 *----------------------------------------------------------------------
4442 curlErrorStrings (Tcl_Interp *interp, Tcl_Obj *CONST objv,int type) {
4448 if (Tcl_GetIntFromObj(interp,objv,&errorCode)) {
4449 snprintf(errorMsg,500,"Invalid error code: %s",Tcl_GetString(objv));
4450 resultPtr=Tcl_NewStringObj(errorMsg,-1);
4451 Tcl_SetObjResult(interp,resultPtr);
4456 resultPtr=Tcl_NewStringObj(curl_easy_strerror(errorCode),-1);
4459 resultPtr=Tcl_NewStringObj(curl_share_strerror(errorCode),-1);
4462 resultPtr=Tcl_NewStringObj(curl_multi_strerror(errorCode),-1);
4465 resultPtr=Tcl_NewStringObj("You're kidding,right?",-1);
4467 Tcl_SetObjResult(interp,resultPtr);
4473 *----------------------------------------------------------------------
4475 * curlEasyStringError --
4477 * This function is invoked to process the "curl::easystrerror" Tcl command.
4478 * It will return a string with an explanation of the error code given.
4481 * A standard Tcl result.
4484 * The interpreter will contain as a result the string with the error
4487 *----------------------------------------------------------------------
4490 curlEasyStringError (ClientData clientData, Tcl_Interp *interp,
4491 int objc,Tcl_Obj *CONST objv[]) {
4494 Tcl_WrongNumArgs(interp,1,objv,"errorCode");
4498 if (curlErrorStrings(interp,objv[1],0)) {
4505 *----------------------------------------------------------------------
4507 * curlShareStringError --
4509 * This function is invoked to process the "curl::sharestrerror" Tcl command.
4510 * It will return a string with an explanation of the error code given.
4513 * A standard Tcl result.
4516 * The interpreter will contain as a result the string with the error
4519 *----------------------------------------------------------------------
4522 curlShareStringError (ClientData clientData, Tcl_Interp *interp,
4523 int objc,Tcl_Obj *CONST objv[]) {
4526 Tcl_WrongNumArgs(interp,1,objv,"errorCode");
4530 if (curlErrorStrings(interp,objv[1],1)) {
4537 *----------------------------------------------------------------------
4539 * curlMultiStringError --
4541 * This function is invoked to process the "curl::multirerror" Tcl command.
4542 * It will return a string with an explanation of the error code given.
4545 * A standard Tcl result.
4548 * The interpreter will contain as a result the string with the error
4551 *----------------------------------------------------------------------
4554 curlMultiStringError (ClientData clientData, Tcl_Interp *interp,
4555 int objc,Tcl_Obj *CONST objv[]) {
4558 Tcl_WrongNumArgs(interp,1,objv,"errorCode");
4562 if (curlErrorStrings(interp,objv[1],2)) {