|
1 /* |
|
2 * Copyright 2005-2006 Intel Corporation |
|
3 * |
|
4 * Licensed under the Apache License, Version 2.0 (the "License"); |
|
5 * you may not use this file except in compliance with the License. |
|
6 * You may obtain a copy of the License at |
|
7 * |
|
8 * http://www.apache.org/licenses/LICENSE-2.0 |
|
9 * |
|
10 * Unless required by applicable law or agreed to in writing, software |
|
11 * distributed under the License is distributed on an "AS IS" BASIS, |
|
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
|
13 * See the License for the specific language governing permissions and |
|
14 * limitations under the License. |
|
15 */ |
|
16 |
|
17 |
|
18 |
|
19 /* ---------------------------------------- |
|
20 * DTNperf 2.5.1 - SERVER |
|
21 * |
|
22 * developed by |
|
23 * |
|
24 * Piero Cornice - piero.cornice(at)gmail.com |
|
25 * Marco Livini - marco.livini(at)gmail.com |
|
26 * |
|
27 * DEIS - Dipartimento di Elettronica, Informatica e Sistemistica |
|
28 * Universita' di Bologna |
|
29 * Italy |
|
30 * ---------------------------------------- |
|
31 */ |
|
32 |
|
33 |
|
34 |
|
35 #ifdef HAVE_CONFIG_H |
|
36 # include <dtn-config.h> |
|
37 #endif |
|
38 |
|
39 #include <stdio.h> |
|
40 #include <unistd.h> |
|
41 #include <errno.h> |
|
42 #include <strings.h> |
|
43 #include <string.h> |
|
44 #include <stdlib.h> |
|
45 #include <time.h> |
|
46 #include <getopt.h> |
|
47 #include <sys/stat.h> |
|
48 #include <sys/file.h> |
|
49 #include <dtn_api.h> |
|
50 |
|
51 |
|
52 |
|
53 #define TEMPSIZE 1024 |
|
54 #define BUFSIZE 16 |
|
55 #define BUNDLE_DIR_DEFAULT "/var/dtn/dtnperf" |
|
56 #define OUTFILE "dtnbuffer.rcv" |
|
57 #define MAXSIZE 256 |
|
58 |
|
59 |
|
60 /* ------------------------------ |
|
61 * Global variables and options |
|
62 * ------------------------------ */ |
|
63 |
|
64 // values between [square brackets] are default |
|
65 const char *progname ; |
|
66 int use_file = 1; // if set to 0, memorize received bundles into memory (max 50000 bytes) |
|
67 // if set to 1, memorize received bundles into a file (-f) [0] |
|
68 int verbose = 0; // if set to 1, show debug_level 0 messages [0] |
|
69 int aggregate = 0; // if > 0, print after aggregate arrivals |
|
70 int debug = 0; // if set to 1, show debug messages [1] |
|
71 int debug_level = 0; |
|
72 char * endpoint = "/dtnperf:/dest"; // endpoint (-e) ["/dtnperf:/dest"] |
|
73 char * bundle_dir = BUNDLE_DIR_DEFAULT; // destination directory (-d) |
|
74 |
|
75 /* ------------------------ |
|
76 * Function Prototypes |
|
77 * ------------------------ */ |
|
78 void print_usage(char*); |
|
79 void parse_options(int, char**); |
|
80 dtn_endpoint_id_t* parse_eid(dtn_handle_t, dtn_endpoint_id_t*, char*); |
|
81 int ContainsChar(char* string, char c); |
|
82 char* GetFileName(char* string, int position); |
|
83 long GetFileLen(char* string, int position); |
|
84 int move_file (char *fileIn, char *fileOut); |
|
85 |
|
86 |
|
87 /* ------------------------------------------------- |
|
88 * main |
|
89 * ------------------------------------------------- */ |
|
90 int main(int argc, char** argv) |
|
91 { |
|
92 |
|
93 /* ----------------------- |
|
94 * variables declaration |
|
95 * ----------------------- */ |
|
96 int k; |
|
97 int ret; |
|
98 dtn_handle_t handle; |
|
99 dtn_endpoint_id_t local_eid; |
|
100 dtn_reg_info_t reginfo; |
|
101 dtn_reg_id_t regid; |
|
102 dtn_bundle_spec_t spec; |
|
103 dtn_bundle_payload_t payload; |
|
104 char *buffer; // buffer used for shell commands |
|
105 char s_buffer[BUFSIZE]; |
|
106 time_t current; |
|
107 dtn_bundle_payload_location_t pl_type = DTN_PAYLOAD_FILE; // payload saved into memory or into file |
|
108 int source_eid_len, dest_eid_len; |
|
109 char *source_eid, *dest_eid; |
|
110 char * filepath; |
|
111 char * filename = OUTFILE; // source filename [OUTFILE] |
|
112 int bufsize; |
|
113 int count = 0; |
|
114 int total = 0; |
|
115 int receiving_file = -1; |
|
116 int destination_file = -1; |
|
117 char temp[TEMPSIZE]; |
|
118 char* receiving_fileName = NULL; |
|
119 long separator_position = 0; |
|
120 long receiving_fileLen = 0; |
|
121 long total_written = 0; |
|
122 long reads = 0; |
|
123 long written = 0; |
|
124 long total_saved = 0; |
|
125 |
|
126 |
|
127 /* ------- |
|
128 * begin |
|
129 * ------- */ |
|
130 |
|
131 // parse command-line options |
|
132 parse_options(argc, argv); |
|
133 if ((debug) && (debug_level > 0)) |
|
134 printf("[debug] parsed command-line options\n"); |
|
135 |
|
136 // show requested options (debug) |
|
137 if (debug) |
|
138 { |
|
139 printf("\nOptions:\n"); |
|
140 printf("\tendpoint : %s\n", endpoint); |
|
141 printf("\tsave bundles to: %s\n", use_file ? "file" : "memory"); |
|
142 printf("\tdestination dir: %s\n", bundle_dir); |
|
143 printf("\n"); |
|
144 } |
|
145 |
|
146 // initialize buffer with shell command ("mkdir -p " + bundle_dir) |
|
147 if ((debug) && (debug_level > 0)) |
|
148 printf("[debug] initializing buffer with shell command..."); |
|
149 buffer = malloc(sizeof(char) * (strlen(bundle_dir) + 10)); |
|
150 sprintf(buffer, "mkdir -p %s", bundle_dir); |
|
151 if ((debug) && (debug_level > 0)) |
|
152 printf(" done. Shell command = %s\n", buffer); |
|
153 |
|
154 // execute shell command |
|
155 if ((debug) && (debug_level > 0)) |
|
156 printf("[debug] executing shell command \"%s\"...", buffer); |
|
157 if (system(buffer) == -1) |
|
158 { |
|
159 fprintf(stderr, "Error opening bundle directory: %s\n", bundle_dir); |
|
160 exit(1); |
|
161 } |
|
162 free(buffer); |
|
163 if ((debug) && (debug_level > 0)) |
|
164 printf(" done\n"); |
|
165 |
|
166 // open the ipc handle |
|
167 if ((debug) && (debug_level > 0)) |
|
168 printf("[debug] opening connection to dtn router..."); |
|
169 int err = dtn_open(&handle); |
|
170 if (err != DTN_SUCCESS) |
|
171 { |
|
172 fprintf(stderr, "fatal error opening dtn handle: %s\n", |
|
173 dtn_strerror(err)); |
|
174 exit(1); |
|
175 } |
|
176 if ((debug) && (debug_level > 0)) |
|
177 printf(" done\n"); |
|
178 |
|
179 // build a local tuple based on the configuration of local dtn router |
|
180 if ((debug) && (debug_level > 0)) |
|
181 printf("[debug] building local eid..."); |
|
182 dtn_build_local_eid(handle, &local_eid, endpoint); |
|
183 if ((debug) && (debug_level > 0)) |
|
184 printf(" done\n"); |
|
185 if (debug) |
|
186 printf("local_eid = %s\n", local_eid.uri); |
|
187 |
|
188 // create a new registration based on this eid |
|
189 if ((debug) && (debug_level > 0)) |
|
190 printf("[debug] registering to local daemon..."); |
|
191 memset(®info, 0, sizeof(reginfo)); |
|
192 dtn_copy_eid(®info.endpoint, &local_eid); |
|
193 reginfo.flags = DTN_REG_DEFER; |
|
194 reginfo.regid = DTN_REGID_NONE; |
|
195 reginfo.expiration = 0; |
|
196 if ((ret = dtn_register(handle, ®info, ®id)) != 0) |
|
197 { |
|
198 fprintf(stderr, "error creating registration: %d (%s)\n", |
|
199 ret, dtn_strerror(dtn_errno(handle))); |
|
200 exit(1); |
|
201 } |
|
202 if ((debug) && (debug_level > 0)) |
|
203 printf(" done\n"); |
|
204 if (debug) |
|
205 printf("regid 0x%x\n", regid); |
|
206 |
|
207 // set bundle destination type |
|
208 if ((debug) && (debug_level > 0)) |
|
209 printf("[debug] choosing bundle destination type..."); |
|
210 if (use_file) |
|
211 pl_type = DTN_PAYLOAD_FILE; |
|
212 else |
|
213 pl_type = DTN_PAYLOAD_MEM; |
|
214 if ((debug) && (debug_level > 0)) |
|
215 printf(" done. Bundles will be saved into %s\n", use_file ? "file" : "memory"); |
|
216 |
|
217 if ((debug) && (debug_level > 0)) |
|
218 printf("[debug] entering infinite loop...\n"); |
|
219 |
|
220 // infinite loop, waiting for bundles |
|
221 while (1) |
|
222 { |
|
223 |
|
224 // wait until receive a bundle |
|
225 memset(&spec, 0, sizeof(spec)); |
|
226 memset(&payload, 0, sizeof(payload)); |
|
227 |
|
228 if ((debug) && (debug_level > 0)) |
|
229 printf("[debug] waiting for bundles..."); |
|
230 if ((ret = dtn_recv(handle, &spec, pl_type, &payload, -1)) < 0) |
|
231 { |
|
232 fprintf(stderr, "error getting recv reply: %d (%s)\n", |
|
233 ret, dtn_strerror(dtn_errno(handle))); |
|
234 exit(1); |
|
235 } |
|
236 if ((debug) && (debug_level > 0)) |
|
237 printf(" bundle received\n"); |
|
238 count++; |
|
239 |
|
240 size_t len; |
|
241 if (pl_type == DTN_PAYLOAD_MEM) |
|
242 { |
|
243 len = payload.buf.buf_len; |
|
244 } |
|
245 else |
|
246 { |
|
247 struct stat st; |
|
248 memset(&st, 0, sizeof(st)); |
|
249 stat(payload.filename.filename_val, &st); |
|
250 len = st.st_size; |
|
251 } |
|
252 |
|
253 total += len; |
|
254 // mark current time |
|
255 if ((debug) && (debug_level > 0)) |
|
256 printf("[debug] marking time..."); |
|
257 current = time(NULL); |
|
258 if ((debug) && (debug_level > 0)) |
|
259 printf(" done\n"); |
|
260 if (aggregate == 0) |
|
261 { |
|
262 printf("%s : %zu bytes from %s\n", |
|
263 ctime(¤t), |
|
264 len, |
|
265 spec.source.uri); |
|
266 } |
|
267 else if (count % aggregate == 0) |
|
268 { |
|
269 printf("%s : %d bundles, total length %d bytes\n", |
|
270 ctime(¤t), count, total); |
|
271 } |
|
272 |
|
273 /* --------------------------------------------------- |
|
274 * parse admin string to select file target location |
|
275 * --------------------------------------------------- */ |
|
276 |
|
277 // copy SOURCE eid |
|
278 if ((debug) && (debug_level > 0)) |
|
279 printf("[debug]\tcopying source eid..."); |
|
280 source_eid_len = sizeof(spec.source.uri); |
|
281 source_eid = malloc(sizeof(char) * source_eid_len + 1); |
|
282 memcpy(source_eid, spec.source.uri, source_eid_len); |
|
283 source_eid[source_eid_len] = '\0'; |
|
284 if ((debug) && (debug_level > 0)) |
|
285 { |
|
286 printf(" done:\n"); |
|
287 printf("\tsource_eid = %s\n", source_eid); |
|
288 printf("\n"); |
|
289 } |
|
290 |
|
291 // copy DEST eid |
|
292 if ((debug) && (debug_level > 0)) |
|
293 printf("[debug]\tcopying dest eid..."); |
|
294 dest_eid_len = sizeof(spec.dest.uri); |
|
295 dest_eid = malloc(sizeof(char) * dest_eid_len + 1); |
|
296 memcpy(dest_eid, spec.dest.uri, dest_eid_len); |
|
297 dest_eid[dest_eid_len] = '\0'; |
|
298 if ((debug) && (debug_level > 0)) |
|
299 { |
|
300 printf(" done:\n"); |
|
301 printf("\tdest_eid = %s\n", dest_eid); |
|
302 printf("\n"); |
|
303 } |
|
304 |
|
305 // recursively create full directory path |
|
306 filepath = malloc(sizeof(char) * dest_eid_len + 10); |
|
307 sprintf(filepath, "mkdir -p %s", bundle_dir); |
|
308 if ((debug) && (debug_level > 0)) |
|
309 printf("[debug] filepath = %s\n", filepath); |
|
310 system(filepath); |
|
311 |
|
312 // create file name |
|
313 sprintf(filepath, "%s/%s", bundle_dir, filename); |
|
314 if ((debug) && (debug_level > 0)) |
|
315 printf("[debug] filepath = %s\n", filepath); |
|
316 |
|
317 // bundle name is the name of the bundle payload file |
|
318 buffer = payload.buf.buf_val; |
|
319 bufsize = payload.buf.buf_len; |
|
320 |
|
321 if ((debug) && (debug_level > 0)) |
|
322 { |
|
323 printf ("======================================\n"); |
|
324 printf (" Bundle received at %s\n", ctime(¤t)); |
|
325 printf (" source: %s\n", spec.source.uri); |
|
326 if (use_file) |
|
327 { |
|
328 printf (" saved into : %s\n", filepath); |
|
329 } |
|
330 |
|
331 printf ("--------------------------------------\n"); |
|
332 } |
|
333 |
|
334 //receiving file |
|
335 if (TEMPSIZE >= len) |
|
336 { |
|
337 if (pl_type == DTN_PAYLOAD_FILE) |
|
338 { // if bundle was saved into file |
|
339 if ((receiving_file = open(payload.filename.filename_val, O_RDONLY)) < 0) |
|
340 { |
|
341 fprintf(stderr, "fatal error opening file %s\n", payload.filename.filename_val); |
|
342 exit(1); |
|
343 } |
|
344 } |
|
345 |
|
346 if (((pl_type == DTN_PAYLOAD_FILE) && (read(receiving_file, temp, len) > 0)) || (payload.buf.buf_len > 0)) |
|
347 { |
|
348 printf("&&(TEMPSIZE>=len)\n"); |
|
349 fflush(stdout); |
|
350 if (payload.buf.buf_len > 0) |
|
351 strcpy(temp, payload.buf.buf_val); |
|
352 |
|
353 if ((separator_position = ContainsChar(temp, '/')) > 0) |
|
354 { |
|
355 if ((debug) && (debug_level > 0)) |
|
356 printf("[debug] Getting the name of file to receive..."); |
|
357 receiving_fileName = GetFileName(temp, separator_position); |
|
358 if ((debug) && (debug_level > 0)) |
|
359 printf("done\n"); |
|
360 if ((debug) && (debug_level > 0)) |
|
361 printf("[debug] Getting the lenght of file to receive..."); |
|
362 receiving_fileLen = GetFileLen(temp, separator_position); |
|
363 if ((debug) && (debug_level > 0)) |
|
364 printf("done\n"); |
|
365 } |
|
366 } |
|
367 |
|
368 if (pl_type == DTN_PAYLOAD_FILE) |
|
369 { |
|
370 close(receiving_file); |
|
371 receiving_file = -1; |
|
372 } |
|
373 } |
|
374 |
|
375 if (pl_type == DTN_PAYLOAD_FILE) |
|
376 { // if bundle was saved into file |
|
377 |
|
378 if ((debug) && (debug_level > 0)) |
|
379 printf("[debug] renaming file %s -> %s...", |
|
380 payload.filename.filename_val, filepath); |
|
381 |
|
382 if (move_file(payload.filename.filename_val, filepath) != 0) |
|
383 { |
|
384 printf("[ERROR] Couldn't rename %s -> %s: %s\n", |
|
385 payload.filename.filename_val, filepath, strerror(errno)); |
|
386 } |
|
387 |
|
388 } |
|
389 else |
|
390 { // if bundle was saved into memory |
|
391 |
|
392 if ((debug) && (debug_level > 0)) |
|
393 { |
|
394 for (k = 0; k < (int)payload.buf.buf_len; k++) |
|
395 { |
|
396 if (buffer[k] >= ' ' && buffer[k] <= '~') |
|
397 s_buffer[k % BUFSIZE] = buffer[k]; |
|
398 else |
|
399 s_buffer[k % BUFSIZE] = '.'; |
|
400 |
|
401 if (k % BUFSIZE == 0) // new line every 16 bytes |
|
402 { |
|
403 printf("%07x ", k); |
|
404 } |
|
405 else if (k % 2 == 0) |
|
406 { |
|
407 printf(" "); // space every 2 bytes |
|
408 } |
|
409 |
|
410 printf("%02x", buffer[k] & 0xff); |
|
411 |
|
412 // print character summary (a la emacs hexl-mode) |
|
413 if (k % BUFSIZE == BUFSIZE - 1) |
|
414 { |
|
415 printf(" | %.*s\n", BUFSIZE, s_buffer); |
|
416 } |
|
417 } // for |
|
418 |
|
419 // print spaces to fill out the rest of the line |
|
420 if (k % BUFSIZE != BUFSIZE - 1) |
|
421 { |
|
422 while (k % BUFSIZE != BUFSIZE - 1) |
|
423 { |
|
424 if (k % 2 == 0) |
|
425 { |
|
426 printf(" "); |
|
427 } |
|
428 printf(" "); |
|
429 k++; |
|
430 } |
|
431 printf(" | %.*s\n", |
|
432 (int)payload.buf.buf_len % BUFSIZE, s_buffer); |
|
433 } // if |
|
434 |
|
435 printf ("======================================\n"); |
|
436 |
|
437 } // if (debug) |
|
438 |
|
439 free(filepath); |
|
440 free(source_eid); |
|
441 free(dest_eid); |
|
442 |
|
443 } |
|
444 |
|
445 fflush(stdout); |
|
446 |
|
447 //reciving file |
|
448 if (receiving_fileName != NULL) |
|
449 { |
|
450 printf("\nreceiving file %s - lenght %lu\n", receiving_fileName, receiving_fileLen); |
|
451 if (pl_type == DTN_PAYLOAD_FILE) |
|
452 close(receiving_file); |
|
453 receiving_file = -1; |
|
454 |
|
455 if ((destination_file = open(receiving_fileName, O_CREAT | O_TRUNC | O_WRONLY | O_APPEND, 0666)) < 0) |
|
456 { |
|
457 fprintf(stderr, "fatal error opening file %s\n", receiving_fileName); |
|
458 exit(1); |
|
459 } |
|
460 |
|
461 while (total_saved < receiving_fileLen) |
|
462 { |
|
463 |
|
464 // wait until receive a bundle |
|
465 memset(&spec, 0, sizeof(spec)); |
|
466 memset(&payload, 0, sizeof(payload)); |
|
467 |
|
468 if ((debug) && (debug_level > 0)) |
|
469 printf("[debug] waiting for bundles..."); |
|
470 if ((ret = dtn_recv(handle, &spec, pl_type, &payload, -1)) < 0) |
|
471 { |
|
472 fprintf(stderr, "error getting recv reply: %d (%s)\n", ret, dtn_strerror(dtn_errno(handle))); |
|
473 exit(1); |
|
474 } |
|
475 if ((debug) && (debug_level > 0)) |
|
476 printf(" bundle received\n"); |
|
477 count++; |
|
478 |
|
479 size_t len; |
|
480 if (pl_type == DTN_PAYLOAD_MEM) |
|
481 { |
|
482 len = payload.buf.buf_len; |
|
483 } |
|
484 else |
|
485 { |
|
486 struct stat st; |
|
487 memset(&st, 0, sizeof(st)); |
|
488 stat(payload.filename.filename_val, &st); |
|
489 len = st.st_size; |
|
490 } |
|
491 |
|
492 total += len; |
|
493 // mark current time |
|
494 if ((debug) && (debug_level > 0)) |
|
495 printf("[debug] marking time..."); |
|
496 current = time(NULL); |
|
497 if ((debug) && (debug_level > 0)) |
|
498 printf(" done\n"); |
|
499 if (aggregate == 0) |
|
500 { |
|
501 printf("%s : %zu bytes from %s\n", |
|
502 ctime(¤t), |
|
503 len, |
|
504 spec.source.uri); |
|
505 } |
|
506 else if (count % aggregate == 0) |
|
507 { |
|
508 printf("%s : %d bundles, total length %d bytes\n", |
|
509 ctime(¤t), count, total); |
|
510 } |
|
511 |
|
512 /* --------------------------------------------------- |
|
513 * parse admin string to select file target location |
|
514 * --------------------------------------------------- */ |
|
515 |
|
516 // copy SOURCE eid |
|
517 if ((debug) && (debug_level > 0)) |
|
518 printf("[debug]\tcopying source eid..."); |
|
519 source_eid_len = sizeof(spec.source.uri); |
|
520 source_eid = malloc(sizeof(char) * source_eid_len + 1); |
|
521 memcpy(source_eid, spec.source.uri, source_eid_len); |
|
522 source_eid[source_eid_len] = '\0'; |
|
523 |
|
524 if ((debug) && (debug_level > 0)) |
|
525 { |
|
526 printf(" done:\n"); |
|
527 printf("\tsource_eid = %s\n", source_eid); |
|
528 printf("\n"); |
|
529 } |
|
530 |
|
531 // copy DEST eid |
|
532 if ((debug) && (debug_level > 0)) |
|
533 printf("[debug]\tcopying dest eid..."); |
|
534 dest_eid_len = sizeof(spec.dest.uri); |
|
535 dest_eid = malloc(sizeof(char) * dest_eid_len + 1); |
|
536 memcpy(dest_eid, spec.dest.uri, dest_eid_len); |
|
537 dest_eid[dest_eid_len] = '\0'; |
|
538 if ((debug) && (debug_level > 0)) |
|
539 { |
|
540 printf(" done:\n"); |
|
541 printf("\tdest_eid = %s\n", dest_eid); |
|
542 printf("\n"); |
|
543 } |
|
544 |
|
545 // recursively create full directory path |
|
546 filepath = malloc(sizeof(char) * dest_eid_len + 10); |
|
547 sprintf(filepath, "mkdir -p %s", bundle_dir); |
|
548 if ((debug) && (debug_level > 0)) |
|
549 printf("[debug] filepath = %s\n", filepath); |
|
550 system(filepath); |
|
551 // create file name |
|
552 sprintf(filepath, "%s/%s", bundle_dir, filename); |
|
553 if ((debug) && (debug_level > 0)) |
|
554 printf("[debug] filepath = %s\n", filepath); |
|
555 // bundle name is the name of the bundle payload file |
|
556 buffer = payload.buf.buf_val; |
|
557 bufsize = payload.buf.buf_len; |
|
558 if ((debug) && (debug_level > 0)) |
|
559 { |
|
560 printf ("======================================\n"); |
|
561 printf (" Bundle received at %s\n", ctime(¤t)); |
|
562 printf (" source: %s\n", spec.source.uri); |
|
563 if (use_file) |
|
564 { |
|
565 printf (" saved into : %s\n", filepath); |
|
566 } |
|
567 printf ("--------------------------------------\n"); |
|
568 } |
|
569 |
|
570 if (pl_type == DTN_PAYLOAD_FILE) |
|
571 { // if bundle was saved into file |
|
572 if ((receiving_file = open(payload.filename.filename_val, O_RDONLY)) < 0) |
|
573 { |
|
574 fprintf(stderr, "fatal error opening file %s\n", payload.filename.filename_val); |
|
575 exit(1); |
|
576 } |
|
577 } |
|
578 |
|
579 |
|
580 if (pl_type == DTN_PAYLOAD_FILE) |
|
581 { |
|
582 while (total_written < (long)len) |
|
583 { |
|
584 reads = read(receiving_file, temp, 1024); |
|
585 written = write(destination_file, temp, reads); |
|
586 total_written += written; |
|
587 lseek(receiving_file, total_written, 0); |
|
588 } |
|
589 |
|
590 } |
|
591 else |
|
592 { |
|
593 while (total_written < (long)len) |
|
594 { |
|
595 written = write(destination_file, payload.buf.buf_val, payload.buf.buf_len ); |
|
596 total_written += written; |
|
597 } |
|
598 |
|
599 } |
|
600 |
|
601 total_saved += total_written; |
|
602 total_written = 0; |
|
603 |
|
604 printf("transfered %lu of %lu\n", total_saved, receiving_fileLen); |
|
605 |
|
606 if (pl_type == DTN_PAYLOAD_FILE) |
|
607 { // if bundle was saved into file |
|
608 if ((debug) && (debug_level > 0)) |
|
609 printf("[debug] renaming file %s -> %s...", payload.filename.filename_val, filepath); |
|
610 if (move_file(payload.filename.filename_val, filepath) != 0) |
|
611 { |
|
612 printf("[ERROR] Couldn't rename %s -> %s: %s\n", payload.filename.filename_val, filepath, strerror(errno)); |
|
613 } |
|
614 |
|
615 } |
|
616 else |
|
617 { // if bundle was saved into memory |
|
618 |
|
619 if ((debug) && (debug_level > 0)) |
|
620 { |
|
621 for (k = 0; k < (int)payload.buf.buf_len; k++) |
|
622 { |
|
623 if (buffer[k] >= ' ' && buffer[k] <= '~') |
|
624 s_buffer[k % BUFSIZE] = buffer[k]; |
|
625 else |
|
626 s_buffer[k % BUFSIZE] = '.'; |
|
627 |
|
628 if (k % BUFSIZE == 0) // new line every 16 bytes |
|
629 { |
|
630 printf("%07x ", k); |
|
631 } |
|
632 else if (k % 2 == 0) |
|
633 { |
|
634 printf(" "); // space every 2 bytes |
|
635 } |
|
636 |
|
637 printf("%02x", buffer[k] & 0xff); |
|
638 |
|
639 // print character summary (a la emacs hexl-mode) |
|
640 if (k % BUFSIZE == BUFSIZE - 1) |
|
641 { |
|
642 printf(" | %.*s\n", BUFSIZE, s_buffer); |
|
643 } |
|
644 } // for |
|
645 |
|
646 // print spaces to fill out the rest of the line |
|
647 if (k % BUFSIZE != BUFSIZE - 1) |
|
648 { |
|
649 while (k % BUFSIZE != BUFSIZE - 1) |
|
650 { |
|
651 if (k % 2 == 0) |
|
652 { |
|
653 printf(" "); |
|
654 } |
|
655 printf(" "); |
|
656 k++; |
|
657 } |
|
658 printf(" | %.*s\n", (int)payload.buf.buf_len % BUFSIZE, s_buffer); |
|
659 } // if |
|
660 |
|
661 printf ("======================================\n"); |
|
662 |
|
663 } // if (debug) |
|
664 |
|
665 free(filepath); |
|
666 free(source_eid); |
|
667 free(dest_eid); |
|
668 } |
|
669 close(receiving_file); |
|
670 fflush(stdout); |
|
671 } |
|
672 total_saved = 0; |
|
673 close(destination_file); |
|
674 receiving_file = -1; |
|
675 printf("completed tranfer of file %s\n\n", receiving_fileName); |
|
676 receiving_fileName = NULL; |
|
677 } //end receiving file |
|
678 |
|
679 } // while(1) |
|
680 |
|
681 // if this was ever changed to gracefully shutdown, it would be good to call: |
|
682 dtn_close(handle); |
|
683 |
|
684 return 0; |
|
685 |
|
686 } //main |
|
687 |
|
688 /* ------------------------------- |
|
689 * Utility Functions |
|
690 * ------------------------------- */ |
|
691 |
|
692 /* ------------- |
|
693 * print_usage |
|
694 * ------------- */ |
|
695 void print_usage(char* progname) |
|
696 { |
|
697 fprintf(stderr, "\n"); |
|
698 fprintf(stderr, "SYNTAX: %s [options]\n", progname); |
|
699 fprintf(stderr, "\n"); |
|
700 fprintf(stderr, "options:\n"); |
|
701 fprintf(stderr, " -d, --ddir <dir>\tDestination directory (if using -f), if dir is not indicated assume dir=%s.\n", BUNDLE_DIR_DEFAULT); |
|
702 fprintf(stderr, " -D, --debug <level>\tDebug messages [0-1], if level is not indicated assume level=0.\n"); |
|
703 fprintf(stderr, " -m, --memory\tSave received bundles into memory.\n"); |
|
704 fprintf(stderr, " -v verbose\tSame as -D 0.\n"); |
|
705 fprintf(stderr, " -a, --aggregate <n>\tPrint message every n arrivals.\n"); |
|
706 fprintf(stderr, " -h, --help\tHelp.\n"); |
|
707 fprintf(stderr, "\n"); |
|
708 exit(1); |
|
709 } |
|
710 |
|
711 /* --------------- |
|
712 * parse_options |
|
713 * --------------- */ |
|
714 void parse_options (int argc, char** argv) |
|
715 { |
|
716 char c, done = 0; |
|
717 |
|
718 while (!done) |
|
719 { |
|
720 |
|
721 static struct option long_options[] = |
|
722 { |
|
723 {"ddir", required_argument, 0, 'd' |
|
724 }, |
|
725 {"endpoint", required_argument, 0, 'e'}, |
|
726 {"memory", no_argument, 0, 'm'}, |
|
727 {"help", no_argument, 0, 'h'}, |
|
728 {"debug", required_argument, 0, 'D'}, |
|
729 {"aggregate", required_argument, 0, 'a'}, |
|
730 }; |
|
731 |
|
732 int option_index = 0; |
|
733 c = getopt_long(argc, argv, "hvD::fmd:e:a:", long_options, &option_index); |
|
734 |
|
735 switch (c) |
|
736 { |
|
737 case 'h': // show help |
|
738 print_usage(argv[0]); |
|
739 exit(1); |
|
740 return ; |
|
741 case 'v': // debug mode |
|
742 debug = 1; |
|
743 break; |
|
744 case 'D': // debug messages |
|
745 debug = 1; |
|
746 if (optarg != NULL) |
|
747 debug_level = atoi(optarg); |
|
748 break; |
|
749 case 'm': // save received bundles into memory |
|
750 use_file = 0; |
|
751 break; |
|
752 case 'd': // destination directory |
|
753 bundle_dir = optarg; |
|
754 break; |
|
755 |
|
756 case 'e': // destination endpoint |
|
757 endpoint = optarg; |
|
758 break; |
|
759 |
|
760 case 'a': // aggregate |
|
761 aggregate = atoi(optarg); |
|
762 break; |
|
763 |
|
764 case '?': |
|
765 break; |
|
766 |
|
767 case (char)(-1): |
|
768 done = 1; |
|
769 break; |
|
770 default: |
|
771 print_usage(argv[0]); |
|
772 exit(1); |
|
773 } |
|
774 } |
|
775 |
|
776 #define CHECK_SET(_arg, _what) \ |
|
777 if (_arg == 0) { \ |
|
778 fprintf(stderr, "\nSYNTAX ERROR: %s must be specified\n", _what); \ |
|
779 print_usage(argv[0]); \ |
|
780 exit(1); \ |
|
781 } |
|
782 |
|
783 } |
|
784 |
|
785 /* ---------------------------- |
|
786 * parse_tuple |
|
787 * ---------------------------- */ |
|
788 dtn_endpoint_id_t* parse_eid(dtn_handle_t handle, dtn_endpoint_id_t* eid, char * str) |
|
789 { |
|
790 // try the string as an actual dtn tuple |
|
791 if (!dtn_parse_eid_string(eid, str)) |
|
792 { |
|
793 return eid; |
|
794 } |
|
795 // build a local tuple based on the configuration of our dtn |
|
796 // router plus the str as demux string |
|
797 else if (!dtn_build_local_eid(handle, eid, str)) |
|
798 { |
|
799 if (debug) |
|
800 fprintf(stdout, "%s (local)\n", str); |
|
801 return eid; |
|
802 } |
|
803 else |
|
804 { |
|
805 fprintf(stderr, "invalid eid string '%s'\n", str); |
|
806 exit(1); |
|
807 } |
|
808 } // end parse_tuple |
|
809 |
|
810 |
|
811 int ContainsChar(char* string, char c) |
|
812 { |
|
813 int i; |
|
814 for (i = strlen(string); i >= 0; i--) |
|
815 { |
|
816 if (string[i] == c) |
|
817 return i; |
|
818 } |
|
819 return -1; |
|
820 } |
|
821 |
|
822 |
|
823 char* GetFileName(char* string, int position) |
|
824 { |
|
825 char temp[1024]; |
|
826 char* res; |
|
827 strcpy(temp, string); |
|
828 temp[position] = '\0'; |
|
829 res = strdup(temp); |
|
830 return res; |
|
831 } |
|
832 |
|
833 |
|
834 long GetFileLen(char* string, int position) |
|
835 { |
|
836 int i; |
|
837 char temp[1024]; |
|
838 strcpy(temp, string); |
|
839 for (i = (position + 1); i <= (int)(strlen(temp) + 1); i++) |
|
840 { |
|
841 temp[i - (position + 1)] = temp[i]; |
|
842 } |
|
843 return atol(temp); |
|
844 } |
|
845 |
|
846 |
|
847 |
|
848 /* -------------------------------------------------- |
|
849 * move_file |
|
850 * -------------------------------------------------- */ |
|
851 |
|
852 int move_file (char *fileIn, char *fileOut) { |
|
853 int rd, result, fdIn, fdOut; |
|
854 char buffer[MAXSIZE]; |
|
855 |
|
856 result = rename(fileIn, fileOut); |
|
857 |
|
858 if (result < 0 && errno == EXDEV) { |
|
859 |
|
860 if ((fdIn = open(fileIn, O_RDONLY)) < 0) { |
|
861 fprintf(stderr, "fatal error opening file %s\n", fileIn); |
|
862 exit(1); |
|
863 } |
|
864 |
|
865 if ((fdOut = open(fileOut, O_CREAT | O_TRUNC | O_WRONLY | O_APPEND, 0666)) < 0) { |
|
866 fprintf(stderr, "fatal error opening file %s\n", fileOut); |
|
867 exit(1); |
|
868 } |
|
869 |
|
870 rd = 0; |
|
871 |
|
872 while ((rd = read(fdIn, buffer, MAXSIZE)) > 0) { |
|
873 write(fdOut, buffer, rd); |
|
874 } |
|
875 |
|
876 close(fdIn); |
|
877 close(fdOut); |
|
878 |
|
879 if (remove(fileIn) < 0) |
|
880 fprintf(stderr, "fatal error deleting file %s\n", fileIn); |
|
881 |
|
882 return 0; |
|
883 } |
|
884 |
|
885 return result; |
|
886 |
|
887 } // end move_file |