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