IBR-DTNSuite
0.12
Main Page
Namespaces
Classes
Files
File List
File Members
dtninbox.cpp
Go to the documentation of this file.
1
/*
2
* dtninbox.cpp
3
*
4
* Copyright (C) 2011 IBR, TU Braunschweig
5
*
6
* Written-by: Johannes Morgenroth <morgenroth@ibr.cs.tu-bs.de>
7
*
8
* Licensed under the Apache License, Version 2.0 (the "License");
9
* you may not use this file except in compliance with the License.
10
* You may obtain a copy of the License at
11
*
12
* http://www.apache.org/licenses/LICENSE-2.0
13
*
14
* Unless required by applicable law or agreed to in writing, software
15
* distributed under the License is distributed on an "AS IS" BASIS,
16
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17
* See the License for the specific language governing permissions and
18
* limitations under the License.
19
*
20
*/
21
22
#include "
config.h
"
23
#include <
ibrdtn/api/Client.h
>
24
#include <
ibrcommon/net/socket.h
>
25
#include <
ibrcommon/thread/Mutex.h
>
26
#include <
ibrcommon/thread/MutexLock.h
>
27
#include <
ibrcommon/thread/SignalHandler.h
>
28
#include <
ibrdtn/data/PayloadBlock.h
>
29
#include <
ibrdtn/data/Bundle.h
>
30
#include <
ibrcommon/data/BLOB.h
>
31
#include <
ibrcommon/data/File.h
>
32
#include <
ibrcommon/appstreambuf.h
>
33
34
#include <stdlib.h>
35
#include <iostream>
36
#include <map>
37
#include <vector>
38
#include <sys/types.h>
39
#include <unistd.h>
40
#include <getopt.h>
41
42
#include "
io/TarUtils.h
"
43
44
//global conf values
45
string
_conf_name
;
46
string
_conf_inbox
;
47
48
//optional parameters
49
string
_conf_workdir
;
50
int
_conf_quiet
=
false
;
51
52
struct
option
long_options
[] =
53
{
54
{
"workdir"
, required_argument, 0,
'w'
},
55
{
"quiet"
, no_argument, 0,
'q'
},
56
{0, 0, 0, 0}
57
};
58
59
void
print_help
()
60
{
61
std::cout <<
"-- dtninbox (IBR-DTN) --"
<< std::endl;
62
std::cout <<
"Syntax: dtninbox [options] <name> <inbox>"
<< std::endl;
63
std::cout <<
" <name> The application name"
<< std::endl;
64
std::cout <<
" <inbox> Directory where incoming files should be placed"
<< std::endl << std::endl;
65
std::cout <<
"* optional parameters *"
<< std::endl;
66
std::cout <<
" -h|--help Display this text"
<< std::endl;
67
std::cout <<
" -w|--workdir Temporary work directory"
<< std::endl;
68
std::cout <<
" --quiet Only print error messages"
<< std::endl;
69
}
70
71
void
read_configuration
(
int
argc,
char
** argv)
72
{
73
// print help if not enough parameters are set
74
if
(argc < 3)
75
{
76
print_help
();
77
exit(EXIT_SUCCESS);
78
}
79
while
(1)
80
{
81
/* getopt_long stores the option index here. */
82
int
option_index = 0;
83
int
c = getopt_long (argc, argv,
"hw:q"
,
84
long_options
, &option_index);
85
/* Detect the end of the options. */
86
if
(c == -1)
87
break
;
88
89
switch
(c)
90
{
91
case
0:
92
/* If this option set a flag, do nothing else now. */
93
if
(
long_options
[option_index].flag != 0)
94
break
;
95
printf (
"option %s"
,
long_options
[option_index].name);
96
if
(optarg)
97
printf (
" with arg %s"
, optarg);
98
printf (
"\n"
);
99
break
;
100
101
case
'h'
:
102
print_help
();
103
exit(EXIT_SUCCESS);
104
break
;
105
case
'w'
:
106
_conf_workdir
= std::string(optarg);
107
break
;
108
default
:
109
abort();
110
break
;
111
}
112
}
113
114
_conf_name
= std::string(argv[optind]);
115
_conf_inbox
= std::string(argv[optind+1]);
116
}
117
118
119
120
// set this variable to false to stop the app
121
bool
_running
=
true
;
122
123
// global connection
124
ibrcommon::socketstream
*
_conn
= NULL;
125
126
void
term
(
int
signal)
127
{
128
if
(signal >= 1)
129
{
130
_running
=
false
;
131
if
(_conn != NULL) _conn->
close
();
132
}
133
}
134
135
/*
136
* main application method
137
*/
138
int
main
(
int
argc,
char
** argv)
139
{
140
// catch process signals
141
ibrcommon::SignalHandler
sighandler(
term
);
142
sighandler.
handle
(SIGINT);
143
sighandler.
handle
(SIGTERM);
144
145
// read the configuration
146
read_configuration
(argc, argv);
147
148
//initialize sighandler after possible exit call
149
sighandler.
initialize
();
150
151
if
(
_conf_workdir
.length() > 0)
152
{
153
ibrcommon::File
blob_path
(
_conf_workdir
);
154
155
if
(blob_path.
exists
())
156
{
157
ibrcommon::BLOB::changeProvider
(
new
ibrcommon::FileBLOBProvider
(blob_path),
true
);
158
}
159
}
160
161
// backoff for reconnect
162
unsigned
int
backoff = 2;
163
164
// loop, if no stop if requested
165
while
(
_running
)
166
{
167
try
{
168
// Create a stream to the server using TCP.
169
ibrcommon::vaddress
addr(
"localhost"
, 4550);
170
ibrcommon::socketstream
conn(
new
ibrcommon::tcpsocket
(addr));
171
172
// set the connection globally
173
_conn = &conn;
174
175
// Initiate a client for synchronous receiving
176
dtn::api::Client
client(
_conf_name
, conn);
177
178
// Connect to the server. Actually, this function initiate the
179
// stream protocol by starting the thread and sending the contact header.
180
client.
connect
();
181
182
// reset backoff if connected
183
backoff = 2;
184
185
// check the connection
186
while
(
_running
)
187
{
188
// receive the bundle
189
dtn::data::Bundle
b = client.
getBundle
();
190
if
(!
_conf_quiet
)
191
std::cout <<
"received bundle: "
<< b.
toString
() << std::endl;
192
193
// get the reference to the blob
194
ibrcommon::BLOB::Reference
ref = b.
find
<
dtn::data::PayloadBlock
>().getBLOB();
195
196
// write files into BLOB while it is locked
197
{
198
ibrcommon::BLOB::iostream
stream = ref.
iostream
();
199
io::TarUtils::read
(
_conf_inbox
, *stream);
200
}
201
}
202
203
// close the client connection
204
client.
close
();
205
206
// close the connection
207
conn.
close
();
208
209
// set the global connection to NULL
210
_conn = NULL;
211
}
catch
(
const
ibrcommon::socket_exception
&) {
212
// set the global connection to NULL
213
_conn = NULL;
214
215
if
(
_running
)
216
{
217
std::cout <<
"Connection to bundle daemon failed. Retry in "
<< backoff <<
" seconds."
<< std::endl;
218
ibrcommon::Thread::sleep
(backoff * 1000);
219
220
// if backoff < 10 minutes
221
if
(backoff < 600)
222
{
223
// set a new backoff
224
backoff = backoff * 2;
225
}
226
}
227
}
catch
(
const
ibrcommon::IOException
&) {
228
// set the global connection to NULL
229
_conn = NULL;
230
231
if
(
_running
)
232
{
233
std::cout <<
"Connection to bundle daemon failed. Retry in "
<< backoff <<
" seconds."
<< std::endl;
234
ibrcommon::Thread::sleep
(backoff * 1000);
235
236
// if backoff < 10 minutes
237
if
(backoff < 600)
238
{
239
// set a new backoff
240
backoff = backoff * 2;
241
}
242
}
243
}
catch
(
const
std::exception&) {
244
// set the global connection to NULL
245
_conn = NULL;
246
}
247
}
248
249
return
(EXIT_SUCCESS);
250
}
tools
src
dtninbox.cpp
Generated on Thu Mar 27 2014 09:26:21 for IBR-DTNSuite by
1.8.4