Subversion Repositories HomeAutomation

Rev

Rev 1665 | Rev 1675 | Go to most recent revision | Only display areas with differences | Regard whitespace | Details | Blame | Last modification | View Log | SVN | RSS feed

Rev 1665 Rev 1674
1
/*
1
/*
2
 *
2
 *
3
 *  Copyright (C) 2010  Mattias Runge
3
 *  Copyright (C) 2010  Mattias Runge
4
 *
4
 *
5
 *  This program is free software; you can redistribute it and/or modify
5
 *  This program is free software; you can redistribute it and/or modify
6
 *  it under the terms of the GNU General Public License as published by
6
 *  it under the terms of the GNU General Public License as published by
7
 *  the Free Software Foundation; either version 2 of the License, or
7
 *  the Free Software Foundation; either version 2 of the License, or
8
 *  (at your option) any later version.
8
 *  (at your option) any later version.
9
 *
9
 *
10
 *  This program is distributed in the hope that it will be useful,
10
 *  This program is distributed in the hope that it will be useful,
11
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
11
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
12
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13
 *  GNU General Public License for more details.
13
 *  GNU General Public License for more details.
14
 *
14
 *
15
 *  You should have received a copy of the GNU General Public License along
15
 *  You should have received a copy of the GNU General Public License along
16
 *  with this program; if not, write to the Free Software Foundation, Inc.,
16
 *  with this program; if not, write to the Free Software Foundation, Inc.,
17
 *  51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
17
 *  51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
18
 *
18
 *
19
 */
19
 */
20
 
20
 
21
#include <string>
21
#include <string>
22
#include <vector>
22
#include <vector>
23
#include <iostream>
23
#include <iostream>
24
 
24
 
25
#include <signal.h>
25
#include <signal.h>
26
#include <stdio.h>
26
#include <stdio.h>
27
#include <stdlib.h>
27
#include <stdlib.h>
28
#include <pwd.h>
28
#include <pwd.h>
29
 
29
 
30
#include <boost/lexical_cast.hpp>
30
#include <boost/lexical_cast.hpp>
31
#include <boost/thread/mutex.hpp>
31
#include <boost/thread/mutex.hpp>
32
#include <boost/thread/condition.hpp>
32
#include <boost/thread/condition.hpp>
33
#include <boost/thread/locks.hpp>
33
#include <boost/thread/locks.hpp>
34
#include <boost/algorithm/string.hpp>
34
#include <boost/algorithm/string.hpp>
35
#include <boost/program_options.hpp>
35
#include <boost/program_options.hpp>
36
 
36
 
37
#include "config.h"
37
#include "config.h"
38
 
38
 
39
#include "net/Manager.h"
39
#include "net/Manager.h"
40
#include "net/Subscriber.h"
40
#include "net/Subscriber.h"
41
#include "net/types.h"
41
#include "net/types.h"
42
 
42
 
43
#include "common/common.h"
43
#include "common/common.h"
44
 
44
 
45
#include <readline/readline.h>
45
#include <readline/readline.h>
46
#include <readline/history.h>
46
#include <readline/history.h>
47
 
47
 
48
using namespace atom;
48
using namespace atom;
49
 
49
 
50
bool finish = false;
50
bool finish = false;
51
common::StringList autocomplete_list;
51
common::StringList autocomplete_list;
52
char* buffer = NULL;
52
char* buffer = NULL;
53
boost::condition on_message_condition;
53
boost::condition on_message_condition;
54
struct termios original_flags;
54
struct termios original_flags;
55
std::string history_filename;
55
std::string history_filename;
56
 
56
 
57
void Handler(int status);
57
void Handler(int status);
58
void CleanUp();
58
void CleanUp();
59
 
59
 
60
char* AutoCompleteGet(const char* text, int state);
60
char* AutoCompleteGet(const char* text, int state);
61
static char** AutoComplete(const char* text, int start, int end);
61
static char** AutoComplete(const char* text, int start, int end);
62
 
62
 
63
std::string GetUserHomeDirectory()
63
std::string GetUserHomeDirectory()
64
{
64
{
65
    return std::string(getpwuid(getuid())->pw_dir);
65
    return std::string(getpwuid(getuid())->pw_dir);
66
}
66
}
67
 
67
 
