ccnget.c

Go to the documentation of this file.
00001 /**
00002  * @file ccnget.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 <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); /* </Name> */
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); /* </AnswerOriginKind> */
00116                 }
00117                 if (env_timeout != NULL) {
00118                         /*
00119                          * Choose the interest lifetime so there are at least 3
00120                          * expressions (in the unsatisfied case).
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); /* </Interest> */
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 }
Generated on Fri May 13 16:27:01 2011 for Content-Centric Networking in C by  doxygen 1.6.3