fetch.c 2.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148
  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-2024 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. #include "portable.h"
  21. #include <stdio.h>
  22. #include <ac/stdlib.h>
  23. #include <ac/string.h>
  24. #include <ac/socket.h>
  25. #include <ac/time.h>
  26. #ifdef HAVE_FETCH
  27. #include <fetch.h>
  28. #endif
  29. #include "lber_pvt.h"
  30. #include "ldap_pvt.h"
  31. #include "ldap_config.h"
  32. #include "ldif.h"
  33. FILE *
  34. ldif_open_url(
  35. LDAP_CONST char *urlstr )
  36. {
  37. FILE *url;
  38. if( strncasecmp( "file:", urlstr, sizeof("file:")-1 ) == 0 ) {
  39. char *p;
  40. urlstr += sizeof("file:")-1;
  41. /* we don't check for LDAP_DIRSEP since URLs should contain '/' */
  42. if ( urlstr[0] == '/' && urlstr[1] == '/' ) {
  43. urlstr += 2;
  44. /* path must be absolute if authority is present
  45. * technically, file://hostname/path is also legal but we don't
  46. * accept a non-empty hostname
  47. */
  48. if ( urlstr[0] != '/' ) {
  49. #ifdef _WIN32
  50. /* An absolute path in improper file://C:/foo/bar format */
  51. if ( urlstr[1] != ':' )
  52. #endif
  53. return NULL;
  54. }
  55. #ifdef _WIN32
  56. /* An absolute path in proper file:///C:/foo/bar format */
  57. if ( urlstr[2] == ':' )
  58. urlstr++;
  59. #endif
  60. }
  61. p = ber_strdup( urlstr );
  62. if ( p == NULL )
  63. return NULL;
  64. /* But we should convert to LDAP_DIRSEP before use */
  65. if ( LDAP_DIRSEP[0] != '/' ) {
  66. char *s = p;
  67. while (( s = strchr( s, '/' )))
  68. *s++ = LDAP_DIRSEP[0];
  69. }
  70. ldap_pvt_hex_unescape( p );
  71. url = fopen( p, "rb" );
  72. ber_memfree( p );
  73. } else {
  74. #ifdef HAVE_FETCH
  75. url = fetchGetURL( (char*) urlstr, "" );
  76. #else
  77. url = NULL;
  78. #endif
  79. }
  80. return url;
  81. }
  82. int
  83. ldif_fetch_url(
  84. LDAP_CONST char *urlstr,
  85. char **valuep,
  86. ber_len_t *vlenp )
  87. {
  88. FILE *url;
  89. char buffer[1024];
  90. char *p = NULL;
  91. size_t total;
  92. size_t bytes;
  93. *valuep = NULL;
  94. *vlenp = 0;
  95. url = ldif_open_url( urlstr );
  96. if( url == NULL ) {
  97. return -1;
  98. }
  99. total = 0;
  100. while( (bytes = fread( buffer, 1, sizeof(buffer), url )) != 0 ) {
  101. char *newp = ber_memrealloc( p, total + bytes + 1 );
  102. if( newp == NULL ) {
  103. ber_memfree( p );
  104. fclose( url );
  105. return -1;
  106. }
  107. p = newp;
  108. AC_MEMCPY( &p[total], buffer, bytes );
  109. total += bytes;
  110. }
  111. fclose( url );
  112. if( total == 0 ) {
  113. char *newp = ber_memrealloc( p, 1 );
  114. if( newp == NULL ) {
  115. ber_memfree( p );
  116. return -1;
  117. }
  118. p = newp;
  119. }
  120. p[total] = '\0';
  121. *valuep = p;
  122. *vlenp = total;
  123. return 0;
  124. }