func parseIndex(sql []byte) (indexName string, indexId interface{}, userId uint64) { var err error keyspaceIndex := bytes.Index(sql, KEYSPACE_ID_COMMENT) if keyspaceIndex == -1 { panic(NewBinlogParseError(fmt.Sprintf("Error parsing index comment, doesn't contain keyspace id %v", string(sql)))) } keyspaceIdComment := sql[keyspaceIndex+len(KEYSPACE_ID_COMMENT):] indexCommentStart := bytes.Index(keyspaceIdComment, INDEX_COMMENT) if indexCommentStart != -1 { indexCommentParts := bytes.SplitN(keyspaceIdComment[indexCommentStart:], COLON_BYTE, 2) userId, err = strconv.ParseUint(string(bytes.SplitN(indexCommentParts[1], mysqlctl.SPACE, 2)[0]), 10, 64) if err != nil { panic(NewBinlogParseError(fmt.Sprintf("Error converting user_id %v", string(sql)))) } indexNameId := bytes.Split(indexCommentParts[0], DOT_BYTE) indexName = string(indexNameId[1]) if indexName == "username" { indexId = string(bytes.TrimRight(indexNameId[2], COLON)) } else { indexId, err = strconv.ParseUint(string(bytes.TrimRight(indexNameId[2], COLON)), 10, 64) if err != nil { panic(NewBinlogParseError(fmt.Sprintf("Error converting index id %v %v", string(bytes.TrimRight(indexNameId[2], COLON)), string(sql)))) } } } return }
func TestNew(t *testing.T) { err := New("foo") if err.Error() != "foo" { t.Errorf("Wrong message") } err = New(fmt.Errorf("foo")) if err.Error() != "foo" { t.Errorf("Wrong message") } bs := [][]byte{New("foo").Stack(), debug.Stack()} // Ignore the first line (as it contains the PC of the .Stack() call) bs[0] = bytes.SplitN(bs[0], []byte("\n"), 2)[1] bs[1] = bytes.SplitN(bs[1], []byte("\n"), 2)[1] if bytes.Compare(bs[0], bs[1]) != 0 { t.Errorf("Stack didn't match") t.Errorf("%s", bs[0]) t.Errorf("%s", bs[1]) } if err.ErrorStack() != err.TypeName()+" "+err.Error()+"\n"+string(err.Stack()) { t.Errorf("ErrorStack is in the wrong format") } }
func statCpu(oC *tCommand) { var aPass [2][7]int var aTotl = [2]int{0, 0} for a := 0; a < len(aPass); a++ { aBuf, _ := ioutil.ReadFile("/proc/stat") aLine := bytes.SplitN(aBuf, []byte{'\n'}, 3) aLine = bytes.SplitN(aLine[1], []byte{' '}, 9) for aN := 0; aN < len(aPass[0]); aN++ { aPass[a][aN], _ = strconv.Atoi(string(aLine[aN+1])) aTotl[a] += aPass[a][aN] } if a == 0 { time.Sleep(time.Duration(150) * time.Millisecond) } } var aArg string for aN := 0; aN < len(aPass[0]); aN++ { aPass[0][aN] = (aPass[1][aN] - aPass[0][aN]) * 1000 / (aTotl[1] - aTotl[0]) aArg += fmt.Sprintf("%4d.%d ", aPass[0][aN]/10, aPass[0][aN]%10) } oC.buf = []byte(fmt.Sprintf("%-6s %-6s %-6s %-6s %-6s %-6s %-6s\n%s\n", "User %", "Niced", "System", "Idle", "IOWait", "IRQ", "SoftIRQ", aArg)) if sDebug { fmt.Println(oC.name) } }
func ParseMessage(line []byte) *Message { line = bytes.TrimSpace(line) if len(line) <= 0 { return nil } m := new(Message) if line[0] == ':' { split := bytes.SplitN(line, []byte{' '}, 2) if len(split) <= 1 { return nil } m.Prefix = string(split[0][1:]) line = split[1] } split := bytes.SplitN(line, []byte{':'}, 2) args := bytes.Split(bytes.TrimSpace(split[0]), []byte{' '}) m.Command = string(bytes.ToUpper(args[0])) m.Args = make([]string, 0, len(args)) for _, arg := range args[1:] { m.Args = append(m.Args, string(arg)) } if len(split) > 1 { m.Args = append(m.Args, string(split[1])) } return m }
// Decode job from byte slice func decodeJob(data []byte) (job *Job, err error) { if len(data) < 12 { return nil, common.Errorf("Invalid data: %V", data) } datatype := common.BytesToUint32([4]byte{data[4], data[5], data[6], data[7]}) l := common.BytesToUint32([4]byte{data[8], data[9], data[10], data[11]}) if len(data[12:]) != int(l) { return nil, common.Errorf("Invalid data: %V", data) } data = data[12:] job = &Job{magicCode: common.RES, DataType: datatype, c: make(chan bool)} switch datatype { case common.JOB_ASSIGN: s := bytes.SplitN(data, []byte{'\x00'}, 3) if len(s) == 3 { job.Handle = string(s[0]) job.Fn = string(s[1]) data = s[2] } case common.JOB_ASSIGN_UNIQ: s := bytes.SplitN(data, []byte{'\x00'}, 4) if len(s) == 4 { job.Handle = string(s[0]) job.Fn = string(s[1]) job.UniqueId = string(s[2]) data = s[3] } } job.Data = data return }
func main() { s := []byte("1,2,3,4") sep := []byte{','} print(bytes.SplitN(s, sep, 2)) print(bytes.SplitN(s, sep, 0)) print(bytes.SplitN(s, sep, -1)) }
// Decode job from byte slice func decodeInPack(data []byte) (inpack *inPack, l int, err error) { if len(data) < minPacketLength { // valid package should not less 12 bytes err = fmt.Errorf("Invalid data: %V", data) return } dl := int(binary.BigEndian.Uint32(data[8:12])) dt := data[minPacketLength : dl+minPacketLength] if len(dt) != int(dl) { // length not equal err = fmt.Errorf("Invalid data: %V", data) return } inpack = getInPack() inpack.dataType = binary.BigEndian.Uint32(data[4:8]) switch inpack.dataType { case dtJobAssign: s := bytes.SplitN(dt, []byte{'\x00'}, 3) if len(s) == 3 { inpack.handle = string(s[0]) inpack.fn = string(s[1]) inpack.data = s[2] } case dtJobAssignUniq: s := bytes.SplitN(dt, []byte{'\x00'}, 4) if len(s) == 4 { inpack.handle = string(s[0]) inpack.fn = string(s[1]) inpack.uniqueId = string(s[2]) inpack.data = s[3] } default: inpack.data = dt } l = dl + minPacketLength return }
func (o *Tree) SetBytes(b []byte) (err error) { zr, e := zlib.NewReader(bytes.NewBuffer(b)) if e == nil { defer zr.Close() b, err = ioutil.ReadAll(zr) if err != nil { return err } } o.Content = b body := b for { split := bytes.SplitN(body, []byte{0}, 2) split1 := bytes.SplitN(split[0], []byte{' '}, 2) o.Entries = append(o.Entries, treeEntry{ Mode: string(split1[0]), File: string(split1[1]), Hash: split[1][0:20]}) body = split[1][20:] if len(split[1]) == 20 { break } } return }
func CreateSlackMessage(eventData []byte) SlackMessage { // Assumes topic is of the form domain/name/icon␀msg // but domain is ignored (should probably be slack.scraperwiki.com) i := bytes.IndexByte(eventData, byte('\x00')) if i == -1 { return SlackMessage{ string(eventData), "dinger", ":broken_heart:", "#log", } } splitEventData := bytes.SplitN(eventData, []byte("\x00"), 2) route := splitEventData[0] text := splitEventData[1] splitRoute := bytes.SplitN(route, []byte("/"), 3) name := splitRoute[1] icon := splitRoute[2] return SlackMessage{ string(text), string(name), string(icon), "#log", } }
func (blp *Blp) parseRotateEvent(line []byte) { rem := bytes.SplitN(line, mysqlctl.BINLOG_ROTATE_TO, 2) rem2 := bytes.SplitN(rem[1], mysqlctl.POS, 2) rotateFilename := strings.TrimSpace(string(rem2[0])) rotatePos, err := strconv.ParseUint(string(rem2[1]), 10, 64) if err != nil { panic(NewBinlogParseError(fmt.Sprintf("Error in extracting rotate pos %v from line %s", err, string(line)))) } if !blp.usingRelayLogs { //If the file being parsed is a binlog, //then the rotate events only correspond to itself. blp.currentPosition.Position.MasterFilename = rotateFilename blp.currentPosition.Position.MasterPosition = rotatePos blp.globalState.parseStats.Add("BinlogRotate."+blp.keyrangeTag, 1) } else { //For relay logs, the rotate events could be that of relay log or the binlog, //the prefix of rotateFilename is used to test which case is it. logsDir, relayFile := path.Split(blp.currentPosition.Position.RelayFilename) currentPrefix := strings.Split(relayFile, ".")[0] rotatePrefix := strings.Split(rotateFilename, ".")[0] if currentPrefix == rotatePrefix { //relay log rotated blp.currentPosition.Position.RelayFilename = path.Join(logsDir, rotateFilename) blp.globalState.parseStats.Add("RelayRotate."+blp.keyrangeTag, 1) } else { //master file rotated blp.currentPosition.Position.MasterFilename = rotateFilename blp.currentPosition.Position.MasterPosition = rotatePos blp.globalState.parseStats.Add("BinlogRotate."+blp.keyrangeTag, 1) } } }
func TestStackFormatMatches(t *testing.T) { defer func() { err := recover() if err != 'a' { t.Fatal(err) } bs := [][]byte{Errorf("hi").StackTrace(), debug.Stack()} // Ignore the first line (as it contains the PC of the .Stack() call) bs[0] = bytes.SplitN(bs[0], []byte("\n"), 2)[1] bs[1] = bytes.SplitN(bs[1], []byte("\n"), 2)[1] if bytes.Compare(bs[0], bs[1]) != 0 { t.Errorf("Stack didn't match") t.Errorf("%s", bs[0]) t.Errorf("%s", bs[1]) } }() err := a() if err != nil { t.Error(err) } }
func ExampleSplitN() { fmt.Printf("%q\n", bytes.SplitN([]byte("a,b,c"), []byte(","), 2)) z := bytes.SplitN([]byte("a,b,c"), []byte(","), 0) fmt.Printf("%q (nil = %v)\n", z, z == nil) // Output: // ["a" "b,c"] // [] (nil = true) }
/*{{{ func (this *IniConfig) Parse(config_path string) (ConfigContainer, error) * 解析配置文件 */ func (this *IniConfig) Parse(config_path string) (ConfigContainer, error) { fp, err := os.Open(config_path) defer fp.Close() if err != nil { return nil, err } cfg := &IniConfigContainer{ //make(map[string]map[string]string), make(config_node), } buff := bufio.NewReader(fp) var mod string for { line, _, err := buff.ReadLine() if io.EOF == err { break } if bytes.Equal(line, empty) { continue } line = bytes.TrimSpace(line) if bytes.HasPrefix(line, AnnoPrefix) { continue } if bytes.HasPrefix(line, ModLeft) && bytes.HasSuffix(line, ModRight) { mod = string(line[1 : len(line)-1]) continue } if mod == "" { continue } if _, ok := cfg.data[mod]; ok == false { cfg.data[mod] = make(config_node) } vals := bytes.SplitN(line, Equal, 2) if len(vals) < 2 { continue } section_val := bytes.SplitN(vals[0], SectionSplit, 2) if len(section_val) < 2 { cfg.data[mod].(config_node)[string(bytes.TrimSpace(vals[0]))] = string(bytes.TrimSpace(vals[1])) } else { section := string(bytes.TrimSpace(section_val[0])) if _, ok := cfg.data[mod].(config_node)[section]; ok == false { cfg.data[mod].(config_node)[section] = make(config_node) } cfg.data[mod].(config_node)[section].(config_node)[string(bytes.TrimSpace(section_val[1]))] = string(bytes.TrimSpace(vals[1])) } } return cfg, nil }
// startAgent executes ssh-agent, and returns a Agent interface to it. func startAgent(t *testing.T) (client Agent, socket string, cleanup func()) { if testing.Short() { // ssh-agent is not always available, and the key // types supported vary by platform. t.Skip("skipping test due to -short") } bin, err := exec.LookPath("ssh-agent") if err != nil { t.Skip("could not find ssh-agent") } cmd := exec.Command(bin, "-s") out, err := cmd.Output() if err != nil { t.Fatalf("cmd.Output: %v", err) } /* Output looks like: SSH_AUTH_SOCK=/tmp/ssh-P65gpcqArqvH/agent.15541; export SSH_AUTH_SOCK; SSH_AGENT_PID=15542; export SSH_AGENT_PID; echo Agent pid 15542; */ fields := bytes.Split(out, []byte(";")) line := bytes.SplitN(fields[0], []byte("="), 2) line[0] = bytes.TrimLeft(line[0], "\n") if string(line[0]) != "SSH_AUTH_SOCK" { t.Fatalf("could not find key SSH_AUTH_SOCK in %q", fields[0]) } socket = string(line[1]) line = bytes.SplitN(fields[2], []byte("="), 2) line[0] = bytes.TrimLeft(line[0], "\n") if string(line[0]) != "SSH_AGENT_PID" { t.Fatalf("could not find key SSH_AGENT_PID in %q", fields[2]) } pidStr := line[1] pid, err := strconv.Atoi(string(pidStr)) if err != nil { t.Fatalf("Atoi(%q): %v", pidStr, err) } conn, err := net.Dial("unix", string(socket)) if err != nil { t.Fatalf("net.Dial: %v", err) } ac := NewClient(conn) return ac, socket, func() { proc, _ := os.FindProcess(pid) if proc != nil { proc.Kill() } conn.Close() os.RemoveAll(filepath.Dir(socket)) } }
func (blp *Blp) parseMasterPosition(line []byte) { var err error rem := bytes.SplitN(line, mysqlctl.BINLOG_END_LOG_POS, 2) masterPosStr := string(bytes.SplitN(rem[1], mysqlctl.SPACE, 2)[0]) blp.nextStmtPosition, err = strconv.ParseUint(masterPosStr, 10, 64) if err != nil { panic(NewBinlogParseError(fmt.Sprintf("Error in extracting master position, %v, sql %v, pos string %v", err, string(line), masterPosStr))) } }
func (blp *Blp) parseGroupId(line []byte) { rem := bytes.SplitN(line, mysqlctl.BINLOG_GROUP_ID, 2) rem2 := bytes.SplitN(rem[1], mysqlctl.SPACE, 2) groupIdStr := strings.TrimSpace(string(rem2[0])) groupId, err := strconv.ParseUint(groupIdStr, 10, 64) if err != nil { panic(NewBinlogParseError(fmt.Sprintf("Error in extracting group_id %v, sql %v", err, string(line)))) } blp.currentPosition.GroupId = groupId }
func (p *AuthDbusCookieSha1) ProcessData(mesg []byte) ([]byte, error) { decodedLen, err := hex.Decode(mesg, mesg) if err != nil { return nil, err } mesgTokens := bytes.SplitN(mesg[:decodedLen], []byte(" "), 3) file, err := os.Open(os.Getenv("HOME") + "/.dbus-keyrings/" + string(mesgTokens[0])) if err != nil { return nil, err } defer file.Close() fileStream := bufio.NewReader(file) var cookie []byte for { line, _, err := fileStream.ReadLine() if err == io.EOF { return nil, errors.New("SHA1 Cookie not found") } else if err != nil { return nil, err } cookieTokens := bytes.SplitN(line, []byte(" "), 3) if bytes.Compare(cookieTokens[0], mesgTokens[1]) == 0 { cookie = cookieTokens[2] break } } challenge := make([]byte, len(mesgTokens[2])) if _, err = rand.Read(challenge); err != nil { return nil, err } for temp := challenge; ; { if index := bytes.IndexAny(temp, " \t"); index == -1 { break } else if _, err := rand.Read(temp[index : index+1]); err != nil { return nil, err } else { temp = temp[index:] } } hash := sha1.New() if _, err := hash.Write(bytes.Join([][]byte{mesgTokens[2], challenge, cookie}, []byte(":"))); err != nil { return nil, err } resp := bytes.Join([][]byte{challenge, []byte(hex.EncodeToString(hash.Sum(nil)))}, []byte(" ")) respHex := make([]byte, hex.EncodedLen(len(resp))) hex.Encode(respHex, resp) return append([]byte("DATA "), respHex...), nil }
func (blp *Bls) parseRotateEvent(line []byte) { rem := bytes.SplitN(line, BINLOG_ROTATE_TO, 2) rem2 := bytes.SplitN(rem[1], POS, 2) rotateFilename := strings.TrimSpace(string(rem2[0])) rotatePos, err := strconv.ParseUint(string(rem2[1]), 10, 64) if err != nil { panic(newBinlogServerError(fmt.Sprintf("Error in extracting rotate pos %v from line %s", err, string(line)))) } //If the file being parsed is a binlog, //then the rotate events only correspond to itself. blp.currentPosition.Position.MasterFilename = rotateFilename blp.currentPosition.Position.MasterPosition = rotatePos blp.globalState.blsStats.parseStats.Add("BinlogRotate."+blp.keyrangeTag, 1) }
func (c *AutoScheduler) listHost(host *Host, dir string) { rs, err := host.Get(dir) if err != nil || rs == nil { return } for _, line := range bytes.SplitN(rs.Body, []byte("\n"), 17) { if bytes.Count(line, []byte(" ")) < 2 || line[1] != '/' { continue } vv := bytes.SplitN(line, []byte(" "), 3) cnt, _ := strconv.ParseFloat(string(vv[2]), 64) adjust := float64(math.Sqrt(cnt)) c.Feedback(host, dir+string(vv[0]), adjust) } }
// ParseLine turns a line into a *Metric (or not) and returns an error if the line was invalid. // note that *Metric can be nil when the line was valid (if the line was empty) // input format: key:value|modifier[|@samplerate] func ParseLine(line []byte) (metric *common.Metric, err error) { // todo: modify this function to use regex. if len(line) == 0 { return nil, nil } parts := bytes.SplitN(bytes.TrimSpace(line), []byte(":"), -1) // If there are more than two colons, return error. if len(parts) != 2 { return nil, errors.New("bad amount of colons") } bucket := parts[0] if len(bucket) == 0 { return nil, errors.New("key zero len") } parts = bytes.SplitN(parts[1], []byte("|"), 3) if len(parts) < 2 { return nil, errors.New("bad amount of pipes") } modifier := string(parts[1]) // todo: put modifiers in a global set so that adding/removing modifiers would be much easy. if modifier != "g" && modifier != "c" && modifier != "ms" { return nil, errors.New("unsupported metric type") } sampleRate := float64(1) if len(parts) == 3 { if parts[2][0] != byte('@') { return nil, errors.New("invalid sampling") } var err error sampleRate, err = strconv.ParseFloat(string(parts[2])[1:], 32) if err != nil { return nil, err } } value, err := strconv.ParseFloat(string(parts[0]), 64) if err != nil { return nil, err } isDelta := parts[0][0] == '+' || parts[0][0] == '-' metric = &common.Metric{ Bucket: string(bucket), Value: value, Modifier: modifier, Sampling: float32(sampleRate), IsDelta: isDelta, } return metric, nil }
// returns an input channel with a raw key, value without collating keys func RawInternalInputProtocol(input io.Reader) <-chan KeyValue { out := make(chan KeyValue, 100) go func() { var line []byte var lineErr error r := bufio.NewReaderSize(input, 1024*1024*2) var lastKey []byte for { if lineErr == io.EOF { break } line, lineErr = r.ReadBytes('\n') if len(line) <= 1 { continue } chunks := bytes.SplitN(line, []byte("\t"), 2) if len(chunks) != 2 { Counter("RawInternalInputProtocol", "invalid line - no tab", 1) log.Printf("invalid line. no tab - %s", line) lastKey = lastKey[:0] continue } out <- KeyValue{chunks[0], chunks[1]} } close(out) }() return out }
// Write parses the standard logging line and passes its components to the // logger for Severity(lb). func (lb logBridge) Write(b []byte) (n int, err error) { var ( file = "???" line = 1 text string ) // Split "d.go:23: message" into "d.go", "23", and "message". if parts := bytes.SplitN(b, []byte{':'}, 3); len(parts) != 3 || len(parts[0]) < 1 || len(parts[2]) < 1 { text = fmt.Sprintf("bad log format: %s", b) } else { file = string(parts[0]) text = string(parts[2][1 : len(parts[2])-1]) // skip leading space and trailing newline line, err = strconv.Atoi(string(parts[1])) if err != nil { text = fmt.Sprintf("bad line number: %s", b) line = 1 } } // printWithFileLine with alsoToStderr=true, so standard log messages // always appear on standard error. entry := &LogEntry{ Format: text, } logging.outputLogEntry(Severity(lb), file, line, true, entry) return len(b), nil }
func findNews(text [][]byte, address, sender string) []byte { // prep the address for searching against text addr := []byte(address) addrStart := bytes.SplitN(addr, []byte("@"), 2)[0] // so we can reuse similar addresses? if len(addrStart) > 15 { addrStart = addrStart[:15] } var news [][]byte badLines := 0 senderBytes := bytes.ToLower([]byte(sender)) for _, line := range text { line := bytes.Trim(line, "-| ?") if isNews(line, addr, addrStart, senderBytes) { badLines = 0 news = append(news, line) } else if (len(news) > 0) && (len(line) > 0) { badLines++ } // get at most 3 or quit if we have bad rows and at least 2 or over 2 bads and 1 good if (len(news) >= 3) || ((badLines > 0) && (len(news) >= 2)) || ((badLines >= 2) && (len(news) >= 1)) { break } } return bytes.Join(news, []byte(" ")) }
func FileGetConfig(filenameOrURL string, timeout ...time.Duration) (map[string]string, error) { data, err := FileGetBytes(filenameOrURL, timeout...) if err != nil { return nil, err } lines := bytes.Split(data, []byte("\n")) config := make(map[string]string, len(lines)) for _, line := range lines { kv := bytes.SplitN(line, []byte("="), 2) if len(kv) < 2 { continue } key := string(bytes.TrimSpace(kv[0])) if len(key) == 0 || key[0] == '#' { continue } value := string(bytes.TrimSpace(kv[1])) if len(value) >= 2 && value[0] == '"' && value[len(value)-1] == '"' { value = value[1 : len(value)-1] } config[key] = value } return config, nil }
func readKey() (string, error) { c, err := ioutil.ReadFile(*keyFile) if err != nil { return "", err } return string(bytes.TrimSpace(bytes.SplitN(c, []byte("\n"), 2)[0])), nil }
func (c *codec) Decode(b []byte) (Message, error) { // [message type] ':' [message id ('+')] ':' [message endpoint] (':' [message data]) parts := bytes.SplitN(b, []byte(":"), 4) if len(parts) < 3 { return nil, errors.New("invalid packet") } mtype, err := strconv.Atoi(string(parts[0])) if err != nil { return nil, err } idPart := parts[1] ack := bytes.HasSuffix(idPart, []byte("+")) if ack { idPart = idPart[:len(idPart)-1] } pid, err := strconv.Atoi(string(idPart)) if err != nil { return nil, err } endpoint := string(parts[2]) var r io.Reader if len(parts) == 4 { r = bytes.NewBuffer(parts[3]) } return newMessage(mtype, pid, ack, endpoint, r), nil }
// LinesBeforeAndAfter reads n lines before and after a given line. // Set lineNumbers to true, to prepend line numbers. func LinesBeforeAndAfter(data []byte, line, before, after int, lineNumbers bool) []byte { // TODO(mattes): Trim empty lines at the beginning and at the end // TODO(mattes): Trim offset whitespace at the beginning of each line, so that indentation is preserved startLine := line - before endLine := line + after lines := bytes.SplitN(data, []byte("\n"), endLine+1) if startLine < 0 { startLine = 0 } if endLine > len(lines) { endLine = len(lines) } selectLines := lines[startLine:endLine] newLines := make([][]byte, 0) lineCounter := startLine + 1 lineNumberDigits := len(strconv.Itoa(len(selectLines))) for _, l := range selectLines { lineCounterStr := strconv.Itoa(lineCounter) if len(lineCounterStr)%lineNumberDigits != 0 { lineCounterStr = strings.Repeat(" ", lineNumberDigits-len(lineCounterStr)%lineNumberDigits) + lineCounterStr } lNew := l if lineNumbers { lNew = append([]byte(lineCounterStr+": "), lNew...) } newLines = append(newLines, lNew) lineCounter += 1 } return bytes.Join(newLines, []byte("\n")) }
// Decode decodes list of capabilities from raw into the list func (l *List) Decode(raw []byte) error { // git 1.x receive pack used to send a leading space on its // git-receive-pack capabilities announcement. We just trim space to be // tolerant to space changes in different versions. raw = bytes.TrimSpace(raw) if len(raw) == 0 { return nil } for _, data := range bytes.Split(raw, []byte{' '}) { pair := bytes.SplitN(data, []byte{'='}, 2) c := Capability(pair[0]) if len(pair) == 1 { if err := l.Add(c); err != nil { return err } continue } if err := l.Add(c, string(pair[1])); err != nil { return err } } return nil }
func NewBuilder(goroot *Repo, name string) (*Builder, error) { b := &Builder{ goroot: goroot, name: name, } // get builderEnv for this tool var err error if b.env, err = b.builderEnv(name); err != nil { return nil, err } // read keys from keyfile fn := "" switch runtime.GOOS { case "plan9": fn = os.Getenv("home") case "windows": fn = os.Getenv("HOMEDRIVE") + os.Getenv("HOMEPATH") default: fn = os.Getenv("HOME") } fn = filepath.Join(fn, ".gobuildkey") if s := fn + "-" + b.name; isFile(s) { // builder-specific file fn = s } c, err := ioutil.ReadFile(fn) if err != nil { return nil, fmt.Errorf("readKeys %s (%s): %s", b.name, fn, err) } b.key = string(bytes.TrimSpace(bytes.SplitN(c, []byte("\n"), 2)[0])) return b, nil }
// DecodeServerEntry extracts server entries from the encoding // used by remote server lists and Psiphon server handshake requests. // // The resulting ServerEntry.LocalSource is populated with serverEntrySource, // which should be one of SERVER_ENTRY_SOURCE_EMBEDDED, SERVER_ENTRY_SOURCE_REMOTE, // SERVER_ENTRY_SOURCE_DISCOVERY, SERVER_ENTRY_SOURCE_TARGET. // ServerEntry.LocalTimestamp is populated with the provided timestamp, which // should be a RFC 3339 formatted string. These local fields are stored with the // server entry and reported to the server as stats (a coarse granularity timestamp // is reported). func DecodeServerEntry( encodedServerEntry, timestamp, serverEntrySource string) (serverEntry *ServerEntry, err error) { hexDecodedServerEntry, err := hex.DecodeString(encodedServerEntry) if err != nil { return nil, common.ContextError(err) } // Skip past legacy format (4 space delimited fields) and just parse the JSON config fields := bytes.SplitN(hexDecodedServerEntry, []byte(" "), 5) if len(fields) != 5 { return nil, common.ContextError(errors.New("invalid encoded server entry")) } serverEntry = new(ServerEntry) err = json.Unmarshal(fields[4], &serverEntry) if err != nil { return nil, common.ContextError(err) } // NOTE: if the source JSON happens to have values in these fields, they get clobbered. serverEntry.LocalSource = serverEntrySource serverEntry.LocalTimestamp = timestamp return serverEntry, nil }