1package imap 2 3import ( 4 "errors" 5) 6 7// A status response type. 8type StatusRespType string 9 10// Status response types defined in RFC 3501 section 7.1. 11const ( 12 // The OK response indicates an information message from the server. When 13 // tagged, it indicates successful completion of the associated command. 14 // The untagged form indicates an information-only message. 15 StatusRespOk StatusRespType = "OK" 16 17 // The NO response indicates an operational error message from the 18 // server. When tagged, it indicates unsuccessful completion of the 19 // associated command. The untagged form indicates a warning; the 20 // command can still complete successfully. 21 StatusRespNo StatusRespType = "NO" 22 23 // The BAD response indicates an error message from the server. When 24 // tagged, it reports a protocol-level error in the client's command; 25 // the tag indicates the command that caused the error. The untagged 26 // form indicates a protocol-level error for which the associated 27 // command can not be determined; it can also indicate an internal 28 // server failure. 29 StatusRespBad StatusRespType = "BAD" 30 31 // The PREAUTH response is always untagged, and is one of three 32 // possible greetings at connection startup. It indicates that the 33 // connection has already been authenticated by external means; thus 34 // no LOGIN command is needed. 35 StatusRespPreauth StatusRespType = "PREAUTH" 36 37 // The BYE response is always untagged, and indicates that the server 38 // is about to close the connection. 39 StatusRespBye StatusRespType = "BYE" 40) 41 42type StatusRespCode string 43 44// Status response codes defined in RFC 3501 section 7.1. 45const ( 46 CodeAlert StatusRespCode = "ALERT" 47 CodeBadCharset StatusRespCode = "BADCHARSET" 48 CodeCapability StatusRespCode = "CAPABILITY" 49 CodeParse StatusRespCode = "PARSE" 50 CodePermanentFlags StatusRespCode = "PERMANENTFLAGS" 51 CodeReadOnly StatusRespCode = "READ-ONLY" 52 CodeReadWrite StatusRespCode = "READ-WRITE" 53 CodeTryCreate StatusRespCode = "TRYCREATE" 54 CodeUidNext StatusRespCode = "UIDNEXT" 55 CodeUidValidity StatusRespCode = "UIDVALIDITY" 56 CodeUnseen StatusRespCode = "UNSEEN" 57) 58 59// A status response. 60// See RFC 3501 section 7.1 61type StatusResp struct { 62 // The response tag. If empty, it defaults to *. 63 Tag string 64 // The status type. 65 Type StatusRespType 66 // The status code. 67 // See https://www.iana.org/assignments/imap-response-codes/imap-response-codes.xhtml 68 Code StatusRespCode 69 // Arguments provided with the status code. 70 Arguments []interface{} 71 // The status info. 72 Info string 73} 74 75func (r *StatusResp) resp() {} 76 77// If this status is NO or BAD, returns an error with the status info. 78// Otherwise, returns nil. 79func (r *StatusResp) Err() error { 80 if r == nil { 81 // No status response, connection closed before we get one 82 return errors.New("imap: connection closed during command execution") 83 } 84 85 if r.Type == StatusRespNo || r.Type == StatusRespBad { 86 return errors.New(r.Info) 87 } 88 return nil 89} 90 91func (r *StatusResp) WriteTo(w *Writer) error { 92 tag := RawString(r.Tag) 93 if tag == "" { 94 tag = "*" 95 } 96 97 if err := w.writeFields([]interface{}{RawString(tag), RawString(r.Type)}); err != nil { 98 return err 99 } 100 101 if err := w.writeString(string(sp)); err != nil { 102 return err 103 } 104 105 if r.Code != "" { 106 if err := w.writeRespCode(r.Code, r.Arguments); err != nil { 107 return err 108 } 109 110 if err := w.writeString(string(sp)); err != nil { 111 return err 112 } 113 } 114 115 if err := w.writeString(r.Info); err != nil { 116 return err 117 } 118 119 return w.writeCrlf() 120} 121