- }
-
- public boolean handleRequest() throws IOException {
- pw.println("* OK " + vhost + " " + IMAP.class.getName() + " IMAP4 v0.1 server ready");
- System.err.println("* OK " + vhost + " " + IMAP.class.getName() + " IMAP4 v0.1 server ready");
- pw.flush();
- while(true) {
- String tag = null;
- try {
- boolean uid = false;
- tag = null;
- // FIXME better error if atom() fails
- tag = atom();
- String command = atom();
- if (command.equalsIgnoreCase("UID")) { uid = true; command = atom(); }
- if (command.equalsIgnoreCase("AUTHENTICATE")) { login(astring(), astring()); }
- else if (command.equalsIgnoreCase("LIST")) list(mailbox(), mailboxPattern());
- else if (command.equalsIgnoreCase("LSUB")) lsub(mailbox(), mailboxPattern());
- else if (command.equalsIgnoreCase("SUBSCRIBE")) { /* FIXME */ }
- else if (command.equalsIgnoreCase("UNSUBSCRIBE")) { /* FIXME */ }
- else if (command.equalsIgnoreCase("CAPABILITY")) { capability(); }
- else if (command.equalsIgnoreCase("LOGIN")) login(astring(), astring());
- else if (command.equalsIgnoreCase("LOGOUT")) { logout(); conn.close(); return false; }
- else if (command.equalsIgnoreCase("RENAME")) rename(mailbox(), atom());
- else if (command.equalsIgnoreCase("APPEND")) append(mailbox(), token());
- else if (command.equalsIgnoreCase("EXAMINE")) select(astring(), true);
- else if (command.equalsIgnoreCase("SELECT")) select(astring(), false);
- else if (command.equalsIgnoreCase("COPY")) copy(Query.num(set()), mailbox());
- else if (command.equalsIgnoreCase("DELETE")) delete(mailbox());
- else if (command.equalsIgnoreCase("CHECK")) check();
- else if (command.equalsIgnoreCase("NOOP")) noop();
- else if (command.equalsIgnoreCase("CREATE")) create(astring());
- else if (command.equalsIgnoreCase("STORE")) store(Query.num(set()), atom(), l());
- else if (command.equalsIgnoreCase("FETCH")) fetch(uid ? Query.uid(set()) : Query.num(set()),
- parseFetchRequest(l()), uid);
- else if (command.equalsIgnoreCase("STATUS")) status(mailbox(), l());
- else throw new Exn.Bad("unrecognized command \"" + command + "\"");
- pw.println(tag + " OK uid " + command + " Completed.");
- System.err.println(tag + " OK uid " + command + " Completed.");
- } catch (Exn.Bad b) { pw.println(tag + " Bad " + b.toString()); System.err.println(tag + " Bad " + b.toString()); b.printStackTrace();
- } catch (Exn.No n) { pw.println(tag + " OK " + n.toString()); System.err.println(tag + " OK " + n.toString());
+ if (t.length == 0 && (t[0].type == Parser.Token.QUOTED || t[0].type == Parser.Token.ATOM)) {
+ if (t[0].astring().equalsIgnoreCase("ALL"))
+ t = new Parser.Token[] { parser.token("FLAGS"), parser.token("INTERNALDATE"),
+ parser.token("ENVELOPE"), parser.token("RFC822.SIZE") };
+ else if (t[0].astring().equalsIgnoreCase("FULL"))
+ t = new Parser.Token[] { parser.token("FLAGS"), parser.token("INTERNALDATE"), parser.token("BODY"),
+ parser.token("ENVELOPE"), parser.token("RFC822.SIZE") };
+ else if (t[0].astring().equalsIgnoreCase("FAST"))
+ t = new Parser.Token[] { parser.token("FLAGS"), parser.token("INTERNALDATE"),
+ parser.token("RFC822.SIZE") };
+ }
+ for(int i=0; i<t.length; i++) {
+ if (r.length() > initlen) r.append(" ");
+ if (t[i] == null || t[i].s == null) continue;
+ String s = t[i].s.toUpperCase();
+ r.append(s.equalsIgnoreCase("BODY.PEEK")?"BODY":s);
+ if (s.equals("BODYSTRUCTURE")) { spec|=BODYSTRUCTURE;if(e){r.append(" ");r.append(Printer.bodystructure(m));}
+ } else if (s.equals("ENVELOPE")) { spec|=ENVELOPE; if(e){r.append(" ");r.append(Printer.envelope(m));}
+ } else if (s.equals("FLAGS")) { spec|=FLAGS; if(e){r.append(" ");r.append(Printer.flags(flags));}
+ } else if (s.equals("INTERNALDATE")) { spec|=INTERNALDATE; if(e){r.append(" ");r.append(Printer.date(m.arrival));}
+ } else if (s.equals("RFC822")) { spec|=RFC822; if(e){r.append(" ");r.append(Printer.message(m));}
+ } else if (s.equals("RFC822.TEXT")) { spec|=RFC822TEXT; if(e){r.append(" ");r.append(Printer.qq(getBodyString(m)));}
+ } else if (s.equals("RFC822.HEADER")){ spec|=HEADER;if(e){r.append(" ");r.append(Printer.qq(m.headers.getString()+"\r\n"));}
+ } else if (s.equals("RFC822.SIZE")) { spec|=RFC822SIZE; if(e){r.append(" ");r.append(m.getLength());}
+ } else if (s.equals("UID")) { spec|=UID; if(e){r.append(" ");r.append(muid); }
+ } else if (!(s.equals("BODY.PEEK") || s.equals("BODY"))) { throw new Server.No("unknown fetch argument: " + s);
+ } else {
+ if (s.equalsIgnoreCase("BODY.PEEK")) spec |= PEEK;
+ //else if (e) api.addFlags(Query.imapNumber(new int[] { num, num }), Mailbox.Flag.SEEN, false, false);
+ if (i >= t.length - 1 || t[i+1].type != Parser.Token.LIST) {
+ spec |= BODYSTRUCTURE;
+ if (e) { r.append(" "); r.append(Printer.bodystructure(m)); } continue;
+ //{ if (e) { r.append(" "); r.append(Printer.qq(m.body)); } continue; }
+ }
+ String payload = "";
+ r.append("[");
+ Parser.Token[] list = t[++i].l();
+ s = list.length == 0 ? "" : list[0].s.toUpperCase();
+ r.append(s);
+ if (list.length == 0) { spec |= RFC822TEXT; if(e) payload = m.headers.getString()+"\r\n"+getBodyString(m); }
+ else if (s.equals("") || s.equals("1")) { spec |= RFC822TEXT; if(e) payload = m.headers.getString()+"\r\n"+getBodyString(m); }
+ else if (s.equals("TEXT")) { spec |= RFC822TEXT; if(e) payload = getBodyString(m); }
+ else if (s.equals("HEADER")) { spec |= HEADER; if(e) payload = m.headers.getString()+"\r\n"; }
+ else if (s.equals("HEADER.FIELDS")) { spec |= FIELDS; payload=headers(r,t[i].l()[1].sl(),false,m,e); }
+ else if (s.equals("HEADER.FIELDS.NOT")) { spec |= FIELDSNOT; payload=headers(r,t[i].l()[1].sl(),true,m,e); }
+ else if (s.equals("MIME")) { throw new Server.Bad("MIME not supported"); }
+ else throw new Server.Bad("unknown section type " + s);
+ if (i<t.length - 1 && (t[i+1].s != null && t[i+1].s.startsWith("<"))) {
+ i++;
+ s = t[i].s.substring(1, t[i].s.indexOf('>'));
+ int dot = s.indexOf('.');
+ start = dot == -1 ? Integer.parseInt(s) : Integer.parseInt(s.substring(0, s.indexOf('.')));
+ end = dot == -1 ? -1 : Integer.parseInt(s.substring(s.indexOf('.') + 1));
+ if (e) { payload = payload.substring(start, Math.min(end+1,payload.length())); r.append("<"+start+">"); }
+ }
+ if (e) { r.append("] "); r.append(Printer.qq(payload)); }