From 6892639e1fcbb8f09ed4ec10facce19a53cae999 Mon Sep 17 00:00:00 2001 From: Gang Zhuo Date: Sat, 26 Apr 2014 16:54:00 +0800 Subject: [PATCH] fixed error that do not close the file handle --- pcs/pcs_utils.c | 5 +- test/daemon.c | 313 ++++++++++++++++++++++++++---------------------- 2 files changed, 175 insertions(+), 143 deletions(-) diff --git a/pcs/pcs_utils.c b/pcs/pcs_utils.c index 14e5ef57..4ee22066 100644 --- a/pcs/pcs_utils.c +++ b/pcs/pcs_utils.c @@ -186,7 +186,7 @@ PCS_API const char *md5_string(const char *str) int i; MD5((const unsigned char*)str, strlen(str), md); for (i = 0; i<16; i++){ - sprintf(&tmp[i * 2], "%02x", 0xFF & md[i]); + sprintf(&tmp[i * 2], "%02x", md[i]); } return tmp; } @@ -211,8 +211,9 @@ PCS_API const char *md5_file(const char *file_name) while (length = fread(buffer, 1, 1024, file)) MD5_Update(&md5, buffer, length); MD5_Final(md, &md5); + fclose(file); for (i = 0; i<16; i++){ - sprintf(&tmp[i * 2], "%02x", 0xFF & md[i]); + sprintf(&tmp[i * 2], "%02x", md[i]); } return tmp; } diff --git a/test/daemon.c b/test/daemon.c index 9ee01ad7..c1865c8d 100644 --- a/test/daemon.c +++ b/test/daemon.c @@ -1,4 +1,4 @@ -#include +#include #include #include #include @@ -69,19 +69,19 @@ typedef struct BackupItem { char *localPath; char *remotePath; int method; - int schedule; /*㼸ֿʼִֵΪһ뿪ʼִʱ6Сʱ = 6 * 60 * 60 = 21600룬˴ֵΪ21600ʾ賿6㿪 */ - int interval; /*ִɺ󣬵ǰִʱintervalΪ´ִʱ䡣86400 = 24Сʱ賿6ִ󣬼24СʱʱΪ´ִʱ䡣*/ - int md5; /*ǷMD5*/ - time_t next_run_time; /* ´ִʱ */ + int schedule; /*几点几分开始执行任务,值为一天从零点零分零秒开始到执行时间的秒数。例:6小时 = 6 * 60 * 60 = 21600秒,此处设置值为21600则表示,于凌晨6点开启任务。 */ + int interval; /*任务执行完成后,当前执行时间加上interval则为下次执行时间。86400秒 = 24小时,即:当凌晨6点执行完任务后,加上24小时的时间作为任务下次执行时间。*/ + int md5; /*是否启用MD5*/ + time_t next_run_time; /* 下次执行时间 */ time_t last_run_time; } BackupItem; typedef struct Config { - char *configFilePath; /*ļ·*/ - char *cookieFilePath; /*ļжCookieʹõcookieļ·*/ - char *cacheFilePath; /*ļ·*/ - char *logFilePath; /*־ļ·*/ - BackupItem *items; /*Ҫ|ԭ*/ + char *configFilePath; /*配置文件路径*/ + char *cookieFilePath; /*从配置文件中读入的Cookie配置项,即使用的cookie文件路径*/ + char *cacheFilePath; /*缓存文件的路径*/ + char *logFilePath; /*日志文件的路径*/ + BackupItem *items; /*需要备份|还原的项*/ int itemCount; int run_in_daemon; @@ -90,25 +90,25 @@ typedef struct Config { } Config; -/*Sqlite*/ +/*Sqlite编译后的语句对象数组*/ typedef struct DbPrepare { sqlite3_stmt **stmts; int count; } DbPrepare; -/*Sqlite*/ +/*Sqlite编译后的语句对象链表*/ typedef struct DbPrepareList { sqlite3_stmt *stmt; struct DbPrepareList *next; } DbPrepareList; -/*ϴûԶݽṹڴݵ*/ +/*上传进度条的用户自定义数据结构,用于传入数据到进度条函数中*/ struct ProgressState { const char *localPath; const char *remotePath; }; -/*ͳƱʱļ*/ +/*统计备份时,各情况的文件数量*/ typedef struct BackupState { int backupFiles; int skipFiles; @@ -121,29 +121,29 @@ typedef struct BackupState { int totalDir; } BackupState; -/*ʱûԶݽṹڴݵصд뺯*/ +/*下载时的用户自定义数据结构,用于传入数据到下载的写入函数中*/ typedef struct DownloadState { FILE *pf; char *msg; size_t size; } DownloadState; -/*¼ȽϽ -"+ D L:/var/www/upload"ַʾһCompareItem -ַͨprintf("%c %c %c:%s\n", p->op, p->type, p->position, p->path)ã -: -"+ D L:/var/www/upload" - ʾؽһĿ¼/var/www/upload -"+ D R:/var/www/upload" - ʾнһĿ¼/var/www/upload -"- F L:/var/www/upload/001.jpg" - ʾؽɾһļ/var/www/upload/001.jpg -"+ F R:/var/www/upload/001.jpg" - ʾн¼һļ/var/www/upload/001.jpg -"A F L:/var/www/upload/001.jpg" - ʾѱļ/var/www/upload/001.jpgϴǵ -"V F R:/var/www/upload/001.jpg" - ʾļ/var/www/upload/001.jpgزǵ +/*记录比较结果的链表 +例:用类似于"+ D L:/var/www/upload"的字符串表示一个CompareItem对象 +(该字符串可通过printf("%c %c %c:%s\n", p->op, p->type, p->position, p->path)来获得), +则有: +"+ D L:/var/www/upload" - 表示本地将创建一个新目录/var/www/upload +"+ D R:/var/www/upload" - 表示网盘中将创建一个新目录/var/www/upload +"- F L:/var/www/upload/001.jpg" - 表示本地将删除一个文件/var/www/upload/001.jpg +"+ F R:/var/www/upload/001.jpg" - 表示网盘中将新加一个文件/var/www/upload/001.jpg +"A F L:/var/www/upload/001.jpg" - 表示将把本地文件/var/www/upload/001.jpg上传并覆盖到网盘中 +"V F R:/var/www/upload/001.jpg" - 表示将把网盘文件/var/www/upload/001.jpg下载并覆盖到本地 */ typedef struct CompareItem { - char op; /*ֵΪA,V,+,-. AʾļϴVʾļأ-ʶļɾ+ʾļ*/ - char type; /*ļͣD - ʶĿ¼F - ʾļ*/ - char position; /*ļĿ¼λãR - ʾļpath洢̣L - ʶļDZļ*/ - char *path; /*ļ·*/ + char op; /*值可为A,V,+,-. A表示文件需上传,V表示文件需下载,-标识文件需删除,+表示文件需添加*/ + char type; /*文件类型:D - 标识目录;F - 表示文件*/ + char position; /*文件或目录的位置:R - 表示操作的文件path存储于网盘;L - 标识操作的文件是本地文件*/ + char *path; /*文件路径。*/ struct CompareItem *next; struct CompareItem *prev; } CompareItem; @@ -154,7 +154,7 @@ static Pcs pcs = NULL; static void print_taks(); -/*ݿļ·*/ +/*返回数据库文件的路径*/ //static const char *db_file_path() //{ // @@ -175,7 +175,7 @@ static void print_taks(); // //} -/*־ļ·*/ +/*返回日志文件的路径*/ static const char *log_file_path() { @@ -265,7 +265,7 @@ static void freeConfig(int keepGlobal) } } -/*ȡļ*/ +/*读取文件内容*/ static int readFileContent(const char *file, char **pBuffer) { FILE *fp; @@ -357,7 +357,7 @@ static int convert_to_time_t_2(char *str) return rc; } -/*ȡļ*/ +/*读取并解析配置文件*/ static int readConfigFile() { long size_of_file; @@ -748,7 +748,7 @@ static int db_update_task_status2(int id, int enabled, time_t last_run_time, tim return 0; } -/*isStart - ʶǷstart_timecappֶ*/ +/*isStart - 标识是否更新start_time和capp两个字段*/ static int db_set_action(const char *action, int status, int isStart) { int rc; @@ -898,8 +898,8 @@ static int db_set_version(int verno) } /* -ɾpathĿ¼л棬ɾpathĻ档 -: db_clear_caches("/backup"); //ɾ"/backup/"ͷļ棬"/backup"Ļ治ɾ +删除path目录下所有缓存,不会删除path的缓存。 +例: db_clear_caches("/backup"); //将删除所有以"/backup/"开头的文件缓存,但是"/backup"的缓存不会删除 */ static int db_clear_caches(const char *path) { @@ -943,8 +943,8 @@ static int db_clear_caches(const char *path) } /* -ɾpathĻ棬Ŀ¼ -: db_remove_cache("/backup"); //ɾ"/backup"Ļ棬"/backup/"ͷĻ治ɾ +删除path的缓存,不包括其子目录 +例: db_remove_cache("/backup"); //将删除"/backup"的缓存,但是以"/backup/"开头的缓存不会删除 */ static int db_remove_cache(const char *path) { @@ -972,8 +972,8 @@ static int db_remove_cache(const char *path) } /* -pathĿ¼лıʶpathĻʶ -: db_set_cache_flags("/backup", 0); //"/backup/"ͷĻʶΪ0"/backup"Ļʶ +设置path目录下所有缓存的标识,不会设置path的缓存标识。 +例: db_set_cache_flags("/backup", 0); //将设置所有以"/backup/"开头的缓存标识为0,但是"/backup"的缓存标识不会设置 */ static int db_set_cache_flags(const char *path, int flag) { @@ -1016,8 +1016,8 @@ static int db_set_cache_flags(const char *path, int flag) } /* -pathıʶĿ¼ -: db_set_cache_flag("/backup", 0); //"/backup"ĻʶΪ0"/backup/"ͷĻʶ +设置path缓存的标识,不包括其子目录 +例: db_set_cache_flag("/backup", 0); //将设置"/backup"的缓存标识为0,但是以"/backup/"开头的缓存标识不会设置 */ static int db_set_cache_flag(const char *path, int flag) { @@ -1224,7 +1224,7 @@ static int quota(UInt64 *usedByteSize, UInt64 *totalByteSize) return 0; } -/* ֱӻļ */ +/* 返回直接或间接文件数量 */ static int method_update_folder(const char *path, DbPrepare *pre, int *pFileCount, int *pDirectFileCount) { PcsFileInfoList *list = NULL; @@ -1301,13 +1301,13 @@ static int method_update(const char *remotePath) PRINT_NOTICE("Server Path: %s", remotePath); action = (char *)pcs_malloc(strlen(remotePath) + 16); strcpy(action, "UPDATE: "); strcat(action, remotePath); - //ȡǰACTION + //获取当前的ACTION if (db_get_action(&actionInfo, action)) { pcs_free(action); PRINT_NOTICE("Update Local Cache - End"); return -1; } - //ACTION״̬ + //检查ACTION状态 if (actionInfo.status == ACTION_STATUS_RUNNING) { PRINT_FATAL("There have another update thread running, which is start by %s at %s", actionInfo.create_app, format_time(actionInfo.start_time)); pcs_free(action); @@ -1316,20 +1316,20 @@ static int method_update(const char *remotePath) return -1; } freeActionInfo(&actionInfo); - //ACTIONΪRUNNING״̬ + //设置ACTION为RUNNING状态 if (db_set_action(action, ACTION_STATUS_RUNNING, 1)) { pcs_free(action); PRINT_NOTICE("Update Local Cache - End"); return -1; } - //ɾǰĿ¼ıػ + //删除当前目录的本地缓存 if (db_remove_cache(remotePath)) { db_set_action(action, ACTION_STATUS_ERROR, 0); pcs_free(action); PRINT_NOTICE("Update Local Cache - End"); return -1; } - //ȡǰĿ¼Ԫ + //获取当前目录的元数据 meta = pcs_meta(pcs, remotePath); if (!meta) { PRINT_FATAL("The remote path not exist: %s", remotePath); @@ -1338,7 +1338,7 @@ static int method_update(const char *remotePath) PRINT_NOTICE("Update Local Cache - End"); return 0; } - //׼ݵеSQL + //准备插入数据到缓存表格中的SQL过程 if (db_prepare(&pre, SQL_CACHE_INSERT, NULL)) { db_set_action(action, ACTION_STATUS_ERROR, 0); pcs_free(action); @@ -1346,7 +1346,7 @@ static int method_update(const char *remotePath) PRINT_NOTICE("Update Local Cache - End"); return -1; } - //浱ǰĿ¼Ԫ + //缓存当前目录的元数据 if (db_add_cache(meta, &pre)) { db_set_action(action, ACTION_STATUS_ERROR, 0); pcs_free(action); @@ -1356,7 +1356,7 @@ static int method_update(const char *remotePath) return -1; } if (meta->isdir) { - //ɾĿ¼ıػ + //删除子目录的本地缓存 if (db_clear_caches(remotePath)) { db_set_action(action, ACTION_STATUS_ERROR, 0); pcs_free(action); @@ -1365,7 +1365,7 @@ static int method_update(const char *remotePath) PRINT_NOTICE("Update Local Cache - End"); return -1; } - //ݹĿ¼ + //递归更新子目录 if (method_update_folder(remotePath, &pre, &fileCount, &directFileCount)) { db_set_action(action, ACTION_STATUS_ERROR, 0); pcs_free(action); @@ -1466,7 +1466,7 @@ static int method_backup_progress(void *clientp, double dltotal, double dlnow, d return 0; } -/*ļ*/ +/*备份文件*/ static int method_backup_file(const my_dirent *localFile, const char *remotePath, DbPrepare *pre, int md5Enabled, BackupState *st) { PcsFileInfo dst = {0}; @@ -1497,20 +1497,30 @@ static int method_backup_file(const my_dirent *localFile, const char *remotePath } if (md5Enabled) { if (dst.fs_id) { - const char *md5 = md5_file(localFile->path); - if (pcs_utils_strcmpi(md5, dst.md5)) { - if (localFile->mtime == ((time_t)dst.server_mtime)) { - PRINT_WARNING("Unable to determine which file is newer: " - "The local file %s and remote file %s have different md5 (%s : %s), " - "they also have same last modify time %s. Force backup the file.", - localFile->path, remotePath, md5, dst.md5, format_time(localFile->mtime)); - //freeCacheInfo(&dst); - //return -1; - need_backup = 1; + const char *md5; + if (dst.md5) { + md5 = md5_file(localFile->path); + if (!md5) { + PRINT_FATAL("Can't calculate md5 for %s.", localFile->path); + freeCacheInfo(&dst); + return -1; + } + else if (pcs_utils_strcmpi(md5, dst.md5)) { + if (localFile->mtime == ((time_t)dst.server_mtime)) { + PRINT_WARNING("Unable to determine which file is newer: " + "The local file %s and remote file %s have different md5 (%s : %s), " + "they also have same last modify time %s. Force backup the file.", + localFile->path, remotePath, md5, dst.md5, format_time(localFile->mtime)); + //freeCacheInfo(&dst); + //return -1; + need_backup = 1; + } + else + need_backup = localFile->mtime > ((time_t)dst.server_mtime); } - else - need_backup = localFile->mtime > ((time_t)dst.server_mtime); } + else + need_backup = localFile->mtime > ((time_t)dst.server_mtime); } else { need_backup = 1; @@ -1579,7 +1589,7 @@ static int method_backup_file(const my_dirent *localFile, const char *remotePath return 0; } -/*Ŀ¼*/ +/*创建目录*/ static int method_backup_mkdir(const char *remotePath, DbPrepare *pre, BackupState *st) { PcsFileInfo dst = {0}; @@ -1607,7 +1617,7 @@ static int method_backup_mkdir(const char *remotePath, DbPrepare *pre, BackupSta st->removeFiles++; } } - if (!dst.fs_id) { //ԶĿ¼ڣ򴴽 + if (!dst.fs_id) { //如果远程目录不存在,则创建 PcsRes pcsres = PCS_NONE; //PcsFileInfo *meta = NULL; PcsFileInfo meta = { 0 }; time_t now; @@ -1616,7 +1626,7 @@ static int method_backup_mkdir(const char *remotePath, DbPrepare *pre, BackupSta PRINT_FATAL("Can't create the directory %s: %s\n", remotePath, pcs_strerror(pcs)); return -1; } - ////ɹ󣬻ȡԪݲ뱾ػ + ////创建成功后,获取其元数据并存入本地缓存 //meta = pcs_meta(pcs, remotePath); //if (!meta) { // PRINT_FATAL("Can't get meta: %s", remotePath); @@ -1657,7 +1667,7 @@ static int method_backup_mkdir(const char *remotePath, DbPrepare *pre, BackupSta return 0; } -/*Ŀ¼*/ +/*备份目录*/ static int method_backup_folder(const char *localPath, const char *remotePath, DbPrepare *pre, int md5Enabled, BackupState *st) { my_dirent *ents = NULL, @@ -1668,7 +1678,7 @@ static int method_backup_folder(const char *localPath, const char *remotePath, D return -1; } ents = list_dir(localPath, 0); - if (!ents) { //ǿĿ¼ + if (!ents) { //如果是空目录 return 0; } ent = ents; @@ -1731,7 +1741,7 @@ static int method_backup_remove_files(PcsSList *slist, DbPrepare *pre, const cha return 0; } -/*ɾѾƳļĿ¼*/ +/*删除本地已经移除的文件或目录*/ static int method_backup_remove_untrack(const char *remotePath, DbPrepare *pre, BackupState *st) { int rc, is_dir; @@ -1834,13 +1844,13 @@ int method_backup(const char *localPath, const char *remotePath, int md5Enabled, action = (char *)pcs_malloc(strlen(localPath) + strlen(remotePath) + 16); strcpy(action, "BACKUP: "); strcat(action, localPath); strcat(action, " -> "); strcat(action, remotePath); - //ȡǰACTION + //获取当前的ACTION if (db_get_action(&ai, action)) { pcs_free(action); PRINT_NOTICE("Backup - End"); return -1; } - //ACTION״̬ + //检查ACTION状态 if (ai.status == ACTION_STATUS_RUNNING) { PRINT_FATAL("There have another backup thread running, which is start by %s at %s", ai.create_app, format_time(ai.start_time)); pcs_free(action); @@ -1849,14 +1859,14 @@ int method_backup(const char *localPath, const char *remotePath, int md5Enabled, return -1; } freeActionInfo(&ai); - //ACTIONΪRUNNING״̬ + //设置ACTION为RUNNING状态 if (db_set_action(action, ACTION_STATUS_RUNNING, 1)) { pcs_free(action); PRINT_NOTICE("Backup - End"); return -1; } - //鱾ػǷ - ʼδ±ػ + //检查本地缓存是否更新 - 开始。如果未更新则更新本地缓存 updateAction = (char *)pcs_malloc(strlen(remotePath) + 16); strcpy(updateAction, "UPDATE: "); strcat(updateAction, remotePath); @@ -1889,9 +1899,9 @@ int method_backup(const char *localPath, const char *remotePath, int md5Enabled, } pcs_free(updateAction); freeActionInfo(&ai); - //鱾ػǷ - + //检查本地缓存是否更新 - 结束 - //رλ + //清除本地标记位 if (db_set_cache_flag(remotePath, 0)) { PRINT_FATAL("Can't reset local cache flags for %s", remotePath); db_set_action(action, ACTION_STATUS_ERROR, 0); @@ -1899,7 +1909,7 @@ int method_backup(const char *localPath, const char *remotePath, int md5Enabled, PRINT_NOTICE("Backup - End"); return -1; } - //Ŀ¼ر + //清除子目录本地标记 if (db_set_cache_flags(remotePath, 0)) { PRINT_FATAL("Can't reset local cache flags for %s", remotePath); db_set_action(action, ACTION_STATUS_ERROR, 0); @@ -1923,7 +1933,7 @@ int method_backup(const char *localPath, const char *remotePath, int md5Enabled, PRINT_NOTICE("Backup - End"); return -1; } - if (rc == 2) { //ΪĿ¼ + if (rc == 2) { //类型为目录 if (method_backup_folder(localPath, remotePath, &pre, md5Enabled, &st)) { db_set_action(action, ACTION_STATUS_ERROR, 0); pcs_free(action); @@ -1933,7 +1943,7 @@ int method_backup(const char *localPath, const char *remotePath, int md5Enabled, return -1; } } - else if (rc == 1) { //Ϊļ + else if (rc == 1) { //类型为文件 if (method_backup_file(ent, remotePath, &pre, md5Enabled, &st)) { db_set_action(action, ACTION_STATUS_ERROR, 0); pcs_free(action); @@ -1953,7 +1963,7 @@ int method_backup(const char *localPath, const char *remotePath, int md5Enabled, return -1; } my_dirent_destroy(ent); - //ƳУزڵļ + //移除服务器中,本地不存在的文件 if (!isCombin && method_backup_remove_untrack(remotePath, &pre, &st)) { //PRINT_FATAL("Can't remove untrack files from the server: %s", remotePath); db_set_action(action, ACTION_STATUS_ERROR, 0); @@ -1995,7 +2005,7 @@ static int method_restore_file(const char *localPath, PcsFileInfo *remote, DbPre int rc; int need_backup = 0; rc = get_file_ent(&ent, localPath); - if (rc == 2) { //Ŀ¼ + if (rc == 2) { //是目录 if (my_dirent_remove(localPath)) { PRINT_FATAL("Can't remove the local dir: %s", localPath); my_dirent_destroy(ent); @@ -2008,19 +2018,31 @@ static int method_restore_file(const char *localPath, PcsFileInfo *remote, DbPre } if (md5Enabled) { if (ent) { - const char *md5 = md5_file((char *)localPath); - if (pcs_utils_strcmpi(md5, remote->md5)) { - if (ent->mtime == ((time_t)remote->server_mtime)) { - PRINT_WARNING("Unable to determine which file is newer: " - "The local file %s and remote file %s have different md5 (%s : %s), " - "they also have same last modify time %s. Force restore the file.", - ent->path, remote->path, md5, remote->md5, format_time(ent->mtime)); - //my_dirent_destroy(ent); - //ent = NULL; - need_backup = 1; + const char *md5; + if (remote->md5) { + md5 = md5_file((char *)localPath); + if (!md5) { + PRINT_FATAL("Can't calculate md5 for %s.", localPath); + my_dirent_destroy(ent); + ent = NULL; + return -1; + } + else if (pcs_utils_strcmpi(md5, remote->md5)) { + if (ent->mtime == ((time_t)remote->server_mtime)) { + PRINT_WARNING("Unable to determine which file is newer: " + "The local file %s and remote file %s have different md5 (%s : %s), " + "they also have same last modify time %s. Force restore the file.", + ent->path, remote->path, md5, remote->md5, format_time(ent->mtime)); + //my_dirent_destroy(ent); + //ent = NULL; + need_backup = 1; + } + else + need_backup = ent->mtime < ((time_t)remote->server_mtime); } - else - need_backup = ent->mtime < ((time_t)remote->server_mtime); + } + else { + need_backup = ent->mtime < ((time_t)remote->server_mtime); } } else { @@ -2176,7 +2198,7 @@ static int method_restore_folder(const char *localPath, const char *remotePath, // return -1; //} - /*ΪļѾȫѯˣݹ鴦ļСֻҪ*/ + /*因为其子文件夹已经全部查询出来了,因此无需递归处理文件夹。只需要创建即可*/ #ifdef WIN32 mkdir(dstPath); #else @@ -2226,7 +2248,7 @@ static int method_restore_remove_untrack(my_dirent *local, const char *remotePat } return 0; } - if (local->is_dir) { //Ŀ¼Ļ + if (local->is_dir) { //是目录的话 ents = list_dir(local->path, 0); if (ents) { ent = ents; @@ -2272,13 +2294,13 @@ static int method_restore(const char *localPath, const char *remotePath, int md5 action = (char *)pcs_malloc(strlen(localPath) + strlen(remotePath) + 16); strcpy(action, "RESTORE: "); strcat(action, localPath); strcat(action, " <- "); strcat(action, remotePath); - //ȡǰACTION + //获取当前的ACTION if (db_get_action(&ai, action)) { pcs_free(action); PRINT_NOTICE("Restore - End"); return -1; } - //ACTION״̬ + //检查ACTION状态 if (ai.status == ACTION_STATUS_RUNNING) { PRINT_FATAL("There have another restore thread running, which is start by %s at %s", ai.create_app, format_time(ai.start_time)); pcs_free(action); @@ -2287,14 +2309,14 @@ static int method_restore(const char *localPath, const char *remotePath, int md5 return -1; } freeActionInfo(&ai); - //ACTIONΪRUNNING״̬ + //设置ACTION为RUNNING状态 if (db_set_action(action, ACTION_STATUS_RUNNING, 1)) { pcs_free(action); PRINT_NOTICE("Restore - End"); return -1; } - //鱾ػǷ - ʼδ±ػ + //检查本地缓存是否更新 - 开始。如果未更新则更新本地缓存 updateAction = (char *)pcs_malloc(strlen(remotePath) + 16); strcpy(updateAction, "UPDATE: "); strcat(updateAction, remotePath); @@ -2327,7 +2349,7 @@ static int method_restore(const char *localPath, const char *remotePath, int md5 } pcs_free(updateAction); freeActionInfo(&ai); - //鱾ػǷ - + //检查本地缓存是否更新 - 结束 if (db_prepare(&pre, SQL_CACHE_INSERT, SQL_CACHE_SELECT, SQL_CACHE_DELETE, SQL_CACHE_UPDATE, SQL_CACHE_SET_FLAG, SQL_CACHE_SELECT_SUB, NULL)) { db_set_action(action, ACTION_STATUS_ERROR, 0); @@ -2344,7 +2366,7 @@ static int method_restore(const char *localPath, const char *remotePath, int md5 return -1; } pcs_setopt(pcs, PCS_OPTION_DOWNLOAD_WRITE_FUNCTION, &method_restore_write); - if (rf.isdir) { //ΪĿ¼ + if (rf.isdir) { //类型为目录 if (method_restore_folder(localPath, remotePath, &pre, md5Enabled, &st)) { pcs_setopt(pcs, PCS_OPTION_DOWNLOAD_WRITE_FUNCTION, NULL); db_set_action(action, ACTION_STATUS_ERROR, 0); @@ -2355,7 +2377,7 @@ static int method_restore(const char *localPath, const char *remotePath, int md5 return -1; } } - else { //Ϊļ + else { //类型为文件 if (method_restore_file(localPath, &rf, &pre, md5Enabled, &st)) { pcs_setopt(pcs, PCS_OPTION_DOWNLOAD_WRITE_FUNCTION, NULL); db_set_action(action, ACTION_STATUS_ERROR, 0); @@ -2368,7 +2390,7 @@ static int method_restore(const char *localPath, const char *remotePath, int md5 } pcs_setopt(pcs, PCS_OPTION_DOWNLOAD_WRITE_FUNCTION, NULL); freeCacheInfo(&rf); - //ƳļϵͳУڷвڵļ + //移除本地文件系统中,在服务器中不存在的文件 if (!isCombin) { my_dirent *local; get_file_ent(&local, localPath); @@ -2408,6 +2430,9 @@ static void addCompareItem(CompareItem *list, char op, char type, char position, { CompareItem *item; item = (CompareItem *)pcs_malloc(sizeof(CompareItem)); + if (!item) { + PRINT_FATAL("Can't create object: CompareItem"); + } memset(item, 0, sizeof(CompareItem)); item->op = op; item->type = type; @@ -2505,35 +2530,41 @@ static void printCompareList(CompareItem *list) printf("Total: %d\n", elem_count); printf( "Sample:\n" - " \"+ D L:/var/www/upload\" - ʾؽһĿ¼/var/www/upload\n" - " \"+ D R:/var/www/upload\" - ʾнһĿ¼ / var / www / upload\n" - " \"- F L:/var/www/upload/001.jpg\" - ʾؽɾһļ / var / www / upload / 001.jpg\n" - " \"+ F R:/var/www/upload/001.jpg\" - ʾн¼һļ / var / www / upload / 001.jpg\n" - " \"A F L:/var/www/upload/001.jpg\" - ʾѱļ / var / www / upload / 001.jpgϴǵ\n" - " \"V F R:/var/www/upload/001.jpg\" - ʾļ / var / www / upload / 001.jpgزǵ\n" + " \"+ D L:/var/www/upload\" - Create new directory \"/var/www/upload\" into local file system\n" + " \"+ D R:/backup/www/upload\" - Create new directory \"/var/backup/upload\" into network disk\n" + " \"- F L:/var/www/upload/001.jpg\" - Delete the \"/var/www/upload/001.jpg\" from local file system\n" + " \"+ F R:/backup/www/upload/001.jpg\" - Add new file \"/backup/www/upload/001.jpg\" into network disk\n" + " \"A F L:/var/www/upload/001.jpg\" - Upload the local file \"/var/www/upload/001.jpg\" into network disk\n" + " \"V F R:/backup/www/upload/001.jpg\" - Download the network file \"/backup/www/upload/001.jpg\" into local file system\n" ); } -/*remoteϢжϱļǷҪ£߱ļǷҪϴ*/ +/*根据remote信息判断本地文件是否需要更新,或者本地文件是否需要上传*/ static int method_compare_file(const char *localPath, PcsFileInfo *remote, DbPrepare *pre, int md5Enabled, CompareItem *list, int *elem_count) { my_dirent *ent = NULL; int rc; rc = get_file_ent(&ent, localPath); - if (rc == 2) { //Ŀ¼ - addCompareItem(list, '-', 'D', 'L', localPath, elem_count); /*ɾĿ¼*/ + if (rc == 2) { //是目录 + addCompareItem(list, '-', 'D', 'L', localPath, elem_count); /*删除本地目录*/ my_dirent_destroy(ent); ent = NULL; } if (ent == NULL) { - addCompareItem(list, '+', 'F', 'L', localPath, elem_count); /*ļ*/ + addCompareItem(list, '+', 'F', 'L', localPath, elem_count); /*创建本地新文件*/ } else { int same_md5 = 0; const char *md5; - if (md5Enabled) { - md5 = md5_file((char *)localPath); - same_md5 = pcs_utils_strcmpi(md5, remote->md5); + if (md5Enabled && remote->md5) { + md5 = md5_file((char *)ent->path); + if (!md5) { + PRINT_FATAL("Can't calculate md5 for %s.", ent->path); + my_dirent_destroy(ent); + return -1; + } + else + same_md5 = pcs_utils_strcmpi(md5, remote->md5); } if (!same_md5) { if (md5Enabled && ent->mtime == ((time_t)remote->server_mtime)) { @@ -2545,10 +2576,10 @@ static int method_compare_file(const char *localPath, PcsFileInfo *remote, DbPre return -1; } if (ent->mtime < ((time_t)remote->server_mtime)) { - addCompareItem(list, OP_ARROW_DOWN, 'F', 'R', remote->path, elem_count); /*ļ*/ + addCompareItem(list, OP_ARROW_DOWN, 'F', 'R', remote->path, elem_count); /*下载网盘文件*/ } else if (ent->mtime >((time_t)remote->server_mtime)) { - addCompareItem(list, OP_ARROW_UP, 'F', 'L', localPath, elem_count); /*ϴļ*/ + addCompareItem(list, OP_ARROW_UP, 'F', 'L', localPath, elem_count); /*上传本地文件*/ } } } @@ -2566,13 +2597,13 @@ static int method_compare_folder(const char *localPath, const char *remotePath, PcsFileInfo ri = { 0 }; rc = get_file_ent(NULL, localPath); switch (rc){ - case 1: //ļ - addCompareItem(list, '-', 'F', 'L', localPath, elem_count); /*ɾļ*/ + case 1: //本地是文件 + addCompareItem(list, '-', 'F', 'L', localPath, elem_count); /*删除本地文件*/ break; - case 2: //Ŀ¼ + case 2: //本地是目录 break; - case 0: //ز - addCompareItem(list, '+', 'D', 'L', localPath, elem_count); /*Ŀ¼*/ + case 0: //本地不存在 + addCompareItem(list, '+', 'D', 'L', localPath, elem_count); /*创建本地新目录*/ break; default: break; @@ -2641,7 +2672,7 @@ static int method_compare_folder(const char *localPath, const char *remotePath, return 0; } -/*Ѱҵбشڣ̲ڵļҵҪӵ̵ıļ*/ +/*寻找到所有本地存在,但是网盘不存在的文件,即找到需要添加到网盘的本地文件*/ static int method_compare_untrack(const char *localPath, const char *remotePath, DbPrepare *pre, CompareItem *list, int *elem_count) { int rc; @@ -2651,12 +2682,12 @@ static int method_compare_untrack(const char *localPath, const char *remotePath, char *dstPath; rc = get_file_ent(NULL, localPath); - if (rc == 2) { //Ŀ¼ + if (rc == 2) { //目录 if (db_get_cache(&rf, pre, remotePath)) { return -1; } if (!rf.fs_id) { - addCompareItem(list, '+', 'D', 'R', remotePath, elem_count); /*Ŀ¼*/ + addCompareItem(list, '+', 'D', 'R', remotePath, elem_count); /*创建新网盘目录*/ } freeCacheInfo(&rf); ents = list_dir(localPath, 0); @@ -2675,12 +2706,12 @@ static int method_compare_untrack(const char *localPath, const char *remotePath, my_dirent_destroy(ents); } } - else if (rc == 1) { //ļ + else if (rc == 1) { //本地是文件 if (db_get_cache(&rf, pre, remotePath)) { return -1; } if (!rf.fs_id) { - addCompareItem(list, '+', 'F', 'R', remotePath, elem_count); /*ļ*/ + addCompareItem(list, '+', 'F', 'R', remotePath, elem_count); /*创建新网盘文件*/ } freeCacheInfo(&rf); } @@ -2714,13 +2745,13 @@ static int method_compare(const char *localPath, const char *remotePath, int md5 action = (char *)pcs_malloc(strlen(localPath) + strlen(remotePath) + 16); strcpy(action, "COMPARE: "); strcat(action, localPath); strcat(action, " <- "); strcat(action, remotePath); - //ȡǰACTION + //获取当前的ACTION if (db_get_action(&ai, action)) { pcs_free(action); PRINT_NOTICE("Compare - End"); return -1; } - //ACTION״̬ + //检查ACTION状态 if (ai.status == ACTION_STATUS_RUNNING) { PRINT_FATAL("There have another compare thread running, which is start by %s at %s", ai.create_app, format_time(ai.start_time)); pcs_free(action); @@ -2729,14 +2760,14 @@ static int method_compare(const char *localPath, const char *remotePath, int md5 return -1; } freeActionInfo(&ai); - //ACTIONΪRUNNING״̬ + //设置ACTION为RUNNING状态 if (db_set_action(action, ACTION_STATUS_RUNNING, 1)) { pcs_free(action); PRINT_NOTICE("Compare - End"); return -1; } - //鱾ػǷ - ʼδ±ػ + //检查本地缓存是否更新 - 开始。如果未更新则更新本地缓存 updateAction = (char *)pcs_malloc(strlen(remotePath) + 16); strcpy(updateAction, "UPDATE: "); strcat(updateAction, remotePath); @@ -2769,7 +2800,7 @@ static int method_compare(const char *localPath, const char *remotePath, int md5 } pcs_free(updateAction); freeActionInfo(&ai); - //鱾ػǷ - + //检查本地缓存是否更新 - 结束 if (db_prepare(&pre, SQL_CACHE_INSERT, SQL_CACHE_SELECT, SQL_CACHE_DELETE, SQL_CACHE_UPDATE, SQL_CACHE_SET_FLAG, SQL_CACHE_SELECT_SUB, NULL)) { db_set_action(action, ACTION_STATUS_ERROR, 0); @@ -2785,7 +2816,7 @@ static int method_compare(const char *localPath, const char *remotePath, int md5 PRINT_NOTICE("Compare - End"); return -1; } - if (rf.isdir) { //ΪĿ¼ + if (rf.isdir) { //类型为目录 if (method_compare_folder(localPath, remotePath, &pre, md5Enabled, &list, &elem_count)) { db_set_action(action, ACTION_STATUS_ERROR, 0); pcs_free(action); @@ -2796,7 +2827,7 @@ static int method_compare(const char *localPath, const char *remotePath, int md5 return -1; } } - else { //Ϊļ + else { //类型为文件 if (method_compare_file(localPath, &rf, &pre, md5Enabled, &list, &elem_count)) { db_set_action(action, ACTION_STATUS_ERROR, 0); pcs_free(action); @@ -2808,7 +2839,7 @@ static int method_compare(const char *localPath, const char *remotePath, int md5 } } freeCacheInfo(&rf); - //ѰұļϵͳУҪӵļĿ¼ + //寻找本地文件系统中,需要添加到服务器的文件或目录 if (method_compare_untrack(localPath, remotePath, &pre, &list, &elem_count)) { //PRINT_FATAL("Can't remove untrack files: %s", localPath); db_set_action(action, ACTION_STATUS_ERROR, 0); @@ -3158,7 +3189,7 @@ static int run_svc(struct params *params) PRINT_NOTICE("Application end up"); return -1; } - /* һPcs */ + /* 创建一个Pcs对象 */ pcs = pcs_create(config.cookieFilePath); if (pcs_islogin(pcs) != PCS_LOGIN) { PRINT_FATAL("Not login or session time out"); @@ -3194,7 +3225,7 @@ static int run_svc(struct params *params) static int parse_run_shell_params(struct params *params, int requireCooki, int requireCache) { - // - ʼ + //读参数 - 开始 if (params->config) { config.configFilePath = pcs_utils_strdup(params->config); if (readConfigFile()) { @@ -3239,7 +3270,7 @@ static int parse_run_shell_params(struct params *params, int requireCooki, int r freeConfig(FALSE); return -1; } - // - + //读参数 - 结束 return 0; } @@ -3261,7 +3292,7 @@ static int run_shell(struct params *params) PRINT_NOTICE("Application end up"); return -1; } - /* һPcs */ + /* 创建一个Pcs对象 */ pcs = pcs_create(config.cookieFilePath); if (pcs_islogin(pcs) != PCS_LOGIN) { PRINT_FATAL("Not login or session time out");