Пример #1
0
void client_handler(int client_socket, server_parameters * parameters) {
    to_log(&logger, "Client handler started: Worker %d\n", getpid());

    char buffer[1024];
    int read  = recv(client_socket, buffer, 1024, MSG_NOSIGNAL);
    while (1) {
        if (read == -1 && (errno == EAGAIN || errno == EWOULDBLOCK)) {
            // should retry
            continue;
        } else if (read <= 0) {
            to_log(&logger, "Worker %d: client discontected\n", getpid());
            break;
        } else {
            to_log(&logger, "Worker %d: received request: %s",
                getpid(), buffer);
            int response_length = 0;
            char * response = handle_http_request(buffer, read, &response_length,
                parameters->directory);
            to_log(&logger, "Worker %d: sending response: %s",
                getpid(), response);
            send(client_socket, response, response_length, MSG_NOSIGNAL);
            free(response);
            close(client_socket);
            break;
        }
    }
    exit(0);
}
Пример #2
0
int main(int argc, char **argv) {
	printf("Starting Simple Http Server...\n");

    struct server_parameters server_parameters;
    if (parse_arguments(argc, argv, &server_parameters) < 0) {
        printf("Failed to parse cmd arguments\n");
        goto exit;
    }
    printf("Server parameters: ");
    print_server_parameters(&server_parameters);
    printf("\n");

    if (daemonize() < 0) {
        printf("Failed to become daemon process.\n");
        goto exit;
    }

    if (logger_init(&logger, LOG_FILE) < 0) {
        exit(-2);
    }

    to_log(&logger, "Simple http server with pid %d started logging.\n", getpid());

    /* lets remove dead processes */
    struct sigaction sa;
    sa.sa_handler = sigchld_handler;
    sigemptyset(&sa.sa_mask);
    sa.sa_flags = SA_RESTART;
    if (sigaction(SIGCHLD, &sa, NULL) == -1) {
        to_log(&logger, "Failed to set up SIGCHLD handler: %d\n",
            strerror(errno));
        goto exit_with_logging;
    }

    accept_clients_loop(&server_parameters);

    sleep(3);

    to_log(&logger, "Simple http server is stopping.\n");

exit_with_logging:
    logger_close(&logger);


exit:
	return 0;
}
Пример #3
0
void run_client_handler(int client_socket, server_parameters * parameters) {
    pid_t pid = fork();
    if (pid < 0) {
        to_log(&logger, "Failed to fork client handler process:\n",
            strerror(errno));
    } else if (pid > 0) {
        // this is a server process, nothing to do
        return;
    } else {
        // this is a process to handle client
        client_handler(client_socket, parameters);
    }
}
Пример #4
0
void usage_report()
{
	if(!usage_per_30min.empty())
	{
		// compute average:
		int sum = 0;
		for(vector<short>::const_iterator i = usage_per_30min.begin();
			i != usage_per_30min.end(); ++i)
			sum += *i;
		to_log("Average presence: " +
			lex_cast_fl(float(sum)/usage_per_30min.size()));
		usage_per_30min.clear();
	}
}
Пример #5
0
void write_player_stats()
{
	string fname = Config::get_config_dir() + playerfilename;
	ofstream file(fname.c_str(), ios_base::binary);
	if(!file)
	{
		to_log("ERROR: could not open player data for writing!");
		return;
	}

	file.write(reinterpret_cast<const char*>(&STAT_VERSION), sizeof(short));

	short numpl;
	if((signed int)(known_players.size()) > MAX_STORED_PLAYERS)
		numpl = MAX_STORED_PLAYERS;
	else // this is done like this 'cuz basically the size can be more than a short fits
		numpl = known_players.size();
	// Note that when called between maps we are writing bots' stats into the
	// file, too!
	file.write(reinterpret_cast<char*>(&numpl), sizeof(short));
	for(list<PlayerStats>::iterator it = known_players.begin();
		it != known_players.end(); ++it)
	{
		file.write(reinterpret_cast<char*>(&it->ID), sizeof(short));
		file.write(known_players.front().password, PASSW_LEN);
		file.write(reinterpret_cast<char*>(it->kills), MAX_WAY_TO_KILL*sizeof(long));
		file.write(reinterpret_cast<char*>(&it->deaths), sizeof(long));
		file.write(reinterpret_cast<char*>(&it->tks), sizeof(long));
		file.write(reinterpret_cast<char*>(&it->healing_recvd), sizeof(long));
		file.write(reinterpret_cast<char*>(&it->total_time), sizeof(long));
		file.write(reinterpret_cast<char*>(&it->time_specced), sizeof(long));
		file.write(reinterpret_cast<char*>(it->time_played), NO_CLASS*sizeof(long));
		file.write(reinterpret_cast<char*>(&it->arch_hits), sizeof(long));
		file.write(reinterpret_cast<char*>(&it->arch_shots), sizeof(long));
		file.write(reinterpret_cast<char*>(&it->cm_hits), sizeof(long));
		file.write(reinterpret_cast<char*>(&it->cm_shots), sizeof(long));
		file.write(reinterpret_cast<char*>(&it->ad_lvl), sizeof(e_AdminLvl));
		file.write(reinterpret_cast<char*>(&it->last_seen), sizeof(time_t));
		numpl = it->last_known_as.size();
		file.write(reinterpret_cast<char *>(&numpl), sizeof(short));
		file.write(it->last_known_as.c_str(), numpl);
	}
}
Пример #6
0
static gboolean dt_iop_basecurve_motion_notify(GtkWidget *widget, GdkEventMotion *event, gpointer user_data)
{
  dt_iop_module_t *self = (dt_iop_module_t *)user_data;
  dt_iop_basecurve_gui_data_t *c = (dt_iop_basecurve_gui_data_t *)self->gui_data;
  dt_iop_basecurve_params_t *p = (dt_iop_basecurve_params_t *)self->params;
  int ch = 0;
  int nodes = p->basecurve_nodes[ch];
  dt_iop_basecurve_node_t *basecurve = p->basecurve[ch];

  GtkAllocation allocation;
  gtk_widget_get_allocation(widget, &allocation);
  const int inset = DT_GUI_CURVE_EDITOR_INSET;
  int height = allocation.height - 2 * inset, width = allocation.width - 2 * inset;
  c->mouse_x = CLAMP(event->x - inset, 0, width);
  c->mouse_y = CLAMP(event->y - inset, 0, height);

  const float mx = c->mouse_x / (float)width;
  const float my = 1.0f - c->mouse_y / (float)height;
  const float linx = to_lin(mx, c->loglogscale), liny = to_lin(my, c->loglogscale);

  if(event->state & GDK_BUTTON1_MASK)
  {
    // got a vertex selected:
    if(c->selected >= 0)
    {
      basecurve[c->selected].x = linx;
      basecurve[c->selected].y = liny;

      // delete vertex if order has changed:
      if(nodes > 2)
        if((c->selected > 0 && basecurve[c->selected - 1].x >= linx)
           || (c->selected < nodes - 1 && basecurve[c->selected + 1].x <= linx))
        {
          for(int k = c->selected; k < nodes - 1; k++)
          {
            basecurve[k].x = basecurve[k + 1].x;
            basecurve[k].y = basecurve[k + 1].y;
          }
          c->selected = -2; // avoid re-insertion of that point immediately after this
          p->basecurve_nodes[ch]--;
        }
      dt_dev_add_history_item(darktable.develop, self, TRUE);
    }
    else if(nodes < 20 && c->selected >= -1)
    {
      // no vertex was close, create a new one!
      if(basecurve[0].x > linx)
        c->selected = 0;
      else
        for(int k = 1; k < nodes; k++)
        {
          if(basecurve[k].x > linx)
          {
            c->selected = k;
            break;
          }
        }
      if(c->selected == -1) c->selected = nodes;
      for(int i = nodes; i > c->selected; i--)
      {
        basecurve[i].x = basecurve[i - 1].x;
        basecurve[i].y = basecurve[i - 1].y;
      }
      // found a new point
      basecurve[c->selected].x = linx;
      basecurve[c->selected].y = liny;
      p->basecurve_nodes[ch]++;
      dt_dev_add_history_item(darktable.develop, self, TRUE);
    }
  }
  else
  {
    // minimum area around the node to select it:
    float min = .04f;
    min *= min; // comparing against square
    int nearest = -1;
    for(int k = 0; k < nodes; k++)
    {
      float dist
          = (my - to_log(basecurve[k].y, c->loglogscale)) * (my - to_log(basecurve[k].y, c->loglogscale))
            + (mx - to_log(basecurve[k].x, c->loglogscale)) * (mx - to_log(basecurve[k].x, c->loglogscale));
      if(dist < min)
      {
        min = dist;
        nearest = k;
      }
    }
    c->selected = nearest;
  }
  gtk_widget_queue_draw(widget);
  return TRUE;
}
Пример #7
0
static gboolean dt_iop_basecurve_draw(GtkWidget *widget, cairo_t *crf, gpointer user_data)
{
  dt_iop_module_t *self = (dt_iop_module_t *)user_data;
  dt_iop_basecurve_gui_data_t *c = (dt_iop_basecurve_gui_data_t *)self->gui_data;
  dt_iop_basecurve_params_t *p = (dt_iop_basecurve_params_t *)self->params;

  int nodes = p->basecurve_nodes[0];
  dt_iop_basecurve_node_t *basecurve = p->basecurve[0];
  if(c->minmax_curve_type != p->basecurve_type[0] || c->minmax_curve_nodes != p->basecurve_nodes[0])
  {
    dt_draw_curve_destroy(c->minmax_curve);
    c->minmax_curve = dt_draw_curve_new(0.0, 1.0, p->basecurve_type[0]);
    c->minmax_curve_nodes = p->basecurve_nodes[0];
    c->minmax_curve_type = p->basecurve_type[0];
    for(int k = 0; k < p->basecurve_nodes[0]; k++)
      (void)dt_draw_curve_add_point(c->minmax_curve, p->basecurve[0][k].x, p->basecurve[0][k].y);
  }
  else
  {
    for(int k = 0; k < p->basecurve_nodes[0]; k++)
      dt_draw_curve_set_point(c->minmax_curve, k, p->basecurve[0][k].x, p->basecurve[0][k].y);
  }
  dt_draw_curve_t *minmax_curve = c->minmax_curve;
  dt_draw_curve_calc_values(minmax_curve, 0.0, 1.0, DT_IOP_TONECURVE_RES, c->draw_xs, c->draw_ys);

  const float xm = basecurve[nodes - 1].x;
  const float x[4] = { 0.7f * xm, 0.8f * xm, 0.9f * xm, 1.0f * xm };
  const float y[4] = { c->draw_ys[CLAMP((int)(x[0] * DT_IOP_TONECURVE_RES), 0, DT_IOP_TONECURVE_RES - 1)],
                       c->draw_ys[CLAMP((int)(x[1] * DT_IOP_TONECURVE_RES), 0, DT_IOP_TONECURVE_RES - 1)],
                       c->draw_ys[CLAMP((int)(x[2] * DT_IOP_TONECURVE_RES), 0, DT_IOP_TONECURVE_RES - 1)],
                       c->draw_ys[CLAMP((int)(x[3] * DT_IOP_TONECURVE_RES), 0, DT_IOP_TONECURVE_RES - 1)] };
  float unbounded_coeffs[3];
  dt_iop_estimate_exp(x, y, 4, unbounded_coeffs);

  const int inset = DT_GUI_CURVE_EDITOR_INSET;
  GtkAllocation allocation;
  gtk_widget_get_allocation(widget, &allocation);
  int width = allocation.width, height = allocation.height;
  cairo_surface_t *cst = dt_cairo_image_surface_create(CAIRO_FORMAT_ARGB32, width, height);
  cairo_t *cr = cairo_create(cst);
  // clear bg
  cairo_set_source_rgb(cr, .2, .2, .2);
  cairo_paint(cr);

  cairo_translate(cr, inset, inset);
  width -= 2 * inset;
  height -= 2 * inset;

#if 0
  // draw shadow around
  float alpha = 1.0f;
  for(int k=0; k<inset; k++)
  {
    cairo_rectangle(cr, -k, -k, width + 2*k, height + 2*k);
    cairo_set_source_rgba(cr, 0, 0, 0, alpha);
    alpha *= 0.6f;
    cairo_fill(cr);
  }
#else
  cairo_set_line_width(cr, DT_PIXEL_APPLY_DPI(1.0));
  cairo_set_source_rgb(cr, .1, .1, .1);
  cairo_rectangle(cr, 0, 0, width, height);
  cairo_stroke(cr);
#endif

  cairo_set_source_rgb(cr, .3, .3, .3);
  cairo_rectangle(cr, 0, 0, width, height);
  cairo_fill(cr);

  cairo_translate(cr, 0, height);
  cairo_scale(cr, 1.0f, -1.0f);

  // draw grid
  cairo_set_line_width(cr, DT_PIXEL_APPLY_DPI(.4));
  cairo_set_source_rgb(cr, .1, .1, .1);
  if(c->loglogscale)
    dt_draw_loglog_grid(cr, 4, 0, 0, width, height, c->loglogscale);
  else
    dt_draw_grid(cr, 4, 0, 0, width, height);

  // draw nodes positions
  cairo_set_line_width(cr, DT_PIXEL_APPLY_DPI(1.));
  cairo_set_source_rgb(cr, 0.6, 0.6, 0.6);
  for(int k = 0; k < nodes; k++)
  {
    const float x = to_log(basecurve[k].x, c->loglogscale), y = to_log(basecurve[k].y, c->loglogscale);
    cairo_arc(cr, x * width, y * height, DT_PIXEL_APPLY_DPI(3), 0, 2. * M_PI);
    cairo_stroke(cr);
  }

  // draw selected cursor
  cairo_set_line_width(cr, DT_PIXEL_APPLY_DPI(1.));

  if(c->selected >= 0)
  {
    cairo_set_source_rgb(cr, .9, .9, .9);
    const float x = to_log(basecurve[c->selected].x, c->loglogscale),
                y = to_log(basecurve[c->selected].y, c->loglogscale);
    cairo_arc(cr, x * width, y * height, DT_PIXEL_APPLY_DPI(4), 0, 2. * M_PI);
    cairo_stroke(cr);
  }

  // draw curve
  cairo_set_line_width(cr, DT_PIXEL_APPLY_DPI(2.));
  cairo_set_source_rgb(cr, .9, .9, .9);
  // cairo_set_line_cap  (cr, CAIRO_LINE_CAP_SQUARE);
  cairo_move_to(cr, 0, height * to_log(c->draw_ys[0], c->loglogscale));
  for(int k = 1; k < DT_IOP_TONECURVE_RES; k++)
  {
    const float xx = k / (DT_IOP_TONECURVE_RES - 1.0);
    if(xx > xm)
    {
      const float yy = dt_iop_eval_exp(unbounded_coeffs, xx);
      const float x = to_log(xx, c->loglogscale), y = to_log(yy, c->loglogscale);
      cairo_line_to(cr, x * width, height * y);
    }
    else
    {
      const float yy = c->draw_ys[k];
      const float x = to_log(xx, c->loglogscale), y = to_log(yy, c->loglogscale);
      cairo_line_to(cr, x * width, height * y);
    }
  }
  cairo_stroke(cr);

  cairo_destroy(cr);
  cairo_set_source_surface(crf, cst, 0, 0);
  cairo_paint(crf);
  cairo_surface_destroy(cst);
  return TRUE;
}
Пример #8
0
static gboolean dt_iop_basecurve_button_press(GtkWidget *widget, GdkEventButton *event, gpointer user_data)
{
  dt_iop_module_t *self = (dt_iop_module_t *)user_data;
  dt_iop_basecurve_params_t *p = (dt_iop_basecurve_params_t *)self->params;
  dt_iop_basecurve_params_t *d = (dt_iop_basecurve_params_t *)self->default_params;
  dt_iop_basecurve_gui_data_t *c = (dt_iop_basecurve_gui_data_t *)self->gui_data;

  int ch = 0;
  int nodes = p->basecurve_nodes[ch];
  dt_iop_basecurve_node_t *basecurve = p->basecurve[ch];

  if(event->button == 1)
  {
    if(event->type == GDK_BUTTON_PRESS && (event->state & GDK_CONTROL_MASK) == GDK_CONTROL_MASK
      && nodes < MAXNODES && c->selected == -1)
    {
      // if we are not on a node -> add a new node at the current x of the pointer and y of the curve at that x
      const int inset = DT_GUI_CURVE_EDITOR_INSET;
      GtkAllocation allocation;
      gtk_widget_get_allocation(widget, &allocation);
      int height = allocation.height - 2 * inset, width = allocation.width - 2 * inset;
      c->mouse_x = CLAMP(event->x - inset, 0, width);
      c->mouse_y = CLAMP(event->y - inset, 0, height);

      const float mx = c->mouse_x / (float)width;
      const float linx = to_lin(mx, c->loglogscale);

      // don't add a node too close to others in x direction, it can crash dt
      int selected = -1;
      if(basecurve[0].x > linx)
        selected = 0;
      else
      {
        for(int k = 1; k < nodes; k++)
        {
          if(basecurve[k].x > linx)
          {
            selected = k;
            break;
          }
        }
      }
      if(selected == -1) selected = nodes;
      // > 0 -> check distance to left neighbour
      // < nodes -> check distance to right neighbour
      if(!((selected > 0 && linx - basecurve[selected - 1].x <= 0.025) ||
           (selected < nodes && basecurve[selected].x - linx <= 0.025)))
      {
        // evaluate the curve at the current x position
        const float y = dt_draw_curve_calc_value(c->minmax_curve, linx);

        if(y >= 0.0 && y <= 1.0) // never add something outside the viewport, you couldn't change it afterwards
        {
          // create a new node
          int selected = _add_node(basecurve, &p->basecurve_nodes[ch], linx, y);

          // maybe set the new one as being selected
          float min = .04f;
          min *= min; // comparing against square
          for(int k = 0; k < nodes; k++)
          {
            float other_y = to_log(basecurve[k].y, c->loglogscale);
            float dist = (y - other_y) * (y - other_y);
            if(dist < min) c->selected = selected;
          }

          dt_dev_add_history_item(darktable.develop, self, TRUE);
          gtk_widget_queue_draw(self->widget);
        }
      }
      return TRUE;
    }
    else if(event->type == GDK_2BUTTON_PRESS)
    {
      // reset current curve
      p->basecurve_nodes[ch] = d->basecurve_nodes[ch];
      p->basecurve_type[ch] = d->basecurve_type[ch];
      for(int k = 0; k < d->basecurve_nodes[ch]; k++)
      {
        p->basecurve[ch][k].x = d->basecurve[ch][k].x;
        p->basecurve[ch][k].y = d->basecurve[ch][k].y;
      }
      c->selected = -2; // avoid motion notify re-inserting immediately.
      dt_dev_add_history_item(darktable.develop, self, TRUE);
      gtk_widget_queue_draw(self->widget);
      return TRUE;
    }
  }
  return FALSE;
}
Пример #9
0
int main(int argc, const char * argv[]) {
    
    
    std::ofstream to_log(to_log_file_path.c_str());
    std::ofstream to_rpy(rpy_file_path.c_str());
    std::ofstream gps_out(gps_out_path.c_str());
    std::ofstream gps_filter_out(gps_filter_out_path.c_str());
    std::ofstream mag_out(mag_out_path.c_str());
    
    try {
        
    // Declaring objects used for inertial navigation
        ACCELEROMETER acc(acc_file_path, Captor::COLD_START);
        GYRO gyro(gyro_file_path, Captor::COLD_START);
        MAGNETOMETER mag(mag_file_path, Captor::COLD_START);
        GPS gps(gps_file_path,GPS::UBLOX);
        GPS_Filter gps_filter(&gps);
        EKF ekf(&gps_filter,&acc,&gyro,&mag);
        
    
    
    
    // Getting offset and gain for accelerometer, gyroscope and magnetometer. Getting GPS HOME field.
    // This routine will warn you if one of the offset couldn't be updated
        int ret = acc.initOffsets();
        if (ret != 1) std::cout << "Couldn't get acc offsets !" << std::endl;
        else std::cout << "Acc offsets updated" << std::endl;
        ret = acc.initGain();
        if (ret != 1) std::cout << "Couldn't get acc gain !" << std::endl;
        else std::cout << "Acc gain updated" << std::endl;
        
        // Advanced calibration for acc (offset and gain)
#ifdef ADCALIBRATION
        ret = acc.performAdvancedAccCalibration();
        if (ret !=1) std::cout << "Couldn't perform acc advanced calibration method" << std::endl;
        else {
            std::cout << "Acc advanced calibration performed" << std::endl;
            acc.correct_GN();
        }
#endif
        
        ret = gyro.initOffsets();
        if (ret != 1) std::cout << "Couldn't get gyro offsets !" << std::endl;
        else std::cout << "Gyro offsets updated" << std::endl;
        ret = gyro.initGain();
        if (ret != 1) std::cout << "Couldn't get gyro gain !" << std::endl;
        else std::cout << "Gyro gain updated" << std::endl;
        
        ret = mag.initOffsets();
        if (ret != 1) std::cout << "Couldn't get magnetometer offsets !" << std::endl;
        else std::cout << "Mag offsets updated" << std::endl;
        
        ret = gps.setHome();
        if (ret != 1) std::cout << "Couldn't get HOME !" << std::endl;
        else std::cout << "HOME updated" << std::endl;
        
        
        
    // Reading lines
        // We create the buffer for the sensor's output values
        Eigen::Vector3f acc_vector_buffer;
        Eigen::Vector3f gyro_vector_buffer;
        Eigen::Vector3d gps_buffer_vector;
        Eigen::Vector3d gps_position_vector;
        
       // We update and correct the magnetometer
        mag._init_earth_even_magnetic_field();
        mag.update_correct();
        // We initialize the state vector giving the initial heading
        ekf.init_state_vector(mag.getHeading());
        //ekf.init_state_vector();
        to_rpy << TODEG*(ekf.toRPY(ekf.get_state_vector())).transpose() << std::endl;           // Storing operation
        
        
        
        while (!acc.line_end && !gyro.line_end){
            
            // Reading from inertial captors and correcting the outputs
            acc.getOutput(&acc_vector_buffer);
            acc.correctOutput(&acc_vector_buffer, ekf.getDCM());
            gyro.getOutput(&gyro_vector_buffer);
            gyro.correctOutput(&gyro_vector_buffer);
            // Updating and correcting magnetometer
            mag.update_correct();
            // Updating GPS and storing into the &gps_buffer_vector
            gps.update(&gps_buffer_vector);
            
            
        
            // Predicting the state vector
            // Extended Kalman Filter according step is the prediction step. We first build the Jacobian matrix linearized around the current state and we then multiply the currrent state vector by such a matrix
            ekf.build_jacobian_matrix(&acc_vector_buffer, &gyro_vector_buffer);
            ekf.predict();
            
            to_rpy << TODEG*(ekf.getRPY()).transpose() << std::endl;                            // Storing operation for data exploitation
            to_log << ekf.get_state_vector().transpose() << std::endl;                          // Storing operation for data exploitation
            //mag_out << TODEG*mag.getHeading() << std::endl;                                   // Storing operation for data exploitation
            mag_out << TODEG*mag.getHeading((ekf.getRPY())(1),(ekf.getRPY())(0)) << std::endl;  // Storing operation for data exploitation

            
    

            
            // Checking inf a new gps data is availaible
            if (gps.isAvailable()){
                // If yes, we first update the GPS filter
                gps.calculatePositionFromHome(&gps_buffer_vector);
                gps_out << gps.getActualPosition().transpose() << std::endl;
                gps.actualizeInternDatas(&gps_buffer_vector);
                gps_filter.predict();
                gps_filter.updateFilter();
                gps_filter_out << gps_filter.getState().transpose() << std::endl;               // Storing operation for data exploitation
                // And we then correct the EKF filter by correcting in order position, speed and quaternion attitude vector
                //ekf.correct();
                //gps_filter.updateSpeedEKF(ekf.getCurrentSpeed());
            }
            
        }

    }
    catch (std::exception const& e)
    { std::cout << e.what() <<  " file " << std::endl; }
    
    

    
    return 0;
}
Пример #10
0
void accept_clients_loop(server_parameters * parameters) {
    int master_socket = socket(AF_INET, SOCK_STREAM, 0);
    if (master_socket < 0) {
        to_log(&logger, "Failed to create master socket: %s\n", strerror(errno));
        return;
    } else {
        to_log(&logger, "Master socket created.\n");
    }

    struct sockaddr_in sa;
    sa.sin_family = AF_INET;
    sa.sin_port = htons(parameters->port);
    if (inet_aton(parameters->ip, &sa.sin_addr) == 0) {
        to_log(&logger, "Failed to convert address.\n");
        goto close_master_socket;
    }
    int yes = 1;
    if (setsockopt(master_socket, SOL_SOCKET, SO_REUSEADDR, &yes,
        sizeof(int)) == -1) {
            to_log(&logger, "Failed setsockopt %s\n", strerror(errno));
            goto close_master_socket;
        }
    if (bind(master_socket, (struct sockaddr *) &sa, sizeof(sa)) < 0) {
        to_log(&logger, "Failed to bind: %s\n", strerror(errno));
        goto close_master_socket;
    } else {
        to_log(&logger, "Binded adderss\n");
    }

    //set_nonblock(master_socket);

    if (listen(master_socket, SOMAXCONN) < 0) {
        to_log(&logger, "Failed to listen: %s\n", strerror(errno));
        goto close_master_socket;
    } else {
        to_log(&logger, "Started listening master socket for clients\n");
    }

    while(1) {
        // accept connections and handle in separate processes
        struct sockaddr_in client_addr;
        socklen_t client_addr_len;
        int client_socket = accept(master_socket, (struct sockaddr*) &client_addr, &client_addr_len);
        if (client_socket > 0) {
            to_log(&logger, "Accepted a new connection\n");
            run_client_handler(client_socket, parameters);
            close(client_socket);
        } else {
            if (errno == EAGAIN) {
                continue;
            } else {
                to_log(&logger, "Failed to accept client connection: %s\n",
                    strerror(errno));
                break;
            }
        }
    }
    

close_master_socket:
    if (close(master_socket) != 0) {
        to_log(&logger, "Failed to close master socket: %s\n", strerror(errno));
        return;
    } else {
        to_log(&logger, "Closed master socket\n");
    }
}
Пример #11
0
// The nopurge argument indicates we are running the server with "--pstats"
void init_known_players(const bool nopurge)
{
	string fname = Config::get_config_dir() + playerfilename;
	ifstream file(fname.c_str(), ios_base::binary);
	if(!file)
	{
		to_log("Could not read player data; file missing or not readable.");
		return;
	}

	short numpl;
	file.read(reinterpret_cast<char*>(&numpl), sizeof(short));
	if(numpl != STAT_VERSION)
	{
		to_log("Wrong statistics version in player data! All statistics will be cleared!");
		return;
	}

	file.read(reinterpret_cast<char*>(&numpl), sizeof(short));
	if(numpl < 0 || numpl > MAX_STORED_PLAYERS)
	{
		to_log("Player datafile is corrupt! Ignoring the data!");
		return;
	}
	if(!nopurge)
		to_log("Player data contains " + lex_cast(numpl)
			+ " entries;");
	PlayerStats tmpstats;
	short sh; char ch;
	tmpstats.password[PASSW_LEN] = '\0';
	int tooold;
	if(nopurge)
		tooold = 0;
	else // statpurge is hours, tooold seconds:
		tooold = 60*60*Config::int_settings[Config::IS_STATPURGE];
	while(numpl--)
	{
		file.read(reinterpret_cast<char*>(&tmpstats.ID), sizeof(short));
		file.read(tmpstats.password, PASSW_LEN);
		file.read(reinterpret_cast<char*>(tmpstats.kills), MAX_WAY_TO_KILL*sizeof(long));
		file.read(reinterpret_cast<char*>(&tmpstats.deaths), sizeof(long));
		file.read(reinterpret_cast<char*>(&tmpstats.tks), sizeof(long));
		file.read(reinterpret_cast<char*>(&tmpstats.healing_recvd), sizeof(long));
		file.read(reinterpret_cast<char*>(&tmpstats.total_time), sizeof(long));
		file.read(reinterpret_cast<char*>(&tmpstats.time_specced), sizeof(long));
		file.read(reinterpret_cast<char*>(tmpstats.time_played), NO_CLASS*sizeof(long));
		file.read(reinterpret_cast<char*>(&tmpstats.arch_hits), sizeof(long));
		file.read(reinterpret_cast<char*>(&tmpstats.arch_shots), sizeof(long));
		file.read(reinterpret_cast<char*>(&tmpstats.cm_hits), sizeof(long));
		file.read(reinterpret_cast<char*>(&tmpstats.cm_shots), sizeof(long));
		file.read(reinterpret_cast<char*>(&tmpstats.ad_lvl), sizeof(e_AdminLvl));
		file.read(reinterpret_cast<char*>(&tmpstats.last_seen), sizeof(time_t));
		tmpstats.last_known_as.clear();
		for(file.read(reinterpret_cast<char *>(&sh), sizeof(short)); sh > 0; --sh)
		{
			file.read(reinterpret_cast<char *>(&ch), sizeof(char));
			tmpstats.last_known_as += ch;
		}
		if(!tooold || tmpstats.ad_lvl > AL_REG || (time(NULL) - tmpstats.last_seen) < tooold)
			known_players.push_back(tmpstats);
	}
	if(!nopurge)
		to_log(lex_cast(known_players.size()) + " entries accepted.");
}