Пример #1
0
static gint sieve_pop_send_queue(SieveSession *session)
{
	SieveCommand *cmd;
	GSList *send_queue = session->send_queue;

	if (session->current_cmd) {
		command_free(session->current_cmd);
		session->current_cmd = NULL;
	}

	if (!send_queue)
		return SE_OK;

	cmd = (SieveCommand *)send_queue->data;
	session->send_queue = g_slist_next(send_queue);
	g_slist_free_1(send_queue);

	log_send(session, cmd);
	session->state = cmd->next_state;
	session->current_cmd = cmd;
	if (session_send_msg(SESSION(session), SESSION_SEND, cmd->msg) < 0)
		return SE_ERROR;

	return SE_OK;
}
Пример #2
0
/**
 * @brief ggs_client_send
 *
 * Send a message to the GGS server.
 * This function uses vnsprintf with some workaround
 * for MS-Windows incorrect behaviour.
 *
 * @param client GGS client.
 * @param fmt Text format.
 * @param ... other args.
 */
static void ggs_client_send(GGSClient *client, const char *fmt, ...) {
	int message_length;
	int size = 256;
	char *buffer;
 	va_list ap;

	if (fmt == NULL) return ;
	
	for (;;) {
		buffer = (char*) malloc(size + 1);
		if (buffer == NULL) return;
		va_start(ap, fmt);
		message_length = vsnprintf(buffer, size, fmt, ap);
		va_end(ap);

		if (message_length > 0 && message_length < size) break;

		if (message_length > 0) size = message_length + 1;
		else size *= 2;
		free(buffer);
	}

	log_send(ggs_log, "GGS", "%s", buffer);
	printf("GGS< %s", buffer);
	send(client->event.socket, buffer, message_length, 0);
	
	free(buffer);
}
Пример #3
0
void xerror(int a, int type)
{
	log_send(ps_log_pipe[1], type | PS_LOG_ERROR2 | 1, a);
	/*switch(a)
	{
		case PIPE_ERROR:
			fprintf(stderr, "ERROR WITH PIPE CREATING\n");
			break;
		case FORK_ERROR:
			fprintf(stderr, "ERROR WITH PROCCESS CREATING\n");
			break;
		case DUP_ERROR:
			fprintf(stderr, "ERROR WITH DUPLICATE FILE DESCRIPTOT\n");
			break;
		case MEMORY_ERROR:
			fprintf(stderr, "ERROR  WITH MEMORY\n");
			break;
		case READ_WRITE_ERROR:
			fprintf(stderr, "ERROR WITH READ/WRITE\n");
			break;
	} */
	if (type)
	{
		handle(0);
	}
	else
	{
		kill(getppid(), SIGUSR2);
	}
	exit(1);
}
Пример #4
0
static void handle_int(int sign) {
	if(sign == SIGINT) {
		server_close(connection);
		if(!db_close(database)) {
			log_send(LEVEL_ERROR, "[MAIN SV] Couldn't correctly logout from database.");
		}
		sem_remove(server_sems);
		log_close();
		exit(EXIT_FAILURE);
	} else if(sign == SIGCHLD) {
		int status;

		(*clients)--;
		waitpid(-1, &status, 0);
	}
}
Пример #5
0
int
daemon_send (struct daemon *d, const char *msg) {
    int     dest_sock;
    int     nb_sent;
    int     nb_sent_sum;
    int     send_size;
//    char    ending_char;

    // Log this (see ../util/logger.c to disactivate this)
    log_send (log_file, msg);

    dest_sock = d->socket;
    if (sem_wait (&d->socket_lock) < 0) {
        log_failure (log_file,
                    "failed to sem_wait socket_lock, error: %s",
                    strerror (errno));
        return -1;
    }

    // Now the socket is locked for us, let's send!
    send_size = strlen (msg);

    // Send the command
    nb_sent_sum = 0;
    while (nb_sent_sum < send_size) {
        nb_sent = send (dest_sock,
                        msg + nb_sent_sum,
                        send_size - nb_sent_sum,
                        0);
        if (nb_sent < 0) {
            log_failure (log_file,
                        "couldn't send to daemon socket, error: %s",
                        strerror (errno));
            return -1;
        }
        nb_sent_sum += nb_sent;
    }

    if (sem_post (&d->socket_lock) < 0) {
        log_failure (log_file,
                    "failed to sem_post socket_lock, error: %s",
                    strerror (errno));
    }

    return 0;
}
Пример #6
0
static void sieve_queue_send(SieveSession *session, SieveState next_state,
		gchar *msg, sieve_session_data_cb_fn cb, gpointer data)
{
	gboolean queue = FALSE;
	SieveCommand *cmd = g_new0(SieveCommand, 1);
	cmd->session = session;
	cmd->next_state = next_state;
	cmd->msg = msg;
	cmd->data = data;
	cmd->cb = cb;

	if (!session_is_connected(SESSION(session))) {
		log_print(LOG_PROTOCOL, "Sieve: connecting to %s:%hu\n",
				session->host, session->port);
		if (sieve_session_connect(session) < 0) {
			sieve_connect_finished(SESSION(session), FALSE);
		}
		queue = TRUE;
	} else if (session->state == SIEVE_RETRY_AUTH) {
		log_print(LOG_PROTOCOL, _("Sieve: retrying auth\n"));
		if (sieve_auth(session) == SE_AUTHFAIL)
			sieve_error(session, _("Auth method not available"));
		queue = TRUE;
	} else if (session->state != SIEVE_READY) {
		log_print(LOG_PROTOCOL, "Sieve: in state %d\n", session->state);
		queue = TRUE;
	}

	if (queue) {
		session->send_queue = g_slist_prepend(session->send_queue, cmd);
	} else {
		if (session->current_cmd)
			command_free(session->current_cmd);
		session->current_cmd = cmd;
		session->state = next_state;
		log_send(session, cmd);
		if (session_send_msg(SESSION(session), SESSION_SEND, cmd->msg) < 0) {
			/* error */
		}
	}
}
Пример #7
0
static void
generic_handler(struct evhttp_request *req, void *arg)
{
  struct evkeyvalq args;
  thd_data *thd = arg;

  if (!loop) {
    event_base_loopexit(thd->base, NULL);
    return;
  }
  if (!req->uri) { return; }

  {
    char *uri = evhttp_decode_uri(req->uri);
    evhttp_parse_query(uri, &args);
    free(uri);
  }

  {
    struct evbuffer *res_buf;
    if (!(res_buf = evbuffer_new())) {
      err(1, "failed to create response buffer");
    }

    evhttp_add_header(req->output_headers, "Connection", "close");

    log_send(req->output_headers, res_buf, thd, &args);
    evhttp_send_reply(req, HTTP_OK, "OK", res_buf);
    evbuffer_free(res_buf);
    /* logging */
    {
      if (thd->log_base_path) {
        if (!thd->log_file) {
          time_t n;
          struct tm *t_st;
          char p[PATH_MAX + 1];

          time(&n);
          t_st = localtime(&n);

          snprintf(p, PATH_MAX, "%s%04d%02d%02d%02d%02d%02d-%02d",
            thd->log_base_path,
            t_st->tm_year + 1900, t_st->tm_mon + 1, t_st->tm_mday,
            t_st->tm_hour, t_st->tm_min, t_st->tm_sec, thd->thread_id);

          if (!(thd->log_file = fopen(p, "a"))) {
            print_error("cannot open log_file %s.", p);
          } else {
            thd->log_count = 0;
          }
        }
        if (thd->log_file) {
          fprintf(thd->log_file, "%s\n", req->uri);
          if (++thd->log_count >= LOG_SPLIT_LINES) {
            fclose(thd->log_file);
            thd->log_file = NULL;
          }
        }
      }
    }
  }
  evhttp_clear_headers(&args);
}
Пример #8
0
int main(int argc, char const * argv[]) {
	const char * config_file;
	int connection_numer = 0, ret, pid;
	short vals[SEM_SIZE] = {1, 1};
	key_t key = ftok("database.sql", KEY_ID);
	key_t key_db = ftok("database.sql", KEY_DB_ID);

	switch(argc) {
		case 1: {
			config_file = CONFIG_FILE_DEFAULT;
		} break;

		case 2: {
			config_file = argv[1];
		} break;

		default: {
			fprintf(stderr, "Usage: 'server.app [config_file]'.\n");
			exit(EXIT_FAILURE);
		}
	}

	pcg32_srandom(time(NULL), (intptr_t)&connection_numer);

	server_sems = sem_make(key, SEM_SIZE, vals);
	if(server_sems == -1) {
		fprintf(stderr, "1 Can't create neccessary data to operate.\n");
		exit(EXIT_FAILURE);
	}

	bettors = mmap(NULL, sizeof(*bettors), PROT_READ | PROT_WRITE, MAP_SHARED | MAP_ANON, -1, 0);
	if(bettors == MAP_FAILED) {
		fprintf(stderr, "2 Can't create neccessary data to operate.\n");
		exit(EXIT_FAILURE);
	}

	clients = mmap(NULL, sizeof(*clients), PROT_READ | PROT_WRITE, MAP_SHARED | MAP_ANON, -1, 0);
	if(clients == MAP_FAILED) {
		fprintf(stderr, "3 Can't create neccessary data to operate.\n");
		exit(EXIT_FAILURE);
	}

	winner = mmap(NULL, sizeof(*winner) * MAX_SIZE, PROT_READ | PROT_WRITE, MAP_SHARED | MAP_ANON, -1, 0);
	if(winner == MAP_FAILED) {
		fprintf(stderr, "4 Can't create neccessary data to operate.\n");
		exit(EXIT_FAILURE);
	}

	*bettors = 0;
	*clients = 0;
	memset(winner, 0, sizeof(*winner) * MAX_SIZE);

	if(!log_open()) {
		fprintf(stderr, "Can't connect logging server.\n");
		//exit(EXIT_FAILURE);
	}

	database = smemory_open(key_db); // TODO: define 8080
	if(database == NULL) {
		fprintf(stderr, "Can't reach the database.\n");
		exit(EXIT_FAILURE);
	}

	connection = server_open(config_file);
	if(connection == NULL) {
		fprintf(stderr, "Can't create the main connection.\n");
		exit(EXIT_FAILURE);
	}

	signal(SIGINT, handle_int);
	signal(SIGCHLD, handle_int);

	while(TRUE) {
		connection_t connection_accepted;

		connection_accepted = server_accept(connection);
		if(connection_accepted == NULL) {
			log_send(LEVEL_ERROR, "[MAIN SV] Can't connect to client.");
			exit(EXIT_FAILURE); // TODO: Exit?
		}

		connection_numer++;
		(*clients)++;

		pid = fork();
		if(pid == -1) {
			log_send(LEVEL_ERROR, "[MAIN SV] Can't assign resources to client.");
			exit(EXIT_FAILURE); // TODO: Exit?
		}

		if(!pid) { // Child process
			// sem_lock(server_sems, 1);
			// (*clients)++;
			// sem_unlock(server_sems, 1);
			server_ajar(connection);
			log_send(LEVEL_INFO, "[CHILD SV] Disconnecting main connection.");

			ret = handle(connection_accepted);
			if(ret == EXIT_FAILURE) {
				log_send(LEVEL_ERROR, "[CHILD SV] There was an error handling client.");
			}

			server_close(connection_accepted);
			log_send(LEVEL_INFO, "[CHILD SV] Closed client connection.");
			// sem_lock(server_sems, 1);
			// (*clients)--;
			// sem_unlock(server_sems, 1);
			exit(ret);
		}

		log_send(LEVEL_INFO, "[MAIN SV] Disconnecting new connection.");
		server_ajar(connection_accepted);
	}

	server_close(connection);
	if(!db_close(database)) {
		log_send(LEVEL_ERROR, "[MAIN SV] Couldn't correctly logout from database.");
	}
	log_close();
	sem_remove(server_sems);

	return 0;
}
Пример #9
0
static int run(connection_t connection, int op) {
	switch(op) {
		case MONEY: {
			if(!money(connection, client_money)) {
				log_send(LEVEL_ERROR, "Error getting the money.");
				return -1;
			}else{
				log_send(LEVEL_INFO, "Succesfully got money.");
			}
		} break;

		case CUCCO_ADD: {
			if(!cucco_add(connection, database)) {
				log_send(LEVEL_ERROR, "Error adding the cucco.");
				return -1;
			}else{
				log_send(LEVEL_INFO, "Succesfully added cucco.");
			}
		} break;

		case CUCCO_REMOVE: {
			if(!cucco_remove(connection, database)) {
				log_send(LEVEL_ERROR, "Error removing the cucco.");
				return -1;
			}else{
				log_send(LEVEL_INFO, "Succesfully removed cucco.");
			}
		} break;

		case LIST: {
			if(!list(connection, database)) {
				log_send(LEVEL_ERROR, "Error getting the list of cuccos.");
				return -1;
			}else{
				log_send(LEVEL_INFO, "Sucesfully returned list of cuccos");
			}
		} break;

		case BET: {
			if(!bet(connection, &client_money, clients, bettors, winner, database)) {
				log_send(LEVEL_ERROR, "Error placing bet.");
				return -1;
			}else{
				log_send(LEVEL_INFO, "Succesfully placed bet.");
			}
		} break;

		case RESET: {
			if(!reset(connection)) {
				log_send(LEVEL_ERROR, "Error reseting the amount of money");
				return -1;
			}
			log_send(LEVEL_INFO, "Succesfully reseted the users amount of money");
			client_money = MONEY_DEFAULT;
		} break;

		case EXIT: {
			log_send(LEVEL_INFO, "[CHILD SV] Exiting.");
			return 1;
		} break;

		default: {
			log_send(LEVEL_ERROR, "Invalid opcode.");
			return -1;
		} break;
	}

	return 0;
}
Пример #10
0
/**
 * record attack log on in temporary buffer msr->auditlogs and make the sql statement format.
 */
