Fossil

Changes On Branch 12c53e1cb6f714bc
Login

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

Changes In Branch tkt-change-hook Through [12c53e1cb6] Excluding Merge-Ins

This is equivalent to a diff from 5c123de48c to 12c53e1cb6

2013-10-14
08:28
Fix compiler warnings. check-in: c932fa47ef user: mistachkin tags: trunk
2013-10-13
15:19
don't hardcode default value of "ticket-change" code check-in: 0e1f94732c user: jan.nijtmans tags: tkt-change-hook
15:13
Put back ticket-change in JSON part as well check-in: 12c53e1cb6 user: jan.nijtmans tags: tkt-change-hook
15:03
One more place where failing run_common_script() should not prevent running manifest_crosslink(). If run_common_script() fails, let the following run_script() output its error-message. check-in: cc5466b8d4 user: jan.nijtmans tags: tkt-change-hook
09:53
merge trunk check-in: a4327ba0b6 user: jan.nijtmans tags: tkt-change-hook
2013-10-11
20:19
Improved the help text for /reports. Started 1.28 changelog entries. check-in: 5c123de48c user: stephan tags: trunk
19:58
Added sub-submenu to /reports for selecting type of event to filter on. check-in: 3e915d420a user: stephan tags: trunk

Changes to src/branch.c.
151
152
153
154
155
156
157

158
159

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

160
161
162
163
164
165
166
167







+

-
+







  }

  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("unable to install new manifest");
    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);
  if( g.argc==3 ){
    fossil_print(
Changes to src/checkin.c.
1804
1805
1806
1807
1808
1809
1810


1811




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

1813
1814
1815
1816
1817
1818
1819
1820
1821
1822
1823







+
+
-
+
+
+
+







  }

  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();
  manifest_crosslink(nvid, &manifest);
    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);

  db_prepare(&q, "SELECT uuid,merge FROM vmerge JOIN blob ON merge=rid"
                 " WHERE id=-4");
  while( db_step(&q)==SQLITE_ROW ){
Changes to src/configure.c.
129
130
131
132
133
134
135


136
137
138
139
140
141
142
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144







+
+








  { "@concealed",             CONFIGSET_ADDR },

  { "@shun",                  CONFIGSET_SHUN },

  { "xfer-common-script",     CONFIGSET_XFER },
  { "xfer-push-script",       CONFIGSET_XFER },
  { "xfer-commit-script",     CONFIGSET_XFER },
  { "xfer-ticket-script",     CONFIGSET_XFER },

};
static int iConfig = 0;

/*
** Return name of first configuration property matching the given mask.
*/
Changes to src/db.c.
2119
2120
2121
2122
2123
2124
2125

2126
2127
2128
2129
2130
2131
2132
2119
2120
2121
2122
2123
2124
2125
2126
2127
2128
2129
2130
2131
2132
2133







+







  { "diff-command",  0,               40, 0, ""                    },
  { "dont-push",     0,                0, 0, "off"                 },
  { "editor",        0,               32, 0, ""                    },
  { "empty-dirs",    0,               40, 1, ""                    },
  { "encoding-glob",  0,              40, 1, ""                    },
  { "gdiff-command", 0,               40, 0, "gdiff"               },
  { "gmerge-command",0,               40, 0, ""                    },
  { "http-allow-regexp",0,            40, 0, ""                    },
  { "http-port",     0,               16, 0, "8080"                },
  { "https-login",   0,                0, 0, "off"                 },
  { "ignore-glob",   0,               40, 1, ""                    },
  { "keep-glob",     0,               40, 1, ""                    },
  { "localauth",     0,                0, 0, "off"                 },
  { "main-branch",   0,               40, 0, "trunk"               },
  { "manifest",      0,                0, 1, "off"                 },
2248
2249
2250
2251
2252
2253
2254




2255
2256
2257
2258
2259
2260
2261
2249
2250
2251
2252
2253
2254
2255
2256
2257
2258
2259
2260
2261
2262
2263
2264
2265
2266







+
+
+
+







**                     diff. If undefined, text diff will be used.
**
**    gmerge-command   A graphical merge conflict resolver command operating
**                     on four files.
**                     Ex: kdiff3 "%baseline" "%original" "%merge" -o "%output"
**                     Ex: xxdiff "%original" "%baseline" "%merge" -M "%output"
**                     Ex: meld "%baseline" "%original" "%merge" "%output"
**
**    http-allow-regexp Specify which URL's are allowed in http requests for
**                     commit and ticket hooks. If empty, no http requests
**                     are allowed whatsoever. Default: "".
**
**    http-port        The TCP/IP port number to use by the "server"
**                     and "ui" commands.  Default: 8080
**
**    https-login      Send login credentials using HTTPS instead of HTTP
**                     even if the login page request came via HTTP.
**
Changes to src/info.c.
2176
2177
2178
2179
2180
2181
2182

