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(®info, 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(®info.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, ®info)) != 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, ®id) != 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, ®info, ®id)) != 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", ¶ms_.mtu_));
1.4084 ++ p.addopt(new oasys::IntOpt("rg", ¶ms_.rg_));
1.4085 + p.addopt(new oasys::UIntOpt("min_retry_interval",
1.4086 + ¶ms_.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", ¶ms->remote_addr_));
1.4142 + p.addopt(new oasys::UInt16Opt("remote_port", ¶ms->remote_port_));
1.4143 + p.addopt(new oasys::UInt16Opt("mtu", ¶ms->mtu_));
1.4144 ++ p.addopt(new oasys::IntOpt("rg", ¶ms->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;