function_cloudaddons.php 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426
  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 36333 2016-12-30 02:29:39Z nemohou $
  7. */
  8. if(!defined('IN_DISCUZ')) {
  9. exit('Access Denied');
  10. }
  11. $addonsource = $_G['config']['addonsource'] ? $_G['config']['addonsource'] : ($_G['setting']['addon_source'] ? $_G['setting']['addon_source'] : array());
  12. $addon = $addonsource ?
  13. $_G['config']['addon'][$addonsource] :
  14. array(
  15. 'website_url' => 'http://addon.discuz.com',
  16. 'download_url' => 'http://addon.discuz.com/index.php',
  17. 'download_ip' => '',
  18. 'check_url' => 'http://addon1.discuz.com/md5/',
  19. 'check_ip' => '',
  20. );
  21. define('CLOUDADDONS_WEBSITE_URL', $addon['website_url']);
  22. define('CLOUDADDONS_DOWNLOAD_URL', $addon['download_url']);
  23. define('CLOUDADDONS_DOWNLOAD_IP', $addon['download_ip']);
  24. define('CLOUDADDONS_CHECK_URL', $addon['check_url']);
  25. define('CLOUDADDONS_CHECK_IP', $addon['check_ip']);
  26. function cloudaddons_md5($file) {
  27. return dfsockopen(CLOUDADDONS_CHECK_URL.$file, 0, '', '', false, CLOUDADDONS_CHECK_IP, 60);
  28. }
  29. function cloudaddons_getuniqueid() {
  30. global $_G;
  31. if(CLOUDADDONS_WEBSITE_URL == 'http://addon.discuz.com') {
  32. return $_G['setting']['siteuniqueid'] ? $_G['setting']['siteuniqueid'] : C::t('common_setting')->fetch('siteuniqueid');
  33. } else {
  34. if(!$_G['setting']['addon_uniqueid']) {
  35. $chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyz';
  36. $addonuniqueid = $chars[date('y')%60].$chars[date('n')].$chars[date('j')].$chars[date('G')].$chars[date('i')].$chars[date('s')].substr(md5($_G['clientip'].TIMESTAMP), 0, 4).random(6);
  37. C::t('common_setting')->update('addon_uniqueid', $addonuniqueid);
  38. require_once libfile('function/cache');
  39. updatecache('setting');
  40. }
  41. return $_G['setting']['addon_uniqueid'];
  42. }
  43. }
  44. function cloudaddons_url($extra) {
  45. global $_G;
  46. require_once DISCUZ_ROOT.'./source/discuz_version.php';
  47. $data = 'siteuniqueid='.rawurlencode(cloudaddons_getuniqueid()).'&siteurl='.rawurlencode($_G['siteurl']).'&sitever='.DISCUZ_VERSION.'/'.DISCUZ_RELEASE.'&sitecharset='.CHARSET.'&mysiteid='.$_G['setting']['my_siteid'];
  48. $param = 'data='.rawurlencode(base64_encode($data));
  49. $param .= '&md5hash='.substr(md5($data.TIMESTAMP), 8, 8).'&timestamp='.TIMESTAMP;
  50. return CLOUDADDONS_DOWNLOAD_URL.'?'.$param.$extra;
  51. }
  52. function cloudaddons_check() {
  53. if(!function_exists('gzuncompress')) {
  54. cpmsg('cloudaddons_check_gzuncompress_error', '', 'error');
  55. }
  56. foreach(array('download', 'addonmd5') as $path) {
  57. $tmpdir = DISCUZ_ROOT.'./data/'.$path.'/'.random(5);
  58. $tmpfile = $tmpdir.'/index.html';
  59. dmkdir($tmpdir, 0777);
  60. if(!is_dir($tmpdir) || !file_exists($tmpfile)) {
  61. cpmsg('cloudaddons_check_write_error', '', 'error');
  62. }
  63. @unlink($tmpfile);
  64. @rmdir($tmpdir);
  65. if(is_dir($tmpdir) || file_exists($tmpfile)) {
  66. cpmsg('cloudaddons_check_write_error', '', 'error');
  67. }
  68. }
  69. }
  70. function cloudaddons_open($extra, $post = '', $timeout = 15) {
  71. return dfsockopen(cloudaddons_url('&from=s').$extra, 0, $post, '', false, CLOUDADDONS_DOWNLOAD_IP, $timeout);
  72. }
  73. function cloudaddons_pluginlogo_url($id) {
  74. return CLOUDADDONS_WEBSITE_URL.'?_'.$id;
  75. }
  76. function cloudaddons_installlog($addonid) {
  77. $array = cloudaddons_getmd5($addonid);
  78. if($array['RevisionID']) {
  79. cloudaddons_open('&mod=app&ac=installlog&rid='.$array['RevisionID']);
  80. }
  81. }
  82. function cloudaddons_downloadlog($addonid) {
  83. $array = cloudaddons_getmd5($addonid);
  84. if($array['RevisionID']) {
  85. cloudaddons_open('&mod=app&ac=downloadlog&rid='.$array['RevisionID']);
  86. }
  87. }
  88. function cloudaddons_faillog($rid, $type) {
  89. $rid = intval($rid);
  90. $type = intval($type);
  91. cloudaddons_open('&mod=app&ac=faillog&rid='.$rid.'&type='.$type.'&serverinfo='.urlencode($_SERVER['SERVER_SOFTWARE']));
  92. }
  93. function cloudaddons_removelog($rid) {
  94. global $_G;
  95. cloudaddons_open('&mod=app&ac=removelog&rid='.$rid);
  96. }
  97. function cloudaddons_validator($addonid) {
  98. $array = cloudaddons_getmd5($addonid);
  99. if(cloudaddons_open('&mod=app&ac=validator&ver=2&addonid='.$addonid.($array !== false ? '&rid='.$array['RevisionID'].'&sn='.$array['SN'].'&rd='.$array['RevisionDateline'] : '')) === '0') {
  100. //cpmsg('cloudaddons_genuine_message', '', 'error', array('addonid' => $addonid));
  101. }
  102. }
  103. function cloudaddons_upgradecheck($addonids) {
  104. $post = array();
  105. foreach($addonids as $addonid) {
  106. $array = cloudaddons_getmd5($addonid);
  107. $post[] = 'rid['.$addonid.']='.$array['RevisionID'].'&sn['.$addonid.']='.$array['SN'].'&rd['.$addonid.']='.$array['RevisionDateline'];
  108. }
  109. return cloudaddons_open('&mod=app&ac=validator&ver=2', implode('&', $post), 15);
  110. }
  111. function cloudaddons_getmd5($md5file) {
  112. $array = array();
  113. if(preg_match('/^[a-z0-9_\.]+$/i', $md5file) && file_exists(DISCUZ_ROOT.'./data/addonmd5/'.$md5file.'.xml')) {
  114. require_once libfile('class/xml');
  115. $xml = implode('', @file(DISCUZ_ROOT.'./data/addonmd5/'.$md5file.'.xml'));
  116. $array = xml2array($xml);
  117. } else {
  118. return false;
  119. }
  120. return $array;
  121. }
  122. function cloudaddons_uninstall($md5file, $dir) {
  123. $array = cloudaddons_getmd5($md5file);
  124. if($array === false) {
  125. return;
  126. }
  127. if(!empty($array['RevisionID'])) {
  128. cloudaddons_removelog($array['RevisionID']);
  129. }
  130. @unlink(DISCUZ_ROOT.'./data/addonmd5/'.$md5file.'.xml');
  131. cloudaddons_cleardir($dir);
  132. }
  133. function cloudaddons_savemd5($md5file, $end, $md5) {
  134. global $_G;
  135. parse_str($end, $r);
  136. require_once libfile('class/xml');
  137. $xml = implode('', @file(DISCUZ_ROOT.'./data/addonmd5/'.$md5file.'.xml'));
  138. $array = xml2array($xml);
  139. $ridexists = false;
  140. $data = array();
  141. if($array['RevisionID']) {
  142. foreach(explode(',', $array['RevisionID']) as $i => $rid) {
  143. $sns = explode(',', $array['SN']);
  144. $datalines = explode(',', $array['RevisionDateline']);
  145. $data[$rid]['SN'] = $sns[$i];
  146. $data[$rid]['RevisionDateline'] = $datalines[$i];
  147. }
  148. }
  149. $data[$r['RevisionID']]['SN'] = $r['SN'];
  150. $data[$r['RevisionID']]['RevisionDateline'] = $r['RevisionDateline'];
  151. $array['Title'] = 'Discuz! Addon MD5';
  152. $array['ID'] = $r['ID'];
  153. $array['RevisionDateline'] = $array['SN'] = $array['RevisionID'] = array();
  154. foreach($data as $rid => $tmp) {
  155. $array['RevisionID'][] = $rid;
  156. $array['SN'][] = $tmp['SN'];
  157. $array['RevisionDateline'][] = $tmp['RevisionDateline'];
  158. }
  159. $array['RevisionID'] = implode(',', $array['RevisionID']);
  160. $array['SN'] = implode(',', $array['SN']);
  161. $array['RevisionDateline'] = implode(',', $array['RevisionDateline']);
  162. $array['Data'] = $array['Data'] ? array_merge($array['Data'], $md5) : $md5;
  163. if(!isset($_G['siteftp'])) {
  164. dmkdir(DISCUZ_ROOT.'./data/addonmd5/', 0777, false);
  165. $fp = fopen(DISCUZ_ROOT.'./data/addonmd5/'.$md5file.'.xml', 'w');
  166. fwrite($fp, array2xml($array));
  167. fclose($fp);
  168. } else {
  169. $localfile = DISCUZ_ROOT.'./data/'.random(5);
  170. $fp = fopen($localfile, 'w');
  171. fwrite($fp, array2xml($array));
  172. fclose($fp);
  173. dmkdir(DISCUZ_ROOT.'./data/addonmd5/', 0777, false);
  174. siteftp_upload($localfile, 'data/addonmd5/'.$md5file.'.xml');
  175. @unlink($localfile);
  176. }
  177. }
  178. function cloudaddons_comparetree($new, $old, $basedir, $md5file = '', $first = 0) {
  179. global $_G;
  180. if($first && file_exists(DISCUZ_ROOT.'./data/addonmd5/'.$md5file.'.xml')) {
  181. require_once libfile('class/xml');
  182. $xml = implode('', @file(DISCUZ_ROOT.'./data/addonmd5/'.$md5file.'.xml'));
  183. $array = xml2array($xml);
  184. $_G['treeop']['md5old'] = $array['Data'];
  185. }
  186. $dh = opendir($new);
  187. while(($file = readdir($dh)) !== false) {
  188. if($file != '.' && $file != '..') {
  189. $newfile = $new.'/'.$file;
  190. $oldfile = $old.'/'.$file;
  191. if(is_file($newfile)) {
  192. $oldfile = preg_replace('/\._addons_$/', '', $oldfile);
  193. $md5key = str_replace($basedir, '', preg_replace('/\._addons_$/', '', $newfile));
  194. $newmd5 = md5_file($newfile);
  195. $oldmd5 = file_exists($oldfile) ? md5_file($oldfile) : '';
  196. if(isset($_G['treeop']['md5old'][$md5key]) && $_G['treeop']['md5old'][$md5key] != $oldmd5 && $oldmd5) {
  197. $_G['treeop']['oldchange'][] = $md5key;
  198. }
  199. if($newmd5 != $oldmd5) {
  200. $_G['treeop']['copy'][] = $newfile;
  201. }
  202. $_G['treeop']['md5'][$md5key] = $newmd5;
  203. } else {
  204. cloudaddons_comparetree($newfile, $oldfile, $basedir);
  205. }
  206. }
  207. }
  208. }
  209. function cloudaddons_copytree($from, $to) {
  210. global $_G;
  211. $dh = opendir($from);
  212. while(($file = readdir($dh)) !== false) {
  213. if($file != '.' && $file != '..') {
  214. $readfile = $from.'/'.$file;
  215. $writefile = $to.'/'.$file;
  216. if(is_file($readfile)) {
  217. if(!in_array($readfile, $_G['treeop']['copy'])) {
  218. continue;
  219. }
  220. if(!isset($_G['siteftp'])) {
  221. $content = -1;
  222. if($fp = @fopen($readfile, 'r')) {
  223. $startTime = microtime();
  224. do {
  225. $canRead = flock($fp, LOCK_SH);
  226. if(!$canRead) {
  227. usleep(round(rand(0, 100) * 1000));
  228. }
  229. } while ((!$canRead) && ((microtime() - $startTime) < 1000));
  230. if(!$canRead) {
  231. cpmsg('cloudaddons_file_read_error', '', 'error');
  232. }
  233. $content = fread($fp, filesize($readfile));
  234. flock($fp, LOCK_UN);
  235. fclose($fp);
  236. }
  237. if($content < 0) {
  238. cpmsg('cloudaddons_file_read_error', '', 'error');
  239. }
  240. dmkdir(dirname($writefile), 0777, false);
  241. $writefile = preg_replace('/\._addons_$/', '', $writefile);
  242. if($fp = fopen($writefile, 'w')) {
  243. $startTime = microtime();
  244. do {
  245. $canWrite = flock($fp, LOCK_EX);
  246. if(!$canWrite) {
  247. usleep(round(rand(0, 100) * 1000));
  248. }
  249. } while ((!$canWrite) && ((microtime() - $startTime) < 1000));
  250. if(!$canWrite) {
  251. cpmsg('cloudaddons_file_write_error', '', 'error');
  252. }
  253. fwrite($fp, $content);
  254. flock($fp, LOCK_UN);
  255. fclose($fp);
  256. }
  257. if(!$canWrite) {
  258. cpmsg('cloudaddons_file_write_error', '', 'error');
  259. }
  260. } else {
  261. $writefile = preg_replace('/\._addons_$/', '', $writefile);
  262. siteftp_upload($readfile, preg_replace('/^'.preg_quote(DISCUZ_ROOT).'/', '', $writefile));
  263. }
  264. if(md5_file($readfile) != md5_file($writefile)) {
  265. cpmsg('cloudaddons_file_write_error', '', 'error');
  266. }
  267. } else {
  268. cloudaddons_copytree($readfile, $writefile);
  269. }
  270. }
  271. }
  272. }
  273. function cloudaddons_deltree($dir) {
  274. if($directory = @dir($dir)) {
  275. while($entry = $directory->read()) {
  276. if($entry == '.' || $entry == '..') {
  277. continue;
  278. }
  279. $filename = $dir.'/'.$entry;
  280. if(is_file($filename)) {
  281. @unlink($filename);
  282. } else {
  283. cloudaddons_deltree($filename);
  284. }
  285. }
  286. $directory->close();
  287. @rmdir($dir);
  288. }
  289. }
  290. function cloudaddons_cleardir($dir) {
  291. if(is_dir($dir)) {
  292. cloudaddons_deltree($dir);
  293. }
  294. }
  295. function cloudaddons_dirwriteable($basedir, $dir, $sourcedir) {
  296. $checkdirs = array($dir);
  297. cloudaddons_getsubdirs($sourcedir, $dir, $checkdirs);
  298. $return = array();
  299. foreach($checkdirs as $k => $dir) {
  300. $writeable = false;
  301. $checkdir = $basedir.'/'.$dir;
  302. if(!is_dir($checkdir)) {
  303. @mkdir($checkdir, 0777);
  304. }
  305. if(is_dir($checkdir)) {
  306. $fp = fopen($checkdir.'/test.txt', 'w');
  307. if($fp) {
  308. fclose($fp);
  309. unlink($checkdir.'/test.txt');
  310. $writeable = true;
  311. } else {
  312. $writeable = false;
  313. }
  314. }
  315. if(!$writeable && $dir) {
  316. $return[] = $dir;
  317. }
  318. }
  319. return $return;
  320. }
  321. function cloudaddons_getsubdirs($dir, $root, &$return) {
  322. static $prefix = false;
  323. if($prefix === false) {
  324. $prefix = strlen($dir) + 1;
  325. }
  326. $dh = opendir($dir);
  327. while(($file = readdir($dh)) !== false) {
  328. if($file != '.' && $file != '..') {
  329. $readfile = $dir.'/'.$file;
  330. if(is_dir($readfile)) {
  331. $return[] = $root.'/'.substr($readfile, $prefix);
  332. cloudaddons_getsubdirs($readfile, $root, $return);
  333. }
  334. }
  335. }
  336. }
  337. function cloudaddons_http_build_query($formdata, $numeric_prefix = null, $key = null) {
  338. $res = array();
  339. foreach((array) $formdata as $k => $v) {
  340. $tmp_key = urlencode(is_int($k) ? $numeric_prefix . $k : $k);
  341. if ($key) {
  342. $tmp_key = $key.'['.$tmp_key.']';
  343. }
  344. if (is_array($v) || is_object($v)) {
  345. $res[] = cloudaddons_http_build_query($v, null, $tmp_key);
  346. } else {
  347. $res[] = $tmp_key.'='.urlencode($v);
  348. }
  349. }
  350. return implode('&', $res);
  351. }
  352. function cloudaddons_clear($type, $id) {
  353. global $_G;
  354. if(isset($_G['config']['plugindeveloper']) && $_G['config']['plugindeveloper'] > 0) {
  355. return;
  356. }
  357. $dirs = array('plugin' => array('plugin', './source/plugin/'), 'template' => array('style', './template/'));
  358. if($dirs[$type] && cloudaddons_getmd5($id.'.'.$type)) {
  359. $entrydir = DISCUZ_ROOT.$dirs[$type][1].$id;
  360. $d = dir($entrydir);
  361. $filedeleted = false;
  362. while($f = $d->read()) {
  363. if(preg_match('/^discuz\_'.$dirs[$type][0].'\_'.$id.'(\_\w+)?\.xml$/', $f)) {
  364. @unlink($entrydir.'/'.$f);
  365. if($type == 'plugin' && !$filedeleted) {
  366. @unlink($entrydir.'/'.$f);
  367. $importtxt = @implode('', file($entrydir.'/'.$f));
  368. $pluginarray = getimportdata('Discuz! Plugin');
  369. if($pluginarray['installfile']) {
  370. @unlink($entrydir.'/'.$pluginarray['installfile']);
  371. }
  372. if($pluginarray['upgradefile']) {
  373. @unlink($entrydir.'/'.$pluginarray['upgradefile']);
  374. }
  375. $filedeleted = true;
  376. }
  377. }
  378. }
  379. }
  380. }
  381. function versioncompatible($versions) {
  382. global $_G;
  383. list($currentversion) = explode(' ', trim(strip_tags($_G['setting']['version'])));
  384. $versions = strip_tags($versions);
  385. foreach(explode(',', $versions) as $version) {
  386. list($version) = explode(' ', trim($version));
  387. if($version && ($currentversion === $version || $version === 'X3' || $version === 'X3.1' || $version === 'X3.2')) {
  388. return true;
  389. }
  390. }
  391. return false;
  392. }
  393. ?>