Subversion Repositories Sites.tela-botanica.org

Rev

Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
7 david 1
<?php
2
 
3
/***************************************************************************\
4
 *  SPIP, Systeme de publication pour l'internet                           *
5
 *                                                                         *
6
 *  Copyright (c) 2001-2005                                                *
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
//
15
// Ce fichier ne sera execute qu'une fois
16
if (defined("_ECRIRE_INC_VERSION")) return;
17
define("_ECRIRE_INC_VERSION", "1");
18
 
19
function define_once ($constant, $valeur) {
20
	if (!defined($constant)) define($constant, $valeur);
21
}
22
 
23
// 6 constantes incontournables et prioritaires
24
 
25
define('_EXTENSION_PHP', '.php3'); # a etendre
26
define('_DIR_RESTREINT_ABS', 'ecrire/');
27
define('_DIR_RESTREINT', (!@is_dir(_DIR_RESTREINT_ABS) ? "" : _DIR_RESTREINT_ABS));
28
define('_FILE_OPTIONS', _DIR_RESTREINT . 'mes_options.php3');
29
define('_FILE_CONNECT_INS', (_DIR_RESTREINT . "inc_connect"));
30
define('_FILE_CONNECT',
31
	(@file_exists(_FILE_CONNECT_INS . _EXTENSION_PHP) ?
32
		(_FILE_CONNECT_INS . _EXTENSION_PHP)
33
	 : false));
34
 
35
//
36
// Gestion des inclusions et infos repertoires
37
//
38
 
39
$included_files = array();
40
 
41
function include_local($file) {
42
	if (@$GLOBALS['included_files'][$file]++) return;
43
	include($file);
44
}
45
 
46
function include_ecrire($file) {
47
# Hack pour etre compatible avec les mes_options qui appellent cette fonction
48
	define_once('_DIR_INCLUDE', _DIR_RESTREINT);
49
	$file = _DIR_INCLUDE . $file;
50
	if (@$GLOBALS['included_files'][$file]++) return;
51
	include($file);
52
}
53
 
54
function include_lang($file) {
55
	$file = _DIR_LANG . $file;
56
	if (@$GLOBALS['included_files'][$file]++) return;
57
	include($file);
58
}
59
 
60
function include_plug($file) {
61
	$file = _DIR_RESTREINT . $file;
62
	if (@$GLOBALS['included_files'][$file]++) return;
63
	if (file_exists($file)) include($file);
64
}
65
 
66
 
67
// *********** traiter les variables ************
68
 
69
// Recuperer les superglobales $_GET si non definies
70
// (en theorie c'est impossible depuis PHP 4.0.3, cf. track_vars)
71
// et les identifier aux $HTTP_XX_VARS
72
foreach (array('_GET', '_POST', '_COOKIE', '_SERVER') as $_table) {
73
	$http_table_vars = 'HTTP'.$_table.'_VARS';
74
	if (!is_array($GLOBALS[$_table])) {
75
		$GLOBALS[$_table] = array();
76
		if (is_array($GLOBALS[$http_table_vars]))
77
			$GLOBALS[$_table] = & $GLOBALS[$http_table_vars];
78
	}
79
		$GLOBALS[$http_table_vars] = & $GLOBALS[$_table];
80
}
81
 
82
 
83
// Magic quotes : on n'en veut pas sur la base,
84
// et on nettoie les GET/POST/COOKIE le cas echeant
85
function magic_unquote($_table) {
86
 
87
	// Certains hebergeurs n'activent pas $GLOBALS['GLOBALS']
88
	if ($_table == 'GLOBALS'
89
	AND !isset($GLOBALS['GLOBALS']))
90
		$GLOBALS['GLOBALS'] = &$GLOBALS;
91
 
92
	if (is_array($GLOBALS[$_table])) {
93
		foreach ($GLOBALS[$_table] as $key => $val) {
94
			if (is_string($val))
95
				$GLOBALS[$_table][$key] = stripslashes($val);
96
		}
97
	}
98
}
99
 
100
@set_magic_quotes_runtime(0);
101
if (@get_magic_quotes_gpc()) {
102
	magic_unquote('_GET');
103
	magic_unquote('_POST');
104
	magic_unquote('_COOKIE');
105
 
106
#	if (@ini_get('register_globals')) // pas fiable
107
		magic_unquote('GLOBALS');
108
}
109
 
110
 
111
 
112
// Dirty hack contre le register_globals a 'Off' (PHP 4.1.x)
113
// A remplacer (un jour!) par une gestion propre des variables admissibles ;-)
114
// Attention pour compatibilite max $_GET n'est pas superglobale
115
// NB: c'est une fonction de maniere a ne pas pourrir $GLOBALS
116
function spip_register_globals() {
117
 
118
	// Liste des variables dont on refuse qu'elles puissent provenir du client
119
	$refuse_gpc = array (
120
		# inc-public.php3
121
		'fond', 'delais',
122
 
123
		# ecrire/inc_auth.php3
124
		'REMOTE_USER',
125
		'PHP_AUTH_USER', 'PHP_AUTH_PW',
126
 
127
		# ecrire/inc_texte.php3
128
		'debut_intertitre', 'fin_intertitre', 'ligne_horizontale',
129
		'ouvre_ref', 'ferme_ref', 'ouvre_note', 'ferme_note',
130
		'les_notes', 'compt_note', 'nombre_surligne',
131
		'url_glossaire_externe', 'puce', 'puce_rtl'
132
	);
133
 
134
	// Liste des variables (contexte) dont on refuse qu'elles soient cookie
135
	// (histoire que personne ne vienne fausser le cache)
136
	$refuse_c = array (
137
		# inc-calcul.php3
138
		'id_parent', 'id_rubrique', 'id_article',
139
		'id_auteur', 'id_breve', 'id_forum', 'id_secteur',
140
		'id_syndic', 'id_syndic_article', 'id_mot', 'id_groupe',
141
		'id_document', 'date', 'lang'
142
	);
143
 
144
 
145
	// Si les variables sont passees en global par le serveur, il faut
146
	// faire quelques verifications de base
147
	if (@ini_get('register_globals')) {
148
		foreach ($refuse_gpc as $var) {
149
			if (isset($GLOBALS[$var])) {
150
				foreach (array('_GET', '_POST', '_COOKIE') as $_table) {
151
					if (
152
					// demande par le client
153
					isset ($GLOBALS[$_table][$var])
154
					// et pas modifie par les fichiers d'appel
155
					AND $GLOBALS[$_table][$var] == $GLOBALS[$var]
156
					) // On ne sait pas si c'est un hack
157
					{
158
						# REMOTE_USER ou fond, c'est grave ;
159
						# pour le reste (cookie 'lang', par exemple), simplement
160
						# interdire la mise en cache de la page produite
161
						switch ($var) {
162
							case 'REMOTE_USER':
163
							case 'fond':
164
								die ("$var interdite");
165
								break;
166
							default:
167
								define ('spip_interdire_cache', true);
168
						}
169
					}
170
				}
171
			}
172
		}
173
		foreach ($refuse_c as $var) {
174
			if (isset($GLOBALS[$var])) {
175
				foreach (array('_COOKIE') as $_table) {
176
					if (
177
					// demande par le client
178
					isset ($GLOBALS[$_table][$var])
179
					// et pas modifie par les fichiers d'appel
180
					AND $GLOBALS[$_table][$var] == $GLOBALS[$var]
181
					)
182
						define ('spip_interdire_cache', true);
183
				}
184
			}
185
		}
186
	}
187
 
188
	// sinon il faut les passer nous-memes, a l'exception des interdites.
189
	// (A changer en une liste des variables admissibles...)
190
	else {
191
		foreach (array('_SERVER', '_COOKIE', '_POST', '_GET') as $_table) {
192
			foreach ($GLOBALS[$_table] as $var => $val) {
193
				if (!isset($GLOBALS[$var])
194
				AND isset($GLOBALS[$_table][$var])
195
				AND ($_table == '_SERVER' OR !in_array($var, $refuse_gpc))
196
				AND ($_table <> '_COOKIE' OR !in_array($var, $refuse_c)))
197
					$GLOBALS[$var] = $val;
198
			}
199
		}
200
	}
201
}
202
spip_register_globals();
203
 
204
 
205
 
206
 
207
 
208
//
209
// *** Parametrage par defaut de SPIP ***
210
//
211
// Ces parametres d'ordre technique peuvent etre modifies
212
// dans ecrire/mes_options.php3 (_FILE_OPTIONS) Les valeurs
213
// specifiees dans ce dernier fichier remplaceront automatiquement
214
// les valeurs ci-dessous.
215
//
216
// Pour creer ecrire/mes_options.php3 : recopier simplement
217
// les lignes ci-dessous, et ajouter le marquage de debut et
218
// de fin de fichier PHP ("< ?php" et "? >", sans les espaces)
219
//
220
 
221
// Prefixe des tables dans la base de donnees
222
// (a modifier pour avoir plusieurs sites SPIP dans une seule base)
223
$table_prefix = "spip";
224
 
225
// Prefixe et chemin des cookies
226
// (a modifier pour installer des sites SPIP dans des sous-repertoires)
227
$cookie_prefix = "spip";
228
$cookie_path = "";
229
 
230
// Dossier des squelettes
231
// (a modifier si l'on veut passer rapidement d'un jeu de squelettes a un autre)
232
$dossier_squelettes = "";
233
 
234
// faut-il autoriser SPIP a compresser les pages a la volee quand le
235
// navigateur l'accepte (valable pour apache >= 1.3 seulement) ?
236
$auto_compress = true;
237
 
238
// Type d'URLs
239
// 'standard': article.php3?id_article=123
240
// 'html': article123.html
241
// 'propres': Titre-de-l-article <http://lab.spip.net/spikini/UrlsPropres>
242
// 'propres2' : Titre-de-l-article.html (base sur 'propres')
243
$type_urls = 'standard';
244
 
245
// creation des vignettes avec image magick en ligne de commande : mettre
246
// le chemin complet '/bin/convert' (Linux) ou '/sw/bin/convert' (fink/Mac OS X)
247
// Note : preferer GD2 ou le module php imagick s'ils sont disponibles
248
$convert_command = 'convert';
249
 
250
// creation des vignettes avec pnmscale
251
// Note: plus facile a installer par FTP,
252
// voir http://gallery.menalto.com/modules.php?op=modload&name=GalleryFAQ&file=index&myfaq=yes&id_cat=2#43
253
$pnmscale_command = 'pnmscale';
254
 
255
// faut-il passer les connexions MySQL en mode debug ?
256
$mysql_debug = false;
257
 
258
// faut-il chronometrer les requetes MySQL ?
259
$mysql_profile = false;
260
 
261
// faut-il faire des connexions completes rappelant le nom du serveur et/ou de
262
// la base MySQL ? (utile si vos squelettes appellent d'autres bases MySQL)
263
// (A desactiver en cas de soucis de connexion chez certains hebergeurs)
264
// Note: un test a l'installation peut aussi avoir desactive
265
// $mysql_rappel_nom_base directement dans le fichier inc_connect.php3
266
$mysql_rappel_connexion = true;
267
$mysql_rappel_nom_base = true;
268
 
269
// faut-il afficher en rouge les chaines non traduites ?
270
$test_i18n = false;
271
 
272
// faut-il souligner en gris, dans articles.php3, les espaces insecables ?
273
$activer_revision_nbsp = false;
274
 
275
// gestion des extras (voir inc_extra.php3 pour plus d'informations)
276
$champs_extra = false;
277
$champs_extra_proposes = false;
278
 
279
// faut-il ignorer l'authentification par auth http/remote_user ?
280
$ignore_auth_http = false;
281
$ignore_remote_user = true; # methode obsolete et risquee
282
 
283
// Faut-il "invalider" les caches quand on depublie ou modifie un article ?
284
// (experimental)
285
# NB: cette option ne concerne que articles,breves,rubriques et site
286
# car les forums et petitions sont toujours invalidants.
287
$invalider_caches = false;
288
 
289
// Quota : la variable $quota_cache, si elle est > 0, indique la taille
290
// totale maximale desiree des fichiers contenus dans le CACHE/ ;
291
// ce quota n'est pas "dur", il ne s'applique qu'une fois par heure et
292
// fait redescendre le cache a la taille voulue ; valeur en Mo
293
// Si la variable vaut 0 aucun quota ne s'applique
294
$quota_cache = 10;
295
 
296
// code a fournir pour obtenir le debuggueur (urls &var_mode=debug)
297
// par defaut seuls les admins : $code_activation_debug='';
298
// pour mettre un mot de passe : $code_activation_debug='x5g8jk9';
299
$code_activation_debug = '';
300
 
301
//
302
// Serveurs externes
303
//
304
# aide en ligne
305
$help_server = 'http://www.spip.net/aide';
306
# TeX
307
$tex_server = 'http://math.spip.org/tex.php';
308
# MathML (pas pour l'instant: manque un bon convertisseur)
309
// $mathml_server = 'http://arno.rezo.net/tex2mathml/latex.php';
310
# Orthographe (serveurs multiples) [pas utilise pour l'instant]
311
$ortho_servers = array ('http://ortho.spip.net/ortho_serveur.php');
312
 
313
// Produire du TeX ou du MathML ?
314
$traiter_math = 'tex';
315
 
316
// Masquer les warning
317
error_reporting(E_ALL ^ E_NOTICE);
318
 
319
// Variables du compilateur de squelettes
320
 
321
$exceptions_des_tables = array();
322
$tables_principales = array();
323
$table_des_tables = array();
324
$tables_relations = array();
325
$tables_relations_keys = array();
326
$table_primary = array();
327
$table_date = array();
328
$tables_des_serveurs_sql['localhost'] =  &$tables_principales;
329
 
330
/* ATTENTION CETTE VARIABLE NE FONCTIONNE PAS ENCORE */
331
// Extension du fichier du squelette
332
$extension_squelette = 'html';
333
/* / MERCI DE VOTRE ATTENTION */
334
 