void msc_record_attacklog(modsec_rec *msr, msre_var *var, msre_actionset *actionset)
{
    int i;
    msre_action *action;
    const apr_array_header_t *tarr = NULL;
    const apr_table_entry_t *telts = NULL;
    const char *cliip;
    unsigned int cliport;
    const char *serip;
    unsigned int serport;
    const char *url;
    const char *method;
    const char *protocol;
    const char *attname;
    const char *clios;
    const char *clibrowser;
    int action_id;
    int severity_id;
    char *attdomain;
    char *sql_statement = NULL;
    char *sql_statement_temp = NULL;
    char *msg = NULL;
    char country[256] = { 0 };
    char province[256] = { 0 };
    char city[256] = { 0 };
    char isp_gbk[512] = { 0 };    
    char *isp_utf8;
    const char *rule_id;
    int rv;
    const char *host;

    if (actionset ? (actionset->severity > msr->txcfg->attacklog_level ? 1 : 0) : 0) {
        return;
    }

    attname = "";
    attdomain = "";
    action_id = 0; 
    severity_id = 0;
    rule_id = "0";
    cliip = msr->remote_addr;
    cliport = msr->remote_port;
    serip = msr->local_addr;
    serport = msr->local_port;
    method = msr->request_method;
    clibrowser = ap_get_client_browser(msr->mp, msr->r);
    clios = ap_get_client_os(msr->mp, msr->r);  
    host = apr_table_get(msr->r->headers_in, "Host");
    url = apr_pstrcat(msr->mp, msr->hostname, msr->r->uri, msr->r->args ? "?" : "", 
                    msr->r->args, NULL);
    protocol = msr->request_protocol;
    if (protocol && !strcmp(protocol, "HTTP/0.9")) {
        url = "/";
        method = "GET";
        host = "";
    }
    
    if (actionset) {
        action_id = actionset->intercept_action;
        severity_id = actionset->severity;
        if (severity_id < 0 || severity_id > 7) {
            return;
        }
        
        /* 获取攻击名称 */
        tarr = apr_table_elts(actionset->actions);
        telts = (const apr_table_entry_t*)tarr->elts;
        for (i = 0; i < tarr->nelts; i++) {
            action = (msre_action *)telts[i].val;
            if (strcmp("tag", action->metadata->name) != 0) {
                continue;
            }
            if ((attname = action->param) == NULL) {
                return ;
            }
        }

        /* 获取攻击域 */           
        attdomain = get_attack_domain(var, method);
        if ((msg = (char *)actionset->msg) == NULL) {
            return;
        }
        if ((rule_id = actionset->id) == NULL) {
            return;
        }
    }

    /* 地理信息提取 */
    ap_ip_get_country(g_ip_location, cliip, country, 256);
    ap_ip_get_province(g_ip_location, cliip, province, 256);
    ap_ip_get_city(g_ip_location, cliip, city, 256);
    ap_ip_get_isp(g_ip_location, cliip, isp_gbk, 512);
    isp_utf8 = ap_convert_all_to_utf8(msr->mp, isp_gbk, "GB2312");   
    if (!isp_utf8 || (isp_utf8 && !strcmp(isp_utf8, ""))) {
        /* 未知isp */
        isp_utf8 = "\xE6\x9C\xAA\xE7\x9F\xA5";
    }
  
    /* 数据库SQL语句 */
    if (!msr->black_list_flag) {          /* 规则攻击日志 */
        sql_statement = apr_psprintf(msr->mp, INSERT_ATTACKLOG_TABLE_SQL, 
            (apr_int64_t)apr_time_sec(apr_time_now()),
            cliip ? dbd_escape(ap_logdb_driver, msr->mp, cliip, ap_logdb_handle) : "", 
            cliport, 
            serip ? dbd_escape(ap_logdb_driver, msr->mp, serip, ap_logdb_handle) : "", 
            serport, 
            apr_socket_get_offline_mode() ?  actions[5] : (actions[action_id] ? actions[action_id] : ""),
            severities[severity_id] ? severities[severity_id] : "", 
            method ? dbd_escape(ap_logdb_driver, msr->mp, method, ap_logdb_handle) : "", 
            attname ? dbd_escape(ap_logdb_driver, msr->mp, attname, ap_logdb_handle) : "", 
            attdomain ? dbd_escape(ap_logdb_driver, msr->mp, attdomain, ap_logdb_handle) : "", 
            protocol ? dbd_escape(ap_logdb_driver, msr->mp, protocol, ap_logdb_handle) :"", 
            msg ? dbd_escape(ap_logdb_driver, msr->mp, msg, ap_logdb_handle) : "",
            url ? dbd_escape(ap_logdb_driver, msr->mp, url, ap_logdb_handle) : "",
            clios ? dbd_escape(ap_logdb_driver, msr->mp, clios, ap_logdb_handle) : "",
            clibrowser ? dbd_escape(ap_logdb_driver, msr->mp, clibrowser, ap_logdb_handle) : "",
            dbd_escape(ap_logdb_driver, msr->mp, country, ap_logdb_handle),
            dbd_escape(ap_logdb_driver, msr->mp, province, ap_logdb_handle),
            dbd_escape(ap_logdb_driver, msr->mp, city, ap_logdb_handle),
            isp_utf8,
            rule_id,
            host ? dbd_escape(ap_logdb_driver, msr->mp, host, ap_logdb_handle) : (msr->r->hostname ? msr->r->hostname : "")
            );

        /* 用于攻击日志的实时监控 */
        sql_statement_temp = apr_psprintf(msr->mp, INSERT_ATTACKLOG_TABLE_SQL_TEMP, 
            (apr_int64_t)apr_time_sec(apr_time_now()),
            cliip ? dbd_escape(ap_logdb_driver, msr->mp, cliip, ap_logdb_handle) : "", 
            attname ? dbd_escape(ap_logdb_driver, msr->mp, attname, ap_logdb_handle) : "", 
            dbd_escape(ap_logdb_driver, msr->mp, country, ap_logdb_handle),
            dbd_escape(ap_logdb_driver, msr->mp, province, ap_logdb_handle),
            dbd_escape(ap_logdb_driver, msr->mp, city, ap_logdb_handle),
            isp_utf8
            );
    } else {                             /* 黑名单攻击日志 */
        if (msr->black_list_log) {
            msg = apr_psprintf(msr->mp, "%s%d", "attack times:", msr->black_list_hitcount);
            sql_statement = apr_psprintf(msr->mp, INSERT_ATTACKLOG_TABLE_SQL, 
                (apr_int64_t)apr_time_sec(apr_time_now()),
                cliip ? dbd_escape(ap_logdb_driver, msr->mp, cliip, ap_logdb_handle) : "", 
                cliport, 
                serip ? dbd_escape(ap_logdb_driver, msr->mp, serip, ap_logdb_handle) : "", 
                serport, 
                apr_socket_get_offline_mode() ?  actions[5] : (actions[1] ? actions[1] : ""),
                severities[0] ? severities[0] : "",   
                method ? dbd_escape(ap_logdb_driver, msr->mp, method, ap_logdb_handle) : "", 
                get_attack_string(msr), 
                dbd_escape(ap_logdb_driver, msr->mp, g_attack_domain[7], ap_logdb_handle),
                protocol ? dbd_escape(ap_logdb_driver, msr->mp, protocol, ap_logdb_handle) : "", 
                msg ? msg : "",
                url ? dbd_escape(ap_logdb_driver, msr->mp, url, ap_logdb_handle) : "",
                clios ? dbd_escape(ap_logdb_driver, msr->mp, clios, ap_logdb_handle) : "",
                clibrowser ? dbd_escape(ap_logdb_driver, msr->mp, clibrowser, ap_logdb_handle) : "",
                dbd_escape(ap_logdb_driver, msr->mp, country, ap_logdb_handle),
                dbd_escape(ap_logdb_driver, msr->mp, province, ap_logdb_handle),
                dbd_escape(ap_logdb_driver, msr->mp, city, ap_logdb_handle),
                isp_utf8,
                rule_id,
                host ? dbd_escape(ap_logdb_driver, msr->mp, host, ap_logdb_handle) : (msr->r->hostname ? msr->r->hostname : "")
                );
            
            /* 用于攻击日志的实时监控 */
            sql_statement_temp = apr_psprintf(msr->mp, INSERT_ATTACKLOG_TABLE_SQL_TEMP, 
                (apr_int64_t)apr_time_sec(apr_time_now()),
                cliip ? dbd_escape(ap_logdb_driver, msr->mp, cliip, ap_logdb_handle) : "", 
                get_attack_string(msr), 
                dbd_escape(ap_logdb_driver, msr->mp, country, ap_logdb_handle),
                dbd_escape(ap_logdb_driver, msr->mp, province, ap_logdb_handle),
                dbd_escape(ap_logdb_driver, msr->mp, city, ap_logdb_handle),   
                isp_utf8
                );
        } 
    }

    if (sql_statement) {
        *(const char **)apr_array_push(msr->attacklogs) = sql_statement;
    }

    if (sql_statement_temp) {
        rv = log_send(sql_statement_temp, 0);
        if (rv < 0) {
            ap_log_error(APLOG_MARK, APLOG_ERR, 0, NULL, "send temp attack log to log server failed.");
        }
    }    
}
Пример #11
0
int merger(int generation, int num, int in_count, int *in, int out, int order, int last)
{
	log_send(ps_log_pipe[1], PS_LOG_MERGER | PS_LOG_PARAM | 5, generation, num, in_count, (order == -1), last);
	string_struct *string = (string_struct *) calloc(in_count, sizeof(string_struct));
	if (string == NULL)
	{
		xerror(MEMORY_ERROR, 0);
	}
	int i, live_count = 0, first = 1, max_i;
	int str_cnt = 0;
	for (i = 0; i < in_count; i++)
	{
		if (read(in[i], &string[i].size, sizeof(string[i].size)) == 0)
		{
			string[i].size = -1;
		}
		else
		{
			string[i].buf_size = string[i].size;
			if ((string[i].str = (char *) calloc(string[i].buf_size, sizeof(char))) == NULL)
			{
				xerror(MEMORY_ERROR, 0);
			}
			if(read(in[i], string[i].str, string[i].size) == -1)
			{
				log_send(ps_log_pipe[1], PS_LOG_MERGER | PS_LOG_ERROR | 0);
				xerror(READ_WRITE_ERROR, 0);
			}
			live_count++;
			str_cnt++;
		}
	}
	
	while (live_count > 0)
	{
		first = 1;
		max_i = 0;
		for (i = 0; i < in_count; i++)
		{
			if (string[i].size != -1)
			{
				if (first)
				{
					max_i = i;
					first = 0;
				}
				else
				{
					if ((xcmp(order,string[i].str, string[max_i].str) > 0))
					{
						max_i = i;
					}
				}
			}
		}
		if (last)
		{
			printf("%s\n", string[max_i].str);
		}
		else
		{
			if(write(out, &string[max_i].size, sizeof(string[max_i].size)) == -1)
			{
				log_send(ps_log_pipe[1], PS_LOG_MERGER | PS_LOG_ERROR | 0);
				xerror(READ_WRITE_ERROR, 0);
			}
			if(write(out, string[max_i].str, string[max_i].size) == -1)
			{
				log_send(ps_log_pipe[1], PS_LOG_MERGER | PS_LOG_ERROR | 0);
				xerror(READ_WRITE_ERROR, 0);
			}
		}
		if (read(in[max_i], &string[max_i].size, sizeof(string[max_i].size)) > 0)
		{
			if (string[max_i].size > string[max_i].buf_size)
			{
				string[max_i].buf_size = string[max_i].size;
				if ((string[max_i].str = realloc(string[max_i].str, string[max_i].buf_size)) == NULL)
				{
					xerror(MEMORY_ERROR, 0);
				}
			}
			if(read(in[max_i], string[max_i].str, string[max_i].size) == -1)
			{
				log_send(ps_log_pipe[1], PS_LOG_MERGER | PS_LOG_ERROR | 0);
				xerror(READ_WRITE_ERROR, 0);
			}
			str_cnt++;
		}
		else
		{
			string[max_i].size = -1;
			live_count--;
		}
	}
	log_send(ps_log_pipe[1], PS_LOG_MERGER | PS_LOG_SUMM | 3, num, generation,  str_cnt);
	return 0;
}