2183
2184
2185
2186
2187
2188
2189
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);
Changes to src/json_branch.c.
289
290
291
292
293
294
295

296
297

298
299
300
301
302
303
304
289
290
291
292
293
294
295
296
297

298
299
300
301
302
303
304
305







+

-
+







  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("unable to install new manifest");
    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.
1653
1654
1655
1656
1657
1658
1659


1660
1661
1662
1663
1664

1665
1666
1667
1668
1669

1670
1671
1672
1673
1674

1675
1676
1677
1678


1679
1680
1681
1682
1683
1684
1685
1653
1654
1655
1656
1657
1658
1659
1660
1661
1662
1663
1664
1665
1666
1667
1668
1669
1670
1671
1672
1673
1674
1675
1676
1677
1678
1679
1680
1681
1682
1683
1684
1685
1686
1687
1688
1689
1690
1691
1692







+
+





+





+





+




+
+







** 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");
    return 0;
  }
  if( g.xlinkClusterOnly && p->type!=CFTYPE_CLUSTER ){
    manifest_destroy(p);
    assert( blob_is_reset(pContent) );
    fossil_error(1, "no manifest");
    return 0;
  }
  if( p->type==CFTYPE_MANIFEST && fetch_baseline(p, 0) ){
    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);
        if( i==0 ){
1766
1767
1768
1769
1770
1771
1772
1773

1774
1775
1776
1777
1778
1779
1780
1773
1774
1775
1776
1777
1778
1779

1780
1781
1782
1783
1784
1785
1786
1787







-
+







      }
      if( tid ){
        switch( p->aTag[i].zName[0] ){
          case '-':  type = 0;  break;  /* Cancel prior occurrences */
          case '+':  type = 1;  break;  /* Apply to target only */
          case '*':  type = 2;  break;  /* Propagate to descendants */
          default:
            fossil_fatal("unknown tag type in manifest: %s", p->aTag);
            fossil_error(1, "unknown tag type in manifest: %s", p->aTag);
            return 0;
        }
        tag_insert(&p->aTag[i].zName[1], type, p->aTag[i].zValue, 
                   rid, p->rDate, tid);
      }
    }
    if( parentid ){
1868
1869
1870
1871
1872
1873
1874


1875
1876
1877
1878
1879
1880
1881
1875
1876
1877
1878
1879
1880
1881
1882
1883
1884
1885
1886
1887
1888
1889
1890







+
+







        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);
  }
2019
2020
2021
2022
2023
2024
2025

2026
2027
2028
2029
2030
2031
2032

2033
2034
2035
2036
2037
2038
2039
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 1;
  return i;
}

/*
** 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
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 ...
Changes to src/tkt.c.
322
323
324
325
326
327
328
329

330
331
332
333
334
335
336
322
323
324
325
326
327
328

329
330
331
332
333
334
335
336







-
+








/*
** Create the TH1 interpreter and load the "change" code.
*/
int ticket_change(void){
  const char *zConfig;
  Th_FossilInit(TH_INIT_DEFAULT);
  zConfig = ticket_change_code();
  zConfig = db_get("ticket-change", "return\n");
  return Th_Eval(g.interp, 0, zConfig, -1);
}

/*
** Recreate the TICKET and TICKETCHNG tables.
*/
void ticket_create_table(int separateConnection){
511
512
513
514
515
516
517
518

519
520
521
522

523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538

539
540

541
542
543
544
545
546
547
511
512
513
514
515
516
517

518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538

539
540
541
542
543
544
545
546
547
548
549







-
+




+















-
+


+







  aField[idx].zAppend = mprintf("%.*s", argl[2], argv[2]);
  return TH_OK;
}