335
// Droits d'acces maximum par defaut
336
@umask(0);
337
 
338
//
339
// Definition des repertoires standards, _FILE_OPTIONS ayant priorite
340
//
341
 
342
if (@file_exists(_FILE_OPTIONS)) {
343
	include(_FILE_OPTIONS);
344
}
345
 
346
// la taille maxi des logos (0 : pas de limite)
347
define_once('_LOGO_MAX_SIZE', 0); # poids en ko
348
define_once('_LOGO_MAX_WIDTH', 0); # largeur en pixels
349
define_once('_LOGO_MAX_HEIGHT', 0); # hauteur en pixels
350
 
351
 
352
define_once('_DIR_INCLUDE', _DIR_RESTREINT);
353
define_once('_DIR_PREFIX1', (_DIR_RESTREINT ? "" : "../"));
354
define_once('_DIR_PREFIX2', _DIR_RESTREINT);
355
 
356
// les repertoires des logos, des documents joints, du CACHE et des sessions
357
define_once('_DIR_IMG', _DIR_PREFIX1 ."IMG/");
358
define_once('_DIR_DOC', _DIR_PREFIX1 ."IMG/");
359
define_once('_DIR_CACHE', _DIR_PREFIX1 ."CACHE/");
360
 
361
define_once('_DIR_SESSIONS', _DIR_PREFIX2 . "data/");
362
define_once('_DIR_TRANSFERT', _DIR_PREFIX2 . "upload/");
363
 
