Advertisement
ZOOOO

Untitled

Dec 18th, 2015
3,990
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 5.25 KB | None | 0 0
  1. #include <iostream>
  2. #include <fstream>
  3. #include <sstream>
  4. #include <algorithm>
  5. #include <iterator>
  6. #include <thread>
  7. #include <unistd.h>
  8. #include <vector>
  9. #include <string>
  10. #include <sys/types.h>
  11. #include <sys/socket.h>
  12. #include <sys/un.h>
  13. #include <mutex>
  14. #include <chrono>
  15. #include <iomanip>
  16. #include <functional>
  17.  
  18. #define SOCK_PATH "/home/threads_loger"
  19. #define BUF_LEN 256
  20.  
  21. time_t parse_time(std::string str) {
  22. tm ret;
  23. memset(&ret, 0, sizeof(tm));
  24. strptime(str.c_str(), "%F %T", &ret);
  25. return mktime(&ret);
  26. }
  27.  
  28. void connection_thread(int sock, struct sockaddr_un addr, std::fstream &log,
  29. std::mutex &log_mutex) {
  30. auto sender = [sock](std::string tmp, int end = 1) -> int {
  31. tmp.resize(BUF_LEN);
  32. tmp[BUF_LEN - 1] = end;
  33. if (send(sock, tmp.c_str(), BUF_LEN, 0) < 0) {
  34. perror("send");
  35. return 0;
  36. }
  37. return 1;
  38. };
  39. auto get_time =
  40. []() -> std::string {
  41. std::time_t now = std::chrono::system_clock::to_time_t(std::chrono::system_clock::now());
  42. char tmp[50];
  43. strftime(tmp, 50UL, "%F %T", localtime(&now));
  44. return std::string {tmp};
  45. };
  46. auto file_find =
  47. [&log, &log_mutex, &sender](std::function<bool(std::string&)> cond) {
  48. std::lock_guard<std::mutex> lg {log_mutex};
  49. log.close();
  50. log.open("log.txt", std::fstream::in);
  51. log.seekg(0);
  52.  
  53. std::string line;
  54. while(std::getline(log, line)) {
  55. if(cond(line)) {
  56. sender(line, 0);
  57. }
  58. }
  59.  
  60. log.close();
  61. log.open("log.txt", std::fstream::in | std::fstream::out | std::fstream::app);
  62. };
  63. while (1) {
  64. char buffer[256];
  65. int n, total = 0;
  66. while (total != 256) {
  67. n = recv(sock, buffer + total, 256, MSG_WAITALL);
  68. if (n < 0) {
  69. perror("recv");
  70. } else if (n == 0) {
  71. break;
  72. }
  73. total += n;
  74. }
  75. if (n == 0) {
  76. break;
  77. }
  78. //get level *, get from * to *, get from *, clear, write * *
  79. std::istringstream iss { std::string(buffer) };
  80. std::string cmd;
  81. iss >> cmd;
  82. if (cmd == "write") {
  83. std::string level, message, time;
  84. iss >> level;
  85. time = get_time();
  86. if (level == "warn" || level == "info" || level == "error") {
  87. char c;
  88. while (isspace(c = iss.get()))
  89. ;
  90. iss.putback(c);
  91. std::getline(iss, message);
  92. std::lock_guard<std::mutex> lg { log_mutex };
  93. log << level << " " << time << " " << message << std::endl;
  94. } else {
  95. if (!sender("wrong type"))
  96. break;
  97. continue;
  98. }
  99. } else if (cmd == "get") {
  100. std::vector<std::string> tokens {
  101. std::istream_iterator<std::string> { iss },
  102. std::istream_iterator<std::string> { } };
  103. if (tokens.size() == 0) {
  104. if (!sender("no args"))
  105. break;
  106. continue;
  107. } else if (tokens[0] == "level") {
  108. if(tokens[1] == "warn" || tokens[1] == "error" || tokens[1] == "info") {
  109. file_find([&level = tokens[1]](std::string &line) -> bool {
  110. if(strncmp(line.c_str(), level.c_str(), strlen(level.c_str())) == 0)
  111. return true;
  112. return false;
  113. });
  114. } else {
  115. if(!sender("wrong type"))
  116. break;
  117. continue;
  118. }
  119.  
  120. } else if (tokens[0] == "from" && tokens.size() == 3) {
  121. file_find([&tokens, from = parse_time(tokens[1] + tokens[2])](std::string &line)-> bool {
  122. std::istringstream iss {line};
  123. std::string tmp1, tmp2;
  124. iss >> tmp1 >> tmp1 >> tmp2;
  125. if(parse_time(tmp1 + tmp2) >= from)
  126. return true;
  127. return false;
  128. });
  129. } else if (tokens[0] == "from" && tokens.size() == 6 && tokens[3] == "to") {
  130. file_find([&tokens, from = parse_time(tokens[1] + tokens[2]), to = parse_time(tokens[4] + tokens[5])](std::string &line)-> bool {
  131. std::istringstream iss {line};
  132. std::string tmp1, tmp2;
  133. iss >> tmp1 >> tmp1 >> tmp2;
  134. if(parse_time(tmp1 + tmp2) >= from && parse_time(tmp1 + tmp2) <= to)
  135. return true;
  136. return false;
  137. });
  138. } else {
  139. if (!sender("wrong syntax"))
  140. break;
  141. continue;
  142. }
  143. } else if (cmd == "clear") {
  144. std::lock_guard<std::mutex> lg { log_mutex };
  145. log.close();
  146. log.open("log.txt",
  147. std::fstream::in | std::fstream::out | std::fstream::trunc);
  148. } else {
  149. if (!sender("wrong command"))
  150. break;
  151. continue;
  152. }
  153. if(!sender("ok!"))
  154. break;
  155. }
  156. close(sock);
  157. unlink(addr.sun_path);
  158. log.sync();
  159. }
  160.  
  161. int main() {
  162. int server_sock, client_sock, client_len, len;
  163. struct sockaddr_un server, client;
  164. std::fstream fout;
  165. fout.open("log.txt",
  166. std::fstream::in | std::fstream::out | std::ios_base::app);
  167. if ((server_sock = socket(AF_UNIX, SOCK_STREAM, 0)) < 0) {
  168. perror("socket");
  169. }
  170. server.sun_family = AF_UNIX;
  171. strcpy(server.sun_path, SOCK_PATH);
  172. unlink(server.sun_path);
  173. len = strlen(server.sun_path) + sizeof(server.sun_family);
  174. if (bind(server_sock, (struct sockaddr *) &server, len) < 0) {
  175. perror("bind");
  176. }
  177.  
  178. if (listen(server_sock, 5) < 0) {
  179. perror("listen");
  180. }
  181. std::mutex log_mutex;
  182. for (;;) {
  183. printf("Waiting for a connection...\n");
  184. client_len = sizeof(client);
  185. if ((client_sock = accept(server_sock, (struct sockaddr *) &client,
  186. (socklen_t *) &client_len)) < 0) {
  187. perror("accept");
  188. }
  189. printf("Connected.\n");
  190.  
  191. std::thread(connection_thread, client_sock, server, std::ref(fout),
  192. std::ref(log_mutex)).detach();
  193. }
  194. return EXIT_SUCCESS;
  195. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement