ref: 3c748ebc11c8a7e8513efcdd61a38a56c8ccfb5a
parent: d78dd0557c8f854322470a86815ea3e0b5f441a4
author: Sigrid Solveig Haflínudóttir <sigrid@ftrv.se>
date: Thu Aug 10 13:28:33 EDT 2023
upas: "move" ctl verb to move messages between imap folders (thanks Risto Salminen)
--- a/sys/man/4/upasfs
+++ b/sys/man/4/upasfs
@@ -206,7 +206,7 @@
.I fs
to open, close, rename, create or remove new mailboxes,
and also to
-delete or flag groups of messages atomically.
+delete, flag, or move groups of messages atomically.
The messages that can be written to this file are:
.TP 2i
.PD 0
@@ -260,6 +260,13 @@
.TP
.B "flag \fImboxname flags number ...\fP
flag the given messages.
+.TP
+.B "move \fImboxname number ... target\fP
+Move the given messages from
+.IR mboxname
+to mailbox named
+.IR target.
+At the moment only supported with IMAP mailboxes.
.PD
.PP
The
--- a/sys/src/cmd/upas/fs/dat.h
+++ b/sys/src/cmd/upas/fs/dat.h
@@ -172,6 +172,7 @@
ulong waketime;
void (*close)(Mailbox*);
void (*decache)(Mailbox*, Message*);
+ char *(*move)(Mailbox*, Message*, char*);
int (*fetch)(Mailbox*, Message*, uvlong, ulong);
void (*delete)(Mailbox*, Message*);
char *(*ctl)(Mailbox*, int, char**);
@@ -215,6 +216,7 @@
void unnewmessage(Mailbox*, Message*, Message*);
char* delmessages(int, char**);
char *flagmessages(int, char**);
+char* movemessages(int, char**);
void digestmessage(Mailbox*, Message*);
int wraptls(int, char*);
--- a/sys/src/cmd/upas/fs/fs.c
+++ b/sys/src/cmd/upas/fs/fs.c
@@ -1242,6 +1242,11 @@
return nil;
return flagmessages(argc - 1, argv + 1);
}
+ if(strcmp(argv[0], "move") == 0){
+ if(argc < 4)
+ return nil;
+ return movemessages(argc - 1, argv + 1);
+ }
if(strcmp(argv[0], "remove") == 0){
v0 = argv0;
flags = 0;
--- a/sys/src/cmd/upas/fs/imap.c
+++ b/sys/src/cmd/upas/fs/imap.c
@@ -1023,7 +1023,29 @@
}
m->inmbox = 0;
}
+static char*
+imap4move(Mailbox *mb, Message *m, char *dest)
+{
+ char *r;
+ Imap *imap;
+ imap = mb->aux;
+ imap4cmd(imap, "uid copy %lud %s", (ulong)m->imapuid, dest);
+ r = imap4resp(imap);
+ if(!isokay(r))
+ return r;
+ imap4cmd(imap, "uid store %lud +flags (\\Deleted)", (ulong)m->imapuid);
+ r = imap4resp(imap);
+ if(!isokay(r))
+ return r;
+ imap4cmd(imap, "expunge");
+ r = imap4resp(imap);
+ if(!isokay(r))
+ return r;
+ m->inmbox = 0;
+ return 0;
+}
+
static char*
imap4sync(Mailbox *mb)
{
@@ -1183,6 +1205,7 @@
mb->delete = imap4delete;
mb->rename = imap4rename;
mb->modflags = imap4modflags;
+ mb->move = imap4move;
mb->addfrom = 1;
return nil;
}
--- a/sys/src/cmd/upas/fs/mbox.c
+++ b/sys/src/cmd/upas/fs/mbox.c
@@ -1137,6 +1137,37 @@
return rerr;
}
+char*
+movemessages(int argc, char **argv)
+{
+ char *err, *dest, *rerr;
+ int i, needwrite;
+ Mailbox *mb;
+ Message *m;
+
+ rerr = 0;
+ for(mb = mbl; mb != nil; mb = mb->next)
+ if(strcmp(*argv, mb->name) == 0)
+ break;
+ if(mb == nil)
+ return "no such mailbox";
+ if(mb->move == nil)
+ return "move not supported";
+ dest = argv[argc - 1];
+ needwrite = 0;
+ for(i = 1; i < argc - 1; i++)
+ for(m = mb->root->part; m; m = m->next)
+ if(strcmp(m->name, argv[i]) == 0){
+ if(err = mb->move(mb, m, dest))
+ rerr = err;
+ else
+ needwrite = 1;
+ }
+ if(needwrite)
+ syncmbox(mb, 1);
+ return rerr;
+}
+
void
msgincref(Mailbox *mb, Message *m)
{
--- a/sys/src/cmd/upas/fs/mdir.c
+++ b/sys/src/cmd/upas/fs/mdir.c
@@ -294,5 +294,6 @@
mb->idxread = idxr;
mb->idxwrite = idxw;
mb->ctl = mdirctl;
+ mb->move = nil;
return nil;
}
--- a/sys/src/cmd/upas/fs/plan9.c
+++ b/sys/src/cmd/upas/fs/plan9.c
@@ -414,5 +414,6 @@
mb->remove = localremove;
mb->rename = localrename;
mb->decache = plan9decache;
+ mb->move = nil;
return nil;
}
--- a/sys/src/cmd/upas/fs/pop3.c
+++ b/sys/src/cmd/upas/fs/pop3.c
@@ -624,6 +624,7 @@
mb->sync = pop3sync;
mb->close = pop3close;
mb->ctl = pop3ctl;
+ mb->move = nil;
mb->addfrom = 1;
return nil;
}