示例#1
0
/*
 * Add gtm slave: to be used after all the configuration is done.
 *
 * This function only maintains internal configuration, updte configuration file,
 * and make backup if configured.   You should run init_gtm_slave and stat_gtm_slave
 * separately.
 */
int
add_gtmSlave(char *name, char *host, int port, char *dir)
{
	char port_s[MAXTOKEN+1];
	char date[MAXTOKEN+1];
	FILE *f;
	int	rc;

	if (isVarYes(VAR_gtmSlave))
	{
		elog(ERROR, "ERROR: GTM slave is already configured.\n");
		return 1;
	}
	if (is_none(host))
	{
		elog(ERROR, "ERROR: Cannot add gtm slave with the name \"none\".\n");
		return 1;
	}
	if (is_none(dir))
	{
		elog(ERROR, "ERROR: Cannot add gtm slave with the directory \"none\".\n");
		return 1;
	}
	if (checkSpecificResourceConflict(name, host, port, dir, TRUE))
	{
		elog(ERROR, "ERROR: New specified name:%s, host:%s, port:%d and dir:\"%s\" conflicts with existing node.\n",
			 name, host, port, dir);
		return 1;
	}
	assign_sval(VAR_gtmSlave, Strdup("y"));
	assign_sval(VAR_gtmSlaveServer, Strdup(host));
	snprintf(port_s, MAXTOKEN, "%d", port);
	assign_sval(VAR_gtmSlavePort, Strdup(port_s));
	assign_sval(VAR_gtmSlaveDir, Strdup(dir));
	makeServerList();
	if ((f = fopen(pgxc_ctl_config_path, "a")) == NULL)
	{
		/* Should it be panic? */
		elog(ERROR, "ERROR: cannot open configuration file \"%s\", %s\n", pgxc_ctl_config_path, strerror(errno));
		return 1;
	}
	fprintf(f, 
			"#===================================================\n"
			"# pgxc configuration file updated due to GTM slave addition\n"
			"#        %s\n", 
			timeStampString(date, MAXTOKEN+1));
	fprintSval(f, VAR_gtmSlave);
	fprintSval(f, VAR_gtmSlaveServer);
	fprintSval(f, VAR_gtmSlavePort);
	fprintSval(f, VAR_gtmSlaveDir);
	fprintf(f, "%s","#----End of reconfiguration -------------------------\n");
	fclose(f);
	backup_configuration();
	if ((rc = init_gtm_slave()) != 0)
		return rc;
	return(start_gtm_slave());
}
示例#2
0
/*
 * Init gtm master -----------------------------------------------------------------
 */
static cmd_t *
prepare_initGtmMaster(void)
{
	cmd_t *cmdInitGtmMaster, *cmdGtmConf, *cmdGxid;
	char date[MAXTOKEN+1];
	FILE *f;
	char **fileList = NULL;

	/* Kill current gtm, bild work directory and run initgtm */
	cmdInitGtmMaster = initCmd(sval(VAR_gtmMasterServer));
	snprintf(newCommand(cmdInitGtmMaster), MAXLINE,
			 "killall -u %s -9 gtm; rm -rf %s; mkdir -p %s;initgtm -Z gtm -D %s",
			 sval(VAR_pgxcUser), 
			 sval(VAR_gtmMasterDir), sval(VAR_gtmMasterDir), sval(VAR_gtmMasterDir));

	/* Then prepare gtm.conf file */

	/* Prepare local Stdin */
	appendCmdEl(cmdInitGtmMaster, (cmdGtmConf = initCmd(sval(VAR_gtmMasterServer))));
	if ((f = prepareLocalStdin(newFilename(cmdGtmConf->localStdin), MAXPATH, NULL)) == NULL)
	{
		cleanCmd(cmdInitGtmMaster);
		return(NULL);
	}
	fprintf(f, 
			"#===============================================\n"
			"# Added at initialization, %s\n"
			"listen_addresses = '*'\n",
			timeStampString(date, MAXTOKEN));
	if (!is_none(sval(VAR_gtmExtraConfig)))
		AddMember(fileList, sval(VAR_gtmExtraConfig));
	if (!is_none(sval(VAR_gtmMasterSpecificExtraConfig)))
		AddMember(fileList, sval(VAR_gtmMasterSpecificExtraConfig));
	appendFiles(f, fileList);
	CleanArray(fileList);
	fprintf(f,
			"port = %s\n"
			"nodename = '%s'\n"
			"startup = ACT\n"
			"# End of addition\n",
			sval(VAR_gtmMasterPort), sval(VAR_gtmName));
	fclose(f);
	/* other options */
	snprintf(newCommand(cmdGtmConf), MAXLINE,
			 "cat >> %s/gtm.conf",
			 sval(VAR_gtmMasterDir));

	/* Setup GTM with appropriate GXID value */
	
	appendCmdEl(cmdGtmConf, (cmdGxid = initCmd(sval(VAR_gtmMasterServer))));
	snprintf(newCommand(cmdGxid), MAXLINE,
			 "(gtm -x 2000 -D %s &); sleep 1; gtm_ctl stop -Z gtm -D %s",
			 sval(VAR_gtmMasterDir), sval(VAR_gtmMasterDir));

	return cmdInitGtmMaster;
}
示例#3
0
/* 
 * Assumes Gtm Slave is configured.
 * Caller should check this.
 */
