Ejemplo n.º 1
0
static void pcp_worker_will_go_down(int code, Datum arg)
{
	if (processType != PT_PCP_WORKER)
	{
		/* should never happen */
		ereport(WARNING,
				(errmsg("pcp_worker_will_go_down called from invalid process")));
		return;
	}
	if(pcp_frontend)
		pcp_close(pcp_frontend);
	processState = EXITING;
	POOL_SETMASK(&UnBlockSig);
	
}
Ejemplo n.º 2
0
Archivo: pcpd.c Proyecto: zixia/nospam
static void proxy_list_rset()
{
	struct proxy_list *p;

	while ((p=proxy_list) != NULL)
	{
		proxy_list=p->next;
		if (p->newevent)
			pcp_destroy_eventid(p->proxy, p->newevent);
		pcp_close(p->proxy);
		free(p->userid);
		if (p->old_event_id)
			free(p->old_event_id);
		proxy_list=p->next;
		free(p);
	}
}
Ejemplo n.º 3
0
Archivo: pcpd.c Proyecto: zixia/nospam
struct PCP *open_calendar(const char *p)
{
        struct PCP *pcp;
        struct passwd *pw=getpwuid(getuid());
        const char *cp;

        if (!pw)
        {
                perror("getpwuid");
                exit(1);
        }

	userid=strdup(pw->pw_name);

        if (p && *p)
	{
		if (chdir(p))
		{
			perror(p);
			exit(1);
		}
	}
        else if ((cp=getenv("PCPDIR")) != NULL && *cp)
        {
		if (chdir(cp))
		{
			perror(cp);
			exit(1);
		}
        }

	pcp=pcp_open_dir(".", userid);

	if (pcp && pcp_cleanup(pcp))
	{
		pcp_close(pcp);
		pcp=NULL;
	}

	if (!pcp)
	{
		perror("pcp_open_dir");
		exit(1);
	}
	return (pcp);
}
Ejemplo n.º 4
0
Archivo: pcpd.c Proyecto: zixia/nospam
static struct proxy_list *proxy(const char *proxy_userid, char **errmsg)
{
	struct proxy_list *p;

	if (errmsg)
		*errmsg=0;

	for (p=proxy_list; p; p=p->next)
	{
		if (addrcmp(proxy_userid, p->userid) == 0)
			return (p);
	}

	p=malloc(sizeof(struct proxy_list));
	if (!p)
		return (NULL);
	memset(p, 0, sizeof(*p));

	if ((p->userid=strdup(proxy_userid)) == NULL)
	{
		free(p);
		return (NULL);
	}

	if ((p->proxy=pcp_find_proxy(proxy_userid, NULL, errmsg)) == NULL ||
	    pcp_set_proxy(p->proxy, userid))
	{
		if (p->proxy)
			pcp_close(p->proxy);
		free(p->userid);
		free(p);
		return (NULL);
	}

	p->next=proxy_list;
	proxy_list=p;
	return (p);
}
Ejemplo n.º 5
0
/* --------------------------------
 * pcp_disconnect - close connection to pgpool
 * --------------------------------
 */
void
pcp_disconnect(void)
{
	int wsize;

	if (pc == NULL)
	{
		if (debug) fprintf(stderr, "DEBUG: connection does not exist\n");
		return;
	}

	pcp_write(pc, "X", 1);
	wsize = htonl(sizeof(int));
	pcp_write(pc, &wsize, sizeof(int));
	if (pcp_flush(pc) < 0)
	{
		/* backend had closed connection already */
	}
	if (debug) fprintf(stderr, "DEBUG: send: tos=\"X\", len=%d\n", (int) sizeof(int));

	pcp_close(pc);
	pc = NULL;
}
Ejemplo n.º 6
0
Archivo: pcp.c Proyecto: ysd001/pgpool2
/* --------------------------------
 * pcp_disconnect - close connection to pgpool
 * --------------------------------
 */
