/* * 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()); }
/* * 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; }
/* * 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); }
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; }
/* * 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); }
/* * 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); }
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; }
/* * 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; }
/* * 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; }
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); }