Beispiel #1
0
void sighup_handler(int sig) {
    GKeyFile *keyfile;
    GError *error = NULL;
    int rc;
    // TODO: handle also closing/reopening of log files and databases
    proxy_error("Received HUP signal: reloading config file...\n");
#ifdef DEBUG
    //g_mem_profile();
    malloc_stats_print(NULL, NULL, "");
#endif
    char *config_file=glovars.proxy_configfile;
    rc=config_file_is_readable(config_file);
    if (rc==0) {
        proxy_error("Config file %s is not readable\n", config_file);
        return;
    }

    keyfile = g_key_file_new();
    if (!g_key_file_load_from_file(keyfile, config_file, G_KEY_FILE_NONE, &error)) {
        proxy_error("Error loading configuration from config file %s\n", config_file);
        g_key_file_free(keyfile);
        return;
    }

    // initialize variables and process config file
    init_global_variables(keyfile,1);

    g_key_file_free(keyfile);

}
// non blocking API
void MySQL_Connection::connect_start() {
	PROXY_TRACE();
	mysql=mysql_init(NULL);
	assert(mysql);
	mysql_options(mysql, MYSQL_OPT_NONBLOCK, 0);
	unsigned int timeout= 1;
	mysql_options(mysql, MYSQL_OPT_CONNECT_TIMEOUT, (void *)&timeout);
	const CHARSET_INFO * c = proxysql_find_charset_nr(mysql_thread___default_charset);
	if (!c) {
		proxy_error("Not existing charset number %u\n", mysql_thread___default_charset);
		assert(0);
	}
	mysql_options(mysql, MYSQL_SET_CHARSET_NAME, c->csname);
	unsigned long client_flags = 0;
	if (mysql_thread___client_found_rows)
		client_flags += CLIENT_FOUND_ROWS;
	if (parent->compression)
		client_flags += CLIENT_COMPRESS;
	if (parent->port) {
		async_exit_status=mysql_real_connect_start(&ret_mysql, mysql, parent->address, userinfo->username, userinfo->password, userinfo->schemaname, parent->port, NULL, client_flags);
	} else {
		async_exit_status=mysql_real_connect_start(&ret_mysql, mysql, "localhost", userinfo->username, userinfo->password, userinfo->schemaname, parent->port, parent->address, client_flags);
	}
	fd=mysql_get_socket(mysql);
}
Beispiel #3
0
void MySQL_Logger::open_log_unlocked() {
	if (log_file_id==0) {
		log_file_id=find_next_id()+1;
	} else {
		log_file_id++;
	}
	char *filen=NULL;
	if (base_filename[0]=='/') { // absolute path
		filen=(char *)malloc(strlen(base_filename)+10);
		sprintf(filen,"/%s.%08d",base_filename,log_file_id);
	} else { // relative path
		filen=(char *)malloc(strlen(datadir)+strlen(base_filename)+10);
		sprintf(filen,"%s/%s.%08d",datadir,base_filename,log_file_id);
	}
	logfile=new std::fstream();
	logfile->exceptions ( std::ofstream::failbit | std::ofstream::badbit );
	try {
		logfile->open(filen , std::ios::out | std::ios::binary);
		proxy_info("Starting new mysql log file %s\n", filen);
	}
	catch (std::ofstream::failure e) {
		proxy_error("Error creating new mysql log file %s\n", filen);
		delete logfile;
		logfile=NULL;
	}
	//int fd=open(filen, O_WRONLY | O_APPEND | O_CREAT , S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP);
	free(filen);
	//close(fd);
};
Beispiel #4
0
/* 
 * send_client - send resposne content to client
 */
