Fossil

Check-in [0fe1771a76]
Login

Check-in [0fe1771a76]

Many hyperlinks are disabled.
Use anonymous login to enable hyperlinks.

Overview
Comment:Phase 4, simplify usage of TH1 hooks and make more consistent. Assume that the common transfer TH1 script is idempotent.
Downloads: Tarball | ZIP archive
Timelines: family | ancestors | descendants | both | tkt-change-hook
Files: files | file ages | folders
SHA1: 0fe1771a766c19a1f5103f3db1fb7e68032ba199
User & Date: mistachkin 2013-10-14 08:19:25.480
Context
2013-10-14
08:20
Rename the HTTP header variable used by httpCmd back to hdr for consistency with other code. ... (check-in: e44932b12c user: mistachkin tags: tkt-change-hook)
08:19
Phase 4, simplify usage of TH1 hooks and make more consistent. Assume that the common transfer TH1 script is idempotent. ... (check-in: 0fe1771a76 user: mistachkin tags: tkt-change-hook)
07:08
Phase 3, the TH1 http command now uses non-global URL data. This also required heavy refactoring of some other callers that use the global URL data. ... (check-in: 8ce9c1af8f user: mistachkin tags: tkt-change-hook)
Changes
Unified Diff Ignore Whitespace Patch
Changes to src/branch.c.
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
  }

  brid = content_put_ex(&branch, 0, 0, 0, isPrivate);
  if( brid==0 ){
    fossil_fatal("trouble committing manifest: %s", g.zErrMsg);
  }
  db_multi_exec("INSERT OR IGNORE INTO unsent VALUES(%d)", brid);
  run_common_script();
  if( manifest_crosslink(brid, &branch)==0 ){
    fossil_fatal("%s\n", g.zErrMsg);
  }
  assert( blob_is_reset(&branch) );
  content_deltify(rootid, brid, 0);
  zUuid = db_text(0, "SELECT uuid FROM blob WHERE rid=%d", brid);
  fossil_print("New branch: %s\n", zUuid);







|







151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
  }

  brid = content_put_ex(&branch, 0, 0, 0, isPrivate);
  if( brid==0 ){
    fossil_fatal("trouble committing manifest: %s", g.zErrMsg);
  }
  db_multi_exec("INSERT OR IGNORE INTO unsent VALUES(%d)", brid);
  xfer_run_common_script();
  if( manifest_crosslink(brid, &branch)==0 ){
    fossil_fatal("%s\n", g.zErrMsg);
  }
  assert( blob_is_reset(&branch) );
  content_deltify(rootid, brid, 0);
  zUuid = db_text(0, "SELECT uuid FROM blob WHERE rid=%d", brid);
  fossil_print("New branch: %s\n", zUuid);
Changes to src/checkin.c.
1805
1806
1807
1808
1809
1810
1811
1812
1813
1814
1815
1816
1817
1818
1819

  nvid = content_put(&manifest);
  if( nvid==0 ){
    fossil_fatal("trouble committing manifest: %s", g.zErrMsg);
  }
  db_multi_exec("INSERT OR IGNORE INTO unsent VALUES(%d)", nvid);
  if( !dryRunFlag ){
    run_common_script();
    if( manifest_crosslink(nvid, &manifest)==0 ){
      fossil_fatal("%s\n", g.zErrMsg);
    }
  }
  assert( blob_is_reset(&manifest) );
  content_deltify(vid, nvid, 0);
  zUuid = db_text(0, "SELECT uuid FROM blob WHERE rid=%d", nvid);







|







1805
1806
1807
1808
1809
1810
1811
1812
1813
1814
1815
1816
1817
1818
1819

  nvid = content_put(&manifest);
  if( nvid==0 ){
    fossil_fatal("trouble committing manifest: %s", g.zErrMsg);
  }
  db_multi_exec("INSERT OR IGNORE INTO unsent VALUES(%d)", nvid);
  if( !dryRunFlag ){
    xfer_run_common_script();
    if( manifest_crosslink(nvid, &manifest)==0 ){
      fossil_fatal("%s\n", g.zErrMsg);
    }
  }
  assert( blob_is_reset(&manifest) );
  content_deltify(vid, nvid, 0);
  zUuid = db_text(0, "SELECT uuid FROM blob WHERE rid=%d", nvid);