/*
** Write a ticket into the repository.
*/
static void ticket_put(
static int ticket_put(
  Blob *pTicket,           /* The text of the ticket change record */
  const char *zTktId,      /* The ticket to which this change is applied */
  int needMod              /* True if moderation is needed */
){
  int result;
  int rid = content_put_ex(pTicket, 0, 0, 0, needMod);
  if( rid==0 ){
    fossil_fatal("trouble committing ticket: %s", g.zErrMsg);
  }
  if( needMod ){
    moderation_table_create();
    db_multi_exec(
      "INSERT INTO modreq(objid, tktid) VALUES(%d,'%s')",
      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();
  manifest_crosslink(rid, pTicket);
  result = manifest_crosslink(rid, pTicket)==0;
  assert( blob_is_reset(pTicket) );
  manifest_crosslink_end();
  return result;
}

/*
** Subscript command:   submit_ticket
**
** Construct and submit a new ticket artifact.  The fields of the artifact
** are the names of the columns in the TICKET table.  The content is
678
679
680
681
682
683
684


685
686
687
688
689
690
691
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.
746
747
748
749
750
751
752


753
754
755
756
757
758
759
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.
1341
1342
1343
1344
1345
1346
1347
1348
1349




1350

1351
1352
1353
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);
      ticket_put(&tktchng, zTktUuid, 0);
      printf("ticket %s succeeded for %s\n",
      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);
      }
    }
  }
}
Changes to src/xfer.c.
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
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
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915

916

917



918
919
920
921
922


923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938




939
940
941
942
943
944
945
946
947
948
949
950





951
952
953
954
955
956
957
958







+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+
-

-
-
-
+
+
+
+

-
-
+
+
+
+
+
+
+
+
+
+




+

-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
-
-
-
-
-
+







** from a server without authorization.
*/
static void server_private_xfer_not_authorized(void){
  @ error not\sauthorized\sto\ssync\sprivate\scontent
}

/*
** TH command:      http -async URL ?PAYLOAD?
**
** Do a HTTP request to specified URL. If PAYLOAD is present
** it will be POST'ed as text/plain, otherwise it's a GET
*/
static int httpCmd(
  Th_Interp *interp,
  void *p,
  int argc,
  const char **argv,
  int *argl
){
  int i;
  const char *zSep, *type, *regexp, *params;
  Blob hdr, payload;
  ReCompiled *pRe = 0;

  if( (argc>1) && strcmp(argv[1],"-async") ){
    Th_ErrorMessage(interp, "synchronous http requests not yet implemented", 0, 0);
    return TH_ERROR;
  }
  ++argv;
  --argc;
  blob_zero(&payload);
  if( argc!=2 ){
    if( argc != 3 ){
      return Th_WrongNumArgs(interp, "http -async url ?payload?");
    }
    blob_append(&payload, argv[2], -1);
    type = "POST";
  }else{
    type = "GET";
  }
  params = strrchr(argv[1], '?');
  url_parse(argv[1], 0);
  if( g.urlIsSsh || g.urlIsFile ){
    Th_ErrorMessage(interp, "url must be http:// or https://", 0, 0);
    return TH_ERROR;
  }
  regexp = db_get("http-allow-regexp", 0);
  if( regexp && regexp[0] ){
    const char * zErr = re_compile(&pRe, regexp, 0);
    if( zErr ){
      Th_SetResult(interp, zErr, -1);
      return TH_ERROR;
    }
  }
  if (!pRe || !re_match(pRe, (const unsigned char *)argv[1], -1) ){
    Th_SetResult(interp, "url not allowed", -1);
    return TH_ERROR;
  }
  re_free(pRe);
  if( transport_open() ){
    Th_ErrorMessage(interp, transport_errmsg(), 0, 0);
    return TH_ERROR;
  }
  blob_zero(&hdr);
  i = strlen(g.urlPath);
  if( (i>0) && (params!=argv[1]) ){
    zSep = "";
  }else{
    zSep = "/";
  }
  blob_appendf(&hdr, "%s %s%s%s HTTP/1.0\r\n", type, zSep, g.urlPath, params?params:"");
  if( g.urlProxyAuth ){
    blob_appendf(&hdr, "Proxy-Authorization: %s\r\n", g.urlProxyAuth);
  }
  if( g.urlPasswd && g.urlUser && g.urlPasswd[0]=='#' ){
    char *zCredentials = mprintf("%s:%s", g.urlUser, &g.urlPasswd[1]);
    char *zEncoded = encode64(zCredentials, -1);
    blob_appendf(&hdr, "Authorization: Basic %s\r\n", zEncoded);
    fossil_free(zEncoded);
    fossil_free(zCredentials);
  }
  blob_appendf(&hdr, "Host: %s\r\n", g.urlHostname);
  blob_appendf(&hdr, "User-Agent: Fossil/" RELEASE_VERSION
                     " (" MANIFEST_DATE " " MANIFEST_VERSION ")\r\n");
  blob_appendf(&hdr, "Content-Type: text/plain\r\n");
  blob_appendf(&hdr, "Content-Length: %d\r\n\r\n", blob_size(&payload));

  transport_send(&hdr);
  transport_send(&payload);
  transport_close();
  g.urlProtocol=0; /* Make sure the url is not re-used. */
  Th_SetResult(interp, "", -1);
  return TH_OK;
}

static int commonScriptRan = 0;

/*
** Run the specified TH1 script, if any, and returns the return code or TH_OK
** Run the specified TH1 script, if any, and returns 1 on error.
** when there is no script.
*/
static int run_script(const char *zScript){
  if( !zScript ){
    return TH_OK; /* No script, return success. */
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. */
  }
  Th_FossilInit(TH_INIT_DEFAULT); /* Make sure TH1 is ready. */
  return Th_Eval(g.interp, 0, zScript, -1);
  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.
*/
static int run_common_script(void){
  return run_script(db_get("xfer-common-script", 0));
}

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;
    }
    Th_CreateCommand(g.interp, "http", httpCmd, 0, 0);
  }
/*
** Run the post-push TH1 script, if any, and returns the return code.
*/
static int run_push_script(void){
  return run_script(db_get("xfer-push-script", 0));
  return result;
}

/*
** If this variable is set, disable login checks.  Used for debugging
** only.
*/
static int disableLogin = 0;
902
903
904
905
906
907
908
909

910
911
912
913
914
915
916
1006
1007
1008
1009
1010
1011
1012

1013
1014
1015
1016
1017
1018
1019
1020







-
+







  g.xferPanic = 1;

  db_begin_transaction();
  db_multi_exec(
     "CREATE TEMP TABLE onremote(rid INTEGER PRIMARY KEY);"
  );
  manifest_crosslink_begin();
  if( run_common_script()==TH_ERROR ){
  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;
1229
1230
1231
1232
1233
1234
1235
1236

1237
1238

1239
1240
1241
1242
1243
1244
1245
1333
1334
1335
1336
1337
1338
1339

1340
1341

1342
1343
1344
1345
1346
1347
1348
1349







-
+

-
+







      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_push_script()==TH_ERROR ){
    if( run_script("xfer-push-script", 0) ){
      cgi_reset_content();
      @ error push\sscript\sfailed:\s%F(Th_GetResult(g.interp, 0))
      @ error push\sscript\sfailed:\s%F(g.zErrMsg)
      nErr++;
    }
    request_phantoms(&xfer, 500);
  }
  if( isClone && nGimme==0 ){
    /* The initial "clone" message from client to server contains no
    ** "gimme" cards. On that initial message, send the client an "igot"
Changes to src/xfersetup.c.
34
35
36
37
38
39
40




41
42
43
44
45
46
47
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51







+
+
+
+








  style_header("Transfer Setup");
  @ <table border="0" cellspacing="20">
  setup_menu_entry("Common", "xfersetup_com",
    "Common TH1 code run before all transfer request processing.");
  setup_menu_entry("Push", "xfersetup_push",
    "Specific TH1 code to run after \"push\" transfer requests.");
  setup_menu_entry("Commit", "xfersetup_commit",
    "The TH1 code run after a commit.");
  setup_menu_entry("Ticket", "xfersetup_ticket",
    "The TH1 code run after a ticket change.");
  @ </table>
  style_footer();
}

/*
** Common implementation for the transfer setup editor pages.
*/
138
139
140
141
142
143
144
145
146
147
148








































142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192











+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
  ;
  xfersetup_generic(
    "Transfer Push Script",
    "xfer-push-script",
    zDefaultXferPush,
    zDesc,
    0,
    0,
    30
  );
}

static const char *zDefaultXferCommit = 0;

/*
** WEBPAGE: xfersetup_commit
*/
void xfersetup_commit_page(void){
  static const char zDesc[] =
  @ Enter TH1 script that runs for each "commit" in a transfer requests.
  ;
  xfersetup_generic(
    "Transfer Commit Script",
    "xfer-commit-script",
    zDefaultXferCommit,
    zDesc,
    0,
    0,
    30
  );
}

static const char *zDefaultXferTicket = 0;

/*
** WEBPAGE: xfersetup_ticket
*/
void xfersetup_ticket_page(void){
  static const char zDesc[] =
  @ Enter TH1 script that runs for each "ticket" change in a transfer requests.
  ;
  xfersetup_generic(
    "Transfer Ticket Script",
    "xfer-ticket-script",
    zDefaultXferTicket,
    zDesc,
    0,
    0,
    30
  );
}