// Add a new message to a mailbox func cmdAppend(args commandArgs, c *Conn) { if !c.assertAuthenticated(args.ID()) { return } mailboxName := args.Arg(appendArgMailbox) mailbox, err := c.User.MailboxByName(mailboxName) if err != nil { c.writeResponse(args.ID(), "NO could not get mailbox") return } length, err := strconv.ParseUint(args.Arg(appendArgLength), 10, 64) if err != nil || length == 0 { c.writeResponse(args.ID(), "BAD invalid length for message literal") return } flagString := args.Arg(appendArgFlags) flags := types.Flags(0) if flagString != "" { flags = types.FlagsFromString(flagString) } // Tell client to send the mail message c.writeResponse("+", "go ahead, feed me your message") // Read in the whole message messageData, err := c.ReadFixedLength(int(length)) if err != nil { return } msg := mailbox.NewMessage() rawMsg, err := types.MessageFromBytes(messageData) if err != nil { c.writeResponse(args.ID(), "NO "+err.Error()) return } msg = msg.SetHeaders(rawMsg.Headers) msg = msg.SetBody(rawMsg.Body) msg = msg.OverwriteFlags(flags) msg, err = msg.Save() if err != nil { c.writeResponse(args.ID(), "NO "+err.Error()) return } c.writeResponse(args.ID(), "OK APPEND completed") }
func cmdStoreFlags(args commandArgs, c *Conn) { if !c.assertSelected(args.ID(), ReadWrite) { return } operation := args.Arg(storeArgOperation) flags := args.Arg(storeArgFlags) uid := strings.ToUpper(args.Arg(storeArgUID)) == "UID " seqSetStr := args.Arg(storeArgRange) silent := false if args.Arg(storeArgSilent) == ".SILENT" { silent = true } var msgs []mailstore.Message seqSet, err := types.InterpretSequenceSet(seqSetStr) if err != nil { c.writeResponse(args.ID(), "NO "+err.Error()) return } if uid { msgs = c.SelectedMailbox.MessageSetByUID(seqSet) } else { msgs = c.SelectedMailbox.MessageSetBySequenceNumber(seqSet) } flagField := types.FlagsFromString(flags) for _, msg := range msgs { if operation == "+" { msg = msg.AddFlags(flagField) } else if operation == "-" { msg = msg.RemoveFlags(flagField) } else { msg = msg.OverwriteFlags(flagField) } msg.Save() if err != nil { c.writeResponse(args.ID(), "NO "+err.Error()) return } // Auto-fetch for the client if !silent { newFlags, err := fetch("FLAGS", c, msg) if err != nil { c.writeResponse(args.ID(), "NO "+err.Error()) return } fetchResponse := fmt.Sprintf("%d FETCH (%s)", msg.SequenceNumber(), newFlags, ) c.writeResponse("", fetchResponse) } } c.writeResponse(args.ID(), "OK STORE Completed") }