ccnseqwriter.c

Go to the documentation of this file.
00001 /**
00002  * @file ccnseqwriter.c
00003  * Streams data from stdin into ccn
00004  *
00005  * A CCNx command-line utility.
00006  *
00007  * Copyright (C) 2010-2012 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 <errno.h>
00021 #include <stdio.h>
00022 #include <stdlib.h>
00023 #include <string.h>
00024 #include <unistd.h>
00025 #include <ccn/ccn.h>
00026 #include <ccn/uri.h>
00027 #include <ccn/seqwriter.h>
00028 
00029 static void
00030 usage(const char *progname)
00031 {
00032         fprintf(stderr,
00033                 "%s [-h] [-b 0<blocksize<=4096] [-r] ccnx:/some/uri\n"
00034                 "    Reads stdin, sending data under the given URI"
00035                 " using ccn versioning and segmentation.\n"
00036                 "    -h generate this help message.\n"
00037                 "    -b specify the block (segment) size for content objects.  Default 1024.\n"
00038                 "    -r generate start-write interest so a repository will"
00039                 " store the content.\n"
00040                 "    -s n set scope of start-write interest.\n"
00041                 "       n = 1(local), 2(neighborhood), 3(everywhere) Default 1.\n",
00042                 progname);
00043         exit(1);
00044 }
00045 /*
00046  * make_template: construct an interest template containing the specified scope
00047  *     An unlimited scope is passed in as 3, and the omission of the scope
00048  *     field from the template indicates this.
00049  */
00050 struct ccn_charbuf *
00051 make_template(int scope)
00052 {
00053     struct ccn_charbuf *templ = NULL;
00054     templ = ccn_charbuf_create();
00055     ccn_charbuf_append_tt(templ, CCN_DTAG_Interest, CCN_DTAG);
00056     ccn_charbuf_append_tt(templ, CCN_DTAG_Name, CCN_DTAG);
00057     ccn_charbuf_append_closer(templ); /* </Name> */
00058     if (0 <= scope && scope <= 2)
00059         ccnb_tagged_putf(templ, CCN_DTAG_Scope, "%d", scope);
00060     ccn_charbuf_append_closer(templ); /* </Interest> */
00061     return(templ);
00062 }
00063 
00064 int
00065 main(int argc, char **argv)
00066 {
00067     const char *progname = argv[0];
00068     struct ccn *ccn = NULL;
00069     struct ccn_charbuf *name = NULL;
00070     struct ccn_seqwriter *w = NULL;
00071     int blocksize = 1024;
00072     int torepo = 0;
00073     int scope = 1;
00074     int i;
00075     int status = 0;
00076     int res;
00077     ssize_t read_res;
00078     size_t blockread;
00079     unsigned char *buf = NULL;
00080     struct ccn_charbuf *templ;
00081     
00082     while ((res = getopt(argc, argv, "hrb:s:")) != -1) {
00083         switch (res) {
00084             case 'b':
00085                 blocksize = atoi(optarg);
00086                 if (blocksize <= 0 || blocksize > 4096)
00087                     usage(progname);
00088                 break;
00089             case 'r':
00090                 torepo = 1;
00091                 break;
00092             case 's':
00093                 scope = atoi(optarg);
00094                 if (scope < 1 || scope > 3)
00095                     usage(progname);
00096                 break;
00097             default:
00098             case 'h':
00099                 usage(progname);
00100                 break;
00101         }
00102     }
00103     argc -= optind;
00104     argv += optind;
00105     if (argc != 1)
00106         usage(progname);
00107     name = ccn_charbuf_create();
00108     res = ccn_name_from_uri(name, argv[0]);
00109     if (res < 0) {
00110         fprintf(stderr, "%s: bad CCN URI: %s\n", progname, argv[0]);
00111         exit(1);
00112     }
00113     ccn = ccn_create();
00114     if (ccn_connect(ccn, NULL) == -1) {
00115         perror("Could not connect to ccnd");
00116         exit(1);
00117     }
00118     
00119     buf = calloc(1, blocksize);
00120     
00121     w = ccn_seqw_create(ccn, name);
00122     if (w == NULL) {
00123         fprintf(stderr, "ccn_seqw_create failed\n");
00124         exit(1);
00125     }
00126     ccn_seqw_set_block_limits(w, blocksize, blocksize);
00127     if (torepo) {
00128         struct ccn_charbuf *name_v = ccn_charbuf_create();
00129         ccn_seqw_get_name(w, name_v);
00130         ccn_name_from_uri(name_v, "%C1.R.sw");
00131         ccn_name_append_nonce(name_v);
00132         templ = make_template(scope);
00133         res = ccn_get(ccn, name_v, templ, 60000, NULL, NULL, NULL, 0);
00134         ccn_charbuf_destroy(&templ);
00135         ccn_charbuf_destroy(&name_v);
00136         if (res < 0) {
00137             fprintf(stderr, "No response from repository\n");
00138             exit(1);
00139         }
00140     }
00141     blockread = 0;
00142     for (i = 0;; i++) {
00143         while (blockread < blocksize) {
00144             ccn_run(ccn, 1);
00145             read_res = read(0, buf + blockread, blocksize - blockread);
00146             if (read_res == 0)
00147                 goto cleanup;
00148             if (read_res < 0) {
00149                 perror("read");
00150                 status = 1;
00151                 goto cleanup;
00152             }
00153             blockread += read_res;
00154         }
00155         res = ccn_seqw_write(w, buf, blockread);
00156         while (res == -1) {
00157             ccn_run(ccn, 100);
00158             res = ccn_seqw_write(w, buf, blockread);
00159         }
00160         if (res != blockread)
00161             abort(); /* hmm, ccn_seqw_write did a short write or something */
00162         blockread = 0;
00163     }
00164     
00165 cleanup:
00166     // flush out any remaining data and close
00167     if (blockread > 0) {
00168         res = ccn_seqw_write(w, buf, blockread);
00169         while (res == -1) {
00170             ccn_run(ccn, 100);
00171             res = ccn_seqw_write(w, buf, blockread);
00172         }
00173     }
00174     ccn_seqw_close(w);
00175     ccn_run(ccn, 1);
00176     free(buf);
00177     buf = NULL;
00178     ccn_charbuf_destroy(&name);
00179     ccn_destroy(&ccn);
00180     exit(status);
00181 }

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