00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017 #ifdef HAVE_CONFIG_H
00018 # include <dtn-config.h>
00019 #endif
00020
00021 #include <stdio.h>
00022 #include <stdlib.h>
00023 #include <string.h>
00024 #include <strings.h>
00025 #include <time.h>
00026 #include <unistd.h>
00027 #include <errno.h>
00028 #include <sys/types.h>
00029 #include <sys/stat.h>
00030 #include <sys/time.h>
00031 #include "dtn_api.h"
00032
00033 #define BUFSIZE 16
00034 #define BUNDLE_DIR_DEFAULT INSTALL_LOCALSTATEDIR "/dtn/dtncpd-incoming"
00035
00036 static const char *progname;
00037
00038 void
00039 usage()
00040 {
00041 fprintf(stderr, "usage: %s [ directory ]\n", progname);
00042 fprintf(stderr, " optional directory parameter is where incoming "
00043 "files will get put\n");
00044 fprintf(stderr, " (defaults to: %s)\n", BUNDLE_DIR_DEFAULT);
00045 exit(1);
00046 }
00047
00048 int
00049 main(int argc, const char** argv)
00050 {
00051 int i;
00052 int ret;
00053 dtn_handle_t handle;
00054 dtn_endpoint_id_t local_eid;
00055 dtn_reg_info_t reginfo;
00056 dtn_reg_id_t regid;
00057 dtn_bundle_spec_t bundle;
00058 dtn_bundle_payload_t payload;
00059 const char* endpoint_demux;
00060 int debug = 1;
00061
00062 char * bundle_dir = 0;
00063
00064 char host[PATH_MAX];
00065 int host_len;
00066 char * dirpath;
00067 char * filename;
00068 char filepath[PATH_MAX];
00069 time_t current;
00070
00071 char * buffer;
00072 char s_buffer[BUFSIZE + 1];
00073
00074 int bufsize, marker, maxwrite;
00075
00076 FILE * target;
00077
00078
00079
00080 setvbuf(stdout, (char *)NULL, _IOLBF, 0);
00081
00082 s_buffer[BUFSIZE] = '\0';
00083
00084 struct stat st;
00085
00086 progname = argv[0];
00087
00088 if (argc > 2) {
00089 usage();
00090 }
00091 else if (argc == 2)
00092 {
00093 if (argv[1][0] == '-') {
00094 usage();
00095 }
00096 bundle_dir = (char *) argv[1];
00097 }
00098 else
00099 {
00100 bundle_dir = BUNDLE_DIR_DEFAULT;
00101 }
00102
00103 if (access(bundle_dir, W_OK | X_OK) == -1) {
00104 fprintf(stderr, "can't access directory '%s': %s\n",
00105 bundle_dir, strerror(errno));
00106 usage();
00107 }
00108
00109 if (stat(bundle_dir, &st) == -1) {
00110 fprintf(stderr, "can't stat directory '%s': %s\n",
00111 bundle_dir, strerror(errno));
00112 usage();
00113 }
00114
00115 if (!S_ISDIR(st.st_mode)) {
00116 fprintf(stderr, "path '%s' is not a directory\n",
00117 bundle_dir);
00118 usage();
00119 }
00120
00121
00122 if (debug) printf("opening connection to dtn router...\n");
00123 int err = dtn_open(&handle);
00124 if (err != DTN_SUCCESS) {
00125 fprintf(stderr, "fatal error opening dtn handle: %s\n",
00126 dtn_strerror(err));
00127 exit(1);
00128 }
00129
00130
00131
00132 endpoint_demux = "/dtncp/recv?file=*";
00133 dtn_build_local_eid(handle, &local_eid, endpoint_demux);
00134 if (debug) printf("local_eid [%s]\n", local_eid.uri);
00135
00136
00137
00138 ret = dtn_find_registration(handle, &local_eid, ®id);
00139 if (ret == 0) {
00140 if (debug) printf("dtn_find_registration succeeded, regid 0x%x\n",
00141 regid);
00142
00143
00144 dtn_bind(handle, regid);
00145
00146 } else if (dtn_errno(handle) == DTN_ENOTFOUND) {
00147 memset(®info, 0, sizeof(reginfo));
00148 dtn_copy_eid(®info.endpoint, &local_eid);
00149 reginfo.flags = DTN_REG_DEFER;
00150 reginfo.regid = DTN_REGID_NONE;
00151 reginfo.expiration = 60 * 60;
00152 if ((ret = dtn_register(handle, ®info, ®id)) != 0) {
00153 fprintf(stderr, "error creating registration: %d (%s)\n",
00154 ret, dtn_strerror(dtn_errno(handle)));
00155 exit(1);
00156 }
00157
00158 if (debug) printf("dtn_register succeeded, regid 0x%x\n", regid);
00159
00160 } else {
00161 fprintf(stderr, "error in dtn_find_registration: %s",
00162 dtn_strerror(dtn_errno(handle)));
00163 exit(1);
00164 }
00165
00166
00167 while(1)
00168 {
00169
00170
00171
00172 dtn_bundle_payload_location_t file_or_mem = DTN_PAYLOAD_FILE;
00173
00174 memset(&bundle, 0, sizeof(bundle));
00175 memset(&payload, 0, sizeof(payload));
00176 memset(&dirpath, 0, sizeof(dirpath));
00177 memset(&filename, 0, sizeof(filename));
00178 memset(&filepath, 0, sizeof(filepath));
00179 memset(&host, 0, sizeof(host));
00180 memset(&st, 0, sizeof(st));
00181
00182 printf("dtn_recv [%s]...\n", local_eid.uri);
00183
00184 if ((ret = dtn_recv(handle, &bundle,
00185 file_or_mem, &payload, -1)) < 0)
00186 {
00187 fprintf(stderr, "error getting recv reply: %d (%s)\n",
00188 ret, dtn_strerror(dtn_errno(handle)));
00189 exit(1);
00190 }
00191
00192
00193 current = time(NULL);
00194
00195 if (strncmp(bundle.source.uri, "dtn://", 6) != 0)
00196 {
00197 fprintf(stderr, "bundle source uri '%s' must be a dtn:// uri\n",
00198 bundle.source.uri);
00199 exit(1);
00200 }
00201
00202
00203 host_len = strchr(&bundle.source.uri[6], '/') - &bundle.source.uri[6];
00204 strncpy(host, &bundle.source.uri[6], host_len);
00205
00206
00207
00208 endpoint_demux = "/dtncp/recv?file=";
00209 dirpath = strstr(bundle.dest.uri, endpoint_demux);
00210 if (!dirpath) {
00211 fprintf(stderr, "can't find %s demux in uri '%s'\n",
00212 endpoint_demux, bundle.dest.uri);
00213 exit(1);
00214 }
00215
00216 dirpath += strlen(endpoint_demux);
00217 if (dirpath[0] == '/') dirpath++;
00218
00219
00220 filename = strrchr(dirpath, '/');
00221 if (filename == 0)
00222 {
00223 filename = dirpath;
00224 dirpath = "";
00225 }
00226 else
00227 {
00228 filename[0] = '\0';
00229 filename++;
00230 }
00231
00232
00233
00234 sprintf(filepath, "mkdir -p %s/%s/%s", bundle_dir, host, dirpath);
00235 system(filepath);
00236
00237
00238 sprintf(filepath, "%s/%s/%s/%s", bundle_dir, host, dirpath, filename);
00239
00240
00241 buffer = payload.filename.filename_val;
00242
00243 bufsize = payload.filename.filename_len;
00244
00245 ret = stat(buffer, &st);
00246
00247 printf ("======================================\n");
00248 printf (" File Received at %s\n", ctime(¤t));
00249 printf (" host : %s\n", host);
00250 printf (" path : %s\n", dirpath);
00251 printf (" file : %s\n", filename);
00252 printf (" loc : %s\n", filepath);
00253 printf (" size : %d bytes\n", (int) st.st_size);
00254
00255
00256 if (file_or_mem == DTN_PAYLOAD_FILE) {
00257 int cmdlen = 5 + strlen(buffer) + strlen(filepath);
00258 char *cmd = malloc(cmdlen);
00259
00260 if (cmd) {
00261 snprintf(cmd, cmdlen, "mv %.*s %s", bufsize, buffer,
00262 filepath);
00263 system(cmd);
00264 printf("Moving payload to final filename: '%s'\n", cmd);
00265 free(cmd);
00266 } else {
00267 printf("Out of memory. Find file in %*s.\n", bufsize,
00268 buffer);
00269 }
00270 } else {
00271
00272 target = fopen(filepath, "w");
00273
00274 if (target == NULL)
00275 {
00276 fprintf(stderr, "Error opening file for writing %s\n",
00277 filepath);
00278 continue;
00279 }
00280 if (debug) printf ("--------------------------------------\n");
00281
00282 marker = 0;
00283 while (marker < bufsize)
00284 {
00285
00286 i=0;
00287 maxwrite = (marker + 256) > bufsize? bufsize-marker : 256;
00288 while (i < maxwrite)
00289 {
00290 i += fwrite(buffer + marker + i, 1, maxwrite - i, target);
00291 }
00292
00293 if (debug)
00294 {
00295 for (i=0; i < maxwrite; i++)
00296 {
00297 if (buffer[marker] >= ' ' && buffer[marker] <= '~')
00298 s_buffer[marker%BUFSIZE] = buffer[i];
00299 else
00300 s_buffer[marker%BUFSIZE] = '.';
00301
00302 if (marker%BUFSIZE == 0)
00303 {
00304 printf("%07x ", marker);
00305 }
00306 else if (marker%2 == 0)
00307 {
00308 printf(" ");
00309 }
00310
00311 printf("%02x", buffer[i] & 0xff);
00312
00313
00314 if (marker%BUFSIZE == BUFSIZE-1)
00315 {
00316 printf(" | %s\n", s_buffer);
00317 }
00318 marker ++;
00319 }
00320 }
00321 else
00322 {
00323 marker += maxwrite;
00324 }
00325 }
00326
00327 fclose(target);
00328
00329
00330 if (debug && marker % BUFSIZE != 0)
00331 {
00332 while (marker % BUFSIZE !=0)
00333 {
00334 s_buffer[marker%BUFSIZE] = ' ';
00335
00336 if (marker%2 == 0)
00337 {
00338 printf(" ");
00339 }
00340
00341 printf(" ");
00342
00343
00344 if (marker%BUFSIZE == BUFSIZE-1)
00345 {
00346 printf(" | %s\n", s_buffer);
00347 }
00348 marker ++;
00349 }
00350 }
00351 printf (" size : %d bytes\n", bufsize);
00352 }
00353
00354 printf ("======================================\n");
00355 dtn_free_payload(&payload);
00356 }
00357
00358 dtn_close(handle);
00359
00360 return 0;
00361 }