Patch to be applied to DTNRGs DTN2
authorAlex McMahon <alex.mcmahon@cs.tcd.ie>
Thu, 21 Apr 2011 15:49:00 +0000
changeset 0bbdee6d8b6dc
child 1 9d3b0f90208b
Patch to be applied to DTNRGs DTN2
(changeset 3509 Thu Apr 21 13:15:00 2011 +0000 )

for middleware used in N4C trials
n4c-dtn2-patch-1
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/n4c-dtn2-patch-1	Thu Apr 21 15:49:00 2011 +0000
     1.3 @@ -0,0 +1,4293 @@
     1.4 +# HG changeset patch
     1.5 +# User Alex McMahon <alex.mcmahon@cs.cs.tcd.ie>
     1.6 +# Date 1303399161 0
     1.7 +# Node ID 875893b4fede677fe2467a8ae2f9af0991b226b9
     1.8 +# Parent  b0407e525e083cb1ad66ff91c4562f71c689c3f8
     1.9 +N4C middleware. This patch applies middleware for N4C applications deployed
    1.10 +during the 2010 trial, IPC updates and LTPconvergence layer updates.
    1.11 +
    1.12 +diff -r b0407e525e08 -r 875893b4fede Makefile
    1.13 +--- a/Makefile	Thu Apr 21 13:15:00 2011 +0000
    1.14 ++++ b/Makefile	Thu Apr 21 15:19:21 2011 +0000
    1.15 +@@ -113,7 +113,9 @@
    1.16 + 		    apps/dtnsend/dtnsend \
    1.17 + 		    apps/dtntunnel/dtntunnel \
    1.18 + 		    apps/num2sdnv/num2sdnv \
    1.19 +-		    apps/num2sdnv/sdnv2num ; do \
    1.20 ++		    apps/num2sdnv/sdnv2num \
    1.21 ++		    apps/dtnN4Cmiddle/dtnN4Cmiddleware \
    1.22 ++		    apps/dtnN4Cmiddle/dtnN4Crecv ; do \
    1.23 + 	    ($(INSTALL_PROGRAM) $$prog $(DESTDIR)$(bindir)) ; \
    1.24 + 	done
    1.25 + 
    1.26 +diff -r b0407e525e08 -r 875893b4fede applib/dtn_ipc.h
    1.27 +--- a/applib/dtn_ipc.h	Thu Apr 21 13:15:00 2011 +0000
    1.28 ++++ b/applib/dtn_ipc.h	Thu Apr 21 15:19:21 2011 +0000
    1.29 +@@ -58,7 +58,7 @@
    1.30 +  * The maximum IPC message size (in bytes). Used primarily for
    1.31 +  * efficiency in buffer allocation since the transport uses TCP.
    1.32 +  */
    1.33 +-#define DTN_MAX_API_MSG 65536
    1.34 ++#define DTN_MAX_API_MSG (1024*1024)
    1.35 + 
    1.36 + /**
    1.37 +  * State of a DTN IPC channel.
    1.38 +diff -r b0407e525e08 -r 875893b4fede applib/dtn_types.h
    1.39 +--- a/applib/dtn_types.h	Thu Apr 21 13:15:00 2011 +0000
    1.40 ++++ b/applib/dtn_types.h	Thu Apr 21 15:19:21 2011 +0000
    1.41 +@@ -49,7 +49,7 @@
    1.42 + #define DTN_MAX_EXEC_LEN ARG_MAX /* length of string passed to exec() */
    1.43 + #define DTN_MAX_AUTHDATA 1024 /* length of auth/security data*/
    1.44 + #define DTN_MAX_REGION_LEN 64 /* 64 chars "should" be long enough */
    1.45 +-#define DTN_MAX_BUNDLE_MEM 50000 /* biggest in-memory bundle is ~50K*/
    1.46 ++#define DTN_MAX_BUNDLE_MEM 1000000 /* biggest in-memory bundle was ~50K, now (just for Phil:-) 1 million bytes*/
    1.47 + #define DTN_MAX_BLOCK_LEN 1024 /* length of block data (currently 1K) */
    1.48 + #define DTN_MAX_BLOCKS 256 /* number of blocks in bundle */
    1.49 + 
    1.50 +diff -r b0407e525e08 -r 875893b4fede applib/dtn_types.x
    1.51 +--- a/applib/dtn_types.x	Thu Apr 21 13:15:00 2011 +0000
    1.52 ++++ b/applib/dtn_types.x	Thu Apr 21 15:19:21 2011 +0000
    1.53 +@@ -40,7 +40,7 @@
    1.54 + %#define DTN_MAX_EXEC_LEN ARG_MAX	/* length of string passed to exec() */
    1.55 + %#define DTN_MAX_AUTHDATA 1024		/* length of auth/security data*/
    1.56 + %#define DTN_MAX_REGION_LEN 64		/* 64 chars "should" be long enough */
    1.57 +-%#define DTN_MAX_BUNDLE_MEM 50000	/* biggest in-memory bundle is ~50K*/
    1.58 ++%#define DTN_MAX_BUNDLE_MEM 1000000	/* biggest in-memory bundle was ~50K, now (just for Phil:-) 1 million bytes*/
    1.59 + %#define DTN_MAX_BLOCK_LEN 1024         /* length of block data (currently 1K) */
    1.60 + %#define DTN_MAX_BLOCKS 256             /* number of blocks in bundle */
    1.61 + 
    1.62 +diff -r b0407e525e08 -r 875893b4fede applib/dtn_types_xdr.c
    1.63 +--- a/applib/dtn_types_xdr.c	Thu Apr 21 13:15:00 2011 +0000
    1.64 ++++ b/applib/dtn_types_xdr.c	Thu Apr 21 15:19:21 2011 +0000
    1.65 +@@ -40,7 +40,7 @@
    1.66 + #define DTN_MAX_EXEC_LEN ARG_MAX /* length of string passed to exec() */
    1.67 + #define DTN_MAX_AUTHDATA 1024 /* length of auth/security data*/
    1.68 + #define DTN_MAX_REGION_LEN 64 /* 64 chars "should" be long enough */
    1.69 +-#define DTN_MAX_BUNDLE_MEM 50000 /* biggest in-memory bundle is ~50K*/
    1.70 ++#define DTN_MAX_BUNDLE_MEM 1000000 /* biggest in-memory bundle was ~50K, now (just for Phil:-) 1 million bytes*/
    1.71 + #define DTN_MAX_BLOCK_LEN 1024 /* length of block data (currently 1K) */
    1.72 + #define DTN_MAX_BLOCKS 256 /* number of blocks in bundle */
    1.73 + 
    1.74 +diff -r b0407e525e08 -r 875893b4fede apps/Makefile
    1.75 +--- a/apps/Makefile	Thu Apr 21 13:15:00 2011 +0000
    1.76 ++++ b/apps/Makefile	Thu Apr 21 15:19:21 2011 +0000
    1.77 +@@ -34,6 +34,8 @@
    1.78 + 	dtnrecv/dtnrecv			\
    1.79 + 	dtnsink/dtnsink			\
    1.80 + 	num2sdnv/num2sdnv		\
    1.81 ++	
    1.82 ++	#dtnN4Cmiddle/pushedContent  \
    1.83 + 
    1.84 + OTHER_APPS :=				\
    1.85 + 	dtnmoteproxy/dtnmoteproxy	\
    1.86 +@@ -44,6 +46,11 @@
    1.87 + 	dtnsend/dtnsend			\
    1.88 + 	dtnsource/dtnsource		\
    1.89 + 	num2sdnv/sdnv2num		\
    1.90 ++	dtnN4Cmiddle/dtnN4Cmiddleware	\
    1.91 ++	dtnN4Cmiddle/tN4C_bundle	\
    1.92 ++	dtnN4Cmiddle/dtnN4Crecv		\
    1.93 ++        
    1.94 ++ 
    1.95 + 
    1.96 + APPS := $(SINGLE_SOURCE_APPS) $(OTHER_APPS)
    1.97 + 
    1.98 +@@ -54,15 +61,15 @@
    1.99 + DTN_LIBS_STATIC := ../applib/libdtnapi.a ../applib/libdtnapi++.a
   1.100 + DTN_LIBS := ../applib/libdtnapi.a $(OASYS_COMPAT_LDFLAGS)
   1.101 + DTN_LIBS++ := $(DTN_LIBS) ../applib/libdtnapi++.a $(OASYS_LDFLAGS) $(EXTLIB_LDFLAGS)
   1.102 +-
   1.103 ++XML_LIBS := $(DTN_LIBS) -lcrypto -lxml2
   1.104 ++XML_FLAGS := -I/usr/include/libxml2 
   1.105 + # Fake build target in case the api lib doesn't exist, but allows us
   1.106 + # to include it as a dependency above so the apps get properly rebuilt
   1.107 + # for the 'all' target
   1.108 + $(DTN_LIBS_STATIC):
   1.109 + 	@echo "ERROR: $@ must be built before the apps can"
   1.110 + 	exit 1
   1.111 +-
   1.112 +-CFLAGS += -I$(SRCDIR)/applib
   1.113 ++CFLAGS += -I$(SRCDIR)/applib $(XML_FLAGS)
   1.114 + CXXFLAGS += -I$(SRCDIR)/applib
   1.115 + LDFLAGS += -L../applib
   1.116 + 
   1.117 +@@ -143,7 +150,30 @@
   1.118 + 	$(CXX) $(CXXFLAGS) $^ -o $@ $(LDFLAGS) $(DTN_LIBS++)
   1.119 + 
   1.120 + #
   1.121 ++#Rules for dtnN4Cmiddleware
   1.122 ++#
   1.123 ++#dtnN4Cmiddle/middle_api.o: dtnN4Cmiddle/middle_api.c
   1.124 ++#	$(CXX) $(CXXFLAGS) $< -o $@ $(LDFLAGS) $(DTN_LIBS)
   1.125 ++#	$(CC) $(CFLAGS) $(CFLAGS) -c $< -o $@
   1.126 ++dtnN4Cmiddle/middle_api.o: dtnN4Cmiddle/middle_api.c
   1.127 ++	$(CC) $(CFLAGS) $(CFLAGS) -c $< -o $@
   1.128 ++	
   1.129 ++dtnN4Cmiddle/dtnN4Cmiddleware: dtnN4Cmiddle/middle_api.o \
   1.130 ++				dtnN4Cmiddle/dtnN4Cmiddleware.o \
   1.131 ++				$(DTN_LIBS_STATIC)				
   1.132 ++	$(CC) $(CFLAGS) $^ -o $@ $(LDFLAGS) $(DTN_LIBS)
   1.133 ++	
   1.134 ++dtnN4Cmiddle/tN4C_bundle: dtnN4Cmiddle/middle_api.o dtnN4Cmiddle/tN4C_bundle.o $(DTN_LIBS_STATIC)				
   1.135 ++	$(CC) $(CFLAGS) $^ -o $@ $(LDFLAGS) $(DTN_LIBS)
   1.136 ++
   1.137 ++dtnN4Cmiddle/dtnN4Crecv: dtnN4Cmiddle/dtnN4Crecv.o dtnN4Cmiddle/pushedContent.o $(DTN_LIBS_STATIC)
   1.138 ++	$(CC) $(CFLAGS) $^ -o $@ $(LDFLAGS) $(XML_LIBS)
   1.139 ++
   1.140 ++#
   1.141 + # Default rule for all single source apps
   1.142 + #
   1.143 + $(SINGLE_SOURCE_APPS): %: %.o $(DTN_LIBS_STATIC)
   1.144 +-	$(CC) $(CFLAGS) $< -o $@ $(LDFLAGS) $(DTN_LIBS)
   1.145 ++	$(CC) $(CFLAGS) $< -o $@ $(LDFLAGS) $(DTN_LIBS) 
   1.146 ++	
   1.147 ++	
   1.148 ++	
   1.149 +diff -r b0407e525e08 -r 875893b4fede apps/dtnN4Cmiddle/N4Cmiddleware.cpp
   1.150 +--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   1.151 ++++ b/apps/dtnN4Cmiddle/N4Cmiddleware.cpp	Thu Apr 21 15:19:21 2011 +0000
   1.152 +@@ -0,0 +1,253 @@
   1.153 ++/*
   1.154 ++ *      N4Cmiddleware.cpp
   1.155 ++ *  
   1.156 ++ */
   1.157 ++
   1.158 ++
   1.159 ++/***********************************************************************
   1.160 ++ * HEADERS
   1.161 ++ * ********************************************************************/
   1.162 ++#include <iostream>
   1.163 ++
   1.164 ++#include <assert.h>
   1.165 ++#include <stdio.h>
   1.166 ++#include <unistd.h>
   1.167 ++#include <errno.h>
   1.168 ++#include <string.h>
   1.169 ++#include <strings.h>
   1.170 ++#include <stdlib.h>
   1.171 ++#include <sys/time.h>
   1.172 ++#include <time.h>
   1.173 ++
   1.174 ++#include <sys/types.h>
   1.175 ++
   1.176 ++//For the socket management
   1.177 ++#include <sys/socket.h>
   1.178 ++#include <arpa/inet.h>
   1.179 ++
   1.180 ++//DTN API
   1.181 ++#include "../../applib/dtn_api.h"
   1.182 ++
   1.183 ++/***********************************************************************
   1.184 ++ * Constant Definitions
   1.185 ++ * ********************************************************************/
   1.186 ++#define LST_PORT 			9090
   1.187 ++#define PENDING_CON_REQ		5				//Tipically for Unix Kernels
   1.188 ++#define RECV_BUFFER_SIZE	(512 + 4096)	//HTTP req max length (other fields + URL)
   1.189 ++#define EID_MAX_LENGTH		4096
   1.190 ++#define TRANS_ID_LENGTH		32
   1.191 ++#define URL_OFFSET			(TRANS_ID_LENGTH + 0 )
   1.192 ++
   1.193 ++
   1.194 ++/***********************************************************************
   1.195 ++ * Typedefs
   1.196 ++ * ********************************************************************/
   1.197 ++typedef struct parsed {
   1.198 ++	uint8_t outURL [EID_MAX_LENGTH];
   1.199 ++	uint16_t outURLlen;
   1.200 ++	uint8_t transID [TRANS_ID_LENGTH];
   1.201 ++} TParsed;
   1.202 ++
   1.203 ++typedef struct TCP_Test {
   1.204 ++	uint8_t HTTP_Response [EID_MAX_LENGTH];
   1.205 ++	uint16_t HTTP_ResponseLen;
   1.206 ++} T_TCP_Test;
   1.207 ++
   1.208 ++
   1.209 ++/******************************************
   1.210 ++ * Function prototipes
   1.211 ++ * ****************************************/
   1.212 ++int procHTTPreq (uint8_t * string, uint16_t len);
   1.213 ++TParsed parseURL(uint8_t * string, unsigned int len);
   1.214 ++dtn_endpoint_id_t * parse_eid(dtn_handle_t handle, dtn_endpoint_id_t * eid,
   1.215 ++                              char * str);
   1.216 ++T_TCP_Test parseTest (uint8_t * string, uint16_t len);
   1.217 ++
   1.218 ++
   1.219 ++/******************************************
   1.220 ++ * MAIN
   1.221 ++ * ****************************************/
   1.222 ++int main(int argc, char** argv)
   1.223 ++{
   1.224 ++	sockaddr_in serverAddr;		//Internet family socket to listen on
   1.225 ++	sockaddr & serverAddrCast = (sockaddr &) serverAddr;
   1.226 ++	int listenFd, connectFd;	//Socket file descriptors for listening and connecting
   1.227 ++	int recvByteLen;
   1.228 ++	char recvBuffer [RECV_BUFFER_SIZE];
   1.229 ++	
   1.230 ++	T_TCP_Test TCP_str;
   1.231 ++
   1.232 ++	
   1.233 ++	/* Create server socket*/
   1.234 ++	listenFd = socket (AF_INET, SOCK_STREAM, 0) ;	// get a tcp/ip socket
   1.235 ++	
   1.236 ++	/*Setup server socket*/
   1.237 ++	memset (&serverAddr , 0, sizeof (serverAddr) ) ;
   1.238 ++	
   1.239 ++	serverAddr.sin_family = AF_INET ;
   1.240 ++	serverAddr.sin_addr.s_addr = htonl(INADDR_ANY);	//any internet interface on this server
   1.241 ++	serverAddr.sin_port = htons (LST_PORT);			//Port to listen on
   1.242 ++	
   1.243 ++	bind(listenFd, &serverAddrCast, sizeof(serverAddr));
   1.244 ++	
   1.245 ++		
   1.246 ++	/*Listen on server socket*/
   1.247 ++	listen(listenFd, PENDING_CON_REQ);
   1.248 ++	
   1.249 ++	do {
   1.250 ++		//Since it gets NULL as input, no address is returned
   1.251 ++		connectFd = accept (listenFd, (sockaddr *) NULL, NULL);	
   1.252 ++		
   1.253 ++		recvByteLen = recv(connectFd, recvBuffer, RECV_BUFFER_SIZE, 0);
   1.254 ++
   1.255 ++		if (recvByteLen != -1)
   1.256 ++		{
   1.257 ++			/**
   1.258 ++			if(procHTTPreq((uint8_t *) recvBuffer, recvByteLen) != 0)
   1.259 ++				printf("\nError on procHTTPreq\n");
   1.260 ++			**/
   1.261 ++		
   1.262 ++			//TCP Test
   1.263 ++			 TCP_str = parseTest((uint8_t *) recvBuffer, recvByteLen);
   1.264 ++			 send(connectFd, TCP_str.HTTP_Response, TCP_str.HTTP_ResponseLen, 0);
   1.265 ++		}
   1.266 ++		shutdown (connectFd, 2);	//Closes send and recv from server
   1.267 ++		close (connectFd);			
   1.268 ++	} while (1);
   1.269 ++	
   1.270 ++	
   1.271 ++	/* Close server socket */ //Does it really need it? 
   1.272 ++	shutdown (listenFd, 2);
   1.273 ++	close (listenFd);
   1.274 ++	
   1.275 ++	return 0;
   1.276 ++}
   1.277 ++
   1.278 ++/***********************
   1.279 ++ * procHTTPreq
   1.280 ++ * */
   1.281 ++int procHTTPreq (uint8_t * string, uint16_t len)
   1.282 ++{
   1.283 ++	TParsed parData;
   1.284 ++	int err;
   1.285 ++	
   1.286 ++	//dtn handler
   1.287 ++	dtn_handle_t handle;
   1.288 ++	
   1.289 ++	//Bundle specs
   1.290 ++	dtn_bundle_spec_t bundle_spec;
   1.291 ++	char bndlDest [EID_MAX_LENGTH + 1] = "dtn://localhost/desttest";
   1.292 ++	char bndlSrc [EID_MAX_LENGTH + 1] = "dtn://localhost/src";
   1.293 ++	char bndlRply_to [EID_MAX_LENGTH + 1]  = "dtn://localhost/src";
   1.294 ++	//Bundle options
   1.295 ++	int expiration                 = 3600; // expiration timer (default one hour)
   1.296 ++	int delivery_options           = 0;    // bundle delivery option bit vector
   1.297 ++	dtn_bundle_priority_t priority = COS_NORMAL; // bundle priority 
   1.298 ++	//Bundle payload
   1.299 ++	dtn_bundle_payload_t payload;
   1.300 ++	//Bundle id
   1.301 ++	dtn_bundle_id_t bundle_id;
   1.302 ++	dtn_reg_id_t regid      = DTN_REGID_NONE;
   1.303 ++
   1.304 ++	//Initialize bndl pars
   1.305 ++	//To be done
   1.306 ++	
   1.307 ++	
   1.308 ++	/*Open a dtn connection*/
   1.309 ++	if((err = dtn_open(&handle)) != 0)
   1.310 ++		return err;
   1.311 ++
   1.312 ++	parData = parseURL(string, len);
   1.313 ++	/* *
   1.314 ++	 * Do whatever with the parsed info
   1.315 ++	 * */
   1.316 ++
   1.317 ++	/*Set up bundle*/
   1.318 ++	// initialize bundle spec
   1.319 ++	memset(&bundle_spec, 0, sizeof(bundle_spec));
   1.320 ++
   1.321 ++	// initialize/parse bundle src/dest/replyto eids
   1.322 ++	//if (verbose) fprintf(stdout, "Destination: %s\n", arg_dest);
   1.323 ++	parse_eid(handle, &bundle_spec.dest, bndlDest);
   1.324 ++
   1.325 ++	//if (verbose) fprintf(stdout, "Source: %s\n", arg_source);
   1.326 ++	parse_eid(handle, &bundle_spec.source, bndlSrc);
   1.327 ++				
   1.328 ++	parse_eid(handle, &bundle_spec.replyto, bndlRply_to);
   1.329 ++	
   1.330 ++	//Set the dtn options
   1.331 ++	bundle_spec.expiration = expiration;
   1.332 ++	bundle_spec.dopts      = delivery_options;
   1.333 ++	bundle_spec.priority   = priority;
   1.334 ++	
   1.335 ++	//Metadata/extension blocks not temporarily, might include request ID later
   1.336 ++	
   1.337 ++	/*Fill bundle payload (URL)*/
   1.338 ++	//check URL structure: does it include '\0'?
   1.339 ++	//It must include transID too
   1.340 ++	dtn_set_payload(&payload, DTN_PAYLOAD_MEM, (char *) parData.outURL, parData.outURLlen);	
   1.341 ++	
   1.342 ++	/*Send bundle*/
   1.343 ++	//might check return value
   1.344 ++	//if ((ret = dtn_send(handle, regid, &bundle_spec, &payload, &bundle_id)) != 0)
   1.345 ++	err = dtn_send(handle, regid, &bundle_spec, &payload, &bundle_id);
   1.346 ++	
   1.347 ++	dtn_close(handle);
   1.348 ++	
   1.349 ++	return err;	
   1.350 ++	
   1.351 ++}
   1.352 ++
   1.353 ++/*****************************
   1.354 ++ * parseURL
   1.355 ++ * */
   1.356 ++TParsed parseURL(uint8_t * string, unsigned int len)
   1.357 ++{
   1.358 ++	TParsed parsedBuff;
   1.359 ++	
   1.360 ++	memcpy (parsedBuff.transID, string, sizeof(uint8_t) * TRANS_ID_LENGTH);	
   1.361 ++	parsedBuff.outURLlen = len - TRANS_ID_LENGTH;
   1.362 ++	memcpy (parsedBuff.outURL, &(string[URL_OFFSET]), sizeof(uint8_t) * parsedBuff.outURLlen);
   1.363 ++	
   1.364 ++	return parsedBuff; //esto no deberia ser asi, dara problemas con los arrays
   1.365 ++}
   1.366 ++
   1.367 ++
   1.368 ++/****************************
   1.369 ++ * parse_eid
   1.370 ++ * */
   1.371 ++dtn_endpoint_id_t * parse_eid(dtn_handle_t handle, 
   1.372 ++                              dtn_endpoint_id_t* eid, char * str)
   1.373 ++{
   1.374 ++    // try the string as an actual dtn eid
   1.375 ++    if (!dtn_parse_eid_string(eid, str)) 
   1.376 ++    {
   1.377 ++        //if (verbose) fprintf(stdout, "%s (literal)\n", str);
   1.378 ++        return eid;
   1.379 ++    }
   1.380 ++    // build a local eid based on the configuration of our dtn
   1.381 ++    // router plus the str as demux string
   1.382 ++    else if (!dtn_build_local_eid(handle, eid, str))
   1.383 ++    {
   1.384 ++        //if (verbose) fprintf(stdout, "%s (local)\n", str);
   1.385 ++        return eid;
   1.386 ++    }
   1.387 ++    else
   1.388 ++    {
   1.389 ++        fprintf(stderr, "invalid eid string '%s'\n", str);
   1.390 ++        exit(1);
   1.391 ++    }
   1.392 ++}
   1.393 ++
   1.394 ++/***************************
   1.395 ++ * parseTest
   1.396 ++ * */
   1.397 ++T_TCP_Test parseTest (uint8_t * string, uint16_t len)
   1.398 ++{
   1.399 ++	T_TCP_Test parData;
   1.400 ++	
   1.401 ++	memcpy(parData.HTTP_Response, string, len);
   1.402 ++	parData.HTTP_ResponseLen = len;
   1.403 ++	
   1.404 ++	return parData;
   1.405 ++}
   1.406 +diff -r b0407e525e08 -r 875893b4fede apps/dtnN4Cmiddle/README.pushedcontent
   1.407 +--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   1.408 ++++ b/apps/dtnN4Cmiddle/README.pushedcontent	Thu Apr 21 15:19:21 2011 +0000
   1.409 +@@ -0,0 +1,72 @@
   1.410 ++
   1.411 ++HOWTO test and then setup pushed content ala N4C
   1.412 ++
   1.413 ++Contact: alex.mcmahon@cs.tcd.ie, stephen.farrell@cs.tcd.ie
   1.414 ++
   1.415 ++Caveat: 
   1.416 ++
   1.417 ++This is all very, very, very hacky stuff which is the
   1.418 ++result of two last-minutes rushes. So sorry, and YMMV;-)
   1.419 ++
   1.420 ++Unit testing:
   1.421 ++
   1.422 ++- turn on testing: make sure UNITEST is #define'd in dtnN4Csettings.h and
   1.423 ++  make the ROOTDIR point somewhere you'd like (and can access), I'm 
   1.424 ++  using $HOME/pushed/test/ for that 
   1.425 ++- go there and make directiories below that:
   1.426 ++	cd $ROOTDIR
   1.427 ++	mkdir  public 
   1.428 ++	mkdir  public/pushedContent
   1.429 ++- make that last one a mercurial repo using hg init
   1.430 ++	cd public/pushedContent; hg init
   1.431 ++- ensure your http_proxy settings are ok so that wget works
   1.432 ++- create public/pushedContent/destination_uris - a file with one destination EID per line
   1.433 ++  and nothing else, assume for now that we'll receive as dtn://tester.dtn/rx
   1.434 ++  and dtn://tester.dtn/rx1 and that that's the content of this file, that's
   1.435 ++  below if you look
   1.436 ++- copy or link DTN2-N4C/apps/dtnN4Cmiddle/generatePushedContent.sh to 
   1.437 ++  $ROOTDIR (copy is probably better)
   1.438 ++- make sure your dtnd is running and choose EIDs that'll work, assume
   1.439 ++  for now that we'll send from dtn://tester.dtn/tx, there's a dtn.conf
   1.440 ++  that does that at the end of this, don't forget to iniitalise the
   1.441 ++  dtnd dn, I'm using $HOME/pushed/test for that directory
   1.442 ++- generate and send some pushed content:
   1.443 ++	.../DTN2-N4C/apps/dtnN4Cmiddle/dtnN4Crecv -m send dtn://tester.dtn/tx
   1.444 ++- that does a whole bunch of wget stuff (depending on what's in your
   1.445 ++  generatePushedContent.sh script) and then sends bundles
   1.446 ++- copy apache_cfg.sh to your test dir and edit to taste - it'll be
   1.447 ++  called at the end of the rx process
   1.448 ++- on the receive side, run 
   1.449 ++	.../DTN2-N4C/apps/dtnN4Cmiddle/dtnN4Crecv -m recv dtn://tester.dtn/rx
   1.450 ++
   1.451 ++
   1.452 ++
   1.453 ++#########################################
   1.454 ++# dtn.conf for the above setup
   1.455 ++
   1.456 ++log /dtnd info "dtnd parsing configuration..."
   1.457 ++# console set addr 127.0.0.1
   1.458 ++console set addr 0.0.0.0
   1.459 ++console set port 5050
   1.460 ++api set local_addr 0.0.0.0
   1.461 ++api set local_port 5010
   1.462 ++set shorthostname "tester"
   1.463 ++console set prompt "tester dtn% "
   1.464 ++storage set type berkeleydb
   1.465 ++set dbdir "/home/stephen/pushed/test/"
   1.466 ++storage set payloaddir $dbdir/bundles
   1.467 ++storage set dbname     DTN
   1.468 ++storage set dbdir      $dbdir/db
   1.469 ++route set type static
   1.470 ++interface add tcp_in tcp local_addr=localhost local_port=2113
   1.471 ++link add tcp_out localhost:2114 ONDEMAND tcp 
   1.472 ++route add dtn://* tcp_out
   1.473 ++route local_eid "dtn://tester.dtn"
   1.474 ++log /dtnd info "dtnd configuration parsing complete"
   1.475 ++
   1.476 ++#########################################
   1.477 ++# destination_uris
   1.478 ++
   1.479 ++dtn://tester.dtn/rx
   1.480 ++dtn://tester.dtn/rx2
   1.481 ++
   1.482 +diff -r b0407e525e08 -r 875893b4fede apps/dtnN4Cmiddle/TCP_test.cpp
   1.483 +--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   1.484 ++++ b/apps/dtnN4Cmiddle/TCP_test.cpp	Thu Apr 21 15:19:21 2011 +0000
   1.485 +@@ -0,0 +1,73 @@
   1.486 ++/*
   1.487 ++ *      TCP_test.cpp
   1.488 ++ *      
   1.489 ++ *      Nelson Dopico <nelson@wsn-laptop>
   1.490 ++ *      
   1.491 ++ */
   1.492 ++
   1.493 ++
   1.494 ++#include <iostream>
   1.495 ++
   1.496 ++#include <stdio.h>
   1.497 ++
   1.498 ++#include <string.h>
   1.499 ++#include <sys/types.h>
   1.500 ++
   1.501 ++#include <netdb.h>
   1.502 ++
   1.503 ++//For the socket management
   1.504 ++#include <sys/socket.h>
   1.505 ++#include <arpa/inet.h>
   1.506 ++
   1.507 ++
   1.508 ++#define RECV_BUFFER_SIZE	(512 + 4096)	//HTTP req max length (other fields + URL)
   1.509 ++
   1.510 ++int main(int argc, char** argv)
   1.511 ++{
   1.512 ++	
   1.513 ++	sockaddr_in server_addr;		//Internet family socket to listen on
   1.514 ++	sockaddr * serverAddrCast = (sockaddr *) & server_addr;
   1.515 ++	int sockFd;	//Socket file descriptor for sending and receiving
   1.516 ++	int recvByteLen;
   1.517 ++	char recvBuffer [RECV_BUFFER_SIZE];
   1.518 ++	
   1.519 ++	struct hostent *server;
   1.520 ++	
   1.521 ++	//char serverName [] = "127.0.0.1";
   1.522 ++	
   1.523 ++	char strSent [] = "Hello world, just testing a socket";
   1.524 ++	
   1.525 ++
   1.526 ++	
   1.527 ++	/* Create socket*/
   1.528 ++	sockFd = socket (AF_INET, SOCK_STREAM, 0) ;	// get a tcp/ip socket
   1.529 ++	
   1.530 ++	memset (&server_addr , 0, sizeof (server_addr) ) ;
   1.531 ++	server = gethostbyname("localhost");
   1.532 ++	memcpy (&(server_addr.sin_addr.s_addr), server->h_addr, server->h_length);
   1.533 ++	
   1.534 ++	server_addr.sin_family = AF_INET ;
   1.535 ++
   1.536 ++	server_addr.sin_port = htons (9090);
   1.537 ++	
   1.538 ++	printf("DEBUG - Hello world 1st\n");
   1.539 ++	
   1.540 ++	if(connect (sockFd, (struct sockaddr *) serverAddrCast, sizeof(server_addr)) != 0)
   1.541 ++		perror("DEBUG - Error on connect\n");
   1.542 ++	
   1.543 ++	printf("DEBUG - Hello world 2nd\n");
   1.544 ++	
   1.545 ++	if(send(sockFd, strSent, strlen(strSent) + 1, 0) == -1)
   1.546 ++		printf("DEBUG - Error on send\n");
   1.547 ++	
   1.548 ++	printf("DEBUG - Hello world 3rd\n");
   1.549 ++			
   1.550 ++	recvByteLen = recv(sockFd, recvBuffer, RECV_BUFFER_SIZE, 0);
   1.551 ++	
   1.552 ++	if(strcmp(strSent, recvBuffer) == 0)
   1.553 ++		printf("DEBUG - Sent and received Strings are the same\n");
   1.554 ++	
   1.555 ++	printf("DEBUG - Hello world\n");	
   1.556 ++	
   1.557 ++	return 0;
   1.558 ++}
   1.559 +diff -r b0407e525e08 -r 875893b4fede apps/dtnN4Cmiddle/apache_cfg.sh
   1.560 +--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   1.561 ++++ b/apps/dtnN4Cmiddle/apache_cfg.sh	Thu Apr 21 15:19:21 2011 +0000
   1.562 +@@ -0,0 +1,67 @@
   1.563 ++# (re-)Configure apache with latest pushed content from dtnN4recv
   1.564 ++#
   1.565 ++# input is DocRoot directory
   1.566 ++#
   1.567 ++# web sites are in $DocRoot/today/N4Csites
   1.568 ++
   1.569 ++# either two inputs or none, I'm in a hurry:-)
   1.570 ++
   1.571 ++# set -x
   1.572 ++
   1.573 ++if [ "$1" != "" ]
   1.574 ++then
   1.575 ++	DOCROOT=$1
   1.576 ++else
   1.577 ++	DOCROOT="/data/www/public/drPushedContent"
   1.578 ++fi
   1.579 ++if [ "$2" != "" ]
   1.580 ++then
   1.581 ++	OUTPUT=$2
   1.582 ++else
   1.583 ++	OUTPUT="/etc/apache2/sites-available/n4csites.conf"
   1.584 ++	# OUTPUT=n4csites.conf
   1.585 ++fi
   1.586 ++# use this to test if we're really gonna restart apache
   1.587 ++LIVEOUTPUT="/etc/apache2/sites-available/n4csites.conf"
   1.588 ++LIVEOUTPUTENAB="/etc/apache2/sites-enabled/n4csites.conf"
   1.589 ++
   1.590 ++sites=`ls $DOCROOT/today/N4Csites`
   1.591 ++
   1.592 ++cat >$OUTPUT <<EOF
   1.593 ++# Automatically generated by N4C pushed content, don't edit
   1.594 ++# Ensure that Apache listens on port 80, and optionally 443
   1.595 ++
   1.596 ++MimeMagicFile /etc/apache2/magic
   1.597 ++
   1.598 ++EOF
   1.599 ++VIP=`ifconfig | grep 10.125.15 | awk -F":" '{print $2}' | awk '{print $1}'`
   1.600 ++echo $VIP
   1.601 ++
   1.602 ++for site in $sites 
   1.603 ++do
   1.604 ++	echo "<VirtualHost $VIP:80>" >>$OUTPUT
   1.605 ++	echo "DocumentRoot " $DOCROOT"/today/N4Csites/"$site >> $OUTPUT 
   1.606 ++	echo "ServerName " $site >> $OUTPUT
   1.607 ++	echo "</VirtualHost>" >>$OUTPUT 
   1.608 ++	echo "" >>$OUTPUT
   1.609 ++	echo "<IfModule mod_ssl.c>" >>$OUTPUT
   1.610 ++	echo "<VirtualHost $VIP:443>" >>$OUTPUT
   1.611 ++	echo "DocumentRoot " $DOCROOT"/today/N4Csites/"$site >> $OUTPUT 
   1.612 ++	echo "ServerName " $site >> $OUTPUT
   1.613 ++	echo "</VirtualHost>" >>$OUTPUT 
   1.614 ++	echo "</IfModule>" >>$OUTPUT 
   1.615 ++	echo "" >>$OUTPUT
   1.616 ++
   1.617 ++done
   1.618 ++
   1.619 ++# now add the link and restart apache (but only if output is in /etc/apache2)
   1.620 ++if [ "$OUTPUT" != "$LIVEOUTPUT" ]
   1.621 ++then
   1.622 ++	echo "done"
   1.623 ++else
   1.624 ++	if [ ! -f "$LIVEOUTPUTENAB" ]
   1.625 ++	then
   1.626 ++		ln -s $OUTPUT $LIVEOUTPUTENAB
   1.627 ++	fi
   1.628 ++	/etc/init.d/apache2 restart
   1.629 ++fi
   1.630 +diff -r b0407e525e08 -r 875893b4fede apps/dtnN4Cmiddle/dtnN4Cmiddleware
   1.631 +Binary file apps/dtnN4Cmiddle/dtnN4Cmiddleware has changed
   1.632 +diff -r b0407e525e08 -r 875893b4fede apps/dtnN4Cmiddle/dtnN4Cmiddleware.c
   1.633 +--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   1.634 ++++ b/apps/dtnN4Cmiddle/dtnN4Cmiddleware.c	Thu Apr 21 15:19:21 2011 +0000
   1.635 +@@ -0,0 +1,142 @@
   1.636 ++/*
   1.637 ++ *      N4Cmiddleware.cpp
   1.638 ++ *  
   1.639 ++ */
   1.640 ++
   1.641 ++
   1.642 ++/***********************************************************************
   1.643 ++ * HEADERS
   1.644 ++ ***********************************************************************/
   1.645 ++#include <assert.h>
   1.646 ++#include <stdio.h>
   1.647 ++#include <unistd.h>
   1.648 ++#include <errno.h>
   1.649 ++#include <string.h>
   1.650 ++#include <strings.h>
   1.651 ++#include <stdlib.h>
   1.652 ++#include <sys/time.h>
   1.653 ++#include <sys/types.h>
   1.654 ++#include <time.h>
   1.655 ++
   1.656 ++//For the socket management
   1.657 ++#include <sys/socket.h>
   1.658 ++#include <arpa/inet.h>
   1.659 ++
   1.660 ++//DTN API
   1.661 ++//#include "../../applib/dtn_api.h"
   1.662 ++//#include "dtn_api.h"
   1.663 ++#include "middle_api.h"
   1.664 ++ 
   1.665 ++
   1.666 ++void validateArgs(int argc, char* argv[]); 
   1.667 ++
   1.668 ++/******************************************
   1.669 ++* MAIN
   1.670 ++******************************************/
   1.671 ++int main(int argc, char** argv)
   1.672 ++{
   1.673 ++    char *progName = strrchr( argv[0], '/' ) + 1; //extract program name from file path
   1.674 ++	char *bndlDest;     //arg[1]
   1.675 ++	char *bndlSrc;      //arg[2]
   1.676 ++	char *bndlRply_to;  //arg[3]
   1.677 ++
   1.678 ++	struct sockaddr_in serverAddr;		//Internet family socket to listen on
   1.679 ++	struct sockaddr * serverAddrCast = (struct sockaddr *) & serverAddr;
   1.680 ++	int listenFd, connectFd;	        //Socket file descriptors for listening and connecting
   1.681 ++	int recvByteLen;
   1.682 ++	int err = 0;
   1.683 ++	char recvBuffer [RECV_BUFFER_SIZE];
   1.684 ++	
   1.685 ++	openlog( progName, LOG_CONS, LOG_USER );
   1.686 ++	
   1.687 ++	validateArgs(argc, argv);	
   1.688 ++	
   1.689 ++    // extract args        
   1.690 ++    bndlDest = argv[1];     // Arg 1 is bundle destination EID
   1.691 ++    bndlSrc = argv[2];      // Arg 2 is bundle source EID
   1.692 ++    bndlRply_to = argv[3];  // Arg 2 is bundle reply to EID
   1.693 ++    
   1.694 ++	T_TCP_Test TCP_str;    
   1.695 ++	
   1.696 ++	/* Create server socket*/
   1.697 ++	listenFd = socket (AF_INET, SOCK_STREAM, 0);	// get a tcp/ip socket
   1.698 ++	syslog ( LOG_INFO, "Created tcp/ip socket" );
   1.699 ++	
   1.700 ++	/*Setup server socket*/
   1.701 ++	memset (&serverAddr , 0, sizeof (serverAddr) );
   1.702 ++	
   1.703 ++	serverAddr.sin_family = AF_INET ;
   1.704 ++	serverAddr.sin_addr.s_addr = htonl(INADDR_ANY);	//any internet interface on this server
   1.705 ++	serverAddr.sin_port = htons (LST_PORT);			//Port to listen on
   1.706 ++	
   1.707 ++	bind(listenFd, serverAddrCast, sizeof(serverAddr));	
   1.708 ++		
   1.709 ++	/*Listen on server socket*/
   1.710 ++	listen(listenFd, PENDING_CON_REQ);
   1.711 ++	syslog ( LOG_INFO, "Listening on socket port: %d", LST_PORT );
   1.712 ++	
   1.713 ++	do {
   1.714 ++		//Since it gets NULL as input, no address is returned
   1.715 ++		connectFd = accept (listenFd, (struct sockaddr *) NULL, NULL);	
   1.716 ++		
   1.717 ++		recvByteLen = recv(connectFd, recvBuffer, RECV_BUFFER_SIZE, 0);
   1.718 ++
   1.719 ++		if (recvByteLen > TRANS_ID_LENGTH)
   1.720 ++		{			
   1.721 ++    		syslog ( LOG_INFO, "%d bytes received on port %d", recvByteLen, LST_PORT );
   1.722 ++    		syslog ( LOG_INFO, "[%s] received on port %d", recvBuffer, LST_PORT );    		
   1.723 ++    		
   1.724 ++			if( (err = procHTTPreq(bndlDest, bndlSrc, bndlRply_to, (uint8_t *) recvBuffer, recvByteLen)) == 0)
   1.725 ++			    syslog ( LOG_INFO, "Success executing procHTTPreq" );				
   1.726 ++			else
   1.727 ++			    syslog ( LOG_ERR, "Error executing procHTTPreq (error code: %d)", err );			    
   1.728 ++			
   1.729 ++            //TCP Test
   1.730 ++//          TCP_str = parseTest((uint8_t *) recvBuffer, recvByteLen);
   1.731 ++//          send(connectFd, TCP_str.HTTP_Response, TCP_str.HTTP_ResponseLen, 0);
   1.732 ++		}
   1.733 ++		
   1.734 ++		shutdown (connectFd, 2);	//Closes send and recv from server
   1.735 ++		close (connectFd);			
   1.736 ++	} while (1);
   1.737 ++	
   1.738 ++	
   1.739 ++	/* Close server socket */ //Does it really need it? 
   1.740 ++	shutdown (listenFd, 2);
   1.741 ++	close (listenFd);
   1.742 ++	
   1.743 ++	return 0;
   1.744 ++}
   1.745 ++
   1.746 ++void validateArgs(int argc, char* argv[])
   1.747 ++{
   1.748 ++    int i;
   1.749 ++    
   1.750 ++    if ( argc != 4 )        // 4 args inc program name
   1.751 ++    {                                    
   1.752 ++        syslog (LOG_ERR, "Program started with incorrect args. Usage: %s bndlDest bndlSrc bndlRply_to", argv[0]);
   1.753 ++        exit(1);
   1.754 ++    }
   1.755 ++
   1.756 ++    for(i=0; i<argc; i++)   // ensure args are not null
   1.757 ++    {
   1.758 ++        if(argv[i] == NULL)
   1.759 ++        {                                       
   1.760 ++            syslog (LOG_ERR, "Program started with incorrect arg %d. Usage: %s bndlDest bndlSrc bndlRply_to", i, argv[0]);         
   1.761 ++            exit(1);
   1.762 ++        }
   1.763 ++    }
   1.764 ++    
   1.765 ++    for(i=1; i<argc; i++)   // ensure eid args are not too long
   1.766 ++    {
   1.767 ++        if(strlen(argv[i]) > EID_MAX_LENGTH)
   1.768 ++        {                                       
   1.769 ++            syslog (LOG_ERR, "Error length of arg %d '%s' was %d which exceeds the max EID length %d", i, argv[i], strlen(argv[i]), EID_MAX_LENGTH);  
   1.770 ++            exit(1);
   1.771 ++        }
   1.772 ++    }
   1.773 ++    
   1.774 ++    syslog (LOG_INFO, "Program started correctly with args: progName=%s, bndlDest=%s, bndlSrc=%s, bndlRply=%s", 
   1.775 ++        argv[0], argv[1], argv[2], argv[3]);
   1.776 ++}
   1.777 ++
   1.778 +diff -r b0407e525e08 -r 875893b4fede apps/dtnN4Cmiddle/dtnN4Crecv
   1.779 +Binary file apps/dtnN4Cmiddle/dtnN4Crecv has changed
   1.780 +diff -r b0407e525e08 -r 875893b4fede apps/dtnN4Cmiddle/dtnN4Crecv.c
   1.781 +--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   1.782 ++++ b/apps/dtnN4Cmiddle/dtnN4Crecv.c	Thu Apr 21 15:19:21 2011 +0000
   1.783 +@@ -0,0 +1,967 @@
   1.784 ++/*
   1.785 ++ *    Copyright 2004-2006 Intel Corporation
   1.786 ++ * 
   1.787 ++ *    Licensed under the Apache License, Version 2.0 (the "License");
   1.788 ++ *    you may not use this file except in compliance with the License.
   1.789 ++ *    You may obtain a copy of the License at
   1.790 ++ * 
   1.791 ++ *        http://www.apache.org/licenses/LICENSE-2.0
   1.792 ++ * 
   1.793 ++ *    Unless required by applicable law or agreed to in writing, software
   1.794 ++ *    distributed under the License is distributed on an "AS IS" BASIS,
   1.795 ++ *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   1.796 ++ *    See the License for the specific language governing permissions and
   1.797 ++ *    limitations under the License.
   1.798 ++ */
   1.799 ++
   1.800 ++#ifdef HAVE_CONFIG_H
   1.801 ++#  include <dtn-config.h>
   1.802 ++#endif
   1.803 ++
   1.804 ++#include <stdio.h>
   1.805 ++#include <unistd.h>
   1.806 ++#include <errno.h>
   1.807 ++#include <strings.h>
   1.808 ++#include <string.h>
   1.809 ++#include <stdlib.h>
   1.810 ++#include <sys/time.h>
   1.811 ++#include <sys/stat.h>
   1.812 ++#include <fcntl.h>
   1.813 ++#include "dtn_api.h"    
   1.814 ++#include "dtnN4Csettings.h"
   1.815 ++#include "pushedContent.h"
   1.816 ++
   1.817 ++#define BUFSIZE 16
   1.818 ++#define BLOCKSIZE 8192
   1.819 ++#define COUNTER_MAX_DIGITS 9
   1.820 ++
   1.821 ++// Find the maximum commandline length
   1.822 ++#ifdef __FreeBSD__
   1.823 ++/* Needed for PATH_MAX, Linux doesn't need it */
   1.824 ++#include <sys/syslimits.h>
   1.825 ++#endif
   1.826 ++
   1.827 ++#ifndef PATH_MAX
   1.828 ++/* A conservative fallback */
   1.829 ++#define PATH_MAX 1024
   1.830 ++#endif
   1.831 ++
   1.832 ++#define PUSHED_CONTENT_SEND 1
   1.833 ++#define PUSHED_CONTENT_RECV 2
   1.834 ++
   1.835 ++const char *progname;
   1.836 ++
   1.837 ++int   verbose           = 0;    	    // verbose output
   1.838 ++int   quiet             = 0;    	    // quiet output
   1.839 ++char* endpoint		    = NULL; 	    // endpoint for registration
   1.840 ++dtn_reg_id_t regid	    = DTN_REGID_NONE;// registration id
   1.841 ++int   expiration	    = 30; 		    // registration expiration time
   1.842 ++int   count             = 0;            // exit after count bundles received
   1.843 ++int   failure_action	= DTN_REG_DEFER;// registration delivery failure action
   1.844 ++char* failure_script	= "";	 	    // script to exec
   1.845 ++int   register_only	    = 0;    	    // register and quit
   1.846 ++int   change		    = 0;    	    // change existing registration 
   1.847 ++int   unregister	    = 0;    	    // remove existing registration 
   1.848 ++int   recv_timeout	    = -1;    	    // timeout to dtn_recv call
   1.849 ++int   sr                = 0;            // status report original bundle creation/seq
   1.850 ++int   id                = 0;            // Ouput transaction ID and URL request
   1.851 ++int   po                = 0;            // Ouput packaged website under transaction ID
   1.852 ++int   no_find_reg	    = 0;    	    // omit call to dtn_find_registration
   1.853 ++int   push_content      = 0;            // pushed content send or receive
   1.854 ++char filename[PATH_MAX];		        // Destination filename for file xfers
   1.855 ++dtn_bundle_payload_location_t bundletype = DTN_PAYLOAD_MEM;
   1.856 ++void
   1.857 ++usage()
   1.858 ++{
   1.859 ++    fprintf(stderr, "usage: %s [opts] <endpoint> \n", progname);
   1.860 ++    fprintf(stderr, "options:\n");
   1.861 ++    fprintf(stderr, " -v verbose\n");
   1.862 ++    fprintf(stderr, " -q quiet\n");
   1.863 ++    fprintf(stderr, " -h help\n");
   1.864 ++    fprintf(stderr, " -d <eid|demux_string> endpoint id\n");
   1.865 ++    fprintf(stderr, " -r <regid> use existing registration regid\n");
   1.866 ++    fprintf(stderr, " -n <count> exit after count bundles received\n");
   1.867 ++    fprintf(stderr, " -e <time> registration expiration time in seconds "
   1.868 ++            "(default: one hour)\n");
   1.869 ++    fprintf(stderr, " -f <defer|drop|exec> failure action\n");
   1.870 ++    fprintf(stderr, " -F <script> failure script for exec action\n");
   1.871 ++    fprintf(stderr, " -x call dtn_register and immediately exit\n");
   1.872 ++    fprintf(stderr, " -c call dtn_change_registration and immediately exit\n");
   1.873 ++    fprintf(stderr, " -u call dtn_unregister and immediately exit\n");
   1.874 ++    fprintf(stderr, " -N don't try to find an existing registration\n");
   1.875 ++    fprintf(stderr, " -t <timeout> timeout value for call to dtn_recv\n");
   1.876 ++    fprintf(stderr, " -o <template> Write out transfers to files using this template (# chars are\n"
   1.877 ++            "replaced with a counter). Example: f##.bin goes to f00.bin, f01.bin, etc...\n");
   1.878 ++    fprintf(stderr, " -p <template> Write out transfers to files using this template (# chars are\n"
   1.879 ++            "replaced with a counter). Example: f##.bin goes to f00.bin, f01.bin, etc.. Ouput packaged website under transaction ID\n");
   1.880 ++    fprintf(stderr, " -s output status report original bundle creation.seq\n");
   1.881 ++    fprintf(stderr, " -S Ouput transaction ID and URL request\n");
   1.882 ++    fprintf(stderr, " -m <send|recv> pushed content send | receive");
   1.883 ++}
   1.884 ++
   1.885 ++void
   1.886 ++parse_options(int argc, char**argv)
   1.887 ++{
   1.888 ++    int c, done = 0;
   1.889 ++
   1.890 ++    progname = argv[0];
   1.891 ++
   1.892 ++    memset(filename, 0, sizeof(char) * PATH_MAX);
   1.893 ++
   1.894 ++    while (!done)
   1.895 ++    {
   1.896 ++        c = getopt(argc, argv, "vqhHd:r:e:f:F:xn:cuNt:o:p:s:Sm:");
   1.897 ++        switch (c)
   1.898 ++        {
   1.899 ++        case 'v':
   1.900 ++            verbose = 1;
   1.901 ++            break;
   1.902 ++        case 'q':
   1.903 ++            quiet = 1;
   1.904 ++            break;
   1.905 ++        case 'h':
   1.906 ++        case 'H':
   1.907 ++            usage();
   1.908 ++            exit(0);
   1.909 ++            return;
   1.910 ++        case 'r':
   1.911 ++            regid = atoi(optarg);
   1.912 ++            break;
   1.913 ++        case 'e':
   1.914 ++            expiration = atoi(optarg);
   1.915 ++            break;
   1.916 ++        case 'f':
   1.917 ++            if (!strcasecmp(optarg, "defer")) {
   1.918 ++                failure_action = DTN_REG_DEFER;
   1.919 ++
   1.920 ++            } else if (!strcasecmp(optarg, "drop")) {
   1.921 ++                failure_action = DTN_REG_DROP;
   1.922 ++
   1.923 ++            } else if (!strcasecmp(optarg, "exec")) {
   1.924 ++                failure_action = DTN_REG_EXEC;
   1.925 ++
   1.926 ++            } else {
   1.927 ++                fprintf(stderr, "invalid failure action '%s'\n", optarg);
   1.928 ++                usage();
   1.929 ++                exit(1);
   1.930 ++            }
   1.931 ++        case 'F':
   1.932 ++            failure_script = optarg;
   1.933 ++            break;
   1.934 ++        case 'x':
   1.935 ++            register_only = 1;
   1.936 ++            break;
   1.937 ++        case 'n':
   1.938 ++            count = atoi(optarg);
   1.939 ++            break;
   1.940 ++        case 'c':
   1.941 ++            change = 1;
   1.942 ++            break;
   1.943 ++        case 'u':
   1.944 ++            unregister = 1;
   1.945 ++            break;
   1.946 ++        case 'N':
   1.947 ++            no_find_reg = 1;
   1.948 ++            break;
   1.949 ++        case 't':
   1.950 ++            recv_timeout = atoi(optarg);
   1.951 ++            break;
   1.952 ++        case 'o':
   1.953 ++            strncpy(filename, optarg, PATH_MAX);
   1.954 ++            break;
   1.955 ++        case 'p':
   1.956 ++            strncpy(filename, optarg, PATH_MAX);
   1.957 ++            po = 1;
   1.958 ++            break;
   1.959 ++        case 's':
   1.960 ++            sr = 1;
   1.961 ++            break;
   1.962 ++        case 'S':
   1.963 ++            id = 1;
   1.964 ++            break;
   1.965 ++        case 'm':
   1.966 ++            if (!strcasecmp(optarg, "send")) {
   1.967 ++                push_content = PUSHED_CONTENT_SEND;
   1.968 ++            
   1.969 ++            } else if (!strcasecmp(optarg, "recv")){
   1.970 ++                push_content = PUSHED_CONTENT_RECV;
   1.971 ++            
   1.972 ++            } else {
   1.973 ++                fprintf(stderr, "invalid pushed content action '%s'\n", optarg);
   1.974 ++                usage();
   1.975 ++                exit(1);
   1.976 ++            }
   1.977 ++            break;
   1.978 ++
   1.979 ++        case -1:
   1.980 ++            done = 1;
   1.981 ++            break;
   1.982 ++        default:
   1.983 ++            // getopt already prints an error message for unknown
   1.984 ++            // option characters
   1.985 ++            usage();
   1.986 ++            exit(1);
   1.987 ++        }
   1.988 ++    }
   1.989 ++
   1.990 ++    endpoint = argv[optind];
   1.991 ++    if (!endpoint && (regid == DTN_REGID_NONE)) {
   1.992 ++        fprintf(stderr, "must specify either an endpoint or a regid\n");
   1.993 ++        usage();
   1.994 ++        exit(1);
   1.995 ++    }
   1.996 ++
   1.997 ++    if ((change || unregister) && (regid == DTN_REGID_NONE)) {
   1.998 ++        fprintf(stderr, "must specify regid when using -%c option\n",
   1.999 ++                change ? 'c' : 'u');
  1.1000 ++        usage();
  1.1001 ++        exit(1);
  1.1002 ++    }
  1.1003 ++
  1.1004 ++    if (failure_action == DTN_REG_EXEC && failure_script == NULL) {
  1.1005 ++        fprintf(stderr, "failure action EXEC must supply script\n");
  1.1006 ++        usage();
  1.1007 ++        exit(1);
  1.1008 ++    }
  1.1009 ++
  1.1010 ++    // the default is to use memory transfer mode, but if someone specifies a
  1.1011 ++    // filename then we need to tell the API to expect a file
  1.1012 ++    if ( filename[0] != '\0' )
  1.1013 ++        bundletype = DTN_PAYLOAD_FILE;
  1.1014 ++
  1.1015 ++    return;
  1.1016 ++}
  1.1017 ++
  1.1018 ++
  1.1019 ++static void
  1.1020 ++print_data(char* buffer, u_int length)
  1.1021 ++{
  1.1022 ++    u_int k;
  1.1023 ++    char s_buffer[BUFSIZE];
  1.1024 ++    for (k=0; k < length; k++)
  1.1025 ++    {
  1.1026 ++        if (buffer[k] >= ' ' && buffer[k] <= '~')
  1.1027 ++            s_buffer[k%BUFSIZE] = buffer[k];
  1.1028 ++        else
  1.1029 ++            s_buffer[k%BUFSIZE] = '.';
  1.1030 ++
  1.1031 ++        if (k%BUFSIZE == 0) // new line every 16 bytes
  1.1032 ++            printf("%07x ", k);
  1.1033 ++        else if (k%2 == 0)
  1.1034 ++            printf(" "); // space every 2 bytes
  1.1035 ++                    
  1.1036 ++        printf("%02x", buffer[k] & 0xff);
  1.1037 ++                    
  1.1038 ++        // print character summary (a la emacs hexl-mode)
  1.1039 ++        if (k%BUFSIZE == BUFSIZE-1)
  1.1040 ++            printf(" |  %.*s\n", BUFSIZE, s_buffer);
  1.1041 ++    }
  1.1042 ++    
  1.1043 ++    // handle leftovers
  1.1044 ++    if ((length % BUFSIZE) != 0) 
  1.1045 ++    {
  1.1046 ++        while (k%BUFSIZE != BUFSIZE-1) 
  1.1047 ++        {
  1.1048 ++            if (k%2 == 0) 
  1.1049 ++                printf(" ");
  1.1050 ++            printf("  ");
  1.1051 ++            k++;
  1.1052 ++        }
  1.1053 ++        printf("   |  %.*s\n", (int)length%BUFSIZE, s_buffer);
  1.1054 ++    }
  1.1055 ++    printf("\n");
  1.1056 ++    return;
  1.1057 ++}
  1.1058 ++
  1.1059 ++void
  1.1060 ++print_req_ID(char* buffer, char *b)
  1.1061 ++{
  1.1062 ++    u_int j;
  1.1063 ++    char j_buffer[BUFSIZE];
  1.1064 ++    char req_ID[31];
  1.1065 ++    *b = 0;
  1.1066 ++    for (j=0; j < 32; j++)
  1.1067 ++    {
  1.1068 ++        if (buffer[j] >= ' ' && buffer[j] <= '~')
  1.1069 ++            j_buffer[j%BUFSIZE] = buffer[j];        
  1.1070 ++        else
  1.1071 ++            j_buffer[j%BUFSIZE] = '.';
  1.1072 ++            
  1.1073 ++            
  1.1074 ++        if (j%BUFSIZE == BUFSIZE-1)
  1.1075 ++        {
  1.1076 ++            snprintf (req_ID, 31, "%.*s", BUFSIZE, j_buffer);
  1.1077 ++            strncat(b, req_ID, 31);
  1.1078 ++        }
  1.1079 ++    }
  1.1080 ++    return;
  1.1081 ++}
  1.1082 ++/*
  1.1083 ++void
  1.1084 ++parse_meta_req_ID(char *buffer, char *d)
  1.1085 ++{
  1.1086 ++    u_int l;
  1.1087 ++    char l_buffer[BUFSIZE];
  1.1088 ++    char meta_req_ID[31];
  1.1089 ++    *d = 0;
  1.1090 ++
  1.1091 ++//        printf("\n%d metadata blocks from [%s]: transit time=%d ms filename %s.tar.gz\n",
  1.1092 ++//               spec.metadata.metadata_len, spec.source.uri, 0, spec.metadata.metadata_val);
  1.1093 ++//        dtn_extension_block_t *meta = spec.metadata.metadata_val;
  1.1094 ++
  1.1095 ++        for (l=0; l < 32; l++) 
  1.1096 ++        {
  1.1097 ++             if (buffer[l] >= ' ' && buffer[l] <= '~'){
  1.1098 ++            l_buffer[l%BUFSIZE] = buffer[l];
  1.1099 ++        }
  1.1100 ++        else
  1.1101 ++            l_buffer[l%BUFSIZE] = '.';
  1.1102 ++        if (l%BUFSIZE == BUFSIZE-1)
  1.1103 ++        {
  1.1104 ++
  1.1105 ++        sprintf (meta_req_ID, "%.*s", BUFSIZE, l_buffer);
  1.1106 ++        strncat(d,meta_req_ID,31);
  1.1107 ++
  1.1108 ++ //           printf("Metadata Extension Block %i:\n", k);
  1.1109 ++  //          printf("\ttype = %i\n\tflags = %i\n",
  1.1110 ++             //      meta[k].type, meta[k].flags);
  1.1111 ++//            print_data(meta[k].data.data_val, meta[k].data.data_len);
  1.1112 ++        }
  1.1113 ++}
  1.1114 ++*/
  1.1115 ++void
  1.1116 ++print_reqval(char* buffer, u_int length, char *val)
  1.1117 ++{
  1.1118 ++    u_int i;
  1.1119 ++    char i_buffer[BUFSIZE];
  1.1120 ++    char reqval[length-32];
  1.1121 ++    *val=0;
  1.1122 ++    for (i=32; i < length; i++)
  1.1123 ++    {
  1.1124 ++        if (buffer[i] >= ' ' && buffer[i] <= '~')
  1.1125 ++            i_buffer[i%BUFSIZE] = buffer[i];
  1.1126 ++        else
  1.1127 ++            i_buffer[i%BUFSIZE] = '.';
  1.1128 ++
  1.1129 ++        if (i%BUFSIZE == BUFSIZE-1)
  1.1130 ++        {
  1.1131 ++            //ret = sprintf (req_ID_buf, " %.*s", BUFSIZE, i_buffer);
  1.1132 ++            sprintf (reqval, "%.*s", BUFSIZE, i_buffer);
  1.1133 ++            strncat(val,reqval,length-32);
  1.1134 ++        }
  1.1135 ++    }
  1.1136 ++
  1.1137 ++    if ((length % BUFSIZE) != 0) 
  1.1138 ++    {
  1.1139 ++        sprintf (reqval, "%.*s", (int)length%BUFSIZE, i_buffer);
  1.1140 ++        strncat(val,reqval,length-32);
  1.1141 ++    }
  1.1142 ++    return;
  1.1143 ++}
  1.1144 ++
  1.1145 ++
  1.1146 ++/* ----------------------------------------------------------------------- */
  1.1147 ++/* Builds the temporary file based on the template given and an integer
  1.1148 ++ * counter value
  1.1149 ++ */
  1.1150 ++int buildfilename(char* template, char* newfilename, int counter )
  1.1151 ++{
  1.1152 ++    char counterasstring[COUNTER_MAX_DIGITS];
  1.1153 ++    char formatstring[10];
  1.1154 ++    char* startloc;
  1.1155 ++    char* endloc;
  1.1156 ++    int templatelen;
  1.1157 ++
  1.1158 ++    strcpy(newfilename, template);
  1.1159 ++
  1.1160 ++    endloc = rindex(newfilename, '#');
  1.1161 ++    /* No template in the filename, just copy it as is */
  1.1162 ++    if ( endloc == NULL )
  1.1163 ++        return 0;
  1.1164 ++        
  1.1165 ++    /* Search backwards for the start of the template */
  1.1166 ++    for ( startloc = endloc; *startloc == '#' && startloc != template; startloc -= 1 );
  1.1167 ++
  1.1168 ++    startloc += 1;
  1.1169 ++
  1.1170 ++    templatelen = endloc - startloc + 1;
  1.1171 ++    if ( templatelen > COUNTER_MAX_DIGITS )
  1.1172 ++        templatelen = COUNTER_MAX_DIGITS;
  1.1173 ++
  1.1174 ++    sprintf(formatstring, "%%0%dd", templatelen);
  1.1175 ++    sprintf(counterasstring, formatstring, counter);
  1.1176 ++
  1.1177 ++    if ( strlen(counterasstring) > (unsigned int)templatelen )
  1.1178 ++        fprintf(stderr, "Warning: Filename template not large enough "
  1.1179 ++                "to support counter value %d\n", counter);
  1.1180 ++
  1.1181 ++    memcpy(startloc, counterasstring, sizeof(char) * templatelen);
  1.1182 ++
  1.1183 ++    return 0;
  1.1184 ++}
  1.1185 ++
  1.1186 ++
  1.1187 ++/* ----------------------------------------------------------------------- */
  1.1188 ++/* File transfers suffer considerably from the inability to safely send 
  1.1189 ++ * metadata on the same channel as the file transfer in DTN.  Perhaps we 
  1.1190 ++ * should work around this?
  1.1191 ++ */
  1.1192 ++int
  1.1193 ++handle_file_transfer(dtn_bundle_spec_t spec, dtn_bundle_payload_t payload,
  1.1194 ++                     int* total_bytes, int counter)
  1.1195 ++{
  1.1196 ++    int tempdes;
  1.1197 ++    int destdes;
  1.1198 ++    char block[BLOCKSIZE];
  1.1199 ++    ssize_t bytesread;
  1.1200 ++    struct stat fileinfo;
  1.1201 ++    char currentfile[PATH_MAX];
  1.1202 ++
  1.1203 ++    // Create the filename by searching for ### characters in the given
  1.1204 ++    // filename and replacing that with an incrementing counter.  
  1.1205 ++    buildfilename(filename, currentfile, counter);
  1.1206 ++
  1.1207 ++    // Try to rename the old file to the new name to avoid unnecessary copying
  1.1208 ++    if (rename(filename, currentfile) == 0) {
  1.1209 ++        // success!
  1.1210 ++
  1.1211 ++    } else {
  1.1212 ++        // Copy the file into place
  1.1213 ++        tempdes = open(payload.filename.filename_val, O_RDONLY);
  1.1214 ++
  1.1215 ++        if ( tempdes < 0 )
  1.1216 ++        {
  1.1217 ++            fprintf(stderr, "While opening the temporary file for reading '%s': %s\n",
  1.1218 ++                    payload.filename.filename_val, strerror(errno));
  1.1219 ++            exit(1);
  1.1220 ++        }
  1.1221 ++
  1.1222 ++        destdes = creat(currentfile, 0644);
  1.1223 ++        
  1.1224 ++        if ( destdes < 0 )
  1.1225 ++        {
  1.1226 ++            fprintf(stderr, "While opening output file for writing '%s': %s\n",
  1.1227 ++                    filename, strerror(errno));
  1.1228 ++            exit(1);
  1.1229 ++        }
  1.1230 ++
  1.1231 ++        // Duplicate the file
  1.1232 ++        while ( (bytesread = read(tempdes, block, sizeof(block))) > 0 )
  1.1233 ++            write(destdes, block, bytesread);
  1.1234 ++
  1.1235 ++        close(tempdes);
  1.1236 ++        close(destdes);
  1.1237 ++        
  1.1238 ++        unlink(payload.filename.filename_val);
  1.1239 ++    }
  1.1240 ++
  1.1241 ++    if ( stat(currentfile, &fileinfo) == -1 )
  1.1242 ++    {
  1.1243 ++        fprintf(stderr, "Unable to stat destination file '%s': %s\n",
  1.1244 ++                currentfile, strerror(errno));
  1.1245 ++        return 1;
  1.1246 ++    }
  1.1247 ++
  1.1248 ++    printf("%d byte file from [%s]: transit time=%d ms, written to '%s'\n",
  1.1249 ++           (int)fileinfo.st_size, spec.source.uri, 0, currentfile);        
  1.1250 ++
  1.1251 ++    *total_bytes += fileinfo.st_size;
  1.1252 ++
  1.1253 ++    return 0;
  1.1254 ++}
  1.1255 ++
  1.1256 ++/* ----------------------------------------------------------------------- */
  1.1257 ++/* Builds the temporary file based on the template given and an integer
  1.1258 ++ * counter value
  1.1259 ++ */
  1.1260 ++int buildwgetfilename(char* template, char* newfilename, int counter )
  1.1261 ++{
  1.1262 ++    char counterasstring[COUNTER_MAX_DIGITS];
  1.1263 ++    char formatstring[10];
  1.1264 ++    char* startloc;
  1.1265 ++    char* endloc;
  1.1266 ++    int templatelen;
  1.1267 ++
  1.1268 ++    strcpy(newfilename, template);
  1.1269 ++
  1.1270 ++    endloc = rindex(newfilename, '#');
  1.1271 ++    /* No template in the filename, just copy it as is */
  1.1272 ++    if ( endloc == NULL )
  1.1273 ++        return 0;
  1.1274 ++
  1.1275 ++    /* Search backwards for the start of the template */
  1.1276 ++    for ( startloc = endloc; *startloc == '#' && startloc != template;
  1.1277 ++          startloc -= 1 );
  1.1278 ++
  1.1279 ++    startloc += 1;
  1.1280 ++
  1.1281 ++    templatelen = endloc - startloc + 1;
  1.1282 ++    if ( templatelen > COUNTER_MAX_DIGITS )
  1.1283 ++        templatelen = COUNTER_MAX_DIGITS;
  1.1284 ++
  1.1285 ++    sprintf(formatstring, "%%0%dd", templatelen);
  1.1286 ++    sprintf(counterasstring, formatstring, counter);
  1.1287 ++
  1.1288 ++    if ( strlen(counterasstring) > (unsigned int)templatelen )
  1.1289 ++        fprintf(stderr, "Warning: Filename template not large enough "
  1.1290 ++                "to support counter value %d\n", counter);
  1.1291 ++
  1.1292 ++    memcpy(startloc, counterasstring, sizeof(char) * templatelen);
  1.1293 ++
  1.1294 ++    return 0;
  1.1295 ++}
  1.1296 ++
  1.1297 ++
  1.1298 ++int
  1.1299 ++handle_wget_file_transfer(dtn_bundle_spec_t spec, dtn_bundle_payload_t payload,
  1.1300 ++                     int* total_bytes, int counter)
  1.1301 ++{
  1.1302 ++    int tempdes;
  1.1303 ++    int destdes;
  1.1304 ++    char block[BLOCKSIZE];
  1.1305 ++    ssize_t bytesread;
  1.1306 ++    struct stat fileinfo;
  1.1307 ++    char currentfile[PATH_MAX];
  1.1308 ++    char cleanup[PATH_MAX];
  1.1309 ++    char tarz[PATH_MAX];
  1.1310 ++    // Create the filename by searching for ### characters in the given
  1.1311 ++    // filename and replacing that with an incrementing counter.  
  1.1312 ++		syslog(LOG_NOTICE,"payload.filename.filename_val = '%s' \nfilename = '%s'\n",
  1.1313 ++                    payload.filename.filename_val, filename);
  1.1314 ++            printf("payload.filename.filename_val = '%s' \nfilename = '%s'\n",
  1.1315 ++                    payload.filename.filename_val, filename);
  1.1316 ++
  1.1317 ++
  1.1318 ++    buildwgetfilename(filename, currentfile, counter);
  1.1319 ++
  1.1320 ++    // Try to rename the old file to the new name to avoid unnecessary copying
  1.1321 ++    if (rename(filename, currentfile) == 0) {
  1.1322 ++        // success!
  1.1323 ++
  1.1324 ++    } else {
  1.1325 ++        // Copy the file into place
  1.1326 ++        tempdes = open(payload.filename.filename_val, O_RDONLY);
  1.1327 ++
  1.1328 ++        if ( tempdes < 0 )
  1.1329 ++        {
  1.1330 ++		syslog(LOG_NOTICE,"While opening the temporary file for reading '%s': %s\n",
  1.1331 ++                    payload.filename.filename_val, strerror(errno));
  1.1332 ++            fprintf(stderr, "While opening the temporary file for reading '%s': %s\n",
  1.1333 ++                    payload.filename.filename_val, strerror(errno));
  1.1334 ++            exit(1);
  1.1335 ++        }
  1.1336 ++
  1.1337 ++        destdes = creat(currentfile, 0644);
  1.1338 ++//destdes = creat(payload.filename.filename_val, 0644);
  1.1339 ++        if ( destdes < 0 )
  1.1340 ++        {
  1.1341 ++		syslog(LOG_NOTICE,"While opening output file for writing '%s': %s\n",
  1.1342 ++                    filename, strerror(errno));
  1.1343 ++            fprintf(stderr, "While opening output file for writing '%s': %s\n",
  1.1344 ++                    filename, strerror(errno));
  1.1345 ++            exit(1);
  1.1346 ++        }
  1.1347 ++
  1.1348 ++        // Duplicate the file
  1.1349 ++        while ( (bytesread = read(tempdes, block, sizeof(block))) > 0 )
  1.1350 ++            write(destdes, block, bytesread);
  1.1351 ++
  1.1352 ++        close(tempdes);
  1.1353 ++        close(destdes);
  1.1354 ++
  1.1355 ++        unlink(payload.filename.filename_val);
  1.1356 ++    }
  1.1357 ++
  1.1358 ++    if ( stat(currentfile, &fileinfo) == -1 )
  1.1359 ++    {
  1.1360 ++        fprintf(stderr, "Unable to stat destination file '%s': %s\n",
  1.1361 ++                currentfile, strerror(errno));
  1.1362 ++        return 1;
  1.1363 ++    }
  1.1364 ++
  1.1365 ++    printf("%d byte file from [%s]: transit time=%d ms, written to '%s'\n",
  1.1366 ++           (int)fileinfo.st_size, spec.source.uri, 0, currentfile);
  1.1367 ++    sprintf(tarz, "%s" " %s", "tar -xvf", currentfile);
  1.1368 ++    system(tarz);
  1.1369 ++    if (verbose) printf("%s\n", tarz);
  1.1370 ++    sprintf(cleanup, "%s" " %s", "rm -r", currentfile);
  1.1371 ++    system(cleanup);
  1.1372 ++    if (verbose) printf("%s\n", cleanup);
  1.1373 ++
  1.1374 ++    *total_bytes += fileinfo.st_size;
  1.1375 ++
  1.1376 ++    return 0;
  1.1377 ++}
  1.1378 ++
  1.1379 ++/***********************************************************************************************************************/
  1.1380 ++
  1.1381 ++int
  1.1382 ++main(int argc, char** argv)
  1.1383 ++{
  1.1384 ++    int i;    
  1.1385 ++    u_int k;
  1.1386 ++    int ret;
  1.1387 ++    int total_bytes = 0;
  1.1388 ++    dtn_handle_t handle;
  1.1389 ++    dtn_endpoint_id_t local_eid;
  1.1390 ++    dtn_reg_info_t reginfo;
  1.1391 ++    dtn_bundle_spec_t spec;
  1.1392 ++    dtn_bundle_payload_t payload;
  1.1393 ++    int call_bind;
  1.1394 ++    dtn_bundle_status_report_t* sr_data;
  1.1395 ++    char req_ID_b[31];
  1.1396 ++    char reqval_c[payload.buf.buf_len];
  1.1397 ++    char wgeturl[payload.buf.buf_len+PATH_MAX];
  1.1398 ++
  1.1399 ++    char tarz[PATH_MAX];
  1.1400 ++    char cleanup[128];
  1.1401 ++    char dtnsendfile[128];
  1.1402 ++    // force stdout to always be line buffered, even if output is
  1.1403 ++    // redirected to a pipe or file
  1.1404 ++    setvbuf(stdout, (char *)NULL, _IOLBF, 0);
  1.1405 ++    
  1.1406 ++    parse_options(argc, argv);
  1.1407 ++    
  1.1408 ++    openlog( progname, LOG_CONS, LOG_USER );
  1.1409 ++    syslog ( LOG_NOTICE, "dtnN4Crecv (pid %d) starting up", getpid() );
  1.1410 ++
  1.1411 ++    if (count == 0) 
  1.1412 ++        printf("dtnN4Crecv (pid %d) starting up\n", getpid());
  1.1413 ++    else 
  1.1414 ++        printf("dtnN4Crecv (pid %d) starting up -- count %u\n", getpid(), count);
  1.1415 ++
  1.1416 ++    // open the ipc handle
  1.1417 ++    if (verbose) printf("opening connection to dtn router...\n");    
  1.1418 ++    if ( (ret = dtn_open(&handle)) != DTN_SUCCESS) 
  1.1419 ++    {
  1.1420 ++        fprintf(stderr, "fatal error opening dtn handle: %s\n", dtn_strerror(ret));
  1.1421 ++        exit(1);
  1.1422 ++    }    
  1.1423 ++    if (verbose) printf("opened connection to dtn router...\n");
  1.1424 ++
  1.1425 ++    // if we're not given a regid, or we're in change mode, we need to
  1.1426 ++    // build up the reginfo
  1.1427 ++    memset(&reginfo, 0, sizeof(reginfo));
  1.1428 ++
  1.1429 ++    if ((regid == DTN_REGID_NONE) || change)
  1.1430 ++    {
  1.1431 ++        // if the specified eid starts with '/', then build a local
  1.1432 ++        // eid based on the configuration of our dtn router plus the
  1.1433 ++        // demux string. otherwise make sure it's a valid one
  1.1434 ++        if (endpoint[0] == '/') 
  1.1435 ++        {
  1.1436 ++            if (verbose) printf("calling dtn_build_local_eid.\n");
  1.1437 ++            dtn_build_local_eid(handle, &local_eid, (char *) endpoint);
  1.1438 ++            if (verbose) printf("local_eid [%s]\n", local_eid.uri);
  1.1439 ++        } 
  1.1440 ++        else 
  1.1441 ++        {
  1.1442 ++            if (verbose) printf("calling parse_eid_string\n");
  1.1443 ++            if (dtn_parse_eid_string(&local_eid, endpoint)) 
  1.1444 ++            {
  1.1445 ++                fprintf(stderr, "invalid destination endpoint '%s'\n", endpoint);
  1.1446 ++                goto err;
  1.1447 ++            }
  1.1448 ++        }
  1.1449 ++
  1.1450 ++        // create a new registration based on this eid
  1.1451 ++        dtn_copy_eid(&reginfo.endpoint, &local_eid);
  1.1452 ++        reginfo.regid             = regid;
  1.1453 ++        reginfo.expiration        = expiration;
  1.1454 ++        reginfo.flags             = failure_action;
  1.1455 ++        reginfo.script.script_val = failure_script;
  1.1456 ++        reginfo.script.script_len = strlen(failure_script) + 1;
  1.1457 ++    }
  1.1458 ++
  1.1459 ++    if (change) 
  1.1460 ++    {
  1.1461 ++        if ((ret = dtn_change_registration(handle, regid, &reginfo)) != 0) 
  1.1462 ++        {
  1.1463 ++            fprintf(stderr, "error changing registration: %d (%s)\n", ret, dtn_strerror(dtn_errno(handle)));
  1.1464 ++            goto err;
  1.1465 ++        }
  1.1466 ++        printf("change registration succeeded, regid %d\n", regid);
  1.1467 ++        goto done;
  1.1468 ++    }
  1.1469 ++    
  1.1470 ++    if (unregister) {
  1.1471 ++        if (dtn_unregister(handle, regid) != 0) {
  1.1472 ++            fprintf(stderr, "error in unregister regid %d: %s\n",
  1.1473 ++                    regid, dtn_strerror(dtn_errno(handle)));
  1.1474 ++            goto err;
  1.1475 ++        }
  1.1476 ++        
  1.1477 ++        printf("unregister succeeded, regid %d\n", regid);
  1.1478 ++        goto done;
  1.1479 ++    }
  1.1480 ++        
  1.1481 ++    // try to see if there is an existing registration that matches
  1.1482 ++    // the given endpoint, in which case we'll use that one.
  1.1483 ++    if (regid == DTN_REGID_NONE && ! no_find_reg) 
  1.1484 ++    {
  1.1485 ++        if (dtn_find_registration(handle, &local_eid, &regid) != 0) 
  1.1486 ++        {
  1.1487 ++            if (dtn_errno(handle) != DTN_ENOTFOUND) 
  1.1488 ++            {
  1.1489 ++                fprintf(stderr, "error in find_registration: %s\n", dtn_strerror(dtn_errno(handle)));
  1.1490 ++                goto err;
  1.1491 ++            }
  1.1492 ++        }
  1.1493 ++        printf("find registration succeeded, regid %d\n", regid);
  1.1494 ++        call_bind = 1;
  1.1495 ++    }
  1.1496 ++    
  1.1497 ++    //todo
  1.1498 ++    if (push_content == PUSHED_CONTENT_SEND)
  1.1499 ++    {
  1.1500 ++        if (send_pushed_content(&local_eid) == 0)
  1.1501 ++            goto done;//todo change these goto statements    
  1.1502 ++        else
  1.1503 ++            goto err;   
  1.1504 ++    }
  1.1505 ++    
  1.1506 ++    // if the user didn't give us a registration to use, get a new one
  1.1507 ++    if (regid == DTN_REGID_NONE) 
  1.1508 ++    {
  1.1509 ++        if ((ret = dtn_register(handle, &reginfo, &regid)) != 0) 
  1.1510 ++        {
  1.1511 ++            fprintf(stderr, "error creating registration: %d (%s)\n", ret, dtn_strerror(dtn_errno(handle)));
  1.1512 ++            goto err;
  1.1513 ++        }
  1.1514 ++
  1.1515 ++        printf("register succeeded, regid %d\n", regid);
  1.1516 ++        call_bind = 0;
  1.1517 ++    } 
  1.1518 ++    else 
  1.1519 ++        call_bind = 1;
  1.1520 ++        
  1.1521 ++        
  1.1522 ++    /*************************************************
  1.1523 ++    *
  1.1524 ++    * At this point the program should either:
  1.1525 ++    * have a registration or have exited
  1.1526 ++    *
  1.1527 ++    *************************************************/
  1.1528 ++        
  1.1529 ++    
  1.1530 ++    if (register_only) 
  1.1531 ++        goto done;
  1.1532 ++
  1.1533 ++    if (call_bind) 
  1.1534 ++    {
  1.1535 ++        // bind the current handle to the found registration
  1.1536 ++        printf("binding to regid %d\n", regid);
  1.1537 ++        if (dtn_bind(handle, regid) != 0) 
  1.1538 ++        {
  1.1539 ++            fprintf(stderr, "error binding to registration: %s\n", dtn_strerror(dtn_errno(handle)));
  1.1540 ++            goto err;
  1.1541 ++        }
  1.1542 ++    }
  1.1543 ++        
  1.1544 ++    // loop waiting for bundles
  1.1545 ++    if (count == 0) 
  1.1546 ++        printf("looping forever to receive bundles\n");
  1.1547 ++    else 
  1.1548 ++        printf("looping to receive %d bundles\n", count);
  1.1549 ++
  1.1550 ++    // Entering the for loop
  1.1551 ++    // the handle should be bound to dtnd
  1.1552 ++    for (i = 0; (count == 0) || (i < count); ++i) 
  1.1553 ++    {
  1.1554 ++        memset(&spec, 0, sizeof(spec));
  1.1555 ++        memset(&payload, 0, sizeof(payload));
  1.1556 ++        if ((ret = dtn_recv(handle, &spec, bundletype, &payload, recv_timeout)) < 0)
  1.1557 ++        {
  1.1558 ++            fprintf(stderr, "error getting recv reply: %d (%s)\n", ret, dtn_strerror(dtn_errno(handle)));
  1.1559 ++            goto err;
  1.1560 ++        }
  1.1561 ++
  1.1562 ++        // Files need to be handled differently than memory transfers
  1.1563 ++        // -p <template> Write out transfers to files using this template (# chars are replaced with a counter). 
  1.1564 ++        //    Example: f##.bin goes to f00.bin, f01.bin, etc.. Ouput packaged website under transaction ID
  1.1565 ++        // if -p is not set     
  1.1566 ++        if ( po == 0) 
  1.1567 ++        {
  1.1568 ++            if ( bundletype == DTN_PAYLOAD_FILE )
  1.1569 ++            {
  1.1570 ++                handle_file_transfer(spec, payload, &total_bytes, i);
  1.1571 ++                dtn_free_payload(&payload);
  1.1572 ++                continue;
  1.1573 ++            }
  1.1574 ++        }
  1.1575 ++
  1.1576 ++        if (!quiet) 
  1.1577 ++        {
  1.1578 ++            //printf("dtn_recv [%s]...\n", local_eid.uri);
  1.1579 ++            printf("\n");
  1.1580 ++        }
  1.1581 ++
  1.1582 ++        total_bytes += payload.buf.buf_len;
  1.1583 ++        if (sr) //-s output status report original bundle creation.seq
  1.1584 ++        {
  1.1585 ++            if (payload.status_report != NULL) 
  1.1586 ++            {
  1.1587 ++                sr_data = payload.status_report;
  1.1588 ++                printf("%llu.%llu\n",
  1.1589 ++                    sr_data->bundle_id.creation_ts.secs,
  1.1590 ++                    sr_data->bundle_id.creation_ts.seqno);
  1.1591 ++            }
  1.1592 ++        }
  1.1593 ++
  1.1594 ++        if (quiet) 
  1.1595 ++        {
  1.1596 ++            dtn_free_payload(&payload);
  1.1597 ++            if (spec.blocks.blocks_len > 0) 
  1.1598 ++            {
  1.1599 ++                free(spec.blocks.blocks_val);
  1.1600 ++                spec.blocks.blocks_val = NULL;
  1.1601 ++                spec.blocks.blocks_len = 0;
  1.1602 ++            }
  1.1603 ++            if (spec.metadata.metadata_len > 0) 
  1.1604 ++            {
  1.1605 ++                free(spec.metadata.metadata_val);
  1.1606 ++                spec.metadata.metadata_val = NULL;
  1.1607 ++                spec.metadata.metadata_len = 0;
  1.1608 ++            }
  1.1609 ++            continue;
  1.1610 ++        }
  1.1611 ++        if (id) // -S Ouput transaction ID and URL request
  1.1612 ++        {
  1.1613 ++            print_req_ID(payload.buf.buf_val, req_ID_b);
  1.1614 ++            print_reqval(payload.buf.buf_val, payload.buf.buf_len, reqval_c);
  1.1615 ++	    syslog(LOG_NOTICE,"Received TX %s"" ""for URL %s"" ", req_ID_b, reqval_c);
  1.1616 ++            if (verbose)  printf("\n%s"" ""%s"" \n", req_ID_b, reqval_c);
  1.1617 ++            syslog(LOG_NOTICE,"%s -P %s/%s %s", WGETSTR, RSDIR, req_ID_b, reqval_c);
  1.1618 ++            sprintf(wgeturl, "%s -P %s/%s %s", WGETSTR, RSDIR, req_ID_b, reqval_c);
  1.1619 ++            syslog(LOG_NOTICE,"%s %s/%s.tar.gz %s/%s", "tar czvf", RSDIR, req_ID_b, RSDIR, req_ID_b);
  1.1620 ++            sprintf(tarz, "%s %s/%s.tar.gz %s/%s", "tar czvf", RSDIR, req_ID_b, RSDIR, req_ID_b);
  1.1621 ++            system(wgeturl); 
  1.1622 ++	    syslog(LOG_NOTICE,"\n%s\n", wgeturl);
  1.1623 ++            if (verbose) printf("\n%s\n", wgeturl);
  1.1624 ++            system(tarz);
  1.1625 ++	    syslog(LOG_NOTICE,"\n%s\n", tarz);
  1.1626 ++            if (verbose) printf("\n%s\n", tarz);
  1.1627 ++            sprintf(cleanup, "%s %s/%s", "rm -r", RSDIR, req_ID_b);
  1.1628 ++            system(cleanup);
  1.1629 ++            syslog(LOG_NOTICE,"%s\n", cleanup);
  1.1630 ++            if (verbose) printf("%s\n", cleanup);
  1.1631 ++	    syslog(LOG_NOTICE,"Sending from %s to requester source %s as transaction %s\n",  local_eid.uri, spec.source.uri, req_ID_b);
  1.1632 ++	    if (verbose) printf("Sending from %s to requester source %s as transaction %s\n",  local_eid.uri, spec.source.uri, req_ID_b);
  1.1633 ++            sprintf(dtnsendfile, "dtnsend -c -e 604800 -s %s -d %s -t f -p %s/%s.tar.gz", local_eid.uri, spec.source.uri, RSDIR, req_ID_b);
  1.1634 ++            printf("%s\n", dtnsendfile);
  1.1635 ++
  1.1636 ++            system(dtnsendfile);
  1.1637 ++            //printf("%s\n", dtnsendfile);
  1.1638 ++            //dtn_free_payload(&payload);
  1.1639 ++            continue;
  1.1640 ++        }
  1.1641 ++        
  1.1642 ++
  1.1643 ++        
  1.1644 ++        //todo
  1.1645 ++        if (push_content == PUSHED_CONTENT_RECV)
  1.1646 ++        {
  1.1647 ++            recv_pushed_content(payload);//todo need to pass rec bundle into fn
  1.1648 ++            //handle_file_transfer(spec, payload, &total_bytes, i);
  1.1649 ++            dtn_free_payload(&payload);
  1.1650 ++            continue; 
  1.1651 ++        }
  1.1652 ++        
  1.1653 ++        if (po) //-p <template> Write out transfers to files using this template (# chars are
  1.1654 ++        {
  1.1655 ++            handle_wget_file_transfer(spec, payload, &total_bytes, i);
  1.1656 ++
  1.1657 ++            dtn_free_payload(&payload);
  1.1658 ++            continue;
  1.1659 ++        }
  1.1660 ++
  1.1661 ++
  1.1662 ++/*        
  1.1663 ++        if (id) 
  1.1664 ++        {
  1.1665 ++            print_req_ID(payload.buf.buf_val, req_ID_b);
  1.1666 ++            printf("%s", req_ID_b);
  1.1667 ++            print_reqval(payload.buf.buf_val, payload.buf.buf_len, reqval_c);
  1.1668 ++            printf("%s", reqval_c);
  1.1669 ++            dtn_free_payload(&payload);
  1.1670 ++
  1.1671 ++            if (spec.blocks.blocks_len > 0) 
  1.1672 ++            {
  1.1673 ++                free(spec.blocks.blocks_val);
  1.1674 ++                spec.blocks.blocks_val = NULL;
  1.1675 ++                spec.blocks.blocks_len = 0;
  1.1676 ++            }
  1.1677 ++            if (spec.metadata.metadata_len > 0) 
  1.1678 ++            {
  1.1679 ++                free(spec.metadata.metadata_val);
  1.1680 ++                spec.metadata.metadata_val = NULL;
  1.1681 ++                spec.metadata.metadata_len = 0;
  1.1682 ++            }
  1.1683 ++            continue;
  1.1684 ++        }
  1.1685 ++*/
  1.1686 ++
  1.1687 ++        printf("\n%d extension blocks from [%s]: transit time=%d ms\n", spec.blocks.blocks_len, spec.source.uri, 0);
  1.1688 ++        dtn_extension_block_t *block = spec.blocks.blocks_val;
  1.1689 ++        for (k = 0; k < spec.blocks.blocks_len; k++) 
  1.1690 ++        {
  1.1691 ++            printf("Extension Block %i:\n", k);
  1.1692 ++            printf("\ttype = %i\n\tflags = %i\n",
  1.1693 ++                   block[k].type, block[k].flags);
  1.1694 ++            print_data(block[k].data.data_val, block[k].data.data_len);
  1.1695 ++        }
  1.1696 ++
  1.1697 ++        printf("\n%d metadata blocks from [%s]: transit time=%d ms\n",
  1.1698 ++               spec.metadata.metadata_len, spec.source.uri, 0);
  1.1699 ++        dtn_extension_block_t *meta = spec.metadata.metadata_val;
  1.1700 ++        for (k = 0; k < spec.metadata.metadata_len; k++) 
  1.1701 ++        {
  1.1702 ++            printf("Metadata Extension Block %i:\n", k);
  1.1703 ++            printf("\ttype = %i\n\tflags = %i\n",
  1.1704 ++                   meta[k].type, meta[k].flags);
  1.1705 ++            print_data(meta[k].data.data_val, meta[k].data.data_len);
  1.1706 ++        }
  1.1707 ++
  1.1708 ++        printf("%d payload bytes from [%s]: transit time=%d ms\n",
  1.1709 ++               payload.buf.buf_len,
  1.1710 ++               spec.source.uri, 0);
  1.1711 ++        print_data(payload.buf.buf_val, payload.buf.buf_len);
  1.1712 ++        printf("\n");
  1.1713 ++
  1.1714 ++        //parse_meta_req_ID(spec.metadata.metadata_val.data.data_val, req_ID_d);
  1.1715 ++        //printf("%s\n", req_ID_d);
  1.1716 ++
  1.1717 ++        dtn_free_payload(&payload);
  1.1718 ++        if (spec.blocks.blocks_len > 0) 
  1.1719 ++        {
  1.1720 ++            free(spec.blocks.blocks_val);
  1.1721 ++            spec.blocks.blocks_val = NULL;
  1.1722 ++            spec.blocks.blocks_len = 0;
  1.1723 ++        }
  1.1724 ++        if (spec.metadata.metadata_len > 0) 
  1.1725 ++        {
  1.1726 ++            free(spec.metadata.metadata_val);
  1.1727 ++            spec.metadata.metadata_val = NULL;
  1.1728 ++            spec.metadata.metadata_len = 0;
  1.1729 ++        }
  1.1730 ++    }//end for loop
  1.1731 ++
  1.1732 ++    printf("dtnN4Crecv (pid %d) exiting: %d bundles received, %d total bytes\n\n",
  1.1733 ++           getpid(), i, total_bytes);
  1.1734 ++
  1.1735 ++done:
  1.1736 ++    dtn_close(handle);
  1.1737 ++    if (push_content == PUSHED_CONTENT_SEND) {
  1.1738 ++    	printf("dtnN4Crecv (pid %d) done pushing content: \n", getpid());
  1.1739 ++	} else {
  1.1740 ++    	printf("dtnN4Crecv (pid %d) done: %d bundles received, %d total bytes\n\n", getpid(), i, total_bytes);
  1.1741 ++	}
  1.1742 ++    closelog ();
  1.1743 ++    return 0;
  1.1744 ++
  1.1745 ++err:
  1.1746 ++    dtn_close(handle);
  1.1747 ++    printf("dtnN4Crecv (pid %d) error: %d bundles received, %d total bytes\n\n", getpid(), i, total_bytes);
  1.1748 ++    closelog ();
  1.1749 ++    return 1;
  1.1750 ++}
  1.1751 +diff -r b0407e525e08 -r 875893b4fede apps/dtnN4Cmiddle/dtnN4Csettings.h
  1.1752 +--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
  1.1753 ++++ b/apps/dtnN4Cmiddle/dtnN4Csettings.h	Thu Apr 21 15:19:21 2011 +0000
  1.1754 +@@ -0,0 +1,68 @@
  1.1755 ++
  1.1756 ++#ifndef DTNN4CSETTINGS
  1.1757 ++#define DTNN4CSETTINGS
  1.1758 ++
  1.1759 ++// This is an anti-hack to make it easier to test the http stuff
  1.1760 ++// from wherever you are.
  1.1761 ++
  1.1762 ++
  1.1763 ++// for dtnN4Crecv
  1.1764 ++#define RSDIR "/data/www/private/HTMLrequester/router_stage"
  1.1765 ++// wget cmd
  1.1766 ++#define WGETSTR "wget -N -r -l 1 --no-remove-listing -p -t 1 -d --quota=104857600"
  1.1767 ++
  1.1768 ++// for pushedContent
  1.1769 ++#define PUBDIR			"/data/www/public"
  1.1770 ++// next two need to be in same filesystem, hard links are used
  1.1771 ++#define RX_PATH       "/data/www/public/rxpushedContent"
  1.1772 ++#define DOCROOT 	    "/data/www/public/drpushedContent"
  1.1773 ++#define RXMETA_FILE     "/data/www/public/rxpushedContent/metadata.xml"
  1.1774 ++
  1.1775 ++// for pushedContent
  1.1776 ++#define SRCDIR			"./public"
  1.1777 ++#define TARPATH         "./public/tars"
  1.1778 ++// next two need to be in same filesystem, hard links are used
  1.1779 ++#define INDEX_FILE      "./index"
  1.1780 ++#define STATUS_FILE     "./hg_status"
  1.1781 ++#define META_FILE       "./metadata.xml"
  1.1782 ++#define DEST_URI_FILE   "./destination_uris"
  1.1783 ++// list of stuff to pass to tar
  1.1784 ++#define FILELIST		"./filelist"
  1.1785 ++
  1.1786 ++#define GEN_PC_FILE     "./generatePushedContent.sh"
  1.1787 ++#define APACFG 			"/data/apps/DTN2/apps/dtnN4Cmiddle/apache_cfg.sh"
  1.1788 ++#define APACFGOUTPUT	"/etc/apache2/sites-available/n4csites.conf"
  1.1789 ++
  1.1790 ++
  1.1791 ++// for pushedContent - to separate crawling and
  1.1792 ++// pushing bundles without getting confused we
  1.1793 ++// need a bit of signalling
  1.1794 ++
  1.1795 ++// if this is set then we'll call GEN_PC_FILE each time we're
  1.1796 ++// run. If it's unset, then we'll drop a GEN_PC_SIGNAL_FILE 
  1.1797 ++// while we're diff'ing and depend on the content generator
  1.1798 ++// (aka crawler) to pause while that file exists
  1.1799 ++#undef	GENERATE_EACH_TIME 
  1.1800 ++
  1.1801 ++// pushedContent.c will create this file when running to
  1.1802 ++// ask generatPushedContent.sh to pause
  1.1803 ++#define GEN_PC_PAUSE_FILE "/tmp/pausegenerating"
  1.1804 ++// generatePushedContent.sh will call pausecheck to 
  1.1805 ++// check for that file, if it exists then pausecheck
  1.1806 ++// will create this one to confirm it is paused
  1.1807 ++// and pushedContent.c can go ahead
  1.1808 ++#define GEN_PC_CONF_FILE "/tmp/generatingpaused"
  1.1809 ++// this is how I know there's a reason to wait
  1.1810 ++// in the first place
  1.1811 ++#define GEN_PC_WORKING "/tmp/generating"
  1.1812 ++// once pushedContent.c is done, it can delete
  1.1813 ++// GEN_PC_PAUSE_FILE and then pauscheck will delete
  1.1814 ++// GEN_PC_CONF_FILE and generatePushedContent.sh
  1.1815 ++// will continue crawling
  1.1816 ++// some wget commands can take a while (if crawling deep)
  1.1817 ++// so pushedContent.c will only hang about for a while
  1.1818 ++// before just exiting, having done nothing, this is
  1.1819 ++// how long...
  1.1820 ++#define SECONDSTOWAIT 1800
  1.1821 ++
  1.1822 ++#endif
  1.1823 +diff -r b0407e525e08 -r 875893b4fede apps/dtnN4Cmiddle/generatePushedContent.sh
  1.1824 +--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
  1.1825 ++++ b/apps/dtnN4Cmiddle/generatePushedContent.sh	Thu Apr 21 15:19:21 2011 +0000
  1.1826 +@@ -0,0 +1,157 @@
  1.1827 ++#!/bin/bash
  1.1828 ++#
  1.1829 ++# webscript
  1.1830 ++
  1.1831 ++set -x
  1.1832 ++
  1.1833 ++#
  1.1834 ++###############################################################################
  1.1835 ++#
  1.1836 ++# create temp dir
  1.1837 ++# wget sites to this dir
  1.1838 ++#
  1.1839 ++###############################################################################
  1.1840 ++dirName=$1
  1.1841 ++if [ "$1" == "" ]
  1.1842 ++then
  1.1843 ++    dirName="N4Csites"
  1.1844 ++fi
  1.1845 ++
  1.1846 ++if [ ! -d $dirName ]
  1.1847 ++then
  1.1848 ++	mkdir $dirName
  1.1849 ++fi
  1.1850 ++
  1.1851 ++# make so folks know we're doing stuff
  1.1852 ++WORKING=/tmp/generating
  1.1853 ++touch $WORKING
  1.1854 ++
  1.1855 ++# http proxy, if needed
  1.1856 ++# export http_proxy="http://www-proxy.cs.tcd.ie:8080"
  1.1857 ++
  1.1858 ++#wget options we'll try out, comment out to remove
  1.1859 ++
  1.1860 ++# add .html to files, e.g. foo.cgi?bar=25 --> foo.cgi?bar=25.html
  1.1861 ++#HTMLEXTENSIONS="-E"
  1.1862 ++
  1.1863 ++# Do logging in wgets
  1.1864 ++LOGFILE="-o /home/dtnuser/pushed/r6/wget.log"
  1.1865 ++
  1.1866 ++# Cookie handling
  1.1867 ++COOKIEFILE="/home/dtnuser/pushed/r6/wget-cookies.txt"
  1.1868 ++COOKIES="--load-cookies=$COOKIEFILE --save-cookies=$COOKIEFILE --keep-session-cookies"
  1.1869 ++
  1.1870 ++# Recursion/mirroring
  1.1871 ++# 1 deep only, shallow in other words
  1.1872 ++RECURS="-r -l 1 -N"
  1.1873 ++# two deep, dangerous for big sites
  1.1874 ++RECURS2="-r -l 2 -N"
  1.1875 ++# the lot
  1.1876 ++RECURSM="-m"
  1.1877 ++
  1.1878 ++# Link handling
  1.1879 ++LINKS="-pk"
  1.1880 ++
  1.1881 ++# SSL options
  1.1882 ++SSLOPT="--no-check-certificate"
  1.1883 ++
  1.1884 ++# Standard options to always use
  1.1885 ++STDOPT="--wait=1 --limit-rate=40K -R 'robots*' -U Mozilla -P $dirName"
  1.1886 ++
  1.1887 ++# put these in the same plaec please!
  1.1888 ++CHECK=./pausecheck.sh
  1.1889 ++
  1.1890 ++WGET="wget $STDOPT $LINKS $RECURS $HTMLEXTENSIONS $LOGFILE $COOKIES $SSLOPT"
  1.1891 ++WGET2="wget $STDOPT $LINKS $RECURS2 $HTMLEXTENSIONS $LOGFILE $COOKIES $SSLOPT"
  1.1892 ++WGETMIN="wget $STDOPT $LINKS $HTMLEXTENSIONS $LOGFILE $COOKIES $SSLOPT"
  1.1893 ++WMIRROR="wget -m -P $dirName $COOKIES $SSLOPT $LOGFILE $HTMLEXTENSIONS"
  1.1894 ++
  1.1895 ++###############################################################################
  1.1896 ++#
  1.1897 ++# wget sites 
  1.1898 ++#
  1.1899 ++###############################################################################
  1.1900 ++
  1.1901 ++# Irish Times mobile
  1.1902 ++$CHECK
  1.1903 ++$WMIRROR http://m.irishtimes.com/
  1.1904 ++# have to fix up filenames
  1.1905 ++cd $dirName/m.irishtimes.com
  1.1906 ++find . -name '*.htm*via*' -exec ../../it_cp.sh {} \;
  1.1907 ++cd images
  1.1908 ++for file in *.jpg?ts=*
  1.1909 ++do
  1.1910 ++	outf=`echo $file | awk -F"?" '{print $1}'`
  1.1911 ++	cp $file $outf
  1.1912 ++done
  1.1913 ++
  1.1914 ++cd ../../..
  1.1915 ++
  1.1916 ++# Weather
  1.1917 ++
  1.1918 ++# (5-day report of saltoluokta) grab just this page.
  1.1919 ++$CHECK
  1.1920 ++$WGET http://www.smhi.se/vadret/vadret-i-sverige/land/fiveDaysForecast.do?geonameid=2680465&redirect=false 
  1.1921 ++cp "$dirName/www.smhi.se/vadret/vadret-i-sverige/land/fiveDaysForecast.do?geonameid=2680465&redirect=false" "$dirName/www.smhi.se/vadret/vadret-i-sverige/land/salto-index.html"
  1.1922 ++
  1.1923 ++# Weather
  1.1924 ++$CHECK
  1.1925 ++$WGET http://www.yr.no/place/Sweden/Norrbotten/Staloluokta/
  1.1926 ++$CHECK
  1.1927 ++$WGET http://www.yr.no/place/Sweden/Norrbotten/Jokkmokk/
  1.1928 ++$CHECK
  1.1929 ++$WGET http://www.yr.no/place/United_Kingdom/
  1.1930 ++$CHECK
  1.1931 ++$WGET http://www.yr.no/place/Germany/  
  1.1932 ++$CHECK
  1.1933 ++$WGET http://www.yr.no/place/Sweden/ 
  1.1934 ++$CHECK
  1.1935 ++$WGET http://www.yr.no/place/Ireland/
  1.1936 ++$CHECK
  1.1937 ++$WGET http://www.yr.no/place/Europe/ 
  1.1938 ++
  1.1939 ++# News
  1.1940 ++$CHECK
  1.1941 ++$WGET http://www.dn.se/nyheter/nyhetsdygnet/m/rss/senaste-nytt
  1.1942 ++cp $dirName/www.dn.se/nyheter/nyhetsdygnet/m/rss/senaste-nytt $dirName/www.dn.se/nyheter/nyhetsdygnet/m/rss/senaste-nytt.rss
  1.1943 ++$CHECK
  1.1944 ++$WGET http://www.expressen.se/1.573280?standAlone=true        # (RSS feed swedish news) 
  1.1945 ++cp $dirName/www.expressen.se/1.573280?standAlone=true $dirName/www.expressen.se/1.573280.rss
  1.1946 ++$CHECK
  1.1947 ++$WGET http://www.dn.se/m/rss/toppnyheter                      # (RSS feed swedish news) 
  1.1948 ++$CHECK
  1.1949 ++$WGET http://www.thelocal.se/RSS/theLocal.xml                 # (RSS feed swedish news in english) 
  1.1950 ++cp $dirName/www.thelocal.se/RSS/theLocal.xml $dirName/www.thelocal.se/RSS/theLocal.rss
  1.1951 ++$CHECK
  1.1952 ++$WGET http://www.nsd.se/allt.rss                              # (RSS feed swedish news) 
  1.1953 ++
  1.1954 ++$CHECK
  1.1955 ++$WGET http://www.expressen.se/1.573280?standAlone=true  
  1.1956 ++$CHECK
  1.1957 ++$WGET http://www.dn.se/m/rss/toppnyheter                 #(RSS feed swedish news) #grab this page + one click deep (no images, scripts, flash etc)
  1.1958 ++$CHECK
  1.1959 ++$WGET http://www.thelocal.se/RSS/theLocal.xml            #(RSS feed swedish news in english) grab this page + one click deep (no images, scripts, flash etc)
  1.1960 ++$CHECK
  1.1961 ++$WGET http://www.nsd.se/allt.rss                         #(RSS feed swedish news) grab this page + one click deep (no images, scripts, flash etc)
  1.1962 ++
  1.1963 ++# Misc. sites of interest
  1.1964 ++#(RSS feed english indigenous news) grab this page + one click deep (no images, scripts, flash etc)
  1.1965 ++$CHECK
  1.1966 ++$WGET http://www.indigenousportal.com/component/option,com_kusoma/id,1/lang,/  
  1.1967 ++
  1.1968 ++# now follow <link> elements from rss feeds
  1.1969 ++./rsslinks.sh
  1.1970 ++for url in `cat stories`
  1.1971 ++do
  1.1972 ++	$WGETMIN $url
  1.1973 ++done
  1.1974 ++
  1.1975 ++# Helicopters
  1.1976 ++$CHECK
  1.1977 ++$WMIRROR http://www.fiskflyg.se/
  1.1978 ++###############################################################################
  1.1979 ++
  1.1980 ++# $CHECK
  1.1981 ++# $WGET2 http://www.irishtimes.com/
  1.1982 ++
  1.1983 ++rm -f $WORKING
  1.1984 +diff -r b0407e525e08 -r 875893b4fede apps/dtnN4Cmiddle/middle_api.c
  1.1985 +--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
  1.1986 ++++ b/apps/dtnN4Cmiddle/middle_api.c	Thu Apr 21 15:19:21 2011 +0000
  1.1987 +@@ -0,0 +1,147 @@
  1.1988 ++/*
  1.1989 ++ *      middle_api.c
  1.1990 ++ *      Functions to be called by dtnN4C middleware applications
  1.1991 ++ */
  1.1992 ++
  1.1993 ++
  1.1994 ++#include <stdio.h>
  1.1995 ++
  1.1996 ++#include "middle_api.h"
  1.1997 ++
  1.1998 ++/***********************
  1.1999 ++ * procHTTPreq
  1.2000 ++ * */
  1.2001 ++int procHTTPreq (const char * bndlDest, const char * bndlSrc, const char * bndlRply_to, uint8_t * string, uint16_t len)
  1.2002 ++{
  1.2003 ++	TParsed parData;
  1.2004 ++	int err;
  1.2005 ++	
  1.2006 ++	//dtn handler
  1.2007 ++	dtn_handle_t handle;
  1.2008 ++	
  1.2009 ++	//Bundle specs
  1.2010 ++	dtn_bundle_spec_t bundle_spec;
  1.2011 ++
  1.2012 ++	//Bundle options
  1.2013 ++	int expiration                 = 604800;      // expiration timer (default one hour)
  1.2014 ++	int delivery_options           = 0;         // bundle delivery option bit vector
  1.2015 ++	dtn_bundle_priority_t priority = COS_NORMAL;// bundle priority 
  1.2016 ++	delivery_options |= DOPTS_CUSTODY;
  1.2017 ++	//Bundle payload
  1.2018 ++	dtn_bundle_payload_t payload;
  1.2019 ++	uint8_t pldRaw	[RECV_BUFFER_SIZE];
  1.2020 ++	uint16_t pldRawLen;
  1.2021 ++	
  1.2022 ++	//Bundle id
  1.2023 ++	dtn_bundle_id_t bundle_id;
  1.2024 ++	dtn_reg_id_t regid = DTN_REGID_NONE;
  1.2025 ++
  1.2026 ++    syslog ( LOG_INFO, "Start of procHTTPreq" );
  1.2027 ++	
  1.2028 ++	/*Open a dtn connection*/
  1.2029 ++	if((err = dtn_open(&handle)) != 0)
  1.2030 ++	{
  1.2031 ++	    syslog ( LOG_ERR, "Error opening DTN connection (code: %d)", err );
  1.2032 ++		return err;
  1.2033 ++	}
  1.2034 ++	else
  1.2035 ++    	syslog ( LOG_INFO, "DTN connection opened" );
  1.2036 ++	
  1.2037 ++	parData = parseURL(string, len);
  1.2038 ++	syslog ( LOG_INFO, "URL Data parsed" ); 
  1.2039 ++
  1.2040 ++	/*Set up bundle*/
  1.2041 ++	// initialize bundle spec
  1.2042 ++	memset(&bundle_spec, 0, sizeof(bundle_spec));
  1.2043 ++
  1.2044 ++	// initialize/parse bundle src/dest/replyto eids
  1.2045 ++	//if (verbose) syslog ( LOG_INFO, "Destination: %s", bndlDest);
  1.2046 ++	parse_eid(handle, &bundle_spec.dest, bndlDest);
  1.2047 ++
  1.2048 ++	//if (verbose) syslog ( LOG_INFO, "Source: %s", bndlSrc);
  1.2049 ++	parse_eid(handle, &bundle_spec.source, bndlSrc);
  1.2050 ++	
  1.2051 ++	//if (verbose) syslog ( LOG_INFO, "Reply To: %s", bndlRply_to);			
  1.2052 ++	parse_eid(handle, &bundle_spec.replyto, bndlRply_to);
  1.2053 ++		
  1.2054 ++	//Set the dtn options
  1.2055 ++	bundle_spec.expiration = expiration;
  1.2056 ++	bundle_spec.dopts      = delivery_options;
  1.2057 ++	bundle_spec.priority   = priority;
  1.2058 ++	
  1.2059 ++	//Metadata/extension blocks not temporarily, might include request ID later
  1.2060 ++	
  1.2061 ++	/*Fill bundle payload (URL)*/
  1.2062 ++	//It must include transID too
  1.2063 ++	memcpy(pldRaw, parData.transID, TRANS_ID_LENGTH);
  1.2064 ++	memcpy(&(pldRaw[TRANS_ID_LENGTH]), parData.outURL, parData.outURLlen);
  1.2065 ++	pldRawLen = TRANS_ID_LENGTH + parData.outURLlen;
  1.2066 ++	syslog ( LOG_INFO, "Transaction ID in the bundle payload %1.32s", (char *)pldRaw);
  1.2067 ++	syslog ( LOG_INFO, "First URL string chars in the bundle payload %1.8s", (char *) &(pldRaw[TRANS_ID_LENGTH]));
  1.2068 ++	  
  1.2069 ++	dtn_set_payload(&payload, DTN_PAYLOAD_MEM, (char *) pldRaw, pldRawLen);	
  1.2070 ++	
  1.2071 ++	/*Send bundle*/	
  1.2072 ++	if( (err = dtn_send(handle, regid, &bundle_spec, &payload, &bundle_id)) != 0 )
  1.2073 ++	    syslog ( LOG_ERR, "Error sending DTN bundle (code: %d)", err );
  1.2074 ++    else
  1.2075 ++        syslog ( LOG_INFO, "DTN bundle sent successfully" );
  1.2076 ++
  1.2077 ++	dtn_close(handle);	
  1.2078 ++	return err;		
  1.2079 ++}
  1.2080 ++
  1.2081 ++/*****************************
  1.2082 ++ * parseURL
  1.2083 ++ * */
  1.2084 ++TParsed parseURL(uint8_t * string, unsigned int len)
  1.2085 ++{
  1.2086 ++	TParsed parsedBuff;
  1.2087 ++	
  1.2088 ++	memcpy (parsedBuff.transID, string, sizeof(uint8_t) * TRANS_ID_LENGTH);	
  1.2089 ++	syslog ( LOG_INFO, "Parsing URL - transID copied: %1.32s", parsedBuff.transID);
  1.2090 ++	parsedBuff.outURLlen = len - TRANS_ID_LENGTH;
  1.2091 ++	memcpy (parsedBuff.outURL, &(string[URL_OFFSET]), sizeof(uint8_t) * parsedBuff.outURLlen);
  1.2092 ++	
  1.2093 ++	return parsedBuff;
  1.2094 ++}
  1.2095 ++
  1.2096 ++
  1.2097 ++/****************************
  1.2098 ++ * parse_eid
  1.2099 ++ * */
  1.2100 ++dtn_endpoint_id_t * parse_eid(dtn_handle_t handle, 
  1.2101 ++                              dtn_endpoint_id_t* eid, char * str)
  1.2102 ++{
  1.2103 ++    // try the string as an actual dtn eid
  1.2104 ++    if (!dtn_parse_eid_string(eid, str)) 
  1.2105 ++    {
  1.2106 ++        //if (verbose) syslog ( LOG_INFO, "%s (literal)", str);
  1.2107 ++        return eid;
  1.2108 ++    }
  1.2109 ++    // build a local eid based on the configuration of our dtn
  1.2110 ++    // router plus the str as demux string
  1.2111 ++    else if (!dtn_build_local_eid(handle, eid, str))
  1.2112 ++    {
  1.2113 ++        //if (verbose) syslog ( LOG_INFO, "%s (local)", str);
  1.2114 ++        return eid;
  1.2115 ++    }
  1.2116 ++    else
  1.2117 ++    {
  1.2118 ++        syslog ( LOG_ERR, "Exiting - invalid eid string '%s'", str);
  1.2119 ++        exit(1);
  1.2120 ++    }
  1.2121 ++}
  1.2122 ++
  1.2123 ++/***************************
  1.2124 ++ * parseTest
  1.2125 ++ * */
  1.2126 ++T_TCP_Test parseTest (uint8_t * string, uint16_t len)
  1.2127 ++{
  1.2128 ++	T_TCP_Test parData;
  1.2129 ++	
  1.2130 ++	memcpy(parData.HTTP_Response, string, len);
  1.2131 ++	parData.HTTP_ResponseLen = len;
  1.2132 ++	
  1.2133 ++	return parData;
  1.2134 ++}
  1.2135 +diff -r b0407e525e08 -r 875893b4fede apps/dtnN4Cmiddle/middle_api.h
  1.2136 +--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
  1.2137 ++++ b/apps/dtnN4Cmiddle/middle_api.h	Thu Apr 21 15:19:21 2011 +0000
  1.2138 +@@ -0,0 +1,59 @@
  1.2139 ++/*
  1.2140 ++ *      middle_api.h
  1.2141 ++ *      Function headers to be called by dtnN4C middleware applications
  1.2142 ++ */
  1.2143 ++
  1.2144 ++#ifdef HAVE_CONFIG_H
  1.2145 ++#  include <dtn-config.h>
  1.2146 ++#endif
  1.2147 ++
  1.2148 ++#include <sys/types.h>
  1.2149 ++#include <syslog.h>
  1.2150 ++
  1.2151 ++//#include "../../applib/dtn_api.h"
  1.2152 ++#include "dtn_api.h"
  1.2153 ++ 
  1.2154 ++#ifndef MIDDLE_API_H
  1.2155 ++#define MIDDLE_API_H
  1.2156 ++ 
  1.2157 ++ 
  1.2158 ++/**********************************************************************
  1.2159 ++* Constant Definitions
  1.2160 ++**********************************************************************/
  1.2161 ++#define LST_PORT 			9090
  1.2162 ++#define PENDING_CON_REQ		5				//Tipically for Unix Kernels
  1.2163 ++#define RECV_BUFFER_SIZE	(512 + 4096)	//HTTP req max length (other fields + URL)
  1.2164 ++#define EID_MAX_LENGTH		4096
  1.2165 ++#define TRANS_ID_LENGTH		32
  1.2166 ++#define URL_OFFSET			(TRANS_ID_LENGTH + 0 )
  1.2167 ++
  1.2168 ++
  1.2169 ++/**********************************************************************
  1.2170 ++* Typedefs
  1.2171 ++**********************************************************************/
  1.2172 ++typedef struct parsed {
  1.2173 ++	uint8_t outURL [EID_MAX_LENGTH];
  1.2174 ++	uint16_t outURLlen;
  1.2175 ++	uint8_t transID [TRANS_ID_LENGTH];
  1.2176 ++} TParsed;
  1.2177 ++
  1.2178 ++typedef struct TCP_Test {
  1.2179 ++	uint8_t HTTP_Response [EID_MAX_LENGTH];
  1.2180 ++	uint16_t HTTP_ResponseLen;
  1.2181 ++} T_TCP_Test;
  1.2182 ++
  1.2183 ++
  1.2184 ++/***********************************************************************
  1.2185 ++* Headers
  1.2186 ++***********************************************************************/
  1.2187 ++int procHTTPreq (const char * bndlDest, const char * bndlSrc, const char * bndlRply_to, uint8_t * string, uint16_t len);
  1.2188 ++ 
  1.2189 ++TParsed parseURL(uint8_t * string, unsigned int len);
  1.2190 ++ 
  1.2191 ++dtn_endpoint_id_t * parse_eid(dtn_handle_t handle, dtn_endpoint_id_t* eid, char * str);
  1.2192 ++                              
  1.2193 ++T_TCP_Test parseTest (uint8_t * string, uint16_t len);
  1.2194 ++ 
  1.2195 ++ 
  1.2196 ++#endif
  1.2197 ++
  1.2198 +diff -r b0407e525e08 -r 875893b4fede apps/dtnN4Cmiddle/pausecheck.sh
  1.2199 +--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
  1.2200 ++++ b/apps/dtnN4Cmiddle/pausecheck.sh	Thu Apr 21 15:19:21 2011 +0000
  1.2201 +@@ -0,0 +1,24 @@
  1.2202 ++#!/bin/bash
  1.2203 ++
  1.2204 ++# This goes with dtnN4Csettings.h:GENERATE_EACH_TIME, if that is undef'd
  1.2205 ++# then we need to check for a file before fetching more
  1.2206 ++CHECKFILE="/tmp/pausegenerating"
  1.2207 ++CONFFILE="/tmp/generatingpaused"
  1.2208 ++
  1.2209 ++if ( [ -f "$CHECKFILE" ] ) 
  1.2210 ++then
  1.2211 ++	touch $CONFFILE
  1.2212 ++fi
  1.2213 ++while ( [ -f "$CHECKFILE" ] ) 
  1.2214 ++do 	
  1.2215 ++	NOW=`date --rfc-3339='seconds'`;
  1.2216 ++	echo "Paused for Send at $NOW..."; 
  1.2217 ++	sleep 5; 
  1.2218 ++done
  1.2219 ++if ( [ -f "$CONFFILE" ] ) 
  1.2220 ++then
  1.2221 ++	NOW=`date --rfc-3339='seconds'`;
  1.2222 ++	echo "Continuing at $NOW"
  1.2223 ++	rm -f $CONFFILE
  1.2224 ++fi
  1.2225 ++
  1.2226 +diff -r b0407e525e08 -r 875893b4fede apps/dtnN4Cmiddle/pushedContent.c
  1.2227 +--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
  1.2228 ++++ b/apps/dtnN4Cmiddle/pushedContent.c	Thu Apr 21 15:19:21 2011 +0000
  1.2229 +@@ -0,0 +1,1561 @@
  1.2230 ++#include <stdio.h>
  1.2231 ++#include <string.h>
  1.2232 ++#include <errno.h>
  1.2233 ++#include <sys/types.h>
  1.2234 ++#include <sys/stat.h>
  1.2235 ++#include <unistd.h>
  1.2236 ++
  1.2237 ++#include "dtnN4Csettings.h"
  1.2238 ++#include "pushedContent.h"
  1.2239 ++
  1.2240 ++// signalling between here and generatePushedContent.sh
  1.2241 ++// see comments in dtnN4Csettings.h for details
  1.2242 ++
  1.2243 ++int release(void)
  1.2244 ++{
  1.2245 ++#ifndef GENERATE_EACH_TIME
  1.2246 ++	// remove file
  1.2247 ++	int rc=unlink(GEN_PC_PAUSE_FILE);
  1.2248 ++	if (rc) {
  1.2249 ++        syslog ( LOG_ERR, "Error (%d) at getFileDiff", rc );
  1.2250 ++        return rc;
  1.2251 ++	}
  1.2252 ++#endif
  1.2253 ++	return (0);
  1.2254 ++}
  1.2255 ++
  1.2256 ++int pauseorget(void)
  1.2257 ++{
  1.2258 ++#ifdef GENERATE_EACH_TIME
  1.2259 ++    // generate content to push
  1.2260 ++    snprintf (generateContent, PATH_MAX, "%s %s/today/%s", GEN_PC_FILE, SRCDIR, LOCALDIR );    
  1.2261 ++    syslog ( LOG_INFO, "Starting to generate pushed content: %s", generateContent );   
  1.2262 ++    if ( (rc = system ( generateContent )) != 0 )
  1.2263 ++    {
  1.2264 ++        syslog ( LOG_ERR, "Error (%d) at generateContent: %s", rc, generateContent );
  1.2265 ++        return rc;
  1.2266 ++    } 
  1.2267 ++    syslog ( LOG_INFO, "Finished generating pushed content" );  
  1.2268 ++#else
  1.2269 ++	// just create a file to signal the separate content generator
  1.2270 ++ 	// to stop and wait for now
  1.2271 ++	FILE *stopandwait=fopen(GEN_PC_PAUSE_FILE,"w");
  1.2272 ++	if (!stopandwait) {
  1.2273 ++        syslog ( LOG_ERR, "Can't create %s",GEN_PC_PAUSE_FILE);
  1.2274 ++		return(-1);
  1.2275 ++	}
  1.2276 ++	fclose(stopandwait);
  1.2277 ++	// now see if the script is around has listened to us
  1.2278 ++	FILE *working=fopen(GEN_PC_WORKING,"r");
  1.2279 ++	if (working!=NULL) {
  1.2280 ++		// better get a confirm
  1.2281 ++		fclose(working);
  1.2282 ++		FILE *conffile=NULL;
  1.2283 ++		int secondstowait=SECONDSTOWAIT;
  1.2284 ++		while(secondstowait>0 && conffile==NULL) {
  1.2285 ++			conffile=fopen(GEN_PC_CONF_FILE,"r");
  1.2286 ++			if (conffile==NULL) {
  1.2287 ++				sleep(1);
  1.2288 ++				secondstowait--;
  1.2289 ++			}
  1.2290 ++		}
  1.2291 ++		if (!conffile) {
  1.2292 ++			release();
  1.2293 ++			return(-1);
  1.2294 ++		}
  1.2295 ++		fclose(conffile);
  1.2296 ++	}
  1.2297 ++#endif
  1.2298 ++	return (0);
  1.2299 ++}
  1.2300 ++
  1.2301 ++/*******************************************************************
  1.2302 ++* generate pushed content using wget script
  1.2303 ++* add new content to repo using hg add
  1.2304 ++* create dif metadata to be sent with content
  1.2305 ++* tar content and metadata
  1.2306 ++* send tar file using dtnsend
  1.2307 ++*******************************************************************/
  1.2308 ++int send_pushed_content(dtn_endpoint_id_t *source_eid)
  1.2309 ++{        
  1.2310 ++    int i, rc, index;
  1.2311 ++#ifdef GENERATE_EACH_TIME
  1.2312 ++    char generateContent[PATH_MAX];
  1.2313 ++#endif
  1.2314 ++    char hg[PATH_MAX];    
  1.2315 ++    char tar[PATH_MAX];
  1.2316 ++    char dtnSendFile[PATH_MAX]; 
  1.2317 ++    char cp[PATH_MAX];  
  1.2318 ++    char tarFile[PATH_MAX];  
  1.2319 ++    int numUris;
  1.2320 ++    char ** destinationUris = (char**) malloc ( sizeof(char*) * MAX_DEST_URI );        
  1.2321 ++    
  1.2322 ++    int numAddFiles;
  1.2323 ++    int numRemoveFiles;
  1.2324 ++    int numReplaceFiles;
  1.2325 ++
  1.2326 ++	char **addFiles=NULL;
  1.2327 ++	char **removeFiles=NULL;
  1.2328 ++	char **replaceFiles=NULL;
  1.2329 ++    
  1.2330 ++    syslog ( LOG_INFO, "Send Pushed content from: %s", source_eid->uri );
  1.2331 ++
  1.2332 ++
  1.2333 ++	char checkfile[PATH_MAX];
  1.2334 ++	struct stat checkstat;
  1.2335 ++	snprintf(checkfile,PATH_MAX,SRCDIR);
  1.2336 ++	rc=stat(checkfile,&checkstat);
  1.2337 ++	if (rc || !S_ISDIR(checkstat.st_mode)) {
  1.2338 ++		rc=mkdir(checkfile,0755);
  1.2339 ++		if (rc) {
  1.2340 ++			syslog(LOG_ERR,"Can't make %s. (%d) ",checkfile, rc);
  1.2341 ++			return(rc);
  1.2342 ++		}
  1.2343 ++	} 
  1.2344 ++ 
  1.2345 ++    for ( i=0; i<MAX_DEST_URI; i++ )
  1.2346 ++        destinationUris[i] = (char*) malloc ( sizeof(char) * DTN_MAX_ENDPOINT_ID );       
  1.2347 ++    
  1.2348 ++    
  1.2349 ++    // get list of destination uris
  1.2350 ++    if ( (rc = getDestinationUris(destinationUris, &numUris)) != 0 )
  1.2351 ++    {
  1.2352 ++        syslog ( LOG_ERR, "Error (%d) at getDestinationUris", rc );
  1.2353 ++        return rc;
  1.2354 ++    }  
  1.2355 ++    
  1.2356 ++    for ( i=0; i<numUris; i++)
  1.2357 ++        syslog ( LOG_INFO, "Send Pushed content to[%d]: %s", i, destinationUris[i] );
  1.2358 ++    
  1.2359 ++    index = getIndex();
  1.2360 ++    updateIndex( index + 1 );
  1.2361 ++	char wd[PATH_MAX];
  1.2362 ++	getcwd(wd,PATH_MAX);
  1.2363 ++	snprintf(tarFile,PATH_MAX,TARPATH);
  1.2364 ++	// special case for absolute TARPATH
  1.2365 ++	if (tarFile[0]=='/') {
  1.2366 ++    	snprintf(tarFile, PATH_MAX, "%s/N4Csites%d.tar", TARPATH, index );
  1.2367 ++	} else {
  1.2368 ++    	snprintf(tarFile, PATH_MAX, "%s/%s/N4Csites%d.tar", wd, TARPATH, index );
  1.2369 ++	}
  1.2370 ++
  1.2371 ++	rc=pauseorget();
  1.2372 ++	if (rc) {
  1.2373 ++        syslog ( LOG_ERR, "Error (%d) at %d", rc,__LINE__ );
  1.2374 ++        return rc;
  1.2375 ++    }  
  1.2376 ++
  1.2377 ++	// better hg init if not done
  1.2378 ++	snprintf(checkfile,PATH_MAX,"%s/.hg",SRCDIR);
  1.2379 ++	rc=stat(checkfile,&checkstat);
  1.2380 ++	if (rc || !S_ISDIR(checkstat.st_mode)) {
  1.2381 ++		char repocmd[PATH_MAX];
  1.2382 ++		snprintf(repocmd,PATH_MAX,"cd %s; hg init",SRCDIR);
  1.2383 ++		syslog( LOG_INFO, "Creating repo: %s", repocmd);
  1.2384 ++		rc=system(repocmd);
  1.2385 ++		if (rc) {
  1.2386 ++			syslog(LOG_ERR,"Can't make repo. (%d) ", rc);
  1.2387 ++			release();
  1.2388 ++			return(rc);
  1.2389 ++		}
  1.2390 ++	} 
  1.2391 ++
  1.2392 ++	// need a "today" dir
  1.2393 ++	snprintf(checkfile,PATH_MAX,"%s/today",SRCDIR);
  1.2394 ++	rc=stat(checkfile,&checkstat);
  1.2395 ++	if (rc || !S_ISDIR(checkstat.st_mode)) {
  1.2396 ++		rc=mkdir(checkfile,0755);
  1.2397 ++		if (rc) {
  1.2398 ++			syslog(LOG_ERR,"Can't make %s. (%d) ",checkfile, rc);
  1.2399 ++			release();
  1.2400 ++			return(rc);
  1.2401 ++		}
  1.2402 ++	} 
  1.2403 ++
  1.2404 ++	// need a "yesterday" dir
  1.2405 ++	snprintf(checkfile,PATH_MAX,"%s/yesterday",SRCDIR);
  1.2406 ++	rc=stat(checkfile,&checkstat);
  1.2407 ++	if (rc || !S_ISDIR(checkstat.st_mode)) {
  1.2408 ++		rc=mkdir(checkfile,0755);
  1.2409 ++		if (rc) {
  1.2410 ++			syslog(LOG_ERR,"Can't make %s. (%d) ", checkfile,rc);
  1.2411 ++			release();
  1.2412 ++			return(rc);
  1.2413 ++		}
  1.2414 ++	} 
  1.2415 ++
  1.2416 ++	// need a "tars" dir
  1.2417 ++	snprintf(checkfile,PATH_MAX,"%s",TARPATH);
  1.2418 ++	rc=stat(checkfile,&checkstat);
  1.2419 ++	if (rc || !S_ISDIR(checkstat.st_mode)) {
  1.2420 ++		rc=mkdir(checkfile,0755);
  1.2421 ++		if (rc) {
  1.2422 ++			syslog(LOG_ERR,"Can't make %s. (%d) ", checkfile,rc);
  1.2423 ++			release();
  1.2424 ++			return(rc);
  1.2425 ++		}
  1.2426 ++	} 
  1.2427 ++
  1.2428 ++    // add new content to repo using hg add
  1.2429 ++    snprintf ( hg, PATH_MAX, "cd %s;hg add today/%s", SRCDIR, LOCALDIR );   
  1.2430 ++    syslog ( LOG_INFO, "Adding pushed content to hg: %s", hg );    
  1.2431 ++    if ( (rc = system ( hg )) != 0 )
  1.2432 ++    {
  1.2433 ++        syslog ( LOG_ERR, "Error (%d) at hg: %s", rc, hg );
  1.2434 ++		release();
  1.2435 ++        return rc;
  1.2436 ++    } 
  1.2437 ++    syslog ( LOG_INFO, "Finished adding pushed content to hg" );   
  1.2438 ++
  1.2439 ++    // create dif metadata to be sent with content
  1.2440 ++    if ( (rc = getFileDiff(&addFiles, &numAddFiles, &removeFiles, &numRemoveFiles, &replaceFiles, &numReplaceFiles)) != 0 )
  1.2441 ++    {
  1.2442 ++        syslog ( LOG_ERR, "Error (%d) at getFileDiff", rc );
  1.2443 ++		release();
  1.2444 ++        return rc;
  1.2445 ++    }  
  1.2446 ++
  1.2447 ++    syslog ( LOG_INFO, "there are: %d addFiles", numAddFiles );
  1.2448 ++    syslog ( LOG_INFO, "there are: %d numRemoveFiles", numRemoveFiles );
  1.2449 ++    syslog ( LOG_INFO, "there are: %d numReplaceFiles", numReplaceFiles );
  1.2450 ++
  1.2451 ++    for(i=0; i<numAddFiles; i++)
  1.2452 ++        syslog ( LOG_INFO, "addFile[%d]: %s", i, addFiles[i] );
  1.2453 ++    for(i=0; i<numRemoveFiles; i++)
  1.2454 ++        syslog ( LOG_INFO, "removeFiles[%d]: %s", i, removeFiles[i] );
  1.2455 ++    for(i=0; i<numReplaceFiles; i++)
  1.2456 ++        syslog ( LOG_INFO, "replaceFiles[%d]: %s", i, replaceFiles[i] );        
  1.2457 ++    
  1.2458 ++    if ( (rc = writeMetadata(addFiles, numAddFiles, removeFiles, numRemoveFiles, replaceFiles, numReplaceFiles, index)) != 0)
  1.2459 ++    {
  1.2460 ++        syslog ( LOG_ERR, "Error (%d) at writeMetadata", rc );
  1.2461 ++		release();
  1.2462 ++        return rc;
  1.2463 ++    } 
  1.2464 ++    
  1.2465 ++	if (!numAddFiles && !numRemoveFiles && !numReplaceFiles) {
  1.2466 ++		// nothing to do
  1.2467 ++		syslog(LOG_INFO, "No files to add/remove/replace");
  1.2468 ++		char emptytar[PATH_MAX];
  1.2469 ++		snprintf(emptytar,PATH_MAX,"%s/%s-empty-%d",TARPATH,LOCALDIR,index);
  1.2470 ++		FILE *ef=fopen(emptytar,"w");
  1.2471 ++		if (!ef) {
  1.2472 ++	        syslog ( LOG_ERR, "Error can't create %s",emptytar);
  1.2473 ++			release();
  1.2474 ++	        return (1);
  1.2475 ++		} else {
  1.2476 ++			fclose(ef);
  1.2477 ++		}
  1.2478 ++	} else {
  1.2479 ++	    // tar content and metadata
  1.2480 ++	    snprintf ( tar, PATH_MAX, "tar -cf %s %s", tarFile, META_FILE );
  1.2481 ++	    syslog ( LOG_INFO, "Starting to tar pushed content: %s", tar );   
  1.2482 ++	    if ( (rc = system ( tar )) != 0 )
  1.2483 ++	    {
  1.2484 ++	        syslog ( LOG_ERR, "Error (%d) at tar: %s", rc, tar );
  1.2485 ++			release();
  1.2486 ++	        return rc;
  1.2487 ++	    } 
  1.2488 ++	    
  1.2489 ++		if (numAddFiles>0) {
  1.2490 ++
  1.2491 ++			FILE *tat=fopen(FILELIST,"w");
  1.2492 ++			if (!tat) { 
  1.2493 ++	            	syslog ( LOG_ERR, "Error (%d) at tar: %s. Skipping", rc, tar );
  1.2494 ++			} else {
  1.2495 ++	    		for ( i=0; i<numAddFiles; i++ ) {
  1.2496 ++	        		fprintf ( tat, "%s\n",addFiles[i] );            
  1.2497 ++	    		}
  1.2498 ++			}
  1.2499 ++			fclose(tat);
  1.2500 ++	        snprintf ( tar, PATH_MAX, "cd %s; tar --append --file=%s -T ../%s", SRCDIR, tarFile, FILELIST);            
  1.2501 ++	        if ( (rc = system ( tar )) != 0 ) {
  1.2502 ++	           	syslog ( LOG_ERR, "Error (%d) at tar: %s. Skipping", rc, tar );
  1.2503 ++	        }         
  1.2504 ++
  1.2505 ++		}
  1.2506 ++	    
  1.2507 ++		if (numReplaceFiles>0) {
  1.2508 ++
  1.2509 ++			FILE *tat=fopen(FILELIST,"w");
  1.2510 ++			if (!tat) { 
  1.2511 ++	            	syslog ( LOG_ERR, "Error (%d) at tar: %s. Skipping", rc, tar );
  1.2512 ++			} else {
  1.2513 ++	    		for ( i=0; i<numReplaceFiles; i++ ) {
  1.2514 ++	        		fprintf ( tat, "%s\n",replaceFiles[i] );            
  1.2515 ++	    		}
  1.2516 ++			}
  1.2517 ++			fclose(tat);
  1.2518 ++	        snprintf ( tar, PATH_MAX, "cd %s; tar --append --file=%s -T ../%s", SRCDIR, tarFile, FILELIST);            
  1.2519 ++	        if ( (rc = system ( tar )) != 0 ) {
  1.2520 ++	           	syslog ( LOG_ERR, "Error (%d) at tar: %s. Skipping", rc, tar );
  1.2521 ++	        }         
  1.2522 ++
  1.2523 ++		}
  1.2524 ++	    
  1.2525 ++	    //todo need to compress this tar file before sending it
  1.2526 ++	 	char compress[PATH_MAX];
  1.2527 ++		snprintf(compress,PATH_MAX,"gzip %s",tarFile);
  1.2528 ++		if ( (rc = system ( compress )) != 0 ) {
  1.2529 ++			syslog ( LOG_ERR, "Error (%d) at compress: %s. Skipping", rc, compress );
  1.2530 ++		}        
  1.2531 ++	    
  1.2532 ++	    // push content
  1.2533 ++	    // -c           if you want custody, currently not set!
  1.2534 ++	    // -e 129600     expiration time in seconds (36 hours)
  1.2535 ++	    // -s           source eid
  1.2536 ++	    // -d           destination eid
  1.2537 ++	    // -t f         payload type: file
  1.2538 ++	    // -p           filename payload data
  1.2539 ++	    for ( i=0; i<numUris; i++ )
  1.2540 ++	    {    
  1.2541 ++	        snprintf ( dtnSendFile, PATH_MAX, "dtnsend -e 129600 -s %s -d %s -t f -p %s.gz",
  1.2542 ++	                    source_eid->uri, destinationUris[i], tarFile );  
  1.2543 ++	        syslog ( LOG_INFO, "dtnSendFile: %s", dtnSendFile );      
  1.2544 ++	        
  1.2545 ++	        if ( (rc = system ( dtnSendFile )) != 0 )
  1.2546 ++	        {
  1.2547 ++	            syslog ( LOG_ERR, "Error (%d) at dtnSendFile: %s", rc, dtnSendFile );
  1.2548 ++				release();
  1.2549 ++	            return rc;
  1.2550 ++	        } 
  1.2551 ++	        else
  1.2552 ++	            syslog ( LOG_INFO, "dtnSendFile: success" ); 
  1.2553 ++	    }
  1.2554 ++	    
  1.2555 ++	    // add new content to repo using hg add
  1.2556 ++	    snprintf ( hg, PATH_MAX, "cd %s;hg commit -m '%s'", SRCDIR, "msg to go here" ); 
  1.2557 ++	    syslog ( LOG_INFO, "hg commit: %s", hg );   
  1.2558 ++	    if ( (rc = system ( hg )) != 0 )
  1.2559 ++	    {
  1.2560 ++	        syslog ( LOG_ERR, "Error (%d) at hg commit: %s", rc, hg );
  1.2561 ++			release();
  1.2562 ++	        return rc;
  1.2563 ++	    } 
  1.2564 ++
  1.2565 ++	}
  1.2566 ++    
  1.2567 ++    snprintf ( cp, PATH_MAX, "cd %s;cp -rf today/%s yesterday/", SRCDIR, LOCALDIR ); 
  1.2568 ++    syslog ( LOG_INFO, "cp: %s", cp );   
  1.2569 ++    if ( (rc = system ( cp )) != 0 )
  1.2570 ++    {
  1.2571 ++        syslog ( LOG_ERR, "Error (%d) at cp: %s", rc, cp );
  1.2572 ++		release();
  1.2573 ++        return rc;
  1.2574 ++    }        
  1.2575 ++    
  1.2576 ++    // free memory
  1.2577 ++    for ( i=0; i<numAddFiles; i++ )
  1.2578 ++        free ( addFiles[i] );
  1.2579 ++    for ( i=0; i<numRemoveFiles; i++ )
  1.2580 ++        free ( removeFiles[i] );
  1.2581 ++    for ( i=0; i<numReplaceFiles; i++ )
  1.2582 ++        free ( replaceFiles[i] );               
  1.2583 ++
  1.2584 ++    free ( addFiles );
  1.2585 ++    free ( removeFiles );
  1.2586 ++    free ( replaceFiles ); 
  1.2587 ++    
  1.2588 ++    for ( i=0; i<MAX_DEST_URI; i++ )
  1.2589 ++        free ( destinationUris[i] );
  1.2590 ++    free ( destinationUris );
  1.2591 ++
  1.2592 ++	release();
  1.2593 ++    
  1.2594 ++    return 0;
  1.2595 ++}
  1.2596 ++
  1.2597 ++int getDestinationUris(char **destinationUris, int *numUris)
  1.2598 ++{
  1.2599 ++    int i;    
  1.2600 ++    FILE *file;
  1.2601 ++
  1.2602 ++    file = fopen ( DEST_URI_FILE , "r" );    
  1.2603 ++    if (file == NULL) 
  1.2604 ++    {
  1.2605 ++        syslog ( LOG_ERR, "Error opening file %s", DEST_URI_FILE );
  1.2606 ++        return -1;
  1.2607 ++    }
  1.2608 ++    
  1.2609 ++    *numUris = 0;
  1.2610 ++    for ( i=0; !feof(file) && i<MAX_DEST_URI; i++ )
  1.2611 ++    {
  1.2612 ++		char line[DTN_MAX_ENDPOINT_ID];
  1.2613 ++        fgets ( line,DTN_MAX_ENDPOINT_ID, file );
  1.2614 ++        if (!feof(file) && !strncmp(line,"dtn://",strlen("dtn://"))) {
  1.2615 ++			// scrub EOL
  1.2616 ++			if (line[strlen(line)-1]=='\n') line[strlen(line)-1]=0x00;
  1.2617 ++			snprintf(destinationUris[*numUris],DTN_MAX_ENDPOINT_ID,line);
  1.2618 ++			(*numUris)++;
  1.2619 ++		}
  1.2620 ++    } 
  1.2621 ++    
  1.2622 ++    return 0;
  1.2623 ++}
  1.2624 ++
  1.2625 ++/*******************************************************************
  1.2626 ++* 
  1.2627 ++*
  1.2628 ++*******************************************************************/
  1.2629 ++int recv_pushed_content(dtn_bundle_payload_t payload)
  1.2630 ++{
  1.2631 ++    int i, rc, index;
  1.2632 ++    int numAddFiles;
  1.2633 ++    int numRemoveFiles;
  1.2634 ++    int numReplaceFiles;    
  1.2635 ++    char tar[PATH_MAX];
  1.2636 ++	char wd[PATH_MAX];
  1.2637 ++	getcwd(wd,PATH_MAX);
  1.2638 ++
  1.2639 ++	char checkfile[PATH_MAX];
  1.2640 ++	struct stat checkstat;
  1.2641 ++
  1.2642 ++	snprintf(checkfile,PATH_MAX,PUBDIR);
  1.2643 ++	rc=stat(checkfile,&checkstat);
  1.2644 ++	if (rc || !S_ISDIR(checkstat.st_mode)) {
  1.2645 ++		rc=mkdir(checkfile,0755);
  1.2646 ++		if (rc) {
  1.2647 ++			syslog(LOG_ERR,"Can't make %s. (%d) ",checkfile, rc);
  1.2648 ++			return(rc);
  1.2649 ++		}
  1.2650 ++	} 
  1.2651 ++
  1.2652 ++	// need a "rxpc_path" dir, make it if needed
  1.2653 ++	snprintf(checkfile,PATH_MAX,RX_PATH);
  1.2654 ++	rc=stat(checkfile,&checkstat);
  1.2655 ++	if (rc || !S_ISDIR(checkstat.st_mode)) {
  1.2656 ++		rc=mkdir(checkfile,0755);
  1.2657 ++		if (rc) {
  1.2658 ++			syslog(LOG_ERR,"Can't make %s. (%d) ",checkfile, rc);
  1.2659 ++			return(rc);
  1.2660 ++		}
  1.2661 ++	} 
  1.2662 ++
  1.2663 ++	// need a "DocRoot" dir, make it if needed
  1.2664 ++	char docRoot[PATH_MAX];
  1.2665 ++	snprintf(docRoot,PATH_MAX,DOCROOT);
  1.2666 ++	// if DOCROOT isn't absolute then preprend cwd
  1.2667 ++	if (docRoot[0]!='/') {
  1.2668 ++		snprintf(docRoot,PATH_MAX,"%s/%s",wd,DOCROOT);
  1.2669 ++	}
  1.2670 ++	rc=stat(docRoot,&checkstat);
  1.2671 ++	if (rc || !S_ISDIR(checkstat.st_mode)) {
  1.2672 ++		rc=mkdir(docRoot,0755);
  1.2673 ++		if (rc) {
  1.2674 ++			syslog(LOG_ERR,"Can't make %s. (%d) ",docRoot, rc);
  1.2675 ++			return(rc);
  1.2676 ++		}
  1.2677 ++	} 
  1.2678 ++
  1.2679 ++    /**************************************************************************/
  1.2680 ++    //untar 
  1.2681 ++	char tnb[PATH_MAX];
  1.2682 ++	if (payload.location==DTN_PAYLOAD_MEM) {
  1.2683 ++		snprintf(tnb,PATH_MAX,"thisisatmpfileXXXXXX");
  1.2684 ++		int mst=mkstemp(tnb);
  1.2685 ++		if (mst==-1) {
  1.2686 ++        	syslog ( LOG_ERR, "Can't open tmp file %s",tnb);
  1.2687 ++        	return rc;
  1.2688 ++		}
  1.2689 ++		ssize_t fw=write(mst,payload.buf.buf_val,payload.buf.buf_len);
  1.2690 ++		if (fw!=(ssize_t)payload.buf.buf_len) {
  1.2691 ++        	syslog ( LOG_ERR, "Filed writing tmp file %s (ret: %d)",tnb,fw);
  1.2692 ++        	return rc;
  1.2693 ++		}
  1.2694 ++		close(mst);
  1.2695 ++    	snprintf ( tar, PATH_MAX, "tar -ozxf %s -C %s/", tnb, RX_PATH ); 
  1.2696 ++	} else {
  1.2697 ++    	snprintf ( tar, PATH_MAX, "tar -ozxf %s -c %s/", payload.filename.filename_val, RX_PATH ); 
  1.2698 ++	}
  1.2699 ++    syslog ( LOG_INFO, "untar: %s", tar );      
  1.2700 ++    if ( (rc = system ( tar )) != 0 ) {
  1.2701 ++		// check if uncompressed works (backwards compat)
  1.2702 ++		if (payload.location==DTN_PAYLOAD_MEM) {
  1.2703 ++    		snprintf ( tar, PATH_MAX, "tar -oxf %s -C %s/", tnb, RX_PATH ); 
  1.2704 ++		} else {
  1.2705 ++    		snprintf ( tar, PATH_MAX, "tar -oxf %s -c %s/", payload.filename.filename_val, RX_PATH ); 
  1.2706 ++		}
  1.2707 ++    	syslog ( LOG_INFO, "untar: %s", tar );      
  1.2708 ++    	if ( (rc = system ( tar )) != 0 ) {
  1.2709 ++        	syslog ( LOG_ERR, "Error (%d) at untar: %s", rc, tar );
  1.2710 ++        	return rc;
  1.2711 ++		} else {
  1.2712 ++			syslog( LOG_INFO, "Recovery! Got uncompressed tarball but I figured it out:-)");
  1.2713 ++		}
  1.2714 ++    }     
  1.2715 ++    syslog ( LOG_INFO, "untar finished: %s", tar );    
  1.2716 ++	if (payload.location==DTN_PAYLOAD_MEM) {
  1.2717 ++		unlink(tnb);
  1.2718 ++	} else {
  1.2719 ++		unlink(payload.filename.filename_val);
  1.2720 ++	}
  1.2721 ++
  1.2722 ++    // allocate memory
  1.2723 ++    char **addFiles = NULL;
  1.2724 ++    char **removeFiles = NULL;
  1.2725 ++    char **removeHash = NULL;
  1.2726 ++    char **replaceFiles = NULL;
  1.2727 ++    char **replaceHash = NULL;
  1.2728 ++
  1.2729 ++
  1.2730 ++    if ( (rc = readMetaData(
  1.2731 ++				&addFiles,
  1.2732 ++				&numAddFiles,
  1.2733 ++				&removeFiles,
  1.2734 ++				&removeHash,
  1.2735 ++				&numRemoveFiles,
  1.2736 ++				&replaceFiles,
  1.2737 ++				&replaceHash,
  1.2738 ++				&numReplaceFiles,
  1.2739 ++				&index)) != 0 )
  1.2740 ++    {
  1.2741 ++        syslog ( LOG_ERR, "Error (%d) at readMetaData", rc );
  1.2742 ++        return rc;
  1.2743 ++    }    
  1.2744 ++
  1.2745 ++	// file names are relative to the RX_PATH dir after untarring
  1.2746 ++	// so go there for a minute
  1.2747 ++	rc=chdir(RX_PATH);
  1.2748 ++	if (rc) {
  1.2749 ++		syslog(LOG_ERR,"Can't chdir to %s - exiting",RX_PATH);
  1.2750 ++		return(rc);
  1.2751 ++	}
  1.2752 ++
  1.2753 ++	// remove/replace work a little differently than you'd
  1.2754 ++	// expect. We're working in a new scatch area that 
  1.2755 ++	// has files already removed or replaced, but we want
  1.2756 ++	// to check that we're removing or replacing the version
  1.2757 ++	// in our DocRoot, so if we decide not to make the change
  1.2758 ++	// we move the original from our DocRoot to the scratch
  1.2759 ++	// area. At the end we copy the scratch on top of the DocRoot
  1.2760 ++	// and we'll be done
  1.2761 ++
  1.2762 ++    // add files is already done, thanks to tar
  1.2763 ++
  1.2764 ++    // remove files
  1.2765 ++    removeDeltaFiles( docRoot, removeFiles, removeHash, numRemoveFiles );
  1.2766 ++    
  1.2767 ++    // replace files
  1.2768 ++    replaceDeltaFiles( docRoot, replaceFiles, replaceHash, numReplaceFiles );
  1.2769 ++
  1.2770 ++    // free memory
  1.2771 ++    for ( i=0; i!=numAddFiles; i++ )
  1.2772 ++        free ( addFiles[i] );
  1.2773 ++    for ( i=0; i!=numRemoveFiles; i++ ) {
  1.2774 ++        free ( removeFiles[i] );
  1.2775 ++        free ( removeHash[i] ); 
  1.2776 ++	}
  1.2777 ++    for ( i=0; i!=numReplaceFiles; i++ ) {
  1.2778 ++        free ( replaceFiles[i] );     
  1.2779 ++        free ( replaceHash[i] );               
  1.2780 ++    }
  1.2781 ++    free ( addFiles );
  1.2782 ++    free ( removeFiles );
  1.2783 ++    free ( removeHash );
  1.2784 ++    free ( replaceFiles ); 
  1.2785 ++    free ( replaceHash );  
  1.2786 ++
  1.2787 ++	// now for the quick swaparoo
  1.2788 ++
  1.2789 ++	rc=chdir(wd);
  1.2790 ++	if (rc) {
  1.2791 ++		syslog(LOG_ERR,"Can't chdir to %s - exiting",wd);
  1.2792 ++		return(rc);
  1.2793 ++	}
  1.2794 ++	// yukkie, but so's everything here and we need the space
  1.2795 ++	char cpminusr[PATH_MAX];
  1.2796 ++	snprintf(cpminusr,PATH_MAX,"cp -r %s/* %s; rm -rf %s",RX_PATH,docRoot,RX_PATH);
  1.2797 ++	syslog(LOG_INFO,"copying: %s",cpminusr);
  1.2798 ++	rc=system(cpminusr);
  1.2799 ++	if (rc) {
  1.2800 ++		syslog(LOG_ERR,"Can't copy %s - exiting",cpminusr);
  1.2801 ++		return(rc);
  1.2802 ++	}
  1.2803 ++
  1.2804 ++	// now we need to reconfigure apache
  1.2805 ++	// we just call a script with docRoot as input for that
  1.2806 ++	// the script is 
  1.2807 ++	char apacfg[PATH_MAX];
  1.2808 ++	snprintf(apacfg,PATH_MAX,"%s %s %s",APACFG,docRoot,APACFGOUTPUT);
  1.2809 ++	syslog(LOG_INFO,"About to reconfigure apache via: %s",apacfg);
  1.2810 ++	rc=system(apacfg);
  1.2811 ++	if (rc) {
  1.2812 ++		syslog(LOG_ERR,"Error (%d) from apacfg: %s",rc,apacfg);
  1.2813 ++	}
  1.2814 ++
  1.2815 ++    return 0;
  1.2816 ++}
  1.2817 ++
  1.2818 ++int removeDeltaFiles( char *docRoot, char **removeFiles, char **removeHash, int numRemoveFiles )
  1.2819 ++{
  1.2820 ++    int i, rc = 0;
  1.2821 ++    char md[MD_SIZE];
  1.2822 ++
  1.2823 ++    for ( i=0; i<numRemoveFiles && rc==0; i++ ) {
  1.2824 ++
  1.2825 ++		char *tp=strstr(removeFiles[i],DELPRECURSOR);
  1.2826 ++		if (!tp || strlen(tp)<=(strlen(DELPRECURSOR)+1)) {
  1.2827 ++			syslog(LOG_ERR,"Error checking removal of %s - parsing",removeFiles[i]);
  1.2828 ++		} else {
  1.2829 ++			char orig[PATH_MAX];
  1.2830 ++			snprintf(orig,PATH_MAX,"%s/%s",docRoot,tp+strlen(DELPRECURSOR));
  1.2831 ++			struct stat origstat;
  1.2832 ++			rc=stat(orig,&origstat);
  1.2833 ++			if (!rc) {
  1.2834 ++				// else gone already, nothing to do
  1.2835 ++        		rc=dohash(orig, HASH_SIZE, md);
  1.2836 ++				if (rc<0) {
  1.2837 ++					syslog(LOG_ERR,"Can't hash %s - its gone so",orig);
  1.2838 ++				} else {
  1.2839 ++        			if ( strncmp( md, removeHash[i], MD_SIZE ) ) {
  1.2840 ++						// only action case - put it back in the scratch area
  1.2841 ++						syslog(LOG_INFO,"Hash mismatch - restoring %s",removeFiles[i]);
  1.2842 ++						// note - hard link - better be same fs
  1.2843 ++            			rc = link(orig,removeFiles[i]);
  1.2844 ++						if (!rc) {
  1.2845 ++							syslog(LOG_ERR,"Can't restore %s - leaving it so",orig);
  1.2846 ++						}
  1.2847 ++        			} 
  1.2848 ++				}
  1.2849 ++			}
  1.2850 ++		}
  1.2851 ++
  1.2852 ++    }
  1.2853 ++    
  1.2854 ++    return rc;
  1.2855 ++}
  1.2856 ++
  1.2857 ++int replaceDeltaFiles( char *docRoot, char **replaceFiles, char **replaceHash, int numReplaceFiles )
  1.2858 ++{
  1.2859 ++    int i, rc = 0;
  1.2860 ++    char md[MD_SIZE];
  1.2861 ++    
  1.2862 ++    for ( i=0; i<numReplaceFiles && rc==0; i++ ) {
  1.2863 ++
  1.2864 ++		char *tp=strstr(replaceFiles[i],REPPRECURSOR);
  1.2865 ++		if (!tp || strlen(tp)<=(strlen(REPPRECURSOR)+1)) {
  1.2866 ++			syslog(LOG_ERR,"Error replacing %s - skipping it",replaceFiles[i]);
  1.2867 ++		} else {
  1.2868 ++			char orig[PATH_MAX];
  1.2869 ++			snprintf(orig,PATH_MAX,"%s/%s",docRoot,tp+strlen(REPPRECURSOR));
  1.2870 ++			struct stat origstat;
  1.2871 ++			rc=stat(orig,&origstat);
  1.2872 ++			if (rc) {
  1.2873 ++				// this file doesn't exist in DocRoot, so no hash against
  1.2874 ++				// which to compare. Therefore in this case, we're done
  1.2875 ++				;
  1.2876 ++			} else {
  1.2877 ++        		rc=dohash(orig, HASH_SIZE, md);
  1.2878 ++				if (rc<0) {
  1.2879 ++					syslog(LOG_ERR,"Can't hash %s - just replacing it so",orig);
  1.2880 ++				} else {
  1.2881 ++        			if ( strncmp( md, replaceHash[i], MD_SIZE ) ) {
  1.2882 ++						// only action case - put it back in the scratch area
  1.2883 ++						syslog(LOG_INFO,"Hash mismatch - restoring %s",replaceFiles[i]);
  1.2884 ++						rc=unlink(replaceFiles[i]);
  1.2885 ++						if (rc) {
  1.2886 ++							syslog(LOG_ERR,"Can't remove %s - leaving new one so",replaceFiles[i]);
  1.2887 ++						}
  1.2888 ++            			rc = link(orig,replaceFiles[i]);
  1.2889 ++						if (rc) {
  1.2890 ++							syslog(LOG_ERR,"Can't restore %s - leaving new one so",orig);
  1.2891 ++						}
  1.2892 ++        			} 
  1.2893 ++				}
  1.2894 ++			}
  1.2895 ++		}
  1.2896 ++    }
  1.2897 ++    
  1.2898 ++    return rc;
  1.2899 ++}
  1.2900 ++
  1.2901 ++/* make a file name safe - for now just %encode "'" characters
  1.2902 ++ * since we'll be passing the filename inside single quotes
  1.2903 ++ * later
  1.2904 ++ */
  1.2905 ++int makeFileNameSafe(char **fname)
  1.2906 ++{
  1.2907 ++	if (!fname || !*fname) return (-1);
  1.2908 ++	// 0x27 is a single quote (I hope:-)
  1.2909 ++	if (strrchr(*fname,0x27)) {
  1.2910 ++		char *tmp=malloc(PATH_MAX);
  1.2911 ++		if (!tmp) {
  1.2912 ++			syslog(LOG_ERR,"malloc error at %d",__LINE__);
  1.2913 ++			return(-1);
  1.2914 ++		}
  1.2915 ++		char *cp=*fname;
  1.2916 ++		int i=0;
  1.2917 ++		while (*cp!='\0' && i<PATH_MAX) {
  1.2918 ++			if (*cp==0x27) {
  1.2919 ++				if (i>(PATH_MAX-4)) { 
  1.2920 ++					free(tmp); 
  1.2921 ++					syslog(LOG_ERR,"malloc error at %d",__LINE__);
  1.2922 ++					return(-1);
  1.2923 ++				}
  1.2924 ++				tmp[i++]='%';
  1.2925 ++				tmp[i++]='2';
  1.2926 ++				tmp[i++]='7';
  1.2927 ++			} else {
  1.2928 ++				tmp[i++]=*cp;
  1.2929 ++			}
  1.2930 ++			cp++;
  1.2931 ++		}
  1.2932 ++		// now rename the file!
  1.2933 ++		syslog(LOG_INFO,"renaming dodgy file from '%s' to '%s'",
  1.2934 ++					*fname,tmp);
  1.2935 ++		int rv=rename(*fname,tmp);
  1.2936 ++		if (rv) {
  1.2937 ++			syslog(LOG_ERR,"rename from '%s' to '%s' failed",
  1.2938 ++				*fname,tmp);
  1.2939 ++			free(tmp);
  1.2940 ++			return(rv);
  1.2941 ++		}
  1.2942 ++		free(*fname);
  1.2943 ++		*fname=tmp;
  1.2944 ++	}
  1.2945 ++	return(0);
  1.2946 ++}
  1.2947 ++/*******************************************************************
  1.2948 ++* using hg status populate the file lists with the files to be
  1.2949 ++* added, removed or replaced
  1.2950 ++*******************************************************************/
  1.2951 ++int getFileDiff(
  1.2952 ++		char ***adds,
  1.2953 ++		int *numAddFiles,
  1.2954 ++		char ***removes,
  1.2955 ++		int *numRemoveFiles,
  1.2956 ++		char ***replaces,
  1.2957 ++		int *numReplaceFiles)
  1.2958 ++{
  1.2959 ++    int lc, rc;
  1.2960 ++    char hg[PATH_MAX];
  1.2961 ++    char line[PATH_MAX];    
  1.2962 ++    FILE * file;
  1.2963 ++
  1.2964 ++	int add_allocd=0;
  1.2965 ++	int del_allocd=0;
  1.2966 ++	int rep_allocd=0;
  1.2967 ++
  1.2968 ++    // Get file names
  1.2969 ++    snprintf ( hg, PATH_MAX, "(cd %s;hg status today/)  > %s", SRCDIR, STATUS_FILE );//todo the path returned may be rel
  1.2970 ++    syslog ( LOG_INFO, "Checking hg status: %s", hg );   
  1.2971 ++    if ( (rc = system ( hg )) != 0 )
  1.2972 ++    {
  1.2973 ++        syslog ( LOG_ERR, "Error: system call %s returned %d", hg, rc );
  1.2974 ++        return rc;
  1.2975 ++    }  
  1.2976 ++    
  1.2977 ++    // read in status  
  1.2978 ++    file = fopen ( STATUS_FILE , "r" );    
  1.2979 ++    if (file == NULL) {
  1.2980 ++        syslog ( LOG_ERR, "Error opening file %s", STATUS_FILE );
  1.2981 ++        return -1;
  1.2982 ++    }
  1.2983 ++
  1.2984 ++    *numAddFiles = 0;
  1.2985 ++    *numRemoveFiles = 0;
  1.2986 ++    *numReplaceFiles = 0;
  1.2987 ++
  1.2988 ++	// initial space allocation
  1.2989 ++    char **addFiles = (char**) malloc ( sizeof(char*) * MAX_FILES );
  1.2990 ++    char **removeFiles = (char**) malloc ( sizeof(char*) * MAX_FILES );
  1.2991 ++    char **replaceFiles = (char**) malloc ( sizeof(char*) * MAX_FILES ); 
  1.2992 ++
  1.2993 ++	add_allocd=MAX_FILES;
  1.2994 ++	del_allocd=MAX_FILES;
  1.2995 ++	rep_allocd=MAX_FILES;
  1.2996 ++    
  1.2997 ++    for ( lc=0; !feof(file) ; lc++ )    
  1.2998 ++    {
  1.2999 ++        fgets ( line, PATH_MAX, file );
  1.3000 ++		if (line[strlen(line)-1]=='\n') line[strlen(line)-1]=0x00;
  1.3001 ++		if (feof(file)) {
  1.3002 ++			; // after last
  1.3003 ++		} else if( strncmp(line, "A ", 2) == 0 ) {
  1.3004 ++            addFiles[*numAddFiles] = strdup (  &(line[2]) );           //exclude "A " when copying path
  1.3005 ++			int rv=makeFileNameSafe(&addFiles[*numAddFiles]);
  1.3006 ++			// only increment if no problem so we ignore crappy stuff
  1.3007 ++			if (!rv) (*numAddFiles)++;
  1.3008 ++        } else if( strncmp(line, "! ", 2) == 0 ) {
  1.3009 ++            removeFiles[*numRemoveFiles] = strdup( &(line[2]));           //exclude "! " when copying path
  1.3010 ++			int rv=makeFileNameSafe(&removeFiles[*numRemoveFiles]);
  1.3011 ++            if (!rv) (*numRemoveFiles)++;
  1.3012 ++        } else if( strncmp(line, "M ", 2) == 0 ) {
  1.3013 ++            replaceFiles[*numReplaceFiles] = strdup( &(line[2]) );           //exclude "M " when copying path
  1.3014 ++			int rv=makeFileNameSafe(&replaceFiles[*numReplaceFiles]);
  1.3015 ++            if (!rv) (*numReplaceFiles)++;
  1.3016 ++        } else {
  1.3017 ++            syslog ( LOG_ERR, "unexpected line in status file: %s", line );
  1.3018 ++		}
  1.3019 ++
  1.3020 ++		// need more space? then get some
  1.3021 ++		if (*numAddFiles && (*numAddFiles%MAX_FILES==0)) {
  1.3022 ++			char **tmp=(char**)realloc(addFiles,(*numAddFiles+MAX_FILES)*sizeof(char*));
  1.3023 ++			if (!tmp) {
  1.3024 ++            	syslog ( LOG_ERR, "Out of memory, line in status file: %s", line );
  1.3025 ++				return(-1);
  1.3026 ++			}
  1.3027 ++			addFiles=tmp;
  1.3028 ++			add_allocd+=MAX_FILES;
  1.3029 ++		}
  1.3030 ++
  1.3031 ++		// need more space? then get some
  1.3032 ++		if (*numReplaceFiles && (*numReplaceFiles%MAX_FILES==0)) {
  1.3033 ++			char **tmp=(char**)realloc(replaceFiles,(*numReplaceFiles+MAX_FILES)*sizeof(char*));
  1.3034 ++			if (!tmp) {
  1.3035 ++            	syslog ( LOG_ERR, "Out of memory, line in status file: %s", line );
  1.3036 ++				return(-1);
  1.3037 ++			}
  1.3038 ++			replaceFiles=tmp;
  1.3039 ++			rep_allocd+=MAX_FILES;
  1.3040 ++		}
  1.3041 ++
  1.3042 ++		// need more space? then get some
  1.3043 ++		if (*numRemoveFiles && (*numRemoveFiles%MAX_FILES)==0) {
  1.3044 ++			char **tmp=(char**)realloc(removeFiles,(*numRemoveFiles+MAX_FILES)*sizeof(char*));
  1.3045 ++			if (!tmp) {
  1.3046 ++            	syslog ( LOG_ERR, "Out of memory, line in status file: %s", line );
  1.3047 ++				return(-1);
  1.3048 ++			}
  1.3049 ++			removeFiles=tmp;
  1.3050 ++			del_allocd+=MAX_FILES;
  1.3051 ++		}
  1.3052 ++    }   
  1.3053 ++ 
  1.3054 ++    fclose (file);
  1.3055 ++
  1.3056 ++	*adds=addFiles;
  1.3057 ++	*removes=removeFiles;
  1.3058 ++	*replaces=replaceFiles;
  1.3059 ++    return 0;
  1.3060 ++}
  1.3061 ++
  1.3062 ++/*******************************************************************
  1.3063 ++* hash the first 'length' bytes of the file 
  1.3064 ++* and return a pointer the hash
  1.3065 ++*******************************************************************/
  1.3066 ++int dohash(char *filename, int length, char *md)
  1.3067 ++{
  1.3068 ++    FILE * file;
  1.3069 ++    int i, lineSize, dataSize;
  1.3070 ++    char data[length];
  1.3071 ++    char line[100];     
  1.3072 ++    unsigned char obuf[20];
  1.3073 ++    char temp[3];     
  1.3074 ++     
  1.3075 ++    md[0] = '\0';     
  1.3076 ++    data[0] = '\0';
  1.3077 ++    
  1.3078 ++    file = fopen ( filename , "r" );    
  1.3079 ++    if (file == NULL) 
  1.3080 ++    {
  1.3081 ++		int lerrno=errno;
  1.3082 ++		char wd[PATH_MAX];
  1.3083 ++		getcwd(wd,PATH_MAX);
  1.3084 ++        syslog ( LOG_ERR, "Error opening file %s from %s", filename, wd );
  1.3085 ++		syslog( LOG_ERR, "Errno (%d): %s",errno,strerror(lerrno));
  1.3086 ++        return -1;
  1.3087 ++    }
  1.3088 ++
  1.3089 ++    // read 'length' char from file into data
  1.3090 ++    while ( !feof(file) )    
  1.3091 ++    {
  1.3092 ++        fgets ( line, 100, file );
  1.3093 ++        lineSize = strlen( line );
  1.3094 ++        dataSize = strlen( data );
  1.3095 ++        
  1.3096 ++        if( dataSize + lineSize < length )
  1.3097 ++            strncat (data, line, lineSize);
  1.3098 ++        else
  1.3099 ++            break;        
  1.3100 ++    }
  1.3101 ++    fclose (file);
  1.3102 ++       
  1.3103 ++    SHA1( (unsigned char *)data, strlen(data), obuf);  
  1.3104 ++    
  1.3105 ++    for (i = 0; i < 20 ; i++) 
  1.3106 ++    {
  1.3107 ++        snprintf(temp, 2, "%02x", obuf[i]);
  1.3108 ++        strncat (md, temp, 2);        
  1.3109 ++    }    
  1.3110 ++
  1.3111 ++    return 0;
  1.3112 ++}
  1.3113 ++
  1.3114 ++// ConvertInput func is from: http://www.xmlsoft.org/examples/testWriter.c
  1.3115 ++// ConvertOutput I hacked together SF
  1.3116 ++
  1.3117 ++#define MY_ENCODING "ISO-8859-1"
  1.3118 ++
  1.3119 ++/**
  1.3120 ++ * ConvertInput:
  1.3121 ++ * @in: string in a given encoding
  1.3122 ++ * @encoding: the encoding used
  1.3123 ++ *
  1.3124 ++ * Converts @in into UTF-8 for processing with libxml2 APIs
  1.3125 ++ *
  1.3126 ++ * Returns the converted UTF-8 string, or NULL in case of error.
  1.3127 ++ */
  1.3128 ++xmlChar *
  1.3129 ++ConvertInput(const char *in, const char *encoding)
  1.3130 ++{
  1.3131 ++    xmlChar *out;
  1.3132 ++    int ret;
  1.3133 ++    int size;
  1.3134 ++    int out_size;
  1.3135 ++    int temp;
  1.3136 ++    xmlCharEncodingHandlerPtr handler;
  1.3137 ++    if (in == 0)
  1.3138 ++        return 0;
  1.3139 ++    handler = xmlFindCharEncodingHandler(encoding);
  1.3140 ++    if (!handler) {
  1.3141 ++        syslog( LOG_ERR, "ConvertInput: no encoding handler found for '%s'\n",
  1.3142 ++               encoding ? encoding : "");
  1.3143 ++        return 0;
  1.3144 ++    }
  1.3145 ++    size = (int) strlen(in) + 1;
  1.3146 ++    out_size = size * 2 - 1;
  1.3147 ++    out = (unsigned char *) xmlMalloc((size_t) out_size);
  1.3148 ++    if (out != 0) {
  1.3149 ++        temp = size - 1;
  1.3150 ++        ret = handler->input(out, &out_size, (const xmlChar *) in, &temp);
  1.3151 ++        if ((ret < 0) || (temp - size + 1)) {
  1.3152 ++            if (ret < 0) {
  1.3153 ++                syslog(LOG_ERR, "ConvertInput: conversion wasn't successful.\n");
  1.3154 ++            } else {
  1.3155 ++                syslog
  1.3156 ++                    (LOG_ERR, "ConvertInput: conversion wasn't successful. converted: %i octets.\n",
  1.3157 ++                     temp);
  1.3158 ++            }
  1.3159 ++            xmlFree(out);
  1.3160 ++            out = 0;
  1.3161 ++        } else {
  1.3162 ++            out = (unsigned char *) xmlRealloc(out, out_size + 1);
  1.3163 ++            out[out_size] = 0;  /*null terminating out */
  1.3164 ++        }
  1.3165 ++    } else {
  1.3166 ++        syslog(LOG_ERR,"ConvertInput: no mem\n");
  1.3167 ++    }
  1.3168 ++    return out;
  1.3169 ++}
  1.3170 ++
  1.3171 ++/**
  1.3172 ++ * ConvertInput:
  1.3173 ++ * @in: string in a given encoding
  1.3174 ++ * @encoding: the encoding used
  1.3175 ++ *
  1.3176 ++ * Converts @in into UTF-8 for processing with libxml2 APIs
  1.3177 ++ *
  1.3178 ++ * Returns the converted UTF-8 string, or NULL in case of error.
  1.3179 ++ */
  1.3180 ++char *
  1.3181 ++ConvertOutput(const xmlChar *in, const char *encoding)
  1.3182 ++{
  1.3183 ++    char *out;
  1.3184 ++    int ret;
  1.3185 ++    int size;
  1.3186 ++    int out_size;
  1.3187 ++    int temp;
  1.3188 ++    xmlCharEncodingHandlerPtr handler;
  1.3189 ++    if (in == 0)
  1.3190 ++        return 0;
  1.3191 ++    handler = xmlFindCharEncodingHandler(encoding);
  1.3192 ++    if (!handler) {
  1.3193 ++        syslog( LOG_ERR, "ConvertInput: no encoding handler found for '%s'\n",
  1.3194 ++               encoding ? encoding : "");
  1.3195 ++        return 0;
  1.3196 ++    }
  1.3197 ++    size = (int) strlen((char*)in) + 1;
  1.3198 ++    out_size = size * 2 - 1;
  1.3199 ++    out = (char *) malloc((size_t) out_size);
  1.3200 ++    if (out != 0) {
  1.3201 ++        temp = size - 1;
  1.3202 ++        ret = handler->output((unsigned char*)out, &out_size, in, &temp);
  1.3203 ++        if ((ret < 0) || (temp - size + 1)) {
  1.3204 ++            if (ret < 0) {
  1.3205 ++                syslog(LOG_ERR, "ConvertOutput: conversion wasn't successful.\n");
  1.3206 ++            } else {
  1.3207 ++                syslog
  1.3208 ++                    (LOG_ERR, "ConvertOutput: conversion wasn't successful. converted: %i octets.\n",
  1.3209 ++                     temp);
  1.3210 ++            }
  1.3211 ++            free(out);
  1.3212 ++            out = 0;
  1.3213 ++        } else {
  1.3214 ++            out = (char *) realloc(out, out_size + 1);
  1.3215 ++            out[out_size] = 0;  /*null terminating out */
  1.3216 ++        }
  1.3217 ++    } else {
  1.3218 ++        syslog(LOG_ERR,"ConvertOutput: no mem\n");
  1.3219 ++    }
  1.3220 ++    return out;
  1.3221 ++}
  1.3222 ++
  1.3223 ++
  1.3224 ++/*******************************************************************
  1.3225 ++* create an xml file containing the files to be added, removed and 
  1.3226 ++* replaced. 
  1.3227 ++* 
  1.3228 ++* a hash of the files being removed / replaced is also included
  1.3229 ++*******************************************************************/
  1.3230 ++int writeMetadata(char **addFiles, int numAddFiles, char **removeFiles, int numRemoveFiles, char **replaceFiles, int numReplaceFiles, int index)
  1.3231 ++{
  1.3232 ++    int i, rc;
  1.3233 ++    char hashFile[PATH_MAX];
  1.3234 ++    char md[MD_SIZE];
  1.3235 ++    char indexStr[20];
  1.3236 ++    xmlTextWriterPtr writer;
  1.3237 ++    syslog ( LOG_INFO, "Starting to write metadata" );     
  1.3238 ++    // Create a new XmlWriter for filename, with no compression. 
  1.3239 ++    writer = xmlNewTextWriterFilename ( META_FILE, 0 );
  1.3240 ++    if ( writer == NULL ) 
  1.3241 ++    {
  1.3242 ++        syslog ( LOG_ERR, "Error creating the xml writer" );
  1.3243 ++		syslog ( LOG_ERR, "XML error Line: %d",__LINE__);
  1.3244 ++        return -1;
  1.3245 ++    }
  1.3246 ++
  1.3247 ++    // Start the document with the xml default for the version,
  1.3248 ++    // encoding ISO 8859-1 and the default for the standalone declaration.
  1.3249 ++    if ( (rc = xmlTextWriterStartDocument(writer, NULL, MY_ENCODING, NULL)) < 0 ) 
  1.3250 ++    {
  1.3251 ++        syslog ( LOG_ERR, "Error (%d) at xmlTextWriterStartDocument", rc );
  1.3252 ++		syslog ( LOG_ERR, "XML error Line: %d",__LINE__);
  1.3253 ++        return rc;
  1.3254 ++    }  
  1.3255 ++
  1.3256 ++	// need an outer wrapper element
  1.3257 ++    if ( (rc = xmlTextWriterStartElement(writer, BAD_CAST "PushMeta")) < 0 )
  1.3258 ++    {
  1.3259 ++        syslog ( LOG_ERR, "Error (%d) at xmlTextWriterStartElement", rc );
  1.3260 ++		syslog ( LOG_ERR, "XML error Line: %d",__LINE__);
  1.3261 ++        return rc;
  1.3262 ++    }
  1.3263 ++    
  1.3264 ++    // Start an element named "INDEX" . 
  1.3265 ++    snprintf(indexStr, 20, "%d", index );
  1.3266 ++    if ( (rc = xmlTextWriterWriteElement(writer, BAD_CAST "INDEX", BAD_CAST indexStr )) < 0 )
  1.3267 ++    {
  1.3268 ++        syslog ( LOG_ERR, "Error (%d) at xmlTextWriterWriteElement", rc );
  1.3269 ++		syslog ( LOG_ERR, "XML error Line: %d",__LINE__);
  1.3270 ++        return rc;
  1.3271 ++    }
  1.3272 ++        
  1.3273 ++    // Start an element named "ENTRIES".
  1.3274 ++    if ( (rc = xmlTextWriterStartElement(writer, BAD_CAST "ENTRIES")) < 0 ) 
  1.3275 ++    {
  1.3276 ++        syslog ( LOG_ERR, "Error (%d) at xmlTextWriterStartElement", rc );
  1.3277 ++		syslog ( LOG_ERR, "XML error Line: %d",__LINE__);
  1.3278 ++        return rc;
  1.3279 ++    }   
  1.3280 ++    
  1.3281 ++    syslog ( LOG_INFO, "Starting to write metadata add entries" );    
  1.3282 ++    // Write out entries to be added 
  1.3283 ++    // <ENTRY type="add">
  1.3284 ++    //    <FILE>some_file.html</FILE>
  1.3285 ++    // </ENTRY>
  1.3286 ++    for ( i=0; i!=numAddFiles; i++ )
  1.3287 ++    {       
  1.3288 ++        // Start an element named "ENTRY" as child of ENTRIES.         
  1.3289 ++        if ( (rc = xmlTextWriterStartElement(writer, BAD_CAST "ENTRY")) < 0 )
  1.3290 ++        {
  1.3291 ++            syslog ( LOG_ERR, "Error (%d) at xmlTextWriterStartElement", rc );
  1.3292 ++			syslog ( LOG_ERR, "Add count: %d, Line: %d",i,__LINE__);
  1.3293 ++            return rc;
  1.3294 ++        }
  1.3295 ++        
  1.3296 ++        // Add an attribute with name "type" and value "add" to ENTRY.
  1.3297 ++        if ( (rc = xmlTextWriterWriteAttribute(writer, BAD_CAST "type", BAD_CAST TYPE_ADD)) < 0) 
  1.3298 ++        {
  1.3299 ++            syslog ( LOG_ERR, "Error (%d) at xmlTextWriterWriteAttribute %s=%s", rc, "type", TYPE_ADD );
  1.3300 ++			syslog ( LOG_ERR, "Add count: %d, Line: %d",i,__LINE__);
  1.3301 ++            return rc;
  1.3302 ++        }
  1.3303 ++        
  1.3304 ++        // Start an element named "FILE" as child of ENTRY. 
  1.3305 ++
  1.3306 ++		xmlChar *tmp=ConvertInput(addFiles[i],MY_ENCODING);
  1.3307 ++		if (tmp!=NULL) {
  1.3308 ++        	if ( (rc = xmlTextWriterWriteElement(writer, BAD_CAST "FILE", tmp )) < 0 )
  1.3309 ++        	{
  1.3310 ++            	syslog ( LOG_ERR, "Error (%d) at xmlTextWriterWriteElement", rc );
  1.3311 ++				syslog ( LOG_ERR, "Add count: %d, Line: %d",i,__LINE__);
  1.3312 ++            	return rc;
  1.3313 ++        	}
  1.3314 ++		} else {
  1.3315 ++           	syslog ( LOG_ERR, "Eror converting: skipping file %d which is %s",i,addFiles[i]);
  1.3316 ++			syslog ( LOG_ERR, "Add count: %d, Line: %d",i,__LINE__);
  1.3317 ++		}
  1.3318 ++
  1.3319 ++        // Close the element named ENTRY. 
  1.3320 ++        if ( (rc = xmlTextWriterEndElement(writer)) < 0) 
  1.3321 ++        {
  1.3322 ++            syslog ( LOG_ERR, "Error (%d) at xmlTextWriterEndElement", rc );
  1.3323 ++			syslog ( LOG_ERR, "Add count: %d, Line: %d",i,__LINE__);
  1.3324 ++            return rc;
  1.3325 ++        }         
  1.3326 ++    }// end "add" for loop   
  1.3327 ++    
  1.3328 ++
  1.3329 ++    syslog ( LOG_INFO, "Starting to write metadata remove entries" );    
  1.3330 ++    // Write out entries to be removed 
  1.3331 ++    // <ENTRY type="remove">
  1.3332 ++    //    <FILE>some_file.html</FILE>
  1.3333 ++    //    <HASH size="1024" type="SHA1">
  1.3334 ++    //       <MD>AKASDFKJ214231SPDGFUSDFAAN22JF</MD>
  1.3335 ++    //    </HASH>
  1.3336 ++    // </ENTRY>
  1.3337 ++    for ( i=0; i!=numRemoveFiles; i++ )
  1.3338 ++    {
  1.3339 ++		// replace today in filename with yesterday and see if we have it
  1.3340 ++		char *tp=strstr(removeFiles[i],"today/");
  1.3341 ++		if (tp==NULL || (strlen(tp)<=6)) {
  1.3342 ++            syslog ( LOG_ERR, "Can't parse %s to replace today with yesterday. Skipping it.",removeFiles[i]);
  1.3343 ++			syslog ( LOG_ERR, "Rem count: %d, Line: %d",i,__LINE__);
  1.3344 ++			continue;
  1.3345 ++		} 
  1.3346 ++		snprintf(hashFile,PATH_MAX,"%s/yesterday/%s",SRCDIR,tp+6);
  1.3347 ++        if ( (rc = dohash(hashFile, HASH_SIZE, md )) < 0 )
  1.3348 ++        {
  1.3349 ++            syslog ( LOG_ERR, "Can't find %s to hash it. Skipping it.",hashFile);
  1.3350 ++			syslog ( LOG_ERR, "Rem count: %d, Line: %d",i,__LINE__);
  1.3351 ++            continue;
  1.3352 ++        } 
  1.3353 ++
  1.3354 ++        // Start an element named "ENTRY" as child of ENTRIES.
  1.3355 ++        if ( (rc = xmlTextWriterStartElement(writer, BAD_CAST "ENTRY")) < 0 )
  1.3356 ++        {
  1.3357 ++            syslog ( LOG_ERR, "Error (%d) at xmlTextWriterStartElement", rc );
  1.3358 ++			syslog ( LOG_ERR, "Rem count: %d, Line: %d",i,__LINE__);
  1.3359 ++            return rc;
  1.3360 ++        }
  1.3361 ++        
  1.3362 ++        // Add an attribute with name "type" and value "remove" to ENTRY. 
  1.3363 ++        if ( (rc = xmlTextWriterWriteAttribute(writer, BAD_CAST "type", BAD_CAST TYPE_REMOVE)) < 0) 
  1.3364 ++        {
  1.3365 ++            syslog ( LOG_ERR, "Error (%d) at xmlTextWriterWriteAttribute %s=%s", rc, "type", TYPE_REMOVE );
  1.3366 ++			syslog ( LOG_ERR, "Rem count: %d, Line: %d",i,__LINE__);
  1.3367 ++            return rc;
  1.3368 ++        }
  1.3369 ++        
  1.3370 ++        // Add an element named "FILE" as child of ENTRY.      
  1.3371 ++		xmlChar *tmp=ConvertInput(removeFiles[i],MY_ENCODING);
  1.3372 ++		if (tmp!=NULL) {
  1.3373 ++        	if ( (rc = xmlTextWriterWriteElement(writer, BAD_CAST "FILE", tmp )) < 0 )
  1.3374 ++        	{
  1.3375 ++            	syslog ( LOG_ERR, "Error (%d) at xmlTextWriterWriteElement", rc );
  1.3376 ++				syslog ( LOG_ERR, "Add count: %d, Line: %d",i,__LINE__);
  1.3377 ++            	return rc;
  1.3378 ++        	}
  1.3379 ++		} else {
  1.3380 ++           	syslog ( LOG_ERR, "Eror converting: skipping file %d which is %s",i,addFiles[i]);
  1.3381 ++			syslog ( LOG_ERR, "Add count: %d, Line: %d",i,__LINE__);
  1.3382 ++		}
  1.3383 ++
  1.3384 ++        // Start an element named "HASH" as child of ENTRY.    
  1.3385 ++        if ( (rc = xmlTextWriterStartElement(writer, BAD_CAST "HASH")) < 0 )
  1.3386 ++        {
  1.3387 ++            syslog ( LOG_ERR, "Error (%d) at xmlTextWriterWriteElement", rc );
  1.3388 ++			syslog ( LOG_ERR, "Rem count: %d, Line: %d",i,__LINE__);
  1.3389 ++            return rc;
  1.3390 ++        }
  1.3391 ++        
  1.3392 ++        // Add an attribute with name "size" and value "1024" to HASH. 
  1.3393 ++        if ( (rc = xmlTextWriterWriteAttribute(writer, BAD_CAST "size", BAD_CAST HASH_SIZE_STR )) < 0) 
  1.3394 ++        {
  1.3395 ++            syslog ( LOG_ERR, "Error (%d) at xmlTextWriterWriteAttribute %s=%s", rc, "size", HASH_SIZE_STR );
  1.3396 ++			syslog ( LOG_ERR, "Rem count: %d, Line: %d",i,__LINE__);
  1.3397 ++            return rc;
  1.3398 ++        }
  1.3399 ++        // Add an attribute with name "type" and value "SHA1" to HASH. 
  1.3400 ++        if ( (rc = xmlTextWriterWriteAttribute(writer, BAD_CAST "type", BAD_CAST TYPE_HASH )) < 0) 
  1.3401 ++        {
  1.3402 ++            syslog ( LOG_ERR, "Error (%d) at xmlTextWriterWriteAttribute %s=%s", rc, "type", TYPE_HASH );
  1.3403 ++			syslog ( LOG_ERR, "Rem count: %d, Line: %d",i,__LINE__);
  1.3404 ++            return rc;
  1.3405 ++        }        
  1.3406 ++        
  1.3407 ++        // Add an element named "MD" as child of HASH. 
  1.3408 ++        if ( (rc = xmlTextWriterWriteElement(writer, BAD_CAST "MD", BAD_CAST md)) < 0 )  
  1.3409 ++        {
  1.3410 ++            syslog ( LOG_ERR, "Error (%d) at xmlTextWriterWriteElement", rc );
  1.3411 ++			syslog ( LOG_ERR, "Rem count: %d, Line: %d",i,__LINE__);
  1.3412 ++            return rc;
  1.3413 ++        }
  1.3414 ++        
  1.3415 ++        //flush writer so md is not over written
  1.3416 ++        if ( (rc = xmlTextWriterFlush(writer)) < 0 )  
  1.3417 ++        {
  1.3418 ++            syslog ( LOG_ERR, "Error (%d) at xmlTextWriterFlush", rc );
  1.3419 ++			syslog ( LOG_ERR, "Rem count: %d, Line: %d",i,__LINE__);
  1.3420 ++            return rc;
  1.3421 ++        }
  1.3422 ++        
  1.3423 ++        // Close the element named HASH. 
  1.3424 ++        if ( (rc = xmlTextWriterEndElement(writer)) < 0) 
  1.3425 ++        {
  1.3426 ++            syslog ( LOG_ERR, "Error (%d) at xmlTextWriterEndElement", rc );
  1.3427 ++			syslog ( LOG_ERR, "Rem count: %d, Line: %d",i,__LINE__);
  1.3428 ++            return rc;
  1.3429 ++        }  
  1.3430 ++        
  1.3431 ++        // Close the element named ENTRY.
  1.3432 ++        if ( (rc = xmlTextWriterEndElement(writer)) < 0) 
  1.3433 ++        {
  1.3434 ++            syslog ( LOG_ERR, "Error (%d) at xmlTextWriterEndElement", rc );
  1.3435 ++			syslog ( LOG_ERR, "Rem count: %d, Line: %d",i,__LINE__);
  1.3436 ++            return rc;
  1.3437 ++        }         
  1.3438 ++        
  1.3439 ++    }//end "remove" for loop     
  1.3440 ++    
  1.3441 ++    
  1.3442 ++    syslog ( LOG_INFO, "Starting to write metadata replace entries" );        
  1.3443 ++    // Write out entries to be replaced 
  1.3444 ++    // <ENTRY type="replace">
  1.3445 ++    //    <FILE>some_file.html</FILE>
  1.3446 ++    //    <HASH size="1024" type="SHA1">
  1.3447 ++    //       <MD>AKASDFKJ214231SPDGFUSDFAAN22JF</MD>
  1.3448 ++    //    </HASH>
  1.3449 ++    // </ENTRY>
  1.3450 ++    for ( i=0; i!=numReplaceFiles; i++ )
  1.3451 ++    {
  1.3452 ++		// replace today in filename with yesterday and see if we have it
  1.3453 ++		char *tp=strstr(replaceFiles[i],"today/");
  1.3454 ++		if (tp==NULL || (strlen(tp)<=6)) {
  1.3455 ++            syslog ( LOG_ERR, "Can no longer find %s. Skipping it.",replaceFiles[i]);
  1.3456 ++			syslog ( LOG_ERR, "Rep count: %d, Line: %d",i,__LINE__);
  1.3457 ++			continue;
  1.3458 ++		} 
  1.3459 ++		snprintf(hashFile,PATH_MAX,"%s/yesterday/%s",SRCDIR,tp+6);
  1.3460 ++        if ( (rc = dohash(hashFile, HASH_SIZE, md )) < 0 )
  1.3461 ++        {
  1.3462 ++            syslog ( LOG_ERR, "Can no longer find %s to hash it. Skipping it.",replaceFiles[i]);
  1.3463 ++			syslog ( LOG_ERR, "Rep count: %d, Line: %d",i,__LINE__);
  1.3464 ++            continue;
  1.3465 ++        } 
  1.3466 ++        
  1.3467 ++        // Start an element named "ENTRY" as child of ENTRIES.         
  1.3468 ++        if ( (rc = xmlTextWriterStartElement(writer, BAD_CAST "ENTRY")) < 0 )
  1.3469 ++        {
  1.3470 ++            syslog ( LOG_ERR, "Error (%d) at xmlTextWriterStartElement", rc );
  1.3471 ++			syslog ( LOG_ERR, "Rep count: %d, Line: %d",i,__LINE__);
  1.3472 ++            return rc;
  1.3473 ++        }
  1.3474 ++        
  1.3475 ++        // Add an attribute with name "type" and value "remove" to ENTRY. 
  1.3476 ++        if ( (rc = xmlTextWriterWriteAttribute(writer, BAD_CAST "type", BAD_CAST TYPE_REPLACE)) < 0) 
  1.3477 ++        {
  1.3478 ++            syslog ( LOG_ERR, "Error (%d) at xmlTextWriterWriteAttribute %s=%s", rc, "type", TYPE_REPLACE );
  1.3479 ++			syslog ( LOG_ERR, "Rep count: %d, Line: %d",i,__LINE__);
  1.3480 ++            return rc;
  1.3481 ++        }
  1.3482 ++        
  1.3483 ++        // Add an element named "FILE" as child of ENTRY. 
  1.3484 ++		xmlChar *tmp=ConvertInput(replaceFiles[i],MY_ENCODING);
  1.3485 ++		if (tmp!=NULL) {
  1.3486 ++        	if ( (rc = xmlTextWriterWriteElement(writer, BAD_CAST "FILE", tmp )) < 0 )
  1.3487 ++        	{
  1.3488 ++            	syslog ( LOG_ERR, "Error (%d) at xmlTextWriterWriteElement", rc );
  1.3489 ++				syslog ( LOG_ERR, "Add count: %d, Line: %d",i,__LINE__);
  1.3490 ++            	return rc;
  1.3491 ++        	}
  1.3492 ++		} else {
  1.3493 ++           	syslog ( LOG_ERR, "Eror converting: skipping file %d which is %s",i,addFiles[i]);
  1.3494 ++			syslog ( LOG_ERR, "Add count: %d, Line: %d",i,__LINE__);
  1.3495 ++		}
  1.3496 ++        
  1.3497 ++        // Start an element named "HASH" as child of ENTRY. 
  1.3498 ++        if ( (rc = xmlTextWriterStartElement(writer, BAD_CAST "HASH")) < 0 )
  1.3499 ++        {
  1.3500 ++            syslog ( LOG_ERR, "Error (%d) at xmlTextWriterWriteElement", rc );
  1.3501 ++			syslog ( LOG_ERR, "Rep count: %d, Line: %d",i,__LINE__);
  1.3502 ++            return rc;
  1.3503 ++        }
  1.3504 ++        
  1.3505 ++        // Add an attribute with name "size" and value "1024" to HASH.
  1.3506 ++        if ( (rc = xmlTextWriterWriteAttribute(writer, BAD_CAST "size", BAD_CAST HASH_SIZE_STR )) < 0) 
  1.3507 ++        {
  1.3508 ++            syslog ( LOG_ERR, "Error (%d) at xmlTextWriterWriteAttribute %s=%s", rc, "size", HASH_SIZE_STR );
  1.3509 ++			syslog ( LOG_ERR, "Rep count: %d, Line: %d",i,__LINE__);
  1.3510 ++            return rc;
  1.3511 ++        }
  1.3512 ++        // Add an attribute with name "type" and value "SHA1" to HASH.   
  1.3513 ++        if ( (rc = xmlTextWriterWriteAttribute(writer, BAD_CAST "type", BAD_CAST TYPE_HASH )) < 0) 
  1.3514 ++        {
  1.3515 ++            syslog ( LOG_ERR, "Error (%d) at xmlTextWriterWriteAttribute %s=%s", rc, "type", TYPE_HASH );
  1.3516 ++			syslog ( LOG_ERR, "Rep count: %d, Line: %d",i,__LINE__);
  1.3517 ++            return rc;
  1.3518 ++        }        
  1.3519 ++        
  1.3520 ++        // Add an element named "MD" as child of HASH.           
  1.3521 ++        if ( (rc = xmlTextWriterWriteElement(writer, BAD_CAST "MD", BAD_CAST md )) < 0 )  
  1.3522 ++        {
  1.3523 ++            syslog ( LOG_ERR, "Error (%d) at xmlTextWriterWriteElement", rc );
  1.3524 ++			syslog ( LOG_ERR, "Rep count: %d, Line: %d",i,__LINE__);
  1.3525 ++            return rc;
  1.3526 ++        }
  1.3527 ++        
  1.3528 ++        //flush writer so md is not over written
  1.3529 ++        if ( (rc = xmlTextWriterFlush(writer)) < 0 )  
  1.3530 ++        {
  1.3531 ++            syslog ( LOG_ERR, "Error (%d) at xmlTextWriterFlush", rc );
  1.3532 ++			syslog ( LOG_ERR, "Rep count: %d, Line: %d",i,__LINE__);
  1.3533 ++            return rc;
  1.3534 ++        }
  1.3535 ++        
  1.3536 ++        // Close the element named HASH.   
  1.3537 ++        if ( (rc = xmlTextWriterEndElement(writer)) < 0) 
  1.3538 ++        {
  1.3539 ++            syslog ( LOG_ERR, "Error (%d) at xmlTextWriterEndElement", rc );
  1.3540 ++			syslog ( LOG_ERR, "Rep count: %d, Line: %d",i,__LINE__);
  1.3541 ++            return rc;
  1.3542 ++        }  
  1.3543 ++        
  1.3544 ++        // Close the element named ENTRY.   
  1.3545 ++        if ( (rc = xmlTextWriterEndElement(writer)) < 0) 
  1.3546 ++        {
  1.3547 ++            syslog ( LOG_ERR, "Error (%d) at xmlTextWriterEndElement", rc );
  1.3548 ++			syslog ( LOG_ERR, "Rep count: %d, Line: %d",i,__LINE__);
  1.3549 ++            return rc;
  1.3550 ++        }         
  1.3551 ++        
  1.3552 ++    }//end "replace" for loop     
  1.3553 ++    
  1.3554 ++    // Close the element named ENTRIES.
  1.3555 ++    if ( (rc = xmlTextWriterEndElement(writer)) < 0) 
  1.3556 ++    {
  1.3557 ++        syslog ( LOG_ERR, "Error (%d) at xmlTextWriterEndElement", rc );
  1.3558 ++		syslog ( LOG_ERR, "XML error Line: %d",__LINE__);
  1.3559 ++        return rc;
  1.3560 ++    } 
  1.3561 ++
  1.3562 ++	// need an outer wrapper element
  1.3563 ++    if ( (rc = xmlTextWriterEndElement(writer)) < 0 )
  1.3564 ++    {
  1.3565 ++        syslog ( LOG_ERR, "Error (%d) at xmlTextWriterEndElement", rc );
  1.3566 ++		syslog ( LOG_ERR, "XML error Line: %d",__LINE__);
  1.3567 ++        return rc;
  1.3568 ++    }
  1.3569 ++
  1.3570 ++    // Here we could close the elements ORDER and EXAMPLE using the
  1.3571 ++    // function xmlTextWriterEndElement, but since we do not want to
  1.3572 ++    // write any other elements, we simply call xmlTextWriterEndDocument,
  1.3573 ++    // which will do all the work. 
  1.3574 ++    if ( (rc = xmlTextWriterEndDocument(writer)) < 0) 
  1.3575 ++    {
  1.3576 ++        syslog ( LOG_ERR, "Error (%d) at xmlTextWriterEndDocument", rc );
  1.3577 ++		syslog ( LOG_ERR, "XML error Line: %d",__LINE__);
  1.3578 ++        return rc;
  1.3579 ++    }
  1.3580 ++
  1.3581 ++    xmlFreeTextWriter(writer);
  1.3582 ++	syslog ( LOG_INFO, "Finished writing metadata" );    
  1.3583 ++    return rc;
  1.3584 ++}
  1.3585 ++
  1.3586 ++
  1.3587 ++/*******************************************************************
  1.3588 ++* read filenames and hash values from xml file
  1.3589 ++*******************************************************************/
  1.3590 ++int readMetaData(
  1.3591 ++		char ***addf,
  1.3592 ++		int *numAddFiles,
  1.3593 ++		char ***remf,
  1.3594 ++		char ***remhash,
  1.3595 ++		int *numRemoveFiles,
  1.3596 ++		char ***repf,
  1.3597 ++		char ***rephash,
  1.3598 ++		int *numReplaceFiles,
  1.3599 ++		int *index)
  1.3600 ++{
  1.3601 ++    xmlDocPtr doc;
  1.3602 ++    xmlXPathContextPtr xpathCtx; 
  1.3603 ++    xmlXPathObjectPtr xpathObj; 
  1.3604 ++    xmlNodeSetPtr nodes;
  1.3605 ++    int size;
  1.3606 ++    int i;    
  1.3607 ++    
  1.3608 ++    *numAddFiles = 0;   
  1.3609 ++    *numRemoveFiles = 0;
  1.3610 ++    *numReplaceFiles = 0;
  1.3611 ++
  1.3612 ++    // Load XML document 
  1.3613 ++    doc = xmlParseFile(RXMETA_FILE);
  1.3614 ++    if (doc == NULL) 
  1.3615 ++    {
  1.3616 ++	    fprintf(stderr, "Error: unable to parse file \"%s\"\n", RXMETA_FILE);
  1.3617 ++    	return(-1);
  1.3618 ++    }
  1.3619 ++
  1.3620 ++    // Create xpath evaluation context 
  1.3621 ++    xpathCtx = xmlXPathNewContext(doc);
  1.3622 ++    if(xpathCtx == NULL) 
  1.3623 ++    {
  1.3624 ++        fprintf(stderr,"Error: unable to create new XPath context\n");
  1.3625 ++        xmlFreeDoc(doc); 
  1.3626 ++        return(-1);
  1.3627 ++    }
  1.3628 ++    
  1.3629 ++    // Evaluate xpath expression  
  1.3630 ++    xpathObj = xmlXPathEvalExpression(BAD_CAST "/PushMeta/INDEX/text()", xpathCtx);    
  1.3631 ++
  1.3632 ++    nodes = xpathObj->nodesetval;    
  1.3633 ++	if (!nodes || !nodes->nodeNr) {
  1.3634 ++		syslog( LOG_ERR, "Missing index in xml");
  1.3635 ++		*index=-1;
  1.3636 ++	} else {
  1.3637 ++		char tmp[PATH_MAX];
  1.3638 ++		snprintf(tmp,PATH_MAX,(char*)nodes->nodeTab[0]->content);
  1.3639 ++    	*index = atoi(tmp);
  1.3640 ++	}
  1.3641 ++    
  1.3642 ++    // Evaluate xpath expression  
  1.3643 ++    xpathObj = xmlXPathEvalExpression(BAD_CAST "/PushMeta/ENTRIES/ENTRY[@type='add']/FILE/text()", xpathCtx);    
  1.3644 ++    nodes = xpathObj->nodesetval;
  1.3645 ++	if (!nodes) size=0;
  1.3646 ++    else size = nodes->nodeNr;
  1.3647 ++    *numAddFiles = size;
  1.3648 ++
  1.3649 ++	// more space if necessary
  1.3650 ++	char **addFiles=(char**)malloc(size*sizeof(char*));
  1.3651 ++	if (!addFiles) {
  1.3652 ++		syslog( LOG_ERR, "Out of memory at %d",__LINE__);
  1.3653 ++		return(-1);
  1.3654 ++	}
  1.3655 ++
  1.3656 ++    for(i = 0; i < size; i++) {
  1.3657 ++		addFiles[i]=ConvertOutput(nodes->nodeTab[i]->content,MY_ENCODING);
  1.3658 ++        if (!addFiles[i]){
  1.3659 ++			syslog(LOG_ERR,"Can't convert at %d",__LINE__);
  1.3660 ++			addFiles[i]=strdup("Dummy");
  1.3661 ++		}
  1.3662 ++	}
  1.3663 ++
  1.3664 ++    // Evaluate xpath expression  
  1.3665 ++    xpathObj = xmlXPathEvalExpression(BAD_CAST "/PushMeta/ENTRIES/ENTRY[@type='remove']/FILE/text()", xpathCtx);    
  1.3666 ++    
  1.3667 ++    nodes = xpathObj->nodesetval;
  1.3668 ++	if (!nodes) size=0;
  1.3669 ++    else size = nodes->nodeNr;
  1.3670 ++    *numRemoveFiles = size;
  1.3671 ++	// more space if necessary
  1.3672 ++	char **removeFiles=(char**)malloc(size*sizeof(char*));
  1.3673 ++	if (!removeFiles) {
  1.3674 ++		syslog( LOG_ERR, "Out of memory at %d",__LINE__);
  1.3675 ++		return(-1);
  1.3676 ++	}
  1.3677 ++	char **removeHash=(char**)malloc(size*sizeof(char*));
  1.3678 ++	if (!removeHash) {
  1.3679 ++		syslog( LOG_ERR, "Out of memory at %d",__LINE__);
  1.3680 ++		return(-1);
  1.3681 ++	}
  1.3682 ++
  1.3683 ++    for(i = 0; i < size; i++) {
  1.3684 ++		removeFiles[i]=ConvertOutput(nodes->nodeTab[i]->content,MY_ENCODING);
  1.3685 ++		if (!removeFiles[i]) {
  1.3686 ++			syslog(LOG_ERR,"Can't convert at %d",__LINE__);
  1.3687 ++			removeFiles[i]=strdup("Dummy");
  1.3688 ++		}
  1.3689 ++	}
  1.3690 ++
  1.3691 ++    xpathObj = xmlXPathEvalExpression(BAD_CAST "/PushMeta/ENTRIES/ENTRY[@type='remove']/HASH/MD/text()", xpathCtx);    
  1.3692 ++    
  1.3693 ++    nodes = xpathObj->nodesetval;
  1.3694 ++	if (!nodes) size=0;
  1.3695 ++    else size = nodes->nodeNr;
  1.3696 ++    
  1.3697 ++    for(i = 0; i < size; i++) 
  1.3698 ++        removeHash[i] = strdup((char*)nodes->nodeTab[i]->content);
  1.3699 ++        
  1.3700 ++    // Evaluate xpath expression  
  1.3701 ++    xpathObj = xmlXPathEvalExpression(BAD_CAST "/PushMeta/ENTRIES/ENTRY[@type='replace']/FILE/text()", xpathCtx);    
  1.3702 ++    
  1.3703 ++    nodes = xpathObj->nodesetval;
  1.3704 ++	if (!nodes) size=0;
  1.3705 ++    else size = nodes->nodeNr;
  1.3706 ++    *numReplaceFiles = size;
  1.3707 ++	// more space if necessary
  1.3708 ++	char **replaceFiles=(char**)malloc(size*sizeof(char*));
  1.3709 ++	if (!replaceFiles) {
  1.3710 ++		syslog( LOG_ERR, "Out of memory at %d",__LINE__);
  1.3711 ++		return(-1);
  1.3712 ++	}
  1.3713 ++	char **replaceHash=(char**)malloc(size*sizeof(char*));
  1.3714 ++	if (!replaceHash) {
  1.3715 ++		syslog( LOG_ERR, "Out of memory at %d",__LINE__);
  1.3716 ++		return(-1);
  1.3717 ++	}
  1.3718 ++
  1.3719 ++    for(i = 0; i < size; i++) {
  1.3720 ++		replaceFiles[i]=ConvertOutput(nodes->nodeTab[i]->content,MY_ENCODING);
  1.3721 ++		if (!replaceFiles[i]) {
  1.3722 ++			syslog(LOG_ERR,"Can't convert at %d",__LINE__);
  1.3723 ++			replaceFiles[i]=strdup("Dummy");
  1.3724 ++		}
  1.3725 ++	}
  1.3726 ++    
  1.3727 ++    xpathObj = xmlXPathEvalExpression(BAD_CAST "/PushMeta/ENTRIES/ENTRY[@type='replace']/HASH/MD/text()", xpathCtx);    
  1.3728 ++    
  1.3729 ++    nodes = xpathObj->nodesetval;
  1.3730 ++	if (!nodes) size=0;
  1.3731 ++    else size = nodes->nodeNr;
  1.3732 ++    
  1.3733 ++    for(i = 0; i < size; i++) 
  1.3734 ++        replaceHash[i] = strdup((char*)nodes->nodeTab[i]->content);
  1.3735 ++
  1.3736 ++    // Cleanup   
  1.3737 ++    xmlXPathFreeObject(xpathObj);
  1.3738 ++    xmlXPathFreeContext(xpathCtx); 
  1.3739 ++    xmlFreeDoc(doc); 
  1.3740 ++
  1.3741 ++	*addf=addFiles;
  1.3742 ++	*remf=removeFiles;
  1.3743 ++	*remhash=removeHash;
  1.3744 ++	*repf=replaceFiles;
  1.3745 ++	*rephash=replaceHash;
  1.3746 ++    
  1.3747 ++    return 0;
  1.3748 ++}
  1.3749 ++
  1.3750 ++int getIndex()
  1.3751 ++{
  1.3752 ++    FILE *file = fopen( INDEX_FILE, "r" );
  1.3753 ++    int index;
  1.3754 ++    char indexStr[16];
  1.3755 ++    
  1.3756 ++    if ( file == 0 ) 
  1.3757 ++    {
  1.3758 ++        syslog ( LOG_ERR, "Could not open index file: %s - restarting index at 000 ", INDEX_FILE );       
  1.3759 ++        index = 0;
  1.3760 ++        updateIndex( index + 1 );
  1.3761 ++        return index;
  1.3762 ++    }    
  1.3763 ++    
  1.3764 ++    fgets(indexStr, 16, file);        
  1.3765 ++    index = atoi(indexStr);
  1.3766 ++    syslog ( LOG_INFO, "Opened index file, index is: %d", index);        
  1.3767 ++    
  1.3768 ++    fclose( file );
  1.3769 ++    return index;
  1.3770 ++}
  1.3771 ++
  1.3772 ++int updateIndex(int index)
  1.3773 ++{
  1.3774 ++    FILE *file = fopen( INDEX_FILE, "w" );
  1.3775 ++    char indexStr[16];
  1.3776 ++    
  1.3777 ++    if ( file == 0 ) 
  1.3778 ++    {
  1.3779 ++        syslog ( LOG_ERR, "Could not open index file: %s for writing ", INDEX_FILE );  
  1.3780 ++        return -1;
  1.3781 ++    }    
  1.3782 ++    
  1.3783 ++    snprintf ( indexStr, 15, "%d", index );
  1.3784 ++    fputs(indexStr, file);        
  1.3785 ++    
  1.3786 ++    syslog ( LOG_INFO, "Writing index %d to file %s", index, INDEX_FILE );        
  1.3787 ++    
  1.3788 ++    fclose( file );
  1.3789 ++    return 0;
  1.3790 ++}
  1.3791 +diff -r b0407e525e08 -r 875893b4fede apps/dtnN4Cmiddle/pushedContent.h
  1.3792 +--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
  1.3793 ++++ b/apps/dtnN4Cmiddle/pushedContent.h	Thu Apr 21 15:19:21 2011 +0000
  1.3794 +@@ -0,0 +1,62 @@
  1.3795 ++// gcc -g -fno-inline  -fPIC -DPIC -MMD -MP -MT "dtnN4Cmiddle/dtnN4Crecv.o dtnN4Cmiddle/dtnN4Crecv.E"  -DHAVE_CONFIG_H -D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64 -I.. -I.. -I/home/aidan/build/DTN2-N4C/oasys/include -I/home/aidan/build/DTN2-N4C/oasys/include/oasys/ext -I../servlib -I/usr/include/tcl8.5 -I/usr/include/libxml2 -lxml2 -lcrypto -Wall -W -Wcast-align  -I../applib  dtnN4Cmiddle/dtnN4Crecv.c dtnN4Cmiddle/pushedContent.h dtnN4Cmiddle/pushedContent.c  -o dtnN4Cmiddle/dtnN4Crecv.o
  1.3796 ++
  1.3797 ++#ifndef PUSHED_CONTENT
  1.3798 ++#define PUSHED_CONTENT
  1.3799 ++
  1.3800 ++#include <stdio.h>
  1.3801 ++#include <stdlib.h>
  1.3802 ++#include <string.h>
  1.3803 ++#include <syslog.h>
  1.3804 ++
  1.3805 ++#include <openssl/sha.h>
  1.3806 ++
  1.3807 ++#include <libxml/encoding.h>
  1.3808 ++#include <libxml/xmlwriter.h>
  1.3809 ++#include <libxml/tree.h>
  1.3810 ++#include <libxml/parser.h>
  1.3811 ++#include <libxml/xpath.h>
  1.3812 ++#include <libxml/xpathInternals.h>
  1.3813 ++
  1.3814 ++#include "dtn_api.h"
  1.3815 ++
  1.3816 ++#define MD_SIZE         80
  1.3817 ++#define HASH_SIZE       4096
  1.3818 ++#define HASH_SIZE_STR   "4096"
  1.3819 ++#define TYPE_HASH       "SHA1"
  1.3820 ++
  1.3821 ++#define TYPE_ADD        "add"
  1.3822 ++#define TYPE_REMOVE     "remove"
  1.3823 ++#define TYPE_REPLACE    "replace"
  1.3824 ++
  1.3825 ++#define MAX_FILES       PATH_MAX
  1.3826 ++#define MAX_DEST_URI    PATH_MAX
  1.3827 ++
  1.3828 ++#define LOCALDIR             "N4Csites"
  1.3829 ++
  1.3830 ++// used by pushedcontent
  1.3831 ++#define ADDPRECURSOR "today/N4Csites/"
  1.3832 ++#define DELPRECURSOR "today/N4Csites/"
  1.3833 ++#define REPPRECURSOR "today/N4Csites/"
  1.3834 ++    
  1.3835 ++
  1.3836 ++#if defined(LIBXML_WRITER_ENABLED) && defined(LIBXML_OUTPUT_ENABLED)
  1.3837 ++    #define MY_ENCODING "ISO-8859-1"
  1.3838 ++#endif
  1.3839 ++
  1.3840 ++int send_pushed_content(dtn_endpoint_id_t *source_eid);
  1.3841 ++int recv_pushed_content(dtn_bundle_payload_t payload);
  1.3842 ++
  1.3843 ++int addDeltaFiles( char *docRoot,char **addFiles, int numAddFiles );
  1.3844 ++int removeDeltaFiles( char *docRoot,char **removeFiles, char **removeHash, int numRemoveFiles );
  1.3845 ++int replaceDeltaFiles( char *docRoot,char **replaceFiles, char **replaceHash, int numReplaceFiles );
  1.3846 ++
  1.3847 ++int getFileDiff(char ***addFiles, int *numAddFiles, char ***removeFiles, int *numRemoveFiles, char ***replaceFiles, int *numReplaceFiles);
  1.3848 ++int dohash(char *filename, int length, char *md);
  1.3849 ++int writeMetadata(char **addFiles, int numAddFiles, char **removeFiles, int numRemoveFiles, char **replaceFiles, int numReplaceFiles, int index);
  1.3850 ++int readMetaData(char ***addFiles, int *numAddFiles, char ***removeFiles, char ***removeHash, int *numRemoveFiles, char ***replaceFiles, char ***replaceHash, int *numReplaceFiles, int *index);
  1.3851 ++
  1.3852 ++int getIndex();
  1.3853 ++int updateIndex(int index);
  1.3854 ++int getDestinationUris(char **destinationUris, int *numUris);
  1.3855 ++#endif
  1.3856 ++
  1.3857 +diff -r b0407e525e08 -r 875893b4fede apps/dtnN4Cmiddle/rsslinks.sh
  1.3858 +--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
  1.3859 ++++ b/apps/dtnN4Cmiddle/rsslinks.sh	Thu Apr 21 15:19:21 2011 +0000
  1.3860 +@@ -0,0 +1,14 @@
  1.3861 ++
  1.3862 ++dirs=N4Csites/*.se
  1.3863 ++
  1.3864 ++rsses=`find $dirs -name *.rss`
  1.3865 ++
  1.3866 ++for rss in $rsses 
  1.3867 ++do
  1.3868 ++	echo "Doing: $rss"
  1.3869 ++	cp $rss /tmp/thisone
  1.3870 ++	cat /tmp/thisone | sed -e 's/<link>/\
  1.3871 ++<link>/g' >/tmp/thisone2
  1.3872 ++	grep "<link>" /tmp/thisone2 | sed -e 's/^.*<link>//g'  | sed -e 's/<\/link>.*//' >>stories
  1.3873 ++done
  1.3874 ++
  1.3875 +diff -r b0407e525e08 -r 875893b4fede apps/dtnN4Cmiddle/tN4C_bundle
  1.3876 +Binary file apps/dtnN4Cmiddle/tN4C_bundle has changed
  1.3877 +diff -r b0407e525e08 -r 875893b4fede apps/dtnN4Cmiddle/tN4C_bundle.c
  1.3878 +--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
  1.3879 ++++ b/apps/dtnN4Cmiddle/tN4C_bundle.c	Thu Apr 21 15:19:21 2011 +0000
  1.3880 +@@ -0,0 +1,34 @@
  1.3881 ++/*
  1.3882 ++ *      tN4C_bundle.c
  1.3883 ++ *      
  1.3884 ++ *      Nelson Dopico <nelson@wsn-laptop>
  1.3885 ++ * 
  1.3886 ++ */
  1.3887 ++
  1.3888 ++
  1.3889 ++#include <stdio.h>
  1.3890 ++#include <sys/types.h>
  1.3891 ++#include "middle_api.h"
  1.3892 ++
  1.3893 ++int main(int argc, char** argv)
  1.3894 ++{
  1.3895 ++    char bndlDest [EID_MAX_LENGTH + 1]      = "dtn://sphere.dtn/HTMLgateway";
  1.3896 ++	char bndlSrc [EID_MAX_LENGTH + 1]       = "dtn://sphere.dtn/HTMLrouter";
  1.3897 ++	char bndlRply_to [EID_MAX_LENGTH + 1]   = "dtn://sphere.dtn/HTMLrouter";
  1.3898 ++	
  1.3899 ++	char eid_string [EID_MAX_LENGTH] = "EID String testing #############@@@";
  1.3900 ++	int err;
  1.3901 ++	
  1.3902 ++	err = procHTTPreq (bndlDest, bndlSrc, bndlRply_to, (uint8_t *) eid_string, strlen(eid_string) + 1);
  1.3903 ++	
  1.3904 ++	if (!err)
  1.3905 ++		printf("DEBUG - Bundle successfully sent\n");
  1.3906 ++	else
  1.3907 ++	{
  1.3908 ++		printf("DEBUG - Error on sent, code %d\n", err);
  1.3909 ++		//perror("DEBUG - Error on sent");
  1.3910 ++	}
  1.3911 ++		
  1.3912 ++	
  1.3913 ++	return 0;
  1.3914 ++}
  1.3915 +diff -r b0407e525e08 -r 875893b4fede apps/dtnN4Cmiddle/tN4C_socket.c
  1.3916 +--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
  1.3917 ++++ b/apps/dtnN4Cmiddle/tN4C_socket.c	Thu Apr 21 15:19:21 2011 +0000
  1.3918 +@@ -0,0 +1,73 @@
  1.3919 ++/*
  1.3920 ++ *      TCP_test.cpp
  1.3921 ++ *      
  1.3922 ++ *      Nelson Dopico <nelson@wsn-laptop>
  1.3923 ++ *      
  1.3924 ++ */
  1.3925 ++
  1.3926 ++
  1.3927 ++#include <iostream>
  1.3928 ++
  1.3929 ++#include <stdio.h>
  1.3930 ++
  1.3931 ++#include <string.h>
  1.3932 ++#include <sys/types.h>
  1.3933 ++
  1.3934 ++#include <netdb.h>
  1.3935 ++
  1.3936 ++//For the socket management
  1.3937 ++#include <sys/socket.h>
  1.3938 ++#include <arpa/inet.h>
  1.3939 ++
  1.3940 ++
  1.3941 ++#define RECV_BUFFER_SIZE	(512 + 4096)	//HTTP req max length (other fields + URL)
  1.3942 ++
  1.3943 ++int main(int argc, char** argv)
  1.3944 ++{
  1.3945 ++	
  1.3946 ++	sockaddr_in server_addr;		//Internet family socket to listen on
  1.3947 ++	sockaddr * serverAddrCast = (sockaddr *) & server_addr;
  1.3948 ++	int sockFd;	//Socket file descriptor for sending and receiving
  1.3949 ++	int recvByteLen;
  1.3950 ++	char recvBuffer [RECV_BUFFER_SIZE];
  1.3951 ++	
  1.3952 ++	struct hostent *server;
  1.3953 ++	
  1.3954 ++	//char serverName [] = "127.0.0.1";
  1.3955 ++	
  1.3956 ++	char strSent [] = "Hello world, just testing a socket";
  1.3957 ++	
  1.3958 ++
  1.3959 ++	
  1.3960 ++	/* Create socket*/
  1.3961 ++	sockFd = socket (AF_INET, SOCK_STREAM, 0) ;	// get a tcp/ip socket
  1.3962 ++	
  1.3963 ++	memset (&server_addr , 0, sizeof (server_addr) ) ;
  1.3964 ++	server = gethostbyname("localhost");
  1.3965 ++	memcpy (&(server_addr.sin_addr.s_addr), server->h_addr, server->h_length);
  1.3966 ++	
  1.3967 ++	server_addr.sin_family = AF_INET ;
  1.3968 ++
  1.3969 ++	server_addr.sin_port = htons (9090);
  1.3970 ++	
  1.3971 ++	printf("DEBUG - Hello world 1st\n");
  1.3972 ++	
  1.3973 ++	if(connect (sockFd, (struct sockaddr *) serverAddrCast, sizeof(server_addr)) != 0)
  1.3974 ++		perror("DEBUG - Error on connect\n");
  1.3975 ++	
  1.3976 ++	printf("DEBUG - Hello world 2nd\n");
  1.3977 ++	
  1.3978 ++	if(send(sockFd, strSent, strlen(strSent) + 1, 0) == -1)
  1.3979 ++		printf("DEBUG - Error on send\n");
  1.3980 ++	
  1.3981 ++	printf("DEBUG - Hello world 3rd\n");
  1.3982 ++			
  1.3983 ++	recvByteLen = recv(sockFd, recvBuffer, RECV_BUFFER_SIZE, 0);
  1.3984 ++	
  1.3985 ++	if(strcmp(strSent, recvBuffer) == 0)
  1.3986 ++		printf("DEBUG - Sent and received Strings are the same\n");
  1.3987 ++	
  1.3988 ++	printf("DEBUG - Hello world\n");	
  1.3989 ++	
  1.3990 ++	return 0;
  1.3991 ++}
  1.3992 +diff -r b0407e525e08 -r 875893b4fede apps/dtnN4Cmiddle/tN4C_socket.cpp
  1.3993 +--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
  1.3994 ++++ b/apps/dtnN4Cmiddle/tN4C_socket.cpp	Thu Apr 21 15:19:21 2011 +0000
  1.3995 +@@ -0,0 +1,73 @@
  1.3996 ++/*
  1.3997 ++ *      TCP_test.cpp
  1.3998 ++ *      
  1.3999 ++ *      Nelson Dopico <nelson@wsn-laptop>
  1.4000 ++ *      
  1.4001 ++ */
  1.4002 ++
  1.4003 ++
  1.4004 ++#include <iostream>
  1.4005 ++
  1.4006 ++#include <stdio.h>
  1.4007 ++
  1.4008 ++#include <string.h>
  1.4009 ++#include <sys/types.h>
  1.4010 ++
  1.4011 ++#include <netdb.h>
  1.4012 ++
  1.4013 ++//For the socket management
  1.4014 ++#include <sys/socket.h>
  1.4015 ++#include <arpa/inet.h>
  1.4016 ++
  1.4017 ++
  1.4018 ++#define RECV_BUFFER_SIZE	(512 + 4096)	//HTTP req max length (other fields + URL)
  1.4019 ++
  1.4020 ++int main(int argc, char** argv)
  1.4021 ++{
  1.4022 ++	
  1.4023 ++	sockaddr_in server_addr;		//Internet family socket to listen on
  1.4024 ++	sockaddr * serverAddrCast = (sockaddr *) & server_addr;
  1.4025 ++	int sockFd;	//Socket file descriptor for sending and receiving
  1.4026 ++	int recvByteLen;
  1.4027 ++	char recvBuffer [RECV_BUFFER_SIZE];
  1.4028 ++	
  1.4029 ++	struct hostent *server;
  1.4030 ++	
  1.4031 ++	//char serverName [] = "127.0.0.1";
  1.4032 ++	
  1.4033 ++	char strSent [] = "Hello world, just testing a socket";
  1.4034 ++	
  1.4035 ++
  1.4036 ++	
  1.4037 ++	/* Create socket*/
  1.4038 ++	sockFd = socket (AF_INET, SOCK_STREAM, 0) ;	// get a tcp/ip socket
  1.4039 ++	
  1.4040 ++	memset (&server_addr , 0, sizeof (server_addr) ) ;
  1.4041 ++	server = gethostbyname("localhost");
  1.4042 ++	memcpy (&(server_addr.sin_addr.s_addr), server->h_addr, server->h_length);
  1.4043 ++	
  1.4044 ++	server_addr.sin_family = AF_INET ;
  1.4045 ++
  1.4046 ++	server_addr.sin_port = htons (9090);
  1.4047 ++	
  1.4048 ++	printf("DEBUG - Hello world 1st\n");
  1.4049 ++	
  1.4050 ++	if(connect (sockFd, (struct sockaddr *) serverAddrCast, sizeof(server_addr)) != 0)
  1.4051 ++		perror("DEBUG - Error on connect\n");
  1.4052 ++	
  1.4053 ++	printf("DEBUG - Hello world 2nd\n");
  1.4054 ++	
  1.4055 ++	if(send(sockFd, strSent, strlen(strSent) + 1, 0) == -1)
  1.4056 ++		printf("DEBUG - Error on send\n");
  1.4057 ++	
  1.4058 ++	printf("DEBUG - Hello world 3rd\n");
  1.4059 ++			
  1.4060 ++	recvByteLen = recv(sockFd, recvBuffer, RECV_BUFFER_SIZE, 0);
  1.4061 ++	
  1.4062 ++	if(strcmp(strSent, recvBuffer) == 0)
  1.4063 ++		printf("DEBUG - Sent and received Strings are the same\n");
  1.4064 ++	
  1.4065 ++	printf("DEBUG - Hello world\n");	
  1.4066 ++	
  1.4067 ++	return 0;
  1.4068 ++}
  1.4069 +diff -r b0407e525e08 -r 875893b4fede servlib/contacts/Link.cc
  1.4070 +--- a/servlib/contacts/Link.cc	Thu Apr 21 13:15:00 2011 +0000
  1.4071 ++++ b/servlib/contacts/Link.cc	Thu Apr 21 15:19:21 2011 +0000
  1.4072 +@@ -39,6 +39,7 @@
  1.4073 + /// Default parameters, values overridden in ParamCommand
  1.4074 + Link::Params::Params()
  1.4075 +     : mtu_(0),
  1.4076 ++	  rg_(-1),
  1.4077 +       min_retry_interval_(5),
  1.4078 +       max_retry_interval_(10 * 60),
  1.4079 +       idle_close_time_(0),
  1.4080 +@@ -313,6 +314,7 @@
  1.4081 +     p.addopt(new oasys::BoolOpt("reliable", &reliable_));
  1.4082 +     p.addopt(new oasys::StringOpt("nexthop", &nexthop_));
  1.4083 +     p.addopt(new oasys::UIntOpt("mtu", &params_.mtu_));
  1.4084 ++    p.addopt(new oasys::IntOpt("rg", &params_.rg_));
  1.4085 +     p.addopt(new oasys::UIntOpt("min_retry_interval",
  1.4086 +                                 &params_.min_retry_interval_));
  1.4087 +     p.addopt(new oasys::UIntOpt("max_retry_interval",
  1.4088 +@@ -605,6 +607,7 @@
  1.4089 +                  "nexthop: %s\n"
  1.4090 +                  "remote eid: %s\n"
  1.4091 +                  "mtu: %u\n"
  1.4092 ++                 "rg: %d\n"
  1.4093 +                  "min_retry_interval: %u\n"
  1.4094 +                  "max_retry_interval: %u\n"
  1.4095 +                  "idle_close_time: %u\n"
  1.4096 +@@ -618,6 +621,7 @@
  1.4097 +                  nexthop(),
  1.4098 +                  remote_eid_.c_str(),
  1.4099 +                  params_.mtu_,
  1.4100 ++                 params_.rg_,
  1.4101 +                  params_.min_retry_interval_,
  1.4102 +                  params_.max_retry_interval_,
  1.4103 +                  params_.idle_close_time_,
  1.4104 +diff -r b0407e525e08 -r 875893b4fede servlib/contacts/Link.h
  1.4105 +--- a/servlib/contacts/Link.h	Thu Apr 21 13:15:00 2011 +0000
  1.4106 ++++ b/servlib/contacts/Link.h	Thu Apr 21 15:19:21 2011 +0000
  1.4107 +@@ -496,6 +496,13 @@
  1.4108 +          * MTU of the link, used to control proactive fragmentation.
  1.4109 +          */
  1.4110 +         u_int mtu_;
  1.4111 ++
  1.4112 ++		/**
  1.4113 ++		 * Red/Green for LTP links 
  1.4114 ++		 * XXXSF This shouldn't be here but I'm not sure how to make it LTP specific - Stephen Farrell
  1.4115 ++		 */
  1.4116 ++		int rg_;
  1.4117 ++
  1.4118 +          
  1.4119 +         /**
  1.4120 +          * Minimum amount to wait between attempts to re-open the link
  1.4121 +diff -r b0407e525e08 -r 875893b4fede servlib/conv_layers/LTPConvergenceLayer.cc
  1.4122 +--- a/servlib/conv_layers/LTPConvergenceLayer.cc	Thu Apr 21 13:15:00 2011 +0000
  1.4123 ++++ b/servlib/conv_layers/LTPConvergenceLayer.cc	Thu Apr 21 15:19:21 2011 +0000
  1.4124 +@@ -59,6 +59,7 @@
  1.4125 +     a->process("local_port", &local_port_);
  1.4126 +     a->process("remote_port", &remote_port_);
  1.4127 + 	a->process("mtu",&mtu_);
  1.4128 ++	a->process("rg",&rg_);
  1.4129 + }
  1.4130 + 
  1.4131 + LTPConvergenceLayer::LTPConvergenceLayer() : IPConvergenceLayer("LTPConvergenceLayer", "ltp")
  1.4132 +@@ -68,6 +69,7 @@
  1.4133 +     defaults_.remote_addr_              = INADDR_NONE;
  1.4134 +     defaults_.remote_port_              = 0;
  1.4135 +     defaults_.mtu_              = 0;
  1.4136 ++    defaults_.rg_              = LTP_ALLRED;
  1.4137 + 
  1.4138 + 	ltp_inited=false;
  1.4139 + 
  1.4140 +@@ -86,6 +88,7 @@
  1.4141 +     p.addopt(new oasys::InAddrOpt("remote_addr", &params->remote_addr_));
  1.4142 +     p.addopt(new oasys::UInt16Opt("remote_port", &params->remote_port_));
  1.4143 +     p.addopt(new oasys::UInt16Opt("mtu", &params->mtu_));
  1.4144 ++    p.addopt(new oasys::IntOpt("rg", &params->rg_));
  1.4145 + 
  1.4146 +     if (! p.parse(argc, argv, invalidp)) {
  1.4147 +         return false;
  1.4148 +@@ -203,6 +206,7 @@
  1.4149 +     log_info("LTP adding %s link %s", link->type_str(), link->nexthop());
  1.4150 + 
  1.4151 + 	int lmtu=link->params().mtu_;
  1.4152 ++	int lrg=link->params().rg_;
  1.4153 + 
  1.4154 + 	// initialise LTPlib
  1.4155 + 	if (!ltp_inited) {
  1.4156 +@@ -226,6 +230,7 @@
  1.4157 +     params->local_addr_ = INADDR_NONE;
  1.4158 +     params->local_port_ = 0;
  1.4159 +     params->mtu_ = lmtu;
  1.4160 ++    params->rg_ = lrg;
  1.4161 + 
  1.4162 +     const char* invalid;
  1.4163 +     if (! parse_params(params, argc, argv, &invalid)) {
  1.4164 +@@ -381,6 +386,7 @@
  1.4165 +     should_stop_ = false;
  1.4166 +     s_sock = 0;
  1.4167 + 	lmtu = params->mtu_;
  1.4168 ++	lrg = params->rg_;
  1.4169 + 
  1.4170 +     // start our thread
  1.4171 + }
  1.4172 +@@ -429,6 +435,7 @@
  1.4173 + 	dest.sock.sin_port=port;
  1.4174 + 
  1.4175 + 	lmtu=params->mtu_;
  1.4176 ++	lrg=params->rg_;
  1.4177 + 
  1.4178 + 	char *sstr=strdup(ltpaddr2str(&source));
  1.4179 + 	char *dstr=strdup(ltpaddr2str(&dest));
  1.4180 +@@ -490,6 +497,18 @@
  1.4181 + 	} else {
  1.4182 + 		log_debug("LTP Tx: not setting LTP mtu 'cause its %d",lmtu);
  1.4183 + 	}
  1.4184 ++	// setup red/green
  1.4185 ++	if (lrg!=LTP_ALLRED) {
  1.4186 ++		rv=ltp_setsockopt(sock,SOL_SOCKET,LTP_SO_RED,&lrg,sizeof(lrg));
  1.4187 ++		if (rv) {
  1.4188 ++			log_err("LTP ltp_setsockopt for SO_RED failed (%d).\n",lrg);
  1.4189 ++			free(inbuf);
  1.4190 ++			return(-1);
  1.4191 ++		}
  1.4192 ++		log_info("LTP Tx: set SO_RED to %d (-1=allred,0=allgreen,other=number of red bytes\n",lrg);
  1.4193 ++	} else {
  1.4194 ++		log_debug("LTP Tx: not setting SO_RED 'cause its all red (%d)",lrg);
  1.4195 ++	}
  1.4196 + 	///bind
  1.4197 + 	rv = ltp_bind(sock,(ltpaddr*)&source,sizeof(source));
  1.4198 + 	if (rv) { 
  1.4199 +@@ -549,7 +568,8 @@
  1.4200 + 
  1.4201 + 	ltpaddr listeners[MAXLTPLISTENERS];
  1.4202 + 	int nlisteners;
  1.4203 +-	int lastlisteners=-1;
  1.4204 ++	int nlastlisteners=-1;
  1.4205 ++	ltpaddr lastlisteners[MAXLTPLISTENERS];
  1.4206 + 
  1.4207 + #define START_INPUTBUNDLE 0x10000
  1.4208 +     size_t rxbufsize = START_INPUTBUNDLE;
  1.4209 +@@ -575,12 +595,31 @@
  1.4210 + 			break;
  1.4211 + 		}
  1.4212 + 		// don't want crazy logging so just when there's a change
  1.4213 +-		if (lastlisteners!=nlisteners) {
  1.4214 +-			log_info("LTP who's listening now says %d listeners (was %d)\n",nlisteners,lastlisteners);
  1.4215 ++		bool difflisteners=false;
  1.4216 ++		if (nlastlisteners!=nlisteners) {
  1.4217 ++			difflisteners=true;
  1.4218 ++		} else {
  1.4219 ++			// check in case the set has changed (order independent)
  1.4220 ++			// inefficient search, but numbers will be small so ok
  1.4221 ++			for (int j=0;!difflisteners && j!=nlisteners;j++) {
  1.4222 ++				bool looking=true;
  1.4223 ++				for (int k=0;looking && k!=nlisteners;k++) {
  1.4224 ++					if (!ltpaddr_cmp(&lastlisteners[j],&listeners[k],sizeof(listeners[k]))) {
  1.4225 ++						looking=false;
  1.4226 ++					}
  1.4227 ++				}
  1.4228 ++				if (looking) difflisteners=true;
  1.4229 ++			}
  1.4230 ++		}
  1.4231 ++		if (difflisteners) {
  1.4232 ++			log_info("LTP who's listening now says %d listeners (was %d)\n",nlisteners,nlastlisteners);
  1.4233 + 			for (int j=0;j!=nlisteners;j++) {
  1.4234 + 				log_debug("LTP \tListener %d %s\n",j,ltpaddr2str(&listeners[j]));
  1.4235 + 			}
  1.4236 ++			memcpy(lastlisteners,listeners,sizeof(listeners)); 
  1.4237 ++			nlastlisteners=nlisteners;
  1.4238 + 		}
  1.4239 ++
  1.4240 + 		// if we're in "opportunistic mode"
  1.4241 + 		// check if I should change link state, depends on who's
  1.4242 + 		// listening and linkpeer;
  1.4243 +@@ -595,14 +634,14 @@
  1.4244 + 							i != links->end(); ++i) {
  1.4245 + 
  1.4246 + 			// other states (e.g. OPENING) exist that we ignore
  1.4247 +-			bool linkopen=(*i)->state()==Link::OPEN;
  1.4248 ++			bool linkopen=((*i)->state()==Link::OPEN);
  1.4249 + 			bool linkclosed=(
  1.4250 + 				(*i)->state()==Link::UNAVAILABLE || 
  1.4251 + 				(*i)->state()==Link::AVAILABLE );
  1.4252 + 			ltpaddr linkpeer;
  1.4253 + 			// might want to use (*i)->nexthop() instead params
  1.4254 + 			str2ltpaddr((char*)(*i)->nexthop(),&linkpeer);
  1.4255 +-			if (lastlisteners!=nlisteners) {
  1.4256 ++			if (difflisteners) {
  1.4257 + 				log_debug("LTP linkpeer: %s\n",ltpaddr2str(&linkpeer));
  1.4258 + 				log_debug("LTP link state: %s, link cl name: %s\n",
  1.4259 + 					Link::state_to_str((*i)->state()),
  1.4260 +@@ -642,8 +681,6 @@
  1.4261 + 			}
  1.4262 + 		}
  1.4263 + 		cmlock.unlock();
  1.4264 +-		// don't log stuff next time 'round
  1.4265 +-		lastlisteners=nlisteners;
  1.4266 + 		// now check if something's arrived for me
  1.4267 + 		int flags;
  1.4268 + 		ltpaddr from;
  1.4269 +diff -r b0407e525e08 -r 875893b4fede servlib/conv_layers/LTPConvergenceLayer.h
  1.4270 +--- a/servlib/conv_layers/LTPConvergenceLayer.h	Thu Apr 21 13:15:00 2011 +0000
  1.4271 ++++ b/servlib/conv_layers/LTPConvergenceLayer.h	Thu Apr 21 15:19:21 2011 +0000
  1.4272 +@@ -71,6 +71,7 @@
  1.4273 + 		in_addr_t remote_addr_;		//address to connect to
  1.4274 + 		u_int16_t remote_port_;		//port to connect to
  1.4275 + 		u_int16_t mtu_; // outbound MTU for link
  1.4276 ++		int32_t rg_; // red/green setting, missing or -1 is allred, 0=allgreen, otherwise #red bytes
  1.4277 + 	};
  1.4278 + 	//struct to hold our default parameters
  1.4279 + 	static Params defaults_;
  1.4280 +@@ -112,6 +113,8 @@
  1.4281 + 		
  1.4282 + 		int lmtu;
  1.4283 + 
  1.4284 ++		int lrg;
  1.4285 ++
  1.4286 + 	protected:
  1.4287 + 		//lets process our incoming ltp segment
  1.4288 + 		void process_data(u_char* bp, size_t len);
  1.4289 +@@ -151,6 +154,7 @@
  1.4290 + 
  1.4291 + 		//ltp MTU to use for outbound DS/RS
  1.4292 + 		int lmtu;
  1.4293 ++		int lrg;
  1.4294 + 		
  1.4295 + 		//our receive buffer size
  1.4296 + 		int rxbufsize;