PageRenderTime 49ms CodeModel.GetById 21ms RepoModel.GetById 0ms app.codeStats 0ms

/source/function/function_cloudaddons.php

https://github.com/jinbo51/DiscuzX
PHP | 367 lines | 330 code | 31 blank | 6 comment | 79 complexity | b136532cc1ce07cbe47f7c8188b4eaca MD5 | raw file
Possible License(s): BSD-3-Clause
  1. <?php
  2. /**
  3. * [Discuz!] (C)2001-2099 Comsenz Inc.
  4. * This is NOT a freeware, use is subject to license terms
  5. *
  6. * $Id: function_cloudaddons.php 32559 2013-02-20 09:35:24Z monkey $
  7. */
  8. if(!defined('IN_DISCUZ')) {
  9. exit('Access Denied');
  10. }
  11. define('CLOUDADDONS_WEBSITE_URL', 'http://addon.discuz.com');
  12. define('CLOUDADDONS_DOWNLOAD_URL', 'http://addon.discuz.com/index.php');
  13. define('CLOUDADDONS_DOWNLOAD_IP', '');
  14. define('CLOUDADDONS_CHECK_URL', 'http://addon1.discuz.com');
  15. define('CLOUDADDONS_CHECK_IP', '');
  16. function cloudaddons_md5($file) {
  17. return dfsockopen(CLOUDADDONS_CHECK_URL.'/md5/'.$file, 0, '', '', false, CLOUDADDONS_CHECK_IP, 999);
  18. }
  19. function cloudaddons_url($extra) {
  20. global $_G;
  21. require_once DISCUZ_ROOT.'./source/discuz_version.php';
  22. $uniqueid = $_G['setting']['siteuniqueid'] ? $_G['setting']['siteuniqueid'] : C::t('common_setting')->fetch('siteuniqueid');
  23. $data = 'siteuniqueid='.rawurlencode($uniqueid).'&siteurl='.rawurlencode($_G['siteurl']).'&sitever='.DISCUZ_VERSION.'/'.DISCUZ_RELEASE.'&sitecharset='.CHARSET.'&mysiteid='.$_G['setting']['my_siteid'];
  24. $param = 'data='.rawurlencode(base64_encode($data));
  25. $param .= '&md5hash='.substr(md5($data.TIMESTAMP), 8, 8).'&timestamp='.TIMESTAMP;
  26. return CLOUDADDONS_DOWNLOAD_URL.'?'.$param.$extra;
  27. }
  28. function cloudaddons_check() {
  29. if(!function_exists('gzuncompress')) {
  30. cpmsg('cloudaddons_check_gzuncompress_error', '', 'error');
  31. }
  32. if(dfsockopen(CLOUDADDONS_WEBSITE_URL.'/image/logo.png', 4, '', '', false, CLOUDADDONS_DOWNLOAD_IP, 999) !== chr(0x89).'PNG') {
  33. cpmsg('cloudaddons_check_url_fopen_error', '', 'error');
  34. }
  35. if(dfsockopen(CLOUDADDONS_CHECK_URL.'/logo.png', 4, '', '', false, CLOUDADDONS_CHECK_IP, 999) !== chr(0x89).'PNG') {
  36. cpmsg('cloudaddons_check_url_fopen_error', '', 'error');
  37. }
  38. foreach(array('download', 'addonmd5') as $path) {
  39. $tmpdir = DISCUZ_ROOT.'./data/'.$path.'/'.random(5);
  40. $tmpfile = $tmpdir.'/index.html';
  41. dmkdir($tmpdir, 0777);
  42. if(!is_dir($tmpdir) || !file_exists($tmpfile)) {
  43. cpmsg('cloudaddons_check_write_error', '', 'error');
  44. }
  45. @unlink($tmpfile);
  46. @rmdir($tmpdir);
  47. if(is_dir($tmpdir) || file_exists($tmpfile)) {
  48. cpmsg('cloudaddons_check_write_error', '', 'error');
  49. }
  50. }
  51. }
  52. function cloudaddons_open($extra, $post = '') {
  53. return dfsockopen(cloudaddons_url('&from=s').$extra, 0, $post, '', false, CLOUDADDONS_DOWNLOAD_IP, 999);
  54. }
  55. function cloudaddons_pluginlogo_url($id) {
  56. return CLOUDADDONS_WEBSITE_URL.'?_'.$id;
  57. }
  58. function cloudaddons_installlog($addonid) {
  59. $array = cloudaddons_getmd5($addonid);
  60. if($array['RevisionID']) {
  61. cloudaddons_open('&mod=app&ac=installlog&rid='.$array['RevisionID']);
  62. }
  63. }
  64. function cloudaddons_downloadlog($addonid) {
  65. $array = cloudaddons_getmd5($addonid);
  66. if($array['RevisionID']) {
  67. cloudaddons_open('&mod=app&ac=downloadlog&rid='.$array['RevisionID']);
  68. }
  69. }
  70. function cloudaddons_faillog($rid, $type) {
  71. $rid = intval($rid);
  72. $type = intval($type);
  73. cloudaddons_open('&mod=app&ac=faillog&rid='.$rid.'&type='.$type.'&serverinfo='.urlencode($_SERVER['SERVER_SOFTWARE']));
  74. }
  75. function cloudaddons_removelog($rid) {
  76. global $_G;
  77. $reason = $_G['cookie']['uninstallreason'];
  78. dsetcookie('uninstallreason', '', -1);
  79. cloudaddons_open('&mod=app&ac=removelog&rid='.$rid.'&reason='.$reason);
  80. }
  81. function cloudaddons_validator($addonid) {
  82. $array = cloudaddons_getmd5($addonid);
  83. if(cloudaddons_open('&mod=app&ac=validator&ver=2&addonid='.$addonid.($array !== false ? '&rid='.$array['RevisionID'].'&sn='.$array['SN'].'&rd='.$array['RevisionDateline'] : '')) === '0') {
  84. cpmsg('cloudaddons_genuine_message', '', 'error', array('addonid' => $addonid));
  85. }
  86. }
  87. function cloudaddons_upgradecheck($addonids) {
  88. $post = array();
  89. foreach($addonids as $addonid) {
  90. $array = cloudaddons_getmd5($addonid);
  91. $post[] = 'rid['.$addonid.']='.$array['RevisionID'].'&sn['.$addonid.']='.$array['SN'].'&rd['.$addonid.']='.$array['RevisionDateline'];
  92. }
  93. return cloudaddons_open('&mod=app&ac=validator&ver=2', implode('&', $post));
  94. }
  95. function cloudaddons_getmd5($md5file) {
  96. $array = array();
  97. if(preg_match('/^[a-z0-9_\.]+$/i', $md5file) && file_exists(DISCUZ_ROOT.'./data/addonmd5/'.$md5file.'.xml')) {
  98. require_once libfile('class/xml');
  99. $xml = implode('', @file(DISCUZ_ROOT.'./data/addonmd5/'.$md5file.'.xml'));
  100. $array = xml2array($xml);
  101. } else {
  102. return false;
  103. }
  104. return $array;
  105. }
  106. function cloudaddons_uninstall($md5file, $dir) {
  107. $array = cloudaddons_getmd5($md5file);
  108. if($array === false) {
  109. return;
  110. }
  111. if(!empty($array['RevisionID'])) {
  112. cloudaddons_removelog($array['RevisionID']);
  113. }
  114. @unlink(DISCUZ_ROOT.'./data/addonmd5/'.$md5file.'.xml');
  115. cloudaddons_cleardir($dir);
  116. }
  117. function cloudaddons_savemd5($md5file, $end, $md5) {
  118. global $_G;
  119. parse_str($end, $r);
  120. require_once libfile('class/xml');
  121. $xml = implode('', @file(DISCUZ_ROOT.'./data/addonmd5/'.$md5file.'.xml'));
  122. $array = xml2array($xml);
  123. $ridexists = false;
  124. $data = array();
  125. if($array['RevisionID']) {
  126. foreach(explode(',', $array['RevisionID']) as $i => $rid) {
  127. $sns = explode(',', $array['SN']);
  128. $datalines = explode(',', $array['RevisionDateline']);
  129. $data[$rid]['SN'] = $sns[$i];
  130. $data[$rid]['RevisionDateline'] = $datalines[$i];
  131. }
  132. }
  133. $data[$r['RevisionID']]['SN'] = $r['SN'];
  134. $data[$r['RevisionID']]['RevisionDateline'] = $r['RevisionDateline'];
  135. $array['Title'] = 'Discuz! Addon MD5';
  136. $array['ID'] = $r['ID'];
  137. $array['RevisionDateline'] = $array['SN'] = $array['RevisionID'] = array();
  138. foreach($data as $rid => $tmp) {
  139. $array['RevisionID'][] = $rid;
  140. $array['SN'][] = $tmp['SN'];
  141. $array['RevisionDateline'][] = $tmp['RevisionDateline'];
  142. }
  143. $array['RevisionID'] = implode(',', $array['RevisionID']);
  144. $array['SN'] = implode(',', $array['SN']);
  145. $array['RevisionDateline'] = implode(',', $array['RevisionDateline']);
  146. $array['Data'] = $array['Data'] ? array_merge($array['Data'], $md5) : $md5;
  147. if(!isset($_G['siteftp'])) {
  148. dmkdir(DISCUZ_ROOT.'./data/addonmd5/', 0777, false);
  149. $fp = fopen(DISCUZ_ROOT.'./data/addonmd5/'.$md5file.'.xml', 'w');
  150. fwrite($fp, array2xml($array));
  151. fclose($fp);
  152. } else {
  153. $localfile = DISCUZ_ROOT.'./data/'.random(5);
  154. $fp = fopen($localfile, 'w');
  155. fwrite($fp, array2xml($array));
  156. fclose($fp);
  157. dmkdir(DISCUZ_ROOT.'./data/addonmd5/', 0777, false);
  158. siteftp_upload($localfile, 'data/addonmd5/'.$md5file.'.xml');
  159. @unlink($localfile);
  160. }
  161. }
  162. function cloudaddons_comparetree($new, $old, $basedir, $md5file, $first = 0) {
  163. global $_G;
  164. if($first && file_exists(DISCUZ_ROOT.'./data/addonmd5/'.$md5file.'.xml')) {
  165. require_once libfile('class/xml');
  166. $xml = implode('', @file(DISCUZ_ROOT.'./data/addonmd5/'.$md5file.'.xml'));
  167. $array = xml2array($xml);
  168. $_G['treeop']['md5old'] = $array['Data'];
  169. }
  170. $dh = opendir($new);
  171. while(($file = readdir($dh)) !== false) {
  172. if($file != '.' && $file != '..') {
  173. $newfile = $new.'/'.$file;
  174. $oldfile = $old.'/'.$file;
  175. if(is_file($newfile)) {
  176. $oldfile = preg_replace('/\._addons_$/', '', $oldfile);
  177. $md5key = str_replace($basedir, '', preg_replace('/\._addons_$/', '', $newfile));
  178. $newmd5 = md5_file($newfile);
  179. $oldmd5 = file_exists($oldfile) ? md5_file($oldfile) : '';
  180. if(isset($_G['treeop']['md5old'][$md5key]) && $_G['treeop']['md5old'][$md5key] != $oldmd5) {
  181. $_G['treeop']['oldchange'][] = $md5key;
  182. }
  183. if($newmd5 != $oldmd5) {
  184. $_G['treeop']['copy'][] = $newfile;
  185. }
  186. $_G['treeop']['md5'][$md5key] = $newmd5;
  187. } else {
  188. cloudaddons_comparetree($newfile, $oldfile, $basedir);
  189. }
  190. }
  191. }
  192. }
  193. function cloudaddons_copytree($from, $to) {
  194. global $_G;
  195. $dh = opendir($from);
  196. while(($file = readdir($dh)) !== false) {
  197. if($file != '.' && $file != '..') {
  198. $readfile = $from.'/'.$file;
  199. $writefile = $to.'/'.$file;
  200. if(is_file($readfile)) {
  201. if(!in_array($readfile, $_G['treeop']['copy'])) {
  202. continue;
  203. }
  204. if(!isset($_G['siteftp'])) {
  205. $content = -1;
  206. if($fp = @fopen($readfile, 'r')) {
  207. $startTime = microtime();
  208. do {
  209. $canRead = flock($fp, LOCK_SH);
  210. if(!$canRead) {
  211. usleep(round(rand(0, 100) * 1000));
  212. }
  213. } while ((!$canRead) && ((microtime() - $startTime) < 1000));
  214. if(!$canRead) {
  215. cpmsg('cloudaddons_file_read_error', '', 'error');
  216. }
  217. $content = fread($fp, filesize($readfile));
  218. flock($fp, LOCK_UN);
  219. fclose($fp);
  220. }
  221. if($content < 0) {
  222. cpmsg('cloudaddons_file_read_error', '', 'error');
  223. }
  224. dmkdir(dirname($writefile), 0777, false);
  225. $writefile = preg_replace('/\._addons_$/', '', $writefile);
  226. if($fp = fopen($writefile, 'w')) {
  227. $startTime = microtime();
  228. do {
  229. $canWrite = flock($fp, LOCK_EX);
  230. if(!$canWrite) {
  231. usleep(round(rand(0, 100) * 1000));
  232. }
  233. } while ((!$canWrite) && ((microtime() - $startTime) < 1000));
  234. if(!$canWrite) {
  235. cpmsg('cloudaddons_file_write_error', '', 'error');
  236. }
  237. fwrite($fp, $content);
  238. flock($fp, LOCK_UN);
  239. fclose($fp);
  240. }
  241. if(!$canWrite) {
  242. cpmsg('cloudaddons_file_write_error', '', 'error');
  243. }
  244. } else {
  245. $writefile = preg_replace('/\._addons_$/', '', $writefile);
  246. siteftp_upload($readfile, preg_replace('/^'.preg_quote(DISCUZ_ROOT).'/', '', $writefile));
  247. }
  248. if(md5_file($readfile) != md5_file($writefile)) {
  249. cpmsg('cloudaddons_file_write_error', '', 'error');
  250. }
  251. } else {
  252. cloudaddons_copytree($readfile, $writefile);
  253. }
  254. }
  255. }
  256. }
  257. function cloudaddons_deltree($dir) {
  258. if($directory = @dir($dir)) {
  259. while($entry = $directory->read()) {
  260. if($entry == '.' || $entry == '..') {
  261. continue;
  262. }
  263. $filename = $dir.'/'.$entry;
  264. if(is_file($filename)) {
  265. @unlink($filename);
  266. } else {
  267. cloudaddons_deltree($filename);
  268. }
  269. }
  270. $directory->close();
  271. @rmdir($dir);
  272. }
  273. }
  274. function cloudaddons_cleardir($dir) {
  275. if(is_dir($dir)) {
  276. cloudaddons_deltree($dir);
  277. }
  278. }
  279. function cloudaddons_dirwriteable($basedir, $dir, $sourcedir) {
  280. $checkdirs = array($dir);
  281. cloudaddons_getsubdirs($sourcedir, $dir, $checkdirs);
  282. $return = array();
  283. foreach($checkdirs as $k => $dir) {
  284. $writeable = false;
  285. $checkdir = $basedir.'/'.$dir;
  286. if(!is_dir($checkdir)) {
  287. @mkdir($checkdir, 0777);
  288. }
  289. if(is_dir($checkdir)) {
  290. $fp = fopen($checkdir.'/test.txt', 'w');
  291. if($fp) {
  292. fclose($fp);
  293. unlink($checkdir.'/test.txt');
  294. $writeable = true;
  295. } else {
  296. $writeable = false;
  297. }
  298. }
  299. if(!$writeable && $dir) {
  300. $return[] = $dir;
  301. }
  302. }
  303. return $return;
  304. }
  305. function cloudaddons_getsubdirs($dir, $root, &$return) {
  306. static $prefix = false;
  307. if($prefix === false) {
  308. $prefix = strlen($dir) + 1;
  309. }
  310. $dh = opendir($dir);
  311. while(($file = readdir($dh)) !== false) {
  312. if($file != '.' && $file != '..') {
  313. $readfile = $dir.'/'.$file;
  314. if(is_dir($readfile)) {
  315. $return[] = $root.'/'.substr($readfile, $prefix);
  316. cloudaddons_getsubdirs($readfile, $root, $return);
  317. }
  318. }
  319. }
  320. }
  321. function cloudaddons_http_build_query($formdata, $numeric_prefix = null, $key = null) {
  322. $res = array();
  323. foreach((array) $formdata as $k => $v) {
  324. $tmp_key = urlencode(is_int($k) ? $numeric_prefix . $k : $k);
  325. if ($key) {
  326. $tmp_key = $key.'['.$tmp_key.']';
  327. }
  328. if (is_array($v) || is_object($v)) {
  329. $res[] = cloudaddons_http_build_query($v, null, $tmp_key);
  330. } else {
  331. $res[] = $tmp_key.'='.urlencode($v);
  332. }
  333. }
  334. return implode('&', $res);
  335. }
  336. ?>