68
class ConsoleClient : public net::Subscriber
68
class ConsoleClient : public net::Subscriber
69
{
69
{
70
public:
70
public:
71
    typedef boost::shared_ptr<ConsoleClient> Pointer;
71
    typedef boost::shared_ptr<ConsoleClient> Pointer;
72
   
72
   
73
    ConsoleClient(std::string address, unsigned int port)
73
    ConsoleClient(std::string address, unsigned int port)
74
    {
74
    {
75
        this->client_id_ = net::Manager::Instance()->Connect(net::PROTOCOL_TCP, address, port);
75
        this->client_id_ = net::Manager::Instance()->Connect(net::PROTOCOL_TCP, address, port);
76
    }
76
    }
77
   
77
   
78
    virtual ~ConsoleClient()
78
    virtual ~ConsoleClient()
79
    {
79
    {
80
        net::Manager::Instance()->Disconnect(this->client_id_);
80
        net::Manager::Instance()->Disconnect(this->client_id_);
81
 
81
 
82
        this->io_service_.stop();
82
        this->io_service_.stop();
83
    }
83
    }
84
   
84
   
85
    std::string GetPrompt()
85
    std::string GetPrompt()
86
    {
86
    {
87
        return this->prompt_;
87
        return this->prompt_;
88
    }
88
    }
89
   
89
   
90
    void SendResponse(std::string payload)
90
    void SendResponse(std::string payload)
91
    {
91
    {
92
        std::string packet = "RESP";
92
        std::string packet = "RESP";
93
        packet += common::PadNumber(payload.length() + 1, 4);
93
        packet += common::PadNumber(payload.length() + 1, 4);
94
        packet += payload;
94
        packet += payload;
95
       
95
       
96
        net::Manager::Instance()->SendTo(this->client_id_, packet);
96
        net::Manager::Instance()->SendTo(this->client_id_, packet);
97
    }
97
    }
98
   
98
   
99
    void AutoCompleteRequest(unsigned int arg_index, std::string commandline)
99
    void AutoCompleteRequest(unsigned int arg_index, std::string commandline)
100
    {
100
    {
101
        std::string payload = common::PadNumber(arg_index, 4);
101
        std::string payload = common::PadNumber(arg_index, 4);
102
        payload += commandline;
102
        payload += commandline;
103
       
103
       
104
        std::string packet = "COMP";
104
        std::string packet = "COMP";
105
        packet += common::PadNumber(payload.length() + 1, 4);
105
        packet += common::PadNumber(payload.length() + 1, 4);
106
        packet += payload;
106
        packet += payload;
107
       
107
       
108
        net::Manager::Instance()->SendTo(this->client_id_, packet);
108
        net::Manager::Instance()->SendTo(this->client_id_, packet);
109
    }
109
    }
110
   
110
   
111
private:
111
private:
112
    net::ClientId client_id_;
112
    net::ClientId client_id_;
113
    std::string prompt_;
113
    std::string prompt_;
-
 
114
    std::vector<unsigned char> buffer_;
114
   
115
   
115
    void SlotOnNewStateHandler(net::ClientId client_id, net::ServerId server_id, net::ClientState client_state)
116
    void SlotOnNewStateHandler(net::ClientId client_id, net::ServerId server_id, net::ClientState client_state)
116
    {
117
    {
117
        if (client_state != net::CLIENT_STATE_CONNECTED)
118
        if (client_state != net::CLIENT_STATE_CONNECTED)
118
        {
119
        {
119
            std::cout << "Disconnected from server." << std::endl;
120
            std::cout << "Disconnected from server." << std::endl;
120
           
121
           
121
            this->client_id_ = 0;
122
            this->client_id_ = 0;
122
            finish = true;
123
            finish = true;
123
            on_message_condition.notify_all();
124
            on_message_condition.notify_all();
124
        }
125
        }
125
    }
126
    }
126
   
127
   
127
    void SlotOnNewDataHandler(net::ClientId client_id, net::ServerId server_id, common::Byteset data)
128
    void SlotOnNewDataHandler(net::ClientId client_id, net::ServerId server_id, common::Byteset data)
128
    {
129
    {
-
 
130
        for (unsigned int n = 0; n < data.GetSize(); n++)
-
 
131
        {
129
        std::string s(data.ToCharString());
132
            this->buffer_.push_back(data[n]);
-
 
133
        }
130
 
134
 
131
        while (s.length() > 0)
135
        while (this->buffer_.size() >= 8)
132
        {
136
        {
133
            std::string command = s.substr(0, 4);
137
            std::string command = "";
-
 
138
            command += (char)this->buffer_[0];
-
 
139
            command += (char)this->buffer_[1];
-
 
140
            command += (char)this->buffer_[2];
-
 
141
            command += (char)this->buffer_[3];
-
 
142
 
-
 
143
            std::string payload_length_str = "";
-
 
144
            payload_length_str += (char)this->buffer_[4];
-
 
145
            payload_length_str += (char)this->buffer_[5];
-
 
146
            payload_length_str += (char)this->buffer_[6];
-
 
147
            payload_length_str += (char)this->buffer_[7];
-
 
148
           
134
            unsigned int payload_length = boost::lexical_cast<unsigned int>(s.substr(4, 4));
149
            unsigned int payload_length = boost::lexical_cast<unsigned int>(payload_length_str);
135
           
150
           
-
 
151
            if (this->buffer_.size() - 8 < payload_length)
-
 
152
            {
-
 
153
                return;
-
 
154
            }
-
 
155
         
-
 
156
            std::string payload = "";
-
 
157
            for (unsigned int n = 8; n < payload_length + 8; n++)
-
 
158
            {
-
 
159
                payload += (char)this->buffer_[n];
-
 
160
            }
-
 
161
           
-
 
162
            this->buffer_.erase(this->buffer_.begin(), this->buffer_.begin() + payload_length + 8);
-
 
163
           
136
            if (command == "TEXT")
164
            if (command == "TEXT")
137
            {
165
            {
138
                std::cout << s.substr(8, payload_length - 1) << std::flush;
166
                std::cout << payload << std::flush;
139
            }
167
            }
140
            else if (command == "PROM")
168
            else if (command == "PROM")
141
            {
169
            {
142
                this->prompt_ = s.substr(8, payload_length - 1);
170
                this->prompt_ = payload;
143
                on_message_condition.notify_all();
171
                on_message_condition.notify_all();
144
            }
172
            }
145
            else if (command == "COMP")
173
            else if (command == "COMP")
146
            {
174
            {
147
                autocomplete_list.clear();
175
                autocomplete_list.clear();
148
               
-
 
149
                if (payload_length > 0)
-
 
150
                {
-
 
151
                    std::string payload = s.substr(8, payload_length - 1);
-
 
152
                   
176
               
153
                    if (payload.length() > 0)
177
                if (payload.length() > 0)
154
                    {
178
                {
155
                        boost::algorithm::split(autocomplete_list, payload, boost::is_any_of("\n"), boost::algorithm::token_compress_on);
179
                    boost::algorithm::split(autocomplete_list, payload, boost::is_any_of("\n"), boost::algorithm::token_compress_on);
156
                    }
-
 
157
                }
180
                }
158
               
181
               
159
                on_message_condition.notify_all();
182
                on_message_condition.notify_all();
160
            }
183
            }
161
            else
184
            else
162
            {
185
            {
163
                std::cerr << "Unknown data received: " << s << std::endl;
186
                std::cerr << "Could not parse package." << std::endl;
164
                finish = true;
187
                finish = true;
165
                on_message_condition.notify_all();
188
                on_message_condition.notify_all();
166
                break;
189
                break;
167
            }
190
            }
168
           
-
 
169
            if (8 + payload_length >= s.length())
-
 
170
            {
-
 
171
                break;
-
 
172
            }
-
 
173
           
-
 
174
            s = s.substr(8 + payload_length);
-
 
175
        }
191
        }
176
    }
192
    }
177
};
193
};
178
 
