00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020 #include <stdlib.h>
00021 #include <stdio.h>
00022 #include <unistd.h>
00023
00024 #include <ccn/ccn.h>
00025 #include <ccn/charbuf.h>
00026 #include <ccn/reg_mgmt.h>
00027 #include <ccn/uri.h>
00028
00029 #define USAGE "[-p port] [ -0123s ] ccnx:/uri ...\n collect arriving content"
00030
00031 static enum ccn_upcall_res incoming_interest(struct ccn_closure *,
00032 enum ccn_upcall_kind,
00033 struct ccn_upcall_info *);
00034 static enum ccn_upcall_res incoming_content(struct ccn_closure *,
00035 enum ccn_upcall_kind,
00036 struct ccn_upcall_info *);
00037 static void usage(void);
00038 static const char *progname;
00039 static int setscope = 0;
00040
00041 int
00042 main(int argc, char **argv)
00043 {
00044 struct ccn *h;
00045 int fflags;
00046 int i;
00047 int opt;
00048 int res;
00049 const char *arg = NULL;
00050 const char *portstr = NULL;
00051 struct ccn_charbuf *regprefix = NULL;
00052 struct ccn_closure in_interest = {0};
00053
00054 setscope = 0;
00055 progname = argv[0];
00056 while ((opt = getopt(argc, argv, "0123shp:")) != -1) {
00057 switch (opt) {
00058 case 'p':
00059 fprintf(stderr, "-p port: not yet implemented\n");
00060 portstr = optarg;
00061 break;
00062 case '0':
00063 case '1':
00064 case '2':
00065 case '3':
00066 setscope = opt - '0';
00067 break;
00068 case 's':
00069 setscope = -1;
00070 break;
00071 case 'h':
00072 default:
00073 usage();
00074 }
00075 }
00076 if (argv[optind] == NULL)
00077 usage();
00078
00079 h = ccn_create();
00080 res = ccn_connect(h, NULL);
00081 if (res < 0) {
00082 ccn_perror(h, "ccn_connect");
00083 return(1);
00084 }
00085 regprefix = ccn_charbuf_create();
00086 in_interest.p = &incoming_interest;
00087 for (i = optind; (arg = argv[i]) != NULL; i++) {
00088 ccn_charbuf_reset(regprefix);
00089 res = ccn_name_from_uri(regprefix, arg);
00090 if (res < 0) {
00091 fprintf(stderr, "%s: not a valid ccnx URI\n", arg);
00092 usage();
00093 }
00094 fflags = CCN_FORW_TAP | CCN_FORW_CHILD_INHERIT | CCN_FORW_ACTIVE;
00095 res = ccn_set_interest_filter_with_flags(h, regprefix, &in_interest, fflags);
00096 if (res < 0) {
00097 ccn_perror(h, "ccn_set_interest_filter_with_flags");
00098 exit(1);
00099 }
00100 }
00101 ccn_run(h, -1);
00102 ccn_charbuf_destroy(®prefix);
00103 ccn_destroy(&h);
00104 return(0);
00105 }
00106
00107 struct mydata {
00108 struct ccn_closure self;
00109 int timeouts;
00110 const char *debug;
00111 char debugspace[1];
00112 };
00113
00114
00115 static enum ccn_upcall_res
00116 incoming_content(struct ccn_closure *selfp,
00117 enum ccn_upcall_kind kind,
00118 struct ccn_upcall_info *info)
00119 {
00120 struct mydata *md;
00121 size_t size;
00122 ssize_t resl;
00123
00124 md = selfp->data;
00125 if (selfp != &md->self)
00126 return(CCN_UPCALL_RESULT_ERR);
00127 switch (kind) {
00128 case CCN_UPCALL_FINAL:
00129 selfp->data = NULL;
00130 free(md);
00131 break;
00132 case CCN_UPCALL_INTEREST_TIMED_OUT:
00133 md->timeouts++;
00134 break;
00135 case CCN_UPCALL_CONTENT_UNVERIFIED:
00136 case CCN_UPCALL_CONTENT:
00137 size = info->pco->offset[CCN_PCO_E];
00138 resl = write(1, info->content_ccnb, size);
00139 if (resl != size)
00140 exit(1);
00141 break;
00142 default:
00143 return(CCN_UPCALL_RESULT_ERR);
00144 }
00145 return(CCN_UPCALL_RESULT_OK);
00146 }
00147
00148
00149
00150
00151
00152
00153
00154
00155
00156
00157
00158
00159
00160 static int
00161 me_too(struct ccn *h,
00162 struct ccn_parsed_interest *pi,
00163 const unsigned char *imsg,
00164 int scope)
00165 {
00166 struct ccn_charbuf *templ;
00167 struct ccn_charbuf *name;
00168 struct mydata *md;
00169 const unsigned char *p;
00170 size_t s;
00171 size_t t;
00172 int res;
00173
00174 templ = ccn_charbuf_create();
00175 name = ccn_charbuf_create();
00176 p = &(imsg[pi->offset[CCN_PI_B_Name]]);
00177 s = pi->offset[CCN_PI_E_Name] - pi->offset[CCN_PI_B_Name];
00178 ccn_charbuf_append(name, p, s);
00179 p = imsg;
00180 s = pi->offset[CCN_PI_B_Scope];
00181 ccn_charbuf_append(templ, p, s);
00182 if (scope >= 0) {
00183 if (scope < 3)
00184 ccnb_tagged_putf(templ, CCN_DTAG_Scope, "%d", scope);
00185 s = pi->offset[CCN_PI_E_Scope];
00186 }
00187 t = pi->offset[CCN_PI_B_Nonce];
00188 ccn_charbuf_append(templ, p + s, t - s);
00189 ccn_charbuf_append_closer(templ);
00190 md = calloc(1, sizeof(*md));
00191 if (md == NULL)
00192 res = -1;
00193 else {
00194 md->self.p = &incoming_content;
00195 md->self.data = md;
00196 res = ccn_express_interest(h, name, &md->self, templ);
00197 }
00198 ccn_charbuf_destroy(&name);
00199 ccn_charbuf_destroy(&templ);
00200 return(res);
00201 }
00202
00203
00204 static enum ccn_upcall_res
00205 incoming_interest(struct ccn_closure *selfp,
00206 enum ccn_upcall_kind kind,
00207 struct ccn_upcall_info *info)
00208 {
00209 switch (kind) {
00210 case CCN_UPCALL_FINAL:
00211
00212 break;
00213 case CCN_UPCALL_INTEREST:
00214 case CCN_UPCALL_CONSUMED_INTEREST:
00215 me_too(info->h, info->pi, info->interest_ccnb, setscope);
00216 break;
00217 default:
00218 return(CCN_UPCALL_RESULT_ERR);
00219 }
00220 return(CCN_UPCALL_RESULT_OK);
00221 }
00222
00223
00224 static void
00225 usage(void)
00226 {
00227 fprintf(stderr, "%s: " USAGE "\n", progname);
00228 exit(1);
00229 }