void send_client(int client_fd, Response *response) {
    #ifdef DEBUG
    printf("enter send_client \n");
    #endif
    if (response != NULL) {
        if (response->content != NULL) {
            if (rio_writen(client_fd, response->content, 
                        response->content_size) < 0) {
                proxy_error("rio_writen in send_client error");
            }
        } else {
            proxy_error("error in send_client, content is NULL\n");
        }
    } else {
        proxy_error("error in send_client, response is NULL\n");
    }
}
void MySQL_Connection::set_names_start() {
	PROXY_TRACE();
	const CHARSET_INFO * c = proxysql_find_charset_nr(options.charset);
	if (!c) {
		proxy_error("Not existing charset number %u\n", options.charset);
		assert(0);
	}
	async_exit_status = mysql_set_character_set_start(&interr,mysql, c->csname);
}
Beispiel #6
0
void term_handler(int sig) {
    proxy_error("Received TERM signal: shutdown in progress...\n");
#ifdef DEBUG
    //g_mem_profile();
    malloc_stats_print(NULL, NULL, "");
#endif
    glovars.shutdown=1;
    sleep(5);
    exit(0);
}
Beispiel #7
0
bool SQLite3DB::execute(const char *str) {
	assert(url);
	assert(db);
	char *err=NULL;
	sqlite3_exec(db, str, NULL, 0, &err);
	if(err!=NULL) {
        proxy_error("SQLITE error: %s --- %s\n", err, str);
		if (assert_on_error) {
			assert(err==0);
		}
		return false;		
	}
	return true;
}
Beispiel #8
0
/* 
 * forward_request - send request from client to its destination server 
 */
