ccnrm.c

Go to the documentation of this file.
00001 /**
00002  * @file ccnrm.c
00003  * Mark as stale any local items a matching given prefixes.
00004  *
00005  * A CCNx command-line utility.
00006  *
00007  * Copyright (C) 2008-2010 Palo Alto Research Center, Inc.
00008  *
00009  * This work is free software; you can redistribute it and/or modify it under
00010  * the terms of the GNU General Public License version 2 as published by the
00011  * Free Software Foundation.
00012  * This work is distributed in the hope that it will be useful, but WITHOUT ANY
00013  * WARRANTY; without even the implied warranty of MERCHANTABILITY or
00014  * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
00015  * for more details. You should have received a copy of the GNU General Public
00016  * License along with this program; if not, write to the
00017  * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
00018  * Boston, MA 02110-1301, USA.
00019  */
00020 #include <stdio.h>
00021 #include <stdlib.h>
00022 #include <string.h>
00023 #include <unistd.h>
00024 #include <ccn/ccn.h>
00025 #include <ccn/uri.h>
00026 
00027 static void
00028 usage(const char *progname)
00029 {
00030     fprintf(stderr,
00031             "%s [-o outfile] ccnx:/a/b ...\n"
00032             "   Remove (mark stale) content matching the given ccn URIs\n"
00033             "   -o outfile - write the ccnb-encoded content to the named file\n",
00034             progname);
00035     exit(1);
00036 }
00037 
00038 /***********
00039 <Interest>
00040   <Name/>
00041   <AnswerOriginKind>19</AnswerOriginKind>
00042   <Scope>0</Scope>
00043 </Interest>
00044 **********/
00045 struct ccn_charbuf *
00046 local_scope_rm_template(void)
00047 {
00048     struct ccn_charbuf *templ = ccn_charbuf_create();
00049     ccn_charbuf_append_tt(templ, CCN_DTAG_Interest, CCN_DTAG);
00050     ccn_charbuf_append_tt(templ, CCN_DTAG_Name, CCN_DTAG);
00051     ccn_charbuf_append_closer(templ); /* </Name> */
00052     ccnb_tagged_putf(templ, CCN_DTAG_AnswerOriginKind, "%2d",
00053                      (CCN_AOK_EXPIRE | CCN_AOK_DEFAULT));
00054     ccnb_tagged_putf(templ, CCN_DTAG_Scope, "0");
00055     ccn_charbuf_append_closer(templ); /* </Interest> */
00056     return(templ);
00057 }
00058 
00059 static
00060 struct mydata {
00061     int nseen;
00062     FILE *output;
00063 } mydata = {0, NULL};
00064 
00065 enum ccn_upcall_res
00066 incoming_content(
00067     struct ccn_closure *selfp,
00068     enum ccn_upcall_kind kind,
00069     struct ccn_upcall_info *info)
00070 {
00071     struct mydata *md = selfp->data;
00072 
00073     if (kind == CCN_UPCALL_FINAL)
00074         return(CCN_UPCALL_RESULT_OK);
00075     if (md == NULL)
00076         return(CCN_UPCALL_RESULT_ERR);
00077     if (kind == CCN_UPCALL_INTEREST_TIMED_OUT)
00078         return(CCN_UPCALL_RESULT_REEXPRESS);
00079     if ((kind != CCN_UPCALL_CONTENT && kind != CCN_UPCALL_CONTENT_UNVERIFIED))
00080         return(CCN_UPCALL_RESULT_ERR);
00081     md->nseen++;
00082     if (md->output != NULL)
00083         fwrite(info->content_ccnb, info->pco->offset[CCN_PCO_E], 1, md->output);
00084     return(CCN_UPCALL_RESULT_REEXPRESS);
00085 }
00086 
00087 /* Use some static data for this simple program */
00088 static struct ccn_closure incoming_content_action = {
00089     .p = &incoming_content,
00090     .data = &mydata
00091 };
00092 
00093 int
00094 main(int argc, char **argv)
00095 {
00096     struct ccn *ccn = NULL;
00097     struct ccn_charbuf *c = NULL;
00098     struct ccn_charbuf *templ = NULL;
00099     int i;
00100     int res;
00101     int opt;
00102     FILE* closethis = NULL;
00103     
00104     while ((opt = getopt(argc, argv, "ho:")) != -1) {
00105         switch (opt) {
00106             case 'o':
00107                 if (strcmp(optarg, "-") == 0)
00108                     mydata.output = stdout;
00109                 else
00110                     mydata.output = closethis = fopen(optarg, "wb");
00111                 if (mydata.output == NULL) {
00112                     perror(optarg);
00113                     exit(1);
00114                 }
00115                 break;
00116             case 'h': /* FALLTHRU */
00117             default: usage(argv[0]);
00118         }
00119     }
00120     
00121     ccn = ccn_create();
00122     if (ccn_connect(ccn, NULL) == -1) {
00123         perror("Could not connect to ccnd");
00124         exit(1);
00125     }
00126     c = ccn_charbuf_create();
00127     /* set scope to only address ccnd, expire anything we get */
00128     templ = local_scope_rm_template();
00129     for (i = optind; argv[i] != NULL; i++) {
00130         c->length = 0;
00131         res = ccn_name_from_uri(c, argv[i]);
00132         if (res < 0) {
00133             fprintf(stderr, "%s: bad ccn URI: %s\n", argv[0], argv[i]);
00134             exit(1);
00135         }
00136         ccn_express_interest(ccn, c, &incoming_content_action, templ);
00137     }
00138     if (i == optind)
00139         usage(argv[0]);
00140     ccn_charbuf_destroy(&templ);
00141     ccn_charbuf_destroy(&c);
00142     for (i = 0;; i++) {
00143         res = mydata.nseen;
00144         ccn_run(ccn, 100); /* stop if we run dry for 1/10 sec */
00145         if (res == mydata.nseen)
00146             break;
00147     }
00148     if (closethis != NULL)
00149         fclose(closethis);
00150     ccn_destroy(&ccn);
00151     fprintf(stderr, "marked stale: %d\n", mydata.nseen);
00152     exit(0);
00153 }

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