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