1 /*
2 ** Copyright (c) 2018 D. Richard Hipp
3 **
4 ** This program is free software; you can redistribute it and/or
5 ** modify it under the terms of the Simplified BSD License (also
6 ** known as the "2-Clause License" or "FreeBSD License".)
7 **
8 ** This program is distributed in the hope that it will be useful,
9 ** but without any warranty; without even the implied warranty of
10 ** merchantability or fitness for a particular purpose.
11 **
12 ** Author contact information:
13 **   drh@hwaci.com
14 **   http://www.hwaci.com/drh/
15 **
16 *******************************************************************************
17 **
18 ** This file contains code used to manage a background processes that
19 ** occur after user interaction with the repository.  Examples of
20 ** backoffice processing includes:
21 **
22 **    *  Sending alerts and notifications
23 **    *  Processing the email queue
24 **    *  Handling post-receive hooks
25 **    *  Automatically syncing to peer repositories
26 **
27 ** Backoffice processing is automatically started whenever there are
28 ** changes to the repository.  The backoffice process dies off after
29 ** a period of inactivity.
30 **
31 ** Steps are taken to ensure that only a single backoffice process is
32 ** running at a time.  Otherwise, there could be race conditions that
33 ** cause adverse effects such as multiple alerts for the same changes.
34 **
35 ** At the same time, we do not want a backoffice process to run forever.
36 ** Backoffice processes should die off after doing whatever work they need
37 ** to do.  In this way, we avoid having lots of idle processes in the
38 ** process table, doing nothing on rarely accessed repositories, and
39 ** if the Fossil binary is updated on a system, the backoffice processes
40 ** will restart using the new binary automatically.
41 **
42 ** At any point in time there should be at most two backoffice processes.
43 ** There is a main process that is doing the actually work, and there is
44 ** a second stand-by process that is waiting for the main process to finish
45 ** and that will become the main process after a delay.
46 **
47 ** After any successful web page reply, the backoffice_check_if_needed()
48 ** routine is called.  That routine checks to see if both one or both of
49 ** the backoffice processes are already running.  That routine remembers the
50 ** status in a global variable.
51 **
52 ** Later, after the repository database is closed, the
53 ** backoffice_run_if_needed() routine is called.  If the prior call
54 ** to backoffice_check_if_needed() indicated that backoffice processing
55 ** might be required, the run_if_needed() attempts to kick off a backoffice
56 ** process.
57 **
58 ** All work performance by the backoffice is in the backoffice_work()
59 ** routine.
60 */
61 #if defined(_WIN32)
62 # if defined(_WIN32_WINNT)
63 #  undef _WIN32_WINNT
64 # endif
65 # define _WIN32_WINNT 0x501
66 #endif
67 #include "config.h"
68 #include "backoffice.h"
69 #include <time.h>
70 #if defined(_WIN32)
71 # include <windows.h>
72 # include <stdio.h>
73 # include <process.h>
74 # if defined(__MINGW32__)
75 #  include <wchar.h>
76 # endif
77 # define GETPID (int)GetCurrentProcessId
78 #else
79 # include <unistd.h>
80 # include <sys/types.h>
81 # include <signal.h>
82 # include <errno.h>
83 # include <sys/time.h>
84 # include <sys/resource.h>
85 # include <fcntl.h>
86 # define GETPID getpid
87 #endif
88 #include <time.h>
89 
90 /*
91 ** The BKOFCE_LEASE_TIME is the amount of time for which a single backoffice
92 ** processing run is valid.  Each backoffice run monopolizes the lease for
93 ** at least this amount of time.  Hopefully all backoffice processing is
94 ** finished much faster than this - usually in less than a second.  But
95 ** regardless of how long each invocation lasts, successive backoffice runs
96 ** must be spaced out by at least this much time.
97 */
98 #define BKOFCE_LEASE_TIME   60    /* Length of lease validity in seconds */
99 
100 #if LOCAL_INTERFACE
101 /*
102 ** An instance of the following object describes a lease on the backoffice
103 ** processing timeslot.  This lease is used to help ensure that no more than
104 ** one process is running backoffice at a time.
105 */
106 struct Lease {
107   sqlite3_uint64 idCurrent; /* process ID for the current lease holder */
108   sqlite3_uint64 tmCurrent; /* Expiration of the current lease */
109   sqlite3_uint64 idNext;    /* process ID for the next lease holder on queue */
110   sqlite3_uint64 tmNext;    /* Expiration of the next lease */
111 };
112 #endif
113 
114 /***************************************************************************
115 ** Local state variables
116 **
117 ** Set to prevent backoffice processing from ever entering sleep or
118 ** otherwise taking a long time to complete.  Set this when a user-visible
119 ** process might need to wait for backoffice to complete.
120 */
121 static int backofficeNoDelay = 0;
122 
123 /* This variable is set to the name of a database on which backoffice
124 ** should run if backoffice process is needed.  It is set by the
125 ** backoffice_check_if_needed() routine which must be run while the database
126 ** file is open.  Later, after the database is closed, the
127 ** backoffice_run_if_needed() will consult this variable to see if it
128 ** should be a no-op.
129 **
130 ** The magic string "x" in this variable means "do not run the backoffice".
131 */
132 static char *backofficeDb = 0;
133 
134 /*
135 ** Log backoffice activity to a file named here.  If not NULL, this
136 ** overrides the "backoffice-logfile" setting of the database.  If NULL,
137 ** the "backoffice-logfile" setting is used instead.
138 */
139 static const char *backofficeLogfile = 0;
140 
141 /*
142 ** Write the log message into this open file.
143 */
144 static FILE *backofficeFILE = 0;
145 
146 /*
147 ** Write backoffice log messages on this BLOB. to this connection:
148 */
149 static Blob *backofficeBlob = 0;
150 
151 /*
152 ** Non-zero for extra logging detail.
153 */
154 static int backofficeLogDetail = 0;
155 
156 /* End of state variables
157 ****************************************************************************/
158 
159 /*
160 ** This function emits a diagnostic message related to the processing in
161 ** this module.
162 */
163 #if defined(_WIN32)
164 # define BKOFCE_ALWAYS_TRACE   (1)
165 extern void sqlite3_win32_write_debug(const char *, int);
166 #else
167 # define BKOFCE_ALWAYS_TRACE   (0)
168 #endif
backofficeTrace(const char * zFormat,...)169 static void backofficeTrace(const char *zFormat, ...){
170   char *zMsg = 0;
171   if( BKOFCE_ALWAYS_TRACE || g.fAnyTrace ){
172     va_list ap;
173     va_start(ap, zFormat);
174     zMsg = sqlite3_vmprintf(zFormat, ap);
175     va_end(ap);
176 #if defined(_WIN32)
177     sqlite3_win32_write_debug(zMsg, -1);
178 #endif
179   }
180   if( g.fAnyTrace ) fprintf(stderr, "%s", zMsg);
181   if( zMsg ) sqlite3_free(zMsg);
182 }
183 
184 /*
185 ** Do not allow backoffice processes to sleep waiting on a timeslot.
186 ** They must either do their work immediately or exit.
187 **
188 ** In a perfect world, this interface would not exist, as there would
189 ** never be a problem with waiting backoffice threads.  But in some cases
190 ** a backoffice will delay a UI thread, so we don't want them to run for
191 ** longer than needed.
192 */
backoffice_no_delay(void)193 void backoffice_no_delay(void){
194   backofficeNoDelay = 1;
195 }
196 
197 /*
198 ** Sleeps for the specified number of milliseconds -OR- until interrupted
199 ** by another thread (if supported by the underlying platform).  Non-zero
200 ** will be returned if the sleep was interrupted.
201 */
backofficeSleep(int milliseconds)202 static int backofficeSleep(int milliseconds){
203 #if defined(_WIN32)
204   assert( milliseconds>=0 );
205   if( SleepEx((DWORD)milliseconds, TRUE)==WAIT_IO_COMPLETION ){
206     return 1;
207   }
208 #else
209   sqlite3_sleep(milliseconds);
210 #endif
211   return 0;
212 }
213 
214 /*
215 ** Parse a unsigned 64-bit integer from a string.  Return a pointer
216 ** to the character of z[] that occurs after the integer.
217 */
backofficeParseInt(const char * z,sqlite3_uint64 * pVal)218 static const char *backofficeParseInt(const char *z, sqlite3_uint64 *pVal){
219   *pVal = 0;
220   if( z==0 ) return 0;
221   while( fossil_isspace(z[0]) ){ z++; }
222   while( fossil_isdigit(z[0]) ){
223     *pVal = (*pVal)*10 + z[0] - '0';
224     z++;
225   }
226   return z;
227 }
228 
229 /*
230 ** Read the "backoffice" property and parse it into a Lease object.
231 **
232 ** The backoffice property should consist of four integers:
233 **
234 **    (1)  Process ID for the active backoffice process.
235 **    (2)  Time (seconds since 1970) for when the active backoffice
236 **         lease expires.
237 **    (3)  Process ID for the on-deck backoffice process.
238 **    (4)  Time when the on-deck process should expire.
239 **
240 ** No other process should start active backoffice processing until
241 ** process (1) no longer exists and the current time exceeds (2).
242 */
backofficeReadLease(Lease * pLease)243 static void backofficeReadLease(Lease *pLease){
244   Stmt q;
245   memset(pLease, 0, sizeof(*pLease));
246   db_unprotect(PROTECT_CONFIG);
247   db_prepare(&q, "SELECT value FROM repository.config"
248                  " WHERE name='backoffice'");
249   if( db_step(&q)==SQLITE_ROW ){
250     const char *z = db_column_text(&q,0);
251     z = backofficeParseInt(z, &pLease->idCurrent);
252     z = backofficeParseInt(z, &pLease->tmCurrent);
253     z = backofficeParseInt(z, &pLease->idNext);
254     backofficeParseInt(z, &pLease->tmNext);
255   }
256   db_finalize(&q);
257   db_protect_pop();
258 }
259 
260 /*
261 ** Return a string that describes how long it has been since the
262 ** last backoffice run.  The string is obtained from fossil_malloc().
263 */
backoffice_last_run(void)264 char *backoffice_last_run(void){
265   Lease x;
266   sqlite3_uint64 tmNow;
267   double rAge;
268   backofficeReadLease(&x);
269   tmNow = time(0);
270   if( x.tmCurrent==0 ){
271     return fossil_strdup("never");
272   }
273   if( tmNow<=(x.tmCurrent-BKOFCE_LEASE_TIME) ){
274     return fossil_strdup("moments ago");
275   }
276   rAge = (tmNow - (x.tmCurrent-BKOFCE_LEASE_TIME))/86400.0;
277   return mprintf("%z ago", human_readable_age(rAge));
278 }
279 
280 /*
281 ** Write a lease to the backoffice property
282 */
backofficeWriteLease(Lease * pLease)283 static void backofficeWriteLease(Lease *pLease){
284   db_unprotect(PROTECT_CONFIG);
285   db_multi_exec(
286     "REPLACE INTO repository.config(name,value,mtime)"
287     " VALUES('backoffice','%lld %lld %lld %lld',now())",
288     pLease->idCurrent, pLease->tmCurrent,
289     pLease->idNext, pLease->tmNext);
290   db_protect_pop();
291 }
292 
293 /*
294 ** Check to see if the specified Win32 process is still alive.  It
295 ** should be noted that even if this function returns non-zero, the
296 ** process may die before another operation on it can be completed.
297 */
298 #if defined(_WIN32)
299 #ifndef PROCESS_QUERY_LIMITED_INFORMATION
300 #  define PROCESS_QUERY_LIMITED_INFORMATION  (0x1000)
301 #endif
backofficeWin32ProcessExists(DWORD dwProcessId)302 static int backofficeWin32ProcessExists(DWORD dwProcessId){
303   HANDLE hProcess;
304   hProcess = OpenProcess(PROCESS_QUERY_LIMITED_INFORMATION,FALSE,dwProcessId);
305   if( hProcess==NULL ) return 0;
306   CloseHandle(hProcess);
307   return 1;
308 }
309 #endif
310 
311 /*
312 ** Check to see if the process identified by pid is alive.  If
313 ** we cannot prove that the process is dead, return true.
314 */
backofficeProcessExists(sqlite3_uint64 pid)315 static int backofficeProcessExists(sqlite3_uint64 pid){
316 #if defined(_WIN32)
317   return pid>0 && backofficeWin32ProcessExists((DWORD)pid)!=0;
318 #else
319   return pid>0 && kill((pid_t)pid, 0)==0;
320 #endif
321 }
322 
323 /*
324 ** Check to see if the process identified by pid has finished.  If
325 ** we cannot prove that the process is still running, return true.
326 */
backofficeProcessDone(sqlite3_uint64 pid)327 static int backofficeProcessDone(sqlite3_uint64 pid){
328 #if defined(_WIN32)
329   return pid<=0 || backofficeWin32ProcessExists((DWORD)pid)==0;
330 #else
331   return pid<=0 || kill((pid_t)pid, 0)!=0;
332 #endif
333 }
334 
335 /*
336 ** Return a process id number for the current process
337 */
backofficeProcessId(void)338 static sqlite3_uint64 backofficeProcessId(void){
339   return (sqlite3_uint64)GETPID();
340 }
341 
342 
343 /*
344 ** COMMAND: test-process-id
345 **
346 ** Usage: %fossil [--sleep N] PROCESS-ID ...
347 **
348 ** Show the current process id, and also tell whether or not all other
349 ** processes IDs on the command line are running or not.  If the --sleep N
350 ** option is provide, then sleep for N seconds before exiting.
351 */
test_process_id_command(void)352 void test_process_id_command(void){
353   const char *zSleep = find_option("sleep",0,1);
354   int i;
355   verify_all_options();
356   fossil_print("ProcessID for this process: %lld\n", backofficeProcessId());
357   if( zSleep ) sqlite3_sleep(1000*atoi(zSleep));
358   for(i=2; i<g.argc; i++){
359     sqlite3_uint64 x = (sqlite3_uint64)atoi(g.argv[i]);
360     fossil_print("ProcessId %lld: exists %d done %d\n",
361                  x, backofficeProcessExists(x),
362                     backofficeProcessDone(x));
363   }
364 }
365 
366 /*
367 ** COMMAND: test-backoffice-lease
368 **
369 ** Usage: %fossil test-backoffice-lease ?--reset?
370 **
371 ** Print out information about the backoffice "lease" entry in the
372 ** config table that controls whether or not backoffice should run.
373 **
374 ** If the --reset option is given, the backoffice lease is reset.
375 ** The use of the --reset option can be disruptive.  It can cause two
376 ** or more backoffice processes to be run simultaneously.  Use it with
377 ** caution.
378 */
test_backoffice_lease(void)379 void test_backoffice_lease(void){
380   sqlite3_int64 tmNow = time(0);
381   Lease x;
382   const char *zLease;
383   db_find_and_open_repository(0,0);
384   if( find_option("reset",0,0)!=0 ){
385     db_unprotect(PROTECT_CONFIG);
386     db_multi_exec(
387       "DELETE FROM repository.config WHERE name='backoffice'"
388     );
389     db_protect_pop();
390   }
391   verify_all_options();
392   zLease = db_get("backoffice","");
393   fossil_print("now:        %lld\n", tmNow);
394   fossil_print("lease:      \"%s\"\n", zLease);
395   backofficeReadLease(&x);
396   fossil_print("idCurrent:  %-20lld", x.idCurrent);
397   if( backofficeProcessExists(x.idCurrent) ) fossil_print(" (exists)");
398   if( backofficeProcessDone(x.idCurrent) ) fossil_print(" (done)");
399   fossil_print("\n");
400   fossil_print("tmCurrent:  %-20lld", x.tmCurrent);
401   if( x.tmCurrent>0 ){
402     fossil_print(" (now%+d)\n",x.tmCurrent-tmNow);
403   }else{
404     fossil_print("\n");
405   }
406   fossil_print("idNext:     %-20lld", x.idNext);
407   if( backofficeProcessExists(x.idNext) ) fossil_print(" (exists)");
408   if( backofficeProcessDone(x.idNext) ) fossil_print(" (done)");
409   fossil_print("\n");
410   fossil_print("tmNext:     %-20lld", x.tmNext);
411   if( x.tmNext>0 ){
412     fossil_print(" (now%+d)\n",x.tmNext-tmNow);
413   }else{
414     fossil_print("\n");
415   }
416 }
417 
418 /*
419 ** If backoffice processing is needed set the backofficeDb variable to the
420 ** name of the database file.  If no backoffice processing is needed,
421 ** this routine makes no changes to state.
422 */
backoffice_check_if_needed(void)423 void backoffice_check_if_needed(void){
424   Lease x;
425   sqlite3_uint64 tmNow;
426 
427   if( backofficeDb ) return;
428   if( g.zRepositoryName==0 ) return;
429   if( g.db==0 ) return;
430   if( !db_table_exists("repository","config") ) return;
431   if( db_get_boolean("backoffice-disable",0) ) return;
432   tmNow = time(0);
433   backofficeReadLease(&x);
434   if( x.tmNext>=tmNow && backofficeProcessExists(x.idNext) ){
435     /* Another backoffice process is already queued up to run.  This
436     ** process does not need to do any backoffice work. */
437     return;
438   }else{
439     /* We need to run backup to be (at a minimum) on-deck */
440     backofficeDb = fossil_strdup(g.zRepositoryName);
441   }
442 }
443 
444 /*
445 ** Call this routine to disable backoffice
446 */
backoffice_disable(void)447 void backoffice_disable(void){
448   backofficeDb = "x";
449 }
450 
451 /*
452 ** Check for errors prior to running backoffice_thread() or backoffice_run().
453 */
backoffice_error_check_one(int * pOnce)454 static void backoffice_error_check_one(int *pOnce){
455   if( *pOnce ){
456     fossil_panic("multiple calls to backoffice()");
457   }
458   *pOnce = 1;
459   if( g.db==0 ){
460     fossil_panic("database not open for backoffice processing");
461   }
462   if( db_transaction_nesting_depth()!=0 ){
463     fossil_panic("transaction %s not closed prior to backoffice processing",
464                  db_transaction_start_point());
465   }
466 }
467 
468 /* This is the main loop for backoffice processing.
469 **
470 ** If another process is already working as the current backoffice and
471 ** the on-deck backoffice, then this routine returns very quickly
472 ** without doing any work.
473 **
474 ** If no backoffice processes are running at all, this routine becomes
475 ** the main backoffice.
476 **
477 ** If a primary backoffice is running, but a on-deck backoffice is
478 ** needed, this routine becomes that on-deck backoffice.
479 */
backoffice_thread(void)480 static void backoffice_thread(void){
481   Lease x;
482   sqlite3_uint64 tmNow;
483   sqlite3_uint64 idSelf;
484   int lastWarning = 0;
485   int warningDelay = 30;
486   static int once = 0;
487 
488   if( sqlite3_db_readonly(g.db, 0) ) return;
489   g.zPhase = "backoffice";
490   backoffice_error_check_one(&once);
491   idSelf = backofficeProcessId();
492   while(1){
493     tmNow = time(0);
494     db_begin_write();
495     backofficeReadLease(&x);
496     if( x.tmNext>=tmNow
497      && x.idNext!=idSelf
498      && backofficeProcessExists(x.idNext)
499     ){
500       /* Another backoffice process is already queued up to run.  This
501       ** process does not need to do any backoffice work and can stop
502       ** immediately. */
503       db_end_transaction(0);
504       backofficeTrace("/***** Backoffice Processing Not Needed In %d *****/\n",
505                       GETPID());
506       break;
507     }
508     if( x.tmCurrent<tmNow && backofficeProcessDone(x.idCurrent) ){
509       /* This process can start doing backoffice work immediately */
510       x.idCurrent = idSelf;
511       x.tmCurrent = tmNow + BKOFCE_LEASE_TIME;
512       x.idNext = 0;
513       x.tmNext = 0;
514       backofficeWriteLease(&x);
515       db_end_transaction(0);
516       backofficeTrace("/***** Begin Backoffice Processing %d *****/\n",
517                       GETPID());
518       backoffice_work();
519       break;
520     }
521     if( backofficeNoDelay || db_get_boolean("backoffice-nodelay",0) ){
522       /* If the no-delay flag is set, exit immediately rather than queuing
523       ** up.  Assume that some future request will come along and handle any
524       ** necessary backoffice work. */
525       db_end_transaction(0);
526       backofficeTrace(
527            "/***** Backoffice No-Delay Exit For %d *****/\n",
528            GETPID());
529       break;
530     }
531     /* This process needs to queue up and wait for the current lease
532     ** to expire before continuing. */
533     x.idNext = idSelf;
534     x.tmNext = (tmNow>x.tmCurrent ? tmNow : x.tmCurrent) + BKOFCE_LEASE_TIME;
535     backofficeWriteLease(&x);
536     db_end_transaction(0);
537     backofficeTrace("/***** Backoffice On-deck %d *****/\n",  GETPID());
538     if( x.tmCurrent >= tmNow ){
539       if( backofficeSleep(1000*(x.tmCurrent - tmNow + 1)) ){
540         /* The sleep was interrupted by a signal from another thread. */
541         backofficeTrace("/***** Backoffice Interrupt %d *****/\n", GETPID());
542         db_end_transaction(0);
543         break;
544       }
545     }else{
546       if( lastWarning+warningDelay < tmNow ){
547         fossil_warning(
548            "backoffice process %lld still running after %d seconds",
549            x.idCurrent, (int)(BKOFCE_LEASE_TIME + tmNow - x.tmCurrent));
550         lastWarning = tmNow;
551         warningDelay *= 2;
552       }
553       if( backofficeSleep(1000) ){
554         /* The sleep was interrupted by a signal from another thread. */
555         backofficeTrace("/***** Backoffice Interrupt %d *****/\n", GETPID());
556         db_end_transaction(0);
557         break;
558       }
559     }
560   }
561   return;
562 }
563 
564 /*
565 ** Append to a message to the backoffice log, if the log is open.
566 */
backoffice_log(const char * zFormat,...)567 void backoffice_log(const char *zFormat, ...){
568   va_list ap;
569   if( backofficeBlob==0 ) return;
570   blob_append_char(backofficeBlob, ' ');
571   va_start(ap, zFormat);
572   blob_vappendf(backofficeBlob, zFormat, ap);
573   va_end(ap);
574 }
575 
576 #if !defined(_WIN32)
577 /*
578 ** Capture routine for signals while running backoffice.
579 */
backoffice_signal_handler(int sig)580 static void backoffice_signal_handler(int sig){
581   const char *zSig = 0;
582   if( sig==SIGSEGV ) zSig = "SIGSEGV";
583   if( sig==SIGFPE )  zSig = "SIGFPE";
584   if( sig==SIGABRT ) zSig = "SIGABRT";
585   if( sig==SIGILL )  zSig = "SIGILL";
586   if( zSig==0 ){
587     backoffice_log("signal-%d", sig);
588   }else{
589     backoffice_log("%s", zSig);
590   }
591   fprintf(backofficeFILE, "%s\n", blob_str(backofficeBlob));
592   fflush(backofficeFILE);
593   exit(1);
594 }
595 #endif
596 
597 #if !defined(_WIN32)
598 /*
599 ** Convert a struct timeval into an integer number of microseconds
600 */
tvms(struct timeval * p)601 static long long int tvms(struct timeval *p){
602   return ((long long int)p->tv_sec)*1000000 + (long long int)p->tv_usec;
603 }
604 #endif
605 
606 
607 /*
608 ** This routine runs to do the backoffice processing.  When adding new
609 ** backoffice processing tasks, add them here.
610 */
backoffice_work(void)611 void backoffice_work(void){
612   /* Log the backoffice run for testing purposes.  For production deployments
613   ** the "backoffice-logfile" property should be unset and the following code
614   ** should be a no-op. */
615   const char *zLog = backofficeLogfile;
616   Blob log;
617   int nThis;
618   int nTotal = 0;
619 #if !defined(_WIN32)
620   struct timeval sStart, sEnd;
621 #endif
622   if( zLog==0 ) zLog = db_get("backoffice-logfile",0);
623   if( zLog && zLog[0] && (backofficeFILE = fossil_fopen(zLog,"a"))!=0 ){
624     int i;
625     char *zName = db_get("project-name",0);
626 #if !defined(_WIN32)
627     gettimeofday(&sStart, 0);
628     signal(SIGSEGV, backoffice_signal_handler);
629     signal(SIGABRT, backoffice_signal_handler);
630     signal(SIGFPE, backoffice_signal_handler);
631     signal(SIGILL, backoffice_signal_handler);
632 #endif
633     if( zName==0 ){
634       zName = (char*)file_tail(g.zRepositoryName);
635       if( zName==0 ) zName = "(unnamed)";
636     }else{
637       /* Convert all spaces in the "project-name" into dashes */
638       for(i=0; zName[i]; i++){ if( zName[i]==' ' ) zName[i] = '-'; }
639     }
640     blob_init(&log, 0, 0);
641     backofficeBlob = &log;
642     blob_appendf(&log, "%s %s", db_text(0, "SELECT datetime('now')"), zName);
643   }
644 
645   /* Here is where the actual work of the backoffice happens */
646   nThis = alert_backoffice(0);
647   if( nThis ){ backoffice_log("%d alerts", nThis); nTotal += nThis; }
648   nThis = hook_backoffice();
649   if( nThis ){ backoffice_log("%d hooks", nThis); nTotal += nThis; }
650 
651   /* Close the log */
652   if( backofficeFILE ){
653     if( nTotal || backofficeLogDetail ){
654       if( nTotal==0 ) backoffice_log("no-op");
655 #if !defined(_WIN32)
656       gettimeofday(&sEnd,0);
657       backoffice_log("elapse-time %d us", tvms(&sEnd) - tvms(&sStart));
658 #endif
659       fprintf(backofficeFILE, "%s\n", blob_str(backofficeBlob));
660     }
661     fclose(backofficeFILE);
662   }
663 }
664 
665 /*
666 ** COMMAND: backoffice*
667 **
668 ** Usage: %fossil backoffice [OPTIONS...] [REPOSITORIES...]
669 **
670 ** Run backoffice processing on the repositories listed.  If no
671 ** repository is specified, run it on the repository of the local checkout.
672 **
673 ** This might be done by a cron job or similar to make sure backoffice
674 ** processing happens periodically.  Or, the --poll option can be used
675 ** to run this command as a daemon that will periodically invoke backoffice
676 ** on a collection of repositories.
677 **
678 ** If only a single repository is named and --poll is omitted, then the
679 ** backoffice work is done in-process.  But if there are multiple repositories
680 ** or if --poll is used, a separate sub-process is started for each poll of
681 ** each repository.
682 **
683 ** Standard options:
684 **
685 **    --debug                 Show what this command is doing.
686 **
687 **    --logfile FILE          Append a log of backoffice actions onto FILE.
688 **
689 **    --min N                 When polling, invoke backoffice at least
690 **                            once every N seconds even if the repository
691 **                            never changes.  0 or negative means disable
692 **                            this feature.  Default: 3600 (once per hour).
693 **
694 **    --poll N                Repeat backoffice calls for repositories that
695 **                            change in appoximately N-second intervals.
696 **                            N less than 1 turns polling off (the default).
697 **                            Recommended polling interval: 60 seconds.
698 **
699 **    --trace                 Enable debugging output on stderr
700 **
701 ** Options intended for internal use only which may change or be
702 ** discontinued in future releases:
703 **
704 **    --nodelay               Do not queue up or wait for a backoffice job
705 **                            to complete. If no work is available or if
706 **                            backoffice has run recently, return immediately.
707 **
708 **    --nolease               Always run backoffice, even if there is a lease
709 **                            conflict.  This option implies --nodelay.  This
710 **                            option is added to secondary backoffice commands
711 **                            that are invoked by the --poll option.
712 */
backoffice_command(void)713 void backoffice_command(void){
714   int nPoll;
715   int nMin;
716   const char *zPoll;
717   int bDebug = 0;
718   int bNoLease = 0;
719   unsigned int nCmd = 0;
720   if( find_option("trace",0,0)!=0 ) g.fAnyTrace = 1;
721   if( find_option("nodelay",0,0)!=0 ) backofficeNoDelay = 1;
722   backofficeLogfile = find_option("logfile",0,1);
723   zPoll = find_option("poll",0,1);
724   nPoll = zPoll ? atoi(zPoll) : 0;
725   zPoll = find_option("min",0,1);
726   nMin = zPoll ? atoi(zPoll) : 3600;
727   bDebug = find_option("debug",0,0)!=0;
728   bNoLease = find_option("nolease",0,0)!=0;
729 
730   /* Silently consume the -R or --repository flag, leaving behind its
731   ** argument. This is for legacy compatibility. Older versions of the
732   ** backoffice command only ran on a single repository that was specified
733   ** using the -R option. */
734   (void)find_option("repository","R",0);
735 
736   verify_all_options();
737   if( g.argc>3 || nPoll>0 ){
738     /* Either there are multiple repositories named on the command-line
739     ** or we are polling.  In either case, each backoffice should be run
740     ** using a separate sub-process */
741     int i;
742     time_t iNow = 0;
743     time_t ix;
744     i64 *aLastRun = fossil_malloc( sizeof(i64)*g.argc );
745     memset(aLastRun, 0, sizeof(i64)*g.argc );
746     while( 1 /* exit via "break;" */){
747       time_t iNext = time(0);
748       for(i=2; i<g.argc; i++){
749         Blob cmd;
750         if( !file_isfile(g.argv[i], ExtFILE) ){
751           continue;  /* Repo no longer exists.  Ignore it. */
752         }
753         if( iNow
754          && iNow>file_mtime(g.argv[i], ExtFILE)
755          && (nMin<=0 || aLastRun[i]+nMin>iNow)
756         ){
757           continue;  /* Not yet time to run this one */
758         }
759         blob_init(&cmd, 0, 0);
760         blob_append_escaped_arg(&cmd, g.nameOfExe, 1);
761         blob_append(&cmd, " backoffice --nodelay", -1);
762         if( g.fAnyTrace ){
763           blob_append(&cmd, " --trace", -1);
764         }
765         if( bDebug ){
766           blob_append(&cmd, " --debug", -1);
767         }
768         if( nPoll>0 ){
769           blob_append(&cmd, " --nolease", -1);
770         }
771         if( backofficeLogfile ){
772           blob_append(&cmd, " --logfile", -1);
773           blob_append_escaped_arg(&cmd, backofficeLogfile, 1);
774         }
775         blob_append_escaped_arg(&cmd, g.argv[i], 1);
776         nCmd++;
777         if( bDebug ){
778           fossil_print("COMMAND[%u]: %s\n", nCmd, blob_str(&cmd));
779         }
780         fossil_system(blob_str(&cmd));
781         aLastRun[i] = iNext;
782         blob_reset(&cmd);
783       }
784       if( nPoll<1 ) break;
785       iNow = iNext;
786       ix = time(0);
787       if( ix < iNow+nPoll ){
788         sqlite3_int64 nMS = (iNow + nPoll - ix)*1000;
789         if( bDebug )fossil_print("SLEEP: %lld\n", nMS);
790         sqlite3_sleep((int)nMS);
791       }
792     }
793   }else{
794     /* Not polling and only one repository named.  Backoffice is run
795     ** once by this process, which then exits */
796     if( g.argc==3 ){
797       g.zRepositoryOption = g.argv[2];
798       g.argc--;
799     }
800     db_find_and_open_repository(0,0);
801     if( bDebug ){
802       backofficeLogDetail = 1;
803     }
804     if( bNoLease ){
805       backoffice_work();
806     }else{
807       backoffice_thread();
808     }
809   }
810 }
811 
812 /*
813 ** This is the main interface to backoffice from the rest of the system.
814 ** This routine launches either backoffice_thread() directly or as a
815 ** subprocess.
816 */
backoffice_run_if_needed(void)817 void backoffice_run_if_needed(void){
818   if( backofficeDb==0 ) return;
819   if( strcmp(backofficeDb,"x")==0 ) return;
820   if( g.db ) return;
821   if( g.repositoryOpen ) return;
822 #if defined(_WIN32)
823   {
824     int i;
825     intptr_t x;
826     char *argv[4];
827     wchar_t *ax[5];
828     argv[0] = g.nameOfExe;
829     argv[1] = "backoffice";
830     argv[2] = "-R";
831     argv[3] = backofficeDb;
832     ax[4] = 0;
833     for(i=0; i<=3; i++) ax[i] = fossil_utf8_to_unicode(argv[i]);
834     x = _wspawnv(_P_NOWAIT, ax[0], (const wchar_t * const *)ax);
835     for(i=0; i<=3; i++) fossil_unicode_free(ax[i]);
836     backofficeTrace(
837       "/***** Subprocess %d creates backoffice child %lu *****/\n",
838       GETPID(), GetProcessId((HANDLE)x));
839     if( x>=0 ) return;
840   }
841 #else /* unix */
842   {
843     pid_t pid = fork();
844     if( pid>0 ){
845       /* This is the parent in a successful fork().  Return immediately. */
846       backofficeTrace(
847         "/***** Subprocess %d creates backoffice child %d *****/\n",
848         GETPID(), (int)pid);
849       return;
850     }
851     if( pid==0 ){
852       /* This is the child of a successful fork().  Run backoffice. */
853       int i;
854       setsid();
855       for(i=0; i<=2; i++){
856         close(i);
857         open("/dev/null", O_RDWR);
858       }
859       for(i=3; i<100; i++){ close(i); }
860       g.fDebug = 0;
861       g.httpIn = 0;
862       g.httpOut = 0;
863       db_open_repository(backofficeDb);
864       backofficeDb = "x";
865       backoffice_thread();
866       db_close(1);
867       backofficeTrace("/***** Backoffice Child %d exits *****/\n", GETPID());
868       exit(0);
869     }
870     fossil_warning("backoffice process %d fork failed, errno %d", GETPID(),
871                    errno);
872   }
873 #endif
874   /* Fork() failed or is unavailable.  Run backoffice in this process, but
875   ** do so with the no-delay setting.
876   */
877   backofficeNoDelay = 1;
878   db_open_repository(backofficeDb);
879   backofficeDb = "x";
880   backoffice_thread();
881   db_close(1);
882 }
883