]> git.vanrenterghem.biz Git - www.vanrenterghem.biz.git/blob - phpBB2_old/admin/xs_include.php
Baseline
[www.vanrenterghem.biz.git] / phpBB2_old / admin / xs_include.php
1 <?php
3 /***************************************************************************
4  *                               xs_include.php
5  *                               --------------
6  *   copyright            : (C) 2003 CyberAlien
7  *   support              : http://www.phpbbstyles.com
8  *
9  *   version              : 2.0.1
10  *
11  *   file revision        : 41
12  *   project revision     : 51
13  *   last modified        : 25 Aug 2004  11:51:47
14  *
15  ***************************************************************************/
17 /***************************************************************************
18  *
19  *   This program is free software; you can redistribute it and/or modify
20  *   it under the terms of the GNU General Public License as published by
21  *   the Free Software Foundation; either version 2 of the License, or
22  *   (at your option) any later version.
23  *
24  ***************************************************************************/
26 if (!defined('IN_PHPBB') || !defined('IN_XS'))
27 {
28         die('Hacking attempt');
29 }
31 if(defined('XS_INCLUDED'))
32 {
33         return;
34 }
35 define('XS_INCLUDED', true);
38 //
39 // include language file
40 //
42 if(!defined('XS_LANG_INCLUDED'))
43 {
44         global $phpbb_root_path, $board_config, $phpEx, $lang;
45         $xs_lang_file = $phpbb_root_path . 'language/lang_' . $board_config['default_lang'] . '/lang_xs.'.$phpEx;
46         if( !@file_exists($xs_lang_file) )
47         {       // load english version if there is no translation to current language
48                 $xs_lang_file = $phpbb_root_path . 'language/lang_english/lang_xs.'.$phpEx;
49         }
50         include($xs_lang_file);
51         define('XS_LANG_INCLUDED', true);
52 }
55 define('XS_SHOWNAV_CONFIG', 0);
56 define('XS_SHOWNAV_INSTALL', 1);
57 define('XS_SHOWNAV_UNINSTALL', 2);
58 define('XS_SHOWNAV_DEFAULT', 3);
59 define('XS_SHOWNAV_CACHE', 4);
60 define('XS_SHOWNAV_IMPORT', 5);
61 define('XS_SHOWNAV_EXPORT', 6);
62 define('XS_SHOWNAV_CLONE', 7);
63 define('XS_SHOWNAV_DOWNLOAD', 8);
64 define('XS_SHOWNAV_EDITTPL', 9);
65 define('XS_SHOWNAV_EDITDB', 10);
66 define('XS_SHOWNAV_EXPORTDB', 11);
67 define('XS_SHOWNAV_UPDATES', 12);
68 define('XS_SHOWNAV_MAX', 13);
70 global $xs_shownav_action;
71 $xs_shownav_action = array(
72         'config',
73         'install',
74         'uninstall',
75         'default',
76         'cache',
77         'import',
78         'export',
79         'clone',
80         'download',
81         'edittpl',
82         'editdb',
83         'exportdb',
84         'updates',
85         );
88 // override styles management in admin navigation
89 function xs_admin_override($modded = false)
90 {
91         if(defined('XS_ADMIN_OVERRIDE_FINISHED'))
92         {
93                 return;
94         }
95         define('XS_ADMIN_OVERRIDE_FINISHED', true);
96         global $module, $phpEx, $xs_shownav_action, $board_config, $lang;
97         // remove default phpBB styles management
98         if(isset($module['Styles']))
99         {
100                 $unset = array('Add_new', 'Create_new', 'Manage', 'Export');
101                 for($i=0; $i<count($unset); $i++)
102                 {
103                         if(isset($module['Styles'][$unset[$i]]))
104                         {
105                                 unset($module['Styles'][$unset[$i]]);
106                         }
107                 }
108                 $module['Styles']['Menu'] = 'xs_frameset.'.$phpEx.'?action=menu&showwarning=1';
109         }
110         // add new menu
111         $module_name = 'Extreme_Styles';
112         $module[$module_name]['Styles_Management'] = 'xs_frameset.'.$phpEx.'?action=menu';
113         for($i=0; $i<XS_SHOWNAV_MAX; $i++)
114         {
115                 $num = pow(2, $i);
116                 if($i != XS_SHOWNAV_DOWNLOAD && ($board_config['xs_shownav'] & $num) > 0)
117                 {
118                         $module[$module_name][$lang['xs_config_shownav'][$i]] = 'xs_frameset.'.$phpEx.'?action=' . $xs_shownav_action[$i];
119                 }
120         }
124 if(!empty($setmodules))
126         if(@function_exists('jr_admin_get_module_list'))
127         {
128                 $tmp_mod = $module;
129                 global $module;
130                 $module = $tmp_mod;
131                 xs_admin_override(true);
132         }
133         return;
136 //
137 // Global defines for eXtreme Styles mod administration panel
138 //
139 define('STYLE_HEADER_START', 'xs_style_01<xs>');
140 define('STYLE_HEADER_END', '</xs>');
141 define('STYLE_HEADER_VERSION', '1');
142 define('STYLE_EXTENSION', '.style');
143 define('TAR_HEADER_PACK', 'a100A8A8A8A12A12A8A1A100A6A2A32A32A8A8a155a12');
144 define('TAR_HEADER_UNPACK', 'a100filename/a8mode/a8uid/a8gid/a12size/a12mtime/a8checksum/a1typeflag/a100link/a6magic/a2version/a32uname/a32gname/a8devmajor/a8devminor/a155prefix/a12extra');
145 define('XS_MAX_ITEMS_PER_STYLE', 32);
146 define('XS_TEMP_DIR', '../cache/');
147 define('XS_FTP_LOCAL', 'no_ftp');
148 define('XS_UPDATE_STYLE', 1);
149 define('XS_UPDATE_MOD', 2);
150 define('XS_UPDATE_PHPBB', 3);
151 define('XS_TPL_PATH', '../../xs_mod/tpl/');
152 define('XS_BACKUP_PREFIX', 'backup.');
153 define('XS_BACKUP_EXT', '.backup');
154 define('XS_MAX_TIMEOUT', 600); // maximum timeout for downloads/import/installation
156 $xs_row_class = array('row1', 'row2');
158 $template_dir = 'templates/';
160 $template->assign_vars(array(
161         'XS_PATH'       => '../xs_mod/',
162         'XS_UL'         => '<table width="100%" cellspacing="0" cellpadding="2" border="0">',
163         'XS_UL2'        => '</table>',
164         'XS_LI'         => '<tr><td width="20" align="center" valign="middle"><img src="../xs_mod/images/dot.gif" border="0" alt="" /></td><td align="left" valign="middle" width="100%"><span class="gen">',
165         'XS_LI2'        => '</span></td></tr>',
166         'S_HIDDEN_FIELDS'       => '<input type="hidden" name="sid" value="' . $userdata['session_id'] . '" />',
167         ));
169 if(!defined('NO_XS_HEADER'))
171         $template->set_filenames(array(
172                 'xs_header' => XS_TPL_PATH . 'xs_header.tpl',
173                 'xs_footer' => XS_TPL_PATH . 'xs_footer.tpl',
174                 ));
175         $template->preparse = 'xs_header';
176         $template->postparse = 'xs_footer';
177         $template->assign_block_vars('nav_left',array('ITEM' => '<a href="' . append_sid('xs_index.'.$phpEx) . '">' . $lang['xs_menu'] . '</a>'));
181 header('Expires: ' . gmdate('D, d M Y H:i:s') . ' GMT');
182 header('Cache-Control: must-revalidate, post-check=0, pre-check=0');
184 //
185 // Check compatibility with mods
186 //
187 if(defined('CACHE_THEMES') && @function_exists('cache_themes'))
189         define('XS_MODS_CATEGORY_HIERARCHY', true);
191 if(isset($theme['theme_public']))
193         define('XS_MODS_ADMIN_TEMPLATES', true);
197 //
198 // Get FTP configuration
199 //
200 function get_ftp_config($action, $post = array(), $allow_local = false, $show_error = '')
202         global $template, $board_config, $db, $lang, $HTTP_POST_VARS, $HTTP_SERVER_VARS;
203         $board_config['xs_ftp_local'] = false;
204         // check if ftp can be used
205         if(!@function_exists('ftp_connect'))
206         {
207                 if($allow_local && xs_dir_writable('../templates/'))
208                 {
209                         $board_config['xs_ftp_local'] = true;
210                         return true;
211                 }
212                 xs_error($lang['xs_ftp_error_fatal']);
213         }
214         // check if we have configuration
215         if(!empty($HTTP_POST_VARS['get_ftp_config']))
216         {
217                 $vars = array('xs_ftp_host', 'xs_ftp_login', 'xs_ftp_path');
218                 for($i=0; $i<count($vars); $i++)
219                 {
220                         $var = $vars[$i];
221                         if($board_config[$var] !== $HTTP_POST_VARS[$var])
222                         {
223                                 $board_config[$var] = stripslashes($HTTP_POST_VARS[$var]);
224                                 $sql = "UPDATE " . CONFIG_TABLE . " SET config_value = '" . xs_sql($board_config[$var]) . "' WHERE config_name = '{$var}'";
225                                 $db->sql_query($sql);
226                         }
227                 }
228                 $board_config['xs_ftp_pass'] = stripslashes($HTTP_POST_VARS['xs_ftp_pass']);
229                 $board_config['xs_ftp_local'] = empty($HTTP_POST_VARS['xs_ftp_local']) ? false : true;
230                 return true;
231         }
232         // check ftp configuration
233         $xs_ftp_host = $board_config['xs_ftp_host'];
234         if(empty($xs_ftp_host))
235         {
236                 $str = $HTTP_SERVER_VARS['HTTP_HOST'];
237                 $template->assign_vars(array(
238                         'HOST_GUESS' => str_replace(array('{HOST}', '{CLICK}'), array($str, 'document.ftp.xs_ftp_host.value=\''.$str.'\''), $lang['xs_ftp_host_guess'])
239                         ));
240         }
241         $dir = getcwd();
242         $xs_ftp_login = $board_config['xs_ftp_login'];
243         if(empty($xs_ftp_login))
244         {
245                 if(substr($dir, 0, 6) === '/home/')
246                 {
247                         $str = substr($dir, 6);
248                         $pos = strpos($str, '/');
249                         if($pos)
250                         {
251                                 $str = substr($str, 0, $pos);
252                                 $template->assign_vars(array(
253                                         'LOGIN_GUESS' => str_replace(array('{LOGIN}', '{CLICK}'), array($str, 'document.ftp.xs_ftp_login.value=\''.$str.'\''), $lang['xs_ftp_login_guess'])
254                                 ));
255                         }
256                 }
257         }
258         $xs_ftp_path = $board_config['xs_ftp_path'];
259         if(empty($xs_ftp_path))
260         {
261                 if(substr($dir, 0, 6) === '/home/');
262                 $str = substr($dir, 6);
263                 $pos = strpos($str, '/');
264                 if($pos)
265                 {
266                         $str = substr($str, $pos + 1);
267                         $pos = strrpos($str, 'admin');
268                         if($pos)
269                         {
270                                 $str = substr($str, 0, $pos-1);
271                                 $template->assign_vars(array(
272                                         'PATH_GUESS' => str_replace(array('{PATH}', '{CLICK}'), array($str, 'document.ftp.xs_ftp_path.value=\''.$str.'\''), $lang['xs_ftp_path_guess'])
273                                 ));
274                         }
275                 }
276         }
277         if($allow_local && xs_dir_writable('../templates/'))
278         {
279                 $template->assign_block_vars('xs_ftp_local', array());
280         }
281         else
282         {
283                 $template->assign_block_vars('xs_ftp_nolocal', array());
284         }
285         $str = '<input type="hidden" name="get_ftp_config" value="1" />';
286         foreach($post as $var => $value)
287         {
288                 $str .= '<input type="hidden" name="' . htmlspecialchars($var) . '" value="' . htmlspecialchars($value) . '" />';
289         }
290         $template->assign_vars(array(
291                         'FORM_ACTION'           => $action,
292                         'S_EXTRA_FIELDS'        => $str,
293                         'XS_FTP_HOST'           => $xs_ftp_host,
294                         'XS_FTP_LOGIN'          => $xs_ftp_login,
295                         'XS_FTP_PATH'           => $xs_ftp_path,
296                 ));
297         if($show_error)
298         {
299                 $template->assign_block_vars('error', array('MSG' => $show_error));
300         }
301         $template->set_filenames(array('config' => XS_TPL_PATH . 'ftp.tpl'));
302         $template->pparse('config');
303         return false;
306 // connect ftp
307 function xs_ftp_connect($action, $post = array(), $allow_local = false)
309         global $ftp, $board_config, $HTTP_POST_VARS, $phpEx, $lang, $template;
310         $HTTP_POST_VARS['get_ftp_config'] = '';
311         if($allow_local && !empty($board_config['xs_ftp_local']))
312         {
313                 $ftp = XS_FTP_LOCAL;
314                 return true;
315         }
316         $ftp = @ftp_connect($board_config['xs_ftp_host']);
317         if(!$ftp)
318         {
319                 get_ftp_config($action, $post, $allow_local, str_replace('{HOST}', $board_config['xs_ftp_host'], $lang['xs_ftp_error_connect']));
320         }
321         $res = @ftp_login($ftp, $board_config['xs_ftp_login'], $board_config['xs_ftp_pass']);
322         if(!$res)
323         {
324                 get_ftp_config($action, $post, $allow_local, $lang['xs_ftp_error_login']);
325         }
326         $res = @ftp_chdir($ftp, $board_config['xs_ftp_path']);
327         if(!$res)
328         {
329                 get_ftp_config($action, $post, $allow_local, str_replace('{DIR}', $board_config['xs_ftp_path'], $lang['xs_ftp_error_chdir']));
330         }
331         // check current directory
332         $current_dir = @ftp_pwd($ftp);
333         $list = @ftp_nlist($ftp, $current_dir);
334         for($i=0; $i<count($list); $i++)
335         {
336                 $list[$i] = strtolower(basename($list[$i]));
337         }
338         // check few files
339         $check = array('extension.inc', 'templates', 'xs_mod');
340         $found = array(false, false, false);
341         for($i=0; $i<count($list); $i++)
342         {
343                 for($j=0; $j<count($check); $j++)
344                 {
345                         if($list[$i] === $check[$j])
346                         {
347                                 $found[$j] = true;
348                         }
349                 }
350         }
351         $error = false;
352         for($i=0; $i<count($check); $i++)
353         {
354                 if(!$found[$i])
355                 {
356                         $error = true;
357                 }
358         }
359         if($error)
360         {
361                 get_ftp_config($action, $post, $allow_local, $lang['xs_ftp_error_nonphpbbdir']);
362         }
363         $HTTP_POST_VARS['get_ftp_config'] = '1';
366 // get .style file header
367 function xs_get_style_header($filename, $str = '')
369         /*
370         header format (v0.01):
371         - header
372         - header size (4 bytes)
373         - file size (4 bytes)
374         - number of entries (1 byte)
375     - entries sizes (number_of_entries bytes)
376     - entries
377         - footer
378         - gzcompressed tar of style (no crc check in tar)
380         entries:
381           - template name
382       - comment
383           - style names
384         */
385         global $xs_header_error, $lang;
386         $xs_header_error = '';
387         if(!$str)
388         {
389                 $f = @fopen($filename, 'rb');
390                 if(!$f)
391                 {
392                         $xs_header_error = $lang['xs_style_header_error_file'];
393                         return false;
394                 }
395                 $str = fread($f, 10240);
396                 fclose($f);
397         }
398         if(substr($str, 0, strlen(STYLE_HEADER_START)) !== STYLE_HEADER_START)
399         {
400                 if(substr($str, 0, 7) === 'error: ')
401                 {
402                         $xs_header_error = '<br /><br />' . $lang['xs_style_header_error_server'] . substr($str, 7);
403                 }
404                 else
405                 {
406                         $xs_header_error = $lang['xs_style_header_error_invalid'];
407                 }
408                 return false;
409         }
410         $start = strlen(STYLE_HEADER_START);
411         $str1 = substr($str, $start, 8);
412         $data = unpack('Nvar1/Nvar2', $str1);
413         $start += 8;
414         $header_size = $data['var1'];
415         $filesize = $data['var2'];
416         $total = ord($str{$start});
417         $start ++;
418         if($total < 3)
419         {
420                 $xs_header_error = $lang['xs_style_header_error_invalid'];
421                 return false;
422         }
423         $items_len = array();
424         for($i=0; $i<$total; $i++)
425         {
426                 $items_len[$i] = ord($str{$i+$start});
427         }
428         $start += $total;
429         $items = array();
430         $tpl = '';
431         for($i=0; $i<$total; $i++)
432         {
433                 $str1 = substr($str, $start, $items_len[$i]);
434                 if($i == 0)     $tpl = $str1;
435                 elseif($i == 1) $comment = $str1;
436                 else    $items[] = $str1;
437                 $start += $items_len[$i];
438         }
439         if(substr($str, $start, strlen(STYLE_HEADER_END)) !== STYLE_HEADER_END)
440         {
441                 $xs_header_error = $lang['xs_style_header_error_invalid'];
442                 return false;
443         }
444         return array(
445                 'template'      => $tpl,
446                 'styles'        => $items,
447                 'date'          => @filemtime($filename),
448                 'comment'       => $comment,
449                 'offset'        => $header_size,
450                 'filename'      => $filename,
451                 'filesize'      => $filesize,
452                 );
456 // check if cache is writable
457 function xs_check_cache($filename)
459         // check if filename is valid
460         global $str, $template, $lang;
461         if(substr($filename, 0, strlen($template->cachedir)) !== $template->cachedir)
462         {
463                 $str .= $lang['xs_check_filename'] . "<br />\n";
464                 return false;
465         }
466         else
467         {
468                 // try to open file
469                 $file = @fopen($filename, 'w');
470                 if(!$file)
471                 {
472                         $str .= sprintf($lang['xs_check_openfile1'], $filename) . "<br />\n";
473                         // try to create directories
474                         $dir = substr($filename, strlen($template->cachedir), strlen($filename));
475                         $dirs = explode('/', $dir);
476                         $path = $template->cachedir; 
477                         @umask(0);
478                         if(!@is_dir($path))
479                         {
480                                 $str .= sprintf($lang['xs_check_nodir'], $path) . "<br />\n";
481                                 if(!@mkdir($path))
482                                 {
483                                         $str .= sprintf($lang['xs_check_nodir2'], $path) . "<br />\n";
484                                         return false;
485                                 }
486                                 else
487                                 {
488                                         $str .= sprintf($lang['xs_check_createddir'], $path) . "<br />\n";
489                                         @chmod($path, 0777);
490                                 }
491                         }
492                         else
493                         {
494                                 $str .= sprintf($lang['xs_check_dir'] , $path) . "<br />\n";
495                         }
496                         if(count($dirs) > 0)
497                         for($i=0; $i<count($dirs)-1; $i++)
498                         {
499                                 if($i>0)
500                                 {
501                                         $path .= '/';
502                                 }
503                                 $path .= $dirs[$i];
504                                 if(!@is_dir($path))
505                                 {
506                                         $str .= sprintf($lang['xs_check_nodir'], $path) . "<br />\n";
507                                         if(!@mkdir($path))
508                                         {
509                                                 $str .= sprintf($lang['xs_check_nodir2'], $path) . "<br />\n";
510                                                 return false;
511                                         }
512                                         else
513                                         {
514                                                 $str .= sprintf($lang['xs_check_createddir'], $path) . "<br />\n";
515                                                 @chmod($path, 0777);
516                                         }
517                                 }
518                                 else
519                                 {
520                                         $str .= sprintf($lang['xs_check_dir'] , $path) . "<br />\n";
521                                 }
522                         }
523                         // try to open file again after directories were created
524                         $file = @fopen($filename, 'w');
525                 }
526                 if(!$file)
527                 {
528                         $str .= sprintf($lang['xs_check_openfile2'], $filename) . "<br />\n";
529                         return false;
530                 }
531                 $str .= sprintf($lang['xs_check_ok'], $filename) . "<br />\n";
532                 fputs($file, '&nbsp;');
533                 fclose($file);
534                 @chmod($filename, 0777);
535                 return true;
536         }
539 // run ftp commands
540 function ftp_myexec($list)
542         global $ftp, $ftp_error, $ftp_log, $ftp_host, $ftp_login, $ftp_pass, $lang;
543         $ftp_error = '';
544         $ftp_log = array();
545         if(empty($ftp))
546         {
547                 // checking ftp extensions
548                 if(!@function_exists('ftp_connect'))
549                 {
550                         $ftp_log[] = $ftp_error = $lang['xs_ftp_log_disabled'];
551                         return false;
552                 }
553                 // connect to server
554                 $ftp_log[] = str_replace('{HOST}', "{$ftp_login}:*@{$ftp_host}", $lang['xs_ftp_log_connecting']);
555                 $ftp = @ftp_connect($ftp_host);
556                 if(!$ftp)
557                 {
558                         $ftp_log[] = $ftp_error = str_replace('{HOST}', $ftp_host, $lang['xs_ftp_log_noconnect']);
559                         return false;
560                 }
561                 $ftp_log[] = $lang['xs_ftp_log_connected'];
562                 // logging in
563                 $logged_in = @ftp_login($ftp, $ftp_login, $ftp_pass);
564                 if(!$logged_in)
565                 {
566                         $ftp_log[] = $ftp_error = str_replace('{USER}', $ftp_login, $lang['xs_ftp_log_nologin']);
567                         @ftp_close($ftp);
568                         return false;
569                 }
570                 $ftp_log[] = $lang['xs_ftp_log_loggedin'];
571         }
572         if(!ftp_myexec2($ftp, $list))
573         {
574                 @ftp_close($ftp);
575                 return false;
576         }
577         @ftp_close($ftp);
578         $ftp_log[] = $lang['xs_ftp_log_end'];
579         return true;
582 // remove all files via ftp
583 function ftp_remove_all($ftp)
585         // get current directory
586         $root_dir = @ftp_pwd($ftp);
587         // get list of files
588         $files = @ftp_nlist($ftp, $root_dir);
589         // remove files/directories
590         for($i=0; $i<count($files); $i++)
591         {
592                 $res = @ftp_chdir($ftp, $files[$i]);
593                 if($res)
594                 {
595                         ftp_remove_all($ftp);
596                         @ftp_chdir($ftp, $root_dir);
597                         @ftp_rmdir($ftp, $files[$i]);
598                 }
599                 else
600                 {
601                         if(!@ftp_delete($ftp, $files[$i]))
602                         {
603                                 @ftp_rmdir($ftp, $files[$i]);
604                         }
605                 }
606         }
607         // change directory back
608         @ftp_chdir($ftp, $root_dir);
611 // execute ftp command. recursive.
612 function ftp_myexec2($ftp, $list)
614         global $ftp_log, $ftp_error, $lang;
615         // getting current directory
616         $root_dir = @ftp_pwd($ftp);
617         if($root_dir === false)
618         {
619                 $ftp_log[] = $ftp_error = $lang['xs_ftp_log_nopwd'];
620                 return false;
621         }
622         $current_dir = strlen($root_dir) ? $root_dir . '/' : '';
623         // run commands
624         for($i=0; $i<count($list); $i++)
625         {
626                 $item=$list[$i];
627                 if($item['command'] == 'mkdir')
628                 {
629                         // create new directory
630                         $res = @ftp_mkdir($ftp, $item['dir']);
631                         if(!$res)
632                         {
633                                 $ftp_log[] = $ftp_error = str_replace('{DIR}', $item['dir'], $lang['xs_ftp_log_nomkdir']);
634                                 if(empty($item['ignore']))
635                                 {
636                                         return false;
637                                 }
638                         }
639                         else
640                         {
641                                 $ftp_log[] = str_replace('{DIR}', $item['dir'], $lang['xs_ftp_log_mkdir']);
642                         }
643                 }
644                 elseif($item['command'] == 'chdir')
645                 {
646                         // change current directory
647                         $res = @ftp_chdir($ftp, $item['dir']);
648                         if(!$res)
649                         {
650                                 $ftp_log[] = $ftp_error = str_replace('{DIR}', $item['dir'], $lang['xs_ftp_log_nochdir']);
651                                 if(empty($item['ignore']))
652                                 {
653                                         return false;
654                                 }
655                         }
656                         else
657                         {
658                                 $ftp_log[] = str_replace('{DIR}', $item['dir'], $lang['xs_ftp_log_chdir']);
659                         }
660                 }
661                 elseif($item['command'] == 'cdup')
662                 {
663                         // change current directory
664                         $res = @ftp_cdup($ftp);
665                         if(!$res)
666                         {
667                                 $ftp_log[] = $ftp_error = str_replace('{DIR}', '..', $lang['xs_ftp_log_nochdir']);
668                                 if(empty($item['ignore']))
669                                 {
670                                         return false;
671                                 }
672                         }
673                         else
674                         {
675                                 $ftp_log[] = str_replace('{DIR}', '..', $lang['xs_ftp_log_chdir']);
676                         }
677                 }
678                 elseif($item['command'] == 'rmdir')
679                 {
680                         // remove directory
681                         $res = @ftp_rmdir($ftp, $item['dir']);
682                         if(!$res)
683                         {
684                                 $ftp_log[] = $ftp_error = str_replace('{DIR}', $item['dir'], $lang['xs_ftp_log_normdir']);
685                                 if(empty($item['ignore']))
686                                 {
687                                         return false;
688                                 }
689                         }
690                         else
691                         {
692                                 $ftp_log[] = str_replace('{DIR}', $item['dir'], $lang['xs_ftp_log_rmdir']);
693                         }
694                 }
695                 elseif($item['command'] == 'upload')
696                 {
697                         // upload file
698                         $res = @ftp_put($ftp, $current_dir . $item['remote'], $item['local'], FTP_BINARY);
699                         if(!$res)
700                         {
701                                 $ftp_log[] = $ftp_error = str_replace('{FILE}', $item['remote'], $lang['xs_ftp_log_noupload']);
702                                 if(empty($item['ignore']))
703                                 {
704                                         return false;
705                                 }
706                         }
707                         else
708                         {
709                                 $ftp_log[] = str_replace('{FILE}', $item['remote'], $lang['xs_ftp_log_upload']);
710                         }
711                 }
712                 elseif($item['command'] == 'chmod')
713                 {
714                         // upload file
715                         $res = @ftp_chmod($ftp, $item['mode'], $current_dir . $item['file']);
716                         if(!$res)
717                         {
718                                 $ftp_log[] = str_replace('{FILE}', $item['file'], $lang['xs_ftp_log_nochmod']);
719                                 if(empty($item['ignore']))
720                                 {
721                                         return false;
722                                 }
723                         }
724                         else
725                         {
726                                 $ftp_log[] = str_replace(array('{FILE}', '{MODE}'), array($item['file'], $item['mode']), $lang['xs_ftp_log_chmod']);
727                         }
728                 }
729                 elseif($item['command'] == 'exec')
730                 {
731                         $res = ftp_myexec2($ftp, $item['list']);
732                         if(!$res)
733                         {
734                                 return false;
735                         }
736                 }
737                 elseif($item['command'] == 'removeall')
738                 {
739                         ftp_remove_all($ftp);
740                 }
741                 else
742                 {
743                         $ftp_log[] = str_replace('{COMMAND}', $item['command'], $lang['xs_ftp_log_invalidcommand']);
744                         if(empty($item['ignore']))
745                         {
746                                 return false;
747                         }
748                 }
749         }
750         // changing current directory back
751         $ftp_log[] = str_replace('{DIR}', $root_dir, $lang['xs_ftp_log_chdir2']);
752         if(!@ftp_chdir($ftp, $root_dir))
753         {
754                 $ftp_log[] = $ftp_error = str_replace('{DIR}', $root_dir, $lang['xs_ftp_log_nochdir2']);
755                 return false;
756         }
757         return true;
760 // return data from theme_info.cfg
761 function xs_get_themeinfo($tpl)
763         // Get contents of theme_info.cfg
764         // Run inside function to avoid theme_info.cfg accessing global variables
765         @include('../templates/' . $tpl . '/theme_info.cfg');
766         return isset($$tpl) ? $$tpl : array();
769 // install style
770 function xs_install_style($tpl, $num)
772         global $db;
773         $data = xs_get_themeinfo($tpl);
774         if(empty($data[$num]))
775         {
776                 return false;
777         }
778         $data = $data[$num];
779         if(empty($data['style_name']))
780         {
781                 return false;
782         }
783         $sql = "SELECT themes_id FROM " . THEMES_TABLE . " WHERE style_name='" . xs_sql($data['style_name']) . "'";
784         if(!$result = $db->sql_query($sql))
785         {
786                 return false;
787         }
788         $row = $db->sql_fetchrow($result);
789         if(!empty($row['themes_id']))
790         {
791                 return false;
792         }
793         $vars = array();
794         $values = array();
795         foreach($data as $var => $value)
796         {
797                 $vars[] = xs_sql($var);
798                 $values[] = xs_sql(stripslashes($value));
799         }
800         $sql = "INSERT INTO " . THEMES_TABLE . " (" . implode(', ', $vars) . ") VALUES ('" . implode("', '", $values) . "')";
801         if(!$result = $db->sql_query($sql))
802         {
803                 return false;
804         }
805         return true;
808 // generate theme_info.cfg for template
809 function xs_generate_themeinfo($theme_rowset, $export, $exportas, $total)
811         global $HTTP_POST_VARS;
812         $vars = array('template_name', 'style_name', 'head_stylesheet', 'body_background', 'body_bgcolor', 'body_text', 'body_link', 'body_vlink', 'body_alink', 'body_hlink', 'tr_color1', 'tr_color2', 'tr_color3', 'tr_class1', 'tr_class2', 'tr_class3', 'th_color1', 'th_color2', 'th_color3', 'th_class1', 'th_class2', 'th_class3', 'td_color1', 'td_color2', 'td_color3', 'td_class1', 'td_class2', 'td_class3', 'fontface1', 'fontface2', 'fontface3', 'fontsize1', 'fontsize2', 'fontsize3', 'fontcolor1', 'fontcolor2', 'fontcolor3', 'span_class1', 'span_class2', 'span_class3', 'img_size_poll', 'img_size_privmsg');
813         $theme_data = '<?php'."\n\n";
814         $theme_data .= "//\n// eXtreme Styles mod (compatible with phpBB 2.0.x) auto-generated theme config file for $exportas\n// Do not change anything in this file unless you know exactly what you are doing!\n//\n\n";
815         for($i = 0; $i < count($theme_rowset); $i++)
816         {
817                 $id = $theme_rowset[$i]['themes_id'];
818                 $theme_name = $theme_rowset[$i]['style_name'];
819                 for($j=0; $j<$total; $j++)
820                 {
821                         if(!empty($HTTP_POST_VARS['export_style_name_'.$j]) && $HTTP_POST_VARS['export_style_id_'.$j] == $id)
822                         {
823                                 $theme_name = stripslashes($HTTP_POST_VARS['export_style_name_'.$j]);
824                                 $theme_rowset[$i]['style_name'] = $theme_name;
825                         }
826                 }
827                 for($j=0; $j<count($vars); $j++)
828                 {
829                         $key = $vars[$j];
830                         $val = $theme_rowset[$i][$key];
831                         if($key === 'style_name')
832                         {
833                                 $theme_data .= '${\'' . $exportas . "'}[$i]['$key'] = \"" . str_replace(array("'", '"'), array("\'", "\\\""), $theme_name) . "\";\n";
834                         }
835                         elseif($key === 'template_name')
836                         {
837                                 $theme_data .= '${\'' . $exportas . "'}[$i]['$key'] = \"" . str_replace(array("'", '"'), array("\'", "\\\""), $exportas) . "\";\n";
838                         }
839                         else
840                         {
841                                 $theme_data .= '${\'' . $exportas . "'}[$i]['$key'] = \"" . str_replace(array("'", '"'), array("\'", "\\\""), str_replace($export, $exportas, $val)) . "\";\n";
842                         }
843                 }
844                 $theme_data .= "\n";
845         }
846         $theme_data .= '?' . '>'; // Done this to prevent highlighting editors getting confused!
847         return $theme_data;
850 // Checks if directory is writable
851 function xs_dir_writable($dir)
853         $filename = 'tmp_' . time();
854         $f = @fopen($dir . $filename, 'wb');
855         if($f)
856         {
857                 fclose($f);
858                 @unlink($dir . $filename);
859                 return true;
860         }
861         return false;
864 // Write to file. Create directory if necessary
865 function xs_write_file($filename, $data)
867         $f = @fopen($filename, 'wb');
868         if(!$f)
869         {
870                 // try to create directories
871                 $pos = strrpos($filename, '/');
872                 if(!$pos)
873                 {
874                         return false;
875                 }
876                 $dir = substr($filename, 0, $pos);
877                 xs_create_dir($dir);
878                 $f = @fopen($filename, 'wb');
879                 if(!$f)
880                 {
881                         return false;
882                 }
883         }
884         fwrite($f, $data);
885         fclose($f);
886         @chmod($filename, 0777);
887         return true;
890 // Create local directory
891 function xs_create_dir($dir)
893         if(!$dir)
894         {
895                 return false;
896         }
897         // remove trailing /
898         if(substr($dir, strlen($dir) - 1) === '/')
899         {
900                 $dir = substr($dir, 0, strlen($dir) - 1);
901                 if(!$dir)
902                 {
903                         return false;
904                 }
905         }
906         if($dir === '.' || $dir === '..')
907         {
908                 return false;
909         }
910         $res = @mkdir($dir, 0777);
911         if($res)
912         {
913                 return true;
914         }
915         // try to create previous directory
916         $pos = strrpos($dir, '/');
917         if(!$pos)
918         {
919                 return false;
920         }
921         $dir1 = substr($dir, 0, $pos);
922         $dir2 = substr($dir, $pos+1);
923         if($dir2 === '.' || $dir2 === '..')
924         {
925                 return false;
926         }
927         if(!xs_create_dir($dir1))
928         {
929                 return false;
930         }
931         $res = @mkdir($dir2, 0777);
932         return $res ? true : false;
935 // replacement for in_array() (because of compatibility problems)
936 function xs_in_array($needle, $haystack)
938         for($i=0; $i<sizeof($haystack); $i++)
939         {
940                 if($haystack[$i] == $needle)
941                 {
942                         return true;
943                 }
944         }
945         return false;
948 // show error and exit
949 function xs_error($error, $line = 0, $file = '')
951         global $template, $lang;
952         if($line || $file)
953         {
954                 $error = basename($file) . '(' . $line . '): ' . $error;
955         }
956         $template->set_filenames(array('errormsg' => XS_TPL_PATH . 'message.tpl'));
957         $template->assign_vars(array(
958                         'MESSAGE_TITLE' => $lang['Error'],
959                         'MESSAGE_TEXT'  => $error
960                 ));
961         $template->pparse('errormsg');
962         xs_exit();
965 // show message and exit
966 function xs_message($title, $message)
968         global $template;
969         $template->set_filenames(array('msg' => XS_TPL_PATH . 'message.tpl'));
970         $template->assign_vars(array(
971                         'MESSAGE_TITLE' => $title,
972                         'MESSAGE_TEXT'  => $message
973                 ));
974         $template->pparse('msg');
975         xs_exit();
978 // pack style to .style
979 function pack_style($name, $newname, $themes, $comment)
981         /*
982         header format (v0.01):
983         - header
984         - header size (4 bytes)
985         - file size (4 bytes)
986         - number of entries (1 byte)
987     - entries sizes (number_of_entries bytes)
988     - entries
989         - footer
990         - gzcompressed tar of style (no crc check in tar)
992         entries:
993           - template name
994       - comment
995           - style names
996         */
997         global $phpbb_root_path, $template_dir;
998         $data = gzcompress(pack_dir($phpbb_root_path . $template_dir . $name, '', $name, $newname));
999         $items_data = chr(strlen($newname)) . chr(strlen($comment));
1000         $items_str = $newname . $comment;
1001         for($i=0; $i<count($themes); $i++)
1002         {
1003                 $str = $themes[$i]['style_name'];
1004                 $items_data .= chr(strlen($str));
1005                 $items_str .= $str;
1006         }
1007         $header_size = strlen(STYLE_HEADER_START) + 8 + 1 + strlen($items_data) + strlen($items_str) + strlen(STYLE_HEADER_END);
1008         $filesize = $header_size + strlen($data);
1009         $header = STYLE_HEADER_START . pack('NN', $header_size, $filesize) . chr(strlen($items_data)) . $items_data . $items_str . STYLE_HEADER_END;
1010         return $header . $data;
1013 // pack directory
1014 function pack_dir($dir1, $dir2, $search, $replace)
1016         global $pack_error, $pack_list, $pack_replace, $lang;
1017         // replacements in content
1018         $search2 = array('templates/'.$search.'/'.$search, 'templates/'.$search);
1019         $replace2 = array('templates/'.$replace.'/'.$replace, 'templates/'.$replace);
1020         // replacements in filename
1021         $search3 = './'.$search;
1022         $replace3 = './'.$replace;
1023         if($pack_error)
1024         {
1025                 return '';
1026         }
1027         $dir = $dir1 . '/' . $dir2;
1028         $res = @opendir($dir);
1029         $str = '';
1030         if(!$res)
1031         {
1032                 $pack_error = str_replace('{DIR}', $lang['xs_export_no_open_dir'], $dir);
1033                 return '';
1034         }
1035         // get list of files/directories
1036         $files = array();
1037         $subdir = array();
1038         while(($file = readdir($res)) !== false)
1039         {
1040                 if($file !== '.' && $file !== '..')
1041                 {
1042                         if(@is_dir($dir . '/' . $file))
1043                         {
1044                                 $subdir[] = $file;
1045                         }
1046                         elseif(@is_file($dir . '/' . $file))
1047                         {
1048                                 $files[] = $file;
1049                         }
1050                 }
1051         }
1052         closedir($res);
1053         // add current directory
1054         $base_dir = ($dir2 ? $dir2 : '.') . '/';
1055         $header = array(
1056                 'filename'      => $base_dir,
1057                 'mode'          => '40777',
1058                 'uid'           => '0',
1059                 'gid'           => '0',
1060                 'size'          => decoct(0),
1061                 'mtime'         => decoct(@filemtime($dir)),
1062                 'checksum'      => '0', // ignore checksum
1063                 'typeflag'      => '5',
1064                 'link'          => '',
1065                 'magic'         => "ustar",
1066                 'version'       => '',
1067                 'uname'         => 'user',
1068                 'gname'         => 'group',
1069                 'devmajor'      => '',
1070                 'devminor'      => '',
1071                 'prefix'        => '',
1072                 'extra'         => ''
1073                 );
1074         $header_str = pack(TAR_HEADER_PACK, $header['filename'], $header['mode'], $header['uid'], $header['gid'], $header['size'], $header['mtime'], $header['checksum'], $header['typeflag'], $header['linkname'], $header['magic'], $header['version'], $header['uname'], $header['gname'], $header['devmajor'], $header['devminor'], $header['prefix'], $header['extra']);
1075         $file_str = '';
1076         $extra_str = '';
1077         $str .= $header_str . $file_str . $extra_str;
1078         // add all files
1079         for($i=0; $i<count($files); $i++)
1080         {
1081                 $file = $files[$i];
1082                 $header['filename'] = $base_dir . $file;
1083                 $pack_list[] = $header['filename'];
1084                 if(isset($pack_replace[$header['filename']]))
1085                 {
1086                         $file_str = $pack_replace[$header['filename']];
1087                         $file_size = strlen($file_str);
1088                 }
1089                 else
1090                 {
1091                         $f = @fopen($dir . '/' . $file, 'rb');
1092                         if(!$f)
1093                         {
1094                                 $pack_error = str_replace('{FILE}', $dir . '/' . $file, $lang['xs_export_no_open_file']);
1095                                 return '';
1096                         }
1097                         $file_size = @filesize($dir . '/' . $file);
1098                         if($file_size)
1099                         {
1100                                 $file_str = fread($f, $file_size);
1101                         }
1102                         else
1103                         {
1104                                 $file_str = '';
1105                         }
1106                         if(strlen($file_str) != $file_size)
1107                         {
1108                                 $pack_error = str_replace('{FILE}', $dir . '/' . $file, $lang['xs_export_no_read_file']);
1109                                 return '';
1110                         }
1111                         fclose($f);
1112                         if($search !== $replace)
1113                         {
1114                                 $file_str = str_replace($search2, $replace2, $file_str);
1115                         }
1116                 }
1117                 if($search !== $replace && substr($header['filename'], strlen($header['filename']) - 4) !== '.tpl')
1118                 {
1119                         if(substr($header['filename'], 0, strlen($search)) === $search)
1120                         {       
1121                                 $header['filename'] = $replace . substr($header['filename'], strlen($search));
1122                         }
1123                         elseif(substr($header['filename'], 0, strlen($search3)) === $search3)
1124                         {       
1125                                 $header['filename'] = $replace3 . substr($header['filename'], strlen($search3));
1126                         }
1127                 }
1128 /*              echo 'filename: ', $header['filename'], '<br />';
1129                 if($header['filename'] === './overall_header.tpl')
1130                 {
1131                         echo 'overall_header.tpl:<br /><hr />', nl2br(htmlspecialchars($file_str)), '<br /><hr /><br />';
1132                 }*/
1133                 $size = strlen($file_str);
1134                 $header['size'] = decoct($size);
1135                 $header['typeflag'] = '0';
1136                 $header['mode'] = '100666';
1137                 $full_size = floor(($size + 511) / 512) * 512;
1138                 $extra_str = $full_size > $size ? str_repeat("\0", $full_size - $size) : '';
1139                 $header_str = pack(TAR_HEADER_PACK, $header['filename'], $header['mode'], $header['uid'], $header['gid'], $header['size'], $header['mtime'], $header['checksum'], $header['typeflag'], $header['linkname'], $header['magic'], $header['version'], $header['uname'], $header['gname'], $header['devmajor'], $header['devminor'], $header['prefix'], $header['extra']);
1140                 $str .= $header_str . $file_str . $extra_str;
1141         }
1142         // add all directories
1143         for($i=0; $i<count($subdir); $i++)
1144         {
1145                 $str .= pack_dir($dir1, $dir2 ? $dir2 . '/' . $subdir[$i] : $subdir[$i], $search, $replace);
1146         }
1147         if(!$dir2)
1148         {
1149                 $str .= str_repeat("\0", 1024);
1150         }
1151         return $str;
1154 // save export configuration
1155 function set_export_method($method, $data)
1157         global $db, $board_config;
1158         $data['method'] = $method;
1159         $str = xs_sql(serialize($data));
1160         $sql = isset($board_config['xs_export_data']) ? "UPDATE " . CONFIG_TABLE . " SET config_value='{$str}' WHERE config_name='xs_export_data'" : "INSERT INTO " . CONFIG_TABLE . " (config_name, config_value) VALUES ('xs_export_data', '{$str}')";
1161         $db->sql_query($sql);
1164 // send file
1165 function xs_download_file($filename, $content, $content_type = '')
1167         if(empty($content_type))
1168         {
1169                 $content_type = 'application/unknown';
1170         }
1171         header('Content-Type: ' . $content_type);
1172         header('Content-Length: ' . strlen($content));
1173         header('Expires: ' . gmdate('D, d M Y H:i:s') . ' GMT');
1174         if($filename)
1175         {
1176                 header('Content-Disposition: inline; filename="' . $filename . '"');
1177         }
1178         header('Cache-Control: must-revalidate, post-check=0, pre-check=0');
1179         header('Pragma: public');
1180         echo $content;
1183 // strip slashes for sql
1184 function xs_sql($sql, $stip = false)
1186         if($strip)
1187         {
1188                 $sql = stripslashes($sql);
1189         }
1190         return str_replace("'", "''", $sql);
1193 // clean template name
1194 function xs_tpl_name($name)
1196         return str_replace(array('\\', '/', "'", '"'), array('','','',''), $name);
1199 // close database and maybe do some other stuff
1200 function xs_exit()
1202         global $db;
1203         if(isset($db))
1204         {
1205                 $db->sql_close();
1206         }
1207         exit;
1210 ?>