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