Advertisement
Guest User

Untitled

a guest
Mar 5th, 2020
179
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 15.85 KB | None | 0 0
  1. extern "C" {
  2. #include <stdio.h>
  3. #include <stdlib.h>
  4. #include <string.h>
  5. #include <time.h>
  6. #include <signal.h>
  7. #include <winsock2.h>
  8. #include "dhnetsdk.h"
  9. #include "cJSON.h"
  10. }
  11.  
  12. int debug;
  13. unsigned short portno;
  14.  
  15. char str_secret[0x40],
  16.      str_ipaddr1[0x40],
  17.      str_portno1[0x40],
  18.      str_usrnam1[0x40],
  19.      str_passwd1[0x40],
  20.      str_ipaddr2[0x40],
  21.      str_portno2[0x40],
  22.      str_usrnam2[0x40],
  23.      str_passwd2[0x40];
  24.  
  25. long loginid1, loginid2;
  26.  
  27. void init();
  28. long login(char *, char *, char *, char *);
  29. void mainloop();
  30.  
  31. int main(void)
  32. {
  33.     init();
  34.  
  35.     mainloop();
  36.  
  37.     return 0;
  38. }
  39.  
  40. void init()
  41. {
  42.     fputs("init...\r\n", stderr);
  43.  
  44.     FILE *fconf;
  45.     char str_config[0x1000] = {},
  46.          str_portno[0x40];
  47.  
  48.     fconf = fopen("config.cfg", "r");
  49.     fread(str_config, 1, sizeof(str_config), fconf);
  50.     fclose(fconf);
  51.  
  52.     debug = strstr(str_config, "debug") ? 1 : 0;
  53.  
  54.     sscanf(strchr(strstr(str_config, "portno"), ':') + 1, "%s", str_portno);
  55.     portno = atoi(str_portno);
  56.  
  57.     sscanf(strchr(strstr(str_config, "secret"), ':') + 1, "%s", str_secret);
  58.  
  59.     sscanf(strchr(strstr(str_config, "ipaddr1"), ':') + 1, "%s", str_ipaddr1);
  60.     sscanf(strchr(strstr(str_config, "portno1"), ':') + 1, "%s", str_portno1);
  61.     sscanf(strchr(strstr(str_config, "usrnam1"), ':') + 1, "%s", str_usrnam1);
  62.     sscanf(strchr(strstr(str_config, "passwd1"), ':') + 1, "%s", str_passwd1);
  63.  
  64.     if (strstr(str_config, "ipaddr2"))
  65.     {
  66.     sscanf(strchr(strstr(str_config, "ipaddr2"), ':') + 1, "%s", str_ipaddr2);
  67.     sscanf(strchr(strstr(str_config, "portno2"), ':') + 1, "%s", str_portno2);
  68.     sscanf(strchr(strstr(str_config, "usrnam2"), ':') + 1, "%s", str_usrnam2);
  69.     sscanf(strchr(strstr(str_config, "passwd2"), ':') + 1, "%s", str_passwd2);
  70.     }
  71.  
  72.     WSADATA wsa;
  73.     WSAStartup(MAKEWORD(2,2), &wsa);
  74.  
  75.     CLIENT_Init(NULL, NULL);
  76.  
  77.     fputs("...init\r\n", stderr);
  78. }
  79.  
  80. long login(char *str_ipaddr, char *str_portno,
  81.            char *str_usrnam, char *str_passwd)
  82. {
  83.     NET_DEVICEINFO st_devinfo = {0};
  84.  
  85.     if (str_ipaddr[0] == '\0') return -1;
  86.  
  87.     return CLIENT_LoginEx(str_ipaddr, atoi(str_portno),
  88.                           str_usrnam, str_passwd,
  89.                           EM_LOGIN_SPEC_CAP_TCP, NULL,
  90.                           &st_devinfo, NULL);
  91. }
  92.  
  93. void relogin()
  94. {
  95.     static time_t last = 0;
  96.     time_t current;
  97.  
  98.     current = time(NULL);
  99.     if (current - last > 300)
  100.     {
  101.         CLIENT_Logout(loginid1);
  102.         loginid1 = login(str_ipaddr1, str_portno1, str_usrnam1, str_passwd1);
  103.         if (loginid2 != -1) {
  104.         CLIENT_Logout(loginid2);
  105.         loginid2 = login(str_ipaddr2, str_portno2, str_usrnam2, str_passwd2);
  106.         }
  107.     }
  108.     last = current;
  109. }
  110.  
  111. void terminator(int);
  112.  
  113. FILE *log, *logfile;
  114.  
  115. void flushlog();
  116.  
  117. void time_to_nettime(time_t, NET_TIME *);
  118.  
  119. void print_inoprec(FILE *, NET_IN_OPERATE_TRAFFIC_LIST_RECORD *);
  120.  
  121. EM_RECORD_OPERATE_TYPE process_conn(SOCKET, NET_TRAFFIC_LIST_RECORD *);
  122.  
  123. void mainloop()
  124. {
  125.     SOCKET sock;
  126.     struct sockaddr_in addr;
  127.     time_t tcurrent, tlast;
  128.  
  129.     addr.sin_family = AF_INET;
  130.     addr.sin_addr.s_addr = INADDR_ANY;
  131.     addr.sin_port = htons(portno);
  132.  
  133.     fputs("socket-bind-listen...\r\n", stderr);
  134.     sock = socket(AF_INET, SOCK_STREAM, 0);
  135.     bind(sock, (const sockaddr *)&addr, sizeof(addr));
  136.     listen(sock, 5);
  137.     fputs("...socket-bind-listen\r\n", stderr);
  138.  
  139.     log = tmpfile();
  140.     logfile = tmpfile();
  141.  
  142.     signal(SIGINT, terminator);
  143.     signal(SIGTERM, terminator);
  144.  
  145.     tlast = time(NULL) - 5*24*60*60;
  146.  
  147.     while (1)
  148.     {
  149.         NET_IN_OPERATE_TRAFFIC_LIST_RECORD in_oprec
  150.             = {sizeof(NET_IN_OPERATE_TRAFFIC_LIST_RECORD)};
  151.         NET_OUT_OPERATE_TRAFFIC_LIST_RECORD out_oprec
  152.             = {sizeof(NET_OUT_OPERATE_TRAFFIC_LIST_RECORD)};
  153.         NET_INSERT_RECORD_INFO insrec_info = {sizeof(NET_INSERT_RECORD_INFO) };
  154.         NET_REMOVE_RECORD_INFO remrec_info = {sizeof(NET_REMOVE_RECORD_INFO) };
  155.         NET_TRAFFIC_LIST_RECORD trlist_rec = {sizeof(NET_TRAFFIC_LIST_RECORD)};
  156.  
  157.         flushlog();
  158.  
  159.         tcurrent = time(NULL);
  160.         if (tcurrent - tlast >= 5*24*60*60)
  161.         {
  162.             char logfilename[0x40];
  163.             sprintf(logfilename, "sashalog%020llu.txt", tcurrent);
  164.             fclose(logfile);
  165.             logfile = fopen(logfilename, "wb");
  166.             tlast = tcurrent;
  167.         }
  168.  
  169.         in_oprec.emOperateType = process_conn(sock, &trlist_rec);
  170.         in_oprec.emRecordType = NET_RECORD_TRAFFICREDLIST;
  171.  
  172.         insrec_info.pRecordInfo = &trlist_rec;
  173.         remrec_info.nRecordNo = trlist_rec.nRecordNo;
  174.  
  175.         relogin();
  176.  
  177.         if (in_oprec.emOperateType == NET_TRAFFIC_LIST_INSERT)
  178.         {
  179.             trlist_rec.nAuthrityNum = 1;
  180.             trlist_rec.stAuthrityTypes[0].dwSize = sizeof(NET_AUTHORITY_TYPE);
  181.             trlist_rec.stAuthrityTypes[0].emAuthorityType = NET_AUTHORITY_OPEN_GATE;
  182.             trlist_rec.stAuthrityTypes[0].bAuthorityEnable = 1;
  183.             in_oprec.pstOpreateInfo = &insrec_info;
  184.             CLIENT_OperateTrafficList(loginid1, &in_oprec, &out_oprec, 10000);
  185.             print_inoprec(log, &in_oprec);
  186.         }
  187.         else
  188.         {
  189.             in_oprec.pstOpreateInfo = &remrec_info;
  190.             CLIENT_OperateTrafficList(loginid1, &in_oprec, &out_oprec, 10000);
  191.             print_inoprec(log, &in_oprec);
  192.  
  193.             if (loginid2 == -1) continue;
  194.  
  195.             tcurrent = time(NULL);
  196.             time_to_nettime(tcurrent, &trlist_rec.stBeginTime);
  197.             time_to_nettime(tcurrent, &trlist_rec.stCancelTime);
  198.             trlist_rec.stCancelTime.dwHour   = 23;
  199.             trlist_rec.stCancelTime.dwMinute = 59;
  200.             trlist_rec.stCancelTime.dwSecond = 59;
  201.  
  202.             in_oprec.emOperateType = NET_TRAFFIC_LIST_INSERT;
  203.             in_oprec.pstOpreateInfo = &insrec_info;
  204.             CLIENT_OperateTrafficList(loginid2, &in_oprec, &out_oprec, 10000);
  205.             print_inoprec(log, &in_oprec);
  206.         }
  207.     }
  208. }
  209.  
  210. int valid_plate(char *);
  211. SOCKET accept_conn(SOCKET);
  212.  
  213. EM_RECORD_OPERATE_TYPE process_conn(SOCKET sock,
  214.                                     NET_TRAFFIC_LIST_RECORD *p_trlist_rec)
  215. {
  216.     EM_RECORD_OPERATE_TYPE ret;
  217.  
  218.     char *head_ok = "HTTP/1.1 200 OK\r\n"
  219.                     "Content-Type: text/plain\r\n"
  220.                     "Connection: close\r\n\r\n"
  221.                     "Okay\r\n\r\n";
  222.  
  223.     char head_bad[0x1000] = "HTTP/1.1 400 Bad Request\r\n"
  224.                             "Content-Type: text/plain\r\n"
  225.                             "Connection: close\r\n\r\n";
  226.  
  227.     char *body_bad = head_bad + strlen(head_bad);
  228.  
  229.     while (1)
  230.     {
  231.         SOCKET _sock;
  232.  
  233.         char buf[0x1000] = {0};
  234.         char *pbuf = buf,
  235.              *pcontlen = NULL;
  236.  
  237.         size_t contlen;
  238.  
  239.         cJSON *json = NULL,
  240.               *secret = NULL,
  241.               *operation = NULL;
  242.  
  243.         _sock = accept_conn(sock);
  244.  
  245.         pbuf += recv(_sock, pbuf, sizeof(buf) - (pbuf - buf), 0);
  246.         pcontlen = strstr(buf, "Content-Length");
  247.         if (pcontlen == NULL) {
  248.             strcpy(body_bad,
  249.                    "bad request: no Content-Length specified\r\n");
  250.             goto bad;
  251.         }
  252.         pcontlen = strchr(pcontlen, ':') + 1;
  253.         sscanf(pcontlen, "%zu", &contlen);
  254.  
  255.         for(char *pbody = strstr(buf, "\r\n\r\n") + 4;
  256.             pbuf - pbody < contlen;
  257.             pbuf += recv(_sock, pbuf, sizeof(buf) - (pbuf - buf), 0));
  258.  
  259.         if (debug) fprintf(log, "request:\r\n%s\r\n", buf);
  260.  
  261.         json = cJSON_Parse(strchr(buf, '{'));
  262.         if (json == NULL) {
  263.             strcpy(body_bad,
  264.                    "bad request: json not present\r\n");
  265.             goto bad;
  266.         }
  267.         secret = cJSON_GetObjectItemCaseSensitive(json, "secret");
  268.         if (secret == NULL) {
  269.             strcpy(body_bad,
  270.                    "bad request: \"secret\" not present\r\n");
  271.             goto bad;
  272.         }
  273.         if (0 != strcmp(secret->valuestring, str_secret)) {
  274.             strcpy(body_bad,
  275.                    "bad request: incorrect secret\r\n");
  276.             goto bad;
  277.         }
  278.         operation = cJSON_GetObjectItemCaseSensitive(json, "operation");
  279.         if (operation == NULL) {
  280.             strcpy(body_bad,
  281.                    "bad request: \"operation\" not present\r\n");
  282.             goto bad;
  283.         }
  284.         if (0 == strcmp(operation->valuestring, "insert"))
  285.         {
  286.             cJSON *plate, *owner, *period;
  287.  
  288.             time_t t_begin, t_cancel;
  289.  
  290.             plate  = cJSON_GetObjectItemCaseSensitive(json, "plate" );
  291.             owner  = cJSON_GetObjectItemCaseSensitive(json, "owner" );
  292.             period = cJSON_GetObjectItemCaseSensitive(json, "period");
  293.  
  294.             if (plate == NULL || owner == NULL
  295.                 || !valid_plate(plate->valuestring))
  296.             {
  297.                 strcpy(body_bad,
  298.                        plate && owner
  299.                        ? "bad request: invalid plate format\r\n"
  300.                        : "bad request: "
  301.                          "\"plate\" or \"owner\" not present\r\n");
  302.                 goto bad;
  303.             }
  304.  
  305.             strncpy(p_trlist_rec->szPlateNumber, plate->valuestring,
  306.                     DH_MAX_PLATE_NUMBER_LEN-1);
  307.             strncpy(p_trlist_rec->szMasterOfCar, owner->valuestring,
  308.                     DH_MAX_NAME_LEN-1);
  309.  
  310.             t_begin = time(NULL);
  311.             t_cancel = t_begin + (period && period->valuedouble > 0
  312.                                   ? period->valuedouble * 3600
  313.                                   : 20 * 365 * 24 * 3600);
  314.  
  315.             time_to_nettime(t_begin , &p_trlist_rec->stBeginTime );
  316.             time_to_nettime(t_cancel, &p_trlist_rec->stCancelTime);
  317.  
  318.             ret = NET_TRAFFIC_LIST_INSERT;
  319.         }
  320.         else if (0 == strcmp(operation->valuestring, "delete"))
  321.         {
  322.             NET_IN_FIND_RECORD_PARAM in_find_param
  323.                 = {sizeof(NET_IN_FIND_RECORD_PARAM)};
  324.             NET_OUT_FIND_RECORD_PARAM out_find_param
  325.                 = {sizeof(NET_OUT_FIND_RECORD_PARAM)};
  326.             FIND_RECORD_TRAFFICREDLIST_CONDITION find_cond
  327.                 = {sizeof(FIND_RECORD_TRAFFICREDLIST_CONDITION)};
  328.  
  329.             cJSON *plate;
  330.  
  331.             plate = cJSON_GetObjectItemCaseSensitive(json, "plate");
  332.             if (plate == NULL) {
  333.                 strcpy(body_bad,
  334.                        "bad request: removal info not present\r\n");
  335.                 goto bad;
  336.             }
  337.  
  338.             in_find_param.emType = NET_RECORD_TRAFFICREDLIST;
  339.             in_find_param.pQueryCondition = &find_cond;
  340.  
  341.             strncpy(find_cond.szPlateNumber, plate->valuestring,
  342.                     DH_MAX_PLATE_NUMBER_LEN);
  343.  
  344.             relogin();
  345.  
  346.             if (CLIENT_FindRecord(loginid1, &in_find_param,
  347.                                             &out_find_param, 2000))
  348.             {
  349.                 NET_IN_FIND_NEXT_RECORD_PARAM in_findnext_param
  350.                     = {sizeof(NET_IN_FIND_NEXT_RECORD_PARAM)};
  351.                 NET_OUT_FIND_NEXT_RECORD_PARAM out_findnext_param
  352.                     = {sizeof(NET_OUT_FIND_NEXT_RECORD_PARAM)};
  353.  
  354.                 int fret;
  355.  
  356.                 in_findnext_param.lFindeHandle
  357.                     = out_find_param.lFindeHandle;
  358.                 in_findnext_param.nFileCount = 1;
  359.                 out_findnext_param.nMaxRecordNum = 1;
  360.                 out_findnext_param.pRecordList = p_trlist_rec;
  361.  
  362.                 fret = CLIENT_FindNextRecord(&in_findnext_param,
  363.                                              &out_findnext_param, 5000);
  364.  
  365.                 CLIENT_FindRecordClose(out_find_param.lFindeHandle);
  366.  
  367.                 if (!fret) {
  368.                     strcpy(body_bad,
  369.                            "bad request: no such plate in the list\r\n");
  370.                     goto bad;
  371.                 }
  372.             }
  373.             else
  374.             {
  375.                 strcpy(body_bad,
  376.                        "bad request: search query failed\r\n");
  377.                 goto bad;
  378.             }
  379.             ret = NET_TRAFFIC_LIST_REMOVE;
  380.         }
  381.         else
  382.         {
  383.             strcpy(body_bad,
  384.                    "bad request: "
  385.                    "operation is neither \"insert\" nor \"delete\"\r\n");
  386.             goto bad;
  387.         }
  388.         send(_sock, head_ok, strlen(head_ok), 0);
  389.         cJSON_Delete(json);
  390.         closesocket(_sock);
  391.         break;
  392.  
  393.         bad:
  394.         send(_sock, head_bad, strlen(head_bad), 0);
  395.         if (json != NULL) cJSON_Delete(json);
  396.         closesocket(_sock);
  397.  
  398.         fputs(body_bad, log);
  399.         flushlog();
  400.     }
  401.     return ret;
  402. }
  403.  
  404. SOCKET accept_conn(SOCKET sock)
  405. {
  406.         SOCKET _sock;
  407.         struct sockaddr_in _addr;
  408.         int szaddr = sizeof(struct sockaddr_in);
  409.  
  410.         time_t tcurrent;
  411.  
  412.         _sock = accept(sock, (sockaddr *)&_addr, &szaddr);
  413.  
  414.         tcurrent = time(NULL);
  415.  
  416.         fprintf(log, "\r\n%s\r\n"
  417.                      "connection accepted from: %s\r\n",
  418.                      ctime(&tcurrent),
  419.                      inet_ntoa(_addr.sin_addr));
  420.  
  421.         return _sock;
  422. }
  423.  
  424. int match(const char *, const char *);
  425.  
  426. int valid_plate(char *plate)
  427. {
  428.     enum { UkrOld, UkrNew, NumFmt };
  429.  
  430.     static const char *format[] = { "DDD-DDCC",
  431.                                     "CCDDDDCC" };
  432.  
  433.     for (int i = 0; i < NumFmt; ++i) {
  434.         if (match(plate, format[i]))
  435.             return 1;
  436.     }
  437.     return 0;
  438. }
  439.  
  440. int match(const char *plate, const char *format)
  441. {
  442.     const char *p, *f;
  443.     for (p = plate, f = format; *p && *f; ++p, ++f)
  444.     {
  445.         int ok;
  446.         switch (*f) {
  447.             case 'L': ok = ('A' <= *p && *p <= 'Z'); break;
  448.             case 'C': ok = (strchr("ABCEHIKMOPTX", *p) != NULL); break;
  449.             case 'D': ok = ('0' <= *p && *p <= '9'); break;
  450.             default:  ok = (*p == *f);
  451.         }
  452.         if (!ok) return 0;
  453.     }
  454.     if (*p || *f) return 0;
  455.  
  456.     return 1;
  457. }
  458.  
  459. void time_to_nettime(time_t time, NET_TIME *pnettime)
  460. {
  461.     struct tm *ymdhms = localtime(&time);
  462.  
  463.     pnettime->dwYear   = ymdhms->tm_year + 1900;
  464.     pnettime->dwMonth  = ymdhms->tm_mon + 1;
  465.     pnettime->dwDay    = ymdhms->tm_mday;
  466.     pnettime->dwHour   = ymdhms->tm_hour;
  467.     pnettime->dwMinute = ymdhms->tm_min;
  468.     pnettime->dwSecond = ymdhms->tm_sec;
  469. }
  470.  
  471. void print_inoprec(FILE *file, NET_IN_OPERATE_TRAFFIC_LIST_RECORD *inoprec)
  472. {
  473.     #define RECINFO     (inoprec->pstOpreateInfo)
  474.     #define INSRECINFO  (((NET_INSERT_RECORD_INFO *)RECINFO)->pRecordInfo)
  475.     #define REMRECINFO  ((NET_REMOVE_RECORD_INFO *)RECINFO)
  476.     #define TBEGIN      (INSRECINFO->stBeginTime)
  477.     #define TCANCEL     (INSRECINFO->stCancelTime)
  478.  
  479.     if (inoprec->emOperateType == NET_TRAFFIC_LIST_INSERT)
  480.     {
  481.         fprintf(file,
  482.                 "INSERTION\r\n"
  483.                 "plate: %s\r\n"
  484.                 "owner: %s\r\n"
  485.                 "begin  time: %02d:%02d:%02d - %02d.%02d.%04d\r\n"
  486.                 "cancel time: %02d:%02d:%02d - %02d.%02d.%04d\r\n",
  487.                 INSRECINFO->szPlateNumber,
  488.                 INSRECINFO->szMasterOfCar,
  489.                 TBEGIN.dwHour, TBEGIN.dwMinute, TBEGIN.dwSecond,
  490.                 TBEGIN.dwDay, TBEGIN.dwMonth, TBEGIN.dwYear,
  491.                 TCANCEL.dwHour, TCANCEL.dwMinute, TCANCEL.dwSecond,
  492.                 TCANCEL.dwDay, TCANCEL.dwMonth, TCANCEL.dwYear);
  493.     }
  494.     else
  495.     {
  496.         fprintf(file,
  497.                 "REMOVAL\r\n"
  498.                 "rec.no.: %d\r\n", REMRECINFO->nRecordNo);
  499.     }
  500.  
  501.     #undef TCANCEL
  502.     #undef TBEGIN
  503.     #undef REMRECINFO
  504.     #undef INSRECINFO
  505.     #undef RECINFO
  506. }
  507.  
  508. void flushlog()
  509. {
  510.     char *buf;
  511.     size_t sz;
  512.  
  513.     sz = ftell(log);
  514.     buf = (char *)malloc(sz);
  515.     rewind(log);
  516.  
  517.     fread(buf, 1, sz, log);
  518.     fwrite(buf, 1, sz, stdout);
  519.     fwrite(buf, 1, sz, logfile);
  520.     fflush(stdout);
  521.     fflush(logfile);
  522.  
  523.     free(buf);
  524.     fclose(log);
  525.     log = tmpfile();
  526. }
  527.  
  528. void terminator(int val)
  529. {
  530.     flushlog();
  531.     exit(0);
  532. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement