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 <errno.h>
00026 #include <ccn/bloom.h>
00027 #include <ccn/ccn.h>
00028 #include <ccn/charbuf.h>
00029 #include <ccn/uri.h>
00030
00031 static void
00032 usage(const char *progname)
00033 {
00034 fprintf(stderr,
00035 "%s [-a] [-c] [-l lifetime] [-s scope] [-u] [-v] [-w timeout] ccnx:/a/b\n"
00036 " Get one content item matching the name prefix and write it to stdout"
00037 "\n"
00038 " -a - allow stale data\n"
00039 " -c - content only, not full ccnb\n"
00040 " -l x - lifetime (seconds) of interest. 0.00012 < x <= 30.0000, Default 4.\n"
00041 " -s {0,1,2} - scope of interest. Default none.\n"
00042 " -u - allow unverified content\n"
00043 " -v - resolve version number\n"
00044 " -w x - wait time (seconds) for response. 0.001 <= timeout <= 60.000, Default 3.0\n",
00045 progname);
00046 exit(1);
00047 }
00048
00049 int
00050 main(int argc, char **argv)
00051 {
00052 struct ccn *h = NULL;
00053 struct ccn_charbuf *name = NULL;
00054 struct ccn_charbuf *templ = NULL;
00055 struct ccn_charbuf *resultbuf = NULL;
00056 const char *arg = NULL;
00057 struct ccn_parsed_ContentObject pcobuf = { 0 };
00058 int res;
00059 int opt;
00060 int allow_stale = 0;
00061 int content_only = 0;
00062 int scope = -1;
00063 const unsigned char *ptr;
00064 size_t length;
00065 int resolve_version = 0;
00066 int timeout_ms = 3000;
00067 const unsigned lifetime_default = CCN_INTEREST_LIFETIME_SEC << 12;
00068 unsigned lifetime_l12 = lifetime_default;
00069 double lifetime;
00070 int get_flags = 0;
00071
00072 while ((opt = getopt(argc, argv, "acl:s:uvw:h")) != -1) {
00073 switch (opt) {
00074 case 'a':
00075 allow_stale = 1;
00076 break;
00077 case 'c':
00078 content_only = 1;
00079 break;
00080 case 'l':
00081 errno = 0;
00082 lifetime = strtod(optarg, NULL);
00083 if (errno != 0) {
00084 perror(optarg);
00085 exit(1);
00086 }
00087 lifetime_l12 = 4096 * (lifetime + 1.0/8192.0);
00088 if (lifetime_l12 == 0 || lifetime_l12 > (30 << 12)) {
00089 fprintf(stderr, "%.5f: invalid lifetime. %.5f < lifetime <= 30.0\n", lifetime, 1.0/8192.0);
00090 exit(1);
00091 }
00092 break;
00093 case 's':
00094 scope = atoi(optarg);
00095 if (scope < 0 || scope > 2) {
00096 fprintf(stderr, "%d: invalid scope. 0 <= scope <= 2\n", scope);
00097 exit(1);
00098 }
00099 case 'u':
00100 get_flags |= CCN_GET_NOKEYWAIT;
00101 break;
00102 case 'v':
00103 if (resolve_version == 0)
00104 resolve_version = CCN_V_HIGHEST;
00105 else
00106 resolve_version = CCN_V_HIGH;
00107 break;
00108 case 'w':
00109 timeout_ms = strtod(optarg, NULL) * 1000;
00110 if (timeout_ms <= 0 || timeout_ms > 60000) {
00111 fprintf(stderr, "%s: invalid timeout. 0.001 <= timeout <= 60.000\n", optarg);
00112 exit(1);
00113 }
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 res = ccn_name_from_uri(name, arg);
00125 if (res < 0) {
00126 fprintf(stderr, "%s: bad ccn URI: %s\n", argv[0], arg);
00127 exit(1);
00128 }
00129 if (argv[optind + 1] != NULL)
00130 fprintf(stderr, "%s warning: extra arguments ignored\n", argv[0]);
00131 h = ccn_create();
00132 res = ccn_connect(h, NULL);
00133 if (res < 0) {
00134 ccn_perror(h, "ccn_connect");
00135 exit(1);
00136 }
00137 if (res < 0) {
00138 fprintf(stderr, "%s: bad ccn URI: %s\n", argv[0], arg);
00139 exit(1);
00140 }
00141 if (allow_stale || lifetime_l12 != lifetime_default || scope != -1) {
00142 templ = ccn_charbuf_create();
00143 ccn_charbuf_append_tt(templ, CCN_DTAG_Interest, CCN_DTAG);
00144 ccn_charbuf_append_tt(templ, CCN_DTAG_Name, CCN_DTAG);
00145 ccn_charbuf_append_closer(templ);
00146 if (allow_stale) {
00147 ccn_charbuf_append_tt(templ, CCN_DTAG_AnswerOriginKind, CCN_DTAG);
00148 ccnb_append_number(templ,
00149 CCN_AOK_DEFAULT | CCN_AOK_STALE);
00150 ccn_charbuf_append_closer(templ);
00151 }
00152 if (scope != -1) {
00153 ccnb_tagged_putf(templ, CCN_DTAG_Scope, "%d", scope);
00154 }
00155 if (lifetime_l12 != lifetime_default) {
00156
00157
00158
00159
00160 unsigned char buf[3] = { 0 };
00161 int i;
00162 for (i = sizeof(buf) - 1; i >= 0; i--, lifetime_l12 >>= 8)
00163 buf[i] = lifetime_l12 & 0xff;
00164 ccnb_append_tagged_blob(templ, CCN_DTAG_InterestLifetime, buf, sizeof(buf));
00165 }
00166 ccn_charbuf_append_closer(templ);
00167 }
00168 resultbuf = ccn_charbuf_create();
00169 if (resolve_version != 0) {
00170 res = ccn_resolve_version(h, name, resolve_version, 500);
00171 if (res >= 0) {
00172 ccn_uri_append(resultbuf, name->buf, name->length, 1);
00173 fprintf(stderr, "== %s\n",
00174 ccn_charbuf_as_string(resultbuf));
00175 resultbuf->length = 0;
00176 }
00177 }
00178 res = ccn_get(h, name, templ, timeout_ms, resultbuf, &pcobuf, NULL, get_flags);
00179 if (res >= 0) {
00180 ptr = resultbuf->buf;
00181 length = resultbuf->length;
00182 if (content_only)
00183 ccn_content_get_value(ptr, length, &pcobuf, &ptr, &length);
00184 if (length > 0)
00185 res = fwrite(ptr, length, 1, stdout) - 1;
00186 }
00187 ccn_charbuf_destroy(&resultbuf);
00188 ccn_charbuf_destroy(&templ);
00189 ccn_charbuf_destroy(&name);
00190 ccn_destroy(&h);
00191 exit(res < 0);
00192 }