Skip to content
This repository has been archived by the owner on Dec 16, 2020. It is now read-only.

Commit

Permalink
Merge branch 'dev'
Browse files Browse the repository at this point in the history
  • Loading branch information
GangZhuo committed Aug 24, 2017
2 parents 106f5f3 + bcd77d4 commit 2085ce4
Show file tree
Hide file tree
Showing 15 changed files with 344 additions and 81 deletions.
4 changes: 3 additions & 1 deletion Makefile.am
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,8 @@ shell_src = shell.c \
rb_tree/red_black_tree.c \
rb_tree/stack.c \
utils.c \
hashtable.c
hashtable.c \
cache.c

baidupcs_SOURCES = \
$(shell_src) \
Expand Down Expand Up @@ -68,6 +69,7 @@ noinst_HEADERS = pcs/BaiduPCS.h \
arg.h \
dir.h \
hashtable.h \
cache.h \
rb_tree/misc.h \
rb_tree/red_black_tree.h \
rb_tree/stack.h
Expand Down
5 changes: 4 additions & 1 deletion Makefile.old
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,8 @@ SHELL_OBJS = bin/shell_arg.o \
bin/rb_tree_stack.o \
bin/red_black_tree.o \
bin/shell_utils.o \
bin/hashtable.o
bin/hashtable.o \
bin/cache.o

#CCFLAGS = -DHAVE_ASPRINTF -DHAVE_ICONV
ifeq ($(LC_OS_NAME), cygwin)
Expand Down Expand Up @@ -75,6 +76,8 @@ bin/rb_tree_stack.o: rb_tree/stack.c rb_tree/stack.h
$(CC) -o $@ -c $(PCS_CCFLAGS) rb_tree/stack.c
bin/red_black_tree.o: rb_tree/red_black_tree.c rb_tree/red_black_tree.h
$(CC) -o $@ -c $(PCS_CCFLAGS) rb_tree/red_black_tree.c
bin/cache.o: cache.c cache.h
$(CC) -o $@ -c $(PCS_CCFLAGS) cache.c

bin/cJSON.o: pcs/cJSON.c pcs/cJSON.h
$(CC) -o $@ -c $(PCS_CCFLAGS) pcs/cJSON.c
Expand Down
22 changes: 18 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -24,8 +24,7 @@ C/C++写的一个百度网盘工具,可以在linux终端中使用。
cd ..
sudo apt install ./baidupcs_*.deb


编译 (Debian):
编译 (Debian) (新方法):
===================================
程序依赖于 libcurl。

Expand All @@ -35,12 +34,27 @@ C/C++写的一个百度网盘工具,可以在linux终端中使用。
git clone https://github.com/GangZhuo/BaiduPCS.git
### 3. 编译源代码
cd BaiduPCS
make clean
make
./configure && make
make install #将安装到/usr/local/bin下
### 4. 手动安装到其他目录,例如 /usr/bin 下
cp ./baidupcs /usr/bin/

编译 (Debian):
===================================
程序依赖于 libcurl。

### 1. 安装依赖
apt-get install build-essential libcurl4-openssl-dev libssl-dev
### 2. 获取源代码
git clone https://github.com/GangZhuo/BaiduPCS.git
### 3. 编译源代码
cd BaiduPCS
make clean -f Makefile.old
make -f Makefile.old
make install -f Makefile.old #将安装到/usr/local/bin下
### 4. 手动安装到其他目录,例如 /usr/bin 下
cp ./bin/pcs /usr/bin/

编译 (Windows):
===================================
### 1. 获取源代码
Expand Down
115 changes: 115 additions & 0 deletions cache.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,115 @@
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
#include <inttypes.h>
#include <string.h>
#include <assert.h>
#ifdef WIN32
# include <WinSock2.h>
# include <Windows.h>
#else
# include <unistd.h>
#endif

#include "cache.h"
#include "pcs/pcs_mem.h"

#ifdef WIN32
#ifndef __MINGW32__
# define lseek _lseek
# define fileno _fileno
# define fseeko _fseeki64
# define ftello _ftelli64
#endif
#endif

int cache_init(cathe_t *cache)
{
memset(cache, 0, sizeof(cathe_t));
cache->blocks.prev = &cache->blocks;
cache->blocks.next = &cache->blocks;
return 0;
}

void cache_uninit(cathe_t *cache)
{
if (cache) {
block_t *block = cache->blocks.next, *tmp;
while (block != &cache->blocks) {
tmp = block;
block = block->next;
pcs_free(tmp->data);
pcs_free(tmp);
}
}
}

