git-svn-id: http://s3fs.googlecode.com/svn/trunk@188 df820570-a93a-0410-bd06-b72b767a4274
This commit is contained in:
rrizun 2010-01-12 00:54:03 +00:00
parent eadd2b17f8
commit ecb9efa5fa
14 changed files with 423 additions and 32 deletions

133
s3fs/.cproject Normal file
View File

@ -0,0 +1,133 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<?fileVersion 4.0.0?>
<cproject>
<storageModule moduleId="org.eclipse.cdt.core.settings">
<cconfiguration id="cdt.managedbuild.toolchain.gnu.base.989591363">
<storageModule buildSystemId="org.eclipse.cdt.managedbuilder.core.configurationDataProvider" id="cdt.managedbuild.toolchain.gnu.base.989591363" moduleId="org.eclipse.cdt.core.settings" name="Linux GCC">
<externalSettings/>
<extensions>
<extension id="org.eclipse.cdt.core.ELF" point="org.eclipse.cdt.core.BinaryParser"/>
<extension id="org.eclipse.cdt.core.MakeErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
<extension id="org.eclipse.cdt.core.GCCErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
<extension id="org.eclipse.cdt.core.GASErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
<extension id="org.eclipse.cdt.core.GLDErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
</extensions>
</storageModule>
<storageModule moduleId="cdtBuildSystem" version="4.0.0">
<configuration artifactName="fusicle" buildProperties="" description="" id="cdt.managedbuild.toolchain.gnu.base.989591363" name="Linux GCC" parent="org.eclipse.cdt.build.core.emptycfg">
<folderInfo id="cdt.managedbuild.toolchain.gnu.base.989591363.286980260" name="/" resourcePath="">
<toolChain id="cdt.managedbuild.toolchain.gnu.base.1898578537" name="cdt.managedbuild.toolchain.gnu.base" superClass="cdt.managedbuild.toolchain.gnu.base">
<targetPlatform archList="all" binaryParser="org.eclipse.cdt.core.ELF" id="cdt.managedbuild.target.gnu.platform.base.349471613" name="Debug Platform" osList="linux,hpux,aix,qnx" superClass="cdt.managedbuild.target.gnu.platform.base"/>
<builder autoBuildTarget="all" buildPath="${workspace_loc:/fusicle}" cleanBuildTarget="clean" enableAutoBuild="true" enableCleanBuild="true" enabledIncrementalBuild="true" id="cdt.managedbuild.target.gnu.builder.base.2123870674" incrementalBuildTarget="all" keepEnvironmentInBuildfile="false" managedBuildOn="false" name="Gnu Make Builder" superClass="cdt.managedbuild.target.gnu.builder.base"/>
<tool id="cdt.managedbuild.tool.gnu.archiver.base.858974388" name="GCC Archiver" superClass="cdt.managedbuild.tool.gnu.archiver.base"/>
<tool id="cdt.managedbuild.tool.gnu.cpp.compiler.base.1346311259" name="GCC C++ Compiler" superClass="cdt.managedbuild.tool.gnu.cpp.compiler.base">
<inputType id="cdt.managedbuild.tool.gnu.cpp.compiler.input.1574162864" superClass="cdt.managedbuild.tool.gnu.cpp.compiler.input"/>
</tool>
<tool id="cdt.managedbuild.tool.gnu.c.compiler.base.583651033" name="GCC C Compiler" superClass="cdt.managedbuild.tool.gnu.c.compiler.base">
<inputType id="cdt.managedbuild.tool.gnu.c.compiler.input.1875711080" superClass="cdt.managedbuild.tool.gnu.c.compiler.input"/>
</tool>
<tool id="cdt.managedbuild.tool.gnu.c.linker.base.661869001" name="GCC C Linker" superClass="cdt.managedbuild.tool.gnu.c.linker.base"/>
<tool id="cdt.managedbuild.tool.gnu.cpp.linker.base.404012928" name="GCC C++ Linker" superClass="cdt.managedbuild.tool.gnu.cpp.linker.base">
<inputType id="cdt.managedbuild.tool.gnu.cpp.linker.input.402002422" superClass="cdt.managedbuild.tool.gnu.cpp.linker.input">
<additionalInput kind="additionalinputdependency" paths="$(USER_OBJS)"/>
<additionalInput kind="additionalinput" paths="$(LIBS)"/>
</inputType>
</tool>
<tool id="cdt.managedbuild.tool.gnu.assembler.base.1146796010" name="GCC Assembler" superClass="cdt.managedbuild.tool.gnu.assembler.base">
<inputType id="cdt.managedbuild.tool.gnu.assembler.input.349109114" superClass="cdt.managedbuild.tool.gnu.assembler.input"/>
</tool>
</toolChain>
</folderInfo>
</configuration>
</storageModule>
<storageModule moduleId="scannerConfiguration">
<autodiscovery enabled="true" problemReportingEnabled="true" selectedProfileId="org.eclipse.cdt.make.core.GCCStandardMakePerProjectProfile"/>
<profile id="org.eclipse.cdt.make.core.GCCStandardMakePerProjectProfile">
<buildOutputProvider>
<openAction enabled="true" filePath=""/>
<parser enabled="true"/>
</buildOutputProvider>
<scannerInfoProvider id="specsFile">
<runAction arguments="-E -P -v -dD ${plugin_state_location}/${specs_file}" command="gcc" useDefault="true"/>
<parser enabled="true"/>
</scannerInfoProvider>
</profile>
<profile id="org.eclipse.cdt.make.core.GCCStandardMakePerFileProfile">
<buildOutputProvider>
<openAction enabled="true" filePath=""/>
<parser enabled="true"/>
</buildOutputProvider>
<scannerInfoProvider id="makefileGenerator">
<runAction arguments="-f ${project_name}_scd.mk" command="make" useDefault="true"/>
<parser enabled="true"/>
</scannerInfoProvider>
</profile>
<profile id="org.eclipse.cdt.managedbuilder.core.GCCManagedMakePerProjectProfile">
<buildOutputProvider>
<openAction enabled="false" filePath=""/>
<parser enabled="false"/>
</buildOutputProvider>
<scannerInfoProvider id="specsFile">
<runAction arguments="-E -P -v -dD ${plugin_state_location}/${specs_file}" command="gcc" useDefault="true"/>
<parser enabled="true"/>
</scannerInfoProvider>
</profile>
<profile id="org.eclipse.cdt.managedbuilder.core.GCCManagedMakePerProjectProfileCPP">
<buildOutputProvider>
<openAction enabled="false" filePath=""/>
<parser enabled="false"/>
</buildOutputProvider>
<scannerInfoProvider id="specsFile">
<runAction arguments="-E -P -v -dD ${plugin_state_location}/specs.cpp" command="g++" useDefault="true"/>
<parser enabled="true"/>
</scannerInfoProvider>
</profile>
<profile id="org.eclipse.cdt.managedbuilder.core.GCCManagedMakePerProjectProfileC">
<buildOutputProvider>
<openAction enabled="false" filePath=""/>
<parser enabled="false"/>
</buildOutputProvider>
<scannerInfoProvider id="specsFile">
<runAction arguments="-E -P -v -dD ${plugin_state_location}/specs.c" command="gcc" useDefault="true"/>
<parser enabled="true"/>
</scannerInfoProvider>
</profile>
<profile id="org.eclipse.cdt.managedbuilder.core.GCCWinManagedMakePerProjectProfile">
<buildOutputProvider>
<openAction enabled="false" filePath=""/>
<parser enabled="false"/>
</buildOutputProvider>
<scannerInfoProvider id="specsFile">
<runAction arguments="-E -P -v -dD ${plugin_state_location}/${specs_file}" command="gcc" useDefault="true"/>
<parser enabled="true"/>
</scannerInfoProvider>
</profile>
<profile id="org.eclipse.cdt.managedbuilder.core.GCCWinManagedMakePerProjectProfileCPP">
<buildOutputProvider>
<openAction enabled="false" filePath=""/>
<parser enabled="false"/>
</buildOutputProvider>
<scannerInfoProvider id="specsFile">
<runAction arguments="-E -P -v -dD ${plugin_state_location}/specs.cpp" command="g++" useDefault="true"/>
<parser enabled="true"/>
</scannerInfoProvider>
</profile>
<profile id="org.eclipse.cdt.managedbuilder.core.GCCWinManagedMakePerProjectProfileC">
<buildOutputProvider>
<openAction enabled="false" filePath=""/>
<parser enabled="false"/>
</buildOutputProvider>
<scannerInfoProvider id="specsFile">
<runAction arguments="-E -P -v -dD ${plugin_state_location}/specs.c" command="gcc" useDefault="true"/>
<parser enabled="true"/>
</scannerInfoProvider>
</profile>
</storageModule>
<storageModule moduleId="org.eclipse.cdt.core.externalSettings"/>
</cconfiguration>
</storageModule>
<storageModule moduleId="cdtBuildSystem" version="4.0.0">
<project id="fusicle.null.329243261" name="fusicle"/>
</storageModule>
</cproject>