364
 
365
// exemples de redefinition possible,
366
// SOUS RESERVE QUE php.ini N'AIT PAS pas openbasedir=. !!!!!!
367
// il est recommande de mettre les deux premiers en dehors de l'arbo http
368
// pour _DIR_DOC, on ne peut le faire qu'en configuration securisee
369
// pour _DIR_IMG, NE PAS LE METTRE en dehors de l'arborescence http
370
 
371
//define('_DIR_CACHE', "/tmp/c/");
372
//define('_DIR_SESSIONS', "/tmp/s/");
373
 
374
//define('_DIR_DOC', "/tmp/d/");
375
//define('_DIR_INCLUDE', _DIR_RESTREINT  ? 'Include/' : '../Include/');
376
// globale des repertoires devant etre accessibles en ecriture
377
// (inutile de mettre leurs sous-repertoires)
378
 
379
$test_dirs = array(_DIR_CACHE, _DIR_IMG, _DIR_SESSIONS);
380
 
381
// les fichiers qu'on y met, entre autres,
382
 
383
define_once('_FILE_CRON_LOCK', _DIR_SESSIONS . 'cron.lock');
384
define_once('_FILE_MYSQL_OUT', _DIR_SESSIONS . 'mysql_out');
385
define_once('_FILE_GARBAGE', _DIR_SESSIONS . '.poubelle');
386
 
387
 
388
// sous-repertoires d'images accessible en ecriture
389
 
390
define_once('_DIR_IMG_ICONES', _DIR_IMG . "icones/");
391
define_once('_DIR_IMG_ICONES_BARRE', _DIR_IMG . "icones_barre/");
392
define_once('_DIR_TeX', _DIR_IMG . "cache-TeX/");
393
 
394
// pour ceux qui n'aiment pas nos icones et notre vocabulaire, tout est prevu
395
 
396
define_once('_DIR_IMG_PACK', (_DIR_RESTREINT . 'img_pack/'));
397
define_once('_DIR_LANG', (_DIR_RESTREINT . 'lang/'));
398
 
399
// qq chaines standard
400
 
401
define_once('_ACCESS_FILE_NAME', '.htaccess');
402
define_once('_AUTH_USER_FILE', '.htpasswd');
403
 