void
pcp_disconnect(PCPConnInfo* pcpConn)
{
	int wsize;

	if(PCPConnectionStatus(pcpConn) != PCP_CONNECTION_OK)
	{
		pcp_internal_error(pcpConn,"invalid PCP connection");
		return;
	}

	pcp_write(pcpConn->pcpConn, "X", 1);
	wsize = htonl(sizeof(int));
	pcp_write(pcpConn->pcpConn, &wsize, sizeof(int));
	if (PCPFlush(pcpConn) < 0)
		return;
	if(pcpConn->Pfdebug)
		fprintf(pcpConn->Pfdebug, "DEBUG: send: tos=\"X\", len=%d\n", (int) sizeof(int));

	pcp_close(pcpConn->pcpConn);
	pcpConn->connState = PCP_CONNECTION_NOT_CONNECTED;
	pcpConn->pcpConn = NULL;
}
Ejemplo n.º 7
0
/* --------------------------------
 * pcp_connect - open connection to pgpool using given arguments
 *
 * return 0 on success, -1 otherwise
 * --------------------------------
 */
int
pcp_connect(char *hostname, int port, char *username, char *password)
{
	struct sockaddr_in addr;
	struct sockaddr_un unix_addr;
	struct hostent *hp;
	int fd;
	int on = 1;
	int len;

	if (pc != NULL)
	{
		if (debug) fprintf(stderr, "DEBUG: connection to backend \"%s\" already exists\n", hostname);
		return 0;
	}

	if (hostname == NULL || *hostname == '\0' || *hostname == '/')
	{
		char *path;

		fd = socket(AF_UNIX, SOCK_STREAM, 0);

		if (fd < 0)
		{
			if (debug) fprintf(stderr, "DEBUG: could not create socket\n");
			errorcode = SOCKERR;
			return -1;
		}

		memset(&unix_addr, 0, sizeof(unix_addr));
		unix_addr.sun_family = AF_UNIX;

		if (hostname == NULL || *hostname == '\0')
		{
			path = UNIX_DOMAIN_PATH;
		}
		else
		{
			path = hostname;
		}

		snprintf(unix_addr.sun_path, sizeof(unix_addr.sun_path), "%s/.s.PGSQL.%d",
				 path, port);

		if (connect(fd, (struct sockaddr *) &unix_addr, sizeof(unix_addr)) < 0)
		{
			if (debug) fprintf(stderr, "DEBUG: could not connect to \"%s\"\n", unix_addr.sun_path);
			close(fd);
			errorcode = CONNERR;
			return -1;
		}
	}
	else
	{
		fd = socket(AF_INET, SOCK_STREAM, 0);
		if (fd < 0)
		{
		  	if (debug) fprintf(stderr, "DEBUG: could not create socket\n");
			errorcode = SOCKERR;
			return -1;
		}

		if (setsockopt(fd, IPPROTO_TCP, TCP_NODELAY,
					   (char *) &on, sizeof(on)) < 0)
		{
			if (debug) fprintf(stderr, "DEBUG: could not set socket option\n");
			close(fd);
			errorcode = SOCKERR;
			return -1;
		}

		memset((char *) &addr, 0, sizeof(addr));
		addr.sin_family = AF_INET;
		hp = gethostbyname(hostname);
		if ((hp == NULL) || (hp->h_addrtype != AF_INET))
		{
			if (debug) fprintf(stderr, "DEBUG: could not retrieve hostname\n");
			close(fd);
			errorcode = HOSTERR;
			return -1;
		}
		memmove((char *) &(addr.sin_addr),
				(char *) hp->h_addr,
				hp->h_length);
		addr.sin_port = htons(port);

		len = sizeof(struct sockaddr_in);
		if (connect(fd, (struct sockaddr *) &addr, len) < 0)
		{
			if (debug) fprintf(stderr, "DEBUG: could not connect to \"%s\"\n", hostname);
			close(fd);
			errorcode = CONNERR;
			return -1;
		}
	}

	pc = pcp_open(fd);
	if (pc == NULL)
	{
		if (debug) fprintf(stderr, "DEBUG: could not allocate buffer space\n");
		close(fd);
		return -1;
	}

	if (pcp_authorize(username, password) < 0)
	{
		pcp_close(pc);
		pc = NULL;
		return -1;
	}

	return 0;
}
Ejemplo n.º 8
0
/* pcp command processor */
static void
pcp_process_command(char tos, char *buf, int buf_len)
{

	if (tos == 'C' || tos == 'd' || tos == 'D' || tos == 'j' ||
		tos == 'J' || tos == 'O' || tos == 'T')
	{
		if (Req_info->switching)
		{
			if(Req_info->request_queue_tail != Req_info->request_queue_head)
			{
				POOL_REQUEST_KIND reqkind;
				reqkind = Req_info->request[(Req_info->request_queue_head +1) % MAX_REQUEST_QUEUE_SIZE].kind;
				
				if (reqkind == NODE_UP_REQUEST)
					ereport(ERROR,
							(errmsg("failed to process PCP request at the moment"),
							 errdetail("failback is in progress")));
				else if (reqkind == NODE_DOWN_REQUEST)
					ereport(ERROR,
							(errmsg("failed to process PCP request at the moment"),
							 errdetail("failover is in progress")));
				else if (reqkind == PROMOTE_NODE_REQUEST)
					ereport(ERROR,
							(errmsg("failed to process PCP request at the moment"),
							 errdetail("promote node operation is in progress")));

				ereport(ERROR,
						(errmsg("failed to process PCP request at the moment"),
						 errdetail("operation is in progress")));
			}
		}
	}
	
	switch (tos)
	{
		case 'A':			/* set configuration parameter */
			set_ps_display("PCP: processing set configration parameter request", false);
			process_set_configration_parameter(pcp_frontend,buf,buf_len);
			break;

		case 'L':			/* node count */
			set_ps_display("PCP: processing node count request", false);
			inform_node_count(pcp_frontend);
			break;

		case 'I':			/* node info */
			set_ps_display("PCP: processing node info request", false);
			inform_node_info(pcp_frontend, buf);
			break;

		case 'N':			/* process count */
			set_ps_display("PCP: processing process count request", false);
			inform_process_count(pcp_frontend);
			break;

		case 'P':			/* process info */
			set_ps_display("PCP: processing process info request", false);
			inform_process_info(pcp_frontend, buf);
			break;

		case 'W':			/* watchdog info */
			set_ps_display("PCP: processing watchdog info request", false);
			inform_watchdog_info(pcp_frontend, buf);
			break;

		case 'D':			/* detach node */
		case 'd':			/* detach node gracefully */
			set_ps_display("PCP: processing detach node request", false);
			process_detach_node(pcp_frontend, buf, tos);
			break;

		case 'C':			/* attach node */
			set_ps_display("PCP: processing attach node request", false);
			process_attach_node(pcp_frontend, buf);
			break;

		case 'T':
			set_ps_display("PCP: processing shutdown request", false);
			process_shutown_request(pcp_frontend, buf[0]);
			break;

		case 'O': /* recovery request */
			set_ps_display("PCP: processing recovery request", false);
			process_recovery_request(pcp_frontend, buf);
			break;

		case 'B': /* status request*/
			set_ps_display("PCP: processing status request request", false);
			process_status_request(pcp_frontend);
			break;

		case 'J':			/* promote node */
		case 'j':			/* promote node gracefully */
			set_ps_display("PCP: processing promote node request", false);
			process_promote_node(pcp_frontend,buf,tos);
			break;

		case 'F':
			ereport(DEBUG1,
					(errmsg("PCP processing request, stop online recovery")));
			break;

		case 'X':			/* disconnect */
			ereport(DEBUG1,
				(errmsg("PCP processing request, client disconnecting"),
					 errdetail("closing PCP connection, and exiting child")));
			pcp_close(pcp_frontend);
			pcp_frontend = NULL;
			/* This child has done its part. Rest in peace now */
			exit(0);
			break;

		default:
			ereport(FATAL,
				(errmsg("PCP processing request"),
					 errdetail("unknown PCP packet type \"%c\"",tos)));
	}
}
Ejemplo n.º 9
0
Archivo: pcp.c Proyecto: ysd001/pgpool2
PCPConnInfo*
pcp_connect(char *hostname, int port, char *username, char *password, FILE *Pfdebug)
{
	struct sockaddr_in addr;
	struct sockaddr_un unix_addr;
	struct hostent *hp;
	char *password_fron_file = NULL;
	char   os_user[256];
	PCPConnInfo* pcpConn = palloc0(sizeof(PCPConnInfo));
	int fd;
	int on = 1;
	int len;

	pcpConn->connState = PCP_CONNECTION_NOT_CONNECTED;
	pcpConn->Pfdebug = Pfdebug;

	if (hostname == NULL || *hostname == '\0' || *hostname == '/')
	{
		char *path;

		fd = socket(AF_UNIX, SOCK_STREAM, 0);

		if (fd < 0)
		{
			pcp_internal_error(pcpConn,
							   "ERROR: failed to create UNIX domain socket. socket error \"%s\"",strerror(errno));
			pcpConn->connState = PCP_CONNECTION_BAD;

			return pcpConn;
		}

		memset(&unix_addr, 0, sizeof(unix_addr));
		unix_addr.sun_family = AF_UNIX;

		if (hostname == NULL || *hostname == '\0')
		{
			path = UNIX_DOMAIN_PATH;
			hostname = path;
		}
		else
		{
			path = hostname;
		}

		snprintf(unix_addr.sun_path, sizeof(unix_addr.sun_path), "%s/.s.PGSQL.%d",
				 path, port);

		if (connect(fd, (struct sockaddr *) &unix_addr, sizeof(unix_addr)) < 0)
		{
			close(fd);

			pcp_internal_error(pcpConn,
							   "ERROR: connection to socket \"%s\" failed with error \"%s\"",unix_addr.sun_path,strerror(errno));
			pcpConn->connState = PCP_CONNECTION_BAD;
			return pcpConn;
		}
	}
	else
	{
		fd = socket(AF_INET, SOCK_STREAM, 0);
		if (fd < 0)
		{
			pcp_internal_error(pcpConn,
							   "ERROR: failed to create INET domain socket with error \"%s\"",strerror(errno));
			pcpConn->connState = PCP_CONNECTION_BAD;
			return pcpConn;
		}

		if (setsockopt(fd, IPPROTO_TCP, TCP_NODELAY,
					   (char *) &on, sizeof(on)) < 0)
		{
			close(fd);

			pcp_internal_error(pcpConn,
							   "ERROR: set socket option failed with error \"%s\"",strerror(errno));
			pcpConn->connState = PCP_CONNECTION_BAD;
			return pcpConn;
		}

		memset((char *) &addr, 0, sizeof(addr));
		addr.sin_family = AF_INET;
		hp = gethostbyname(hostname);
		if ((hp == NULL) || (hp->h_addrtype != AF_INET))
		{
			close(fd);
			pcp_internal_error(pcpConn,
							   "ERROR: could not retrieve hostname. gethostbyname failed with error \"%s\"",strerror(errno));
			pcpConn->connState = PCP_CONNECTION_BAD;
			return pcpConn;

		}
		memmove((char *) &(addr.sin_addr),
				(char *) hp->h_addr,
				hp->h_length);
		addr.sin_port = htons(port);

		len = sizeof(struct sockaddr_in);
		if (connect(fd, (struct sockaddr *) &addr, len) < 0)
		{
			close(fd);
			pcp_internal_error(pcpConn,
							   "ERROR: connection to host \"%s\" failed with error \"%s\"",hostname,strerror(errno));
			pcpConn->connState = PCP_CONNECTION_BAD;
			return pcpConn;
		}
	}

	pcpConn->pcpConn = pcp_open(fd);
	if (pcpConn->pcpConn == NULL)
	{
		close(fd);
		pcp_internal_error(pcpConn,
						   "ERROR: failed to allocate memory");
		pcpConn->connState = PCP_CONNECTION_BAD;
		return pcpConn;
	}
	pcpConn->connState = PCP_CONNECTION_CONNECTED;

	/*
	 * If username is not provided. Use the os user name
	 * and do not complain if it (getting os user name) gets failed
	 */
	if (username == NULL && get_os_username(os_user, sizeof(os_user)))
		username = os_user;

	/*
	 * If password is not provided. lookup in pcppass file
	 */
	if (password == NULL || *password == '\0')
	{
		char port_str[100];
		snprintf(port_str, sizeof(port_str), "%d",port);
		password_fron_file = PasswordFromFile(pcpConn, hostname, port_str, username);
		password = password_fron_file;
	}

	if (pcp_authorize(pcpConn,username, password) < 0)
	{
		pcp_close(pcpConn->pcpConn);
		pcpConn->pcpConn = NULL;
		pcpConn->connState = PCP_CONNECTION_AUTH_ERROR;
	}
	else
		pcpConn->connState = PCP_CONNECTION_OK;

	if(password_fron_file)
		pfree(password_fron_file);

	return pcpConn;
}
Ejemplo n.º 10
0
Archivo: pcpd.c Proyecto: zixia/nospam
int main(int argc, char **argv)
{
	int argn=1;
	static const char * const authvars[]={NULL};

	signal(SIGPIPE, SIG_IGN);
	umask(022);

	if (argn >= argc)
	{
		struct PCP *pcp;

		pcp=open_calendar(NULL);

		mainloop(pcp);
		exit(0);
	}

	maildir_cache_init(TIMEOUT * 2, CACHEDIR, LOCALCACHEOWNER, authvars);

	if (strcmp(argv[argn], "start") == 0)
	{
		struct group *gr;

		if (chdir(CALENDARDIR) < 0)
		{
			perror(CALENDARDIR);
			exit(1);
		}
		gr=getgrnam(MAILGROUP);

		if (!gr)
		{
			fprintf(stderr, "Unknown group: %s\n", MAILGROUP);
			exit(1);
		}

		authtoken_init();
		libmail_changeuidgid(getuid(), gr->gr_gid);
		start();
	}
	else if (strcmp(argv[argn], "login") == 0 ||
		 strcmp(argv[argn], "slogin") == 0)
	{
		struct PCP *pcp;
		int flag;
		struct group *gr;

		gr=getgrnam(MAILGROUP);

		if (!gr)
		{
			fprintf(stderr, "Unknown group: %s\n", MAILGROUP);
			exit(1);
		}
		libmail_changeuidgid(getuid(), gr->gr_gid);

		if (chdir(CALENDARDIR) < 0)
		{
			perror(CALENDARDIR);
			exit(1);
		}

		authtoken_init();
		userid=login(strcmp(argv[argn], "login"), &flag);

		pcp=pcp_open_dir(".", userid);

		if (pcp && flag && pcp_cleanup(pcp))
		{
			pcp_close(pcp);
			syslog(LOG_CRIT, "pcpd: pcp_cleanup failed");
			pcp=NULL;
		}

		if (!pcp)
		{
			syslog(LOG_CRIT, "pcpd: pcp_open_dir failed");
			perror("pcp_open_dir");
			exit(1);
		}

		mainloop(pcp);
		exit(0);
	}
	else if (strcmp(argv[argn], "stop") == 0)
	{
		if (chdir(CALENDARDIR) < 0)
		{
			perror(CALENDARDIR);
			exit(1);
		}
		ll_daemon_stop(LOCKFILE, PIDFILE);
		exit(0);
	}
	else if (strcmp(argv[argn], "open") == 0)
	{
		++argn;
		if (argn < argc)
		{
			struct PCP *pcp;

			pcp=open_calendar(argv[argn]);

			mainloop(pcp);
			exit(0);
		}
	}
	fprintf(stderr, "Usage: %s (start|stop|open [path])\n", argv[0]);
	exit(1);
	return (0);
}
Ejemplo n.º 11
0
Archivo: pcpd.c Proyecto: zixia/nospam
static void accept_pcpd(int sock, int pubsock, int privsock, int flag)
{
	int fd;
	pid_t pid;
	struct PCP *pcp;

	if ((fd=accept_sock(sock)) < 0)
		return;

	if (fcntl(fd, F_SETFL, 0) < 0)
	{
		syslog(LOG_CRIT, "pcpd: fcntl() failed: %m");
		close(fd);
		return;
	}

	maildir_cache_purge();
	pid=fork();

	if (pid < 0)
	{
		syslog(LOG_CRIT, "pcpd: fork() failed: %m");
		close(fd);
		return;
	}

	if (pid)
	{
		close(fd);
		return;	/* Parent resumes listening */
	}

	/* child */

	close(pubsock);
	close(privsock);

	close(0);
	if (dup(fd) != 0)
		exit(0);
	close(1);
	if (dup(fd) != 1)
		exit(0);
	close(fd);
	userid=login(flag, &flag);

	pcp=pcp_open_dir(".", userid);

	if (pcp && flag && pcp_cleanup(pcp))
	{
		pcp_close(pcp);
		syslog(LOG_CRIT, "pcpd: pcp_cleanup failed");
		pcp=NULL;
	}

	if (!pcp)
	{
		syslog(LOG_CRIT, "pcpd: pcp_open_dir failed");
		perror("pcp_open_dir");
		exit(1);
	}

	mainloop(pcp);
	exit(0);
}