/* From: Nand Mulchandani Newsgroups: comp.mail.mime Subject: Java program to convert Sun mailtool to Netscape mailbox format Date: Thu, 07 Aug 1997 14:49:48 -0700 Message-ID: <33EA42FC.EBE032F4@nospamoblix.com> */ import java.io.*; import java.util.*; /** * * Sun mailtool converter v1.0 * * by Nand Mulchandani, Oblix Inc. * * Sun mailtool uses Content-Length to figure out the * size of each mail message in a file. It also sometimes * forgets to convert the From lines within the body of * each message into >From. This causes mail programs like * Netscape mail don't get confused about messages and * messes up reading old mail files. * * This program takes the name of a Sun mailtool file, and * parses each mail message. For the body of each message, * it checks to see if there are any "unescaped" From lines, * which it correctly escapes. * * The cool bonus is that it actually goes and updates the * Content-Length field in the header once it is done, so that * if anybody uses that field, they will get a correct value. * * Note that this makes no attempt to convert any included * attachments to various other formats, etc. Use sun-to-mime * to do that. * * COMPILING AND RUNNING : * * Compile this with the javac compiler : * prompt% javac Main.java * * Run using the java interpreter : * prompt% java Main >& * * This program dumps everything out to stdout. * * NOTE : This code was tested on all my own mail files, that * seemed to convert over very nicely. No guarantees on how it * will do for you, and I don't intend to fix any bugs, etc. * on this code. */ class Main { public static void Convert(String filename) { File f; FileInputStream inputStream; DataInputStream dataStream; String curLine; try { f = new File(filename); inputStream = new FileInputStream(f); dataStream = new DataInputStream(inputStream); int len = -1; int eaten = 0; int newLength = 0; int numMessages = 0; boolean inHeader = true; int numFrom = 0; Vector headerVector = new Vector(); Vector bodyVector = new Vector(); while (true) { if (inHeader == true) { curLine = dataStream.readLine(); if (curLine == null) break; if (curLine.startsWith("From")) { if (numFrom == 0) { numMessages++; } /* * numFrom deals with having multiple From lines * in the header of a message. This is only for * keeping track of the number of messages. * Note that we don't really use numMessages anywhere, * I just put it there to validate if this was working * right or not. */ numFrom++; } else if (curLine.startsWith("Content-Length")) { StringTokenizer ss; ss = new StringTokenizer(curLine, ":"); ss.nextToken(); len = Integer.parseInt(ss.nextToken().trim()); eaten = 0; newLength = len; } else if (curLine.equals("")) { /* The header has now ended */ inHeader = false; numFrom = 0; } headerVector.addElement(curLine); } else { /* Just read and spit out the rest of this stuff */ if (len != -1 && eaten != len) { curLine = dataStream.readLine(); if (curLine == null) break; eaten += curLine.length() + 1; if (curLine.startsWith("From")) { curLine = ">" + curLine; newLength++; } bodyVector.addElement(curLine); } else { /* * Dump the message, checking to mutate * Content-Length if required. */ for (Enumeration e = headerVector.elements(); e.hasMoreElements(); ) { String sss = (String) e.nextElement(); if (sss.startsWith("Content-Length")) { if (newLength != len) System.out.println("Content-Length: " + newLength); else System.out.println(sss); } else { System.out.println(sss); } } /* Dump the body */ for (Enumeration e = bodyVector.elements(); e.hasMoreElements(); ) { String sss = (String) e.nextElement(); System.out.println(sss); } /* Get ready for the next message ! */ len = -1; inHeader = true; numFrom = 0; headerVector = new Vector(); bodyVector = new Vector(); } } } //System.out.println("Num Messages = " + numMessages); } catch (Exception e) { e.printStackTrace(); } } public static void main(String argv[]) { if (argv.length == 0) { System.err.println("Usage: java Main "); System.exit(1); } Convert(argv[0]); } } /* EOF */