Beispiel #1
0
size_t pcs_http_write(char *ptr, size_t size, size_t nmemb, void *userdata)
{
	struct pcs_http *http = (struct pcs_http *)userdata;
	size_t sz;
	char *p;

	if (size == 0 || nmemb == 0) {
		return 0;
	}
	sz = size * nmemb;
	if (!pcs_http_parse_http_head(http, &ptr, &sz, PcsTrue)) {
		if (http->strerror) pcs_free(http->strerror);
		http->strerror = pcs_utils_strdup("Cannot parse the http head. ");
		return 0;
	}
	if (sz > 0) {
		if (http->res_type == PCS_HTTP_RES_TYPE_NORMAL + 1) {
			http->res_body = pcs_http_append_bytes(http->res_body, http->res_body_size, ptr, sz);
			http->res_body_size += sz;
		}
		else if (http->res_type == PCS_HTTP_RES_TYPE_VALIDATE_TEXT + 1) {
			//验证内容正确性
			p = &ptr[sz - 1];
			while(p > ptr) {
				if (*p == 0) {
					if (http->strerror) pcs_free(http->strerror);
					http->strerror = pcs_utils_strdup("The response is not the validate text. ");
					return 0;
				}
				p--;
			}
			http->res_body = pcs_http_append_bytes(http->res_body, http->res_body_size, ptr, sz);
			http->res_body_size += sz;
		}
		else if (http->res_type == PCS_HTTP_RES_TYPE_RAW + 1) {
			http->res_body = pcs_http_append_bytes(http->res_body, http->res_body_size, ptr, sz);
			http->res_body_size += sz;
		}
		else if (http->res_type == PCS_HTTP_RES_TYPE_DOWNLOAD + 1) {
			if (!http->write_func) {
				if (http->strerror) pcs_free(http->strerror);
				http->strerror = pcs_utils_strdup("Have no write function. ");
				return 0;
			}
			return (*http->write_func)(ptr, sz, http->res_content_length, http->write_data);
		}
		else
			return 0;
	}

	return size * nmemb;
}
Beispiel #2
0
PCS_API PcsRes pcs_setopt(Pcs handle, PcsOption opt, void *value)
{
	PcsRes res = PCS_OK;
	struct pcs *pcs = (struct pcs *)handle;
	switch (opt)
	{
	case PCS_OPTION_USERNAME:
		if (pcs->username) pcs_free(pcs->username);
		pcs->username = pcs_utils_strdup((char *)value);
		break;
	case PCS_OPTION_PASSWORD:
		if (pcs->password) pcs_free(pcs->password);
		pcs->password = pcs_utils_strdup((char *)value);
		break;
	case PCS_OPTION_CAPTCHA_FUNCTION:
		pcs->captcha_func = (PcsGetCaptchaFunction)value;
		break;
	case PCS_OPTION_CAPTCHA_FUNCTION_DATA:
		pcs->captcha_data = value;
		break;
	case PCS_OPTION_DOWNLOAD_WRITE_FUNCTION:
		pcs_http_setopt(pcs->http, PCS_HTTP_OPTION_HTTP_WRITE_FUNCTION, value);
		break;
	case PCS_OPTION_DOWNLOAD_WRITE_FUNCTION_DATA:
		pcs_http_setopt(pcs->http, PCS_HTTP_OPTION_HTTP_WRITE_FUNCTION_DATE, value);
		break;
	case PCS_OPTION_HTTP_RESPONSE_FUNCTION:
		pcs_http_setopt(pcs->http, PCS_HTTP_OPTION_HTTP_RESPONSE_FUNCTION, value);
		break;
	case PCS_OPTION_HTTP_RESPONSE_FUNCTION_DATE:
		pcs_http_setopt(pcs->http, PCS_HTTP_OPTION_HTTP_RESPONSE_FUNCTION_DATE, value);
		break;
	case PCS_OPTION_PROGRESS_FUNCTION:
		pcs_http_setopt(pcs->http, PCS_HTTP_OPTION_PROGRESS_FUNCTION, value);
		break;
	case PCS_OPTION_PROGRESS_FUNCTION_DATE:
		pcs_http_setopt(pcs->http, PCS_HTTP_OPTION_PROGRESS_FUNCTION_DATE, value);
		break;
	case PCS_OPTION_PROGRESS:
		pcs_http_setopt(pcs->http, PCS_HTTP_OPTION_PROGRESS, value);
		break;
	default:
		pcs_set_errmsg(handle, "Unknown option");
		res = PCS_UNKNOWN_OPT;
		break;
	}
	return res;
}
Beispiel #3
0
PCS_API PcsFileInfo *pcs_fileinfo_clone(PcsFileInfo *fi)
{
	PcsFileInfo *res = pcs_fileinfo_create();
	if (!res) return 0;
	res->fs_id = fi->fs_id;
	res->path = pcs_utils_strdup(fi->path);
	res->server_filename = pcs_utils_strdup(fi->server_filename);
	res->server_ctime = fi->server_ctime;
	res->server_mtime = fi->server_mtime;
	res->local_ctime = fi->local_ctime;
	res->local_mtime = fi->local_mtime;
	res->size = fi->size;
	res->category = fi->category;
	res->isdir = fi->isdir;
	res->dir_empty = fi->dir_empty;
	res->empty = fi->empty;
	res->md5 = pcs_utils_strdup(fi->md5);
	res->dlink = pcs_utils_strdup(fi->dlink);
	if (fi->block_list) {
		char **p = fi->block_list;
		int i = 0;
		while(*p) {
			i++;
			p++;
		}
		res->block_list = (char **)pcs_malloc((i + 1) * sizeof(char *));
		if (res->block_list) {
			i = 0;
			p = fi->block_list;
			while(*p) {
				res->block_list[i++] = pcs_utils_strdup(*p);
				p++;
			}
		}
	}
	res->ifhassubdir = fi->ifhassubdir;
	if (fi->thumbs) {
        res->thumbs = pcs_slist2_clone(fi->thumbs);
    }
    return res;
}
Beispiel #4
0
PCS_API int64_t pcs_http_get_download_filesize(PcsHttp handle, const char *url, PcsBool follow_location)
{
	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);
	curl_easy_setopt(http->curl, CURLOPT_NOBODY, 1L);   //不需要body
	res = curl_easy_perform(http->curl);
	if (res == CURLE_OK) {
		curl_easy_getinfo(http->curl, CURLINFO_CONTENT_LENGTH_DOWNLOAD, &downloadFileLenth);
	}
	else {
		if (!http->strerror) http->strerror = pcs_utils_strdup(curl_easy_strerror(res));
		downloadFileLenth = 0;
	}
	return (int64_t)downloadFileLenth;
}
Beispiel #5
0
PCS_API void pcs_http_setopt(PcsHttp handle, PcsHttpOption opt, void *value)
{
	struct pcs_http *http = (struct pcs_http *)handle;
	switch (opt)
	{
	case PCS_HTTP_OPTION_HTTP_WRITE_FUNCTION:
		http->write_func = (PcsHttpWriteFunction)value;
		break;
	case PCS_HTTP_OPTION_HTTP_WRITE_FUNCTION_DATE:
		http->write_data = value;
		break;
	case PCS_HTTP_OPTION_HTTP_READ_FUNCTION:
		break;
	case PCS_HTTP_OPTION_HTTP_READ_FUNCTION_DATE:
		break;
	case PCS_HTTP_OPTION_HTTP_RESPONSE_FUNCTION:
		http->response_func = (PcsHttpResponseFunction)value;
		break;
	case PCS_HTTP_OPTION_HTTP_RESPONSE_FUNCTION_DATE:
		http->response_data = value;
		break;
	case PCS_HTTP_OPTION_PROGRESS_FUNCTION:
		http->progress_func = (PcsHttpProgressCallback)value;
		break;
	case PCS_HTTP_OPTION_PROGRESS_FUNCTION_DATE:
		http->progress_data = value;
		break;
	case PCS_HTTP_OPTION_PROGRESS:
		http->progress = (unsigned char)((unsigned long)value);
		break;
	case PCS_HTTP_OPTION_USAGE:
		if (http->usage) pcs_free(http->usage);
		http->usage = value ? pcs_utils_strdup((char *)value) : NULL;
		break;
	case PCS_HTTP_OPTION_TIMEOUT:
		http->timeout = (int)((long)value);
		break;
	case PCS_HTTP_OPTION_CONNECTTIMEOUT:
		http->connect_timeout = (int)((long)value);
		break;
	default:
		break;
	}
}
Beispiel #6
0
static error_t add_arg(struct params *params, char *arg)
{
	char **p;
	int i;
	p = (char **) pcs_malloc((params->args_count + 1) * sizeof(char *));
	if (!p) {
		print_arg_err("alloc memory failed\n");
		params->is_fail = PcsTrue;
		return EINVAL;
	}
	if (params->args_count > 0) {
		for (i = 0; i < params->args_count; i++) {
			p[i] = params->args[i];
		}
		pcs_free(params->args);
	}
	params->args = p;
	p = &params->args[params->args_count];
	params->args_count++;
	*p = pcs_utils_strdup(arg);
	return 0;
}
Beispiel #7
0
/*转换JSON对象为PcsFileInfo对象。
JSON对象格式为:
{
	"fs_id": 123,
	"path": "/a/b",
	"server_filename": "b",
	"mtime": 1899383,
	"ctime": 1899383,
	"server_mtime": 1899383,
	"server_ctime": 1899383,
	"local_mtime": 1899383,
	"local_ctime": 1899383,
	"isdir": 1,
	"category": 1,
	"size": 0,
	"dir_empty": 0,
	"empty": 0,
	"ifhassubdir": 0,
	"md5": "",
	"dlink": "",
	"block_list": [ "/a/b/1", "a/b/2" ]
}
*/
static PcsFileInfo *pcs_parse_fileinfo(cJSON * item)
{
	cJSON *val, *list;
	PcsFileInfo *fi = pcs_fileinfo_create();
	val = cJSON_GetObjectItem(item, "fs_id");
	if ((val = cJSON_GetObjectItem(item, "fs_id")))
		fi->fs_id = (UInt64)val->valuedouble;

	val = cJSON_GetObjectItem(item, "path");
	if (val)
		fi->path = pcs_utils_strdup(val->valuestring);

	val = cJSON_GetObjectItem(item, "server_filename");
	if (val)
		fi->server_filename = pcs_utils_strdup(val->valuestring);

	val = cJSON_GetObjectItem(item, "mtime");
	if (val)
		fi->server_mtime = (UInt64)val->valuedouble;

	val = cJSON_GetObjectItem(item, "ctime");
	if (val)
		fi->server_ctime = (UInt64)val->valuedouble;

	val = cJSON_GetObjectItem(item, "server_mtime");
	if (val)
		fi->server_mtime = (UInt64)val->valuedouble;

	val = cJSON_GetObjectItem(item, "server_ctime");
	if (val)
		fi->server_ctime = (UInt64)val->valuedouble;

	val = cJSON_GetObjectItem(item, "local_mtime");
	if (val)
		fi->local_mtime = (UInt64)val->valuedouble;

	val = cJSON_GetObjectItem(item, "local_ctime");
	if (val)
		fi->local_ctime = (UInt64)val->valuedouble;

	val = cJSON_GetObjectItem(item, "isdir");
	if (val)
		fi->isdir = val->valueint ? PcsTrue : PcsFalse;

	val = cJSON_GetObjectItem(item, "category");
	if (val)
		fi->category = val->valueint;

	val = cJSON_GetObjectItem(item, "size");
	if (val)
		fi->size = (UInt64)val->valuedouble;

	val = cJSON_GetObjectItem(item, "dir_empty");
	if (val)
		fi->dir_empty = val->valueint ? PcsTrue : PcsFalse;

	val = cJSON_GetObjectItem(item, "empty");
	if (val)
		fi->empty = val->valueint ? PcsTrue : PcsFalse;

	val = cJSON_GetObjectItem(item, "ifhassubdir");
	if (val)
		fi->ifhassubdir = val->valueint ? PcsTrue : PcsFalse;

	val = cJSON_GetObjectItem(item, "md5");
	if (val)
		fi->md5 = pcs_utils_strdup(val->valuestring);

	val = cJSON_GetObjectItem(item, "dlink");
	if (val)
		fi->dlink = pcs_utils_strdup(val->valuestring);

	list = cJSON_GetObjectItem(item, "block_list");
	if (list) {
		int i, cnt = cJSON_GetArraySize(list);
		if (cnt > 0) {
			fi->block_list = (char **) pcs_malloc((cnt + 1) + sizeof(char *));
			if (!fi->block_list) return fi;
			memset(fi->block_list, 0, (cnt + 1) + sizeof(char *));
			for (i = 0; i < cnt; i++) {
				val = cJSON_GetArrayItem(list, i);
				fi->block_list[i] = pcs_utils_strdup(val->valuestring);
			}
		}
	}
	return fi;
}
Beispiel #8
0
PCS_API PcsRes pcs_login(Pcs handle)
{
	struct pcs *pcs = (struct pcs *)handle;
	PcsRes res;
	char *p, *html, *url, *token, *code_string, captch[8], *post_data, *tt;
	cJSON *json, *root, *item;
	int error = -1, i;

	pcs_clear_errmsg(handle);
	html = pcs_http_get(pcs->http, URL_HOME, PcsTrue);
	if (!html) {
		pcs_set_errmsg(handle, "Can't get response from the server.");
		return PCS_NETWORK_ERROR;
	}
	html = pcs_http_get(pcs->http, URL_PASSPORT_API "login", PcsTrue);
	if (!html) {
		pcs_set_errmsg(handle, "Can't get response from the server.");
		return PCS_NETWORK_ERROR;
	}
	url = pcs_utils_sprintf(URL_PASSPORT_API "getapi" "&tpl=ik" "&apiver=v3" "&class=login" "&tt=%d", 
		(int)time(0));
	html = pcs_http_get(pcs->http, url, PcsTrue); pcs_free(url);
	if (!html) {
		pcs_set_errmsg(handle, "Can't get response from the server.");
		return PCS_NETWORK_ERROR;
	}
	json = cJSON_Parse(html);
	if (!json){
		pcs_set_errmsg(handle, "Can't parse the response as object. Response: %s", html);
		return PCS_WRONG_RESPONSE;
	}

	root = cJSON_GetObjectItem(json, "data");
	if (!root) {
		pcs_set_errmsg(handle, "Can't read res.data. Response: %s", html);
		cJSON_Delete(json);
		return PCS_WRONG_RESPONSE;
	}

	item = cJSON_GetObjectItem(root, "token");
	if (!item) {
		pcs_set_errmsg(handle, "Can't read res.token. Response: %s", html);
		cJSON_Delete(json);
		return PCS_WRONG_RESPONSE;
	}
	token = pcs_utils_strdup(item->valuestring);

	item = cJSON_GetObjectItem(root, "codeString");
	if (!item) {
		pcs_set_errmsg(handle, "Can't read res.codeString. Response: %s", html);
		pcs_free(token);
		cJSON_Delete(json);
		return PCS_WRONG_RESPONSE;
	}
	code_string = pcs_utils_strdup(item->valuestring);

	cJSON_Delete(json);

	p = token;
	while (*p) {
		if (!((*p >= '0' && *p <= '9') || (*p >= 'a' && *p <= 'f') || (*p >= 'A' && *p <= 'F'))) {
			pcs_set_errmsg(handle, "Invalid token. Token: %s", token);
			pcs_free(token);
			pcs_free(code_string);
			return PCS_WRONG_RESPONSE;
		}
		p++;
	}

	i = 0;
try_login:
	if (code_string[0]) {
		res = pcs_get_captcha(pcs, code_string, captch, sizeof(captch));
		if (res != PCS_OK) {
			pcs_free(token);
			pcs_free(code_string);
			return res;
		}
	}
	tt = pcs_utils_sprintf("%d", (int)time(0));
	post_data = pcs_http_build_post_data(pcs->http,
		"ppui_logintime", "6852",
		"charset", "UTF-8",
		"codestring", code_string,
		"token", token,
		"isPhone", "false",
		"index", "0",
		"u", "",
		"safeflg", "0",
		"staticpage", "http://www.baidu.com/cache/user/html/jump.html",
		"loginType", "1",
		"tpl", "mn",
		"callback", "parent.bdPass.api.login._postCallback",
		"username", pcs->username,
		"password", pcs->password,
		"verifycode", captch,
		"mem_pass", "on",
		"tt", tt,
		NULL);
	pcs_free(tt);
	if (!post_data) {
		pcs_set_errmsg(handle, "Can't build the post data.");
		pcs_free(token);
		pcs_free(code_string);
		return PCS_BUILD_POST_DATA;
	}
	html = pcs_http_post(pcs->http, URL_PASSPORT_API "login", post_data, PcsTrue);
	pcs_free(post_data);
	if (!html) {
		pcs_set_errmsg(handle, "Can't get the response from the server.");
		pcs_free(token);
		pcs_free(code_string);
		return PCS_NETWORK_ERROR;
	}
	else {
		char *errorStr = pcs_get_embed_query_int_value_by_key(html, "&error");
		if (!errorStr) {
			pcs_set_errmsg(handle, "Can't read the error from the response. Response: %s", html);
			pcs_free(token);
			pcs_free(code_string);
			return PCS_NETWORK_ERROR;
		}
		error = atoi(errorStr);
		pcs_free(errorStr);
	}

	if (error == 0) {
		if (pcs_islogin(pcs) == PCS_LOGIN) {
			pcs_free(token);
			pcs_free(code_string);
			return PCS_OK;
		}
		else {
			pcs_set_errmsg(handle, "Unknown Error");
			pcs_free(token);
			pcs_free(code_string);
			return PCS_FAIL;
		}
	}
	else {
		if (code_string) pcs_free(code_string);
		code_string = pcs_get_embed_query_token_by_key(html, "&codestring");
		if (!code_string) {
			pcs_set_errmsg(handle, "Can't read the codestring from the response. Response: %s", html);
			pcs_free(token);
			pcs_free(code_string);
			return PCS_FAIL;
		}
	}
	if (i < 1 && code_string[0]) {
		i++;
		goto try_login;
	}
	pcs_free(token);
	pcs_free(code_string);
	pcs_set_errmsg(handle, "Unknown Error");
	return PCS_FAIL;
}
Beispiel #9
0
/*
根据传入参数,执行api函数。
opera: delete, rename, move, copy
*/
static PcsPanApiRes *pcs_pan_api_filemanager(Pcs handle, const char *opera, const char *filelist, int file_count)
{
	struct pcs *pcs = (struct pcs *)handle;
	cJSON *json, *item, *list, *val;
	char *url, *html, *postdata;
	int error, cnt, i;
	PcsPanApiRes *res = NULL;
	PcsPanApiResInfoList *tail, *ri;

	PcsBool err_no_space = PcsFalse, //errno = -10 剩余空间不足
		err_target_not_exist = PcsFalse, //errno = -8 文件已存在于目标文件夹中
		err_src_file_not_exist = PcsFalse, //errno = -9 文件不存在
		err_has_succ_items = PcsFalse; //是否存在处理成功的文件项

	url = pcs_build_pan_api_url(handle, "filemanager",
		"opera", opera,
		NULL);
	if (!url) {
		pcs_set_errmsg(handle, "Can't build the url.");
		return NULL;
	}

	postdata = pcs_http_build_post_data(pcs->http, "filelist", filelist, NULL);
	if (!postdata) {
		pcs_set_errmsg(handle, "Can't build the post data.");
		pcs_free(url);
		return NULL;
	}
	html = pcs_http_post(pcs->http, url, postdata, PcsTrue);
	pcs_free(url);
	pcs_free(postdata);
	if (!html) {
		pcs_set_errmsg(handle, "Can't get response from the server.");
		return NULL;
	}
	json = cJSON_Parse(html);
	if (!json){
		pcs_set_errmsg(handle, "Can't parse the response as object. Response: %s", html);
		return NULL;
	}
	item = cJSON_GetObjectItem(json, "errno");
	if (!item) {
		pcs_set_errmsg(handle, "Can't read res.errno. Response: %s", html);
		cJSON_Delete(json);
		return NULL;
	}
	error = item->valueint;
	res = pcs_pan_api_res_create();
	if (!res) {
		pcs_set_errmsg(handle, "Can't create the object: PcsPanApiRes");
		cJSON_Delete(json);
		return NULL;
	}
	res->error = error;

	list = cJSON_GetObjectItem(json, "info");
	if (!list) {
		pcs_set_errmsg(handle, "Can't read res.info. Response: %s", html);
		cJSON_Delete(json);
		return NULL;
	}

	cnt = cJSON_GetArraySize(list);
	for (i = 0; i < cnt; i++) {
		item = cJSON_GetArrayItem(list, i);
		ri = pcs_pan_api_res_infolist_create();
		if (!ri) {
			pcs_set_errmsg(handle, "Can't create the object: PcsPanApiResInfoList");
			cJSON_Delete(json);
			if (res) pcs_pan_api_res_destroy(res);
			return NULL;
		}
		val = cJSON_GetObjectItem(item, "path");
		if (val)
			ri->info.path = pcs_utils_strdup(val->valuestring);
		val = cJSON_GetObjectItem(item, "errno");
		ri->info.error = val->valueint;
		if (!res->info_list) {
			res->info_list = tail = ri;
		}
		else {
			tail->next = ri;
			tail = ri;
		}
		switch (ri->info.error) {
		case 0: //I:处理成功
			err_has_succ_items = PcsTrue;
			break;
		case -8: //D:文件已存在于目标文件夹中
			err_target_not_exist = PcsTrue;
			break;
		case -9: //C:文件不存在
			err_src_file_not_exist = PcsTrue;
			break;
		case -10: //G:剩余空间不足
			err_no_space = PcsTrue;
			break;
		}
	}
	cJSON_Delete(json);
	if (res->error != 0) {
		int is_move = strcmp(opera, "move") == 0;
		if (is_move || strcmp(opera, "copy") == 0) {
			if (res->error == 12) {
				if (!err_no_space && !err_src_file_not_exist && !err_target_not_exist) {
					pcs_set_errmsg(handle, "%s%s", is_move ? "移动" : "复制", "失败,请稍候重试");
				}
				else {
					if (cnt == file_count && !err_has_succ_items) {
						if (err_no_space)
							pcs_set_errmsg(handle, "%s%s", is_move ? "移动" : "复制", "失败,剩余空间不足");
						else if (err_target_not_exist)
							pcs_set_errmsg(handle, "%s%s", is_move ? "移动" : "复制", "失败,文件已存在于目标文件夹中");
						else if (err_src_file_not_exist)
							pcs_set_errmsg(handle, "%s%s", is_move ? "移动" : "复制", "失败,待处理文件不存在");
					}
					else {
						if (err_no_space)
							pcs_set_errmsg(handle, "%s%s", is_move ? "移动" : "复制", "失败,剩余空间不足");
						else if (err_target_not_exist)
							pcs_set_errmsg(handle, "%s%s", is_move ? "移动" : "复制", "失败,部分文件已存在于目标文件夹中");
						else if (err_src_file_not_exist)
							pcs_set_errmsg(handle, "%s%s", is_move ? "移动" : "复制", "失败,部分待处理文件不存在");
					}
				}
			}
			else {
				pcs_set_errmsg(handle, "%s%s", is_move ? "移动" : "复制", "失败,未知错误");
			}
		}
		else if (strcmp(opera, "delete") == 0) {
			pcs_set_errmsg(handle, "删除文件失败,请稍候重试");
		}
		else if (strcmp(opera, "rename") == 0) {
			if (res->error == -8 || res->error == -9 || (cnt > 0 && (res->info_list->info.error == -8 || res->info_list->info.error == -9)))
				pcs_set_errmsg(handle, "名称已在使用,请使用其他名称");
			else if (res->error == 12 && cnt > 0 && res->info_list->info.error == -9)
				pcs_set_errmsg(handle, "重命名失败,文件已被删除或移走");
			else
				pcs_set_errmsg(handle, "文件(夹)重命名失败, 网络错误");
		}
	}
	return res;
}
Beispiel #10
0
static error_t parse_opt (int key, char *arg, struct argp_state *state)
{
	struct params *params = (struct params *)state->input;
	int i;

	switch (key) {
	case ARGP_KEY_INIT:
		if (params->username) pcs_free(params->username);
		if (params->password) pcs_free(params->password);
		if (params->sort) pcs_free(params->sort);
		if (params->cookie) pcs_free(params->cookie);
		if (params->rc4_key) pcs_free(params->rc4_key);
		if (params->args) {
			for (i = 0; i < params->args_count; i++) {
				pcs_free(params->args[i]);
			}
			pcs_free(params->args);
		}
		if (params->config) pcs_free(params->config);
		if (params->cache) pcs_free(params->cache);
		params->is_fail = PcsFalse;
		params->username = NULL;
		params->password = NULL;
		params->cookie = NULL;
		params->rc4_key = NULL;
		params->sort = NULL;
		params->is_recursion = PcsFalse;
		params->is_force = PcsFalse;
		params->is_desc = PcsFalse;
		params->use_urlc = PcsFalse;
		params->is_append = PcsFalse;
		params->is_verbose = PcsFalse;
		params->is_synch = PcsFalse;
		params->is_rc4 = PcsFalse;
		params->action = ACTION_NONE;
		params->args = NULL;
		params->args_count = 0;
		params->config = NULL;
		params->cache = NULL;
		params->md5 = PcsFalse;
		break;

	case ARGP_KEY_NO_ARGS:
		break;

	case ARGP_KEY_ARG:
		if (state->arg_num == 0) {
			if (strcmp(arg, "quota") == 0 || strcmp(arg, "info") == 0)
				params->action = ACTION_QUOTA;
			else if (strcmp(arg, "list") == 0 || strcmp(arg, "ls") == 0)
				params->action = ACTION_LIST;
			else if (strcmp(arg, "rename") == 0)
				params->action = ACTION_RENAME;
			else if (strcmp(arg, "move") == 0 || strcmp(arg, "mv") == 0)
				params->action = ACTION_MOVE;
			else if (strcmp(arg, "copy") == 0 || strcmp(arg, "cp") == 0)
				params->action = ACTION_COPY;
			else if (strcmp(arg, "mkdir") == 0)
				params->action = ACTION_MKDIR;
			else if (strcmp(arg, "delete") == 0 || strcmp(arg, "remove") == 0 || strcmp(arg, "rm") == 0)
				params->action = ACTION_DELETE;
			else if (strcmp(arg, "download") == 0 || strcmp(arg, "down") == 0)
				params->action = ACTION_DOWNLOAD;
			else if (strcmp(arg, "upload") == 0 || strcmp(arg, "up") == 0)
				params->action = ACTION_UPLOAD;
			else if (strcmp(arg, "cat") == 0)
				params->action = ACTION_CAT;
			else if (strcmp(arg, "echo") == 0)
				params->action = ACTION_ECHO;
			else if (strcmp(arg, "search") == 0)
				params->action = ACTION_SEARCH;
			else if (strcmp(arg, "meta") == 0)
				params->action = ACTION_META;
			else if (strcmp(arg, "svc") == 0)
				params->action = ACTION_SVC;
			else if (strcmp(arg, "reset") == 0)
				params->action = ACTION_RESET;
			else if (strcmp(arg, "update") == 0)
				params->action = ACTION_UPDATE;
			else if (strcmp(arg, "backup") == 0)
				params->action = ACTION_BACKUP;
			else if (strcmp(arg, "restore") == 0)
				params->action = ACTION_RESTORE;
			else if (strcmp(arg, "combin") == 0)
				params->action = ACTION_COMBIN;
			else if (strcmp(arg, "compare") == 0)
				params->action = ACTION_COMPARE;
			else if (strcmp(arg, "time") == 0)
				params->action = ACTION_TIME;
			else if (strcmp(arg, "ls-op") == 0)
				params->action = ACTION_LIST_ACTION;
			else if (strcmp(arg, "md5") == 0)
				params->action = ACTION_MD5;
			else {
				print_arg_err("unknown command\n");
				return EINVAL;
			}
			break;
		}
		if (add_arg(params, arg) != 0)
			return EINVAL;
		break;

	case 'u':
		if (arg && arg[0]) {
			params->username = pcs_utils_strdup(arg);
		}
		//else {
		//	print_arg_err("Not specify username\n");
		//	return EINVAL;
		//}
		break;

	case 'p':
		if (arg && arg[0]) {
			params->password = pcs_utils_strdup(arg);
		}
		break;

	case 'r':
		params->is_recursion = PcsTrue;
		break;

	case 'f':
		params->is_force = PcsTrue;
		break;

	case 's':
		if (arg) {
			params->sort = pcs_utils_strdup(arg);
		}
		break;

	case 'i':
		params->is_desc = PcsTrue;
		break;

	case 'U':
		params->use_urlc = PcsTrue;
		break;

	case 'a':
		params->is_append = PcsTrue;
		break;

	case 'v':
		params->is_verbose = PcsTrue;
		break;

	case OPT_SYNCH:
		params->is_synch = PcsTrue;
		break;

	case OPT_COOKIE:
		if (arg && arg[0]) {
			params->cookie = pcs_utils_strdup(arg);
		}
		break;

	case OPT_RC4:
		params->is_rc4 = PcsTrue;
		if (arg && arg[0]) {
			params->rc4_key = pcs_utils_strdup(arg);
		}
		break;

	case OPT_CONFIG:
		if (arg && arg[0]) {
			params->config = pcs_utils_strdup(arg);
		}
		break;

	case OPT_CACHE:
		if (arg && arg[0]) {
			params->cache = pcs_utils_strdup(arg);
		}
		break;

	case OPT_MD5:
		params->md5 = PcsTrue;
		break;

	case ARGP_KEY_END:
	case ARGP_KEY_ARGS:
	case ARGP_KEY_SUCCESS:
	default:
		
		return ARGP_ERR_UNKNOWN;
	}
	return 0;
}