Mise en route du suivi.
[aidenligne_francais_universite.git] / ecrire / inc / flock.php
1 <?php
2
3 /***************************************************************************\
4 * SPIP, Systeme de publication pour l'internet *
5 * *
6 * Copyright (c) 2001-2007 *
7 * Arnaud Martin, Antoine Pitrou, Philippe Riviere, Emmanuel Saint-James *
8 * *
9 * Ce programme est un logiciel libre distribue sous licence GNU/GPL. *
10 * Pour plus de details voir le fichier COPYING.txt ou l'aide en ligne. *
11 \***************************************************************************/
12
13
14 if (!defined("_ECRIRE_INC_VERSION")) return;
15
16 // http://doc.spip.org/@spip_file_get_contents
17 function spip_file_get_contents ($fichier) {
18 if (substr($fichier, -3) != '.gz') {
19 if (function_exists('file_get_contents')
20 AND os_serveur != 'windows') # windows retourne ''
21 return @file_get_contents ($fichier);
22 else
23 return join('', @file($fichier));
24 } else
25 return join('', @gzfile($fichier));
26 }
27
28 // options = array(
29 // 'phpcheck' => 'oui' # verifier qu'on a bien du php
30 // dezippe automatiquement les fichiers .gz
31 // http://doc.spip.org/@lire_fichier
32 function lire_fichier ($fichier, &$contenu, $options=false) {
33 $contenu = '';
34 if (!@file_exists($fichier))
35 return false;
36
37 #spip_timer('lire_fichier');
38
39 if ($fl = @fopen($fichier, 'r')) {
40
41 // verrou lecture
42 @flock($fl, LOCK_SH);
43
44 // a-t-il ete supprime par le locker ?
45 if (!@file_exists($fichier)) {
46 @fclose($fl);
47 return false;
48 }
49
50 // lire le fichier
51 $contenu = spip_file_get_contents($fichier);
52
53 // liberer le verrou
54 @flock($fl, LOCK_UN);
55 @fclose($fl);
56
57 // Verifications
58 $ok = true;
59 if ($options['phpcheck'] == 'oui')
60 $ok &= (ereg("[?]>\n?$", $contenu));
61
62 #spip_log("$fread $fichier ".spip_timer('lire_fichier'));
63 if (!$ok)
64 spip_log("echec lecture $fichier");
65
66 return $ok;
67 }
68 }
69
70
71 //
72 // Ecrire un fichier de maniere un peu sure
73 //
74 // zippe les fichiers .gz
75 // http://doc.spip.org/@ecrire_fichier
76 function ecrire_fichier ($fichier, $contenu, $ecrire_quand_meme = false, $truncate=true) {
77
78 // Ne rien faire si on est en preview, debug, ou si une erreur
79 // grave s'est presentee (compilation du squelette, MySQL, etc)
80 if ((
81 (isset($GLOBALS['var_preview'])&&$GLOBALS['var_preview'])
82 OR (isset($GLOBALS['var_mode'])&&($GLOBALS['var_mode'] == 'debug'))
83 OR defined('spip_interdire_cache'))
84 AND !$ecrire_quand_meme)
85 return;
86
87 $gzip = (substr($fichier, -3) == '.gz');
88
89 #spip_timer('ecrire_fichier');
90
91 // verrouiller le fichier destination
92 if ($fp = @fopen($fichier, 'a'))
93 @flock($fp, LOCK_EX);
94 else
95 return false;
96
97 // ecrire les donnees, compressees le cas echeant
98 // (on ouvre un nouveau pointeur sur le fichier, ce qui a l'avantage
99 // de le recreer si le locker qui nous precede l'avait supprime...)
100 if ($gzip) $contenu = gzencode($contenu);
101 if ($truncate)
102 @ftruncate($fp,0);
103 $s = @fputs($fp, $contenu, $a = strlen($contenu));
104
105 $ok = ($s == $a);
106
107 // liberer le verrou et fermer le fichier
108 @flock($fp, LOCK_UN);
109 @fclose($fp);
110
111 if (!$ok) {
112 spip_log("echec ecriture fichier $fichier");
113 @unlink($fichier);
114 }
115
116 return $ok;
117 }
118
119 //
120 // Supprimer le fichier de maniere sympa (flock)
121 //
122 // http://doc.spip.org/@supprimer_fichier
123 function supprimer_fichier($fichier) {
124 if (!@file_exists($fichier))
125 return;
126
127 // verrouiller le fichier destination
128 if ($fp = @fopen($fichier, 'a'))
129 @flock($fp, LOCK_EX);
130 else
131 return;
132
133 // liberer le verrou
134 @flock($fp, LOCK_UN);
135 @fclose($fp);
136
137 // supprimer
138 @unlink($fichier);
139 }
140
141
142 //
143 // Retourne $base/${subdir}/ si le sous-repertoire peut etre cree,
144 // $base/${subdir}_ sinon ; $nobase signale qu'on ne veut pas de $base/
145 // On peut aussi ne donner qu'un seul argument,
146 // subdir valant alors ce qui suit le dernier / dans $base
147 //
148 // http://doc.spip.org/@sous_repertoire
149 function sous_repertoire($base, $subdir='', $nobase = false) {
150 $base = str_replace("//", "/", $base);
151 if (preg_match(',[/_]$,', $base)) $base = substr($base,0,-1);
152 if (!strlen($subdir)) {
153 $n = strrpos($base, "/");
154 if ($n === false) return $nobase ? '' : ($base .'/');
155 $subdir = substr($base, $n+1);
156 $base = substr($base, 0, $n+1);
157 } else {
158 $base .= '/';
159 $subdir = str_replace("/", "", "$subdir");
160 }
161 $baseaff = $nobase ? '' : $base;
162
163 if (@file_exists("$base${subdir}.plat"))
164 return "$baseaff${subdir}_";;
165
166 $path = $base.$subdir; # $path = 'IMG/distant/pdf' ou 'IMG/distant_pdf'
167
168 if (file_exists("$path/.ok"))
169 return "$baseaff$subdir/";
170
171 @mkdir($path, _SPIP_CHMOD);
172 @chmod($path, _SPIP_CHMOD);
173
174 $ok = false;
175 if ($test = @fopen("$path/dir_test.php", "w")) {
176 @fputs($test, '<'.'?php $ok = true; ?'.'>');
177 @fclose($test);
178 @include("$path/dir_test.php");
179 @unlink("$path/dir_test.php");
180 }
181 if ($ok) {
182 @touch ("$path/.ok");
183 spip_log("creation $base$subdir/");
184 return "$baseaff$subdir/";
185 }
186
187 $f = @fopen("$base${subdir}.plat", "w");
188 if ($f)
189 fclose($f);
190 else {
191 spip_log("echec creation $base${subdir}");
192 if (!_DIR_RESTREINT)
193 $base = preg_replace(',^' . _DIR_RACINE .',', '',$base);
194 if ($test) $base .= $subdir;
195 include_spip('inc/headers');
196 redirige_par_entete(generer_url_action('test_dirs',"test_dir=$base",true));
197 }
198 spip_log("faux sous-repertoire $base${subdir}");
199 return "$baseaff${subdir}";
200 }
201
202 //
203 // Cette fonction parcourt recursivement le repertoire $dir, et renvoie les
204 // fichiers dont le chemin verifie le pattern (preg) donne en argument.
205 // En cas d'echec retourne un array() vide
206 //
207 // Usage: array preg_files('ecrire/data/', '[.]lock$');
208 //
209 // Attention, afin de conserver la compatibilite avec les repertoires '.plat'
210 // si $dir = 'rep/sous_rep_' au lieu de 'rep/sous_rep/' on scanne 'rep/' et on
211 // applique un pattern '^rep/sous_rep_'
212 // si $recurs vaut false, la fonction ne descend pas dans les sus repertoires
213 //
214 // http://doc.spip.org/@preg_files
215 function preg_files($dir, $pattern=-1 /* AUTO */, $maxfiles = 10000, $recurs=array()) {
216 $nbfiles = 0;
217 if ($pattern == -1)
218 $pattern = "^$dir";
219 $fichiers = array();
220 // revenir au repertoire racine si on a recu dossier/truc
221 // pour regarder dossier/truc/ ne pas oublier le / final
222 $dir = preg_replace(',/[^/]*$,', '', $dir);
223 if ($dir == '') $dir = '.';
224
225 if (@is_dir($dir) AND is_readable($dir) AND $d = @opendir($dir)) {
226 while (($f = readdir($d)) !== false && ($nbfiles<$maxfiles)) {
227 if ($f[0] != '.' # ignorer . .. .svn etc
228 AND $f != 'CVS'
229 AND $f != 'remove.txt'
230 AND is_readable($f = "$dir/$f")) {
231 if (is_file($f)) {
232 if (preg_match(";$pattern;iS", $f))
233 {
234 $fichiers[] = $f;
235 $nbfiles++;
236 }
237 }
238 else if (is_dir($f) AND is_array($recurs)){
239 $rp = @realpath($f);
240 if (!is_string($rp) OR !strlen($rp)) $rp=$f; # realpath n'est peut etre pas autorise
241 if (!isset($recurs[$rp])) {
242 $recurs[$rp] = true;
243 $beginning = $fichiers;
244 $end = preg_files("$f/", $pattern,
245 $maxfiles-$nbfiles, $recurs);
246 $fichiers = array_merge((array)$beginning, (array)$end);
247 $nbfiles = count($fichiers);
248 }
249 }
250 }
251 }
252 closedir($d);
253 }
254 else {
255 spip_log("repertoire $dir absent ou illisible");
256 }
257 sort($fichiers);
258 return $fichiers;
259 }
260
261 ?>