예제 #1
0
파일: ne_socket.c 프로젝트: dveeden/Prestan
/* This implemementation does not attempt to support IPv6 using
 * gethostbyname2 et al.  */
ne_sock_addr *ne_addr_resolve(const char *hostname, int flags)
{
    ne_sock_addr *addr = ne_calloc(sizeof *addr);
#ifdef USE_GETADDRINFO
    struct addrinfo hints = {0};
    char *pnt;
    hints.ai_socktype = SOCK_STREAM;
    if (hostname[0] == '[' && ((pnt = strchr(hostname, ']')) != NULL)) {
	char *hn = ne_strdup(hostname + 1);
	hn[pnt - hostname - 1] = '\0';
#ifdef AI_NUMERICHOST /* this was missing from the RFC2133 API */
	hints.ai_flags = AI_NUMERICHOST;
#endif
        hints.ai_family = AF_INET6;
	addr->errnum = getaddrinfo(hn, NULL, &hints, &addr->result);
	ne_free(hn);
    } else {
        hints.ai_family = ipv6_disabled ? AF_INET : AF_UNSPEC;
	addr->errnum = getaddrinfo(hostname, NULL, &hints, &addr->result);
    }
#else /* Use gethostbyname() */
    unsigned long laddr;
    struct hostent *hp;
    
    laddr = inet_addr(hostname);
    if (laddr == INADDR_NONE) {
	hp = gethostbyname(hostname);
	if (hp == NULL) {
#ifdef WIN32
	    addr->errnum = WSAGetLastError();
#else
            addr->errnum = h_errno;
#endif
	} else if (hp->h_length != sizeof(struct in_addr)) {
	    /* fail gracefully if somebody set RES_USE_INET6 */
	    addr->errnum = NO_RECOVERY;
	} else {
	    size_t n;
	    /* count addresses */
	    for (n = 0; hp->h_addr_list[n] != NULL; n++)
		/* noop */;

	    addr->count = n;
	    addr->addrs = ne_malloc(n * sizeof *addr->addrs);

	    for (n = 0; n < addr->count; n++)
		memcpy(&addr->addrs[n], hp->h_addr_list[n], hp->h_length);
	}
    } else {
	addr->addrs = ne_malloc(sizeof *addr->addrs);
	addr->count = 1;
	memcpy(addr->addrs, &laddr, sizeof *addr->addrs);
    }
#endif
    return addr;
}
예제 #2
0
파일: ne_uri.c 프로젝트: berte/mediaplayer
char *ne_path_escape(const char *path) 
{
    const unsigned char *pnt;
    char *ret, *p;
    size_t count = 0;

    for (pnt = (const unsigned char *)path; *pnt != '\0'; pnt++) {
        count += path_escape_ch(*pnt);
    }

    if (count == 0) {
	return ne_strdup(path);
    }

    p = ret = ne_malloc(strlen(path) + 2 * count + 1);
    for (pnt = (const unsigned char *)path; *pnt != '\0'; pnt++) {
	if (path_escape_ch(*pnt)) {
	    /* Escape it - %<hex><hex> */
	    sprintf(p, "%%%02x", (unsigned char) *pnt);
	    p += 3;
	} else {
	    *p++ = *pnt;
	}
    }
    *p = '\0';
    return ret;
}
예제 #3
0
파일: dirname.c 프로젝트: GCrean/sitecopy
char *
dir_name (const char *path)
{
  char *newpath;
  char *slash;
  int length;			/* Length of result, not including NUL.  */

  slash = strrchr (path, '/');
  if (slash == 0)
    {
      /* File is in the current directory.  */
      path = "";
      length = 0;
    }
  else
    {
      /* Remove any trailing slashes from the result.
      while (slash > path && *slash == '/')
      --slash; */

      length = slash - path + 1;
    }
  newpath = (char *) ne_malloc (length + 1);
  if (newpath == 0)
    return 0;
  strncpy (newpath, path, length);
  newpath[length] = 0;
  return newpath;
}
예제 #4
0
/* Returns a copy certificate of certificate SRC. */
static gnutls_x509_crt x509_crt_copy(gnutls_x509_crt src)
{
    int ret;
    size_t size;
    gnutls_datum tmp;
    gnutls_x509_crt dest;
    
    if (gnutls_x509_crt_init(&dest) != 0) {
        return NULL;
    }

    if (gnutls_x509_crt_export(src, GNUTLS_X509_FMT_DER, NULL, &size) 
        != GNUTLS_E_SHORT_MEMORY_BUFFER) {
        gnutls_x509_crt_deinit(dest);
        return NULL;
    }

    tmp.data = ne_malloc(size);
    ret = gnutls_x509_crt_export(src, GNUTLS_X509_FMT_DER, tmp.data, &size);
    if (ret == 0) {
        tmp.size = size;
        ret = gnutls_x509_crt_import(dest, &tmp, GNUTLS_X509_FMT_DER);
    }

    if (ret) {
        gnutls_x509_crt_deinit(dest);
        dest = NULL;
    }

    ne_free(tmp.data);
    return dest;
}
예제 #5
0
파일: uri.c 프로젝트: lb1a/avfs
/* Escapes the abspath segment of a URI.
 * Returns ne_malloc-allocated string.
 */
