Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- extern "C" {
- #include <stdio.h>
- #include <stdlib.h>
- #include <string.h>
- #include <time.h>
- #include <signal.h>
- #include <winsock2.h>
- #include "dhnetsdk.h"
- #include "cJSON.h"
- }
- int debug;
- unsigned short portno;
- char str_secret[0x40],
- str_ipaddr1[0x40],
- str_portno1[0x40],
- str_usrnam1[0x40],
- str_passwd1[0x40],
- str_ipaddr2[0x40],
- str_portno2[0x40],
- str_usrnam2[0x40],
- str_passwd2[0x40];
- long loginid1, loginid2;
- void init();
- long login(char *, char *, char *, char *);
- void mainloop();
- int main(void)
- {
- init();
- mainloop();
- return 0;
- }
- void init()
- {
- fputs("init...\r\n", stderr);
- FILE *fconf;
- char str_config[0x1000] = {},
- str_portno[0x40];
- fconf = fopen("config.cfg", "r");
- fread(str_config, 1, sizeof(str_config), fconf);
- fclose(fconf);
- debug = strstr(str_config, "debug") ? 1 : 0;
- sscanf(strchr(strstr(str_config, "portno"), ':') + 1, "%s", str_portno);
- portno = atoi(str_portno);
- sscanf(strchr(strstr(str_config, "secret"), ':') + 1, "%s", str_secret);
- sscanf(strchr(strstr(str_config, "ipaddr1"), ':') + 1, "%s", str_ipaddr1);
- sscanf(strchr(strstr(str_config, "portno1"), ':') + 1, "%s", str_portno1);
- sscanf(strchr(strstr(str_config, "usrnam1"), ':') + 1, "%s", str_usrnam1);
- sscanf(strchr(strstr(str_config, "passwd1"), ':') + 1, "%s", str_passwd1);
- if (strstr(str_config, "ipaddr2"))
- {
- sscanf(strchr(strstr(str_config, "ipaddr2"), ':') + 1, "%s", str_ipaddr2);
- sscanf(strchr(strstr(str_config, "portno2"), ':') + 1, "%s", str_portno2);
- sscanf(strchr(strstr(str_config, "usrnam2"), ':') + 1, "%s", str_usrnam2);
- sscanf(strchr(strstr(str_config, "passwd2"), ':') + 1, "%s", str_passwd2);
- }
- WSADATA wsa;
- WSAStartup(MAKEWORD(2,2), &wsa);
- CLIENT_Init(NULL, NULL);
- fputs("...init\r\n", stderr);
- }
- long login(char *str_ipaddr, char *str_portno,
- char *str_usrnam, char *str_passwd)
- {
- NET_DEVICEINFO st_devinfo = {0};
- if (str_ipaddr[0] == '\0') return -1;
- return CLIENT_LoginEx(str_ipaddr, atoi(str_portno),
- str_usrnam, str_passwd,
- EM_LOGIN_SPEC_CAP_TCP, NULL,
- &st_devinfo, NULL);
- }
- void relogin()
- {
- static time_t last = 0;
- time_t current;
- current = time(NULL);
- if (current - last > 300)
- {
- CLIENT_Logout(loginid1);
- loginid1 = login(str_ipaddr1, str_portno1, str_usrnam1, str_passwd1);
- if (loginid2 != -1) {
- CLIENT_Logout(loginid2);
- loginid2 = login(str_ipaddr2, str_portno2, str_usrnam2, str_passwd2);
- }
- }
- last = current;
- }
- void terminator(int);
- FILE *log, *logfile;
- void flushlog();
- void time_to_nettime(time_t, NET_TIME *);
- void print_inoprec(FILE *, NET_IN_OPERATE_TRAFFIC_LIST_RECORD *);
- EM_RECORD_OPERATE_TYPE process_conn(SOCKET, NET_TRAFFIC_LIST_RECORD *);
- void mainloop()
- {
- SOCKET sock;
- struct sockaddr_in addr;
- time_t tcurrent, tlast;
- addr.sin_family = AF_INET;
- addr.sin_addr.s_addr = INADDR_ANY;
- addr.sin_port = htons(portno);
- fputs("socket-bind-listen...\r\n", stderr);
- sock = socket(AF_INET, SOCK_STREAM, 0);
- bind(sock, (const sockaddr *)&addr, sizeof(addr));
- listen(sock, 5);
- fputs("...socket-bind-listen\r\n", stderr);
- log = tmpfile();
- logfile = tmpfile();
- signal(SIGINT, terminator);
- signal(SIGTERM, terminator);
- tlast = time(NULL) - 5*24*60*60;
- while (1)
- {
- NET_IN_OPERATE_TRAFFIC_LIST_RECORD in_oprec
- = {sizeof(NET_IN_OPERATE_TRAFFIC_LIST_RECORD)};
- NET_OUT_OPERATE_TRAFFIC_LIST_RECORD out_oprec
- = {sizeof(NET_OUT_OPERATE_TRAFFIC_LIST_RECORD)};
- NET_INSERT_RECORD_INFO insrec_info = {sizeof(NET_INSERT_RECORD_INFO) };
- NET_REMOVE_RECORD_INFO remrec_info = {sizeof(NET_REMOVE_RECORD_INFO) };
- NET_TRAFFIC_LIST_RECORD trlist_rec = {sizeof(NET_TRAFFIC_LIST_RECORD)};
- flushlog();
- tcurrent = time(NULL);
- if (tcurrent - tlast >= 5*24*60*60)
- {
- char logfilename[0x40];
- sprintf(logfilename, "sashalog%020llu.txt", tcurrent);
- fclose(logfile);
- logfile = fopen(logfilename, "wb");
- tlast = tcurrent;
- }
- in_oprec.emOperateType = process_conn(sock, &trlist_rec);
- in_oprec.emRecordType = NET_RECORD_TRAFFICREDLIST;
- insrec_info.pRecordInfo = &trlist_rec;
- remrec_info.nRecordNo = trlist_rec.nRecordNo;
- relogin();
- if (in_oprec.emOperateType == NET_TRAFFIC_LIST_INSERT)
- {
- trlist_rec.nAuthrityNum = 1;
- trlist_rec.stAuthrityTypes[0].dwSize = sizeof(NET_AUTHORITY_TYPE);
- trlist_rec.stAuthrityTypes[0].emAuthorityType = NET_AUTHORITY_OPEN_GATE;
- trlist_rec.stAuthrityTypes[0].bAuthorityEnable = 1;
- in_oprec.pstOpreateInfo = &insrec_info;
- CLIENT_OperateTrafficList(loginid1, &in_oprec, &out_oprec, 10000);
- print_inoprec(log, &in_oprec);
- }
- else
- {
- in_oprec.pstOpreateInfo = &remrec_info;
- CLIENT_OperateTrafficList(loginid1, &in_oprec, &out_oprec, 10000);
- print_inoprec(log, &in_oprec);
- if (loginid2 == -1) continue;
- tcurrent = time(NULL);
- time_to_nettime(tcurrent, &trlist_rec.stBeginTime);
- time_to_nettime(tcurrent, &trlist_rec.stCancelTime);
- trlist_rec.stCancelTime.dwHour = 23;
- trlist_rec.stCancelTime.dwMinute = 59;
- trlist_rec.stCancelTime.dwSecond = 59;
- in_oprec.emOperateType = NET_TRAFFIC_LIST_INSERT;
- in_oprec.pstOpreateInfo = &insrec_info;
- CLIENT_OperateTrafficList(loginid2, &in_oprec, &out_oprec, 10000);
- print_inoprec(log, &in_oprec);
- }
- }
- }
- int valid_plate(char *);
- SOCKET accept_conn(SOCKET);
- EM_RECORD_OPERATE_TYPE process_conn(SOCKET sock,
- NET_TRAFFIC_LIST_RECORD *p_trlist_rec)
- {
- EM_RECORD_OPERATE_TYPE ret;
- char *head_ok = "HTTP/1.1 200 OK\r\n"
- "Content-Type: text/plain\r\n"
- "Connection: close\r\n\r\n"
- "Okay\r\n\r\n";
- char head_bad[0x1000] = "HTTP/1.1 400 Bad Request\r\n"
- "Content-Type: text/plain\r\n"
- "Connection: close\r\n\r\n";
- char *body_bad = head_bad + strlen(head_bad);
- while (1)
- {
- SOCKET _sock;
- char buf[0x1000] = {0};
- char *pbuf = buf,
- *pcontlen = NULL;
- size_t contlen;
- cJSON *json = NULL,
- *secret = NULL,
- *operation = NULL;
- _sock = accept_conn(sock);
- pbuf += recv(_sock, pbuf, sizeof(buf) - (pbuf - buf), 0);
- pcontlen = strstr(buf, "Content-Length");
- if (pcontlen == NULL) {
- strcpy(body_bad,
- "bad request: no Content-Length specified\r\n");
- goto bad;
- }
- pcontlen = strchr(pcontlen, ':') + 1;
- sscanf(pcontlen, "%zu", &contlen);
- for(char *pbody = strstr(buf, "\r\n\r\n") + 4;
- pbuf - pbody < contlen;
- pbuf += recv(_sock, pbuf, sizeof(buf) - (pbuf - buf), 0));
- if (debug) fprintf(log, "request:\r\n%s\r\n", buf);
- json = cJSON_Parse(strchr(buf, '{'));
- if (json == NULL) {
- strcpy(body_bad,
- "bad request: json not present\r\n");
- goto bad;
- }
- secret = cJSON_GetObjectItemCaseSensitive(json, "secret");
- if (secret == NULL) {
- strcpy(body_bad,
- "bad request: \"secret\" not present\r\n");
- goto bad;
- }
- if (0 != strcmp(secret->valuestring, str_secret)) {
- strcpy(body_bad,
- "bad request: incorrect secret\r\n");
- goto bad;
- }
- operation = cJSON_GetObjectItemCaseSensitive(json, "operation");
- if (operation == NULL) {
- strcpy(body_bad,
- "bad request: \"operation\" not present\r\n");
- goto bad;
- }
- if (0 == strcmp(operation->valuestring, "insert"))
- {
- cJSON *plate, *owner, *period;
- time_t t_begin, t_cancel;
- plate = cJSON_GetObjectItemCaseSensitive(json, "plate" );
- owner = cJSON_GetObjectItemCaseSensitive(json, "owner" );
- period = cJSON_GetObjectItemCaseSensitive(json, "period");
- if (plate == NULL || owner == NULL
- || !valid_plate(plate->valuestring))
- {
- strcpy(body_bad,
- plate && owner
- ? "bad request: invalid plate format\r\n"
- : "bad request: "
- "\"plate\" or \"owner\" not present\r\n");
- goto bad;
- }
- strncpy(p_trlist_rec->szPlateNumber, plate->valuestring,
- DH_MAX_PLATE_NUMBER_LEN-1);
- strncpy(p_trlist_rec->szMasterOfCar, owner->valuestring,
- DH_MAX_NAME_LEN-1);
- t_begin = time(NULL);
- t_cancel = t_begin + (period && period->valuedouble > 0
- ? period->valuedouble * 3600
- : 20 * 365 * 24 * 3600);
- time_to_nettime(t_begin , &p_trlist_rec->stBeginTime );
- time_to_nettime(t_cancel, &p_trlist_rec->stCancelTime);
- ret = NET_TRAFFIC_LIST_INSERT;
- }
- else if (0 == strcmp(operation->valuestring, "delete"))
- {
- NET_IN_FIND_RECORD_PARAM in_find_param
- = {sizeof(NET_IN_FIND_RECORD_PARAM)};
- NET_OUT_FIND_RECORD_PARAM out_find_param
- = {sizeof(NET_OUT_FIND_RECORD_PARAM)};
- FIND_RECORD_TRAFFICREDLIST_CONDITION find_cond
- = {sizeof(FIND_RECORD_TRAFFICREDLIST_CONDITION)};
- cJSON *plate;
- plate = cJSON_GetObjectItemCaseSensitive(json, "plate");
- if (plate == NULL) {
- strcpy(body_bad,
- "bad request: removal info not present\r\n");
- goto bad;
- }
- in_find_param.emType = NET_RECORD_TRAFFICREDLIST;
- in_find_param.pQueryCondition = &find_cond;
- strncpy(find_cond.szPlateNumber, plate->valuestring,
- DH_MAX_PLATE_NUMBER_LEN);
- relogin();
- if (CLIENT_FindRecord(loginid1, &in_find_param,
- &out_find_param, 2000))
- {
- NET_IN_FIND_NEXT_RECORD_PARAM in_findnext_param
- = {sizeof(NET_IN_FIND_NEXT_RECORD_PARAM)};
- NET_OUT_FIND_NEXT_RECORD_PARAM out_findnext_param
- = {sizeof(NET_OUT_FIND_NEXT_RECORD_PARAM)};
- int fret;
- in_findnext_param.lFindeHandle
- = out_find_param.lFindeHandle;
- in_findnext_param.nFileCount = 1;
- out_findnext_param.nMaxRecordNum = 1;
- out_findnext_param.pRecordList = p_trlist_rec;
- fret = CLIENT_FindNextRecord(&in_findnext_param,
- &out_findnext_param, 5000);
- CLIENT_FindRecordClose(out_find_param.lFindeHandle);
- if (!fret) {
- strcpy(body_bad,
- "bad request: no such plate in the list\r\n");
- goto bad;
- }
- }
- else
- {
- strcpy(body_bad,
- "bad request: search query failed\r\n");
- goto bad;
- }
- ret = NET_TRAFFIC_LIST_REMOVE;
- }
- else
- {
- strcpy(body_bad,
- "bad request: "
- "operation is neither \"insert\" nor \"delete\"\r\n");
- goto bad;
- }
- send(_sock, head_ok, strlen(head_ok), 0);
- cJSON_Delete(json);
- closesocket(_sock);
- break;
- bad:
- send(_sock, head_bad, strlen(head_bad), 0);
- if (json != NULL) cJSON_Delete(json);
- closesocket(_sock);
- fputs(body_bad, log);
- flushlog();
- }
- return ret;
- }
- SOCKET accept_conn(SOCKET sock)
- {
- SOCKET _sock;
- struct sockaddr_in _addr;
- int szaddr = sizeof(struct sockaddr_in);
- time_t tcurrent;
- _sock = accept(sock, (sockaddr *)&_addr, &szaddr);
- tcurrent = time(NULL);
- fprintf(log, "\r\n%s\r\n"
- "connection accepted from: %s\r\n",
- ctime(&tcurrent),
- inet_ntoa(_addr.sin_addr));
- return _sock;
- }
- int match(const char *, const char *);
- int valid_plate(char *plate)
- {
- enum { UkrOld, UkrNew, NumFmt };
- static const char *format[] = { "DDD-DDCC",
- "CCDDDDCC" };
- for (int i = 0; i < NumFmt; ++i) {
- if (match(plate, format[i]))
- return 1;
- }
- return 0;
- }
- int match(const char *plate, const char *format)
- {
- const char *p, *f;
- for (p = plate, f = format; *p && *f; ++p, ++f)
- {
- int ok;
- switch (*f) {
- case 'L': ok = ('A' <= *p && *p <= 'Z'); break;
- case 'C': ok = (strchr("ABCEHIKMOPTX", *p) != NULL); break;
- case 'D': ok = ('0' <= *p && *p <= '9'); break;
- default: ok = (*p == *f);
- }
- if (!ok) return 0;
- }
- if (*p || *f) return 0;
- return 1;
- }
- void time_to_nettime(time_t time, NET_TIME *pnettime)
- {
- struct tm *ymdhms = localtime(&time);
- pnettime->dwYear = ymdhms->tm_year + 1900;
- pnettime->dwMonth = ymdhms->tm_mon + 1;
- pnettime->dwDay = ymdhms->tm_mday;
- pnettime->dwHour = ymdhms->tm_hour;
- pnettime->dwMinute = ymdhms->tm_min;
- pnettime->dwSecond = ymdhms->tm_sec;
- }
- void print_inoprec(FILE *file, NET_IN_OPERATE_TRAFFIC_LIST_RECORD *inoprec)
- {
- #define RECINFO (inoprec->pstOpreateInfo)
- #define INSRECINFO (((NET_INSERT_RECORD_INFO *)RECINFO)->pRecordInfo)
- #define REMRECINFO ((NET_REMOVE_RECORD_INFO *)RECINFO)
- #define TBEGIN (INSRECINFO->stBeginTime)
- #define TCANCEL (INSRECINFO->stCancelTime)
- if (inoprec->emOperateType == NET_TRAFFIC_LIST_INSERT)
- {
- fprintf(file,
- "INSERTION\r\n"
- "plate: %s\r\n"
- "owner: %s\r\n"
- "begin time: %02d:%02d:%02d - %02d.%02d.%04d\r\n"
- "cancel time: %02d:%02d:%02d - %02d.%02d.%04d\r\n",
- INSRECINFO->szPlateNumber,
- INSRECINFO->szMasterOfCar,
- TBEGIN.dwHour, TBEGIN.dwMinute, TBEGIN.dwSecond,
- TBEGIN.dwDay, TBEGIN.dwMonth, TBEGIN.dwYear,
- TCANCEL.dwHour, TCANCEL.dwMinute, TCANCEL.dwSecond,
- TCANCEL.dwDay, TCANCEL.dwMonth, TCANCEL.dwYear);
- }
- else
- {
- fprintf(file,
- "REMOVAL\r\n"
- "rec.no.: %d\r\n", REMRECINFO->nRecordNo);
- }
- #undef TCANCEL
- #undef TBEGIN
- #undef REMRECINFO
- #undef INSRECINFO
- #undef RECINFO
- }
- void flushlog()
- {
- char *buf;
- size_t sz;
- sz = ftell(log);
- buf = (char *)malloc(sz);
- rewind(log);
- fread(buf, 1, sz, log);
- fwrite(buf, 1, sz, stdout);
- fwrite(buf, 1, sz, logfile);
- fflush(stdout);
- fflush(logfile);
- free(buf);
- fclose(log);
- log = tmpfile();
- }
- void terminator(int val)
- {
- flushlog();
- exit(0);
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement