ccnpeek.c

Go to the documentation of this file.
00001 /**
00002  * @file ccnpeek.c
00003  * Get one content item matching the name prefix and write it to stdout.
00004  * Written as test for ccn_get, but probably useful for debugging.
00005  *
00006  * A CCNx command-line utility.
00007  *
00008  * Copyright (C) 2009-2010 Palo Alto Research Center, Inc.
00009  *
00010  * This work is free software; you can redistribute it and/or modify it under
00011  * the terms of the GNU General Public License version 2 as published by the
00012  * Free Software Foundation.
00013  * This work is distributed in the hope that it will be useful, but WITHOUT ANY
00014  * WARRANTY; without even the implied warranty of MERCHANTABILITY or
00015  * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
00016  * for more details. You should have received a copy of the GNU General Public
00017  * License along with this program; if not, write to the
00018  * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
00019  * Boston, MA 02110-1301, USA.
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); /* </Name> */
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); /* </AnswerOriginKind> */
00151                 }
00152         if (scope != -1) {
00153             ccnb_tagged_putf(templ, CCN_DTAG_Scope, "%d", scope);
00154         }
00155                 if (lifetime_l12 != lifetime_default) {
00156                         /*
00157                          * Choose the interest lifetime so there are at least 3
00158                          * expressions (in the unsatisfied case).
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); /* </Interest> */
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 }

Generated on Thu Feb 16 00:43:59 2012 for Content-Centric Networking in C by  doxygen 1.5.6