char *uri_abspath_escape(const char *abs_path) 
{
    const char *pnt;
    char *ret, *retpos;
    int count = 0;
    for (pnt = abs_path; *pnt != '\0'; pnt++) {
	if (ESCAPE(*pnt)) {
	    count++;
	}
    }
    if (count == 0) {
	return ne_strdup(abs_path);
    }
    /* An escaped character is "%xx", i.e., two MORE
     * characters than the original string */
    retpos = ret = ne_malloc(strlen(abs_path) + 2*count + 1);
    for (pnt = abs_path; *pnt != '\0'; pnt++) {
	if (ESCAPE(*pnt)) {
	    /* Escape it - %<hex><hex> */
	    sprintf(retpos, "%%%02x", (unsigned char) *pnt);
	    retpos += 3;
	} else {
	    /* It's cool */
	    *retpos++ = *pnt;
	}
    }
    *retpos = '\0';
    return ret;
}
예제 #6
0
파일: ne_gnutls.c 프로젝트: GCrean/sitecopy
/* Return the certificate chain sent by the peer, or NULL on error. */
static ne_ssl_certificate *make_peers_chain(gnutls_session sock)
{
    ne_ssl_certificate *current = NULL, *top = NULL;
    const gnutls_datum *certs;
    unsigned int n, count;

    certs = gnutls_certificate_get_peers(sock, &count);
    if (!certs) {
        return NULL;
    }
    
    for (n = 0; n < count; n++) {
        ne_ssl_certificate *cert;
        gnutls_x509_crt x5;

        if (gnutls_x509_crt_init(&x5) ||
            gnutls_x509_crt_import(x5, &certs[n], GNUTLS_X509_FMT_DER)) {
            ne_ssl_cert_free(top);
            return NULL;
        }

        cert = populate_cert(ne_malloc(sizeof *cert), x5);
        
        if (top == NULL) {
            current = top = cert;
        } else {
            current->issuer = cert;
            current = cert;
        }
    }
    
    return top;
}
예제 #7
0
파일: ne_md5.c 프로젝트: GCrean/sitecopy
struct ne_md5_ctx *
ne_md5_create_ctx(void)
{
  struct md5_ctx *ctx = ne_malloc(sizeof *ctx);
  md5_init_ctx(ctx);
  return ctx;
}
예제 #8
0
파일: ne_locks.c 프로젝트: nevermatch/davix
/* this simply registers the accessor for the function. */
static void lk_create(ne_request *req, void *session, 
		       const char *method, const char *uri)
{
    struct lh_req_cookie *lrc = ne_malloc(sizeof *lrc);
    lrc->store = session;
    lrc->submit = NULL;
    ne_set_request_private(req, HOOK_ID, lrc);
}
예제 #9
0
/* Stores the "hostname[:port]" segment */
static void set_hostport(struct host_info *host, unsigned int defaultport)
{
    size_t len = strlen(host->hostname);
    host->hostport = ne_malloc(len + 10);
    strcpy(host->hostport, host->hostname);
    if (host->port != defaultport)
	ne_snprintf(host->hostport + len, 9, ":%u", host->port);
}
예제 #10
0
void ne_set_useragent(ne_session *sess, const char *token)
{
    if (sess->user_agent) ne_free(sess->user_agent);
    sess->user_agent = ne_malloc(strlen(UAHDR) + strlen(AGENT) + 
                                 strlen(token) + 1);
#ifdef HAVE_STPCPY
    strcpy(stpcpy(stpcpy(sess->user_agent, UAHDR), token), AGENT);
#else
    strcat(strcat(strcpy(sess->user_agent, UAHDR), token), AGENT);
#endif
}
예제 #11
0
파일: ne_locks.c 프로젝트: nevermatch/davix
/* Insert 'lock' into lock list *list. */
static void insert_lock(struct lock_list **list, struct ne_lock *lock)
{
    struct lock_list *item = ne_malloc(sizeof *item);
    if (*list != NULL) {
	(*list)->prev = item;
    }
    item->prev = NULL;
    item->next = *list;
    item->lock = lock;
    *list = item;
}
예제 #12
0
static void set_cookie_hdl(void *userdata, const char *value)
{
    char **pairs = pair_string(value, ';', '=', "\"'", " \r\n\t");
    ne_cookie *cook;
    ne_cookie_cache *cache = userdata;
    int n;

    /* Check sanity */
    if (pairs[0] == NULL || pairs[1] == NULL) {
	/* yagaboo */
	return;
    }

    NE_DEBUG(NE_DBG_HTTP, "Got cookie name=%s\n", pairs[0]);

    /* Search for a cookie of this name */
    NE_DEBUG(NE_DBG_HTTP, "Searching for existing cookie...\n");
    for (cook = cache->cookies; cook != NULL; cook = cook->next) {
	if (strcasecmp(cook->name, pairs[0]) == 0) {
	    break;
	}
    }
    
    if (cook == NULL) {
	NE_DEBUG(NE_DBG_HTTP, "New cookie.\n");
	cook = ne_malloc(sizeof *cook);
	memset(cook, 0, sizeof *cook);
	cook->name = ne_strdup(pairs[0]);
	cook->next = cache->cookies;
	cache->cookies = cook;
    } else {
	/* Free the old value */
	ne_free(cook->value);
    }

    cook->value = ne_strdup(pairs[1]);

    for (n = 2; pairs[n] != NULL; n+=2) {
	NE_DEBUG(NE_DBG_HTTP, "Cookie parm %s=%s\n", pairs[n], pairs[n+1]);
	if (strcasecmp(pairs[n], "path") == 0) {
	    cook->path = ne_strdup(pairs[n+1]);
	} else if (strcasecmp(pairs[n], "max-age") == 0) {
	    int t = atoi(pairs[n+1]);
	    cook->expiry = time(NULL) + (time_t)t;
	} else if (strcasecmp(pairs[n], "domain") == 0) {
	    cook->domain = ne_strdup(pairs[n+1]);
	}
    }

    NE_DEBUG(NE_DBG_HTTP, "End of parms.\n");

    pair_string_free(pairs);
}
예제 #13
0
파일: utils.c 프로젝트: Distrotech/neon
int any_2xx_request_body(ne_session *sess, const char *uri)
{
    ne_request *req = ne_request_create(sess, "GET", uri);
#define BSIZE 5000
    char *body = memset(ne_malloc(BSIZE), 'A', BSIZE);
    int ret;
    ne_set_request_body_buffer(req, body, BSIZE);
    ret = ne_request_dispatch(req);
    ne_free(body);
    ONV(ret != NE_OK || ne_get_status(req)->klass != 2,
	("request failed: %s", ne_get_error(sess)));
    ne_request_destroy(req);
    return ret;
}
예제 #14
0
/* Returns the time/date GMT, in RFC1123-type format: eg
 *  Sun, 06 Nov 1994 08:49:37 GMT. */