int forward_request(int client_fd, Request *request, Response *response) {
    rio_t   server_rio;
    int server_fd;
    char hostname[MAXLINE];
    int  port = 80;

    extract_hostname_port(request->host_str, hostname, &port);

    #ifdef DEBUG
    printf("extract hostname:%s\n", hostname);
    printf("extract port:%d\n", port);
    #endif
    if ((server_fd = open_clientfd(hostname, port)) < 0) {
        sleep(2);
        if ((server_fd = open_clientfd(hostname, port)) < 0) {
            sleep(2);
            if ((server_fd = open_clientfd(hostname, port)) < 0) {
                proxy_error(strcat(hostname, " connection refuesed"));
                close(server_fd);
                return -1;
            }
        }
    }

    rio_readinitb(&server_rio, server_fd);
    #ifdef DEBUG
    printf("request_str:%s", request->request_str); 
    #endif
    
    rio_writen(server_fd, request->request_str, strlen(request->request_str));
    rio_writen(server_fd, request->host_str, strlen(request->host_str));
    /* send cookie to server */
    if (request->cookie_size != 0) {
        rio_writen(server_fd, request->cookie, request->cookie_size);
    }
    /* send user-agent info to server */
    if (request->user_agent_size != 0) {
        rio_writen(server_fd, request->user_agent, request->user_agent_size);
    }
    rio_writen(server_fd, "\r\n", strlen("\r\n"));
    
    if (forward_response(client_fd, server_fd, response) < 0) {
        close(server_fd);
        return -1;
    }
    close(server_fd);
    return 1;
}
Beispiel #9
0
int SQLite3DB::return_one_int(const char *str) {
	char *error=NULL;
	int cols=0;
	int affected_rows=0;
	int ret=0;
	SQLite3_result *resultset=NULL;
	execute_statement(str, &error , &cols , &affected_rows , &resultset);
	if (error) {
		proxy_error("Error on %s : %s\n", str, error);
		free(error);
	} else {
		for (std::vector<SQLite3_row *>::iterator it = resultset->rows.begin() ; it != resultset->rows.end(); ++it) {
			SQLite3_row *r=*it;
			ret=atoi(r->fields[0]);
			break;
		}
	}
	if (resultset) delete resultset;
	return ret;
}
Beispiel #10
0
static int open_event_participant(struct PCP_retr *r,
				  const char *n, const char *id,
				  void *vp)
{
	struct proxy_list *p;
	char *errmsg;

	if (proxy_userid)
	{
		printf("500-Cannot create proxy in proxy mode.\n");
		errno=EIO;
		return (-1);
	}

	p=proxy(n, &errmsg);

	if (p)
	{
		if ((p->old_event_id=strdup(id)) == NULL)
			return (-1);
		return (0);
	}

	if (!force_flag)
	{
		if (errmsg)
		{
			proxy_error(n, errmsg);
			free(errmsg);
		}
		errno=EIO;
		return (-1);
	}
	if (errmsg)
		free(errmsg);

	p->flags |= PROXY_IGNORE;
	return (0);
}
Beispiel #11
0
void MySQL_Data_Stream::check_data_flow() {
	if ( (PSarrayIN->len || queue_data(queueIN) ) && ( PSarrayOUT->len || queue_data(queueOUT) ) ){
		// there is data at both sides of the data stream: this is considered a fatal error
		proxy_error("Session=%p, DataStream=%p -- Data at both ends of a MySQL data stream: IN <%d bytes %d packets> , OUT <%d bytes %d packets>\n", sess, this, PSarrayIN->len , queue_data(queueIN) , PSarrayOUT->len , queue_data(queueOUT));
		shut_soft();
	}
	//if ((myds_type==MYDS_BACKEND) && (myconn->myconn.net.fd==0) && (revents & POLLOUT)) {
	if ((myds_type==MYDS_BACKEND) && myconn && (myconn->fd==0) && (revents & POLLOUT)) {
		int rc;
		int error;
		socklen_t len = sizeof(error);
		rc=getsockopt(fd, SOL_SOCKET, SO_ERROR, &error, &len);
		assert(rc==0);
		if (error==0) {
			//myconn->myconn.net.fd=fd; // connect succeeded
			myconn->fd=fd; // connect succeeded
		} else {
			errno=error;
			perror("check_data_flow");
			shut_soft();
		}
	}
}
Beispiel #12
0
void forward_response(int client_fd, int server_fd, Response *response) {
    #ifdef DEBUG
    printf("enter forward_response\n");
    #endif
    size_t n;
    int length = -1;
    char header_buffer[MAXLINE];
    char content_buffer[MAX_OBJECT_SIZE];
    int read_size;
    rio_t   server_rio;
    int header_line = 0;
    int move_flag = 0;
    char move_new_address[MAXLINE];
    rio_readinitb(&server_rio, server_fd);
    while ((n = rio_readlineb(&server_rio, header_buffer, MAXLINE)) != 0) { 
        strcat(response->header, header_buffer); 
//parse response
//if return status code is 3XX
//address moved. 
//need to send another request to the indicated place
//until get 2XX or 4XX or 5XX.
header_line ++;
//status code 3XX  
if((header_line == 1) && (header_buffer[state_offset] == '3')) {
move_flag =1;
}
if((move_flag == 1) && strstr(header_buffer,"Location:")) {
//moved to new address.
//I suggest change the address in request and return. then send request again.
strcat(move_new_address, (header_buffer+move_offset));
}
//add exit here
        /*
        if (rio_writen(client_fd, header_buffer, n) < 0) {
            proxy_error("rio_writen in forward_response header error");  
        }*/
        
        if (strstr(header_buffer, "Content-Length: ")) {
            sscanf(header_buffer + 16, "%d", &length);
        }
        if (!strcmp(header_buffer, "\r\n")) {
            break;
        }
    }

    if (length == -1)
        read_size = MAX_OBJECT_SIZE;
    else 
        read_size = min(length, MAX_OBJECT_SIZE);
    
    #ifdef DEBUG
    printf("finish response header\n");
    #endif

    int sum = 0;
    while ((n = rio_readnb(&server_rio, content_buffer, read_size)) != 0) { 
        if (rio_writen(client_fd, content_buffer, n) < 0) {
            proxy_error("rio_writen in forward_response content error");  
            Close(client_fd);
        }
        sum += n;
    }

    #ifdef DEBUG 
    printf("read byte size:%u\n", sum);
    #endif
    
    if (sum <= MAX_OBJECT_SIZE) {
        response->content = Malloc(sizeof(char) * sum);
        memcpy(response->content, content_buffer, sum * sizeof(char)); 
        response->content_size = sum;
    } else {
        response->content_size = sum;
    }
    #ifdef DEBUG
    printf("leave forward_response\n");
    #endif
}
Beispiel #13
0
static inline void copy_single_line_str(rio_t *client_rio, char *buffer) {
    if (rio_readlineb(client_rio, buffer, MAXLINE) < 0) {
        proxy_error("copy_single_lienstr error");
    }
    buffer[strlen(buffer)] = '\0';
}
Beispiel #14
0
/* 
 * forward_response - send request to server, then store resposne content
 * in cache if necessary 
 */