View File

@ -5,7 +5,77 @@
<projects>
</projects>
<buildSpec>
<buildCommand>
<name>org.eclipse.cdt.managedbuilder.core.genmakebuilder</name>
<arguments>
<dictionary>
<key>org.eclipse.cdt.make.core.cleanBuildTarget</key>
<value>clean</value>
</dictionary>
<dictionary>
<key>org.eclipse.cdt.make.core.enableCleanBuild</key>
<value>true</value>
</dictionary>
<dictionary>
<key>?name?</key>
<value></value>
</dictionary>
<dictionary>
<key>org.eclipse.cdt.make.core.append_environment</key>
<value>true</value>
</dictionary>
<dictionary>
<key>org.eclipse.cdt.make.core.stopOnError</key>
<value>true</value>
</dictionary>
<dictionary>
<key>org.eclipse.cdt.make.core.buildCommand</key>
<value>make</value>
</dictionary>
<dictionary>
<key>org.eclipse.cdt.make.core.contents</key>
<value>org.eclipse.cdt.make.core.activeConfigSettings</value>
</dictionary>
<dictionary>
<key>org.eclipse.cdt.make.core.buildLocation</key>
<value>${workspace_loc:/fusicle}</value>
</dictionary>
<dictionary>
<key>org.eclipse.cdt.make.core.useDefaultBuildCmd</key>
<value>true</value>
</dictionary>
<dictionary>
<key>org.eclipse.cdt.make.core.enableAutoBuild</key>
<value>true</value>
</dictionary>
<dictionary>
<key>org.eclipse.cdt.make.core.enableFullBuild</key>
<value>true</value>
</dictionary>
<dictionary>
<key>org.eclipse.cdt.make.core.buildArguments</key>
<value></value>
</dictionary>
<dictionary>
<key>org.eclipse.cdt.make.core.fullBuildTarget</key>
<value>all</value>
</dictionary>
<dictionary>
<key>org.eclipse.cdt.make.core.autoBuildTarget</key>
<value>all</value>
</dictionary>
</arguments>
</buildCommand>
<buildCommand>
<name>org.eclipse.cdt.managedbuilder.core.ScannerConfigBuilder</name>
<arguments>
</arguments>
</buildCommand>
</buildSpec>
<natures>
<nature>org.eclipse.cdt.core.ccnature</nature>
<nature>org.eclipse.cdt.managedbuilder.core.ScannerConfigNature</nature>
<nature>org.eclipse.cdt.managedbuilder.core.managedBuildNature</nature>
<nature>org.eclipse.cdt.core.cnature</nature>
</natures>
</projectDescription>