static cmd_t *
prepare_initGtmSlave(void)
{
	char date[MAXTOKEN+1];
	cmd_t *cmdInitGtm, *cmdGtmConf;
	FILE *f;
	char **fileList = NULL;

	if (!isVarYes(VAR_gtmSlave) || (sval(VAR_gtmSlaveServer) == NULL) || is_none(sval(VAR_gtmSlaveServer)))
	{
		elog(ERROR, "ERROR: GTM slave is not configured.\n");
		return(NULL);
	}
	/* Kill current gtm, build work directory and run initgtm */
	cmdInitGtm = initCmd(sval(VAR_gtmSlaveServer));
	snprintf(newCommand(cmdInitGtm), MAXLINE,
			 "killall -u %s -9 gtm; rm -rf %s; mkdir -p %s; initgtm -Z gtm -D %s",
			 sval(VAR_pgxcUser),
			 sval(VAR_gtmSlaveDir), sval(VAR_gtmSlaveDir), sval(VAR_gtmSlaveDir));

	/* Prepare gtm.conf file */

	/* Prepare local Stdin */
	appendCmdEl(cmdInitGtm, (cmdGtmConf = initCmd(sval(VAR_gtmSlaveServer))));
	snprintf(newCommand(cmdGtmConf), MAXLINE,
			 "cat >> %s/gtm.conf",
			 sval(VAR_gtmSlaveDir));
	if ((f = prepareLocalStdin(newFilename(cmdGtmConf->localStdin), MAXPATH, NULL)) == NULL)
	{
		cleanCmd(cmdInitGtm);
		return(NULL);
	}
	fprintf(f, 
			"#===============================================\n"
			"# Added at initialization, %s\n"
			"listen_addresses = '*'\n",
			timeStampString(date, MAXPATH+1));
	if (!is_none(sval(VAR_gtmExtraConfig)))
		AddMember(fileList, sval(VAR_gtmExtraConfig));
	if (!is_none(sval(VAR_gtmMasterSpecificExtraConfig)))
		AddMember(fileList, sval(VAR_gtmMasterSpecificExtraConfig));
	appendFiles(f, fileList);
	CleanArray(fileList);
	fprintf(f,
			"port = %s\n"
			"nodename = '%s'\n"
			"startup = STANDBY\n"
			"active_host = '%s'\n"
			"active_port = %d\n"
			"# End of addition\n",
			sval(VAR_gtmSlavePort), sval(VAR_gtmName),
			sval(VAR_gtmMasterServer), atoi(sval(VAR_gtmMasterPort)));
	fclose(f);
	return (cmdInitGtm);
}
示例#4
0
int
remove_gtmSlave(bool clean_opt)
{
	FILE *f;

	/* Check if gtm_slave is configured */
	if (!isVarYes(VAR_gtmSlave) || !sval(VAR_gtmSlaveServer) || is_none(sval(VAR_gtmSlaveServer)))
	{
		elog(ERROR, "ERROR: GTM slave is not configured.\n");
		return 1;
	}
	/* Check if gtm_slave is not running */
	if (!do_gtm_ping(sval(VAR_gtmSlaveServer), atoi(sval(VAR_gtmSlavePort))))
	{
		elog(ERROR, "ERROR: GTM slave is now running. Cannot remove it.\n");
		return 1;
	}
	elog(NOTICE, "Removing gtm slave.\n");
	/* Clean */
	if (clean_opt)
		clean_gtm_slave();
	/* Reconfigure */
	reset_var(VAR_gtmSlave);
	assign_sval(VAR_gtmSlave, Strdup("n"));
	reset_var(VAR_gtmSlaveServer);
	assign_sval(VAR_gtmSlaveServer, Strdup("none"));
	reset_var(VAR_gtmSlavePort);
	assign_sval(VAR_gtmSlavePort, Strdup("-1"));
	reset_var(VAR_gtmSlaveDir);
	assign_sval(VAR_gtmSlaveDir, Strdup("none"));
	/* Write the configuration file and bakup it */
	if ((f = fopen(pgxc_ctl_config_path, "a")) == NULL)
	{
		/* Should it be panic? */
		elog(ERROR, "ERROR: cannot open configuration file \"%s\", %s\n", pgxc_ctl_config_path, strerror(errno));
		return 1;
	}
	fprintf(f, 
			"#===================================================\n"
			"# pgxc configuration file updated due to GTM slave removal\n"
			"#        %s\n",
			timeStampString(date, MAXTOKEN+1));
	fprintSval(f, VAR_gtmSlave);
	fprintSval(f, VAR_gtmSlaveServer);
	fprintSval(f, VAR_gtmSlavePort);
	fprintSval(f, VAR_gtmSlaveDir);
	fprintf(f, "%s", "#----End of reconfiguration -------------------------\n");
	fclose(f);
	backup_configuration();
	elog(NOTICE, "Done.\n");
	return 0;
}
示例#5
0
/*
 * Reconnect to the current GTM master --------------------------------------------------
 *
 * When failed over, the current Master must have been updated.
 * Remember to update gtm_proxy configuration file so that it 
 * connects to the new master at the next start.
 * Please note that we assume GTM has already been failed over.
 * First argument is gtm_proxy nodename
 */
static cmd_t *
prepare_reconnectGtmProxy(char *nodeName)
{
	cmd_t *cmdGtmCtl, *cmdGtmProxyConf;
	int idx;
	FILE *f;
	char date[MAXTOKEN+1];

	if ((idx = gtmProxyIdx(nodeName)) < 0)
	{
		elog(ERROR, "ERROR: Specified name %s is not GTM Proxy\n", nodeName);
		return(NULL);
	}

	/* gtm_ctl reconnect */
	cmdGtmCtl = initCmd(aval(VAR_gtmProxyServers)[idx]);
	snprintf(newCommand(cmdGtmCtl), MAXLINE,
			 "gtm_ctl reconnect -Z gtm_proxy -D %s -o \\\"-s %s -t %s\\\"",
			 aval(VAR_gtmProxyDirs)[idx], sval(VAR_gtmMasterServer), sval(VAR_gtmMasterPort));

	/* gtm_proxy.conf */
	appendCmdEl(cmdGtmCtl, (cmdGtmProxyConf = initCmd(aval(VAR_gtmProxyServers)[idx])));
	if ((f = prepareLocalStdin(newFilename(cmdGtmProxyConf->localStdin), MAXPATH, NULL)) == NULL)
	{
		cleanCmd(cmdGtmCtl);
		return(NULL);
	}
	fprintf(f, 
			"#===================================================\n"
			"# Updated due to GTM Proxy reconnect\n"
			"#        %s\n"
			"gtm_host = '%s'\n"
			"gtm_port = %s\n"
			"#----End of reconfiguration -------------------------\n",
			timeStampString(date, MAXTOKEN),
			sval(VAR_gtmMasterServer),
			sval(VAR_gtmMasterPort));
	fclose(f);
	snprintf(newCommand(cmdGtmProxyConf), MAXLINE,
			 "cat >> %s/gtm_proxy.conf", aval(VAR_gtmProxyDirs)[idx]);
	return(cmdGtmCtl);
}
示例#6
0
/* 
 * Does not check if node name is valid.
 */
