4 * The secure anycast tunneling protocol (satp) defines a protocol used
\r
5 * for communication between any combination of unicast and anycast
\r
6 * tunnel endpoints. It has less protocol overhead than IPSec in Tunnel
\r
7 * mode and allows tunneling of every ETHER TYPE protocol (e.g.
\r
8 * ethernet, ip, arp ...). satp directly includes cryptography and
\r
9 * message authentication based on the methodes used by SRTP. It is
\r
10 * intended to deliver a generic, scaleable and secure solution for
\r
11 * tunneling and relaying of packets of any protocol.
\r
14 * Copyright (C) 2007-2009 Othmar Gsenger, Erwin Nindl,
\r
15 * Christian Pointner <satp@wirdorange.org>
\r
17 * This file is part of Anytun.
\r
19 * Anytun is free software: you can redistribute it and/or modify
\r
20 * it under the terms of the GNU General Public License as published by
\r
21 * the Free Software Foundation, either version 3 of the License, or
\r
22 * any later version.
\r
24 * Anytun is distributed in the hope that it will be useful,
\r
25 * but WITHOUT ANY WARRANTY; without even the implied warranty of
\r
26 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
\r
27 * GNU General Public License for more details.
\r
29 * You should have received a copy of the GNU General Public License
\r
30 * along with anytun. If not, see <http://www.gnu.org/licenses/>.
\r
33 #ifndef ANYTUN_sysexec_hpp_INCLUDED
\r
34 #define ANYTUN_sysexec_hpp_INCLUDED
\r
36 #include <algorithm>
\r
37 #include <iostream> // todo remove
\r
38 #include <windows.h>
\r
43 CloseHandle(process_info_.hProcess);
\r
44 CloseHandle(process_info_.hThread);
\r
48 STARTUPINFOA getStartupInfo() {
\r
49 STARTUPINFOA startup_info;
\r
50 startup_info.cb = sizeof(STARTUPINFOA);
\r
51 GetStartupInfoA(&startup_info);
\r
53 //startup_info.dwFlags = STARTF_USESTDHANDLES;
\r
54 //startup_info.hStdInput = CreateFile("NUL", GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, 0, 0, 0); // INVALID_HANDLE_VALUE;
\r
55 //startup_info.hStdOutput = CreateFile("NUL", GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, 0, 0, 0); // INVALID_HANDLE_VALUE;
\r
56 //startup_info.hStdError = CreateFile("NUL", GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, 0, 0, 0); // INVALID_HANDLE_VALUE;
\r
57 startup_info.dwFlags |= STARTF_USESHOWWINDOW;
\r
58 startup_info.wShowWindow = SW_HIDE;
\r
60 return startup_info;
\r
63 char const * const BATCH_FILE_EXTS[] = { ".bat", ".cmd" };
\r
64 int const BATCH_FILE_EXTS_COUNT = sizeof(BATCH_FILE_EXTS) / sizeof(BATCH_FILE_EXTS[0]);
\r
66 bool endsWith(std::string const& string, std::string const& suffix) {
\r
67 return string.find(suffix, string.size() - suffix.size()) != std::string::npos;
\r
70 void SysExec::doExec(StringVector args, StringList env)
\r
72 std::vector<char> arguments;
\r
74 bool isBatchFile = false;
\r
75 for(int i = 0; i < BATCH_FILE_EXTS_COUNT; ++i) {
\r
76 if(endsWith(script_, BATCH_FILE_EXTS[i])) {
\r
83 std::string const BATCH_INTERPRETER = "cmd /c \"";
\r
84 arguments.insert(arguments.end(), BATCH_INTERPRETER.begin(), BATCH_INTERPRETER.end());
\r
86 arguments.push_back('\"');
\r
87 arguments.insert(arguments.end(), script_.begin(), script_.end());
\r
88 arguments.push_back('\"');
\r
89 arguments.push_back(' ');
\r
91 for(StringVector::const_iterator it = args.begin(); it != args.end(); ++it) {
\r
92 arguments.push_back('\"');
\r
93 arguments.insert(arguments.end(), it->begin(), it->end());
\r
94 arguments.push_back('\"');
\r
95 arguments.push_back(' ');
\r
99 arguments.push_back('\"');
\r
101 arguments.push_back(0);
\r
103 STARTUPINFOA startup_info = getStartupInfo();
\r
105 std::map<std::string, std::string> envDict;
\r
106 for(StringList::const_iterator it = env.begin(); it != env.begin(); ++it) {
\r
107 size_t delimiter_pos = it->find('=');
\r
108 envDict.insert(std::make_pair(it->substr(0, delimiter_pos), it->substr(delimiter_pos + 1)));
\r
110 std::vector<char> env;
\r
111 for(std::map<std::string, std::string>::iterator it = envDict.begin(); it != envDict.end(); ++it) {
\r
112 env.insert(env.end(), it->first.begin(), it->first.end());
\r
117 if(!CreateProcessA(NULL,
\r
129 cLog.msg(Log::PRIO_ERROR) << "executing script '" << script_ << "' CreateProcess() error: " << GetLastError();
\r
134 int SysExec::waitForScript()
\r
136 DWORD result = WaitForSingleObject(process_info_.hProcess, INFINITE);
\r
137 assert(WAIT_OBJECT_0 == result); // WAIT_FAILED, WAIT_TIMEOUT ... ???
\r
138 bool success = GetExitCodeProcess(process_info_.hProcess, &return_code_) != 0;
\r
139 assert(true == success); // false -> HU?
\r
141 CloseHandle(process_info_.hProcess);
\r
142 CloseHandle(process_info_.hThread);
\r
145 return static_cast<int>(return_code_);
\r
148 void SysExec::waitAndDestroy(SysExec*& s)
\r
153 s->waitForScript();
\r
154 cLog.msg(Log::PRIO_NOTICE) << "script '" << s->script_ << "' returned " << s->return_code_;
\r
160 #endif // ANYTUN_sysexec_hpp_INCLUDED
\r