ctorrent: import from packages
authorPeter Wagner <tripolar@gmx.at>
Mon, 16 Jun 2014 09:38:45 +0000 (11:38 +0200)
committerPeter Wagner <tripolar@gmx.at>
Mon, 16 Jun 2014 09:38:45 +0000 (11:38 +0200)
Signed-off-by: Peter Wagner <tripolar@gmx.at>
net/ctorrent-svn/Makefile [new file with mode: 0644]
net/ctorrent-svn/patches/100-compile-fix.patch [new file with mode: 0644]
net/ctorrent-svn/patches/300-negative.patch [new file with mode: 0644]
net/ctorrent/Makefile [new file with mode: 0644]
net/ctorrent/patches/100-CVE-2009-1759.patch [new file with mode: 0644]
net/ctorrent/patches/100-negative-ints.patch [new file with mode: 0644]

diff --git a/net/ctorrent-svn/Makefile b/net/ctorrent-svn/Makefile
new file mode 100644 (file)
index 0000000..f55eb9e
--- /dev/null
@@ -0,0 +1,97 @@
+#
+# Copyright (C) 2006-2008 OpenWrt.org
+#
+# This is free software, licensed under the GNU General Public License v2.
+# See /LICENSE for more information.
+#
+
+include $(TOPDIR)/rules.mk
+
+PKG_NAME:=ctorrent-svn
+PKG_REV:=322
+PKG_VERSION:=r$(PKG_REV)
+PKG_RELEASE:=1
+
+PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz
+PKG_SOURCE_URL:=https://dtorrent.svn.sourceforge.net/svnroot/dtorrent/dtorrent/trunk
+PKG_SOURCE_SUBDIR:=$(PKG_NAME)-$(PKG_VERSION)
+PKG_SOURCE_VERSION:=$(PKG_REV)
+PKG_SOURCE_PROTO:=svn
+
+PKG_BUILD_DIR:=$(BUILD_DIR)/$(PKG_NAME)-$(BUILD_VARIANT)/$(PKG_NAME)-$(PKG_VERSION)
+
+include $(INCLUDE_DIR)/package.mk
+
+define Package/ctorrent-svn/Default
+  SUBMENU:=BitTorrent
+  SECTION:=net
+  CATEGORY:=Network
+  DEPENDS:=+uclibcxx
+  TITLE:=console-based BitTorrent client
+  MAINTAINER:=Peter Wagner <tripolar@gmx.at>
+  URL:=http://www.rahul.net/dholmes/ctorrent/
+endef
+
+define Package/ctorrent-svn/Default/description
+       CTorrent is a BitTorrent client written in the C programming language,
+       known to be a very robust and mature programming language, which produces
+       fast and optimized application.
+endef
+
+define Package/ctorrent-svn
+$(call Package/ctorrent-svn/Default)
+  TITLE+= (with OpenSSL support)
+  DEPENDS+=+libopenssl
+  VARIANT:=ssl
+endef
+
+define Package/ctorrent-svn/description
+$(call Package/ctorrent-svn/Default/description)
+ This package is built with OpenSSL support.
+endef
+
+define Package/ctorrent-svn-nossl
+$(call Package/ctorrent-svn/Default)
+  TITLE+= (with builtin SHA-1)
+  VARIANT:=nossl
+endef
+
+define Package/ctorrent-svn-nossl/description
+$(call Package/ctorrent-svn/Default/description)
+ This package is built with builtin (Steve Reid's public-domain) SHA-1 support
+endef
+
+CONFIGURE_VARS += \
+       CXX="g++-uc" \
+       LIBS="-nodefaultlibs -luClibc++ $(LIBGCC_S) -lc"
+
+ifeq ($(BUILD_VARIANT),ssl)
+       CONFIGURE_ARGS += \
+               --with-ssl="$(STAGING_DIR)/usr"
+endif
+
+ifeq ($(BUILD_VARIANT),nossl)
+       CONFIGURE_ARGS += \
+               --with-ssl=no
+endif
+
+define Build/Configure
+       (cd $(PKG_BUILD_DIR); touch \
+               configure.ac \
+               aclocal.m4 \
+               Makefile.in \
+               config.h.in \
+               configure \
+       );
+       $(call Build/Configure/Default)
+endef
+
+define Package/ctorrent-svn/install
+       $(INSTALL_DIR) $(1)/usr/bin
+       $(INSTALL_BIN) $(PKG_BUILD_DIR)/ctorrent $(1)/usr/bin/ctorrent
+endef
+
+Package/ctorrent-svn-nossl/install = $(Package/ctorrent-svn/install)
+
+$(eval $(call BuildPackage,ctorrent-svn))
+$(eval $(call BuildPackage,ctorrent-svn-nossl))
diff --git a/net/ctorrent-svn/patches/100-compile-fix.patch b/net/ctorrent-svn/patches/100-compile-fix.patch
new file mode 100644 (file)
index 0000000..bb7d33f
--- /dev/null
@@ -0,0 +1,88 @@
+diff --git a/btconfig.cpp b/btconfig.cpp
+index e1badd0..aaa6feb 100644
+--- a/btconfig.cpp
++++ b/btconfig.cpp
+@@ -828,7 +828,7 @@ void CfgCTCS(Config<const char *> *config)
+     strncpy(CTCS.m_host, *cfg_ctcs, MAXHOSTNAMELEN-1);
+     CTCS.m_host[MAXHOSTNAMELEN-1] = '\0';
+     if( (s = strchr(CTCS.m_host, ':')) ) *s='\0';
+-    CTCS.m_port = atoi(s = (strchr(*cfg_ctcs, ':')+1));
++    CTCS.m_port = atoi(s = (char*)(strchr(*cfg_ctcs, ':')+1));
+     if( strchr(s, ':') )
+       CONSOLE.Input("Enter CTCS password: ", CTCS.m_pass, CTCS_PASS_SIZE);
+     else *CTCS.m_pass = '\0';
+diff --git a/btcontent.cpp b/btcontent.cpp
+index d84f450..88ccb50 100644
+--- a/btcontent.cpp
++++ b/btcontent.cpp
+@@ -1408,27 +1408,27 @@ void btContent::CompletionCommand()
+         ptmp = cmdstr + strlen(cmdstr);
+         parg = strstr(parg, "&t") + 2;
+         strcat(pt, parg);
+-        pt = strstr(ptmp, "&t");
+-        if( pd ) pd = strstr(ptmp, "&d");
+-        if( pw ) pw = strstr(ptmp, "&w");
++        pt = (char *)strstr(ptmp, "&t");
++        if( pd ) pd = (char *)strstr(ptmp, "&d");
++        if( pw ) pw = (char *)strstr(ptmp, "&w");
+       }
+       if( pd && (!pt || pd < pt) && (!pw || pd < pw) ){
+         strcpy(pd, m_btfiles.GetDataName());
+         ptmp = cmdstr + strlen(cmdstr);
+         parg = strstr(parg, "&d") + 2;
+         strcat(pd, parg);
+-        pd = strstr(ptmp, "&d");
+-        if( pt ) pt = strstr(ptmp, "&t");
+-        if( pw ) pw = strstr(ptmp, "&w");
++        pd = (char *)strstr(ptmp, "&d");
++        if( pt ) pt = (char *)strstr(ptmp, "&t");
++        if( pw ) pw = (char *)strstr(ptmp, "&w");
+       }
+       if( pw && (!pt || pw < pt) && (!pd || pw < pd) ){
+         strcpy(pw, wd);
+         ptmp = cmdstr + strlen(cmdstr);
+         parg = strstr(parg, "&w") + 2;
+         strcat(pw, parg);
+-        pw = strstr(ptmp, "&w");
+-        if( pt ) pt = strstr(ptmp, "&t");
+-        if( pd ) pd = strstr(ptmp, "&d");
++        pw = (char *)strstr(ptmp, "&w");
++        if( pt ) pt = (char *)strstr(ptmp, "&t");
++        if( pd ) pd = (char *)strstr(ptmp, "&d");
+       }
+     }
+   }
+diff --git a/console.cpp b/console.cpp
+index bdadb61..5ab2492 100644
+--- a/console.cpp
++++ b/console.cpp
+@@ -511,11 +511,8 @@ void ConStream::Error(int sev, const char *message, ...)
+   va_list ap;
+   va_start(ap, message);
+-  if( g_console_ready ) CONSOLE.Error(sev, message, ap);
+-  else{
+     vfprintf(stderr, message, ap);
+     fflush(stderr);
+-  }
+   va_end(ap);
+ }
+@@ -1766,7 +1763,7 @@ void Console::Warning(int sev, const char *message, ...)
+   va_end(ap);
+ }
+-
++/*
+ void Console::Error(int sev, const char *message, va_list ap)
+ {
+   vsnprintf(m_buffer, sizeof(m_buffer), message, ap);
+@@ -1778,7 +1775,7 @@ void Console::Error(int sev, const char *message, va_list ap)
+   m_warnings.AddMessage(sev, m_buffer);
+   if( sev && *cfg_ctcs ) CTCS.Send_Info(sev, m_buffer);
+ }
+-
++*/
+ void Console::Debug(const char *message, ...)
+ {
diff --git a/net/ctorrent-svn/patches/300-negative.patch b/net/ctorrent-svn/patches/300-negative.patch
new file mode 100644 (file)
index 0000000..e1e1e65
--- /dev/null
@@ -0,0 +1,14 @@
+diff --git a/bencode.cpp b/bencode.cpp
+index fef82ba..b7f14bc 100644
+--- a/bencode.cpp
++++ b/bencode.cpp
+@@ -45,6 +45,9 @@ size_t buf_int(const char *b, size_t len, char beginchar, char endchar,
+     p++;
+     len--;
+   }
++  if( *p == '-'){
++    p++; len--;
++  }
+   for( psave = p; len && isdigit(*p); p++, len-- );
diff --git a/net/ctorrent/Makefile b/net/ctorrent/Makefile
new file mode 100644 (file)
index 0000000..16504e2
--- /dev/null
@@ -0,0 +1,84 @@
+#
+# Copyright (C) 2006-2008 OpenWrt.org
+#
+# This is free software, licensed under the GNU General Public License v2.
+# See /LICENSE for more information.
+#
+
+include $(TOPDIR)/rules.mk
+
+PKG_NAME:=ctorrent
+PKG_VERSION:=dnh3.3.2
+PKG_RELEASE:=6
+
+PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz
+PKG_SOURCE_URL:=@SF/dtorrent \
+       http://www.rahul.net/dholmes/ctorrent/
+PKG_MD5SUM:=59b23dd05ff70791cd6449effa7fc3b6
+
+PKG_BUILD_DIR:=$(BUILD_DIR)/$(PKG_NAME)-$(BUILD_VARIANT)/$(PKG_NAME)-$(PKG_VERSION)
+
+include $(INCLUDE_DIR)/uclibc++.mk
+include $(INCLUDE_DIR)/package.mk
+
+define Package/ctorrent/Default
+  SUBMENU:=BitTorrent
+  SECTION:=net
+  CATEGORY:=Network
+  DEPENDS:=$(CXX_DEPENDS)
+  TITLE:=console-based BitTorrent client
+  MAINTAINER:=Peter Wagner <tripolar@gmx.at>
+  URL:=http://www.rahul.net/dholmes/ctorrent/
+endef
+
+define Package/ctorrent/Default/description
+       CTorrent is a BitTorrent client written in the C programming language,
+       known to be a very robust and mature programming language, which produces
+       fast and optimized application.
+endef
+
+define Package/ctorrent
+$(call Package/ctorrent/Default)
+  TITLE+= (with OpenSSL support)
+  DEPENDS+=+libopenssl
+  VARIANT:=ssl
+endef
+
+define Package/ctorrent/description
+$(call Package/ctorrent/Default/description)
+ This package is built with OpenSSL support.
+endef
+
+define Package/ctorrent-nossl
+$(call Package/ctorrent/Default)
+  TITLE+= (with builtin SHA-1)
+  VARIANT:=nossl
+endef
+
+define Package/ctorrent-nossl/description
+$(call Package/ctorrent/Default/description)
+ This package is built with builtin (Steve Reid's public-domain) SHA-1 support
+endef
+
+CONFIGURE_VARS += \
+       CXXFLAGS="$$$$CXXFLAGS -fno-rtti"
+
+ifeq ($(BUILD_VARIANT),ssl)
+       CONFIGURE_ARGS += \
+               --with-ssl="$(STAGING_DIR)/usr"
+endif
+
+ifeq ($(BUILD_VARIANT),nossl)
+       CONFIGURE_ARGS += \
+               --with-ssl=no
+endif
+
+define Package/ctorrent/install
+       $(INSTALL_DIR) $(1)/usr/bin
+       $(INSTALL_BIN) $(PKG_BUILD_DIR)/$(PKG_NAME) $(1)/usr/bin/$(PKG_NAME)
+endef
+
+Package/ctorrent-nossl/install = $(Package/ctorrent/install)
+
+$(eval $(call BuildPackage,ctorrent))
+$(eval $(call BuildPackage,ctorrent-nossl))
diff --git a/net/ctorrent/patches/100-CVE-2009-1759.patch b/net/ctorrent/patches/100-CVE-2009-1759.patch
new file mode 100644 (file)
index 0000000..86ae1d7
--- /dev/null
@@ -0,0 +1,364 @@
+Patch for CVE-2009-1759.
+Source: Upstream SVN, rev 302 from the dtorrent-3 branch.
+
+Index: a/bencode.h
+===================================================================
+--- a/bencode.h        (revision 300)
++++ b/bencode.h        (revision 302)
+@@ -25,7 +25,7 @@
+ size_t decode_list(const char *b,size_t len,const char *keylist);
+ size_t decode_rev(const char *b,size_t len,const char *keylist);
+ size_t decode_query(const char *b,size_t len,const char *keylist,const char **ps,size_t *pi,int64_t *pl,int method);
+-size_t decode_list2path(const char *b, size_t n, char *pathname);
++size_t decode_list2path(const char *b, size_t n, char *pathname, size_t maxlen);
+ size_t bencode_buf(const char *str,size_t len,FILE *fp);
+ size_t bencode_str(const char *str, FILE *fp);
+ size_t bencode_int(const uint64_t integer, FILE *fp);
+Index: a/bencode.cpp
+===================================================================
+--- a/bencode.cpp      (revision 300)
++++ b/bencode.cpp      (revision 302)
+@@ -233,22 +233,28 @@
+   return bencode_end_dict_list(fp);
+ }
+-size_t decode_list2path(const char *b, size_t n, char *pathname)
++size_t decode_list2path(const char *b, size_t n, char *pathname, size_t maxlen)
+ {
+   const char *pb = b;
+   const char *s = (char *) 0;
++  const char *endmax = pathname + maxlen - 1;
+   size_t r,q;
+   if( 'l' != *pb ) return 0;
+   pb++;
+   n--;
+   if( !n ) return 0;
+-  for(; n;){
++  while( n && pathname < endmax ){
+     if(!(r = buf_str(pb, n, &s, &q)) ) return 0;
++    if( q >= maxlen ) return 0;
+     memcpy(pathname, s, q);
+     pathname += q;
+-    pb += r; n -= r; 
+-    if( 'e' != *pb ){*pathname = PATH_SP, pathname++;} else break;
++    maxlen -= q;
++    pb += r;
++    n -= r; 
++    if( 'e' == *pb ) break;
++    if( pathname >= endmax ) return 0;
++    *pathname++ = PATH_SP;
+   }
+   *pathname = '\0';
+   return (pb - b + 1);
+Index: a/btfiles.cpp
+===================================================================
+--- a/btfiles.cpp      (revision 300)
++++ b/btfiles.cpp      (revision 302)
+@@ -449,7 +449,8 @@
+   return 0;
+ }
+-int btFiles::BuildFromMI(const char *metabuf, const size_t metabuf_len, const char *saveas)
++int btFiles::BuildFromMI(const char *metabuf, const size_t metabuf_len,
++  const char *saveas, unsigned char exam_only)
+ {
+   char path[MAXPATHLEN];
+   const char *s, *p;
+@@ -458,11 +459,19 @@
+   int f_warned = 0;
+   if( !decode_query(metabuf, metabuf_len, "info|name", &s, &q, (int64_t*)0,
+-      QUERY_STR) || MAXPATHLEN <= q )
++        QUERY_STR) || MAXPATHLEN <= q ){
++    errno = EINVAL;
+     return -1;
++  }
+   memcpy(path, s, q);
+   path[q] = '\0';
++  if( !exam_only &&
++      (PATH_SP == path[0] || '/' == path[0] || 0==strncmp("..", path, 2)) ){
++    CONSOLE.Warning(1, "error, unsafe path \"%s\" in torrent data", path);
++    errno = EINVAL;
++    return -1;
++  }
+   r = decode_query(metabuf, metabuf_len, "info|files", (const char**)0, &q,
+                    (int64_t*)0, QUERY_POS);
+@@ -471,21 +480,31 @@
+     BTFILE *pbf_last = (BTFILE*) 0; 
+     BTFILE *pbf = (BTFILE*) 0;
+     size_t dl;
++    unsigned long nfiles = 0;
++
+     if( decode_query(metabuf,metabuf_len,"info|length",
+-                    (const char**) 0,(size_t*) 0,(int64_t*) 0,QUERY_LONG) )
++                    (const char**) 0,(size_t*) 0,(int64_t*) 0,QUERY_LONG) ){
++      errno = EINVAL;
+       return -1;
++    }
+     if( saveas ){
+       m_directory = new char[strlen(saveas) + 1];
+ #ifndef WINDOWS
+-      if(!m_directory) return -1;
++      if( !m_directory ){
++        errno = ENOMEM;
++        return -1;
++      }
+ #endif
+       strcpy(m_directory,saveas);
+     }else{
+       int f_conv;
+       char *tmpfn = new char[strlen(path)*2+5];
+ #ifndef WINDOWS
+-      if( !tmpfn ) return -1;
++      if( !tmpfn ){
++        errno = ENOMEM;
++        return -1;
++      }
+ #endif
+       if( f_conv = ConvertFilename(tmpfn, path, strlen(path)*2+5) ){
+         if( arg_flg_convert_filenames ){
+@@ -493,6 +512,7 @@
+ #ifndef WINDOWS
+           if( !m_directory ){
+             delete []tmpfn;
++            errno = ENOMEM;
+             return -1;
+           }
+ #endif
+@@ -507,7 +527,10 @@
+       if( !f_conv || !arg_flg_convert_filenames ){
+         m_directory = new char[strlen(path) + 1];
+ #ifndef WINDOWS
+-        if( !m_directory ) return -1;
++        if( !m_directory ){
++          errno = ENOMEM;
++          return -1;
++        }
+ #endif
+         strcpy(m_directory,path);
+       }
+@@ -517,24 +540,50 @@
+     p = metabuf + r + 1; 
+     q--;
+     for(; q && 'e' != *p; p += dl, q -= dl){
+-      if(!(dl = decode_dict(p, q, (const char*) 0)) ) return -1;
+-      if( !decode_query(p, dl, "length", (const char**) 0,
+-                       (size_t*) 0,&t,QUERY_LONG) ) return -1;
++      if( !(dl = decode_dict(p, q, (const char*) 0)) ||
++          !decode_query(p, dl, "length", (const char**) 0, (size_t*) 0, &t,
++                        QUERY_LONG) ){
++        errno = EINVAL;
++        return -1;
++      }
+       pbf = _new_bfnode();
+ #ifndef WINDOWS
+-      if( !pbf ) return -1;
++      if( !pbf ){
++        errno = ENOMEM;
++        return -1;
++      }
+ #endif
++      nfiles++;
+       pbf->bf_length = t;
+       m_total_files_length += t;
+       r = decode_query(p, dl, "path", (const char **)0, &n, (int64_t*)0,
+                        QUERY_POS);
+-      if( !r ) return -1;
+-      if(!decode_list2path(p + r, n, path)) return -1;
++      if( !r || !decode_list2path(p + r, n, path, sizeof(path)) ){
++        CONSOLE.Warning(1,
++          "error, invalid path in torrent data for file %lu at offset %llu",
++          nfiles, m_total_files_length - t);
++        delete pbf;
++        errno = EINVAL;
++        return -1;
++      }
++      if( !exam_only &&
++          (PATH_SP == path[0] || '/' == path[0] || 0==strncmp("..", path, 2)) ){
++        CONSOLE.Warning(1,
++          "error, unsafe path \"%s\" in torrent data for file %lu",
++          path, nfiles);
++        delete pbf;
++        errno = EINVAL;
++        return -1;
++      }
++
+       int f_conv;
+       char *tmpfn = new char[strlen(path)*2+5];
+ #ifndef WINDOWS
+-      if( !tmpfn ) return -1;
++      if( !tmpfn ){
++        errno = ENOMEM;
++        return -1;
++      }
+ #endif
+       if( f_conv = ConvertFilename(tmpfn, path, strlen(path)*2+5) ){
+         if( arg_flg_convert_filenames ){
+@@ -542,6 +591,7 @@
+ #ifndef WINDOWS
+           if( !pbf->bf_filename ){
+             delete []tmpfn;
++            errno = ENOMEM;
+             return -1;
+           }
+ #endif
+@@ -556,7 +606,10 @@
+       if( !f_conv || !arg_flg_convert_filenames ){
+         pbf->bf_filename = new char[strlen(path) + 1];
+ #ifndef WINDOWS
+-        if( !pbf->bf_filename ) return -1;
++        if( !pbf->bf_filename ){
++          errno = ENOMEM;
++          return -1;
++        }
+ #endif
+         strcpy(pbf->bf_filename, path);
+       }
+@@ -564,30 +617,42 @@
+       pbf_last = pbf;
+     }
+   }else{
+-    if( !decode_query(metabuf,metabuf_len,"info|length",
+-                     (const char**) 0,(size_t*) 0,&t,QUERY_LONG) )
++    if( !decode_query(metabuf,metabuf_len, "info|length",
++                      (const char**)0, (size_t*) 0, &t, QUERY_LONG) ){
++      errno = EINVAL;
+       return -1;
++    }
+     m_btfhead = _new_bfnode();
+ #ifndef WINDOWS
+-    if( !m_btfhead) return -1;
++    if( !m_btfhead ){
++      errno = ENOMEM;
++      return -1;
++    }
+ #endif
+     m_btfhead->bf_length = m_total_files_length = t;
+     if( saveas ){
+       m_btfhead->bf_filename = new char[strlen(saveas) + 1];
+ #ifndef WINDOWS
+-      if(!m_btfhead->bf_filename ) return -1;
++      if( !m_btfhead->bf_filename ){
++        errno = ENOMEM;
++        return -1;
++      }
+ #endif
+       strcpy(m_btfhead->bf_filename, saveas);
+     }else if( arg_flg_convert_filenames ){
+       char *tmpfn = new char[strlen(path)*2+5];
+ #ifndef WINDOWS
+-      if( !tmpfn ) return -1;
++      if( !tmpfn ){
++        errno = ENOMEM;
++        return -1;
++      }
+ #endif
+       ConvertFilename(tmpfn, path, strlen(path)*2+5);
+       m_btfhead->bf_filename = new char[strlen(tmpfn) + 1];
+ #ifndef WINDOWS
+       if( !m_btfhead->bf_filename ){
+         delete []tmpfn;
++        errno = ENOMEM;
+         return -1;
+       }
+ #endif
+@@ -596,7 +661,10 @@
+     }else{
+       m_btfhead->bf_filename = new char[strlen(path) + 1];
+ #ifndef WINDOWS
+-      if(!m_btfhead->bf_filename ) return -1;
++      if( !m_btfhead->bf_filename ){
++        errno = ENOMEM;
++        return -1;
++      }
+ #endif
+       strcpy(m_btfhead->bf_filename, path);
+     }
+@@ -694,6 +762,32 @@
+ size_t btFiles::FillMetaInfo(FILE* fp)
+ {
+   BTFILE *p;
++  const char *refname, *s;
++  char path[MAXPATHLEN];
++
++  refname = m_directory ? m_directory : m_btfhead->bf_filename;
++  while( (s = strchr(refname, PATH_SP)) && *(s + 1) ){
++    refname = s + 1;
++  }
++  if( m_directory && '.' == *refname ){
++    char dir[MAXPATHLEN];
++    if( getcwd(dir, sizeof(dir)) && 0==chdir(m_directory) ){
++      if( getcwd(path, sizeof(path)) ){
++        refname = path;
++        while( (s = strchr(refname, PATH_SP)) && *(s + 1) ){
++          refname = s + 1;
++        }
++      }
++      chdir(dir);
++    }
++  }
++  if( '/' == *refname || '\0' == *refname || '.' == *refname ){
++    CONSOLE.Warning(1, "error, inappropriate file or directory name \"%s\"",
++      m_directory ? m_directory : m_btfhead->bf_filename);
++    errno = EINVAL;
++    return 0;
++  }
++
+   if( m_directory ){
+     // multi files
+     if( bencode_str("files", fp) != 1 ) return 0;
+@@ -715,16 +809,15 @@
+     if(bencode_end_dict_list(fp) != 1 ) return 0;
+     
+     if(bencode_str("name", fp) != 1) return 0;
+-    return bencode_str(m_directory, fp);
+-    
++    return bencode_str(refname, fp);
+   }else{
+     if( bencode_str("length", fp) != 1 ) return 0;
+     if( bencode_int(m_btfhead->bf_length, fp) != 1) return 0;
+     
+     if( bencode_str("name", fp) != 1 ) return 0;
+-    return bencode_str(m_btfhead->bf_filename, fp);
++    return bencode_str(refname, fp);
+   }
+-  return 1;
++  return 0;
+ }
+Index: a/btcontent.cpp
+===================================================================
+--- a/btcontent.cpp    (revision 300)
++++ b/btcontent.cpp    (revision 302)
+@@ -357,7 +357,11 @@
+   cfg_req_queue_length = (m_piece_length / cfg_req_slice_size) * 2 - 1;
+-  if( m_btfiles.BuildFromMI(b, flen, saveas) < 0 ) ERR_RETURN();
++  if( m_btfiles.BuildFromMI(b, flen, saveas, arg_flg_exam_only) < 0 ){
++    if( EINVAL == errno )
++      CONSOLE.Warning(1, "Torrent metainfo file data is invalid or unusable.");
++    ERR_RETURN();
++  }
+   delete []b;
+   b = (char *)0;
+Index: a/btfiles.h
+===================================================================
+--- a/btfiles.h        (revision 300)
++++ b/btfiles.h        (revision 302)
+@@ -61,7 +61,7 @@
+   
+   int BuildFromFS(const char *pathname);
+   int BuildFromMI(const char *metabuf, const size_t metabuf_len,
+-                  const char *saveas);
++                  const char *saveas, unsigned char exam_only);
+   char *GetDataName() const;
+   uint64_t GetTotalLength() const { return m_total_files_length; }
diff --git a/net/ctorrent/patches/100-negative-ints.patch b/net/ctorrent/patches/100-negative-ints.patch
new file mode 100644 (file)
index 0000000..864ce1b
--- /dev/null
@@ -0,0 +1,13 @@
+--- a/bencode.cpp
++++ b/bencode.cpp
+@@ -44,6 +44,10 @@ size_t buf_long(const char *b,size_t len
+     p++; len--;
+   }
++  if( *p == '-'){
++    p++; len--;
++  }
++
+   for(psave = p; len && isdigit(*p); p++,len--) ;
+   if(!len || MAX_INT_SIZ < (p - psave) || *p != endchar) return 0;