最近用七牛的SDK简单的实现了一个备份资料的小工具,虽然七牛官网也有单纯的上传文件的工具,但还是自己写了一个,分享给大家,工程目录bakdata,工程目录图如下
其中inc中是需要用到的头文件,lib是.a文件,我之前已经把SDK编译成了lqiniu.a文件存放在下面,obj是编译后的o文件,src为我的源文件
至于第三方库的依赖,主要是SDK依赖的openssl和cul还有就是我自己引入了配置文件的读取库ccl
其中主要介绍src下面的2个源文件main.c和ccl_conf.c
其中main.c文件如下
#include <stdio.h> #include <time.h> #include <io.h> #include "rs.h" #include "ccl_conf.h" void debug(Qiniu_Client* client, Qiniu_Error err) { printf("\nerror code: %d, message: %s\n", err.code, err.message); printf("respose header:\n%s", Qiniu_Buffer_CStr(&client->respHeader)); printf("respose body:\n%s\n", Qiniu_Buffer_CStr(&client->b)); } char* uptoken(Qiniu_Client* client, const char* bucket) { Qiniu_RS_PutPolicy putPolicy; Qiniu_Zero(putPolicy); putPolicy.scope = bucket; return Qiniu_RS_PutPolicy_Token(&putPolicy, NULL); } char* upload(Qiniu_Client* client, char* uptoken, const char* key, const char* localFile) { Qiniu_Error err; Qiniu_Io_PutRet putRet; err = Qiniu_Io_PutFile(client, &putRet, uptoken, key, localFile, NULL); if (err.code != 200) { debug(client, err); return NULL; } return strdup(putRet.hash); /* 注意需要后续使用的变量要复制出来 */ } /** * 解析配置文件中的参数信息 * */ int parse_argv(const char const *conf_path, char *ak, char *sk, char *wn, char *path, char *tmp_path, char *folder_name, char *suffix_format) { int ret_conf = init_conf_path(conf_path); if(ret_conf == -1) { printf("init_conf_path error\n"); return ret_conf; } ret_conf = get_ak(ak); if(ret_conf == -1) { printf("error ak value\n"); return ret_conf; } ret_conf = get_sk(sk); if(ret_conf == -1) { printf("error sk value\n"); return ret_conf; }; ret_conf = get_wn(wn); if(ret_conf == -1) { printf("error wn value\n"); return ret_conf; }; ret_conf = get_path(path); if(ret_conf == -1) { printf("error path value\n"); return ret_conf; }; ret_conf = get_tmp_path(tmp_path); if(ret_conf == -1) { printf("error tmp_path value\n"); return ret_conf; }; ret_conf = get_folder_name(folder_name); if(ret_conf == -1) { printf("error folder_name value\n"); return ret_conf; }; /** ret_conf = get_suffix_format(suffix_format); if(ret_conf == -1) { printf("error suffix_format value\n"); return ret_conf; }; **/ } int main(int argc, char* argv[]) { Qiniu_Client client; char ak[64]; //AccessKey值 char sk[64]; //SecretKey值 char wn[128]; //空间名称 char path[256]; //备份文件绝对路径 char tmp_path[256]; //打包文件临时绝对路径 char folder_name[128]; //需要备份的目录 char suffix_format[16]; //备份文件名后缀 char conf_path[256]; //配置文件路径 char *default_conf_path="/etc/bakdata.conf"; memset(ak,'\0',sizeof(ak)); memset(sk,'\0',sizeof(sk)); memset(wn,'\0',sizeof(wn)); memset(path,'\0',sizeof(path)); memset(tmp_path,'\0',sizeof(tmp_path)); memset(folder_name,'\0',sizeof(folder_name)); memset(suffix_format,'\0',sizeof(suffix_format)); memset(conf_path,'\0',sizeof(conf_path)); //判断配置文件在默认路径是否存在 int flag = access(default_conf_path,0); if(flag == 0) { strcpy(conf_path,default_conf_path); } if(argc >= 2) { strcpy(conf_path,argv[1]); } int ret_conf = parse_argv(conf_path,ak,sk,wn,path,tmp_path,folder_name,suffix_format); if(-1 == ret_conf) { printf("get conf file failed!\n"); exit(-1); } char exec[512]; char upload_file_name[128]; char upload_file_full_name[256]; memset(exec,'\0',sizeof(exec)); memset(upload_file_name,'\0',sizeof(upload_file_name)); memset(upload_file_full_name,'\0',sizeof(upload_file_full_name)); time_t tt; time(&tt); struct tm *t = localtime(&tt); sprintf(upload_file_name,"%s%d%02d%02d%02d%02d%02d.tar.gz",folder_name,t->tm_year+1900,t->tm_mon+1,t->tm_mday,t->tm_hour,t->tm_min,t->tm_sec); sprintf(upload_file_full_name,"%s%s",tmp_path,upload_file_name); sprintf(exec,"cd %s && tar -zcf %s %s",path,upload_file_full_name,folder_name); int status = system(exec); if(0 != status) { printf("tar fill failed\n"); exit(-1); } QINIU_ACCESS_KEY = ak; QINIU_SECRET_KEY = sk; Qiniu_Servend_Init(-1); /* 全局初始化函数,整个进程只需要调用一次 */ Qiniu_Client_InitMacAuth(&client, 1024, NULL); /* HTTP客户端初始化。HTTP客户端是线程不安全的,不要在多个线程间共用 */ char *token = uptoken(&client,wn); char *ret = upload(&client,token,upload_file_name,upload_file_full_name); if(NULL != ret) { printf("the hash code is : %s\n",ret); free(ret); } remove(upload_file_full_name); //删除临时文件 Qiniu_Client_Cleanup(&client); /* 每个HTTP客户端使用完后释放 */ Qiniu_Servend_Cleanup(); /* 全局清理函数,只需要在进程退出时调用一次 */ return 0; }
#include <string.h> //for use function : strcpy #include <ccl/ccl.h> #include "ccl_conf.h" #define PATH_MAX_LENGTH 256 static char conf_path[PATH_MAX_LENGTH]; int init_conf_path(const char const *src_conf_path) { memset(conf_path,'\0',sizeof(conf_path)); if(NULL == src_conf_path || strcmp(src_conf_path,"") == 0) return -1; strcpy(conf_path,src_conf_path); return 0; } static int get_conf_value(char *key,char *buf) { int ret = -1; struct ccl_t config; const struct ccl_pair_t *iter; config.comment_char = '#'; config.sep_char = '='; config.str_char = '"'; ccl_parse(&config, conf_path);//conf fileName while((iter = ccl_iterate(&config)) != 0) { if(strcmp(key,iter->key) == 0) { ret = 0; strcpy(buf,iter->value); break; } } ccl_release(&config); return ret; } int get_ak(char *buf) { return get_conf_value("ak",buf); } int get_sk(char *buf) { return get_conf_value("sk",buf); } int get_path(char *buf) { return get_conf_value("path",buf); } int get_wn(char *buf) { return get_conf_value("wn",buf); } int get_tmp_path(char *buf) { return get_conf_value("tmp_path",buf); } int get_folder_name(char *buf) { return get_conf_value("folder_name",buf); } int get_suffix_format(char *buf) { return get_conf_value("suffix_name",buf); }
.PHONY: build build: bin/bakdata bin/bakdata: obj/main.o obj/ccl_conf.o gcc -o bin/bakdata obj/main.o obj/ccl_conf.o -Llib -lqiniu -lcurl -lssl -lcrypto -lm -lccl obj/main.o: src/main.c inc/rs.h inc/ccl_conf.h gcc -Iinc -c src/main.c -o obj/main.o obj/ccl_conf.o: src/ccl_conf.c inc/ccl_conf.h gcc -Iinc -c src/ccl_conf.c -o obj/ccl_conf.o clean: rm -rf obj/* rm -rf bin/*
;ccl库地址 http://files.sbooth.org/ccl-0.1.1.tar.gz ;AccessKey对应的值 ak=七牛创建的AccessKey ;SecretKey对应的值 sk=七牛创建的SecretKey ;对应的空间名称 wn=test ;需要备份的绝对路径 path=/root/ ;备份临时文件绝对路径 tmp_path=/root/ ;要备份的文件名称 folder_name=bakdata ;备份文件后缀名格式 suffix_format=yyyyMMhhmm