404
 
405
// tidy en ligne de commande (si on ne l'a pas en module php,
406
// ou si le module php ne marche pas)
407
// '/bin/tidy' ou '/usr/local/bin/tidy' ou tout simplement 'tidy'
408
#define_once('_TIDY_COMMAND', 'tidy');
409
 
410
// Version courante de SPIP
411
// Stockee sous forme de nombre decimal afin de faciliter les comparaisons
412
// (utilise pour les modifs de la base de donnees)
413
 
414
// version de la base
415
$spip_version = 1.821;
416
 
417
// version de spip
418
$spip_version_affichee = "1.8.2";
419
 
420
 
421
// ** Securite **
422
$auteur_session = '';
423
$connect_statut = '';
424
$hash_recherche = '';
425
$hash_recherche_strict = '';
426
 
427
 
428
 
429
//
430
// Capacites php (en fonction de la version)
431
//
432
 
433
$flag_get_cfg_var = (@get_cfg_var('error_reporting') != "");
434
$flag_ini_get = (function_exists("ini_get")
435
	&& (@ini_get('max_execution_time') > 0));	// verifier pas desactivee
436
$flag_gz = function_exists("gzencode"); #php 4.0.4
437
$flag_ob = ($flag_ini_get
438
	&& !ereg("ob_", ini_get('disable_functions'))
439
	&& function_exists("ob_start"));
440
$flag_crypt = function_exists("crypt");
441
$flag_wordwrap = function_exists("wordwrap");
442
$flag_apc = function_exists("apc_rm");
443
$flag_sapi_name = function_exists("php_sapi_name");
444
$flag_utf8_decode = function_exists("utf8_decode");
445
$flag_ldap = function_exists("ldap_connect");
446
$flag_flock = function_exists("flock");
447
$flag_ImageCreateTrueColor = function_exists("ImageCreateTrueColor");
448
$flag_ImageCopyResampled = function_exists("ImageCopyResampled");
449
$flag_ImageGif = function_exists("ImageGif");
450
$flag_ImageJpeg = function_exists("ImageJpeg");
451
$flag_ImagePng = function_exists("ImagePng");
452
$flag_imagick = function_exists("imagick_readimage");	// http://pear.sourceforge.net/en/packages.imagick.php
453
 
454
$flag_gd = $flag_ImageGif || $flag_ImageJpeg || $flag_ImagePng;
455
$flag_revisions = function_exists("gzcompress");
456
 
457
//
458
// Appliquer le prefixe cookie
459
//
460
function spip_setcookie ($name='', $value='', $expire=0, $path='AUTO', $domain='', $secure='') {
461
	$name = ereg_replace ('^spip_', $GLOBALS['cookie_prefix'].'_', $name);
462
	if ($path == 'AUTO') $path=$GLOBALS['cookie_path'];
463
 
464
	if ($secure)
465
		@setcookie ($name, $value, $expire, $path, $domain, $secure);
466
	else if ($domain)
467
		@setcookie ($name, $value, $expire, $path, $domain);
468
	else if ($path)
469
		@setcookie ($name, $value, $expire, $path);
470
	else if ($expire)
471
		@setcookie ($name, $value, $expire);
472
	else
473
		@setcookie ($name, $value);
474
}
475
 
476
if ($cookie_prefix != 'spip') {
477
	foreach ($_COOKIE as $name => $value) {
478
		if (ereg('^spip_', $name)) {
479
			unset($_COOKIE[$name]);
480
			unset($$name);
481
		}
482
	}
483
	foreach ($_COOKIE as $name => $value) {
484
		if (ereg('^'.$cookie_prefix.'_', $name)) {
485
			$spipname = ereg_replace ('^'.$cookie_prefix.'_', 'spip_', $name);
486
			$_COOKIE[$spipname] = $INSECURE[$spipname] = $value;
487
			$$spipname = $value;
488
		}
489
	}
490
}
491
 
492
 
493
//
494
// Sommes-nous dans l'empire du Mal ?
495
//
496
if (strpos($_SERVER['SERVER_SOFTWARE'], '(Win') !== false)
497
	define ('os_serveur', 'windows');
498
 
499
 
500
//
501
// Non ! Car le GNU veille... (Entete HTTP de frimeur)
502
//
503
if (!headers_sent())
504
	@header("Composed-By: SPIP $spip_version_affichee @ www.spip.net");
505
 
506
 
507
//
508
// Enregistrement des evenements
509
//
510
function spip_log($message, $logname='spip') {
511
 
512
	$pid = '(pid '.@getmypid().')';
513
	if (!$ip = $GLOBALS['REMOTE_ADDR']) $ip = '-';
514
 
515
	$message = date("M d H:i:s")." $ip $pid "
516
		.ereg_replace("\n*$", "\n", $message);
517
 
518
	$logfile = _DIR_SESSIONS . $logname . '.log';
519
	if (@file_exists($logfile) && (@filesize($logfile) > 10*1024)) {
520
		$rotate = true;
521
		$message .= "[-- rotate --]\n";
522
	}
523
	$f = @fopen($logfile, "ab");
524
	if ($f) {
525
		fputs($f, $message);
526
		fclose($f);
527
	}
528
	if ($rotate) {
529
		@unlink($logfile.'.3');
530
		@rename($logfile.'.2',$logfile.'.3');
531
		@rename($logfile.'.1',$logfile.'.2');
532
		@rename($logfile,$logfile.'.1');
533
	}
534
 
535
	// recopier les spip_log mysql (ce sont uniquement des erreurs)
536
	// dans le spip_log general
537
	if ($logname == 'mysql')
538
		spip_log($message);
539
}
540
 
541
 
542
//
543
// Infos sur le fichier courant
544
//
545
 
546
// Compatibilite avec serveurs ne fournissant pas $REQUEST_URI
547
if (!$REQUEST_URI) {
548
	$REQUEST_URI = $PHP_SELF;
549
	if ($QUERY_STRING AND !strpos($REQUEST_URI, '?'))
550
		$REQUEST_URI .= '?'.$QUERY_STRING;
551
}
552
 
