apply.js 3.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167
  1. /**
  2. * @author oldj
  3. * @blog https://oldj.net
  4. *
  5. * try to apply hosts
  6. */
  7. 'use strict'
  8. const fs = require('fs')
  9. const path = require('path')
  10. const exec = require('child_process').exec
  11. const getPref = require('./actions/getPref')
  12. const getLang = require('./actions/getLang')
  13. const io = require('./io')
  14. const {sys_host_path, work_path} = require('./paths')
  15. const crypto = require('crypto')
  16. const md5File = require('md5-file')
  17. const applyAfter_Unix = require('./applyAfter_Unix')
  18. const platform = process.platform
  19. const svr = require('./svr')
  20. let sudo_pswd = ''
  21. let lang = null
  22. function needPswd (str) {
  23. str = str.toLowerCase()
  24. console.log('---')
  25. console.log(str)
  26. let keys = [
  27. 'Permission denied'
  28. , 'incorrect password'
  29. , 'Password:Sorry, try again.'
  30. ]
  31. return !!keys.find(k => str.includes(k.toLowerCase()))
  32. }
  33. function apply_Unix (content, callback) {
  34. let tmp_fn = path.join(work_path, 'tmp.txt')
  35. if (typeof content !== 'string') {
  36. callback('bad content')
  37. return
  38. }
  39. io.pWriteFile(tmp_fn, content)
  40. .then(() => {
  41. let cmd
  42. if (!sudo_pswd) {
  43. cmd = [
  44. `cat "${tmp_fn}" > ${sys_host_path}`
  45. , `rm -rf ${tmp_fn}`
  46. ].join(' && ')
  47. } else {
  48. sudo_pswd = sudo_pswd.replace(/'/g, '\\x27')
  49. cmd = [
  50. `echo '${sudo_pswd}' | sudo -S chmod 777 ${sys_host_path}`
  51. , `cat "${tmp_fn}" > ${sys_host_path}`
  52. , `echo '${sudo_pswd}' | sudo -S chmod 644 ${sys_host_path}`
  53. // , 'rm -rf ' + tmp_fn
  54. ].join(' && ')
  55. }
  56. return cmd
  57. })
  58. .then(cmd => {
  59. exec(cmd, function (error, stdout, stderr) {
  60. // command output is in stdout
  61. if (!error) {
  62. callback()
  63. return
  64. }
  65. callback(!sudo_pswd || needPswd(stdout + stderr) ? 'need_sudo' : error)
  66. })
  67. })
  68. }
  69. function apply_Win32 (content, callback) {
  70. // todo 判断写入权限
  71. try {
  72. fs.writeFileSync(sys_host_path, content, 'utf-8')
  73. } catch (e) {
  74. console.log(e)
  75. let msg = e.message
  76. msg = `${msg}\n\n${lang.please_run_as_admin}`
  77. alert(msg)
  78. return
  79. }
  80. // todo 刷新 DNS 缓存
  81. callback()
  82. }
  83. function tryToApply (content, callback) {
  84. if (platform !== 'win32') {
  85. // unix
  86. apply_Unix(content, (e) => {
  87. if (e) {
  88. callback(e)
  89. } else {
  90. applyAfter_Unix(sudo_pswd, callback)
  91. }
  92. })
  93. } else {
  94. // win32
  95. apply_Win32(content, callback)
  96. }
  97. }
  98. module.exports = (cnt, pswd) => {
  99. if (pswd) {
  100. sudo_pswd = pswd
  101. }
  102. let pref
  103. return Promise.resolve()
  104. .then(() => {
  105. return getPref()
  106. .then(p => {
  107. pref = p
  108. return p.user_language || 'en'
  109. })
  110. .then(l => {
  111. return getLang(svr, l)
  112. })
  113. .then(v => lang = v || {})
  114. })
  115. .then(() => {
  116. return new Promise((resolve, reject) => {
  117. let file_md5 = md5File.sync(sys_host_path)
  118. let cnt_md5 = crypto.createHash('md5').update(cnt).digest('hex')
  119. if (file_md5 === cnt_md5) {
  120. // 文件相同
  121. resolve()
  122. return
  123. }
  124. tryToApply(cnt, e => e ? reject(e) : resolve())
  125. //reject('need_sudo')
  126. })
  127. })
  128. .then(() => {
  129. return new Promise((resolve, reject) => {
  130. let after_cmd = pref.after_cmd
  131. if (after_cmd) {
  132. exec(after_cmd, (error, stdout, stderr) => {
  133. // command output is in stdout
  134. if (error) {
  135. reject(`AfterCmdError:\n\n${stderr}`)
  136. } else {
  137. resolve()
  138. }
  139. })
  140. } else {
  141. resolve()
  142. }
  143. })
  144. })
  145. }