static cmd_t *
prepare_initGtmProxy(char *nodeName)
{
	cmd_t *cmdInitGtm, *cmdGtmProxyConf;
	int idx;
	FILE *f;
	char timestamp[MAXTOKEN+1];
	char **fileList = NULL;

	if ((idx = gtmProxyIdx(nodeName)) < 0)
	{
		elog(ERROR, "ERROR: Specified name %s is not GTM Proxy configuration.\n", nodeName);
		return NULL;
	}

	/* Build directory and run initgtm */
	cmdInitGtm = initCmd(aval(VAR_gtmProxyServers)[idx]);
	snprintf(newCommand(cmdInitGtm), MAXLINE,
			 "killall -u %s -9 gtm_proxy;"
			 "rm -rf %s;"
			 "mkdir -p %s;"
			 "initgtm -Z gtm_proxy -D %s",
			 sval(VAR_pgxcUser),
			 aval(VAR_gtmProxyDirs)[idx],
			 aval(VAR_gtmProxyDirs)[idx],
			 aval(VAR_gtmProxyDirs)[idx]);

	/* Configure gtm_proxy.conf */
	appendCmdEl(cmdInitGtm, (cmdGtmProxyConf = initCmd(aval(VAR_gtmProxyServers)[idx])));
	if ((f = prepareLocalStdin(newFilename(cmdGtmProxyConf->localStdin), MAXPATH, NULL)) == NULL)
	{
		cleanCmd(cmdInitGtm);
		return NULL;
	}
	fprintf(f,
			"#===========================\n"
			"# Added at initialization, %s\n"
			"listen_addresses = '*'\n"
			"worker_threads = 1\n"
			"gtm_connect_retry_interval = 1\n",
			timeStampString(timestamp, MAXTOKEN));;
	if (!is_none(sval(VAR_gtmPxyExtraConfig)))
		AddMember(fileList, sval(VAR_gtmPxyExtraConfig));
	if (!is_none(aval(VAR_gtmPxySpecificExtraConfig)[idx]))
		AddMember(fileList, aval(VAR_gtmPxySpecificExtraConfig)[idx]);
	appendFiles(f, fileList);
	CleanArray(fileList);
	fprintf(f,			
			"nodename = '%s'\n"
			"port = %s\n"
			"gtm_host = '%s'\n"
			"gtm_port = %s\n"
			"# End of addition\n",
			aval(VAR_gtmProxyNames)[idx],
			aval(VAR_gtmProxyPorts)[idx],
			sval(VAR_gtmMasterServer),
			sval(VAR_gtmMasterPort));
	fclose(f);
	snprintf(newCommand(cmdGtmProxyConf), MAXLINE,
			 "cat >> %s/gtm_proxy.conf", aval(VAR_gtmProxyDirs)[idx]);
	return(cmdInitGtm);
}
示例#7
0
int
remove_gtmProxy(char *name, bool clean_opt)
{
	FILE *f;
	int idx;

	/* Check if gtm proxy exists */
	if ((idx = gtmProxyIdx(name)) < 0)
	{
		elog(ERROR, "ERROR: %s is not a gtm proxy.\n", name);
		return 1;
	}
	/* Check if it is in use */
	if (ifExists(VAR_coordMasterServers, aval(VAR_gtmProxyServers)[idx]) ||
		ifExists(VAR_coordSlaveServers, aval(VAR_gtmProxyServers)[idx]) ||
		ifExists(VAR_datanodeMasterServers, aval(VAR_gtmProxyServers)[idx]) ||
		ifExists(VAR_datanodeSlaveServers, aval(VAR_gtmProxyServers)[idx]))
	{
		elog(ERROR, "ERROR: GTM Proxy %s is in use\n", name);
		return 1;
	}
	elog(NOTICE, "NOTICE: removing gtm_proxy %s\n", name);
	/* Clean */
	if (clean_opt)
	{
		char **nodelist = NULL;

		elog(NOTICE, "NOTICE: cleaning target resources.\n");
		AddMember(nodelist, name);
		clean_gtm_proxy(nodelist);
		CleanArray(nodelist);
	}
	/* Reconfigure */
	var_assign(&aval(VAR_gtmProxyNames)[idx], Strdup("none"));
	var_assign(&aval(VAR_gtmProxyServers)[idx], Strdup("none"));
	var_assign(&aval(VAR_gtmProxyPorts)[idx], Strdup("-1"));
	var_assign(&aval(VAR_gtmProxyDirs)[idx], Strdup("none"));
	handle_no_slaves();
	makeServerList();
	/* Update configuration file and backup it */
	if ((f = fopen(pgxc_ctl_config_path, "a")) == NULL)
	{
		/* Should it be panic? */
		elog(ERROR, "ERROR: cannot open configuration file \"%s\", %s\n", pgxc_ctl_config_path, strerror(errno));
		return 1;
	}
	fprintf(f, 
			"#===================================================\n"
			"# pgxc configuration file updated due to GTM proxy addition\n"
			"#        %s\n"
			"%s=%s\n"					/* gtmProxy */
			"%s=( %s )\n"				/* gtmProxyNames */
			"%s=( %s )\n"				/* gtmProxyServers */
			"%s=( %s )\n"				/* gtmProxyPorts */
			"%s=( %s )\n"				/* gtmProxyDirs */
			"#----End of reconfiguration -------------------------\n",
			timeStampString(date, MAXTOKEN+1),
			VAR_gtmProxy, sval(VAR_gtmProxy),
			VAR_gtmProxyNames, listValue(VAR_gtmProxyNames),
			VAR_gtmProxyServers, listValue(VAR_gtmProxyServers),
			VAR_gtmProxyPorts, listValue(VAR_gtmProxyPorts),
			VAR_gtmProxyDirs, listValue(VAR_gtmProxyDirs));
	fclose(f);
	backup_configuration();
	elog(NOTICE, "Done.\n");
	return 0;
}
示例#8
0
/*
 * Add gtm proxy: to be used after all the configuration is done.
 *
 * This function only maintains internal configuration, updte configuration file,
 * and make backup if configured.   You should run init and start it separately.
 */
