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; }
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; }
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; }
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; }
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; } }
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 = ¶ms->args[params->args_count]; params->args_count++; *p = pcs_utils_strdup(arg); return 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; }
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; }
/* 根据传入参数,执行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; }
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; }