ccn_splitccnb.c

Go to the documentation of this file.
00001 /**
00002  * @file ccn_splitccnb.c
00003  * Utility to break up a file filled with ccnb-encoded data items into
00004  * one data item per file.
00005  *
00006  * A CCNx command-line utility.
00007  *
00008  * Copyright (C) 2008, 2009 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 
00022 #include <fcntl.h>
00023 #include <sys/types.h>
00024 #include <sys/stat.h>
00025 #include <sys/mman.h>
00026 #include <limits.h>
00027 #include <stddef.h>
00028 #include <stdio.h>
00029 #include <stdlib.h>
00030 #include <string.h>
00031 #include <unistd.h>
00032 
00033 #include <ccn/coding.h>
00034 
00035 struct fstate {
00036     char *prefix;
00037     int segnum;
00038 };
00039 
00040 static char *
00041 segment_prefix(char *path)
00042 {
00043     char *s, *d, *r;
00044 
00045     s = strrchr(path, '/');
00046     if (s == NULL) s = path;
00047     d = strrchr(s, '.');
00048     if (d == NULL) d = s + strlen(s);
00049     r = calloc(1, 1 + d - path);
00050     memcpy(r, path, d - path);
00051     return (r);
00052 }
00053 
00054 static int
00055 write_segment(unsigned char *data, size_t s, struct fstate *perfilestate)
00056 {
00057     int ofd;
00058     char ofile[256];
00059     mode_t mode = S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH;
00060     int res;
00061 
00062     sprintf(ofile, "%s-%05d.ccnb", perfilestate->prefix, perfilestate->segnum);
00063     ofd = open(ofile, O_CREAT | O_WRONLY | O_TRUNC, mode);
00064     if (ofd == -1) {
00065         perror("open");
00066         return (1);
00067     }
00068     res = write(ofd, data, s);
00069     close(ofd);
00070     if (res != s) {
00071         perror("write");
00072         return (1);
00073     }
00074     perfilestate->segnum++;
00075     return (0);
00076 }
00077 
00078 static int
00079 process_test(unsigned char *data, size_t n, struct fstate *perfilestate)
00080 {
00081     struct ccn_skeleton_decoder skel_decoder = {0};
00082     struct ccn_skeleton_decoder *d = &skel_decoder;
00083     int res = 0;
00084     size_t s;
00085 
00086  retry:
00087     s = ccn_skeleton_decode(d, data, n);
00088     if (d->state < 0) {
00089         res = 1;
00090         fprintf(stderr, "error state %d after %d of %d chars\n",
00091             (int)d->state, (int)s, (int)n);
00092     }
00093     else if (s == 0) {
00094         fprintf(stderr, "nothing to do\n");
00095     }
00096     else {
00097         if (s < n) {
00098             if (write_segment(data, s, perfilestate) != 0) {
00099                 return (1);
00100             }
00101             /* fprintf(stderr, "resuming at index %d\n", (int)d->index); */
00102             data += s;
00103             n -= s;
00104             goto retry;
00105         }
00106         fprintf(stderr, "\n");
00107     }
00108     if (!CCN_FINAL_DSTATE(d->state)) {
00109         res = 1;
00110         fprintf(stderr, "incomplete state %d after %d of %d chars\n",
00111             (int)d->state, (int)s, (int)n);
00112     } else  if (write_segment(data, s, perfilestate) != 0) {
00113         res = 1;
00114     }
00115     return(res);
00116 }
00117 
00118 static int
00119 process_fd(int fd, struct fstate *perfilestate)
00120 {
00121     unsigned char *buf;
00122     ssize_t len;
00123     struct stat s;
00124     int res = 0;
00125 
00126     res = fstat(fd, &s);
00127     len = s.st_size;
00128     buf = (unsigned char *)mmap((void *)NULL, len, PROT_READ, MAP_PRIVATE, fd, 0);
00129     if (buf == (void *)-1) return (1);
00130     fprintf(stderr, " <!-- input is %6lu bytes -->\n", (unsigned long)len);
00131     res |= process_test(buf, len, perfilestate);
00132     munmap((void *)buf, len);
00133     return(res);
00134 }
00135 
00136 
00137 static int
00138 process_file(char *path, struct fstate *perfilestate)
00139 {
00140     int fd;
00141     int res = 0;
00142 
00143     fd = open(path, O_RDONLY);
00144     if (-1 == fd) {
00145         perror(path);
00146         return(1);
00147     }
00148 
00149     perfilestate->segnum = 0;
00150     if (perfilestate->prefix != NULL) free(perfilestate->prefix);
00151     perfilestate->prefix = segment_prefix(path);
00152 
00153     res = process_fd(fd, perfilestate);
00154     if (fd > 0)
00155         close(fd);
00156     return(res);
00157 }
00158 
00159 int
00160 main(int argc, char *argv[])
00161 {
00162     int i;
00163     int res = 0;
00164     struct fstate perfilestate = {0};
00165 
00166     for (i = 1; argv[i] != 0; i++) {
00167         fprintf(stderr, "<!-- Processing %s -->\n", argv[i]);
00168         res |= process_file(argv[i], &perfilestate);
00169     }
00170     return(res);
00171 }
00172 

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