int
add_gtmProxy(char *name, char *host, int port, char *dir)
{
	char port_s[MAXTOKEN+1];
	char date[MAXTOKEN+1];
	FILE *f;
	char **nodelist = NULL;
	int rc;

	if (is_none(host))
	{
		elog(ERROR, "ERROR: Cannot add gtm proxy with the name \"none\".\n");
		return 1;
	}
	if (is_none(dir))
	{
		elog(ERROR, "ERROR: Cannot add gtm proxy with the directory \"none\".\n");
		return 1;
	}
	if (checkSpecificResourceConflict(name, host, port, dir, TRUE))
	{
		elog(ERROR, "ERROR: New specified name:%s, host:%s, port:%d and dir:\"%s\" conflicts with existing node.\n",
			 name, host, port, dir);
		return 1;
	}
	if (!isVarYes(VAR_gtmProxy))
	{
		assign_sval(VAR_gtmProxy, Strdup("y"));
		reset_var(VAR_gtmProxyNames);
	}
	add_val(find_var(VAR_gtmProxyNames), Strdup(name));
	add_val(find_var(VAR_gtmProxyServers), Strdup(host));
	snprintf(port_s, MAXTOKEN, "%d", port);
	add_val(find_var(VAR_gtmProxyPorts), Strdup(port_s));
	add_val(find_var(VAR_gtmProxyDirs), Strdup(dir));
	add_val(find_var(VAR_gtmPxySpecificExtraConfig), Strdup("none"));
	makeServerList();
	if ((f = fopen(pgxc_ctl_config_path, "a")) == NULL)
	{
		/* Should it be panic? */
		elog(ERROR, "ERROR: cannot open configuration file \"%s\", %s\n", pgxc_ctl_config_path, strerror(errno));
		return 1;
	}
	fprintf(f, 
			"#===================================================\n"
			"# pgxc configuration file updated due to GTM proxy (%s) addition\n"
			"#        %s\n",
			name,
			timeStampString(date, MAXTOKEN+1));
	fprintSval(f, VAR_gtmProxy);
	fprintAval(f, VAR_gtmProxyNames);
	fprintAval(f, VAR_gtmProxyServers);
	fprintAval(f, VAR_gtmProxyPorts);
	fprintAval(f, VAR_gtmProxyDirs);
	fprintAval(f, VAR_gtmPxySpecificExtraConfig);
	fprintf(f, "%s", "#----End of reconfiguration -------------------------\n");
	fclose(f);
	AddMember(nodelist, name);
	init_gtm_proxy(nodelist);
	rc = start_gtm_proxy(nodelist);
	CleanArray(nodelist);
	return rc;
}
示例#9
0
/*
 * Failover the gtm ------------------------------------------------------
 */
