| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168 |
- /**
- * @author oldj
- * @blog https://oldj.net
- *
- * try to apply hosts
- */
- 'use strict'
- const fs = require('fs')
- const path = require('path')
- const exec = require('child_process').exec
- const getPref = require('./actions/getPref')
- const getLang = require('./actions/getLang')
- const io = require('./io')
- const {sys_hosts_path, work_path} = require('./paths')
- const crypto = require('crypto')
- const md5File = require('md5-file')
- const applyAfter_Unix = require('./applyAfter_Unix')
- const platform = process.platform
- const svr = require('./svr')
- let sudo_pswd = ''
- let lang = null
- function needPswd (str) {
- str = str.toLowerCase()
- console.log('---')
- console.log(str)
- let keys = [
- 'Permission denied'
- , 'incorrect password'
- , 'Password:Sorry, try again.'
- ]
- return !!keys.find(k => str.includes(k.toLowerCase()))
- }
- function apply_Unix (content, callback) {
- let tmp_fn = path.join(work_path, 'tmp.txt')
- if (typeof content !== 'string') {
- callback('bad content')
- return
- }
- io.pWriteFile(tmp_fn, content)
- .then(() => {
- let cmd
- if (!sudo_pswd) {
- cmd = [
- `cat "${tmp_fn}" > ${sys_hosts_path}`
- , `rm -rf ${tmp_fn}`
- ].join(' && ')
- } else {
- sudo_pswd = sudo_pswd.replace(/'/g, '\\x27')
- cmd = [
- `echo '${sudo_pswd}' | sudo -S chmod 777 ${sys_hosts_path}`
- , `cat "${tmp_fn}" > ${sys_hosts_path}`
- , `echo '${sudo_pswd}' | sudo -S chmod 644 ${sys_hosts_path}`
- // , 'rm -rf ' + tmp_fn
- ].join(' && ')
- }
- return cmd
- })
- .then(cmd => {
- exec(cmd, function (error, stdout, stderr) {
- // command output is in stdout
- if (!error) {
- callback()
- return
- }
- callback(!sudo_pswd || needPswd(stdout + stderr) ? 'need_sudo' : error)
- })
- })
- }
- function apply_Win32 (content, callback) {
- // todo 判断写入权限
- try {
- fs.writeFileSync(sys_hosts_path, content, 'utf-8')
- } catch (e) {
- console.log(e)
- let msg = e.message
- msg = `${msg}\n\n${lang.please_run_as_admin}`
- console.log(msg)
- svr.broadcast('alert', msg)
- return
- }
- // todo 刷新 DNS 缓存
- callback()
- }
- function tryToApply (content, callback) {
- if (platform !== 'win32') {
- // unix
- apply_Unix(content, (e) => {
- if (e) {
- callback(e)
- } else {
- applyAfter_Unix(sudo_pswd, callback)
- }
- })
- } else {
- // win32
- apply_Win32(content, callback)
- }
- }
- module.exports = (cnt, pswd) => {
- if (pswd) {
- sudo_pswd = pswd
- }
- let pref
- return Promise.resolve()
- .then(() => {
- return getPref()
- .then(p => {
- pref = p
- return p.user_language || 'en'
- })
- .then(l => {
- return getLang(svr, l)
- })
- .then(v => lang = v || {})
- })
- .then(() => {
- return new Promise((resolve, reject) => {
- let file_md5 = md5File.sync(sys_hosts_path)
- let cnt_md5 = crypto.createHash('md5').update(cnt).digest('hex')
- if (file_md5 === cnt_md5) {
- // 文件相同
- resolve()
- return
- }
- tryToApply(cnt, e => e ? reject(e) : resolve())
- //reject('need_sudo')
- })
- })
- .then(() => {
- return new Promise((resolve, reject) => {
- let after_cmd = pref.after_cmd
- if (after_cmd) {
- exec(after_cmd, (error, stdout, stderr) => {
- // command output is in stdout
- if (error) {
- reject(`AfterCmdError:\n\n${stderr}`)
- } else {
- resolve()
- }
- })
- } else {
- resolve()
- }
- })
- })
- }
|