194
 
179
ConsoleClient::Pointer cc;
195
ConsoleClient::Pointer cc;
180
 
196
 
181
 
197
 
182
int main(int argc, char **argv)
198
int main(int argc, char **argv)
183
{
199
{
184
    // Signal handlers
200
    // Signal handlers
185
    signal(SIGTERM, Handler);
201
    signal(SIGTERM, Handler);
186
    signal(SIGINT, Handler);
202
    signal(SIGINT, Handler);
187
    signal(SIGQUIT, Handler);
203
    signal(SIGQUIT, Handler);
188
    signal(SIGABRT, Handler);
204
    signal(SIGABRT, Handler);
189
    signal(SIGPIPE, Handler);
205
    signal(SIGPIPE, Handler);
190
   
206
   
191
    boost::mutex guard_mutex;
207
    boost::mutex guard_mutex;
192
   
208
   
193
    // Setup readline
209
    // Setup readline
194
    history_filename = GetUserHomeDirectory() + "/.atomic_history";
210
    history_filename = GetUserHomeDirectory() + "/.atomic_history";
195
    read_history(history_filename.data());
211
    read_history(history_filename.data());
196
   
212
   
197
    rl_attempted_completion_function = AutoComplete;
213
    rl_attempted_completion_function = AutoComplete;
198
   
214
   
199
    // Save command line state
215
    // Save command line state
200
    tcgetattr(fileno(stdin), &original_flags);
216
    tcgetattr(fileno(stdin), &original_flags);
201
   
217
   
202
    // Parse commandline
218
    // Parse commandline
203
    boost::program_options::options_description command_line;
219
    boost::program_options::options_description command_line;
204
    boost::program_options::variables_map variable_map;
220
    boost::program_options::variables_map variable_map;
205
   
221
   
206
    command_line.add_options()
222
    command_line.add_options()
207
    ("help,h",    "produce help message")
223
    ("help,h",    "produce help message")
208
    ("command,c", boost::program_options::value<std::string>()->default_value(""), "command")
224
    ("command,c", boost::program_options::value<std::string>()->default_value(""), "command")
209
    ("server,s",  boost::program_options::value<std::string>()->default_value("localhost"), "server address")
225
    ("server,s",  boost::program_options::value<std::string>()->default_value("localhost"), "server address")
210
    ("port,p",    boost::program_options::value<unsigned int>()->default_value(1202), "server port");
226
    ("port,p",    boost::program_options::value<unsigned int>()->default_value(1202), "server port");
211
   
227
   
212
    try
228
    try
213
    {
229
    {
214
        boost::program_options::store(boost::program_options::command_line_parser(argc, argv).options(command_line).run(), variable_map);
230
        boost::program_options::store(boost::program_options::command_line_parser(argc, argv).options(command_line).run(), variable_map);
215
    }
231
    }
216
    catch (boost::program_options::unknown_option e)
232
    catch (boost::program_options::unknown_option e)
217
    {
233
    {
218
        std::cerr << e.what() << std::endl;
234
        std::cerr << e.what() << std::endl;
219
        std::cout << command_line << std::endl;
235
        std::cout << command_line << std::endl;
220
        CleanUp();
236
        CleanUp();
221
        return EXIT_FAILURE;
237
        return EXIT_FAILURE;
222
    }
238
    }
223
    catch (boost::program_options::invalid_syntax e)
239
    catch (boost::program_options::invalid_syntax e)
224
    {
240
    {
225
        std::cerr << e.what() << std::endl;
241
        std::cerr << e.what() << std::endl;
226
        std::cout << command_line << std::endl;
242
        std::cout << command_line << std::endl;
227
        CleanUp();
243
        CleanUp();
228
        return EXIT_FAILURE;
244
        return EXIT_FAILURE;
229
    }
245
    }
230
   
246
   
231
    if (variable_map.count("help") != 0)
247
    if (variable_map.count("help") != 0)
232
    {
248
    {
233
        std::cout << command_line << std::endl;
249
        std::cout << command_line << std::endl;
234
        CleanUp();
250
        CleanUp();
235
        return EXIT_SUCCESS;
251
        return EXIT_SUCCESS;
236
    }
252
    }
237
   
253
   
238
    net::Manager::Create();
254
    net::Manager::Create();
239
 
255
 
240
    if (variable_map["command"].as<std::string>() == "")
256
    if (variable_map["command"].as<std::string>() == "")
241
    {
257
    {
242
        std::cout << "\033[29;1mAtom Interactive Console, version " + std::string(VERSION) + " starting...\033[0m" << std::endl;
258
        std::cout << "\033[29;1mAtom Interactive Console, version " + std::string(VERSION) + " starting...\033[0m" << std::endl;
243
        std::cout << "\033[29;1mReleased under GPL version 2.\033[0m" << std::endl;
259
        std::cout << "\033[29;1mReleased under GPL version 2.\033[0m" << std::endl;
244
        std::cout << "Written by Mattias Runge 2010." << std::endl;
260
        std::cout << "Written by Mattias Runge 2010." << std::endl;
245
       
261
       
246
        std::cout << "Connecting to " << variable_map["server"].as<std::string>().data() << ":" << variable_map["port"].as<unsigned int>() << "..." << std::endl;
262
        std::cout << "Connecting to " << variable_map["server"].as<std::string>().data() << ":" << variable_map["port"].as<unsigned int>() << "..." << std::endl;
247
    }
263
    }
248
   
264
   
249
    try
265
    try
250
    {
266
    {
251
        cc = ConsoleClient::Pointer(new ConsoleClient(variable_map["server"].as<std::string>(), variable_map["port"].as<unsigned int>()));
267
        cc = ConsoleClient::Pointer(new ConsoleClient(variable_map["server"].as<std::string>(), variable_map["port"].as<unsigned int>()));
252
    }
268
    }
253
    catch (std::runtime_error& e)
269
    catch (std::runtime_error& e)
254
    {
270
    {
255
        std::cerr << "Connection error: " << e.what() << std::endl;
271
        std::cerr << "Connection error: " << e.what() << std::endl;
256
        CleanUp();
272
        CleanUp();
257
        return EXIT_FAILURE;
273
        return EXIT_FAILURE;
258
    }
274
    }
259
   
275
   
260
    if (variable_map["command"].as<std::string>() != "")
276
    if (variable_map["command"].as<std::string>() != "")
261
    {
277
    {
262
        boost::mutex::scoped_lock guard(guard_mutex);
278
        boost::mutex::scoped_lock guard(guard_mutex);
263
        on_message_condition.wait(guard);
279
        on_message_condition.wait(guard);
264
       
280
       
265
        if (!finish)
281
        if (!finish)
266
        {
282
        {
267
            cc->SendResponse(variable_map["command"].as<std::string>());
283
            cc->SendResponse(variable_map["command"].as<std::string>());
268
           
284
           
269
            if (!finish)
285
            if (!finish)
270
            {
286
            {
271
                on_message_condition.wait(guard);
287
                on_message_condition.wait(guard);
272
            }
288
            }
273
        }
289
        }
274
    }
290
    }
275
    else
291
    else
276
    {
292
    {
277
        while (true)
293
        while (true)
278
        {
294
        {
279
            boost::mutex::scoped_lock guard(guard_mutex);
295
            boost::mutex::scoped_lock guard(guard_mutex);
280
            on_message_condition.wait(guard);
296
            on_message_condition.wait(guard);
281
           
297
           
282
            if (finish)
298
            if (finish)
283
            {
299
            {
284
                break;
300
                break;
285
            }
301
            }
286
           
302
           
287
            while ((buffer = readline(cc->GetPrompt().data())) != NULL)
303
            while ((buffer = readline(cc->GetPrompt().data())) != NULL)
288
            {
304
            {
289
                if (finish)
305
                if (finish)
290
                {
306
                {
291
                    break;
307
                    break;
292
                }
308
                }
293
               
309
               
294
                if (strlen(buffer) == 0)
310
                if (strlen(buffer) == 0)
295
                {
311
                {
296
                    continue;
312
                    continue;
297
                }
313
                }
298
               
314
               
299
                break;
315
                break;
300
            }
316
            }
301
           
317
           
302
            if (finish)
318
            if (finish)
303
            {
319
            {
304
                break;
320
                break;
305
            }
321
            }
306
           
322
           
307
            cc->SendResponse(buffer);
323
            cc->SendResponse(buffer);
308
            add_history(buffer);
324
            add_history(buffer);
309
        }
325
        }
310
    }
326
    }
311
   
327
   
312
    CleanUp();
328
    CleanUp();
313
   
329
   
314
    return EXIT_SUCCESS;
330
    return EXIT_SUCCESS;
315
}
331
}
316
 