int
failover_gtm(void)
{
	char date[MAXTOKEN+1];
	char *stdIn;
	int rc;
	FILE *f;
	
	elog(INFO, "Failover gtm\n");
	if (!isVarYes(VAR_gtmSlave) || (sval(VAR_gtmSlaveServer) == NULL) || is_none(sval(VAR_gtmSlaveServer)))
	{
		elog(ERROR, "ERROR: GTM slave is not configured. Cannot failover.\n");
		return(1);
	}
	
	if (do_gtm_ping(sval(VAR_gtmSlaveServer), atoi(sval(VAR_gtmSlavePort))) != 0)
	{
		elog(ERROR, "ERROR: GTM slave is not running\n");
		return(1);
	}

	/* Promote the slave */
	elog(NOTICE, "Running \"gtm_ctl promote -Z gtm -D %s\"\n", sval(VAR_gtmSlaveDir));
	rc = doImmediate(sval(VAR_gtmSlaveServer), NULL, 
					 "gtm_ctl promote -Z gtm -D %s", sval(VAR_gtmSlaveDir));
	if (WEXITSTATUS(rc) != 0)
	{
		elog(ERROR, "ERROR: could not promote gtm (host:%s, dir:%s)\n", sval(VAR_gtmSlaveServer), sval(VAR_gtmSlaveDir));
		return 1;
	}

	/* Configure promoted gtm */
	if ((f = prepareLocalStdin(newFilename(stdIn), MAXPATH, NULL)) == NULL)
		return(1);
	fprintf(f,
			"#===================================================\n"
			"# Updated due to GTM failover\n"
			"#        %s\n"
			"startup = ACT\n"
			"#----End of reconfiguration -------------------------\n",
			timeStampString(date, MAXTOKEN+1));
	fclose(f);
	elog(NOTICE, "Updating gtm.conf at %s:%s\n", sval(VAR_gtmSlaveServer), sval(VAR_gtmSlaveDir));
	rc = doImmediate(sval(VAR_gtmSlaveServer), stdIn, "cat >> %s/gtm.conf", sval(VAR_gtmSlaveDir));
	if (WEXITSTATUS(rc) != 0)
	{
		elog(ERROR, "ERROR: could not update gtm.conf (host: %s, dir:%s)\n", sval(VAR_gtmSlaveServer), sval(VAR_gtmSlaveDir));
		return 1;
	}

	/* Update and backup configuration file */
	if ((f = prepareLocalStdin(stdIn, MAXPATH, NULL)) == NULL)
		return(1);
	fprintf(f,
			"#===================================================\n"
			"# pgxc configuration file updated due to GTM failover\n"
			"#        %s\n"
			"gtmMasterServer=%s\n"
			"gtmMasterPort=%s\n"
			"gtmMasterDir=%s\n"
			"gtmSlave=n\n"
			"gtmSlaveServer=none\n"
			"gtmSlavePort=0\n"
			"gtmSlaveDir=none\n"
			"#----End of reconfiguration -------------------------\n",
			timeStampString(date, MAXTOKEN+1),
			sval(VAR_gtmSlaveServer),
			sval(VAR_gtmSlavePort),
			sval(VAR_gtmSlaveDir));
	fclose(f);
	rc = doImmediate(NULL, stdIn, "cat >> %s", pgxc_ctl_config_path);
	if (WEXITSTATUS(rc) != 0)
	{
		elog(ERROR, "ERROR: could not update gtm.conf (host: %s, dir:%s)\n", sval(VAR_gtmSlaveServer), sval(VAR_gtmSlaveDir));
		return 1;
	}
	freeAndReset(stdIn);
	backup_configuration();

	/* Reconfigure myself */
	assign_val(VAR_gtmMasterServer, VAR_gtmSlaveServer); reset_var(VAR_gtmSlaveServer);
	assign_val(VAR_gtmMasterPort, VAR_gtmSlavePort); reset_var(VAR_gtmSlavePort);
	assign_val(VAR_gtmMasterDir, VAR_gtmSlaveDir); reset_var(VAR_gtmSlaveDir);
	assign_sval(VAR_gtmSlaveServer, "none");
	assign_sval(VAR_gtmSlavePort, "0");
	assign_sval(VAR_gtmSlaveDir, "none");
	assign_sval(VAR_gtmSlave, "n");

	return 0;
}
示例#10
0
int dealWithAConnection()
{
    debug("ok: childProcess().start.");
    close(pSession->localListener); // child doesn't need the listener
    debug("ok: childProcess(). close(localListener).");

    string tString;
    int tTryTime = 0;
    pSession->sessionClosed = 0;
    pSession->userLogedIn = 0;
    pSession->sCurrentPathForClient = "";
    pSession->tryTimeMax = 3;

    packSftpMessagePacket("+Sunny SFTP Service. Please send user-ID. Test ID: lab123.");
    packTcpPacket();

    while(1)//each loop for each command
    {
        pHandleSftpPacket->sExpectedPacketType = "commandPacket";

        while(pSession->userLogedIn == 0)
        {
            debug("ok: checking user-ID.");
            tTryTime ++;

            unpackTcpPacket();// may set pSession->sessionClosed = 1
            if(pSession->sessionClosed)
            {
                return 1;
            }
            unpackSftpPacket();

            if(!pHandleSftpCommandPacket->sCmd.compare("USER"))
            {
                if(!pHandleSftpCommandPacket->sArgs.compare("lab123"))
                {
                    pSession->userLogedIn = 1;
                    cout<<endl<<"ok: " + pHandleSftpCommandPacket->sArgs +" logged in."<<endl<<endl;
                    packSftpMessagePacket("!" + pHandleSftpCommandPacket->sArgs +" logged in.");
                    packTcpPacket();
                    break;
                }
                else
                {
                    cout<<"ok: Invalid user-id, need try again."<<endl;
                    if(tTryTime >= pSession->tryTimeMax)
                    {
                        cout<<"ERR: Illegal access. A user tried " + decimalToString(tTryTime) + " times. Session will close."<<endl;
                        pSession->sessionClosed = 1;
                        close(pSession->localSocket);
                        debug("ok: child: close(localSocket).");
                        exit(1);
                    }
                    packSftpMessagePacket("-Invalid user-id, you have " + decimalToString(pSession->tryTimeMax-tTryTime) + " time(s) left to try.");
                    packTcpPacket();
                }
            }
            else
            {
                cout<<"ok: Illegal command, need \"USER ID\"."<<endl;
                if(tTryTime >= pSession->tryTimeMax)
                {
                    cout<<"ERR: Illegal access. A user tried " + decimalToString(tTryTime) + " times. Session will close."<<endl;
                    pSession->sessionClosed = 1;
                    close(pSession->localSocket);
                    debug("ok: child: close(localSocket).");
                    exit(1);
                }
                packSftpMessagePacket("-Illegal command, please send \"USER ID\", you have " + decimalToString(pSession->tryTimeMax-tTryTime) + " time(s) left to try.");
                packTcpPacket();
            }
        }

        unpackTcpPacket();
        pHandleSftpPacket->sExpectedPacketType = "commandPacket";
        unpackSftpPacket();

        pSession->commandTimer = clock();

        if(!pHandleSftpCommandPacket->sCmd.compare("SEND") && pSession->readyForSubcommand)
        {
            debug("ok: switch cmd: SEND.start.");
            sendTheRequestFile();
            pSession->readyForSubcommand = 0;
            debug("ok: switch cmd: SEND.end.");
        }
        else if(!pHandleSftpCommandPacket->sCmd.compare("STOP") && pSession->readyForSubcommand)
        {
            debug("ok: switch cmd: STOP.start.");
            pSession->readyForSubcommand = 0;
            debug("ok: switch cmd: STOP.end.");
        }
        else if(!pHandleSftpCommandPacket->sCmd.compare("STOR"))
        {
            debug("ok: switch cmd: STOR.start.");
            if(pHandleSftpCommandPacket->sArgs.size() < 5)
            {
                printf("ERR: unexpected command:%s.\n",pHandleSftpCommandPacket->sArgs.c_str());
                packSftpMessagePacket("-ERR: server received unexpected command");
                packTcpPacket();
                continue;
            }

            pHandleSftpCommandPacket->sArgFirst = pHandleSftpCommandPacket->sArgs.substr(0,3);
            pHandleSftpCommandPacket->sArgFirst = toUpString(pHandleSftpCommandPacket->sArgFirst);
            pHandleSftpCommandPacket->sArgSecond = pHandleSftpCommandPacket->sArgs.substr(4);

            if(!pHandleSftpCommandPacket->sArgFirst.compare("NEW"))
            {
                pSession->sLocalFileAddress = pSession->sCurrentPath + pSession->sCurrentPathForClient + pHandleSftpCommandPacket->sArgSecond;
                openReadFile();
                closeReadFile();
                if(pAboutReadFile->sizeFile != -1)//file exists
                {
                    pHandleSftpCommandPacket->sArgSecond = (timeStampString() + "_" + pHandleSftpCommandPacket->sArgSecond);
                    if(dbug)printf("ok: new filename:%s.\n",pHandleSftpCommandPacket->sArgSecond.c_str());
                    pSession->sLocalFileAddress = pSession->sCurrentPath + pSession->sCurrentPathForClient + pHandleSftpCommandPacket->sArgSecond;

                    packSftpMessagePacket("+File exists, will create new generation of file.");
                    packTcpPacket();

                    pSession->readyForSubcommand = 1;
                }
                else//file not exists
                {
                    pSession->sLocalFileAddress = pSession->sCurrentPath + pSession->sCurrentPathForClient + pHandleSftpCommandPacket->sArgSecond;
                    packSftpMessagePacket("+File does not exist, will create new file.");
                    packTcpPacket();

                    pSession->readyForSubcommand = 1;
                }
            }
            else if(!pHandleSftpCommandPacket->sArgFirst.compare("OLD"))
            {
                pSession->sLocalFileAddress = pSession->sCurrentPath + pSession->sCurrentPathForClient + pHandleSftpCommandPacket->sArgSecond;
                openReadFile();
                closeReadFile();
                if(pAboutReadFile->sizeFile != -1)//file exists
                {
                    pSession->sLocalFileAddress = pSession->sCurrentPath + pSession->sCurrentPathForClient + pHandleSftpCommandPacket->sArgSecond;
                    packSftpMessagePacket("+Will write over old file.");
                    packTcpPacket();

                    pSession->readyForSubcommand = 1;
                }
                else//file not exists
                {
                    pSession->sLocalFileAddress = pSession->sCurrentPath + pSession->sCurrentPathForClient + pHandleSftpCommandPacket->sArgSecond;
                    packSftpMessagePacket("+Will create new file.");
                    packTcpPacket();

                    pSession->readyForSubcommand = 1;
                }
            }
            else if(!pHandleSftpCommandPacket->sArgFirst.compare("APP"))
            {
                pSession->sLocalFileAddress = pSession->sCurrentPath + pSession->sCurrentPathForClient + pHandleSftpCommandPacket->sArgSecond;
                openReadFile();
                closeReadFile();
                if(pAboutReadFile->sizeFile != -1)//file exists
                {
                    pSession->sLocalFileAddress = pSession->sCurrentPath + pSession->sCurrentPathForClient + pHandleSftpCommandPacket->sArgSecond;
                    packSftpMessagePacket("+Will append to file.");
                    packTcpPacket();

                    char aChar[] = "ab";
                    pAboutWriteFile->pOpenWriteType = aChar;//after transfer, set back to default //pAboutWriteFile->pOpenWriteType = aDefaultOpenWriteType
                    pSession->readyForSubcommand = 1;
                }
                else//file not exists
                {
                    pSession->sLocalFileAddress = pSession->sCurrentPath + pSession->sCurrentPathForClient + pHandleSftpCommandPacket->sArgSecond;
                    packSftpMessagePacket("+Will create file.");
                    packTcpPacket();

                    pSession->readyForSubcommand = 1;
                }
            }
            else
            {
                printf("ERR: unexpected command:%s.\n",pHandleSftpCommandPacket->sArgs.c_str());
                packSftpMessagePacket("-ERR: server received unexpected command.");
                packTcpPacket();
                continue;
            }
            debug("ok: switch cmd: STOR.end.");
        }
        else if(!pHandleSftpCommandPacket->sCmd.compare("SIZE") && pSession->readyForSubcommand)
        {
            debug("ok: switch cmd: SIZE.start.");
            pAboutWriteFile->sizeFile = atoi(pHandleSftpCommandPacket->sArgs.c_str());
            printf("ok: file size: %d bytes.\n",pAboutWriteFile->sizeFile);
            int tInt;
            if(pAboutWriteFile->sizeFile >= (tInt = pAboutWriteFile->sizeFreeDiskByte()) )
            {
                if(dbug)printf("ok: disk free size >= %d bytes.\n",tInt);
                say("ERR: disk full.");
                packSftpMessagePacket("-Not enough room, dont send it.");
                packTcpPacket();
                continue;
            }
            else//disk space is ok
            {
                if(dbug)printf("ok: disk free size > %d bytes.\n",tInt);
                packSftpMessagePacket("+ok, waiting for file.");
                packTcpPacket();
                say("ok: ready to receive file.");

                pHandleSftpPacket->sExpectedPacketType = "dataPacket";

                if(receiveTheRequestFile())
                {
                    packSftpMessagePacket("-Couldn't save.");
                    packTcpPacket();
                    say("ERR: couldn't save.");
                    continue;
                }
                else
                {
                    packSftpMessagePacket("+Saved:"+pSession->sLocalFileAddress.substr(pSession->sCurrentPath.size()));
                    packTcpPacket();
                    cout<<"ok: saved:" + pSession->sLocalFileAddress<<endl;
                }
            }//if //else//disk space is ok
            pSession->readyForSubcommand = 0;
            pAboutWriteFile->pOpenWriteType = aDefaultOpenWriteType;//"wb"
            debug("ok: switch cmd: SIZE.end.");
        }//else if "SIZE"
        else if(!pHandleSftpCommandPacket->sCmd.compare("RETR"))
        {
            debug("ok: switch cmd: RETR.start.");
            pSession->sLocalFileAddress = pSession->sCurrentPath + pSession->sCurrentPathForClient + pHandleSftpCommandPacket->sArgs;
            if(dbug)cout<<"ok: sFileAddress:"<<pSession->sLocalFileAddress<<endl;

            if(openReadFile())
            {
                printf("ERR: file not exists:%s.\n",pHandleSftpCommandPacket->sArgs.c_str());
                packSftpMessagePacket("-ERR: file not exists.");
                packTcpPacket();
                continue;
            }
            closeReadFile();
            tString = decimalToString(pAboutReadFile->sizeFile);

            packSftpMessagePacket(tString);
            packTcpPacket();
            pSession->readyForSubcommand = 1;
            debug("ok: switch cmd: RETR.end.");
        }
        else if(!pHandleSftpCommandPacket->sCmd.compare("NAME"))
        {
            debug("ok: switch cmd: NAME.start.");
            pSession->sLocalFileAddress = pSession->sCurrentPath + pSession->sCurrentPathForClient + pHandleSftpCommandPacket->sArgs;

            if(openReadFile())
            {
                printf("ERR: file not exists:%s.\n",pHandleSftpCommandPacket->sArgs.c_str());
                packSftpMessagePacket("-ERR: file not exists.");
                packTcpPacket();
                continue;
            }
            closeReadFile();
            packSftpMessagePacket("+File exists.");
            packTcpPacket();

            string tsOldName = pHandleSftpCommandPacket->sArgs;
            unpackTcpPacket();
            pHandleSftpPacket->sExpectedPacketType = "commandPacket";
            unpackSftpPacket();
            if(pHandleSftpCommandPacket->sCmd.compare("TOBE"))//if not "TOBE"
            {
                printf("ERR: unexpected command following \"NAME\":%s.",pHandleSftpCommandPacket->sArgs.c_str());
                packSftpMessagePacket("-ERR: server received unexpected command following \"NAME\".");
                packTcpPacket();
                continue;
            }

            if(!openReadFile(pSession->sCurrentPath + pSession->sCurrentPathForClient + pHandleSftpCommandPacket->sArgs))
            {
                printf("ERR: new filename exists:%s.\n",pHandleSftpCommandPacket->sArgs.c_str());
                packSftpMessagePacket("-ERR: new filename exists.");
                packTcpPacket();

                closeReadFile();
                continue;
            }

            if(rename(  (pSession->sCurrentPath + pSession->sCurrentPathForClient + tsOldName).c_str(),
                        (pSession->sCurrentPath + pSession->sCurrentPathForClient + pHandleSftpCommandPacket->sArgs).c_str()
                     ))
            {
                printf("ERR: rename error, file may under using:%s.\n",pHandleSftpCommandPacket->sArgs.c_str());
                packSftpMessagePacket("-ERR: rename error, file may under using.");
                packTcpPacket();
                continue;
            }
            packSftpMessagePacket("+" + tsOldName +" renamed to " + pHandleSftpCommandPacket->sArgs);
            packTcpPacket();
            debug("ok: switch cmd: NAME.end.");
        }
        else if(!pHandleSftpCommandPacket->sCmd.compare("KILL"))
        {
            debug("ok: switch cmd: KILL.start.");
            if (remove((pSession->sCurrentPath + pSession->sCurrentPathForClient + pHandleSftpCommandPacket->sArgs).c_str()))
            {
                printf("ERR: unexpected filename:%s.\n",pHandleSftpCommandPacket->sArgs.c_str());
                packSftpMessagePacket("-ERR: server received unexpected filename.");
                packTcpPacket();
                continue;
            }
            cout<<"ok: file:" + pHandleSftpCommandPacket->sArgs + " deleted."<<endl;
            packSftpMessagePacket("+" + pHandleSftpCommandPacket->sArgs + " deleted.");
            packTcpPacket();
            debug("ok: switch cmd: KILL.end.");
        }
        else if(!pHandleSftpCommandPacket->sCmd.compare("LIST"))
        {
            debug("ok: switch cmd: LIST.start.");
            if(pHandleSftpCommandPacket->sArgs.size() < 1)
            {
                printf("ERR: unexpected command:%s.\n",pHandleSftpCommandPacket->sCommand.c_str());
                packSftpMessagePacket("-ERR: server received unexpected command");
                packTcpPacket();
                continue;
            }
            pHandleSftpCommandPacket->sArgFirst = pHandleSftpCommandPacket->sArgs.substr(0,1);
            pHandleSftpCommandPacket->sArgFirst = toUpString(pHandleSftpCommandPacket->sArgFirst);
            if(pHandleSftpCommandPacket->sArgs.size() > 2)
            {
                if(pHandleSftpCommandPacket->sArgs[0] == '/')
                {
                    pHandleSftpCommandPacket->sArgs.erase(0,1);
                }
                pHandleSftpCommandPacket->sArgSecond = pHandleSftpCommandPacket->sArgs.substr(2);
            }
            else
            {
                pHandleSftpCommandPacket->sArgSecond = "";
            }

            struct dirent * tpDirent = NULL;
            DIR * tpDirectory = NULL;
            string tsDirectoryToList = pSession->sCurrentPath + pSession->sCurrentPathForClient + pHandleSftpCommandPacket->sArgSecond;
            string tsList = "";
            struct stat tStat;
            string tsFileAddress;
            string tsLine = "";

            tpDirectory = opendir(tsDirectoryToList.c_str());
            if( tpDirectory == NULL)
            {
                printf("ERR: unexpected directory to list:%s.\n",tsDirectoryToList.c_str());
                packSftpMessagePacket("-ERR: unexpected directory to list.");
                packTcpPacket();
                continue;
            }
            if(dbug)cout<<"ok: directory to list:"<<tsDirectoryToList<<endl;
            if(!pHandleSftpCommandPacket->sArgFirst.compare("F"))
            {
                tsList = "+" + pSession->sCurrentPathForClient + pHandleSftpCommandPacket->sArgSecond + "\n";
                while((tpDirent = readdir(tpDirectory)))
                {
                    if(tsList.size() + 15 >= tcpLoadMax || tsList.size() + strlen(tpDirent->d_name) >= tcpLoadMax - 5 )
                    {
                        tsList.append("...etc...");
                        tsList.append("\n");
                        break;
                    }
                    tsList.append(tpDirent->d_name);
                    tsList.append("\n");
                }
                closedir(tpDirectory);
                if(dbug)cout<<"ok: list:"<<endl<<tsList<<endl;
                packSftpMessagePacket(tsList);
                packTcpPacket();

                tsList = "";
                tsDirectoryToList = pSession->sCurrentPath + pSession->sCurrentPathForClient;
                pHandleSftpCommandPacket->sArgFirst = "";
                pHandleSftpCommandPacket->sArgSecond = "";
            }
            else if(!pHandleSftpCommandPacket->sArgFirst.compare("V"))
            {
                tsList = "+" + pSession->sCurrentPathForClient + pHandleSftpCommandPacket->sArgSecond + "\n";
                while((tpDirent = readdir(tpDirectory)))
                {
                    tsLine = "";
                    tsLine += tpDirent->d_name;

                    tsFileAddress = pSession->sCurrentPath + pSession->sCurrentPathForClient + tpDirent->d_name;
                    stat(tsFileAddress.c_str(), &tStat);
                    if(S_ISDIR(tStat.st_mode))//if folder
                    {
                        tsLine += "\t<LIST>...\n";
                    }
                    else
                    {
                        tsLine += "\t";
                        tsLine += decimalToString(tStat.st_size);
                        tsLine += "\t";
                        tsLine += time_tToString(tStat.st_mtime);
                        tsLine += "\n";
                    }
                    if(tsList.size() + 15 >= tcpLoadMax || tsList.size() + tsLine.size() >= tcpLoadMax - 5)
                    {
                        tsList.append("...etc...");
                        tsList.append("\n");
                        break;
                    }
                    else
                    {
                        tsList += tsLine;
                    }
                }
                closedir(tpDirectory);
                if(dbug)cout<<"ok: list:"<<endl<<tsList<<endl;
                packSftpMessagePacket(tsList);
                packTcpPacket();

                tsList = "";
                tsDirectoryToList = pSession->sCurrentPath + pSession->sCurrentPathForClient;
                pHandleSftpCommandPacket->sArgFirst = "";
                pHandleSftpCommandPacket->sArgSecond = "";
            }
            else
            {
                printf("ERR: unexpected LIST argument:%s.\n",pHandleSftpCommandPacket->sArgs.c_str());
                packSftpMessagePacket("-ERR: server received unexpected LIST argument.");
                packTcpPacket();

                tsList = "";
                tsDirectoryToList = pSession->sCurrentPath + pSession->sCurrentPathForClient;
                pHandleSftpCommandPacket->sArgFirst = "";
                pHandleSftpCommandPacket->sArgSecond = "";
                continue;
            }
            debug("ok: switch cmd: LIST.end.");
        }
        else if(!pHandleSftpCommandPacket->sCmd.compare("CDIR"))
        {
            debug("ok: switch cmd: CDIR.start.");
            if(pHandleSftpCommandPacket->sArgs[0] == '/')
            {
                pHandleSftpCommandPacket->sArgs.erase(0,1);
            }
            if(pHandleSftpCommandPacket->sArgs.size() > 0)
            {
                if(pHandleSftpCommandPacket->sArgs[pHandleSftpCommandPacket->sArgs.size()-1] != '/')
                {
                    pHandleSftpCommandPacket->sArgs += "/";
                }
            }

            DIR * tpDirectoryCdir = NULL;
            string tsDirectoryToCdir = pSession->sCurrentPath + pHandleSftpCommandPacket->sArgs;
            tpDirectoryCdir = opendir(tsDirectoryToCdir.c_str());
            if( tpDirectoryCdir == NULL)
            {
                printf("ERR: unexpected real directory to change to:%s.\n",tsDirectoryToCdir.c_str());
                packSftpMessagePacket("-ERR: unexpected directory to chang to.");
                packTcpPacket();
                continue;
            }
            if(dbug)cout<<"ok: real directory to change to:"<<tsDirectoryToCdir<<endl;
            packSftpMessagePacket("!Changed working dir to /"+pHandleSftpCommandPacket->sArgs);
            packTcpPacket();
            pSession->sCurrentPathForClient = pHandleSftpCommandPacket->sArgs;
            cout<<"ok: sCurrentPathForClient:/"<<pSession->sCurrentPathForClient<<endl;
            debug("ok: switch cmd: CDIR.end.");
        }
        else if(!pHandleSftpCommandPacket->sCmd.compare("TYPE"))
        {
            debug("ok: switch cmd: TYPE.start.");
            packSftpMessagePacket("-This server is binary mode only.");
            packTcpPacket();
            debug("ok: switch cmd: TYPE.end.");
        }
        else if(!pHandleSftpCommandPacket->sCmd.compare("DONE"))
        {
            debug("ok: switch cmd: DONE.start.");
            packSftpMessagePacket("+.");///need change
            packTcpPacket();
            debug("ok: switch cmd: DONE.end.");
            break;
        }
        else
        {
            printf("ERR: unexpected command:%s.",pHandleSftpCommandPacket->sArgs.c_str());
            packSftpMessagePacket("-ERR: server received unexpected command");
            packTcpPacket();
            continue;
        }

        printf("\nok: finished command: \"%s\".%s.\n\n",pHandleSftpCommandPacket->sCommand.c_str(),timeStamp());
        pSession->commandTimer = clock() - pSession->commandTimer;
        printf("ok: handeling this command costs: %i s.\n",pSession->commandTimer/CLOCKS_PER_SEC);
    }//while(1)//each loop for each command

    printf("\nok: finished command: \"DONE\".\n");
    pSession->commandTimer = clock() - pSession->commandTimer;
    printf("ok: handeling this command costs: %i s.\n",pSession->commandTimer/CLOCKS_PER_SEC);
    pSession->sessionClosed = 0;

    close(pSession->localSocket);
    debug("ok: child: close(localSocket).");

    exit(0);
}