├── thread-pool ├── README ├── README.md ├── testthreadpool ├── test.c ├── thread_pool.h └── thread_pool.c ├── README.md ├── src ├── testFolder │ └── testfile ├── test ├── evclient ├── evserver ├── evclient2 ├── evserver2 ├── sourceCount.sh ├── common.c ├── common.h ├── thread_pool.h ├── README ├── conn_pool.h ├── mysql_encap.h ├── sha1.h ├── lock.h ├── filePathLinkedlist.h ├── conn_pool.cpp ├── thread_pool.c ├── mysql_encap.cpp └── evServer.c ├── test ├── src2 ├── test ├── evclient ├── evclient2 ├── evserver ├── evserver2 ├── sourceCount.sh ├── common.h ├── common.c ├── thread_pool.h ├── README ├── conn_pool.h ├── mysql_encap.h ├── sha1.h ├── lock.h ├── filePathLinkedlist.h ├── conn_pool.cpp ├── thread_pool.c ├── evServer.c ├── client.c └── mysql_encap.cpp ├── mysql-encap ├── test ├── testfolder │ └── 1.txt ├── testvar ├── evclient ├── evclient2 ├── evserver2 ├── testCount ├── testlock ├── testConnPool ├── testvar.cpp ├── testLock.cpp ├── testMysqlEncap.cpp ├── conn_pool.h ├── mysql_encap.h ├── testConnPool.cpp ├── README ├── lock.h ├── conn_pool.cpp └── mysql_encap.cpp ├──  ├── source-code-manager(开源的代码) ├── .scm │ ├── HEAD │ ├── branch │ │ ├── branch1 │ │ │ ├── commit │ │ │ └── index │ │ └── master │ │ │ ├── commit │ │ │ └── index │ └── obj │ │ ├── blob │ │ ├── 804d716fc5844f1cc5516c8f0be7a480517fdea2 │ │ ├── 97fc2447393fc67ee10ed2a899c1ade0416ef33b │ │ └── d2166871514c944bc5daddd8d891ac927e3590d4 │ │ ├── tree │ │ ├── 26b39d1ef3b8020626030cbd53d03085b5645238 │ │ ├── b1346a58772efca44682074da6afe309972a70f1 │ │ └── d9078c014baa7e69e899d78a734c0db32a7644c8 │ │ └── commit │ │ ├── 7abf9c258c274f1821090c441f5f0b684d2be4fb │ │ ├── a559a6fc5b763ad80b743bad0654dad3e6c19e39 │ │ └── eb33180cbc247fddb6cf2d5cbc6763345248ac1c ├── a.out ├── .objs │ ├── main.o │ └── code │ │ ├── src │ │ ├── obj.o │ │ ├── cmds.o │ │ ├── init.o │ │ ├── branch.o │ │ └── commit.o │ │ └── util │ │ ├── file.o │ │ ├── sha1.o │ │ ├── common.o │ │ ├── strings.o │ │ └── filelist.o ├── inc │ ├── cmds.h │ ├── obj.h │ ├── scm.h │ ├── strings.h │ ├── commit.h │ ├── common.h │ ├── sha.h │ └── filelist.h ├── makefile ├── main.c └── code │ ├── src │ ├── init.c │ ├── commit.c │ └── branch.c │ └── util │ ├── strings.c │ ├── file.c │ └── common.c ├── evclient ├── evclient2 ├── evserver ├── evserver2 ├── SHA1 ├── testsha ├── testsha++ ├── README ├── testsha1.c └── sha1.h ├── 开发笔记 ├── tips.txt └── bugs.txt ├── testFileName ├── test └── test.c ├── commitlog ├── testRead ├── testReset ├── testWrite ├── testpending ├── testReset.c ├── readPending.c ├── writePending.c └── pending.c ├── testChangRoot ├── chroot ├── testroot ├── new file └── testroot.c ├── testStringLinkedList ├── unit_test ├── unit_test2 ├── unit_test.c └── filePathLinkedlist.h ├── sourceCount.sh ├── common.h ├── common.c ├── sql_table ├── new file ├── tables └── get ├── thread_pool.h ├── README ├── conn_pool.h ├── mysql_encap.h ├── sha1.h ├── lock.h ├── testGetRealPath └── test_get_real_path.c ├── filePathLinkedlist.h ├── conn_pool.cpp ├── client.c ├── thread_pool.c ├── evServer.c ├── mysql_encap.cpp └── sock.h /thread-pool/README: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ManGo 2 | ===== 3 | -------------------------------------------------------------------------------- /src/testFolder/testfile: -------------------------------------------------------------------------------- 1 | v1 2 | -------------------------------------------------------------------------------- /test: -------------------------------------------------------------------------------- 1 | this is a test files 2 | haha 3 | -------------------------------------------------------------------------------- /src2/test: -------------------------------------------------------------------------------- 1 | this is a test files 2 | haha 3 | -------------------------------------------------------------------------------- /mysql-encap/test: -------------------------------------------------------------------------------- 1 | this is a test files 2 | haha 3 | -------------------------------------------------------------------------------- /mysql-encap/testfolder/1.txt: -------------------------------------------------------------------------------- 1 | 1dsfadfa 2 | ++fas 3 | -------------------------------------------------------------------------------- /src/test: -------------------------------------------------------------------------------- 1 | test dir comment 2 | this is version 3 3 | v4 -------------------------------------------------------------------------------- /: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/codercheng/ManGo/master/ -------------------------------------------------------------------------------- /source-code-manager(开源的代码)/.scm/HEAD: -------------------------------------------------------------------------------- 1 | branch: branch1 2 | -------------------------------------------------------------------------------- /evclient: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/codercheng/ManGo/master/evclient -------------------------------------------------------------------------------- /evclient2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/codercheng/ManGo/master/evclient2 -------------------------------------------------------------------------------- /evserver: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/codercheng/ManGo/master/evserver -------------------------------------------------------------------------------- /evserver2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/codercheng/ManGo/master/evserver2 -------------------------------------------------------------------------------- /SHA1/testsha: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/codercheng/ManGo/master/SHA1/testsha -------------------------------------------------------------------------------- /src/evclient: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/codercheng/ManGo/master/src/evclient -------------------------------------------------------------------------------- /src/evserver: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/codercheng/ManGo/master/src/evserver -------------------------------------------------------------------------------- /SHA1/testsha++: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/codercheng/ManGo/master/SHA1/testsha++ -------------------------------------------------------------------------------- /src/evclient2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/codercheng/ManGo/master/src/evclient2 -------------------------------------------------------------------------------- /src/evserver2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/codercheng/ManGo/master/src/evserver2 -------------------------------------------------------------------------------- /src2/evclient: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/codercheng/ManGo/master/src2/evclient -------------------------------------------------------------------------------- /src2/evclient2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/codercheng/ManGo/master/src2/evclient2 -------------------------------------------------------------------------------- /src2/evserver: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/codercheng/ManGo/master/src2/evserver -------------------------------------------------------------------------------- /src2/evserver2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/codercheng/ManGo/master/src2/evserver2 -------------------------------------------------------------------------------- /thread-pool/README.md: -------------------------------------------------------------------------------- 1 | thread-pool 2 | =========== 3 | 4 | a simple thread pool 5 | -------------------------------------------------------------------------------- /开发笔记/tips.txt: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/codercheng/ManGo/master/开发笔记/tips.txt -------------------------------------------------------------------------------- /SHA1/README: -------------------------------------------------------------------------------- 1 | gcc -g -Wall sha1.c sha.h testsha1.c -o testsha 2 | 3 | ./testsha a.txt 4 | -------------------------------------------------------------------------------- /testFileName/test: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/codercheng/ManGo/master/testFileName/test -------------------------------------------------------------------------------- /commitlog/testRead: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/codercheng/ManGo/master/commitlog/testRead -------------------------------------------------------------------------------- /commitlog/testReset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/codercheng/ManGo/master/commitlog/testReset -------------------------------------------------------------------------------- /commitlog/testWrite: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/codercheng/ManGo/master/commitlog/testWrite -------------------------------------------------------------------------------- /mysql-encap/testvar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/codercheng/ManGo/master/mysql-encap/testvar -------------------------------------------------------------------------------- /commitlog/testpending: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/codercheng/ManGo/master/commitlog/testpending -------------------------------------------------------------------------------- /mysql-encap/evclient: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/codercheng/ManGo/master/mysql-encap/evclient -------------------------------------------------------------------------------- /mysql-encap/evclient2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/codercheng/ManGo/master/mysql-encap/evclient2 -------------------------------------------------------------------------------- /mysql-encap/evserver2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/codercheng/ManGo/master/mysql-encap/evserver2 -------------------------------------------------------------------------------- /mysql-encap/testCount: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/codercheng/ManGo/master/mysql-encap/testCount -------------------------------------------------------------------------------- /mysql-encap/testlock: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/codercheng/ManGo/master/mysql-encap/testlock -------------------------------------------------------------------------------- /source-code-manager(开源的代码)/.scm/branch/branch1/commit: -------------------------------------------------------------------------------- 1 | 7abf9c258c274f1821090c441f5f0b684d2be4fb 2 | -------------------------------------------------------------------------------- /source-code-manager(开源的代码)/.scm/branch/master/commit: -------------------------------------------------------------------------------- 1 | 7abf9c258c274f1821090c441f5f0b684d2be4fb 2 | -------------------------------------------------------------------------------- /testChangRoot/chroot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/codercheng/ManGo/master/testChangRoot/chroot -------------------------------------------------------------------------------- /testChangRoot/testroot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/codercheng/ManGo/master/testChangRoot/testroot -------------------------------------------------------------------------------- /mysql-encap/testConnPool: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/codercheng/ManGo/master/mysql-encap/testConnPool -------------------------------------------------------------------------------- /thread-pool/testthreadpool: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/codercheng/ManGo/master/thread-pool/testthreadpool -------------------------------------------------------------------------------- /source-code-manager(开源的代码)/a.out: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/codercheng/ManGo/master/source-code-manager(开源的代码)/a.out -------------------------------------------------------------------------------- /testStringLinkedList/unit_test: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/codercheng/ManGo/master/testStringLinkedList/unit_test -------------------------------------------------------------------------------- /testStringLinkedList/unit_test2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/codercheng/ManGo/master/testStringLinkedList/unit_test2 -------------------------------------------------------------------------------- /source-code-manager(开源的代码)/.objs/main.o: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/codercheng/ManGo/master/source-code-manager(开源的代码)/.objs/main.o -------------------------------------------------------------------------------- /source-code-manager(开源的代码)/.objs/code/src/obj.o: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/codercheng/ManGo/master/source-code-manager(开源的代码)/.objs/code/src/obj.o -------------------------------------------------------------------------------- /source-code-manager(开源的代码)/.objs/code/src/cmds.o: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/codercheng/ManGo/master/source-code-manager(开源的代码)/.objs/code/src/cmds.o -------------------------------------------------------------------------------- /source-code-manager(开源的代码)/.objs/code/src/init.o: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/codercheng/ManGo/master/source-code-manager(开源的代码)/.objs/code/src/init.o -------------------------------------------------------------------------------- /source-code-manager(开源的代码)/.objs/code/util/file.o: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/codercheng/ManGo/master/source-code-manager(开源的代码)/.objs/code/util/file.o -------------------------------------------------------------------------------- /source-code-manager(开源的代码)/.objs/code/util/sha1.o: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/codercheng/ManGo/master/source-code-manager(开源的代码)/.objs/code/util/sha1.o -------------------------------------------------------------------------------- /testChangRoot/new file: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | int main(){ 4 | chroot("."); 5 | chdir("/"); 6 | execlp("/bin/sh",NULL); 7 | return 0; 8 | } 9 | -------------------------------------------------------------------------------- /source-code-manager(开源的代码)/.objs/code/src/branch.o: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/codercheng/ManGo/master/source-code-manager(开源的代码)/.objs/code/src/branch.o -------------------------------------------------------------------------------- /source-code-manager(开源的代码)/.objs/code/src/commit.o: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/codercheng/ManGo/master/source-code-manager(开源的代码)/.objs/code/src/commit.o -------------------------------------------------------------------------------- /source-code-manager(开源的代码)/.objs/code/util/common.o: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/codercheng/ManGo/master/source-code-manager(开源的代码)/.objs/code/util/common.o -------------------------------------------------------------------------------- /source-code-manager(开源的代码)/.objs/code/util/strings.o: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/codercheng/ManGo/master/source-code-manager(开源的代码)/.objs/code/util/strings.o -------------------------------------------------------------------------------- /source-code-manager(开源的代码)/.scm/branch/branch1/index: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/codercheng/ManGo/master/source-code-manager(开源的代码)/.scm/branch/branch1/index -------------------------------------------------------------------------------- /source-code-manager(开源的代码)/.scm/branch/master/index: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/codercheng/ManGo/master/source-code-manager(开源的代码)/.scm/branch/master/index -------------------------------------------------------------------------------- /source-code-manager(开源的代码)/.objs/code/util/filelist.o: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/codercheng/ManGo/master/source-code-manager(开源的代码)/.objs/code/util/filelist.o -------------------------------------------------------------------------------- /commitlog/testReset.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | int main() { 6 | FILE *fp = fopen("pending", "w"); 7 | fclose(fp); 8 | return 0; 9 | } 10 | -------------------------------------------------------------------------------- /sourceCount.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | find . -maxdepth 1 -name '*.c' -or -name '*.cpp' -or -name '*.h' | xargs wc -l 3 | 4 | find ./SHA1/ -maxdepth 1 -name '*.c' -or -name '*.cpp' -or -name '*.h' | xargs wc -l 5 | -------------------------------------------------------------------------------- /src/sourceCount.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | find . -maxdepth 1 -name '*.c' -or -name '*.cpp' -or -name '*.h' | xargs wc -l 3 | 4 | #find ./SHA1/ -maxdepth 1 -name '*.c' -or -name '*.cpp' -or -name '*.h' | xargs wc -l 5 | -------------------------------------------------------------------------------- /src2/sourceCount.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | find . -maxdepth 1 -name '*.c' -or -name '*.cpp' -or -name '*.h' | xargs wc -l 3 | 4 | find ./SHA1/ -maxdepth 1 -name '*.c' -or -name '*.cpp' -or -name '*.h' | xargs wc -l 5 | -------------------------------------------------------------------------------- /source-code-manager(开源的代码)/.scm/obj/blob/804d716fc5844f1cc5516c8f0be7a480517fdea2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/codercheng/ManGo/master/source-code-manager(开源的代码)/.scm/obj/blob/804d716fc5844f1cc5516c8f0be7a480517fdea2 -------------------------------------------------------------------------------- /source-code-manager(开源的代码)/.scm/obj/blob/97fc2447393fc67ee10ed2a899c1ade0416ef33b: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/codercheng/ManGo/master/source-code-manager(开源的代码)/.scm/obj/blob/97fc2447393fc67ee10ed2a899c1ade0416ef33b -------------------------------------------------------------------------------- /source-code-manager(开源的代码)/.scm/obj/blob/d2166871514c944bc5daddd8d891ac927e3590d4: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/codercheng/ManGo/master/source-code-manager(开源的代码)/.scm/obj/blob/d2166871514c944bc5daddd8d891ac927e3590d4 -------------------------------------------------------------------------------- /source-code-manager(开源的代码)/.scm/obj/tree/26b39d1ef3b8020626030cbd53d03085b5645238: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/codercheng/ManGo/master/source-code-manager(开源的代码)/.scm/obj/tree/26b39d1ef3b8020626030cbd53d03085b5645238 -------------------------------------------------------------------------------- /source-code-manager(开源的代码)/.scm/obj/tree/b1346a58772efca44682074da6afe309972a70f1: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/codercheng/ManGo/master/source-code-manager(开源的代码)/.scm/obj/tree/b1346a58772efca44682074da6afe309972a70f1 -------------------------------------------------------------------------------- /source-code-manager(开源的代码)/.scm/obj/tree/d9078c014baa7e69e899d78a734c0db32a7644c8: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/codercheng/ManGo/master/source-code-manager(开源的代码)/.scm/obj/tree/d9078c014baa7e69e899d78a734c0db32a7644c8 -------------------------------------------------------------------------------- /source-code-manager(开源的代码)/.scm/obj/commit/7abf9c258c274f1821090c441f5f0b684d2be4fb: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/codercheng/ManGo/master/source-code-manager(开源的代码)/.scm/obj/commit/7abf9c258c274f1821090c441f5f0b684d2be4fb -------------------------------------------------------------------------------- /source-code-manager(开源的代码)/.scm/obj/commit/a559a6fc5b763ad80b743bad0654dad3e6c19e39: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/codercheng/ManGo/master/source-code-manager(开源的代码)/.scm/obj/commit/a559a6fc5b763ad80b743bad0654dad3e6c19e39 -------------------------------------------------------------------------------- /source-code-manager(开源的代码)/.scm/obj/commit/eb33180cbc247fddb6cf2d5cbc6763345248ac1c: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/codercheng/ManGo/master/source-code-manager(开源的代码)/.scm/obj/commit/eb33180cbc247fddb6cf2d5cbc6763345248ac1c -------------------------------------------------------------------------------- /SHA1/testsha1.c: -------------------------------------------------------------------------------- 1 | #include "sha1.h" 2 | #include 3 | 4 | int main(){ 5 | ShaBuffer sha; 6 | char file[256]; 7 | scanf("%s",file); 8 | sha_file(file, sha); 9 | printf("sha:%s\n",sha); 10 | return 0; 11 | } 12 | -------------------------------------------------------------------------------- /开发笔记/bugs.txt: -------------------------------------------------------------------------------- 1 | 1. send: Resource temporarily unavailable 2 | "Resource temporarily unavailable" is the error message corresponding to EAGAIN, which means that the operation would have blocked but nonblocking operation was requested. 3 | 程序在传送文件的时候,我需要的是非阻塞的传送,但是在evServer.c中却把accept之后的sockfd设置为了non-blocking,也就会返回EAGAIN。 4 | 5 | 2. 传送大文件时候的bufsize设置的太小,这个东西最后统一设置在配置文件 6 | -------------------------------------------------------------------------------- /testChangRoot/testroot.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | 6 | int main(){ 7 | int ret = chroot("/home"); 8 | if(ret == -1){ 9 | printf("%s\n", strerror(errno)); 10 | } 11 | else{ 12 | printf("success\n"); 13 | } 14 | ret = chdir("/"); 15 | if(ret == -1){ 16 | printf("2--error\n"); 17 | }else{ 18 | printf("success\n"); 19 | } 20 | execl("/bin/ls","ls",NULL); 21 | return 0; 22 | } 23 | -------------------------------------------------------------------------------- /thread-pool/test.c: -------------------------------------------------------------------------------- 1 | #include "thread_pool.h" 2 | #include 3 | 4 | void *taskprocess(void *arg) 5 | { 6 | printf("aaaaaaaaaaaaaaaaaaaaaaaaaa\n"); 7 | usleep(1000); 8 | return NULL; 9 | } 10 | 11 | 12 | int main() 13 | { 14 | thread_pool_init(5); 15 | int i; 16 | for(i=1; i<=10; i++) 17 | { 18 | thread_pool_add_task(taskprocess,(void *)i); 19 | usleep(1000); 20 | } 21 | sleep(1); 22 | thread_pool_destroy(); 23 | return 0; 24 | } 25 | -------------------------------------------------------------------------------- /source-code-manager(开源的代码)/inc/cmds.h: -------------------------------------------------------------------------------- 1 | #ifndef CMDS_H_ 2 | #define CMDS_H_ 3 | int cmd_version(int argc, char *argv[]); 4 | int cmd_sha(int argc, char *argv[]); 5 | int cmd_init(int argc, char *argv[]); 6 | int cmd_branch(int argc, char *argv[]); 7 | int cmd_status(int argc, char *argv[]); 8 | int cmd_add(int argc, char *argv[]); 9 | int cmd_ls(int argc, char *argv[]); 10 | int cmd_commit(int argc, char *argv[]); 11 | int cmd_info(int argc, char *argv[]); 12 | int cmd_rm(int argc, char *argv[]); 13 | int cmd_checkout(int argc, char *argv[]); 14 | #endif 15 | -------------------------------------------------------------------------------- /testStringLinkedList/unit_test.c: -------------------------------------------------------------------------------- 1 | #include "filePathLinkedlist.h" 2 | 3 | int main() 4 | { 5 | FilePathList *list = (FilePathList *)malloc(sizeof(FilePathList)); 6 | init(list); 7 | 8 | int i; 9 | for(i=0; i<11; i++) { 10 | //FilePathListNode * newpath = (FilePathListNode *)malloc(sizeof(FilePathListNode)); 11 | //sprintf(newpath->filename, "%s::%d", "chengshuguang/test.c", i); 12 | //newpath->next = NULL; 13 | push_to_list(list, "cheng/test.c", "21", "shshshshshshsh", 123455677, 0); 14 | } 15 | unit_test(list); 16 | 17 | return 0; 18 | } 19 | -------------------------------------------------------------------------------- /commitlog/readPending.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | 6 | typedef struct { 7 | int action; 8 | long time; 9 | char sha1[41]; 10 | char path[218]; 11 | }record; 12 | 13 | int main() { 14 | FILE *fp = fopen("pending", "r"); 15 | if(fp == NULL) { 16 | printf("open file pending error\n"); 17 | return -1; 18 | } 19 | while(1) { 20 | record r; 21 | fread(&r, sizeof(r), 1, fp); 22 | if (feof(fp)) break; 23 | printf("%d, %ld, %s, %s\n", r.action, r.time, r.sha1, r.path); 24 | } 25 | fclose(fp); 26 | return 0; 27 | } 28 | -------------------------------------------------------------------------------- /commitlog/writePending.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | 6 | 7 | typedef struct { 8 | int action; 9 | long time; 10 | char sha1[41]; 11 | char path[218]; 12 | }record; 13 | 14 | int main() { 15 | FILE *fp = fopen("pending", "a+"); 16 | int i; 17 | for (i=0; i<2; i++) { 18 | record r; 19 | r.action = i; 20 | r.time = time(NULL); 21 | strcpy(r.sha1, "xxooxxooxx"); 22 | strcpy(r.path, "/chengshuguang/mango/web/test"); 23 | fwrite(&r, sizeof(r), 1, fp); 24 | } 25 | fclose(fp); 26 | return 0; 27 | } 28 | -------------------------------------------------------------------------------- /common.h: -------------------------------------------------------------------------------- 1 | /* 2 | * 把出错处理,还有一些共用函数都整合到这个类中来 3 | */ 4 | #ifndef COMMON_H_ 5 | #define COMMON_H_ 6 | 7 | #include 8 | #include 9 | 10 | #ifndef __cplusplus 11 | typedef enum { 12 | false = 0, 13 | true = 1 14 | }bool; 15 | #endif 16 | 17 | typedef enum { 18 | ADD_FILES, 19 | GET_FILES, 20 | SEND_FILES, 21 | TEST_ADD, 22 | TEST_GET 23 | }command; 24 | 25 | typedef struct message_{ 26 | command cmd; 27 | }message; 28 | 29 | typedef struct { 30 | char path[256]; 31 | char sha1[41]; 32 | long m_time; 33 | char comment[512]; 34 | }addinfo; 35 | 36 | 37 | 38 | bool isItFile(const char *name); 39 | bool isItFolder(const char *name); 40 | int getTime(char buffer[64]); 41 | 42 | 43 | 44 | #endif -------------------------------------------------------------------------------- /src2/common.h: -------------------------------------------------------------------------------- 1 | /* 2 | * 把出错处理,还有一些共用函数都整合到这个类中来 3 | */ 4 | #ifndef COMMON_H_ 5 | #define COMMON_H_ 6 | 7 | #include 8 | #include 9 | 10 | #ifndef __cplusplus 11 | 12 | typedef enum { 13 | false = 0, 14 | true = 1 15 | }bool; 16 | #endif 17 | 18 | typedef enum { 19 | ADD_FILES, 20 | GET_FILES, 21 | SEND_FILES, 22 | TEST_ADD, 23 | TEST_GET, 24 | INIT 25 | }command; 26 | 27 | typedef struct message_{ 28 | command cmd; 29 | }message; 30 | 31 | typedef struct { 32 | char path[256]; 33 | char sha1[41]; 34 | long m_time; 35 | char comment[512]; 36 | }addinfo; 37 | 38 | 39 | 40 | bool isItFile(const char *name); 41 | bool isItFolder(const char *name); 42 | int getTime(char buffer[64]); 43 | 44 | 45 | 46 | #endif -------------------------------------------------------------------------------- /source-code-manager(开源的代码)/inc/obj.h: -------------------------------------------------------------------------------- 1 | #ifndef _OBJ_H 2 | #define _OBJ_H 3 | #include "commit.h" 4 | #include "strings.h" 5 | bool getBranchName(String const s); 6 | bool setBranchName(String const s); 7 | 8 | bool getCurrentIndexFile(String s); 9 | bool readIndexFile(FileList index, String indexfile); 10 | bool readTree(FileList tree, ShaBuffer treeSha); 11 | 12 | bool copyFileToCache(File f); 13 | bool moveFileFromCacheToRepo(File f); 14 | bool copyFileFromRepo(File f); 15 | 16 | bool copyTreeToRepo(File f); 17 | bool copyTreeFromRepo(ShaBuffer tree, const char *dest, int mode); 18 | 19 | bool getCurrentCommit(Commit c, ShaBuffer currentCommit); 20 | bool setCurrentCommit(ShaBuffer commitSha); 21 | bool compareIndexWithWorkingArea(void); 22 | #endif 23 | -------------------------------------------------------------------------------- /common.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include "common.h" 9 | 10 | int getTime(char buffer[64]){ 11 | time_t t; 12 | struct tm *tim; 13 | t = time(NULL); 14 | tim = localtime(&t); 15 | strftime(buffer, 64, "%a %b %d %H:%M:%S %Y", tim); 16 | return 0; 17 | } 18 | 19 | bool isItFolder(const char *name){ 20 | struct stat s; 21 | if(0 == stat(name, &s)){ 22 | if(S_ISDIR(s.st_mode)) 23 | return true; 24 | } 25 | return false; 26 | } 27 | 28 | bool isItFile(const char *name){ 29 | struct stat s; 30 | if(0 == stat(name, &s)){ 31 | if(S_ISREG(s.st_mode)) 32 | return true; 33 | } 34 | return false; 35 | } 36 | -------------------------------------------------------------------------------- /src/common.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include "common.h" 9 | 10 | int getTime(char buffer[64]){ 11 | time_t t; 12 | struct tm *tim; 13 | t = time(NULL); 14 | tim = localtime(&t); 15 | strftime(buffer, 64, "%a %b %d %H:%M:%S %Y", tim); 16 | return 0; 17 | } 18 | 19 | bool isItFolder(const char *name){ 20 | struct stat s; 21 | if(0 == stat(name, &s)){ 22 | if(S_ISDIR(s.st_mode)) 23 | return true; 24 | } 25 | return false; 26 | } 27 | 28 | bool isItFile(const char *name){ 29 | struct stat s; 30 | if(0 == stat(name, &s)){ 31 | if(S_ISREG(s.st_mode)) 32 | return true; 33 | } 34 | return false; 35 | } 36 | -------------------------------------------------------------------------------- /src2/common.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include "common.h" 9 | 10 | int getTime(char buffer[64]){ 11 | time_t t; 12 | struct tm *tim; 13 | t = time(NULL); 14 | tim = localtime(&t); 15 | strftime(buffer, 64, "%a %b %d %H:%M:%S %Y", tim); 16 | return 0; 17 | } 18 | 19 | bool isItFolder(const char *name){ 20 | struct stat s; 21 | if(0 == stat(name, &s)){ 22 | if(S_ISDIR(s.st_mode)) 23 | return true; 24 | } 25 | return false; 26 | } 27 | 28 | bool isItFile(const char *name){ 29 | struct stat s; 30 | if(0 == stat(name, &s)){ 31 | if(S_ISREG(s.st_mode)) 32 | return true; 33 | } 34 | return false; 35 | } 36 | -------------------------------------------------------------------------------- /src/common.h: -------------------------------------------------------------------------------- 1 | /* 2 | * 把出错处理,还有一些共用函数都整合到这个类中来 3 | */ 4 | #ifndef COMMON_H_ 5 | #define COMMON_H_ 6 | 7 | #include 8 | #include 9 | /*important: for debug, add the next line*/ 10 | //#define _DEBUG_ 1 11 | 12 | #ifndef __cplusplus 13 | 14 | typedef enum { 15 | false = 0, 16 | true = 1 17 | }bool; 18 | #endif 19 | 20 | typedef enum { 21 | INIT, 22 | ADD, 23 | GET, 24 | DIFF, 25 | HISTORY, 26 | TAG, 27 | SHOW_TAG, 28 | GET_VERSION_BY_TAG 29 | }command; 30 | 31 | typedef struct message_{ 32 | command cmd; 33 | }message; 34 | 35 | typedef struct { 36 | char path[256]; 37 | char sha1[41]; 38 | long m_time; 39 | char comment[512]; 40 | }addinfo; 41 | 42 | 43 | 44 | bool isItFile(const char *name); 45 | bool isItFolder(const char *name); 46 | int getTime(char buffer[64]); 47 | 48 | 49 | 50 | #endif -------------------------------------------------------------------------------- /source-code-manager(开源的代码)/inc/scm.h: -------------------------------------------------------------------------------- 1 | #ifndef _SCM_H_ 2 | #define _SCM_H_ 3 | 4 | #include 5 | 6 | #define SCM_VERSION_NUMBER "0.04" 7 | #define SCM_DEFAULT_BRANCH "master" 8 | 9 | #define SCM_FOLDER ".scm" 10 | #define SCM_BRANCH_FOLDER ".scm/branch" 11 | #define SCM_OBJECTS_FOLDER ".scm/obj" 12 | 13 | #define SCM_BLOB_FOLDER ".scm/obj/blob" 14 | #define SCM_COMMIT_FOLDER ".scm/obj/commit" 15 | #define SCM_TREE_FOLDER ".scm/obj/tree" 16 | #define SCM_TEMP_FOLDER ".scm/tmp" 17 | 18 | #define SCM_BRANCH_CACHE_FOLDER "cache" 19 | 20 | #define SCM_HEAD_FILE ".scm/HEAD" 21 | #define SCM_INDEX_FILENAME "index" 22 | #define SCM_COMMIT_FILENAME "commit" 23 | 24 | #define SCM_FOLDER_PERMISSION S_IRWXU | S_IROTH | S_IRGRP 25 | #define SCM_HEAD_FILE_PERMISSION S_IRWXU | S_IROTH | S_IRGRP 26 | #define SCM_OBJECT_FILE_PERMISSION S_IRUSR | S_IROTH | S_IRGRP 27 | 28 | #endif 29 | -------------------------------------------------------------------------------- /source-code-manager(开源的代码)/inc/strings.h: -------------------------------------------------------------------------------- 1 | #ifndef STRING_H_ 2 | #define STRING_H_ 3 | #include 4 | #include "common.h" 5 | 6 | 7 | 8 | struct _string; 9 | typedef struct _string *String; 10 | 11 | String String_Create(void); 12 | void String_Delete(String s); 13 | 14 | void String_add(String s, const String s1); 15 | void String_clone(String s, const String s1); 16 | 17 | void String_SetSize(String s, const uint32_t size); 18 | 19 | void String_strcat(String s, const char *str); 20 | void String_strcpy(String s, const char *str); 21 | 22 | int String_strlen(const String s); 23 | int String_strcmp(const String s, const char *s1); 24 | int String_compare(const String s, const String s1); 25 | const char* s_getstr(const String s); 26 | int String_format(String s, const char *format, ...); 27 | void String_NormalizeFolderName(String s); 28 | void String_NormalizeFileName(String s); 29 | #endif 30 | -------------------------------------------------------------------------------- /mysql-encap/testvar.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | using namespace std; 4 | 5 | class TestVar{ 6 | public: 7 | TestVar():b(2), e(a){ 8 | a = 1; 9 | cout< 4 | #include "scm.h" 5 | #include "sha.h" 6 | #include "strings.h" 7 | #include "common.h" 8 | 9 | struct _Commit 10 | { 11 | ShaBuffer tree; 12 | ShaBuffer parent0, parent1; 13 | time_t rawtime; 14 | String author; 15 | String message; 16 | }; 17 | 18 | typedef struct _Commit *Commit; 19 | 20 | void Commit_Reset(Commit s); 21 | Commit Commit_Create(void); 22 | void Commit_Delete(Commit c); 23 | bool Commit_SetTree(Commit c, const ShaBuffer tree); 24 | bool Commit_SetParent(Commit c, const ShaBuffer parent0, const ShaBuffer parent1); 25 | bool Commit_SetMessage(Commit c, const char *message); 26 | bool Commit_SetAuthor(Commit c, const char *authorName, const char *authorEmailId); 27 | 28 | bool WriteCommitFile(Commit s, ShaBuffer commit); 29 | void PrintCommit(Commit s); 30 | bool Commit_ReadCommitFile(Commit c, const ShaBuffer commitSha); 31 | bool Commit_WriteCommitFile(Commit c, ShaBuffer commitSha); 32 | #endif 33 | -------------------------------------------------------------------------------- /source-code-manager(开源的代码)/makefile: -------------------------------------------------------------------------------- 1 | CC=gcc 2 | INCLUDE_DIR =inc 3 | CC_FLAG=-Wall -g 4 | SRC=code/src code/util . 5 | OBJ_FLAGS=-Wall -c 6 | LDFLAGS +=-lz 7 | EXECUTABLES=a.out 8 | SOURCES=$(foreach DIR, $(SRC),$(wildcard $(DIR)/*.c)) 9 | INCLUDE += $(foreach includedir, $(INCLUDE_DIR),-I $(includedir)) 10 | INCLUDE_FILES += $(foreach includedir, $(INCLUDE_DIR),$(includedir)/*.h) 11 | OBJS_FOLDER=.objs 12 | OBJECTS := $(addprefix ${OBJS_FOLDER}/,$(SOURCES:.c=.o)) 13 | 14 | all: ${EXECUTABLES} 15 | 16 | .PHONY: all clean distclean 17 | 18 | ${OBJS_FOLDER}: 19 | mkdir -p ${foreach s, ${SRC}, ${OBJS_FOLDER}/${s}} 20 | 21 | ${EXECUTABLES}: ${OBJS_FOLDER} ${OBJECTS} ${INCLUDE_FILES} 22 | ${CC} ${INCLUDE} ${OPT} ${CC_FLAG} ${LDFLAGS} ${OBJECTS} -o $@ && ctags -R --c-kinds=+p --fields=+S 23 | 24 | #if any header files gets modified compile the whole project again 25 | .objs/%.o: %.c ${INCLUDE_FILES} 26 | ${CC} ${INCLUDE} ${OPT} ${OBJ_FLAGS} $< -o $@ 27 | 28 | clean: 29 | rm -rf ${EXECUTABLES} ${OBJS_FOLDER} 30 | cleanscm: 31 | rm -rf .scm 32 | 33 | distclean: clean 34 | 35 | -------------------------------------------------------------------------------- /sql_table/new file: -------------------------------------------------------------------------------- 1 | create table repository (id int auto_increment primary key, name varchar(256) not null); 2 | ---------------------------------------------------- 3 | insert into repository values(NULL, 'test1'); 4 | insert into repository values(NULL, 'test2'); 5 | select * from repository; 6 | select id from repository where name = 'test2'; 7 | ------------------------------------------------------ 8 | 9 | create table item ( itemId int auto_increment primary key, version int not null, sha1 char(41) not null, path varchar(256) not null, m_time bigint); 10 | 11 | ---------------------------------------------------- 12 | insert into item values(NULL, 1, 'flafsdakfjsiahfuishdiuf', 'test.c', 12321847); 13 | 14 | select * from item where itemId = 1; 15 | ------------------------------------------------------ 16 | 17 | create table history ( historyId int auto_increment primary key, itemId int not null, version int not null, sha1 char(41) not null, path varchar(256) not null, m_time bigint, user varchar(20) not null, action int not null, commitGroup int not null); 18 | 19 | 20 | -------------------------------------------------------------------------------- /src/thread_pool.h: -------------------------------------------------------------------------------- 1 | #ifndef THREAD_POOL_H 2 | #define THREAD_POOL_H 3 | 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | 10 | typedef struct task 11 | { 12 | void *(*taskfunc)(void *arg);//声明一个函数指针 13 | void *arg;//函数的参数 14 | struct task *next; 15 | }task; 16 | 17 | typedef struct thread_pool 18 | { 19 | task *task_queue_head;//任务队列 20 | task *task_queue_end;//指向任务队列结尾 21 | int task_queue_size; 22 | 23 | pthread_t *thread_queue;//线程队列 24 | int thread_num; 25 | int idle_thread_num;//空闲线程数 26 | 27 | int is_pool_destroyed; 28 | 29 | pthread_mutex_t queue_mutex;//用来互斥访问任务队列 30 | pthread_cond_t queue_cond; 31 | }thread_pool; 32 | 33 | 34 | #ifdef __cplusplus 35 | extern "C"{ 36 | #endif 37 | 38 | extern thread_pool *pool; 39 | extern int thread_pool_init(int thread_pool_size); 40 | //extern void * thread_pool_entrance(void *arg); 41 | extern int thread_pool_add_task(void *(*taskfunc)(void *arg), void *arg); 42 | extern int thread_pool_destroy(); 43 | 44 | #ifdef __cplusplus 45 | } 46 | #endif 47 | 48 | #endif //THREAD_POOL_H 49 | -------------------------------------------------------------------------------- /thread_pool.h: -------------------------------------------------------------------------------- 1 | #ifndef THREAD_POOL_H 2 | #define THREAD_POOL_H 3 | 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | 10 | typedef struct task 11 | { 12 | void *(*taskfunc)(void *arg);//声明一个函数指针 13 | void *arg;//函数的参数 14 | struct task *next; 15 | }task; 16 | 17 | typedef struct thread_pool 18 | { 19 | task *task_queue_head;//任务队列 20 | task *task_queue_end;//指向任务队列结尾 21 | int task_queue_size; 22 | 23 | pthread_t *thread_queue;//线程队列 24 | int thread_num; 25 | int idle_thread_num;//空闲线程数 26 | 27 | int is_pool_destroyed; 28 | 29 | pthread_mutex_t queue_mutex;//用来互斥访问任务队列 30 | pthread_cond_t queue_cond; 31 | }thread_pool; 32 | 33 | 34 | #ifdef __cplusplus 35 | extern "C"{ 36 | #endif 37 | 38 | extern thread_pool *pool; 39 | extern int thread_pool_init(int thread_pool_size); 40 | //extern void * thread_pool_entrance(void *arg); 41 | extern int thread_pool_add_task(void *(*taskfunc)(void *arg), void *arg); 42 | extern int thread_pool_destroy(); 43 | 44 | #ifdef __cplusplus 45 | } 46 | #endif 47 | 48 | #endif //THREAD_POOL_H 49 | -------------------------------------------------------------------------------- /src2/thread_pool.h: -------------------------------------------------------------------------------- 1 | #ifndef THREAD_POOL_H 2 | #define THREAD_POOL_H 3 | 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | 10 | typedef struct task 11 | { 12 | void *(*taskfunc)(void *arg);//声明一个函数指针 13 | void *arg;//函数的参数 14 | struct task *next; 15 | }task; 16 | 17 | typedef struct thread_pool 18 | { 19 | task *task_queue_head;//任务队列 20 | task *task_queue_end;//指向任务队列结尾 21 | int task_queue_size; 22 | 23 | pthread_t *thread_queue;//线程队列 24 | int thread_num; 25 | int idle_thread_num;//空闲线程数 26 | 27 | int is_pool_destroyed; 28 | 29 | pthread_mutex_t queue_mutex;//用来互斥访问任务队列 30 | pthread_cond_t queue_cond; 31 | }thread_pool; 32 | 33 | 34 | #ifdef __cplusplus 35 | extern "C"{ 36 | #endif 37 | 38 | extern thread_pool *pool; 39 | extern int thread_pool_init(int thread_pool_size); 40 | //extern void * thread_pool_entrance(void *arg); 41 | extern int thread_pool_add_task(void *(*taskfunc)(void *arg), void *arg); 42 | extern int thread_pool_destroy(); 43 | 44 | #ifdef __cplusplus 45 | } 46 | #endif 47 | 48 | #endif //THREAD_POOL_H 49 | -------------------------------------------------------------------------------- /thread-pool/thread_pool.h: -------------------------------------------------------------------------------- 1 | #ifndef THREAD_POOL_H 2 | #define THREAD_POOL_H 3 | 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | 10 | typedef struct task 11 | { 12 | void *(*taskfunc)(void *arg);//声明一个函数指针 13 | void *arg;//函数的参数 14 | struct task *next; 15 | }task; 16 | 17 | typedef struct thread_pool 18 | { 19 | task *task_queue_head;//任务队列 20 | task *task_queue_end;//指向任务队列结尾 21 | int task_queue_size; 22 | 23 | pthread_t *thread_queue;//线程队列 24 | int thread_num; 25 | int idle_thread_num;//空闲线程数 26 | 27 | int is_pool_destroyed; 28 | 29 | pthread_mutex_t queue_mutex;//用来互斥访问任务队列 30 | pthread_cond_t queue_cond; 31 | }thread_pool; 32 | 33 | 34 | #ifdef __cplusplus 35 | extern "C"{ 36 | #endif 37 | 38 | extern thread_pool *pool; 39 | extern int thread_pool_init(int thread_pool_size); 40 | //extern void * thread_pool_entrance(void *arg); 41 | extern int thread_pool_add_task(void *(*taskfunc)(void *arg), void *arg); 42 | extern int thread_pool_destroy(); 43 | 44 | #ifdef __cplusplus 45 | } 46 | #endif 47 | 48 | #endif //THREAD_POOL_H 49 | -------------------------------------------------------------------------------- /README: -------------------------------------------------------------------------------- 1 | //server 未加数据库 2 | gcc -g -Wall -L /usr/local/lib -lev sock.h evServer.c common.h -o evserver 3 | 4 | //加上数据库 5 | g++ -g -Wall -lmysqlclient -lpthread -L /usr/local/lib -lev mysql_encap.cpp mysql_encap.h conn_pool.cpp conn_pool.h sock.h evServer.c common.h -o evserver2 6 | 7 | //加上线程池 8 | g++ -g -Wall -lmysqlclient -lpthread -L /usr/local/lib -lev thread_pool.c thread_pool.h mysql_encap.cpp mysql_encap.h conn_pool.cpp conn_pool.h sock.h evServer.c common.h -o evserver2 9 | 10 | //加sha1.h 需要了 11 | //g++ -g -Wall -lmysqlclient -lpthread -L /usr/local/lib -lev thread_pool.c thread_pool.h mysql_encap.cpp mysql_encap.h conn_pool.cpp conn_pool.h sha1.h sha1.c sock.h evServer.c common.h -o evserver2*/ 12 | 13 | 14 | g++ -g -Wall -lmysqlclient -lpthread -L /usr/local/lib -lev thread_pool.c thread_pool.h mysql_encap.cpp mysql_encap.h conn_pool.cpp conn_pool.h sock.h sha1.h sha1.c files.h evServer.c common.h common.c -o evserver2 15 | 16 | 17 | 18 | //client 19 | gcc -g -Wall sock.h client.c -o evclient 20 | g++ -g -Wall -lmysqlclient -lpthread -L /usr/local/lib client.c sock.h sha1.c sha1.h common.h common.c mysql_encap.cpp mysql_encap.h files.h -o evclient2 21 | 22 | -------------------------------------------------------------------------------- /src/README: -------------------------------------------------------------------------------- 1 | //server 未加数据库 2 | gcc -g -Wall -L /usr/local/lib -lev sock.h evServer.c common.h -o evserver 3 | 4 | //加上数据库 5 | g++ -g -Wall -lmysqlclient -lpthread -L /usr/local/lib -lev mysql_encap.cpp mysql_encap.h conn_pool.cpp conn_pool.h sock.h evServer.c common.h -o evserver2 6 | 7 | //加上线程池 8 | g++ -g -Wall -lmysqlclient -lpthread -L /usr/local/lib -lev thread_pool.c thread_pool.h mysql_encap.cpp mysql_encap.h conn_pool.cpp conn_pool.h sock.h evServer.c common.h -o evserver2 9 | 10 | //加sha1.h 需要了 11 | //g++ -g -Wall -lmysqlclient -lpthread -L /usr/local/lib -lev thread_pool.c thread_pool.h mysql_encap.cpp mysql_encap.h conn_pool.cpp conn_pool.h sha1.h sha1.c sock.h evServer.c common.h -o evserver2*/ 12 | 13 | 14 | g++ -g -Wall -lmysqlclient -lpthread -L /usr/local/lib -lev thread_pool.c thread_pool.h mysql_encap.cpp mysql_encap.h conn_pool.cpp conn_pool.h sock.h sha1.h sha1.c files.h evServer.c common.h common.c -o evserver2 15 | 16 | 17 | 18 | //client 19 | gcc -g -Wall sock.h client.c -o evclient 20 | g++ -g -Wall -lmysqlclient -lpthread -L /usr/local/lib client.c sock.h sha1.c sha1.h common.h common.c mysql_encap.cpp mysql_encap.h files.h -o evclient2 21 | 22 | -------------------------------------------------------------------------------- /src2/README: -------------------------------------------------------------------------------- 1 | //server 未加数据库 2 | gcc -g -Wall -L /usr/local/lib -lev sock.h evServer.c common.h -o evserver 3 | 4 | //加上数据库 5 | g++ -g -Wall -lmysqlclient -lpthread -L /usr/local/lib -lev mysql_encap.cpp mysql_encap.h conn_pool.cpp conn_pool.h sock.h evServer.c common.h -o evserver2 6 | 7 | //加上线程池 8 | g++ -g -Wall -lmysqlclient -lpthread -L /usr/local/lib -lev thread_pool.c thread_pool.h mysql_encap.cpp mysql_encap.h conn_pool.cpp conn_pool.h sock.h evServer.c common.h -o evserver2 9 | 10 | //加sha1.h 需要了 11 | //g++ -g -Wall -lmysqlclient -lpthread -L /usr/local/lib -lev thread_pool.c thread_pool.h mysql_encap.cpp mysql_encap.h conn_pool.cpp conn_pool.h sha1.h sha1.c sock.h evServer.c common.h -o evserver2*/ 12 | 13 | 14 | g++ -g -Wall -lmysqlclient -lpthread -L /usr/local/lib -lev thread_pool.c thread_pool.h mysql_encap.cpp mysql_encap.h conn_pool.cpp conn_pool.h sock.h sha1.h sha1.c files.h evServer.c common.h common.c -o evserver2 15 | 16 | 17 | 18 | //client 19 | gcc -g -Wall sock.h client.c -o evclient 20 | g++ -g -Wall -lmysqlclient -lpthread -L /usr/local/lib client.c sock.h sha1.c sha1.h common.h common.c mysql_encap.cpp mysql_encap.h files.h -o evclient2 21 | 22 | -------------------------------------------------------------------------------- /mysql-encap/testLock.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include "lock.h" 3 | #include 4 | #include 5 | 6 | using namespace std; 7 | 8 | MutexLock mutex; 9 | int cnt = 2000; 10 | 11 | void *f(void *arg){ 12 | int t_num = (int)arg; 13 | while(true){ 14 | MutexGuard lock(mutex); 15 | if(cnt>0){ 16 | usleep(1); 17 | printf("%d: %d\n", t_num, cnt--); 18 | }else{ 19 | break; 20 | } 21 | 22 | } 23 | return NULL; 24 | } 25 | 26 | int main(){ 27 | pthread_t tid; 28 | pthread_t tid1; 29 | pthread_t tid2; 30 | pthread_t tid3; 31 | int ret = pthread_create(&tid, NULL, f,(void*)1); 32 | if(ret == -1){ 33 | perror("create error\n"); 34 | } 35 | 36 | ret = pthread_create(&tid1, NULL, f, (void*)2); 37 | if(ret == -1){ 38 | perror("create error\n"); 39 | } 40 | 41 | ret = pthread_create(&tid2, NULL, f, (void*)3); 42 | if(ret == -1){ 43 | perror("create error\n"); 44 | } 45 | 46 | ret = pthread_create(&tid3, NULL, f, (void*)4); 47 | if(ret == -1){ 48 | perror("create error\n"); 49 | } 50 | 51 | pthread_join(tid, NULL); 52 | pthread_join(tid1, NULL); 53 | pthread_join(tid2, NULL); 54 | pthread_join(tid3, NULL); 55 | return 0; 56 | } 57 | -------------------------------------------------------------------------------- /source-code-manager(开源的代码)/inc/common.h: -------------------------------------------------------------------------------- 1 | #ifndef COMMON_H 2 | #define COMMON_H 3 | #include 4 | #include 5 | typedef enum 6 | { 7 | false = 0, 8 | true = 1, 9 | }bool; 10 | 11 | #define MAX_BUFFER_SIZE 4096 12 | 13 | #define OBJECT_FILE_LIST 0xFF000001 14 | #define OBJECT_COMMIT_FILE 0xFF000002 15 | 16 | 17 | #define LOG_ERROR(format, ...) fprintf(stderr, format "\n", ## __VA_ARGS__) 18 | #define LOG_INFO(format, ...) fprintf(stdout, format "\n", ## __VA_ARGS__) 19 | 20 | typedef unsigned int uint32_t; 21 | typedef unsigned short int uint16_t; 22 | 23 | 24 | void* XMALLOC(size_t size); 25 | void* XREALLOC(void *p, size_t size); 26 | void PrintAllocatedBytes(void); 27 | #define XFREE(x) do { if(NULL != x) free(x), x = NULL; }while(0) 28 | 29 | extern void *memcpy (void *dest, const void *src, size_t n); 30 | 31 | int Nstrlen(const char *str); 32 | bool isItFile(const char *name); 33 | bool isItFolder(const char *name); 34 | int getTime(char buffer[64]); 35 | bool copyFile(const char *source, const char *destination, const int mode); 36 | bool compressAndSave(const char *sourceFile, const char *destFile, int mode); 37 | bool decompressAndSave(const char *sourceFile, const char *destFile, int mode); 38 | #endif 39 | -------------------------------------------------------------------------------- /mysql-encap/testMysqlEncap.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | #include "mysql_encap.h" 6 | 7 | using namespace std; 8 | 9 | int main(){ 10 | MysqlEncap *sql_conn = new MysqlEncap; 11 | sql_conn->Connect("localhost","root", "110315"); 12 | 13 | sql_conn->ExecuteQuery("select * from testdb.student;"); 14 | printf("rows count:%d\n", sql_conn->GetQueryResultCount()); 15 | while(sql_conn->FetchRow()){ 16 | printf("%s,%s\n",sql_conn->GetField("sid"),sql_conn->GetField("name")); 17 | } 18 | 19 | // printf("-------------------------------\n"); 20 | // sql_conn->StartTransaction(); 21 | // 22 | // sql_conn->Execute("update testdb.student set name = 'chengshuguang' where name = 'testapi';"); 23 | // sql_conn->Execute("insert into testdb.student values (19, 'waba19', 'test2.c');"); 24 | // if (sql_conn->EndTransaction()) { 25 | // printf("return 1---commit\n"); 26 | // } else { 27 | // printf("return 0---rollback\n"); 28 | // } 29 | 30 | // printf("-------------------------------\n"); 31 | // sql_conn->ExecuteQuery("select * from testdb.student;"); 32 | // while(sql_conn->FetchRow()){ 33 | // printf("%s,%s\n",sql_conn->GetField("sid"),sql_conn->GetField("name")); 34 | // } 35 | delete sql_conn; 36 | 37 | return 0; 38 | } 39 | -------------------------------------------------------------------------------- /conn_pool.h: -------------------------------------------------------------------------------- 1 | #ifndef CONN_POOL_H_ 2 | #define CONN_POOL_H_ 3 | 4 | #include "mysql_encap.h" 5 | #include "lock.h" 6 | #include 7 | #include 8 | 9 | #define HOST "localhost" 10 | #define USERNAME "root" 11 | #define PASSWORD "110315" 12 | 13 | #define MAX_CONNPOOL_SIZE 4 14 | #define INIT_CONNPOOL_SIZE 2 15 | 16 | class ConnPool{ 17 | public: 18 | static ConnPool *GetInstance(); 19 | MysqlEncap *GetOneConn(); 20 | void ReleaseOneConn(MysqlEncap *); 21 | void ShowStatus(); 22 | private: 23 | int curSize;//目前已有的连接,包括connlist中空闲的和已经分配出去的 24 | int maxSize_; 25 | 26 | string hostip_; 27 | string username_; 28 | string password_; 29 | 30 | list connList;//空闲的conn 31 | MutexLock mutex; 32 | 33 | static ConnPool *conn_pool;//singleton 34 | 35 | ConnPool(const char *hostip, const char *username, const char *password, 36 | int maxSize, int initSize); 37 | ~ConnPool(); 38 | void InitConnPool(const char *hostip, const char *username, const char *password, 39 | int initSize); 40 | void DestroyConnection(MysqlEncap *sql_conn); 41 | void DestroyConnPool(); 42 | 43 | private: 44 | //禁止copy 45 | ConnPool(const ConnPool &); 46 | ConnPool &operator=(const ConnPool &); 47 | }; 48 | 49 | #endif 50 | -------------------------------------------------------------------------------- /src/conn_pool.h: -------------------------------------------------------------------------------- 1 | #ifndef CONN_POOL_H_ 2 | #define CONN_POOL_H_ 3 | 4 | #include "mysql_encap.h" 5 | #include "lock.h" 6 | #include 7 | #include 8 | 9 | #define HOST "localhost" 10 | #define USERNAME "root" 11 | #define PASSWORD "110315" 12 | 13 | #define MAX_CONNPOOL_SIZE 4 14 | #define INIT_CONNPOOL_SIZE 2 15 | 16 | class ConnPool{ 17 | public: 18 | static ConnPool *GetInstance(); 19 | MysqlEncap *GetOneConn(); 20 | void ReleaseOneConn(MysqlEncap *); 21 | void ShowStatus(); 22 | private: 23 | int curSize;//目前已有的连接,包括connlist中空闲的和已经分配出去的 24 | int maxSize_; 25 | 26 | string hostip_; 27 | string username_; 28 | string password_; 29 | 30 | list connList;//空闲的conn 31 | MutexLock mutex; 32 | 33 | static ConnPool *conn_pool;//singleton 34 | 35 | ConnPool(const char *hostip, const char *username, const char *password, 36 | int maxSize, int initSize); 37 | ~ConnPool(); 38 | void InitConnPool(const char *hostip, const char *username, const char *password, 39 | int initSize); 40 | void DestroyConnection(MysqlEncap *sql_conn); 41 | void DestroyConnPool(); 42 | 43 | private: 44 | //禁止copy 45 | ConnPool(const ConnPool &); 46 | ConnPool &operator=(const ConnPool &); 47 | }; 48 | 49 | #endif 50 | -------------------------------------------------------------------------------- /src2/conn_pool.h: -------------------------------------------------------------------------------- 1 | #ifndef CONN_POOL_H_ 2 | #define CONN_POOL_H_ 3 | 4 | #include "mysql_encap.h" 5 | #include "lock.h" 6 | #include 7 | #include 8 | 9 | #define HOST "localhost" 10 | #define USERNAME "root" 11 | #define PASSWORD "110315" 12 | 13 | #define MAX_CONNPOOL_SIZE 4 14 | #define INIT_CONNPOOL_SIZE 2 15 | 16 | class ConnPool{ 17 | public: 18 | static ConnPool *GetInstance(); 19 | MysqlEncap *GetOneConn(); 20 | void ReleaseOneConn(MysqlEncap *); 21 | void ShowStatus(); 22 | private: 23 | int curSize;//目前已有的连接,包括connlist中空闲的和已经分配出去的 24 | int maxSize_; 25 | 26 | string hostip_; 27 | string username_; 28 | string password_; 29 | 30 | list connList;//空闲的conn 31 | MutexLock mutex; 32 | 33 | static ConnPool *conn_pool;//singleton 34 | 35 | ConnPool(const char *hostip, const char *username, const char *password, 36 | int maxSize, int initSize); 37 | ~ConnPool(); 38 | void InitConnPool(const char *hostip, const char *username, const char *password, 39 | int initSize); 40 | void DestroyConnection(MysqlEncap *sql_conn); 41 | void DestroyConnPool(); 42 | 43 | private: 44 | //禁止copy 45 | ConnPool(const ConnPool &); 46 | ConnPool &operator=(const ConnPool &); 47 | }; 48 | 49 | #endif 50 | -------------------------------------------------------------------------------- /mysql-encap/conn_pool.h: -------------------------------------------------------------------------------- 1 | #ifndef CONN_POOL_H_ 2 | #define CONN_POOL_H_ 3 | 4 | #include "mysql_encap.h" 5 | #include "lock.h" 6 | #include 7 | #include 8 | 9 | #define HOST "localhost" 10 | #define USERNAME "root" 11 | #define PASSWORD "110315" 12 | 13 | #define MAX_CONNPOOL_SIZE 4 14 | #define INIT_CONNPOOL_SIZE 2 15 | 16 | class ConnPool{ 17 | public: 18 | static ConnPool *GetInstance(); 19 | MysqlEncap *GetOneConn(); 20 | void ReleaseOneConn(MysqlEncap *); 21 | void ShowStatus(); 22 | private: 23 | int curSize;//目前已有的连接,包括connlist中空闲的和已经分配出去的 24 | int maxSize_; 25 | 26 | string hostip_; 27 | string username_; 28 | string password_; 29 | 30 | list connList;//空闲的conn 31 | MutexLock mutex; 32 | 33 | static ConnPool *conn_pool;//singleton 34 | 35 | ConnPool(const char *hostip, const char *username, const char *password, 36 | int maxSize, int initSize); 37 | ~ConnPool(); 38 | void InitConnPool(const char *hostip, const char *username, const char *password, 39 | int initSize); 40 | void DestroyConnection(MysqlEncap *sql_conn); 41 | void DestroyConnPool(); 42 | 43 | private: 44 | //禁止copy 45 | ConnPool(const ConnPool &); 46 | ConnPool &operator=(const ConnPool &); 47 | }; 48 | 49 | #endif 50 | -------------------------------------------------------------------------------- /mysql_encap.h: -------------------------------------------------------------------------------- 1 | #ifndef MYSQL_ENCAP_H_ 2 | #define MYSQL_ENCAP_H_ 3 | 4 | #include 5 | #include 6 | #include 7 | #include 8 | 9 | using namespace std; 10 | 11 | class MysqlEncap{ 12 | 13 | public: 14 | MysqlEncap(); 15 | ~MysqlEncap(); 16 | 17 | bool Connect(const char *ip, const char *username, const 18 | char *password); 19 | void CloseConnect(); 20 | 21 | 22 | bool ExecuteQuery(const char *sql); 23 | bool Execute(const char *sql); 24 | bool StartTransaction(); 25 | //修改为:当返回值0的时候,是ROLLBACK,1--COMMIT 26 | bool EndTransaction(); 27 | 28 | 29 | 30 | char *GetField(const char *fieldname);//根据列的名字查找当前行,得到该列的值 31 | char *GetField(int filednum);//根据列的序号查找当前行,得到该列的值 32 | char **FetchRow();//拿出一行结果 33 | 34 | private: 35 | bool ReConnect(); 36 | void FreeResult();//释放上一次查询的结果 37 | 38 | private: 39 | 40 | bool isConnected;//判断是否连接 41 | bool bCommit;//当用到事务时,该值用来选择是commit还是rollback 42 | int fieldcnt;//查询结果有几列 43 | map mapFiledToIndex;//查询结果列名字到序号的映射:id->0; name->1 44 | 45 | MYSQL sql_conn;//数据库连接 46 | MYSQL_RES *sql_result;//查询结果 47 | MYSQL_ROW sql_row;//结果中的当前行,FetchRow(); 48 | 49 | //保存连接信息,保证重连 50 | string hostip_; 51 | string username_; 52 | string password_; 53 | 54 | }; 55 | 56 | #endif 57 | -------------------------------------------------------------------------------- /src2/mysql_encap.h: -------------------------------------------------------------------------------- 1 | #ifndef MYSQL_ENCAP_H_ 2 | #define MYSQL_ENCAP_H_ 3 | 4 | #include 5 | #include 6 | #include 7 | #include 8 | 9 | using namespace std; 10 | 11 | class MysqlEncap{ 12 | 13 | public: 14 | MysqlEncap(); 15 | ~MysqlEncap(); 16 | 17 | bool Connect(const char *ip, const char *username, const 18 | char *password); 19 | void CloseConnect(); 20 | 21 | 22 | bool ExecuteQuery(const char *sql); 23 | bool Execute(const char *sql); 24 | bool StartTransaction(); 25 | //修改为:当返回值0的时候,是ROLLBACK,1--COMMIT 26 | bool EndTransaction(); 27 | 28 | 29 | 30 | char *GetField(const char *fieldname);//根据列的名字查找当前行,得到该列的值 31 | char *GetField(int filednum);//根据列的序号查找当前行,得到该列的值 32 | char **FetchRow();//拿出一行结果 33 | 34 | private: 35 | bool ReConnect(); 36 | void FreeResult();//释放上一次查询的结果 37 | 38 | private: 39 | 40 | bool isConnected;//判断是否连接 41 | bool bCommit;//当用到事务时,该值用来选择是commit还是rollback 42 | int fieldcnt;//查询结果有几列 43 | map mapFiledToIndex;//查询结果列名字到序号的映射:id->0; name->1 44 | 45 | MYSQL sql_conn;//数据库连接 46 | MYSQL_RES *sql_result;//查询结果 47 | MYSQL_ROW sql_row;//结果中的当前行,FetchRow(); 48 | 49 | //保存连接信息,保证重连 50 | string hostip_; 51 | string username_; 52 | string password_; 53 | 54 | }; 55 | 56 | #endif 57 | -------------------------------------------------------------------------------- /src/mysql_encap.h: -------------------------------------------------------------------------------- 1 | #ifndef MYSQL_ENCAP_H_ 2 | #define MYSQL_ENCAP_H_ 3 | 4 | #include 5 | #include 6 | #include 7 | #include 8 | 9 | using namespace std; 10 | 11 | class MysqlEncap{ 12 | 13 | public: 14 | MysqlEncap(); 15 | ~MysqlEncap(); 16 | 17 | bool Connect(const char *ip, const char *username, const 18 | char *password); 19 | void CloseConnect(); 20 | 21 | 22 | bool ExecuteQuery(const char *sql); 23 | bool Execute(const char *sql); 24 | bool StartTransaction(); 25 | //修改为:当返回值0的时候,是ROLLBACK,1--COMMIT 26 | bool EndTransaction(); 27 | 28 | //return the query result count, that is, how many rows 29 | int GetQueryResultCount(); 30 | 31 | char *GetField(const char *fieldname);//根据列的名字查找当前行,得到该列的值 32 | char *GetField(int filednum);//根据列的序号查找当前行,得到该列的值 33 | char **FetchRow();//拿出一行结果 34 | 35 | private: 36 | bool ReConnect(); 37 | void FreeResult();//释放上一次查询的结果 38 | 39 | private: 40 | 41 | bool isConnected;//判断是否连接 42 | bool bCommit;//当用到事务时,该值用来选择是commit还是rollback 43 | int fieldcnt;//查询结果有几列, column not rows 44 | map mapFiledToIndex;//查询结果列名字到序号的映射:id->0; name->1 45 | 46 | MYSQL sql_conn;//数据库连接 47 | MYSQL_RES *sql_result;//查询结果 48 | MYSQL_ROW sql_row;//结果中的当前行,FetchRow(); 49 | 50 | //保存连接信息,保证重连 51 | string hostip_; 52 | string username_; 53 | string password_; 54 | 55 | }; 56 | 57 | #endif 58 | -------------------------------------------------------------------------------- /mysql-encap/mysql_encap.h: -------------------------------------------------------------------------------- 1 | #ifndef MYSQL_ENCAP_H_ 2 | #define MYSQL_ENCAP_H_ 3 | 4 | #include 5 | #include 6 | #include 7 | #include 8 | 9 | using namespace std; 10 | 11 | class MysqlEncap{ 12 | 13 | public: 14 | MysqlEncap(); 15 | ~MysqlEncap(); 16 | 17 | bool Connect(const char *ip, const char *username, const 18 | char *password); 19 | void CloseConnect(); 20 | 21 | 22 | bool ExecuteQuery(const char *sql); 23 | bool Execute(const char *sql); 24 | bool StartTransaction(); 25 | //修改为:当返回值0的时候,是ROLLBACK,1--COMMIT 26 | bool EndTransaction(); 27 | 28 | //return the query result count, that is, how many rows 29 | int GetQueryResultCount(); 30 | 31 | char *GetField(const char *fieldname);//根据列的名字查找当前行,得到该列的值 32 | char *GetField(int filednum);//根据列的序号查找当前行,得到该列的值 33 | char **FetchRow();//拿出一行结果 34 | 35 | private: 36 | bool ReConnect(); 37 | void FreeResult();//释放上一次查询的结果 38 | 39 | private: 40 | 41 | bool isConnected;//判断是否连接 42 | bool bCommit;//当用到事务时,该值用来选择是commit还是rollback 43 | int fieldcnt;//查询结果有几列, column not rows 44 | map mapFiledToIndex;//查询结果列名字到序号的映射:id->0; name->1 45 | 46 | MYSQL sql_conn;//数据库连接 47 | MYSQL_RES *sql_result;//查询结果 48 | MYSQL_ROW sql_row;//结果中的当前行,FetchRow(); 49 | 50 | //保存连接信息,保证重连 51 | string hostip_; 52 | string username_; 53 | string password_; 54 | 55 | }; 56 | 57 | #endif 58 | -------------------------------------------------------------------------------- /mysql-encap/testConnPool.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | *测试连接池类ConnPool: 3 | *g++ -g -Wall -lmysqlclient -lpthread mysql_encap.cpp mysql_encap.h conn_pool.cpp conn_pool.h testConnPool.cpp -o testConnPool 4 | */ 5 | 6 | #include "conn_pool.h" 7 | #include 8 | #include "mysql_encap.h" 9 | #include 10 | #include 11 | #include 12 | #include 13 | using namespace std; 14 | 15 | ConnPool* conn_pool = ConnPool::GetInstance(); 16 | 17 | void *run(void *arg){ 18 | while(true){ 19 | MysqlEncap *sql_conn = conn_pool->GetOneConn(); 20 | // sql_conn->ExecuteQuery("select * from testdb.student;"); 21 | // 22 | // while(sql_conn->FetchRow()){ 23 | // printf("%s,%s\n",sql_conn->GetField("sid"),sql_conn->GetField("name")); 24 | // } 25 | 26 | conn_pool->ShowStatus(); 27 | sleep(rand()%3); 28 | conn_pool->ReleaseOneConn(sql_conn); 29 | 30 | conn_pool->ShowStatus(); 31 | } 32 | return NULL; 33 | } 34 | 35 | int main(){ 36 | srand(time(0)); 37 | freopen("out.txt","w",stdout); 38 | pthread_t tid1; 39 | pthread_t tid2; 40 | pthread_t tid3; 41 | pthread_t tid4; 42 | int ret; 43 | ret = pthread_create(&tid1, NULL, run, (void *)1); 44 | ret = pthread_create(&tid2, NULL, run, (void *)2); 45 | ret = pthread_create(&tid3, NULL, run, (void *)3); 46 | ret = pthread_create(&tid4, NULL, run, (void *)4); 47 | 48 | 49 | pthread_join(tid1, NULL); 50 | pthread_join(tid2, NULL); 51 | 52 | return 0; 53 | } 54 | -------------------------------------------------------------------------------- /sql_table/tables: -------------------------------------------------------------------------------- 1 | create table repository (id int auto_increment primary key, name varchar(256) not null); 2 | ---------------------------------------------------- 3 | insert into repository values(NULL, 'test1'); 4 | insert into repository values(NULL, 'test2'); 5 | select * from repository; 6 | select id from repository where name = 'test2'; 7 | ------------------------------------------------------ 8 | 9 | create table item ( itemId int auto_increment primary key, version int not null, sha1 char(41) not null, path varchar(256) not null, m_time bigint); 10 | 11 | ---------------------------------------------------- 12 | insert into item values(NULL, 1, 'flafsdakfjsiahfuishdiuf', 'test.c', 12321847); 13 | 14 | select * from item where itemId = 1; 15 | ------------------------------------------------------ 16 | 17 | create table history ( historyId int auto_increment primary key, itemId int not null, version int not null, sha1 char(41) not null, path varchar(256) not null, m_time bigint, user varchar(20) not null, action int not null, commitGroup int not null); 18 | 19 | create table tag(tagId int auto_increment primary key, tagName char(40) not null, itemId int not null, version int not null); 20 | insert into testdb.tag values(NULL, '%s', %s, %s); 21 | insert into testdb.tag values(NULL, 'testTag', 90, 2); 22 | 23 | alter table testdb.tag add column path varchar(256) not null after itemId; 24 | 25 | alter table t1 add column addr varchar(20) not null after user1; 26 | 27 | 28 | -------------------------------------------------------------------------------- /commitlog/pending.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | typedef struct { 6 | int action; 7 | long time; 8 | char sha1[41]; 9 | char path[218]; 10 | }record; 11 | 12 | int writePending(int action, char *sha1, char *path) { 13 | FILE *fp = fopen("pending", "a+"); 14 | if(fp == NULL) { 15 | fprintf(stderr, "open pending file error\n"); 16 | return -1; 17 | } 18 | record r; 19 | r.action = action; 20 | r.time = time(NULL); 21 | strcpy(r.sha1, sha1); 22 | strcpy(r.path, path); 23 | fwrite(&r, sizeof(r), 1, fp); 24 | 25 | fclose(fp); 26 | return 0; 27 | } 28 | 29 | int readPending() { 30 | FILE *fp = fopen("pending", "r"); 31 | if(fp == NULL) { 32 | printf("open file pending error\n"); 33 | return -1; 34 | } 35 | while(1) { 36 | record r; 37 | fread(&r, sizeof(r), 1, fp); 38 | if (feof(fp)) break; 39 | printf("-%d-, -%ld-, -%s-, -%s-\n", r.action, r.time, r.sha1, r.path); 40 | } 41 | fclose(fp); 42 | return 0; 43 | } 44 | 45 | int resetPending() { 46 | FILE *fp = fopen("pending", "w"); 47 | if(fp == NULL) { 48 | printf("open file pending error\n"); 49 | return -1; 50 | } 51 | fclose(fp); 52 | return 0; 53 | } 54 | 55 | int main() { 56 | printf("*****************write**************************\n"); 57 | writePending(1, "xxooxxooxx111", "woshi_1"); 58 | writePending(0, "xxooxxooxx222", "woshi_2"); 59 | printf("*****************read***************************\n"); 60 | readPending(); 61 | printf("*****************reset**************************\n"); 62 | resetPending(); 63 | printf("************************************************\n"); 64 | 65 | return 0; 66 | } 67 | -------------------------------------------------------------------------------- /source-code-manager(开源的代码)/inc/sha.h: -------------------------------------------------------------------------------- 1 | /** 2 | * file sha1.h 3 | * 4 | * Copyright (C) 2006-2010, Brainspark B.V. 5 | * 6 | * This file is part of PolarSSL (http://www.polarssl.org) 7 | * Lead Maintainer: Paul Bakker 8 | * 9 | * All rights reserved. 10 | * 11 | * This program is free software; you can redistribute it and/or modify 12 | * it under the terms of the GNU General Public License as published by 13 | * the Free Software Foundation; either version 2 of the License, or 14 | * (at your option) any later version. 15 | * 16 | * This program is distributed in the hope that it will be useful, 17 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 18 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 19 | * GNU General Public License for more details. 20 | * 21 | * You should have received a copy of the GNU General Public License along 22 | * with this program; if not, write to the Free Software Foundation, Inc., 23 | * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 24 | */ 25 | #ifndef POLARSSL_SHA1_H 26 | #define POLARSSL_SHA1_H 27 | 28 | 29 | /*20 bytes for sha so 40 bytes to put it in hex and one byte for NULL 30 | * A SHA is valid only if it ends with a NULL char*/ 31 | #define SHA_HASH_LENGTH 40 32 | typedef unsigned char ShaBuffer[SHA_HASH_LENGTH+1]; 33 | 34 | bool sha_buffer(const unsigned char *input, int ilen, ShaBuffer sha); 35 | bool sha_file(const char *path, ShaBuffer sha); 36 | bool sha_compare(const ShaBuffer s1, const ShaBuffer s2); 37 | inline void sha_reset(ShaBuffer sha); 38 | #endif /* sha1.h */ 39 | -------------------------------------------------------------------------------- /sha1.h: -------------------------------------------------------------------------------- 1 | /** 2 | * file sha1.h 3 | * 4 | * Copyright (C) 2006-2010, Brainspark B.V. 5 | * 6 | * This file is part of PolarSSL (http://www.polarssl.org) 7 | * Lead Maintainer: Paul Bakker 8 | * 9 | * All rights reserved. 10 | * 11 | * This program is free software; you can redistribute it and/or modify 12 | * it under the terms of the GNU General Public License as published by 13 | * the Free Software Foundation; either version 2 of the License, or 14 | * (at your option) any later version. 15 | * 16 | * This program is distributed in the hope that it will be useful, 17 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 18 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 19 | * GNU General Public License for more details. 20 | * 21 | * You should have received a copy of the GNU General Public License along 22 | * with this program; if not, write to the Free Software Foundation, Inc., 23 | * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 24 | */ 25 | #ifndef POLARSSL_SHA1_H 26 | #define POLARSSL_SHA1_H 27 | 28 | #ifndef __cplusplus 29 | typedef enum{ 30 | false = 0, 31 | true = 1 32 | }bool; 33 | #endif 34 | 35 | /*20 bytes for sha so 40 bytes to put it in hex and one byte for NULL 36 | * A SHA is valid only if it ends with a NULL char*/ 37 | #define SHA_HASH_LENGTH 40 38 | typedef unsigned char ShaBuffer[SHA_HASH_LENGTH+1]; 39 | 40 | bool sha_buffer(const unsigned char *input, int ilen, ShaBuffer sha); 41 | bool sha_file(const char *path, ShaBuffer sha); 42 | bool sha_compare(const ShaBuffer s1, const ShaBuffer s2); 43 | inline void sha_reset(ShaBuffer sha); 44 | #endif /* sha1.h */ 45 | -------------------------------------------------------------------------------- /SHA1/sha1.h: -------------------------------------------------------------------------------- 1 | /** 2 | * file sha1.h 3 | * 4 | * Copyright (C) 2006-2010, Brainspark B.V. 5 | * 6 | * This file is part of PolarSSL (http://www.polarssl.org) 7 | * Lead Maintainer: Paul Bakker 8 | * 9 | * All rights reserved. 10 | * 11 | * This program is free software; you can redistribute it and/or modify 12 | * it under the terms of the GNU General Public License as published by 13 | * the Free Software Foundation; either version 2 of the License, or 14 | * (at your option) any later version. 15 | * 16 | * This program is distributed in the hope that it will be useful, 17 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 18 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 19 | * GNU General Public License for more details. 20 | * 21 | * You should have received a copy of the GNU General Public License along 22 | * with this program; if not, write to the Free Software Foundation, Inc., 23 | * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 24 | */ 25 | #ifndef POLARSSL_SHA1_H 26 | #define POLARSSL_SHA1_H 27 | 28 | #ifndef __cplusplus 29 | typedef enum{ 30 | false = 0, 31 | true = 1 32 | }bool; 33 | #endif 34 | 35 | /*20 bytes for sha so 40 bytes to put it in hex and one byte for NULL 36 | * A SHA is valid only if it ends with a NULL char*/ 37 | #define SHA_HASH_LENGTH 40 38 | typedef unsigned char ShaBuffer[SHA_HASH_LENGTH+1]; 39 | 40 | bool sha_buffer(const unsigned char *input, int ilen, ShaBuffer sha); 41 | bool sha_file(const char *path, ShaBuffer sha); 42 | bool sha_compare(const ShaBuffer s1, const ShaBuffer s2); 43 | inline void sha_reset(ShaBuffer sha); 44 | #endif /* sha1.h */ 45 | -------------------------------------------------------------------------------- /src/sha1.h: -------------------------------------------------------------------------------- 1 | /** 2 | * file sha1.h 3 | * 4 | * Copyright (C) 2006-2010, Brainspark B.V. 5 | * 6 | * This file is part of PolarSSL (http://www.polarssl.org) 7 | * Lead Maintainer: Paul Bakker 8 | * 9 | * All rights reserved. 10 | * 11 | * This program is free software; you can redistribute it and/or modify 12 | * it under the terms of the GNU General Public License as published by 13 | * the Free Software Foundation; either version 2 of the License, or 14 | * (at your option) any later version. 15 | * 16 | * This program is distributed in the hope that it will be useful, 17 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 18 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 19 | * GNU General Public License for more details. 20 | * 21 | * You should have received a copy of the GNU General Public License along 22 | * with this program; if not, write to the Free Software Foundation, Inc., 23 | * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 24 | */ 25 | #ifndef POLARSSL_SHA1_H 26 | #define POLARSSL_SHA1_H 27 | 28 | #ifndef __cplusplus 29 | typedef enum{ 30 | false = 0, 31 | true = 1 32 | }bool; 33 | #endif 34 | 35 | /*20 bytes for sha so 40 bytes to put it in hex and one byte for NULL 36 | * A SHA is valid only if it ends with a NULL char*/ 37 | #define SHA_HASH_LENGTH 40 38 | typedef unsigned char ShaBuffer[SHA_HASH_LENGTH+1]; 39 | 40 | bool sha_buffer(const unsigned char *input, int ilen, ShaBuffer sha); 41 | bool sha_file(const char *path, ShaBuffer sha); 42 | bool sha_compare(const ShaBuffer s1, const ShaBuffer s2); 43 | inline void sha_reset(ShaBuffer sha); 44 | #endif /* sha1.h */ 45 | -------------------------------------------------------------------------------- /src2/sha1.h: -------------------------------------------------------------------------------- 1 | /** 2 | * file sha1.h 3 | * 4 | * Copyright (C) 2006-2010, Brainspark B.V. 5 | * 6 | * This file is part of PolarSSL (http://www.polarssl.org) 7 | * Lead Maintainer: Paul Bakker 8 | * 9 | * All rights reserved. 10 | * 11 | * This program is free software; you can redistribute it and/or modify 12 | * it under the terms of the GNU General Public License as published by 13 | * the Free Software Foundation; either version 2 of the License, or 14 | * (at your option) any later version. 15 | * 16 | * This program is distributed in the hope that it will be useful, 17 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 18 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 19 | * GNU General Public License for more details. 20 | * 21 | * You should have received a copy of the GNU General Public License along 22 | * with this program; if not, write to the Free Software Foundation, Inc., 23 | * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 24 | */ 25 | #ifndef POLARSSL_SHA1_H 26 | #define POLARSSL_SHA1_H 27 | 28 | #ifndef __cplusplus 29 | typedef enum{ 30 | false = 0, 31 | true = 1 32 | }bool; 33 | #endif 34 | 35 | /*20 bytes for sha so 40 bytes to put it in hex and one byte for NULL 36 | * A SHA is valid only if it ends with a NULL char*/ 37 | #define SHA_HASH_LENGTH 40 38 | typedef unsigned char ShaBuffer[SHA_HASH_LENGTH+1]; 39 | 40 | bool sha_buffer(const unsigned char *input, int ilen, ShaBuffer sha); 41 | bool sha_file(const char *path, ShaBuffer sha); 42 | bool sha_compare(const ShaBuffer s1, const ShaBuffer s2); 43 | inline void sha_reset(ShaBuffer sha); 44 | #endif /* sha1.h */ 45 | -------------------------------------------------------------------------------- /source-code-manager(开源的代码)/main.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include "cmds.h" 4 | #include "sha.h" 5 | #include "filelist.h" 6 | 7 | typedef int (*command_fn)(int argc, char *argv[]); 8 | struct commands 9 | { 10 | char commandName[16]; 11 | command_fn function; 12 | char *helpmsg; 13 | }; 14 | 15 | 16 | int main(int argc, char *argv[]) 17 | { 18 | struct commands cmds[] = { {"sha", cmd_sha , "compute hash of the files"}, 19 | {"version", cmd_version , "display version "}, 20 | {"init", cmd_init , "intialize the repo"}, 21 | {"branch", cmd_branch , "displays the current branch"}, 22 | {"status", cmd_status , "show's current status wrt to index file"}, 23 | {"add", cmd_add , "adds file's or folders into the index file"}, 24 | {"ls", cmd_ls , "prints the file's"}, 25 | {"commit", cmd_commit , "commits the current changes into repo"}, 26 | {"info", cmd_info , "prints information about a commit"}, 27 | {"rm", cmd_rm , "remove file from list"}, 28 | {"checkout", cmd_checkout , "checkout a file/folder or a commit"}, 29 | }; 30 | const int commands_len = sizeof(cmds)/sizeof(*cmds); 31 | 32 | int i, returnValue = 1; 33 | 34 | if(1 == argc) 35 | { 36 | LOG_INFO("Currently supported commands\n"); 37 | for(i = 0; i < commands_len; i++) 38 | { 39 | LOG_INFO(" %-16s %s", cmds[i].commandName, cmds[i].helpmsg); 40 | } 41 | return 0; 42 | } 43 | for(i = 0; i < commands_len; i++) 44 | { 45 | if(0 == strcmp(cmds[i].commandName, argv[1])) 46 | { 47 | returnValue = cmds[i].function(argc, argv); 48 | break; 49 | } 50 | } 51 | if(i == commands_len) 52 | { 53 | LOG_ERROR("command '%s' not found, to see list of commands run '%s' without arguments", argv[1], argv[0]); 54 | } 55 | return returnValue; 56 | } 57 | -------------------------------------------------------------------------------- /mysql-encap/README: -------------------------------------------------------------------------------- 1 | 2 | *******************************【MysqlEncap】************************************ 3 | 4 | 简介:该类 MysqlEncap 封装了Mysql数据库操作的接口api, 提供了更加方便的数据库操作 5 | 使用: 6 | 1. MysqlEncap *conn = new MysqlEncap;//新建一个类对象指针 7 | 2. conn->Connect("ip","username", "password");//建立连接 8 | 9 | 3. sql 查询语句:[select] 10 | conn->ExecuteQuery("select * from testdb.student;"); 11 | 4. sql 修改语句:[use, delete, insert, update...] 12 | conn->Execute("update testdb.student set name = 'chengshuguang' where name = 'testapi';"); 13 | 14 | 5. 事务Transaction:(EndTransaction()会根据执行结果自动选择commit或者rollback) 15 | * conn->StartTransaction(); 16 | * ... 17 | * do something... 18 | * .... 19 | * conn->EndTransaction();//修改为:当返回值0的时候,是ROLLBACK,1--COMMIT 20 | 21 | 6. 查询结果的输出: 22 | * while(conn->FetchRow()){ 23 | printf("%s,%s\n",conn->GetField("sid"),conn->GetField("name")); 24 | } 25 | 其中conn->GetField("sid")还可以是conn->GetField(0),用结果的顺序号表示 26 | * while(char **r = conn->FetchRow()){ 27 | printf("%s,%s\n", r[0], r[1]); 28 | } 29 | 7. 关闭一个连接 30 | conn->CloseConnect(); 31 | 32 | ********************************【ConnPool】************************************* 33 | 简介: 该类实现了一个连接池,其中利用到封装好的mutex[lock.h] 和 封装的MysqlEncap类 34 | 使用: 35 | 1. ConnPool* conn_pool = ConnPool::GetInstance();//得到一个连接池对象,singleton 模式 36 | 2. MysqlEncap *sql_conn = conn_pool->GetOneConn();//从连接池中获得一条连接 37 | 3. conn_pool->ReleaseOneConn(sql_conn);//归还连接到连接池中 38 | 4. conn_pool->ShowStatus();//查看目前连接池的状态信息 39 | 40 | 初始化连接池的信息:【conn_pool.h】文件中配置 41 | #define HOST "localhost" 42 | #define USERNAME "root" 43 | #define PASSWORD "110315" 44 | 45 | #define MAX_CONNPOOL_SIZE 3 46 | #define INIT_CONNPOOL_SIZE 1 47 | //test 48 | g++ -g -Wall -lmysqlclient -lpthread mysql_encap.cpp mysql_encap.h conn_pool.cpp conn_pool.h testConnPool.cpp -o testConnPool 49 | 50 | 51 | 52 | -------------------------------------------------------------------------------- /sql_table/get: -------------------------------------------------------------------------------- 1 | //get subfolder and files 2 | select itemId, max(version)version from history where pItemId = 73 and historyId < 2111 group by itemId; 3 | 4 | 得到itemId之后,怎么拿,传文件,这个还是要文件的路径名,所以现在的历史表中是没有存在文件名,所以需要item表,刚好直接在select 5 | //folder and by latest version 6 | select historyId, itemId, pItemId, max(version) from testdb.history where pItemId = 73 group by itemId; 7 | 8 | //folder and by history version 9 | select t1.itemId, t1.path, t2.version from item t1 10 | inner join 11 | (select itemId, max(version)version from history where pItemId = 73 and historyId < 2111 group by itemId)t2 12 | on t1.itemId = t2.itemId; 13 | 14 | ================== Folder ========================================================================= 15 | // 16 | i use the sha1 to differentiate folder and file 17 | // 18 | by latest version 19 | { 20 | //getSubFile 21 | //select path, max(version)version from testdb.history where pItemId = 73 and sha1 != '0' group by itemId; 22 | select path, version from testdb.item where pItemId = 73 and sha1 != '0'; 23 | 24 | //getSubFolder 25 | //select path, max(version)version from testdb.history where pItemId = 73 and sha1 ='0' group by itemId 26 | select path from testdb.item where pItemId = 73 and sha1 = '0'; 27 | 28 | finally, recursively... 29 | } 30 | 31 | by history version 32 | { 33 | //get history id, itemId(as pItemId below) 34 | select historyId, itemId from testdb.history where path = 'folder1' and version = 7; 35 | 36 | 37 | //getSubFile 38 | select path, max(version)version from testdb.history where pItemId = 73 and historyId < 2109 and sha1 != '0' group by itemId; 39 | 40 | attention: the historyId will not change, it is always the init folder's historyId; have nothing to do with the subfolder 41 | //getSubFolder 42 | select itemId, path, max(version)version from testdb.history where pItemId = 73 and historyId < 2109 and sha1 = '0' group by itemId; 43 | 44 | 45 | finally, recursively... 46 | } 47 | 48 | 现在得到了itemId, 路径名 和版本信息,,其实我们只需要path::version 组成数组 49 | -------------------------------------------------------------------------------- /testStringLinkedList/filePathLinkedlist.h: -------------------------------------------------------------------------------- 1 | /* 2 | * this file define a linked list to save the path::version string array; 3 | * it may be very easy to implement this class in C++, but i want a C style one 4 | */ 5 | 6 | #include 7 | #include 8 | #include 9 | 10 | //#include 11 | 12 | typedef struct FilePathListNode_ { 13 | char filename[256]; 14 | char sha1[41]; 15 | time_t m_time; 16 | struct FilePathListNode_ *next; 17 | }FilePathListNode; 18 | 19 | typedef struct { 20 | FilePathListNode *head; 21 | FilePathListNode *tail; 22 | int size; 23 | }FilePathList; 24 | 25 | void init(FilePathList *list) { 26 | list->head = list->tail = NULL; 27 | list->size = 0; 28 | } 29 | 30 | void push_back(FilePathList *list, FilePathListNode *node) { 31 | if(list->head == NULL) { 32 | list->head = node; 33 | list->tail = node; 34 | } else { 35 | list->tail = list->tail->next = node; 36 | } 37 | list->size++; 38 | } 39 | 40 | 41 | /* 42 | * aim: if isFile, push path::version to the file list 43 | * else if idDir, push path to the file list 44 | */ 45 | void push_to_list(FilePathList *filelist, char *path, char *version,\ 46 | char *sha1, time_t m_time, int isDir) { 47 | FilePathListNode * newpath = (FilePathListNode *)malloc(sizeof(FilePathListNode)); 48 | if(!isDir) { 49 | sprintf(newpath->filename, "%s::%s", path, version); 50 | sprintf(newpath->sha1, "%s", sha1); 51 | newpath->m_time = m_time; 52 | newpath->next = NULL; 53 | push_back(filelist, newpath); 54 | } else { 55 | sprintf(newpath->filename, "%s", path); 56 | newpath->next = NULL; 57 | push_back(filelist, newpath); 58 | } 59 | 60 | } 61 | 62 | void unit_test(FilePathList *list) { 63 | if(list->size == 0) 64 | return; 65 | printf("list size: %d\n", list->size); 66 | FilePathListNode *tmp = list->head; 67 | while(tmp != list->tail) { 68 | printf("%s--%s--%ld\n", tmp->filename, tmp->sha1, tmp->m_time); 69 | tmp = tmp->next; 70 | } 71 | printf("%s--%s--%ld\n", tmp->filename, tmp->sha1, tmp->m_time); 72 | } 73 | -------------------------------------------------------------------------------- /lock.h: -------------------------------------------------------------------------------- 1 | /************************************************** 2 | * 该类主要是对mutex进行了RAII封装,以后还会封装condition, 3 | * 目的当然是为了便于编程使用啊 4 | * 用法: 5 | * MutexLock mutex;//定义一个mutex 6 | * 7 | * void foo(){ 8 | ... 9 | * MutexGuard lock(mutex); 10 | * ... 11 | * do something... 12 | * ... 13 | * } 14 | * lock 只在它的作用域内有效 15 | **************************************************/ 16 | 17 | #ifndef LOCK_H_ 18 | #define LOCK_H_ 19 | 20 | #include 21 | 22 | /************************************************ 23 | * mutex api的简单封装 24 | *************************************************/ 25 | class MutexLock{ 26 | public: 27 | MutexLock(){ 28 | pthread_mutex_init(&mutex_, NULL); 29 | } 30 | ~MutexLock(){ 31 | pthread_mutex_destroy(&mutex_); 32 | } 33 | 34 | void Lock(){ 35 | pthread_mutex_lock(&mutex_); 36 | } 37 | void UnLock(){ 38 | pthread_mutex_unlock(&mutex_); 39 | } 40 | 41 | private: 42 | pthread_mutex_t mutex_; 43 | 44 | private: 45 | //禁止copy 46 | MutexLock(const MutexLock &); 47 | MutexLock &operator=(const MutexLock &); 48 | }; 49 | 50 | /************************************************ 51 | * 只是简单的对mutex做RAII封装 52 | * use: 53 | * void foo(){ 54 | * MutexGuard lock(mutex); 55 | * ... 56 | * do something... 57 | * ... 58 | * } 59 | *************************************************/ 60 | class MutexGuard{ 61 | public: 62 | //explicit 防止隐式转换 63 | explicit MutexGuard(MutexLock &mutex):mutex_(mutex){//引用只能用 64 | //mutex_ = mutex; 65 | mutex_.Lock(); 66 | } 67 | ~MutexGuard(){ 68 | mutex_.UnLock(); 69 | } 70 | private: 71 | MutexLock &mutex_;//由于mutexLock不允许拷贝,所以用引用 72 | 73 | private: 74 | //禁止copy 75 | MutexGuard(const MutexGuard &); 76 | MutexGuard &operator=(const MutexGuard &); 77 | }; 78 | // 见陈硕的muduo网络库实现 79 | #define MutexGuard(x) do{\ 80 | fprintf(stderr, "Error:line:%d, function:%s(), file:%s\nthis should be used like this:\nMutexGuard lock(your_mutex);\n",\ 81 | __LINE__, __FUNCTION__, __FILE__);\ 82 | }while(0); 83 | 84 | #endif 85 | -------------------------------------------------------------------------------- /src/lock.h: -------------------------------------------------------------------------------- 1 | /************************************************** 2 | * 该类主要是对mutex进行了RAII封装,以后还会封装condition, 3 | * 目的当然是为了便于编程使用啊 4 | * 用法: 5 | * MutexLock mutex;//定义一个mutex 6 | * 7 | * void foo(){ 8 | ... 9 | * MutexGuard lock(mutex); 10 | * ... 11 | * do something... 12 | * ... 13 | * } 14 | * lock 只在它的作用域内有效 15 | **************************************************/ 16 | 17 | #ifndef LOCK_H_ 18 | #define LOCK_H_ 19 | 20 | #include 21 | 22 | /************************************************ 23 | * mutex api的简单封装 24 | *************************************************/ 25 | class MutexLock{ 26 | public: 27 | MutexLock(){ 28 | pthread_mutex_init(&mutex_, NULL); 29 | } 30 | ~MutexLock(){ 31 | pthread_mutex_destroy(&mutex_); 32 | } 33 | 34 | void Lock(){ 35 | pthread_mutex_lock(&mutex_); 36 | } 37 | void UnLock(){ 38 | pthread_mutex_unlock(&mutex_); 39 | } 40 | 41 | private: 42 | pthread_mutex_t mutex_; 43 | 44 | private: 45 | //禁止copy 46 | MutexLock(const MutexLock &); 47 | MutexLock &operator=(const MutexLock &); 48 | }; 49 | 50 | /************************************************ 51 | * 只是简单的对mutex做RAII封装 52 | * use: 53 | * void foo(){ 54 | * MutexGuard lock(mutex); 55 | * ... 56 | * do something... 57 | * ... 58 | * } 59 | *************************************************/ 60 | class MutexGuard{ 61 | public: 62 | //explicit 防止隐式转换 63 | explicit MutexGuard(MutexLock &mutex):mutex_(mutex){//引用只能用 64 | //mutex_ = mutex; 65 | mutex_.Lock(); 66 | } 67 | ~MutexGuard(){ 68 | mutex_.UnLock(); 69 | } 70 | private: 71 | MutexLock &mutex_;//由于mutexLock不允许拷贝,所以用引用 72 | 73 | private: 74 | //禁止copy 75 | MutexGuard(const MutexGuard &); 76 | MutexGuard &operator=(const MutexGuard &); 77 | }; 78 | // 见陈硕的muduo网络库实现 79 | #define MutexGuard(x) do{\ 80 | fprintf(stderr, "Error:line:%d, function:%s(), file:%s\nthis should be used like this:\nMutexGuard lock(your_mutex);\n",\ 81 | __LINE__, __FUNCTION__, __FILE__);\ 82 | }while(0); 83 | 84 | #endif 85 | -------------------------------------------------------------------------------- /src2/lock.h: -------------------------------------------------------------------------------- 1 | /************************************************** 2 | * 该类主要是对mutex进行了RAII封装,以后还会封装condition, 3 | * 目的当然是为了便于编程使用啊 4 | * 用法: 5 | * MutexLock mutex;//定义一个mutex 6 | * 7 | * void foo(){ 8 | ... 9 | * MutexGuard lock(mutex); 10 | * ... 11 | * do something... 12 | * ... 13 | * } 14 | * lock 只在它的作用域内有效 15 | **************************************************/ 16 | 17 | #ifndef LOCK_H_ 18 | #define LOCK_H_ 19 | 20 | #include 21 | 22 | /************************************************ 23 | * mutex api的简单封装 24 | *************************************************/ 25 | class MutexLock{ 26 | public: 27 | MutexLock(){ 28 | pthread_mutex_init(&mutex_, NULL); 29 | } 30 | ~MutexLock(){ 31 | pthread_mutex_destroy(&mutex_); 32 | } 33 | 34 | void Lock(){ 35 | pthread_mutex_lock(&mutex_); 36 | } 37 | void UnLock(){ 38 | pthread_mutex_unlock(&mutex_); 39 | } 40 | 41 | private: 42 | pthread_mutex_t mutex_; 43 | 44 | private: 45 | //禁止copy 46 | MutexLock(const MutexLock &); 47 | MutexLock &operator=(const MutexLock &); 48 | }; 49 | 50 | /************************************************ 51 | * 只是简单的对mutex做RAII封装 52 | * use: 53 | * void foo(){ 54 | * MutexGuard lock(mutex); 55 | * ... 56 | * do something... 57 | * ... 58 | * } 59 | *************************************************/ 60 | class MutexGuard{ 61 | public: 62 | //explicit 防止隐式转换 63 | explicit MutexGuard(MutexLock &mutex):mutex_(mutex){//引用只能用 64 | //mutex_ = mutex; 65 | mutex_.Lock(); 66 | } 67 | ~MutexGuard(){ 68 | mutex_.UnLock(); 69 | } 70 | private: 71 | MutexLock &mutex_;//由于mutexLock不允许拷贝,所以用引用 72 | 73 | private: 74 | //禁止copy 75 | MutexGuard(const MutexGuard &); 76 | MutexGuard &operator=(const MutexGuard &); 77 | }; 78 | // 见陈硕的muduo网络库实现 79 | #define MutexGuard(x) do{\ 80 | fprintf(stderr, "Error:line:%d, function:%s(), file:%s\nthis should be used like this:\nMutexGuard lock(your_mutex);\n",\ 81 | __LINE__, __FUNCTION__, __FILE__);\ 82 | }while(0); 83 | 84 | #endif 85 | -------------------------------------------------------------------------------- /mysql-encap/lock.h: -------------------------------------------------------------------------------- 1 | /************************************************** 2 | * 该类主要是对mutex进行了RAII封装,以后还会封装condition, 3 | * 目的当然是为了便于编程使用啊 4 | * 用法: 5 | * MutexLock mutex;//定义一个mutex 6 | * 7 | * void foo(){ 8 | ... 9 | * MutexGuard lock(mutex); 10 | * ... 11 | * do something... 12 | * ... 13 | * } 14 | * lock 只在它的作用域内有效 15 | **************************************************/ 16 | 17 | #ifndef LOCK_H_ 18 | #define LOCK_H_ 19 | 20 | #include 21 | 22 | /************************************************ 23 | * mutex api的简单封装 24 | *************************************************/ 25 | class MutexLock{ 26 | public: 27 | MutexLock(){ 28 | pthread_mutex_init(&mutex_, NULL); 29 | } 30 | ~MutexLock(){ 31 | pthread_mutex_destroy(&mutex_); 32 | } 33 | 34 | void Lock(){ 35 | pthread_mutex_lock(&mutex_); 36 | } 37 | void UnLock(){ 38 | pthread_mutex_unlock(&mutex_); 39 | } 40 | 41 | private: 42 | pthread_mutex_t mutex_; 43 | 44 | private: 45 | //禁止copy 46 | MutexLock(const MutexLock &); 47 | MutexLock &operator=(const MutexLock &); 48 | }; 49 | 50 | /************************************************ 51 | * 只是简单的对mutex做RAII封装 52 | * use: 53 | * void foo(){ 54 | * MutexGuard lock(mutex); 55 | * ... 56 | * do something... 57 | * ... 58 | * } 59 | *************************************************/ 60 | class MutexGuard{ 61 | public: 62 | //explicit 防止隐式转换 63 | explicit MutexGuard(MutexLock &mutex):mutex_(mutex){//引用只能用 64 | //mutex_ = mutex; 65 | mutex_.Lock(); 66 | } 67 | ~MutexGuard(){ 68 | mutex_.UnLock(); 69 | } 70 | private: 71 | MutexLock &mutex_;//由于mutexLock不允许拷贝,所以用引用 72 | 73 | private: 74 | //禁止copy 75 | MutexGuard(const MutexGuard &); 76 | MutexGuard &operator=(const MutexGuard &); 77 | }; 78 | // 见陈硕的muduo网络库实现 79 | #define MutexGuard(x) do{\ 80 | fprintf(stderr, "Error:line:%d, function:%s(), file:%s\nthis should be used like this:\nMutexGuard lock(your_mutex);\n",\ 81 | __LINE__, __FUNCTION__, __FILE__);\ 82 | }while(0); 83 | 84 | #endif 85 | -------------------------------------------------------------------------------- /testGetRealPath/test_get_real_path.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | 8 | 9 | void getParent(char *parent, const char *fullpath); 10 | 11 | int main() 12 | { 13 | char path [256]; 14 | char realpath[256]; 15 | scanf("%s",path); 16 | 17 | char pwd[256]; 18 | getcwd(pwd, 256); 19 | printf("-----------pwd:%s\n", pwd); 20 | char tmppwd[256]; 21 | strcpy(tmppwd, pwd); 22 | /*get the real path*/ 23 | while(1) { 24 | char tmp[256]; 25 | if(access("b1", F_OK) != 0) { /*file not exist*/ 26 | if(strcmp(tmppwd, "/") == 0) 27 | { 28 | printf("*** Set a WC first! ****\n"); 29 | chdir(pwd); 30 | return -1; 31 | } 32 | getParent(tmp, tmppwd); 33 | if(strcmp(tmp, "") == 0) 34 | strcpy(tmp, "/"); 35 | printf("%s\n",tmp); 36 | chdir(tmp); 37 | memset(tmppwd, 0, sizeof(tmppwd)); 38 | strcpy(tmppwd, tmp); 39 | } else { 40 | break; 41 | } 42 | } 43 | //chdir(pwd); 44 | 45 | printf("++%s\n", tmppwd); 46 | if(strlen(tmppwd) != strlen(pwd)) { /*path is not real path*/ 47 | char *p; 48 | if(strcmp(tmppwd, "/") == 0) { 49 | p = pwd + 1; 50 | } else { 51 | p = pwd + strlen(tmppwd)+1; /*discard the front '/'*/ 52 | } 53 | printf("plus:%s\n", p); 54 | sprintf(realpath, "%s/%s", p, path); 55 | printf("realpath:%s\n", realpath); 56 | } else { 57 | strcpy(realpath, path); 58 | } 59 | 60 | 61 | printf("realpath:%s\n", realpath); 62 | 63 | getcwd(pwd, 256); 64 | printf("-----------pwd:%s\n", pwd); 65 | return 0; 66 | } 67 | 68 | 69 | /* 70 | * 从文件路径中解析出它的父目录(chengshuguang/a.txt--->chengshuguang) 71 | */ 72 | void getParent(char *parent, const char *fullpath) { 73 | const char *tail; 74 | int tmp; 75 | 76 | tmp = strlen(fullpath); 77 | tail = fullpath + tmp - 1; 78 | while (*tail == '/') /*去掉结尾所有的‘/’*/ 79 | tail--; 80 | while (tail>=fullpath && *tail!='/') /*找到倒数第一个slash*/ 81 | tail--; 82 | while (*tail == '/') /*去掉结尾所有的‘/’*/ 83 | tail--; 84 | strncpy(parent, fullpath, tail-fullpath+1); 85 | parent[tail-fullpath+1] = '\0'; 86 | } -------------------------------------------------------------------------------- /testFileName/test.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | /* 5 | * parse the fullpath name(/chengshuguang/a.txt), get the filename(a.txt) and the parent dir(/chenshuguang/). 6 | */ 7 | 8 | int getFileName(char* filename,char *parent, const char* fullpath, int maxlen) { 9 | char strtmp[128], *head; 10 | //char strtmp2[128], *head2; 11 | const char *tail; 12 | int tmp; 13 | tmp = strlen(fullpath); 14 | tail = fullpath + tmp - 1; 15 | while (*tail == '/') /*去掉结尾所有的‘/’*/ 16 | tail--; 17 | head = strtmp; 18 | 19 | while (tail>=fullpath && *tail!='/') /*得到filename的倒序*/ 20 | *head++ = *tail--; 21 | strncpy(parent, fullpath, tail-fullpath+1); 22 | parent[tail-fullpath+1] = '\0'; 23 | head--; 24 | 25 | while (maxlen>0 && head>=strtmp) { 26 | *filename++ = *head--; 27 | maxlen--; 28 | } 29 | if (maxlen>0) { 30 | *filename = '\0'; 31 | return 0; // 32 | } 33 | else return -1; /*文件名太长*/ 34 | } 35 | /* 36 | * 从文件路径中解析出它的父目录 37 | */ 38 | void getParent(char *parent, const char *fullpath) { 39 | const char *tail; 40 | int tmp; 41 | 42 | tmp = strlen(fullpath); 43 | tail = fullpath + tmp - 1; 44 | while (*tail == '/') /*去掉结尾所有的‘/’*/ 45 | tail--; 46 | while (tail>=fullpath && *tail!='/') /*找到倒数第一个slash*/ 47 | tail--; 48 | while (*tail == '/') /*去掉结尾所有的‘/’*/ 49 | tail--; 50 | strncpy(parent, fullpath, tail-fullpath+1); 51 | parent[tail-fullpath+1] = '\0'; 52 | } 53 | /* 54 | * the server stores the files in the format:[filename::version] 55 | * for example, readMe of version 2 will be stored by the name readMe::2 56 | */ 57 | /*char *getNewFileName(char *filename, int version) {*/ 58 | /* char newname[256];*/ 59 | /* sprintf(newname, "%s::%d", filename, version);*/ 60 | /* return newname;*/ 61 | /*}*/ 62 | 63 | int main() { 64 | //char filename[128]; 65 | //char parent[128]; 66 | //getFileName(filename, parent, "chengshuguang/test.c", 128); 67 | //printf("%s\n%s\n",filename, parent); 68 | //getParent(parent, "/test.c/"); 69 | //printf("%s\n", parent); 70 | char *path = "/chengshuguang/"; 71 | char newname[256]; 72 | sprintf(newname, "%s::%d", path, 23); 73 | printf("-%s-\n", newname); 74 | return 0; 75 | } 76 | -------------------------------------------------------------------------------- /filePathLinkedlist.h: -------------------------------------------------------------------------------- 1 | /* 2 | * this file define a linked list to save the path::version string array; 3 | * it may be very easy to implement this class in C++, but i want a C style one 4 | */ 5 | 6 | #include 7 | #include 8 | //#include 9 | //#include 10 | 11 | typedef struct FilePathListNode_ { 12 | char filename[256]; 13 | char sha1[41]; 14 | char m_time[32]; 15 | int isDir; 16 | struct FilePathListNode_ *next; 17 | }FilePathListNode; 18 | 19 | typedef struct { 20 | FilePathListNode *head; 21 | FilePathListNode *tail; 22 | int size; 23 | }FilePathList; 24 | 25 | void init(FilePathList *list) { 26 | list->head = list->tail = NULL; 27 | list->size = 0; 28 | } 29 | 30 | 31 | void push_back(FilePathList *list, FilePathListNode *node) { 32 | if(list->head == NULL) { 33 | list->head = node; 34 | list->tail = node; 35 | } else { 36 | list->tail = list->tail->next = node; 37 | } 38 | list->size++; 39 | } 40 | 41 | void unit_test(FilePathList *list) { 42 | if(list->size == 0) 43 | return; 44 | printf("list size: %d\n", list->size); 45 | FilePathListNode *tmp = list->head; 46 | while(tmp != list->tail) { 47 | if(!tmp->isDir) 48 | printf("<%s--%s--%s> dir:%d\n", tmp->filename, tmp->sha1, tmp->m_time, tmp->isDir); 49 | else 50 | printf("<%s> dir:%d\n", tmp->filename, tmp->isDir); 51 | 52 | //printf("%s\n", tmp->filename); 53 | tmp = tmp->next; 54 | } 55 | if(!tmp->isDir) 56 | printf("<%s--%s--%s> dir:%d\n", tmp->filename, tmp->sha1, tmp->m_time, tmp->isDir); 57 | else 58 | printf("<%s> dir:%d\n", tmp->filename, tmp->isDir); 59 | //printf("%s\n", tmp->filename); 60 | } 61 | 62 | 63 | //strLinkedList is used to 64 | //record the version number 65 | typedef struct strNode{ 66 | char str[28]; 67 | struct strNode *next; 68 | }strNode; 69 | 70 | typedef struct { 71 | strNode *head; 72 | strNode *tail; 73 | }strLinkedList; 74 | 75 | void initStr(strLinkedList *list) { 76 | list->head = list->tail = NULL; 77 | } 78 | 79 | void push_back_str(strLinkedList *list, strNode *node) { 80 | if(list->head == NULL) { 81 | list->head = node; 82 | list->tail = node; 83 | } else { 84 | list->tail = list->tail->next = node; 85 | } 86 | } 87 | -------------------------------------------------------------------------------- /src/filePathLinkedlist.h: -------------------------------------------------------------------------------- 1 | /* 2 | * this file define a linked list to save the path::version string array; 3 | * it may be very easy to implement this class in C++, but i want a C style one 4 | */ 5 | 6 | #include 7 | #include 8 | //#include 9 | //#include 10 | 11 | typedef struct FilePathListNode_ { 12 | char filename[256]; 13 | char sha1[41]; 14 | char m_time[32]; 15 | int isDir; 16 | struct FilePathListNode_ *next; 17 | }FilePathListNode; 18 | 19 | typedef struct { 20 | FilePathListNode *head; 21 | FilePathListNode *tail; 22 | int size; 23 | }FilePathList; 24 | 25 | void init(FilePathList *list) { 26 | list->head = list->tail = NULL; 27 | list->size = 0; 28 | } 29 | 30 | 31 | void push_back(FilePathList *list, FilePathListNode *node) { 32 | if(list->head == NULL) { 33 | list->head = node; 34 | list->tail = node; 35 | } else { 36 | list->tail = list->tail->next = node; 37 | } 38 | list->size++; 39 | } 40 | 41 | void unit_test(FilePathList *list) { 42 | if(list->size == 0) 43 | return; 44 | printf("list size: %d\n", list->size); 45 | FilePathListNode *tmp = list->head; 46 | while(tmp != list->tail) { 47 | if(!tmp->isDir) 48 | printf("<%s--%s--%s> dir:%d\n", tmp->filename, tmp->sha1, tmp->m_time, tmp->isDir); 49 | else 50 | printf("<%s> dir:%d\n", tmp->filename, tmp->isDir); 51 | 52 | //printf("%s\n", tmp->filename); 53 | tmp = tmp->next; 54 | } 55 | if(!tmp->isDir) 56 | printf("<%s--%s--%s> dir:%d\n", tmp->filename, tmp->sha1, tmp->m_time, tmp->isDir); 57 | else 58 | printf("<%s> dir:%d\n", tmp->filename, tmp->isDir); 59 | //printf("%s\n", tmp->filename); 60 | } 61 | 62 | 63 | //strLinkedList is used to 64 | //record the version number 65 | typedef struct strNode{ 66 | char str[28]; 67 | struct strNode *next; 68 | }strNode; 69 | 70 | typedef struct { 71 | strNode *head; 72 | strNode *tail; 73 | }strLinkedList; 74 | 75 | void initStr(strLinkedList *list) { 76 | list->head = list->tail = NULL; 77 | } 78 | 79 | void push_back_str(strLinkedList *list, strNode *node) { 80 | if(list->head == NULL) { 81 | list->head = node; 82 | list->tail = node; 83 | } else { 84 | list->tail = list->tail->next = node; 85 | } 86 | } 87 | -------------------------------------------------------------------------------- /src2/filePathLinkedlist.h: -------------------------------------------------------------------------------- 1 | /* 2 | * this file define a linked list to save the path::version string array; 3 | * it may be very easy to implement this class in C++, but i want a C style one 4 | */ 5 | 6 | #include 7 | #include 8 | //#include 9 | //#include 10 | 11 | typedef struct FilePathListNode_ { 12 | char filename[256]; 13 | char sha1[41]; 14 | char m_time[32]; 15 | int isDir; 16 | struct FilePathListNode_ *next; 17 | }FilePathListNode; 18 | 19 | typedef struct { 20 | FilePathListNode *head; 21 | FilePathListNode *tail; 22 | int size; 23 | }FilePathList; 24 | 25 | void init(FilePathList *list) { 26 | list->head = list->tail = NULL; 27 | list->size = 0; 28 | } 29 | 30 | 31 | void push_back(FilePathList *list, FilePathListNode *node) { 32 | if(list->head == NULL) { 33 | list->head = node; 34 | list->tail = node; 35 | } else { 36 | list->tail = list->tail->next = node; 37 | } 38 | list->size++; 39 | } 40 | 41 | void unit_test(FilePathList *list) { 42 | if(list->size == 0) 43 | return; 44 | printf("list size: %d\n", list->size); 45 | FilePathListNode *tmp = list->head; 46 | while(tmp != list->tail) { 47 | if(!tmp->isDir) 48 | printf("<%s--%s--%s> dir:%d\n", tmp->filename, tmp->sha1, tmp->m_time, tmp->isDir); 49 | else 50 | printf("<%s> dir:%d\n", tmp->filename, tmp->isDir); 51 | 52 | //printf("%s\n", tmp->filename); 53 | tmp = tmp->next; 54 | } 55 | if(!tmp->isDir) 56 | printf("<%s--%s--%s> dir:%d\n", tmp->filename, tmp->sha1, tmp->m_time, tmp->isDir); 57 | else 58 | printf("<%s> dir:%d\n", tmp->filename, tmp->isDir); 59 | //printf("%s\n", tmp->filename); 60 | } 61 | 62 | 63 | //strLinkedList is used to 64 | //record the version number 65 | typedef struct strNode{ 66 | char str[28]; 67 | struct strNode *next; 68 | }strNode; 69 | 70 | typedef struct { 71 | strNode *head; 72 | strNode *tail; 73 | }strLinkedList; 74 | 75 | void initStr(strLinkedList *list) { 76 | list->head = list->tail = NULL; 77 | } 78 | 79 | void push_back_str(strLinkedList *list, strNode *node) { 80 | if(list->head == NULL) { 81 | list->head = node; 82 | list->tail = node; 83 | } else { 84 | list->tail = list->tail->next = node; 85 | } 86 | } 87 | -------------------------------------------------------------------------------- /source-code-manager(开源的代码)/inc/filelist.h: -------------------------------------------------------------------------------- 1 | #ifndef _FILE_LIST_H 2 | #define _FILE_LIST_H 3 | #include "strings.h" 4 | #include "sha.h" 5 | 6 | /*File operations*/ 7 | struct _file; 8 | typedef struct _file *File; 9 | 10 | struct _file 11 | { 12 | String filename; 13 | uint32_t mode, mtime, size; 14 | ShaBuffer sha; 15 | bool deleted; 16 | }; 17 | 18 | 19 | File File_Create(void); 20 | void File_Delete(File f); 21 | void File_Clone(File f, const File f1); 22 | bool File_SetFileData(File f, const char *filename, const bool computeSha); 23 | 24 | /*Converts the file data into machine independent form 25 | * and places the output in buffer. 26 | * Return the size of data written into buffer */ 27 | int File_Serialize(File f, unsigned char * const buffer, const int bufferSize); 28 | bool File_DeSerialize(File f, unsigned const char *data, const int dataSize); 29 | 30 | /**********End of file operations********************************/ 31 | 32 | /* Public API's for FileList. By Default the list is sorted during add.*/ 33 | struct _filelist; 34 | typedef struct _filelist *FileList; 35 | 36 | typedef enum 37 | { 38 | FILE_NEW = 0, 39 | FILE_DELETED, 40 | FILE_MODIFIED, 41 | FILE_LAST_VALUE 42 | }DifferenceType; 43 | 44 | typedef int (*fn_difference)(File ref, File n, DifferenceType, void*); 45 | 46 | /*Operations on list*/ 47 | FileList FileList_Create(void); 48 | void FileList_Delete(FileList f); 49 | void FileList_ResetList(FileList f); 50 | inline uint32_t FileList_GetListLength(FileList f); 51 | inline bool FileList_Find(FileList f, const char *filename, uint32_t * const pos); 52 | File* FileList_GetListDetails(const FileList f, uint32_t * const listLength); 53 | bool FileList_InsertFile(FileList f, const char* filename, const bool computeSha); 54 | bool FileList_RemoveFile(FileList f, const char *filename, const bool recursive); 55 | bool FileList_MergeList(FileList masterList, const FileList newList); 56 | bool FileList_GetDifference(const FileList reference, const FileList list, fn_difference function, void *data); 57 | 58 | /*Function to convert list into format which is transportable accross 59 | * network or machines*/ 60 | bool FileList_Serialize(FileList f, const char *filename); 61 | bool FileList_DeSerialize(FileList f, const char *filename); 62 | 63 | /*Get the contents of the directory into the list.*/ 64 | bool FileList_GetDirectoryConents(FileList f, const char *path, const bool recursive, const bool computeSha); 65 | 66 | /*Print the list*/ 67 | void FileList_PrintList(const FileList f, const bool recursive, const bool longlist); 68 | #endif 69 | -------------------------------------------------------------------------------- /conn_pool.cpp: -------------------------------------------------------------------------------- 1 | #include "conn_pool.h" 2 | #include 3 | #include 4 | 5 | ConnPool *ConnPool::conn_pool = NULL; 6 | 7 | ConnPool::ConnPool(const char *hostip, const char *username, const char *password, 8 | int maxSize, int initSize){ 9 | assert(maxSize >= initSize); 10 | assert(maxSize>0 && initSize>0); 11 | 12 | hostip_ = hostip; 13 | username_ = username; 14 | password_ = password; 15 | 16 | maxSize_ = maxSize; 17 | curSize = 0; 18 | InitConnPool(hostip, username, password, initSize); 19 | } 20 | 21 | ConnPool *ConnPool::GetInstance(){ 22 | if(conn_pool == NULL) 23 | conn_pool = new ConnPool(HOST, USERNAME, PASSWORD, MAX_CONNPOOL_SIZE, INIT_CONNPOOL_SIZE); 24 | return conn_pool; 25 | } 26 | 27 | void ConnPool::InitConnPool(const char *hostip, const char *username, const char *password, 28 | int initSize){ 29 | MutexGuard lock(mutex); 30 | MysqlEncap *conn; 31 | try{ 32 | for(int i=0; iConnect(hostip_.c_str(), username_.c_str(), password_.c_str()); 35 | if(conn != NULL){ 36 | connList.push_back(conn); 37 | curSize++; 38 | }else{ 39 | fprintf(stderr,"InitConnPool error\n"); 40 | } 41 | } 42 | }catch(...){ 43 | fprintf(stderr,"InitConnPool error\n"); 44 | } 45 | } 46 | 47 | MysqlEncap* ConnPool::GetOneConn(){ 48 | MysqlEncap *conn; 49 | MutexGuard lock(mutex); 50 | if(connList.size() > 0){//注意区分connlist里面的是可用连接,而cursize表示所有建立的连接 51 | conn = connList.front(); 52 | connList.pop_front(); 53 | //curSize--;//不能-- 54 | }else{ 55 | if(curSize < maxSize_){ 56 | conn = new MysqlEncap; 57 | conn->Connect(hostip_.c_str(), username_.c_str(), password_.c_str()); 58 | if(conn != NULL){ 59 | //connList.push_back(conn);//这里不能加入到队列,直接反给使用者 60 | curSize++; 61 | }else{ 62 | fprintf(stderr,"get conn error\n"); 63 | } 64 | }else{ 65 | return NULL; 66 | } 67 | } 68 | return conn; 69 | } 70 | 71 | 72 | void ConnPool::ReleaseOneConn(MysqlEncap *conn){ 73 | if(conn){ 74 | MutexGuard lock(mutex); 75 | connList.push_back(conn); 76 | } 77 | } 78 | 79 | ConnPool::~ConnPool(){ 80 | DestroyConnPool(); 81 | } 82 | //目前只保证connlist里面空闲连接被释放,剩下的分配出去的连接 83 | //还没有去管,基于不是程序退出不会销毁线程池,所以也没关系 84 | void ConnPool::DestroyConnPool(){ 85 | list::iterator iter; 86 | MutexGuard lock(mutex); 87 | for(iter=connList.begin(); iter!=connList.end(); iter++){ 88 | DestroyConnection(*iter); 89 | } 90 | curSize = 0; 91 | connList.clear(); 92 | } 93 | 94 | void ConnPool::DestroyConnection(MysqlEncap *conn){ 95 | if(conn){ 96 | conn->CloseConnect(); 97 | } 98 | delete conn; 99 | } 100 | 101 | void ConnPool::ShowStatus(){ 102 | printf("+++++++The Pool Status++++++\n"); 103 | printf("curSize: %d\n", curSize); 104 | printf("free conn: %d used conn: %d\n", connList.size(), curSize-connList.size()); 105 | printf("++++++++++ End +++++++++++++\n"); 106 | } 107 | 108 | 109 | 110 | 111 | 112 | 113 | -------------------------------------------------------------------------------- /src/conn_pool.cpp: -------------------------------------------------------------------------------- 1 | #include "conn_pool.h" 2 | #include 3 | #include 4 | 5 | ConnPool *ConnPool::conn_pool = NULL; 6 | 7 | ConnPool::ConnPool(const char *hostip, const char *username, const char *password, 8 | int maxSize, int initSize){ 9 | assert(maxSize >= initSize); 10 | assert(maxSize>0 && initSize>0); 11 | 12 | hostip_ = hostip; 13 | username_ = username; 14 | password_ = password; 15 | 16 | maxSize_ = maxSize; 17 | curSize = 0; 18 | InitConnPool(hostip, username, password, initSize); 19 | } 20 | 21 | ConnPool *ConnPool::GetInstance(){ 22 | if(conn_pool == NULL) 23 | conn_pool = new ConnPool(HOST, USERNAME, PASSWORD, MAX_CONNPOOL_SIZE, INIT_CONNPOOL_SIZE); 24 | return conn_pool; 25 | } 26 | 27 | void ConnPool::InitConnPool(const char *hostip, const char *username, const char *password, 28 | int initSize){ 29 | MutexGuard lock(mutex); 30 | MysqlEncap *conn; 31 | try{ 32 | for(int i=0; iConnect(hostip_.c_str(), username_.c_str(), password_.c_str()); 35 | if(conn != NULL){ 36 | connList.push_back(conn); 37 | curSize++; 38 | }else{ 39 | fprintf(stderr,"InitConnPool error\n"); 40 | } 41 | } 42 | }catch(...){ 43 | fprintf(stderr,"InitConnPool error\n"); 44 | } 45 | } 46 | 47 | MysqlEncap* ConnPool::GetOneConn(){ 48 | MysqlEncap *conn; 49 | MutexGuard lock(mutex); 50 | if(connList.size() > 0){//注意区分connlist里面的是可用连接,而cursize表示所有建立的连接 51 | conn = connList.front(); 52 | connList.pop_front(); 53 | //curSize--;//不能-- 54 | }else{ 55 | if(curSize < maxSize_){ 56 | conn = new MysqlEncap; 57 | conn->Connect(hostip_.c_str(), username_.c_str(), password_.c_str()); 58 | if(conn != NULL){ 59 | //connList.push_back(conn);//这里不能加入到队列,直接反给使用者 60 | curSize++; 61 | }else{ 62 | fprintf(stderr,"get conn error\n"); 63 | } 64 | }else{ 65 | return NULL; 66 | } 67 | } 68 | return conn; 69 | } 70 | 71 | 72 | void ConnPool::ReleaseOneConn(MysqlEncap *conn){ 73 | if(conn){ 74 | MutexGuard lock(mutex); 75 | connList.push_back(conn); 76 | } 77 | } 78 | 79 | ConnPool::~ConnPool(){ 80 | DestroyConnPool(); 81 | } 82 | //目前只保证connlist里面空闲连接被释放,剩下的分配出去的连接 83 | //还没有去管,基于不是程序退出不会销毁线程池,所以也没关系 84 | void ConnPool::DestroyConnPool(){ 85 | list::iterator iter; 86 | MutexGuard lock(mutex); 87 | for(iter=connList.begin(); iter!=connList.end(); iter++){ 88 | DestroyConnection(*iter); 89 | } 90 | curSize = 0; 91 | connList.clear(); 92 | } 93 | 94 | void ConnPool::DestroyConnection(MysqlEncap *conn){ 95 | if(conn){ 96 | conn->CloseConnect(); 97 | } 98 | delete conn; 99 | } 100 | 101 | void ConnPool::ShowStatus(){ 102 | printf("+++++++The Pool Status++++++\n"); 103 | printf("curSize: %d\n", curSize); 104 | printf("free conn: %d used conn: %d\n", connList.size(), curSize-connList.size()); 105 | printf("++++++++++ End +++++++++++++\n"); 106 | } 107 | 108 | 109 | 110 | 111 | 112 | 113 | -------------------------------------------------------------------------------- /src2/conn_pool.cpp: -------------------------------------------------------------------------------- 1 | #include "conn_pool.h" 2 | #include 3 | #include 4 | 5 | ConnPool *ConnPool::conn_pool = NULL; 6 | 7 | ConnPool::ConnPool(const char *hostip, const char *username, const char *password, 8 | int maxSize, int initSize){ 9 | assert(maxSize >= initSize); 10 | assert(maxSize>0 && initSize>0); 11 | 12 | hostip_ = hostip; 13 | username_ = username; 14 | password_ = password; 15 | 16 | maxSize_ = maxSize; 17 | curSize = 0; 18 | InitConnPool(hostip, username, password, initSize); 19 | } 20 | 21 | ConnPool *ConnPool::GetInstance(){ 22 | if(conn_pool == NULL) 23 | conn_pool = new ConnPool(HOST, USERNAME, PASSWORD, MAX_CONNPOOL_SIZE, INIT_CONNPOOL_SIZE); 24 | return conn_pool; 25 | } 26 | 27 | void ConnPool::InitConnPool(const char *hostip, const char *username, const char *password, 28 | int initSize){ 29 | MutexGuard lock(mutex); 30 | MysqlEncap *conn; 31 | try{ 32 | for(int i=0; iConnect(hostip_.c_str(), username_.c_str(), password_.c_str()); 35 | if(conn != NULL){ 36 | connList.push_back(conn); 37 | curSize++; 38 | }else{ 39 | fprintf(stderr,"InitConnPool error\n"); 40 | } 41 | } 42 | }catch(...){ 43 | fprintf(stderr,"InitConnPool error\n"); 44 | } 45 | } 46 | 47 | MysqlEncap* ConnPool::GetOneConn(){ 48 | MysqlEncap *conn; 49 | MutexGuard lock(mutex); 50 | if(connList.size() > 0){//注意区分connlist里面的是可用连接,而cursize表示所有建立的连接 51 | conn = connList.front(); 52 | connList.pop_front(); 53 | //curSize--;//不能-- 54 | }else{ 55 | if(curSize < maxSize_){ 56 | conn = new MysqlEncap; 57 | conn->Connect(hostip_.c_str(), username_.c_str(), password_.c_str()); 58 | if(conn != NULL){ 59 | //connList.push_back(conn);//这里不能加入到队列,直接反给使用者 60 | curSize++; 61 | }else{ 62 | fprintf(stderr,"get conn error\n"); 63 | } 64 | }else{ 65 | return NULL; 66 | } 67 | } 68 | return conn; 69 | } 70 | 71 | 72 | void ConnPool::ReleaseOneConn(MysqlEncap *conn){ 73 | if(conn){ 74 | MutexGuard lock(mutex); 75 | connList.push_back(conn); 76 | } 77 | } 78 | 79 | ConnPool::~ConnPool(){ 80 | DestroyConnPool(); 81 | } 82 | //目前只保证connlist里面空闲连接被释放,剩下的分配出去的连接 83 | //还没有去管,基于不是程序退出不会销毁线程池,所以也没关系 84 | void ConnPool::DestroyConnPool(){ 85 | list::iterator iter; 86 | MutexGuard lock(mutex); 87 | for(iter=connList.begin(); iter!=connList.end(); iter++){ 88 | DestroyConnection(*iter); 89 | } 90 | curSize = 0; 91 | connList.clear(); 92 | } 93 | 94 | void ConnPool::DestroyConnection(MysqlEncap *conn){ 95 | if(conn){ 96 | conn->CloseConnect(); 97 | } 98 | delete conn; 99 | } 100 | 101 | void ConnPool::ShowStatus(){ 102 | printf("+++++++The Pool Status++++++\n"); 103 | printf("curSize: %d\n", curSize); 104 | printf("free conn: %d used conn: %d\n", connList.size(), curSize-connList.size()); 105 | printf("++++++++++ End +++++++++++++\n"); 106 | } 107 | 108 | 109 | 110 | 111 | 112 | 113 | -------------------------------------------------------------------------------- /mysql-encap/conn_pool.cpp: -------------------------------------------------------------------------------- 1 | #include "conn_pool.h" 2 | #include 3 | #include 4 | 5 | ConnPool *ConnPool::conn_pool = NULL; 6 | 7 | ConnPool::ConnPool(const char *hostip, const char *username, const char *password, 8 | int maxSize, int initSize){ 9 | assert(maxSize >= initSize); 10 | assert(maxSize>0 && initSize>0); 11 | 12 | hostip_ = hostip; 13 | username_ = username; 14 | password_ = password; 15 | 16 | maxSize_ = maxSize; 17 | curSize = 0; 18 | InitConnPool(hostip, username, password, initSize); 19 | } 20 | 21 | ConnPool *ConnPool::GetInstance(){ 22 | if(conn_pool == NULL) 23 | conn_pool = new ConnPool(HOST, USERNAME, PASSWORD, MAX_CONNPOOL_SIZE, INIT_CONNPOOL_SIZE); 24 | return conn_pool; 25 | } 26 | 27 | void ConnPool::InitConnPool(const char *hostip, const char *username, const char *password, 28 | int initSize){ 29 | MutexGuard lock(mutex); 30 | MysqlEncap *conn; 31 | try{ 32 | for(int i=0; iConnect(hostip_.c_str(), username_.c_str(), password_.c_str()); 35 | if(conn != NULL){ 36 | connList.push_back(conn); 37 | curSize++; 38 | }else{ 39 | fprintf(stderr,"InitConnPool error\n"); 40 | } 41 | } 42 | }catch(...){ 43 | fprintf(stderr,"InitConnPool error\n"); 44 | } 45 | } 46 | 47 | MysqlEncap* ConnPool::GetOneConn(){ 48 | MysqlEncap *conn; 49 | MutexGuard lock(mutex); 50 | if(connList.size() > 0){//注意区分connlist里面的是可用连接,而cursize表示所有建立的连接 51 | conn = connList.front(); 52 | connList.pop_front(); 53 | //curSize--;//不能-- 54 | }else{ 55 | if(curSize < maxSize_){ 56 | conn = new MysqlEncap; 57 | conn->Connect(hostip_.c_str(), username_.c_str(), password_.c_str()); 58 | if(conn != NULL){ 59 | //connList.push_back(conn);//这里不能加入到队列,直接反给使用者 60 | curSize++; 61 | }else{ 62 | fprintf(stderr,"InitConnPool error\n"); 63 | } 64 | }else{ 65 | return NULL; 66 | } 67 | } 68 | return conn; 69 | } 70 | 71 | 72 | void ConnPool::ReleaseOneConn(MysqlEncap *conn){ 73 | if(conn){ 74 | MutexGuard lock(mutex); 75 | connList.push_back(conn); 76 | } 77 | } 78 | 79 | ConnPool::~ConnPool(){ 80 | DestroyConnPool(); 81 | } 82 | //目前只保证connlist里面空闲连接被释放,剩下的分配出去的连接 83 | //还没有去管,基于不是程序退出不会销毁线程池,所以也没关系 84 | void ConnPool::DestroyConnPool(){ 85 | list::iterator iter; 86 | MutexGuard lock(mutex); 87 | for(iter=connList.begin(); iter!=connList.end(); iter++){ 88 | DestroyConnection(*iter); 89 | } 90 | curSize = 0; 91 | connList.clear(); 92 | } 93 | 94 | void ConnPool::DestroyConnection(MysqlEncap *conn){ 95 | if(conn){ 96 | conn->CloseConnect(); 97 | } 98 | delete conn; 99 | } 100 | 101 | void ConnPool::ShowStatus(){ 102 | printf("+++++++The Pool Status++++++\n"); 103 | printf("curSize: %d\n", curSize); 104 | printf("free conn: %d used conn: %d\n", connList.size(), curSize-connList.size()); 105 | printf("++++++++++ End +++++++++++++\n"); 106 | } 107 | 108 | 109 | 110 | 111 | 112 | 113 | -------------------------------------------------------------------------------- /client.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include "common.h" 10 | #include "sha1.h" 11 | #include "files.h" 12 | 13 | #include "sock.h" 14 | 15 | 16 | int main(int argc, char **argv){ 17 | int sock_fd; 18 | create_and_conn(&sock_fd, "127.0.0.1", 9999); 19 | while(1){ 20 | message msg; 21 | printf("input the cmd(0:add 1:get 2:send [3:add 4:get])\n"); 22 | int input; 23 | scanf("%d", &input); 24 | getchar();//去除stdin中的'\n' 25 | switch(input){ 26 | case TEST_ADD: { 27 | msg.cmd = TEST_ADD; 28 | int ret = send(sock_fd, &msg, sizeof(msg), 0); 29 | if(ret == -1){ 30 | perror("send cmd msg\n"); 31 | } 32 | printf("file need to transfer:"); 33 | char path [256]; 34 | scanf("%s",path); 35 | printf("-------------start send----------\n"); 36 | Send(path, sock_fd); 37 | printf("-------------end send ----------\n"); 38 | break; 39 | 40 | } 41 | 42 | case TEST_GET: { 43 | msg.cmd = TEST_GET; 44 | int ret = send(sock_fd, &msg, sizeof(msg), 0); 45 | if(ret == -1){ 46 | perror("send cmd msg\n"); 47 | } 48 | printf("file need to Get:"); 49 | char path [256]; 50 | scanf("%s",path); 51 | getchar(); 52 | char version[32]; 53 | scanf("%s", version); 54 | getchar(); 55 | int byLatestVersion, recursive; 56 | scanf("%d %d", &byLatestVersion, &recursive); 57 | printf("-------------start Get----------\n"); 58 | clientGetFile(sock_fd, path, version, recursive, byLatestVersion); 59 | printf("-------------end Get ----------\n"); 60 | break; 61 | } 62 | 63 | case ADD_FILES:{ 64 | msg.cmd = ADD_FILES; 65 | int ret = send(sock_fd, &msg, sizeof(msg), 0); 66 | if(ret == -1){ 67 | perror("send cmd msg\n"); 68 | } 69 | 70 | /* addinfo info;*/ 71 | /* strcpy(info.path, "test.txt");*/ 72 | /* strcpy(info.comment, "init add test.txt");*/ 73 | /* ShaBuffer sha;*/ 74 | /* sha_file(info.path, sha);*/ 75 | /* strcpy(info.sha1, (char *)sha);*/ 76 | /* */ 77 | /* printf("sha:%s\n",sha);*/ 78 | /* */ 79 | /* */ 80 | /* ret = send(sock_fd, &info, sizeof(info), 0);*/ 81 | /* if(ret == -1){*/ 82 | /* perror("send info\n");*/ 83 | /* }*/ 84 | /* int needSendFile;*/ 85 | /* printf("get needSendFile info\n");*/ 86 | /* ret = recv(sock_fd, &needSendFile, sizeof(needSendFile), 0);*/ 87 | /* if(ret == -1){*/ 88 | /* perror("recv needSendFile info\n");*/ 89 | /* }*/ 90 | /* printf("end get needSendFile info\n");*/ 91 | /* if(needSendFile) {*/ 92 | /* printf("begin send file\n");*/ 93 | /* Send(info.path, sock_fd);*/ 94 | /* printf("end send file\n");*/ 95 | /* } else {*/ 96 | /* printf("file is same as the server\n");*/ 97 | /* }*/ 98 | /* */ 99 | break; 100 | } 101 | case GET_FILES:{ 102 | msg.cmd = GET_FILES; 103 | int ret = send(sock_fd, &msg, sizeof(msg), 0); 104 | if(ret == -1){ 105 | perror("send msg\n"); 106 | } 107 | //getFile(sock_fd); 108 | break; 109 | } 110 | case SEND_FILES:{ 111 | msg.cmd = SEND_FILES; 112 | int ret = send(sock_fd, &msg, sizeof(msg), 0); 113 | if(ret == -1){ 114 | perror("send msg\n"); 115 | } 116 | //getFile(sock_fd); 117 | break; 118 | } 119 | } 120 | 121 | 122 | //getFile(sock_fd); 123 | } 124 | 125 | 126 | close(sock_fd); 127 | return 0; 128 | 129 | } 130 | -------------------------------------------------------------------------------- /source-code-manager(开源的代码)/code/src/init.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include "scm.h" 6 | #include "filelist.h" 7 | 8 | static bool setBranchInHEAD(const char *branchName) 9 | { 10 | int fd, ch; 11 | bool returnValue = false; 12 | String s = String_Create(); 13 | fd = open(SCM_HEAD_FILE, O_CREAT | O_TRUNC | O_WRONLY, SCM_HEAD_FILE_PERMISSION); 14 | if(-1 == fd) 15 | { 16 | LOG_ERROR("fatal: setBranch: open('%s') failed(%d)", SCM_HEAD_FILE, errno); 17 | goto EXIT; 18 | } 19 | /*Write the branch name to 'head' file*/ 20 | String_format(s, "branch: %s", branchName); 21 | if(write(fd, s_getstr(s), String_strlen(s)) != String_strlen(s)) 22 | { 23 | LOG_ERROR("write() failed with errno %d", errno); 24 | close(fd); 25 | goto EXIT; 26 | } 27 | /*write a new line character*/ 28 | ch = '\n'; 29 | ch = write(fd, &ch, 1); 30 | close(fd); 31 | returnValue = true; 32 | EXIT: 33 | String_Delete(s); 34 | return returnValue; 35 | } 36 | 37 | static bool CreateFirstIndexFile(const char *path) 38 | { 39 | FileList f; 40 | bool returnValue; 41 | f = FileList_Create(); 42 | FileList_ResetList(f); 43 | FileList_InsertFile(f,".",false); 44 | returnValue = FileList_Serialize(f, path); 45 | FileList_Delete(f); 46 | return returnValue; 47 | } 48 | 49 | static bool createEmptyCommitFile(const char *path) 50 | { 51 | int fd, dummy; 52 | char *str = "\0"; 53 | fd = open(path, O_CREAT | O_TRUNC | O_WRONLY, SCM_HEAD_FILE_PERMISSION); 54 | if(fd < 0) 55 | { 56 | LOG_ERROR("createEmptyCommitFile: open('%s') failed(%d)", path, errno); 57 | return false; 58 | } 59 | dummy = write(fd, str, 1); 60 | close(fd); 61 | return true; 62 | } 63 | int cmd_init(int argc, char *argv[]) 64 | { 65 | int i; 66 | String s; 67 | char *folders[] = { SCM_FOLDER, 68 | SCM_BRANCH_FOLDER, 69 | SCM_OBJECTS_FOLDER, 70 | SCM_BLOB_FOLDER, 71 | SCM_COMMIT_FOLDER, 72 | SCM_TREE_FOLDER, 73 | SCM_TEMP_FOLDER}; 74 | const int size = sizeof(folders)/sizeof(folders[0]); 75 | 76 | if(true == isItFolder(".scm")) 77 | { 78 | LOG_ERROR("fatal: delete the .scm folder then try again"); 79 | return 1; 80 | } 81 | 82 | /*create all the folders*/ 83 | for(i = 0; i < size; i++) 84 | { 85 | if(0 != mkdir(folders[i], SCM_FOLDER_PERMISSION)) 86 | { 87 | LOG_ERROR("fatal: mkdir('%s') failed(%d)", folders[i], errno); 88 | return 1; 89 | } 90 | } 91 | 92 | s = String_Create(); 93 | String_format(s, "%s/%s", SCM_BRANCH_FOLDER, SCM_DEFAULT_BRANCH); 94 | /*Create the branch folder*/ 95 | if(0 != mkdir(s_getstr(s), SCM_FOLDER_PERMISSION)) 96 | { 97 | LOG_ERROR("mkdir('%s') failed(%d)", s_getstr(s), errno); 98 | String_Delete(s); 99 | return 1; 100 | } 101 | 102 | String_format(s, "%s/%s/%s", SCM_BRANCH_FOLDER, SCM_DEFAULT_BRANCH, SCM_BRANCH_CACHE_FOLDER); 103 | /*Create the branch folder*/ 104 | if(0 != mkdir(s_getstr(s), SCM_FOLDER_PERMISSION)) 105 | { 106 | LOG_ERROR("mkdir('%s') failed(%d)", s_getstr(s), errno); 107 | String_Delete(s); 108 | return 1; 109 | } 110 | /*set the branch name in 'HEAD' file*/ 111 | setBranchInHEAD(SCM_DEFAULT_BRANCH); 112 | 113 | String_format(s, "%s/%s/%s", SCM_BRANCH_FOLDER, SCM_DEFAULT_BRANCH, SCM_INDEX_FILENAME); 114 | /*Create a empty index file*/ 115 | if(false == CreateFirstIndexFile(s_getstr(s))) 116 | { 117 | LOG_INFO("CreateEmptyIndexFile() failed()"); 118 | } 119 | 120 | String_format(s, "%s/%s/%s", SCM_BRANCH_FOLDER, SCM_DEFAULT_BRANCH, SCM_COMMIT_FILENAME); 121 | createEmptyCommitFile(s_getstr(s)); 122 | String_Delete(s); 123 | return 0; 124 | } 125 | -------------------------------------------------------------------------------- /thread_pool.c: -------------------------------------------------------------------------------- 1 | #include "thread_pool.h" 2 | 3 | thread_pool *pool = NULL; 4 | static void * thread_pool_entrance(void *arg) 5 | { 6 | int thread_id = (int)arg; 7 | printf("thread %d is created\n",thread_id); 8 | 9 | while(1) 10 | { 11 | pthread_mutex_lock(&(pool->queue_mutex)); 12 | while(pool->task_queue_size == 0 && !pool->is_pool_destroyed)//必须用while,防止假唤醒 13 | { 14 | pthread_cond_wait(&(pool->queue_cond),&(pool->queue_mutex));//等待的时候会解锁,唤醒后加锁 15 | } 16 | 17 | if(pool->is_pool_destroyed) 18 | { 19 | printf("thread %d exit!!!\n",thread_id); 20 | pthread_mutex_unlock(&(pool->queue_mutex));//中途退出最容易出错,注意要解锁 21 | pthread_exit(NULL); 22 | } 23 | 24 | pool->idle_thread_num--;//线程进入忙碌状态 25 | //从任务队列中取出任务 26 | task *work; 27 | work = pool->task_queue_head; 28 | pool->task_queue_head = pool->task_queue_head->next; 29 | if(pool->task_queue_head == NULL) 30 | pool->task_queue_end = NULL; 31 | 32 | pool->task_queue_size--; 33 | 34 | pthread_mutex_unlock(&(pool->queue_mutex)); 35 | 36 | //回调函数 37 | (*(work->taskfunc))(work->arg); 38 | pool->idle_thread_num++;//线程空闲 39 | } 40 | return NULL; 41 | } 42 | 43 | 44 | int thread_pool_init(int thread_pool_size) 45 | { 46 | pool = (thread_pool *)malloc(sizeof(thread_pool));//不要最先给线程池分配空间 47 | 48 | pool->is_pool_destroyed = 0; 49 | 50 | pool->task_queue_head = NULL; 51 | pool->task_queue_end = NULL; 52 | pool->task_queue_size = 0; 53 | 54 | pool->thread_num = thread_pool_size; 55 | pool->thread_queue = (pthread_t *)malloc(thread_pool_size * sizeof(pthread_t)); 56 | pool->idle_thread_num = thread_pool_size; 57 | 58 | //创建线程 59 | int i, ret; 60 | for(i=0; ithread_queue[i]), NULL, thread_pool_entrance, (void *)i); 63 | if(ret < 0) 64 | { 65 | printf("thread create error!!!\n"); 66 | thread_pool_destroy();//注意销毁,避免内存泄漏 67 | return -1; 68 | } 69 | } 70 | 71 | pthread_mutex_init(&(pool->queue_mutex), NULL); 72 | pthread_cond_init(&(pool->queue_cond), NULL); 73 | 74 | return 0; 75 | } 76 | 77 | 78 | typedef void *(*taskfunc)(void *arg); 79 | int thread_pool_add_task(taskfunc func, void *arg) 80 | { 81 | task *newtask; 82 | newtask = (task *)malloc(sizeof(task)); 83 | newtask->taskfunc = func; 84 | newtask->arg = arg; 85 | newtask->next = NULL; 86 | 87 | pthread_mutex_lock(&(pool->queue_mutex)); 88 | 89 | if(pool->task_queue_head == NULL) 90 | { 91 | pool->task_queue_head = pool->task_queue_end = newtask; 92 | } 93 | else 94 | { 95 | pool->task_queue_end = pool->task_queue_end->next = newtask; 96 | } 97 | pool->task_queue_size++; 98 | 99 | pthread_cond_signal(&(pool->queue_cond)); 100 | pthread_mutex_unlock(&(pool->queue_mutex)); 101 | 102 | return 0; 103 | } 104 | 105 | 106 | int thread_pool_destroy() 107 | { 108 | if(pool->is_pool_destroyed)//防止多次销毁 109 | return -1; 110 | 111 | pool->is_pool_destroyed = 1; 112 | 113 | pthread_cond_broadcast(&(pool->queue_cond));//通知所有线程线程池销毁了 114 | int i; 115 | for(i=0; ithread_num; i++)//等待线程全部执行完 116 | pthread_join(pool->thread_queue[i], NULL); 117 | 118 | //销毁任务队列 119 | task *temp = NULL; 120 | while(pool->task_queue_head) 121 | { 122 | temp = pool->task_queue_head; 123 | pool->task_queue_head = pool->task_queue_head->next; 124 | free(temp); 125 | } 126 | //pool->task_queue_head = NULL; 127 | //pool->task_queue_end = NULL; 128 | 129 | //销毁线程队列 130 | free(pool->thread_queue); 131 | pool->thread_queue = NULL; 132 | 133 | pthread_mutex_destroy(&(pool->queue_mutex)); 134 | pthread_cond_destroy(&(pool->queue_cond)); 135 | 136 | free(pool); 137 | pool = NULL; 138 | 139 | return 0; 140 | } 141 | 142 | -------------------------------------------------------------------------------- /src/thread_pool.c: -------------------------------------------------------------------------------- 1 | #include "thread_pool.h" 2 | 3 | thread_pool *pool = NULL; 4 | static void * thread_pool_entrance(void *arg) 5 | { 6 | int thread_id = (int)arg; 7 | printf("thread %d is created\n",thread_id); 8 | 9 | while(1) 10 | { 11 | pthread_mutex_lock(&(pool->queue_mutex)); 12 | while(pool->task_queue_size == 0 && !pool->is_pool_destroyed)//必须用while,防止假唤醒 13 | { 14 | pthread_cond_wait(&(pool->queue_cond),&(pool->queue_mutex));//等待的时候会解锁,唤醒后加锁 15 | } 16 | 17 | if(pool->is_pool_destroyed) 18 | { 19 | printf("thread %d exit!!!\n",thread_id); 20 | pthread_mutex_unlock(&(pool->queue_mutex));//中途退出最容易出错,注意要解锁 21 | pthread_exit(NULL); 22 | } 23 | 24 | pool->idle_thread_num--;//线程进入忙碌状态 25 | //从任务队列中取出任务 26 | task *work; 27 | work = pool->task_queue_head; 28 | pool->task_queue_head = pool->task_queue_head->next; 29 | if(pool->task_queue_head == NULL) 30 | pool->task_queue_end = NULL; 31 | 32 | pool->task_queue_size--; 33 | 34 | pthread_mutex_unlock(&(pool->queue_mutex)); 35 | 36 | //回调函数 37 | (*(work->taskfunc))(work->arg); 38 | pool->idle_thread_num++;//线程空闲 39 | } 40 | return NULL; 41 | } 42 | 43 | 44 | int thread_pool_init(int thread_pool_size) 45 | { 46 | pool = (thread_pool *)malloc(sizeof(thread_pool));//不要最先给线程池分配空间 47 | 48 | pool->is_pool_destroyed = 0; 49 | 50 | pool->task_queue_head = NULL; 51 | pool->task_queue_end = NULL; 52 | pool->task_queue_size = 0; 53 | 54 | pool->thread_num = thread_pool_size; 55 | pool->thread_queue = (pthread_t *)malloc(thread_pool_size * sizeof(pthread_t)); 56 | pool->idle_thread_num = thread_pool_size; 57 | 58 | //创建线程 59 | int i, ret; 60 | for(i=0; ithread_queue[i]), NULL, thread_pool_entrance, (void *)i); 63 | if(ret < 0) 64 | { 65 | printf("thread create error!!!\n"); 66 | thread_pool_destroy();//注意销毁,避免内存泄漏 67 | return -1; 68 | } 69 | } 70 | 71 | pthread_mutex_init(&(pool->queue_mutex), NULL); 72 | pthread_cond_init(&(pool->queue_cond), NULL); 73 | 74 | return 0; 75 | } 76 | 77 | 78 | typedef void *(*taskfunc)(void *arg); 79 | int thread_pool_add_task(taskfunc func, void *arg) 80 | { 81 | task *newtask; 82 | newtask = (task *)malloc(sizeof(task)); 83 | newtask->taskfunc = func; 84 | newtask->arg = arg; 85 | newtask->next = NULL; 86 | 87 | pthread_mutex_lock(&(pool->queue_mutex)); 88 | 89 | if(pool->task_queue_head == NULL) 90 | { 91 | pool->task_queue_head = pool->task_queue_end = newtask; 92 | } 93 | else 94 | { 95 | pool->task_queue_end = pool->task_queue_end->next = newtask; 96 | } 97 | pool->task_queue_size++; 98 | 99 | pthread_cond_signal(&(pool->queue_cond)); 100 | pthread_mutex_unlock(&(pool->queue_mutex)); 101 | 102 | return 0; 103 | } 104 | 105 | 106 | int thread_pool_destroy() 107 | { 108 | if(pool->is_pool_destroyed)//防止多次销毁 109 | return -1; 110 | 111 | pool->is_pool_destroyed = 1; 112 | 113 | pthread_cond_broadcast(&(pool->queue_cond));//通知所有线程线程池销毁了 114 | int i; 115 | for(i=0; ithread_num; i++)//等待线程全部执行完 116 | pthread_join(pool->thread_queue[i], NULL); 117 | 118 | //销毁任务队列 119 | task *temp = NULL; 120 | while(pool->task_queue_head) 121 | { 122 | temp = pool->task_queue_head; 123 | pool->task_queue_head = pool->task_queue_head->next; 124 | free(temp); 125 | } 126 | //pool->task_queue_head = NULL; 127 | //pool->task_queue_end = NULL; 128 | 129 | //销毁线程队列 130 | free(pool->thread_queue); 131 | pool->thread_queue = NULL; 132 | 133 | pthread_mutex_destroy(&(pool->queue_mutex)); 134 | pthread_cond_destroy(&(pool->queue_cond)); 135 | 136 | free(pool); 137 | pool = NULL; 138 | 139 | return 0; 140 | } 141 | 142 | -------------------------------------------------------------------------------- /src2/thread_pool.c: -------------------------------------------------------------------------------- 1 | #include "thread_pool.h" 2 | 3 | thread_pool *pool = NULL; 4 | static void * thread_pool_entrance(void *arg) 5 | { 6 | int thread_id = (int)arg; 7 | printf("thread %d is created\n",thread_id); 8 | 9 | while(1) 10 | { 11 | pthread_mutex_lock(&(pool->queue_mutex)); 12 | while(pool->task_queue_size == 0 && !pool->is_pool_destroyed)//必须用while,防止假唤醒 13 | { 14 | pthread_cond_wait(&(pool->queue_cond),&(pool->queue_mutex));//等待的时候会解锁,唤醒后加锁 15 | } 16 | 17 | if(pool->is_pool_destroyed) 18 | { 19 | printf("thread %d exit!!!\n",thread_id); 20 | pthread_mutex_unlock(&(pool->queue_mutex));//中途退出最容易出错,注意要解锁 21 | pthread_exit(NULL); 22 | } 23 | 24 | pool->idle_thread_num--;//线程进入忙碌状态 25 | //从任务队列中取出任务 26 | task *work; 27 | work = pool->task_queue_head; 28 | pool->task_queue_head = pool->task_queue_head->next; 29 | if(pool->task_queue_head == NULL) 30 | pool->task_queue_end = NULL; 31 | 32 | pool->task_queue_size--; 33 | 34 | pthread_mutex_unlock(&(pool->queue_mutex)); 35 | 36 | //回调函数 37 | (*(work->taskfunc))(work->arg); 38 | pool->idle_thread_num++;//线程空闲 39 | } 40 | return NULL; 41 | } 42 | 43 | 44 | int thread_pool_init(int thread_pool_size) 45 | { 46 | pool = (thread_pool *)malloc(sizeof(thread_pool));//不要最先给线程池分配空间 47 | 48 | pool->is_pool_destroyed = 0; 49 | 50 | pool->task_queue_head = NULL; 51 | pool->task_queue_end = NULL; 52 | pool->task_queue_size = 0; 53 | 54 | pool->thread_num = thread_pool_size; 55 | pool->thread_queue = (pthread_t *)malloc(thread_pool_size * sizeof(pthread_t)); 56 | pool->idle_thread_num = thread_pool_size; 57 | 58 | //创建线程 59 | int i, ret; 60 | for(i=0; ithread_queue[i]), NULL, thread_pool_entrance, (void *)i); 63 | if(ret < 0) 64 | { 65 | printf("thread create error!!!\n"); 66 | thread_pool_destroy();//注意销毁,避免内存泄漏 67 | return -1; 68 | } 69 | } 70 | 71 | pthread_mutex_init(&(pool->queue_mutex), NULL); 72 | pthread_cond_init(&(pool->queue_cond), NULL); 73 | 74 | return 0; 75 | } 76 | 77 | 78 | typedef void *(*taskfunc)(void *arg); 79 | int thread_pool_add_task(taskfunc func, void *arg) 80 | { 81 | task *newtask; 82 | newtask = (task *)malloc(sizeof(task)); 83 | newtask->taskfunc = func; 84 | newtask->arg = arg; 85 | newtask->next = NULL; 86 | 87 | pthread_mutex_lock(&(pool->queue_mutex)); 88 | 89 | if(pool->task_queue_head == NULL) 90 | { 91 | pool->task_queue_head = pool->task_queue_end = newtask; 92 | } 93 | else 94 | { 95 | pool->task_queue_end = pool->task_queue_end->next = newtask; 96 | } 97 | pool->task_queue_size++; 98 | 99 | pthread_cond_signal(&(pool->queue_cond)); 100 | pthread_mutex_unlock(&(pool->queue_mutex)); 101 | 102 | return 0; 103 | } 104 | 105 | 106 | int thread_pool_destroy() 107 | { 108 | if(pool->is_pool_destroyed)//防止多次销毁 109 | return -1; 110 | 111 | pool->is_pool_destroyed = 1; 112 | 113 | pthread_cond_broadcast(&(pool->queue_cond));//通知所有线程线程池销毁了 114 | int i; 115 | for(i=0; ithread_num; i++)//等待线程全部执行完 116 | pthread_join(pool->thread_queue[i], NULL); 117 | 118 | //销毁任务队列 119 | task *temp = NULL; 120 | while(pool->task_queue_head) 121 | { 122 | temp = pool->task_queue_head; 123 | pool->task_queue_head = pool->task_queue_head->next; 124 | free(temp); 125 | } 126 | //pool->task_queue_head = NULL; 127 | //pool->task_queue_end = NULL; 128 | 129 | //销毁线程队列 130 | free(pool->thread_queue); 131 | pool->thread_queue = NULL; 132 | 133 | pthread_mutex_destroy(&(pool->queue_mutex)); 134 | pthread_cond_destroy(&(pool->queue_cond)); 135 | 136 | free(pool); 137 | pool = NULL; 138 | 139 | return 0; 140 | } 141 | 142 | -------------------------------------------------------------------------------- /thread-pool/thread_pool.c: -------------------------------------------------------------------------------- 1 | #include "thread_pool.h" 2 | 3 | thread_pool *pool = NULL; 4 | static void * thread_pool_entrance(void *arg) 5 | { 6 | int thread_id = (int)arg; 7 | printf("thread %d is created\n",thread_id); 8 | 9 | while(1) 10 | { 11 | pthread_mutex_lock(&(pool->queue_mutex)); 12 | while(pool->task_queue_size == 0 && !pool->is_pool_destroyed)//必须用while,防止假唤醒 13 | { 14 | pthread_cond_wait(&(pool->queue_cond),&(pool->queue_mutex));//等待的时候会解锁,唤醒后加锁 15 | } 16 | 17 | if(pool->is_pool_destroyed) 18 | { 19 | printf("thread %d exit!!!\n",thread_id); 20 | pthread_mutex_unlock(&(pool->queue_mutex));//中途退出最容易出错,注意要解锁 21 | pthread_exit(NULL); 22 | } 23 | 24 | pool->idle_thread_num--;//线程进入忙碌状态 25 | //从任务队列中取出任务 26 | task *work; 27 | work = pool->task_queue_head; 28 | pool->task_queue_head = pool->task_queue_head->next; 29 | if(pool->task_queue_head == NULL) 30 | pool->task_queue_end = NULL; 31 | 32 | pool->task_queue_size--; 33 | 34 | pthread_mutex_unlock(&(pool->queue_mutex)); 35 | 36 | //回调函数 37 | (*(work->taskfunc))(work->arg); 38 | pool->idle_thread_num++;//线程空闲 39 | } 40 | return NULL; 41 | } 42 | 43 | 44 | int thread_pool_init(int thread_pool_size) 45 | { 46 | pool = (thread_pool *)malloc(sizeof(thread_pool));//不要最先给线程池分配空间 47 | 48 | pool->is_pool_destroyed = 0; 49 | 50 | pool->task_queue_head = NULL; 51 | pool->task_queue_end = NULL; 52 | pool->task_queue_size = 0; 53 | 54 | pool->thread_num = thread_pool_size; 55 | pool->thread_queue = (pthread_t *)malloc(thread_pool_size * sizeof(pthread_t)); 56 | pool->idle_thread_num = thread_pool_size; 57 | 58 | //创建线程 59 | int i, ret; 60 | for(i=0; ithread_queue[i]), NULL, thread_pool_entrance, (void *)i); 63 | if(ret < 0) 64 | { 65 | printf("thread create error!!!\n"); 66 | thread_pool_destroy();//注意销毁,避免内存泄漏 67 | return -1; 68 | } 69 | } 70 | 71 | pthread_mutex_init(&(pool->queue_mutex), NULL); 72 | pthread_cond_init(&(pool->queue_cond), NULL); 73 | 74 | return 0; 75 | } 76 | 77 | 78 | typedef void *(*taskfunc)(void *arg); 79 | int thread_pool_add_task(taskfunc func, void *arg) 80 | { 81 | task *newtask; 82 | newtask = (task *)malloc(sizeof(task)); 83 | newtask->taskfunc = func; 84 | newtask->arg = arg; 85 | newtask->next = NULL; 86 | 87 | pthread_mutex_lock(&(pool->queue_mutex)); 88 | 89 | if(pool->task_queue_head == NULL) 90 | { 91 | pool->task_queue_head = pool->task_queue_end = newtask; 92 | } 93 | else 94 | { 95 | pool->task_queue_end = pool->task_queue_end->next = newtask; 96 | } 97 | pool->task_queue_size++; 98 | 99 | pthread_cond_signal(&(pool->queue_cond)); 100 | pthread_mutex_unlock(&(pool->queue_mutex)); 101 | 102 | return 0; 103 | } 104 | 105 | 106 | int thread_pool_destroy() 107 | { 108 | if(pool->is_pool_destroyed)//防止多次销毁 109 | return -1; 110 | 111 | pool->is_pool_destroyed = 1; 112 | 113 | pthread_cond_broadcast(&(pool->queue_cond));//通知所有线程线程池销毁了 114 | int i; 115 | for(i=0; ithread_num; i++)//等待线程全部执行完 116 | pthread_join(pool->thread_queue[i], NULL); 117 | 118 | //销毁任务队列 119 | task *temp = NULL; 120 | while(pool->task_queue_head) 121 | { 122 | temp = pool->task_queue_head; 123 | pool->task_queue_head = pool->task_queue_head->next; 124 | free(temp); 125 | } 126 | //pool->task_queue_head = NULL; 127 | //pool->task_queue_end = NULL; 128 | 129 | //销毁线程队列 130 | free(pool->thread_queue); 131 | pool->thread_queue = NULL; 132 | 133 | pthread_mutex_destroy(&(pool->queue_mutex)); 134 | pthread_cond_destroy(&(pool->queue_cond)); 135 | 136 | free(pool); 137 | pool = NULL; 138 | 139 | return 0; 140 | } 141 | 142 | -------------------------------------------------------------------------------- /source-code-manager(开源的代码)/code/util/strings.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include "strings.h" 7 | 8 | #define MIN_STRING_SIZE 16 9 | 10 | struct _string 11 | { 12 | char *str; 13 | uint32_t strLen, strSize; 14 | }; 15 | 16 | void String_SetSize(String s, const uint32_t size) 17 | { 18 | if(s->strSize < size) 19 | { 20 | s->str = (char*)XREALLOC(s->str, size); 21 | memset(s->str+s->strSize, 0, size - s->strSize); 22 | s->strSize = size; 23 | } 24 | 25 | return; 26 | } 27 | 28 | String String_Create(void) 29 | { 30 | String s; 31 | s = (String)XMALLOC(sizeof(struct _string)); 32 | s->strLen = 0; 33 | s->strSize = MIN_STRING_SIZE; 34 | s->str = (char*)XMALLOC(s->strSize); 35 | memset(s->str, 0, s->strSize); 36 | return s; 37 | } 38 | 39 | void String_Delete(String s) 40 | { 41 | XFREE(s->str); 42 | XFREE(s); 43 | return; 44 | } 45 | 46 | void String_clone(String s, const String s1) 47 | { 48 | if(s1->strLen >= s->strSize) 49 | { 50 | String_SetSize(s, MIN_STRING_SIZE + s1->strLen); 51 | } 52 | s->strLen = s1->strLen; 53 | strncpy(s->str, s1->str, s1->strLen); 54 | return; 55 | } 56 | 57 | void String_add(String s, const String s1) 58 | { 59 | if((s1->strLen + s->strLen) >= s->strSize) 60 | { 61 | String_SetSize(s, MIN_STRING_SIZE + s1->strLen + s->strLen); 62 | } 63 | s->strLen = s1->strLen+s->strLen - 1; 64 | strncat(s->str, s1->str, s1->strLen); 65 | return; 66 | } 67 | 68 | int String_compare(const String s, const String s1) 69 | { 70 | return strcmp(s->str, s1->str); 71 | } 72 | 73 | int String_strcmp(const String s, const char *s1) 74 | { 75 | return strcmp(s->str, s1); 76 | } 77 | void String_strcpy(String s, const char *str) 78 | { 79 | if(NULL != str) 80 | { 81 | int len = strlen(str)+1; 82 | 83 | if(len >= s->strSize) 84 | { 85 | String_SetSize(s, MIN_STRING_SIZE + len); 86 | } 87 | s->strLen = len; 88 | strncpy(s->str, str, len); 89 | } 90 | else 91 | { 92 | LOG_ERROR("String_strcpy: trying to copy NULL string"); 93 | } 94 | return; 95 | } 96 | void String_strcat(String s, const char *str) 97 | { 98 | if(NULL != str) 99 | { 100 | int len = strlen(str); 101 | if((len+s->strLen) >= s->strSize) 102 | { 103 | String_SetSize(s, MIN_STRING_SIZE + len + s->strLen); 104 | } 105 | s->strLen += len; 106 | strncat(s->str, str, len); 107 | } 108 | return; 109 | } 110 | 111 | const char* s_getstr(const String s) 112 | { 113 | return (const char*)s->str; 114 | } 115 | 116 | int String_strlen(const String s) 117 | { 118 | return (int)(s->strLen-1); 119 | } 120 | 121 | void String_DebugPrint(const String s) 122 | { 123 | printf("\nLen : %d", s->strLen); 124 | printf("\nSize : %d", s->strSize); 125 | printf("\nstr : %s", s->str); 126 | printf("\n"); 127 | } 128 | 129 | int String_format(String s, const char *format, ...) 130 | { 131 | int len = MIN_STRING_SIZE; 132 | va_list v; 133 | do 134 | { 135 | va_start(v, format); 136 | String_SetSize(s, len+MIN_STRING_SIZE); 137 | len = vsnprintf(s->str, s->strSize, format, v); 138 | va_end(v); 139 | } 140 | while(len >= s->strSize); 141 | s->strLen = len+1; 142 | return len; 143 | } 144 | 145 | /*Converts the foldername to the following format 146 | * ./ 147 | * */ 148 | void String_NormalizeFolderName(String s) 149 | { 150 | if(isItFolder(s->str) || isItFile(s->str)) 151 | { 152 | char *ptr, buffer[1024]; 153 | ptr = realpath(s->str, NULL); 154 | getcwd(buffer, 1024); 155 | if(strncmp(ptr, buffer, strlen(buffer)) == 0) 156 | { 157 | int len = strlen(buffer); 158 | strcpy(s->str, "."); 159 | strcat(s->str, ptr+len); 160 | s->strLen = strlen(s->str); 161 | } 162 | else 163 | { 164 | LOG_INFO("fatal: '%s' is outsize repo!", s->str); 165 | exit(1); 166 | } 167 | XFREE(ptr); 168 | } 169 | else 170 | String_NormalizeFileName(s); 171 | return; 172 | } 173 | 174 | void String_NormalizeFileName(String s) 175 | { 176 | if(strncmp(s->str, "./", 2) != 0) 177 | { 178 | String_SetSize(s, s->strLen+5); 179 | memmove(s->str+2, s->str, s->strLen); 180 | s->str[0] = '.'; 181 | s->str[1] = '/'; 182 | s->strLen = s->strLen+2; 183 | s->str[s->strLen] = 0; 184 | } 185 | return; 186 | } 187 | -------------------------------------------------------------------------------- /source-code-manager(开源的代码)/code/util/file.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include "filelist.h" 8 | 9 | #define INT_SIZE sizeof(uint32_t) 10 | 11 | 12 | File File_Create(void) 13 | { 14 | File f = (File)XMALLOC(sizeof(struct _file)); 15 | f->filename = String_Create(); 16 | 17 | f->deleted = false; 18 | f->mode = f->mtime = f->size = 0; 19 | sha_reset(f->sha); 20 | return f; 21 | } 22 | 23 | void File_Clone(File f, const File f1) 24 | { 25 | String_clone(f->filename, f1->filename); 26 | f->mode = f1->mode; 27 | f->mtime = f1->mtime; 28 | f->size = f1->size; 29 | memcpy(f->sha, f1->sha, SHA_HASH_LENGTH); 30 | } 31 | void File_Delete(File f) 32 | { 33 | String_Delete(f->filename); 34 | XFREE(f); 35 | return; 36 | } 37 | 38 | bool File_SetFileData(File f, const char *filename, const bool computeSha) 39 | { 40 | bool returnValue = false; 41 | struct stat s; 42 | if(0 == stat(filename, &s)) 43 | { 44 | returnValue = true; 45 | 46 | String_strcpy(f->filename, filename); 47 | 48 | /*Save the file properties*/ 49 | f->mode = s.st_mode; 50 | f->mtime = s.st_mtime; 51 | f->size = s.st_size; 52 | 53 | /*compute the sha if necessary*/ 54 | if(S_ISREG(s.st_mode) && (true == computeSha)) 55 | { 56 | returnValue = sha_file(filename, f->sha); 57 | } 58 | else 59 | { 60 | f->sha[0] = '\0'; 61 | } 62 | } 63 | else 64 | { 65 | LOG_ERROR("File_SetFileData: File '%s' doesn't exist", filename); 66 | } 67 | return returnValue; 68 | } 69 | 70 | int File_Serialize(File f, unsigned char * const buffer, const int bufferSize) 71 | { 72 | int pos = 0; 73 | int Slen = strlen((char*)f->sha)+1; 74 | int mode, size, mtime, lenSha, lenFilename, totalLen; 75 | 76 | /*Total Length = sizeof(f->mode) + sizeof(f->size) + sizeof(f->mtime) + lenOfFilename + lenOfSha + SHA_HASH_LENGTH + strlen(Filename)*/ 77 | totalLen = INT_SIZE * 5 + String_strlen(f->filename) + Slen; 78 | if(totalLen > bufferSize) 79 | { 80 | return 0; 81 | } 82 | mode = htonl(f->mode); 83 | size = htonl(f->size); 84 | mtime = htonl(f->mtime); 85 | lenSha = htonl(Slen); 86 | lenFilename = htonl(String_strlen(f->filename)); 87 | 88 | memcpy(buffer + pos, &mode, INT_SIZE); pos += INT_SIZE; 89 | memcpy(buffer + pos, &size, INT_SIZE); pos += INT_SIZE; 90 | memcpy(buffer + pos, &mtime, INT_SIZE); pos += INT_SIZE; 91 | memcpy(buffer + pos, &lenSha, INT_SIZE); pos += INT_SIZE; 92 | memcpy(buffer + pos, &lenFilename, INT_SIZE); pos += INT_SIZE; 93 | memcpy(buffer + pos, f->sha, Slen); pos += Slen; 94 | 95 | memcpy(buffer + pos, s_getstr(f->filename), String_strlen(f->filename)); 96 | pos += String_strlen(f->filename); 97 | 98 | return totalLen; 99 | } 100 | bool File_DeSerialize(File f, unsigned const char *data, const int dataSize) 101 | { 102 | int pos = 0; 103 | char filename[1024]; 104 | int lenSha, lenFilename; 105 | 106 | if(dataSize < INT_SIZE*5) 107 | { 108 | LOG_ERROR("invalid dataSize %d, min size %d", dataSize, INT_SIZE *5); 109 | return false; 110 | } 111 | 112 | /*Get the size of each element in the record*/ 113 | memcpy(&(f->mode), data + pos, INT_SIZE); pos += INT_SIZE; 114 | memcpy(&(f->size), data + pos, INT_SIZE); pos += INT_SIZE; 115 | memcpy(&(f->mtime), data + pos, INT_SIZE); pos += INT_SIZE; 116 | memcpy(&lenSha, data + pos, INT_SIZE); pos += INT_SIZE; 117 | memcpy(&lenFilename, data + pos, INT_SIZE); pos += INT_SIZE; 118 | 119 | lenSha = ntohl(lenSha); 120 | f->mode = ntohl(f->mode); 121 | f->size = ntohl(f->size); 122 | f->mtime = ntohl(f->mtime); 123 | lenFilename = ntohl(lenFilename); 124 | if(lenSha > (SHA_HASH_LENGTH+1)) 125 | { 126 | LOG_ERROR("SHA length %d is not correct value, it should have been %d", lenSha, SHA_HASH_LENGTH+1); 127 | return false; 128 | } 129 | if(dataSize != (INT_SIZE * 5 + lenSha + lenFilename)) 130 | { 131 | LOG_ERROR("invalid dataSize %d, dataSize should have been %d, %d", dataSize, INT_SIZE * 5 + lenSha + lenFilename, lenSha); 132 | return false; 133 | } 134 | 135 | memcpy(f->sha, data + pos, lenSha); pos += lenSha; 136 | memcpy(filename, data + pos, lenFilename); pos += lenFilename; 137 | 138 | filename[lenFilename] = '\0'; 139 | String_strcpy(f->filename, filename); 140 | return true; 141 | } 142 | 143 | -------------------------------------------------------------------------------- /evServer.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include "common.h" 10 | #include "sock.h" 11 | #include "conn_pool.h" 12 | #include "mysql_encap.h" 13 | #include "thread_pool.h" 14 | #include "files.h" 15 | 16 | ev_io *accept_watcher; 17 | struct ev_loop *main_loop; 18 | int listen_fd;//声明 服务器监听fd 19 | //db连接池 20 | ConnPool* conn_pool; 21 | 22 | void setnonblocking(int sock); 23 | void accept_cb(struct ev_loop *main_loop, ev_io * io_w, int e); 24 | void send_cb(struct ev_loop *main_loop, ev_io * io_w, int e); 25 | void message_cb(struct ev_loop *main_loop, ev_io* io_w, int e); 26 | 27 | void *taskprocess(void *arg); 28 | void *addfile(void *arg); 29 | void *testadd(void *arg); 30 | void *testget(void *arg); 31 | 32 | int main() { 33 | 34 | main_loop = ev_default_loop(0); 35 | 36 | create_bind_listen(&listen_fd, 9999, 5); 37 | 38 | int reuse = 1; 39 | if(setsockopt(listen_fd,SOL_SOCKET ,SO_REUSEADDR,&reuse,sizeof(reuse)) != 0) { 40 | printf("setsockopt error in reuseaddr[%d]\n", listen_fd); 41 | } 42 | setnonblocking(listen_fd); 43 | 44 | signal(SIGPIPE, SIG_IGN); 45 | 46 | 47 | conn_pool = ConnPool::GetInstance();//bind 成功在初始化线程池 48 | thread_pool_init(5);//线程池 49 | 50 | accept_watcher = (struct ev_io *)malloc(sizeof(struct ev_io)); 51 | ev_io_init (accept_watcher, accept_cb, listen_fd, EV_READ); 52 | ev_io_start(main_loop,accept_watcher); 53 | 54 | ev_run(main_loop,0); 55 | 56 | return 0; 57 | } 58 | 59 | void setnonblocking(int sock) { 60 | int opts; 61 | opts = fcntl(sock, F_GETFL); 62 | if(opts < 0) { 63 | perror("fcntl(sock, GETFL)"); 64 | exit(1); 65 | } 66 | opts = opts | O_NONBLOCK; 67 | if(fcntl(sock, F_SETFL, opts) < 0) { 68 | perror("fcntl(sock,SETFL,opts)"); 69 | exit(1); 70 | } 71 | } 72 | 73 | void accept_cb(struct ev_loop *main_loop,ev_io *io_w,int e) { 74 | int conn_fd;//声明 连接的fd,也就是accept之后的 75 | struct sockaddr_in client_addr; 76 | socklen_t len = sizeof(client_addr); 77 | conn_fd = accept(io_w->fd, (struct sockaddr *)&client_addr, &len); 78 | //setnonblocking(conn_fd); /*后面传送文件,没有必要非阻塞*/ 79 | 80 | if(conn_fd > 0){ 81 | printf("got connection from ip:%s, port:%d\n",inet_ntoa(client_addr.sin_addr),ntohs(client_addr.sin_port)); 82 | //ev_io *send_watcher = (struct ev_io *)malloc(sizeof(struct ev_io)); 83 | //ev_io_init (send_watcher, send_cb, conn_fd, EV_WRITE); 84 | //ev_io_start(main_loop, send_watcher); 85 | 86 | ev_io *msg_watcher = (struct ev_io *)malloc(sizeof(struct ev_io)); 87 | ev_io_init (msg_watcher, message_cb, conn_fd, EV_READ); 88 | ev_io_start(main_loop, msg_watcher); 89 | } 90 | else if(conn_fd < 0){ 91 | printf("connection error ...\n"); 92 | } 93 | } 94 | 95 | void send_cb(struct ev_loop *main_loop, ev_io *io_w, int e) { 96 | printf("sock can write\n"); 97 | char path[512]; 98 | printf("input the path:"); 99 | scanf("%s",path); 100 | path[strlen(path)]='\0'; 101 | printf("%s-\n",path); 102 | //Send(path, io_w->fd); 103 | } 104 | void message_cb(struct ev_loop *main_loop, ev_io* io_w, int e) { 105 | message msg; 106 | int ret = recv(io_w->fd, &msg, sizeof(msg), 0); 107 | if(ret == -1){ 108 | perror("recv message error\n"); 109 | } 110 | printf("msg recv :%d\n", msg.cmd); 111 | ev_io_stop(main_loop, io_w); 112 | 113 | switch(msg.cmd){ 114 | case GET_FILES: 115 | { 116 | thread_pool_add_task(taskprocess,(void *)io_w->fd); 117 | break; 118 | } 119 | case ADD_FILES: 120 | printf("add files\n"); 121 | thread_pool_add_task(addfile,(void *)io_w->fd); 122 | break; 123 | case SEND_FILES: 124 | { 125 | char path[512]; 126 | printf("input the path:"); 127 | scanf("%s",path); 128 | path[strlen(path)]='\0'; 129 | printf("%s-\n",path); 130 | //Send(path, io_w->fd); 131 | break; 132 | } 133 | case TEST_ADD: 134 | { 135 | printf("-----------test add----------\n"); 136 | thread_pool_add_task(testadd,(void *)io_w->fd); 137 | break; 138 | } 139 | case TEST_GET: 140 | { 141 | printf("----------test get------------\n"); 142 | thread_pool_add_task(testget,(void *)io_w->fd); 143 | } 144 | default: 145 | break; 146 | } 147 | 148 | } 149 | void *testget(void *arg) { 150 | int sockfd = (int)arg; 151 | MysqlEncap *sql_conn = conn_pool->GetOneConn(); 152 | printf("server send file start 1:\n"); 153 | serverSendFile(sockfd, sql_conn); 154 | conn_pool->ReleaseOneConn(sql_conn); 155 | return NULL; 156 | } 157 | void *testadd(void *arg) { 158 | int sockfd = (int)arg; 159 | MysqlEncap *sql_conn = conn_pool->GetOneConn(); 160 | printf("server get file start 1:\n"); 161 | getFile(sockfd, sql_conn); 162 | conn_pool->ReleaseOneConn(sql_conn); 163 | return NULL; 164 | } 165 | void *addfile(void *arg) { 166 | return NULL; 167 | 168 | } 169 | 170 | void *taskprocess(void *arg) { 171 | int sockfd = (int)arg; 172 | MysqlEncap *sql_conn = conn_pool->GetOneConn(); 173 | // sql_conn->ExecuteQuery("select * from testdb.student;"); 174 | // while(sql_conn->FetchRow()){ 175 | // printf("%s,%s\n",sql_conn->GetField("sid"),sql_conn->GetField("name")); 176 | // } 177 | sql_conn->ExecuteQuery("select path from testdb.student where sid = 11;"); 178 | if(sql_conn->FetchRow()) { 179 | Send(sql_conn->GetField("path"), sockfd); 180 | } 181 | conn_pool->ReleaseOneConn(sql_conn); 182 | return NULL; 183 | } 184 | -------------------------------------------------------------------------------- /src2/evServer.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include "common.h" 10 | #include "sock.h" 11 | #include "conn_pool.h" 12 | #include "mysql_encap.h" 13 | #include "thread_pool.h" 14 | #include "files.h" 15 | 16 | ev_io *accept_watcher; 17 | struct ev_loop *main_loop; 18 | int listen_fd;//声明 服务器监听fd 19 | //db连接池 20 | ConnPool* conn_pool; 21 | 22 | void setnonblocking(int sock); 23 | void accept_cb(struct ev_loop *main_loop, ev_io * io_w, int e); 24 | void send_cb(struct ev_loop *main_loop, ev_io * io_w, int e); 25 | void message_cb(struct ev_loop *main_loop, ev_io* io_w, int e); 26 | 27 | void *taskprocess(void *arg); 28 | void *addfile(void *arg); 29 | void *testadd(void *arg); 30 | void *testget(void *arg); 31 | 32 | int main() { 33 | 34 | main_loop = ev_default_loop(0); 35 | 36 | create_bind_listen(&listen_fd, 9999, 5); 37 | 38 | int reuse = 1; 39 | if(setsockopt(listen_fd,SOL_SOCKET ,SO_REUSEADDR,&reuse,sizeof(reuse)) != 0) { 40 | printf("setsockopt error in reuseaddr[%d]\n", listen_fd); 41 | } 42 | setnonblocking(listen_fd); 43 | 44 | signal(SIGPIPE, SIG_IGN); 45 | 46 | 47 | conn_pool = ConnPool::GetInstance();//bind 成功在初始化线程池 48 | thread_pool_init(5);//线程池 49 | 50 | accept_watcher = (struct ev_io *)malloc(sizeof(struct ev_io)); 51 | ev_io_init (accept_watcher, accept_cb, listen_fd, EV_READ); 52 | ev_io_start(main_loop,accept_watcher); 53 | 54 | ev_run(main_loop,0); 55 | 56 | return 0; 57 | } 58 | 59 | void setnonblocking(int sock) { 60 | int opts; 61 | opts = fcntl(sock, F_GETFL); 62 | if(opts < 0) { 63 | perror("fcntl(sock, GETFL)"); 64 | exit(1); 65 | } 66 | opts = opts | O_NONBLOCK; 67 | if(fcntl(sock, F_SETFL, opts) < 0) { 68 | perror("fcntl(sock,SETFL,opts)"); 69 | exit(1); 70 | } 71 | } 72 | 73 | void accept_cb(struct ev_loop *main_loop,ev_io *io_w,int e) { 74 | int conn_fd;//声明 连接的fd,也就是accept之后的 75 | struct sockaddr_in client_addr; 76 | socklen_t len = sizeof(client_addr); 77 | conn_fd = accept(io_w->fd, (struct sockaddr *)&client_addr, &len); 78 | //setnonblocking(conn_fd); /*后面传送文件,没有必要非阻塞*/ 79 | 80 | if(conn_fd > 0){ 81 | printf("got connection from ip:%s, port:%d\n",inet_ntoa(client_addr.sin_addr),ntohs(client_addr.sin_port)); 82 | //ev_io *send_watcher = (struct ev_io *)malloc(sizeof(struct ev_io)); 83 | //ev_io_init (send_watcher, send_cb, conn_fd, EV_WRITE); 84 | //ev_io_start(main_loop, send_watcher); 85 | 86 | ev_io *msg_watcher = (struct ev_io *)malloc(sizeof(struct ev_io)); 87 | ev_io_init (msg_watcher, message_cb, conn_fd, EV_READ); 88 | ev_io_start(main_loop, msg_watcher); 89 | } 90 | else if(conn_fd < 0){ 91 | printf("connection error ...\n"); 92 | } 93 | } 94 | 95 | void send_cb(struct ev_loop *main_loop, ev_io *io_w, int e) { 96 | printf("sock can write\n"); 97 | char path[512]; 98 | printf("input the path:"); 99 | scanf("%s",path); 100 | path[strlen(path)]='\0'; 101 | printf("%s-\n",path); 102 | //Send(path, io_w->fd); 103 | } 104 | void message_cb(struct ev_loop *main_loop, ev_io* io_w, int e) { 105 | message msg; 106 | int ret = recv(io_w->fd, &msg, sizeof(msg), 0); 107 | if(ret == -1){ 108 | perror("recv message error\n"); 109 | } 110 | printf("msg recv :%d\n", msg.cmd); 111 | ev_io_stop(main_loop, io_w); 112 | 113 | switch(msg.cmd){ 114 | case GET_FILES: 115 | { 116 | thread_pool_add_task(taskprocess,(void *)io_w->fd); 117 | break; 118 | } 119 | case ADD_FILES: 120 | printf("add files\n"); 121 | thread_pool_add_task(addfile,(void *)io_w->fd); 122 | break; 123 | case SEND_FILES: 124 | { 125 | char path[512]; 126 | printf("input the path:"); 127 | scanf("%s",path); 128 | path[strlen(path)]='\0'; 129 | printf("%s-\n",path); 130 | //Send(path, io_w->fd); 131 | break; 132 | } 133 | case TEST_ADD: 134 | { 135 | printf("-----------test add----------\n"); 136 | thread_pool_add_task(testadd,(void *)io_w->fd); 137 | break; 138 | } 139 | case TEST_GET: 140 | { 141 | printf("----------test get------------\n"); 142 | thread_pool_add_task(testget,(void *)io_w->fd); 143 | } 144 | default: 145 | break; 146 | } 147 | 148 | } 149 | void *testget(void *arg) { 150 | int sockfd = (int)arg; 151 | MysqlEncap *sql_conn = conn_pool->GetOneConn(); 152 | printf("server send file start 1:\n"); 153 | serverSendFile(sockfd, sql_conn); 154 | conn_pool->ReleaseOneConn(sql_conn); 155 | return NULL; 156 | } 157 | void *testadd(void *arg) { 158 | int sockfd = (int)arg; 159 | MysqlEncap *sql_conn = conn_pool->GetOneConn(); 160 | printf("server get file start 1:\n"); 161 | getFile(sockfd, sql_conn); 162 | conn_pool->ReleaseOneConn(sql_conn); 163 | return NULL; 164 | } 165 | void *addfile(void *arg) { 166 | return NULL; 167 | 168 | } 169 | 170 | void *taskprocess(void *arg) { 171 | int sockfd = (int)arg; 172 | MysqlEncap *sql_conn = conn_pool->GetOneConn(); 173 | // sql_conn->ExecuteQuery("select * from testdb.student;"); 174 | // while(sql_conn->FetchRow()){ 175 | // printf("%s,%s\n",sql_conn->GetField("sid"),sql_conn->GetField("name")); 176 | // } 177 | sql_conn->ExecuteQuery("select path from testdb.student where sid = 11;"); 178 | if(sql_conn->FetchRow()) { 179 | Send(sql_conn->GetField("path"), sockfd); 180 | } 181 | conn_pool->ReleaseOneConn(sql_conn); 182 | return NULL; 183 | } 184 | -------------------------------------------------------------------------------- /src2/client.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include "common.h" 12 | #include "sha1.h" 13 | #include "files.h" 14 | 15 | #include "sock.h" 16 | 17 | #define WORKING_FOLDER_TAG ".wokingfolder.tag" 18 | #define PATH_LENGTH 256 19 | 20 | int getRealPath(char *path, char *realPath); 21 | bool checkFileExist(char *path); 22 | 23 | int main(int argc, char **argv){ 24 | int sock_fd; 25 | create_and_conn(&sock_fd, "127.0.0.1", 9999); 26 | while(1){ 27 | message msg; 28 | printf("input the cmd(0:add 1:get 2:send [3:add 4:get 5:wc-tag])\n"); 29 | int input; 30 | scanf("%d", &input); 31 | getchar();//去除stdin中的'\n' 32 | switch(input){ 33 | case INIT: { 34 | //create a tag in current working folder 35 | //to indicate this is the WC 36 | char mode[] = "0444"; 37 | int ret; 38 | int m = strtol(mode, 0, 8); 39 | ret = creat(WORKING_FOLDER_TAG, m); 40 | if(ret == -1) 41 | { 42 | perror("creat file"); 43 | } 44 | break; 45 | } 46 | case TEST_ADD: { 47 | int ret; 48 | printf("file need to transfer:"); 49 | char path [256]; 50 | char realpath[256]; 51 | scanf("%s",path); 52 | 53 | if(!checkFileExist(path)){ 54 | printf("Error:%s doesn't exist!\n", path); 55 | goto EXIT; 56 | } 57 | /*get real path, that is, have prefix*/ 58 | ret = getRealPath(path, realpath); 59 | if(ret == -1) { 60 | goto EXIT; 61 | } 62 | printf("real path:%s\n", realpath); 63 | 64 | 65 | //mes send after all is ok 66 | msg.cmd = TEST_ADD; 67 | ret = send(sock_fd, &msg, sizeof(msg), 0); 68 | if(ret == -1){ 69 | perror("send cmd msg\n"); 70 | } 71 | 72 | printf("-------------start send----------\n"); 73 | Send(realpath, sock_fd); 74 | printf("-------------end send ----------\n"); 75 | break; 76 | 77 | } 78 | 79 | case TEST_GET: { 80 | int ret; 81 | printf("file need to Get:"); 82 | char path [256]; 83 | char realpath[256]; 84 | scanf("%s",path); 85 | 86 | /*get real path, that is, have prefix*/ 87 | ret = getRealPath(path, realpath); 88 | if(ret == -1) { 89 | goto EXIT;//return -1; 90 | } 91 | printf("real path:%s\n", realpath); 92 | 93 | getchar(); 94 | char version[32]; 95 | scanf("%s", version); 96 | getchar(); 97 | int byLatestVersion, recursive; 98 | scanf("%d %d", &byLatestVersion, &recursive); 99 | 100 | //msg send after all is ok 101 | msg.cmd = TEST_GET; 102 | ret = send(sock_fd, &msg, sizeof(msg), 0); 103 | if(ret == -1){ 104 | perror("send cmd msg\n"); 105 | } 106 | printf("-------------start Get----------\n"); 107 | clientGetFile(sock_fd, realpath, version, recursive, byLatestVersion); 108 | printf("-------------end Get ----------\n"); 109 | break; 110 | } 111 | 112 | case ADD_FILES:{ 113 | msg.cmd = ADD_FILES; 114 | int ret = send(sock_fd, &msg, sizeof(msg), 0); 115 | if(ret == -1){ 116 | perror("send cmd msg\n"); 117 | } 118 | break; 119 | } 120 | case GET_FILES:{ 121 | msg.cmd = GET_FILES; 122 | int ret = send(sock_fd, &msg, sizeof(msg), 0); 123 | if(ret == -1){ 124 | perror("send msg\n"); 125 | } 126 | //getFile(sock_fd); 127 | break; 128 | } 129 | case SEND_FILES:{ 130 | msg.cmd = SEND_FILES; 131 | int ret = send(sock_fd, &msg, sizeof(msg), 0); 132 | if(ret == -1){ 133 | perror("send msg\n"); 134 | } 135 | //getFile(sock_fd); 136 | break; 137 | } 138 | } 139 | break; 140 | 141 | //getFile(sock_fd); 142 | } 143 | 144 | EXIT: 145 | close(sock_fd); 146 | return 0; 147 | 148 | } 149 | 150 | bool checkFileExist(char *path) { 151 | if(access(path, F_OK) != 0) { /*file not exist*/ 152 | return false; 153 | } 154 | return true; 155 | } 156 | 157 | /* 158 | * according to the working fold, get the real path name. 159 | * e.g. 160 | * the path is 'file.txt', but the working folder is not in 161 | * this folder, it is in the parent folder 'src'. so the real 162 | * path name should be 'src/file.txt' which is the identification 163 | * in the server 164 | * 165 | * how: serch the parent folder to search the wc-tag file 166 | */ 167 | int getRealPath(char *path, char *realpath) { 168 | char pwd[PATH_LENGTH]; 169 | getcwd(pwd, PATH_LENGTH); 170 | char tmppwd[PATH_LENGTH]; 171 | strcpy(tmppwd, pwd); 172 | /*get the real path*/ 173 | while(1) { 174 | char tmp[PATH_LENGTH]; 175 | if(access(WORKING_FOLDER_TAG, F_OK) != 0) { /*file not exist*/ 176 | if(strcmp(tmppwd, "/") == 0) 177 | { 178 | printf("*** Set a WC first! ****\n"); 179 | chdir(pwd); 180 | return -1; 181 | } 182 | getParent(tmp, tmppwd); 183 | if(strcmp(tmp, "") == 0) 184 | strcpy(tmp, "/"); 185 | chdir(tmp); 186 | memset(tmppwd, 0, sizeof(tmppwd)); 187 | strcpy(tmppwd, tmp); 188 | } else { 189 | break; 190 | } 191 | } 192 | chdir(pwd); 193 | 194 | if(strlen(tmppwd) != strlen(pwd)) { /*path is not real path*/ 195 | char *p; 196 | if(strcmp(tmppwd, "/") == 0) { 197 | p = pwd + 1; 198 | } else { 199 | p = pwd + strlen(tmppwd)+1; /*discard the front '/'*/ 200 | } 201 | sprintf(realpath, "%s/%s", p, path); 202 | } else { 203 | strcpy(realpath, path); 204 | } 205 | 206 | return 0; 207 | } -------------------------------------------------------------------------------- /mysql_encap.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | *问题一: 怎么判断数据库其实已经断开了,查询一次这种太耗时了吧 3 | * 目前的做法是,在查询的时候如果抛出异常,则进行重连 4 | **/ 5 | #include "mysql_encap.h" 6 | #include 7 | #include 8 | #include 9 | #include 10 | 11 | 12 | using namespace std; 13 | 14 | /*构造函数*/ 15 | MysqlEncap::MysqlEncap(){ 16 | isConnected = false; 17 | sql_result = NULL; 18 | mysql_init(&sql_conn); 19 | } 20 | /*析构函数*/ 21 | MysqlEncap::~MysqlEncap(){ 22 | FreeResult(); 23 | CloseConnect(); 24 | } 25 | /**************************************************** 26 | * 建立数据库连接 27 | * ip: 数据库主机ip 28 | * username: 登录mysql用户名 29 | * password: 密码 30 | ****************************************************/ 31 | bool MysqlEncap::Connect(const char *ip, const char *username, const 32 | char *password){ 33 | hostip_ = ip; 34 | username_ = username; 35 | password_ = password; 36 | if(isConnected){ 37 | return true; 38 | } 39 | if(mysql_real_connect(&sql_conn, ip, username, password, 40 | NULL, 0, NULL, 0) == NULL){ 41 | fprintf(stderr, "%s\n", mysql_error(&sql_conn)); 42 | return false; 43 | } 44 | isConnected = true; 45 | printf("connect establish [user:%s]\n",username); 46 | return true; 47 | } 48 | 49 | /************************************************ 50 | * 关闭连接 51 | ************************************************/ 52 | void MysqlEncap::CloseConnect(){ 53 | mysql_close(&sql_conn); 54 | isConnected = false; 55 | } 56 | 57 | /************************************************ 58 | * 重新连接 59 | ************************************************/ 60 | bool MysqlEncap::ReConnect(){ 61 | CloseConnect(); 62 | if(mysql_real_connect(&sql_conn, hostip_.c_str(), username_.c_str(), password_.c_str(), 63 | NULL, 0, NULL, 0) == NULL){ 64 | fprintf(stderr,"Reconnect:%s\n", mysql_error(&sql_conn)); 65 | return false; 66 | } 67 | isConnected = true; 68 | return true; 69 | } 70 | /************************************************ 71 | * 检查连接,如果连接断开则重连 72 | ************************************************/ 73 | 74 | 75 | /************************************************ 76 | * 查询语句 77 | ************************************************/ 78 | bool MysqlEncap::ExecuteQuery(const char *sql){ 79 | printf("sql:%s\n",sql); 80 | assert(sql != NULL); 81 | if(sql == NULL) 82 | return true; 83 | if(!isConnected){ 84 | fprintf(stderr,"connection was not established\n"); 85 | bCommit = false;//如果有事务,出错不能提交 86 | } 87 | try{ 88 | if(mysql_real_query(&sql_conn, sql, strlen(sql)) != 0){ 89 | fprintf(stderr, "select query error\n"); 90 | bCommit = false; 91 | return false; 92 | } 93 | FreeResult(); 94 | sql_result = mysql_store_result(&sql_conn); 95 | } catch(...){ 96 | ReConnect();//这种情况是在,执行语句没有出错的情况下,抛出的异常,另外isConnected = true 97 | isConnected = true; 98 | bCommit = false;//如果有事务,出错不能提交 99 | return false; 100 | } 101 | fieldcnt = mysql_num_fields(sql_result); 102 | mapFiledToIndex.clear(); 103 | MYSQL_FIELD *fields = mysql_fetch_fields(sql_result); 104 | for(int i=0; i= fieldcnt){ 194 | fprintf(stderr,"the index is out of bound"); 195 | return NULL; 196 | } 197 | return sql_row[fieldnum]; 198 | } 199 | 200 | 201 | 202 | 203 | 204 | 205 | 206 | 207 | 208 | 209 | 210 | 211 | -------------------------------------------------------------------------------- /src2/mysql_encap.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | *问题一: 怎么判断数据库其实已经断开了,查询一次这种太耗时了吧 3 | * 目前的做法是,在查询的时候如果抛出异常,则进行重连 4 | **/ 5 | #include "mysql_encap.h" 6 | #include 7 | #include 8 | #include 9 | #include 10 | 11 | 12 | using namespace std; 13 | 14 | /*构造函数*/ 15 | MysqlEncap::MysqlEncap(){ 16 | isConnected = false; 17 | sql_result = NULL; 18 | mysql_init(&sql_conn); 19 | } 20 | /*析构函数*/ 21 | MysqlEncap::~MysqlEncap(){ 22 | FreeResult(); 23 | CloseConnect(); 24 | } 25 | /**************************************************** 26 | * 建立数据库连接 27 | * ip: 数据库主机ip 28 | * username: 登录mysql用户名 29 | * password: 密码 30 | ****************************************************/ 31 | bool MysqlEncap::Connect(const char *ip, const char *username, const 32 | char *password){ 33 | hostip_ = ip; 34 | username_ = username; 35 | password_ = password; 36 | if(isConnected){ 37 | return true; 38 | } 39 | if(mysql_real_connect(&sql_conn, ip, username, password, 40 | NULL, 0, NULL, 0) == NULL){ 41 | fprintf(stderr, "%s\n", mysql_error(&sql_conn)); 42 | return false; 43 | } 44 | isConnected = true; 45 | printf("connect establish [user:%s]\n",username); 46 | return true; 47 | } 48 | 49 | /************************************************ 50 | * 关闭连接 51 | ************************************************/ 52 | void MysqlEncap::CloseConnect(){ 53 | mysql_close(&sql_conn); 54 | isConnected = false; 55 | } 56 | 57 | /************************************************ 58 | * 重新连接 59 | ************************************************/ 60 | bool MysqlEncap::ReConnect(){ 61 | CloseConnect(); 62 | if(mysql_real_connect(&sql_conn, hostip_.c_str(), username_.c_str(), password_.c_str(), 63 | NULL, 0, NULL, 0) == NULL){ 64 | fprintf(stderr,"Reconnect:%s\n", mysql_error(&sql_conn)); 65 | return false; 66 | } 67 | isConnected = true; 68 | return true; 69 | } 70 | /************************************************ 71 | * 检查连接,如果连接断开则重连 72 | ************************************************/ 73 | 74 | 75 | /************************************************ 76 | * 查询语句 77 | ************************************************/ 78 | bool MysqlEncap::ExecuteQuery(const char *sql){ 79 | printf("sql:%s\n",sql); 80 | assert(sql != NULL); 81 | if(sql == NULL) 82 | return true; 83 | if(!isConnected){ 84 | fprintf(stderr,"connection was not established\n"); 85 | bCommit = false;//如果有事务,出错不能提交 86 | } 87 | try{ 88 | if(mysql_real_query(&sql_conn, sql, strlen(sql)) != 0){ 89 | fprintf(stderr, "select query error\n"); 90 | bCommit = false; 91 | return false; 92 | } 93 | FreeResult(); 94 | sql_result = mysql_store_result(&sql_conn); 95 | } catch(...){ 96 | ReConnect();//这种情况是在,执行语句没有出错的情况下,抛出的异常,另外isConnected = true 97 | isConnected = true; 98 | bCommit = false;//如果有事务,出错不能提交 99 | return false; 100 | } 101 | fieldcnt = mysql_num_fields(sql_result); 102 | mapFiledToIndex.clear(); 103 | MYSQL_FIELD *fields = mysql_fetch_fields(sql_result); 104 | for(int i=0; i= fieldcnt){ 194 | fprintf(stderr,"the index is out of bound"); 195 | return NULL; 196 | } 197 | return sql_row[fieldnum]; 198 | } 199 | 200 | 201 | 202 | 203 | 204 | 205 | 206 | 207 | 208 | 209 | 210 | 211 | -------------------------------------------------------------------------------- /src/mysql_encap.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | *问题一: 怎么判断数据库其实已经断开了,查询一次这种太耗时了吧 3 | * 目前的做法是,在查询的时候如果抛出异常,则进行重连 4 | **/ 5 | #include "mysql_encap.h" 6 | #include 7 | #include 8 | #include 9 | #include 10 | 11 | 12 | using namespace std; 13 | 14 | /*构造函数*/ 15 | MysqlEncap::MysqlEncap(){ 16 | isConnected = false; 17 | sql_result = NULL; 18 | mysql_init(&sql_conn); 19 | } 20 | /*析构函数*/ 21 | MysqlEncap::~MysqlEncap(){ 22 | FreeResult(); 23 | CloseConnect(); 24 | } 25 | /**************************************************** 26 | * 建立数据库连接 27 | * ip: 数据库主机ip 28 | * username: 登录mysql用户名 29 | * password: 密码 30 | ****************************************************/ 31 | bool MysqlEncap::Connect(const char *ip, const char *username, const 32 | char *password){ 33 | hostip_ = ip; 34 | username_ = username; 35 | password_ = password; 36 | if(isConnected){ 37 | return true; 38 | } 39 | if(mysql_real_connect(&sql_conn, ip, username, password, 40 | NULL, 0, NULL, 0) == NULL){ 41 | fprintf(stderr, "%s\n", mysql_error(&sql_conn)); 42 | return false; 43 | } 44 | isConnected = true; 45 | printf("connect establish [user:%s]\n",username); 46 | return true; 47 | } 48 | 49 | /************************************************ 50 | * 关闭连接 51 | ************************************************/ 52 | void MysqlEncap::CloseConnect(){ 53 | mysql_close(&sql_conn); 54 | isConnected = false; 55 | } 56 | 57 | /************************************************ 58 | * 重新连接 59 | ************************************************/ 60 | bool MysqlEncap::ReConnect(){ 61 | CloseConnect(); 62 | if(mysql_real_connect(&sql_conn, hostip_.c_str(), username_.c_str(), password_.c_str(), 63 | NULL, 0, NULL, 0) == NULL){ 64 | fprintf(stderr,"Reconnect:%s\n", mysql_error(&sql_conn)); 65 | return false; 66 | } 67 | isConnected = true; 68 | return true; 69 | } 70 | /************************************************ 71 | * 检查连接,如果连接断开则重连 72 | ************************************************/ 73 | 74 | 75 | /************************************************ 76 | * 查询语句 77 | ************************************************/ 78 | bool MysqlEncap::ExecuteQuery(const char *sql){ 79 | printf("sql:%s\n",sql); 80 | assert(sql != NULL); 81 | if(sql == NULL) 82 | return true; 83 | if(!isConnected){ 84 | fprintf(stderr,"connection was not established\n"); 85 | bCommit = false;//如果有事务,出错不能提交 86 | } 87 | try{ 88 | if(mysql_real_query(&sql_conn, sql, strlen(sql)) != 0){ 89 | fprintf(stderr, "select query error\n"); 90 | bCommit = false; 91 | return false; 92 | } 93 | FreeResult(); 94 | sql_result = mysql_store_result(&sql_conn); 95 | } catch(...){ 96 | ReConnect();//这种情况是在,执行语句没有出错的情况下,抛出的异常,另外isConnected = true 97 | isConnected = true; 98 | bCommit = false;//如果有事务,出错不能提交 99 | return false; 100 | } 101 | fieldcnt = mysql_num_fields(sql_result); 102 | mapFiledToIndex.clear(); 103 | MYSQL_FIELD *fields = mysql_fetch_fields(sql_result); 104 | for(int i=0; i= fieldcnt){ 198 | fprintf(stderr,"the index is out of bound"); 199 | return NULL; 200 | } 201 | return sql_row[fieldnum]; 202 | } 203 | 204 | 205 | 206 | 207 | 208 | 209 | 210 | 211 | 212 | 213 | 214 | 215 | -------------------------------------------------------------------------------- /mysql-encap/mysql_encap.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | *问题一: 怎么判断数据库其实已经断开了,查询一次这种太耗时了吧 3 | * 目前的做法是,在查询的时候如果抛出异常,则进行重连 4 | **/ 5 | #include "mysql_encap.h" 6 | #include 7 | #include 8 | #include 9 | #include 10 | 11 | 12 | using namespace std; 13 | 14 | /*构造函数*/ 15 | MysqlEncap::MysqlEncap(){ 16 | isConnected = false; 17 | sql_result = NULL; 18 | mysql_init(&sql_conn); 19 | } 20 | /*析构函数*/ 21 | MysqlEncap::~MysqlEncap(){ 22 | FreeResult(); 23 | CloseConnect(); 24 | } 25 | /**************************************************** 26 | * 建立数据库连接 27 | * ip: 数据库主机ip 28 | * username: 登录mysql用户名 29 | * password: 密码 30 | ****************************************************/ 31 | bool MysqlEncap::Connect(const char *ip, const char *username, const 32 | char *password){ 33 | hostip_ = ip; 34 | username_ = username; 35 | password_ = password; 36 | if(isConnected){ 37 | return true; 38 | } 39 | if(mysql_real_connect(&sql_conn, ip, username, password, 40 | NULL, 0, NULL, 0) == NULL){ 41 | fprintf(stderr, "%s\n", mysql_error(&sql_conn)); 42 | return false; 43 | } 44 | isConnected = true; 45 | printf("connect establish [user:%s]\n",username); 46 | return true; 47 | } 48 | 49 | /************************************************ 50 | * 关闭连接 51 | ************************************************/ 52 | void MysqlEncap::CloseConnect(){ 53 | mysql_close(&sql_conn); 54 | isConnected = false; 55 | } 56 | 57 | /************************************************ 58 | * 重新连接 59 | ************************************************/ 60 | bool MysqlEncap::ReConnect(){ 61 | CloseConnect(); 62 | if(mysql_real_connect(&sql_conn, hostip_.c_str(), username_.c_str(), password_.c_str(), 63 | NULL, 0, NULL, 0) == NULL){ 64 | fprintf(stderr,"Reconnect:%s\n", mysql_error(&sql_conn)); 65 | return false; 66 | } 67 | isConnected = true; 68 | return true; 69 | } 70 | /************************************************ 71 | * 检查连接,如果连接断开则重连 72 | ************************************************/ 73 | 74 | 75 | /************************************************ 76 | * 查询语句 77 | ************************************************/ 78 | bool MysqlEncap::ExecuteQuery(const char *sql){ 79 | printf("sql:%s\n",sql); 80 | assert(sql != NULL); 81 | if(sql == NULL) 82 | return true; 83 | if(!isConnected){ 84 | fprintf(stderr,"connection was not established\n"); 85 | bCommit = false;//如果有事务,出错不能提交 86 | } 87 | try{ 88 | if(mysql_real_query(&sql_conn, sql, strlen(sql)) != 0){ 89 | fprintf(stderr, "select query error\n"); 90 | bCommit = false; 91 | return false; 92 | } 93 | FreeResult(); 94 | sql_result = mysql_store_result(&sql_conn); 95 | } catch(...){ 96 | ReConnect();//这种情况是在,执行语句没有出错的情况下,抛出的异常,另外isConnected = true 97 | isConnected = true; 98 | bCommit = false;//如果有事务,出错不能提交 99 | return false; 100 | } 101 | fieldcnt = mysql_num_fields(sql_result); 102 | mapFiledToIndex.clear(); 103 | MYSQL_FIELD *fields = mysql_fetch_fields(sql_result); 104 | for(int i=0; i= fieldcnt){ 198 | fprintf(stderr,"the index is out of bound"); 199 | return NULL; 200 | } 201 | return sql_row[fieldnum]; 202 | } 203 | 204 | 205 | 206 | 207 | 208 | 209 | 210 | 211 | 212 | 213 | 214 | 215 | -------------------------------------------------------------------------------- /src/evServer.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include "common.h" 10 | #include "sock.h" 11 | #include "conn_pool.h" 12 | #include "mysql_encap.h" 13 | #include "thread_pool.h" 14 | #include "files.h" 15 | 16 | ev_io *accept_watcher; 17 | struct ev_loop *main_loop; 18 | int listen_fd;//声明 服务器监听fd 19 | //db连接池 20 | ConnPool* conn_pool; 21 | 22 | void setnonblocking(int sock); 23 | void accept_cb(struct ev_loop *main_loop, ev_io * io_w, int e); 24 | void message_cb(struct ev_loop *main_loop, ev_io* io_w, int e); 25 | 26 | void *add(void *arg); 27 | void *get(void *arg); 28 | void *showhistory(void *arg); 29 | void *dotag(void *arg) ; 30 | void *showtag(void *arg); 31 | void *getVersionByTag(void *arg); 32 | 33 | int main() { 34 | 35 | main_loop = ev_default_loop(0); 36 | 37 | create_bind_listen(&listen_fd, 9999, 5); 38 | 39 | int reuse = 1; 40 | if(setsockopt(listen_fd,SOL_SOCKET ,SO_REUSEADDR, &reuse, sizeof(reuse)) != 0) { 41 | printf("setsockopt error in reuseaddr[%d]\n", listen_fd); 42 | } 43 | setnonblocking(listen_fd); 44 | 45 | signal(SIGPIPE, SIG_IGN); 46 | 47 | 48 | conn_pool = ConnPool::GetInstance();//bind 成功在初始化线程池 49 | thread_pool_init(5);//线程池 50 | 51 | accept_watcher = (struct ev_io *)malloc(sizeof(struct ev_io)); 52 | ev_io_init (accept_watcher, accept_cb, listen_fd, EV_READ); 53 | ev_io_start(main_loop,accept_watcher); 54 | 55 | ev_run(main_loop,0); 56 | 57 | return 0; 58 | } 59 | 60 | void setnonblocking(int sock) { 61 | int opts; 62 | opts = fcntl(sock, F_GETFL); 63 | if(opts < 0) { 64 | perror("fcntl(sock, GETFL)"); 65 | exit(1); 66 | } 67 | opts = opts | O_NONBLOCK; 68 | if(fcntl(sock, F_SETFL, opts) < 0) { 69 | perror("fcntl(sock,SETFL,opts)"); 70 | exit(1); 71 | } 72 | } 73 | 74 | void accept_cb(struct ev_loop *main_loop, ev_io *io_w, int e) { 75 | int conn_fd;//声明 连接的fd,也就是accept之后的 76 | struct sockaddr_in client_addr; 77 | socklen_t len = sizeof(client_addr); 78 | conn_fd = accept(io_w->fd, (struct sockaddr *)&client_addr, &len); 79 | //setnonblocking(conn_fd); /*后面传送文件,没有必要非阻塞*/ 80 | 81 | if(conn_fd > 0){ 82 | printf("got connection from ip:%s, port:%d\n",inet_ntoa(client_addr.sin_addr),ntohs(client_addr.sin_port)); 83 | 84 | ev_io *msg_watcher = (struct ev_io *)malloc(sizeof(struct ev_io)); 85 | ev_io_init (msg_watcher, message_cb, conn_fd, EV_READ); 86 | ev_io_start(main_loop, msg_watcher); 87 | } 88 | else if(conn_fd < 0){ 89 | printf("connection error ...\n"); 90 | } 91 | } 92 | 93 | 94 | void message_cb(struct ev_loop *main_loop, ev_io* io_w, int e) { 95 | message msg; 96 | int ret = recv(io_w->fd, &msg, sizeof(msg), 0); 97 | if(ret == -1){ 98 | perror("recv message error\n"); 99 | } else if(0 == ret) { 100 | printf("client quit!\n"); 101 | ev_io_stop(main_loop, io_w);//stop watch...when return 102 | return; 103 | } 104 | printf("cmd recv :%d\n", msg.cmd); 105 | ev_io_stop(main_loop, io_w); 106 | 107 | switch(msg.cmd){ 108 | case ADD: 109 | { 110 | thread_pool_add_task(add, (void *)io_w->fd); 111 | break; 112 | } 113 | case GET: 114 | { 115 | thread_pool_add_task(get, (void *)io_w->fd); 116 | break; 117 | } 118 | case HISTORY: 119 | { 120 | thread_pool_add_task(showhistory, (void *)io_w->fd); 121 | break; 122 | } 123 | case TAG: 124 | { 125 | thread_pool_add_task(dotag, (void *)io_w->fd); 126 | break; 127 | } 128 | case SHOW_TAG: 129 | { 130 | thread_pool_add_task(showtag, (void *)io_w->fd); 131 | break; 132 | } 133 | case GET_VERSION_BY_TAG: 134 | { 135 | thread_pool_add_task(getVersionByTag, (void *)io_w->fd); 136 | break; 137 | } 138 | default: 139 | break; 140 | } 141 | 142 | } 143 | void *getVersionByTag(void *arg) { 144 | int sockfd = (int)arg; 145 | 146 | MysqlEncap *sql_conn = conn_pool->GetOneConn(); 147 | 148 | serverSendVersionByTagName(sockfd, sql_conn); 149 | 150 | conn_pool->ReleaseOneConn(sql_conn); 151 | 152 | return NULL; 153 | } 154 | void *showtag(void *arg) { 155 | int sockfd = (int)arg; 156 | 157 | MysqlEncap *sql_conn = conn_pool->GetOneConn(); 158 | 159 | serverSendTag(sockfd, sql_conn); 160 | 161 | conn_pool->ReleaseOneConn(sql_conn); 162 | 163 | return NULL; 164 | } 165 | void *dotag(void *arg) { 166 | int sockfd = (int)arg; 167 | 168 | MysqlEncap *sql_conn = conn_pool->GetOneConn(); 169 | sql_conn->StartTransaction();//开启一个事务 170 | 171 | serverDoTag(sockfd, sql_conn); 172 | 173 | sql_conn->EndTransaction(); 174 | conn_pool->ReleaseOneConn(sql_conn); 175 | return NULL; 176 | } 177 | void *showhistory(void *arg) { 178 | int sockfd = (int)arg; 179 | 180 | MysqlEncap *sql_conn = conn_pool->GetOneConn(); 181 | 182 | serverSendHistory(sockfd, sql_conn); 183 | 184 | conn_pool->ReleaseOneConn(sql_conn); 185 | 186 | return NULL; 187 | } 188 | //client get, that is, server send 189 | void *get(void *arg) { 190 | int sockfd = (int)arg; 191 | 192 | MysqlEncap *sql_conn = conn_pool->GetOneConn(); 193 | //sql query doesn't need transaction 194 | //sql_conn->StartTransaction();//开启一个事务 195 | 196 | serverSendFile(sockfd, sql_conn); 197 | 198 | //sql_conn->EndTransaction(); 199 | conn_pool->ReleaseOneConn(sql_conn); 200 | 201 | return NULL; 202 | } 203 | //client add, that is, server get 204 | void *add(void *arg) { 205 | int sockfd = (int)arg; 206 | 207 | MysqlEncap *sql_conn = conn_pool->GetOneConn(); 208 | sql_conn->StartTransaction();//开启一个事务 209 | 210 | getFile(sockfd, sql_conn); 211 | 212 | sql_conn->EndTransaction(); 213 | conn_pool->ReleaseOneConn(sql_conn); 214 | return NULL; 215 | } -------------------------------------------------------------------------------- /source-code-manager(开源的代码)/code/src/commit.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | 11 | #include "scm.h" 12 | #include "commit.h" 13 | #include "common.h" 14 | 15 | 16 | Commit Commit_Create(void) 17 | { 18 | Commit c; 19 | c = (Commit)XMALLOC(sizeof(struct _Commit)); 20 | sha_reset(c->parent0); 21 | sha_reset(c->parent1); 22 | sha_reset(c->tree); 23 | c->author = String_Create(); 24 | c->message = String_Create(); 25 | c->rawtime = 0; 26 | return c; 27 | } 28 | 29 | void Commit_Delete(Commit c) 30 | { 31 | String_Delete(c->author); 32 | String_Delete(c->message); 33 | XFREE(c); 34 | return ; 35 | } 36 | 37 | void Commit_Reset(Commit c) 38 | { 39 | sha_reset(c->parent0); 40 | sha_reset(c->parent1); 41 | sha_reset(c->tree); 42 | c->rawtime = 0; 43 | String_strcpy(c->author, "\0"); 44 | String_strcpy(c->message, "\0"); 45 | return; 46 | } 47 | 48 | bool Commit_SetParent(Commit c, const ShaBuffer parent0, const ShaBuffer parent1) 49 | { 50 | memcpy(c->parent0, parent0, SHA_HASH_LENGTH); 51 | memcpy(c->parent1, parent1, SHA_HASH_LENGTH); 52 | return true; 53 | } 54 | 55 | bool Commit_SetTree(Commit c, const ShaBuffer tree) 56 | { 57 | int len = strlen((char*)tree); 58 | if(len < SHA_HASH_LENGTH) 59 | { 60 | LOG_ERROR("Commit_SetTree() Sha length %d != %d", len, SHA_HASH_LENGTH); 61 | return false; 62 | } 63 | memcpy(c->tree, tree, SHA_HASH_LENGTH); 64 | return true; 65 | } 66 | 67 | bool Commit_SetAuthor(Commit c, const char *authorName, const char *authorEmailId) 68 | { 69 | String_format(c->author, "%s <%s>", authorName, authorEmailId); 70 | return true; 71 | } 72 | 73 | bool Commit_SetMessage(Commit c, const char *message) 74 | { 75 | String_strcpy(c->message, message); 76 | return true; 77 | } 78 | 79 | #define INT_SIZE sizeof(uint32_t) 80 | bool Commit_WriteCommitFile(Commit c, ShaBuffer commitSha) 81 | { 82 | uint32_t fd, temp, dummy; 83 | bool returnValue = false; 84 | String s = String_Create(); 85 | 86 | c->rawtime = time(NULL); 87 | String_format(s, "%s:%s:%s:%u", c->tree, c->parent0, c->parent1, (uint32_t)c->rawtime); 88 | 89 | sha_buffer((const unsigned char *)s_getstr(s), String_strlen(s), commitSha); 90 | String_format(s,"%s/%s", SCM_COMMIT_FOLDER, commitSha); 91 | if(true == isItFile(s_getstr(s))) 92 | { 93 | LOG_ERROR("fatal Commit_WriteCommitFile() commit '%s' already exist", commitSha); 94 | abort(); 95 | } 96 | fd = open(s_getstr(s), O_CREAT | O_TRUNC | O_WRONLY, SCM_OBJECT_FILE_PERMISSION); 97 | if(fd < 0) 98 | { 99 | LOG_ERROR("Commit_WriteCommitFile() open('%s') failed(%d)", s_getstr(s), errno); 100 | goto EXIT; 101 | } 102 | 103 | /*Write the object identification Code..*/ 104 | temp = htonl(OBJECT_COMMIT_FILE); 105 | dummy = write(fd, &temp, INT_SIZE); 106 | 107 | /*time */ 108 | temp = htonl(c->rawtime); 109 | dummy = write(fd, &temp, INT_SIZE); 110 | 111 | /*size of tree SHA*/ 112 | temp = htonl(strlen((char*)c->tree)+1); 113 | dummy = write(fd, &temp, INT_SIZE); 114 | dummy = write(fd, c->tree, ntohl(temp)); 115 | 116 | /*size of parent0*/ 117 | temp = htonl(strlen((char*)c->parent0)+1); 118 | dummy = write(fd, &temp, INT_SIZE); 119 | dummy = write(fd, c->parent0, ntohl(temp)); 120 | 121 | /*size of parent1*/ 122 | temp = htonl(strlen((char*)c->parent1)+1); 123 | dummy = write(fd, &temp, INT_SIZE); 124 | dummy = write(fd, c->parent1, ntohl(temp)); 125 | 126 | /*length of author*/ 127 | temp = htonl(String_strlen(c->author)+1); 128 | dummy = write(fd, &temp, INT_SIZE); 129 | dummy = write(fd, s_getstr(c->author), ntohl(temp)); 130 | 131 | /*length of message*/ 132 | temp = htonl(String_strlen(c->message)+1); 133 | dummy = write(fd, &temp, INT_SIZE); 134 | dummy = write(fd, s_getstr(c->message), ntohl(temp)); 135 | returnValue = true; 136 | close(fd); 137 | EXIT: 138 | String_Delete(s); 139 | return returnValue; 140 | } 141 | 142 | bool Commit_ReadCommitFile(Commit c, const ShaBuffer commitSha) 143 | { 144 | String s = String_Create(); 145 | bool returnValue = false; 146 | uint32_t fd, len = strlen((char*)commitSha), temp, dummy; 147 | if(len != SHA_HASH_LENGTH) 148 | { 149 | LOG_ERROR("Commit_ReadCommitFile() shaLength %d != %d", len, SHA_HASH_LENGTH); 150 | goto EXIT; 151 | } 152 | 153 | String_format(s,"%s/%s", SCM_COMMIT_FOLDER, commitSha); 154 | if(false == isItFile(s_getstr(s))) 155 | { 156 | LOG_ERROR("fatal Commit_ReadCommitFile() commit '%s' doesn't exist", commitSha); 157 | goto EXIT; 158 | } 159 | fd = open(s_getstr(s), O_RDONLY); 160 | 161 | 162 | /*read the object identification Code and check it*/ 163 | dummy = read(fd, &temp, INT_SIZE); 164 | temp = ntohl(temp); 165 | if(temp != OBJECT_COMMIT_FILE) 166 | { 167 | LOG_ERROR("Commit_ReadCommitFile: '%s' not a commit file", commitSha); 168 | close(fd); 169 | goto EXIT; 170 | } 171 | 172 | /*read the time*/ 173 | dummy = read(fd, &temp, INT_SIZE); 174 | c->rawtime = ntohl(temp); 175 | 176 | /*read the tree Sha*/ 177 | dummy = read(fd, &temp, INT_SIZE); 178 | temp = ntohl(temp); 179 | dummy = read(fd, c->tree, temp); 180 | 181 | /*read parent0*/ 182 | dummy = read(fd, &temp, INT_SIZE); 183 | temp = ntohl(temp); 184 | dummy = read(fd, c->parent0, temp); 185 | 186 | /*read parent1*/ 187 | dummy = read(fd, &temp, INT_SIZE); 188 | temp = ntohl(temp); 189 | dummy = read(fd, c->parent1, temp); 190 | 191 | /*read the author name and EmailId*/ 192 | dummy = read(fd, &temp, INT_SIZE); 193 | temp = ntohl(temp); 194 | String_SetSize(c->author,temp+10); 195 | dummy = read(fd, (void*)s_getstr(c->author), temp); 196 | 197 | /*read the message*/ 198 | dummy = read(fd, &temp, INT_SIZE); 199 | temp = ntohl(temp); 200 | String_SetSize(c->message,temp+10); 201 | dummy = read(fd, (void*)s_getstr(c->message), temp); 202 | 203 | returnValue = true; 204 | close(fd); 205 | EXIT: 206 | String_Delete(s); 207 | return returnValue; 208 | } 209 | 210 | -------------------------------------------------------------------------------- /source-code-manager(开源的代码)/code/src/branch.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include "cmds.h" 7 | #include "sha.h" 8 | #include "strings.h" 9 | #include "filelist.h" 10 | #include "common.h" 11 | #include "scm.h" 12 | #include "obj.h" 13 | #include "commit.h" 14 | 15 | 16 | bool printAllBranches(void) 17 | { 18 | File *list; 19 | String branch; 20 | uint32_t num, i, len = strlen(SCM_BRANCH_FOLDER); 21 | FileList f; 22 | bool returnValue = false; 23 | 24 | f = FileList_Create(); 25 | branch = String_Create(); 26 | if(getBranchName(branch) == false) 27 | { 28 | LOG_ERROR("current branch not set!!"); 29 | goto EXIT; 30 | } 31 | 32 | FileList_GetDirectoryConents(f, SCM_BRANCH_FOLDER,false,false); 33 | list = FileList_GetListDetails(f,&num); 34 | 35 | for(i = 0; i < num; i++) 36 | { 37 | if(strcmp(s_getstr(list[i]->filename)+len+3, s_getstr(branch)) == 0) 38 | LOG_INFO("*%s", s_getstr(list[i]->filename)+len+3); 39 | else 40 | LOG_INFO(" %s", s_getstr(list[i]->filename)+len+3); 41 | } 42 | returnValue = true; 43 | EXIT: 44 | FileList_Delete(f); 45 | String_Delete(branch); 46 | return returnValue; 47 | } 48 | 49 | bool createNewBranch(String branchName) 50 | { 51 | FILE *fp; 52 | bool returnValue = false; 53 | String temp = String_Create(); 54 | String currentBranch = String_Create(); 55 | Commit currentCommit = Commit_Create(); 56 | ShaBuffer commitSha; 57 | String_format(temp, "%s/%s", SCM_BRANCH_FOLDER, s_getstr(branchName)); 58 | if(isItFolder(s_getstr(temp))) 59 | { 60 | LOG_ERROR("branch '%s' already exist's. try with another name", s_getstr(branchName)); 61 | goto EXIT; 62 | } 63 | if(false == getCurrentCommit(currentCommit,commitSha)) 64 | { 65 | LOG_ERROR("commit not set in the current branch"); 66 | goto EXIT; 67 | } 68 | if(0 != mkdir(s_getstr(temp), SCM_FOLDER_PERMISSION)) 69 | { 70 | LOG_ERROR("fatal: mkdir('%s') failed(%d)", s_getstr(temp), errno); 71 | goto EXIT; 72 | } 73 | String_format(temp, "%s/%s/%s", SCM_BRANCH_FOLDER, s_getstr(branchName), SCM_BRANCH_CACHE_FOLDER); 74 | if(0 != mkdir(s_getstr(temp), SCM_FOLDER_PERMISSION)) 75 | { 76 | LOG_ERROR("fatal: mkdir('%s') failed(%d)", s_getstr(temp), errno); 77 | goto EXIT; 78 | } 79 | 80 | String_format(temp, "%s/%s/%s", SCM_BRANCH_FOLDER, s_getstr(branchName), SCM_INDEX_FILENAME); 81 | copyTreeFromRepo(currentCommit->tree, s_getstr(temp), SCM_HEAD_FILE_PERMISSION); 82 | 83 | 84 | String_format(temp, "%s/%s/%s", SCM_BRANCH_FOLDER, s_getstr(branchName), SCM_COMMIT_FILENAME); 85 | fp = fopen(s_getstr(temp), "w"); 86 | if(NULL == fp) 87 | { 88 | LOG_ERROR("unable to write into commit file '%s'", s_getstr(temp)); 89 | goto EXIT; 90 | } 91 | fprintf(fp, "%s\n", commitSha); 92 | fclose(fp); 93 | LOG_INFO("created branch '%s' pointing to commit '%s'", s_getstr(branchName), commitSha); 94 | EXIT: 95 | Commit_Delete(currentCommit); 96 | String_Delete(temp); 97 | String_Delete(currentBranch); 98 | return returnValue; 99 | } 100 | 101 | int difference(File ref, File n,DifferenceType type, void *data) 102 | { 103 | String branch = (String)data; 104 | String temp = String_Create(); 105 | switch(type) 106 | { 107 | case FILE_NEW: 108 | if(S_ISDIR(n->mode)) 109 | mkdir(s_getstr(n->filename), n->mode); 110 | else 111 | { 112 | /*if file is not found in repo then check in cache*/ 113 | String_format(temp, "%s/%s/%s/%s", SCM_BRANCH_FOLDER, s_getstr(branch), SCM_BRANCH_CACHE_FOLDER, n->sha); 114 | if(isItFile(s_getstr(temp))) 115 | { 116 | /*File Found in cache*/ 117 | decompressAndSave(s_getstr(temp),s_getstr(n->filename),n->mode); 118 | } 119 | else if(false == copyFileFromRepo(n)) 120 | { 121 | /*File not found in repo... what to do now?*/ 122 | } 123 | 124 | } 125 | break; 126 | case FILE_DELETED: 127 | if(isItFile(s_getstr(ref->filename))) 128 | unlink(s_getstr(ref->filename)); 129 | else 130 | { 131 | String_format(temp, "rm -rf %s", s_getstr(ref->filename)); 132 | system(s_getstr(temp)); 133 | String_Delete(temp); 134 | return 0; //skip this folder 135 | } 136 | break; 137 | case FILE_MODIFIED: 138 | if(S_ISREG(n->mode)) 139 | { 140 | /*if file is not found in repo then check in cache*/ 141 | String_format(temp, "%s/%s/%s/%s", SCM_BRANCH_FOLDER, s_getstr(branch), SCM_BRANCH_CACHE_FOLDER, n->sha); 142 | if(isItFile(s_getstr(temp))) 143 | { 144 | /*File Found in cache*/ 145 | decompressAndSave(s_getstr(temp),s_getstr(n->filename),n->mode); 146 | } 147 | else if(false == copyFileFromRepo(n)) 148 | { 149 | /*File not found in repo... what to do now?*/ 150 | } 151 | } 152 | else 153 | { 154 | chmod(s_getstr(n->filename), n->mode); 155 | } 156 | break; 157 | case FILE_LAST_VALUE: 158 | default: 159 | break; 160 | } 161 | 162 | String_Delete(temp); 163 | return 1; 164 | } 165 | bool setWorkingAreaToBranch(String branch) 166 | { 167 | String temp; 168 | bool returnValue = false; 169 | FileList currentList, nextList; 170 | 171 | currentList = FileList_Create(); 172 | nextList = FileList_Create(); 173 | temp = String_Create(); 174 | 175 | /*check is the branch exist*/ 176 | String_format(temp, "%s/%s", SCM_BRANCH_FOLDER, s_getstr(branch)); 177 | if(false == isItFolder(s_getstr(temp))) 178 | { 179 | LOG_INFO("branch '%s' doesn't exist", s_getstr(branch)); 180 | goto EXIT; 181 | } 182 | /*if the working area differes from index, then backout from branching*/ 183 | if(true == compareIndexWithWorkingArea()) 184 | { 185 | LOG_ERROR("working changes not reflected in index, add them to index and try again"); 186 | goto EXIT; 187 | } 188 | if(false == readIndexFile(currentList, NULL)) 189 | { 190 | goto EXIT; 191 | } 192 | String_format(temp, "%s/%s/%s", SCM_BRANCH_FOLDER, s_getstr(branch), SCM_INDEX_FILENAME); 193 | if(false == FileList_DeSerialize(nextList, s_getstr(temp))) 194 | goto EXIT; 195 | /* Now copy all the file of this branch to work area. The copy is done in 196 | * difference() function. We first analyse what has modified in these 2 branch 197 | * and just restore the changes.*/ 198 | if(false == FileList_GetDifference(currentList,nextList,difference, branch)) 199 | { 200 | goto EXIT; 201 | } 202 | setBranchName(branch); 203 | returnValue = true; 204 | EXIT: 205 | FileList_Delete(nextList); 206 | FileList_Delete(currentList); 207 | String_Delete(temp); 208 | return returnValue; 209 | } 210 | int cmd_branch(int argc, char *argv[]) 211 | { 212 | String s, branchName; 213 | bool createBranch, setBranch; 214 | 215 | s = String_Create(); 216 | branchName = String_Create(); 217 | createBranch = setBranch = false; 218 | 219 | if(argc >= 3) 220 | { 221 | int o; 222 | while((o = getopt(argc, argv, "hc:s:")) != -1) 223 | { 224 | switch(o) 225 | { 226 | case 'c': 227 | String_strcpy(branchName, optarg); 228 | createBranch = true; 229 | break; 230 | case 's': 231 | String_strcpy(branchName, optarg); 232 | setBranch = true; 233 | break; 234 | case 'h': 235 | default: 236 | LOG_ERROR("usage %s %s [-c ] [-s ]\nWhen run with no arguments prints all the branchs", argv[0], argv[1]); 237 | goto EXIT; 238 | } 239 | } 240 | } 241 | if((true == setBranch) && (true == createBranch)) 242 | { 243 | LOG_ERROR("Lets do one at a time!! first create the branch and then try to set it"); 244 | goto EXIT; 245 | } 246 | if((false == setBranch) && (false == createBranch)) 247 | { 248 | printAllBranches(); 249 | } 250 | 251 | if(true == createBranch) 252 | { 253 | createNewBranch(branchName); 254 | } 255 | if(true == setBranch) 256 | { 257 | if(true == setWorkingAreaToBranch(branchName)) 258 | LOG_INFO("Switch to branch '%s'", s_getstr(branchName)); 259 | } 260 | EXIT: 261 | String_Delete(s); 262 | String_Delete(branchName); 263 | return 0; 264 | } 265 | -------------------------------------------------------------------------------- /source-code-manager(开源的代码)/code/util/common.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include "common.h" 11 | 12 | #define MIN_MEMORY_TO_ALLOCATE 16 13 | 14 | static int numOfBytesAllocated = 0; 15 | void* XMALLOC(size_t size) 16 | { 17 | void *ptr; 18 | if(MIN_MEMORY_TO_ALLOCATE > size) 19 | size = MIN_MEMORY_TO_ALLOCATE; 20 | numOfBytesAllocated += size; 21 | ptr = malloc(size); 22 | if(NULL == ptr) 23 | { 24 | LOG_ERROR("unable to allocate memory of size %d", size); 25 | exit(1); 26 | } 27 | return ptr; 28 | } 29 | 30 | void PrintAllocatedBytes(void) 31 | { 32 | LOG_INFO("numOfBytesAllocated :%d", numOfBytesAllocated); 33 | return; 34 | } 35 | void* XREALLOC(void *p, size_t size) 36 | { 37 | void *ptr; 38 | ptr = realloc(p, size); 39 | if(NULL == ptr) 40 | { 41 | LOG_ERROR("unable to [Re]allocate memory of size %d", size); 42 | exit(1); 43 | } 44 | return ptr; 45 | } 46 | 47 | 48 | int Nstrlen(const char *str) 49 | { 50 | int len = 0 ; 51 | if(NULL != str) 52 | { 53 | while(str[len] != 0) 54 | len++; 55 | } 56 | return len; 57 | } 58 | int getTime(char buffer[64]) 59 | { 60 | time_t t; 61 | struct tm *tim; 62 | t = time(NULL); 63 | tim = localtime(&t); 64 | strftime(buffer, 64, "%a %b %d %H:%M:%S %Y", tim); 65 | return 0; 66 | } 67 | 68 | bool isItFolder(const char *name) 69 | { 70 | struct stat s; 71 | if(0 == stat(name, &s)) 72 | { 73 | if(S_ISDIR(s.st_mode)) 74 | return true; 75 | } 76 | return false; 77 | } 78 | 79 | bool isItFile(const char *name) 80 | { 81 | struct stat s; 82 | if(0 == stat(name, &s)) 83 | { 84 | if(S_ISREG(s.st_mode)) 85 | return true; 86 | } 87 | return false; 88 | } 89 | 90 | 91 | 92 | /*This below is got from zpipe.c, which comes part of the zlib library. 93 | * The 2 functions are used to compress and decompress files...*/ 94 | 95 | #define CHUNK 16384 96 | 97 | /* Compress from file source to file dest until EOF on source. 98 | def() returns Z_OK on success, Z_MEM_ERROR if memory could not be 99 | allocated for processing, Z_STREAM_ERROR if an invalid compression 100 | level is supplied, Z_VERSION_ERROR if the version of zlib.h and the 101 | version of the library linked do not match, or Z_ERRNO if there is 102 | an error reading or writing the files. */ 103 | bool compressAndSave(const char *sourceFile, const char *destFile, int mode) 104 | { 105 | int ret, flush; 106 | unsigned have; 107 | z_stream strm; 108 | unsigned char in[CHUNK]; 109 | unsigned char out[CHUNK]; 110 | FILE *source, *dest; 111 | 112 | source = fopen(sourceFile, "r"); 113 | if(NULL == source) 114 | { 115 | LOG_ERROR("unable to open file '%s'", sourceFile); 116 | return false; 117 | } 118 | dest = fopen(destFile, "w"); 119 | if(NULL == dest) 120 | { 121 | LOG_ERROR("unable to open file '%s'", destFile); 122 | fclose(source); 123 | return false; 124 | } 125 | /* allocate deflate state */ 126 | strm.zalloc = NULL; 127 | strm.zfree = NULL; 128 | strm.opaque = NULL; 129 | ret = deflateInit(&strm, Z_BEST_SPEED); 130 | if (ret != Z_OK) 131 | return ret; 132 | 133 | /* compress until end of file */ 134 | do { 135 | strm.avail_in = fread(in, 1, CHUNK, source); 136 | if (ferror(source)) { 137 | (void)deflateEnd(&strm); 138 | return false; 139 | } 140 | flush = feof(source) ? Z_FINISH : Z_NO_FLUSH; 141 | strm.next_in = in; 142 | 143 | /* run deflate() on input until output buffer not full, finish 144 | compression if all of source has been read in */ 145 | do { 146 | strm.avail_out = CHUNK; 147 | strm.next_out = out; 148 | ret = deflate(&strm, flush); /* no bad return value */ 149 | assert(ret != Z_STREAM_ERROR); /* state not clobbered */ 150 | have = CHUNK - strm.avail_out; 151 | if (fwrite(out, 1, have, dest) != have || ferror(dest)) { 152 | (void)deflateEnd(&strm); 153 | return false; 154 | } 155 | } while (strm.avail_out == 0); 156 | assert(strm.avail_in == 0); /* all input will be used */ 157 | 158 | /* done when last data in file processed */ 159 | } while (flush != Z_FINISH); 160 | fclose(source); 161 | fclose(dest); 162 | chmod(destFile, mode); 163 | /* clean up and return */ 164 | (void)deflateEnd(&strm); 165 | return true; 166 | } 167 | 168 | /* Decompress from file source to file dest until stream ends or EOF. 169 | inf() returns Z_OK on success, Z_MEM_ERROR if memory could not be 170 | allocated for processing, Z_DATA_ERROR if the deflate data is 171 | invalid or incomplete, Z_VERSION_ERROR if the version of zlib.h and 172 | the version of the library linked do not match, or Z_ERRNO if there 173 | is an error reading or writing the files. */ 174 | bool decompressAndSave(const char *sourceFile, const char *destFile, int mode) 175 | { 176 | int ret; 177 | unsigned have; 178 | z_stream strm; 179 | unsigned char in[CHUNK]; 180 | unsigned char out[CHUNK]; 181 | FILE *source, *dest; 182 | source = fopen(sourceFile, "r"); 183 | if(NULL == source) 184 | { 185 | LOG_ERROR("unable to open file '%s'", sourceFile); 186 | return false; 187 | } 188 | dest = fopen(destFile, "w"); 189 | if(NULL == destFile) 190 | { 191 | LOG_ERROR("unable to open file '%s'", destFile); 192 | fclose(source); 193 | return false; 194 | } 195 | /* allocate inflate state */ 196 | strm.zalloc = Z_NULL; 197 | strm.zfree = Z_NULL; 198 | strm.opaque = Z_NULL; 199 | strm.avail_in = 0; 200 | strm.next_in = Z_NULL; 201 | ret = inflateInit(&strm); 202 | if (ret != Z_OK) 203 | return ret; 204 | 205 | /* decompress until deflate stream ends or end of file */ 206 | do { 207 | strm.avail_in = fread(in, 1, CHUNK, source); 208 | if (ferror(source)) { 209 | (void)inflateEnd(&strm); 210 | return false; 211 | } 212 | if (strm.avail_in == 0) 213 | break; 214 | strm.next_in = in; 215 | 216 | /* run inflate() on input until output buffer not full */ 217 | do { 218 | strm.avail_out = CHUNK; 219 | strm.next_out = out; 220 | ret = inflate(&strm, Z_NO_FLUSH); 221 | assert(ret != Z_STREAM_ERROR); /* state not clobbered */ 222 | switch (ret) { 223 | case Z_NEED_DICT: 224 | ret = Z_DATA_ERROR; /* and fall through */ 225 | case Z_DATA_ERROR: 226 | case Z_MEM_ERROR: 227 | (void)inflateEnd(&strm); 228 | return false; 229 | } 230 | have = CHUNK - strm.avail_out; 231 | if (fwrite(out, 1, have, dest) != have || ferror(dest)) { 232 | (void)inflateEnd(&strm); 233 | return Z_ERRNO; 234 | } 235 | } while (strm.avail_out == 0); 236 | 237 | /* done when inflate() says it's done */ 238 | } while (ret != Z_STREAM_END); 239 | 240 | fclose(source); 241 | fclose(dest); 242 | chmod(destFile, mode); 243 | /* clean up and return */ 244 | (void)inflateEnd(&strm); 245 | return ret == Z_STREAM_END ? true : false; 246 | } 247 | bool copyFile(const char *source, const char *destination, const int mode) 248 | { 249 | bool returnValue = false; 250 | int fd_s, fd_d, len; 251 | char buffer[MAX_BUFFER_SIZE]; 252 | 253 | fd_s = open(source, O_RDONLY); 254 | if(0 > fd_s) 255 | { 256 | LOG_ERROR("open(%s) failed(%d)", source, errno); 257 | goto EXIT; 258 | } 259 | fd_d = open(destination, O_CREAT | O_TRUNC | O_WRONLY, mode); 260 | if(0 > fd_d) 261 | { 262 | LOG_ERROR("open(%s) failed(%d)", destination, errno); 263 | close(fd_s); 264 | goto EXIT; 265 | } 266 | 267 | while((len = read(fd_s, buffer, MAX_BUFFER_SIZE)) != 0) 268 | { 269 | if(len != write(fd_d, buffer, len)) 270 | { 271 | LOG_ERROR("write() failed(%d) to write specified number of bytes ", errno); 272 | returnValue = false; 273 | close(fd_s); 274 | close(fd_d); 275 | goto EXIT; 276 | } 277 | } 278 | 279 | returnValue = true; 280 | close(fd_s); 281 | close(fd_d); 282 | 283 | chmod(destination, mode); /*Set the mode of the files..*/ 284 | EXIT: 285 | return returnValue; 286 | } 287 | -------------------------------------------------------------------------------- /sock.h: -------------------------------------------------------------------------------- 1 | #ifndef SOCK_H_ 2 | #define SOCK_H_ 3 | 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include 12 | #include 13 | #include 14 | #include 15 | #define USE_SENDFILE_ 1 16 | 17 | /*也是可以留着在配置里面修改的*/ 18 | #define BUFSIZE 4096*1024 19 | 20 | #define HANDLE_ERROR_EXIT(error_string) do{perror(error_string);exit(-1);}while(0) 21 | 22 | //typedef struct{ 23 | // char filename[236]; 24 | // char filelen[16]; 25 | // int cmd; 26 | //}FileHeader;//256 byte 27 | 28 | /*server*/ 29 | void create_bind_listen(int *listen_fd, int port, int backlog){ 30 | 31 | *listen_fd = socket(AF_INET, SOCK_STREAM, 0); 32 | if(-1 == *listen_fd){ 33 | HANDLE_ERROR_EXIT("can not create sock"); 34 | } 35 | 36 | struct sockaddr_in server_addr; 37 | memset(&server_addr, 0, sizeof(server_addr)); 38 | 39 | server_addr.sin_port = htons(port); 40 | server_addr.sin_family = AF_INET; 41 | server_addr.sin_addr.s_addr = htonl(INADDR_ANY); 42 | 43 | int ret; 44 | ret = bind(*listen_fd, (struct sockaddr *)&server_addr, sizeof(server_addr)); 45 | if(-1 == ret){ 46 | HANDLE_ERROR_EXIT("can not bind"); 47 | } 48 | ret = listen(*listen_fd, backlog); 49 | if(-1 == ret){ 50 | HANDLE_ERROR_EXIT("can not listen"); 51 | } 52 | } 53 | 54 | /*client*/ 55 | void create_and_conn(int *sock_fd, char *ip, int port){ 56 | *sock_fd = socket(AF_INET, SOCK_STREAM, 0); 57 | if(-1 == *sock_fd){ 58 | HANDLE_ERROR_EXIT("can not create sock"); 59 | } 60 | struct sockaddr_in server_addr; 61 | memset(&server_addr, 0, sizeof(server_addr)); 62 | 63 | server_addr.sin_family = AF_INET; 64 | server_addr.sin_port = htons(port); 65 | server_addr.sin_addr.s_addr = inet_addr(ip); 66 | 67 | int ret; 68 | ret = connect(*sock_fd, (struct sockaddr *)&server_addr, sizeof(struct sockaddr)); 69 | if(-1 == ret){ 70 | HANDLE_ERROR_EXIT("can not bind"); 71 | } 72 | } 73 | 74 | ///*send file info*/ 75 | //void SendFileInfo(char *path, int conn_fd, off_t size, int end){ 76 | // FileHeader header; 77 | // //printf("^^^^^^%s^^^%d\n",path,(int)size); 78 | // strncpy(header.filename, path, strlen(path)+1); 79 | // //header.filename[strlen(header.filename)]='\0'; 80 | // sprintf(header.filelen, "%d", (int)size); 81 | // header.cmd = end;//0 not end 82 | 83 | // int ret; 84 | // ret = send(conn_fd, &header, sizeof(header), 0); 85 | // if(-1 == ret){ 86 | // perror("send file name"); 87 | // } 88 | // if(end != 1) 89 | // printf("filename:%s, file len:%s Byte\n",header.filename,header.filelen); 90 | //} 91 | 92 | //void processPathName(char *);//declare 93 | //void getFile(int conn_fd){ 94 | // while(1){ 95 | // /*get file name*/ 96 | // int ret; 97 | // FileHeader header; 98 | // ret = recv(conn_fd, &header, sizeof(header), 0); 99 | // if(-1 == ret){ 100 | // perror("recv fileinfo"); 101 | // } 102 | // if(header.cmd == 1)//end of transfer 103 | // break; 104 | // 105 | // processPathName(header.filename);// now , main for mkdir recursively 106 | // 107 | // printf("------->%s<---\n",header.filename); 108 | // char cwd[512]; 109 | // getcwd(cwd,512); 110 | // printf("cwd:%s\n",cwd); 111 | // 112 | // /*if file exists, override or cancel*/ 113 | // int flag = 1;//write or not 114 | // /*file exist*/ 115 | // if(access(header.filename,F_OK) == 0){ 116 | // //fprintf(stderr,"current dir have a file with the same name[%s]!", header.filename); 117 | // printf("current dir have a file with the same name[%s]! continue?(yes or no)\n", header.filename); 118 | // 119 | // while(1){ 120 | // char cmd[10]; 121 | // fgets(cmd, 10, stdin); 122 | // cmd[strlen(cmd)-1]='\0';// discard '\n' 123 | // printf("cmd:%s-\n",cmd); 124 | // if(!strncmp(cmd,"no",2)){ 125 | // flag = 0; 126 | // break; 127 | // }else if(!strncmp(cmd, "yes", 3)){ 128 | // break; 129 | // }else{ 130 | // printf("invalid input! please input again[yes or no]!\n"); 131 | // } 132 | // } 133 | // } 134 | // if(flag){ 135 | // FILE *fp = fopen(header.filename, "w"); 136 | // int byteleft; 137 | // byteleft = atoi(header.filelen); 138 | 139 | 140 | // int len; 141 | // char buf[BUFSIZE]; 142 | // while(byteleft){ 143 | // printf("byte left:%d\n",byteleft); 144 | // len = recv(conn_fd, buf,byteleft>=BUFSIZE?BUFSIZE-1:byteleft, 0);//代码应该在这个地方有问题 145 | // printf("len recv:%d\n",len); 146 | // if(len == 0){ 147 | // printf("server quit...\n"); 148 | // break; 149 | // }else if(len < 0){ 150 | // printf("receive error...\n"); 151 | // break; 152 | // } 153 | // byteleft-=len; 154 | // fwrite(buf, sizeof(char), len, fp); 155 | // //printf("---------------\n%s\n--------------\n",buf); 156 | // memset(buf, 0, sizeof(buf)); 157 | // 158 | // } 159 | // fclose(fp); 160 | // } 161 | // } 162 | //} 163 | 164 | 165 | ///*send file*/ 166 | //void SendFile(char *path, int conn_fd, off_t size){ 167 | 168 | // SendFileInfo(path, conn_fd, size, 0);//发送文件名 169 | //#ifdef USE_SENDFILE_ 170 | // //struct stat s; 171 | // int filefd = open(path, O_RDONLY); 172 | // sendfile(conn_fd, filefd, NULL, size); 173 | // close(filefd); 174 | //#else 175 | // FILE *fp = fopen(path, "r"); 176 | // if(fp == NULL){ 177 | // perror("open file"); 178 | // } 179 | // int file_size; 180 | // int len; 181 | // char buf[BUFSIZE]; 182 | // while((file_size = fread(buf, sizeof(char), BUFSIZE, fp)) > 0){ 183 | // len = send(conn_fd, buf, file_size, 0); 184 | // memset(buf, 0, sizeof(buf)); 185 | // if(len < 0) { 186 | // perror("send"); 187 | // } 188 | // else if(len == 0) 189 | // { 190 | // perror("client quit the connection"); 191 | // } 192 | // } 193 | // fclose(fp); 194 | //#endif 195 | //} 196 | ///*send dir*/ 197 | //void SendDir(char *path, int conn_fd){ 198 | // struct dirent *temp_path; 199 | // struct stat s; 200 | // DIR *dir; 201 | // char newpath[512]; 202 | 203 | // dir = opendir(path); 204 | // if(dir == NULL){ 205 | // perror("opendir error"); 206 | // return; 207 | // } 208 | // while((temp_path = readdir(dir))!=NULL){ 209 | // 210 | // if(!strcmp(temp_path->d_name,".")||!strcmp(temp_path->d_name,"..")) 211 | // continue; 212 | // sprintf(newpath, "%s/%s", path, temp_path->d_name); 213 | // 214 | // lstat(newpath, &s); 215 | // if(S_ISDIR(s.st_mode)){ 216 | // SendDir(newpath, conn_fd); 217 | // }else if(S_ISREG(s.st_mode)){ 218 | // SendFile(newpath, conn_fd, s.st_size); 219 | // } 220 | // } 221 | // closedir(dir); 222 | //} 223 | ///*send file or dir*/ 224 | //void Send(char *path, int conn_fd){ 225 | // struct stat s; 226 | // lstat(path, &s); 227 | // if(S_ISREG(s.st_mode)){ 228 | // SendFile(path, conn_fd, s.st_size); 229 | // }else if(S_ISDIR(s.st_mode)){ 230 | // SendDir(path, conn_fd); 231 | // } 232 | // SendFileInfo(path, conn_fd, 0, 1);//1 for end of file transfer 233 | //} 234 | 235 | 236 | ///* 237 | //* parse the fullpath name(/chengshuguang/a.txt), get the filename(a.txt) and the parent dir(/chenshuguang/). 238 | //*/ 239 | 240 | //int getFileName(char* filename,char *parent, const char* fullpath, int maxlen) { 241 | // char strtmp[128], *head; 242 | // //char strtmp2[128], *head2; 243 | // const char *tail; 244 | // int tmp; 245 | // tmp = strlen(fullpath); 246 | // tail = fullpath + tmp - 1; 247 | // while (*tail == '/') /*去掉结尾所有的‘/’*/ 248 | // tail--; 249 | // head = strtmp; 250 | // 251 | // while (tail>=fullpath && *tail!='/') /*得到filename的倒序*/ 252 | // *head++ = *tail--; 253 | // strncpy(parent, fullpath, tail-fullpath+1); 254 | // parent[tail-fullpath+1] = '\0'; 255 | // head--; 256 | // 257 | // while (maxlen>0 && head>=strtmp) { 258 | // *filename++ = *head--; 259 | // maxlen--; 260 | // } 261 | // if (maxlen>0) { 262 | // *filename = '\0'; 263 | // return 0; // 264 | // } 265 | // else return -1; /*文件名太长*/ 266 | //} 267 | 268 | 269 | ///* 270 | //*1. make dir if the dir does not exit 271 | //*2. create the file if does not exit 272 | //*/ 273 | //void processPathName(char *fullpath){ 274 | // char *temp; 275 | // temp = fullpath; 276 | // int dircount = 0; 277 | // while(1){ 278 | // char dir[128]; 279 | // while((*temp == '/'||*temp ==' ') && *temp != '\n') 280 | // temp++; 281 | // char *slash = strchr(temp,'/'); 282 | // if(slash == NULL) 283 | // break; 284 | // strncpy(dir,temp,slash-temp); 285 | // dir[slash-temp]='\0'; 286 | // if(access(dir,F_OK)){ 287 | // if(mkdir(dir, 0755) < 0){ 288 | // fprintf(stderr, "make dir [%s] error\n", dir); 289 | // } 290 | // } 291 | // chdir(dir); 292 | // temp = slash +1; 293 | // dircount++; 294 | // //在这个地方处理文件名怎么样??,感觉不错 295 | // // 296 | // // 297 | // // 298 | // // 299 | // //Todo: 300 | // } 301 | // while(dircount--){ 302 | // chdir("..");//返回原来的目录 303 | // } 304 | //} 305 | 306 | #endif 307 | --------------------------------------------------------------------------------