Fossil SCM

added output redirect and client force for hook

wolfgang 2010-10-18 15:46 StvPrivateHook2
Commit ccef28b54b3662d4b9dc9f556a3b35c9c4b6e8a4
2 files changed +15 -2 +25 -7
+15 -2
--- src/db.c
+++ src/db.c
@@ -1526,10 +1526,12 @@
15261526
{ "localauth", 0, 0, "0" },
15271527
{ "mtime-changes", 0, 0, "0" },
15281528
{ "pgp-command", 0, 32, "gpg --clearsign -o " },
15291529
{ "proxy", 0, 32, "off" },
15301530
{ "push-hook-cmd", 0, 32, "" },
1531
+ { "push-hook-force",
1532
+ 0, 0, "" },
15311533
{ "push-hook-pattern-client",
15321534
0, 32, "" },
15331535
{ "push-hook-pattern-server",
15341536
0, 32, "" },
15351537
{ "ssh-command", 0, 32, "" },
@@ -1605,12 +1607,23 @@
16051607
** then a direct HTTP connection is used.
16061608
**
16071609
** push-hook-cmd this is the command line, that will be activated
16081610
** as push hook. Output redirects should be added to
16091611
** this command line.
1610
-** The complete pattern, sent by the client will be
1611
-** appended to the command line.
1612
+** The complete command line looks like:
1613
+** command name: the configured value for push-hook-cmd
1614
+** argument 1: timestamp followed by random-number
1615
+** argument 2: pattern sent by client
1616
+** As fallback, stdin/stderr are redirected to files
1617
+** hook-log-<timestamp followed by random-number>
1618
+**
1619
+** push-hook-force
1620
+** if this is set on the client, it will request always
1621
+** the hook activation, even if no files where pushed on
1622
+** the sync.
1623
+** if this is set on the server, it will accept hook
1624
+** activiation, even if no files where pushed.
16121625
**
16131626
** push-hook-pattern-client
16141627
** if set, a client push will sent this message to the
16151628
** server, to activate the push hook command.
16161629
**
16171630
--- src/db.c
+++ src/db.c
@@ -1526,10 +1526,12 @@
1526 { "localauth", 0, 0, "0" },
1527 { "mtime-changes", 0, 0, "0" },
1528 { "pgp-command", 0, 32, "gpg --clearsign -o " },
1529 { "proxy", 0, 32, "off" },
1530 { "push-hook-cmd", 0, 32, "" },
 
 
1531 { "push-hook-pattern-client",
1532 0, 32, "" },
1533 { "push-hook-pattern-server",
1534 0, 32, "" },
1535 { "ssh-command", 0, 32, "" },
@@ -1605,12 +1607,23 @@
1605 ** then a direct HTTP connection is used.
1606 **
1607 ** push-hook-cmd this is the command line, that will be activated
1608 ** as push hook. Output redirects should be added to
1609 ** this command line.
1610 ** The complete pattern, sent by the client will be
1611 ** appended to the command line.
 
 
 
 
 
 
 
 
 
 
 
