00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
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 #include <ccn/uri.h>
00035
00036
00037
00038
00039
00040 static size_t
00041 process_data(struct ccn_skeleton_decoder *d, unsigned char *data, size_t n, struct ccn_charbuf *c)
00042 {
00043 size_t s;
00044
00045 retry:
00046 s = ccn_skeleton_decode(d, data, n);
00047 if (d->state < 0)
00048 return (0);
00049 if (CCN_FINAL_DSTATE(d->state)) {
00050 c->length = 0;
00051 ccn_uri_append(c, data, s, 1);
00052 printf("%s\n", ccn_charbuf_as_string(c));
00053 data += s;
00054 n -= s;
00055 if (n > 0) goto retry;
00056 }
00057 return(n);
00058 }
00059
00060 static int
00061 process_fd(int fd, struct ccn_charbuf *c)
00062 {
00063 struct ccn_skeleton_decoder skel_decoder = {0};
00064 struct ccn_skeleton_decoder *d = &skel_decoder;
00065 unsigned char *bufp;
00066 unsigned char buf[1024 * 1024];
00067 ssize_t len;
00068 struct stat s;
00069 size_t res = 0;
00070
00071 if (0 != fstat(fd, &s)) {
00072 perror("fstat");
00073 return(1);
00074 }
00075
00076 if (S_ISREG(s.st_mode)) {
00077 res = s.st_size;
00078 bufp = (unsigned char *)mmap((void *)NULL, res,
00079 PROT_READ, MAP_PRIVATE, fd, 0);
00080 if (bufp != (void *)-1) {
00081 res = process_data(d, bufp, res, c);
00082 if (!CCN_FINAL_DSTATE(d->state)) {
00083 fprintf(stderr, "%s state %d after %lu bytes\n",
00084 (d->state < 0) ? "error" : "incomplete",
00085 (int)d->state,
00086 (unsigned long)d->index);
00087 return(1);
00088 }
00089 return(0);
00090 }
00091 }
00092
00093
00094 bufp = &buf[0];
00095 res = 0;
00096 while ((len = read(fd, bufp + res, sizeof(buf) - res)) > 0) {
00097 len += res;
00098 res = process_data(d, bufp, len, c);
00099 if (d->state < 0) {
00100 fprintf(stderr, "error state %d\n", (int)d->state);
00101 return(1);
00102 }
00103
00104
00105
00106 if (res != 0)
00107 memmove(bufp, bufp + (len - res), res);
00108 memset(d, 0, sizeof(*d));
00109 }
00110 if (!CCN_FINAL_DSTATE(d->state)) {
00111 fprintf(stderr, "%s state %d\n",
00112 (d->state < 0) ? "error" : "incomplete", d->state);
00113 return(1);
00114 }
00115 return(0);
00116 }
00117
00118
00119 static int
00120 process_file(char *path, struct ccn_charbuf *c)
00121 {
00122 int fd = -1;
00123 int res = 0;
00124 if (strcmp(path, "-") == 0) {
00125 fd = STDIN_FILENO;
00126 } else {
00127 fd = open(path, O_RDONLY);
00128 if (-1 == fd) {
00129 perror(path);
00130 return(1);
00131 }
00132
00133 }
00134 res = process_fd(fd, c);
00135 close(fd);
00136 return(res);
00137 }
00138
00139 static void
00140 usage(const char *progname)
00141 {
00142 fprintf(stderr,
00143 "%s [-h] [file1 ... fileN]\n"
00144 " Produces a list of names from the ccnb encoded"
00145 " objects in the given file(s), or from stdin if no files or \"-\"\n",
00146 progname);
00147 exit(1);
00148 }
00149
00150 int
00151 main(int argc, char *argv[])
00152 {
00153 int i;
00154 int res = 0;
00155 struct ccn_charbuf *c = ccn_charbuf_create();
00156 int opt;
00157
00158 while ((opt = getopt(argc, argv, "h")) != -1) {
00159 switch (opt) {
00160 case 'h':
00161 default:
00162 usage(argv[0]);
00163 }
00164 }
00165
00166 if (argv[optind] == NULL)
00167 return (process_fd(STDIN_FILENO, c));
00168
00169 for (i = optind; argv[i] != 0; i++) {
00170 res |= process_file(argv[i], c);
00171 }
00172 return(res);
00173 }
00174