| 1082 | |
| 1083 | |
| 1084 | def _command(self, name, *args): |
| 1085 | |
| 1086 | if self.state not in Commands[name]: |
| 1087 | self.literal = None |
| 1088 | raise self.error("command %s illegal in state %s, " |
| 1089 | "only allowed in states %s" % |
| 1090 | (name, self.state, |
| 1091 | ', '.join(Commands[name]))) |
| 1092 | |
| 1093 | for typ in ('OK', 'NO', 'BAD'): |
| 1094 | if typ in self.untagged_responses: |
| 1095 | del self.untagged_responses[typ] |
| 1096 | |
| 1097 | if 'READ-ONLY' in self.untagged_responses \ |
| 1098 | and not self.is_readonly: |
| 1099 | raise self.readonly('mailbox status changed to READ-ONLY') |
| 1100 | |
| 1101 | tag = self._new_tag() |
| 1102 | name = bytes(name, self._encoding) |
| 1103 | data = tag + b' ' + name |
| 1104 | for arg in args: |
| 1105 | if arg is None: continue |
| 1106 | if isinstance(arg, str): |
| 1107 | arg = bytes(arg, self._encoding) |
| 1108 | if _control_chars.search(arg): |
| 1109 | raise ValueError("Control characters not allowed in commands") |
| 1110 | data = data + b' ' + arg |
| 1111 | |
| 1112 | literal = self.literal |
| 1113 | if literal is not None: |
| 1114 | self.literal = None |
| 1115 | if type(literal) is type(self._command): |
| 1116 | literator = literal |
| 1117 | else: |
| 1118 | literator = None |
| 1119 | if self.utf8_enabled: |
| 1120 | data = data + bytes(' UTF8 (~{%s}' % len(literal), self._encoding) |
| 1121 | literal = literal + b')' |
| 1122 | else: |
| 1123 | data = data + bytes(' {%s}' % len(literal), self._encoding) |
| 1124 | |
| 1125 | if __debug__: |
| 1126 | if self.debug >= 4: |
| 1127 | self._mesg('> %r' % data) |
| 1128 | else: |
| 1129 | self._log('> %r' % data) |
| 1130 | |
| 1131 | try: |
| 1132 | self.send(data + CRLF) |
| 1133 | except OSError as val: |
| 1134 | raise self.abort('socket error: %s' % val) |
| 1135 | |
| 1136 | if literal is None: |
| 1137 | return tag |
| 1138 | |
| 1139 | while 1: |
| 1140 | # Wait for continuation response |
| 1141 | |