1package smtp 2 3import ( 4 "fmt" 5 "strings" 6) 7 8func parseCmd(line string) (cmd string, arg string, err error) { 9 line = strings.TrimRight(line, "\r\n") 10 11 l := len(line) 12 switch { 13 case strings.HasPrefix(strings.ToUpper(line), "STARTTLS"): 14 return "STARTTLS", "", nil 15 case l == 0: 16 return "", "", nil 17 case l < 4: 18 return "", "", fmt.Errorf("Command too short: %q", line) 19 case l == 4: 20 return strings.ToUpper(line), "", nil 21 case l == 5: 22 // Too long to be only command, too short to have args 23 return "", "", fmt.Errorf("Mangled command: %q", line) 24 } 25 26 // If we made it here, command is long enough to have args 27 if line[4] != ' ' { 28 // There wasn't a space after the command? 29 return "", "", fmt.Errorf("Mangled command: %q", line) 30 } 31 32 // I'm not sure if we should trim the args or not, but we will for now 33 //return strings.ToUpper(line[0:4]), strings.Trim(line[5:], " "), nil 34 return strings.ToUpper(line[0:4]), strings.Trim(line[5:], " \n\r"), nil 35} 36 37// Takes the arguments proceeding a command and files them 38// into a map[string]string after uppercasing each key. Sample arg 39// string: 40// " BODY=8BITMIME SIZE=1024 SMTPUTF8" 41// The leading space is mandatory. 42func parseArgs(args []string) (map[string]string, error) { 43 argMap := map[string]string{} 44 for _, arg := range args { 45 if arg == "" { 46 continue 47 } 48 m := strings.Split(arg, "=") 49 switch len(m) { 50 case 2: 51 argMap[strings.ToUpper(m[0])] = m[1] 52 case 1: 53 argMap[strings.ToUpper(m[0])] = "" 54 default: 55 return nil, fmt.Errorf("Failed to parse arg string: %q", arg) 56 } 57 } 58 return argMap, nil 59} 60 61func parseHelloArgument(arg string) (string, error) { 62 domain := arg 63 if idx := strings.IndexRune(arg, ' '); idx >= 0 { 64 domain = arg[:idx] 65 } 66 if domain == "" { 67 return "", fmt.Errorf("Invalid domain") 68 } 69 return domain, nil 70} 71