apps/dtnperf/dtnperf-server.c
changeset 0 2b3e5ec03512
equal deleted inserted replaced
-1:000000000000 0:2b3e5ec03512
       
     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(&reginfo, 0, sizeof(reginfo));
       
   192 	dtn_copy_eid(&reginfo.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, &reginfo, &regid)) != 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(&current),
       
   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(&current), 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(&current));
       
   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(&current),
       
   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(&current), 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(&current));
       
   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