553
if (!$PATH_TRANSLATED) {
554
	if ($SCRIPT_FILENAME) $PATH_TRANSLATED = $SCRIPT_FILENAME;
555
	else if ($DOCUMENT_ROOT && $SCRIPT_URL) $PATH_TRANSLATED = $DOCUMENT_ROOT.$SCRIPT_URL;
556
}
557
 
558
# obsoletes: utiliser les constantes ci-dessus.
559
# Conserver pour compatibilite vieilles contrib uniquement
560
$flag_ecrire = !@file_exists(_DIR_RESTREINT_ABS . 'inc_version.php3');
561
$dir_ecrire = (ereg("/ecrire/", $GLOBALS['REQUEST_URI'])) ? '' : 'ecrire/';
562
 
563
// API d'appel a la base de donnees
564
function spip_query($query) {
565
 
566
	// Remarque : si on est appele par l'install,
567
	// la connexion initiale a ete faite avant
568
	if (!$GLOBALS['db_ok']) {
569
		// Essaie de se connecter
570
		if (_FILE_CONNECT)
571
			include_local(_FILE_CONNECT);
572
	}
573
 
574
	// Erreur de connexion
575
	if (!$GLOBALS['db_ok'])
576
		return;
577
 
578
	// Vieux format de fichier connexion
579
	// Note: la version 0.1 est compatible avec la 0.2 (mais elle gere
580
	// moins bien les erreurs timeout sur SQL), on ne force donc pas l'upgrade
581
	if ($GLOBALS['spip_connect_version'] < 0.1) {
582
		if (!_DIR_RESTREINT) {$GLOBALS['db_ok'] = false; return;}
583
		@Header("Location: upgrade.php3?reinstall=oui");
584
		exit;
585
	}
586
 
587
	// Faire la requete
588
	return spip_query_db($query);
589
}
590
 
591
 
592
//
593
// Infos de config PHP
594
//
595
 
596
// cf. liste des sapi_name - http://fr.php.net/php_sapi_name
597
$php_module = (($flag_sapi_name AND eregi("apache", @php_sapi_name())) OR
598
	ereg("^Apache.* PHP", $SERVER_SOFTWARE));
599
$php_cgi = ($flag_sapi_name AND eregi("cgi", @php_sapi_name()));
600
 
601
function http_status($status) {
602
	global $php_cgi, $REDIRECT_STATUS;
603
 
604
	if ($REDIRECT_STATUS && $REDIRECT_STATUS == $status) return;
605
	$status_string = array(
606
		200 => '200 OK',
607
		301 => '301 Moved Permanently',
608
		304 => '304 Not Modified',
609
		401 => '401 Unauthorized',
610
		403 => '403 Forbidden',
611
		404 => '404 Not Found'
612
	);
613
 
614
	if ($php_cgi) Header("Status: $status");
615
	else Header("HTTP/1.0 ".$status_string[$status]);
616
}
617
 
618
function http_gmoddate($lastmodified) {
619
	return gmdate("D, d M Y H:i:s", $lastmodified);
620
}
621
function http_last_modified($lastmodified, $expire = 0) {
622
	$gmoddate = http_gmoddate($lastmodified);
623
	if ($GLOBALS['HTTP_IF_MODIFIED_SINCE']
624
	AND !preg_match(',IIS/,', $_SERVER['SERVER_SOFTWARE'])) # MSoft IIS is dumb
625
	{
626
		$if_modified_since = ereg_replace(';.*$', '', $GLOBALS['HTTP_IF_MODIFIED_SINCE']);
627
		$if_modified_since = trim(str_replace('GMT', '', $if_modified_since));
628
		if ($if_modified_since == $gmoddate) {
629
			http_status(304);
630
			$headers_only = true;
631
		}
632
	}
633
	@Header ("Last-Modified: ".$gmoddate." GMT");
634
	if ($expire)
635
		@Header ("Expires: ".http_gmoddate($expire)." GMT");
636
	return $headers_only;
637
}
638
 
639
$flag_upload = (!$flag_get_cfg_var || (get_cfg_var('upload_max_filesize') > 0));
640
 
641
function tester_upload() {
642
	return $GLOBALS['flag_upload'];
643
}
644
 
645
 
646
//
647
// Reglage de l'output buffering : si possible, generer une sortie
648
// compressee pour economiser de la bande passante
649
//
650
function test_obgz () {
651
	return
652
	$GLOBALS['auto_compress']
653
	&& $GLOBALS['flag_ob']
654
	&& (phpversion()<>'4.0.4')
655
	&& function_exists("ob_gzhandler")
656
	// special bug de proxy
657
	&& !eregi("NetCache|Hasd_proxy", $GLOBALS['HTTP_VIA'])
658
	// special bug Netscape Win 4.0x
659
	&& !eregi("Mozilla/4\.0[^ ].*Win", $GLOBALS['HTTP_USER_AGENT'])
660
	// special bug Apache2x
661
	&& !eregi("Apache(-[^ ]+)?/2", $GLOBALS['SERVER_SOFTWARE'])
662
	&& !($GLOBALS['flag_sapi_name'] AND ereg("^apache2", @php_sapi_name()))
663
	// si la compression est deja commencee, stop
664
	&& !@ini_get("zlib.output_compression")
665
	&& !@ini_get("output_handler")
666
	&& !$GLOBALS['var_mode'] # bug avec le debugueur qui appelle ob_end_clean()
667
	;
668
}
669
 
670
// si un buffer est deja ouvert, stop
671
if ($flag_ob AND strlen(ob_get_contents())==0 AND !headers_sent()) {
672
	@header("Vary: Cookie, Accept-Encoding");
673
	if (test_obgz()) {
674
		ob_start('ob_gzhandler');
675
	}
676
}
677
 
678
 
