xref: /netbsd-src/external/bsd/openldap/dist/libraries/libldap/fetch.c (revision 549b59ed3ccf0d36d3097190a0db27b770f3a839)
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 *
ldif_open_url(LDAP_CONST char * urlstr)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
ldif_fetch_url(LDAP_CONST char * urlstr,char ** valuep,ber_len_t * vlenp)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