char *ne_rfc1123_date(time_t anytime) {
    struct tm *gmt;
    char *ret;
    gmt = gmtime(&anytime);
    if (gmt == NULL)
        return NULL;
    ret = ne_malloc(29 + 1); /* dates are 29 chars long */
    /*  it goes: Sun, 06 Nov 1994 08:49:37 GMT */
    ne_snprintf(ret, 30, RFC1123_FORMAT,
                rfc1123_weekdays[gmt->tm_wday], gmt->tm_mday,
                short_months[gmt->tm_mon], 1900 + gmt->tm_year,
                gmt->tm_hour, gmt->tm_min, gmt->tm_sec);

    return ret;
}
예제 #15
0
static void add_hook(struct hook **hooks, const char *id, void_fn fn, void *ud)
{
    struct hook *hk = ne_malloc(sizeof (struct hook)), *pos;

    if (*hooks != NULL) {
	for (pos = *hooks; pos->next != NULL; pos = pos->next)
	    /* nullop */;
	pos->next = hk;
    } else {
	*hooks = hk;
    }

    hk->id = id;
    hk->fn = fn;
    hk->userdata = ud;
    hk->next = NULL;
}
예제 #16
0
ne_inet_addr *ne_sock_peer(ne_socket *sock, unsigned int *port)
{
    union saun {
        struct sockaddr sa;
        struct sockaddr_in sin;
#if defined(USE_GETADDRINFO) && defined(AF_INET6)
        struct sockaddr_in6 sin6;
#endif
    } saun;
    socklen_t len = sizeof saun;
    ne_inet_addr *ia;
    struct sockaddr *sad = (struct sockaddr *)&saun;

    if (getpeername(sock->fd, sad, &len) != 0) {
        set_strerror(sock, errno);
        return NULL;
    }

#if !defined(USE_GETADDRINFO) || !defined(AF_INET6)
    if (sad->sa_family != AF_INET) {
        set_error(sock, _("Socket family not supported"));
        return NULL;
    }
#endif                  

    ia = ne_calloc(sizeof *ia);
#ifdef USE_GETADDRINFO
    ia->ai_addr = ne_malloc(sizeof *ia);
    ia->ai_addrlen = len;
    memcpy(ia->ai_addr, sad, len);
    ia->ai_family = saun.sa.sa_family;
#else
    memcpy(ia, &saun.sin.sin_addr.s_addr, sizeof *ia);
#endif    

#if defined(USE_GETADDRINFO) && defined(AF_INET6)
    *port = ntohs(saun.sa.sa_family == AF_INET ? 
                  saun.sin.sin_port : saun.sin6.sin6_port);
#else
    *port = ntohs(saun.sin.sin_port);
#endif

    return ia;
}
예제 #17
0
파일: socket.c 프로젝트: Ugnis/Far-NetBox
static int large_writes(void)
{
#define LARGE_SIZE (123456)
    struct string str;
    ne_socket *sock;
    ssize_t n;

    str.data = ne_malloc(LARGE_SIZE);
    str.len = LARGE_SIZE;

    for (n = 0; n < LARGE_SIZE; n++)
	str.data[n] = 41 + n % 130;
    
    CALL(begin(&sock, serve_expect, &str));
    CALL(full_write(sock, str.data, str.len));
    
    ne_free(str.data);
    return finish(sock, 1);    
}
예제 #18
0
파일: ne_uri.c 프로젝트: berte/mediaplayer
/* This function directly implements the "Merge Paths" algorithm
 * described in RFC 3986 section 5.2.3. */
