ocread.c 5.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202
  1. /* Copyright 2009, UCAR/Unidata and OPeNDAP, Inc.
  2. See the COPYRIGHT file for more information. */
  3. #include "config.h"
  4. #include <sys/stat.h>
  5. #ifdef HAVE_UNISTD_H
  6. #include <unistd.h>
  7. #endif
  8. #include <fcntl.h>
  9. #include <sys/types.h>
  10. #ifdef HAVE_NETINET_IN_H
  11. #include <netinet/in.h>
  12. #endif
  13. #include "ocinternal.h"
  14. #include "ocdebug.h"
  15. #include "ochttp.h"
  16. #include "ocread.h"
  17. #include "ocrc.h"
  18. #include "occurlfunctions.h"
  19. extern int oc_curl_file_supported;
  20. /*Forward*/
  21. static int readpacket(CURL*, OCURI*, OCbytes*, OCdxd, long*);
  22. static int readfile(char* path, char* suffix, OCbytes* packet);
  23. static int readfiletofile(char* path, char* suffix, FILE* stream, unsigned long*);
  24. int
  25. readDDS(OCstate* state, OCtree* tree)
  26. {
  27. int stat = OC_NOERR;
  28. long lastmodified = -1;
  29. ocurisetconstraints(state->uri,tree->constraint);
  30. ocset_user_password(state);
  31. stat = readpacket(state->curl,state->uri,state->packet,OCDDS,
  32. &lastmodified);
  33. if(stat == OC_NOERR) state->ddslastmodified = lastmodified;
  34. return stat;
  35. }
  36. int
  37. readDAS(OCstate* state, OCtree* tree)
  38. {
  39. int stat = OC_NOERR;
  40. ocurisetconstraints(state->uri,tree->constraint);
  41. stat = readpacket(state->curl,state->uri,state->packet,OCDAS,NULL);
  42. return stat;
  43. }
  44. int
  45. readversion(CURL* curl, OCURI* url, OCbytes* packet)
  46. {
  47. return readpacket(curl,url,packet,OCVER,NULL);
  48. }
  49. static
  50. char* ocdxdextension[] ={
  51. ".dds", /*OCDDS*/
  52. ".das", /*OCDAS*/
  53. ".dods", /*OCDATADDS*/
  54. ".vers", /*OCVERS*/
  55. };
  56. static int
  57. readpacket(CURL* curl,OCURI* url,OCbytes* packet,OCdxd dxd,long* lastmodified)
  58. {
  59. int stat = OC_NOERR;
  60. int fileprotocol = 0;
  61. char* suffix = ocdxdextension[dxd];
  62. char* fetchurl = NULL;
  63. fileprotocol = (strcmp(url->protocol,"file")==0);
  64. if(fileprotocol && !oc_curl_file_supported) {
  65. /* Short circuit file://... urls*/
  66. /* We do this because the test code always needs to read files*/
  67. fetchurl = ocuribuild(url,NULL,NULL,0);
  68. stat = readfile(fetchurl,suffix,packet);
  69. } else {
  70. int flags = 0;
  71. if(!fileprotocol) flags |= OCURICONSTRAINTS;
  72. flags |= OCURIENCODE;
  73. fetchurl = ocuribuild(url,NULL,suffix,flags);
  74. MEMCHECK(fetchurl,OC_ENOMEM);
  75. if(ocdebug > 0)
  76. {fprintf(stderr,"fetch url=%s\n",fetchurl); fflush(stderr);}
  77. stat = ocfetchurl(curl,fetchurl,packet,lastmodified);
  78. if(ocdebug > 0)
  79. {fprintf(stderr,"fetch complete\n"); fflush(stderr);}
  80. }
  81. free(fetchurl);
  82. return OCTHROW(stat);
  83. }
  84. int
  85. readDATADDS(OCstate* state, OCtree* tree, OCflags flags)
  86. {
  87. int stat = OC_NOERR;
  88. long lastmod = -1;
  89. if((flags & OCONDISK) == 0) {
  90. ocurisetconstraints(state->uri,tree->constraint);
  91. stat = readpacket(state->curl,state->uri,state->packet,OCDATADDS,&lastmod);
  92. if(stat == OC_NOERR)
  93. state->datalastmodified = lastmod;
  94. tree->data.datasize = ocbyteslength(state->packet);
  95. } else {
  96. OCURI* url = state->uri;
  97. int fileprotocol = 0;
  98. char* readurl = NULL;
  99. fileprotocol = (strcmp(url->protocol,"file")==0);
  100. if(fileprotocol && !oc_curl_file_supported) {
  101. readurl = ocuribuild(url,NULL,NULL,0);
  102. stat = readfiletofile(readurl, ".dods", tree->data.file, &tree->data.datasize);
  103. } else {
  104. int flags = 0;
  105. if(!fileprotocol) flags |= OCURICONSTRAINTS;
  106. flags |= OCURIENCODE;
  107. ocurisetconstraints(url,tree->constraint);
  108. readurl = ocuribuild(url,NULL,".dods",flags);
  109. MEMCHECK(readurl,OC_ENOMEM);
  110. if (ocdebug > 0)
  111. {fprintf(stderr, "fetch url=%s\n", readurl);fflush(stderr);}
  112. stat = ocfetchurl_file(state->curl, readurl, tree->data.file,
  113. &tree->data.datasize, &lastmod);
  114. if(stat == OC_NOERR)
  115. state->datalastmodified = lastmod;
  116. if (ocdebug > 0)
  117. {fprintf(stderr,"fetch complete\n"); fflush(stderr);}
  118. }
  119. free(readurl);
  120. }
  121. return OCTHROW(stat);
  122. }
  123. static int
  124. readfiletofile(char* path, char* suffix, FILE* stream, unsigned long* sizep)
  125. {
  126. int stat = OC_NOERR;
  127. OCbytes* packet = ocbytesnew();
  128. size_t len;
  129. /* check for leading file:/// */
  130. if(ocstrncmp(path,"file:///",8)==0) path += 7; /* assume absolute path*/
  131. stat = readfile(path,suffix,packet);
  132. if(stat != OC_NOERR) goto unwind;
  133. len = oclistlength(packet);
  134. if(stat == OC_NOERR) {
  135. size_t written;
  136. fseek(stream,0,SEEK_SET);
  137. written = fwrite(ocbytescontents(packet),1,len,stream);
  138. if(written != len) stat = OC_EIO;
  139. }
  140. if(sizep != NULL) *sizep = len;
  141. unwind:
  142. ocbytesfree(packet);
  143. return OCTHROW(stat);
  144. }
  145. static int
  146. readfile(char* path, char* suffix, OCbytes* packet)
  147. {
  148. int stat = OC_NOERR;
  149. char buf[1024];
  150. char filename[1024];
  151. int count,size,fd;
  152. /* check for leading file:/// */
  153. if(ocstrncmp(path,"file://",7)==0) path += 7; /* assume absolute path*/
  154. strcpy(filename,path);
  155. if(suffix != NULL) strcat(filename,suffix);
  156. fd = open(filename,O_RDONLY);
  157. if(fd < 0) {
  158. oc_log(LOGERR,"open failed:%s",filename);
  159. return OCTHROW(OC_EOPEN);
  160. }
  161. size=0;
  162. stat = OC_NOERR;
  163. for(;;) {
  164. count = read(fd,buf,sizeof(buf));
  165. if(count <= 0)
  166. break;
  167. else if(count < 0) {
  168. stat = OC_EIO;
  169. oc_log(LOGERR,"read failed: %s",filename);
  170. break;
  171. }
  172. ocbytesappendn(packet,buf,count);
  173. size += count;
  174. }
  175. close(fd);
  176. return OCTHROW(stat);
  177. }