1612 **
1613 ** push-hook-pattern-client
1614 ** if set, a client push will sent this message to the
1615 ** server, to activate the push hook command.
1616 **
1617
--- src/db.c
+++ src/db.c
@@ -1526,10 +1526,12 @@
1526 { "localauth", 0, 0, "0" },
1527 { "mtime-changes", 0, 0, "0" },
1528 { "pgp-command", 0, 32, "gpg --clearsign -o " },
1529 { "proxy", 0, 32, "off" },
1530 { "push-hook-cmd", 0, 32, "" },
1531 { "push-hook-force",
1532 0, 0, "" },
1533 { "push-hook-pattern-client",
1534 0, 32, "" },
1535 { "push-hook-pattern-server",
1536 0, 32, "" },
1537 { "ssh-command", 0, 32, "" },
@@ -1605,12 +1607,23 @@
1607 ** then a direct HTTP connection is used.
1608 **
1609 ** push-hook-cmd this is the command line, that will be activated
1610 ** as push hook. Output redirects should be added to
1611 ** this command line.
1612 ** The complete command line looks like:
1613 ** command name: the configured value for push-hook-cmd
1614 ** argument 1: timestamp followed by random-number
1615 ** argument 2: pattern sent by client
1616 ** As fallback, stdin/stderr are redirected to files
1617 ** hook-log-<timestamp followed by random-number>
1618 **
1619 ** push-hook-force
1620 ** if this is set on the client, it will request always
1621 ** the hook activation, even if no files where pushed on
1622 ** the sync.
1623 ** if this is set on the server, it will accept hook
1624 ** activiation, even if no files where pushed.
1625 **
1626 ** push-hook-pattern-client
1627 ** if set, a client push will sent this message to the
1628 ** server, to activate the push hook command.
1629 **
1630
+25 -7
--- src/xfer.c
+++ src/xfer.c
@@ -74,33 +74,48 @@
7474
){
7575
fossil_fatal("push hook pattern '%s' doesn't match configuration '%s'\n",
7676
g.argv[2],zPushHookPattern);
7777
}
7878
}
79
- post_push_hook(g.argv[2]);
79
+ post_push_hook(g.argv[2],'C');
8080
}
8181
8282
/*
8383
** Let a server-side external agent know that a push has completed. /fatman
84
+** The second argument controls, how the command is called:
85
+** P - client request with pushed files
86
+** F - client request without pushed files(FORCE!)
87
+** C - server side command line activation
8488
*/
85
-void post_push_hook(char const * const zPushHookLine){
89
+void post_push_hook(char const * const zPushHookLine, const char requestType){
8690
/*
8791
** TO DO: get the string cmd from a config file? Or the database local
8892
** settings, as someone suggested? Ditto output and error logs. /fatman
8993
*/
9094
const char *zCmd = db_get("push-hook-cmd", "");
95
+ int allowForced = db_get_boolean("push-hook-force", 0);
9196
92
- if( zCmd && zCmd[0] ){
97
+ if( requestType=='P' && !allowForced){
98
+ fossil_print("Forced push call from client not allowed,"
99
+ " skipping call for '%s'\n", zPushHookLine);
100
+ }else if( zCmd && zCmd[0] ){
93101
int rc;
94102
char * zCalledCmd;
103
+ char * zDate;
104
+ const char *zRnd;
105
+
106
+
107
+ zDate = db_text(0, "SELECT strftime('%%Y%%m%%d%%H%%M%%f','now')");
108
+ zRnd = db_text(0, "SELECT lower(hex(randomblob(6)))");
95109
96
- zCalledCmd = mprintf("%s %s",zCmd,zPushHookLine);
110
+ zCalledCmd = mprintf("%s %s-%s %s >hook-log-%s-%s 2>&1",zCmd,zDate,zRnd,zPushHookLine,zDate,zRnd);
97111
rc = system(zCalledCmd);
98112
if (rc != 0) {
99113
fossil_print("The post-push-hook command \"%s\" failed.", zCalledCmd);
100114
}
101115
free(zCalledCmd);
116
+ free(zDate);
102117
}else{
103118
fossil_print("No push hook configured, skipping call for '%s'\n", zPushHookLine);
104119
}
105120
}
106121
@@ -686,11 +701,11 @@
686701
if( blob_buffer(&xfer.line)[0]=='#' ){
687702
if( lenPushHookPattern
688703
&& 0 == memcmp(blob_buffer(&xfer.line)+1,
689704
zPushHookPattern, lenPushHookPattern)
690705
){
691
- post_push_hook(blob_buffer(&xfer.line)+1);
706
+ post_push_hook(blob_buffer(&xfer.line)+2,blob_buffer(&xfer.line)[1]);
692707
}
693708
continue;
694709
}
695710
xfer.nToken = blob_tokenize(&xfer.line, xfer.aToken, count(xfer.aToken));
696711
@@ -1021,10 +1036,11 @@
10211036
Blob recv; /* Reply we got back from the server */
10221037
Xfer xfer; /* Transfer data */
10231038
const char *zSCode = db_get("server-code", "x");
10241039
const char *zPCode = db_get("project-code", 0);
10251040
const char *zPushHookPattern = db_get("push-hook-pattern-client", "");
1041
+ int allowForced = db_get_boolean("push-hook-force", 0);
10261042
10271043
10281044
if( db_get_boolean("dont-push", 0) ) pushFlag = 0;
10291045
if( pushFlag + pullFlag + cloneFlag == 0
10301046
&& configRcvMask==0 && configSendMask==0 ) return;
@@ -1404,17 +1420,19 @@
14041420
}
14051421
14061422
/* If this is a clone, the go at least two rounds */
14071423
if( cloneFlag && nCycle==1 ) go = 1;
14081424
};
1409
- if (pushFlag && nFileSend > 0) {
1425
+ if( pushFlag && ( (nFileSend > 0) || allowForced ) ){
14101426
if( zPushHookPattern && zPushHookPattern[0] ){
1411
- blob_appendf(&send, "#%s\n", zPushHookPattern);
1427
+ blob_appendf(&send, "#%c%s\n",
1428
+ ((nFileSend > 0)?'P':'F'), zPushHookPattern);
14121429
http_exchange(&send, &recv, cloneFlag==0 || nCycle>0);
14131430
blob_reset(&send);
14141431
nCardSent++;
14151432
}
1433
+ int allowForced = db_get_boolean("push-hook-force", 0);
14161434
}
14171435
transport_stats(&nSent, &nRcvd, 1);
14181436
fossil_print("Total network traffic: %d bytes sent, %d bytes received\n",
14191437
nSent, nRcvd);
14201438
transport_close();
14211439
--- src/xfer.c
+++ src/xfer.c
@@ -74,33 +74,48 @@
74 ){
75 fossil_fatal("push hook pattern '%s' doesn't match configuration '%s'\n",
76 g.argv[2],zPushHookPattern);
77 }
78 }
79 post_push_hook(g.argv[2]);
80 }
81
82 /*
83 ** Let a server-side external agent know that a push has completed. /fatman
 
 
 
 
84 */
85 void post_push_hook(char const * const zPushHookLine){
86 /*
87 ** TO DO: get the string cmd from a config file? Or the database local
88 ** settings, as someone suggested? Ditto output and error logs. /fatman
89 */
90 const char *zCmd = db_get("push-hook-cmd", "");
 
91
92 if( zCmd && zCmd[0] ){
 
 
 
93 int rc;
94 char * zCalledCmd;
 
 
 
 
 
 
95
96 zCalledCmd = mprintf("%s %s",zCmd,zPushHookLine);
97 rc = system(zCalledCmd);
98 if (rc != 0) {
99 fossil_print("The post-push-hook command \"%s\" failed.", zCalledCmd);
100 }
101 free(zCalledCmd);
 
102 }else{
103 fossil_print("No push hook configured, skipping call for '%s'\n", zPushHookLine);
104 }
105 }
106
@@ -686,11 +701,11 @@
686 if( blob_buffer(&xfer.line)[0]=='#' ){
687 if( lenPushHookPattern
688 && 0 == memcmp(blob_buffer(&xfer.line)+1,
689 zPushHookPattern, lenPushHookPattern)
690 ){
691 post_push_hook(blob_buffer(&xfer.line)+1);
692 }
693 continue;
694 }
695 xfer.nToken = blob_tokenize(&xfer.line, xfer.aToken, count(xfer.aToken));
696
@@ -1021,10 +1036,11 @@
1021 Blob recv; /* Reply we got back from the server */
1022 Xfer xfer; /* Transfer data */
1023 const char *zSCode = db_get("server-code", "x");
1024 const char *zPCode = db_get("project-code", 0);
1025 const char *zPushHookPattern = db_get("push-hook-pattern-client", "");
 