int forward_response(int client_fd, int server_fd, Response *response) {
    #ifdef DEBUG
    printf("enter forward_response\n");
    #endif
    size_t  n;
    int     length = -1;
    int     read_size;
    rio_t   server_rio;
    char header_buffer[MAXLINE];
    char temp_buffer[MAX_OBJECT_SIZE];
    char  buffer[10 * MAX_OBJECT_SIZE];
    char content_buffer[10 * MAX_OBJECT_SIZE];

    rio_readinitb(&server_rio, server_fd);
    int buffer_pos = 0;
    while ((n = rio_readlineb(&server_rio, header_buffer, MAXLINE)) != 0) { 
        memcpy(response->header + buffer_pos, 
                header_buffer, sizeof(char) * n);      
        buffer_pos += n;
        
        /*specify content-length info if header has this info */
        if (strstr(header_buffer, "Content-Length: ")) {
            sscanf(header_buffer + 16, "%d", &length);
        }
        if (!strcmp(header_buffer, "\r\n")) {
            break;
        }
    }

    if (length == -1)
        read_size = MAX_OBJECT_SIZE;
    else 
        read_size = min(length, MAX_OBJECT_SIZE);
    
    #ifdef DEBUG
    printf("finish response header\n");
    #endif

    int sum = 0;
    while ((n = rio_readnb(&server_rio, temp_buffer, read_size)) != 0) { 
        memcpy(content_buffer + sum, temp_buffer, sizeof(char) * n);      
        sum += n;
    }

    memcpy(buffer, response->header, sizeof(char) * buffer_pos);
    memcpy(buffer + buffer_pos, content_buffer,  sizeof(char) * sum);
    if (rio_writen(client_fd, buffer, buffer_pos + sum) < 0) {
            sleep(1);
            if (rio_writen(client_fd, buffer, buffer_pos + sum) < 0) {
                sleep(2);
                if (rio_writen(client_fd, buffer, buffer_pos + sum) < 0)
                    proxy_error("rio_writen in forward_response" 
                            " header content error");
                    return -1;
            }
    }

    #ifdef DEBUG 
    printf("read byte size:%u\n", sum);
    #endif
    
    if (sum <= MAX_OBJECT_SIZE) {
        response->content = Malloc(sizeof(char) * sum);
        memcpy(response->content, content_buffer, sum * sizeof(char)); 
        response->content_size = sum;
    } else {
        response->content_size = sum;
    }

    #ifdef DEBUG
    printf("leave forward_response\n");
    #endif
    return 1;
}
MDB_ASYNC_ST MySQL_Connection::handler(short event) {
	if (mysql==NULL) {
		// it is the first time handler() is being called
		async_state_machine=ASYNC_CONNECT_START;
		myds->wait_until=myds->sess->thread->curtime+mysql_thread___connect_timeout_server*1000;
	}
handler_again:
	proxy_debug(PROXY_DEBUG_MYSQL_PROTOCOL, 6,"async_state_machine=%d\n", async_state_machine);
	switch (async_state_machine) {
		case ASYNC_CONNECT_START:
			connect_start();
			if (async_exit_status) {
				next_event(ASYNC_CONNECT_CONT);
			} else {
				NEXT_IMMEDIATE(ASYNC_CONNECT_END);
			}
			break;
		case ASYNC_CONNECT_CONT:
			if (event) {
				connect_cont(event);
			}
			if (async_exit_status) {
					if (myds->sess->thread->curtime >= myds->wait_until) {
						NEXT_IMMEDIATE(ASYNC_CONNECT_TIMEOUT);
					}
      	next_event(ASYNC_CONNECT_CONT);
			} else {
				NEXT_IMMEDIATE(ASYNC_CONNECT_END);
			}
    break;
			break;
		case ASYNC_CONNECT_END:
			if (!ret_mysql) {
				// always increase the counter
				proxy_error("Failed to mysql_real_connect() on %s:%d , %d: %s\n", parent->address, parent->port, mysql_errno(mysql), mysql_error(mysql));
    		NEXT_IMMEDIATE(ASYNC_CONNECT_FAILED);
			} else {
    		NEXT_IMMEDIATE(ASYNC_CONNECT_SUCCESSFUL);
			}
    	break;
		case ASYNC_CONNECT_SUCCESSFUL:
			__sync_fetch_and_add(&MyHGM->status.server_connections_connected,1);
			__sync_fetch_and_add(&parent->connect_OK,1);
			break;
		case ASYNC_CONNECT_FAILED:
			parent->connect_error(mysql_errno(mysql));
			break;
		case ASYNC_CONNECT_TIMEOUT:
			proxy_error("Connect timeout on %s:%d : %llu - %llu = %llu\n",  parent->address, parent->port, myds->sess->thread->curtime , myds->wait_until, myds->sess->thread->curtime - myds->wait_until);
			parent->connect_error(mysql_errno(mysql));
			break;
		case ASYNC_CHANGE_USER_START:
			change_user_start();
			if (async_exit_status) {
				next_event(ASYNC_CHANGE_USER_CONT);
			} else {
				NEXT_IMMEDIATE(ASYNC_CHANGE_USER_END);
			}
			break;
		case ASYNC_CHANGE_USER_CONT:
			assert(myds->sess->status==CHANGING_USER_SERVER);
			change_user_cont(event);
			if (async_exit_status) {
				next_event(ASYNC_CHANGE_USER_CONT);
			} else {
				NEXT_IMMEDIATE(ASYNC_CHANGE_USER_END);
			}
			break;
		case ASYNC_CHANGE_USER_END:
			if (ret_bool) {
				fprintf(stderr,"Failed to mysql_change_user()");
				NEXT_IMMEDIATE(ASYNC_CHANGE_USER_FAILED);
			} else {
				NEXT_IMMEDIATE(ASYNC_CHANGE_USER_SUCCESSFUL);
			}
			break;
		case ASYNC_CHANGE_USER_SUCCESSFUL:
			break;
		case ASYNC_CHANGE_USER_FAILED:
			break;
		case ASYNC_PING_START:
			ping_start();
			if (async_exit_status) {
				next_event(ASYNC_PING_CONT);
			} else {
				NEXT_IMMEDIATE(ASYNC_PING_END);
			}
			break;
		case ASYNC_PING_CONT:
			assert(myds->sess->status==PINGING_SERVER);
			ping_cont(event);
			if (async_exit_status) {
				next_event(ASYNC_PING_CONT);
			} else {
				NEXT_IMMEDIATE(ASYNC_PING_END);
			}
			break;
		case ASYNC_PING_END:
			if (interr) {
				NEXT_IMMEDIATE(ASYNC_PING_FAILED);
			} else {
				NEXT_IMMEDIATE(ASYNC_PING_SUCCESSFUL);
			}
			break;
		case ASYNC_PING_SUCCESSFUL:
			break;
		case ASYNC_PING_FAILED:
			break;
		case ASYNC_QUERY_START:
			real_query_start();
			__sync_fetch_and_add(&parent->queries_sent,1);
			__sync_fetch_and_add(&parent->bytes_sent,query.length);
			myds->sess->thread->status_variables.queries_backends_bytes_sent+=query.length;
			if (async_exit_status) {
				next_event(ASYNC_QUERY_CONT);
			} else {
#ifdef PROXYSQL_USE_RESULT
				NEXT_IMMEDIATE(ASYNC_USE_RESULT_START);
#else
				NEXT_IMMEDIATE(ASYNC_STORE_RESULT_START);
#endif
			}
			break;
		case ASYNC_QUERY_CONT:
			real_query_cont(event);
			if (async_exit_status) {
				next_event(ASYNC_QUERY_CONT);
			} else {
#ifdef PROXYSQL_USE_RESULT
				NEXT_IMMEDIATE(ASYNC_USE_RESULT_START);
#else
				NEXT_IMMEDIATE(ASYNC_STORE_RESULT_START);
#endif
			}
			break;
		case ASYNC_STORE_RESULT_START:
			if (mysql_errno(mysql)) {
				NEXT_IMMEDIATE(ASYNC_QUERY_END);
			}
			store_result_start();
			if (async_exit_status) {
				next_event(ASYNC_STORE_RESULT_CONT);
			} else {
				NEXT_IMMEDIATE(ASYNC_QUERY_END);
			}
			break;
		case ASYNC_STORE_RESULT_CONT:
			store_result_cont(event);
			if (async_exit_status) {
				next_event(ASYNC_STORE_RESULT_CONT);
			} else {
				NEXT_IMMEDIATE(ASYNC_QUERY_END);
			}
			break;
		case ASYNC_USE_RESULT_START:
			if (mysql_errno(mysql)) {
				NEXT_IMMEDIATE(ASYNC_QUERY_END);
			}
			mysql_result=mysql_use_result(mysql);
			if (mysql_result==NULL) {
				NEXT_IMMEDIATE(ASYNC_QUERY_END);
			} else {
				MyRS=new MySQL_ResultSet(&myds->sess->client_myds->myprot, mysql_result, mysql);
				async_fetch_row_start=false;
				NEXT_IMMEDIATE(ASYNC_USE_RESULT_CONT);
			}
			break;
		case ASYNC_USE_RESULT_CONT:
			if (async_fetch_row_start==false) {
				async_exit_status=mysql_fetch_row_start(&mysql_row,mysql_result);
				async_fetch_row_start=true;
			} else {
				async_exit_status=mysql_fetch_row_cont(&mysql_row,mysql_result, mysql_status(event, true));
			}
			if (async_exit_status) {
				next_event(ASYNC_USE_RESULT_CONT);
			} else {
				async_fetch_row_start=false;
				if (mysql_row) {
					unsigned int br=MyRS->add_row(mysql_row);
					__sync_fetch_and_add(&parent->bytes_recv,br);
					myds->sess->thread->status_variables.queries_backends_bytes_recv+=br;
					NEXT_IMMEDIATE(ASYNC_USE_RESULT_CONT);
				} else {
					MyRS->add_eof();
					NEXT_IMMEDIATE(ASYNC_QUERY_END);
				}
			}
			break;
		case ASYNC_QUERY_END:
			break;
		case ASYNC_SET_AUTOCOMMIT_START:
			set_autocommit_start();
			if (async_exit_status) {
				next_event(ASYNC_SET_AUTOCOMMIT_CONT);
			} else {
				NEXT_IMMEDIATE(ASYNC_SET_AUTOCOMMIT_END);
			}
			break;
		case ASYNC_SET_AUTOCOMMIT_CONT:
			set_autocommit_cont(event);
			if (async_exit_status) {
				next_event(ASYNC_SET_AUTOCOMMIT_CONT);
			} else {
				NEXT_IMMEDIATE(ASYNC_SET_AUTOCOMMIT_END);
			}
			break;
		case ASYNC_SET_AUTOCOMMIT_END:
			if (ret_bool) {
				NEXT_IMMEDIATE(ASYNC_SET_AUTOCOMMIT_FAILED);
			} else {
				NEXT_IMMEDIATE(ASYNC_SET_AUTOCOMMIT_SUCCESSFUL);
			}
			break;
		case ASYNC_SET_AUTOCOMMIT_SUCCESSFUL:
			break;
		case ASYNC_SET_AUTOCOMMIT_FAILED:
			fprintf(stderr,"%s\n",mysql_error(mysql));
			break;
		case ASYNC_SET_NAMES_START:
			set_names_start();
			if (async_exit_status) {
				next_event(ASYNC_SET_NAMES_CONT);
			} else {
				NEXT_IMMEDIATE(ASYNC_SET_NAMES_END);
			}
			break;
		case ASYNC_SET_NAMES_CONT:
			set_names_cont(event);
			if (async_exit_status) {
				next_event(ASYNC_SET_NAMES_CONT);
			} else {
				NEXT_IMMEDIATE(ASYNC_SET_NAMES_END);
			}
			break;
		case ASYNC_SET_NAMES_END:
			if (interr) {
				NEXT_IMMEDIATE(ASYNC_SET_NAMES_FAILED);
			} else {
				NEXT_IMMEDIATE(ASYNC_SET_NAMES_SUCCESSFUL);
			}
			break;
		case ASYNC_SET_NAMES_SUCCESSFUL:
			break;
		case ASYNC_SET_NAMES_FAILED:
			fprintf(stderr,"%s\n",mysql_error(mysql));
			break;
		case ASYNC_INITDB_START:
			initdb_start();
			if (async_exit_status) {
				next_event(ASYNC_INITDB_CONT);
			} else {
				NEXT_IMMEDIATE(ASYNC_INITDB_END);
			}
			break;
		case ASYNC_INITDB_CONT:
			initdb_cont(event);
			if (async_exit_status) {
				next_event(ASYNC_INITDB_CONT);
			} else {
				NEXT_IMMEDIATE(ASYNC_INITDB_END);
			}
			break;
		case ASYNC_INITDB_END:
			if (interr) {
				NEXT_IMMEDIATE(ASYNC_INITDB_FAILED);
			} else {
				NEXT_IMMEDIATE(ASYNC_INITDB_SUCCESSFUL);
			}
			break;
		case ASYNC_INITDB_SUCCESSFUL:
			break;
		case ASYNC_INITDB_FAILED:
			fprintf(stderr,"%s\n",mysql_error(mysql));
			break;
		default:
			assert(0); //we should never reach here
			break;
		}
	return async_state_machine;
}
Beispiel #16
0
static struct PCP_new_eventid *readnewevent(struct PCP *pcp)
{
	struct PCP_save_event se;
	struct readnewevent_s rne;
	struct PCP_new_eventid *ne;
	const char *cp;
	struct proxy_list *p;
	int first_save=1;

