00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021 #include "SyncActions.h"
00022 #include "SyncBase.h"
00023 #include "SyncHashCache.h"
00024 #include "SyncNode.h"
00025 #include "SyncPrivate.h"
00026 #include "SyncRoot.h"
00027 #include "SyncUtil.h"
00028 #include "SyncTreeWorker.h"
00029 #include "IndexSorter.h"
00030
00031 #include <errno.h>
00032 #include <stdarg.h>
00033 #include <stdlib.h>
00034 #include <stdio.h>
00035 #include <string.h>
00036 #include <strings.h>
00037 #include <unistd.h>
00038 #include <sys/stat.h>
00039 #include <sys/time.h>
00040
00041 #include <ccn/ccn.h>
00042 #include <ccn/charbuf.h>
00043 #include <ccn/digest.h>
00044 #include <ccn/fetch.h>
00045 #include <ccn/seqwriter.h>
00046 #include <ccn/uri.h>
00047
00048 struct SyncTestParms {
00049 struct SyncBaseStruct *base;
00050 struct SyncRootStruct *root;
00051 int mode;
00052 int mark;
00053 int scope;
00054 int life;
00055 int sort;
00056 int bufs;
00057 int verbose;
00058 int resolve;
00059 int segmented;
00060 int blockSize;
00061 char *inputName;
00062 char *target;
00063 char *topoPrefix;
00064 char *namingPrefix;
00065 int nSplits;
00066 int *splits;
00067 struct timeval startTime;
00068 struct timeval stopTime;
00069 intmax_t fSize;
00070 };
00071
00072
00073
00074
00075
00076 #include <ccnr/ccnr_private.h>
00077
00078 #include <ccnr/ccnr_sync.h>
00079
00080
00081
00082 PUBLIC void
00083 ccnr_msg(struct ccnr_handle *h, const char *fmt, ...)
00084 {
00085 struct timeval t;
00086 va_list ap;
00087 struct ccn_charbuf *b = ccn_charbuf_create();
00088 ccn_charbuf_reserve(b, 1024);
00089 gettimeofday(&t, NULL);
00090 ccn_charbuf_putf(b, "%s\n", fmt);
00091 char *fb = ccn_charbuf_as_string(b);
00092 va_start(ap, fmt);
00093 vfprintf(stdout, fb, ap);
00094 va_end(ap);
00095 fflush(stdout);
00096 ccn_charbuf_destroy(&b);
00097 }
00098
00099 PUBLIC int
00100 ccnr_msg_level_from_string(char *s) {
00101
00102 if (s == NULL)
00103 return -1;
00104 if (strcasecmp(s, "NONE") == 0)
00105 return 0;
00106 if (strcasecmp(s, "SEVERE") == 0)
00107 return 3;
00108 if (strcasecmp(s, "ERROR") == 0)
00109 return 5;
00110 if (strcasecmp(s, "WARNING") == 0)
00111 return 7;
00112 if (strcasecmp(s, "INFO") == 0)
00113 return 9;
00114 if (strcasecmp(s, "FINE") == 0)
00115 return 11;
00116 if (strcasecmp(s, "FINER") == 0)
00117 return 13;
00118 if (strcasecmp(s, "FINEST") == 0)
00119 return 15;
00120 return -1;
00121 }
00122
00123 PUBLIC void
00124 r_sync_notify_after(struct ccnr_handle *ccnr, ccnr_hwm item)
00125 {
00126
00127 ccnr->notify_after = (ccnr_accession) item;
00128 }
00129
00130 PUBLIC int
00131 r_sync_enumerate(struct ccnr_handle *ccnr,
00132 struct ccn_charbuf *interest)
00133 {
00134 int ans = -1;
00135 return(ans);
00136 }
00137
00138
00139 PUBLIC int
00140 r_sync_lookup(struct ccnr_handle *ccnr,
00141 struct ccn_charbuf *interest,
00142 struct ccn_charbuf *content_ccnb)
00143 {
00144 int ans = -1;
00145 return(ans);
00146 }
00147
00148
00149
00150
00151
00152 PUBLIC enum ccn_upcall_res
00153 r_sync_upcall_store(struct ccnr_handle *ccnr,
00154 enum ccn_upcall_kind kind,
00155 struct ccn_upcall_info *info)
00156 {
00157 enum ccn_upcall_res ans = CCN_UPCALL_RESULT_ERR;
00158 return(ans);
00159 }
00160
00161
00162
00163
00164
00165
00166
00167 PUBLIC int
00168 r_sync_local_store(struct ccnr_handle *ccnr,
00169 struct ccn_charbuf *content)
00170 {
00171 int ans = -1;
00172 return(ans);
00173 }
00174
00175 PUBLIC uintmax_t
00176 ccnr_accession_encode(struct ccnr_handle *ccnr, ccnr_accession a)
00177 {
00178 return(a);
00179 }
00180
00181 PUBLIC ccnr_accession
00182 ccnr_accession_decode(struct ccnr_handle *ccnr, uintmax_t encoded)
00183 {
00184 return(encoded);
00185 }
00186
00187 PUBLIC int
00188 ccnr_accession_compare(struct ccnr_handle *ccnr, ccnr_accession x, ccnr_accession y)
00189 {
00190 if (x > y) return 1;
00191 if (x == y) return 0;
00192 if (x < y) return -1;
00193 return CCNR_NOT_COMPARABLE;
00194 }
00195
00196 PUBLIC uintmax_t
00197 ccnr_hwm_encode(struct ccnr_handle *ccnr, ccnr_hwm hwm)
00198 {
00199 return(hwm);
00200 }
00201
00202 PUBLIC ccnr_hwm
00203 ccnr_hwm_decode(struct ccnr_handle *ccnr, uintmax_t encoded)
00204 {
00205 return(encoded);
00206 }
00207
00208 PUBLIC int
00209 ccnr_acc_in_hwm(struct ccnr_handle *ccnr, ccnr_accession a, ccnr_hwm hwm)
00210 {
00211 return(a <= hwm);
00212 }
00213
00214 PUBLIC ccnr_hwm
00215 ccnr_hwm_update(struct ccnr_handle *ccnr, ccnr_hwm hwm, ccnr_accession a)
00216 {
00217 return(a <= hwm ? hwm : a);
00218 }
00219
00220 PUBLIC ccnr_hwm
00221 ccnr_hwm_merge(struct ccnr_handle *ccnr, ccnr_hwm x, ccnr_hwm y)
00222 {
00223 return(x < y ? y : x);
00224 }
00225
00226 PUBLIC int
00227 ccnr_hwm_compare(struct ccnr_handle *ccnr, ccnr_hwm x, ccnr_hwm y)
00228 {
00229 if (x > y) return 1;
00230 if (x == y) return 0;
00231 if (x < y) return -1;
00232 return CCNR_NOT_COMPARABLE;
00233 }
00234
00235
00236
00237
00238
00239
00240 static int
00241 noteErr(const char *fmt, ...) {
00242 struct timeval t;
00243 va_list ap;
00244 struct ccn_charbuf *b = ccn_charbuf_create();
00245 ccn_charbuf_reserve(b, 1024);
00246 gettimeofday(&t, NULL);
00247 ccn_charbuf_putf(b, "** ERROR: %s\n", fmt);
00248 char *fb = ccn_charbuf_as_string(b);
00249 va_start(ap, fmt);
00250 vfprintf(stderr, fb, ap);
00251 va_end(ap);
00252 fflush(stderr);
00253 ccn_charbuf_destroy(&b);
00254 return -1;
00255 }
00256
00257
00258
00259
00260
00261 static int
00262 parseAndAccumName(char *s, struct SyncNameAccum *na) {
00263 int i = 0;
00264 for (;;) {
00265 char c = s[i];
00266 int d = SyncDecodeUriChar(c);
00267 if (d <= 0) break;
00268 i++;
00269 }
00270 char save = s[i];
00271 s[i] = 0;
00272 struct ccn_charbuf *cb = ccn_charbuf_create();
00273 int skip = ccn_name_from_uri(cb, (const char *) s);
00274 s[i] = save;
00275 if (skip <= 0) {
00276
00277 ccn_charbuf_destroy(&cb);
00278 return skip;
00279 }
00280
00281
00282 intmax_t size = 0;
00283 for (;;) {
00284 char c = s[i];
00285 if (c >= '0' && c <= '9') break;
00286 if (c < ' ') break;
00287 i++;
00288 }
00289 for (;;) {
00290 char c = s[i];
00291 if (c < '0' || c > '9') break;
00292 size = size * 10 + SyncDecodeHexDigit(c);
00293 i++;
00294 }
00295
00296 SyncNameAccumAppend(na, cb, size);
00297 return skip;
00298 }
00299
00300 static struct SyncNameAccum *
00301 readAndAccumNames(FILE *input, int rem) {
00302 struct SyncNameAccum *na = SyncAllocNameAccum(4);
00303 static int tempLim = 4*1024;
00304 char *temp = NEW_ANY(tempLim+4, char);
00305 while (rem > 0) {
00306
00307 int len = 0;
00308 while (len < tempLim) {
00309 int c = fgetc(input);
00310 if (c < 0 || c == '\n') break;
00311 temp[len] = c;
00312 len++;
00313 }
00314 temp[len] = 0;
00315 if (len == 0)
00316
00317 break;
00318
00319 int pos = 0;
00320 static char *key = "ccnx:";
00321 int keyLen = strlen(key);
00322 int found = 0;
00323 while (pos < len) {
00324 if (strncasecmp(temp+pos, key, keyLen) == 0) {
00325
00326 parseAndAccumName(temp+pos, na);
00327 found++;
00328 break;
00329 }
00330 pos++;
00331 }
00332 if (found == 0) {
00333
00334 for (pos = 0; pos < len; pos++) {
00335 if (temp[pos]== '/') {
00336 parseAndAccumName(temp+pos, na);
00337 break;
00338 }
00339 }
00340 }
00341 rem--;
00342 }
00343 free(temp);
00344 return na;
00345 }
00346
00347
00348
00349
00350
00351 static void
00352 printTreeInner(struct SyncTreeWorkerHead *head,
00353 struct ccn_charbuf *tmpB,
00354 struct ccn_charbuf *tmpD,
00355 FILE *f) {
00356 int i = 0;
00357 struct SyncTreeWorkerEntry *ent = SyncTreeWorkerTop(head);
00358 struct SyncHashCacheEntry *ce = ent->cacheEntry;
00359 if (ce == NULL) {
00360 fprintf(f, "?? no cacheEntry ??\n");
00361 return;
00362 }
00363 struct SyncNodeComposite *nc = ((head->remote > 0) ? ce->ncR : ce->ncL);
00364 if (nc == NULL) {
00365 fprintf(f, "?? no cacheEntry->nc ??\n");
00366 return;
00367 }
00368 for (i = 1; i < head->level; i++) fprintf(f, " | ");
00369 char *hex = SyncHexStr(nc->hash->buf, nc->hash->length);
00370 fprintf(f, "node, depth = %d, refs = %d, leaves = %d, hash = %s\n",
00371 (int) nc->treeDepth, (int) nc->refLen, (int) nc->leafCount, hex);
00372 free(hex);
00373 ssize_t pos = 0;
00374 while (pos < nc->refLen) {
00375 struct SyncNodeElem *ep = &nc->refs[pos];
00376 ent->pos = pos;
00377 if (ep->kind & SyncElemKind_leaf) {
00378
00379 struct ccn_buf_decoder nameDec;
00380 struct ccn_buf_decoder *nameD = NULL;
00381 nameD = SyncInitDecoderFromOffset(&nameDec, nc, ep->start, ep->stop);
00382 ccn_charbuf_reset(tmpB);
00383 ccn_charbuf_reset(tmpD);
00384 SyncAppendElementInner(tmpB, nameD);
00385 ccn_uri_append(tmpD, tmpB->buf, tmpB->length, 1);
00386 for (i = 0; i < head->level; i++) fprintf(f, " | ");
00387 fprintf(f, "%s\n", ccn_charbuf_as_string(tmpD));
00388 } else {
00389
00390 SyncTreeWorkerPush(head);
00391 printTreeInner(head, tmpB, tmpD, f);
00392 SyncTreeWorkerPop(head);
00393 }
00394 pos++;
00395 }
00396 }
00397
00398 static void
00399 printTree(struct SyncTreeWorkerHead *head, FILE *f) {
00400 struct ccn_charbuf *tmpB = ccn_charbuf_create();
00401 struct ccn_charbuf *tmpD = ccn_charbuf_create();
00402 printTreeInner(head, tmpB, tmpD, f);
00403 ccn_charbuf_destroy(&tmpB);
00404 ccn_charbuf_destroy(&tmpD);
00405 }
00406
00407 static void putMark(FILE *f) {
00408 struct timeval mark;
00409 gettimeofday(&mark, 0);
00410 fprintf(f, "%ju.%06u: ",
00411 (uintmax_t) mark.tv_sec,
00412 (unsigned) mark.tv_usec);
00413 }
00414
00415
00416
00417
00418
00419
00420 static struct SyncNodeComposite *
00421 testGenComposite(struct SyncBaseStruct *base, int nRefs) {
00422 int res = 0;
00423 struct SyncNodeComposite *nc = SyncAllocComposite(base);
00424 struct ccn_charbuf *tmp = ccn_charbuf_create();
00425
00426
00427 while (nRefs > 0 && res == 0) {
00428 ccn_charbuf_reset(tmp);
00429 res |= SyncAppendRandomName(tmp, 5, 12);
00430 SyncNodeAddName(nc, tmp);
00431 nRefs--;
00432 }
00433
00434 SyncEndComposite(nc);
00435 ccn_charbuf_destroy(&tmp);
00436
00437 nc->err = res;
00438 return nc;
00439 }
00440
00441 static int
00442 testEncodeDecode(struct SyncTestParms *parms) {
00443 struct SyncBaseStruct *base = parms->base;
00444 struct ccn_charbuf *cb = ccn_charbuf_create();
00445 cb->length = 0;
00446 ccnb_element_begin(cb, CCN_DTAG_Content);
00447 fwrite(cb->buf, sizeof(unsigned char), cb->length, stdout);
00448
00449 struct SyncNodeComposite *nc = testGenComposite(base, 4);
00450
00451 SyncWriteComposite(nc, stdout);
00452
00453 struct ccn_buf_decoder ds;
00454 struct ccn_buf_decoder *d = SyncInitDecoderFromCharbuf(&ds, nc->cb, 0);
00455 struct SyncNodeComposite *chk = SyncAllocComposite(base);
00456 SyncParseComposite(chk, d);
00457 SyncWriteComposite(chk, stdout);
00458 SyncFreeComposite(chk);
00459
00460 int pos = cb->length;
00461 ccnb_element_end(cb);
00462 fwrite(cb->buf+pos, sizeof(unsigned char), cb->length-pos, stdout);
00463 fflush(stdout);
00464
00465 SyncFreeComposite(nc);
00466
00467 cb->length = 0;
00468 ccn_charbuf_destroy(&cb);
00469
00470 return 0;
00471 }
00472
00473 static int
00474 testReader(struct SyncTestParms *parms) {
00475 char *fn = parms->inputName;
00476 int sort = parms->sort;
00477 FILE *f = fopen(fn, "r");
00478 int res = 0;
00479 if (f != NULL) {
00480 sync_time startTime = SyncCurrentTime();
00481 struct SyncNameAccum *na = readAndAccumNames(f, 1000000);
00482 fclose(f);
00483 struct ccn_charbuf *tmp = ccn_charbuf_create();
00484 int i = 0;
00485 IndexSorter_Base ixBase = NULL;
00486 int accumNameBytes = 0;
00487 int accumContentBytes = 0;
00488 if (sort > 0) {
00489 IndexSorter_Index ixLim = na->len;
00490 ixBase = IndexSorter_New(ixLim, -1);
00491 ixBase->sorter = SyncNameAccumSorter;
00492 ixBase->client = na;
00493 IndexSorter_Index ix = 0;
00494 for (; ix < ixLim; ix++) IndexSorter_Add(ixBase, ix);
00495 }
00496 struct ccn_charbuf *lag = NULL;
00497 for (;i < na->len; i++) {
00498 int j = i;
00499 if (ixBase != NULL) j = IndexSorter_Rem(ixBase);
00500 struct ccn_charbuf *each = na->ents[j].name;
00501 if (sort == 1 && lag != NULL) {
00502 int cmp = SyncCmpNames(each, lag);
00503 if (cmp < 0)
00504 return noteErr("bad sort (order)!");
00505 if (cmp == 0)
00506 return noteErr("bad sort (duplicate)!");
00507 }
00508 struct ccn_charbuf *repl = each;
00509 accumNameBytes = accumNameBytes + repl->length;
00510 ssize_t size = na->ents[j].data;
00511 accumContentBytes = accumContentBytes + size;
00512 ccn_charbuf_reset(tmp);
00513 ccn_uri_append(tmp, repl->buf, repl->length, 1);
00514 if (sort != 2) {
00515 fprintf(stdout, "%4d", i);
00516 if (sort) fprintf(stdout, ", %4d", j);
00517 fprintf(stdout, ", %8zd, ", size);
00518 }
00519 fprintf(stdout, "%s\n", ccn_charbuf_as_string(tmp));
00520 lag = each;
00521 if (repl != each) ccn_charbuf_destroy(&repl);
00522 }
00523 int64_t dt = SyncDeltaTime(startTime, SyncCurrentTime());
00524 dt = (dt + 500)/ 1000;
00525 fprintf(stdout, "-- %d names, %d name bytes, %d content bytes, %d.%03d seconds\n",
00526 na->len, accumNameBytes, accumContentBytes,
00527 (int) (dt / 1000), (int) (dt % 1000));
00528 if (ixBase != NULL) IndexSorter_Free(&ixBase);
00529 ccn_charbuf_destroy(&tmp);
00530 na = SyncFreeNameAccum(na);
00531 } else {
00532 return noteErr("testReader, could not open %s", fn);
00533 }
00534 return res;
00535 }
00536
00537 static struct SyncRootStruct *
00538 newDefaultRoot(struct SyncTestParms *parms, struct SyncNameAccum *filter) {
00539 int res = 0;
00540 struct SyncRootStruct *root = NULL;
00541 struct ccn_charbuf *topo = ccn_charbuf_create();
00542 struct ccn_charbuf *prefix = ccn_charbuf_create();
00543 for (;;) {
00544 res = ccn_name_from_uri(topo, parms->topoPrefix);
00545 if (res < 0) {noteErr("invalid topo prefix"); break; }
00546
00547 res = ccn_name_from_uri(prefix, parms->namingPrefix);
00548 if (res < 0) {noteErr("invalid naming prefix"); break; }
00549
00550 root = SyncAddRoot(parms->base, topo, prefix, filter);
00551 break;
00552 }
00553 ccn_charbuf_destroy(&topo);
00554 ccn_charbuf_destroy(&prefix);
00555 return root;
00556 }
00557
00558 static int
00559 testReadBuilder(struct SyncTestParms *parms) {
00560 FILE *f = fopen(parms->inputName, "r");
00561 int ns = parms->nSplits;
00562 int res = 0;
00563
00564 if (f != NULL) {
00565 struct SyncRootStruct *root = parms->root;
00566
00567 if (root == NULL) {
00568
00569 root = newDefaultRoot(parms, NULL);
00570 }
00571
00572 if (root->namesToAdd != NULL)
00573 SyncFreeNameAccum(root->namesToAdd);
00574
00575 struct SyncLongHashStruct longHash;
00576 int split = 0;
00577 memset(&longHash, 0, sizeof(longHash));
00578 longHash.pos = MAX_HASH_BYTES;
00579 for (;;) {
00580 int i = 0;
00581 if (ns == 0) {
00582 root->namesToAdd = readAndAccumNames(f, 1000000);
00583 } else {
00584 int p = 0;
00585 int k = parms->splits[split];
00586 if (split > 0) p = parms->splits[split-1];
00587 if (k <= 0 || k >= ns) {
00588 return noteErr("splits: bad k %d", k);
00589 break;
00590 }
00591 if (p < 0 || p >= k) {
00592 return noteErr("splits: bad p %d", k);
00593 break;
00594 }
00595 root->namesToAdd = readAndAccumNames(f, k-p);
00596 }
00597
00598 if (root->namesToAdd == NULL || root->namesToAdd->len <= 0)
00599
00600 break;
00601
00602 for (i = 0; i < root->namesToAdd->len; i++) {
00603 SyncAccumHash(&longHash, root->namesToAdd->ents[i].name);
00604 }
00605 SyncUpdateRoot(root);
00606
00607 struct ccn_charbuf *hb = SyncLongHashToBuf(&longHash);
00608 struct ccn_charbuf *rb = root->currentHash;
00609 if (rb->length != hb->length
00610 || memcmp(rb->buf, hb->buf, hb->length) != 0) {
00611
00612 char *hexL = SyncHexStr(hb->buf, hb->length);
00613 char *hexR = SyncHexStr(rb->buf, rb->length);
00614 res = noteErr("hexL %s, hexR %s", hexL, hexR);
00615 free(hexL);
00616 free(hexR);
00617 return res;
00618 }
00619 ccn_charbuf_destroy(&hb);
00620
00621 struct SyncHashCacheEntry *ce = SyncRootTopEntry(root);
00622 struct SyncTreeWorkerHead *tw = SyncTreeWorkerCreate(root->ch, ce, 0);
00623 switch (parms->mode) {
00624 case 0: {
00625
00626 break;
00627 }
00628 case 1: {
00629
00630 SyncWriteComposite(ce->ncL, stdout);
00631 break;
00632 }
00633 case 2: {
00634
00635 SyncTreeWorkerInit(tw, ce, 0);
00636 printTree(tw, stdout);
00637 fprintf(stdout, "-----------------------\n");
00638 break;
00639 }
00640 default: {
00641
00642 break;
00643 }
00644 }
00645
00646
00647 tw = SyncTreeWorkerFree(tw);
00648 split++;
00649 if (ns > 0 && split >= ns) break;
00650 }
00651
00652 fclose(f);
00653 return 0;
00654
00655 } else {
00656 return noteErr("testReadBuilder, could not open %s", parms->inputName);
00657 }
00658 }
00659
00660 static struct SyncRootStruct *
00661 testRootCoding(struct SyncTestParms *parms, struct SyncRootStruct *root) {
00662 struct SyncBaseStruct *base = parms->base;
00663 struct ccn_charbuf *cb1 = ccn_charbuf_create();
00664 int res = 0;
00665 SyncRootAppendSlice(cb1, root);
00666
00667 SyncRemRoot(root);
00668
00669 struct ccn_buf_decoder ds;
00670 struct ccn_buf_decoder *d = SyncInitDecoderFromCharbuf(&ds, cb1, 0);
00671 root = SyncRootDecodeAndAdd(base, d);
00672 if (root == NULL) {
00673 res = noteErr("SyncRootDecodeAndAdd, failed");
00674 }
00675 if (res ==0) {
00676
00677 struct ccn_charbuf *cb2 = ccn_charbuf_create();
00678 SyncRootAppendSlice(cb2, root);
00679
00680 if (res == 0) {
00681
00682 if (cb1->length == 0 || cb1->length != cb2->length) {
00683 res = noteErr("testRootCoding, bad encoding lengths, %d != %d",
00684 (int) cb1->length, (int) cb2->length);
00685 }
00686 }
00687 if (res == 0) {
00688
00689 ssize_t cmp = memcmp(cb1->buf, cb2->buf, cb1->length);
00690 if (cmp != 0) {
00691 res = noteErr("testRootCoding, bad encoding data",
00692 (int) cb1->length, (int) cb2->length);
00693 res = -1;
00694 }
00695 }
00696 ccn_charbuf_destroy(&cb2);
00697 }
00698 ccn_charbuf_destroy(&cb1);
00699
00700 if (res == 0) return root;
00701
00702 SyncRemRoot(root);
00703 return NULL;
00704
00705 }
00706
00707 static int
00708 testRootLookup (struct SyncTestParms *parms, struct SyncRootStruct *root,
00709 char * goodName, char * badName) {
00710 int res = 0;
00711
00712 struct ccn_charbuf *name = ccn_charbuf_create();
00713 ccn_name_from_uri(name, goodName);
00714 enum SyncRootLookupCode ec = SyncRootLookupName(root, name);
00715 if (ec != SyncRootLookupCode_covered) {
00716 res = noteErr("testRootLookup, good name not covered, %s",
00717 goodName);
00718 }
00719 ccn_charbuf_reset(name);
00720 ccn_name_from_uri(name, badName);
00721 ec = SyncRootLookupName(root, name);
00722 if (ec != SyncRootLookupCode_none) {
00723 res = noteErr("testRootLookup, bad name not rejected, %s",
00724 badName);
00725 }
00726 return res;
00727 }
00728
00729 static int
00730 testRootBasic(struct SyncTestParms *parms) {
00731 int res = 0;
00732 struct SyncRootStruct *root = NULL;
00733
00734 struct ccn_charbuf *cb = ccn_charbuf_create();
00735 uintmax_t val = 37;
00736 res |= SyncAppendTaggedNumber(cb, CCN_DTAG_SyncVersion, val);
00737
00738 if (res == 0) {
00739 struct ccn_buf_decoder ds;
00740 struct ccn_buf_decoder *d = ccn_buf_decoder_start(&ds, cb->buf, cb->length);
00741 if (SyncParseUnsigned(d, CCN_DTAG_SyncVersion) != val
00742 || d->decoder.state < 0)
00743 res = -__LINE__;
00744 }
00745
00746 if (res < 0) {
00747 return noteErr("testRootBasic, basic numbers failed, %d", res);
00748 }
00749
00750
00751
00752 root = newDefaultRoot(parms, NULL);
00753 if (root == NULL) return noteErr("testRootBasic, newDefaultRoot");
00754 root = testRootCoding(parms, root);
00755 if (root == NULL) return noteErr("testRootBasic, testRootCoding");
00756 char goodName[1024];
00757 char *badName = "ccnx:/bogus/XXX";
00758 snprintf(goodName, sizeof(goodName), "%s/PARC/XXX", parms->namingPrefix);
00759 res = testRootLookup(parms, root,
00760 goodName,
00761 badName);
00762 if (res < 0) noteErr("testRootBasic, lookup");
00763 SyncRemRoot(root);
00764
00765 struct SyncNameAccum *filter = SyncAllocNameAccum(4);
00766 struct ccn_charbuf *clause = ccn_charbuf_create();
00767 ccn_name_from_uri(clause, "/PARC");
00768 SyncNameAccumAppend(filter, clause, 0);
00769 root = newDefaultRoot(parms, filter);
00770 ccn_charbuf_destroy(&clause);
00771 SyncFreeNameAccum(filter);
00772 if (root == NULL) {
00773 return noteErr("testRootBasic, newDefaultRoot with filter");
00774 }
00775
00776 res = testRootLookup(parms, root,
00777 goodName,
00778 badName);
00779 if (res < 0) noteErr("testRootBasic, lookup with filter");
00780 SyncRemRoot(root);
00781
00782 return res;
00783 }
00784
00785 static int
00786 localStore(struct ccn *ccn, struct ccn_charbuf *nm, struct ccn_charbuf *cb) {
00787 struct ccn_charbuf *tmp = ccn_charbuf_create();
00788 ccn_create_version(ccn, nm, CCN_V_NOW, 0, 0);
00789 ccn_charbuf_append_charbuf(tmp, nm);
00790 ccn_name_from_uri(tmp, "%C1.R.sw");
00791 ccn_name_append_nonce(tmp);
00792 ccn_get(ccn, tmp, NULL, 6000, NULL, NULL, NULL, 0);
00793 ccn_charbuf_destroy(&tmp);
00794
00795 struct ccn_charbuf *cob = ccn_charbuf_create();
00796 struct ccn_signing_params sp = CCN_SIGNING_PARAMS_INIT;
00797 const void *cp = NULL;
00798 size_t cs = 0;
00799 int res = 0;
00800 if (cb != NULL) {
00801 sp.type = CCN_CONTENT_DATA;
00802 cp = (const void *) cb->buf;
00803 cs = cb->length;
00804 } else {
00805 sp.type = CCN_CONTENT_GONE;
00806 }
00807 ccn_name_append_numeric(nm, CCN_MARKER_SEQNUM, 0);
00808 sp.sp_flags |= CCN_SP_FINAL_BLOCK;
00809 res |= ccn_sign_content(ccn,
00810 cob,
00811 nm,
00812 &sp,
00813 cp,
00814 cs);
00815 res |= ccn_put(ccn, (const void *) cob->buf, cob->length);
00816
00817 ccn_charbuf_destroy(&cob);
00818 return res;
00819 }
00820
00821 static int
00822 sendSlice(struct SyncTestParms *parms,
00823 char *topo, char *prefix,
00824 int count, char **clauses) {
00825
00826 struct ccn_charbuf *cb = ccn_charbuf_create();
00827 struct ccn_charbuf *hash = ccn_charbuf_create();
00828 struct ccn_charbuf *nm = ccn_charbuf_create();
00829 int i = 0;
00830 int res = 0;
00831 res |= ccnb_element_begin(cb, CCN_DTAG_SyncConfigSlice);
00832 res |= SyncAppendTaggedNumber(cb, CCN_DTAG_SyncVersion, SLICE_VERSION);
00833 res |= ccn_name_from_uri(nm, topo);
00834 res |= ccn_charbuf_append_charbuf(cb, nm);
00835 res |= ccn_name_from_uri(nm, prefix);
00836 res |= ccn_charbuf_append_charbuf(cb, nm);
00837 res |= ccnb_element_begin(cb, CCN_DTAG_SyncConfigSliceList);
00838 for (i = 0; i < count ; i++) {
00839 res |= SyncAppendTaggedNumber(cb, CCN_DTAG_SyncConfigSliceOp, 0);
00840 res |= ccn_name_from_uri(nm, clauses[i]);
00841 res |= ccn_charbuf_append_charbuf(cb, nm);
00842 }
00843 res |= ccnb_element_end(cb);
00844 res |= ccnb_element_end(cb);
00845
00846 if (res >= 0) {
00847
00848 struct ccn *ccn = NULL;
00849 struct ccn_digest *cow = ccn_digest_create(CCN_DIGEST_DEFAULT);
00850 size_t sz = ccn_digest_size(cow);
00851 unsigned char *dst = ccn_charbuf_reserve(hash, sz);
00852 ccn_digest_init(cow);
00853 ccn_digest_update(cow, cb->buf, cb->length);
00854 ccn_digest_final(cow, dst, sz);
00855 hash->length = sz;
00856 ccn_digest_destroy(&cow);
00857
00858
00859 static char *localLit = "\xC1.M.S.localhost";
00860 static char *sliceCmd = "\xC1.S.cs";
00861 res |= ccn_name_init(nm);
00862 res |= ccn_name_append_str(nm, localLit);
00863 res |= ccn_name_append_str(nm, sliceCmd);
00864 res |= ccn_name_append(nm, hash->buf, hash->length);
00865
00866 if (res >= 0) {
00867
00868 struct ccn_charbuf *hashOnly = ccn_charbuf_create();
00869 ccn_name_init(hashOnly);
00870 ccn_name_append(hashOnly, hash->buf, hash->length);
00871 struct ccn_charbuf *uri = SyncUriForName(hashOnly);
00872 fprintf(stdout, "sendSlice, root hash %s\n",
00873 ccn_charbuf_as_string(uri));
00874 ccn_charbuf_destroy(&uri);
00875 }
00876
00877 ccn = ccn_create();
00878 if (ccn_connect(ccn, NULL) == -1) {
00879 perror("Could not connect to ccnd");
00880 exit(1);
00881 }
00882 if (res >= 0) res |= localStore(ccn, nm, cb);
00883 if (res < 0) {
00884 res = noteErr("sendSlice, failed");
00885 } else {
00886 struct ccn_charbuf *uri = SyncUriForName(nm);
00887 if (parms->mode != 0) {
00888 if (parms->mark) putMark(stdout);
00889 fprintf(stdout, "sendSlice, sent %s\n",
00890 ccn_charbuf_as_string(uri));
00891 }
00892 ccn_charbuf_destroy(&uri);
00893 }
00894
00895 ccn_destroy(&ccn);
00896 }
00897
00898 ccn_charbuf_destroy(&cb);
00899 ccn_charbuf_destroy(&hash);
00900 ccn_charbuf_destroy(&nm);
00901 if (res > 0) res = 0;
00902 return res;
00903 }
00904
00905 struct storeFileStruct {
00906 struct SyncTestParms *parms;
00907 struct ccn_charbuf *nm;
00908 struct ccn_charbuf *cb;
00909 struct ccn *ccn;
00910 off_t bs;
00911 off_t fSize;
00912 FILE *file;
00913 unsigned char *segData;
00914 int nSegs;
00915 int stored;
00916 };
00917
00918 static int64_t
00919 segFromInfo(struct ccn_upcall_info *info) {
00920
00921
00922 if (info == NULL) return -1;
00923 const unsigned char *ccnb = info->content_ccnb;
00924 struct ccn_indexbuf *cc = info->content_comps;
00925 if (cc == NULL || ccnb == NULL) {
00926
00927 cc = info->interest_comps;
00928 ccnb = info->interest_ccnb;
00929 if (cc == NULL || ccnb == NULL) return -1;
00930 }
00931 int ns = cc->n;
00932 if (ns > 2) {
00933
00934 int start = cc->buf[ns - 2];
00935 int stop = cc->buf[ns - 1];
00936 if (start < stop) {
00937 size_t len = 0;
00938 const unsigned char *data = NULL;
00939 ccn_ref_tagged_BLOB(CCN_DTAG_Component, ccnb, start, stop, &data, &len);
00940 if (len > 0 && data != NULL) {
00941
00942
00943 if (data[0] != CCN_MARKER_SEQNUM) return -1;
00944 int64_t n = 0;
00945 int i = 0;
00946 for (i = 1; i < len; i++) {
00947 n = n * 256 + data[i];
00948 }
00949 return n;
00950 }
00951 }
00952 }
00953 return -1;
00954 }
00955
00956 static enum ccn_upcall_res
00957 storeHandler(struct ccn_closure *selfp,
00958 enum ccn_upcall_kind kind,
00959 struct ccn_upcall_info *info) {
00960 struct storeFileStruct *sfd = selfp->data;
00961 enum ccn_upcall_res ret = CCN_UPCALL_RESULT_OK;
00962 switch (kind) {
00963 case CCN_UPCALL_FINAL:
00964 free(selfp);
00965 break;
00966 case CCN_UPCALL_INTEREST: {
00967 int64_t seg = segFromInfo(info);
00968 struct ccn_charbuf *uri = ccn_charbuf_create();
00969 ccn_uri_append(uri, sfd->nm->buf, sfd->nm->length, 0);
00970 char *str = ccn_charbuf_as_string(uri);
00971 if (seg >= 0 && seg < sfd->nSegs) {
00972 struct ccn_charbuf *name = SyncCopyName(sfd->nm);
00973 struct ccn_charbuf *cb = ccn_charbuf_create();
00974 struct ccn_charbuf *cob = ccn_charbuf_create();
00975 off_t bs = sfd->bs;
00976 off_t pos = seg * bs;
00977 off_t rs = sfd->fSize - pos;
00978 if (rs > bs) rs = bs;
00979
00980 ccn_charbuf_reserve(cb, rs);
00981 cb->length = rs;
00982 char *cp = ccn_charbuf_as_string(cb);
00983
00984
00985 int res = fseeko(sfd->file, pos, SEEK_SET);
00986 if (res >= 0) {
00987 res = fread(cp, rs, 1, sfd->file);
00988 if (res < 0) {
00989 char *eMess = strerror(errno);
00990 fprintf(stderr, "ERROR in fread, %s, seg %d, %s\n",
00991 eMess, (int) seg, str);
00992 }
00993 } else {
00994 char *eMess = strerror(errno);
00995 fprintf(stderr, "ERROR in fseeko, %s, seg %d, %s\n",
00996 eMess, (int) seg, str);
00997 }
00998
00999 if (res >= 0) {
01000 struct ccn_signing_params sp = CCN_SIGNING_PARAMS_INIT;
01001 const void *cp = NULL;
01002 size_t cs = 0;
01003 sp.type = CCN_CONTENT_DATA;
01004 cp = (const void *) cb->buf;
01005 cs = cb->length;
01006 if (seg+1 == sfd->nSegs) sp.sp_flags |= CCN_SP_FINAL_BLOCK;
01007 ccn_name_append_numeric(name, CCN_MARKER_SEQNUM, seg);
01008 res |= ccn_sign_content(sfd->ccn,
01009 cob,
01010 name,
01011 &sp,
01012 cp,
01013 rs);
01014 res |= ccn_put(sfd->ccn, (const void *) cob->buf, cob->length);
01015
01016 if (res < 0) {
01017 return noteErr("seg %d, %s",
01018 (int) seg,
01019 str);
01020 } else if (sfd->parms->verbose) {
01021 if (sfd->parms->mark) putMark(stdout);
01022 fprintf(stdout, "put seg %d, %s\n",
01023 (int) seg,
01024 str);
01025 }
01026
01027
01028 unsigned char uc = sfd->segData[seg];
01029 if (uc == 0) {
01030 uc++;
01031 sfd->stored++;
01032 } else if (uc < 255) uc++;
01033 sfd->segData[seg] = uc;
01034 }
01035
01036 ccn_charbuf_destroy(&name);
01037 ccn_charbuf_destroy(&cb);
01038 ccn_charbuf_destroy(&cob);
01039
01040 }
01041 ccn_charbuf_destroy(&uri);
01042 ret = CCN_UPCALL_RESULT_INTEREST_CONSUMED;
01043 break;
01044 }
01045 default:
01046 ret = CCN_UPCALL_RESULT_ERR;
01047 break;
01048 }
01049 return ret;
01050 }
01051
01052 static void
01053 formatStats(struct SyncTestParms *parms) {
01054 int64_t dt = (1000000*(parms->stopTime.tv_sec-parms->startTime.tv_sec)
01055 + parms->stopTime.tv_usec-parms->startTime.tv_usec);
01056 if (dt <= 0) dt = 1;
01057 int64_t rate = 0;
01058
01059 switch (parms->mode) {
01060 case 0: {
01061
01062 break;
01063 }
01064 case 3: {
01065
01066 const char *expid = getenv("CCN_EXPERIMENT_ID");
01067 const char *sep = " ";
01068 if (expid == NULL) {
01069 expid = "";
01070 sep = "";
01071 }
01072 rate = (parms->fSize * 1000000) / dt;
01073 if (parms->mark) putMark(stderr);
01074 fprintf(stderr,
01075 "%ld.%06u SyncTest[%d]: %s%s"
01076 "%jd bytes transferred in %ld.%06u seconds (%ld bytes/sec)"
01077 "\n",
01078 (long) parms->stopTime.tv_sec,
01079 (unsigned) parms->stopTime.tv_usec,
01080 (int)getpid(),
01081 expid,
01082 sep,
01083 (intmax_t) parms->fSize,
01084 (long) (dt / 1000000),
01085 (unsigned) (dt % 1000000),
01086 (long) rate
01087 );
01088 break;
01089 }
01090 default: {
01091
01092 dt = (dt + 500) / 1000;
01093 if (dt <= 0) dt = 1;
01094 rate = parms->fSize / dt;
01095
01096 if (parms->mark) putMark(stdout);
01097 fprintf(stdout, "transferred %jd bytes in %d.%03d seconds = %d.%03d MB/sec\n",
01098 (intmax_t) parms->fSize,
01099 (int) (dt / 1000), (int) dt % 1000,
01100 (int) (rate / 1000), (int) rate % 1000);
01101 break;
01102 }
01103
01104 }
01105 }
01106
01107 static int
01108 getFile(struct SyncTestParms *parms, char *src, char *dst) {
01109
01110
01111 FILE *file = NULL;
01112
01113 if (dst != NULL) {
01114 file = fopen(dst, "w");
01115 if (file == NULL) {
01116 perror("fopen failed");
01117 return -1;
01118 }
01119 }
01120
01121 struct ccn *ccn = NULL;
01122 ccn = ccn_create();
01123 #if (CCN_API_VERSION >= 4004)
01124
01125 if (dst == NULL)
01126 ccn_defer_verification(ccn, 1);
01127 #endif
01128 if (ccn_connect(ccn, NULL) == -1) {
01129 perror("Could not connect to ccnd");
01130 return -1;
01131 }
01132 struct ccn_charbuf *cb = ccn_charbuf_create();
01133 struct ccn_charbuf *nm = ccn_charbuf_create();
01134 int bs = parms->blockSize;
01135
01136 int res = ccn_name_from_uri(nm, src);
01137 if (res < 0) {
01138 perror("ccn_name_from_uri failed");
01139 return -1;
01140 }
01141
01142 if (parms->resolve) {
01143 res = ccn_resolve_version(ccn, nm, CCN_V_HIGH, parms->life*1000);
01144
01145 if (res < 0) {
01146 perror("ccn_resolve_version failed");
01147 return -1;
01148 }
01149 }
01150
01151 struct ccn_fetch *cf = ccn_fetch_new(ccn);
01152 struct ccn_charbuf *template = SyncGenInterest(NULL,
01153 parms->scope,
01154 parms->life,
01155 -1, -1, NULL);
01156
01157 if (parms->verbose) {
01158 ccn_fetch_set_debug(cf, stderr,
01159 ccn_fetch_flags_NoteOpenClose
01160 | ccn_fetch_flags_NoteNeed
01161 | ccn_fetch_flags_NoteFill
01162 | ccn_fetch_flags_NoteTimeout
01163 | ccn_fetch_flags_NoteFinal);
01164 }
01165 gettimeofday(&parms->startTime, 0);
01166
01167 if (parms->segmented == 0) {
01168
01169 struct ccn_parsed_ContentObject pcos;
01170 res = ccn_get(ccn, nm, template,
01171 parms->life*1000,
01172 cb, &pcos, NULL, 0);
01173 if (res < 0) {
01174 perror("get failed");
01175 return -1;
01176 }
01177 if (file != NULL) {
01178 size_t nItems = fwrite(ccn_charbuf_as_string(cb), cb->length, 1, file);
01179 if (nItems < 1) {
01180 perror("fwrite failed");
01181 return -1;
01182 }
01183 }
01184 parms->fSize = parms->fSize + cb->length;
01185
01186 } else {
01187
01188 struct ccn_fetch_stream *fs = ccn_fetch_open(cf, nm,
01189 "SyncTest",
01190 template,
01191 parms->bufs,
01192 0, 0);
01193 ccn_charbuf_destroy(&template);
01194 if (fs == NULL) {
01195 perror("ccn_fetch_open failed");
01196 return -1;
01197 }
01198 ccn_charbuf_reserve(cb, bs);
01199 cb->length = bs;
01200 char *cp = ccn_charbuf_as_string(cb);
01201
01202 for (;;) {
01203 intmax_t av = ccn_fetch_avail(fs);
01204 if (av == CCN_FETCH_READ_NONE) {
01205 ccn_run(ccn, 1);
01206 continue;
01207 }
01208 int nb = ccn_fetch_read(fs, cp, bs);
01209 if (nb > 0) {
01210 if (file != NULL) {
01211 size_t nItems = fwrite(cp, nb, 1, file);
01212 if (nItems < 1) {
01213 perror("fwrite failed");
01214 exit(1);
01215 }
01216 }
01217 parms->fSize = parms->fSize + nb;
01218 } else if (nb == CCN_FETCH_READ_NONE) {
01219
01220 ccn_run(ccn, 1);
01221 } else {
01222 if (nb == CCN_FETCH_READ_END) break;
01223 if (nb == CCN_FETCH_READ_TIMEOUT) {
01224 perror("read failed, timeout");
01225 exit(1);
01226 }
01227 char temp[256];
01228 snprintf(temp, sizeof(temp), "ccn_fetch_read failed: %d", nb);
01229 perror(temp);
01230 return -1;
01231 }
01232 }
01233 ccn_fetch_close(fs);
01234 }
01235
01236 gettimeofday(&parms->stopTime, 0);
01237
01238 if (file != NULL)
01239 fclose(file);
01240
01241 ccn_fetch_destroy(cf);
01242
01243 ccn_destroy(&ccn);
01244 ccn_charbuf_destroy(&cb);
01245 ccn_charbuf_destroy(&nm);
01246
01247 formatStats(parms);
01248
01249 if (res > 0) res = 0;
01250 return res;
01251 }
01252
01253 static int
01254 putFile(struct SyncTestParms *parms, char *src, char *dst) {
01255
01256
01257 struct stat myStat;
01258 int res = stat(src, &myStat);
01259 if (res < 0) {
01260 perror("putFile failed, stat");
01261 return -1;
01262 }
01263 off_t fSize = myStat.st_size;
01264
01265 if (fSize == 0) {
01266 return noteErr("stat failed, empty src");
01267 }
01268 FILE *file = fopen(src, "r");
01269 if (file == NULL) {
01270 perror("putFile failed, fopen");
01271 return -1;
01272 }
01273
01274 struct ccn *ccn = NULL;
01275 ccn = ccn_create();
01276 if (ccn_connect(ccn, NULL) == -1) {
01277 return noteErr("Could not connect to ccnd");
01278 }
01279 struct ccn_charbuf *cb = ccn_charbuf_create();
01280 struct ccn_charbuf *nm = ccn_charbuf_create();
01281 struct ccn_charbuf *cmd = ccn_charbuf_create();
01282 int bs = parms->blockSize;
01283
01284 res = ccn_name_from_uri(nm, dst);
01285 if (res < 0) {
01286 return noteErr("ccn_name_from_uri failed");
01287 }
01288 ccn_create_version(ccn, nm, CCN_V_NOW, 0, 0);
01289
01290 struct storeFileStruct *sfData = NEW_STRUCT(1, storeFileStruct);
01291 sfData->parms = parms;
01292 sfData->file = file;
01293 sfData->bs = bs;
01294 sfData->nm = nm;
01295 sfData->cb = cb;
01296 sfData->ccn = ccn;
01297 sfData->fSize = fSize;
01298 sfData->nSegs = (fSize + bs -1) / bs;
01299 sfData->segData = NEW_ANY(sfData->nSegs, unsigned char);
01300
01301 struct ccn_charbuf *template = SyncGenInterest(NULL,
01302 parms->scope,
01303 parms->life,
01304 -1, -1, NULL);
01305 struct ccn_closure *action = NEW_STRUCT(1, ccn_closure);
01306 action->p = storeHandler;
01307 action->data = sfData;
01308
01309 parms->fSize = fSize;
01310
01311
01312 res = ccn_set_interest_filter(ccn, nm, action);
01313 if (res < 0) {
01314 return noteErr("ccn_set_interest_filter failed");
01315 }
01316 ccn_run(ccn, 40);
01317
01318
01319 ccn_charbuf_append_charbuf(cmd, nm);
01320 ccn_name_from_uri(cmd, "%C1.R.sw");
01321 ccn_name_append_nonce(cmd);
01322
01323 if (parms->verbose) {
01324 if (parms->mark) putMark(stdout);
01325 fprintf(stdout, "put init, %s\n",
01326 ccn_charbuf_as_string(cmd));
01327 }
01328 gettimeofday(&parms->startTime, 0);
01329 ccn_get(ccn, cmd, template, 6000, NULL, NULL, NULL, 0);
01330
01331
01332 while (sfData->stored < sfData->nSegs) {
01333 ccn_run(ccn, 2);
01334 }
01335
01336 gettimeofday(&parms->stopTime, 0);
01337
01338 res = ccn_set_interest_filter(ccn, nm, NULL);
01339 if (res < 0) {
01340 return noteErr("ccn_set_interest_filter failed (removal)");
01341 }
01342 ccn_run(ccn, 40);
01343
01344 free(sfData->segData);
01345 free(sfData);
01346 ccn_destroy(&ccn);
01347 fclose(file);
01348 ccn_charbuf_destroy(&cb);
01349 ccn_charbuf_destroy(&cmd);
01350 ccn_charbuf_destroy(&nm);
01351
01352 formatStats(parms);
01353
01354 if (res > 0) res = 0;
01355 return res;
01356 }
01357
01358 static int
01359 existingRootOp(struct SyncTestParms *parms,
01360 char *topo, char *prefix,
01361 int delete) {
01362
01363
01364 struct ccn *ccn = NULL;
01365 int res = 0;
01366
01367 ccn = ccn_create();
01368 if (ccn_connect(ccn, NULL) == -1) {
01369 perror("Could not connect to ccnd");
01370 exit(1);
01371 }
01372
01373
01374 static char *cmdLit = "\xC1.S.rs";
01375 struct ccn_charbuf *nm = ccn_charbuf_create();
01376 if (delete) cmdLit = "\xC1.S.cs";
01377
01378 res |= ccn_name_init(nm);
01379 res |= ccn_name_from_uri(nm, topo);
01380 if (prefix != NULL) {
01381 struct ccn_charbuf *pre = ccn_charbuf_create();
01382 res |= ccn_name_from_uri(pre, prefix);
01383 res |= ccn_name_append_str(nm, cmdLit);
01384 res |= SyncAppendAllComponents(nm, pre);
01385 ccn_charbuf_destroy(&pre);
01386 }
01387
01388 struct ccn_charbuf *cb = ccn_charbuf_create();
01389 if (delete) {
01390
01391 res |= localStore(ccn, nm, NULL);
01392 if (res < 0) {
01393 res = noteErr("requestDelete, failed");
01394 } else {
01395
01396 struct ccn_charbuf *uri = SyncUriForName(nm);
01397 if (parms->mark) putMark(stdout);
01398 fprintf(stdout, "requestDelete, sent %s\n",
01399 ccn_charbuf_as_string(uri));
01400 ccn_charbuf_destroy(&uri);
01401 }
01402 } else {
01403
01404 struct ccn_charbuf *tmpl = SyncGenInterest(NULL, 1, 2, -1, 1, NULL);
01405 res |= ccn_get(ccn, nm, tmpl, 6000, cb, NULL, NULL, 0);
01406
01407 const unsigned char *xp = NULL;
01408 size_t xs = 0;
01409 if (res < 0) {
01410 res = noteErr("requestStats, ccn_get failed");
01411 } else {
01412 res |= SyncPointerToContent(cb, NULL, &xp, &xs);
01413
01414 if (res < 0 || xs == 0) {
01415 res = noteErr("requestStats, failed");
01416 } else {
01417 if (parms->mark) putMark(stdout);
01418 fwrite(xp, xs, sizeof(char), stdout);
01419 fprintf(stdout, "\n");
01420 }
01421 }
01422 ccn_charbuf_destroy(&tmpl);
01423 }
01424 ccn_charbuf_destroy(&cb);
01425 ccn_charbuf_destroy(&nm);
01426 ccn_destroy(&ccn);
01427 if (res > 0) res = 0;
01428 return res;
01429 }
01430
01431 int
01432 main(int argc, char **argv) {
01433 int i = 1;
01434 int seen = 0;
01435 int res = 0;
01436 struct SyncTestParms parmStore;
01437 struct SyncTestParms *parms = &parmStore;
01438 struct SyncBaseStruct *base = SyncNewBase(NULL, NULL, NULL);
01439
01440 memset(parms, 0, sizeof(parmStore));
01441
01442 parms->mode = 1;
01443 parms->scope = 1;
01444 parms->life = 4;
01445 parms->bufs = 4;
01446 parms->blockSize = 4096;
01447 parms->base = base;
01448 parms->resolve = 1;
01449 parms->segmented = 1;
01450 parms->topoPrefix = "/Topo";
01451 parms->namingPrefix = "/Naming";
01452
01453 while (i < argc && res >= 0) {
01454 char * sw = argv[i];
01455 i++;
01456 char *arg1 = NULL;
01457 char *arg2 = NULL;
01458 if (i < argc) arg1 = argv[i];
01459 if (i+1 < argc) arg2 = argv[i+1];
01460 if (strcasecmp(sw, "-debug") == 0 || strcasecmp(sw, "-d") == 0) {
01461 i++;
01462 base->debug = ccnr_msg_level_from_string(arg1);
01463 if (base->debug < 0) {
01464 res = noteErr("invalid debug level %s", arg1);
01465 }
01466 } else if (strcasecmp(sw, "-v") == 0) {
01467 parms->verbose = 1;
01468 } else if (strcasecmp(sw, "-cat2") == 0) {
01469 parms->mode = 3;
01470 } else if (strcasecmp(sw, "-mark") == 0) {
01471 parms->mark = 1;
01472 } else if (strcasecmp(sw, "-null") == 0) {
01473 parms->mode = 0;
01474 } else if (strcasecmp(sw, "-binary") == 0) {
01475 parms->mode = 1;
01476 } else if (strcasecmp(sw, "-ccnb") == 0) {
01477 parms->mode = 1;
01478 } else if (strcasecmp(sw, "-text") == 0) {
01479 parms->mode = 2;
01480 } else if (strcasecmp(sw, "-nores") == 0) {
01481 parms->resolve = 0;
01482 } else if (strcasecmp(sw, "-noseg") == 0) {
01483 parms->segmented = 0;
01484 } else if (strcasecmp(sw, "-bs") == 0) {
01485 i++;
01486 if (arg1 != NULL) {
01487 int bs = atoi(arg1);
01488 if (bs <= 0 || bs > 64*1024) {
01489 res = noteErr("invalid block size %s", arg1);
01490 }
01491 parms->blockSize = bs;
01492 } else
01493 res = noteErr("missing block size");
01494 seen++;
01495 } else if (strcasecmp(sw, "-bufs") == 0) {
01496 if (arg1 != NULL) {
01497 i++;
01498 int bufs = atoi(arg1);
01499 if (bufs <= 0 || bufs > 1024) {
01500 res = noteErr("invalid number of buffers %s", arg1);
01501 break;
01502 }
01503 parms->bufs = bufs;
01504 } else
01505 res = noteErr("missing number of buffers");
01506 } else if (strcasecmp(sw, "-scope") == 0) {
01507 if (arg1 != NULL) {
01508 int scope = atoi(arg1);
01509 if (scope < -1 || scope > 2) {
01510 res = noteErr("invalid scope %s", arg1);
01511 break;
01512 }
01513 parms->scope = scope;
01514 i++;
01515 } else
01516 res = noteErr("missing scope");
01517 seen++;
01518 } else if (strcasecmp(sw, "-life") == 0) {
01519 if (arg1 != NULL) {
01520 int life = atoi(arg1);
01521 if (life < -1 || life > 30) {
01522 res = noteErr("invalid interest lifetime %s", arg1);
01523 break;
01524 }
01525 parms->life = life;
01526 i++;
01527 } else
01528 res = noteErr("missing interest lifetime");
01529 seen++;
01530 } else if (strcasecmp(sw, "-basic") == 0) {
01531 res = testRootBasic(parms);
01532 seen++;
01533 } else if (strcasecmp(sw, "-topo") == 0) {
01534 if (arg1 != NULL) {
01535 parms->topoPrefix = arg1;
01536 i++;
01537 } else
01538 res = noteErr("missing topo prefix");
01539 seen++;
01540 } else if (strcasecmp(sw, "-prefix") == 0) {
01541 if (arg1 != NULL) {
01542 parms->namingPrefix = arg1;
01543 i++;
01544 } else
01545 res = noteErr("missing naming prefix");
01546 seen++;
01547 } else if (strcasecmp(sw, "-target") == 0) {
01548 if (arg1 != NULL) {
01549 parms->target = arg1;
01550 i++;
01551 } else
01552 res = noteErr("missing target");
01553 seen++;
01554 } else if (strcasecmp(sw, "-build") == 0) {
01555 if (arg1 != NULL) {
01556 i++;
01557 parms->inputName = arg1;
01558 res = testReadBuilder(parms);
01559 } else
01560 res = noteErr("missing file name");
01561 seen++;
01562 } else if (strcasecmp(sw, "-read") == 0) {
01563 if (arg1 != NULL) {
01564 i++;
01565 parms->inputName = arg1;
01566 parms->sort = 0;
01567 res = testReader(parms);
01568 } else
01569 res = noteErr("missing file name");
01570 seen++;
01571 } else if (strcasecmp(sw, "-sort") == 0) {
01572 if (arg1 != NULL) {
01573 i++;
01574 parms->inputName = arg1;
01575 parms->sort = 1;
01576 res = testReader(parms);
01577 } else
01578 res = noteErr("missing file name");
01579 seen++;
01580 } else if (strcasecmp(sw, "-abs") == 0) {
01581 if (arg1 != NULL) {
01582 i++;
01583 parms->inputName = arg1;
01584 parms->sort = 2;
01585 res = testReader(parms);
01586 } else
01587 res = noteErr("missing file name");
01588 seen++;
01589 } else if (strcasecmp(sw, "-splits") == 0) {
01590 int n = 0;
01591 while (i >= argc) {
01592 char *x = argv[i];
01593 char c = x[0];
01594 if (c < '0' || c > '9') break;
01595 n++;
01596 i++;
01597 }
01598 parms->nSplits = n;
01599 if (parms->splits != NULL) free(parms->splits);
01600 parms->splits = NULL;
01601 if (n > 0) {
01602 int j = 0;
01603 parms->splits = NEW_ANY(n, int);
01604 i = i - n;
01605 while (j < n) {
01606 parms->splits[j] = atoi(argv[i]);
01607 i++;
01608 j++;
01609 }
01610 }
01611 seen++;
01612 } else if (strcasecmp(sw, "-encode") == 0) {
01613 res = testEncodeDecode(parms);
01614 seen++;
01615 } else if (strcasecmp(sw, "-slice") == 0) {
01616 char **clauses = NEW_ANY(argc, char *);
01617 int count = 0;
01618 if (arg1 != NULL && arg2 != NULL) {
01619 i++;
01620 i++;
01621 while (i < argc) {
01622 char *clause = argv[i];
01623 if (clause[0] == '-' || clause[0] == 0) break;
01624 i++;
01625 clauses[count] = clause;
01626 count++;
01627 }
01628 res = sendSlice(parms, arg1, arg2, count, clauses);
01629 } else
01630 res = noteErr("missing slice topo or prefix");
01631 seen++;
01632 } else if (strcasecmp(sw, "-get") == 0) {
01633 if (arg1 != NULL) {
01634 i++;
01635 if (arg2 != NULL) {
01636
01637 if (arg2[0] != '-') i++;
01638 else arg2 = NULL;
01639 }
01640 res = getFile(parms, arg1, arg2);
01641 } else {
01642 res = noteErr("missing src file");
01643 }
01644 seen++;
01645 } else if (strcasecmp(sw, "-put") == 0) {
01646 if (arg1 == NULL) {
01647 res = noteErr("missing src file");
01648 } else if (arg2 == NULL) {
01649 res = noteErr("missing dst file");
01650 } else {
01651 i++;
01652 i++;
01653 res = putFile(parms, arg1, arg2);
01654 }
01655 seen++;
01656 } else if (strcasecmp(sw, "-stats") == 0) {
01657 if (arg1 != NULL && arg2 != NULL) {
01658 i++;
01659 i++;
01660 res = existingRootOp(parms, arg1, arg2, 0);
01661 } else
01662 res = noteErr("missing topo or hash");
01663 seen++;
01664 } else if (strcasecmp(sw, "-delete") == 0) {
01665 if (arg1 != NULL && arg2 != NULL) {
01666 i++;
01667 i++;
01668 res = existingRootOp(parms, arg1, arg2, 1);
01669 } else
01670 res = noteErr("missing topo or hash");
01671 seen++;
01672 } else {
01673
01674 noteErr("invalid switch: %s", sw);
01675 seen = 0;
01676 break;
01677 }
01678 }
01679 if (parms->splits != NULL) free(parms->splits);
01680 if (parms->root != NULL) SyncRemRoot(parms->root);
01681 SyncFreeBase(&base);
01682 if (seen == 0 && res >= 0) {
01683 printf("usage: \n");
01684 printf(" -debug S set debug level {NONE, SEVERE, ERROR, WARNING, INFO, FINE, FINER, FINEST}\n");
01685 printf(" -v verbose\n");
01686 printf(" -null no output\n");
01687 printf(" -ccnb use binary output\n");
01688 printf(" -binary use binary output\n");
01689 printf(" -text use text output\n");
01690 printf(" -cat2 use ccncatchunks2 format\n");
01691 printf(" -mark print a time code prefix\n");
01692 printf(" -nores avoid resolve version\n");
01693 printf(" -noseg no segments\n");
01694 printf(" -scope N scope=N for repo commands (default 1)\n");
01695 printf(" -life N life=N for interests (default 4)\n");
01696 printf(" -bs N set block size for put (default 4096)\n");
01697 printf(" -bufs N number of buffers for get (default 4)\n");
01698 printf(" -topo T set default topo prefix to T\n");
01699 printf(" -prefix P set default naming prefix to P\n");
01700 printf(" -basic some very basic tests\n");
01701 printf(" -read F read names from file F\n");
01702 printf(" -sort F read names from file F, sort them\n");
01703 printf(" -encode simple encode/decode test\n");
01704 printf(" -build F build tree from file F\n");
01705 printf(" -get src [dst] src is uri in repo, dst is file name (optional)\n");
01706 printf(" -put src dst src is file name, dst is uri in repo\n");
01707 printf(" -slice T P C* topo, prefix, clause ... (send slice to repo)\n");
01708 printf(" -delete T H delete root with topo T, hash H from the repo\n");
01709 printf(" -stats T H print statistics for root with topo T, hash H\n");
01710 }
01711 return res;
01712 }