679
class Link {
680
	var $file;
681
	var $vars;
682
	var $arrays;
683
 
684
	//
685
	// Contructeur : a appeler soit avec l'URL du lien a creer,
686
	// soit sans parametres, auquel cas l'URL est l'URL courante
687
	//
688
	// parametre $root = demander un lien a partir de la racine du serveur /
689
	function Link($url = '', $root = false) {
690
		global $_POST;
691
		static $link = '';
692
 
693
		$this->vars = array();
694
		$this->arrays = array();
695
 
696
		// Normal case
697
		if ($link) {
698
			if ($url) {
699
				$v = split('[\?\&]', $url);
700
				list(, $this->file) = each($v);
701
				while (list(, $var) = each($v)) {
702
					list($name, $value) = split('=', $var, 2);
703
					$name = urldecode($name);
704
					$value = urldecode($value);
705
					if (ereg('^(.*)\[\]$', $name, $regs)) {
706
						$this->arrays[$regs[1]][] = $value;
707
					}
708
					else {
709
						$this->vars[$name] = $value;
710
					}
711
				}
712
			}
713
			else {
714
				$this->file = $link->file;
715
				$this->vars = $link->vars;
716
				$this->arrays = $link->arrays;
717
			}
718
			return;
719
		}
720
 
721
		// Si aucun URL n'est specifie, creer le lien "propre"
722
		// ou l'on supprime de l'URL courant les bidules inutiles
723
		if (!$url) {
724
			// GET variables are read from the original URL
725
			// (_GET may contain additional variables
726
			// introduced by rewrite-rules)
727
			$url = $GLOBALS['REQUEST_URI'];
728
			// Warning !!!!
729
			// since non encoded arguments may be present
730
			// (especially those coming from Rewrite Rule)
731
			// find the begining of the query string
732
			// to compute the script-name
733
			if ($v = strpos($url,'?'))
734
			  $v = strrpos(substr($url, 0, $v), '/');
735
			else $v = strrpos($url, '/');
736
			if (!$root) $url = substr($url, $v + 1);
737
			if (!$url) $url = "./";
738
			if (count($_POST)) {
739
				$vars = array();
740
				foreach ($_POST as $var => $val)
741
					if (preg_match('/^id_/', $var))
742
						$vars[$var] = $val;
743
			}
744
		}
745
		$v = split('[\?\&]', $url);
746
		list(, $this->file) = each($v);
747
		if (!$vars) {
748
			while (list(,$var) = each($v)) {
749
				list($name, $value) = split('=', $var, 2);
750
				$name = urldecode($name);
751
				$value = urldecode($value);
752
				if (ereg('^(.*)\[\]$', $name, $regs))
753
					$vars[$regs[1]][] = $value;
754
				else
755
					$vars[$name] = $value;
756
			}
757
		}
758
 
759
		if (is_array($vars)) {
760
			foreach ($vars as $name => $value) {
761
				// items supprimes
762
				if (!preg_match('/^('.
763
				(!_DIR_RESTREINT ?
764
					'|lang|set_options|set_couleur|set_disp|set_ecran':
765
					'var_mode|show_docs')
766
				. ')$/i', $name)) {
767
					if (is_array($value))
768
						$this->arrays[$name] = $value;
769
					else
770
						$this->vars[$name] = $value;
771
				}
772
			}
773
		}
774
	}
775
 
776
	//
777
	// Effacer une variable
778
	//
779
	function delVar($name) {
780
		if($this->vars[$name]) unset($this->vars[$name]);
781
		if($this->arrays[$name]) unset($this->arrays[$name]);
782
	}
783
 
784
	//
785
	// Ajouter une variable
786
	// (si aucune valeur n'est specifiee, prend la valeur globale actuelle)
787
	//
788
	function addVar($name, $value = '__global__') {
789
		if ($value == '__global__') $value = $GLOBALS[$name];
790
		if (is_array($value))
791
			$this->arrays[$name] = $value;
792
		else
793
			$this->vars[$name] = $value;
794
	}
795
 
796
	//
797
	// Recuperer l'URL correspondant au lien
798
	//
799
	function getUrl($anchor = '') {
800
		$url = $this->file;
801
		if (!$url) $url = './';
802
		$query = '';
803
		foreach($this->vars as $name => $value)
804
			$query .= '&'.$name.'='.urlencode($value);
805
 
806
		foreach ($this->arrays as $name => $table)
807
		foreach ($table as $value)
808
			$query .= '&'.$name.'[]='.urlencode($value);
809
 
810
		if ($query) $query = '?'. substr($query, 1);
811
		if ($anchor) $anchor = '#'.$anchor;
812
		return "$url$query$anchor";
813
	}
814
 
815
	//
816
	// Recuperer le debut de formulaire correspondant au lien
817
	// (tag ouvrant + entrees cachees representant les variables)
818
	//
819
 
820
	function getForm($method = 'get', $query = '', $enctype = '') {
821
		$form = "<form method='$method' action='".$this->file.$query."'";
822
		if ($enctype) $form .= " enctype='$enctype'";
823
		$form .= " style='border: 0px; margin: 0px;'>\n";
824
		foreach ($this->vars as $name => $value) {
825
			$value = ereg_replace('&amp;(#[0-9]+;)', '&\1', htmlspecialchars($value));
826
			$form .= "<input type=\"hidden\" name=\"$name\" value=\"$value\" />\n";
827
		}
828
		foreach ($this->arrays as $name => $table)
829
		foreach ($table as $value) {
830
			$value = ereg_replace('&amp;(#[0-9]+;)', '&\1', htmlspecialchars($value));
831
			$form .= "<input type=\"hidden\" name=\"".$name."[]\" value=\"".$value."\" />\n";
832
		}
833
 
834
		return $form;
835
	}
836
}
837
 
838
 
839
// Lien vers la page demandee et lien nettoye ne contenant que des id_objet
840
$clean_link = new Link();
841
 
842
 