View File

View File

12
s3fs/Makefile Normal file
View File

@ -0,0 +1,12 @@
all:
g++ -ggdb -Wall $(shell pkg-config fuse --cflags --libs) $(shell pkg-config libcurl --cflags --libs) $(shell xml2-config --cflags --libs) -lcrypto s3fs.cpp -o s3fs
@echo ok!
install: all
cp -f s3fs /usr/bin
dist: all
tar -cvzf s3fs.tar.gz -C .. s3fs/COPYING s3fs/Makefile s3fs/s3fs.cpp
clean:
rm -f s3fs s3fs.o

View File

@ -1,6 +0,0 @@
LIBS = $(DEPS_LIBS)
INCLUDES = $(DEPS_CFLAGS)
bin_PROGRAMS = s3fs
s3fs_SOURCES = s3fs.cpp

6
s3fs/Makefile.lsb Normal file
View File

@ -0,0 +1,6 @@
all:
LSBCC_SHAREDLIBS=fuse:curl:ssl /opt/lsb/bin/lsbc++ -Wall -Wl,--allow-shlib-undefined $(shell pkg-config fuse --cflags --libs) -lcurl $(shell xml2-config --cflags --libs) -lssl -ggdb s3fs.cpp -o s3fs
@echo ok!
clean:
rm -f s3fs s3fs.o