	if (!deleted_eventid)
		proxy_list_rset();

	/* Open new proxy connections */

	while ((cp=strtok(NULL, " ")) != NULL)
	{
		char *errmsg, *q;
		char *n=strdup(cp);
		struct proxy_list *pcp;

		if (!n)
		{
			syslog(LOG_ALERT, "Out of memory.");
			exit(1);
		}

		if (proxy_userid)
		{
			printf("500-Cannot create proxy in proxy mode.\n");
			free(n);
			errno=EIO;
			return (NULL);
		}

		strcpy(n, cp);
		pcp=proxy(n, &errmsg);

		if (pcp)
		{
			pcp->flags |= PROXY_NEW;
			free(n);
			continue;
		}

		if (force_flag)
		{
			pcp->flags |= PROXY_IGNORE;
			free(n);
			continue;
		}

		while (errmsg && (q=strchr(errmsg, '\n')) != 0)
			*q='/';
		printf("500-%s: %s\n", n, errmsg ? errmsg:"Failed to create a proxy connection.");
		free(n);
		proxy_list_rset();
		return (NULL);
	}

	memset(&se, 0, sizeof(se));
	if ((rne.tmpfile=tmpfile()) == NULL)
		return (NULL);
	time(&rne.last_noop_time);

	rne.seeneol=1;
	rne.seendot=0;
	rne.seeneof=0;
	rne.cnt=0;
	rne.pcp=pcp;
	pcpdtimer_init(&rne.inactivity_timeout);
	rne.inactivity_timeout.handler=&inactive;
	pcpdtimer_install(&rne.inactivity_timeout, 300);

