18eda0a3a73022e04e64419b8d7bd62da3dbe3c0etturney//
28eda0a3a73022e04e64419b8d7bd62da3dbe3c0etturney//  Copyright (C) 2015 Google, Inc.
38eda0a3a73022e04e64419b8d7bd62da3dbe3c0etturney//
48eda0a3a73022e04e64419b8d7bd62da3dbe3c0etturney//  Licensed under the Apache License, Version 2.0 (the "License");
58eda0a3a73022e04e64419b8d7bd62da3dbe3c0etturney//  you may not use this file except in compliance with the License.
68eda0a3a73022e04e64419b8d7bd62da3dbe3c0etturney//  You may obtain a copy of the License at:
78eda0a3a73022e04e64419b8d7bd62da3dbe3c0etturney//
88eda0a3a73022e04e64419b8d7bd62da3dbe3c0etturney//  http://www.apache.org/licenses/LICENSE-2.0
98eda0a3a73022e04e64419b8d7bd62da3dbe3c0etturney//
108eda0a3a73022e04e64419b8d7bd62da3dbe3c0etturney//  Unless required by applicable law or agreed to in writing, software
118eda0a3a73022e04e64419b8d7bd62da3dbe3c0etturney//  distributed under the License is distributed on an "AS IS" BASIS,
128eda0a3a73022e04e64419b8d7bd62da3dbe3c0etturney//  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
138eda0a3a73022e04e64419b8d7bd62da3dbe3c0etturney//  See the License for the specific language governing permissions and
148eda0a3a73022e04e64419b8d7bd62da3dbe3c0etturney//  limitations under the License.
158eda0a3a73022e04e64419b8d7bd62da3dbe3c0etturney//
168eda0a3a73022e04e64419b8d7bd62da3dbe3c0etturney
178eda0a3a73022e04e64419b8d7bd62da3dbe3c0etturney#include "base.h"
188eda0a3a73022e04e64419b8d7bd62da3dbe3c0etturney#include <rapidjson/document.h>
198eda0a3a73022e04e64419b8d7bd62da3dbe3c0etturney#include <rapidjson/writer.h>
208eda0a3a73022e04e64419b8d7bd62da3dbe3c0etturney#include <rapidjson/stringbuffer.h>
218eda0a3a73022e04e64419b8d7bd62da3dbe3c0etturney#include "utils/command_receiver.h"
228eda0a3a73022e04e64419b8d7bd62da3dbe3c0etturney
238eda0a3a73022e04e64419b8d7bd62da3dbe3c0etturney#include <arpa/inet.h>
248eda0a3a73022e04e64419b8d7bd62da3dbe3c0etturney#include <errno.h>
258eda0a3a73022e04e64419b8d7bd62da3dbe3c0etturney#include <iostream>
268eda0a3a73022e04e64419b8d7bd62da3dbe3c0etturney#include <netinet/in.h>
278eda0a3a73022e04e64419b8d7bd62da3dbe3c0etturney#include <pthread.h>
288eda0a3a73022e04e64419b8d7bd62da3dbe3c0etturney#include <signal.h>
298eda0a3a73022e04e64419b8d7bd62da3dbe3c0etturney#include <stdlib.h>
308eda0a3a73022e04e64419b8d7bd62da3dbe3c0etturney#include <sys/types.h>
318eda0a3a73022e04e64419b8d7bd62da3dbe3c0etturney#include <sys/socket.h>
328eda0a3a73022e04e64419b8d7bd62da3dbe3c0etturney#include <unistd.h>
338eda0a3a73022e04e64419b8d7bd62da3dbe3c0etturney
348eda0a3a73022e04e64419b8d7bd62da3dbe3c0etturneyconst int kBacklogInt = 10;
358eda0a3a73022e04e64419b8d7bd62da3dbe3c0etturney#define PORT 8080
368eda0a3a73022e04e64419b8d7bd62da3dbe3c0etturney#define SOCK_BUF_LEN 100
378eda0a3a73022e04e64419b8d7bd62da3dbe3c0etturney#define MEMSET_VALUE 0
388eda0a3a73022e04e64419b8d7bd62da3dbe3c0etturney
398eda0a3a73022e04e64419b8d7bd62da3dbe3c0etturneyint client_sock;
408eda0a3a73022e04e64419b8d7bd62da3dbe3c0etturneyint socket_desc;
418eda0a3a73022e04e64419b8d7bd62da3dbe3c0etturney
428eda0a3a73022e04e64419b8d7bd62da3dbe3c0etturneyvoid SockTest() {
438eda0a3a73022e04e64419b8d7bd62da3dbe3c0etturney  char str[SOCK_BUF_LEN];
448eda0a3a73022e04e64419b8d7bd62da3dbe3c0etturney  int listen_fd, comm_fd, c;
458eda0a3a73022e04e64419b8d7bd62da3dbe3c0etturney  struct sockaddr_in servaddr, client;
468eda0a3a73022e04e64419b8d7bd62da3dbe3c0etturney  rapidjson::Document d;
478eda0a3a73022e04e64419b8d7bd62da3dbe3c0etturney  rapidjson::StringBuffer buffer;
488eda0a3a73022e04e64419b8d7bd62da3dbe3c0etturney  rapidjson::Writer<rapidjson::StringBuffer> writer(buffer);
498eda0a3a73022e04e64419b8d7bd62da3dbe3c0etturney  CommandReceiver cr;
508eda0a3a73022e04e64419b8d7bd62da3dbe3c0etturney
518eda0a3a73022e04e64419b8d7bd62da3dbe3c0etturney  listen_fd = socket(AF_INET, SOCK_STREAM, 0);
528eda0a3a73022e04e64419b8d7bd62da3dbe3c0etturney  memset (&servaddr, MEMSET_VALUE, sizeof(servaddr));
538eda0a3a73022e04e64419b8d7bd62da3dbe3c0etturney  servaddr.sin_family = AF_INET;
548eda0a3a73022e04e64419b8d7bd62da3dbe3c0etturney  servaddr.sin_addr.s_addr = INADDR_ANY;
558eda0a3a73022e04e64419b8d7bd62da3dbe3c0etturney  servaddr.sin_port = htons(PORT);
568eda0a3a73022e04e64419b8d7bd62da3dbe3c0etturney
578eda0a3a73022e04e64419b8d7bd62da3dbe3c0etturney  int bind_result = bind(
588eda0a3a73022e04e64419b8d7bd62da3dbe3c0etturney          listen_fd, (struct sockaddr *) &servaddr, sizeof(servaddr));
598eda0a3a73022e04e64419b8d7bd62da3dbe3c0etturney  if (bind_result != 0) {
608eda0a3a73022e04e64419b8d7bd62da3dbe3c0etturney    LOG(ERROR) << sl4n::kTagStr <<
618eda0a3a73022e04e64419b8d7bd62da3dbe3c0etturney      ": Failed to assign the address to the socket."
628eda0a3a73022e04e64419b8d7bd62da3dbe3c0etturney      << " Error: " << strerror(errno) << ", " << errno;
638eda0a3a73022e04e64419b8d7bd62da3dbe3c0etturney    exit(1);
648eda0a3a73022e04e64419b8d7bd62da3dbe3c0etturney  }
658eda0a3a73022e04e64419b8d7bd62da3dbe3c0etturney
668eda0a3a73022e04e64419b8d7bd62da3dbe3c0etturney  int listen_result = listen(listen_fd, kBacklogInt);
678eda0a3a73022e04e64419b8d7bd62da3dbe3c0etturney  if (listen_result != 0) {
688eda0a3a73022e04e64419b8d7bd62da3dbe3c0etturney    LOG(ERROR) << sl4n::kTagStr << ": Failed to setup the passive socket."
698eda0a3a73022e04e64419b8d7bd62da3dbe3c0etturney     << " Error: " << strerror(errno) << ", " << errno;
708eda0a3a73022e04e64419b8d7bd62da3dbe3c0etturney    exit(1);
718eda0a3a73022e04e64419b8d7bd62da3dbe3c0etturney  }
728eda0a3a73022e04e64419b8d7bd62da3dbe3c0etturney
738eda0a3a73022e04e64419b8d7bd62da3dbe3c0etturney  comm_fd = accept(listen_fd, (struct sockaddr*)&client, (socklen_t*)&c);
748eda0a3a73022e04e64419b8d7bd62da3dbe3c0etturney  if (comm_fd == -1) {
758eda0a3a73022e04e64419b8d7bd62da3dbe3c0etturney    LOG(ERROR) << sl4n::kTagStr << ": Failed to accept the socket."
768eda0a3a73022e04e64419b8d7bd62da3dbe3c0etturney      << " Error: " << strerror(errno) << ", " << errno;
778eda0a3a73022e04e64419b8d7bd62da3dbe3c0etturney    exit(1);
788eda0a3a73022e04e64419b8d7bd62da3dbe3c0etturney  }
798eda0a3a73022e04e64419b8d7bd62da3dbe3c0etturney
808eda0a3a73022e04e64419b8d7bd62da3dbe3c0etturney  while (true) {
818eda0a3a73022e04e64419b8d7bd62da3dbe3c0etturney    memset(str, MEMSET_VALUE, sizeof(str));
828eda0a3a73022e04e64419b8d7bd62da3dbe3c0etturney    int read_result = read(comm_fd, str, SOCK_BUF_LEN);
838eda0a3a73022e04e64419b8d7bd62da3dbe3c0etturney    if (read_result < 0) {
848eda0a3a73022e04e64419b8d7bd62da3dbe3c0etturney      LOG(FATAL) << sl4n::kTagStr << ": Failed to write to the socket."
858eda0a3a73022e04e64419b8d7bd62da3dbe3c0etturney        << " Error: " << strerror(errno) << ", " << errno;
868eda0a3a73022e04e64419b8d7bd62da3dbe3c0etturney      exit(1);
878eda0a3a73022e04e64419b8d7bd62da3dbe3c0etturney    }
888eda0a3a73022e04e64419b8d7bd62da3dbe3c0etturney
898eda0a3a73022e04e64419b8d7bd62da3dbe3c0etturney    d.Parse(str);
908eda0a3a73022e04e64419b8d7bd62da3dbe3c0etturney    cr.Call(d);
918eda0a3a73022e04e64419b8d7bd62da3dbe3c0etturney    d.Accept(writer);
928eda0a3a73022e04e64419b8d7bd62da3dbe3c0etturney    std::string str2 = buffer.GetString();
938eda0a3a73022e04e64419b8d7bd62da3dbe3c0etturney    str2 += '\n';
948eda0a3a73022e04e64419b8d7bd62da3dbe3c0etturney    strncpy(str, str2.c_str(), sizeof(str)-1);
958eda0a3a73022e04e64419b8d7bd62da3dbe3c0etturney    int result = write(comm_fd, str, strlen(str)+1);
968eda0a3a73022e04e64419b8d7bd62da3dbe3c0etturney    if (result < 0) {
978eda0a3a73022e04e64419b8d7bd62da3dbe3c0etturney      LOG(FATAL) << sl4n::kTagStr << ": Failed to write to the socket."
988eda0a3a73022e04e64419b8d7bd62da3dbe3c0etturney        << " Error: " << strerror(errno) << ", " << errno;
998eda0a3a73022e04e64419b8d7bd62da3dbe3c0etturney      exit(1);
1008eda0a3a73022e04e64419b8d7bd62da3dbe3c0etturney    }
1018eda0a3a73022e04e64419b8d7bd62da3dbe3c0etturney    d.RemoveAllMembers(); // Remove all members from the json object
1028eda0a3a73022e04e64419b8d7bd62da3dbe3c0etturney    buffer.Clear();
1038eda0a3a73022e04e64419b8d7bd62da3dbe3c0etturney  }
1048eda0a3a73022e04e64419b8d7bd62da3dbe3c0etturney}
1058eda0a3a73022e04e64419b8d7bd62da3dbe3c0etturney
1068eda0a3a73022e04e64419b8d7bd62da3dbe3c0etturneyint main(int argc, char **argv) {
1078eda0a3a73022e04e64419b8d7bd62da3dbe3c0etturney    logging::LoggingSettings log_settings;
1088eda0a3a73022e04e64419b8d7bd62da3dbe3c0etturney    if (!logging::InitLogging(log_settings)) {
1098eda0a3a73022e04e64419b8d7bd62da3dbe3c0etturney      LOG(ERROR) << "Failed to set up logging";
1108eda0a3a73022e04e64419b8d7bd62da3dbe3c0etturney      return EXIT_FAILURE;
1118eda0a3a73022e04e64419b8d7bd62da3dbe3c0etturney    }
1128eda0a3a73022e04e64419b8d7bd62da3dbe3c0etturney    SockTest();
1138eda0a3a73022e04e64419b8d7bd62da3dbe3c0etturney    return 0;
1148eda0a3a73022e04e64419b8d7bd62da3dbe3c0etturney}
115