View File

View File

View File

@ -1,15 +0,0 @@
# Process this file with autoconf to produce a configure script.
AC_INIT
AM_INIT_AUTOMAKE(s3fs,1.0.0)
AC_PROG_CC
AC_PROG_CXX
AC_PROG_INSTALL
PKG_CHECK_MODULES(DEPS, fuse libcurl libxml-2.0)
AC_SUBST(DEPS_LIBS)
AC_SUBST(DEPS_CFLAGS)
AC_OUTPUT(Makefile)

58
s3fs/contrib/readme.txt Normal file
View File

@ -0,0 +1,58 @@
S3FS-Fuse
S3FS is FUSE (File System in User Space) based solution to mount/unmount an Amazon S3 storage buckets and use system commands with S3 just like it was another Hard Disk.
In order to compile s3fs, You'll need the following requirements:
* Kernel-devel packages (or kernel source) installed that is the SAME version of your running kernel
* LibXML2-devel packages
* CURL-devel packages (or compile curl from sources at: curl.haxx.se/ use 7.15.X)
* GCC, GCC-C++
* pkgconfig
* FUSE (2.7.x)
* FUSE Kernel module installed and running (RHEL 4.x/CentOS 4.x users - read below)
* OpenSSL-devel (0.9.8)
* Subversion
If you're using YUM or APT to install those packages, then it might require additional packaging, allow it to be installed.
Downloading & Compiling:
------------------------
In order to download s3fs, user the following command:
svn checkout http://s3fs.googlecode.com/svn/trunk/ s3fs-read-only
Go inside the directory that has been created (s3fs-read-only/s3fs) and run: make
This should compile the code. If everything goes OK, you'll be greated with "ok!" at the end and you'll have a binary file called "s3fs"
As root (you can use su, su -, sudo) do: "make inatall" -this will copy the "s3fs" binary to /usr/bin.
Congratulations. S3fs is now compiled and Installed.
Usage:
------
In order to use s3fs, make sure you have the Access Key and the Secret Key handy.
First, create a directory where to mount the S3 bucket you want to use.
Example (as root): mkdir -p /mnt/s3
Then run: s3fs mybucket -o accessKeyId=aaa -o secretAccessKey=bbb /mnt/s3
This will mount your bucket to /mnt/s3. You can do a simple "ls -l /mnt/s3" to see the content of your bucket.
If you want to allow other people access the same bucket in the same machine, you can add "-o allow _other" to read/write/delete content of the bucket.
You can add a fixed mount point in /etc/fstab, here's an example:
s3fs#mybucket /mnt/s3 fuse allow_other,accessKeyId=XXX ,secretAccessKey=YYY 0 0
This will mount upon reboot (or by launching: mount -a) your bucket on your machine.
All other options can be read at: http://code.google.com/p/s3fs/wiki/FuseOverAmazon
Known Issues:
-------------
s3fs should be working fine with S3 storage. However, There are couple of limitations:
* There is no full UID/GID support yet, everything looks as "root" and if you allow others to access the bucket, others can erase files. There is, however, permissions support built in.
* Currently s3fs could hang the CPU if you have lots of time-outs. This is *NOT* a fault of s3fs but rather libcurl. This happends when you try to copy thousands of files in 1 session, it doesn't happend when you upload hundreds of files or less.
* CentOS 4.x/RHEL 4.x users - if you use the kernel that shipped with your distribution and didn't upgrade to the latest kernel RedHat/CentOS gives, you might have a problem loading the "fuse" kernel. Please upgrade to the latest kernel (2.6.16 or above) and make sure "fuse" kernel module is compiled and loadable since FUSE requires this kernel module and s3fs requires it as well.
* Moving/renaming/erasing files takes time since the whole file needs to be accessed first. A workaround could be touse s3fs's cache support with the use_cache option.

124
s3fs/p Normal file
View File

