예제 #1
0
파일: pcs.c 프로젝트: imzjy/baidupcs
PCS_API PcsFileInfo *pcs_meta(Pcs handle, const char *path)
{
	PcsFileInfoList *filist;
	PcsFileInfo *meta = NULL;
	char *dir, *key;
	PcsFileInfoListIterater iterater;
	
	pcs_clear_errmsg(handle);
	dir = pcs_utils_basedir(path);
	key = pcs_utils_filename(path);
	filist = pcs_search(handle, dir, key, PcsFalse);
	pcs_free(dir);
	pcs_free(key);
	if (!filist)
		return NULL;
	pcs_filist_iterater_init(filist, &iterater, PcsFalse);
	while(pcs_filist_iterater_next(&iterater)) {
		if (pcs_utils_strcmpi(path, iterater.current->path) == 0) {
			meta = iterater.current;
			break;
		}
	}
	if (meta) {
		meta = pcs_fileinfo_clone(meta);
		if (!meta) {
			pcs_set_errmsg(handle, "Can't clone the meta data.");
		}
	}
	else {
		pcs_set_errmsg(handle, "Can't find the file.");
	}
	pcs_filist_destroy(filist);
	return meta;
}
예제 #2
0
파일: shell.c 프로젝트: abitduck/baidupcs
static void print_filelist(PcsFileInfoList *list)
{
	char tmp[64] = {0};
	int cnt_file = 0,
		cnt_dir = 0,
		size_width = 1,
		w;
	PcsFileInfo *file = NULL;
	size_t total = 0;
	PcsFileInfoListIterater iterater;

	pcs_filist_iterater_init(list, &iterater, PcsFalse);
	while(pcs_filist_iterater_next(&iterater)) {
		file = iterater.current;
		w = -1;
		size_tostr(file->size, &w, ' ');
		if (size_width < w)
			size_width = w;
		total += file->size;
		if (file->isdir)
			cnt_dir++;
		else
			cnt_file++;
	}

	if (size_width < 4)
		size_width = 4;
	putchar('\n');
	print_filelist_head(size_width);
	puts("------------------------------------------------------------------------------");
	pcs_filist_iterater_init(list, &iterater, PcsFalse);
	while(pcs_filist_iterater_next(&iterater)) {
		file = iterater.current;
		print_filelist_row(file, size_width);
	}
	puts("------------------------------------------------------------------------------");
	pcs_utils_readable_size(total, tmp, 63, NULL);
	tmp[63] = '\0';
	printf("Total: %s, File Count: %d, Directory Count: %d\n", tmp, cnt_file, cnt_dir);
	putchar('\n');
}
예제 #3
0
파일: shell.c 프로젝트: abitduck/baidupcs
static int exec_download_dir(Pcs pcs, const char *remote_path, const char *local_path,
							 int force, int recursion, int synch)
{
	int ft;
	hashtable *ht;
	my_dirent *ents, *ent, *local_file;
	PcsFileInfoList *remote_files;
	PcsFileInfoListIterater iterater;
	PcsFileInfo *file;
	PcsRes dres;
	char *dest_path;
	struct download_state ddstat;
	FILE *pf;

	printf("\nDownload %s to %s\n", remote_path, local_path);
	ft = is_dir_or_file(local_path);
	if (ft == 1) {
		printf("Invalidate target: %s is not the directory.\n", local_path);
		return -1;
	}
	else if (ft == 2) {
		//if (!force) {
		//	printf("execute upload command failed: The target %s exist.\n", remote_path);
		//	return -1;
		//}
	}
	else {
		if (mkdir(local_path)) {
			printf("Cannot create the directory %s.\n", local_path);
			return -1;
		}
	}

	ents = list_dir(local_path, 0);

	ht = hashtable_create(100, 1, NULL);
	if (!ht) {
		printf("Cannot create hashtable.\n");
		my_dirent_destroy(ents);
		return -1;
	}
	ent = ents;
	while(ent) {
		if (hashtable_add(ht, ent->path, ent)) {
			printf("Cannot add item into hashtable.\n");
			hashtable_destroy(ht);
			my_dirent_destroy(ents);
			return -1;
		}
		ent = ent->next;
	}

	remote_files = get_file_list(pcs, remote_path, NULL, PcsFalse, PcsFalse);
	if (!remote_files) {
		hashtable_destroy(ht);
		my_dirent_destroy(ents);
		if (pcs_strerror(pcs)) {
			printf("Cannot list the remote files.\n");
			return -1;
		}
		return 0;
	}

	pcs_filist_iterater_init(remote_files, &iterater, PcsFalse);
	while(pcs_filist_iterater_next(&iterater)) {
		file = iterater.current;
		dest_path = combin_local_path(local_path, file->server_filename);
		if (!dest_path) {
			printf("Cannot alloca memory. 0%s, %s\n", local_path, file->server_filename);
			pcs_filist_destroy(remote_files);
			hashtable_destroy(ht);
			my_dirent_destroy(ents);
			return -1;
		}
		if (file->isdir) {
			if (force || recursion) {
				local_file = (my_dirent *)hashtable_get(ht, dest_path);
				if (local_file) {
					local_file->user_flag = 1;
					printf("[SKIP] d %s\n", file->path);
				}
				else if (recursion) {
					if (mkdir(dest_path)) {
						printf("[FAIL] d %s Cannot create the folder %s\n", file->path, dest_path);
						pcs_free(dest_path);
						pcs_filist_destroy(remote_files);
						hashtable_destroy(ht);
						my_dirent_destroy(ents);
						return -1;
					}
					else {
						printf("[SUCC] d %s => %s\n", file->path, dest_path);
					}
				}
			}
		}
		else {
			local_file = (my_dirent *)hashtable_get(ht, dest_path);
			if (local_file) local_file->user_flag = 1;
			if (force || !local_file || my_dirent_get_mtime(local_file) < ((time_t)file->server_mtime)) {
				ddstat.msg = (char *) pcs_malloc(strlen(dest_path) + 12);
				if (!ddstat.msg) {
					printf("Cannot alloca memory. 1%s, %s\n", local_path, file->server_filename);
					pcs_free(dest_path);
					pcs_filist_destroy(remote_files);
					hashtable_destroy(ht);
					my_dirent_destroy(ents);
					return -1;
				}
				sprintf(ddstat.msg, "Download %s ", dest_path);
				pf = fopen(dest_path, "wb");
				if (!pf) {
					printf("Cannot create the local file: %s\n", dest_path);
					pcs_free(dest_path);
					pcs_free(ddstat.msg);
					pcs_filist_destroy(remote_files);
					hashtable_destroy(ht);
					my_dirent_destroy(ents);
					return -1;
				}
				ddstat.pf = pf;
				ddstat.size = 0;
				pcs_setopt(pcs, PCS_OPTION_DOWNLOAD_WRITE_FUNCTION_DATA, &ddstat);
				dres = pcs_download(pcs, file->path);
				pcs_free(ddstat.msg);
				fclose(ddstat.pf);
				if (dres != PCS_OK) {
					printf("[FAIL] - %s => %s\n", file->path, dest_path);
					pcs_free(dest_path);
					pcs_filist_destroy(remote_files);
					hashtable_destroy(ht);
					my_dirent_destroy(ents);
					return -1;
				}
				my_dirent_utime(dest_path, file->server_mtime);
				printf("[SUCC] - %s => %s\n", file->path, dest_path);
			}
			else {
				printf("[SKIP] - %s\n", file->path);
			}
		}
		pcs_free(dest_path);
	}
	if (recursion) {
		pcs_filist_iterater_init(remote_files, &iterater, PcsFalse);
		while(pcs_filist_iterater_next(&iterater)) {
			file = iterater.current;
			dest_path = combin_local_path(local_path, file->server_filename);
			if (!dest_path) {
				printf("Cannot alloca memory. 2%s, %s\n", local_path, file->server_filename);
				pcs_filist_destroy(remote_files);
				hashtable_destroy(ht);
				my_dirent_destroy(ents);
				return -1;
			}
			if (file->isdir) {
				if (exec_download_dir(pcs, file->path, dest_path, force, recursion, synch)) {
					pcs_free(dest_path);
					pcs_filist_destroy(remote_files);
					hashtable_destroy(ht);
					my_dirent_destroy(ents);
					return -1;
				}
			}
			pcs_free(dest_path);
		}
	}
	if (synch) {
		hashtable_iterater *iterater;

		iterater = hashtable_iterater_create(ht);
		hashtable_iterater_reset(iterater);
		while(hashtable_iterater_next(iterater)) {
			local_file = (my_dirent *)hashtable_iterater_current(iterater);
			if (!local_file->user_flag) {
				if (my_dirent_remove(local_file->path)) {
					printf("[DELETE] [FAIL] %s %s \n", local_file->is_dir ? "d" : "-", local_file->path);
				}
				else {
					printf("[DELETE] [SUCC] %s %s \n", local_file->is_dir ? "d" : "-", local_file->path);
				}
			}
		}
		hashtable_iterater_destroy(iterater);
	}

	pcs_filist_destroy(remote_files);
	hashtable_destroy(ht);
	my_dirent_destroy(ents);
	return 0;
}
예제 #4
0
파일: shell.c 프로젝트: abitduck/baidupcs
static PcsFileInfoList *get_file_list(Pcs pcs, const char *dir, const char *sort, PcsBool desc, PcsBool recursion)
{
	PcsFileInfoList *reslist = NULL,
		*list = NULL,
		*sublist = NULL,
		*item = NULL;
	PcsFileInfo *info = NULL;
	int page_index = 1,
		page_size = 100;
	int cnt = 0, cnt_total = 0;
	while(1) {
		printf("List %s, Got %d Files           \r", dir, cnt_total);
		fflush(stdout);
		list = pcs_list(pcs, dir, 
			page_index, page_size,
			sort ? sort : "name", 
			sort ? desc : PcsFalse);
		if (!list) {
			if (pcs_strerror(pcs))
				printf("Cannot list %s: %s\n", dir, pcs_strerror(pcs));
			return NULL;
		}
		cnt = list->count;
		cnt_total += cnt;
		if (recursion) {
			PcsFileInfoListItem *listitem;
			PcsFileInfoListIterater iterater;
			reslist = pcs_filist_create();
			if (!reslist) {
				printf("Cannot create the PcsFileInfoList object for %s.\n", dir);
				pcs_filist_destroy(list);
				return NULL;
			}
			pcs_filist_iterater_init(list, &iterater, PcsFalse);
			while(pcs_filist_iterater_next(&iterater)) {
				info = iterater.current;
				listitem = iterater.cursor;
				pcs_filist_remove(list, listitem, &iterater);
				pcs_filist_add(reslist, listitem);
				if (info->isdir) {
					sublist = get_file_list(pcs, info->path, sort, desc, recursion);
					if (sublist) {
						pcs_filist_combin(reslist, sublist);
						pcs_filist_destroy(sublist);
					}
				}
				else {
					/*
					 * 因为百度网盘返回的都是文件夹在前,文件在后,
					 * 因此遇到第一个文件,则后边的都是文件。
					 * 所以可以跳过检查,直接合并
					*/
					pcs_filist_combin(reslist, list);
					break;
				}
			}
			pcs_filist_destroy(list);
		}
		else {
			reslist = list;
		}
		if (cnt > 0) {
			printf("List %s, Got %d Files           \r", dir, cnt_total);
			fflush(stdout);
		}
		if (cnt < page_size) {
			break;
		}
		page_index++;
	}
	return reslist;
}
예제 #5
0
파일: shell.c 프로젝트: abitduck/baidupcs
static int exec_upload_dir(Pcs pcs, const char *local_path, const char *remote_path,
							 int force, int recursion, int synch)
{
	int ft = 0, res = 0, ric = 0;
	char *dest_path = NULL;
	PcsFileInfo *meta = NULL,
		*remote_file = NULL;
	PcsFileInfoList *remote_filelist = NULL;
	PcsFileInfoListIterater iterater = {0};
	PcsRes pcsres = PCS_NONE;
	PcsPanApiRes *pcsapires = NULL;
	hashtable *ht = NULL;
	my_dirent *ents = NULL,
		*ent = NULL;

	printf("\nUpload %s to %s\n", local_path, remote_path);
exec_upload_dir_label_1:
	meta = pcs_meta(pcs, remote_path);
	if (meta) {
		if (meta->isdir)
			ft = 2;
		else
			ft = 1;
		pcs_fileinfo_destroy(meta);
		meta = NULL;
	}
	else if (pcs_strerror(pcs)) {
		printf("Cannot get the meta for %s: %s\n", remote_path, pcs_strerror(pcs));
		ric = retry_cancel();
		if (ric == 'r')
			goto exec_upload_dir_label_1;
		else
			return -1;
	}
	if (ft == 1) {
		if (force) {
			PcsSList slist = { 
				(char *)remote_path,
				0
			};
			printf("Delete the %s, since the target is not the directory and you specify -f.\n", remote_path);
exec_upload_dir_label_2:
			pcsapires = pcs_delete(pcs, &slist);
			if (!pcsapires) {
				printf("[DELETE] [FAIL] - %s: %s\n", remote_path, pcs_strerror(pcs));
				ric = retry_cancel();
				if (ric == 'r')
					goto exec_upload_dir_label_2;
				else
					return -1;
			}
			else {
				printf("[DELETE] [SUCC] - %s \n", remote_path);
				pcs_pan_api_res_destroy(pcsapires);
			}
exec_upload_dir_label_3:
			pcsres = pcs_mkdir(pcs, remote_path);
			if (pcsres != PCS_OK) {
				printf("[FAIL] Cannot create the directory %s: %s\n", remote_path, pcs_strerror(pcs));
				ric = retry_cancel();
				if (ric == 'r')
					goto exec_upload_dir_label_3;
				else
					return -1;
			}
			else {
				printf("[SUCC] Create directory %s\n", remote_path);
				goto exec_upload_dir_label_5;
			}
		}
		else {
			printf("The target %s is not the directory. You can use -f to force recreate the directory.\n", remote_path);
		}
		return -1;
	}
	else if (ft == 2) {
	}
	else {
exec_upload_dir_label_4:
		pcsres = pcs_mkdir(pcs, remote_path);
		if (pcsres != PCS_OK) {
			printf("[FAIL] Cannot create the directory %s: %s\n", remote_path, pcs_strerror(pcs));
			ric = retry_cancel();
			if (ric == 'r')
				goto exec_upload_dir_label_4;
			else
				return -1;
		}
		else {
			printf("[SUCC] Create directory %s\n", remote_path);
			goto exec_upload_dir_label_5;
		}
	}

exec_upload_dir_label_5:
	printf("Get remote file list %s.\n", remote_path);
	remote_filelist = get_file_list(pcs, remote_path, NULL, PcsFalse, PcsFalse);
	if (!remote_filelist && pcs_strerror(pcs)) {
		printf("[FAIL] Cannot list the directory %s: %s\n", remote_path, pcs_strerror(pcs));
		ric = retry_cancel();
		if (ric == 'r')
			goto exec_upload_dir_label_5;
		else
			return -1;
	}
	if (remote_filelist) {
		ht = hashtable_create(remote_filelist->count, 1, NULL);
		if (!ht) {
			printf("Cannot create hashtable.\n");
			goto exec_upload_dir_label_00;
		}
		pcs_filist_iterater_init(remote_filelist, &iterater, PcsFalse);
		while(pcs_filist_iterater_next(&iterater)) {
			remote_file = iterater.current;
			if (hashtable_add(ht, remote_file->path, remote_file)) {
				printf("Cannot add object to hashtable.\n");
				goto exec_upload_dir_label_00;
			}
		}
	}

	ents = list_dir(local_path, 0);
	if (!ents) {
		printf("[SKIP] d %s empty directory.\n", local_path);
		goto exec_upload_dir_label_0;
	}
	ent = ents;
	while(ent) {
		dest_path = combin_remote_path(remote_path, ent->filename);
		if (!dest_path) {
			printf("Cannot combin the path.\n");
			goto exec_upload_dir_label_00;
		}
		if (ent->is_dir) {
			if (force || recursion) {
				remote_file = ht ? (PcsFileInfo *)hashtable_get(ht, dest_path) : NULL;
				if (remote_file) {
					remote_file->user_flag = 1;
					printf("[SKIP] d %s\n", ent->path);
				}
				else if (recursion) {
exec_upload_dir_label_6:
					pcsres = pcs_mkdir(pcs, dest_path);
					if (pcsres != PCS_OK) {
						printf("[FAIL] d %s Cannot create the directory %s: %s\n", ent->path, dest_path, pcs_strerror(pcs));
						ric = retry_cancel();
						if (ric == 'r') {
							goto exec_upload_dir_label_6;
						}
						else {
							goto exec_upload_dir_label_00;
						}
					}
					else {
						printf("[SUCC] d %s => %s\n", ent->path, dest_path);
					}
				}
			}
		}
		else {
			remote_file = ht ? (PcsFileInfo *)hashtable_get(ht, dest_path) : NULL;
			if (remote_file) remote_file->user_flag = 1;
			if (force || !remote_file || ((time_t)remote_file->server_mtime) < my_dirent_get_mtime(ent)) {
exec_upload_dir_label_7:
				pcs_setopt(pcs, PCS_OPTION_PROGRESS_FUNCTION_DATE, ent->path);
				pcs_setopt(pcs, PCS_OPTION_PROGRESS, (void *)PcsTrue);
				meta = pcs_upload(pcs, dest_path, PcsTrue, ent->path);
				pcs_setopt(pcs, PCS_OPTION_PROGRESS, (void *)PcsFalse);
				pcs_setopt(pcs, PCS_OPTION_PROGRESS_FUNCTION_DATE, NULL);
				if (!meta) {
					printf("[FAIL] - %s Cannot upload the file: %s\n", ent->path, pcs_strerror(pcs));
					ric = retry_cancel();
					if (ric == 'r') {
						goto exec_upload_dir_label_7;
					}
					else {
						goto exec_upload_dir_label_00;
					}
				}
				printf("[SUCC] - %s => %s\n", ent->path, meta->path);
				pcs_fileinfo_destroy(meta); meta = NULL;
			}
			else {
				printf("[SKIP] - %s\n", ent->path);
			}
		}
		ent = ent->next;
		pcs_free(dest_path); dest_path = NULL;
	}
	if (recursion) {
		ent = ents;
		while(ent) {
			dest_path = combin_remote_path(remote_path, ent->filename);
			if (!dest_path) {
				printf("Cannot combin the path.\n");
				goto exec_upload_dir_label_00;
			}
			if (ent->is_dir) {
				if (exec_upload_dir(pcs, ent->path, dest_path, force, recursion, synch)) {
					goto exec_upload_dir_label_00;
				}
			}
			ent = ent->next;
			pcs_free(dest_path); dest_path = NULL;
		}
	}
	if (synch && ht) {
		hashtable_iterater *iterater;
		PcsSList slist = {0,0};

		iterater = hashtable_iterater_create(ht);
		hashtable_iterater_reset(iterater);
		while(hashtable_iterater_next(iterater)) {
			remote_file = (PcsFileInfo *)hashtable_iterater_current(iterater);
			if (!remote_file->user_flag) {
				slist.string = remote_file->path;
exec_upload_dir_label_8:
				pcsapires = pcs_delete(pcs, &slist);
				if (!pcsapires) {
					printf("[DELETE] [FAIL] %s %s Cannot delete the %s: %s\n",
						remote_file->isdir ? "d" : "-",
						remote_file->path, 
						remote_file->isdir ? "directory" : "fire", pcs_strerror(pcs));
					ric = retry_cancel();
					if (ric == 'r') {
						goto exec_upload_dir_label_8;
					}
					else {
						goto exec_upload_dir_label_00;
					}
				}
				else {
					printf("[DELETE] [SUCC] %s %s \n", remote_file->isdir ? "d" : "-", remote_file->path);
					pcs_pan_api_res_destroy(pcsapires);
				}
			}
		}
		hashtable_iterater_destroy(iterater);
	}
	goto exec_upload_dir_label_0;
exec_upload_dir_label_00:
	res = -1;
exec_upload_dir_label_0:
	if (dest_path) pcs_free(dest_path);
	if (meta) pcs_fileinfo_destroy(meta);
	if (ht) hashtable_destroy(ht);
	if (remote_filelist) pcs_filist_destroy(remote_filelist);
	if (ents) my_dirent_destroy(ents);
	return res;
}