Home | History | Annotate | Line # | Download | only in libldap
fetch.c revision 1.3
      1 /*	$NetBSD: fetch.c,v 1.3 2021/08/14 16:14:55 christos Exp $	*/
      2 
      3 /* fetch.c - routines for fetching data at URLs */
      4 /* $OpenLDAP$ */
      5 /* This work is part of OpenLDAP Software <http://www.openldap.org/>.
      6  *
      7  * Copyright 1999-2021 The OpenLDAP Foundation.
      8  * Portions Copyright 1999-2003 Kurt D. Zeilenga.
      9  * All rights reserved.
     10  *
     11  * Redistribution and use in source and binary forms, with or without
     12  * modification, are permitted only as authorized by the OpenLDAP
     13  * Public License.
     14  *
     15  * A copy of this license is available in the file LICENSE in the
     16  * top-level directory of the distribution or, alternatively, at
     17  * <http://www.OpenLDAP.org/license.html>.
     18  */
     19 /* This work was initially developed by Kurt D. Zeilenga for
     20  * inclusion in OpenLDAP Software.
     21  */
     22 
     23 #include <sys/cdefs.h>
     24 __RCSID("$NetBSD: fetch.c,v 1.3 2021/08/14 16:14:55 christos Exp $");
     25 
     26 #include "portable.h"
     27 
     28 #include <stdio.h>
     29 
     30 #include <ac/stdlib.h>
     31 
     32 #include <ac/string.h>
     33 #include <ac/socket.h>
     34 #include <ac/time.h>
     35 
     36 #ifdef HAVE_FETCH
     37 #include <fetch.h>
     38 #endif
     39 
     40 #include "lber_pvt.h"
     41 #include "ldap_pvt.h"
     42 #include "ldap_config.h"
     43 #include "ldif.h"
     44 
     45 FILE *
     46 ldif_open_url(
     47 	LDAP_CONST char *urlstr )
     48 {
     49 	FILE *url;
     50 
     51 	if( strncasecmp( "file:", urlstr, sizeof("file:")-1 ) == 0 ) {
     52 		char *p;
     53 		urlstr += sizeof("file:")-1;
     54 
     55 		/* we don't check for LDAP_DIRSEP since URLs should contain '/' */
     56 		if ( urlstr[0] == '/' && urlstr[1] == '/' ) {
     57 			urlstr += 2;
     58 			/* path must be absolute if authority is present
     59 			 * technically, file://hostname/path is also legal but we don't
     60 			 * accept a non-empty hostname
     61 			 */
     62 			if ( urlstr[0] != '/' ) {
     63 #ifdef _WIN32
     64 				/* An absolute path in improper file://C:/foo/bar format */
     65 				if ( urlstr[1] != ':' )
     66 #endif
     67 				return NULL;
     68 			}
     69 #ifdef _WIN32
     70 			/* An absolute path in proper file:///C:/foo/bar format */
     71 			if ( urlstr[2] == ':' )
     72 				urlstr++;
     73 #endif
     74 		}
     75 
     76 		p = ber_strdup( urlstr );
     77 
     78 		/* But we should convert to LDAP_DIRSEP before use */
     79 		if ( LDAP_DIRSEP[0] != '/' ) {
     80 			char *s = p;
     81 			while (( s = strchr( s, '/' )))
     82 				*s++ = LDAP_DIRSEP[0];
     83 		}
     84 
     85 		ldap_pvt_hex_unescape( p );
     86 
     87 		url = fopen( p, "rb" );
     88 
     89 		ber_memfree( p );
     90 	} else {
     91 #ifdef HAVE_FETCH
     92 		url = fetchGetURL( (char*) urlstr, "" );
     93 #else
     94 		url = NULL;
     95 #endif
     96 	}
     97 	return url;
     98 }
     99 
    100 int
    101 ldif_fetch_url(
    102     LDAP_CONST char	*urlstr,
    103     char	**valuep,
    104     ber_len_t *vlenp )
    105 {
    106 	FILE *url;
    107 	char buffer[1024];
    108 	char *p = NULL;
    109 	size_t total;
    110 	size_t bytes;
    111 
    112 	*valuep = NULL;
    113 	*vlenp = 0;
    114 
    115 	url = ldif_open_url( urlstr );
    116 
    117 	if( url == NULL ) {
    118 		return -1;
    119 	}
    120 
    121 	total = 0;
    122 
    123 	while( (bytes = fread( buffer, 1, sizeof(buffer), url )) != 0 ) {
    124 		char *newp = ber_memrealloc( p, total + bytes + 1 );
    125 		if( newp == NULL ) {
    126 			ber_memfree( p );
    127 			fclose( url );
    128 			return -1;
    129 		}
    130 		p = newp;
    131 		AC_MEMCPY( &p[total], buffer, bytes );
    132 		total += bytes;
    133 	}
    134 
    135 	fclose( url );
    136 
    137 	if( total == 0 ) {
    138 		char *newp = ber_memrealloc( p, 1 );
    139 		if( newp == NULL ) {
    140 			ber_memfree( p );
    141 			return -1;
    142 		}
    143 		p = newp;
    144 	}
    145 
    146 	p[total] = '\0';
    147 	*valuep = p;
    148 	*vlenp = total;
    149 
    150 	return 0;
    151 }
    152