00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021 #include <stdio.h>
00022 #include <stdlib.h>
00023 #include <string.h>
00024 #include <unistd.h>
00025 #include <ccn/ccn.h>
00026 #include <ccn/charbuf.h>
00027 #include <ccn/uri.h>
00028 #include <ccn/fetch.h>
00029
00030
00031
00032
00033 static void
00034 usage(const char *progname)
00035 {
00036 fprintf(stderr,
00037 "%s [-h] [-d flags] [-p pipeline] [-s scope] [-a] ccnx:/a/b ...\n"
00038 " Reads streams at the given ccn URIs and writes to stdout\n"
00039 " -h produces this message\n"
00040 " -d flags specifies the fetch debug flags which are the sum of\n"
00041 " NoteGlitch = 1,\n"
00042 " NoteAddRem = 2,\n"
00043 " NoteNeed = 4,\n"
00044 " NoteFill = 8,\n"
00045 " NoteFinal = 16,\n"
00046 " NoteTimeout = 32,\n"
00047 " NoteOpenClose = 64\n"
00048 " -p pipeline specifies the size of the pipeline\n"
00049 " -s scope specifies the scope for the interests\n"
00050 " -a allow stale data\n",
00051 progname);
00052 exit(1);
00053 }
00054
00055 struct ccn_charbuf *
00056 make_template(int allow_stale, int scope)
00057 {
00058 struct ccn_charbuf *templ = ccn_charbuf_create();
00059 ccn_charbuf_append_tt(templ, CCN_DTAG_Interest, CCN_DTAG);
00060 ccn_charbuf_append_tt(templ, CCN_DTAG_Name, CCN_DTAG);
00061 ccn_charbuf_append_closer(templ);
00062
00063 ccn_charbuf_append_tt(templ, CCN_DTAG_MaxSuffixComponents, CCN_DTAG);
00064 ccnb_append_number(templ, 1);
00065 ccn_charbuf_append_closer(templ);
00066 if (allow_stale) {
00067 ccn_charbuf_append_tt(templ, CCN_DTAG_AnswerOriginKind, CCN_DTAG);
00068 ccnb_append_number(templ, CCN_AOK_DEFAULT | CCN_AOK_STALE);
00069 ccn_charbuf_append_closer(templ);
00070 }
00071 if (scope >= 0) {
00072 ccnb_tagged_putf(templ, CCN_DTAG_Scope, "%d", scope);
00073 }
00074 ccn_charbuf_append_closer(templ);
00075 return(templ);
00076 }
00077
00078
00079
00080
00081
00082
00083 int
00084 main(int argc, char **argv)
00085 {
00086 struct ccn *ccn = NULL;
00087 struct ccn_fetch *fetch = NULL;
00088 struct ccn_charbuf *name = NULL;
00089 struct ccn_charbuf *templ = NULL;
00090 const char *arg = NULL;
00091 int dflag = 0;
00092 int allow_stale = 0;
00093 int scope = -1;
00094 int pipeline = 4;
00095 unsigned char buf[8192];
00096 int i;
00097 int res;
00098 int opt;
00099 int assumeFixed = 0;
00100
00101 while ((opt = getopt(argc, argv, "had:p:s:")) != -1) {
00102 switch (opt) {
00103 case 'a':
00104 allow_stale = 1;
00105 break;
00106 case 'd':
00107 dflag = atoi(optarg);
00108 break;
00109 case 'p':
00110 pipeline = atoi(optarg);
00111 break;
00112 case 's':
00113 scope = atoi(optarg);
00114 break;
00115 case 'h':
00116 default:
00117 usage(argv[0]);
00118 }
00119 }
00120 arg = argv[optind];
00121 if (arg == NULL)
00122 usage(argv[0]);
00123 name = ccn_charbuf_create();
00124
00125 for (i = optind; argv[i] != NULL; i++) {
00126 name->length = 0;
00127 res = ccn_name_from_uri(name, argv[i]);
00128 if (res < 0) {
00129 fprintf(stderr, "%s: bad ccn URI: %s\n", argv[0], argv[i]);
00130 exit(1);
00131 }
00132 }
00133
00134 ccn = ccn_create();
00135 if (ccn_connect(ccn, NULL) == -1) {
00136 perror("Could not connect to ccnd");
00137 exit(1);
00138 }
00139
00140 templ = make_template(allow_stale, scope);
00141
00142 fetch = ccn_fetch_new(ccn);
00143 if (dflag) {
00144 ccn_fetch_set_debug(fetch, stderr, dflag);
00145 }
00146
00147 for (i = optind; (arg = argv[i]) != NULL; i++) {
00148 name->length = 0;
00149 res = ccn_name_from_uri(name, argv[i]);
00150 struct ccn_fetch_stream *stream = ccn_fetch_open(fetch, name, arg, templ, pipeline, CCN_V_HIGHEST, assumeFixed);
00151 if (NULL == stream) {
00152 continue;
00153 }
00154 while ((res = ccn_fetch_read(stream, buf, sizeof(buf))) != 0) {
00155 if (res > 0) {
00156 fwrite(buf, res, 1, stdout);
00157 } else if (res == CCN_FETCH_READ_NONE) {
00158 if (ccn_run(ccn, 1000) < 0) {
00159 fprintf(stderr, "%s: error during ccn_run\n", argv[0]);
00160 exit(1);
00161 }
00162 } else if (res == CCN_FETCH_READ_END) {
00163 break;
00164 } else if (res == CCN_FETCH_READ_TIMEOUT) {
00165
00166 ccn_reset_timeout(stream);
00167 if (ccn_run(ccn, 1000) < 0) {
00168 fprintf(stderr, "%s: error during ccn_run\n", argv[0]);
00169 exit(1);
00170 }
00171 } else {
00172
00173 fprintf(stderr, "%s: fetch error: %s\n", argv[0], arg);
00174 exit(1);
00175 }
00176 }
00177 stream = ccn_fetch_close(stream);
00178 }
00179 fflush(stdout);
00180 fetch = ccn_fetch_destroy(fetch);
00181 ccn_destroy(&ccn);
00182 ccn_charbuf_destroy(&name);
00183 exit(0);
00184 }