/* * Concordance Programming Language * * E-mail processing script to load, parse, and delete source files. * * Dataflight Software, Inc. * 2337 Roscomare Road, Suite 11 * Los Angeles, CA 90077 * * * */ int isWindows = 1; int DOCBIT = 65536; main() { int fh, db, bt, i, rc, length; text szText; char string[256]; /* Isolate the existing documents, we'll process only the new mail. */ if (ver() < 7.0) search(db, "0"); else search(db, "0", SEARCHDATABASE); /* Find and import every e-mail in the directory. */ rc = 0; for(string = findfirst("c:\temp\e-mail.*",0); string[0]; string = findnext()) { Message("Importing "+string,FALSE); i = import(db->MAIL,szText = "c:\temp\"+string,"",0,0,"B",0, 8000000); rc = rc + 1; } if (rc == 0) messageBox("I didn't find any e-mails in C:\Temp to process.", program(), MB_ICONEXCLAMATION | MB_OK); else { /* Erase the e-mails, we've loaded them. */ for(string = findfirst("c:\temp\e-mail.*",0); string[0]; string = findnext()) { Message("Erasing "+string,FALSE); erase("c:\temp\"+string); } /* Now use search to isolate the new documents from the pre-existing documents. */ if (ver() < 7) search(db, "0 not "+str(db.query)); else search(db, "0 not "+str(db.query), SEARCHDATABASE); /* Loop through the new e-mails and parse the data, copy the TO, FROM date to their fields. */ cycle(db) { Message("Processing "+str(docno(db))+" of "+str(count(db)),FALSE); MAIL = trim(MAIL); /* Copy the date out to a temporary field, we need to parse it. */ copyToField(db, isfield(db,"DATETIME"), isfield(db,"MAIL"), "DATE:", 0); copyToField(db, isfield(db,"MESSAGEID"), isfield(db,"MAIL"), "MESSAGE-ID:", 0); /* Convert the date from text to numeric. */ db->DATE = fixDate(DATETIME); /* Copy the rest of the e-mail information. */ copyToField(db, isfield(db,"FROM"), isfield(db,"MAIL"), "FROM:", ','); /* If mail is from me, mark as "SELF" */ /* if (trim(upper(db->FROM)) == "SELF ") db->FROM = "Jeff Lipsman "; */ copyToField(db, isfield(db,"CC"), isfield(db,"MAIL"), "CC:", ','); copyToField(db, isfield(db,"BCC"), isfield(db,"MAIL"), "BCC:", ','); copyToField(db, isfield(db,"TO"), isfield(db,"MAIL"), "TO:", ','); /* If mail is to me, mark as "SELF" */ /* if (trim(upper(db->TO)) == "SELF ") db->TO = "Jeff Lipsman "; */ copyToField(db, isfield(db,"SUBJECT"), isfield(db,"MAIL"), "SUBJECT:", 0); copyToField(db, isfield(db,"ORG"), isfield(db,"MAIL"), "ORGANIZATION:", 0); /* Remove any uuencoded garbage. */ if (rc = match(MAIL, string = "begin 660 ", 1)) { if (rc = findnline(MAIL, rc, i)) MAIL = trim(substr(MAIL, 1, rc)); } if (rc = match(MAIL, string = "begin 644 ", 1)) { if (rc = findnline(MAIL, rc, i)) MAIL = trim(substr(MAIL, 1, rc)); } if (rc = match(MAIL, string = "begin 600 ", 1)) { if (rc = findnline(MAIL, rc, i)) MAIL = trim(substr(MAIL, 1, rc)); } if (rc = match(MAIL, string = "Content-transfer-encoding: base64", 1)) { if (rc = findnline(MAIL, rc, i)) MAIL = trim(substr(MAIL, 1, rc)); } if (rc = match(MAIL, string = "Content-Type: application/",1)) { if (rc = findnline(MAIL, rc, i)) MAIL = trim(substr(MAIL, 1, rc)); } } } /* Finished, leave the user on the first record. */ first(db); unlockdoc(db); user("Windows", "Table"); } /* main() */ /**************************************************************** * Name: copyToField * * Synopsis: Locates e-mail header fields and parses them. * ****************************************************************/ copyToField(int db; int to; int from; text pszMatch; int delimiter) { int i, l, rc, length, limit; if ((from <> 0) and (to <> 0)) { l = len(pszMatch); rc = 0; /* The headers are separated from the e-mail by a blank line. */ /* Do not look beyond this line, or you will pick up bad data. */ limit = match(db->from, newline()+newline(), 1); while (rc = match(upper(db->from), pszMatch, rc + 1)) { /* Only pick the entry if it starts the line. This will ignore ** embedded references to TO:, FROM:, etc. It should also ignore ** quoted threads included in this e-mail. It will not ignore ** unquoted threads, which will cause errors, but there is no ** perfect way around this via a file parser. */ i = findline(db->from, rc, length); if (rc == i) break; } /* Now copy the data. */ if ((rc > 0) and (rc < limit)) { db->to = trim(substr(db->from, rc + l, length - (rc - i) - l)); /* If the entry, i.e. FROM:, ends with a comma, then the */ /* list of entries is continued on the next line. Grab it. */ if (delimiter) { rc = rc + l; while (asc(addr(db->to, len(db->to))) == delimiter) { if (rc = findnline(db->from, rc, length)) db->to = db->to + " " + trim(substr(db->from, rc, length)); else break; } } } } } /* copyToField() */ /**************************************************************** * Name: fixDate * * Synopsis: Converts a text date to numeric date. * ****************************************************************/ fixDate(text pszDate) { char string[200]; int i, year, day, month; /* Tue, 13 Jan 1998 12:54:53 +0000 */ string = pszDate; i = 0; while((string[i] <> 0) and (isdigit(string[i]) == FALSE)) i = i + 1; day = num(addr(string,i+1)); while((string[i] <> 0) and (isalpha(string[i]) == FALSE)) i = i + 1; switch(upper(substr(addr(string,i+1),1,3))) { case "JAN": month = 1; break; case "FEB": month = 2; break; case "MAR": month = 3; break; case "APR": month = 4; break; case "MAY": month = 5; break; case "JUN": month = 6; break; case "JUL": month = 7; break; case "AUG": month = 8; break; case "SEP": month = 9; break; case "OCT": month = 10; break; case "NOV": month = 11; break; case "DEC": month = 12; break; } while((string[i] <> 0) and (isdigit(string[i]) == FALSE)) i = i + 1; year = num(addr(string,i+1)); return(ctod(str(month)+"/"+str(day)+"/"+str(year))); } /* fixDate() */ RGB(char red, grn, blu) { return(((blu & 255) * 65536) | ((grn & 255) * 256) | (red & 255)); } /**************************************************************** * Name: Message * * Synopsis: Displays error message and waits for key. * ****************************************************************/ Message(text message; int wait) { text screen; int key; int fg, bk, tr, tc; tr = 8; tc = 13; bk = RGB(255,0,255); fg = isWindows ? RGB(160,0,160) : MenuColor_; cursoroff(); if (wait) screen = save(tr, tc, tr + 3, tc + 56); box(tr , tc , tr + 2, tc + 54,"3U", fg, bk); puts(tr + 1,tc + 1,pad(message,'C',53), isWindows ? RGB(255,255,255) : fg,bk); if (wait) { while(keypress()) getkey(); key = getkey(); restore(tr,tc,screen); } return(asc(upper(chr(key)))); } /* Message() */ /**************************************************************** * Global Variable Declarations and Initialization * ****************************************************************/ /* findfirst() file attributes. */ int A_NORMAL = 00; /* Normal file - No read/write restrictions */ int A_RDONLY = 01; /* Read only file */ int A_HIDDEN = 02; /* Hidden file */ int A_SYSTEM = 04; /* System file */ int A_VOLID = 08; /* Volume ID file */ int A_SUBDIR = 16; /* Subdirectory */ int A_ARCH = 32; /* Archive file */ /* edit() mode attributes. A // Alpha only mode. U // Upper case conversion. N // Numeric only mode. Y // Y mode for dates. M // M mode for dates. D // D mode for dates. C // Cut and paste mode. S // Scroll field left and right, no wordwrapping. E // Return on [Enter], no CR in data. T // Always edit from the top. B // Always edit from the bottom. @ // Display only this field. ! // Return when this field is entered, don't edit. N:99.99 */ int CTRLPGUP = 33792, F11 = 34048, F12 = 34304, EOF = -1; short LEFT = 19200, RIGHT = 19712, UP = 18432, DOWN = 20480, HOME = 18176, END = 20224, PGUP = 18688, PGDN = 20736, CTRLPGDN = 30208, F1 = 15104, F2 = 15360, F3 = 15616, F4 = 15872, F5 = 16128, F6 = 16384, F7 = 16640, F8 = 16896, F9 = 17152, F10 = 17408; char ESC = 27, CTRLP = 16, FALSE = 0, TRUE = 1, TAB = 9, CR = 13, LF = 10, FF = 12; /* Standard dialog button return values. */ int IDOK = 1; int IDCANCEL = 2; int IDABORT = 3; int IDRETRY = 4; int IDIGNORE = 5; int IDYES = 6; int IDNO = 7; /* MessageBox() display options. */ int MB_OK = 0; int MB_OKCANCEL = 1; int MB_ABORTRETRYIGNORE = 2; int MB_YESNOCANCEL = 3; int MB_YESNO = 4; int MB_RETRYCANCEL = 5; int MB_ICONHAND = 16; int MB_ICONQUESTION = 32; int MB_ICONEXCLAMATION = 48; int MB_ICONASTERISK = 64; int MB_ICONINFORMATION = MB_ICONASTERISK; int MB_ICONSTOP = MB_ICONHAND; int MB_DEFBUTTON1 = 0; int MB_DEFBUTTON2 = 256; int MB_DEFBUTTON3 = 512; int MB_APPLMODAL = 0; int MB_SYSTEMMODAL = 4096; int MB_TASKMODAL = 8192; int MB_NOFOCUS = 32768; /**********************************************************/ /* The first byte of every entry in the database.TRK file */ /* indicates the type of log entry and the type of event. */ /**********************************************************/ int LOGDELETION = 'D'; int LOGDELETION_OLD = 1 ; int LOGFIELDEDITED = 2 ; int LOGTAGADDED = 4 ; int LOGTAGDELETED = 8 ; int LOGEVENTSDELETED = 'P'; int LOGREINDEX = 'R'; int LOGSECURITYDELETION = 'S'; /********************************************************/ /* Definitions for the shellExecute() command. */ /********************************************************/ int SW_HIDE = 0; int SW_MINIMIZE = 6; int SW_RESTORE = 9; int SW_SHOW = 5; int SW_SHOWMAXIMIZED = 3; int SW_SHOWMINIMIZED = 2; int SW_SHOWMINNOACTIVE = 7; int SW_SHOWNA = 8; int SW_SHOWNOACTIVATE = 4; int SW_SHOWNORMAL = 1; /********************************************************/ /* Definitions for the search() command's flag param V7.*/ /********************************************************/ int SEARCHDATABASE = 4; int SEARCHNOTES = 8; int SEARCHALL = 4|8;