int cache_reset(cathe_t *cache)
{
cache_uninit(cache);
cache->blocks.prev = &cache->blocks;
cache->blocks.next = &cache->blocks;
cache->total_size = 0;
return 0;
}

block_t *cache_newblock(curl_off_t start, char *data, size_t size)
{
block_t *block;
block = pcs_malloc(sizeof(block_t));
if (!block)
return NULL;
memset(block, 0, sizeof(block_t));
block->start = start;
block->size = size;
block->data = pcs_malloc(size);
if (!block->data) {
free(block);
return NULL;
}
memcpy(block->data, data, size);
return block;
}

int cache_addblock(cathe_t *cache, block_t *block)
{
block_t *pos = cache->blocks.next;
cache->total_size += block->size;
/* find position */
while (pos != &cache->blocks) {
if (pos->start > block->start)
break;
pos = pos->next;
}
block->next = pos;
block->prev = pos->prev;
pos->prev->next = block;
pos->prev = block;
return 0;
}

int cache_add(cathe_t *cache, curl_off_t start, char *data, size_t size)
{
block_t *block, *pos = cache->blocks.next;
block = cache_newblock(start, data, size);
if (!block)
return -1;
return cache_addblock(cache, block);
}

int cache_flush(cathe_t *cache)
{
block_t *block = cache->blocks.next;
int r;
while (block != &cache->blocks) {
r = fseeko((cache->fp), block->start, SEEK_SET);
if (r)
return -1;
r = fwrite(block->data, 1, block->size, cache->fp);
if (r != block->size)
return -1;
block = block->next;
}
return 0;
}

42 changes: 42 additions & 0 deletions cache.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
#ifndef _PCS_SHELL_CAHCE_H
#define _PCS_SHELL_CAHCE_H

#include "pcs/pcs.h"

#ifndef MAX_CACHE_SIZE
#define MAX_CACHE_SIZE (1 * 1024) /* 1MiB */
#endif

#ifdef __cplusplus
extern "C" {
#endif

typedef struct block {
curl_off_t start;
size_t size;
char *data;
struct block *prev;
struct block *next;
} block_t;

typedef struct cache {
block_t blocks;
FILE *fp;
size_t total_size;
} cathe_t;

int cache_init(cathe_t *cache);

void cache_uninit(cathe_t *cache);

int cache_add(cathe_t *cache, curl_off_t start, char *data, size_t size);

int cache_flush(cathe_t *cache);

int cache_reset(cathe_t *cache);

#ifdef __cplusplus
}
#endif

#endif
2 changes: 1 addition & 1 deletion openwrt/Makefile
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
include $(TOPDIR)/rules.mk

PKG_NAME:=BaiduPCS
PKG_VERSION:=0.2.6
PKG_VERSION:=0.3
PKG_RELEASE:=$(PKG_SOURCE_VERSION)

PKG_BUILD_DIR := $(BUILD_DIR)/$(PKG_NAME)-$(PKG_VERSION)
Expand Down
11 changes: 3 additions & 8 deletions pcs/pcs.c
Original file line number Diff line number Diff line change
Expand Up @@ -34,12 +34,6 @@

#define PCS_SKIP_SPACE(p) while((*p) && (*p == ' ' || *p == '\f' || *p == '\n' || *p == '\r' || *p == '\t' || *p == '\v')) p++

//#define PCS_IS_TOKEN_CHAR(ch) (((ch) >= '0' && (ch) <= '9')\
// || ((ch) >= 'a' && (ch) <= 'z')\
// || ((ch) >= 'A' && (ch) <= 'Z')\
// || (ch) == '_'\
// || (ch) == '-')

#define PCS_IS_TOKEN_CHAR(ch) ((ch) != '&' && (ch) != '?' && (ch) != '#' && (ch) > 32 && (ch) < 127)

#define URL_HOME "http://www.baidu.com"
Expand Down Expand Up @@ -128,9 +122,7 @@ PCS_API void pcs_set_errmsg(Pcs handle, const char *fmt, ...)

PCS_API void pcs_cat_errmsg(Pcs handle, const char *fmt, ...)
{
struct pcs *pcs = (struct pcs *)handle;
char *errmsg;
size_t sz = 0;
va_list args;
va_start(args, fmt);
errmsg = pcs_utils_vsprintf(fmt, args);
Expand Down Expand Up @@ -323,6 +315,9 @@ static char *pcs_get_yunData(const char *html, const char *key)
p++;
}
return val;
#undef st_push
#undef st_pop
#undef st_top
}