@ -0,0 +1,124 @@
--- s3fs/s3fs.cpp 2008-08-13 01:01:47.000000000 +0200
+++ ../s3fs/s3fs.cpp 2009-05-26 16:18:19.000000000 +0200
@@ -319,6 +319,7 @@
static string AWSSecretAccessKey;
static string host = "http://s3.amazonaws.com";
static mode_t root_mode = 0;
+static string service_path = "/";
// if .size()==0 then local file cache is disabled
static string use_cache;
@@ -506,7 +507,7 @@
int
get_headers(const char* path, headers_t& meta) {
- string resource(urlEncode("/"+bucket + path));
+ string resource(urlEncode(service_path + bucket + path));
string url(host + resource);
auto_curl curl;
@@ -549,7 +550,7 @@
*/
int
get_local_fd(const char* path) {
- string resource(urlEncode("/"+bucket + path));
+ string resource(urlEncode(service_path + bucket + path));
string url(host + resource);
string baseName = mybasename(path);
@@ -653,7 +654,7 @@
*/
static int
put_headers(const char* path, headers_t meta) {
- string resource = urlEncode("/"+bucket + path);
+ string resource = urlEncode(service_path + bucket + path);
string url = host + resource;
auto_curl curl;
@@ -708,7 +709,7 @@
*/
static int
put_local_fd(const char* path, headers_t meta, int fd) {
- string resource = urlEncode("/"+bucket + path);
+ string resource = urlEncode(service_path + bucket + path);
string url = host + resource;
struct stat st;
@@ -784,7 +785,7 @@
}
}
- string resource = urlEncode("/"+bucket + path);
+ string resource = urlEncode(service_path +bucket + path);
string url = host + resource;
auto_curl curl;
@@ -894,7 +895,7 @@
// If pathname already exists, or is a symbolic link, this call fails with an EEXIST error.
cout << "mknod[path="<< path << "][mode=" << mode << "]" << endl;
- string resource = urlEncode("/"+bucket + path);
+ string resource = urlEncode(service_path + bucket + path);
string url = host + resource;
auto_curl curl;
@@ -927,7 +928,7 @@
s3fs_mkdir(const char *path, mode_t mode) {
cout << "mkdir[path=" << path << "][mode=" << mode << "]" << endl;
- string resource = urlEncode("/"+bucket + path);
+ string resource = urlEncode(service_path + bucket + path);
string url = host + resource;
auto_curl curl;
@@ -960,7 +961,7 @@
s3fs_unlink(const char *path) {
cout << "unlink[path=" << path << "]" << endl;
- string resource = urlEncode("/"+bucket + path);
+ string resource = urlEncode(service_path + bucket + path);
string url = host + resource;
auto_curl curl;
@@ -984,7 +985,7 @@
s3fs_rmdir(const char *path) {
cout << "unlink[path=" << path << "]" << endl;
- string resource = urlEncode("/"+bucket + path);
+ string resource = urlEncode(service_path + bucket + path);
string url = host + resource;
auto_curl curl;
@@ -1233,7 +1234,7 @@
while (IsTruncated == "true") {
string responseText;
- string resource = urlEncode("/"+bucket); // this is what gets signed
+ string resource = urlEncode(service_path + bucket); // this is what gets signed
string query = "delimiter=/&prefix=";
if (strcmp(path, "/") != 0)
@@ -1309,7 +1310,7 @@
CURL* curl_handle = alloc_curl_handle();
- string resource = urlEncode("/"+bucket + "/" + Key);
+ string resource = urlEncode(service_path + bucket + "/" + Key);
string url = host + resource;
stuff_t stuff;
@@ -1562,6 +1563,14 @@
use_cache = strchr(arg, '=') + 1;
return 0;
}
+ if (strstr(arg, "host=") != 0) {
+ host = strchr(arg, '=') + 1;
+ return 0;
+ }
+ if (strstr(arg, "servicepath=") != 0) {
+ service_path = strchr(arg, '=') + 1;
+ return 0;
+ }
if (strstr(arg, "connect_timeout=") != 0) {
connect_timeout = strtol(strchr(arg, '=') + 1, 0, 10);
return 0;

BIN
s3fs/s3fs Executable file

Binary file not shown.

View File

@ -319,6 +319,7 @@ static string AWSAccessKeyId;
static string AWSSecretAccessKey;
static string host = "http://s3.amazonaws.com";
static mode_t root_mode = 0;
static string service_path = "/";
// if .size()==0 then local file cache is disabled
static string use_cache;
@ -506,7 +507,7 @@ mkdirp(const string& path, mode_t mode) {
int
get_headers(const char* path, headers_t& meta) {
string resource(urlEncode("/"+bucket + path));
string resource(urlEncode(service_path + bucket + path));
string url(host + resource);
auto_curl curl;
@ -549,7 +550,7 @@ get_headers(const char* path, headers_t& meta) {
*/
int
get_local_fd(const char* path) {
string resource(urlEncode("/"+bucket + path));
string resource(urlEncode(service_path + bucket + path));
string url(host + resource);
string baseName = mybasename(path);
@ -653,7 +654,7 @@ get_local_fd(const char* path) {
*/
static int
put_headers(const char* path, headers_t meta) {
string resource = urlEncode("/"+bucket + path);
string resource = urlEncode(service_path + bucket + path);
string url = host + resource;
auto_curl curl;
@ -708,7 +709,7 @@ put_headers(const char* path, headers_t meta) {
*/
static int
put_local_fd(const char* path, headers_t meta, int fd) {
string resource = urlEncode("/"+bucket + path);
string resource = urlEncode(service_path + bucket + path);
string url = host + resource;
struct stat st;
@ -784,7 +785,7 @@ s3fs_getattr(const char *path, struct stat *stbuf) {
}
}
string resource = urlEncode("/"+bucket + path);
string resource = urlEncode(service_path +bucket + path);
string url = host + resource;
auto_curl curl;
@ -894,7 +895,7 @@ s3fs_mknod(const char *path, mode_t mode, dev_t rdev) {
// If pathname already exists, or is a symbolic link, this call fails with an EEXIST error.
cout << "mknod[path="<< path << "][mode=" << mode << "]" << endl;
string resource = urlEncode("/"+bucket + path);
string resource = urlEncode(service_path + bucket + path);
string url = host + resource;
auto_curl curl;
@ -927,7 +928,7 @@ static int
s3fs_mkdir(const char *path, mode_t mode) {
cout << "mkdir[path=" << path << "][mode=" << mode << "]" << endl;
string resource = urlEncode("/"+bucket + path);
string resource = urlEncode(service_path + bucket + path);
string url = host + resource;
auto_curl curl;
@ -960,7 +961,7 @@ static int
s3fs_unlink(const char *path) {
cout << "unlink[path=" << path << "]" << endl;
string resource = urlEncode("/"+bucket + path);
string resource = urlEncode(service_path + bucket + path);
string url = host + resource;
auto_curl curl;
@ -984,7 +985,7 @@ static int
s3fs_rmdir(const char *path) {
cout << "unlink[path=" << path << "]" << endl;
string resource = urlEncode("/"+bucket + path);
string resource = urlEncode(service_path + bucket + path);
string url = host + resource;
auto_curl curl;
@ -1233,7 +1234,7 @@ s3fs_readdir(const char *path, void *buf, fuse_fill_dir_t filler, off_t offset,
while (IsTruncated == "true") {
string responseText;
string resource = urlEncode("/"+bucket); // this is what gets signed
string resource = urlEncode(service_path + bucket); // this is what gets signed
string query = "delimiter=/&prefix=";
if (strcmp(path, "/") != 0)
@ -1309,7 +1310,7 @@ s3fs_readdir(const char *path, void *buf, fuse_fill_dir_t filler, off_t offset,
CURL* curl_handle = alloc_curl_handle();
string resource = urlEncode("/"+bucket + "/" + Key);
string resource = urlEncode(service_path + bucket + "/" + Key);
string url = host + resource;
stuff_t stuff;
@ -1562,6 +1563,14 @@ my_fuse_opt_proc(void *data, const char *arg, int key, struct fuse_args *outargs
use_cache = strchr(arg, '=') + 1;
return 0;
}
if (strstr(arg, "host=") != 0) {
host = strchr(arg, '=') + 1;
return 0;
}
if (strstr(arg, "servicepath=") != 0) {
service_path = strchr(arg, '=') + 1;
return 0;
}
if (strstr(arg, "connect_timeout=") != 0) {
connect_timeout = strtol(strchr(arg, '=') + 1, 0, 10);
return 0;