Attachment "patch-hook.txt" to
ticket [77de516a1f]
added by
wolfgang
2010-10-16 15:13:45.
CHANGED src/db.c
Index: src/db.c
===================================================================
--- src/db.c
+++ src/db.c
@@ -1525,10 +1525,16 @@
{ "http-port", 0, 16, "8080" },
{ "localauth", 0, 0, "0" },
{ "mtime-changes", 0, 0, "0" },
{ "pgp-command", 0, 32, "gpg --clearsign -o " },
{ "proxy", 0, 32, "off" },
+ { "push-hook-pattern-client",
+ 0, 32, "" },
+ { "push-hook-pattern-cmd",
+ 0, 32, "" },
+ { "push-hook-pattern-server",
+ 0, 32, "" },
{ "ssh-command", 0, 32, "" },
{ "web-browser", 0, 32, "" },
{ 0,0,0,0 }
};
@@ -1596,10 +1602,26 @@
**
** proxy URL of the HTTP proxy. If undefined or "off" then
** the "http_proxy" environment variable is consulted.
** If the http_proxy environment variable is undefined
** then a direct HTTP connection is used.
+**
+** push-hook-pattern-client
+** if set, a client push will sent this message to the
+** server, to activate the push hook command.
+**
+** push-hook-pattern-cmd
+** this is the command line, that will be activated
+** as push hook. Output redirects should be added to
+** this command line.
+** The complete pattern, sent by the client will be
+** appended to the command line.
+**
+** push-hook-pattern-server
+** if set, and a client send this pattern at the end of
+** a push, the push hook command will be executed. This
+** might be a prefix of the pattern, sent by the client.
**
** ssh-command Command used to talk to a remote machine with
** the "ssh://" protocol.
**
** web-browser A shell command used to launch your preferred
CHANGED src/xfer.c
Index: src/xfer.c
===================================================================
--- src/xfer.c
+++ src/xfer.c
@@ -40,10 +40,32 @@
int nDeltaRcvd; /* Number of deltas received */
int nDanglingFile; /* Number of dangling deltas received */
int mxSend; /* Stop sending "file" with pOut reaches this size */
};
+/*
+** Let a server-side external agent know that a push has completed. /fatman
+*/
+void post_push_hook(char const * const zPushHookLine){
+ /*
+ ** TO DO: get the string cmd from a config file? Or the database local
+ ** settings, as someone suggested? Ditto output and error logs. /fatman
+ */
+ const char *zCmd = db_get("push-hook-pattern-cmd", "");
+
+ if( zCmd && zCmd[0] ){
+ int rc;
+ char * zCalledCmd;
+
+ zCalledCmd = mprintf("%s %s",zCmd,zPushHookLine);
+ rc = system(zCalledCmd);
+ if (rc != 0) {
+ fossil_print("The post-push-hook command \"%s\" failed.", zCalledCmd);
+ }
+ free(zCalledCmd);
+ }
+}
/*
** The input blob contains a UUID. Convert it into a record ID.
** Create a phantom record if no prior record exists and
** phantomize is true.
@@ -596,10 +618,13 @@
int isClone = 0;
int nGimme = 0;
int size;
int recvConfig = 0;
char *zNow;
+ const char *zPushHookPattern = db_get("push-hook-pattern-server", "");
+ int lenPushHookPattern = (zPushHookPattern && zPushHookPattern[0])
+ ? strlen(zPushHookPattern) : 0;
if( strcmp(PD("REQUEST_METHOD","POST"),"POST") ){
fossil_redirect_home();
}
memset(&xfer, 0, sizeof(xfer));
@@ -617,11 +642,19 @@
);
zNow = db_text(0, "SELECT strftime('%%Y-%%m-%%dT%%H:%%M:%%S', 'now')");
@ # timestamp %s(zNow)
manifest_crosslink_begin();
while( blob_line(xfer.pIn, &xfer.line) ){
- if( blob_buffer(&xfer.line)[0]=='#' ) continue;
+ if( blob_buffer(&xfer.line)[0]=='#' ){
+ if( lenPushHookPattern
+ && 0 == memcmp(blob_buffer(&xfer.line)+1,
+ zPushHookPattern, lenPushHookPattern)
+ ){
+ post_push_hook(blob_buffer(&xfer.line)+1);
+ }
+ continue;
+ }
xfer.nToken = blob_tokenize(&xfer.line, xfer.aToken, count(xfer.aToken));
/* file UUID SIZE \n CONTENT
** file UUID DELTASRC SIZE \n CONTENT
**
@@ -948,10 +981,12 @@
Blob send; /* Text we are sending to the server */
Blob recv; /* Reply we got back from the server */
Xfer xfer; /* Transfer data */
const char *zSCode = db_get("server-code", "x");
const char *zPCode = db_get("project-code", 0);
+ const char *zPushHookPattern = db_get("push-hook-pattern-client", "");
+
if( db_get_boolean("dont-push", 0) ) pushFlag = 0;
if( pushFlag + pullFlag + cloneFlag == 0
&& configRcvMask==0 && configSendMask==0 ) return;
@@ -1330,14 +1365,22 @@
}
/* If this is a clone, the go at least two rounds */
if( cloneFlag && nCycle==1 ) go = 1;
};
+ if (pushFlag && nFileSend > 0) {
+ if( zPushHookPattern && zPushHookPattern[0] ){
+ blob_appendf(&send, "#%s\n", zPushHookPattern);
+ http_exchange(&send, &recv, cloneFlag==0 || nCycle>0);
+ blob_reset(&send);
+ nCardSent++;
+ }
+ }
transport_stats(&nSent, &nRcvd, 1);
fossil_print("Total network traffic: %d bytes sent, %d bytes received\n",
nSent, nRcvd);
transport_close();
transport_global_shutdown();
db_multi_exec("DROP TABLE onremote");
manifest_crosslink_end();
db_end_transaction(0);
}