From 2f3a03bf739b66c1c7219c264f658777ae17b92d Mon Sep 17 00:00:00 2001 From: Philipp Zabel Date: Sat, 1 May 2010 11:04:23 +0200 Subject: [PATCH] Switch from libsoup to libcurl, add login and my information support libsoup in maemo doesn't support encrypted connections. --- Makefile.am | 15 +- configure.ac | 12 +- src/adac-mitfahrclub.vala | 330 +++++++++++++++++++-- src/beifahrer-cli.vala | 26 +- vapi/libcurl.deps | 1 + vapi/libcurl.vapi | 693 +++++++++++++++++++++++++++++++++++++++++++++ 6 files changed, 1047 insertions(+), 30 deletions(-) create mode 100644 vapi/libcurl.deps create mode 100644 vapi/libcurl.vapi diff --git a/Makefile.am b/Makefile.am index 0b76648..4f60bc9 100644 --- a/Makefile.am +++ b/Makefile.am @@ -59,7 +59,7 @@ beifahrer_VALAFLAGS = --disable-dbus-transformation --thread --vapidir ./vapi \ --pkg libosso-abook-1.0 \ --pkg libhildonmime \ --pkg liblocation \ - --pkg libsoup-2.4 + --pkg libcurl beifahrer_CFLAGS = -DGETTEXT_PACKAGE=\"@GETTEXT_PACKAGE@\" \ ${DBUS_CFLAGS} \ ${GCONF_CFLAGS} \ @@ -68,7 +68,7 @@ beifahrer_CFLAGS = -DGETTEXT_PACKAGE=\"@GETTEXT_PACKAGE@\" \ ${MAEMO_LAUNCHER_CFLAGS} \ ${OSSO_CFLAGS} \ ${ABOOK_CFLAGS} \ - ${SOUP_CFLAGS} \ + ${CURL_CFLAGS} ${XML_CFLAGS} beifahrer_LDADD = \ ${DBUS_LIBS} \ @@ -78,7 +78,7 @@ beifahrer_LDADD = \ ${MAEMO_LAUNCHER_LIBS} \ ${OSSO_LIBS} \ ${ABOOK_LIBS} \ - ${SOUP_LIBS} \ + ${CURL_LIBS} \ ${XML_LIBS} beifahrer_cli_VALASOURCES = src/beifahrer-cli.vala src/adac-mitfahrclub.vala @@ -89,15 +89,18 @@ src/beifahrer-cli.c: ${beifahrer_cli_VALASOURCES} ${VALAC} -C ${beifahrer_cli_VALASOURCES} ${beifahrer_cli_VALAFLAGS} beifahrer_cli_VALAFLAGS = --thread --vapidir ./vapi \ - --pkg libsoup-2.4 \ + --pkg gio-2.0 \ + --pkg libcurl \ --pkg libxml-2.0 beifahrer_cli_CFLAGS = -DGETTEXT_PACKAGE=\"@GETTEXT_PACKAGE@\" \ ${GIO_CFLAGS} \ - ${SOUP_CFLAGS} \ + ${CURL_CFLAGS} \ + ${GTHREAD_CFLAGS} \ ${XML_CFLAGS} beifahrer_cli_LDADD = \ ${GIO_LIBS} \ - ${SOUP_LIBS} \ + ${CURL_LIBS} \ + ${GTHREAD_LIBS} \ ${XML_LIBS} CLEANFILES = \ diff --git a/configure.ac b/configure.ac index f7c3c92..72a1c2b 100644 --- a/configure.ac +++ b/configure.ac @@ -16,6 +16,10 @@ AC_PROG_LIBTOOL CFLAGS="$CFLAGS -Wall -ansi -Wmissing-prototypes -Wmissing-declarations" +PKG_CHECK_MODULES(CURL, libcurl) +AC_SUBST(CURL_LIBS) +AC_SUBST(CURL_CFLAGS) + PKG_CHECK_MODULES(GCONF, gconf-2.0 >= 2.16.0) AC_SUBST(GCONF_LIBS) AC_SUBST(GCONF_CFLAGS) @@ -32,6 +36,10 @@ PKG_CHECK_MODULES(GOBJECT, gobject-2.0) AC_SUBST(GOBJECT_LIBS) AC_SUBST(GOBJECT_CFLAGS) +PKG_CHECK_MODULES(GTHREAD, gthread-2.0) +AC_SUBST(GTHREAD_LIBS) +AC_SUBST(GTHREAD_CFLAGS) + PKG_CHECK_MODULES(HILDON, hildon-1 >= 2.2.0) AC_SUBST(HILDON_LIBS) AC_SUBST(HILDON_CFLAGS) @@ -67,10 +75,6 @@ PKG_CHECK_MODULES(OSSO, libosso >= 2.20) AC_SUBST(OSSO_LIBS) AC_SUBST(OSSO_CFLAGS) -PKG_CHECK_MODULES(SOUP, libsoup-2.4 >= 2.26.3) -AC_SUBST(SOUP_LIBS) -AC_SUBST(SOUP_CFLAGS) - PKG_CHECK_MODULES(GIO, gio-2.0 >= 2.20.3) AC_SUBST(GIO_LIBS) AC_SUBST(GIO_CFLAGS) diff --git a/src/adac-mitfahrclub.vala b/src/adac-mitfahrclub.vala index a9a8ace..b78fe54 100644 --- a/src/adac-mitfahrclub.vala +++ b/src/adac-mitfahrclub.vala @@ -71,40 +71,201 @@ public class Lift : Object { } } -public class CallbackMessage : Soup.Message { - public SourceFunc callback; - - public CallbackMessage (string url, SourceFunc? _callback) { - method = "GET"; - callback = _callback; - set_uri (new Soup.URI (url)); +public class MyInformation { + public enum Gender { + MALE, + FEMALE } + + public Gender gender; + public string title; + public string first_name; + public string last_name; + public Date birthday; + public Date registered_since; + + // Address + public string street; + public string number; + public string zip_code; + public string city; + public string country; + + // Contact + public string phone1; + public string phone2; + public string phone3; + public string cell; + public string email1; + public string email2; + + public bool smoker; + public bool adac_member; } public class AdacMitfahrclub { - const string BASE_URI = "http://mitfahrclub.adac.de"; + const string HTTP_BASE_URI = "http://mitfahrclub.adac.de"; + const string HTTPS_BASE_URI = "https://mitfahrclub.adac.de"; - Soup.SessionAsync session; + Curl.EasyHandle curl; List city_list = null; public AdacMitfahrclub () { - session = new Soup.SessionAsync (); + curl = new Curl.EasyHandle (); + // FIXME: Fremantle SDK doesn't come with certs + curl.setopt (Curl.Option.SSL_VERIFYPEER, 0); + // curl.setopt (Curl.Option.VERBOSE, 1); } - private void message_finished (Soup.Session session, Soup.Message message) { - Idle.add (((CallbackMessage) message).callback); + private string _url = null; + private SourceFunc callback = null; + void* download_thread () { + curl.setopt (Curl.Option.WRITEFUNCTION, write_callback); + curl.setopt (Curl.Option.WRITEDATA, this); + curl.setopt (Curl.Option.URL, _url); + if (aeolus_cookie != null) + curl.setopt (Curl.Option.COOKIE, "MIKINIMEDIA=%s; Quirinus[adacAeolus]=%s;".printf (mikini_cookie, aeolus_cookie)); + else if (mikini_cookie != null) + curl.setopt (Curl.Option.COOKIE, "MIKINIMEDIA=%s".printf (mikini_cookie)); + var res = curl.perform (); + + if (callback != null) + Idle.add (callback); + callback = null; + + return null; + } + + StringBuilder result; + + [CCode (instance_pos = -1)] + size_t write_callback (void *buffer, size_t size, size_t nmemb) { + // if (cancellable != null && cancellable.is_cancelled ()) + // return 0; + + result.append_len ((string) buffer, (ssize_t) (size * nmemb)); + + return size * nmemb; } private async Html.Doc* get_html_document (string url) { - var message = new CallbackMessage (url, get_html_document.callback); - session.queue_message (message, message_finished); + _url = url; + callback = get_html_document.callback; + result = new StringBuilder (); + try { + Thread.create(download_thread, false); + } catch (ThreadError e) { + critical ("Failed to create download thread\n"); + return null; + } yield; - return Html.Doc.read_memory ((char[]) message.response_body.data, (int) message.response_body.length, + return Html.Doc.read_memory ((char[]) result.str, (int) result.len, url, null, Html.ParserOption.NOERROR | Html.ParserOption.NOWARNING); } + private string username; + private string password; + private string mikini_cookie; + private string aeolus_cookie; + + public void set_cookie (string value) { + aeolus_cookie = value; + } + + public void login (string? _username, string? _password) { + username = _username; + password = _password; + if (logged_in) + return; + if (login_callback != null) + return; + login_thread (); + } + + public bool logged_in = false; + private SourceFunc login_callback = null; + public async bool login_async (string? _username, string? _password) { + username = _username; + password = _password; + if (logged_in) + return true; + if (login_callback != null) + return false; + login_callback = login_async.callback; + result = new StringBuilder (); + try { + Thread.create(login_thread, false); + } catch (ThreadError e) { + critical ("Failed to create login thread\n"); + return false; + } + + yield; + login_callback = null; + + return logged_in; + } + + void *login_thread () { + result = new StringBuilder (); + curl.setopt (Curl.Option.URL, HTTP_BASE_URI); + curl.setopt (Curl.Option.WRITEFUNCTION, write_callback); + curl.setopt (Curl.Option.WRITEDATA, this); + curl.setopt (Curl.Option.COOKIEFILE, ""); + var res = curl.perform (); + + Curl.SList cookies; + curl.getinfo (Curl.Info.COOKIELIST, out cookies); + unowned Curl.SList cookie = cookies; + while (cookie != null) { + if (cookie.data != null) { + var c = cookie.data.split ("\t"); + if (c.length > 5) + print ("%s=%s\n", c[5], c[6]); + if (c[5] == "MIKINIMEDIA") + mikini_cookie = c[6]; + } + cookie = cookie.next; + } + + result = new StringBuilder (); + string postdata = "data[User][continue]=/&data[User][js_allowed]=0&data[User][cookie_allowed]=1&data[User][username]=%s&data[User][password]=%s&data[User][remember_me]=1".printf (username, password); + curl.setopt (Curl.Option.POSTFIELDS, postdata); + curl.setopt (Curl.Option.URL, HTTPS_BASE_URI + "/users/login/"); + curl.setopt (Curl.Option.SSL_VERIFYPEER, 0); + res = curl.perform (); + // print ("%s\n", result.str); + + cookies = null; + curl.getinfo (Curl.Info.COOKIELIST, out cookies); + cookie = cookies; + while (cookie != null) { + if (cookie.data != null) { + var c = cookie.data.split ("\t"); + if (c.length > 5) + print ("%s=%s\n", c[5], c[6]); + // "Quirinus[adacAeolus]" + if (c[5] == "Quirinus[adacAeolus]") { + aeolus_cookie = c[6]; + logged_in = true; + } + } + cookie = cookie.next; + } + + if (result.str.contains ("
Die eingegebenen Zugangsdaten konnten nicht gefunden werden. Bitte versuchen Sie es erneut.
")) { + print ("LOGIN FAILED\n"); + aeolus_cookie = null; + logged_in = false; + } + + if (login_callback != null) + Idle.add (login_callback); + return null; + } + private void save_city_list () { FileStream list_file = FileStream.open ("/home/user/.cache/beifahrer/city_list", "w"); if (list_file == null) @@ -166,7 +327,7 @@ public class AdacMitfahrclub { } public async unowned List? download_city_list () { - var doc = yield get_html_document (BASE_URI); + var doc = yield get_html_document (HTTP_BASE_URI); if (doc == null) { stderr.printf ("Error: parsing failed\n"); return null; @@ -253,7 +414,7 @@ public class AdacMitfahrclub { return null; } - string url = BASE_URI + "/mitfahrclub/%s/%s/b.html".printf ( + string url = HTTP_BASE_URI + "/mitfahrclub/%s/%s/b.html".printf ( city_from, city_to ); @@ -369,7 +530,7 @@ public class AdacMitfahrclub { } public async bool update_lift_details (Lift lift) { - string url = BASE_URI + lift.href; + string url = HTTP_BASE_URI + lift.href; var doc = yield get_html_document (url); if (doc == null) { @@ -512,6 +673,139 @@ public class AdacMitfahrclub { return true; } + public async MyInformation get_my_information () { + string url = HTTPS_BASE_URI + "/users/view"; + + var doc = yield get_html_document (url); + if (doc == null) { + stderr.printf ("Error: parsing failed\n"); + return null; + } + + var table = search_tag_by_class (doc->children, "table", "user"); + if (table == null) { + stderr.printf ("Error: does not contain user table\n"); + return null; + } + + var my_info = new MyInformation (); + + Xml.Node* n; + for (n = table->children; n != null; n = n->next) { + if (n->name == "tr") { + var n2 = n->children; + if (n2 == null || n2->name != "td" || + n2->children == null || n2->children->name != "text") + continue; + + string text = n2->children->content; + + n2 = n2->next; + if (n2 != null && n2->name == "text") + n2 = n2->next; + if (n2 == null || n2->name != "td" || + n2->children == null || n2->children->name != "text") + continue; + + string content = n2->children->content; + + switch (text) { + case "Anrede": + my_info.gender = (content == "Herr") ? MyInformation.Gender.MALE : MyInformation.Gender.FEMALE; + continue; + case "Titel": + my_info.title = content; + continue; + case "Vorname": + my_info.first_name = content; + continue; + case "Name": + my_info.last_name = content; + continue; + case "Geburtsdatum": + // my_info.birthday = ... + continue; + case "registriert seit": + // my_info.registered_since = content; + continue; + // default: + // print ("\t%s=%s\n", text, content); + // break; + } + + text = content; + + n2 = n2->next; + if (n2 != null && n2->name == "text") + n2 = n2->next; + if (n2 == null || n2->name != "td") + continue; + + if (n2->children != null && n2->children->name != "text") + content = n2->children->content; + else + content = ""; + + switch (text) { + case "Straße, Nr.": + my_info.street = content; + my_info.number = ""; + continue; + case "PLZ, Ort": + my_info.zip_code = ""; + my_info.city = content; + continue; + case "Land": + my_info.country = content; + continue; + case "Telefon 1": + my_info.phone1 = content; + continue; + case "Telefon 2": + my_info.phone2 = content; + continue; + case "Telefon 3": + my_info.phone3 = content; + continue; + case "Handy": + my_info.cell = content; + continue; + case "Email 1": + my_info.email1 = content; + continue; + case "Email 2": + my_info.email2 = content; + continue; + case "Raucher": + // FIXME + my_info.smoker = false; + continue; + case "ADAC-Mitglied": + // FIXME + my_info.adac_member = false; + continue; + // default: + // print ("\"%s\"=\"%s\"\n", text, content); + // break; + } + } + } + +/* + + Anrede + Herr + + + Titel + + -- + + ... +*/ + return my_info; + } + Xml.Node* search_tag_by_property (Xml.Node* node, string tag, string prop, string val) requires (node != null) { for (var n = node; n != null; n = n->next) { if (n->name == tag && n->get_prop (prop) == val) diff --git a/src/beifahrer-cli.vala b/src/beifahrer-cli.vala index 31bf3d9..aefa372 100644 --- a/src/beifahrer-cli.vala +++ b/src/beifahrer-cli.vala @@ -72,17 +72,36 @@ async void get_details (string href) { loop.quit (); } +void usage () { + print ("usage: beifahrer-cli [date]\n"); + print ("or: beifahrer-cli details \n"); + print ("or: beifahrer-cli login \n"); + print ("or: beifahrer-cli login \n"); +} + static int main (string[] args) { loop = new MainLoop (null); if (args.length < 3) { - print ("usage: beifahrer-cli [date]\n"); - print ("or: beifahrer-cli details \n"); + usage (); return 1; } + Curl.global_init (Curl.GLOBAL_DEFAULT); + adac = new AdacMitfahrclub (); + if (args[1] == "login") { + if (args.length > 3) { + adac.login (args[2], args[3]); + } else { + adac.set_cookie (args[2]); + adac.login (null, null); + } + loop.run (); + return 0; + } + if (args[1] == "details") { get_details.begin (args[2]); @@ -104,5 +123,8 @@ static int main (string[] args) { get_lifts.begin (city_from, city_to, date); loop.run (); + + Curl.global_cleanup (); + return 0; } diff --git a/vapi/libcurl.deps b/vapi/libcurl.deps new file mode 100644 index 0000000..b3188f7 --- /dev/null +++ b/vapi/libcurl.deps @@ -0,0 +1 @@ +posix diff --git a/vapi/libcurl.vapi b/vapi/libcurl.vapi new file mode 100644 index 0000000..5857006 --- /dev/null +++ b/vapi/libcurl.vapi @@ -0,0 +1,693 @@ +[CCode (cheader_filename = "curl/curl.h")] +namespace Curl { + [CCode (cname = "CURL_GLOBAL_SSL")] + public const long GLOBAL_SSL; + [CCode (cname = "CURL_GLOBAL_WIN32")] + public const long GLOBAL_WIN32; + [CCode (cname = "CURL_GLOBAL_ALL")] + public const long GLOBAL_ALL; + [CCode (cname = "CURL_GLOBAL_NOTHING")] + public const long GLOBAL_NOTHING; + [CCode (cname = "CURL_GLOBAL_DEFAULT")] + public const int GLOBAL_DEFAULT; + public Curl.Code global_init (long flags); + public Curl.Code global_init_mem (long flags, Curl.MallocCallback m, Curl.FreeCallback f, Curl.ReallocCallback r, Curl.StrdupCallback s, Curl.CallocCallback c); + public static void global_cleanup (); + [Compact] + [CCode (cname = "CURL", cprefix = "curl_easy_", free_function = "curl_easy_cleanup")] + public class EasyHandle { + [CCode (cname = "curl_easy_init")] + public EasyHandle (); + [PrintfFormat] + public Curl.Code setopt (Curl.Option option, ...); + public Curl.Code perform (); + [PrintfFormat] + public Curl.Code getinfo (Curl.Info info, ...); + public Curl.EasyHandle duphandle (); + public void reset (); + public Curl.Code recv (void *buffer, size_t buflen, out size_t n); + public Curl.Code send (void *buffer, size_t buflen, out size_t n); + public string escape (string @string, int length); + public string unescape (string @string, int length, out int outlength); + [CCode (has_target = false)] + public delegate int SocketCallback (Curl.Socket s, int what, void* userp, void *socketp); + } + [CCode (cname = "CURLcode", cprefix = "CURLE_")] + public enum Code { + OK, + UNSUPPORTED_PROTOCOL, + FAILED_INIT, + URL_MALFORMAT, + COULDNT_RESOLVE_PROXY, + COULDNT_RESOLVE_HOST, + COULDNT_CONNECT, + FTP_WEIRD_SERVER_REPLY, + REMOTE_ACCESS_DENIED, + FTP_WEIRD_PASS_REPLY, + FTP_WEIRD_PASV_REPLY, + FTP_WEIRD_227_FORMAT, + FTP_CANT_GET_HOST, + FTP_COULDNT_SET_TYPE, + PARTIAL_FILE, + FTP_COULDNT_RETR_FILE, + QUOTE_ERROR, + HTTP_RETURNED_ERROR, + WRITE_ERROR, + UPLOAD_FAILED, + READ_ERROR, + OUT_OF_MEMORY, + OPERATION_TIMEDOUT, + FTP_PORT_FAILED, + FTP_COULDNT_USE_REST, + RANGE_ERROR, + HTTP_POST_ERROR, + SSL_CONNECT_ERROR, + BAD_DOWNLOAD_RESUME, + FILE_COULDNT_READ_FILE, + LDAP_CANNOT_BIND, + LDAP_SEARCH_FAILED, + FUNCTION_NOT_FOUND, + ABORTED_BY_CALLBACK, + BAD_FUNCTION_ARGUMENT, + INTERFACE_FAILED, + TOO_MANY_REDIRECTS, + UNKNOWN_TELNET_OPTION, + TELNET_OPTION_SYNTAX, + PEER_FAILED_VERIFICATION, + GOT_NOTHING, + SSL_ENGINE_NOTFOUND, + SSL_ENGINE_SETFAILED, + SEND_ERROR, + RECV_ERROR, + SSL_CERTPROBLEM, + SSL_CIPHER, + SSL_CACERT, + BAD_CONTENT_ENCODING, + LDAP_INVALID_URL, + FILESIZE_EXCEEDED, + USE_SSL_FAILED, + SEND_FAIL_REWIND, + SSL_ENGINE_INITFAILED, + LOGIN_DENIED, + TFTP_NOTFOUND, + TFTP_PERM, + REMOTE_DISK_FULL, + TFTP_ILLEGAL, + TFTP_UNKNOWNID, + REMOTE_FILE_EXISTS, + TFTP_NOSUCHUSER, + CONV_FAILED, + CONV_REQD, + SSL_CACERT_BADFILE, + REMOTE_FILE_NOT_FOUND, + SSH, + SSL_SHUTDOWN_FAILED, + AGAIN, + SSL_CRL_BADFILE, + SSL_ISSUER_ERROR, + [CCode (cname = "CURL_LAST")] + LAST + } + [CCode (name = "CURLoption", cprefix = "CURLOPT_")] + public enum Option { + FILE, + URL, + PORT, + PROXY, + USERPWD, + PROXYUSERPWD, + RANGE, + INFILE, + WRITEDATA, + READDATA, + ERRORBUFFER, + WRITEFUNCTION, + READFUNCTION, + TIMEOUT, + INFILESIZE, + POSTFIELDS, + REFERER, + FTPPORT, + USERAGENT, + LOW_SPEED_LIMIT, + LOW_SPEED_TIME, + RESUME_FROM, + COOKIE, + HTTPHEADER, + HTTPPOST, // struct HTTPPost + SSLCERT, + KEYPASSWD, + CRLF, + QUOTE, + WRITEHEADER, + HEADERDATA, + COOKIEFILE, + SSLVERSION, + TIMECONDITION, + TIMEVALUE, + CUSTOMREQUEST, + STDERR, + POSTQUOTE, + WRITEINFO, + VERBOSE, + HEADER, + NOPROGRESS, + NOBODY, + FAILONERROR, + UPLOAD, + POST, + DIRLISTONLY, + APPEND, + NETRC, + FOLLOWLOCATION, + TRANSFERTEXT, + PUT, + PROGRESSFUNCTION, + PROGRESSDATA, + AUTOREFERER, + PROXYPORT, + POSTFIELDSIZE, + HTTPPROXYTUNNEL, + INTERFACE, + KRBLEVEL, + SSL_VERIFYPEER, + CAINFO, + MAXREDIRS, + FILETIME, + TELNETOPTIONS, + MAXCONNECTS, + CLOSEPOLICY, + FRESH_CONNECT, + FORBID_REUSE, + RANDOM_FILE, + EGDSOCKET, + CONNECTTIMEOUT, + HEADERFUNCTION, + HTTPGET, + SSL_VERIFYHOST, + COOKIEJAR, + SSL_CIPHER_LIST, + HTTP_VERSION, + FTP_USE_EPSV, + SSLCERTTYPE, + SSLKEY, + SSLKEYTYPE, + SSLENGINE, + SSLENGINE_DEFAULT, + DNS_USE_GLOBAL_CACHE, + DNS_CACHE_TIMEOUT, + PREQUOTE, + DEBUGFUNCTION, + DEBUGDATA, + COOKIESESSION, + CAPATH, + BUFFERSIZE, + NOSIGNAL, + SHARE, + PROXYTYPE , + ENCODING, + PRIVATE, + HTTP200ALIASES, + UNRESTRICTED_AUTH, + FTP_USE_EPRT, + HTTPAUTH, + SSL_CTX_FUNCTION, + SSL_CTX_DATA, + FTP_CREATE_MISSING_DIRS, + PROXYAUTH, + FTP_RESPONSE_TIMEOUT, + IPRESOLVE, + MAXFILESIZE, + INFILESIZE_LARGE, + RESUME_FROM_LARGE, + MAXFILESIZE_LARGE, + NETRC_FILE, + USE_SSL, + POSTFIELDSIZE_LARGE, + TCP_NODELAY, + FTPSSLAUTH, + IOCTLFUNCTION, + IOCTLDATA, + FTP_ACCOUNT, + COOKIELIST, + IGNORE_CONTENT_LENGTH, + FTP_SKIP_PASV_IP, + FTP_FILEMETHOD, + LOCALPORT, + LOCALPORTRANGE, + CONNECT_ONLY, + CONV_FROM_NETWORK_FUNCTION, + CONV_TO_NETWORK_FUNCTION, + CONV_FROM_UTF8_FUNCTION, + MAX_SEND_SPEED_LARGE, + MAX_RECV_SPEED_LARGE, + FTP_ALTERNATIVE_TO_USER, + SOCKOPTFUNCTION, + SOCKOPTDATA, + SSL_SESSIONID_CACHE, + SSH_AUTH_TYPES, + SSH_PUBLIC_KEYFILE, + SSH_PRIVATE_KEYFILE, + FTP_SSL_CCC, + TIMEOUT_MS, + CONNECTTIMEOUT_MS, + HTTP_TRANSFER_DECODING, + HTTP_CONTENT_DECODING, + NEW_FILE_PERMS, + NEW_DIRECTORY_PERMS, + POSTREDIR, + SSH_HOST_PUBLIC_KEY_MD5, + OPENSOCKETFUNCTION, + OPENSOCKETDATA, + COPYPOSTFIELDS, + PROXY_TRANSFER_MODE, + SEEKFUNCTION, + SEEKDATA, + CRLFILE, + ISSUERCERT, + ADDRESS_SCOPE, + CERTINFO, + USERNAME, + PASSWORD, + PROXYUSERNAME, + PROXYPASSWORD, + NOPROXY, + TFTP_BLKSIZE, + SOCKS5_GSSAPI_SERVICE, + SOCKS5_GSSAPI_NEC, + PROTOCOLS, + REDIR_PROTOCOLS, + SSH_KNOWNHOSTS, + SSH_KEYFUNCTION, + SSH_KEYDATA, + LASTENTRY + } + [CCode (name = "CURLINFO", cprefix = "CURLINFO_")] + public enum Info { + STRING, + LONG, + DOUBLE, + SLIST, + EFFECTIVE_URL, + RESPONSE_CODE, + TOTAL_TIME, + NAMELOOKUP_TIME, + CONNECT_TIME, + PRETRANSFER_TIME, + SIZE_UPLOAD, + SIZE_DOWNLOAD, + SPEED_DOWNLOAD, + SPEED_UPLOAD, + HEADER_SIZE, + REQUEST_SIZE, + SSL_VERIFYRESULT, + FILETIME, + CONTENT_LENGTH_DOWNLOAD, + CONTENT_LENGTH_UPLOAD, + STARTTRANSFER_TIME, + CONTENT_TYPE, + REDIRECT_TIME, + REDIRECT_COUNT, + PRIVATE, + HTTP_CONNECTCODE, + HTTPAUTH_AVAIL, + PROXYAUTH_AVAIL, + OS_ERRNO, + NUM_CONNECTS, + SSL_ENGINES, + COOKIELIST, + LASTSOCKET, + FTP_ENTRY_PATH, + REDIRECT_URL, + PRIMARY_IP, + APPCONNECT_TIME, + CERTINFO, + CONDITION_UNMET, + LASTONE + } + [CCode (cname = "curl_progress_callback")] + public delegate int ProgressCallback (void* clientp, double dltotal, double dlnow, double ultotal, double ulnow); + [CCode (cname = "CURL_WRITEFUNC_PAUSE")] + public const size_t WRITEFUNC_PAUSE; + [CCode (cname = "curl_write_callback")] + public delegate size_t WriteCallback (char* buffer, size_t size, size_t nitems, void *outstream); + [CCode (cname = "CURL_SEEKFUNC_OK")] + public const int SEEKFUNC_OK; + [CCode (cname = "CURL_SEEKFUNC_FAIL")] + public const int SEEKFUNC_FAIL; + [CCode (cname = "CURL_SEEKFUNC_CANTSEEK")] + public const int SEEKFUNC_CANTSEEK; + [Ccode (cname = "curl_seek_callback")] + public delegate int SeekCallback (void* instream, Curl.Offset offset, int origin); + [CCode (cname = "CURL_READFUNC_ABORT")] + public const size_t READFUNC_ABORT; + [CCode (cname = "CURL_READFUNC_PAUSE")] + public const size_t READFUNC_PAUSE; + [CCode (cname = "curl_read_callback")] + public delegate size_t ReadCallback (char* buffer, size_t size, size_t nitems, void *instream); + [CCode (cname = "curlsocktype", cprefix = "CURLSOCKTYPE_")] + public enum SocketType { + IPCXN, + LAST + } + [CCode (cname = "curl_sockopt_callback")] + public delegate size_t SockoptCallback (void* clientp, Curl.Socket curlfd, Curl.SocketType purpose); + [CCode (cname = "curlioerr", cprefix = "CURLIOE_")] + public enum IOError { + OK, + UNKNOWNCMD, + FAILRESTART, + LAST + } + [CCode (cname = "curliocmd", cprefix = "CURLIOCMD_")] + public enum IOCmd { + NOP, + RESTARTREAD, + LAST + } + [CCode (cname = "curl_ioctl_callback")] + public delegate Curl.IOError IoctlCallback (Curl.EasyHandle handle, int cmd, void* clientp); + [CCode (cname = "curl_malloc_callback")] + public delegate void* MallocCallback (size_t size); + [CCode (cname = "curl_free_callback")] + public delegate void FreeCallback (void* ptr); + [CCode (cname = "curl_realloc_callback")] + public delegate void* ReallocCallback (void* ptr, size_t size); + [CCode (cname = "curl_strdup_callback")] + public delegate string StrdupCallback (string str); + [CCode (cname = "curl_calloc_callback")] + public delegate void* CallocCallback (size_t nmemb, size_t size); + [CCode (cname = "curl_infotype", cprefix = "CURLINFO_")] + public enum InfoType { + TEXT, + HEADER_IN, + HEADER_OUT, + DATA_IN, + DATA_OUT, + SSL_DATA_IN, + SSL_DATA_OUT + } + [CCode (cname = "curl_debug_callback")] + public delegate int DebugCallback (Curl.EasyHandle handle, Curl.InfoType type, [CCode (array_length_type = "size_t")] char[] data, void* userptr); + [CCode (cname = "curl_conv_callback")] + public delegate Curl.Code ConvCallback ([CCode (array_length_type = "size_t")] char[] buffer); + [CCode (cname = "curl_ssl_ctx_callback")] + public delegate Curl.Code SSLCtxCallback (Curl.EasyHandle curl, void* ssl_ctx, void* userptr); + [CCode (cname = "curl_proxytype", cprefix = "CURLPROXY_")] + public enum ProxyType { + HTTP, + HTTP_1_0, + SOCKS4, + SOCKS5, + SOCKS4A, + SOCKS5_HOSTNAME + } + namespace AuthType { + [CCode (cname = "CURLAUTH_NONE")] + public const int NONE; + [CCode (cname = "CURLAUTH_BASIC")] + public const int BASIC; + [CCode (cname = "CURLAUTH_DIGEST")] + public const int DIGEST; + [CCode (cname = "CURLAUTH_GSSNEGOTIATE")] + public const int GSSNEGOTIATE; + [CCode (cname = "CURLAUTH_NTLM")] + public const int NTLM; + [CCode (cname = "CURLAUTH_DIGEST_IE")] + public const int DIGEST_IE; + [CCode (cname = "CURLAUTH_ANY")] + public const int ANY; + [CCode (cname = "CURLAUTH_ANYSAFE")] + public const int ANYSAFE; + } + namespace SSHAuthType { + [CCode (cname = "CURLSSH_AUTH_ANY")] + public const int ANY; + [CCode (cname = "CURLSSH_AUTH_NONE")] + public const int NONE; + [CCode (cname = "CURLSSH_AUTH_PUBLICKEY")] + public const int PUBLICKEY; + [CCode (cname = "CURLSSH_AUTH_PASSWORD")] + public const int PASSWORD; + [CCode (cname = "CURLSSH_AUTH_HOST")] + public const int HOST; + [CCode (cname = "CURLSSH_AUTH_KEYBOARD")] + public const int KEYBOARD; + [CCode (cname = "CURLSSH_AUTH_DEFAULT")] + public const int DEFAULT; + } + public const int ERROR_SIZE; + [CCode (cname = "curl_usessl", cprefix = "CURLUSESSL_")] + public enum UseSSL { + NONE, + TRY, + CONTROL, + ALL + } + [CCode (cname = "curl_ftpccc", cprefix = "CURLFTPSSL_")] + enum FTPSSL { + CCC_NONE, + CCC_PASSIVE, + CCC_ACTIVE + } + [CCode (cname = "curl_ftpauth", cprefix = "CURLFTPAUTH_")] + enum FTPAuthType { + DEFAULT, + SSL, + TLS + } + [CCode (cname = "curl_ftpcreatedir", cprefix = "CURLFTP_CREATE_DIR_")] + enum FTPCreateDir { + NONE, + [CCode (cname = "CURLFTP_CREATE_DIR")] + CREATE, + RETRY + } + [CCode (cname = "curl_ftpmethod", cprefix = "CURLFTPMETHOD_")] + enum FTPMethod { + DEFAULT, + MULTICWD, + NOCWD, + SINGLECWD + } + namespace Proto { + [CCode (cname = "CURLPROTO_HTTP")] + public const int HTTP; + [CCode (cname = "CURLPROTO_HTTPS")] + public const int HTTPS; + [CCode (cname = "CURLPROTO_FTP")] + public const int FTP; + [CCode (cname = "CURLPROTO_FTPS")] + public const int FTPS; + [CCode (cname = "CURLPROTO_SCP")] + public const int SCP; + [CCode (cname = "CURLPROTO_SFTP")] + public const int SFTP; + [CCode (cname = "CURLPROTO_TELNET")] + public const int TELNET; + [CCode (cname = "CURLPROTO_LDAP")] + public const int LDAP; + [CCode (cname = "CURLPROTO_LDAPS")] + public const int LDAPS; + [CCode (cname = "CURLPROTO_DICT")] + public const int DICT; + [CCode (cname = "CURLPROTO_FILE")] + public const int FILE; + [CCode (cname = "CURLPROTO_TFTP")] + public const int TFTP; + [CCode (cname = "CURLPROTO_ALL")] + public const int ALL; + } + public const int IPRESOLVE_WHATEVER; + public const int IPRESOLVE_V4; + public const int IPRESOLVE_V6; + public const int REDIR_GET_ALL; + public const int REDIR_POST_301; + public const int REDIR_POST_302; + public const int REDIR_POST_ALL; + [CCode (cname = "curl_TimeCond", cprefix = "CURL_TIMECOND_")] + public enum TimeCond { + NONE, + IFMODSINCE, + IFUNMODSINCE, + LASTMOD + } + [CCode (cname = "CURLformoption", cprefix = "CURLFORM_")] + public enum FormOption { + COPYNAME, + PTRNAME, + NAMELENGTH, + COPYCONTENTS, + PTRCONTENTS, + CONTENTSLENGTH, + FILECONTENT, + ARRAY, + OBSOLETE, + FILE, + BUFFER, + BUFFERPTR, + BUFFERLENGTH, + CONTENTTYPE, + CONTENTHEADER, + FILENAME, + END, + OBSOLETE2, + STREAM + } + [CCode (cname = "struct curl_forms")] + public struct Forms { + public Curl.FormOption option; + public string value; + } + [CCode (cname = "CURLFORMcode", cprefix = "CURL_FORMADD_")] + public enum FormCode { + OK, + MEMORY, + OPTION_TWICE, + NULL, + UNKNOWN_OPTION, + INCOMPLETE, + ILLEGAL_ARRAY, + DISABLED + } + [CCode (sentinel = "CURLFORM_END")] + public Curl.FormCode formadd (ref Curl.HTTPPost httppost, ref unowned Curl.HTTPPost last_post, ...); + [CCode (cname = "curl_formget_callback")] + public delegate size_t FormgetCallback (void* arg, [CCode (array_size_type = "size_t")] char[] buf); + public int formget (Curl.HTTPPost form, void* arg, Curl.FormgetCallback append); + public unowned string version (); + public void free (void* p); + [Compact] + [CCode (cname = "struct curl_slist", cprefix = "curl_slist_", free_function = "curl_slist_free_all")] + public class SList { + public string data; + public Curl.SList next; + public static SList append (SList? slist, string data); + } + [CCode (cname = "CURLMcode", cprefix = "CURLM_")] + public enum MultiCode { + CALL_MULTI_PERFORM, + CALL_MULTI_SOCKET, + OK, + BAD_HANDLE, + BAD_EASY_HANDLE, + OUT_OF_MEMORY, + INTERNAL_ERROR, + BAD_SOCKET, + UNKNOWN_OPTION + } + [CCode (cname = "CURLMSG", cprefix = "CURLMSG_")] + public enum MessageType { + NONE, + DONE + } + [CCode (cname = "CURLMsg")] + public struct Message { + public Curl.MessageType msg; + public Curl.EasyHandle easy_handle; + [CCode (cname = "data.whatever")] + public void* whatever; + [CCode (cname = "data.result")] + public Curl.Code result; + } + [Compact] + [CCode (cname = "CURLM", cprefix = "curl_multi_", free_function = "curl_multi_cleanup")] + public class MultiHandle { + [CCode (cname = "curl_multi_init")] + public MultiHandle (); + public Curl.MultiCode add_handle (Curl.EasyHandle curl_handle); + public Curl.MultiCode remove_handle (Curl.EasyHandle curl_handle); + public Curl.MultiCode fdset (Posix.fd_set? read_fd_set, Posix.fd_set? write_fd_set, Posix.fd_set? exc_fd_set, out int max_fd); + public Curl.MultiCode perform (out int running_handles); + public unowned Curl.Message info_read (out int msgs_in_queue); + public unowned string strerror (Curl.MultiCode code); + public Curl.MultiCode socket_action (Curl.Socket s, int ev_bitmask, out int running_handles); + public Curl.MultiCode socket_all (out int running_handles); + public Curl.MultiCode timeout (out long milliseconds); + [Printf] + public Curl.MultiCode setopt (Curl.MultiOption option, ...); + public Curl.MultiCode assign (Curl.Socket sockfd, void* sockp); + } + [CCode (has_target = false)] + public delegate int TimerCallback (Curl.MultiHandle multi, long timeout_ms, void* userp); + [SimpleType] + [CCode (cname = "curl_socket_t")] + public struct Socket { + } + [SimpleType] + [CCode (cname = "curl_off_t")] + public struct Offset { + } + [CCode (cname = "CURL_SOCKET_BAD")] + public const Curl.Socket SOCKET_BAD; + [CCode (cname = "CURL_POLL_NONE")] + public const int POLL_NONE; + [CCode (cname = "CURL_POLL_IN")] + public const int POLL_IN; + [CCode (cname = "CURL_POLL_OUT")] + public const int POLL_OUT; + [CCode (cname = "CURL_POLL_INOUT")] + public const int POLL_INOUT; + [CCode (cname = "CURL_POLL_REMOVE")] + public const int POLL_REMOVE; + [CCode (cname = "CURL_SOCKET_TIMEOUT")] + public const int SOCKET_TIMEOUT; + [CCode (cname = "CURL_CSELECT_IN")] + public const int CSELECT_IN; + [CCode (cname = "CURL_CSELECT_OUT")] + public const int CSELECT_OUT; + [CCode (cname = "CURL_CSELECT_ERR")] + public const int CSELECT_ERR; + [CCode (cname = "CURLMoption")] + public enum MultiOption { + SOCKETFUNCTION, + SOCKETDATA, + PIPELINING, + TIMERFUNCTION, + TIMERDATA, + MAXCONNECTS + } + [Compact] + [CCode (cname = "struct curl_httppost", free_function = "curl_formfree")] + public class HTTPPost { + public Curl.HTTPPost next; + [CCode (array_length_cname = "namelength", array_length_type = "long")] + public weak char[] name; + [CCode (array_length_cname = "contentslength", array_length_type = "long")] + public weak char[] contents; + [CCode (array_length_cname = "bufferlength", array_length_type = "long")] + public weak char[] buffer; + public string contenttype; + public Curl.SList contentheader; + public Curl.HTTPPost more; + public long flags; + public string showfilename; + public void* userp; + [CCode (cname = "HTTPPOST_FILENAME")] + public const long FILENAME; + [CCode (cname = "HTTPPOST_READFILE")] + public const long READFILE; + [CCode (cname = "HTTPPOST_PTRCONTENTS")] + public const long PTRCONTENTS; + [CCode (cname = "HTTPPOST_BUFFER")] + public const long BUFFER; + [CCode (cname = "HTTPPOST_PTRBUFFER")] + public const long PTRBUFFER; + [CCode (cname = "HTTPPOST_CALLBACK")] + public const long CALLBACK; + } + [CCode (cname = "LIBCURL_COPYRIGHT")] + public const string COPYRIGHT; + [CCode (cname = "LIBCURL_VERSION")] + public const string VERSION; + [CCode (cname = "LIBCURL_VERSION_MAJOR")] + public const int VERSION_MAJOR; + [CCode (cname = "LIBCURL_VERSION_MINOR")] + public const int VERSION_MINOR; + [CCode (cname = "LIBCURL_VERSION_PATCH")] + public const int VERSION_PATCH; + [CCode (cname = "LIBCURL_VERSION_NUM")] + public const int VERSION_NUM; + [CCode (cname = "LIBCURL_TIMESTAMP")] + public const string TIMESTAMP; +} -- 1.7.9.5