static char *merge_paths(const ne_uri *base, const char *path)
{
    const char *p;

    if (base->host && base->path[0] == '\0') {
        return ne_concat("/", path, NULL);
    }
    
    p = strrchr(base->path, '/');
    if (p == NULL) {
        return ne_strdup(path);
    } else {
        size_t len = p - base->path + 1;
        char *ret = ne_malloc(strlen(path) + len + 1);

        memcpy(ret, base->path, len);
        memcpy(ret + len, path, strlen(path) + 1);
        return ret;
    }
}
예제 #19
0
파일: uri.c 프로젝트: lb1a/avfs
char *uri_parent(const char *uri) 
{
    const char *pnt;
    char *ret;
    pnt = uri+strlen(uri)-1;
    while (*(--pnt) != '/' && pnt >= uri) /* noop */;
    if (pnt < uri) {
	/* not a valid absPath */
	return NULL;
    }
    /*  uri    
     *   V
     *   |---|
     *   /foo/bar/
     */
    ret = ne_malloc((pnt - uri) + 2);
    memcpy(ret, uri, (pnt - uri) + 1);
    ret[1+(pnt-uri)] = '\0';
    pnt++;
    return ret;
}
예제 #20
0
파일: uri.c 프로젝트: lb1a/avfs
/* Un-escapes a URI. Returns ne_malloc-allocated URI */
char *uri_unescape(const char *uri) 
{
    const char *pnt;
    char *ret, *retpos, buf[5] = { "0x00\0" };
    retpos = ret = ne_malloc(strlen(uri) + 1);
    for (pnt = uri; *pnt != '\0'; pnt++) {
	if (*pnt == '%') {
	    if (!isxdigit((unsigned char) pnt[1]) || 
		!isxdigit((unsigned char) pnt[2])) {
		/* Invalid URI */
		return NULL;
	    }
	    buf[2] = *++pnt; buf[3] = *++pnt; /* bit faster than memcpy */
	    *retpos++ = (char)strtol(buf, NULL, 16);
	} else {
	    *retpos++ = *pnt;
	}
    }
    *retpos = '\0';
    return ret;
}
예제 #21
0
char *ne_ssl_cert_export(const ne_ssl_certificate *cert)
{
    unsigned char *der;
    size_t len = 0;
    char *ret;

    /* find the length of the DER encoding. */
    if (gnutls_x509_crt_export(cert->subject, GNUTLS_X509_FMT_DER, NULL, &len) != 
        GNUTLS_E_SHORT_MEMORY_BUFFER) {
        return NULL;
    }
    
    der = ne_malloc(len);
    if (gnutls_x509_crt_export(cert->subject, GNUTLS_X509_FMT_DER, der, &len)) {
        ne_free(der);
        return NULL;
    }
    
    ret = ne_base64(der, len);
    ne_free(der);
    return ret;
}
예제 #22
0
파일: socket.c 프로젝트: Ugnis/Far-NetBox
static int large_writev(void)
{
    struct string str;
    ne_socket *sock;
    ssize_t n;
    struct ne_iovec vec[4];

    str.data = ne_malloc(LARGE_SIZE);
    str.len = LARGE_SIZE;

    for (n = 0; n < LARGE_SIZE; n++)
	str.data[n] = 41 + n % 130;
    
    for (n = 0; n < 4; n++) {
        vec[n].base = str.data + n * LARGE_SIZE / 4;
        vec[n].len = LARGE_SIZE / 4;
    }

    CALL(begin(&sock, serve_expect, &str));
    CALL(full_writev(sock, vec, 4));
    
    ne_free(str.data);
    return finish(sock, 1);    
}
예제 #23
0
/* Callback invoked when the SSL server requests a client certificate.  */
static int provide_client_cert(gnutls_session session,
                               const gnutls_datum *req_ca_rdn, int nreqs,
                               const gnutls_pk_algorithm *sign_algos,
                               int sign_algos_length, gnutls_retr_st *st)
{
    ne_session *sess = gnutls_session_get_ptr(session);
    
    if (!sess) {
        return GNUTLS_E_RECEIVED_ILLEGAL_PARAMETER;
    }

    NE_DEBUG(NE_DBG_SSL, "ssl: Client cert provider callback; %d CA names.\n",
             nreqs);

    if (!sess->client_cert && sess->ssl_provide_fn) {
#ifdef HAVE_NEW_DN_API
        const ne_ssl_dname **dns;
        ne_ssl_dname *dnarray;
        unsigned dncount = 0;
        int n;

        dns = ne_malloc(nreqs * sizeof(ne_ssl_dname *));
        dnarray = ne_calloc(nreqs * sizeof(ne_ssl_dname));

        for (n = 0; n < nreqs; n++) {
            gnutls_x509_dn_t dn;

            if (gnutls_x509_dn_init(&dn) == 0) {
                dnarray[n].dn = dn;
                if (gnutls_x509_dn_import(dn, &req_ca_rdn[n]) == 0) {
                    dns[dncount++] = &dnarray[n];
                }
                else {
                    gnutls_x509_dn_deinit(dn);
                }            
            }
        }
       
        NE_DEBUG(NE_DBG_SSL, "ssl: Mapped %d CA names to %u DN objects.\n",
                 nreqs, dncount);

        sess->ssl_provide_fn(sess->ssl_provide_ud, sess, dns, dncount);
        
        for (n = 0; n < nreqs; n++) {
            if (dnarray[n].dn) {
                gnutls_x509_dn_deinit(dnarray[n].dn);
            }
        }

        ne_free(dns);
        ne_free(dnarray);
#else /* HAVE_NEW_DN_API */
        /* Nothing to do here other than pretend no CA names were
         * given, and hope the caller can cope. */
        sess->ssl_provide_fn(sess->ssl_provide_ud, sess, NULL, 0);
#endif
    }

    if (sess->client_cert) {
        gnutls_certificate_type type = gnutls_certificate_type_get(session);
        if (type == GNUTLS_CRT_X509) {
            NE_DEBUG(NE_DBG_SSL, "Supplying client certificate.\n");

            st->type = type;
            st->ncerts = 1;
            st->cert.x509 = &sess->client_cert->cert.subject;
            st->key.x509 = sess->client_cert->pkey;
            
            /* tell GNU TLS not to deallocate the certs. */
            st->deinit_all = 0;
        } else {
            return GNUTLS_E_UNSUPPORTED_CERTIFICATE_TYPE;
        }
    } 
    else {
        NE_DEBUG(NE_DBG_SSL, "No client certificate supplied.\n");
        st->ncerts = 0;
        sess->ssl_cc_requested = 1;
        return 0;
    }

    return 0;
}
예제 #24
0
int ne_sock_connect_ssl(ne_socket *sock, ne_ssl_context *ctx, void *userdata)
{
    int ret;

#if defined(HAVE_OPENSSL)
    SSL *ssl;

    if (seed_ssl_prng()) {
	set_error(sock, _("SSL disabled due to lack of entropy"));
	return NE_SOCK_ERROR;
    }

    /* If runtime library version differs from compile-time version
     * number in major/minor/fix level, abort soon. */
    if ((SSLeay() ^ OPENSSL_VERSION_NUMBER) & 0xFFFFF000) {
        set_error(sock, _("SSL disabled due to library version mismatch"));
        return NE_SOCK_ERROR;
    }

    sock->ssl = ssl = SSL_new(ctx->ctx);
    if (!ssl) {
	set_error(sock, _("Could not create SSL structure"));
	return NE_SOCK_ERROR;
    }
    
    SSL_set_app_data(ssl, userdata);
    SSL_set_mode(ssl, SSL_MODE_AUTO_RETRY);
    SSL_set_fd(ssl, sock->fd);
    sock->ops = &iofns_ssl;
    
    if (ctx->sess)
	SSL_set_session(ssl, ctx->sess);

    ret = SSL_connect(ssl);
    if (ret != 1) {
	error_ossl(sock, ret);
	SSL_free(ssl);
	sock->ssl = NULL;
	return NE_SOCK_ERROR;
    }
#elif defined(HAVE_GNUTLS)
    /* DH and RSA params are set in ne_ssl_context_create */
    gnutls_init(&sock->ssl, GNUTLS_CLIENT);
    gnutls_set_default_priority(sock->ssl);
    gnutls_session_set_ptr(sock->ssl, userdata);
    gnutls_credentials_set(sock->ssl, GNUTLS_CRD_CERTIFICATE, ctx->cred);

    gnutls_transport_set_ptr(sock->ssl, (gnutls_transport_ptr) sock->fd);

    if (ctx->cache.client.data) {
#if defined(HAVE_GNUTLS_SESSION_GET_DATA2)
        gnutls_session_set_data(sock->ssl, 
                                ctx->cache.client.data, 
                                ctx->cache.client.size);
#else
        gnutls_session_set_data(sock->ssl, 
                                ctx->cache.client.data, 
                                ctx->cache.client.len);
#endif
    }
    sock->ops = &iofns_ssl;

    ret = gnutls_handshake(sock->ssl);
    if (ret < 0) {
	error_gnutls(sock, ret);
        return NE_SOCK_ERROR;
    }

    if (!gnutls_session_is_resumed(sock->ssl)) {
        /* New session.  The old method of using the _get_data
         * function seems to be broken with 1.3.0 and later*/
#if defined(HAVE_GNUTLS_SESSION_GET_DATA2)
        gnutls_session_get_data2(sock->ssl, &ctx->cache.client);
#else
        ctx->cache.client.len = 0;
        if (gnutls_session_get_data(sock->ssl, NULL, 
                                    &ctx->cache.client.len) == 0) {
            ctx->cache.client.data = ne_malloc(ctx->cache.client.len);
            gnutls_session_get_data(sock->ssl, ctx->cache.client.data, 
                                    &ctx->cache.client.len);
        }
#endif
    }
#endif
    return 0;
}
예제 #25
0
파일: ne_uri.c 프로젝트: berte/mediaplayer
/* This function directly implements the "Remove Dot Segments"
 * algorithm described in RFC 3986 section 5.2.4. */
