#13795: Initial commit for sflphone-android

includes: libexpat libyaml libdbus-c++ commoncpp ccrtp
          libdbus (from android-4.0.4 sources)

TODO:
- git ignores "/jni/sflphone", sflphone repo should be cloned.
- sflphone-android only needs daemon directory. Ideally it should be possible
to clone it without cloning the whole sflphone project.
into sfl-android (commit 6a0fa7a "#13961: Fix cipher handling" has been used here)
- add pjsip-android project as a git submodule
- sflphone-android needs pjsip android project. Ideally daemon git repository
should not embed pjsip. Instead pjsip should be clone from official repositories.

Considering this, structure should have three distincts git repos:

sflphone-android/.git
sflphone-android/jni/ccrtp-1.8.0-android
sflphone-android/jni/commoncpp2-1.8.1-android
sflphone-android/jni/dbus
sflphone-android/jni/libdbus-c++-0.9.0-android
sflphone-android/jni/libexpat
sflphone-android/jni/libyaml

sflphone-android/jni/sflphone-daemon/.git
sflphone-android/jni/sflphone-daemon/src/audio
sflphone-android/jni/sflphone-daemon/src/config
sflphone-android/jni/sflphone-daemon/src/dbus
sflphone-android/jni/sflphone-daemon/src/history
sflphone-android/jni/sflphone-daemon/src/hooks
sflphone-android/jni/sflphone-daemon/src/iax
sflphone-android/jni/sflphone-daemon/src/sip
sflphone-android/jni/sflphone-daemon/src/video

sflphone-android/jni/pjsip-android/.git

