jcunews

eml2mbx.js

Mar 2nd, 2019
120
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. /*
  2. EML2MBOX, 2019-03-03, AGPL v3
  3. https://www.reddit.com/user/jcunews1/
  4.  
  5. This script will convert one or more EML email files and combine them into a MBOX/MBX/MBS mailbox file.
  6.  
  7. Requirements:
  8.   Windows  : Windows 95/NT4.
  9.   Linux/Mac: WINE with Windows Script Host installed.
  10.  
  11. Usage:
  12.   eml2mbx.js {target file} {source files...}
  13. Or:
  14.   cscript eml2mbx.js {target file} {source files...}
  15.  
  16. Examples:
  17.   cscript eml2mbx.js messages.mbox *.eml
  18.   eml2mbx.js messages.mbs "msg files\*.eml" temp\2019*.eml
  19. */
  20.  
  21.  
  22.  
  23. //UI-independent boolean prompt
  24. function confirm(msg) {
  25.   if (WScript.fullname.charAt(WScript.fullname.lastIndexOf("\\") + 1).toUpperCase() === "C") {
  26.     WScript.stdout.write(msg);
  27.     return WScript.stdin.readline().toUpperCase() === "Y";
  28.   } else return (new ActiveXObject("wscript.shell")).popup(msg, 0, "EML2MBX", 36) === 6;
  29. }
  30.  
  31. //UI-independent text display
  32. function output(s, title, type) {
  33.   if (WScript.fullname.charAt(WScript.fullname.lastIndexOf("\\") + 1) === "C") {
  34.     WScript.stdout.write(s);
  35.   } else (new ActiveXObject("wscript.shell")).popup(s, 0, title, type || 64);
  36. }
  37.  
  38. function out(s, type) {
  39.   output(s, "EML2MBX", type);
  40. }
  41.  
  42. function help() {
  43.   out("Usage: eml2mbx {target file} {source files...}");
  44.   WScript.quit(1);
  45. }
  46.  
  47. //split specified file path and returns the directory and file name in an array
  48. function splitPath(s) {
  49.   var b, i;
  50.   if (s.charAt(1) === ":") {
  51.     b = s.slice(0, 3);
  52.     s = s.slice(3);
  53.   } else if (s.slice(0, 2) === "\\\\") { //absolute remote path
  54.     b = "\\\\";
  55.     s = s.slice(2);
  56.   } else b = "";
  57.   if (s.charAt(s.length - 1) === "\\") s = s.slice(0, s.length - 1);
  58.   if ((i = s.lastIndexOf("\\")) >= 0) {
  59.     return [b + s.slice(0, i + 1), s.slice(i + 1)];
  60.   } else return [b + ".\\", s];
  61. }
  62.  
  63. //compare specified file name against a file mask
  64. function matchMask(s, mask) {
  65.   return (new RegExp("^" + mask.replace(/./g, function(a) {
  66.     switch (a) {
  67.       case "$":
  68.       case "(":
  69.       case "+":
  70.       case ".":
  71.       case "[":
  72.       case "\\":
  73.       case "^":
  74.       case "{":
  75.       case "|":
  76.         return "\\" + a;
  77.       case "*":
  78.         return ".*?";
  79.       case "?":
  80.         return ".";
  81.       default:
  82.         return a;
  83.     }
  84.   }) + "$", "i")).test(s);
  85. }
  86.  
  87. dt = null;
  88. em = "";
  89.  
  90. function checkfield(s) {
  91.   var i, m, d;
  92.   s = s.replace(/\r?\n/g, " ").replace(/^\s+|\s+$/, "");;
  93.   if ((s.slice(0, 9) === "Received:")) {
  94.     i = s.lastIndexOf(";");
  95.     if (i < 0) return;
  96.     s = s.slice(i + 1).replace(/^\s+/, "");
  97.     if (!s) return;
  98.     d = new Date(s);
  99.     if (!isNaN(d.getTime())) dt = d;
  100.   } else if ((m = s.match(/^From:\s+(.*<([^>]+)|.*)/)) && !em) {
  101.     em = m[2] || m[1];
  102.   }
  103. }
  104.  
  105. fs = new ActiveXObject("scripting.filesystemobject");
  106. tfp = WScript.arguments(0);
  107. sfs = [];
  108. for (i = 1; i < WScript.arguments.length; i++) {
  109.   fn = (pt = splitPath(WScript.arguments(i)))[1];
  110.   pt = pt[0];
  111.   try {
  112.     dr = fs.getfolder(pt);
  113.     pt = dr.path;
  114.     if (pt.charAt(pt.length - 1) !== "\\") pt += "\\";
  115.   } catch(z) {
  116.     out("Path is inaccessible: " + pt, 16);
  117.     WScript.quit(2);
  118.   }
  119.   sfs.push([pt, fn]);
  120. }
  121. if (!sfs.length || !tfp) help();
  122. if (fs.fileexists(tfp) && !confirm("Target file is already exists.\nDo you want to overwrite it?")) WScript.quit(3);
  123. try {
  124.   tf = fs.createtextfile(tfp, true, false);
  125. } catch(z) {
  126.   out("Can not overwrite target file.", 16);
  127.   WScript.quit(3);
  128. }
  129. cnt = 0;
  130. for (i = 0; i < sfs.length; i++) {
  131.   ls = new Enumerator(fs.getfolder(sfs[i][0]).files);
  132.   for (; !ls.atEnd(); ls.moveNext()) {
  133.     if (!matchMask(ls.item().name, sfs[i][1])) continue;
  134.     try {
  135.       sf = fs.opentextfile(ls.item().path, 1, false, 0);
  136.     } catch(z) {
  137.     }
  138.     buf = "";
  139.     hdr = "";
  140.     dt = null;
  141.     em = "";
  142.     while (!sf.atendofstream) {
  143.       s = sf.readline();
  144.       if (s.charAt(0) !== " ") {
  145.         hdr = s + "\r\n";
  146.       } else hdr += s + "\r\n";
  147.       checkfield(hdr);
  148.       buf += s + "\r\n";
  149.     }
  150.     if (dt && em) {
  151.       if (WScript.fullname.charAt(WScript.fullname.lastIndexOf("\\") + 1).toUpperCase() === "C") out(em + " " + dt.toDateString() + " " + dt.toTimeString().replace(/UTC/, ""));
  152.       tf.writeline("From " + em + " " + dt.toDateString() + " " + dt.toTimeString().replace(/UTC/, "") + "\r\n" + buf);
  153.     } else {
  154.       if (!dt) {
  155.         if (!em) {
  156.           out("Missing received date and sender's email address in file: " + ls.item().path, 16);
  157.         } else out("Missing received date in file: " + ls.item().path, 16);
  158.       } else out("Missing sender's email address in file: " + ls.item().path, 16);
  159.       WScript.quit(4);
  160.     }
  161.     sf.close();
  162.     cnt++;
  163.   }
  164. }
  165. out("\nProcessed " + cnt + " messages.");
RAW Paste Data