843
// URLs avec passage & -> &amp;
844
function quote_amp ($url) {
845
	$url = str_replace("&amp;", "&", $url);
846
	$url = str_replace("&", "&amp;", $url);
847
	return $url;
848
}
849
 
850
 
851
//
852
// Module de lecture/ecriture/suppression de fichiers utilisant flock()
853
//
854
include_ecrire('inc_flock.php3');
855
 
856
 
857
//
858
// Gerer les valeurs meta
859
//
860
function lire_meta($nom) {
861
	global $meta;
862
	return $meta[$nom];
863
}
864
function lire_meta_maj($nom) {
865
	global $meta_maj;
866
	return $meta_maj[$nom];
867
}
868
 
869
// Lire les meta cachees
870
if (!defined('_DATA_META_CACHE') AND !defined('_ECRIRE_INC_META')) {
871
	unset($meta); # parano
872
 
873
	if (file_exists(_DIR_SESSIONS . 'meta_cache.php3'))
874
		include(_DIR_SESSIONS . 'meta_cache.php3');
875
	// en cas d'echec refaire le fichier
876
	if (!is_array($meta) AND _FILE_CONNECT) {
877
 
878
		include_ecrire('inc_meta.php3');
879
		ecrire_metas();
880
	}
881
}
882
 
883
// Verifier la conformite d'une ou plusieurs adresses email
884
//  retourne false ou la  normalisation de la derniere adresse donnee
885
function email_valide($adresses) {
886
	foreach (explode(',', $adresses) as $v) {
887
	  // nettoyer certains formats
888
	  // "Marie Toto <Marie@toto.com>"
889
		$adresse = trim(eregi_replace("^[^<>\"]*<([^<>\"]+)>$", "\\1", $v));
890
		// RFC 822
891
		if (!eregi('^[^()<>@,;:\\"/[:space:]]+(@([-_0-9a-z]+\.)*[-_0-9a-z]+)$', $adresse))
892
			return false;
893
	}
894
	return $adresse;
895
}
896
 
897
//
898
// Traduction des textes de SPIP
899
//
900
function _T($texte, $args = '') {
901
	include_ecrire('inc_lang.php3');
902
	$text = traduire_chaine($texte, $args);
903
	if (!empty($GLOBALS['xhtml'])) {
904
		include_ecrire("inc_charsets.php3");
905
		$text = html2unicode($text);
906
	}
907
 
908
	return $text ? $text :
909
	  // pour les chaines non traduites
910
	  (($n = strpos($texte,':')) === false ? $texte :
911
	   substr($texte, $n+1));
912
}
913
 
914
// chaines en cours de traduction
915
function _L($text) {
916
	if ($GLOBALS['test_i18n'])
917
		return "<span style='color:red;'>$text</span>";
918
	else
919
		return $text;
920
}
921
 
922
// Langue principale du site
923
$langue_site = lire_meta('langue_site');
924
if (!$langue_site) include_ecrire('inc_lang.php3');
925
$spip_lang = $langue_site;
926
 
927
 
928
// Nommage bizarre des tables d'objets
929
function table_objet($type) {
930
	if ($type == 'site' OR $type == 'syndic')
931
		return 'syndic';
932
	else if ($type == 'forum')
933
		return 'forum';
934
	else
935
		return $type.'s';
936
}
937
function id_table_objet($type) {
938
	if ($type == 'site' OR $type == 'syndic')
939
		return 'id_syndic';
940
	else if ($type == 'forum')
941
		return 'id_forum';
942
	else
943
		return 'id_'.$type;
944
}
945
 
946
 
947
//
948
// spip_timer : on l'appelle deux fois et on a la difference, affichable
949
//
950
function spip_timer($t='rien') {
951
	static $time;
952
	$a=time(); $b=microtime();
953
 
954
	if (isset($time[$t])) {
955
		$p = $a + $b - $time[$t];
956
		unset($time[$t]);
957
		return sprintf("%.2fs", $p);
958
	} else
959
		$time[$t] = $a + $b;
960
}
961
 
962
 
963
// spip_touch : verifie si un fichier existe et n'est pas vieux (duree en s)
964
// et le cas echeant le touch() ; renvoie true si la condition est verifiee
965
// et fait touch() sauf si ca n'est pas souhaite
966
// (regle aussi le probleme des droits sur les fichiers touch())
967
function spip_touch($fichier, $duree=0, $touch=true) {
968
	if (!($exists = @file_exists($fichier))
969
	|| ($duree == 0)
970
	|| (@filemtime($fichier) < time() - $duree)) {
971
		if ($touch) {
972
			if (!@touch($fichier)) { @unlink($fichier); @touch($fichier); };
973
			if (!$exists) @chmod($fichier, 0666);
974
		}
975
		return true;
976
	}
977
	return false;
978
}
979
 
980
//
981
// cron() : execution des taches de fond
982
// quand il est appele par spip_background.php3, il est gourmand ;
983
// quand il est appele par inc-public il n'est pas gourmand
984
//
985
function cron($gourmand = false) {
986
	$touch = _DIR_SESSIONS.'.background';
987
	$touch_gourmand = $touch.'-gourmand';
988
 
989
	// Si on est gourmand, ou si le fichier gourmand n'existe pas
990
	// (ou est trop vieux), on va voir si un cron est necessaire.
991
	// Au passage si on est gourmand on le dit aux autres
992
	if (spip_touch($touch_gourmand, 60, $gourmand)
993
	OR $gourmand) {
994
 
995
		// Faut-il travailler ? Pas tous en meme temps svp
996
		// Au passage si on travaille on bloque les autres
997
		if (spip_touch($touch, 1)) {
998
			include_ecrire('inc_cron.php3');
999
			spip_cron();
1000
		}
1001
	}
1002
}
1003
 
1004
 