Signed-off-by: Emeric Vigier <emeric.vigier@savoirfairelinux.com>
diff --git a/jni/commoncpp2-1.8.1-android/src/url.cpp b/jni/commoncpp2-1.8.1-android/src/url.cpp
new file mode 100644
index 0000000..8880b79
--- /dev/null
+++ b/jni/commoncpp2-1.8.1-android/src/url.cpp
@@ -0,0 +1,866 @@
+// Copyright (C) 2001-2005 Open Source Telecom Corporation.
+// Copyright (C) 2006-2010 David Sugar, Tycho Softworks.
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+//
+// As a special exception, you may use this file as part of a free software
+// library without restriction.  Specifically, if other files instantiate
+// templates or use macros or inline functions from this file, or you compile
+// this file and link it with other files to produce an executable, this
+// file does not by itself cause the resulting executable to be covered by
+// the GNU General Public License.  This exception does not however
+// invalidate any other reasons why the executable file might be covered by
+// the GNU General Public License.
+//
+// This exception applies only to the code released under the name GNU
+// Common C++.  If you copy code from other releases into a copy of GNU
+// Common C++, as the General Public License permits, the exception does
+// not apply to the code that you add in this way.  To avoid misleading
+// anyone as to the status of such modified files, you must delete
+// this exception notice from them.
+//
+// If you write modifications of your own for GNU Common C++, it is your choice
+// whether to permit this exception to apply to your modifications.
+// If you do not wish that, delete this exception notice.
+//
+
+#include <cc++/config.h>
+#ifdef  CCXX_WITHOUT_EXTRAS
+#include <cc++/export.h>
+#endif
+#include <cc++/file.h>
+#include <cc++/thread.h>
+#include <cc++/exception.h>
+#include <cc++/address.h>
+#include <cc++/socket.h>
+#ifndef CCXX_WITHOUT_EXTRAS
+#include <cc++/export.h>
+#endif
+#include <cc++/url.h>
+
+#include <string>
+#include <cstdio>
+#include <cstdlib>
+#include <fcntl.h>
+#include <cerrno>
+#include <iostream>
+
+#ifdef  WIN32
+#include <io.h>
+#endif
+
+#ifdef HAVE_SSTREAM
+#include <sstream>
+#else
+#include <strstream>
+#endif
+
+#include <cctype>
+
+#ifndef WIN32
+// cause problem on Solaris
+#if !defined(__sun) && !defined(__SUN__)
+#ifdef  HAVE_NET_IF_H
+#include <net/if.h>
+#endif
+#endif
+#include <sys/ioctl.h>
+#endif
+
+#ifdef  CCXX_NAMESPACES
+namespace ost {
+using namespace std;
+#endif
+
+URLStream::URLStream(Family fam, timeout_t to) :
+TCPStream(fam)
+{
+    persistent = false;
+    proxyPort = 0;
+    timeout = to;
+    protocol = protocolHttp1_0;
+    follow = true;
+    proxyAuth = authAnonymous;
+    encoding = encodingBinary;
+    proxyUser = proxyPasswd = NULL;
+    auth = authAnonymous;
+    cookie = agent = pragma = referer = user = password = NULL;
+    localif = NULL;
+    setError(false);
+}
+
+int URLStream::aRead(char *buffer, size_t len, timeout_t timer)
+{
+    return readData(buffer, len, 0, timer);
+}
+
+int URLStream::aWrite(char *buffer, size_t len, timeout_t timer)
+{
+    return writeData(buffer, len, timer);
+}
+
+void URLStream::httpHeader(const char *header, const char *value)
+{
+}
+
+char **URLStream::extraHeader(void)
+{
+    return NULL;
+}
+
+int URLStream::underflow(void)
+{
+    ssize_t len = 0, rlen;
+    char *buf;
+
+    if(bufsize == 1)
+        return TCPStream::underflow();
+
+    if(!gptr())
+        return EOF;
+
+    if(gptr() < egptr())
+        return (unsigned char)*gptr();
+
+    rlen = (ssize_t)((gbuf + bufsize) - eback());
+    if(encoding == encodingChunked) {
+        buf = (char *)eback();
+        *buf = '\n';
+        while(!chunk && (*buf == '\n' || *buf == '\r')) {
+            *buf = 0;
+            len = readLine(buf, rlen, timeout);
+        }
+        if(len) {
+            if(!chunk)
+                chunk = strtol(buf, NULL, 16);
+
+            if(rlen > (int)chunk)
+                rlen = chunk;
+        }
+        else
+            rlen = -1;
+    }
+
+    if(rlen > 0) {
+        if(Socket::state == STREAM)
+            rlen = aRead((char *)eback(), rlen, timeout);
+        else if(timeout) {
+            if(Socket::isPending(pendingInput, timeout))
+                rlen = readData(eback(), rlen);
+            else
+                rlen = -1;
+        }
+        else
+            rlen = readData(eback(), rlen);
+    }
+    if(encoding == encodingChunked && rlen > 0)
+        chunk -= rlen;
+
+    if(rlen < 1) {
+        if(rlen < 0)
+            clear(ios::failbit | rdstate());
+        return EOF;
+    }
+    setg(eback(), eback(), eback() + rlen);
+    return (unsigned char)*gptr();
+}
+
+void URLStream::setProxy(const char *host, tpport_t port)
+{
+    switch(family) {
+#ifdef  CCXX_IPV6
+    case IPV6:
+        v6proxyHost = host;
+        break;
+#endif
+    case IPV4:
+        proxyHost = host;
+        break;
+    default:
+        proxyPort = 0;
+        return;
+    }
+    proxyPort = port;
+}
+
+URLStream::Error URLStream::submit(const char *path, const char **vars, size_t buf)
+{
+    Error status = errInvalid, saved;
+
+    if(!strnicmp(path, "http:", 5)) {
+        urlmethod = methodHttpGet;
+        path = strchr(path + 5, '/');
+        status = sendHTTPHeader(path, vars, buf);
+    }
+    if((status == errInvalid || status == errTimeout)) {
+        if(Socket::state != AVAILABLE)
+            close();
+        return status;
+    }
+    else {
+        saved = status;
+        status = getHTTPHeaders();
+        if(status == errSuccess)
+            return saved;
+        else if(status == errTimeout) {
+            if(Socket::state != AVAILABLE)
+                close();
+        }
+        return status;
+    }
+}
+
+URLStream::Error URLStream::post(const char *path, MIMEMultipartForm &form, size_t buf)
+{
+    Error status = errInvalid, saved;
+    if(!strnicmp(path, "http:", 5)) {
+        urlmethod = methodHttpPostMultipart;
+        path = strchr(path + 5, '/');
+        status = sendHTTPHeader(path, (const char **)form.getHeaders(), buf);
+    }
+
+    if(status == errInvalid || status == errTimeout) {
+        if(Socket::state != AVAILABLE)
+            close();
+        return status;
+    }
+    saved = status;
+    status = getHTTPHeaders();
+    if(status == errSuccess) {
+        form.body(dynamic_cast<std::ostream *>(this));
+        return saved;
+    }
+    if(status == errTimeout) {
+        if(Socket::state != AVAILABLE)
+            close();
+    }
+    return status;
+}
+
+URLStream::Error URLStream::post(const char *path, const char **vars, size_t buf)
+{
+    Error status = errInvalid, saved;
+
+    if(!strnicmp(path, "http:", 5)) {
+        urlmethod = methodHttpPost;
+        path = strchr(path + 5, '/');
+        status = sendHTTPHeader(path, vars, buf);
+    }
+
+    if((status == errInvalid || status == errTimeout)) {
+        if(Socket::state != AVAILABLE)
+            close();
+        return status;
+    }
+    saved = status;
+    status = getHTTPHeaders();
+    if(status == errSuccess)
+        return saved;
+    if(status == errTimeout) {
+        if(Socket::state != AVAILABLE)
+            close();
+    }
+    return status;
+}
+
+
+URLStream::Error URLStream::head(const char *path, size_t buf)
+{
+    Error status = errInvalid, saved;
+
+    if(!strnicmp(path, "http:", 5)) {
+        urlmethod = methodHttpGet;
+        path = strchr(path + 5, '/');
+        status = sendHTTPHeader(path, NULL, buf);
+    }
+
+    if((status == errInvalid || status == errTimeout)) {
+        if(Socket::state != AVAILABLE)
+            close();
+        return status;
+    }
+    else {
+        saved = status;
+        status = getHTTPHeaders();
+        if(status == errSuccess)
+            return saved;
+        else if(status == errTimeout) {
+            if(Socket::state != AVAILABLE)
+                close();
+        }
+        return status;
+    }
+}
+
+URLStream &URLStream::getline(char *buffer, size_t size)
+{
+    size_t len;
+
+    *buffer = 0;
+    // TODO: check, we mix use of streambuf with Socket::readLine...
+    iostream::getline(buffer, (unsigned long)size);
+    len = strlen(buffer);
+
+    while(len) {
+        if(buffer[len - 1] == '\r' || buffer[len - 1] == '\n')
+            buffer[len - 1] = 0;
+        else
+            break;
+        --len;
+    }
+    return *this;
+}
+
+URLStream::Error URLStream::get(size_t buffer)
+{
+    String path = String("http://") + m_host;
+
+    if ( m_address.operator[](0) != '/' )
+        path += "/";
+
+    path += m_address;
+
+    return get(path.c_str(), buffer);
+}
+
+URLStream::Error URLStream::get(const char *urlpath, size_t buf)
+{
+    const char *path = urlpath;
+    Error status = errInvalid, saved;
+
+    urlmethod = methodFileGet;
+
+    if(Socket::state != AVAILABLE)
+        close();
+
+
+    if(!strnicmp(path, "file:", 5)) {
+        urlmethod = methodFileGet;
+        path += 5;
+    }
+    else if(!strnicmp(path, "http:", 5)) {
+        urlmethod = methodHttpGet;
+        path = strchr(path + 5, '/');
+    }
+    switch(urlmethod) {
+    case methodHttpGet:
+        status = sendHTTPHeader(path, NULL, buf);
+        break;
+    case methodFileGet:
+        if(so != INVALID_SOCKET)
+            ::close((int)so);
+        so = ::open(path, O_RDWR);
+        if(so == INVALID_SOCKET)
+            so = ::open(path, O_RDONLY);
+        // FIXME: open return the same handle type as socket call ??
+        if(so == INVALID_SOCKET)
+            return errInvalid;
+        Socket::state = STREAM;
+        allocate(buf);
+        return errSuccess;
+    default:
+                break;
+    }
+
+
+    if((status == errInvalid || status == errTimeout)) {
+        if(Socket::state != AVAILABLE)
+            close();
+        return status;
+    }
+    else {
+        saved = status;
+        status = getHTTPHeaders();
+        if(status == errSuccess)
+            return saved;
+        else if(status == errTimeout) {
+            if(Socket::state != AVAILABLE)
+                close();
+        }
+        return status;
+    }
+}
+
+URLStream::Error URLStream::getHTTPHeaders()
+{
+    char buffer[512];
+    size_t buf = sizeof(buffer);
+    Error status = errSuccess;
+    char *cp, *ep;
+    ssize_t len = 1;
+    char nc = 0;
+
+    chunk = ((unsigned)-1) / 2;
+    encoding = encodingBinary;
+    while(len > 0) {
+        len = readLine(buffer, buf, timeout);
+        if(len < 1)
+            return errTimeout;
+
+        // FIXME: for multiline syntax ??
+        if(buffer[0] == ' ' || buffer[0] == '\r' || buffer[0] == '\n')
+            break;
+        cp = strchr(buffer, ':');
+        if(!cp)
+            continue;
+        *(cp++) = 0;
+        while(*cp == ' ' || *cp == '\t')
+            ++cp;
+        ep = strchr(cp, '\n');
+        if(!ep)
+            ep = &nc;
+        while(*ep == '\n' || *ep == '\r' || *ep == ' ') {
+            *ep = 0;
+            if((--ep) < cp)
+                break;
+        }
+        if(!stricmp(buffer, "Transfer-Encoding")) {
+            if(!stricmp(cp, "chunked")) {
+                chunk = 0;
+                encoding = encodingChunked;
+            }
+        }
+        httpHeader(buffer, cp);
+    }
+    return status;
+}
+
+
+void URLStream::close(void)
+{
+    if(Socket::state == AVAILABLE)
+        return;
+
+    endStream();
+    so = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
+    if(so != INVALID_SOCKET)
+        Socket::state = AVAILABLE;
+}
+
+URLStream::Error URLStream::sendHTTPHeader(const char *url, const char **vars, size_t buf)
+{
+    // TODO: implement authentication
+    char reloc[4096];
+    // "//" host ":" port == max 2 + 128 + 1 + 5 + 1(\0) = 137, rounded 140
+    char host[140];
+    // TODO: add support for //user:pass@host:port/ syntax
+#ifdef HAVE_SSTREAM
+    ostringstream str;
+#else
+    char buffer[4096];
+    strstream str(buffer, sizeof(buffer), ios::out);
+#endif
+    char *ref, *cp, *ep;
+    char *hp;
+    const char *uri = "/";
+    int count = 0;
+    size_t len = 0;
+    tpport_t port = 80;
+    const char **args = vars;
+    const char *var;
+    bool lasteq = true;
+
+    struct servent *svc;
+
+retry:
+#ifdef HAVE_SSTREAM
+    str.str("");
+#else
+    buffer[0] = 0;
+    str.seekp(0);
+#endif
+
+    setString(host, sizeof(host), url);
+reformat:
+    hp = strchr(host, '/');
+    if(!hp) {
+        host[0] = '/';
+        setString(host + 1, sizeof(host) - 1, url);
+        goto reformat;
+    }
+    while(*hp == '/')
+        ++hp;
+    cp = strchr(hp, '/');
+    if (cp) *cp = 0;
+    ep = strrchr(hp, ':');
+    if(ep) {
+        *ep = 0;
+        ++ep;
+        if(isdigit(*ep))
+            port = atoi(ep);
+        else {
+            Socket::mutex.enter();
+            svc = getservbyname(ep, "tcp");
+            if(svc)
+                port = ntohs(svc->s_port);
+            Socket::mutex.leave();
+        }
+    }
+
+    if(!proxyPort) {
+        const char* ep1 = url;
+        while(*ep1 == '/')
+            ++ep1;
+        ep1 = strchr(ep1, '/');
+        if(ep1)
+                uri = ep1;
+    }
+
+    switch(urlmethod) {
+    case methodHttpGet:
+        str << "GET ";
+        if(proxyPort) {
+            str << "http:" << url;
+            if(!cp) str << '/';
+        }
+        else
+            str << uri;
+        break;
+    case methodHttpPost:
+    case methodHttpPostMultipart:
+        str << "POST ";
+        if(proxyPort) {
+            str << "http:" << url;
+            if(!cp) str << '/';
+        }
+        else
+            str << uri;
+        break;
+    default:
+        return errInvalid;
+    }
+
+    if(vars && urlmethod == methodHttpGet) {
+        str << "?";
+        while(*vars) {
+            if(count++ && lasteq)
+                str << "&";
+            str << *vars;
+            if(!lasteq)
+                lasteq = true;
+            else if(strchr(*vars, '='))
+                lasteq = true;
+            else {
+                lasteq = false;
+                str << "=";
+            }
+            ++vars;
+        }
+    }
+
+    switch(protocol) {
+    case protocolHttp1_1:
+        str << " HTTP/1.1" << "\r\n";
+        break;
+    case protocolHttp1_0:
+        str << " HTTP/1.0" << "\r\n";
+        break;
+    }
+
+    if ( m_host.empty() )
+        m_host = hp;
+
+    str << "Host: " << hp << "\r\n";
+    if(agent)
+        str << "User-Agent: " << agent << "\r\n";
+
+    if(cookie)
+        str << "Cookie: " << cookie << "\r\n";
+
+    if(pragma)
+        str << "Pragma: " << pragma << "\r\n";
+
+    if(referer)
+        str << "Referer: " << referer << "\r\n";
+
+    switch(auth) {
+    case authBasic:
+        str << "Authorization: Basic ";
+        snprintf(reloc, 64, "%s:%s", user, password);
+        b64Encode(reloc, reloc + 64, 128);
+        str << reloc + 64 << "\r\n";
+    case authAnonymous:
+        break;
+    }
+
+    switch(proxyAuth) {
+    case authBasic:
+        str << "Proxy-Authorization: Basic ";
+        snprintf(reloc, 64, "%s:%s", proxyUser, proxyPasswd);
+        b64Encode(reloc, reloc + 64, 128);
+        str << reloc + 64 << "\r\n";
+        str << "Proxy-Connection: close" << "\r\n";
+    case authAnonymous:
+        break;
+    }
+
+
+    str << "Connection: close\r\n";
+    char **add = extraHeader();
+    if(add) {
+        while(*add) {
+            str << *(add++) << ": ";
+            str << *(add++) << "\r\n";
+        }
+    }
+    if(vars)
+        switch(urlmethod) {
+        case methodHttpPost:
+            while(*args) {
+                var = *args;
+                if(count++ || !strchr(var, '='))
+                    len += strlen(var) + 1;
+                else
+                    len = strlen(var);
+                ++args;
+            }
+            count = 0;
+            len += 2;
+            str << "Content-Type: application/x-www-form-urlencoded" << "\r\n";
+            str << "Content-Length: " << (unsigned)len << "\r\n";
+            break;
+        case methodHttpPostMultipart:
+            while(*args)
+                str << *(args++) << "\r\n";
+        default:
+            break;
+        }
+
+    str << "\r\n";
+#ifdef HAVE_SSTREAM
+    // sstream does not want ends
+#else
+    str << ends;
+#endif
+
+    if(Socket::state != AVAILABLE)
+            close();
+#ifndef WIN32
+#ifdef  SOICGIFINDEX
+    if (localif != NULL) {
+        struct ifreq ifr;
+
+        switch(family) {
+#ifdef  CCXX_IPV6
+        case IPV6:
+            sockaddr_in6 source;
+            int alen = sizeof(source);
+
+            memset(&ifr, 0, sizeof(ifr));
+            setString(ifr.ifr_name, sizeof(ifr.ifr_name), localif);
+            if (ioctl(so, SIOCGIFINDEX, &ifr) < 0)
+                return errInterface;
+            else {
+                if (setsockopt(so, SOL_SOCKET, SO_BINDTODEVICE, &ifr, sizeof(ifr)) == -1)
+                    return errInterface;
+                else if(getsockname(so, (struct sockaddr*)&source,(socklen_t *) &alen) == -1)
+                    return errInterface;
+                else if (bind(so, (struct sockaddr*)&source, sizeof(source)) == -1)
+                    return errInterface;
+                else
+                    source.sin6_port = 0;
+            }
+
+            break;
+#endif
+        case IPV4:
+            sockaddr_in source;
+            int alen = sizeof(source);
+
+            memset(&ifr, 0, sizeof(ifr));
+            setString(ifr.ifr_name, sizeof(ifr.ifr_name), localif);
+            if (ioctl(so, SIOCGIFINDEX, &ifr) < 0)
+                return errInterface;
+            else {
+                if (setsockopt(so, SOL_SOCKET, SO_BINDTODEVICE, &ifr, sizeof(ifr)) == -1)
+                    return errInterface;
+                else if(getsockname(so, (struct sockaddr*)&source,(socklen_t *) &alen) == -1)
+                    return errInterface;
+                else if (bind(so, (struct sockaddr*)&source, sizeof(source)) == -1)
+                    return errInterface;
+                else
+                    source.sin_port = 0;
+            }
+        }
+
+    }
+#endif
+#endif
+
+    if(proxyPort) {
+        switch(family) {
+#ifdef  CCXX_IPV6
+        case IPV6:
+            connect(v6proxyHost, proxyPort, (unsigned)buf);
+            break;
+#endif
+        case IPV4:
+                connect(proxyHost, proxyPort, (unsigned)buf);
+            break;
+        }
+    }
+    else {
+        switch(family) {
+#ifdef  CCXX_IPV6
+        case IPV6:
+            connect(IPV6Host(hp), port, (unsigned)buf);
+            break;
+#endif
+        case IPV4:
+            connect(IPV4Host(hp), port, (unsigned)buf);
+        }
+    }
+
+    if(!isConnected())
+        return errUnreachable;
+
+    // FIXME: send (or write) can send less than len bytes
+    // use stream funcion ??
+#ifdef HAVE_SSTREAM
+    writeData(str.str().c_str(), _IOLEN64 str.str().length());
+#else
+    writeData(str.str().c_str(), _IOLEN64 str.str().length());
+#endif
+
+    if(urlmethod == methodHttpPost && vars) {
+#ifdef HAVE_SSTREAM
+            str.str() = "";
+#else
+        str.seekp(0);
+#endif
+        bool sep = false;
+        while(*vars) {
+            if(sep)
+                writeData("&", 1);
+            else
+                sep = true;
+            var = *vars;
+            if(!strchr(var, '=')) {
+                snprintf(reloc, sizeof(reloc), "%s=%s", var, *(++vars));
+                writeData(reloc, strlen(reloc));
+            }
+            else
+                writeData(var, strlen(var));
+            ++vars;
+        }
+        writeData("\r\n", 2);
+    }
+
+cont:
+#ifdef HAVE_SSTREAM
+    char buffer[4096];
+#else
+    // nothing here
+#endif
+
+    len = readLine(buffer, sizeof(buffer) - 1, timeout);
+    if(len < 1)
+        return errTimeout;
+
+    if(strnicmp(buffer, "HTTP/", 5))
+        return errInvalid;
+
+    ref = strchr(buffer, ' ');
+    while(*ref == ' ')
+        ++ref;
+
+    switch(atoi(ref)) {
+        default:
+        return errInvalid;
+    case 100:
+        goto cont;
+        case 200:
+        return errSuccess;
+        case 401:
+        return errUnauthorized;
+        case 403:
+        return errForbidden;
+        case 404:
+        return errMissing;
+        case 405:
+        return errDenied;
+        case 500:
+        case 501:
+        case 502:
+        case 503:
+        case 504:
+        case 505:
+        return errFailure;
+        case 300:
+        case 301:
+        case 302:
+        break;
+    }
+    if(!follow)
+        return errRelocated;
+    for(;;) {
+        len = readLine(reloc, sizeof(reloc), timeout);
+        if(len < 1)
+            return errTimeout;
+        if(!strnicmp(reloc, "Location: ", 10))
+            break;
+    }
+    if(!strnicmp(reloc + 10, "http:", 5)) {
+        url = strchr(reloc + 15, '/');
+        ep = (char *)(url + strlen(url) - 1);
+        while(*ep == '\r' || *ep == '\n')
+            *(ep--) = 0;
+    }
+    else
+        url = reloc + 10;
+    close();
+    goto retry;
+}
+
+void URLStream::setAuthentication(Authentication a, const char *value)
+{
+    auth = a;
+    if (auth != authAnonymous) {
+        if(!user)
+            user = "anonymous";
+        if(!password)
+            password = "";
+    }
+}
+
+void URLStream::setProxyAuthentication(Authentication a, const char *value)
+{
+    proxyAuth = a;
+    if (proxyAuth != authAnonymous) {
+        if(!proxyUser)
+            proxyUser = "anonymous";
+
+        if(!proxyPasswd)
+            proxyPasswd = "";
+    }
+}
+
+void URLStream::setReferer(const char *str)
+{
+    if(!str)
+        return;
+    referer = str;
+}
+
+#ifdef  CCXX_NAMESPACES
+}
+#endif
+
+/** EMACS **
+ * Local variables:
+ * mode: c++
+ * c-basic-offset: 4
+ * End:
+ */