aboutsummaryrefslogtreecommitdiff
path: root/boca-1.5.2/src/db.php
blob: 6d437dcd302439fc298fcff434015dd6a3f404ca (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
<?php
////////////////////////////////////////////////////////////////////////////////
//BOCA Online Contest Administrator
//    Copyright (C) 2003-2012 by BOCA Development Team (bocasystem@gmail.com)
//
//    This program is free software: you can redistribute it and/or modify
//    it under the terms of the GNU General Public License as published by
//    the Free Software Foundation, either version 3 of the License, or
//    (at your option) any later version.
//
//    This program is distributed in the hope that it will be useful,
//    but WITHOUT ANY WARRANTY; without even the implied warranty of
//    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
//    GNU General Public License for more details.
//    You should have received a copy of the GNU General Public License
//    along with this program.  If not, see <http://www.gnu.org/licenses/>.
////////////////////////////////////////////////////////////////////////////////
// Last modified 21/jul/2012 by cassio@ime.usp.br
if(isset($_SESSION["locr"]) && isset($_SESSION["loc"]) && !is_readable($_SESSION["locr"] . '/private/conf.php')) {
	MSGError('Permission problems in ' . $_SESSION["locr"] . '/private/conf.php - the file must be readable to the user running the web server');
	exit;
}
require_once('hex.php');
require_once('globals.php');
require_once('private/conf.php');

//para compatibilidade com versoes velhas e novas do php, varias das funcoes foram
//colocadas aqui para guarantir a portabilidade. Infelizmente algumas trocas de nomes
//e parametros aconteceram com a versao 4.2.0 do php.
function DB_lo_open($conn, $file, $mode) {
	if (strcmp(phpversion(),'4.2.0')<0)
		return pg_loopen ($conn, $file, $mode);
	else
		return pg_lo_open ($conn, $file, $mode);
}
function DB_lo_read_tobrowser($contest,$id) {
	$str = DB_lo_read($contest,$id);
	echo $str;
	return true;
}

function DB_lo_read($contest,$id,$s=-1) {
	if (strcmp(phpversion(),'4.2.0')<0) {
		if($s<0) {
			$str='';
			while (($buf = pg_loread ($id, 100000)) != false) $str .= $buf;
		} else
			$str = pg_loread ($id, $s);
	}
	else {
		if($s<0) {
			$str='';
			while (($buf = pg_lo_read ($id, 100000)) != false) $str .= $buf;
		} else
			$str = pg_lo_read ($id, $s);
	}
	if(($str2 = DB_unlock($contest,$str))===false) return $str;
	return $str2;
}
function DB_unlock($contest,$str,$c=null) {
	if($contest <= 0) return false;
	if(($ct = DBContestInfo($contest,$c)) == null) return false;
	if(strlen($ct['contestunlockkey']) > 1) {
		$ar=explode(',',$ct['contestkeys']);
		foreach($ar as $key) {
			if(substr($key,0,10) == substr($str,0,10)) {
				$pass=decryptData(substr($key,15),$ct['contestunlockkey'],'db_unlock');
				if(substr($pass,0,5) != '#####') continue;
				$str2=decryptData($str,$pass,'db_unlock2');
				if($str2=='') continue;
				return $str2;
			}
		}
	}
	return false;
}

function DB_lo_import($conn, $file) {
	if (strcmp(phpversion(),'4.2.0')<0)
		return pg_loimport ($file, $conn);
	else
		return pg_lo_import ($conn, $file);
}
function DB_lo_export($contest, $conn, $oid, $file) {
	if (strcmp(phpversion(),'4.2.0')<0)
		$stat= pg_loexport ($oid, $file, $conn);
	else
		$stat= pg_lo_export ($oid, $file, $conn);
	if($stat===false) return false;
	if(!is_readable($file)) return false;
	if(($str=DB_unlock($contest,file_get_contents($file),$conn))!==false) {
		file_put_contents($file,$str);
		return 2;
	}
	return 1;
}
function DB_lo_close($id) {
	if (strcmp(phpversion(),'4.2.0')<0)
		return pg_loclose ($id);
	else
		return pg_lo_close ($id);
}
function DB_lo_create($conn) {
	if (strcmp(phpversion(),'4.2.0')<0)
		return pg_locreate ($conn);
	else
		return pg_lo_create ($conn);
}
function DB_lo_write($fp, $data) {
	if (strcmp(phpversion(),'4.2.0')<0)
		return pg_lowrite ($fp, $data);
	else
		return pg_lo_write ($fp, $data);
}
function DB_lo_unlink($conn, $data) {
	if(($fp = DB_lo_open ($conn, $data, "r"))===false) return false;
	DB_lo_close($fp);
	if (strcmp(phpversion(),'4.2.0')<0)
		return pg_lounlink ($conn, $data);
	else
		return pg_lo_unlink ($conn, $data);
}
function DB_pg_exec($conn, $data) {
	if (strcmp(phpversion(),'4.2.0')<0)
		return pg_exec ($conn, $data);
	else
		return pg_query ($conn, $data);
}
function escape_string($str) {
	if(strcmp(phpversion(),'4.2.0')<0)
		return addslashes($str);
	else
		return pg_escape_string($str);
}

//abrir conexao com o banco de dados
//temos aqui um problema de seguranca. A senha/usuario para acesso ao postgresql
//fica guardada em texto plano em um arquivo com permissao de acesso para todos com shell 
//na maquina. O melhor a fazer eh configurar o postgres para permitir acesso no banco de
//dados do boca ao usuario dono desses arquivos php. Esses problemas nao existem quando
//shell no servidor do boca+postgres eh restrito.
function DBConnect($forcenew=false) {
        // procura por arquivo com as configuracao. se nao achar, usa padroes
	$conf = globalconf();
	if($conf["dblocal"]=="true") {
		if($forcenew)
			$conn = @pg_connect ("connect_timeout=10 dbname=".$conf["dbname"]." user=".$conf["dbuser"].
								 " password=".$conf["dbpass"],PGSQL_CONNECT_FORCE_NEW);
		else
			$conn = @pg_connect ("connect_timeout=10 dbname=".$conf["dbname"]." user=".$conf["dbuser"].
								 " password=".$conf["dbpass"]);
	} else {
		if($forcenew)
			$conn = @pg_connect ("connect_timeout=10 host=".$conf["dbhost"]." port=".$conf["dbport"]." dbname=".$conf["dbname"].
								 " user=".$conf["dbuser"]." password=".$conf["dbpass"],PGSQL_CONNECT_FORCE_NEW);
		else
			$conn = @pg_connect ("connect_timeout=10 host=".$conf["dbhost"]." port=".$conf["dbport"]." dbname=".$conf["dbname"].
								 " user=".$conf["dbuser"]." password=".$conf["dbpass"]);
	}
	if (!$conn) {
		LOGError("Unable to connect to database (${conf["dbhost"]},${conf["dbname"]},${conf["dbuser"]}).");
		MSGError("Unable to connect to database (${conf["dbhost"]}:${conf["dbport"]},${conf["dbname"]},${conf["dbuser"]}). ".
			"Is it running? Is the DB password in conf.php correct?");
		exit;
	}
	if(isset($conf["dbclientenc"]))
		DBExecNonStop($conn,"SET NAMES '${conf["dbclientenc"]}'","set client encoding");
	return $conn;
}
//fecha a conexao com o banco (isso nao eh realmente necessario, ja que o php/apache cuidam do servico)
function DBClose($c) {
	pg_close($c);
}
//executar instrucao no banco de dados, sem finalizar a execucao do php
//em caso de erro (mas com uma chamada para a funcao LOGLevel) 
//$conn eh a conexao com o banco
//$sql eh a instrucao sql
//$txt eh um pequeno texto descrevendo o que esta sendo feito no sql
function DBExecNonStop($conn,$sql,$txt='') {
	if($txt=='') $txt='unknown at '.getFunctionName();
	$result = @DB_pg_exec ($conn, $sql);
	if (!$result) {
		LOGLevel("Unable to exec SQL in the database ($txt). " .
                         " Error=(" . pg_errormessage($conn) . ")", 2);
	}
	return $result;
}
//executar instrucao no banco de dados, finalizando a execucao do php
//em caso de erro (alem da chamada para a funcao LOGLevel e alerta na tela) 
//$conn eh a conexao com o banco
//$sql eh a instrucao sql
//$txt eh um pequeno texto descrevendo o que esta sendo feito no sql
function DBExec($conn,$sql,$txt='') {
	if($txt=='') $txt='unknown at '.getFunctionName();
	$result = DB_pg_exec ($conn, $sql);
	if (!$result) {
		LOGError("Unable to exec SQL in the database ($txt). " .
				 " SQL=(" . sanitizeText(str_replace("\n", " ",$sql)) . "Error=(" . sanitizeText(str_replace("\n", " ",pg_errormessage($conn))) . ")");
		MSGError("Unable to exec SQL in the database ($txt). Aborting.");
		exit;
	}
	return $result;
}
//executar instrucao no banco de dados, sem finalizar a execucao do php
//mesmo em caso de erro (apenas uma janela de aviso tentara ser mostrada ao usuario
//$conn eh a conexao com o banco
//$sql eh a instrucao sql
//$txt eh um pequeno texto descrevendo o que esta sendo feito no sql
function DBExecNoSQLLog($sql,$txt='') {
	if($txt=='') $txt='unknown at '.getFunctionName();
	$conn = DBConnect(true);
	$result = DB_pg_exec ($conn, $sql);
	pg_close($conn);
	if (!$result) {
		MSGError("Unable to exec SQL in the database ($txt).");
	}
	return $result;
}
//devolve o numero de linhas da consulta
function DBnlines ($result) {
	return pg_numrows ($result);
}
//pega uma linha da consulta no formato de array
function DBRow ($r, $i) {
	return pg_fetch_array ($r, $i, PGSQL_ASSOC);
}
//faz a consulta e pega uma linha da consulta no formato de array
//$sql eh a consulta em sql
//$i eh a linha desejada, comecando de zero
//$txt eh uma descricao da consulta sendo feita
function DBGetRow ($sql,$i,$c=null,$txt='') {
	if($txt=='') $txt='unknown at '.getFunctionName();
	if($c==null)
		$c = DBConnect();
	$r = DBExec($c,$sql,$txt);
	if (DBnlines($r) < $i+1) return null;
	$a = DBRow ($r, $i);
	if (!$a) {
		LOGError("Unable to get row $i from a query ($txt). SQL=(" . $sql . ")");
		MSGError("Unable to get row from query ($txt).");
		exit;
	}
	return $a;
}
function DBDropDatabase() {
	$conf = globalconf();
	if($conf["dblocal"]=="true")
		$conn = pg_connect ("connect_timeout=10 dbname=template1 user=".$conf["dbsuperuser"]." password=".$conf["dbsuperpass"]);
	else
		$conn = pg_connect ("connect_timeout=10 host=".$conf["dbhost"]." port=".$conf["dbport"]." dbname=template1 user=".$conf["dbsuperuser"].
				   " password=".$conf["dbsuperpass"]);
	 if(!$conn) {
		 MSGError("Unable to connect to template1 as ".$conf["dbsuperuser"]);
		 exit;
	 }
	 $r = DBExecNonStop($conn, "drop database ${conf["dbname"]}", "DBDropDatabase(drop)");
}
// pg_connect ("options='--client_encoding=UTF8' dbname=template1 ... ????
function DBCreateDatabase() {
	$conf = globalconf();
	if($conf["dblocal"]=="true")
		$conn = pg_connect ("connect_timeout=10 dbname=template1 user=".$conf["dbsuperuser"]." password=".$conf["dbsuperpass"]);
	else
		$conn = pg_connect ("connect_timeout=10 host=".$conf["dbhost"]." port=".$conf["dbport"]." dbname=template1 user=".$conf["dbsuperuser"].
				   " password=".$conf["dbsuperpass"]);

	 if(!$conn) {
		 MSGError("Unable to connect to template1 as ".$conf["dbsuperuser"]);
		 exit;
	 }
	 if(isset($conf["dbencoding"]))
		 $r = DBExec($conn, "create database ${conf["dbname"]} with encoding = '${conf["dbencoding"]}'", "DBCreateDatabase(create)");
	 else
		 $r = DBExec($conn, "create database ${conf["dbname"]} with encoding = 'UTF8'", "DBCreateDatabase(create)");
}

function DBcrc($contest,$id, $c=null) {
	$docommit=false;
	if($c == null) {
		$docommit=true;
		$c = DBConnect();
		DBExec($c, "begin work", "DBcrc(begin)");
	}
	if(($f = DB_lo_open($c, $id, "r")) === false) {
		if($docommit)
			DBExec($c, "commit work", "DBcrc(commit)");
        // just to return a unique string that will not match any other...
		return "no-HASH-" . rand() . "-" . rand() . "-" . time();
	}
	$str = DB_lo_read($contest,$f);
	DB_lo_close($f);
	if($docommit)
		DBExec($c, "commit work", "DBcrc(commit)");
	return myshorthash($str);
}

require_once('flog.php');
require_once('fclar.php');
require_once('frun.php');
require_once('ftask.php');
require_once('fproblem.php');
require_once('flanguage.php');
require_once('fscore.php');
require_once('fanswer.php');
require_once('fcontest.php');
require_once('fbkp.php');
require_once('fextdata.php');
require_once('fzip.php');
require_once('fballoon.php');
// eof
?>