Example #1
0
// Read reads and decodes quoted-printable data from the underlying reader.
func (r *Reader) Read(p []byte) (int, error) {
	// Deviations from RFC 2045:
	// 1. in addition to "=\r\n", "=\n" is also treated as soft line break.
	// 2. it will pass through a '\r' or '\n' not preceded by '=', consistent
	//    with other broken QP encoders & decoders.
	var n int
	var err error
	for len(p) > 0 {
		if len(r.line) == 0 {
			if err = r.Fn(); err != nil {
				return n, err
			}
			r.line, r.rerr = r.br.ReadSlice('\n')
			r.gerr.addUnrecover(r.rerr)

			// Does the line end in CRLF instead of just LF?
			hasLF := bytes.HasSuffix(r.line, lf)
			hasCR := bytes.HasSuffix(r.line, crlf)
			wholeLine := r.line
			r.line = bytes.TrimRightFunc(wholeLine, isQPDiscardWhitespace)
			if bytes.HasSuffix(r.line, softSuffix) {
				rightStripped := wholeLine[len(r.line):]
				r.line = r.line[:len(r.line)-1]
				if !bytes.HasPrefix(rightStripped, lf) && !bytes.HasPrefix(rightStripped, crlf) {
					r.rerr = fmt.Errorf("quotedprintable: invalid bytes after =: %q", rightStripped)
					r.gerr.add(r.rerr)
				}
			} else if hasLF {
				if hasCR {
					r.line = append(r.line, '\r', '\n')
				} else {
					r.line = append(r.line, '\n')
				}
			}
			continue
		}
		b := r.line[0]

		switch {
		case b == '=':
			b, err = readHexByte(r.line[1:])
			if err != nil {
				b = '='
				r.gerr.add(err)
				break // this modification allow bad email to be parsed too
				//return n, err
			}
			r.line = r.line[2:] // 2 of the 3; other 1 is done below
		case b == '\t' || b == '\r' || b == '\n':
		case b < ' ' || b > '~':
			//return n, fmt.Errorf("quotedprintable: invalid unescaped byte 0x%02x in body", b)
			r.gerr.add(fmt.Errorf("quotedprintable: invalid unescaped byte 0x%02x in body", b))
		}
		p[0] = b
		p = p[1:]
		r.line = r.line[1:]
		n++
	}
	return n, r.Fn()
}
Example #2
0
func main() {
	s := []byte("123456789")
	f := func(r rune) bool {
		return r > '7'
	}
	fmt.Println(string(bytes.TrimRightFunc(s, f)))
}
Example #3
0
func EncodeKey(key []byte) string {
	// we do sloppy work and process safe bytes only at the beginning
	// and end; this avoids many false positives in large binary data

	var left, middle, right string

	{
		mid := bytes.TrimLeftFunc(key, isSafe)
		if len(key)-len(mid) > prettyTheshold {
			left = string(key[:len(key)-len(mid)]) + string(FragSeparator)
			key = mid
		}
	}

	{
		mid := bytes.TrimRightFunc(key, isSafe)
		if len(key)-len(mid) > prettyTheshold {
			right = string(FragSeparator) + string(key[len(mid):])
			key = mid
		}
	}

	if len(key) > 0 {
		middle = "@" + hex.EncodeToString(key)
	}

	return strings.Trim(left+middle+right, string(FragSeparator))
}
Example #4
0
func (g *gobot) Listen() (err error) {
	start, err := g.slackApi.startRTM()
	if err != nil {
		return
	}
	if !start.Okay {
		return fmt.Errorf("Real-Time Messaging failed to start, aborting: %s", start.Error)
	}

	if g.setupFunc != nil {
		g.setupFunc(g.slackApi)
	}

	conn := start.openWebSocket()

	healthChecks(conn)

	for {
		_, msg, err := conn.ReadMessage()
		if err != nil {
			return err
		}
		var msgType unmarshalled
		if err = json.Unmarshal(bytes.TrimRightFunc(msg, func(r rune) bool { return r == '\x00' }), &msgType); err != nil {
			return err
		}
		go g.delegate(msgType.Type, msg)
	}
}
Example #5
0
// sanitizeText tries to make the given string easier to read when presented
// as a single line. It squashes each run of white space into a single
// space, trims leading and trailing white space and trailing full
// stops. If newlineSemi is true, any newlines will be replaced with a
// semicolon.
func sanitizeText(s string, newlineSemi bool) []byte {
	out := make([]byte, 0, len(s))
	prevWhite := false
	for _, r := range s {
		if newlineSemi && r == '\n' && len(out) > 0 {
			out = append(out, ';')
			prevWhite = true
			continue
		}
		if unicode.IsSpace(r) {
			if len(out) > 0 {
				prevWhite = true
			}
			continue
		}
		if prevWhite {
			out = append(out, ' ')
			prevWhite = false
		}
		out = append(out, string(r)...)
	}
	// Remove final space, any full stops and any final semicolon
	// we might have added.
	out = bytes.TrimRightFunc(out, func(r rune) bool {
		return r == '.' || r == ' ' || r == ';'
	})
	return out
}
Example #6
0
func main() {
	whitespace := " \t\r\n"

	padded := []byte("  \t\r\n\r\n\r\n  hello!!!    \t\t\t\t")
	trimmed := bytes.Trim(padded, whitespace)
	log.Printf("Trim removed runes in %q from the ends of %q to produce %q", whitespace, padded, trimmed)

	rhyme := []byte("aabbccddee")
	trimFunced := bytes.TrimFunc(rhyme, trimOdd)
	log.Printf("TrimFunc removed 'odd' runes from %q to produce %q", rhyme, trimFunced)

	leftTrimmed := bytes.TrimLeft(padded, whitespace)
	log.Printf("TrimLeft removed runes in %q from the left side of %q to produce %q", whitespace, padded, leftTrimmed)

	leftTrimFunced := bytes.TrimLeftFunc(rhyme, trimOdd)
	log.Printf("TrimLeftFunc removed 'odd' runes from the left side of %q to produce %q", rhyme, leftTrimFunced)

	rightTrimmed := bytes.TrimRight(padded, whitespace)
	log.Printf("TrimRight removed runes in %q from the right side of %q to produce %q", whitespace, padded, rightTrimmed)

	rightTrimFunced := bytes.TrimRightFunc(rhyme, trimOdd)
	log.Printf("TrimRightFunc removed 'odd' runes from the right side of %q to produce %q", rhyme, rightTrimFunced)

	spaceTrimmed := bytes.TrimSpace(padded)
	log.Printf("TrimSpace trimmed all whitespace from the ends of %q to produce %q", padded, spaceTrimmed)
}
Example #7
0
// Read reads and decodes quoted-printable data from the underlying reader.
func (r *Reader) Read(p []byte) (n int, err error) {
	// Deviations from RFC 2045:
	// 1. in addition to "=\r\n", "=\n" is also treated as soft line break.
	// 2. it will pass through a '\r' or '\n' not preceded by '=', consistent
	//    with other broken QP encoders & decoders.
	// 3. it accepts soft line-break (=) at end of message (issue 15486); i.e.
	//    the final byte read from the underlying reader is allowed to be '=',
	//    and it will be silently ignored.
	for len(p) > 0 {
		if len(r.line) == 0 {
			if r.rerr != nil {
				return n, r.rerr
			}
			r.line, r.rerr = r.br.ReadSlice('\n')

			// Does the line end in CRLF instead of just LF?
			hasLF := bytes.HasSuffix(r.line, lf)
			hasCR := bytes.HasSuffix(r.line, crlf)
			wholeLine := r.line
			r.line = bytes.TrimRightFunc(wholeLine, isQPDiscardWhitespace)
			if bytes.HasSuffix(r.line, softSuffix) {
				rightStripped := wholeLine[len(r.line):]
				r.line = r.line[:len(r.line)-1]
				if !bytes.HasPrefix(rightStripped, lf) && !bytes.HasPrefix(rightStripped, crlf) &&
					!(len(rightStripped) == 0 && len(r.line) > 0 && r.rerr == io.EOF) {
					r.rerr = fmt.Errorf("quotedprintable: invalid bytes after =: %q", rightStripped)
				}
			} else if hasLF {
				if hasCR {
					r.line = append(r.line, '\r', '\n')
				} else {
					r.line = append(r.line, '\n')
				}
			}
			continue
		}
		b := r.line[0]

		switch {
		case b == '=':
			b, err = readHexByte(r.line[1:])
			if err != nil {
				return n, err
			}
			r.line = r.line[2:] // 2 of the 3; other 1 is done below
		case b == '\t' || b == '\r' || b == '\n':
			break
		case b < ' ' || b > '~':
			return n, fmt.Errorf("quotedprintable: invalid unescaped byte 0x%02x in body", b)
		}
		p[0] = b
		p = p[1:]
		r.line = r.line[1:]
		n++
	}
	return n, nil
}
Example #8
0
func ZeroUnPadding(origData []byte, blockSize int) []byte {
	return bytes.TrimRightFunc(origData,
		func(r rune) bool {
			if r == rune(0) && blockSize > 0 {
				blockSize--
				return true
			}
			return false
		})
}
Example #9
0
func (q *qpReader) Read(p []byte) (n int, err error) {
	for len(p) > 0 {
		if len(q.line) == 0 {
			if q.rerr != nil {
				return n, q.rerr
			}
			q.skipWhite = true
			q.line, q.rerr = q.br.ReadSlice('\n')

			// Does the line end in CRLF instead of just LF?
			hasLF := bytes.HasSuffix(q.line, lf)
			hasCR := bytes.HasSuffix(q.line, crlf)
			wholeLine := q.line
			q.line = bytes.TrimRightFunc(wholeLine, isQPDiscardWhitespace)
			if bytes.HasSuffix(q.line, softSuffix) {
				rightStripped := wholeLine[len(q.line):]
				q.line = q.line[:len(q.line)-1]
				if !bytes.HasPrefix(rightStripped, lf) && !bytes.HasPrefix(rightStripped, crlf) {
					q.rerr = fmt.Errorf("multipart: invalid bytes after =: %q", rightStripped)
				}
			} else if hasLF {
				if hasCR {
					q.line = append(q.line, '\r', '\n')
				} else {
					q.line = append(q.line, '\n')
				}
			}
			continue
		}
		b := q.line[0]
		if q.skipWhite && isQPSkipWhiteByte(b) {
			q.line = q.line[1:]
			continue
		}
		q.skipWhite = false

		switch {
		case b == '=':
			b, err = q.readHexByte(q.line[1:])
			if err != nil {
				return n, err
			}
			q.line = q.line[2:] // 2 of the 3; other 1 is done below
		case b == '\t' || b == '\r' || b == '\n':
			break
		case b < ' ' || b > '~':
			return n, fmt.Errorf("multipart: invalid unescaped byte 0x%02x in quoted-printable body", b)
		}
		p[0] = b
		p = p[1:]
		q.line = q.line[1:]
		n++
	}
	return n, nil
}
Example #10
0
func (b *bufferHelper) NextXAsString(fieldName string, x int, remainingBytes *int) string {
	bString := b.NextX(fieldName, x, remainingBytes)
	if b.Error != nil {
		return ""
	}

	// trim nulls from end
	return string(bytes.TrimRightFunc(bString, func(r rune) bool {
		return r == 0x0
	}))
}
Example #11
0
func minifyReadFile(file string) []byte {
	f, err := os.Open(file)
	if err != nil {
		log.Fatalln(err)
	}
	defer f.Close()
	var lastLineEnd byte
	var partMark int
	var r = bufio.NewReader(f)
	var buf = new(bytes.Buffer)
	for {
		line, part, err := r.ReadLine()
		if part {
			partMark++
		} else if partMark > 0 {
			partMark = -1
		} else {
			partMark = 0
		}
		if len(line) > 0 {
			switch partMark {
			case 0:
				line = bytes.TrimSpace(line)
			case 1:
				line = bytes.TrimLeftFunc(line, unicode.IsSpace)
			default:
				if partMark < 0 {
					partMark = 0
					line = bytes.TrimRightFunc(line, unicode.IsSpace)
				}
			}
			buf.Write(line)
			lastLineEnd = line[len(line)-1]
		}
		if err != nil && r.Buffered() == 0 {
			break
		}
	}
	// make sure line end with \n
	if lastLineEnd != '\n' {
		buf.WriteByte('\n')
	}
	return buf.Bytes()
}
Example #12
0
// Parse a debian changelog from r for any changes happening later than afterVersion
func Parse(r io.Reader, afterVersion string) (Changelog, error) {
	scanner := bufio.NewScanner(r)
	changelog := make(Changelog, 0, 5)
	change := Change{}
	inside := false

	for scanner.Scan() {
		b := bytes.TrimRightFunc(scanner.Bytes(), unicode.IsSpace)
		if b2 := bytes.TrimSpace(b); len(b2) < len(b) && !inside {
			b = b2
		}
		if len(b) == 0 {
			if inside {
				change.Changes = append(change.Changes, '\n')
			}
			continue
		}

		if !inside && change.parseVersionLine(b) {
			if len(afterVersion) > 0 && change.Version == afterVersion {
				break
			}
			inside = true
			continue
		}

		if inside && change.parseChangedByLine(b) {
			changelog = append(changelog, change)
			change = Change{}
			inside = false
			continue
		}

		change.Changes = append(change.Changes, b...)
		change.Changes = append(change.Changes, '\n')
	}

	if err := scanner.Err(); err != nil {
		return nil, err
	}
	return changelog, nil
}
Example #13
0
func decrypt(key, src []byte) (dst []byte, err error) {

	block, err := aes.NewCipher(key)
	if err != nil {
		return nil, err
	}

	if len(src) < aes.BlockSize {
		return nil, fmt.Errorf("invalid source, too short")
	}

	iv := src[:ivLength]
	cipherText := src[ivLength:]
	mode := cipher.NewCBCDecrypter(block, iv)
	mode.CryptBlocks(cipherText, cipherText)

	// handle padding
	lastByte := cipherText[len(cipherText)-1:]
	buf := bytes.NewBuffer(lastByte)
	uVal, err := binary.ReadUvarint(buf)
	if err != nil {
		return nil, fmt.Errorf("Invalid padding, %s", err)
	}
	paddingLength := int(uVal)

	if paddingLength > aes.BlockSize && paddingLength != 32 {
		return nil, fmt.Errorf("Decription failed")
	}
	if paddingLength == 32 {
		return bytes.TrimRightFunc(cipherText, unicode.IsSpace), nil
	}
	paddingIndex := len(cipherText) - paddingLength - 1
	if bytes.Compare(cipherText[paddingIndex:], bytes.Repeat(lastByte, paddingLength)) == 0 {
		return nil, fmt.Errorf("Decription failed")
	}

	return cipherText[:len(cipherText)-paddingLength], nil
}
Example #14
0
func EncodeKey(key []byte) string {
	// we do sloppy work and process safe bytes only at the beginning
	// and end; this avoids many false positives in large binary data

	var left, right []byte
	var middle string

	if key[0] != '.' {
		mid := bytes.TrimLeftFunc(key, isSafe)
		if len(key)-len(mid) > prettyTheshold {
			left = key[:len(key)-len(mid)]
			key = mid
		}
	}

	{
		mid := bytes.TrimRightFunc(key, isSafe)
		if len(mid) == 0 && len(key) > 0 && key[0] == '.' {
			// don't let right safe zone reach all the way to leading dot
			mid = key[:1]
		}
		if len(key)-len(mid) > prettyTheshold {
			right = key[len(mid):]
			key = mid
		}
	}

	if len(key) > 0 {
		middle = "@" + hex.EncodeToString(key)
	}

	return strings.Trim(
		string(left)+string(FragSeparator)+middle+string(FragSeparator)+string(right),
		string(FragSeparator),
	)
}
Example #15
0
// IF allowEOF is true it won't return io.EOF as an error, but see it as the end
// of the value.
func getValue(buf *buffer, end byte, allowEOF bool) ([]byte, error) {
	var started, isQouted, qoutedClosed bool
	var value []byte
	var er error

	for {
		c, err := buf.ReadByte()
		if err != nil {
			if allowEOF && err == io.EOF {
				er = err
				break
			}

			return []byte{}, err
		}

		if !started {
			if isSpace(c) {
				continue
			}

			if c == qouteByte {
				isQouted = true
			} else {
				value = append(value, c)
			}

			started = true
			continue
		}

		if qoutedClosed {
			if isSpace(c) {
				continue
			} else if c != end {
				return []byte{}, fmt.Errorf("unexpected %s after closed qoute", string(c))
			}
		}

		if c == qouteByte {
			if isQouted && value[len(value)-1] != escapeByte {
				qoutedClosed = true
				continue
			} else if value[len(value)-1] == escapeByte {
				// replace the escape byte with the byte being escaped.
				value[len(value)-1] = c
				continue
			}
		}

		if c == end && (!isQouted || qoutedClosed) {
			break
		}

		value = append(value, c)
	}

	if !isQouted {
		value = bytes.TrimRightFunc(value, unicode.IsSpace)
	}

	// todo: trim left space.
	return value, er
}
Example #16
0
func ZeroUnPadding(origData []byte) []byte {
	return bytes.TrimRightFunc(origData, func(r rune) bool {
		return r == rune(0)
	})
}
func (sp *SyslogProcessor) processSyslogPkt() {
	var pkt []byte
	var addr string
	var n int
	var packet Packet
	for {
		select {
		case packet = <-sp.recieverPipe:
		case <-sp.closeCh:
			return
		}
		pkt = packet.pkt
		addr = packet.addr
		n = packet.n
		m := new(SyslogMessage)
		m.Source = addr
		m.Time = time.Now().UTC()

		// Parse priority (if exists)
		prio := 13 // default priority
		hasPrio := false
		if pkt[0] == '<' {
			n = 1 + bytes.IndexByte(pkt[1:], '>')
			if n > 1 && n < 5 {
				p, err := strconv.Atoi(string(pkt[1:n]))
				if err == nil && p >= 0 {
					hasPrio = true
					prio = p
					pkt = pkt[n+1:]
				}
			}
		}
		m.Severity = Severity(prio & 0x07)
		m.Facility = Facility(prio >> 3)
		// Parse header (if exists)
		if hasPrio && len(pkt) >= 16 && pkt[15] == ' ' {
			// Get timestamp
			layout := "Jan _2 15:04:05"
			ts, err := time.Parse(layout, string(pkt[:15]))
			if err == nil && !ts.IsZero() {
				// Get hostname
				n = 16 + bytes.IndexByte(pkt[16:], ' ')
				if n != 15 {
					m.Timestamp = ts
					m.Hostname = string(pkt[16:n])
					pkt = pkt[n+1:]
				}
			}
			// TODO: check for version an new format of header as
			// described in RFC 5424.
		}

		// Parse msg part
		msg := string(bytes.TrimRightFunc(pkt, isNulCrLf))
		n = strings.IndexFunc(msg, isNotAlnum)
		if n != -1 {
			m.Tag = msg[:n]
			m.Content = msg[n:]
		} else {
			m.Content = msg
		}
		msg = strings.TrimFunc(msg, unicode.IsSpace)
		n = strings.IndexFunc(msg, unicode.IsSpace)
		if n != -1 {
			m.Tag1 = msg[:n]
			m.Content1 = strings.TrimLeftFunc(msg[n+1:], unicode.IsSpace)
		} else {
			m.Content1 = msg
		}
		esoutput, err := sp.EncodeESFormat(m)
		if err != nil {
			log.Println(err)
			continue
		}
		sp.outputPipe <- esoutput
	}
}
Example #18
0
File: tree.go Project: rjeczalik/fs
// Decode builds fs.Tree from given reader using bt.DecodeLine callback for parsing
// node's name and its depth in the tree. Tree returns ErrTreeBuilder error when
// a call to ct gives invalid values.
//
// If tb.DecodeLine is nil, Unix.DecodeLine is used.
func (tb TreeBuilder) Decode(r io.Reader) (fs FS, err error) {
	var (
		e         error
		dir       = Directory{}
		buf       = bufio.NewReader(r)
		dec       = tb.DecodeLine
		glob      []Directory
		name      []byte
		prevName  []byte
		depth     int
		prevDepth int
	)
	fs.Tree = dir
	if dec == nil {
		dec = Unix.DecodeLine
	}
	line, err := buf.ReadBytes('\n')
	if len(line) == 0 || err == io.EOF {
		err = io.ErrUnexpectedEOF
		return
	}
	if err != nil {
		return
	}
	if len(line) != 1 || line[0] != '.' {
		p := filepath.FromSlash(string(bytes.TrimSpace(line)))
		if err = fs.MkdirAll(p, 0); err != nil {
			return
		}
		var perr *os.PathError
		if dir, perr = fs.lookup(p); perr != nil {
			err = perr
			return
		}
	}
	glob = append(glob, dir)
	for {
		line, err = buf.ReadBytes('\n')
		if len(bytes.TrimSpace(line)) == 0 {
			// Drain the buffer, needed for some use-cases (encoding, net/rpc)
			io.Copy(ioutil.Discard, buf)
			err, line = io.EOF, nil
		} else {
			depth, name, e = tb.DecodeLine(bytes.TrimRightFunc(line, unicode.IsSpace))
			if len(name) == 0 || depth < 0 || e != nil {
				// Drain the buffer, needed for some use-cases (encoding, net/rpc)
				io.Copy(ioutil.Discard, buf)
				err, line = e, nil
				if err == nil || err == io.EOF {
					err = ErrTreeBuilder
				}
			}
		}
		// Skip first iteration.
		if len(prevName) != 0 {
			// Insert the node from previous iteration - node is a directory when
			// a diference of the tree depth > 0, a file otherwise.
			var (
				name  string
				value interface{}
			)
			if bytes.HasSuffix(prevName, []byte{'/'}) {
				name, value = string(bytes.TrimRight(prevName, "/")), Directory{}
			} else {
				name, value = string(prevName), File{}
			}
			switch {
			case depth > prevDepth:
				d := Directory{}
				dir[name], glob, dir = d, append(glob, dir), d
			case depth == prevDepth:
				dir[name] = value
			case depth < prevDepth:
				n := max(len(glob)+depth-prevDepth, 0)
				dir[name], dir, glob = value, glob[n], glob[:n]
			}
		}
		// A node from each iteration is handled on the next one. That's why the
		// error handling is deferred.
		if len(line) == 0 {
			if err == io.EOF {
				err = nil
			}
			return
		}
		prevDepth, prevName = depth, name
	}
}
Example #19
0
// receiver loops reading data from the client's network connection and writing
// it to the current driver for processing. If the read times out the connection
// will be closed and the inactive user disconnected.
func (c *Client) receiver() {

	// Our initial login driver.
	driver := driver.New(c)

	// buffer is the input buffer which may be drip fed data from a client. This
	// caters for input being read in multiple reads, multiple inputs being read
	// in a single read and byte-at-a-time reads - currently from Windows telnet
	// clients.  It has a fixed length and capacity to avoid re-allocations.
	// bCursor points to the *next* byte in the buffer to be filled.
	buffer := make([]byte, BUFFER_SIZE, BUFFER_SIZE)
	bCursor := 0

	// Short & simple function to simplify for loop
	//
	// NOTE: Slicing the buffer with buffer[0:bCursor] stops us accidently
	// reading an LF in the garbage portion of the buffer after the cursor.
	// See next TODO for notes on the garbage.
	nextLF := func() int {
		return bytes.IndexByte(buffer[0:bCursor], 0x0A)
	}

	var b int      // bytes read from network
	var err error  // any comms error
	var LF int     // next linefeed position
	var cmd []byte // extracted command to be processed

	// Loop on connection until we bail out or timeout
	for !c.isBailing() && !driver.IsQuitting() {

		c.conn.SetReadDeadline(time.Now().Add(MAX_TIMEOUT))
		b, err = c.conn.Read(buffer[bCursor:])

		if b > 0 {

			// If buffer would overflow discard current buffer by
			// setting the buffer length back to zero
			if bCursor+b >= BUFFER_SIZE {
				bCursor = 0
				continue
			}
			bCursor += b

			for LF = nextLF(); LF != -1; LF = nextLF() {

				// NOTE: This could be buffer[0:LF-1] to save trimming the CR before
				// the LF as Telnet is supposed to send CR+LF. However if we just get
				// sent an LF - might be malicious or a badly written / configured
				// client - then [0:LF-1] causes a 'slice bounds out of range' panic.
				// Trimming extra characters is simpler than adding checking
				// specifically for the corner case.

				cmd = bytes.TrimRightFunc(buffer[0:LF], unicode.IsSpace)

				driver.Process(string(cmd))

				// Remove the part of the buffer we just processed by copying the bytes
				// after the bCursor to the front of the buffer.
				//
				// TODO: This has the side effect of being quick and simple but leaves
				// input garbage from the bCursor to the end of the buffer. Will this
				// be an issue? A security issue? We could setup a zero buffer and copy
				// enough to overwrite the garbage? See previous NOTE on garbage check.
				copy(buffer, buffer[LF+1:])
				bCursor -= LF + 1
			}
		}

		// Check for errors reading data (see io.Reader for details)
		if err != nil {
			if oe, ok := err.(*net.OpError); ok && oe.Timeout() {
				c.prompt = sender.PROMPT_NONE
				c.Send("")
				driver.Logout()
				c.Send("\n\n[RED]Idle connection terminated by server.")
				log.Printf("Closing idle connection for: %s", c)
				break
			}
			c.bailing(err)
		}

	}

	driver.Logout()
}
Example #20
0
// Trim space from the right.
func (buf *parserBuf) trimSpaceRight() {
	buf.bytes = bytes.TrimRightFunc(buf.bytes, unicode.IsSpace)
}
Example #21
0
func (s *Server) receiver(c net.PacketConn) {
	//q := (chan<- Message)(s.q)
	buf := make([]byte, 1024)
	for {
		n, addr, err := c.ReadFrom(buf)
		if err != nil {
			if !s.shutdown {
				s.l.Fatalln("Read error:", err)
			}
			return
		}
		pkt := buf[:n]

		m := new(Message)
		m.Source = addr
		m.Time = time.Now()

		// Parse priority (if exists)
		prio := 13 // default priority
		hasPrio := false
		if pkt[0] == '<' {
			n = 1 + bytes.IndexByte(pkt[1:], '>')
			if n > 1 && n < 5 {
				p, err := strconv.Atoi(string(pkt[1:n]))
				if err == nil && p >= 0 {
					hasPrio = true
					prio = p
					pkt = pkt[n+1:]
				}
			}
		}
		m.Severity = Severity(prio & 0x07)
		m.Facility = Facility(prio >> 3)

		// Parse header (if exists)
		if hasPrio && len(pkt) >= 16 && pkt[15] == ' ' {
			// Get timestamp
			layout := "Jan _2 15:04:05"
			ts, err := time.Parse(layout, string(pkt[:15]))
			if err == nil && !ts.IsZero() {
				// Get hostname
				n = 16 + bytes.IndexByte(pkt[16:], ' ')
				if n != 15 {
					m.Timestamp = ts
					m.Hostname = string(pkt[16:n])
					pkt = pkt[n+1:]
				}
			}
			// TODO: check for version an new format of header as
			// described in RFC 5424.
		}

		// Parse msg part
		msg := string(bytes.TrimRightFunc(pkt, isNulCrLf))
		n = strings.IndexFunc(msg, isNotAlnum)
		if n != -1 {
			m.Tag = msg[:n]
			m.Content = msg[n:]
		} else {
			m.Content = msg
		}
		msg = strings.TrimFunc(msg, unicode.IsSpace)
		n = strings.IndexFunc(msg, unicode.IsSpace)
		if n != -1 {
			m.Tag1 = msg[:n]
			m.Content1 = strings.TrimLeftFunc(msg[n+1:], unicode.IsSpace)
		} else {
			m.Content1 = msg
		}

		s.passToHandlers(m)
	}
}
Example #22
0
// URL-encodes the `source` byte slice and strips trailing padding
// characters.
func encode64(source []byte) []byte {
	encoded := make([]byte, base64.URLEncoding.EncodedLen(len(source)))
	base64.URLEncoding.Encode(encoded, source)
	return bytes.TrimRightFunc(encoded, isPadding64)
}
Example #23
0
func trimRightSpaceBytes(b []byte) []byte {
	return bytes.TrimRightFunc(b, unicode.IsSpace)
}
Example #24
0
func (p *parser) NextValue() (*parseValue, error) {
	result := new(parseValue)
	inValue := false
	for {
		rawLine, err := p.nextLine()
		// make copy
		rawLine = append([]byte{}, rawLine...)
		if err == io.EOF && inValue {
			// will return EOF on next read
			return result, nil
		} else if err != nil {
			return result, err
		}
		// strip trailing whitespace
		line := bytes.TrimRightFunc(rawLine, unicode.IsSpace)
		if inValue {
			if len(line) == 0 || !startsWithSpace(line) {
				// leave p.bufLine intact for next call
				return result, nil
			}
			result.value = append(result.value, '\n')
			result.value = append(result.value, bytes.TrimLeftFunc(line, unicode.IsSpace)...)
			result.addRawLine(rawLine)
			// we crossed the line, so mark it zero
			p.bufLine = nil
		} else if len(line) > 0 {
			result.lineNum = p.lineNum
			switch line[0] {
			case ';':
				result.entryType = entryTypeComment
				result.addRawLine(rawLine)
				p.bufLine = nil
				return result, nil
			case '[':
				if line[len(line)-1] != ']' {
					return nil, newParseError(ErrInvalidSection, p.lineNum)
				}
				result.entryType = entryTypeSection
				result.section = strings.TrimFunc(string(line[1:len(line)-1]), unicode.IsSpace)
				result.addRawLine(rawLine)
				p.bufLine = nil
				return result, nil
			default:
				kv := bytes.SplitN(line, []byte("="), 2)
				if len(kv) != 2 {
					return nil, newParseError(ErrInvalidEntry, p.lineNum)
				}
				result.entryType = entryTypeKV
				result.key = string(bytes.TrimRightFunc(kv[0], unicode.IsSpace))
				value := bytes.TrimLeftFunc(kv[1], unicode.IsSpace)
				result.value = append([]byte{}, value...)
				result.addRawLine(rawLine)
				// the next line may be a continuation of this value
				inValue = true
				p.bufLine = nil
			}
		} else {
			// empty line
			result.entryType = entryTypeBlank
			result.addRawLine([]byte(""))
			p.bufLine = nil
			return result, nil
		}
	}
}