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/bloom.h>
00026 #include <ccn/ccn.h>
00027 #include <ccn/charbuf.h>
00028 #include <ccn/uri.h>
00029
00030 static void
00031 usage(const char *progname)
00032 {
00033 fprintf(stderr,
00034 "%s [-a] [-c] ccnx:/a/b\n"
00035 " Get one content item matching the name prefix and write it to stdout"
00036 "\n"
00037 " -a - allow stale data\n"
00038 " -c - content only, not full ccnb\n"
00039 " -v - resolve version number\n",
00040 progname);
00041 exit(1);
00042 }
00043
00044 int
00045 main(int argc, char **argv)
00046 {
00047 struct ccn *h = NULL;
00048 struct ccn_charbuf *name = NULL;
00049 struct ccn_charbuf *templ = NULL;
00050 struct ccn_charbuf *resultbuf = NULL;
00051 const char *arg = NULL;
00052 struct ccn_parsed_ContentObject pcobuf = { 0 };
00053 int res;
00054 int opt;
00055 int allow_stale = 0;
00056 int content_only = 0;
00057 const unsigned char *ptr;
00058 size_t length;
00059 int resolve_version = 0;
00060 const char *env_timeout = getenv("CCN_LINGER");
00061 int timeout_ms = 3000;
00062
00063 while ((opt = getopt(argc, argv, "hacv")) != -1) {
00064 switch (opt) {
00065 case 'a':
00066 allow_stale = 1;
00067 break;
00068 case 'c':
00069 content_only = 1;
00070 break;
00071 case 'v':
00072 if (resolve_version == 0)
00073 resolve_version = CCN_V_HIGHEST;
00074 else
00075 resolve_version = CCN_V_HIGH;
00076 break;
00077 case 'h':
00078 default:
00079 usage(argv[0]);
00080 }
00081 }
00082 arg = argv[optind];
00083 if (arg == NULL)
00084 usage(argv[0]);
00085 name = ccn_charbuf_create();
00086 res = ccn_name_from_uri(name, arg);
00087 if (res < 0) {
00088 fprintf(stderr, "%s: bad ccn URI: %s\n", argv[0], arg);
00089 exit(1);
00090 }
00091 if (argv[optind + 1] != NULL)
00092 fprintf(stderr, "%s warning: extra arguments ignored\n", argv[0]);
00093 h = ccn_create();
00094 res = ccn_connect(h, NULL);
00095 if (res < 0) {
00096 ccn_perror(h, "ccn_connect");
00097 exit(1);
00098 }
00099 if (res < 0) {
00100 fprintf(stderr, "%s: bad ccn URI: %s\n", argv[0], arg);
00101 exit(1);
00102 }
00103 if (env_timeout != NULL && (res = atoi(env_timeout)) > 0) {
00104 timeout_ms = res * 1000;
00105 }
00106 if (allow_stale || env_timeout != NULL) {
00107 templ = ccn_charbuf_create();
00108 ccn_charbuf_append_tt(templ, CCN_DTAG_Interest, CCN_DTAG);
00109 ccn_charbuf_append_tt(templ, CCN_DTAG_Name, CCN_DTAG);
00110 ccn_charbuf_append_closer(templ);
00111 if (allow_stale) {
00112 ccn_charbuf_append_tt(templ, CCN_DTAG_AnswerOriginKind, CCN_DTAG);
00113 ccnb_append_number(templ,
00114 CCN_AOK_DEFAULT | CCN_AOK_STALE);
00115 ccn_charbuf_append_closer(templ);
00116 }
00117 if (env_timeout != NULL) {
00118
00119
00120
00121
00122 unsigned char buf[3] = { 0 };
00123 unsigned lifetime;
00124 int i;
00125 if (timeout_ms > 60000)
00126 lifetime = 30 << 12;
00127 else {
00128 lifetime = timeout_ms * 2 / 5 * 4096 / 1000;
00129 }
00130 for (i = sizeof(buf) - 1; i >= 0; i--, lifetime >>= 8)
00131 buf[i] = lifetime & 0xff;
00132 ccnb_append_tagged_blob(templ, CCN_DTAG_InterestLifetime, buf, sizeof(buf));
00133 }
00134 ccn_charbuf_append_closer(templ);
00135 }
00136 resultbuf = ccn_charbuf_create();
00137 if (resolve_version != 0) {
00138 res = ccn_resolve_version(h, name, resolve_version, 500);
00139 if (res >= 0) {
00140 ccn_uri_append(resultbuf, name->buf, name->length, 1);
00141 fprintf(stderr, "== %s\n",
00142 ccn_charbuf_as_string(resultbuf));
00143 resultbuf->length = 0;
00144 }
00145 }
00146 res = ccn_get(h, name, templ, timeout_ms, resultbuf, &pcobuf, NULL, 0);
00147 if (res >= 0) {
00148 ptr = resultbuf->buf;
00149 length = resultbuf->length;
00150 if (content_only)
00151 ccn_content_get_value(ptr, length, &pcobuf, &ptr, &length);
00152 if (length > 0)
00153 res = fwrite(ptr, length, 1, stdout) - 1;
00154 }
00155 ccn_charbuf_destroy(&resultbuf);
00156 ccn_charbuf_destroy(&templ);
00157 ccn_charbuf_destroy(&name);
00158 ccn_destroy(&h);
00159 exit(res < 0);
00160 }