/*从URL地址的QueryString中解析出类似于 &error=123&a= 的值。此例中,key传入"&error",将返回123*/
Expand Down
2 changes: 1 addition & 1 deletion pcs/pcs.h
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
#include "pcs_slist.h"
#include "pcs_utils.h"

#define PCS_API_VERSION "v1.1.4"
#define PCS_API_VERSION "v1.1.5"

#define PCS_RAPIDUPLOAD_THRESHOLD (256 * 1024)

Expand Down
29 changes: 20 additions & 9 deletions pcs/pcs_http.c
Original file line number Diff line number Diff line change
Expand Up @@ -89,9 +89,11 @@ enum HttpMethod
HTTP_METHOD_POST
};

static inline void pcs_http_prepare(struct pcs_http *http, enum HttpMethod method, const char *url, PcsBool follow_location,
static inline void pcs_http_prepare(struct pcs_http *http, enum HttpMethod method,
const char *url, PcsBool follow_location,
PcsHttpWriteFunction write_func, void *state,
curl_off_t max_recv_speed, curl_off_t max_send_speed,
long min_recv_speed, long min_recv_speed_time,
curl_off_t resume_from, curl_off_t max_length)
{
pcs_http_reset_response(http);
Expand All @@ -113,6 +115,15 @@ static inline void pcs_http_prepare(struct pcs_http *http, enum HttpMethod metho
curl_easy_setopt(http->curl, CURLOPT_WRITEFUNCTION, write_func);
curl_easy_setopt(http->curl, CURLOPT_WRITEDATA, state);

if (min_recv_speed > 0 && min_recv_speed_time > 0) {
curl_easy_setopt(http->curl, CURLOPT_LOW_SPEED_LIMIT, min_recv_speed);
curl_easy_setopt(http->curl, CURLOPT_LOW_SPEED_TIME, min_recv_speed_time);
}
else {
curl_easy_setopt(http->curl, CURLOPT_LOW_SPEED_LIMIT, 1024L);
curl_easy_setopt(http->curl, CURLOPT_LOW_SPEED_TIME, 30L);
}

// 设置文件续传的位置给libcurl
if (resume_from && max_length) {
char *range = pcs_utils_sprintf("%" PRId64 "-%" PRId64, resume_from, resume_from + max_length - 1);
Expand Down Expand Up @@ -455,8 +466,6 @@ PCS_API PcsHttp pcs_http_create(const char *cookie_file)
}
curl_easy_setopt(http->curl, CURLOPT_SSL_VERIFYPEER, 0L);
curl_easy_setopt(http->curl, CURLOPT_SSL_VERIFYHOST, 0L);
curl_easy_setopt(http->curl, CURLOPT_LOW_SPEED_LIMIT, 1024L);
curl_easy_setopt(http->curl, CURLOPT_LOW_SPEED_TIME, 60L);
curl_easy_setopt(http->curl, CURLOPT_SSL_VERIFYHOST, 0L);
curl_easy_setopt(http->curl, CURLOPT_USERAGENT, USAGE);
curl_easy_setopt(http->curl, CURLOPT_FOLLOWLOCATION, 1L);
Expand Down Expand Up @@ -807,15 +816,15 @@ PCS_API int pcs_http_get_response_size(PcsHttp handle)
PCS_API char *pcs_http_get(PcsHttp handle, const char *url, PcsBool follow_location)
{
struct pcs_http *http = (struct pcs_http *)handle;
pcs_http_prepare(http, HTTP_METHOD_GET, url, follow_location, &pcs_http_write, http, 0, 0, 0, 0);
pcs_http_prepare(http, HTTP_METHOD_GET, url, follow_location, &pcs_http_write, http, 0, 0, 0, 0, 0, 0);
return pcs_http_perform(http, url);
}

PCS_API char *pcs_http_get_raw(PcsHttp handle, const char *url, PcsBool follow_location, size_t *sz)
{
struct pcs_http *http = (struct pcs_http *)handle;
char *data;
pcs_http_prepare(http, HTTP_METHOD_GET, url, follow_location, &pcs_http_write, http, 0, 0, 0, 0);
pcs_http_prepare(http, HTTP_METHOD_GET, url, follow_location, &pcs_http_write, http, 0, 0, 0, 0, 0, 0);
http->res_type = PCS_HTTP_RES_TYPE_RAW;
data = pcs_http_perform(http, url);
if (sz) *sz = http->res_body_size;
Expand All @@ -825,7 +834,7 @@ PCS_API char *pcs_http_get_raw(PcsHttp handle, const char *url, PcsBool follow_l
PCS_API char *pcs_http_post(PcsHttp handle, const char *url, char *post_data, PcsBool follow_location)
{
struct pcs_http *http = (struct pcs_http *)handle;
pcs_http_prepare(http, HTTP_METHOD_POST, url, follow_location, &pcs_http_write, http, 0, 0, 0, 0);
pcs_http_prepare(http, HTTP_METHOD_POST, url, follow_location, &pcs_http_write, http, 0, 0, 0, 0, 0, 0);
if (post_data)
curl_easy_setopt(http->curl, CURLOPT_POSTFIELDS, post_data);
else
Expand All @@ -837,7 +846,9 @@ PCS_API PcsBool pcs_http_get_download(PcsHttp handle, const char *url, PcsBool f
{
struct pcs_http *http = (struct pcs_http *)handle;
pcs_http_prepare(http, HTTP_METHOD_GET, url, follow_location, &pcs_http_write, http,
max_speed, 0, resume_from, max_length);
max_speed, 0,
5 * 1024L, 10L, /* 10秒内的平均下载速度低于 5KB/s 的话,则取消下载 */
resume_from, max_length);
http->res_type = PCS_HTTP_RES_TYPE_DOWNLOAD;
pcs_http_perform(http, url);
return http->strerror == NULL ? PcsTrue : PcsFalse;
Expand All @@ -853,7 +864,7 @@ PCS_API int64_t pcs_http_get_download_filesize(PcsHttp handle, const char *url,
CURLcode res;
double downloadFileLenth = 0;
struct pcs_http *http = (struct pcs_http *)handle;
pcs_http_prepare(http, HTTP_METHOD_GET, url, follow_location, pcs_http_null_write, NULL, 0, 0, 0, 0);
pcs_http_prepare(http, HTTP_METHOD_GET, url, follow_location, pcs_http_null_write, NULL, 0, 0, 0, 0, 0, 0);
curl_easy_setopt(http->curl, CURLOPT_NOBODY, 1L); //不需要body
res = curl_easy_perform(http->curl);
if (res == CURLE_OK) {
Expand Down Expand Up @@ -967,7 +978,7 @@ PCS_API char *pcs_post_httpform(PcsHttp handle, const char *url, PcsHttpForm dat
struct pcs_http *http = (struct pcs_http *)handle;
struct http_post *formpost = (struct http_post *)data;
char *rc;
pcs_http_prepare(http, HTTP_METHOD_POST, url, follow_location, &pcs_http_write, http, 0, max_speed, 0, 0);
pcs_http_prepare(http, HTTP_METHOD_POST, url, follow_location, &pcs_http_write, http, 0, max_speed, 0, 0, 0, 0);
if (data){
curl_easy_setopt(http->curl, CURLOPT_HTTPPOST, formpost->formpost);
if (formpost->read_func) {
Expand Down
4 changes: 1 addition & 3 deletions pcs/pcs_utils.c
Original file line number Diff line number Diff line change
Expand Up @@ -132,8 +132,6 @@ PCS_API char* pcs_utils_readable_size(double size/*in bytes*/, char *buf, int bu
/* Human-readable left time */
PCS_API char* pcs_utils_readable_left_time(int64_t second, char *buf, int buf_size, char *sp)
{
int i = 0;
const char* units[] = { "B", "KB", "MB", "GB", "TB", "PB", "EB", "ZB", "YB" };
int day = (int)(second / (24 * 60 * 60));
int hour = (int)((second % (24 * 60 * 60)) / (60 * 60));
int minute = (int)(((second % (24 * 60 * 60)) % (60 * 60)) / 60);
Expand Down Expand Up @@ -310,7 +308,7 @@ PCS_API const char *pcs_md5_file_s(const char *file_name)
printf("%s can't be openedn", file_name);
return 0;
}
while (length = fread(buffer, 1, 1024, file))
while ((length = fread(buffer, 1, 1024, file)))
MD5_Update(&md5, buffer, length);
MD5_Final(md, &md5);
fclose(file);
Expand Down
Loading

0 comments on commit 2085ce4

Please sign in to comment.