	for (p=proxy_list; p; p=p->next)
	{
		struct PCP_save_event se;

		if ( !(p->flags & PROXY_NEW))
			continue;

		if (fseek(rne.tmpfile, 0L, SEEK_SET) < 0
		    || lseek(fileno(rne.tmpfile), 0L, SEEK_SET) < 0)
		{
			int save_errno=errno;
			proxy_list_rset();
			pcpdtimer_triggered(&rne.inactivity_timeout);
			fclose(rne.tmpfile);
			errno=save_errno;
			return (NULL);
		}

		memset(&se, 0, sizeof(se));
		if (first_save)
		{
			se.write_event_func_misc_ptr= &rne;
			se.write_event_func=readnewevent_callback;
		}
		else
			se.write_event_fd=fileno(rne.tmpfile);

		if ((p->newevent=pcp_new_eventid(p->proxy,
						 p->old_event_id,
						 &se)) == NULL)
		{
			pcpdtimer_triggered(&rne.inactivity_timeout);

			if (force_flag)
			{
				/* Force it through */

				p->flags &= ~PROXY_NEW;
				p->flags |= PROXY_IGNORE;
				continue;
			}

			proxy_error(p->userid,
				    pcp_errmsg(p->proxy));
			proxy_list_rset();
			fclose(rne.tmpfile);
			errno=EIO;
			return (NULL);
		}
		if (first_save)
			pcpdtimer_triggered(&rne.inactivity_timeout);
		first_save=0;
	}


	if (first_save)
	{
		se.write_event_func_misc_ptr= &rne;
		se.write_event_func=readnewevent_callback;
	}
	else
		se.write_event_fd=fileno(rne.tmpfile);

	if (mkparticipants(&se) || fseek(rne.tmpfile, 0L, SEEK_SET) < 0
	    || lseek(fileno(rne.tmpfile), 0L, SEEK_SET) < 0)
	{
		int save_errno=errno;

		proxy_list_rset();
		fclose(rne.tmpfile);
		errno=save_errno;
		return (NULL);
	}

	if ((ne=pcp_new_eventid(pcp, deleted_eventid, &se)) == NULL)
	{
		while (!rne.seeneof)
		{
			char buf[512];

			readnewevent_callback(buf, sizeof(buf), &se);
		}
	}
	pcpdtimer_triggered(&rne.inactivity_timeout);
	if (first_save)
	{
		if (fflush(rne.tmpfile) || ferror(rne.tmpfile))
		{
			int save_errno=errno;

			proxy_list_rset();
			fclose(rne.tmpfile);
			errno=save_errno;
			return (NULL);
		}
	}

	notbooked=1;
	fclose(rne.tmpfile);
	return (ne);
}