1#!/usr/bin/php 2<?php 3if ('cli' != php_sapi_name()) die(); 4 5ini_set('memory_limit','128M'); 6if(!defined('DOKU_INC')) define('DOKU_INC',realpath(dirname(__FILE__).'/../').'/'); 7require_once(DOKU_INC.'inc/init.php'); 8require_once(DOKU_INC.'inc/common.php'); 9require_once(DOKU_INC.'inc/pageutils.php'); 10require_once(DOKU_INC.'inc/search.php'); 11require_once(DOKU_INC.'inc/indexer.php'); 12require_once(DOKU_INC.'inc/auth.php'); 13require_once(DOKU_INC.'inc/cliopts.php'); 14session_write_close(); 15 16// Version tag used to force rebuild on upgrade 17// Need to keep in sync with lib/exe/indexer.php 18if(!defined('INDEXER_VERSION')) define('INDEXER_VERSION', 2); 19 20// handle options 21$short_opts = 'hcuq'; 22$long_opts = array('help', 'clear', 'update', 'quiet'); 23$OPTS = Doku_Cli_Opts::getOptions(__FILE__,$short_opts,$long_opts); 24if ( $OPTS->isError() ) { 25 fwrite( STDERR, $OPTS->getMessage() . "\n"); 26 _usage(); 27 exit(1); 28} 29$CLEAR = false; 30$QUIET = false; 31foreach ($OPTS->options as $key => $val) { 32 switch ($key) { 33 case 'h': 34 case 'help': 35 _usage(); 36 exit; 37 case 'c': 38 case 'clear': 39 $CLEAR = true; 40 break; 41 case 'q': 42 case 'quiet': 43 $QUIET = true; 44 break; 45 } 46} 47 48#------------------------------------------------------------------------------ 49# Action 50 51if($CLEAR) _clearindex(); 52_update(); 53 54 55 56#------------------------------------------------------------------------------ 57 58function _usage() { 59 print "Usage: indexer.php <options> 60 61 Updates the searchindex by indexing all new or changed pages 62 when the -c option is given the index is cleared first. 63 64 OPTIONS 65 -h, --help show this help and exit 66 -c, --clear clear the index before updating 67 -q, --quiet don't produce any output 68"; 69} 70 71function _update(){ 72 global $conf; 73 74 $data = array(); 75 _quietecho("Searching pages... "); 76 search($data,$conf['datadir'],'search_allpages',array('skipacl' => true)); 77 _quietecho(count($data)." pages found.\n"); 78 79 foreach($data as $val){ 80 _index($val['id']); 81 } 82} 83 84function _index($id){ 85 global $CLEAR; 86 87 // if not cleared only update changed and new files 88 if(!$CLEAR){ 89 $idxtag = metaFN($id,'.indexed'); 90 if(@file_exists($idxtag)){ 91 if(io_readFile($idxtag) >= INDEXER_VERSION){ 92 $last = @filemtime(metaFN($id,'.indexed')); 93 if($last > @filemtime(wikiFN($id))) return; 94 } 95 } 96 } 97 98 _lock(); 99 _quietecho("$id... "); 100 idx_addPage($id); 101 io_saveFile(metaFN($id,'.indexed'),INDEXER_VERSION); 102 _quietecho("done.\n"); 103 _unlock(); 104} 105 106/** 107 * lock the indexer system 108 */ 109function _lock(){ 110 global $conf; 111 $lock = $conf['lockdir'].'/_indexer.lock'; 112 $said = false; 113 while(!@mkdir($lock, $conf['dmode'])){ 114 if(time()-@filemtime($lock) > 60*5){ 115 // looks like a stale lock - remove it 116 @rmdir($lock); 117 }else{ 118 if($said){ 119 _quietecho("."); 120 }else{ 121 _quietecho("Waiting for lockfile (max. 5 min)"); 122 $said = true; 123 } 124 sleep(15); 125 } 126 } 127 if($conf['dperm']) chmod($lock, $conf['dperm']); 128 if($said) _quietecho("\n"); 129} 130 131/** 132 * unlock the indexer sytem 133 */ 134function _unlock(){ 135 global $conf; 136 $lock = $conf['lockdir'].'/_indexer.lock'; 137 @rmdir($lock); 138} 139 140/** 141 * Clear all index files 142 */ 143function _clearindex(){ 144 global $conf; 145 _lock(); 146 _quietecho("Clearing index... "); 147 io_saveFile($conf['indexdir'].'/page.idx',''); 148 io_saveFile($conf['indexdir'].'/title.idx',''); 149 $dir = @opendir($conf['indexdir']); 150 if($dir!==false){ 151 while(($f = readdir($dir)) !== false){ 152 if(substr($f,-4)=='.idx' && 153 (substr($f,0,1)=='i' || substr($f,0,1)=='w')) 154 @unlink($conf['indexdir']."/$f"); 155 } 156 } 157 _quietecho("done.\n"); 158 _unlock(); 159} 160 161function _quietecho($msg) { 162 global $QUIET; 163 if(!$QUIET) echo $msg; 164} 165 166//Setup VIM: ex: et ts=2 enc=utf-8 : 167