static char *remove_dot_segments(const char *path)
{
    char *in, *inc, *out;

    inc = in = ne_strdup(path);
    out = ne_malloc(strlen(path) + 1);
    out[0] = '\0';

    while (in[0]) {
        /* case 2.A: */
        if (strncmp(in, "./", 2) == 0) {
            in += 2;
        } 
        else if (strncmp(in, "../", 3) == 0) {
            in += 3;
        }

        /* case 2.B: */
        else if (strncmp(in, "/./", 3) == 0) {
            in += 2;
        }
        else if (strcmp(in, "/.") == 0) {
            in[1] = '\0';
        }

        /* case 2.C: */
        else if (strncmp(in, "/../", 4) == 0 || strcmp(in, "/..") == 0) {
            char *p;

            /* Make the next character in the input buffer a "/": */
            if (in[3] == '\0') {
                /* terminating "/.." case */
                in += 2;
                in[0] = '/';
            } else {
                /* "/../" prefix case */
                in += 3;
            }

            /* Trim the last component from the output buffer, or
             * empty it. */
            p = strrchr(out, '/');
            if (p) {
                *p = '\0';
            } else {
                out[0] = '\0';
            }
        }

        /* case 2.D: */
        else if (strcmp(in, ".") == 0 || strcmp(in, "..") == 0) {
            in[0] = '\0';
        }

        /* case 2.E */
        else {
            char *p;

            /* Search for the *second* "/" if the leading character is
             * already "/": */
            p = strchr(in + (in[0] == '/'), '/');
            /* Otherwise, copy the whole string */
            if (p == NULL) p = strchr(in, '\0');

            strncat(out, in, p - in);
            in = p;
        }
    }

    ne_free(inc);

    return out;
}
예제 #26
0
/* This implemementation does not attempt to support IPv6 using
 * gethostbyname2 et al.  */