1005
//
1006
// qq  fonctions service pour les 2 niveaux
1007
//
1008
function calculer_hierarchie($id_rubrique, $exclure_feuille = false) {
1009
	if (!$id_rubrique)
1010
		return '0';
1011
	if (!$exclure_feuille)
1012
		$hierarchie = ",$id_rubrique";
1013
 
1014
	do {
1015
		$q = spip_query("SELECT id_parent FROM spip_rubriques WHERE id_rubrique=$id_rubrique");
1016
		list($id_rubrique) = spip_fetch_array($q);
1017
		$hierarchie = ",$id_rubrique".$hierarchie;
1018
	} while ($id_rubrique);
1019
 
1020
	return substr($hierarchie, 1); // Attention ca demarre toujours par '0'
1021
}
1022
 
1023
 
1024
//
1025
// Retourne $subdir/ si le sous-repertoire peut etre cree, '' sinon
1026
//
1027
 
1028
function creer_repertoire($base, $subdir) {
1029
	if (@file_exists("$base/.plat")) return '';
1030
	$path = $base.'/'.$subdir;
1031
	if (@file_exists($path)) return "$subdir/";
1032
 
1033
	@mkdir($path, 0777);
1034
	@chmod($path, 0777);
1035
	$ok = false;
1036
	if ($f = @fopen("$path/.test", "w")) {
1037
		@fputs($f, '<'.'?php $ok = true; ?'.'>');
1038
		@fclose($f);
1039
		include("$path/.test");
1040
	}
1041
	if (!$ok) {
1042
		$f = @fopen("$base/.plat", "w");
1043
		if ($f)
1044
			fclose($f);
1045
		else {
1046
			redirige_par_entete("spip_test_dirs.php3");
1047
		}
1048
	}
1049
	return ($ok? "$subdir/" : '');
1050
}
1051
 
1052
 
1053
//
1054
// Entetes
1055
//
1056
function redirige_par_entete($url) {
1057
	header("Location: $url");
1058
#	include_ecrire('inc_cron.php3');
1059
#	spip_cron();
1060
	spip_log("redirige $url");
1061
	exit;
1062
}
1063
 
1064
function debut_entete($title, $entete='') {
1065
	global $flag_preserver;
1066
 
1067
	if (!$charset = lire_meta('charset'))
1068
		$charset = 'utf-8';
1069
	if (!$entete)
1070
		$entete = "Content-Type: text/html; charset=$charset";
1071
 
1072
	if (!$flag_preserver) @header($entete);
1073
	return "<!DOCTYPE HTML PUBLIC '-//W3C//DTD HTML 4.01 Transitional//EN' 'http://www.w3.org/TR/html4/loose.dtd'>\n" .
1074
	  "<html lang='".$GLOBALS['spip_lang']."' dir='".($GLOBALS['spip_lang_rtl'] ? 'rtl' : 'ltr')."'>\n" .
1075
	  "<head>\n" .
1076
#	  "<base href='$base' />\n" .
1077
	  "<title>$title</title>\n" .
1078
	  "<meta http-equiv='Content-Type' content='text/html; charset=$charset'>\n";
1079
}
1080
 
1081
 
1082
// Transforme n'importe quel champ en une chaine utilisable
1083
// en PHP ou Javascript en toute securite
1084
// < ? php $x = '[(#TEXTE|texte_script)]'; ? >
1085
function texte_script($texte) {
1086
	return str_replace('\'', '\\\'', str_replace('\\', '\\\\', $texte));
1087
}
1088
 
1089
//
1090
// find_in_path() : chercher un fichier nomme x selon le chemin rep1:rep2:rep3
1091
//
1092
define_once('_SPIP_PATH', './:squelettes/:dist/:formulaires/');
1093
function find_in_path ($filename, $path='AUTO') {
1094
	// Chemin standard depuis l'espace public
1095
 
1096
	if ($path == 'AUTO') {
1097
		$path = _SPIP_PATH;
1098
		if ($GLOBALS['dossier_squelettes'])
1099
			$path = $GLOBALS['dossier_squelettes'].'/:'.$path;
1100
	}
1101
 
1102
	// Depuis l'espace prive, remonter d'un cran
1103
	$racine = (_DIR_RESTREINT ? '' : '../');
1104
 
1105
	// Parcourir le chemin
1106
	foreach (split(':', $path) as $dir) {
1107
		if (substr($dir, 0,1)<>'/') $dir = "$racine$dir";
1108
		if (substr($dir, -1,1)<>'/') $dir .= "/";
1109
		$f = "$dir$filename";
1110
#		spip_log("find_in_path: essai $f");
1111
		if (@is_readable($f)) {
1112
			return $f;
1113
		}
1114
	}
1115
 
1116
}
1117
 
1118
 
1119
//
1120
// Que faire si Spip n'est pas installe... sauf si justement on l'installe!
1121
//
1122
if (!(_FILE_CONNECT
1123
OR defined('_ECRIRE_INSTALL')
1124
OR defined('_TEST_DIRS')
1125
OR defined('_ECRIRE_AIDE'))) {
1126
	// Soit on est dans ecrire/ et on envoie sur l'installation
1127
	if (@file_exists("inc_version.php3")) {
1128
		header("Location: " . _DIR_RESTREINT . "install.php3");
1129
		exit;
1130
	}
1131
	// Soit on est dans le site public
1132
	else if (defined("_INC_PUBLIC")) {
1133
		# on ne peut pas deviner ces repertoires avant l'installation !
1134
		define('_DIR_INCLUDE', _DIR_RESTREINT);
1135
		define('_DIR_IMG_PACK', (_DIR_RESTREINT . 'img_pack/'));
1136
		define('_DIR_LANG', (_DIR_RESTREINT . 'lang/'));
1137
		$db_ok = false;
1138
		include_ecrire ("inc_presentation.php3");
1139
		install_debut_html(_T('info_travaux_titre'));
1140
		echo "<p>"._T('info_travaux_texte')."</p>";
1141
		install_fin_html();
1142
		exit;
1143
	}
1144
	// Soit on est appele de l'exterieur (spikini, etc)
1145
}
1146
 
1147
?>