Changes to src/info.c.
2176
2177
2178
2179
2180
2181
2182
2183
2184
2185
2186
2187
2188
2189
2190
      Blob cksum;
      blob_appendf(&ctrl, "U %F\n", g.zLogin);
      md5sum_blob(&ctrl, &cksum);
      blob_appendf(&ctrl, "Z %b\n", &cksum);
      db_begin_transaction();
      g.markPrivate = content_is_private(rid);
      nrid = content_put(&ctrl);
      run_common_script();
      manifest_crosslink(nrid, &ctrl);
      assert( blob_is_reset(&ctrl) );
      db_end_transaction(0);
    }
    cgi_redirectf("ci?name=%s", zUuid);
  }
  blob_zero(&comment);







|







2176
2177
2178
2179
2180
2181
2182
2183
2184
2185
2186
2187
2188
2189
2190
      Blob cksum;
      blob_appendf(&ctrl, "U %F\n", g.zLogin);
      md5sum_blob(&ctrl, &cksum);
      blob_appendf(&ctrl, "Z %b\n", &cksum);
      db_begin_transaction();
      g.markPrivate = content_is_private(rid);
      nrid = content_put(&ctrl);
      xfer_run_common_script();
      manifest_crosslink(nrid, &ctrl);
      assert( blob_is_reset(&ctrl) );
      db_end_transaction(0);
    }
    cgi_redirectf("ci?name=%s", zUuid);
  }
  blob_zero(&comment);
