SyncUtil.c

Go to the documentation of this file.
00001 /**
00002  * @file sync/SyncUtil.c
00003  *  
00004  * Part of CCNx Sync.
00005  *
00006  * Copyright (C) 2011 Palo Alto Research Center, Inc.
00007  *
00008  * This library is free software; you can redistribute it and/or modify it
00009  * under the terms of the GNU Lesser General Public License version 2.1
00010  * as published by the Free Software Foundation.
00011  * This library is distributed in the hope that it will be useful,
00012  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00013  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
00014  * Lesser General Public License for more details. You should have received
00015  * a copy of the GNU Lesser General Public License along with this library;
00016  * if not, write to the Free Software Foundation, Inc., 51 Franklin Street,
00017  * Fifth Floor, Boston, MA 02110-1301 USA.
00018  */
00019 
00020 #include "SyncBase.h"
00021 #include "SyncActions.h"
00022 #include "SyncHashCache.h"
00023 #include "SyncNode.h"
00024 #include "SyncRoot.h"
00025 #include "SyncUtil.h"
00026 #include "IndexSorter.h"
00027 #include <stdlib.h>
00028 #include <string.h>
00029 #include <strings.h>
00030 #include <sys/time.h>
00031 #include <ccnr/ccnr_msg.h>
00032 #include <ccnr/ccnr_sync.h>
00033 #include <ccn/ccn.h>
00034 #include <ccn/charbuf.h>
00035 #include <ccn/coding.h>
00036 #include <ccn/indexbuf.h>
00037 
00038 
00039 static int freshLimit = 30;             // freshness limit, in seconds
00040 
00041 // external utilities
00042 
00043 #define SET_ERR(d) SyncSetDecodeErr(d, -__LINE__)
00044 extern void
00045 SyncNoteErr(const char *msg) {
00046     char *s = getenv("CCNS_NOTE_ERR");
00047     int useStdErr = 0;
00048     if (s != NULL && s[0] != 0)
00049         useStdErr = strtol(s, NULL, 10);
00050     if (useStdErr > 0) {
00051         fprintf(stderr, "**** error in %s\n", msg);
00052         fflush(stderr);
00053     }
00054 }
00055 
00056 extern int
00057 SyncSetDecodeErr(struct ccn_buf_decoder *d, int val) {
00058     SyncNoteErr("setErr");
00059     if (d->decoder.state >= 0) d->decoder.state = val;
00060     return val;
00061 }
00062 
00063 extern int
00064 SyncCheckDecodeErr(struct ccn_buf_decoder *d) {
00065     return d->decoder.state < 0;
00066 }
00067 
00068 extern sync_time
00069 SyncCurrentTime(void) {
00070     const int64_t M = 1000*1000;
00071     struct timeval now = {0};
00072     gettimeofday(&now, 0);
00073     return now.tv_sec*M+now.tv_usec;
00074 }
00075 
00076 extern int64_t
00077 SyncDeltaTime(sync_time mt1, sync_time mt2) {
00078     return mt2-mt1;
00079 }
00080 
00081 extern struct ccn_buf_decoder *
00082 SyncInitDecoderFromCharbufRange(struct ccn_buf_decoder *d,
00083                                 const struct ccn_charbuf *cb,
00084                                 ssize_t start, ssize_t stop) {
00085     if (((size_t) stop) >  cb->length) stop = cb->length;
00086     if (start < 0 || start > stop) {
00087         SET_ERR(d); // invalid
00088     } else {
00089         ccn_buf_decoder_start(d, cb->buf+start, stop - start);
00090     }
00091     d->decoder.nest = 1;
00092     return d;
00093 }
00094 
00095 extern struct ccn_buf_decoder *
00096 SyncInitDecoderFromCharbuf(struct ccn_buf_decoder *d,
00097                            const struct ccn_charbuf *cb,
00098                            ssize_t start) {
00099     return SyncInitDecoderFromCharbufRange(d, cb, start, cb->length);
00100 }
00101 
00102 extern int
00103 SyncDecodeHexDigit(char c) {
00104     if (c >= '0' && c <= '9') return c - '0';
00105     if (c >= 'a' && c <= 'f') return 10 + c - 'a';
00106     if (c >= 'A' && c <= 'F') return 10 + c - 'A';
00107     return -1;
00108 }
00109 
00110 extern int
00111 SyncDecodeUriChar(char c) {
00112     if ((c >= 'A' && c <= 'Z') || (c >= 'a' && c <= 'z')
00113         || (c >= '0' && c <= '9')
00114         || c == '/' || c == '%' || c == ':'
00115         || c == '.' || c == '-' || c == '_' || c == '~') {
00116         // valid character
00117         return c;
00118     }
00119     return -1;
00120 }
00121 
00122 extern char *
00123 SyncHexStr(const unsigned char *cp, size_t sz) {
00124     char *hex = NEW_ANY(sz*2+1, char);
00125     char *hexLit = "0123456789abcdef";
00126     int i = 0;
00127     for (i = 0; i < sz; i++) {
00128         hex[i+i] = hexLit[(cp[i] / 16) & 15];
00129         hex[i+i+1] = hexLit[cp[i] & 15];
00130     }
00131     return hex;
00132 }
00133 
00134 /////////////////////////////////////////////////////////////////
00135 // Routines for root-relative reporting.
00136 /////////////////////////////////////////////////////////////////
00137 
00138 extern int
00139 SyncNoteFailed(struct SyncRootStruct *root, char *where, char *why, int line) {
00140     if (root->base->debug >= CCNL_SEVERE)
00141         ccnr_msg(root->base->ccnr, "%s, root#%u, failed, %s, line %d",
00142                  where, root->rootId, why, line);
00143     SyncNoteErr("Sync.SyncNoteFailed");
00144     return -line;
00145 }
00146 
00147 extern void
00148 SyncNoteSimple(struct SyncRootStruct *root, char *where, char *s1) {
00149     ccnr_msg(root->base->ccnr, "%s, root#%u, %s", where, root->rootId, s1);
00150 }
00151 
00152 extern void
00153 SyncNoteSimple2(struct SyncRootStruct *root, char *where, char *s1, char *s2) {
00154     ccnr_msg(root->base->ccnr, "%s, root#%u, %s, %s", where, root->rootId, s1, s2);
00155 }
00156 
00157 extern void
00158 SyncNoteSimple3(struct SyncRootStruct *root, char *where, char *s1, char *s2, char *s3) {
00159     ccnr_msg(root->base->ccnr, "%s, root#%u, %s, %s, %s", where, root->rootId, s1, s2, s3);
00160 }
00161 
00162 extern void
00163 SyncNoteUri(struct SyncRootStruct *root, char *where, char *why, struct ccn_charbuf *name) {
00164     struct ccn_charbuf *uri = SyncUriForName(name);
00165     char *str = ccn_charbuf_as_string(uri);
00166     ccnr_msg(root->base->ccnr, "%s, root#%u, %s, %s", where, root->rootId, why, str);
00167     ccn_charbuf_destroy(&uri);
00168 }
00169 
00170 extern void
00171 SyncNoteUriBase(struct SyncBaseStruct *base, char *where, char *why, struct ccn_charbuf *name) {
00172     struct ccn_charbuf *uri = SyncUriForName(name);
00173     char *str = ccn_charbuf_as_string(uri);
00174     ccnr_msg(base->ccnr, "%s, %s, %s", where, why, str);
00175     ccn_charbuf_destroy(&uri);
00176 }
00177 
00178 /////////////////////////////////////////////////////////////////
00179 // Routines for dealing with names.
00180 /////////////////////////////////////////////////////////////////
00181 
00182 extern int
00183 SyncCmpNamesInner(struct ccn_buf_decoder *xx, struct ccn_buf_decoder *yy) {
00184     // adapted from ccn_compare_names
00185     if (ccn_buf_match_dtag(xx, CCN_DTAG_Name))
00186         ccn_buf_advance(xx);
00187     else SET_ERR(xx);
00188     if (ccn_buf_match_dtag(yy, CCN_DTAG_Name))
00189         ccn_buf_advance(yy);
00190     else SET_ERR(yy);
00191     ssize_t cmp = 0;
00192     while (SyncCheckDecodeErr(xx) == 0 && SyncCheckDecodeErr(yy) == 0) {
00193         int more_x = ccn_buf_match_dtag(xx, CCN_DTAG_Component);
00194         int more_y = ccn_buf_match_dtag(yy, CCN_DTAG_Component);
00195         cmp = more_x - more_y;
00196         if (more_x == 0 || cmp != 0)
00197             break;
00198         ccn_buf_advance(xx);
00199         ccn_buf_advance(yy);
00200         size_t xs = 0;
00201         size_t ys = 0;
00202         const unsigned char *xp = NULL;
00203         const unsigned char *yp = NULL;
00204         if (ccn_buf_match_blob(xx, &xp, &xs)) ccn_buf_advance(xx);
00205         if (ccn_buf_match_blob(yy, &yp, &ys)) ccn_buf_advance(yy);
00206         cmp = xs - ys;
00207         if (cmp != 0)
00208             break;
00209         if (xs != 0) {
00210             cmp = memcmp(xp, yp, xs);
00211             if (cmp != 0)
00212                 break;
00213         }
00214         ccn_buf_check_close(xx);
00215         ccn_buf_check_close(yy);
00216     }
00217     ccn_buf_check_close(xx);
00218     ccn_buf_check_close(yy);
00219     if (cmp > 0) return 1;
00220     if (cmp < 0) return -1;
00221     return 0;
00222 }
00223 
00224 extern int
00225 SyncCmpNames(const struct ccn_charbuf *cbx, const struct ccn_charbuf *cby) {
00226     struct ccn_buf_decoder xds;
00227     struct ccn_buf_decoder *xx = SyncInitDecoderFromCharbuf(&xds, cbx, 0);
00228     struct ccn_buf_decoder yds;
00229     struct ccn_buf_decoder *yy = SyncInitDecoderFromCharbuf(&yds, cby, 0);
00230     int cmp = SyncCmpNamesInner(xx, yy);
00231     if (SyncCheckDecodeErr(xx) || SyncCheckDecodeErr(yy)) return SYNC_BAD_CMP;
00232     return (cmp);
00233 }
00234 
00235 // tests to see if the offset refers to a name
00236 // no errors
00237 extern int
00238 SyncIsName(const struct ccn_charbuf *cb) {
00239     struct ccn_buf_decoder xds;
00240     struct ccn_buf_decoder *d = SyncInitDecoderFromCharbuf(&xds, cb, 0);
00241     if (!SyncCheckDecodeErr(d) && ccn_buf_match_dtag(d, CCN_DTAG_Name))
00242         return 1;
00243     return 0;
00244 }
00245 
00246 int
00247 SyncComponentCount(const struct ccn_charbuf *name) {
00248     struct ccn_buf_decoder ds;
00249     struct ccn_buf_decoder *d = SyncInitDecoderFromCharbuf(&ds, name, 0);
00250     int count = 0;
00251     if (ccn_buf_match_dtag(d, CCN_DTAG_Name)) {
00252         ccn_buf_advance(d);
00253         while (ccn_buf_match_dtag(d, CCN_DTAG_Component)) {
00254             const unsigned char *cPtr = NULL;
00255             size_t cSize = 0;
00256             ccn_buf_advance(d);
00257             if (ccn_buf_match_blob(d, &cPtr, &cSize)) ccn_buf_advance(d);
00258             ccn_buf_check_close(d);
00259             count++;
00260         }
00261         ccn_buf_check_close(d);
00262         if (!SyncCheckDecodeErr(d))
00263             return count;
00264     }
00265     return -1;
00266 }
00267 
00268 extern int
00269 SyncPatternMatch(const struct ccn_charbuf *pattern,
00270                  const struct ccn_charbuf *name,
00271                  int start) {
00272     struct ccn_buf_decoder xds;
00273     struct ccn_buf_decoder *xx = SyncInitDecoderFromCharbuf(&xds, pattern, 0);
00274     struct ccn_buf_decoder yds;
00275     struct ccn_buf_decoder *yy = SyncInitDecoderFromCharbuf(&yds, name, 0);
00276     if (!ccn_buf_match_dtag(xx, CCN_DTAG_Name)) return -1;
00277     ccn_buf_advance(xx);
00278     if (!ccn_buf_match_dtag(yy, CCN_DTAG_Name)) return -1;
00279     ccn_buf_advance(yy);
00280     int match = 0;
00281     int index = 0;
00282     while (index < start) {
00283         // skip initial components of name
00284         if (!ccn_buf_match_dtag(yy, CCN_DTAG_Component))
00285             return -1;
00286         ccn_buf_advance(yy);
00287         if (!ccn_buf_match_blob(yy, NULL, NULL))
00288             return -1;
00289         ccn_buf_advance(yy);
00290         ccn_buf_check_close(yy);
00291         index++;
00292     }
00293     while (SyncCheckDecodeErr(xx) == 0 && SyncCheckDecodeErr(yy) == 0) {
00294         int more_x = ccn_buf_match_dtag(xx, CCN_DTAG_Component);
00295         int more_y = ccn_buf_match_dtag(yy, CCN_DTAG_Component);
00296         if (more_x == 0) {
00297             // end of pattern
00298             ccn_buf_check_close(xx);
00299             if (!SyncCheckDecodeErr(xx))
00300                 return match;
00301             return -1;
00302         }
00303         if (more_y == 0) {
00304             // end of name
00305             ccn_buf_check_close(yy);
00306             if (!SyncCheckDecodeErr(yy))
00307                 return 0;
00308             return -1;
00309         }
00310         ccn_buf_advance(xx);
00311         ccn_buf_advance(yy);
00312         size_t xs = 0;
00313         size_t ys = 0;
00314         const unsigned char *xp = NULL;
00315         const unsigned char *yp = NULL;
00316         if (ccn_buf_match_blob(xx, &xp, &xs)) ccn_buf_advance(xx);
00317         if (ccn_buf_match_blob(yy, &yp, &ys)) ccn_buf_advance(yy);
00318         int star = 0;
00319         if (xs > 0 && (xp[0] == 255)) {
00320             // a component starting with FF may be a star-matcher
00321             // if not a single byte, swallow the FF
00322             xs--;
00323             xp++;
00324             if (xs == 0) star = 1;
00325         }
00326         if (star) {
00327             // star-matching
00328         } else if (xs != ys) {
00329             // name lengths differ
00330             return 0;
00331         } else {
00332             // equal sizes, check contents
00333             ssize_t cmp = memcmp(xp, yp, xs);
00334             if (cmp != 0) return 0;
00335         }
00336         match++;
00337         ccn_buf_check_close(xx);
00338         ccn_buf_check_close(yy);
00339     }
00340     return (-1);
00341 }
00342 
00343 int
00344 SyncPrefixMatch(const struct ccn_charbuf *prefix,
00345                 const struct ccn_charbuf *name,
00346                 int start) {
00347     struct ccn_buf_decoder xds;
00348     struct ccn_buf_decoder *xx = SyncInitDecoderFromCharbuf(&xds, prefix, 0);
00349     struct ccn_buf_decoder yds;
00350     struct ccn_buf_decoder *yy = SyncInitDecoderFromCharbuf(&yds, name, 0);
00351     if (!ccn_buf_match_dtag(xx, CCN_DTAG_Name)) return -1;
00352     ccn_buf_advance(xx);
00353     if (!ccn_buf_match_dtag(yy, CCN_DTAG_Name)) return -1;
00354     ccn_buf_advance(yy);
00355     int match = 0;
00356     int index = 0;
00357     while (index < start) {
00358         // skip initial components of name
00359         if (!ccn_buf_match_dtag(yy, CCN_DTAG_Component)) break;
00360         ccn_buf_advance(yy);
00361         if (ccn_buf_match_blob(yy, NULL, NULL)) ccn_buf_advance(yy);
00362         index++;
00363     }
00364     while (SyncCheckDecodeErr(xx) == 0 && SyncCheckDecodeErr(yy) == 0) {
00365         int more_x = ccn_buf_match_dtag(xx, CCN_DTAG_Component);
00366         int more_y = ccn_buf_match_dtag(yy, CCN_DTAG_Component);
00367         if (more_x == 0) {
00368             // end of prefix
00369             ccn_buf_check_close(xx);
00370             if (!SyncCheckDecodeErr(xx))
00371                 return match;
00372             return -1;
00373         }
00374         if (more_y == 0) {
00375             // end of name
00376             ccn_buf_check_close(yy);
00377             if (!SyncCheckDecodeErr(yy))
00378                 return 0;
00379             return -1;
00380         }
00381         ccn_buf_advance(xx);
00382         ccn_buf_advance(yy);
00383         size_t xs = 0;
00384         size_t ys = 0;
00385         const unsigned char *xp = NULL;
00386         const unsigned char *yp = NULL;
00387         if (ccn_buf_match_blob(xx, &xp, &xs)) ccn_buf_advance(xx);
00388         if (ccn_buf_match_blob(yy, &yp, &ys)) ccn_buf_advance(yy);
00389         if (xs != ys) {
00390             // name lengths differ
00391             return 0;
00392         } else if (xs > 0) {
00393             // equal sizes, check contents
00394             ssize_t cmp = memcmp(xp, yp, xs);
00395             if (cmp != 0) return 0;
00396         }
00397         match++;
00398         ccn_buf_check_close(xx);
00399         ccn_buf_check_close(yy);
00400     }
00401     return -1;
00402 }
00403 
00404 extern int
00405 SyncComponentMatch(const struct ccn_charbuf *x,
00406                    const struct ccn_charbuf *y) {
00407     struct ccn_buf_decoder xds;
00408     struct ccn_buf_decoder *xx = SyncInitDecoderFromCharbuf(&xds, x, 0);
00409     struct ccn_buf_decoder yds;
00410     struct ccn_buf_decoder *yy = SyncInitDecoderFromCharbuf(&yds, y, 0);
00411     if (!ccn_buf_match_dtag(xx, CCN_DTAG_Name)) return -1;
00412     ccn_buf_advance(xx);
00413     if (!ccn_buf_match_dtag(yy, CCN_DTAG_Name)) return -1;
00414     ccn_buf_advance(yy);
00415     int match = 0;
00416     size_t xs = 0;
00417     size_t ys = 0;
00418     const unsigned char *xp = NULL;
00419     const unsigned char *yp = NULL;
00420     for (;;) {
00421         if (!ccn_buf_match_dtag(xx, CCN_DTAG_Component)) break;
00422         if (!ccn_buf_match_dtag(yy, CCN_DTAG_Component)) break;
00423         ccn_buf_advance(xx);
00424         ccn_buf_advance(yy);
00425         if (!ccn_buf_match_blob(xx, &xp, &xs)) return -1;
00426         if (!ccn_buf_match_blob(yy, &yp, &ys)) return -1;
00427         if (xs != ys) break;
00428         ssize_t cmp = memcmp(xp, yp, xs);
00429         if (cmp != 0) break;
00430         ccn_buf_advance(xx);
00431         ccn_buf_advance(yy);
00432         ccn_buf_check_close(xx);
00433         ccn_buf_check_close(yy);
00434         match++;
00435     }
00436     if (SyncCheckDecodeErr(xx)) match = -1;
00437     if (SyncCheckDecodeErr(yy)) match = -1;
00438     return match;
00439 }
00440 
00441 extern int
00442 SyncGetComponentPtr(const struct ccn_charbuf *src, int comp,
00443                     const unsigned char **xp, ssize_t *xs) {
00444     struct ccn_buf_decoder sbd;
00445     struct ccn_buf_decoder *s = SyncInitDecoderFromCharbuf(&sbd, src, 0);
00446     if (ccn_buf_match_dtag(s, CCN_DTAG_Name) && (xp != NULL) && (xs != NULL)) {
00447         int pos = 0;
00448         ccn_buf_advance(s);
00449         while (pos <= comp) {
00450             if (!ccn_buf_match_dtag(s, CCN_DTAG_Component)) break;
00451             ccn_buf_advance(s);
00452             if (!ccn_buf_match_blob(s, xp, (size_t *) xs)) break;
00453             ccn_buf_advance(s);
00454             ccn_buf_check_close(s);
00455             if (SyncCheckDecodeErr(s)) break;
00456             if (pos == comp)
00457                 // found the component
00458                 return 0;
00459             pos++;
00460         }
00461     }
00462     return -1;
00463 }
00464 
00465 extern int
00466 SyncAppendAllComponents(struct ccn_charbuf *dst,
00467                         const struct ccn_charbuf *src) {
00468     struct ccn_buf_decoder sbd;
00469     struct ccn_buf_decoder *s = SyncInitDecoderFromCharbuf(&sbd, src, 0);
00470     int count = 0;
00471     int pos = 0;
00472     if (!ccn_buf_match_dtag(s, CCN_DTAG_Name))
00473         // src is not a name
00474         return -__LINE__;
00475     ccn_buf_advance(s);
00476     for (;;) {
00477         if (!ccn_buf_match_dtag(s, CCN_DTAG_Component)) break;
00478         ccn_buf_advance(s);
00479         const unsigned char *cPtr = NULL;
00480         size_t cSize = 0;
00481         if (ccn_buf_match_blob(s, &cPtr, &cSize)) ccn_buf_advance(s);
00482         if (ccn_name_append(dst, cPtr, cSize) < 0)
00483             return -__LINE__;
00484         count++;
00485         ccn_buf_check_close(s);
00486         if (SyncCheckDecodeErr(s)) return -__LINE__;
00487         pos++;
00488     }
00489     ccn_buf_check_close(s);
00490     if (SyncCheckDecodeErr(s)) return -__LINE__;
00491     return count;
00492 }
00493 
00494 extern struct ccn_charbuf *
00495 SyncNameForIndexbuf(const unsigned char *buf, struct ccn_indexbuf *comps) {
00496     struct ccn_charbuf *name = ccn_charbuf_create();
00497     ccn_name_init(name);
00498     int i = 0;
00499     int nComp = comps->n-1;
00500     int res = 0;
00501     for (i = 0; i < nComp; i++) {
00502         const unsigned char *cp = NULL;
00503         size_t sz = 0;
00504         res |= ccn_name_comp_get(buf, comps, i, &cp, &sz);
00505         if (res < 0) break;
00506         res |= ccn_name_append(name, cp, sz);
00507         if (res < 0) break;
00508     }
00509     if (res < 0) {
00510         SyncNoteErr("SyncNameForIndexbuf failed");
00511         ccn_charbuf_destroy(&name);
00512         return NULL;
00513     }
00514     return name;
00515 }
00516 
00517 struct ccn_charbuf *
00518 SyncUriForName(struct ccn_charbuf *name) {
00519     struct ccn_charbuf *ret = ccn_charbuf_create();
00520     ccn_uri_append(ret, name->buf, name->length, 0);
00521     return ret;
00522 }
00523 
00524 /////////////////////////////////////////////////////////////////
00525 // Routines for dealing with hashes.
00526 /////////////////////////////////////////////////////////////////
00527 
00528 extern void
00529 SyncGetHashPtr(const struct ccn_buf_decoder *hd,
00530                const unsigned char ** xp, ssize_t *xs) {
00531     struct ccn_buf_decoder xds = *hd;
00532     struct ccn_buf_decoder *xd = &xds;
00533     size_t us = 0;
00534     if (ccn_buf_match_dtag(xd, CCN_DTAG_SyncContentHash)) {
00535         ccn_buf_advance(xd);
00536         if (ccn_buf_match_blob(xd, xp, &us)) ccn_buf_advance(xd);
00537         ccn_buf_check_close(xd);
00538     } else if (ccn_buf_match_dtag(xd, CCN_DTAG_Component)) {
00539         ccn_buf_advance(xd);
00540         if (ccn_buf_match_blob(xd, xp, &us)) ccn_buf_advance(xd);
00541         ccn_buf_check_close(xd);
00542     } else if (ccn_buf_match_dtag(xd, CCN_DTAG_Name)) {
00543         ccn_buf_advance(xd);
00544         for (;;) {
00545             if (!ccn_buf_match_dtag(xd, CCN_DTAG_Component)) break;
00546             ccn_buf_advance(xd);
00547             if (ccn_buf_match_blob(xd, xp, &us)) ccn_buf_advance(xd);
00548             ccn_buf_check_close(xd);
00549         }
00550         ccn_buf_check_close(xd);
00551     }
00552     xs[0] = (ssize_t) us;
00553     if (SyncCheckDecodeErr(xd)) {
00554         // close bug
00555         xp[0] = NULL;
00556         xs[0] = 0;
00557         SyncSetDecodeErr(xd, -__LINE__);
00558     }
00559 }
00560 
00561 extern ssize_t
00562 SyncCmpHashesRaw(const unsigned char * xp, ssize_t xs,
00563                  const unsigned char * yp, ssize_t ys) {
00564     ssize_t cmp = xs - ys;
00565     if (cmp == 0) {
00566         cmp = memcmp(xp, yp, xs);
00567     }
00568     return cmp;
00569 }
00570 
00571 // accumulates a simple hash code into the hash accumulator
00572 // hash code is raw bytes
00573 extern void
00574 SyncAccumHashRaw(struct SyncLongHashStruct *hp,
00575                  const unsigned char * xp, size_t xs) {
00576     unsigned char *ap = hp->bytes;
00577     int as = MAX_HASH_BYTES;
00578     int aLim = hp->pos;
00579     int c = 0;
00580     if (xs < 2)
00581         SyncNoteErr("SyncAccumHashRaw, xs < 2");
00582     // first, accum from x until no more bytes
00583     while (xs > 0 && as > 0) {
00584         int val = c;
00585         xs--;
00586         as--;
00587         val = val + ap[as] + xp[xs];
00588         c = (val >> 8) & 255;
00589         ap[as] = val & 255;
00590     }
00591     // second, propagate the carry (if any)
00592     while (c > 0 && as > 0) {
00593         as--;
00594         c = c + ap[as];
00595         ap[as] = c & 255;
00596         c = (c >> 8) & 255;
00597     }
00598     // last, update the position (if less than the original)
00599     if (as < aLim) hp->pos = as;
00600 }
00601 
00602 // accumulates a simple hash code referenced by a decoder
00603 // into the hash accumulator for the composite node
00604 // non-destructive of decoder
00605 extern void
00606 SyncAccumHashInner(struct SyncLongHashStruct *hp,
00607                    const struct ccn_buf_decoder *d) {
00608     const unsigned char * xp = NULL;
00609     ssize_t xs = -1;
00610     SyncGetHashPtr(d, &xp, &xs);
00611     if (xs >= 0 && xp != NULL)
00612         SyncAccumHashRaw(hp, xp, xs);
00613 }
00614 
00615 // accumulates a simple hash code referenced by a decoder
00616 // into the hash accumulator for the composite node
00617 // non-destructive of decoder
00618 extern void
00619 SyncAccumHash(struct SyncLongHashStruct *hp, const struct ccn_charbuf *cb) {
00620     struct ccn_buf_decoder ds;
00621     struct ccn_buf_decoder *d = SyncInitDecoderFromCharbuf(&ds, cb, 0);
00622     SyncAccumHashInner(hp, d);
00623 }
00624 
00625 extern struct ccn_charbuf *
00626 SyncLongHashToBuf(const struct SyncLongHashStruct *hp) {
00627     struct ccn_charbuf *ret = ccn_charbuf_create();
00628     int pos = hp->pos;
00629     ccn_charbuf_append(ret, hp->bytes+pos, MAX_HASH_BYTES-pos);
00630     return ret;
00631 }
00632 
00633 // makes a small, unsigned hash code from a full hash
00634 // useful to speed up hash table lookups
00635 extern uint32_t
00636 SyncSmallHash(const unsigned char * xp, ssize_t xs) {
00637     uint32_t ret = 0;
00638     if (xs > 0 && xp != NULL) {
00639         int i = 0;
00640         while (i < xs && i < ((int) sizeof(ret))) {
00641             ret = (ret << 8) + (xp[i] & 255);
00642             i++;
00643         }
00644     }
00645     return ret;
00646 }
00647 
00648 
00649 
00650 /////////////////////////////////////////////////////////////////
00651 // Routines for appending numbers, hashes and names to a charbuf.
00652 /////////////////////////////////////////////////////////////////
00653 
00654 extern int
00655 SyncAppendTaggedNumber(struct ccn_charbuf *cb,
00656                        enum ccn_dtag dtag,
00657                        unsigned val) {
00658     int res = ccnb_tagged_putf(cb, dtag, "%u", val);
00659     return res;
00660 }
00661 
00662 // appends a sequence of random bytes
00663 extern int
00664 SyncAppendRandomBytes(struct ccn_charbuf *cb, int n) {
00665     size_t len = cb->length;
00666     ccn_charbuf_reserve(cb, n);
00667     unsigned char *dst = cb->buf + len;
00668     int i = 0;
00669     while (i < n) {
00670         unsigned int r = random();
00671         dst[i] = (unsigned char) (r & 255);
00672         i++;
00673     }
00674     cb->length = len + n;
00675     return 0;
00676 }
00677 
00678 // appends a random hash code as a ContentHash
00679 extern int
00680 SyncAppendRandomHash(struct ccn_charbuf *cb, int n) {
00681     int res = ccn_charbuf_append_tt(cb, CCN_DTAG_SyncContentHash, CCN_DTAG);
00682     res |= ccn_charbuf_append_tt(cb, n, CCN_BLOB);
00683     res |= SyncAppendRandomBytes(cb, n);
00684     res |= ccn_charbuf_append_closer(cb);
00685     return res;
00686 }
00687 
00688 // appends a random name of nComp random-length components plus a random hash
00689 extern int
00690 SyncAppendRandomName(struct ccn_charbuf *cb, int nComp, int maxCompLen) {
00691     struct ccn_charbuf *rb = ccn_charbuf_create();
00692     int res = ccn_charbuf_append_tt(cb, CCN_DTAG_Name, CCN_DTAG);
00693     res |= ccn_charbuf_append_closer(cb);
00694     while (nComp > 0 && res == 0) {
00695         unsigned nb = random();
00696         nb = (nb % (maxCompLen+1));
00697         ccn_charbuf_reset(rb);
00698         SyncAppendRandomBytes(rb, nb);
00699         res |= ccn_name_append(cb, rb->buf, nb);
00700         nComp--;
00701     }
00702     // always have a hash code as the last component
00703     ccn_charbuf_reset(rb);
00704     res |= SyncAppendRandomBytes(rb, DEFAULT_HASH_BYTES);
00705     res |= ccn_name_append(cb, rb->buf, rb->length);
00706     
00707     ccn_charbuf_destroy(&rb);
00708     
00709     return res;
00710 }
00711 
00712 // appendElementInner appends the ccnb encoding from the decoder to the cb output
00713 // types supported: CCN_DTAG_Name, CCN_DTAG_SyncContentHash, CCN_DTAG_BinaryValue
00714 // any error returns < 0
00715 // this routine advances the decoder!
00716 extern int
00717 SyncAppendElementInner(struct ccn_charbuf *cb, struct ccn_buf_decoder *d) {
00718     int res = 0;
00719     int src = 0;
00720     if (ccn_buf_match_dtag(d, CCN_DTAG_Name)) {
00721         ccn_buf_advance(d);
00722         int res = ccn_charbuf_append_tt(cb, CCN_DTAG_Name, CCN_DTAG);
00723         res |= ccn_charbuf_append_closer(cb);
00724         while (ccn_buf_match_dtag(d, CCN_DTAG_Component)) {
00725             const unsigned char *cPtr = NULL;
00726             size_t cSize = 0;
00727             ccn_buf_advance(d);
00728             if (ccn_buf_match_blob(d, &cPtr, &cSize)) ccn_buf_advance(d);
00729             res |= ccn_name_append(cb, cPtr, cSize);
00730             ccn_buf_check_close(d);
00731         }
00732         ccn_buf_check_close(d);
00733     } else if (ccn_buf_match_dtag(d, CCN_DTAG_SyncContentHash)) {
00734         const unsigned char *cPtr = NULL;
00735         size_t cSize = 0;
00736         ccn_buf_advance(d);
00737         if (ccn_buf_match_blob(d, &cPtr, &cSize)) ccn_buf_advance(d);
00738         res |= ccnb_append_tagged_blob(cb, CCN_DTAG_SyncContentHash, cPtr, cSize);
00739     } else if (ccn_buf_match_dtag(d, CCN_DTAG_BinaryValue)) {
00740         const unsigned char *cPtr = NULL;
00741         size_t cSize = 0;
00742         ccn_buf_advance(d);
00743         if (ccn_buf_match_blob(d, &cPtr, &cSize)) ccn_buf_advance(d);
00744         res |= ccnb_append_tagged_blob(cb, CCN_DTAG_BinaryValue, cPtr, cSize);
00745     } else res = -__LINE__;
00746     if (SyncCheckDecodeErr(d)) src = -__LINE__;
00747     if (res == 0) res = src;
00748     return res;
00749 }
00750 
00751 // appendElement appends the ccnb encoding from the src to the dst
00752 // types supported: CCN_DTAG_Name, CCN_DTAG_SyncContentHash, CCN_DTAG_BinaryValue
00753 // any error returns < 0
00754 extern int
00755 SyncAppendElement(struct ccn_charbuf *dst, const struct ccn_charbuf *src) {
00756     struct ccn_buf_decoder ds;
00757     struct ccn_buf_decoder *d = SyncInitDecoderFromCharbuf(&ds, src, 0);
00758     int res = SyncAppendElementInner(dst, d);
00759     return res;
00760 }
00761 
00762 extern struct ccn_charbuf *
00763 SyncExtractName(struct ccn_buf_decoder *d) {
00764     struct ccn_charbuf *name = NULL;
00765     if (ccn_buf_match_dtag(d, CCN_DTAG_Name)) {
00766         name = ccn_charbuf_create();
00767         int res = SyncAppendElementInner(name, d);
00768         if (res < 0) {
00769             // parse error, so get rid of the buffer
00770             ccn_charbuf_destroy(&name);
00771             SyncSetDecodeErr(d, -__LINE__);
00772         }
00773     } else
00774         SyncSetDecodeErr(d, -__LINE__);
00775     return name;
00776 }
00777 
00778 extern struct ccn_charbuf *
00779 SyncCopyName(const struct ccn_charbuf *name) {
00780     struct ccn_charbuf *ret = ccn_charbuf_create();
00781     ccn_charbuf_append_charbuf(ret, name);
00782     return ret;
00783 }
00784 
00785 ///////////////////////////////////////////////////////
00786 // Routines for simple parsing
00787 ///////////////////////////////////////////////////////
00788 
00789 extern unsigned
00790 SyncParseUnsigned(struct ccn_buf_decoder *d, enum ccn_dtag dtag) {
00791     uintmax_t val = 0;
00792     if (ccn_buf_match_dtag(d, dtag)) {
00793         ccn_buf_advance(d);
00794         if (ccn_parse_uintmax(d, &val) >= 0) {
00795             ccn_buf_check_close(d);
00796             if (SyncCheckDecodeErr(d) == 0)
00797                 return val;
00798         }
00799     }
00800     SET_ERR(d);
00801     return val;
00802 }
00803 
00804 extern ssize_t
00805 SyncParseHash(struct ccn_buf_decoder *d) {
00806     ssize_t off = d->decoder.token_index;
00807     ccn_parse_required_tagged_BLOB(d, CCN_DTAG_SyncContentHash, 0, MAX_HASH_BYTES);
00808     return off;
00809 }
00810 
00811 extern ssize_t
00812 SyncParseName(struct ccn_buf_decoder *d) {
00813     ssize_t off = d->decoder.token_index;
00814     if (ccn_buf_match_dtag(d, CCN_DTAG_Name)) {
00815         ccn_buf_advance(d);
00816         while (ccn_buf_match_dtag(d, CCN_DTAG_Component)) {
00817             ccn_buf_advance(d);
00818             if (ccn_buf_match_blob(d, NULL, NULL)) ccn_buf_advance(d);
00819             ccn_buf_check_close(d);
00820         }
00821         ccn_buf_check_close(d);
00822     } else SET_ERR(d);
00823     return off;
00824 }
00825 
00826 ////////////////////////////////////////
00827 // Name and Node Accumulators
00828 ////////////////////////////////////////
00829 
00830 extern struct SyncNameAccum *
00831 SyncAllocNameAccum(int lim) {
00832     struct SyncNameAccum *na = NEW_STRUCT(1, SyncNameAccum);
00833     if (lim < 4) lim = 4;
00834     na->lim = lim;
00835     na->ents = NEW_STRUCT(lim, SyncNameAccumEntry);
00836     return na;
00837 }
00838 
00839 extern struct SyncNameAccum *
00840 SyncFreeNameAccum(struct SyncNameAccum *na) {
00841     if (na != NULL) {
00842         if (na->ents != NULL) free(na->ents);
00843         free(na);
00844     }
00845     return NULL;
00846 }
00847 
00848 extern struct SyncNameAccum *
00849 SyncFreeNameAccumAndNames(struct SyncNameAccum *na) {
00850     if (na != NULL) {
00851         if (na->ents != NULL) {
00852             int i = 0;
00853             for (i = 0; i < na->len; i++) {
00854                 struct ccn_charbuf *name = na->ents[i].name;
00855                 if (name != NULL) {
00856                     ccn_charbuf_destroy(&name);
00857                     na->ents[i].name = NULL;
00858                 }
00859             }
00860             free(na->ents);
00861             na->ents = NULL;
00862         }
00863         free(na);
00864     }
00865     return NULL;
00866 }
00867 
00868 extern int
00869 SyncNameAccumSorter(IndexSorter_Base base,
00870                     IndexSorter_Index x, IndexSorter_Index y) {
00871     struct SyncNameAccum *na = (struct SyncNameAccum *) base->client;
00872     IndexSorter_Index len = na->len;
00873     if (x < len && y < len) {
00874         struct ccn_charbuf *cbx = na->ents[x].name;
00875         struct ccn_charbuf *cby = na->ents[y].name;
00876         int cmp = SyncCmpNames(cbx, cby);
00877         if (cmp != SYNC_BAD_CMP) return cmp;
00878     }
00879     SyncNoteErr("nameAccumSorter");
00880     return 0;
00881 }
00882 
00883 extern int
00884 SyncNameAccumAppend(struct SyncNameAccum *na,
00885                     struct ccn_charbuf *name,
00886                     intmax_t data) {
00887     if (name == NULL || name->length == 0)
00888         SyncNoteErr("SyncNameAccumAppend");
00889 
00890     struct SyncNameAccumEntry *ents = na->ents;
00891     int len = na->len;
00892     if (len == na->lim) {
00893         // expand the storage
00894         int newLim = na->lim + na->lim/2 + 4;
00895         struct SyncNameAccumEntry *newEnts = NEW_STRUCT(newLim, SyncNameAccumEntry);
00896         memcpy(newEnts, ents, len*sizeof(struct SyncNameAccumEntry));
00897         free(ents);
00898         na->lim = newLim;
00899         ents = newEnts;
00900         na->ents = newEnts;
00901     }
00902     ents[len].name = name;
00903     ents[len].data = data;
00904     na->len = len + 1;
00905     return 1;
00906 }
00907 
00908 extern struct ccn_charbuf *
00909 SyncNameAccumCanon(struct SyncNameAccum *na,
00910                    const struct ccn_charbuf *name) {
00911     struct ccn_charbuf *found = NULL;
00912     int i = 0;
00913     // scan for an existing name
00914     for (i = 0; i < na->len; i++) {
00915         int cmp = SyncCmpNames(name, na->ents[i].name);
00916         if (cmp == 0) {
00917             // existing name found, bump the count
00918             found = na->ents[i].name;
00919             na->ents[i].data++;
00920             break;
00921         }
00922     }
00923     if (found == NULL) {
00924         // make a new one and append it
00925         found = ccn_charbuf_create();
00926         ccn_charbuf_append_charbuf(found, name);
00927         SyncNameAccumAppend(na, found, 1);
00928     }
00929     return found;
00930 }
00931 
00932 extern struct SyncNodeAccum *
00933 SyncAllocNodeAccum(int lim) {
00934     struct SyncNodeAccum *na = NEW_STRUCT(1, SyncNodeAccum);
00935     if (lim < 4) lim = 4;
00936     na->lim = lim;
00937     na->ents = NEW_ANY(lim, struct SyncNodeComposite *);
00938     return na;
00939 }
00940 
00941 extern struct SyncNodeAccum *
00942 SyncFreeNodeAccum(struct SyncNodeAccum *na) {
00943     if (na != NULL) {
00944         if (na->ents != NULL) free(na->ents);
00945         free(na);
00946     }
00947     return NULL;
00948 }
00949 
00950 extern void
00951 SyncAccumNode(struct SyncNodeAccum *na, struct SyncNodeComposite *nc) {
00952     struct SyncNodeComposite **ents = na->ents;
00953     int len = na->len;
00954     if (len == na->lim) {
00955         // expand the storage
00956         int newLim = na->lim + na->lim/2 + 4;
00957         struct SyncNodeComposite **newEnts = NEW_ANY(newLim,
00958                                                      struct SyncNodeComposite *);
00959         memcpy(newEnts, ents, len*sizeof(struct SyncNodeComposite *));
00960         free(ents);
00961         na->lim = newLim;
00962         ents = newEnts;
00963         na->ents = newEnts;
00964     }
00965     ents[len] = nc;
00966     na->len = len + 1;
00967 }
00968 
00969 ///////////////////////////////////////////////////////
00970 // Routines for simple interest creation
00971 ///////////////////////////////////////////////////////
00972 
00973 static int
00974 appendLifetime(struct ccn_charbuf *cb, int lifetime) {
00975     unsigned char buf[sizeof(int32_t)];
00976     int32_t dreck = lifetime << 12;
00977     int pos = sizeof(int32_t);
00978     int res = 0;
00979     while (dreck > 0 && pos > 0) {
00980         pos--;
00981         buf[pos] = dreck & 255;
00982         dreck = dreck >> 8;
00983     }
00984     res |= ccnb_append_tagged_blob(cb, CCN_DTAG_InterestLifetime,
00985                                    buf+pos, sizeof(buf)-pos);
00986     return res;
00987 }
00988 
00989 static int
00990 appendExclusions(struct ccn_charbuf *cb, struct SyncNameAccum *excl) {
00991     if (excl != NULL) {
00992         int i = 0;
00993         ccn_charbuf_append_tt(cb, CCN_DTAG_Exclude, CCN_DTAG);
00994         for (i = 0; i < excl->len; i++) {
00995             struct ccn_charbuf *name = excl->ents[i].name;
00996             // append just the first component
00997             struct ccn_buf_decoder ds;
00998             struct ccn_buf_decoder *d = SyncInitDecoderFromCharbuf(&ds, name, 0);
00999             size_t cSize = 0;
01000             if (ccn_buf_match_dtag(d, CCN_DTAG_Name)) {
01001                 ccn_buf_advance(d);
01002                 if (ccn_buf_match_dtag(d, CCN_DTAG_Component)) {
01003                     ccn_buf_advance(d);
01004                     const unsigned char *cPtr = NULL;
01005                     if (ccn_buf_match_blob(d, &cPtr, &cSize)) {
01006                         ccn_buf_advance(d);
01007                         ccnb_append_tagged_blob(cb, CCN_DTAG_Component, cPtr, cSize);
01008                     }
01009                 }
01010             }
01011             if (cSize == 0) return -__LINE__;
01012         }
01013         ccn_charbuf_append_closer(cb); /* </Exclude> */
01014         return 1;
01015     }
01016     return 0;
01017 }
01018 
01019 extern struct ccn_charbuf *
01020 SyncGenInterest(struct ccn_charbuf *name,
01021                 int scope, int lifetime, int maxSuffix, int childPref,
01022                 struct SyncNameAccum *excl) {
01023     struct ccn_charbuf *cb = ccn_charbuf_create();
01024     ccn_charbuf_append_tt(cb, CCN_DTAG_Interest, CCN_DTAG);
01025     int res = 0;
01026     if (name == NULL) {
01027         res |= ccn_charbuf_append_tt(cb, CCN_DTAG_Name, CCN_DTAG);
01028         res |= ccn_charbuf_append_closer(cb); /* </Name> */
01029     } else {
01030         ccn_charbuf_append_charbuf(cb, name);
01031     }
01032     if (maxSuffix >= 0)
01033         ccnb_tagged_putf(cb, CCN_DTAG_MaxSuffixComponents, "%d", maxSuffix);
01034     res |= appendExclusions(cb, excl);
01035     if (childPref >= 0)
01036         // low bit determines least/most preference
01037         ccnb_tagged_putf(cb, CCN_DTAG_ChildSelector, "%d", childPref);
01038     if (scope >= 0)
01039         ccnb_tagged_putf(cb, CCN_DTAG_Scope, "%d", scope);
01040     if (lifetime > 0)
01041         appendLifetime(cb, lifetime);
01042     ccn_charbuf_append_closer(cb); /* </Interest> */
01043     if (res < 0) {
01044         ccn_charbuf_destroy(&cb);
01045     }
01046     return cb;
01047 }
01048 
01049 ///////////////////////////////////////////////////////
01050 // Routines for local repo read/write
01051 ///////////////////////////////////////////////////////
01052 
01053 extern struct ccn_charbuf *
01054 SyncNameForLocalNode(struct SyncRootStruct *root, struct ccn_charbuf *hash) {
01055     // form the name of the node
01056     // use the NodeFetch convention, but at the local host
01057     struct ccn_charbuf *sh = root->sliceHash;
01058     struct ccn_charbuf *nm = ccn_charbuf_create();
01059     int res = 0;
01060     res |= ccn_name_init(nm);
01061     res |= ccn_name_append_str(nm, "\xC1.M.S.localhost");
01062     res |= ccn_name_append_str(nm, "\xC1.S.nf");
01063     res |= ccn_name_append(nm, sh->buf, sh->length);
01064     res |= ccn_name_append(nm, hash->buf, hash->length);
01065     if (res < 0) ccn_charbuf_destroy(&nm);
01066     return nm;
01067 }
01068 
01069 extern int
01070 SyncPointerToContent(struct ccn_charbuf *cb, struct ccn_parsed_ContentObject *pco,
01071                      const unsigned char **xp, size_t *xs) {
01072     struct ccn_parsed_ContentObject pcos;
01073     int res = 0;
01074     if (pco == NULL) {
01075         // not already parsed, so do it now
01076         pco = &pcos;
01077         res = ccn_parse_ContentObject(cb->buf, cb->length,
01078                                       pco, NULL);
01079     }
01080     if (res >= 0)
01081         // worth trying to extract the content
01082         res = ccn_content_get_value(cb->buf, cb->length, pco, xp, xs);
01083     return res;
01084 }
01085 
01086 extern struct ccn_charbuf *
01087 SyncSignBuf(struct SyncBaseStruct *base,
01088             struct ccn_charbuf *cb,
01089             struct ccn_charbuf *name,
01090             long fresh, int flags) {
01091     struct ccn_charbuf *cob = ccn_charbuf_create();
01092     struct ccn_signing_params sp = CCN_SIGNING_PARAMS_INIT;
01093     
01094     if (cb != NULL) {
01095         // signing content, will put as data
01096         sp.type = CCN_CONTENT_DATA;
01097     } else {
01098         // cb == NULL requests deletion
01099         cb = ccn_charbuf_create();
01100         sp.type = CCN_CONTENT_GONE;
01101     }
01102     sp.sp_flags |= flags;
01103     
01104     if (fresh > 0 && fresh <= freshLimit) {
01105         sp.template_ccnb = ccn_charbuf_create();
01106         ccn_charbuf_append_tt(sp.template_ccnb, CCN_DTAG_SignedInfo, CCN_DTAG);
01107         ccnb_tagged_putf(sp.template_ccnb, CCN_DTAG_FreshnessSeconds, "%ld", fresh);
01108         sp.sp_flags |= CCN_SP_TEMPL_FRESHNESS;
01109         ccn_charbuf_append_closer(sp.template_ccnb);
01110     }
01111     
01112     int res = ccn_sign_content(base->ccn,
01113                                cob,
01114                                name,
01115                                &sp,
01116                                cb->buf,
01117                                cb->length);
01118     
01119     if (sp.template_ccnb != NULL) 
01120         ccn_charbuf_destroy(&sp.template_ccnb);
01121     if (sp.type == CCN_CONTENT_GONE)
01122         ccn_charbuf_destroy(&cb);
01123     if (res < 0) {
01124         // it did not work, so return the output buffer
01125         ccn_charbuf_destroy(&cob);
01126         return NULL;
01127     }
01128     return cob;
01129 }
01130 
01131 extern int
01132 SyncLocalRepoStore(struct SyncBaseStruct *base,
01133                    struct ccn_charbuf *name,
01134                    struct ccn_charbuf *content,
01135                    int flags) {
01136     char *here = "Sync.SyncLocalRepoStore";
01137     int res = -__LINE__;
01138     struct ccn_charbuf *cob = SyncSignBuf(base, content, name, -1, flags);
01139     char *why = NULL;
01140     if (cob == NULL)
01141         why = "signing failed";
01142     else {
01143         res = r_sync_local_store(base->ccnr, cob);
01144         if (res < 0) why = "store failed";
01145         ccn_charbuf_destroy(&cob);
01146     }
01147     if (why != NULL)
01148         if (base->debug >= CCNL_ERROR)
01149             SyncNoteUriBase(base, here, why, name);
01150     return res;
01151 }
01152 
01153 extern int
01154 SyncLocalRepoFetch(struct SyncBaseStruct *base,
01155                    struct ccn_charbuf *name,
01156                    struct ccn_charbuf *cb,
01157                    struct ccn_parsed_ContentObject *pco) {
01158     char *here = "Sync.SyncLocalRepoFetch";
01159     struct ccnr_handle *ccnr = base->ccnr;
01160     struct ccn_charbuf *interest = SyncGenInterest(name, 1, 1, -1, 1, NULL);
01161     struct ccn_parsed_ContentObject pcos;
01162     if (pco == NULL) pco = &pcos;
01163     if (interest == NULL) return -__LINE__;
01164     int res = r_sync_lookup(ccnr, interest, cb);
01165     char *why = NULL;
01166     ccn_charbuf_destroy(&interest);
01167     if (res < 0) why = "fetch failed";
01168     else {
01169         res = ccn_parse_ContentObject(cb->buf, cb->length, pco, NULL);
01170         if (res < 0) why = "parse failed";
01171         else {
01172             res = ccn_verify_content(base->ccn, cb->buf, pco);
01173             if (res < 0) why = "verify failed";
01174         }
01175     }
01176     if (why != NULL)
01177         if (base->debug >= CCNL_ERROR)
01178             SyncNoteUriBase(base, here, why, name);
01179     return res;
01180 }
01181 
01182 
01183 

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