332
 
317
static char** AutoComplete(const char* text, int start, int end)
333
static char** AutoComplete(const char* text, int start, int end)
318
{
334
{
319
    unsigned int count = 0;
335
    unsigned int count = 0;
320
    boost::mutex guard_mutex;
336
    boost::mutex guard_mutex;
321
 
337
 
322
    for (unsigned int n = 0; n < start; n++)
338
    for (unsigned int n = 0; n < start; n++)
323
    {
339
    {
324
        if (rl_line_buffer[n] == ' ')
340
        if (rl_line_buffer[n] == ' ')
325
        {
341
        {
326
            count++;
342
            count++;
327
        }
343
        }
328
    }
344
    }
329
   
345
   
330
    cc->AutoCompleteRequest(count, rl_line_buffer);
346
    cc->AutoCompleteRequest(count, rl_line_buffer);
331
   
347
   
332
    boost::mutex::scoped_lock guard(guard_mutex);
348
    boost::mutex::scoped_lock guard(guard_mutex);
333
    on_message_condition.wait(guard);
349
    on_message_condition.wait(guard);
334
   
350
   
335
    /*if (autocomplete_list.size() == 0)
351
    /*if (autocomplete_list.size() == 0)
336
    {
352
    {
337
        return NULL;
353
        return NULL;
338
    }*/
354
    }*/
339
   
355
   
340
    return rl_completion_matches(text, &AutoCompleteGet);
356
    return rl_completion_matches(text, &AutoCompleteGet);
341
}
357
}
342
 
