aboutsummaryrefslogtreecommitdiffstats
path: root/phpBB/phpbb/db/driver/sqlite.php
blob: 59ec895c0fa1aa2f60eafe057efeeba01985f4ad (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
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
<?php
/**
*
* @package dbal
* @copyright (c) 2005 phpBB Group
* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2
*
*/

namespace phpbb\db\driver;

/**
* Sqlite Database Abstraction Layer
* Minimum Requirement: 2.8.2+
* @package dbal
*/
class sqlite extends \phpbb\db\driver\driver
{
	var $connect_error = '';

	/**
	* Connect to server
	*/
	function sql_connect($sqlserver, $sqluser, $sqlpassword, $database, $port = false, $persistency = false, $new_link = false)
	{
		$this->persistency = $persistency;
		$this->user = $sqluser;
		$this->server = $sqlserver . (($port) ? ':' . $port : '');
		$this->dbname = $database;

		$error = '';
		if ($this->persistency)
		{
			if (!function_exists('sqlite_popen'))
			{
				$this->connect_error = 'sqlite_popen function does not exist, is sqlite extension installed?';
				return $this->sql_error('');
			}
			$this->db_connect_id = @sqlite_popen($this->server, 0666, $error);
		}
		else
		{
			if (!function_exists('sqlite_open'))
			{
				$this->connect_error = 'sqlite_open function does not exist, is sqlite extension installed?';
				return $this->sql_error('');
			}
			$this->db_connect_id = @sqlite_open($this->server, 0666, $error);
		}

		if ($this->db_connect_id)
		{
			@sqlite_query('PRAGMA short_column_names = 1', $this->db_connect_id);
//			@sqlite_query('PRAGMA encoding = "UTF-8"', $this->db_connect_id);
		}

		return ($this->db_connect_id) ? true : array('message' => $error);
	}

	/**
	* Version information about used database
	* @param bool $raw if true, only return the fetched sql_server_version
	* @param bool $use_cache if true, it is safe to retrieve the stored value from the cache
	* @return string sql server version
	*/
	function sql_server_info($raw = false, $use_cache = true)
	{
		global $cache;

		if (!$use_cache || empty($cache) || ($this->sql_server_version = $cache->get('sqlite_version')) === false)
		{
			$result = @sqlite_query('SELECT sqlite_version() AS version', $this->db_connect_id);
			$row = @sqlite_fetch_array($result, SQLITE_ASSOC);

			$this->sql_server_version = (!empty($row['version'])) ? $row['version'] : 0;

			if (!empty($cache) && $use_cache)
			{
				$cache->put('sqlite_version', $this->sql_server_version);
			}
		}

		return ($raw) ? $this->sql_server_version : 'SQLite ' . $this->sql_server_version;
	}

	/**
	* SQL Transaction
	* @access private
	*/
	function _sql_transaction($status = 'begin')
	{
		switch ($status)
		{
			case 'begin':
				return @sqlite_query('BEGIN', $this->db_connect_id);
			break;

			case 'commit':
				return @sqlite_query('COMMIT', $this->db_connect_id);
			break;

			case 'rollback':
				return @sqlite_query('ROLLBACK', $this->db_connect_id);
			break;
		}

		return true;
	}

	/**
	* Base query method
	*
	* @param	string	$query		Contains the SQL query which shall be executed
	* @param	int		$cache_ttl	Either 0 to avoid caching or the time in seconds which the result shall be kept in cache
	* @return	mixed				When casted to bool the returned value returns true on success and false on failure
	*
	* @access	public
	*/
	function sql_query($query = '', $cache_ttl = 0)
	{
		if ($query != '')
		{
			global $cache;

			// EXPLAIN only in extra debug mode
			if (defined('DEBUG'))
			{
				$this->sql_report('start', $query);
			}

			$this->query_result = ($cache && $cache_ttl) ? $cache->sql_load($query) : false;
			$this->sql_add_num_queries($this->query_result);

			if ($this->query_result === false)
			{
				if (($this->query_result = @sqlite_query($query, $this->db_connect_id)) === false)
				{
					$this->sql_error($query);
				}

				if (defined('DEBUG'))
				{
					$this->sql_report('stop', $query);
				}

				if ($cache && $cache_ttl)
				{
					$this->open_queries[(int) $this->query_result] = $this->query_result;
					$this->query_result = $cache->sql_save($this, $query, $this->query_result, $cache_ttl);
				}
				else if (strpos($query, 'SELECT') === 0 && $this->query_result)
				{
					$this->open_queries[(int) $this->query_result] = $this->query_result;
				}
			}
			else if (defined('DEBUG'))
			{
				$this->sql_report('fromcache', $query);
			}
		}
		else
		{
			return false;
		}

		return $this->query_result;
	}

	/**
	* Build LIMIT query
	*/
	function _sql_query_limit($query, $total, $offset = 0, $cache_ttl = 0)
	{
		$this->query_result = false;

		// if $total is set to 0 we do not want to limit the number of rows
		if ($total == 0)
		{
			$total = -1;
		}

		$query .= "\n LIMIT " . ((!empty($offset)) ? $offset . ', ' . $total : $total);

		return $this->sql_query($query, $cache_ttl);
	}

	/**
	* Return number of affected rows
	*/
	function sql_affectedrows()
	{
		return ($this->db_connect_id) ? @sqlite_changes($this->db_connect_id) : false;
	}

	/**
	* Fetch current row
	*/
	function sql_fetchrow($query_id = false)
	{
		global $cache;

		if ($query_id === false)
		{
			$query_id = $this->query_result;
		}

		if ($cache && $cache->sql_exists($query_id))
		{
			return $cache->sql_fetchrow($query_id);
		}

		return ($query_id !== false) ? @sqlite_fetch_array($query_id, SQLITE_ASSOC) : false;
	}

	/**
	* Seek to given row number
	* rownum is zero-based
	*/
	function sql_rowseek($rownum, &$query_id)
	{
		global $cache;

		if ($query_id === false)
		{
			$query_id = $this->query_result;
		}

		if ($cache && $cache->sql_exists($query_id))
		{
			return $cache->sql_rowseek($rownum, $query_id);
		}

		return ($query_id !== false) ? @sqlite_seek($query_id, $rownum) : false;
	}

	/**
	* Get last inserted id after insert statement
	*/
	function sql_nextid()
	{
		return ($this->db_connect_id) ? @sqlite_last_insert_rowid($this->db_connect_id) : false;
	}

	/**
	* Free sql result
	*/
	function sql_freeresult($query_id = false)
	{
		global $cache;

		if ($query_id === false)
		{
			$query_id = $this->query_result;
		}

		if ($cache && !is_object($query_id) && $cache->sql_exists($query_id))
		{
			return $cache->sql_freeresult($query_id);
		}

		return true;
	}

	/**
	* Escape string used in sql query
	*/
	function sql_escape($msg)
	{
		return @sqlite_escape_string($msg);
	}

	/**
	* Correctly adjust LIKE expression for special characters
	* For SQLite an underscore is a not-known character... this may change with SQLite3
	*/
	function sql_like_expression($expression)
	{
		// Unlike LIKE, GLOB is case sensitive (unfortunatly). SQLite users need to live with it!
		// We only catch * and ? here, not the character map possible on file globbing.
		$expression = str_replace(array(chr(0) . '_', chr(0) . '%'), array(chr(0) . '?', chr(0) . '*'), $expression);

		$expression = str_replace(array('?', '*'), array("\?", "\*"), $expression);
		$expression = str_replace(array(chr(0) . "\?", chr(0) . "\*"), array('?', '*'), $expression);

		return 'GLOB \'' . $this->sql_escape($expression) . '\'';
	}

	/**
	* return sql error array
	* @access private
	*/
	function _sql_error()
	{
		if (function_exists('sqlite_error_string'))
		{
			$error = array(
				'message'	=> @sqlite_error_string(@sqlite_last_error($this->db_connect_id)),
				'code'		=> @sqlite_last_error($this->db_connect_id),
			);
		}
		else
		{
			$error = array(
				'message'	=> $this->connect_error,
				'code'		=> '',
			);
		}

		return $error;
	}

	/**
	* Build db-specific query data
	* @access private
	*/
	function _sql_custom_build($stage, $data)
	{
		return $data;
	}

	/**
	* Close sql connection
	* @access private
	*/
	function _sql_close()
	{
		return @sqlite_close($this->db_connect_id);
	}

	/**
	* Build db-specific report
	* @access private
	*/
	function _sql_report($mode, $query = '')
	{
		switch ($mode)
		{
			case 'start':
			break;

			case 'fromcache':
				$endtime = explode(' ', microtime());
				$endtime = $endtime[0] + $endtime[1];

				$result = @sqlite_query($query, $this->db_connect_id);
				while ($void = @sqlite_fetch_array($result, SQLITE_ASSOC))
				{
					// Take the time spent on parsing rows into account
				}

				$splittime = explode(' ', microtime());
				$splittime = $splittime[0] + $splittime[1];

				$this->sql_report('record_fromcache', $query, $endtime, $splittime);

			break;
		}
	}
}
="hl opt">); } #------------------------------------------------------------------------------ sub doPartitionDisks { my ($o, $hds) = @_; if ($o->{lnx4win}) { my @l = sort { $a->{device_windobe} cmp $b->{device_windobe} } grep { isFat($_) } fsedit::get_fstab(@{$o->{hds}}) or die "wow, lnx4win with no fat partitions! hard times :("; my $real_part = @l > 1 && $o->doPartitionDisksLnx4winDev(\@l) || $l[0]; my $handle = loopback::inspect($real_part, '', 'rw') or die _("This partition can't be used for loopback"); my $size = loopback::getFree($handle->{dir}, $real_part); my $max_linux = 1000 << 11; $max_linux *= 10 if $::expert; my $min_linux = 300 << 11; $min_linux /= 3 if $::expert; my $min_freewin = 100 << 11; $min_freewin /= 10 if $::expert; my $swap = { type => 0x82, loopback_file => '/lnx4win/swapfile', mntpoint => 'swap', size => 64 << 11, device => $real_part, notFormatted => 1 }; my $root = { type => 0x83, loopback_file => '/lnx4win/linuxsys.img', mntpoint => '/', size => 0, device => $real_part, notFormatted => 1 }; $root->{size} = min($size - $swap->{size} - $min_freewin, $max_linux); log::l("lnx4win $root->{size} <= $min_linux (minlinux), $size (minavail) - $swap->{size} (swapsize) - $min_freewin (minfreewin), $max_linux (maxlinux)"); $root->{size} > $min_linux or die "not enough room on that partition for lnx4win"; $o->doPartitionDisksLnx4winSize(\$root->{size}, \$swap->{size}, $size - 2 * $swap->{size}, 2 * $swap->{size}); unlink "$handle->{dir}$_" foreach "/lnx4win/swapfile", "/lnx4win/linuxsys.img"; push @{$real_part->{loopback}}, $root, $swap; } else { unless ($::testing) { partition_table::write($_) foreach @$hds; } } } sub doPartitionDisksLnx4winDev {} sub doPartitionDisksLnx4winSize {} #------------------------------------------------------------------------------ sub ask_mntpoint_s { my ($o, $fstab) = @_; #- TODO: set the mntpoints #- assure type is at least ext2 (fsedit::get_root($fstab) || {})->{type} = 0x83; my %m; foreach (@$fstab) { my $m = $_->{mntpoint}; next unless $m && $m ne 'swap'; #- there may be a lot of swap. $m{$m} and die _("Duplicate mount point %s", $m); $m{$m} = 1; #- in case the type does not correspond, force it to ext2 $_->{type} = 0x83 if $m =~ m|^/| && !isFat($_); } } sub rebootNeeded($) { my ($o) = @_; log::l("Rebooting..."); c::_exit(0); } sub choosePartitionsToFormat($$) { my ($o, $fstab) = @_; foreach (@$fstab) { $_->{mntpoint} = "swap" if isSwap($_); $_->{mntpoint} or next; add2hash_($_, { toFormat => $_->{notFormatted} }); if (!$_->{toFormat}) { my $t = isLoopback($_) ? eval { fsedit::typeOfPart($o->{prefix} . loopback::file($_)) } : fsedit::typeOfPart($_->{device}); $_->{toFormatUnsure} = $_->{mntpoint} eq "/" || #- if detected dos/win, it's not precise enough to just compare the types (too many of them) (isFat({ type => $t }) ? !isFat($_) : $t != $_->{type}); } } } sub formatMountPartitions { my ($o) = @_; fs::formatMount_all($o->{raid}, $o->{fstab}, $o->{prefix}); } #------------------------------------------------------------------------------ sub setPackages { my ($o) = @_; install_any::setPackages($o); } sub selectPackagesToUpgrade { my ($o) = @_; install_any::selectPackagesToUpgrade($o); } sub choosePackages { my ($o, $packages, $compss, $compssUsers, $compssUsersSorted, $first_time) = @_; #- now for upgrade, package that must be upgraded are #- selected first, after is used the same scheme as install. #- make sure we kept some space left for available else the system may #- not be able to start (xfs at least). my $available = install_any::getAvailableSpace($o); my $availableCorrected = pkgs::invCorrectSize($available / sqr(1024)) * sqr(1024); log::l("available size $available (corrected $availableCorrected)"); foreach (values %{$packages->[0]}) { pkgs::packageSetFlagSkip($_, 0); pkgs::packageSetFlagUnskip($_, 0); } pkgs::unselectAllPackages($packages); pkgs::selectPackage($o->{packages}, pkgs::packageByName($o->{packages}, $_) || next) foreach @{$o->{default_packages}}; add2hash_($o, { compssListLevel => $::expert ? 90 : 80 }) unless $::auto_install; pkgs::setSelectedFromCompssList($o->{compssListLevels}, $packages, $o->{compssListLevel}, $available, $o->{installClass}) if exists $o->{compssListLevel}; $available; } sub beforeInstallPackages { my ($o) = @_; #- save these files in case of upgrade failure. if ($o->{isUpgrade}) { foreach (@filesToSaveForUpgrade) { unlink "$o->{prefix}/$_.mdkgisave"; if (-e "$o->{prefix}/$_") { eval { commands::cp("$o->{prefix}/$_", "$o->{prefix}/$_.mdkgisave") }; } } } #- some packages need such files for proper installation. install_any::write_ldsoconf($o->{prefix}); fs::write($o->{prefix}, $o->{fstab}, $o->{manualFstab}, $o->{useSupermount}); network::add2hosts("$o->{prefix}/etc/hosts", "localhost.localdomain", "127.0.0.1"); require pkgs; pkgs::init_db($o->{prefix}, $o->{isUpgrade}); } sub pkg_install { my ($o, @l) = @_; require pkgs; pkgs::selectPackage($o->{packages}, pkgs::packageByName($o->{packages}, $_) || die "$_ rpm not found") foreach @l; $o->installPackages; } sub installPackages($$) { #- complete REWORK, TODO and TOCHECK! my ($o) = @_; my $packages = $o->{packages}; if (@{$o->{toRemove} || []}) { #- hack to ensure proper upgrade of packages from other distribution, #- as release number are not mandrake based. this causes save of #- important files and restore them after. foreach (@{$o->{toSave} || []}) { if (-e "$o->{prefix}/$_") { unlink "$o->{prefix}/$_.mdkgisave"; eval { commands::cp("$o->{prefix}/$_", "$o->{prefix}/$_.mdkgisave") }; } } pkgs::remove($o->{prefix}, $o->{toRemove}); foreach (@{$o->{toSave} || []}) { if (-e "$o->{prefix}/$_.mdkgisave") { unlink "$o->{prefix}/$_"; rename "$o->{prefix}/$_.mdkgisave", "$o->{prefix}/$_"; } } $o->{toSave} = []; #- hack for compat-glibc to upgrade properly :-( if (pkgs::packageFlagSelected(pkgs::packageByName($packages, 'compat-glibc'))) { rename "$o->{prefix}/usr/i386-glibc20-linux", "$o->{prefix}/usr/i386-glibc20-linux.mdkgisave"; } } #- small transaction will be built based on this selection and depslist. my @toInstall = pkgs::packagesToInstall($packages); $ENV{DURING_INSTALL} = 1; pkgs::install($o->{prefix}, $o->{isUpgrade}, \@toInstall, $packages->[1], $packages->[2]); delete $ENV{DURING_INSTALL}; } sub afterInstallPackages($) { my ($o) = @_; return if $::g_auto_install; -x "$o->{prefix}/usr/bin/dumpkeys" or $::testing or die "Some important packages didn't get installed properly. Please switch to console 2 (using ctrl-alt-f2) and look at the log file /tmp/ddebug.log Consoles 1,3,4,7 may also contain interesting information"; pkgs::done_db(); #- why not? cuz weather is nice today :-) [pixel] sync(); sync(); $o->pcmciaConfig(); #- for mandrake_firstime output "$o->{prefix}/var/lock/TMP_1ST", ""; #- remove the nasty acon... run_program::rooted($o->{prefix}, "chkconfig", "--del", "acon") unless $ENV{LANGUAGE} =~ /ar/; #- make the mdk fonts last in available fonts for buggy kde run_program::rooted($o->{prefix}, "chkfontpath", "--remove", "/usr/X11R6/lib/X11/fonts/mdk"); run_program::rooted($o->{prefix}, "chkfontpath", "--add", "/usr/X11R6/lib/X11/fonts/mdk"); #- call update-menus at the end of package installation run_program::rooted($o->{prefix}, "update-menus"); #- mainly for auto_install's run_program::rooted($o->{prefix}, "sh", "-c", $o->{postInstall}) if $o->{postInstall}; #- create /etc/sysconfig/desktop file according to user choice and presence of /usr/bin/kdm or /usr/bin/gdm. my $f = "$o->{prefix}/etc/sysconfig/desktop"; if ($o->{compssUsersChoice}{KDE} && -x "$o->{prefix}/usr/bin/kdm") { output($f, "KDE\n"); } elsif ($o->{compssUsersChoice}{Gnome} && -x "$o->{prefix}/usr/bin/gdm") { output($f, "GNOME\n"); } if ($o->{pcmcia}) { substInFile { s/.*(TaskBarShowAPMStatus).*/$1=1/ } "$o->{prefix}/usr/lib/X11/icewm/preferences"; eval { commands::cp("$o->{prefix}/usr/share/applnk/System/kapm.kdelnk", "$o->{prefix}/etc/skel/Desktop/Autostart/kapm.kdelnk") }; } my $msec = "$o->{prefix}/etc/security/msec"; substInFile { s/^audio\n//; $_ .= "audio\n" if eof } "$msec/group.conf" if -d $msec; substInFile { s/^cdrom\n//; $_ .= "cdrom\n" if eof } "$msec/group.conf" if -d $msec; substInFile { s/^xgrp\n//; $_ .= "xgrp\n" if eof } "$msec/group.conf" if -d $msec; my $pkg = pkgs::packageByName($o->{packages}, 'urpmi'); if ($pkg && pkgs::packageFlagSelected($pkg)) { install_any::install_urpmi($o->{prefix}, $o->{method}, $o->{packages}[2]); substInFile { s/^urpmi\n//; $_ .= "urpmi\n" if eof } "$msec/group.conf" if -d $msec; } #- update language and icons for KDE. log::l("updating language for kde"); install_any::kdelang_postinstall($o->{prefix}); log::l("updating kde icons according to available devices"); install_any::kdeicons_postinstall($o->{prefix}); my $welcome = _("Welcome to %s", "[HOSTNAME]"); substInFile { s/^(GreetString)=.*/$1=$welcome/ } "$o->{prefix}/usr/share/config/kdmrc"; substInFile { s/^(UserView)=false/$1=true/ } "$o->{prefix}/usr/share/config/kdmrc" if $o->{security} < 3; run_program::rooted($o->{prefix}, "kdeDesktopCleanup"); #- konsole and gnome-terminal are lamers in exotic languages, link them to something better if ($o->{lang} =~ /ja|ko|zh/) { foreach ("konsole", "gnome-terminal") { my $f = "$o->{prefix}/usr/bin/$_"; symlinkf("X11/rxvt.sh", $f) if -e $f; } } #- my $hasttf; #- my $dest = "/usr/X11R6/lib/X11/fonts/drakfont"; #- foreach my $d (map { $_->{mntpoint} } grep { isFat($_) } @{$o->{fstab}}) { #- foreach my $D (map { "$d/$_" } grep { m|^win|i } all("$o->{prefix}$d")) { #- $D .= "/fonts"; #- -d "$o->{prefix}$D" or next; #- log::l("found win font dir $D"); #- if (!$hasttf) { #- $hasttf = $o->ask_okcancel('', #-_("Some true type fonts from windows have been found on your computer. #-Do you want to use them? Be sure you have the right to use them under Linux."), 1) or goto nottf; #- mkdir "$o->{prefix}$dest", 0755; #- } #- /(.*)\.ttf/i and symlink "$D/$_", "$o->{prefix}$dest/$1.ttf" foreach grep { /\.ttf/i } all("$o->{prefix}$D"); #- } #- } #- nottf: #- if ($hasttf) { #- run_program::rooted($o->{prefix}, "ttmkfdir", "-d", $dest, "-o", "$dest/fonts.dir"); #- run_program::rooted($o->{prefix}, "chkfontpath", "--add", $dest); #- } foreach (install_any::list_skels()) { my $found; substInFile { $found ||= /KFM Misc Defaults/; $_ .= "[KFM Misc Defaults] GridWidth=85 GridHeight=70 " if eof && !$found; } "$o->{prefix}$_/.kde/share/config/kfmrc" } #- to ensure linuxconf doesn't cry against those files being in the future -e $_ and touch($_) foreach map { "$o->{prefix}/$_" } '/etc/conf.modules', '/etc/crontab', '/etc/sysconfig/mouse', '/etc/X11/fs/config'; #- move some file after an upgrade that may be seriously annoying. #- and rename saved files to .mdkgiorig. if ($o->{isUpgrade}) { log::l("moving previous desktop files that have been updated to Trash of each user"); install_any::move_desktop_file($o->{prefix}); foreach (@filesToSaveForUpgrade) { if (-e "$o->{prefix}$_.mdkgisave") { unlink "$o->{prefix}$_.mdkgiorig"; rename "$o->{prefix}/$_.mdkgisave", "$o->{prefix}/$_.mdkgiorig"; } } } } #------------------------------------------------------------------------------ sub selectMouse($) { my ($o) = @_; } #------------------------------------------------------------------------------ sub configureNetwork($) { my ($o) = @_; my $etc = "$o->{prefix}/etc"; network::write_conf("$etc/sysconfig/network", $o->{netc}); network::write_resolv_conf("$etc/resolv.conf", $o->{netc}); network::write_interface_conf("$etc/sysconfig/network-scripts/ifcfg-$_->{DEVICE}", $_) foreach @{$o->{intf}}; network::add2hosts("$etc/hosts", $o->{netc}{HOSTNAME}, map { $_->{IPADDR} } @{$o->{intf}}); network::sethostname($o->{netc}) unless $::testing; network::addDefaultRoute($o->{netc}) unless $::testing; $o->pkg_install("dhcpcd") if grep { $_->{BOOTPROTO} =~ /^(dhcp)$/ } @{$o->{intf}}; # Handle also pump (this is still in initscripts no?) $o->pkg_install("pump") if grep { $_->{BOOTPROTO} =~ /^(pump|bootp)$/ } @{$o->{intf}}; #-res_init(); #- reinit the resolver so DNS changes take affect miscellaneousNetwork($o); } #------------------------------------------------------------------------------ sub pppConfig { my ($o) = @_; $o->{modem} or return; symlinkf($o->{modem}{device}, "$o->{prefix}/dev/modem") or log::l("creation of $o->{prefix}/dev/modem failed"); $o->pkg_install("ppp") unless $::testing; my %toreplace; $toreplace{$_} = $o->{modem}{$_} foreach qw(connection phone login passwd auth domain dns1 dns2); $toreplace{kpppauth} = ${{ 'Script-based' => 0, 'PAP' => 1, 'Terminal-based' => 2, 'CHAP' => 3, }}{$o->{modem}{auth}}; $toreplace{phone} =~ s/\D//g; $toreplace{dnsserver} = join ',', map { $o->{modem}{$_} } "dns1", "dns2"; $toreplace{dnsserver} .= $toreplace{dnsserver} && ','; #- using peerdns or dns1,dns2 avoid writing a /etc/resolv.conf file. $toreplace{peerdns} = "yes"; $toreplace{connection} ||= 'DialupConnection'; $toreplace{domain} ||= 'localdomain'; $toreplace{intf} ||= 'ppp0'; $toreplace{papname} = $o->{modem}{auth} eq 'PAP' && $toreplace{login}; #- build ifcfg-ppp0. my $ifcfg = "$o->{prefix}/etc/sysconfig/network-scripts/ifcfg-ppp0"; local *IFCFG; open IFCFG, ">$ifcfg" or die "Can't open $ifcfg"; print IFCFG <<END; DEVICE="$toreplace{intf}" ONBOOT="no" USERCTL="no" MODEMPORT="/dev/modem" LINESPEED="115200" PERSIST="yes" DEFABORT="yes" DEBUG="yes" INITSTRING="ATZ" DEFROUTE="yes" HARDFLOWCTL="yes" ESCAPECHARS="no" PPPOPTIONS="" PAPNAME="$toreplace{papname}" REMIP="" NETMASK="" IPADDR="" MRU="" MTU="" DISCONNECTTIMEOUT="5" RETRYTIMEOUT="60" BOOTPROTO="none" PEERDNS="$toreplace{peerdns}" END foreach (1..2) { if ($toreplace{"dns$_"}) { print IFCFG <<END; DNS$_=$toreplace{"dns$_"} END } } close IFCFG; #- build chat-ppp0. my $chat = "$o->{prefix}/etc/sysconfig/network-scripts/chat-ppp0"; local *CHAT; open CHAT, ">$chat" or die "Can't open $chat"; print CHAT <<END; 'ABORT' 'BUSY' 'ABORT' 'ERROR' 'ABORT' 'NO CARRIER' 'ABORT' 'NO DIALTONE' 'ABORT' 'Invalid Login' 'ABORT' 'Login incorrect' '' 'ATZ' 'OK' 'ATDT$toreplace{phone}' 'CONNECT' '' END if ($o->{modem}{auth} eq 'Terminal-based' || $o->{modem}{auth} eq 'Script-based') { print CHAT <<END; 'ogin:' '$toreplace{login}' 'ord:' '$toreplace{passwd}' END } print CHAT <<END; 'TIMEOUT' '5' '~--' '' END close CHAT; if ($o->{modem}{auth} eq 'PAP') { #- need to create a secrets file for the connection. my $secrets = "$o->{prefix}/etc/ppp/" . lc($o->{modem}{auth}) . "-secrets"; my @l = cat_($secrets); my $replaced = 0; do { $replaced ||= 1 if s/^\s*"?$toreplace{login}"?\s+ppp0\s+(\S+)/"$toreplace{login}" ppp0 "$toreplace{passwd}"/; } foreach @l; if ($replaced) { local *F; open F, ">$secrets" or die "Can't open $secrets: $!"; print F @l; } else { local *F; open F, ">>$secrets" or die "Can't open $secrets: $!"; print F "$toreplace{login} ppp0 \"$toreplace{passwd}\"\n"; } #- restore access right to secrets file, just in case. chmod 0600, $secrets; } #- CHAP is not supported by initscripts, need patching before doing more on that here! #-install_any::template2userfile($o->{prefix}, "$ENV{SHARE_PATH}/kppprc.in", ".kde/share/config/kppprc", 1, %toreplace); commands::mkdir_("-p", "$o->{prefix}/usr/share/config"); template2file("$ENV{SHARE_PATH}/kppprc.in", "$o->{prefix}/usr/share/config/kppprc", %toreplace); miscellaneousNetwork($o); } #------------------------------------------------------------------------------ sub installCrypto { my ($o) = @_; my $u = $o->{crypto} or return; $u->{mirror} && $u->{packages} or return; $o->upNetwork; require crypto; my @crypto_packages = crypto::getPackages($o->{prefix}, $o->{packages}, $u->{mirror}); my $oldGetFile = \&install_any::getFile; local *install_any::getFile = sub { my ($rpmfile) = @_; if ($rpmfile =~ /^(.*)-[^-]*-[^-]*$/ && member($1, @crypto_packages)) { log::l("crypto::getFile $rpmfile"); crypto::getFile($rpmfile, $u->{mirror}); } else { #- use previous getFile typically if non cryptographic packages #- have been selected by dependancies. log::l("normal getFile $rpmfile"); &$oldGetFile($rpmfile); } }; $o->pkg_install(@{$u->{packages}}); } #------------------------------------------------------------------------------ sub pcmciaConfig($) { my ($o) = @_; my $t = $o->{pcmcia}; #- should be set after installing the package above else the file will be renamed. setVarsInSh("$o->{prefix}/etc/sysconfig/pcmcia", { PCMCIA => $t ? "yes" : "no", PCIC => $t, PCIC_OPTS => "", CORE_OPTS => "", }); } #------------------------------------------------------------------------------ sub timeConfig { my ($o, $f) = @_; require timezone; timezone::write($o->{prefix}, $o->{timezone}, $f); } #------------------------------------------------------------------------------ sub servicesConfig {} #------------------------------------------------------------------------------ sub printerConfig { my($o) = @_; if ($o->{printer}{configured}) { require pkgs; pkgs::selectPackage($o->{packages}, pkgs::packageByName($o->{packages}, 'rhs-printfilters')); $o->installPackages($o->{packages}); require printer; foreach (keys %{$o->{printer}{configured} || {}}) { log::l("configuring printer queue $_->{queue}"); printer::copy_printer_params($_, $o->{printer}); #- setup all configured queues, which is not the case interactively where #- only the working queue is setup on configuration. printer::configure_queue($o->{printer}); } } } #------------------------------------------------------------------------------ my @etc_pass_fields = qw(name pw uid gid realname home shell); sub setRootPassword($) { my ($o) = @_; my $p = $o->{prefix}; my $u = $o->{superuser} ||= {}; $u->{pw} ||= $u->{password} && install_any::crypt($u->{password}); my @lines = cat_(my $f = "$p/etc/passwd") or log::l("missing passwd file"), return; local *F; open F, "> $f" or die "failed to write file $f: $!\n"; foreach (@lines) { if (/^root:/) { chomp; my %l; @l{@etc_pass_fields} = split ':'; add2hash($u, \%l); $_ = join(':', @$u{@etc_pass_fields}) . "\n"; } print F $_; } } #------------------------------------------------------------------------------ sub addUser($) { my ($o) = @_; my $p = $o->{prefix}; my (%uids, %gids); foreach (glob_("$p/home")) { my ($u, $g) = (stat($_))[4,5]; $uids{$u} = 1; $gids{$g} = 1; } my %done; my @l = grep { if (!$_->{name} || getpwnam($_->{name}) || $done{$_->{name}}) { 0; } else { $_->{home} ||= "/home/$_->{name}"; my $u = $_->{uid} || ($_->{oldu} = (stat("$p$_->{home}"))[4]); my $g = $_->{gid} || ($_->{oldg} = (stat("$p$_->{home}"))[5]); #- search for available uid above 501 else initscripts may fail to change language for KDE. if (!$u || getpwuid($u)) { for ($u = 501; getpwuid($u) || $uids{$u}; $u++) {} } if (!$g || getgrgid($g)) { for ($g = 501; getgrgid($g) || $gids{$g}; $g++) {} } $_->{uid} = $u; $uids{$u} = 1; $_->{gid} = $g; $gids{$g} = 1; $_->{pw} ||= $_->{password} && install_any::crypt($_->{password}); $_->{shell} ||= "/bin/bash"; $done{$_->{name}} = 1; } } @{$o->{users} || []}; my @passwd = cat_("$p/etc/passwd");; local *F; open F, ">> $p/etc/passwd" or die "can't append to passwd file: $!"; print F join(':', @$_{@etc_pass_fields}), "\n" foreach @l; open F, ">> $p/etc/group" or die "can't append to group file: $!"; print F "$_->{name}:x:$_->{gid}:\n" foreach @l; foreach my $u (@l) { if (! -d "$p$u->{home}") { my $mode = $o->{security} < 2 ? 0755 : 0750; eval { commands::cp("-f", "$p/etc/skel", "$p$u->{home}") }; if ($@) { log::l("copying of skel failed: $@"); mkdir("$p$u->{home}", $mode); } else { chmod $mode, "$p$u->{home}"; } } eval { commands::chown_("-r", "$u->{uid}.$u->{gid}", "$p$u->{home}") } if $u->{uid} != $u->{oldu} || $u->{gid} != $u->{oldg}; } require any; any::addUsers($o->{prefix}, @l); } #------------------------------------------------------------------------------ sub createBootdisk($) { my ($o) = @_;