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
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
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