1026
1027
1028 if( db_get_boolean("dont-push", 0) ) pushFlag = 0;
1029 if( pushFlag + pullFlag + cloneFlag == 0
1030 && configRcvMask==0 && configSendMask==0 ) return;
@@ -1404,17 +1420,19 @@
1404 }
1405
1406 /* If this is a clone, the go at least two rounds */
1407 if( cloneFlag && nCycle==1 ) go = 1;
1408 };
1409 if (pushFlag && nFileSend > 0) {
1410 if( zPushHookPattern && zPushHookPattern[0] ){
1411 blob_appendf(&send, "#%s\n", zPushHookPattern);
 
1412 http_exchange(&send, &recv, cloneFlag==0 || nCycle>0);
1413 blob_reset(&send);
1414 nCardSent++;
1415 }
 
1416 }
1417 transport_stats(&nSent, &nRcvd, 1);
1418 fossil_print("Total network traffic: %d bytes sent, %d bytes received\n",
1419 nSent, nRcvd);
1420 transport_close();
1421
--- src/xfer.c
+++ src/xfer.c
@@ -74,33 +74,48 @@
74 ){
75 fossil_fatal("push hook pattern '%s' doesn't match configuration '%s'\n",
76 g.argv[2],zPushHookPattern);
77 }
78 }
79 post_push_hook(g.argv[2],'C');
80 }
81
82 /*
83 ** Let a server-side external agent know that a push has completed. /fatman
84 ** The second argument controls, how the command is called:
85 ** P - client request with pushed files
86 ** F - client request without pushed files(FORCE!)
87 ** C - server side command line activation
88 */
89 void post_push_hook(char const * const zPushHookLine, const char requestType){
90 /*
91 ** TO DO: get the string cmd from a config file? Or the database local
92 ** settings, as someone suggested? Ditto output and error logs. /fatman
93 */
94 const char *zCmd = db_get("push-hook-cmd", "");
95 int allowForced = db_get_boolean("push-hook-force", 0);
96
97 if( requestType=='P' && !allowForced){
98 fossil_print("Forced push call from client not allowed,"
99 " skipping call for '%s'\n", zPushHookLine);
100 }else if( zCmd && zCmd[0] ){
101 int rc;
102 char * zCalledCmd;
103 char * zDate;
104 const char *zRnd;
105
106
107 zDate = db_text(0, "SELECT strftime('%%Y%%m%%d%%H%%M%%f','now')");
108 zRnd = db_text(0, "SELECT lower(hex(randomblob(6)))");
109
110 zCalledCmd = mprintf("%s %s-%s %s >hook-log-%s-%s 2>&1",zCmd,zDate,zRnd,zPushHookLine,zDate,zRnd);
111 rc = system(zCalledCmd);
112 if (rc != 0) {
113 fossil_print("The post-push-hook command \"%s\" failed.", zCalledCmd);
114 }
115 free(zCalledCmd);
116 free(zDate);
117 }else{
118 fossil_print("No push hook configured, skipping call for '%s'\n", zPushHookLine);
119 }
120 }
121
@@ -686,11 +701,11 @@
701 if( blob_buffer(&xfer.line)[0]=='#' ){
702 if( lenPushHookPattern
703 && 0 == memcmp(blob_buffer(&xfer.line)+1,
704 zPushHookPattern, lenPushHookPattern)
705 ){
706 post_push_hook(blob_buffer(&xfer.line)+2,blob_buffer(&xfer.line)[1]);
707 }
708 continue;
709 }
710 xfer.nToken = blob_tokenize(&xfer.line, xfer.aToken, count(xfer.aToken));
711
@@ -1021,10 +1036,11 @@
1036 Blob recv; /* Reply we got back from the server */
1037 Xfer xfer; /* Transfer data */
1038 const char *zSCode = db_get("server-code", "x");
1039 const char *zPCode = db_get("project-code", 0);
1040 const char *zPushHookPattern = db_get("push-hook-pattern-client", "");
1041 int allowForced = db_get_boolean("push-hook-force", 0);
1042
1043
1044 if( db_get_boolean("dont-push", 0) ) pushFlag = 0;
1045 if( pushFlag + pullFlag + cloneFlag == 0
1046 && configRcvMask==0 && configSendMask==0 ) return;
@@ -1404,17 +1420,19 @@
1420 }
1421
1422 /* If this is a clone, the go at least two rounds */
1423 if( cloneFlag && nCycle==1 ) go = 1;
1424 };
1425 if( pushFlag && ( (nFileSend > 0) || allowForced ) ){
1426 if( zPushHookPattern && zPushHookPattern[0] ){
1427 blob_appendf(&send, "#%c%s\n",
1428 ((nFileSend > 0)?'P':'F'), zPushHookPattern);
1429 http_exchange(&send, &recv, cloneFlag==0 || nCycle>0);
1430 blob_reset(&send);
1431 nCardSent++;
1432 }
1433 int allowForced = db_get_boolean("push-hook-force", 0);
1434 }
1435 transport_stats(&nSent, &nRcvd, 1);
1436 fossil_print("Total network traffic: %d bytes sent, %d bytes received\n",
1437 nSent, nRcvd);
1438 transport_close();
1439

Keyboard Shortcuts

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