Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <iostream>
- #include <cstdio>
- #include <cstring>
- #include <cstdlib>
- #include <vector>
- #include <sstream>
- #include <iterator>
- #include <algorithm>
- #include <memory>
- #include <sys/types.h>
- #include <sys/socket.h>
- #include <errno.h>
- #include <netinet/in.h>
- #include <sys/poll.h>
- #include <arpa/inet.h>
- #include <unistd.h>
- #include <fcntl.h>
- #include <asn1/Request.h>
- #include <asn1/Response.h>
- #define MAXCOUNT 1024
- #define TRUE 1
- #define FALSE 0
- #define CONST 128 * 128
- #define BUF_LEN 1 << 20
- #define PORT 5001
- #define SSYMBOL(x) #x
- #define SYMBOL(X) SSYMBOL(X)
- #define F_NAME "log.txt"
- #define WRITE 1200075747
- #define WARN -1897635125
- #define INFO -1442228161
- #define ERROR -907056764
- #define GET 1806773703
- #define CLEAR 352069091
- #define BEFORE -115185719
- using namespace std;
- unsigned int HashRot13(const char * str) {
- unsigned int hash = 0;
- for(; *str; str++) {
- hash += (unsigned char)(*str); hash -= (hash << 13) | (hash >> 19);
- }
- return hash;
- }
- int recvn(int sock, void *buf, int buflen) {
- int n, total = 0;
- while (total != buflen) {
- n = recv(sock, (char*) buf + total, buflen - total, 0);
- if (n <= 0)
- return n;
- total += n;
- }
- return total;
- }
- vector<string> lexer(char* str) {
- vector<string> lexems {};
- for(string tmp = ""; *str; str++) {
- for(tmp.clear(); *str && !isspace(*(str)); tmp += *str, str++);
- lexems.push_back(tmp);
- }
- return lexems;
- }
- int resolve_command(const char *buffer, Request_t &req) {
- istringstream iss { string { buffer } }; //для простого разбиения на токены
- string cmd, tmp;
- iss >> cmd;
- unsigned int cmdHash = HashRot13(cmd.c_str());
- switch (cmdHash) {
- case WRITE: { //write *level* *msg*
- iss >> tmp;
- //заполняем поля
- req.present = Request_PR_add;
- LogLevel_t &level = req.choice.add.level;
- MessageText_t &msg = req.choice.add.msg;
- msg.buf = nullptr;
- unsigned int tmpHash = HashRot13(tmp.c_str());
- switch (tmpHash) {
- case WARN:
- level = LogLevel_warn;
- break;
- case INFO:
- level = LogLevel_info;
- break;
- case ERROR:
- level = LogLevel_error;
- break;
- default :
- printf("wrong level\n");
- return 0;
- }
- //пропуск лидирующих пробелов
- char c;
- while (isspace(c = iss.get()));
- iss.putback(c);
- getline(iss, tmp);
- OCTET_STRING_fromString(&msg, tmp.c_str());
- break;
- } case GET: {//get level lvl [from data [to data]] | get from data [to data]
- //заполнение полей
- req.present = Request_PR_get;
- LogLevel_t *&level = req.choice.get.level;
- GeneralizedTime_t *&from = req.choice.get.begin, *&to =
- req.choice.get.end;
- //разбиваем на токены и смотрим, какие есть условия
- char* q = (char*)buffer;
- vector<string> tokens = lexer(q);
- auto l = find(tokens.begin(), tokens.end(), "level") + 1;
- auto f = find(tokens.begin(), tokens.end(), "since") + 1;
- auto t = find(tokens.begin(), tokens.end(), "before") + 1;
- if (l == tokens.end() || f == tokens.end() || t == tokens.end()) {
- printf("syntax error\n");
- return 0;
- }
- //вносим условия в структуру
- if (l < tokens.end()) {
- level = (LogLevel_t*)malloc(sizeof(LogLevel_t));
- if (*l == "warn") {
- *level = LogLevel_warn;
- } else if (*l == "info") {
- *level = LogLevel_info;
- } else if (*l == "error") {
- *level = LogLevel_error;
- } else {
- delete level;
- printf("syntax error\n");
- return 0;
- }
- }
- if (f < tokens.end()) {
- from = (GeneralizedTime_t*)malloc(sizeof(GeneralizedTime_t));
- memset(from, 0, sizeof(GeneralizedTime_t));
- //для более удобного ввода даты в виде гггг.мм.дд.чч.мм.сс
- f->erase(remove(f->begin(), f->end(), '.'), f->end());
- OCTET_STRING_fromString(from, f->c_str());
- }
- if (t < tokens.end()) {
- to = (GeneralizedTime_t*)malloc(sizeof(GeneralizedTime_t));;
- memset(to, 0, sizeof(GeneralizedTime_t));
- t->erase(remove(t->begin(), t->end(), '.'), t->end());
- OCTET_STRING_fromString(to, t->c_str());
- }
- break;
- //xer_fprint(stdout, &asn_DEF_Request, &req);
- } case CLEAR : {
- //заполнение полей
- req.present = Request_PR_clear;
- iss >> tmp;
- //определение типа все или до
- if (tmp == "") {
- req.choice.clear.present = ClearRequest_PR_all;
- } else if (tmp == "before") {
- iss >> tmp;
- tmp.erase(remove(tmp.begin(), tmp.end(), '.'), tmp.end());
- req.choice.clear.present = ClearRequest_PR_olderThan;
- OCTET_STRING_fromString(&req.choice.clear.choice.olderThan,
- tmp.c_str());
- } else {
- printf("syntax error\n");
- return 0;
- }
- //xer_fprint(stdout, &asn_DEF_Request, &req);
- break;
- } default : {
- printf("syntax error\n");
- return 0;
- }
- }
- return 1;
- }
- void print_resp(Response_t *resp) {
- if(resp->present == Response_PR_records) {
- int n = resp->choice.records.list.count;
- for(int i = 0; i < n; i++) {
- LogRecord_t *tmp = resp->choice.records.list.array[i];
- switch(tmp->level) {
- case LogLevel_warn:
- printf("warn ");
- break;
- case LogLevel_error:
- printf("error ");
- break;
- case LogLevel_info:
- printf("info ");
- break;
- }
- auto p = tmp->ip.choice.iPBinaryAddress.choice.iPBinV4Address.buf;
- printf("%d.%d.%d.%d ", p[0], p[1], p[2], p[3]);
- tm t;
- asn_GT2time(&tmp->timestamp, &t, 0);
- char buf[50];
- strftime(buf, 50UL, "%F %T", &t);
- printf("%s %.*s\n",buf, tmp->msg.size, tmp->msg.buf);
- }
- } else {
- printf("nothing found\n");
- }
- fflush(stdout);
- }
- int main(void) {
- int sock, timeout;
- struct sockaddr_in saddr;
- memset(&saddr,0,sizeof(saddr));
- sock = socket(AF_INET,SOCK_STREAM,0);
- saddr.sin_family = AF_INET;
- inet_aton("127.0.0.1",&saddr.sin_addr);
- saddr.sin_port = htons(12345);
- timeout = (3 * 6 * 1000);
- struct pollfd fds[2];
- fds[0].fd = sock;
- fds[0].events = POLLIN;
- connect(sock,(struct sockaddr*) &saddr, sizeof(saddr));
- fds[1].fd = STDIN_FILENO;
- fds[1].events = POLLIN;
- std::unique_ptr<char> buffer_h{(char*)calloc(BUF_LEN, sizeof(char))};
- char *buffer = buffer_h.get();
- string inp = "";
- while( poll(fds, 2, timeout)) {
- printf("download...\n");
- memset(buffer, 0, BUF_LEN);
- getline(cin, inp);
- Request_t req;
- memset(&req, 0, sizeof(Request_t));
- //проверка ввода
- if (resolve_command(inp.c_str(), req)) {
- asn_enc_rval_t er;
- //если проверка прошла, кодируем
- er = der_encode_to_buffer(&asn_DEF_Request, &req, buffer, BUF_LEN);
- if (er.encoded == -1) {
- ASN_STRUCT_FREE_CONTENTS_ONLY(asn_DEF_Request, &req);
- perror("encoded");
- return 1;
- }
- uint32_t len = er.encoded;
- len = htonl(len);
- if (send(sock, &len, sizeof(len), 0) < 0) {
- perror("send");
- ASN_STRUCT_FREE_CONTENTS_ONLY(asn_DEF_Request, &req);
- return 1;
- }
- len = ntohl(len);
- if (send(sock, buffer, len, 0) < 0) {
- perror("send");
- ASN_STRUCT_FREE_CONTENTS_ONLY(asn_DEF_Request, &req);
- return 1;
- }
- ASN_STRUCT_FREE_CONTENTS_ONLY(asn_DEF_Request, &req);
- }
- if (poll(fds, 2, timeout/18)){
- //обработка ответа с сервера
- uint32_t len, n;
- n = recvn(sock, &len, sizeof(len));
- if(n <= 0)
- continue;
- len = ntohl(len);
- char *tmp = (char *) malloc(len * sizeof(char));
- n = recvn(sock, tmp, len);
- asn_dec_rval_t rv;
- Response_t *resp = nullptr;
- //декодировли
- rv = ber_decode(0, &asn_DEF_Response, (void**) &resp, tmp, len);
- //вывели
- if(rv.code != RC_OK) {
- perror("cannot decode");
- free(tmp);
- ASN_STRUCT_FREE(asn_DEF_Response, resp);
- continue;
- }
- print_resp(resp);
- //xer_fprint(stdout, &asn_DEF_Response, resp);
- ASN_STRUCT_FREE(asn_DEF_Response, resp);
- free(tmp);
- }
- fflush(stdout);
- }
- free(buffer);
- return 0;
- }
Add Comment
Please, Sign In to add comment