Fossil SCM

When TH1 'transfer hooks' are enabled, provide the list of UUIDs received by the server to the script.

mistachkin 2014-09-09 20:01 trunk merge
Commit fc32fae7bcec405f3b1a654ba6b895fcafb61968
+2 -2
--- src/manifest.c
+++ src/manifest.c
@@ -1522,11 +1522,11 @@
15221522
db_prepare(&q, "SELECT uuid FROM pending_tkt");
15231523
while( db_step(&q)==SQLITE_ROW ){
15241524
const char *zUuid = db_column_text(&q, 0);
15251525
ticket_rebuild_entry(zUuid);
15261526
if( permitHooks && rc==TH_OK ){
1527
- rc = xfer_run_script(zScript, zUuid);
1527
+ rc = xfer_run_script(zScript, zUuid, 0);
15281528
}
15291529
}
15301530
db_finalize(&q);
15311531
db_multi_exec("DROP TABLE pending_tkt");
15321532
@@ -2066,11 +2066,11 @@
20662066
}
20672067
db_end_transaction(0);
20682068
if( permitHooks ){
20692069
rc = xfer_run_common_script();
20702070
if( rc==TH_OK ){
2071
- rc = xfer_run_script(zScript, zUuid);
2071
+ rc = xfer_run_script(zScript, zUuid, 0);
20722072
}
20732073
}
20742074
if( p->type==CFTYPE_MANIFEST ){
20752075
manifest_cache_insert(p);
20762076
}else{
20772077
--- src/manifest.c
+++ src/manifest.c
@@ -1522,11 +1522,11 @@
1522 db_prepare(&q, "SELECT uuid FROM pending_tkt");
1523 while( db_step(&q)==SQLITE_ROW ){
1524 const char *zUuid = db_column_text(&q, 0);
1525 ticket_rebuild_entry(zUuid);
1526 if( permitHooks && rc==TH_OK ){
1527 rc = xfer_run_script(zScript, zUuid);
1528 }
1529 }
1530 db_finalize(&q);
1531 db_multi_exec("DROP TABLE pending_tkt");
1532
@@ -2066,11 +2066,11 @@
2066 }
2067 db_end_transaction(0);
2068 if( permitHooks ){
2069 rc = xfer_run_common_script();
2070 if( rc==TH_OK ){
2071 rc = xfer_run_script(zScript, zUuid);
2072 }
2073 }
2074 if( p->type==CFTYPE_MANIFEST ){
2075 manifest_cache_insert(p);
2076 }else{
2077
--- src/manifest.c
+++ src/manifest.c
@@ -1522,11 +1522,11 @@
1522 db_prepare(&q, "SELECT uuid FROM pending_tkt");
1523 while( db_step(&q)==SQLITE_ROW ){
1524 const char *zUuid = db_column_text(&q, 0);
1525 ticket_rebuild_entry(zUuid);
1526 if( permitHooks && rc==TH_OK ){
1527 rc = xfer_run_script(zScript, zUuid, 0);
1528 }
1529 }
1530 db_finalize(&q);
1531 db_multi_exec("DROP TABLE pending_tkt");
1532
@@ -2066,11 +2066,11 @@
2066 }
2067 db_end_transaction(0);
2068 if( permitHooks ){
2069 rc = xfer_run_common_script();
2070 if( rc==TH_OK ){
2071 rc = xfer_run_script(zScript, zUuid, 0);
2072 }
2073 }
2074 if( p->type==CFTYPE_MANIFEST ){
2075 manifest_cache_insert(p);
2076 }else{
2077
+21 -1
--- src/th_main.c
+++ src/th_main.c
@@ -1499,11 +1499,31 @@
14991499
Th_SetVar(g.interp, zName, -1, zValue, strlen(zValue));
15001500
}
15011501
}
15021502
15031503
/*
1504
-** Store a list value in a variable in the interpreter.
1504
+** Appends an element to a TH1 list value. This function is called by the
1505
+** transfer subsystem; therefore, it must be very careful to avoid doing
1506
+** any unnecessary work. To that end, the TH1 subsystem will not be called
1507
+** or initialized if the list pointer is zero (i.e. which will be the case
1508
+** when TH1 transfer hooks are disabled).
1509
+*/
1510
+void Th_AppendToList(
1511
+ char **pzList,
1512
+ int *pnList,
1513
+ const char *zElem,
1514
+ int nElem
1515
+){
1516
+ if( pzList && zElem ){
1517
+ Th_FossilInit(TH_INIT_DEFAULT);
1518
+ Th_ListAppend(g.interp, pzList, pnList, zElem, nElem);
1519
+ }
1520
+}
1521
+
1522
+/*
1523
+** Stores a list value in the specified TH1 variable using the specified
1524
+** array of strings as the source of the element values.
15051525
*/
15061526
void Th_StoreList(
15071527
const char *zName,
15081528
char **pzList,
15091529
int nList
15101530
--- src/th_main.c
+++ src/th_main.c
@@ -1499,11 +1499,31 @@
1499 Th_SetVar(g.interp, zName, -1, zValue, strlen(zValue));
1500 }
1501 }
1502
1503 /*
1504 ** Store a list value in a variable in the interpreter.
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1505 */
1506 void Th_StoreList(
1507 const char *zName,
1508 char **pzList,
1509 int nList
1510
--- src/th_main.c
+++ src/th_main.c
@@ -1499,11 +1499,31 @@
1499 Th_SetVar(g.interp, zName, -1, zValue, strlen(zValue));
1500 }
1501 }
1502
1503 /*
1504 ** Appends an element to a TH1 list value. This function is called by the
1505 ** transfer subsystem; therefore, it must be very careful to avoid doing
1506 ** any unnecessary work. To that end, the TH1 subsystem will not be called
1507 ** or initialized if the list pointer is zero (i.e. which will be the case
1508 ** when TH1 transfer hooks are disabled).
1509 */
1510 void Th_AppendToList(
1511 char **pzList,
1512 int *pnList,
1513 const char *zElem,
1514 int nElem
1515 ){
1516 if( pzList && zElem ){
1517 Th_FossilInit(TH_INIT_DEFAULT);
1518 Th_ListAppend(g.interp, pzList, pnList, zElem, nElem);
1519 }
1520 }
1521
1522 /*
1523 ** Stores a list value in the specified TH1 variable using the specified
1524 ** array of strings as the source of the element values.
1525 */
1526 void Th_StoreList(
1527 const char *zName,
1528 char **pzList,
1529 int nList
1530
+21 -1
--- src/th_main.c
+++ src/th_main.c
@@ -1499,11 +1499,31 @@
14991499
Th_SetVar(g.interp, zName, -1, zValue, strlen(zValue));
15001500
}
15011501
}
15021502
15031503
/*
1504
-** Store a list value in a variable in the interpreter.
1504
+** Appends an element to a TH1 list value. This function is called by the
1505
+** transfer subsystem; therefore, it must be very careful to avoid doing
1506
+** any unnecessary work. To that end, the TH1 subsystem will not be called
1507
+** or initialized if the list pointer is zero (i.e. which will be the case
1508
+** when TH1 transfer hooks are disabled).
1509
+*/
1510
+void Th_AppendToList(
1511
+ char **pzList,
1512
+ int *pnList,
1513
+ const char *zElem,
1514
+ int nElem
1515
+){
1516
+ if( pzList && zElem ){
1517
+ Th_FossilInit(TH_INIT_DEFAULT);
1518
+ Th_ListAppend(g.interp, pzList, pnList, zElem, nElem);
1519
+ }
1520
+}
1521
+
1522
+/*
1523
+** Stores a list value in the specified TH1 variable using the specified
1524
+** array of strings as the source of the element values.
15051525
*/
15061526
void Th_StoreList(
15071527
const char *zName,
15081528
char **pzList,
15091529
int nList
15101530
--- src/th_main.c
+++ src/th_main.c
@@ -1499,11 +1499,31 @@
1499 Th_SetVar(g.interp, zName, -1, zValue, strlen(zValue));
1500 }
1501 }
1502
1503 /*
1504 ** Store a list value in a variable in the interpreter.
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1505 */
1506 void Th_StoreList(
1507 const char *zName,
1508 char **pzList,
1509 int nList
1510
--- src/th_main.c
+++ src/th_main.c
@@ -1499,11 +1499,31 @@
1499 Th_SetVar(g.interp, zName, -1, zValue, strlen(zValue));
1500 }
1501 }
1502
1503 /*
1504 ** Appends an element to a TH1 list value. This function is called by the
1505 ** transfer subsystem; therefore, it must be very careful to avoid doing
1506 ** any unnecessary work. To that end, the TH1 subsystem will not be called
1507 ** or initialized if the list pointer is zero (i.e. which will be the case
1508 ** when TH1 transfer hooks are disabled).
1509 */
1510 void Th_AppendToList(
1511 char **pzList,
1512 int *pnList,
1513 const char *zElem,
1514 int nElem
1515 ){
1516 if( pzList && zElem ){
1517 Th_FossilInit(TH_INIT_DEFAULT);
1518 Th_ListAppend(g.interp, pzList, pnList, zElem, nElem);
1519 }
1520 }
1521
1522 /*
1523 ** Stores a list value in the specified TH1 variable using the specified
1524 ** array of strings as the source of the element values.
1525 */
1526 void Th_StoreList(
1527 const char *zName,
1528 char **pzList,
1529 int nList
1530
+3 -2
--- src/tkt.c
+++ src/tkt.c
@@ -322,13 +322,14 @@
322322
}
323323
324324
/*
325325
** Create the TH1 interpreter and load the "change" code.
326326
*/
327
-int ticket_change(void){
327
+int ticket_change(const char *zUuid){
328328
const char *zConfig;
329329
Th_FossilInit(TH_INIT_DEFAULT);
330
+ Th_Store("uuid", zUuid);
330331
zConfig = ticket_change_code();
331332
return Th_Eval(g.interp, 0, zConfig, -1);
332333
}
333334
334335
/*
@@ -637,11 +638,11 @@
637638
blob_str(&tktchng));
638639
}
639640
ticket_put(&tktchng, zUuid,
640641
(g.perm.ModTkt==0 && db_get_boolean("modreq-tkt",0)==1));
641642
}
642
- return ticket_change();
643
+ return ticket_change(zUuid);
643644
}
644645
645646
646647
/*
647648
** WEBPAGE: tktnew
648649
--- src/tkt.c
+++ src/tkt.c
@@ -322,13 +322,14 @@
322 }
323
324 /*
325 ** Create the TH1 interpreter and load the "change" code.
326 */
327 int ticket_change(void){
328 const char *zConfig;
329 Th_FossilInit(TH_INIT_DEFAULT);
 
330 zConfig = ticket_change_code();
331 return Th_Eval(g.interp, 0, zConfig, -1);
332 }
333
334 /*
@@ -637,11 +638,11 @@
637 blob_str(&tktchng));
638 }
639 ticket_put(&tktchng, zUuid,
640 (g.perm.ModTkt==0 && db_get_boolean("modreq-tkt",0)==1));
641 }
642 return ticket_change();
643 }
644
645
646 /*
647 ** WEBPAGE: tktnew
648
--- src/tkt.c
+++ src/tkt.c
@@ -322,13 +322,14 @@
322 }
323
324 /*
325 ** Create the TH1 interpreter and load the "change" code.
326 */
327 int ticket_change(const char *zUuid){
328 const char *zConfig;
329 Th_FossilInit(TH_INIT_DEFAULT);
330 Th_Store("uuid", zUuid);
331 zConfig = ticket_change_code();
332 return Th_Eval(g.interp, 0, zConfig, -1);
333 }
334
335 /*
@@ -637,11 +638,11 @@
638 blob_str(&tktchng));
639 }
640 ticket_put(&tktchng, zUuid,
641 (g.perm.ModTkt==0 && db_get_boolean("modreq-tkt",0)==1));
642 }
643 return ticket_change(zUuid);
644 }
645
646
647 /*
648 ** WEBPAGE: tktnew
649
+45 -18
--- src/xfer.c
+++ src/xfer.c
@@ -113,11 +113,16 @@
113113
** be initialized to an empty string.
114114
**
115115
** Any artifact successfully received by this routine is considered to
116116
** be public and is therefore removed from the "private" table.
117117
*/
118
-static void xfer_accept_file(Xfer *pXfer, int cloneFlag){
118
+static void xfer_accept_file(
119
+ Xfer *pXfer,
120
+ int cloneFlag,
121
+ char **pzUuidList,
122
+ int *pnUuidList
123
+){
119124
int n;
120125
int rid;
121126
int srcid = 0;
122127
Blob content, hash;
123128
int isPriv;
@@ -155,10 +160,12 @@
155160
srcid = 0;
156161
pXfer->nFileRcvd++;
157162
}
158163
rid = content_put_ex(&content, blob_str(&pXfer->aToken[1]), srcid,
159164
0, isPriv);
165
+ Th_AppendToList(pzUuidList, pnUuidList, blob_str(&pXfer->aToken[1]),
166
+ blob_size(&pXfer->aToken[1]));
160167
remote_has(rid);
161168
blob_reset(&content);
162169
return;
163170
}
164171
if( pXfer->nToken==4 ){
@@ -165,10 +172,12 @@
165172
Blob src, next;
166173
srcid = rid_from_uuid(&pXfer->aToken[2], 1, isPriv);
167174
if( content_get(srcid, &src)==0 ){
168175
rid = content_put_ex(&content, blob_str(&pXfer->aToken[1]), srcid,
169176
0, isPriv);
177
+ Th_AppendToList(pzUuidList, pnUuidList, blob_str(&pXfer->aToken[1]),
178
+ blob_size(&pXfer->aToken[1]));
170179
pXfer->nDanglingFile++;
171180
db_multi_exec("DELETE FROM phantom WHERE rid=%d", rid);
172181
if( !isPriv ) content_make_public(rid);
173182
blob_reset(&src);
174183
blob_reset(&content);
@@ -185,10 +194,11 @@
185194
sha1sum_blob(&content, &hash);
186195
if( !blob_eq_str(&pXfer->aToken[1], blob_str(&hash), -1) ){
187196
blob_appendf(&pXfer->err, "content does not match sha1 hash");
188197
}
189198
rid = content_put_ex(&content, blob_str(&hash), 0, 0, isPriv);
199
+ Th_AppendToList(pzUuidList, pnUuidList, blob_str(&hash), blob_size(&hash));
190200
blob_reset(&hash);
191201
if( rid==0 ){
192202
blob_appendf(&pXfer->err, "%s", g.zErrMsg);
193203
blob_reset(&content);
194204
}else{
@@ -220,11 +230,15 @@
220230
** be initialized to an empty string.
221231
**
222232
** Any artifact successfully received by this routine is considered to
223233
** be public and is therefore removed from the "private" table.
224234
*/
225
-static void xfer_accept_compressed_file(Xfer *pXfer){
235
+static void xfer_accept_compressed_file(
236
+ Xfer *pXfer,
237
+ char **pzUuidList,
238
+ int *pnUuidList
239
+){
226240
int szC; /* CSIZE */
227241
int szU; /* USIZE */
228242
int rid;
229243
int srcid = 0;
230244
Blob content;
@@ -261,10 +275,12 @@
261275
srcid = 0;
262276
pXfer->nFileRcvd++;
263277
}
264278
rid = content_put_ex(&content, blob_str(&pXfer->aToken[1]), srcid,
265279
szC, isPriv);
280
+ Th_AppendToList(pzUuidList, pnUuidList, blob_str(&pXfer->aToken[1]),
281
+ blob_size(&pXfer->aToken[1]));
266282
remote_has(rid);
267283
blob_reset(&content);
268284
}
269285
270286
/*
@@ -853,21 +869,19 @@
853869
}
854870
855871
/*
856872
** Run the specified TH1 script, if any, and returns 1 on error.
857873
*/
858
-int xfer_run_script(const char *zScript, const char *zUuid){
859
- int rc;
860
- if( !zScript ) return TH_OK;
874
+int xfer_run_script(
875
+ const char *zScript,
876
+ const char *zUuidOrList,
877
+ int bIsList
878
+){
879
+ int rc = TH_OK;
880
+ if( !zScript ) return rc;
861881
Th_FossilInit(TH_INIT_DEFAULT);
862
- if( zUuid ){
863
- rc = Th_SetVar(g.interp, "uuid", -1, zUuid, -1);
864
- if( rc!=TH_OK ){
865
- fossil_error(1, "%s", Th_GetResult(g.interp, 0));
866
- return rc;
867
- }
868
- }
882
+ Th_Store(bIsList ? "uuids" : "uuid", zUuidOrList ? zUuidOrList : "");
869883
rc = Th_Eval(g.interp, 0, zScript, -1);
870884
if( rc!=TH_OK ){
871885
fossil_error(1, "%s", Th_GetResult(g.interp, 0));
872886
}
873887
return rc;
@@ -883,11 +897,11 @@
883897
** # ... code here
884898
** set common_done 1
885899
** }
886900
*/
887901
int xfer_run_common_script(void){
888
- return xfer_run_script(xfer_common_code(), 0);
902
+ return xfer_run_script(xfer_common_code(), 0, 0);
889903
}
890904
891905
/*
892906
** If this variable is set, disable login checks. Used for debugging
893907
** only.
@@ -917,10 +931,15 @@
917931
int nGimme = 0;
918932
int size;
919933
int recvConfig = 0;
920934
char *zNow;
921935
int rc;
936
+ const char *zScript = 0;
937
+ char *zUuidList = 0;
938
+ int nUuidList = 0;
939
+ char **pzUuidList = 0;
940
+ int *pnUuidList = 0;
922941
923942
if( fossil_strcmp(PD("REQUEST_METHOD","POST"),"POST") ){
924943
fossil_redirect_home();
925944
}
926945
g.zLogin = "anonymous";
@@ -951,10 +970,15 @@
951970
rc = xfer_run_common_script();
952971
if( rc==TH_ERROR ){
953972
cgi_reset_content();
954973
@ error common\sscript\sfailed:\s%F(g.zErrMsg)
955974
nErr++;
975
+ }
976
+ zScript = xfer_push_code();
977
+ if( zScript ){ /* NOTE: Are TH1 transfer hooks enabled? */
978
+ pzUuidList = &zUuidList;
979
+ pnUuidList = &nUuidList;
956980
}
957981
while( blob_line(xfer.pIn, &xfer.line) ){
958982
if( blob_buffer(&xfer.line)[0]=='#' ) continue;
959983
if( blob_size(&xfer.line)==0 ) continue;
960984
xfer.nToken = blob_tokenize(&xfer.line, xfer.aToken, count(xfer.aToken));
@@ -969,11 +993,11 @@
969993
cgi_reset_content();
970994
@ error not\sauthorized\sto\swrite
971995
nErr++;
972996
break;
973997
}
974
- xfer_accept_file(&xfer, 0);
998
+ xfer_accept_file(&xfer, 0, pzUuidList, pnUuidList);
975999
if( blob_size(&xfer.err) ){
9761000
cgi_reset_content();
9771001
@ error %T(blob_str(&xfer.err))
9781002
nErr++;
9791003
break;
@@ -990,11 +1014,11 @@
9901014
cgi_reset_content();
9911015
@ error not\sauthorized\sto\swrite
9921016
nErr++;
9931017
break;
9941018
}
995
- xfer_accept_compressed_file(&xfer);
1019
+ xfer_accept_compressed_file(&xfer, pzUuidList, pnUuidList);
9961020
if( blob_size(&xfer.err) ){
9971021
cgi_reset_content();
9981022
@ error %T(blob_str(&xfer.err))
9991023
nErr++;
10001024
break;
@@ -1275,19 +1299,22 @@
12751299
blobarray_reset(xfer.aToken, xfer.nToken);
12761300
blob_reset(&xfer.line);
12771301
}
12781302
if( isPush ){
12791303
if( rc==TH_OK ){
1280
- rc = xfer_run_script(xfer_push_code(), 0);
1304
+ rc = xfer_run_script(zScript, zUuidList, 1);
12811305
if( rc==TH_ERROR ){
12821306
cgi_reset_content();
12831307
@ error push\sscript\sfailed:\s%F(g.zErrMsg)
12841308
nErr++;
12851309
}
12861310
}
12871311
request_phantoms(&xfer, 500);
12881312
}
1313
+ if( zUuidList ){
1314
+ Th_Free(g.interp, zUuidList);
1315
+ }
12891316
if( isClone && nGimme==0 ){
12901317
/* The initial "clone" message from client to server contains no
12911318
** "gimme" cards. On that initial message, send the client an "igot"
12921319
** card for every artifact currently in the repository. This will
12931320
** cause the client to create phantoms for all artifacts, which will
@@ -1637,21 +1664,21 @@
16371664
** file UUID DELTASRC SIZE \n CONTENT
16381665
**
16391666
** Receive a file transmitted from the server.
16401667
*/
16411668
if( blob_eq(&xfer.aToken[0],"file") ){
1642
- xfer_accept_file(&xfer, (syncFlags & SYNC_CLONE)!=0);
1669
+ xfer_accept_file(&xfer, (syncFlags & SYNC_CLONE)!=0, 0, 0);
16431670
nArtifactRcvd++;
16441671
}else
16451672
16461673
/* cfile UUID USIZE CSIZE \n CONTENT
16471674
** cfile UUID DELTASRC USIZE CSIZE \n CONTENT
16481675
**
16491676
** Receive a compressed file transmitted from the server.
16501677
*/
16511678
if( blob_eq(&xfer.aToken[0],"cfile") ){
1652
- xfer_accept_compressed_file(&xfer);
1679
+ xfer_accept_compressed_file(&xfer, 0, 0);
16531680
nArtifactRcvd++;
16541681
}else
16551682
16561683
/* gimme UUID
16571684
**
16581685
--- src/xfer.c
+++ src/xfer.c
@@ -113,11 +113,16 @@
113 ** be initialized to an empty string.
114 **
115 ** Any artifact successfully received by this routine is considered to
116 ** be public and is therefore removed from the "private" table.
117 */
118 static void xfer_accept_file(Xfer *pXfer, int cloneFlag){
 
 
 
 
 
119 int n;
120 int rid;
121 int srcid = 0;
122 Blob content, hash;
123 int isPriv;
@@ -155,10 +160,12 @@
155 srcid = 0;
156 pXfer->nFileRcvd++;
157 }
158 rid = content_put_ex(&content, blob_str(&pXfer->aToken[1]), srcid,
159 0, isPriv);
 
 
160 remote_has(rid);
161 blob_reset(&content);
162 return;
163 }
164 if( pXfer->nToken==4 ){
@@ -165,10 +172,12 @@
165 Blob src, next;
166 srcid = rid_from_uuid(&pXfer->aToken[2], 1, isPriv);
167 if( content_get(srcid, &src)==0 ){
168 rid = content_put_ex(&content, blob_str(&pXfer->aToken[1]), srcid,
169 0, isPriv);
 
 
170 pXfer->nDanglingFile++;
171 db_multi_exec("DELETE FROM phantom WHERE rid=%d", rid);
172 if( !isPriv ) content_make_public(rid);
173 blob_reset(&src);
174 blob_reset(&content);
@@ -185,10 +194,11 @@
185 sha1sum_blob(&content, &hash);
186 if( !blob_eq_str(&pXfer->aToken[1], blob_str(&hash), -1) ){
187 blob_appendf(&pXfer->err, "content does not match sha1 hash");
188 }
189 rid = content_put_ex(&content, blob_str(&hash), 0, 0, isPriv);
 
190 blob_reset(&hash);
191 if( rid==0 ){
192 blob_appendf(&pXfer->err, "%s", g.zErrMsg);
193 blob_reset(&content);
194 }else{
@@ -220,11 +230,15 @@
220 ** be initialized to an empty string.
221 **
222 ** Any artifact successfully received by this routine is considered to
223 ** be public and is therefore removed from the "private" table.
224 */
225 static void xfer_accept_compressed_file(Xfer *pXfer){
 
 
 
 
226 int szC; /* CSIZE */
227 int szU; /* USIZE */
228 int rid;
229 int srcid = 0;
230 Blob content;
@@ -261,10 +275,12 @@
261 srcid = 0;
262 pXfer->nFileRcvd++;
263 }
264 rid = content_put_ex(&content, blob_str(&pXfer->aToken[1]), srcid,
265 szC, isPriv);
 
 
266 remote_has(rid);
267 blob_reset(&content);
268 }
269
270 /*
@@ -853,21 +869,19 @@
853 }
854
855 /*
856 ** Run the specified TH1 script, if any, and returns 1 on error.
857 */
858 int xfer_run_script(const char *zScript, const char *zUuid){
859 int rc;
860 if( !zScript ) return TH_OK;
 
 
 
 
861 Th_FossilInit(TH_INIT_DEFAULT);
862 if( zUuid ){
863 rc = Th_SetVar(g.interp, "uuid", -1, zUuid, -1);
864 if( rc!=TH_OK ){
865 fossil_error(1, "%s", Th_GetResult(g.interp, 0));
866 return rc;
867 }
868 }
869 rc = Th_Eval(g.interp, 0, zScript, -1);
870 if( rc!=TH_OK ){
871 fossil_error(1, "%s", Th_GetResult(g.interp, 0));
872 }
873 return rc;
@@ -883,11 +897,11 @@
883 ** # ... code here
884 ** set common_done 1
885 ** }
886 */
887 int xfer_run_common_script(void){
888 return xfer_run_script(xfer_common_code(), 0);
889 }
890
891 /*
892 ** If this variable is set, disable login checks. Used for debugging
893 ** only.
@@ -917,10 +931,15 @@
917 int nGimme = 0;
918 int size;
919 int recvConfig = 0;
920 char *zNow;
921 int rc;
 
 
 
 
 
922
923 if( fossil_strcmp(PD("REQUEST_METHOD","POST"),"POST") ){
924 fossil_redirect_home();
925 }
926 g.zLogin = "anonymous";
@@ -951,10 +970,15 @@
951 rc = xfer_run_common_script();
952 if( rc==TH_ERROR ){
953 cgi_reset_content();
954 @ error common\sscript\sfailed:\s%F(g.zErrMsg)
955 nErr++;
 
 
 
 
 
956 }
957 while( blob_line(xfer.pIn, &xfer.line) ){
958 if( blob_buffer(&xfer.line)[0]=='#' ) continue;
959 if( blob_size(&xfer.line)==0 ) continue;
960 xfer.nToken = blob_tokenize(&xfer.line, xfer.aToken, count(xfer.aToken));
@@ -969,11 +993,11 @@
969 cgi_reset_content();
970 @ error not\sauthorized\sto\swrite
971 nErr++;
972 break;
973 }
974 xfer_accept_file(&xfer, 0);
975 if( blob_size(&xfer.err) ){
976 cgi_reset_content();
977 @ error %T(blob_str(&xfer.err))
978 nErr++;
979 break;
@@ -990,11 +1014,11 @@
990 cgi_reset_content();
991 @ error not\sauthorized\sto\swrite
992 nErr++;
993 break;
994 }
995 xfer_accept_compressed_file(&xfer);
996 if( blob_size(&xfer.err) ){
997 cgi_reset_content();
998 @ error %T(blob_str(&xfer.err))
999 nErr++;
1000 break;
@@ -1275,19 +1299,22 @@
1275 blobarray_reset(xfer.aToken, xfer.nToken);
1276 blob_reset(&xfer.line);
1277 }
1278 if( isPush ){
1279 if( rc==TH_OK ){
1280 rc = xfer_run_script(xfer_push_code(), 0);
1281 if( rc==TH_ERROR ){
1282 cgi_reset_content();
1283 @ error push\sscript\sfailed:\s%F(g.zErrMsg)
1284 nErr++;
1285 }
1286 }
1287 request_phantoms(&xfer, 500);
1288 }
 
 
 
1289 if( isClone && nGimme==0 ){
1290 /* The initial "clone" message from client to server contains no
1291 ** "gimme" cards. On that initial message, send the client an "igot"
1292 ** card for every artifact currently in the repository. This will
1293 ** cause the client to create phantoms for all artifacts, which will
@@ -1637,21 +1664,21 @@
1637 ** file UUID DELTASRC SIZE \n CONTENT
1638 **
1639 ** Receive a file transmitted from the server.
1640 */
1641 if( blob_eq(&xfer.aToken[0],"file") ){
1642 xfer_accept_file(&xfer, (syncFlags & SYNC_CLONE)!=0);
1643 nArtifactRcvd++;
1644 }else
1645
1646 /* cfile UUID USIZE CSIZE \n CONTENT
1647 ** cfile UUID DELTASRC USIZE CSIZE \n CONTENT
1648 **
1649 ** Receive a compressed file transmitted from the server.
1650 */
1651 if( blob_eq(&xfer.aToken[0],"cfile") ){
1652 xfer_accept_compressed_file(&xfer);
1653 nArtifactRcvd++;
1654 }else
1655
1656 /* gimme UUID
1657 **
1658
--- src/xfer.c
+++ src/xfer.c
@@ -113,11 +113,16 @@
113 ** be initialized to an empty string.
114 **
115 ** Any artifact successfully received by this routine is considered to
116 ** be public and is therefore removed from the "private" table.
117 */
118 static void xfer_accept_file(
119 Xfer *pXfer,
120 int cloneFlag,
121 char **pzUuidList,
122 int *pnUuidList
123 ){
124 int n;
125 int rid;
126 int srcid = 0;
127 Blob content, hash;
128 int isPriv;
@@ -155,10 +160,12 @@
160 srcid = 0;
161 pXfer->nFileRcvd++;
162 }
163 rid = content_put_ex(&content, blob_str(&pXfer->aToken[1]), srcid,
164 0, isPriv);
165 Th_AppendToList(pzUuidList, pnUuidList, blob_str(&pXfer->aToken[1]),
166 blob_size(&pXfer->aToken[1]));
167 remote_has(rid);
168 blob_reset(&content);
169 return;
170 }
171 if( pXfer->nToken==4 ){
@@ -165,10 +172,12 @@
172 Blob src, next;
173 srcid = rid_from_uuid(&pXfer->aToken[2], 1, isPriv);
174 if( content_get(srcid, &src)==0 ){
175 rid = content_put_ex(&content, blob_str(&pXfer->aToken[1]), srcid,
176 0, isPriv);
177 Th_AppendToList(pzUuidList, pnUuidList, blob_str(&pXfer->aToken[1]),
178 blob_size(&pXfer->aToken[1]));
179 pXfer->nDanglingFile++;
180 db_multi_exec("DELETE FROM phantom WHERE rid=%d", rid);
181 if( !isPriv ) content_make_public(rid);
182 blob_reset(&src);
183 blob_reset(&content);
@@ -185,10 +194,11 @@
194 sha1sum_blob(&content, &hash);
195 if( !blob_eq_str(&pXfer->aToken[1], blob_str(&hash), -1) ){
196 blob_appendf(&pXfer->err, "content does not match sha1 hash");
197 }
198 rid = content_put_ex(&content, blob_str(&hash), 0, 0, isPriv);
199 Th_AppendToList(pzUuidList, pnUuidList, blob_str(&hash), blob_size(&hash));
200 blob_reset(&hash);
201 if( rid==0 ){
202 blob_appendf(&pXfer->err, "%s", g.zErrMsg);
203 blob_reset(&content);
204 }else{
@@ -220,11 +230,15 @@
230 ** be initialized to an empty string.
231 **
232 ** Any artifact successfully received by this routine is considered to
233 ** be public and is therefore removed from the "private" table.
234 */
235 static void xfer_accept_compressed_file(
236 Xfer *pXfer,
237 char **pzUuidList,
238 int *pnUuidList
239 ){
240 int szC; /* CSIZE */
241 int szU; /* USIZE */
242 int rid;
243 int srcid = 0;
244 Blob content;
@@ -261,10 +275,12 @@
275 srcid = 0;
276 pXfer->nFileRcvd++;
277 }
278 rid = content_put_ex(&content, blob_str(&pXfer->aToken[1]), srcid,
279 szC, isPriv);
280 Th_AppendToList(pzUuidList, pnUuidList, blob_str(&pXfer->aToken[1]),
281 blob_size(&pXfer->aToken[1]));
282 remote_has(rid);
283 blob_reset(&content);
284 }
285
286 /*
@@ -853,21 +869,19 @@
869 }
870
871 /*
872 ** Run the specified TH1 script, if any, and returns 1 on error.
873 */
874 int xfer_run_script(
875 const char *zScript,
876 const char *zUuidOrList,
877 int bIsList
878 ){
879 int rc = TH_OK;
880 if( !zScript ) return rc;
881 Th_FossilInit(TH_INIT_DEFAULT);
882 Th_Store(bIsList ? "uuids" : "uuid", zUuidOrList ? zUuidOrList : "");
 
 
 
 
 
 
883 rc = Th_Eval(g.interp, 0, zScript, -1);
884 if( rc!=TH_OK ){
885 fossil_error(1, "%s", Th_GetResult(g.interp, 0));
886 }
887 return rc;
@@ -883,11 +897,11 @@
897 ** # ... code here
898 ** set common_done 1
899 ** }
900 */
901 int xfer_run_common_script(void){
902 return xfer_run_script(xfer_common_code(), 0, 0);
903 }
904
905 /*
906 ** If this variable is set, disable login checks. Used for debugging
907 ** only.
@@ -917,10 +931,15 @@
931 int nGimme = 0;
932 int size;
933 int recvConfig = 0;
934 char *zNow;
935 int rc;
936 const char *zScript = 0;
937 char *zUuidList = 0;
938 int nUuidList = 0;
939 char **pzUuidList = 0;
940 int *pnUuidList = 0;
941
942 if( fossil_strcmp(PD("REQUEST_METHOD","POST"),"POST") ){
943 fossil_redirect_home();
944 }
945 g.zLogin = "anonymous";
@@ -951,10 +970,15 @@
970 rc = xfer_run_common_script();
971 if( rc==TH_ERROR ){
972 cgi_reset_content();
973 @ error common\sscript\sfailed:\s%F(g.zErrMsg)
974 nErr++;
975 }
976 zScript = xfer_push_code();
977 if( zScript ){ /* NOTE: Are TH1 transfer hooks enabled? */
978 pzUuidList = &zUuidList;
979 pnUuidList = &nUuidList;
980 }
981 while( blob_line(xfer.pIn, &xfer.line) ){
982 if( blob_buffer(&xfer.line)[0]=='#' ) continue;
983 if( blob_size(&xfer.line)==0 ) continue;
984 xfer.nToken = blob_tokenize(&xfer.line, xfer.aToken, count(xfer.aToken));
@@ -969,11 +993,11 @@
993 cgi_reset_content();
994 @ error not\sauthorized\sto\swrite
995 nErr++;
996 break;
997 }
998 xfer_accept_file(&xfer, 0, pzUuidList, pnUuidList);
999 if( blob_size(&xfer.err) ){
1000 cgi_reset_content();
1001 @ error %T(blob_str(&xfer.err))
1002 nErr++;
1003 break;
@@ -990,11 +1014,11 @@
1014 cgi_reset_content();
1015 @ error not\sauthorized\sto\swrite
1016 nErr++;
1017 break;
1018 }
1019 xfer_accept_compressed_file(&xfer, pzUuidList, pnUuidList);
1020 if( blob_size(&xfer.err) ){
1021 cgi_reset_content();
1022 @ error %T(blob_str(&xfer.err))
1023 nErr++;
1024 break;
@@ -1275,19 +1299,22 @@
1299 blobarray_reset(xfer.aToken, xfer.nToken);
1300 blob_reset(&xfer.line);
1301 }
1302 if( isPush ){
1303 if( rc==TH_OK ){
1304 rc = xfer_run_script(zScript, zUuidList, 1);
1305 if( rc==TH_ERROR ){
1306 cgi_reset_content();
1307 @ error push\sscript\sfailed:\s%F(g.zErrMsg)
1308 nErr++;
1309 }
1310 }
1311 request_phantoms(&xfer, 500);
1312 }
1313 if( zUuidList ){
1314 Th_Free(g.interp, zUuidList);
1315 }
1316 if( isClone && nGimme==0 ){
1317 /* The initial "clone" message from client to server contains no
1318 ** "gimme" cards. On that initial message, send the client an "igot"
1319 ** card for every artifact currently in the repository. This will
1320 ** cause the client to create phantoms for all artifacts, which will
@@ -1637,21 +1664,21 @@
1664 ** file UUID DELTASRC SIZE \n CONTENT
1665 **
1666 ** Receive a file transmitted from the server.
1667 */
1668 if( blob_eq(&xfer.aToken[0],"file") ){
1669 xfer_accept_file(&xfer, (syncFlags & SYNC_CLONE)!=0, 0, 0);
1670 nArtifactRcvd++;
1671 }else
1672
1673 /* cfile UUID USIZE CSIZE \n CONTENT
1674 ** cfile UUID DELTASRC USIZE CSIZE \n CONTENT
1675 **
1676 ** Receive a compressed file transmitted from the server.
1677 */
1678 if( blob_eq(&xfer.aToken[0],"cfile") ){
1679 xfer_accept_compressed_file(&xfer, 0, 0);
1680 nArtifactRcvd++;
1681 }else
1682
1683 /* gimme UUID
1684 **
1685

Keyboard Shortcuts

Open search /
Next entry (timeline) j
Previous entry (timeline) k
Open focused entry Enter
Show this help ?
Toggle theme Top nav button