Subversion Repositories Kolibri OS

Rev

Go to most recent revision | Blame | Last modification | View Log | RSS feed

  1. /*
  2.  * Gopher protocol
  3.  *
  4.  * Copyright (c) 2009 Toshimitsu Kimura
  5.  *
  6.  * based on libavformat/http.c, Copyright (c) 2000, 2001 Fabrice Bellard
  7.  *
  8.  * This file is part of FFmpeg.
  9.  *
  10.  * FFmpeg is free software; you can redistribute it and/or
  11.  * modify it under the terms of the GNU Lesser General Public
  12.  * License as published by the Free Software Foundation; either
  13.  * version 2.1 of the License, or (at your option) any later version.
  14.  *
  15.  * FFmpeg is distributed in the hope that it will be useful,
  16.  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  17.  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  18.  * Lesser General Public License for more details.
  19.  *
  20.  * You should have received a copy of the GNU Lesser General Public
  21.  * License along with FFmpeg; if not, write to the Free Software
  22.  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  23.  */
  24.  
  25. #include "libavutil/avstring.h"
  26. #include "avformat.h"
  27. #include "internal.h"
  28. #include "network.h"
  29. #include "url.h"
  30.  
  31. typedef struct {
  32.     URLContext *hd;
  33. } GopherContext;
  34.  
  35. static int gopher_write(URLContext *h, const uint8_t *buf, int size)
  36. {
  37.     GopherContext *s = h->priv_data;
  38.     return ffurl_write(s->hd, buf, size);
  39. }
  40.  
  41. static int gopher_connect(URLContext *h, const char *path)
  42. {
  43.     char buffer[1024];
  44.  
  45.     if (!*path) return AVERROR(EINVAL);
  46.     switch (*++path) {
  47.         case '5':
  48.         case '9':
  49.             path = strchr(path, '/');
  50.             if (!path) return AVERROR(EINVAL);
  51.             break;
  52.         default:
  53.             av_log(h, AV_LOG_WARNING,
  54.                    "Gopher protocol type '%c' not supported yet!\n",
  55.                    *path);
  56.             return AVERROR(EINVAL);
  57.     }
  58.  
  59.     /* send gopher sector */
  60.     snprintf(buffer, sizeof(buffer), "%s\r\n", path);
  61.  
  62.     if (gopher_write(h, buffer, strlen(buffer)) < 0)
  63.         return AVERROR(EIO);
  64.  
  65.     return 0;
  66. }
  67.  
  68. static int gopher_close(URLContext *h)
  69. {
  70.     GopherContext *s = h->priv_data;
  71.     if (s->hd) {
  72.         ffurl_close(s->hd);
  73.         s->hd = NULL;
  74.     }
  75.     return 0;
  76. }
  77.  
  78. static int gopher_open(URLContext *h, const char *uri, int flags)
  79. {
  80.     GopherContext *s = h->priv_data;
  81.     char hostname[1024], auth[1024], path[1024], buf[1024];
  82.     int port, err;
  83.  
  84.     h->is_streamed = 1;
  85.  
  86.     /* needed in any case to build the host string */
  87.     av_url_split(NULL, 0, auth, sizeof(auth), hostname, sizeof(hostname), &port,
  88.                  path, sizeof(path), uri);
  89.  
  90.     if (port < 0)
  91.         port = 70;
  92.  
  93.     ff_url_join(buf, sizeof(buf), "tcp", NULL, hostname, port, NULL);
  94.  
  95.     s->hd = NULL;
  96.     err = ffurl_open(&s->hd, buf, AVIO_FLAG_READ_WRITE,
  97.                      &h->interrupt_callback, NULL);
  98.     if (err < 0)
  99.         goto fail;
  100.  
  101.     if ((err = gopher_connect(h, path)) < 0)
  102.         goto fail;
  103.     return 0;
  104.  fail:
  105.     gopher_close(h);
  106.     return err;
  107. }
  108.  
  109. static int gopher_read(URLContext *h, uint8_t *buf, int size)
  110. {
  111.     GopherContext *s = h->priv_data;
  112.     int len = ffurl_read(s->hd, buf, size);
  113.     return len;
  114. }
  115.  
  116.  
  117. URLProtocol ff_gopher_protocol = {
  118.     .name           = "gopher",
  119.     .url_open       = gopher_open,
  120.     .url_read       = gopher_read,
  121.     .url_write      = gopher_write,
  122.     .url_close      = gopher_close,
  123.     .priv_data_size = sizeof(GopherContext),
  124.     .flags          = URL_PROTOCOL_FLAG_NETWORK,
  125. };
  126.