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