Changes to src/json_branch.c.
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
  blob_appendf(&branch, "Z %b\n", &mcksum);

  brid = content_put(&branch);
  if( brid==0 ){
    fossil_fatal("Problem committing manifest: %s", g.zErrMsg);
  }
  db_multi_exec("INSERT OR IGNORE INTO unsent VALUES(%d)", brid);
  run_common_script();
  if( manifest_crosslink(brid, &branch)==0 ){
    fossil_fatal("%s\n", g.zErrMsg);
  }
  assert( blob_is_reset(&branch) );
  content_deltify(rootid, brid, 0);
  if( zNewRid ){
    *zNewRid = brid;







|







289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
  blob_appendf(&branch, "Z %b\n", &mcksum);

  brid = content_put(&branch);
  if( brid==0 ){
    fossil_fatal("Problem committing manifest: %s", g.zErrMsg);
  }
  db_multi_exec("INSERT OR IGNORE INTO unsent VALUES(%d)", brid);
  xfer_run_common_script();
  if( manifest_crosslink(brid, &branch)==0 ){
    fossil_fatal("%s\n", g.zErrMsg);
  }
  assert( blob_is_reset(&branch) );
  content_deltify(rootid, brid, 0);
  if( zNewRid ){
    *zNewRid = brid;
Changes to src/manifest.c.
1649
1650
1651
1652
1653
1654
1655
1656
1657
1658
1659
1660
1661
1662
1663
1664
1665
1666
1667
**
** Historical note:  This routine original processed manifests only.
** Processing for other control artifacts was added later.  The name
** of the routine, "manifest_crosslink", and the name of this source
** file, is a legacy of its original use.
*/
int manifest_crosslink(int rid, Blob *pContent){
  int i;
  Manifest *p;
  Stmt q;
  int parentid = 0;
  const char *hook = 0;
  const char *zUuid = 0;

  if( (p = manifest_cache_find(rid))!=0 ){
    blob_reset(pContent);
  }else if( (p = manifest_parse(pContent, rid, 0))==0 ){
    assert( blob_is_reset(pContent) || pContent==0 );
    fossil_error(1, "syntax error in manifest");







|



|







1649
1650
1651
1652
1653
1654
1655
1656
1657
1658
1659
1660
1661
1662
1663
1664
1665
1666
1667
**
** Historical note:  This routine original processed manifests only.
** Processing for other control artifacts was added later.  The name
** of the routine, "manifest_crosslink", and the name of this source
** file, is a legacy of its original use.
*/
int manifest_crosslink(int rid, Blob *pContent){
  int i, result;
  Manifest *p;
  Stmt q;
  int parentid = 0;
  const char *zScript = 0;
  const char *zUuid = 0;

  if( (p = manifest_cache_find(rid))!=0 ){
    blob_reset(pContent);
  }else if( (p = manifest_parse(pContent, rid, 0))==0 ){
    assert( blob_is_reset(pContent) || pContent==0 );
    fossil_error(1, "syntax error in manifest");
1677
1678
1679
1680
1681
1682
1683
1684
1685
1686
1687
1688
1689
1690
1691
    manifest_destroy(p);
    assert( blob_is_reset(pContent) );
    fossil_error(1, "cannot fetch baseline manifest");
    return 0;
  }
  db_begin_transaction();
  if( p->type==CFTYPE_MANIFEST ){
    hook = "xfer-commit-script";
    zUuid = db_text(0, "SELECT uuid FROM blob WHERE rid=%d", rid);
    if( !db_exists("SELECT 1 FROM mlink WHERE mid=%d", rid) ){
      char *zCom;
      for(i=0; i<p->nParent; i++){
        int pid = uuid_to_rid(p->azParent[i], 1);
        db_multi_exec("INSERT OR IGNORE INTO plink(pid, cid, isprim, mtime)"
                      "VALUES(%d, %d, %d, %.17g)", pid, rid, i==0, p->rDate);







|







1677
1678
1679
1680
1681
1682
1683
1684
1685
1686
1687
1688
1689
1690
1691
    manifest_destroy(p);
    assert( blob_is_reset(pContent) );
    fossil_error(1, "cannot fetch baseline manifest");
    return 0;
  }
  db_begin_transaction();
  if( p->type==CFTYPE_MANIFEST ){
    zScript = xfer_commit_code();
    zUuid = db_text(0, "SELECT uuid FROM blob WHERE rid=%d", rid);
    if( !db_exists("SELECT 1 FROM mlink WHERE mid=%d", rid) ){
      char *zCom;
      for(i=0; i<p->nParent; i++){
        int pid = uuid_to_rid(p->azParent[i], 1);
        db_multi_exec("INSERT OR IGNORE INTO plink(pid, cid, isprim, mtime)"
                      "VALUES(%d, %d, %d, %.17g)", pid, rid, i==0, p->rDate);
1875
1876
1877
1878
1879
1880
1881
1882
1883
1884
1885
1886
1887
1888
1889
        TAG_BGCOLOR, rid
      );
    }
  }
  if( p->type==CFTYPE_TICKET ){
    char *zTag;

    hook = "xfer-ticket-script";
    zUuid = p->zTicketUuid;
    assert( manifest_crosslink_busy==1 );
    zTag = mprintf("tkt-%s", p->zTicketUuid);
    tag_insert(zTag, 1, 0, rid, p->rDate, rid);
    free(zTag);
    db_multi_exec("INSERT OR IGNORE INTO pending_tkt VALUES(%Q)",
                  p->zTicketUuid);







|







1875
1876
1877
1878
1879
1880
1881
1882
1883
1884
1885
1886
1887
1888
1889
        TAG_BGCOLOR, rid
      );
    }
  }
  if( p->type==CFTYPE_TICKET ){
    char *zTag;

    zScript = xfer_ticket_code();
    zUuid = p->zTicketUuid;
    assert( manifest_crosslink_busy==1 );
    zTag = mprintf("tkt-%s", p->zTicketUuid);
    tag_insert(zTag, 1, 0, rid, p->rDate, rid);
    free(zTag);
    db_multi_exec("INSERT OR IGNORE INTO pending_tkt VALUES(%Q)",
                  p->zTicketUuid);
2028
2029
2030
2031
2032
2033
2034
2035
2036
2037
2038
2039
2040
2041
2042
2043
2044
2045
2046
2047
2048
2049
      "REPLACE INTO event(type,mtime,objid,user,comment)"
      "VALUES('g',%.17g,%d,%Q,%Q)",
      p->rDate, rid, p->zUser, blob_str(&comment)+1
    );
    blob_reset(&comment);
  }
  db_end_transaction(0);
  i = run_script(hook, zUuid)==0;
  if( p->type==CFTYPE_MANIFEST ){
    manifest_cache_insert(p);
  }else{
    manifest_destroy(p);
  }
  assert( blob_is_reset(pContent) );
  return i;
}

/*
** COMMAND: test-crosslink
**
** Usage:  %fossil test-crosslink RECORDID
**







|






|







2028
2029
2030
2031
2032
2033
2034
2035
2036
2037
2038
2039
2040
2041
2042
2043
2044
2045
2046
2047
2048
2049
      "REPLACE INTO event(type,mtime,objid,user,comment)"
      "VALUES('g',%.17g,%d,%Q,%Q)",
      p->rDate, rid, p->zUser, blob_str(&comment)+1
    );
    blob_reset(&comment);
  }
  db_end_transaction(0);
  result = (xfer_run_script(zScript, zUuid)==TH_OK);
  if( p->type==CFTYPE_MANIFEST ){
    manifest_cache_insert(p);
  }else{
    manifest_destroy(p);
  }
  assert( blob_is_reset(pContent) );
  return result;
}

/*
** COMMAND: test-crosslink
**
** Usage:  %fossil test-crosslink RECORDID
**
Changes to src/tag.c.
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
  }else{
    blob_appendf(&ctrl, "\n");
  }
  blob_appendf(&ctrl, "U %F\n", zUserOvrd ? zUserOvrd : g.zLogin);
  md5sum_blob(&ctrl, &cksum);
  blob_appendf(&ctrl, "Z %b\n", &cksum);
  nrid = content_put(&ctrl);
  run_common_script();
  manifest_crosslink(nrid, &ctrl);
  assert( blob_is_reset(&ctrl) );
}

/*
** COMMAND: tag
** Usage: %fossil tag SUBCOMMAND ...







|







324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
  }else{
    blob_appendf(&ctrl, "\n");
  }
  blob_appendf(&ctrl, "U %F\n", zUserOvrd ? zUserOvrd : g.zLogin);
  md5sum_blob(&ctrl, &cksum);
  blob_appendf(&ctrl, "Z %b\n", &cksum);
  nrid = content_put(&ctrl);
  xfer_run_common_script();
  manifest_crosslink(nrid, &ctrl);
  assert( blob_is_reset(&ctrl) );
}

/*
** COMMAND: tag
** Usage: %fossil tag SUBCOMMAND ...
Changes to src/tkt.c.
532
533
534
535
536
537
538

539
540
541
542
543
544
545
      rid, zTktId
    );
  }else{
    db_multi_exec("INSERT OR IGNORE INTO unsent VALUES(%d);", rid);
    db_multi_exec("INSERT OR IGNORE INTO unclustered VALUES(%d);", rid);
  }
  manifest_crosslink_begin();

  result = manifest_crosslink(rid, pTicket)==0;
  assert( blob_is_reset(pTicket) );
  manifest_crosslink_end();
  return result;
}

/*







>







532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
      rid, zTktId
    );
  }else{
    db_multi_exec("INSERT OR IGNORE INTO unsent VALUES(%d);", rid);
    db_multi_exec("INSERT OR IGNORE INTO unclustered VALUES(%d);", rid);
  }
  manifest_crosslink_begin();
  xfer_run_common_script();
  result = manifest_crosslink(rid, pTicket)==0;
  assert( blob_is_reset(pTicket) );
  manifest_crosslink_end();
  return result;
}

/*
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
    cgi_redirect(mprintf("%s/tktview/%s", g.zTop, zNewUuid));
    return;
  }
  captcha_generate(0);
  @ </form>
  if( g.thTrace ) Th_Trace("END_TKTVIEW<br />\n", -1);
  style_footer();
  run_common_script();
  run_script("xfer-ticket-script", zNewUuid);
}

/*
** WEBPAGE: tktedit
** WEBPAGE: debug_tktedit
**
** Edit a ticket.  The ticket is identified by the name CGI parameter.







|
|







681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
    cgi_redirect(mprintf("%s/tktview/%s", g.zTop, zNewUuid));
    return;
  }
  captcha_generate(0);
  @ </form>
  if( g.thTrace ) Th_Trace("END_TKTVIEW<br />\n", -1);
  style_footer();
  xfer_run_common_script();
  xfer_run_script(xfer_ticket_code(), zNewUuid);
}

/*
** WEBPAGE: tktedit
** WEBPAGE: debug_tktedit
**
** Edit a ticket.  The ticket is identified by the name CGI parameter.
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
    cgi_redirect(mprintf("%s/tktview/%s", g.zTop, zName));
    return;
  }
  captcha_generate(0);
  @ </form>
  if( g.thTrace ) Th_Trace("BEGIN_TKTEDIT<br />\n", -1);
  style_footer();
  run_common_script();
  run_script("xfer-ticket-script", zName);
}

/*
** Check the ticket table schema in zSchema to see if it appears to
** be well-formed.  If everything is OK, return NULL.  If something is
** amiss, then return a pointer to a string (obtained from malloc) that
** describes the problem.







|
|







751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
    cgi_redirect(mprintf("%s/tktview/%s", g.zTop, zName));
    return;
  }
  captcha_generate(0);
  @ </form>
  if( g.thTrace ) Th_Trace("BEGIN_TKTEDIT<br />\n", -1);
  style_footer();
  xfer_run_common_script();
  xfer_run_script(xfer_ticket_code(), zName);
}

/*
** Check the ticket table schema in zSchema to see if it appears to
** be well-formed.  If everything is OK, return NULL.  If something is
** amiss, then return a pointer to a string (obtained from malloc) that
** describes the problem.
1347
1348
1349
1350
1351
1352
1353
1354
1355
1356
1357
1358
1359
1360
1361
1362
                       aField[i].zName, strlen(zValue), zValue);
        }
      }
      blob_appendf(&tktchng, "K %s\n", zTktUuid);
      blob_appendf(&tktchng, "U %F\n", zUser);
      md5sum_blob(&tktchng, &cksum);
      blob_appendf(&tktchng, "Z %b\n", &cksum);
      if( run_common_script() || ticket_put(&tktchng, zTktUuid, 0)){
        fossil_fatal("%s\n", g.zErrMsg);
      }else{
        fossil_print("ticket %s succeeded for %s\n",
             (eCmd==set?"set":"add"),zTktUuid);
      }
    }
  }
}







|








1348
1349
1350
1351
1352
1353
1354
1355
1356
1357
1358
1359
1360
1361
1362
1363
                       aField[i].zName, strlen(zValue), zValue);
        }
      }
      blob_appendf(&tktchng, "K %s\n", zTktUuid);
      blob_appendf(&tktchng, "U %F\n", zUser);
      md5sum_blob(&tktchng, &cksum);
      blob_appendf(&tktchng, "Z %b\n", &cksum);
      if( ticket_put(&tktchng, zTktUuid, 0) ){
        fossil_fatal("%s\n", g.zErrMsg);
      }else{
        fossil_print("ticket %s succeeded for %s\n",
             (eCmd==set?"set":"add"),zTktUuid);
      }
    }
  }
}
Changes to src/xfer.c.
817
818
819
820
821
822
823





824
825

826
827
828
829
830
831
832
833
834
835
836





837
838
839
840





841
842
843
844
845
846
847
848
849
850
851
852
853
854

855
856
857
858
859
860




861








862
863
864
865
866
867
868
** Called when there is an attempt to transfer private content to and
** from a server without authorization.
*/
static void server_private_xfer_not_authorized(void){
  @ error not\sauthorized\sto\ssync\sprivate\scontent
}






static int commonScriptRan = 0;


/*
** Run the specified TH1 script, if any, and returns 1 on error.
*/
int run_script(const char *zScript, const char *zUuid){
  int result = 0;
  if( !commonScriptRan || !zScript || !(zScript = db_get(zScript, 0))){
    return 0; /* No script or common script didn't run, return success. */
  }
  if( commonScriptRan == 1 ){
    if( zUuid ){
      Th_SetVar(g.interp, "uuid", -1, zUuid, strlen(zUuid));





    }
    result = Th_Eval(g.interp, 0, zScript, -1) != TH_OK;
  }else{
    result = TH_ERROR;





  }
  if (result) fossil_error(1, "%s", Th_GetResult(g.interp, 0));
  return result;
}

/*
** Run the pre-transfer TH1 script, if any, and returns the return code.
** Prepare the "http" command for use in other hook scripts.
*/
int run_common_script(void){
  int result = 0;
  if( !commonScriptRan ){
    Th_FossilInit(TH_INIT_DEFAULT); /* Make sure TH1 is ready. */
    commonScriptRan = 1; /* enable run_script to do something */

    result = run_script("xfer-common-script", 0);
    if( result == TH_ERROR ){
      /* Error message is left in th interpreter. */
      commonScriptRan = 2;
    }
  }




  return result;








}

/*
** If this variable is set, disable login checks.  Used for debugging
** only.
*/
static int disableLogin = 0;







>
>
>
>
>
|
|
>

|

|
<
|
<
|
|
<
<
>
>
>
>
>
|
|
<
<
>
>
>
>
>
|
<
<
|
<

|
<

|
|
|
|
<
>
|
|
|
|


>
>
>
>

>
>
>
>
>
>
>
>







817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835

836

837
838


839
840
841
842
843
844
845


846
847
848
849
850
851


852

853
854

855
856
857
858
859

860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
** Called when there is an attempt to transfer private content to and
** from a server without authorization.
*/
static void server_private_xfer_not_authorized(void){
  @ error not\sauthorized\sto\ssync\sprivate\scontent
}

/*
** Return the common TH1 code to evaluate prior to evaluating any other
** TH1 transfer notification scripts.
*/
const char *xfer_common_code(void){
  return db_get("xfer-common-script", 0);
}

/*
** Return the TH1 code to evaluate when a push is processed.
*/
const char *xfer_push_code(void){

  return db_get("xfer-push-script", 0);

}



/*
** Return the TH1 code to evaluate when a commit is processed.
*/
const char *xfer_commit_code(void){
  return db_get("xfer-commit-script", 0);
}



/*
** Return the TH1 code to evaluate when a ticket change is processed.
*/
const char *xfer_ticket_code(void){
  return db_get("xfer-ticket-script", 0);
}




/*
** Run the specified TH1 script, if any, and returns 1 on error.

*/
int xfer_run_script(const char *zScript, const char *zUuid){
  int result;
  if( !zScript ) return TH_OK;
  Th_FossilInit(TH_INIT_DEFAULT);

  if( zUuid ){
    result = Th_SetVar(g.interp, "uuid", -1, zUuid, -1);
    if( result!=TH_OK ){
      fossil_error(1, "%s", Th_GetResult(g.interp, 0));
      return result;
    }
  }
  result = Th_Eval(g.interp, 0, zScript, -1);
  if( result!=TH_OK ){
    fossil_error(1, "%s", Th_GetResult(g.interp, 0));
  }
  return result;
}

/*
** Runs the pre-transfer TH1 script, if any, and returns its return code.
*/
int xfer_run_common_script(void){
  Th_FossilInit(TH_INIT_DEFAULT);
  return xfer_run_script(xfer_common_code(), 0);
}

/*
** If this variable is set, disable login checks.  Used for debugging
** only.
*/
static int disableLogin = 0;
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
  g.xferPanic = 1;

  db_begin_transaction();
  db_multi_exec(
     "CREATE TEMP TABLE onremote(rid INTEGER PRIMARY KEY);"
  );
  manifest_crosslink_begin();
  if( run_common_script() ){
    cgi_reset_content();
    @ error common\sscript\sfailed:\s%F(Th_GetResult(g.interp, 0))
    nErr++;
  }
  while( blob_line(xfer.pIn, &xfer.line) ){
    if( blob_buffer(&xfer.line)[0]=='#' ) continue;
    if( blob_size(&xfer.line)==0 ) continue;







|







934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
  g.xferPanic = 1;

  db_begin_transaction();
  db_multi_exec(
     "CREATE TEMP TABLE onremote(rid INTEGER PRIMARY KEY);"
  );
  manifest_crosslink_begin();
  if( xfer_run_common_script()!=TH_OK ){
    cgi_reset_content();
    @ error common\sscript\sfailed:\s%F(Th_GetResult(g.interp, 0))
    nErr++;
  }
  while( blob_line(xfer.pIn, &xfer.line) ){
    if( blob_buffer(&xfer.line)[0]=='#' ) continue;
    if( blob_size(&xfer.line)==0 ) continue;
1243
1244
1245
1246
1247
1248
1249
1250
1251
1252
1253
1254
1255
1256
1257
      cgi_reset_content();
      @ error bad\scommand:\s%F(blob_str(&xfer.line))
    }
    blobarray_reset(xfer.aToken, xfer.nToken);
    blob_reset(&xfer.line);
  }
  if( isPush ){
    if( run_script("xfer-push-script", 0) ){
      cgi_reset_content();
      @ error push\sscript\sfailed:\s%F(g.zErrMsg)
      nErr++;
    }
    request_phantoms(&xfer, 500);
  }
  if( isClone && nGimme==0 ){







|







1261
1262
1263
1264
1265
1266
1267
1268
1269
1270
1271
1272
1273
1274
1275
      cgi_reset_content();
      @ error bad\scommand:\s%F(blob_str(&xfer.line))
    }
    blobarray_reset(xfer.aToken, xfer.nToken);
    blob_reset(&xfer.line);
  }
  if( isPush ){
    if( xfer_run_script(xfer_push_code(), 0)!=TH_OK ){
      cgi_reset_content();
      @ error push\sscript\sfailed:\s%F(g.zErrMsg)
      nErr++;
    }
    request_phantoms(&xfer, 500);
  }
  if( isClone && nGimme==0 ){