358
 
343
char* AutoCompleteGet(const char* text, int state)
359
char* AutoCompleteGet(const char* text, int state)
344
{
360
{
345
    static int index = 0;
361
    static int index = 0;
346
    int length = strlen(text);
362
    int length = strlen(text);
347
    std::string name;
363
    std::string name;
348
   
364
   
349
    if (!state) // First run
365
    if (!state) // First run
350
    {
366
    {
351
        index = 0;
367
        index = 0;
352
    }
368
    }
353
   
369
   
354
    while (autocomplete_list.size() > index)
370
    while (autocomplete_list.size() > index)
355
    {
371
    {
356
        name = autocomplete_list[index];
372
        name = autocomplete_list[index];
357
       
373
       
358
        index++;
374
        index++;
359
       
375
       
360
        if (strncmp(name.data(), text, length) == 0)
376
        if (strncmp(name.data(), text, length) == 0)
361
        {
377
        {
362
            char *result = (char*)malloc(name.size() + 1);
378
            char *result = (char*)malloc(name.size() + 1);
363
            strcpy(result, name.data());
379
            strcpy(result, name.data());
364
           
380
           
365
            return result;
381
            return result;
366
        }
382
        }
367
    }
383
    }
368
   
384
   
369
    return NULL;
385
    return NULL;
370
}
386
}
371
 
