fetch.c revision 1.4 1 /* $NetBSD: fetch.c,v 1.4 2025/09/05 21:16:21 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-2024 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.4 2025/09/05 21:16:21 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 if ( p == NULL )
78 return NULL;
79
80 /* But we should convert to LDAP_DIRSEP before use */
81 if ( LDAP_DIRSEP[0] != '/' ) {
82 char *s = p;
83 while (( s = strchr( s, '/' )))
84 *s++ = LDAP_DIRSEP[0];
85 }
86
87 ldap_pvt_hex_unescape( p );
88
89 url = fopen( p, "rb" );
90
91 ber_memfree( p );
92 } else {
93 #ifdef HAVE_FETCH
94 url = fetchGetURL( (char*) urlstr, "" );
95 #else
96 url = NULL;
97 #endif
98 }
99 return url;
100 }
101
102 int
103 ldif_fetch_url(
104 LDAP_CONST char *urlstr,
105 char **valuep,
106 ber_len_t *vlenp )
107 {
108 FILE *url;
109 char buffer[1024];
110 char *p = NULL;
111 size_t total;
112 size_t bytes;
113
114 *valuep = NULL;
115 *vlenp = 0;
116
117 url = ldif_open_url( urlstr );
118
119 if( url == NULL ) {
120 return -1;
121 }
122
123 total = 0;
124
125 while( (bytes = fread( buffer, 1, sizeof(buffer), url )) != 0 ) {
126 char *newp = ber_memrealloc( p, total + bytes + 1 );
127 if( newp == NULL ) {
128 ber_memfree( p );
129 fclose( url );
130 return -1;
131 }
132 p = newp;
133 AC_MEMCPY( &p[total], buffer, bytes );
134 total += bytes;
135 }
136
137 fclose( url );
138
139 if( total == 0 ) {
140 char *newp = ber_memrealloc( p, 1 );
141 if( newp == NULL ) {
142 ber_memfree( p );
143 return -1;
144 }
145 p = newp;
146 }
147
148 p[total] = '\0';
149 *valuep = p;
150 *vlenp = total;
151
152 return 0;
153 }
154