apps/dtnrespond/dtnrespond.c
changeset 19 ce4cfc1cb1b6
parent 8 ce3cb8a86959
child 20 7fd5f0de6c59
equal deleted inserted replaced
18:3d1ea31e2a19 19:ce4cfc1cb1b6
    63 {
    63 {
    64     fprintf(stderr, "usage: %s -l < local endpoint > -f < matching filename > "
    64     fprintf(stderr, "usage: %s -l < local endpoint > -f < matching filename > "
    65                     "[opts]\n", progname);
    65                     "[opts]\n", progname);
    66     fprintf(stderr, "options:\n");
    66     fprintf(stderr, "options:\n");
    67     fprintf(stderr, " -n  < count > exit after count bundles received\n");
    67     fprintf(stderr, " -n  < count > exit after count bundles received\n");
       
    68     fprintf(stderr, " -r  < eid > reply to endpoint\n");
    68     fprintf(stderr, " -e  < seconds > bundle expiry time\n");
    69     fprintf(stderr, " -e  < seconds > bundle expiry time\n");
    69     fprintf(stderr, " -i  < regid > existing registration id\n");
    70     fprintf(stderr, " -i  < regid > existing registration id\n");
    70     fprintf(stderr, " -E  < seconds > registration expiry time\n");
    71     fprintf(stderr, " -E  < seconds > registration expiry time\n");
    71     fprintf(stderr, " -A  < defer | drop | exec > failure action\n");
    72     fprintf(stderr, " -A  < defer | drop | exec > failure action\n");
    72     fprintf(stderr, " -S  < script > failure script for exec action\n");
    73     fprintf(stderr, " -S  < script > failure script for exec action\n");
    93 * returns success or exits on failure.
    94 * returns success or exits on failure.
    94 *******************************************************************************/
    95 *******************************************************************************/
    95 int
    96 int
    96 parse_options(int argc, char** argv,
    97 parse_options(int argc, char** argv,
    97     char * local_eid_name,              // l
    98     char * local_eid_name,              // l
       
    99     char * reply_eid_name,              // r
    98     char * matching_filename,           // f
   100     char * matching_filename,           // f
    99     int * count,                        // n
   101     int * count,                        // n
   100     dtn_timeval_t * bundle_expiry,      // e
   102     dtn_timeval_t * bundle_expiry,      // e
   101     dtn_reg_id_t * regid,               // i
   103     dtn_reg_id_t * regid,               // i
   102     dtn_timeval_t * reg_expiry,         // E
   104     dtn_timeval_t * reg_expiry,         // E
   110 
   112 
   111     progname = argv[0];
   113     progname = argv[0];
   112 
   114 
   113     //initialize strings
   115     //initialize strings
   114     memset(local_eid_name,    0, sizeof(char) * PATH_MAX);
   116     memset(local_eid_name,    0, sizeof(char) * PATH_MAX);
       
   117     memset(reply_eid_name,    0, sizeof(char) * PATH_MAX);
   115     memset(matching_filename, 0, sizeof(char) * PATH_MAX);
   118     memset(matching_filename, 0, sizeof(char) * PATH_MAX);
   116     memset(reg_fail_script,   0, sizeof(char) * PATH_MAX);
   119     memset(reg_fail_script,   0, sizeof(char) * PATH_MAX);
   117 
   120 
   118     while( !done )
   121     while( !done )
   119     {
   122     {
   120         c = getopt(argc, argv, "l:f:n:e:i:E:A:S:P:DXFRcC1NWvhH");
   123         c = getopt(argc, argv, "l:f:n:e:i:E:A:S:P:DXFRcC1NWvhH");
   121         switch(c)
   124         switch(c)
   122         {
   125         {
   123         case 'l':
   126         case 'l':
   124             strncpy(local_eid_name, optarg, PATH_MAX);
   127             strncpy(local_eid_name, optarg, PATH_MAX);
       
   128             break;
       
   129         case 'r':
       
   130             strncpy(reply_eid_name, optarg, PATH_MAX);
   125             break;
   131             break;
   126         case 'f':
   132         case 'f':
   127             strncpy(matching_filename, optarg, PATH_MAX);
   133             strncpy(matching_filename, optarg, PATH_MAX);
   128             break;
   134             break;
   129         case 'n':
   135         case 'n':
   213             // getopt already prints error message for unknown option characters
   219             // getopt already prints error message for unknown option characters
   214             usage();
   220             usage();
   215             exit(1);
   221             exit(1);
   216         }             
   222         }             
   217     }
   223     }
       
   224 
       
   225     // if no reply-to eid set, use the local eid
       
   226     if (reply_eid_name == NULL)
       
   227         strncpy(reply_eid_name, local_eid_name, PATH_MAX);
       
   228 
   218     return 0;
   229     return 0;
   219 }
   230 }
   220 
   231 
   221 /*******************************************************************************
   232 /*******************************************************************************
   222 * validate options:
   233 * validate options:
   223 * returns success or exits on failure 
   234 * returns success or exits on failure 
   224 *******************************************************************************/
   235 *******************************************************************************/
   225 int
   236 int
   226 validate_options(const char * local_eid_name, const char * matching_filename)
   237 validate_options(const char * local_eid_name,
       
   238     const char * reply_eid_name,
       
   239     const char * matching_filename)
   227 {
   240 {
   228 #define REQUIRE(test, err_msg) \
   241 #define REQUIRE(test, err_msg) \
   229     if(!test) { \
   242     if(!test) { \
   230         fprintf(stderr, err_msg); \
   243         fprintf(stderr, err_msg); \
   231         usage(); \
   244         usage(); \
   232         exit(1); \
   245         exit(1); \
   233     }
   246     }
   234 
   247 
   235     REQUIRE(strlen(local_eid_name) > 0, "-l <local eid> required\n");
   248     REQUIRE(strlen(local_eid_name) > 0, "-l <local eid> required\n");
       
   249     REQUIRE(strlen(reply_eid_name) > 0, "-r <reply eid> required\n");
   236     REQUIRE(strlen(matching_filename) > 0, "-f <matching filename> required\n");
   250     REQUIRE(strlen(matching_filename) > 0, "-f <matching filename> required\n");
   237     
   251     
   238     return 0;
   252     return 0;
   239 }
   253 }
   240 
   254 
   323 
   337 
   324     return DTN_SUCCESS;
   338     return DTN_SUCCESS;
   325 }
   339 }
   326 
   340 
   327 /*******************************************************************************
   341 /*******************************************************************************
       
   342 * parse eid:
       
   343 *  
       
   344 * code lifted from dtnsend
       
   345 * todo: check this
       
   346 *******************************************************************************/
       
   347 dtn_endpoint_id_t *
       
   348 parse_eid(dtn_handle_t handle,
       
   349     dtn_endpoint_id_t * eid,
       
   350     const char * str,
       
   351     int verbose)
       
   352 {
       
   353     // try the string as an actual dtn eid
       
   354     if (dtn_parse_eid_string(eid, str) == DTN_SUCCESS) {
       
   355         if (verbose) fprintf(stdout, "%s (literal)\n", str);
       
   356         return eid;
       
   357     }
       
   358 
       
   359     // build a local eid based on the configuration of our dtn
       
   360     // router plus the str as demux string
       
   361     else if (dtn_build_local_eid(handle, eid, str) == DTN_SUCCESS) {
       
   362         if (verbose) fprintf(stdout, "%s (local)\n", str);
       
   363         return eid;
       
   364     }
       
   365     else {
       
   366         fprintf(stderr, "invalid eid string '%s'\n", str);
       
   367         exit(1);
       
   368     }
       
   369 }
       
   370 
       
   371 /*******************************************************************************
   328 * trim whitespace:
   372 * trim whitespace:
   329 * first move past any leading whitespace 
   373 * first move past any leading whitespace 
   330 * after the first non-whitespace char bef=gin copying to output
   374 * after the first non-whitespace char bef=gin copying to output
   331 * finish by setting any trailing whitespace to 0
   375 * finish by setting any trailing whitespace to 0
   332 * @return 0 on success or -1 if input not completely read
   376 * @return 0 on success or -1 if input not completely read
   652 *******************************************************************************/
   696 *******************************************************************************/
   653 int
   697 int
   654 send_response_bpq(dtn_handle_t * handle,
   698 send_response_bpq(dtn_handle_t * handle,
   655     dtn_reg_id_t regid,
   699     dtn_reg_id_t regid,
   656     dtn_bundle_spec_t * query_bundle_spec,
   700     dtn_bundle_spec_t * query_bundle_spec,
       
   701     const dtn_endpoint_id_t * reply_eid,
   657     dtn_bpq_extension_block_data_t * query_bpq_block_data,
   702     dtn_bpq_extension_block_data_t * query_bpq_block_data,
   658     const char * pathname,
   703     const char * pathname,
   659     int bundle_expiry,
   704     int bundle_expiry,
   660     dtn_bundle_priority_t  priority,
   705     dtn_bundle_priority_t  priority,
   661     int delivery_options,
   706     int delivery_options,
   705     response_bpq_block.flags = DTN_BPQ_BLOCK_FLAGS;
   750     response_bpq_block.flags = DTN_BPQ_BLOCK_FLAGS;
   706     response_bpq_block.data.data_len = buf_len;
   751     response_bpq_block.data.data_len = buf_len;
   707     response_bpq_block.data.data_val = buf;
   752     response_bpq_block.data.data_val = buf;
   708 
   753 
   709     // copy dest src
   754     // copy dest src
   710     dtn_copy_eid(&response_bundle_spec.dest,    &(query_bundle_spec->source));
   755     dtn_copy_eid(&response_bundle_spec.dest,    &(query_bundle_spec->replyto));
   711     dtn_copy_eid(&response_bundle_spec.source,  &(query_bundle_spec->dest));
   756     dtn_copy_eid(&response_bundle_spec.source,  &(query_bundle_spec->dest));
   712     dtn_copy_eid(&response_bundle_spec.replyto, &(query_bundle_spec->dest));
   757     dtn_copy_eid(&response_bundle_spec.replyto, reply_eid);
   713 
   758 
   714     // set the bundle spec dtn options
   759     // set the bundle spec dtn options
   715     response_bundle_spec.expiration = bundle_expiry;
   760     response_bundle_spec.expiration = bundle_expiry;
   716     response_bundle_spec.dopts = delivery_options;
   761     response_bundle_spec.dopts = delivery_options;
   717     response_bundle_spec.priority = priority;
   762     response_bundle_spec.priority = priority;
   744 * source of the query.
   789 * source of the query.
   745 *******************************************************************************/
   790 *******************************************************************************/
   746 int
   791 int
   747 receive_bpq(dtn_handle_t * handle,
   792 receive_bpq(dtn_handle_t * handle,
   748     dtn_reg_id_t regid,
   793     dtn_reg_id_t regid,
       
   794     const dtn_endpoint_id_t * reply_eid,
   749     const char * matching_filename,
   795     const char * matching_filename,
   750     int  count,
   796     int  count,
   751     int bundle_expiry,
   797     int bundle_expiry,
   752     dtn_bundle_priority_t  priority,
   798     dtn_bundle_priority_t  priority,
   753     int delivery_options,
   799     int delivery_options,
   817                                          bpq_block_data.query.query_val);
   863                                          bpq_block_data.query.query_val);
   818 
   864 
   819             ret = send_response_bpq(handle,
   865             ret = send_response_bpq(handle,
   820                                     regid,
   866                                     regid,
   821                                     &bundle_spec,
   867                                     &bundle_spec,
       
   868                                     reply_eid,
   822                                     &bpq_block_data,
   869                                     &bpq_block_data,
   823                                     pathname,
   870                                     pathname,
   824                                     bundle_expiry,
   871                                     bundle_expiry,
   825                                     priority,
   872                                     priority,
   826                                     delivery_options,
   873                                     delivery_options,
   843 *******************************************************************************/
   890 *******************************************************************************/
   844 int
   891 int
   845 main(int argc, char** argv)
   892 main(int argc, char** argv)
   846 {
   893 {
   847     dtn_endpoint_id_t local_eid;
   894     dtn_endpoint_id_t local_eid;
       
   895     dtn_endpoint_id_t reply_eid;
   848     char local_eid_name[PATH_MAX];
   896     char local_eid_name[PATH_MAX];
       
   897     char reply_eid_name[PATH_MAX];
   849     char matching_filename[PATH_MAX];
   898     char matching_filename[PATH_MAX];
   850     int count = -1;                                     //forever
   899     int count = -1;                                     //forever
   851     dtn_timeval_t bundle_expiry = 3600;                 //one hour
   900     dtn_timeval_t bundle_expiry = 3600;                 //one hour
   852     dtn_reg_id_t regid = DTN_REGID_NONE;
   901     dtn_reg_id_t regid = DTN_REGID_NONE;
   853     dtn_timeval_t reg_expiry = 30;
   902     dtn_timeval_t reg_expiry = 30;
   859     int err = 0;
   908     int err = 0;
   860     dtn_handle_t handle;
   909     dtn_handle_t handle;
   861 
   910 
   862     parse_options(argc, argv,
   911     parse_options(argc, argv,
   863         local_eid_name,
   912         local_eid_name,
       
   913         reply_eid_name,
   864         matching_filename,
   914         matching_filename,
   865         &count,
   915         &count,
   866         &bundle_expiry,
   916         &bundle_expiry,
   867         &regid,
   917         &regid,
   868         &reg_expiry,
   918         &reg_expiry,
   870         reg_fail_script,
   920         reg_fail_script,
   871         &priority,
   921         &priority,
   872         &delivery_options,
   922         &delivery_options,
   873         &verbose);
   923         &verbose);
   874 
   924 
   875     validate_options(local_eid_name, matching_filename);
   925     validate_options(local_eid_name, reply_eid_name, matching_filename);
   876 
   926 
   877     // open the ipc handle
   927     // open the ipc handle
   878     if (verbose) fprintf(stdout, "opening connection to dtn router...\n");
   928     if (verbose) fprintf(stdout, "opening connection to dtn router...\n");
   879     if ((err = dtn_open(&handle)) != DTN_SUCCESS) {
   929     if ((err = dtn_open(&handle)) != DTN_SUCCESS) {
   880         fprintf(stderr, "fatal error opening dtn handle: %s\n",
   930         fprintf(stderr, "fatal error opening dtn handle: %s\n",
   881                 dtn_strerror(err));
   931                 dtn_strerror(err));
   882         exit(1);
   932         exit(1);
   883     }
   933     }
   884     if (verbose) fprintf(stdout, "opened connection to dtn router...\n");
   934     if (verbose) fprintf(stdout, "opened connection to dtn router...\n");
       
   935 
       
   936     parse_eid(handle, &reply_eid, reply_eid_name, verbose);
       
   937     if (verbose) fprintf(stdout, "parsed reply_eid: %s\n", reply_eid.uri);
   885 
   938 
   886     // get dtn registration
   939     // get dtn registration
   887     if (verbose) fprintf(stdout, "registering with dtn...\n");
   940     if (verbose) fprintf(stdout, "registering with dtn...\n");
   888     register_with_dtn(handle,
   941     register_with_dtn(handle,
   889         &local_eid,
   942         &local_eid,
   898 
   951 
   899     // get to work
   952     // get to work
   900     // this fn will likely never exit so the handle won't be closed...
   953     // this fn will likely never exit so the handle won't be closed...
   901     receive_bpq(&handle,
   954     receive_bpq(&handle,
   902         regid,
   955         regid,
       
   956         &reply_eid,
   903         matching_filename,
   957         matching_filename,
   904         count,
   958         count,
   905         bundle_expiry,
   959         bundle_expiry,
   906         priority,
   960         priority,
   907         delivery_options,
   961         delivery_options,