387
 
372
void CleanUp()
388
void CleanUp()
373
{
389
{
374
    std::cout << std::endl;
390
    std::cout << std::endl;
375
    //std::cout << "Cleaning up..." << std::endl;
391
    //std::cout << "Cleaning up..." << std::endl;
376
 
392
 
377
    write_history(history_filename.data());
393
    write_history(history_filename.data());
378
   
394
   
379
    cc.reset();
395
    cc.reset();
380
   
396
   
381
    net::Manager::Delete();
397
    net::Manager::Delete();
382
   
398
   
383
    if (buffer != NULL)
399
    if (buffer != NULL)
384
    {
400
    {
385
        free(buffer);
401
        free(buffer);
386
    }
402
    }
387
   
403
   
388
    //std::cout << "Thank you for using Atom. Goodbye!" << std::endl;
404
    //std::cout << "Thank you for using Atom. Goodbye!" << std::endl;
389
   
405
   
390
    tcsetattr(fileno(stdin), TCSANOW, &original_flags); // Restore
406
    tcsetattr(fileno(stdin), TCSANOW, &original_flags); // Restore
391
}
407
}
392
 
408
 
393
void Handler(int status)
409
void Handler(int status)
394
{
410
{
395
    std::string signal_name = "Unknown";
411
    std::string signal_name = "Unknown";
396
   
412
   
397
    switch (status)
413
    switch (status)
398
    {
414
    {
399
        case SIGTERM:
415
        case SIGTERM:
400
        {
416
        {
401
            signal_name = "Terminate";
417
            signal_name = "Terminate";
402
            break;
418
            break;
403
        }  
419
        }  
404
        case SIGINT:
420
        case SIGINT:
405
        {
421
        {
406
            signal_name = "Interupt";
422
            signal_name = "Interupt";
407
            break;
423
            break;
408
        }  
424
        }  
409
        case SIGQUIT:
425
        case SIGQUIT:
410
        {
426
        {
411
            signal_name = "Quit";
427
            signal_name = "Quit";
412
            break;
428
            break;
413
        }  
429
        }  
414
        case SIGABRT:
430
        case SIGABRT:
415
        {
431
        {
416
            signal_name = "Abort";
432
            signal_name = "Abort";
417
            break;
433
            break;
418
        }  
434
        }  
419
        case SIGIO:
435
        case SIGIO:
420
        {
436
        {
421
            signal_name = "I/O";
437
            signal_name = "I/O";
422
            break;
438
            break;
423
        }  
439
        }  
424
        case SIGPIPE:
440
        case SIGPIPE:
425
        {
441
        {
426
            signal_name = "Pipe";
442
            signal_name = "Pipe";
427
            break;
443
            break;
428
        }
444
        }
429
    }
445
    }
430
   
446
   
431
   
447
   
432
    if (status != SIGPIPE)
448
    if (status != SIGPIPE)
433
    {
449
    {
434
        CleanUp();
450
        CleanUp();
435
        exit(0);
451
        exit(0);
436
    }
452
    }
437
}
453
}