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. Default 4.\n"
00049 " pipeline >= 0.\n"
00050 " -s scope specifies the scope for the interests. Default unlimited.\n"
00051 " scope = 0 (cache), 1 (local), 2 (neighborhood), 3 (unlimited).\n"
00052 " -a allow stale data\n",
00053 progname);
00054 exit(1);
00055 }
00056
00057 struct ccn_charbuf *
00058 make_template(int allow_stale, int scope)
00059 {
00060 struct ccn_charbuf *templ = ccn_charbuf_create();
00061 ccn_charbuf_append_tt(templ, CCN_DTAG_Interest, CCN_DTAG);
00062 ccn_charbuf_append_tt(templ, CCN_DTAG_Name, CCN_DTAG);
00063 ccn_charbuf_append_closer(templ);
00064
00065 ccn_charbuf_append_tt(templ, CCN_DTAG_MaxSuffixComponents, CCN_DTAG);
00066 ccnb_append_number(templ, 1);
00067 ccn_charbuf_append_closer(templ);
00068 if (allow_stale) {
00069 ccn_charbuf_append_tt(templ, CCN_DTAG_AnswerOriginKind, CCN_DTAG);
00070 ccnb_append_number(templ, CCN_AOK_DEFAULT | CCN_AOK_STALE);
00071 ccn_charbuf_append_closer(templ);
00072 }
00073 if (scope >= 0 && scope <= 2) {
00074 ccnb_tagged_putf(templ, CCN_DTAG_Scope, "%d", scope);
00075 }
00076 ccn_charbuf_append_closer(templ);
00077 return(templ);
00078 }
00079
00080
00081
00082
00083
00084
00085 int
00086 main(int argc, char **argv)
00087 {
00088 struct ccn *ccn = NULL;
00089 struct ccn_fetch *fetch = NULL;
00090 struct ccn_charbuf *name = NULL;
00091 struct ccn_charbuf *templ = NULL;
00092 const char *arg = NULL;
00093 int dflag = 0;
00094 int allow_stale = 0;
00095 int scope = -1;
00096 int pipeline = 4;
00097 unsigned char buf[8192];
00098 int i;
00099 int res;
00100 int opt;
00101 int assumeFixed = 0;
00102
00103 while ((opt = getopt(argc, argv, "had:p:s:")) != -1) {
00104 switch (opt) {
00105 case 'a':
00106 allow_stale = 1;
00107 break;
00108 case 'd':
00109 dflag = atoi(optarg);
00110 break;
00111 case 'p':
00112 pipeline = atoi(optarg);
00113 if (pipeline < 0)
00114 usage(argv[0]);
00115 break;
00116 case 's':
00117 scope = atoi(optarg);
00118 if (scope < 0 || scope > 3)
00119 usage(argv[0]);
00120 break;
00121 case 'h':
00122 default:
00123 usage(argv[0]);
00124 }
00125 }
00126 arg = argv[optind];
00127 if (arg == NULL)
00128 usage(argv[0]);
00129 name = ccn_charbuf_create();
00130
00131 for (i = optind; argv[i] != NULL; i++) {
00132 name->length = 0;
00133 res = ccn_name_from_uri(name, argv[i]);
00134 if (res < 0) {
00135 fprintf(stderr, "%s: bad ccn URI: %s\n", argv[0], argv[i]);
00136 exit(1);
00137 }
00138 }
00139
00140 ccn = ccn_create();
00141 if (ccn_connect(ccn, NULL) == -1) {
00142 perror("Could not connect to ccnd");
00143 exit(1);
00144 }
00145
00146 templ = make_template(allow_stale, scope);
00147
00148 fetch = ccn_fetch_new(ccn);
00149 if (dflag) {
00150 ccn_fetch_set_debug(fetch, stderr, dflag);
00151 }
00152
00153 for (i = optind; (arg = argv[i]) != NULL; i++) {
00154 name->length = 0;
00155 res = ccn_name_from_uri(name, argv[i]);
00156 struct ccn_fetch_stream *stream = ccn_fetch_open(fetch, name, arg, templ, pipeline, CCN_V_HIGHEST, assumeFixed);
00157 if (NULL == stream) {
00158 continue;
00159 }
00160 while ((res = ccn_fetch_read(stream, buf, sizeof(buf))) != 0) {
00161 if (res > 0) {
00162 fwrite(buf, res, 1, stdout);
00163 } else if (res == CCN_FETCH_READ_NONE) {
00164 fflush(stdout);
00165 if (ccn_run(ccn, 1000) < 0) {
00166 fprintf(stderr, "%s: error during ccn_run\n", argv[0]);
00167 exit(1);
00168 }
00169 } else if (res == CCN_FETCH_READ_END) {
00170 break;
00171 } else if (res == CCN_FETCH_READ_TIMEOUT) {
00172
00173 ccn_reset_timeout(stream);
00174 fflush(stdout);
00175 if (ccn_run(ccn, 1000) < 0) {
00176 fprintf(stderr, "%s: error during ccn_run\n", argv[0]);
00177 exit(1);
00178 }
00179 } else {
00180
00181 fprintf(stderr, "%s: fetch error: %s\n", argv[0], arg);
00182 exit(1);
00183 }
00184 }
00185 stream = ccn_fetch_close(stream);
00186 }
00187 fflush(stdout);
00188 fetch = ccn_fetch_destroy(fetch);
00189 ccn_destroy(&ccn);
00190 ccn_charbuf_destroy(&name);
00191 exit(0);
00192 }