404

[ Avaa Bypassed ]




Upload:

Command:

botdev@18.223.241.144: ~ $
'use strict'

const glob = require('./lib/glob')

const RE_SPACE = /\s/
const RE_LINE_BREAK = /\r|\n/
const RE_SECTION_DIRECTIVE = /^(Host|Match)$/i
const RE_QUOTED = /^(")(.*)\1$/

const DIRECTIVE = 1
const COMMENT = 2


class SSHConfig extends Array {
  /**
   * Query ssh config by host.
   *
   * @return {Object} The applied options of current Host
   */
  compute(host) {
    let obj = {}
    let setProperty = (name, value) => {
      if (name === 'IdentityFile') {
        let list = obj[name] || (obj[name] = [])
        list.push(value)
      }
      else if (obj[name] === undefined) {
        obj[name] = value
      }
    }

    for (let i = 0; i < this.length; i++) {
      let line = this[i]

      if (line.type !== DIRECTIVE) {
        continue
      }
      else if (line.param === 'Host') {
        if (glob(line.value, host)) {
          setProperty(line.param, line.value)

          line.config
            .filter(line => line.type === DIRECTIVE)
            .forEach(line => setProperty(line.param, line.value))
        }
      }
      else if (line.param === 'Match') {
        // TODO
      }
      else {
        setProperty(line.param, line.value)
      }
    }

    return obj
  }


  /**
   * find section by Host or Match
   */
  find(opts) {
    let result = this.constructor.find(this, opts)
    return result ? result[0] : null
  }


  /**
   * Remove section
   */
  remove(opts) {
    let result = this.constructor.find(this, opts)

    if (result) {
      return this.splice(result[1], 1)
    }
  }


  /**
   * toString()
   */
  toString() {
    return this.constructor.stringify(this)
  }


  /**
   * Append new section to existing ssh config.
   */
  append(opts) {
    let indent = '  '

    outer:
    for (const line of this) {
      if (RE_SECTION_DIRECTIVE.test(line.param)) {
        for (const subline of line.config) {
          if (subline.before) {
            indent = subline.before
            break outer
          }
        }
      }
    }

    if (this.length > 0) {
      let lastLine = this[this.length - 1]
      if (lastLine.config) lastLine = lastLine.config[lastLine.config.length - 1]
      if (!lastLine.after.trim()) {
        lastLine.after = '\n'
      }
    }

    let config = this
    let configWas = this

    for (const param in opts) {
      const line = {
        type: DIRECTIVE,
        param,
        separator: ' ',
        value: opts[param],
        before: '',
        after: '\n'
      }

      if (RE_SECTION_DIRECTIVE.test(param)) {
        config = configWas
        config.push(line)
        config = line.config = new SSHConfig()
      } else {
        line.before = config === configWas ? '' : indent
        config.push(line)
      }
    }

    return configWas
  }


  static find(config, opts) {
    if (!(opts && ('Host' in opts || 'Match' in opts))) {
      throw new Error('Can only find by Host or Match')
    }

    for (let i = 0; i < config.length; i++) {
      const line = config[i]

      if (line.type === DIRECTIVE &&
          RE_SECTION_DIRECTIVE.test(line.param) &&
          line.param in opts &&
          opts[line.param] === line.value) {
        return [line, i]
      }
    }

    return null
  }


  /**
   * Stringify structured object into ssh config text
   */
  static stringify(config) {
    let str = ''

    let format = line => {
      str += line.before

      if (line.type === COMMENT) {
        str += line.content
      }
      else if (line.type === DIRECTIVE) {
        str += line.quoted || (line.param == 'IdentityFile' && RE_SPACE.test(line.value))
          ? `${line.param}${line.separator}"${line.value}"`
          : `${line.param}${line.separator}${line.value}`
      }

      str += line.after

      if (line.config) {
        line.config.forEach(format)
      }
    }

    config.forEach(format)

    return str
  }


  static get DIRECTIVE() {
    return DIRECTIVE
  }


  static get COMMENT() {
    return COMMENT
  }


  /**
   * Parse ssh config text into structured object.
   */
  static parse(str) {
    let i = 0
    let chr = next()
    let config = new SSHConfig()
    let configWas = config

    function next() {
      return str[i++]
    }

    function space() {
      let spaces = ''

      while (RE_SPACE.test(chr)) {
        spaces += chr
        chr = next()
      }

      return spaces
    }

    function linebreak() {
      let breaks = ''

      while (RE_LINE_BREAK.test(chr)) {
        breaks += chr
        chr = next()
      }

      return breaks
    }

    function option() {
      let opt = ''

      while (chr && chr !== ' ' && chr !== '=') {
        opt += chr
        chr = next()
      }

      return opt
    }

    function separator() {
      let sep = space()

      if (chr === '=') {
        sep += chr
        chr = next()
      }

      return sep + space()
    }

    function value() {
      let val = ''

      while (chr && !RE_LINE_BREAK.test(chr)) {
        val += chr
        chr = next()
      }

      return val.trim()
    }

    function comment() {
      let type = COMMENT
      let content = ''

      while (chr && !RE_LINE_BREAK.test(chr)) {
        content += chr
        chr = next()
      }

      return { type, content }
    }

    function directive() {
      let type = DIRECTIVE

      return {
        type,
        param: option(),
        separator: separator(),
        value: value()
      }
    }

    function line() {
      let before = space()
      let node = chr === '#' ? comment() : directive()
      let after = linebreak()

      node.before = before
      node.after = after

      if (RE_QUOTED.test(node.value)) {
        node.value = node.value.replace(RE_QUOTED, '$2')
        node.quoted = true
      }

      return node
    }


    while (chr) {
      let node = line()

      if (node.type === DIRECTIVE && RE_SECTION_DIRECTIVE.test(node.param)) {
        config = configWas
        config.push(node)
        config = node.config = new SSHConfig()
      }
      else {
        config.push(node)
      }
    }

    return configWas
  }
}


module.exports = SSHConfig

Filemanager

Name Type Size Permission Actions
lib Folder 0755
History.md File 1.91 KB 0644
LICENSE File 1.04 KB 0644
Readme.md File 4.5 KB 0644
index.js File 5.96 KB 0644
package.json File 3.21 KB 0644