gopher.c 1.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <string.h>
  4. #include <unistd.h>
  5. #include <sys/socket.h>
  6. #include "output.h"
  7. #include "wgetlite.h"
  8. #include "gopher.h"
  9. #include "util.h"
  10. /*
  11. * This is a simple Gopher (RFC 1436) support.
  12. */
  13. int gopher_retrieve(struct wgetfile *finfo)
  14. {
  15. FILE *f;
  16. char *token;
  17. char type, trailbuf[4];
  18. int rv;
  19. long flength;
  20. if(strlen(finfo->host_file) > 1) {
  21. token = &finfo->host_file[2];
  22. type = finfo->host_file[1];
  23. } else {
  24. /*
  25. * If there is nothing given, it likely may be
  26. * some menu.
  27. */
  28. token = finfo->host_file;
  29. type = '1';
  30. }
  31. fdprintf(finfo->sock, "%s\r\n", token);
  32. f = wget_open(finfo, NULL);
  33. if(!f)
  34. return 1;
  35. /* finfo, file, len, sofar, closefd */
  36. rv = generic_transfer(finfo, f, 0, 0, 0);
  37. if(rv)
  38. goto closereturn;
  39. switch(type){
  40. case '0':
  41. case '1':
  42. /*
  43. * We should be at the end of the file.
  44. */
  45. flength = ftell(f);
  46. if(flength < 0) {
  47. rv = 1;
  48. goto closereturn;
  49. }
  50. if(flength < 4)
  51. break;
  52. if(fseek(f, flength - 4, SEEK_SET) < 0) {
  53. rv = 1;
  54. goto closereturn;
  55. }
  56. memset(trailbuf, 0, sizeof(trailbuf));
  57. if(!fread(trailbuf, 1, 4, f)) {
  58. rv = 1;
  59. goto closereturn;
  60. }
  61. /*
  62. * Check for maldesigned gopher servers using '\n'
  63. * instead of '\r\n'.
  64. */
  65. if(!memcmp(trailbuf+2, ".\n", 2)) {
  66. flength -= 2;
  67. } else if(!memcmp(trailbuf+1, ".\r\n", 3)) {
  68. flength -= 3;
  69. } else {
  70. break;
  71. }
  72. if(ftruncate(fileno(f), flength) < 0) {
  73. rv = 1;
  74. goto closereturn;
  75. }
  76. break;
  77. }
  78. closereturn:
  79. rv |= wget_close(finfo, f);
  80. if(!rv)
  81. wget_success(finfo);
  82. return rv;
  83. }