/* * tclcurl.h -- * * Header file for the TclCurl extension to enable Tcl interpreters * to access libcurl. * * Copyright (c) 2001-2011 Andres Garcia Garcia. * * See the file "license.terms" for information on usage and redistribution * of this file, and for a DISCLAIMER OF ALL WARRANTIES. * */ #if (defined(WIN32) || defined(_WIN32)) #define CURL_STATICLIB 1 #endif #include #include #include #include #include #include #define _MPRINTF_REPLACE #include #ifdef __cplusplus extern "C" { #endif /* * Windows needs to know which symbols to export. Unix does not. * BUILD_tclcurl should be undefined for Unix. * Actually I don't use this, but it was in TEA so I keep in case * I ever understand what it is for. */ #ifdef BUILD_tclcurl #undef TCL_STORAGE_CLASS #define TCL_STORAGE_CLASS DLLEXPORT #endif #define TclCurlVersion "7.22.0" /* * This struct will contain the data of a transfer if the user wants * to put the body into a Tcl variable */ struct MemoryStruct { char *memory; size_t size; }; /* * Struct that will be used for a linked list with all the * data for a post */ struct formArrayStruct { struct curl_forms *formArray; struct curl_slist *formHeaderList; struct formArrayStruct *next; }; struct curlObjData { CURL *curl; Tcl_Command token; Tcl_Command shareToken; Tcl_Interp *interp; struct curl_slist *headerList; struct curl_slist *quote; struct curl_slist *prequote; struct curl_slist *postquote; struct curl_httppost *postListFirst; struct curl_httppost *postListLast; struct formArrayStruct *formArray; char *outFile; FILE *outHandle; int outFlag; char *inFile; FILE *inHandle; int inFlag; char *proxy; int transferText; char *errorBuffer; char *errorBufferName; char *errorBufferKey; char *headerFile; FILE *headerHandle; int headerFlag; char *stderrFile; FILE *stderrHandle; int stderrFlag; char *randomFile; char *headerVar; char *bodyVarName; struct MemoryStruct bodyVar; char *progressProc; char *cancelTransVarName; int cancelTrans; char *writeProc; char *readProc; char *debugProc; struct curl_slist *http200aliases; char *command; int anyAuthFlag; char *sshkeycallProc; struct curl_slist *mailrcpt; char *chunkBgnProc; char *chunkBgnVar; char *chunkEndProc; char *fnmatchProc; struct curl_slist *resolve; struct curl_slist *telnetoptions; }; struct shcurlObjData { Tcl_Command token; CURLSH *shandle; }; #ifndef multi_h CONST static char *commandTable[] = { "setopt", "perform", "getinfo", "cleanup", "configure", "duphandle", "reset", "pause", "resume", (char *) NULL }; CONST static char *optionTable[] = { "CURLOPT_URL", "CURLOPT_FILE", "CURLOPT_READDATA", "CURLOPT_USERAGENT", "CURLOPT_REFERER", "CURLOPT_VERBOSE", "CURLOPT_HEADER", "CURLOPT_NOBODY", "CURLOPT_PROXY", "CURLOPT_PROXYPORT", "CURLOPT_HTTPPROXYTUNNEL", "CURLOPT_FAILONERROR", "CURLOPT_TIMEOUT", "CURLOPT_LOW_SPEED_LIMIT", "CURLOPT_LOW_SPEED_TIME", "CURLOPT_RESUME_FROM", "CURLOPT_INFILESIZE", "CURLOPT_UPLOAD", "CURLOPT_FTPLISTONLY", "CURLOPT_FTPAPPEND", "CURLOPT_NETRC", "CURLOPT_FOLLOWLOCATION","CURLOPT_TRANSFERTEXT", "CURLOPT_PUT", "CURLOPT_MUTE", "CURLOPT_USERPWD", "CURLOPT_PROXYUSERPWD", "CURLOPT_RANGE", "CURLOPT_ERRORBUFFER", "CURLOPT_HTTPGET", "CURLOPT_POST", "CURLOPT_POSTFIELDS", "CURLOPT_POSTFIELDSIZE", "CURLOPT_FTPPORT", "CURLOPT_COOKIE", "CURLOPT_COOKIEFILE", "CURLOPT_HTTPHEADER", "CURLOPT_HTTPPOST", "CURLOPT_SSLCERT", "CURLOPT_SSLCERTPASSWD", "CURLOPT_SSLVERSION", "CURLOPT_CRLF", "CURLOPT_QUOTE", "CURLOPT_POSTQUOTE", "CURLOPT_WRITEHEADER", "CURLOPT_TIMECONDITION", "CURLOPT_TIMEVALUE", "CURLOPT_CUSTOMREQUEST", "CURLOPT_STDERR", "CURLOPT_INTERFACE", "CURLOPT_KRB4LEVEL", "CURLOPT_SSL_VERIFYPEER","CURLOPT_CAINFO", "CURLOPT_FILETIME", "CURLOPT_MAXREDIRS", "CURLOPT_MAXCONNECTS", "CURLOPT_CLOSEPOLICY", "CURLOPT_RANDOM_FILE", "CURLOPT_EGDSOCKET", "CURLOPT_CONNECTTIMEOUT", "CURLOPT_NOPROGRESS", "CURLOPT_HEADERVAR", "CURLOPT_BODYVAR", "CURLOPT_PROGRESSPROC","CURLOPT_CANCELTRANSVARNAME","CURLOPT_WRITEPROC", "CURLOPT_READPROC", "CURLOPT_SSL_VERIFYHOST", "CURLOPT_COOKIEJAR", "CURLOPT_SSL_CIPHER_LIST","CURLOPT_HTTP_VERSION", "CURLOPT_FTP_USE_EPSV", "CURLOPT_SSLCERTTYPE", "CURLOPT_SSLKEY", "CURLOPT_SSLKEYTYPE", "CURLOPT_SSLKEYPASSWD", "CURLOPT_SSL_ENGINE", "CURLOPT_SSL_ENGINEDEFAULT", "CURLOPT_PREQUOTE", "CURLOPT_DEBUGPROC", "CURLOPT_DNS_CACHE_TIMEOUT", "CURLOPT_DNS_USE_GLOBAL_CACHE", "CURLOPT_COOKIESESSION","CURLOPT_CAPATH", "CURLOPT_BUFFERSIZE", "CURLOPT_NOSIGNAL", "CURLOPT_ENCODING", "CURLOPT_PROXYTYPE", "CURLOPT_HTTP200ALIASES", "CURLOPT_UNRESTRICTED_AUTH", "CURLOPT_FTP_USE_EPRT", "CURLOPT_NOSUCHOPTION", "CURLOPT_HTTPAUTH", "CURLOPT_FTP_CREATE_MISSING_DIRS", "CURLOPT_PROXYAUTH", "CURLOPT_FTP_RESPONSE_TIMEOUT", "CURLOPT_IPRESOLVE", "CURLOPT_MAXFILESIZE", "CURLOPT_NETRC_FILE", "CURLOPT_FTP_SSL", "CURLOPT_SHARE", "CURLOPT_PORT", "CURLOPT_TCP_NODELAY", "CURLOPT_AUTOREFERER", "CURLOPT_SOURCE_HOST", "CURLOPT_SOURCE_USERPWD", "CURLOPT_SOURCE_PATH", "CURLOPT_SOURCE_PORT", "CURLOPT_PASV_HOST", "CURLOPT_SOURCE_PREQUOTE","CURLOPT_SOURCE_POSTQUOTE", "CURLOPT_FTPSSLAUTH", "CURLOPT_SOURCE_URL", "CURLOPT_SOURCE_QUOTE", "CURLOPT_FTP_ACCOUNT", "CURLOPT_IGNORE_CONTENT_LENGTH", "CURLOPT_COOKIELIST", "CURLOPT_FTP_SKIP_PASV_IP", "CURLOPT_FTP_FILEMETHOD", "CURLOPT_LOCALPORT", "CURLOPT_LOCALPORTRANGE", "CURLOPT_MAX_SEND_SPEED_LARGE", "CURLOPT_MAX_RECV_SPEED_LARGE", "CURLOPT_FTP_ALTERNATIVE_TO_USER", "CURLOPT_SSL_SESSIONID_CACHE", "CURLOPT_SSH_AUTH_TYPES", "CURLOPT_SSH_PUBLIC_KEYFILE", "CURLOPT_SSH_PRIVATE_KEYFILE", "CURLOPT_TIMEOUT_MS", "CURLOPT_CONNECTTIMEOUT_MS", "CURLOPT_HTTP_CONTENT_DECODING", "CURLOPT_HTTP_TRANSFER_DECODING", "CURLOPT_KRBLEVEL", "CURLOPT_NEW_FILE_PERMS", "CURLOPT_NEW_DIRECTORY_PERMS", "CURLOPT_KEYPASSWD", "CURLOPT_APPEND", "CURLOPT_DIRLISTONLY", "CURLOPT_USE_SSL", "CURLOPT_POST301", "CURLOPT_SSH_HOST_PUBLIC_KEY_MD5", "CURLOPT_PROXY_TRANSFER_MODE", "CURLOPT_CRLFILE", "CURLOPT_ISSUERCERT", "CURLOPT_ADDRESS_SCOPE", "CURLOPT_CERTINFO", "CURLOPT_POSTREDIR", "CURLOPT_USERNAME", "CURLOPT_PASSWORD", "CURLOPT_PROXYUSERNAME", "CURLOPT_PROXYPASSWORD", "CURLOPT_TFTP_BLKSIZE", "CURLOPT_SOCKS5_GSSAPI_SERVICE", "CURLOPT_SOCKS5_GSSAPI_NEC", "CURLOPT_PROTOCOLS", "CURLOPT_REDIR_PROTOCOLS","CURLOPT_FTP_SSL_CC", "CURLOPT_SSH_KNOWNHOSTS", "CURLOPT_SSH_KEYFUNCTION","CURLOPT_MAIL_FROM", "CURLOPT_MAIL_RCPT", "CURLOPT_FTP_USE_PRET", "CURLOPT_WILDCARDMATCH", "CURLOPT_CHUNK_BGN_PROC", "CURLOPT_CHUNK_BGN_VAR", "CURLOPT_CHUNK_END_PROC", "CURLOPT_FNMATCH_PROC", "CURLOPT_RESOLVE", "CURLOPT_TLSAUTH_USERNAME", "CURLOPT_TLSAUTH_PASSWORD","CURLOPT_GSSAPI_DELEGATION", "CURLOPT_NOPROXY", "CURLOPT_TELNETOPTIONS", (char *)NULL }; CONST static char *configTable[] = { "-url", "-file", "-infile", "-useragent", "-referer", "-verbose", "-header", "-nobody", "-proxy", "-proxyport", "-httpproxytunnel", "-failonerror", "-timeout", "-lowspeedlimit", "-lowspeedtime", "-resumefrom", "-infilesize", "-upload", "-ftplistonly", "-ftpappend", "-netrc", "-followlocation", "-transfertext", "-put", "-mute", "-userpwd", "-proxyuserpwd", "-range", "-errorbuffer", "-httpget", "-post", "-postfields", "-postfieldssize", "-ftpport", "-cookie", "-cookiefile", "-httpheader", "-httppost", "-sslcert", "-sslcertpasswd", "-sslversion", "-crlf", "-quote", "-postquote", "-writeheader", "-timecondition", "-timevalue", "-customrequest", "-stderr", "-interface", "-krb4level", "-sslverifypeer", "-cainfo", "-filetime", "-maxredirs", "-maxconnects", "-closepolicy", "-randomfile", "-egdsocket", "-connecttimeout", "-noprogress", "-headervar", "-bodyvar", "-progressproc", "-canceltransvarname", "-writeproc", "-readproc", "-sslverifyhost", "-cookiejar", "-sslcipherlist", "-httpversion", "-ftpuseepsv", "-sslcerttype", "-sslkey", "-sslkeytype", "-sslkeypasswd", "-sslengine", "-sslenginedefault", "-prequote", "-debugproc", "-dnscachetimeout", "-dnsuseglobalcache", "-cookiesession", "-capath", "-buffersize", "-nosignal", "-encoding", "-proxytype", "-http200aliases", "-unrestrictedauth", "-ftpuseeprt", "-command", "-httpauth", "-ftpcreatemissingdirs", "-proxyauth", "-ftpresponsetimeout", "-ipresolve", "-maxfilesize", "-netrcfile", "-ftpssl", "-share", "-port", "-tcpnodelay", "-autoreferer", "-sourcehost", "-sourceuserpwd", "-sourcepath", "-sourceport", "-pasvhost", "-sourceprequote", "-sourcepostquote", "-ftpsslauth", "-sourceurl", "-sourcequote", "-ftpaccount", "-ignorecontentlength", "-cookielist", "-ftpskippasvip", "-ftpfilemethod", "-localport", "-localportrange", "-maxsendspeed", "-maxrecvspeed", "-ftpalternativetouser", "-sslsessionidcache", "-sshauthtypes", "-sshpublickeyfile", "-sshprivatekeyfile", "-timeoutms", "-connecttimeoutms", "-contentdecoding", "-transferdecoding", "-krblevel", "-newfileperms", "-newdirectoryperms", "-keypasswd", "-append", "-dirlistonly", "-usessl", "-post301", "-sshhostpublickeymd5", "-proxytransfermode", "-crlfile", "-issuercert", "-addressscope", "-certinfo", "-postredir", "-username", "-password", "-proxyuser", "-proxypassword", "-tftpblksize", "-socks5gssapiservice","-socks5gssapinec", "-protocols", "-redirprotocols", "-ftpsslcc", "-sshknownhosts", "-sshkeyproc", "-mailfrom", "-mailrcpt", "-ftpusepret", "-wildcardmatch", "-chunkbgnproc", "-chunkbgnvar", "-chunkendproc", "-fnmatchproc", "-resolve", "-tlsauthusername", "-tlsauthpassword", "-gssapidelegation", "-noproxy", "-telnetoptions", (char *) NULL }; CONST static char *timeCond[] = { "ifmodsince", "ifunmodsince", (char *)NULL }; CONST static char *getInfoTable[]={ "effectiveurl", "httpcode", "responsecode", "filetime", "totaltime", "namelookuptime", "connecttime", "pretransfertime","sizeupload", "sizedownload", "speeddownload", "speedupload", "headersize", "requestsize", "sslverifyresult", "contentlengthdownload", "contentlengthupload", "starttransfertime", "contenttype", "redirecttime", "redirectcount", "httpauthavail", "proxyauthavail", "oserrno", "numconnects", "sslengines", "httpconnectcode","cookielist", "ftpentrypath", "redirecturl", "primaryip", "appconnecttime", "certinfo", "conditionunmet", "primaryport", "localip", "localport", (char *)NULL }; CONST static char *curlFormTable[]={ "name", "contents", "file", "contenttype", "contentheader", "filename", "bufferName", "buffer", "filecontent", (char *)NULL }; CONST static char *httpVersionTable[] = { "none", "1.0", "1.1", (char *)NULL }; CONST static char *netrcTable[] = { "optional", "ignored", "required", (char *)NULL }; CONST static char *encodingTable[] = { "identity", "deflated", "all", (char *)NULL }; CONST static char *versionInfoTable[] = { "-version", "-versionnum", "-host", "-features", "-sslversion", "-sslversionnum", "-libzversion", "-protocols", (char *)NULL }; CONST static char *proxyTypeTable[] = { "http", "http1.0", "socks4", "socks4a", "socks5", "socks5h", (char *)NULL }; CONST static char *httpAuthMethods[] = { "basic", "digest", "digestie", "gssnegotiate", "ntlm", "any", "anysafe", "ntlmwb",(char *)NULL }; CONST static char *ipresolve[] = { "whatever", "v4", "v6", (char *)NULL }; CONST static char *ftpssl[] = { "nope", "try", "control", "all", (char *)NULL }; CONST static char *shareCmd[] = { "share", "unshare", "cleanup", (char *)NULL }; CONST static char *lockData[] = { "cookies", "dns", (char *)NULL }; CONST static char *ftpsslauth[] = { "default", "ssl", "tls", (char *)NULL }; CONST static char *ftpsslccc[] = { "none", "passive", "active", (char *)NULL }; CONST static char *sslversion[] = { "default", "tlsv1", "sslv2", "sslv3", "tlsv1_0", "tlsv1_1", "tlsv1_2", (char *)NULL }; CONST static char *ftpfilemethod[] = { "default", "multicwd", "nocwd", "singlecwd", (char *)NULL }; CONST static char *sshauthtypes[] = { "publickey", "password", "host", "keyboard", "any", (char *)NULL }; CONST static char *postredir[] = { "301", "302", "all", (char *)NULL }; CONST static char *protocolNames[] = { "http", "https", "ftp", "ftps", "scp", "sftp", "telnet", "ldap", "ldaps","dict", "file","tftp", "all", "imap", "imaps", "pop3", "pop3s", "smtp", "smtps", "rtsp", "rtmp", "rtmpt", "rtmpe", "rtmpte", "rtmps", "rtmpts", "gopher", (char*)NULL }; CONST static char *tlsauth[] = { "none", "srp", (char *)NULL }; CONST static char *gssapidelegation[] = { "flag", "policyflag", (char *) NULL }; int curlseek(void *instream, curl_off_t offset, int origin); int Tclcurl_MultiInit (Tcl_Interp *interp); #endif int Tclcurl_Init(Tcl_Interp *interp); char *curlCreateObjCmd(Tcl_Interp *interp,struct curlObjData *curlData); int curlInitObjCmd(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]); int curlObjCmd(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]); int curlDeleteCmd(ClientData clientData); int curlPerform(Tcl_Interp *interp,CURL *curlHandle,struct curlObjData *curlData); int curlSetOptsTransfer(Tcl_Interp *interp, struct curlObjData *curlData,int objc, Tcl_Obj *CONST objv[]); int curlConfigTransfer(Tcl_Interp *interp, struct curlObjData *curlData,int objc, Tcl_Obj *CONST objv[]); int curlDupHandle(Tcl_Interp *interp, struct curlObjData *curlData,int objc, Tcl_Obj *CONST objv[]); int curlResetHandle(Tcl_Interp *interp, struct curlObjData *curlData); int curlSetOpts(Tcl_Interp *interp, struct curlObjData *curlData, Tcl_Obj *CONST objv,int tableIndex); int SetoptInt(Tcl_Interp *interp,CURL *curlHandle,CURLoption opt,int tableIndex, Tcl_Obj *tclObj); int SetoptLong(Tcl_Interp *interp,CURL *curlHandle,CURLoption opt,int tableIndex, Tcl_Obj *tclObj); int SetoptCurlOffT(Tcl_Interp *interp,CURL *curlHandle,CURLoption opt,int tableIndex, Tcl_Obj *tclObj); int SetoptChar(Tcl_Interp *interp,CURL *curlHandle,CURLoption opt, int tableIndex,Tcl_Obj *tclObj); int SetoptSHandle(Tcl_Interp *interp,CURL *curlHandle,CURLoption opt, int tableIndex,Tcl_Obj *tclObj); int SetoptsList(Tcl_Interp *interp,struct curl_slist **slistPtr,Tcl_Obj *CONST objv); CURLcode curlGetInfo(Tcl_Interp *interp,CURL *curlHandle,int tableIndex); void curlFreeSpace(struct curlObjData *curlData); void curlErrorSetOpt(Tcl_Interp *interp,CONST char **configTable, int option,CONST char *parPtr); size_t curlHeaderReader(void *ptr,size_t size,size_t nmemb,FILE *stream); size_t curlBodyReader(void *ptr,size_t size,size_t nmemb,FILE *curlDataPtr); int curlProgressCallback(void *clientp,double dltotal,double dlnow, double ultotal,double ulnow); size_t curlWriteProcInvoke(void *ptr,size_t size,size_t nmemb,FILE *curlDataPtr); size_t curlReadProcInvoke(void *ptr,size_t size,size_t nmemb,FILE *curlDataPtr); long curlChunkBgnProcInvoke (const void *transfer_info, void *curlDataPtr, int remains); long curlChunkEndProcInvoke (void *curlDataPtr); int curlfnmatchProcInvoke(void *curlDataPtr, const char *pattern, const char *filename); /* Puts a ssh key into a Tcl object */ Tcl_Obj *curlsshkeyextract(Tcl_Interp *interp,const struct curl_khkey *key); /* Function that will be invoked by libcurl to see what the user wants to do about the new ssh host */ size_t curlsshkeycallback(CURL *easy, /* easy handle */ const struct curl_khkey *knownkey, /* known */ const struct curl_khkey *foundkey, /* found */ enum curl_khmatch, /* libcurl's view on the keys */ void *curlData); int curlDebugProcInvoke(CURL *curlHandle, curl_infotype infoType, char * dataPtr, size_t size, void *curlData); int curlVersion (ClientData clientData, Tcl_Interp *interp, int objc,Tcl_Obj *CONST objv[]); int curlEscape(ClientData clientData, Tcl_Interp *interp, int objc,Tcl_Obj *CONST objv[]); int curlUnescape(ClientData clientData, Tcl_Interp *interp, int objc,Tcl_Obj *CONST objv[]); int curlVersionInfo (ClientData clientData, Tcl_Interp *interp, int objc,Tcl_Obj *CONST objv[]); int curlCopyCurlData (struct curlObjData *curlDataOld, struct curlObjData *curlDataNew); int curlOpenFile(Tcl_Interp *interp,char *fileName, FILE **handle, int writing, int text); int curlOpenFiles (Tcl_Interp *interp,struct curlObjData *curlData); void curlCloseFiles(struct curlObjData *curlData); int curlSetPostData(Tcl_Interp *interp,struct curlObjData *curlData); void curlResetPostData(struct curlObjData *curlDataPtr); void curlResetFormArray(struct curl_forms *formArray); void curlSetBodyVarName(Tcl_Interp *interp,struct curlObjData *curlDataPtr); char *curlstrdup (char *old); char *curlCreateShareObjCmd (Tcl_Interp *interp,struct shcurlObjData *shcurlData); int curlShareInitObjCmd (ClientData clientData, Tcl_Interp *interp, int objc,Tcl_Obj *CONST objv[]); int curlShareObjCmd (ClientData clientData, Tcl_Interp *interp, int objc,Tcl_Obj *CONST objv[]); int curlCleanUpShareCmd(ClientData clientData); #ifdef TCL_THREADS TCL_DECLARE_MUTEX(cookieLock) TCL_DECLARE_MUTEX(dnsLock) TCL_DECLARE_MUTEX(sslLock) TCL_DECLARE_MUTEX(connectLock) void curlShareLockFunc (CURL *handle, curl_lock_data data , curl_lock_access access, void *userptr); void curlShareUnLockFunc(CURL *handle, curl_lock_data data, void *userptr); #endif int curlErrorStrings (Tcl_Interp *interp, Tcl_Obj *CONST objv,int type); int curlEasyStringError (ClientData clientData, Tcl_Interp *interp, int objc,Tcl_Obj *CONST objv[]); int curlShareStringError (ClientData clientData, Tcl_Interp *interp, int objc,Tcl_Obj *CONST objv[]); int curlMultiStringError (ClientData clientData, Tcl_Interp *interp, int objc,Tcl_Obj *CONST objv[]); #ifdef __cplusplus } #endif