ne_sock_addr *ne_addr_resolve(const char *hostname, int flags)
{
    ne_sock_addr *addr = ne_calloc(sizeof *addr);
#ifdef USE_GETADDRINFO
    struct addrinfo hints = {0};
    char *pnt;
    hints.ai_socktype = SOCK_STREAM;
    if (hostname[0] == '[' && ((pnt = strchr(hostname, ']')) != NULL)) {
	char *hn = ne_strdup(hostname + 1);
	hn[pnt - hostname - 1] = '\0';
#ifdef AI_NUMERICHOST /* added in the RFC2553 API */
	hints.ai_flags = AI_NUMERICHOST;
#endif
        hints.ai_family = AF_INET6;
	addr->errnum = getaddrinfo(hn, NULL, &hints, &addr->result);
	ne_free(hn);
    } else {
#ifdef USE_GAI_ADDRCONFIG /* added in the RFC3493 API */
        hints.ai_flags = AI_ADDRCONFIG;
        hints.ai_family = AF_UNSPEC;
        addr->errnum = getaddrinfo(hostname, NULL, &hints, &addr->result);
#else
        hints.ai_family = ipv6_disabled ? AF_INET : AF_UNSPEC;
	addr->errnum = getaddrinfo(hostname, NULL, &hints, &addr->result);
#endif
    }
#else /* Use gethostbyname() */
    in_addr_t laddr;
    struct hostent *hp;
    struct hostent h;
    char buf[sizeof(struct in_addr) +
             sizeof(struct in_addr *)*2 +
             sizeof(char *)*8 + 384/*namebuffer*/ + 32/* margin */];
    int errn;
    
    laddr = inet_addr(hostname);
    if (laddr == INADDR_NONE) {
        if (ne_find_cached_host(hostname, &laddr)) {
            addr->addrs = ne_malloc(sizeof *addr->addrs);
            addr->count = 1;
            memcpy(addr->addrs, &laddr, sizeof *addr->addrs);
            return addr;
        }
        
        gethostbyname_r(hostname, &h, buf, sizeof(buf), &hp, &errn);
            //hp = gethostbyname(hostname);
	if (hp == NULL) {
#ifdef WIN32
	    addr->errnum = WSAGetLastError();
#else
            addr->errnum = h_errno;
#endif
	    if (!addr->errnum) {
		addr->errnum = NO_RECOVERY;
	    }
	} else if (hp->h_length != sizeof(struct in_addr)) {
	    /* fail gracefully if somebody set RES_USE_INET6 */
	    addr->errnum = NO_RECOVERY;
	} else {
	    size_t n;
	    /* count addresses */
	    for (n = 0; hp->h_addr_list[n] != NULL; n++)
		/* noop */;

	    addr->count = n;
	    addr->addrs = ne_malloc(n * sizeof *addr->addrs);

            if (n > 0)
                ne_add_cached_host(hostname, hp->h_addr_list[0]);
            
	    for (n = 0; n < addr->count; n++)
		memcpy(&addr->addrs[n], hp->h_addr_list[n], hp->h_length);
	}
    } else {
	addr->addrs = ne_malloc(sizeof *addr->addrs);
	addr->count = 1;
	memcpy(addr->addrs, &laddr, sizeof *addr->addrs);
    }
#endif
    return addr;
}
예제 #27
0
파일: ne_md5.c 프로젝트: GCrean/sitecopy
struct ne_md5_ctx *
ne_md5_dup_ctx(struct ne_md5_ctx *ctx)
{
  return memcpy(ne_malloc(sizeof *ctx), ctx, sizeof *ctx);
}