home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
OS/2 Shareware BBS: 5 Edit
/
05-Edit.zip
/
emacmail.zip
/
movemail.c
next >
Wrap
Text File
|
1993-08-07
|
10KB
|
374 lines
/* movemail.c -- Convert all the mail messages in files listed in
* argv[1] into a single file argv[02] so that the EMACS rmail
* command can find & process it.
*
* Return Code is ...
* 0 - Some sort of error, look at stderr for the meaning.
* 255 - Everything okay.
*
* Stuart Wilson
* stuartw@pec.co.nz
* July 1992.
*
* Copyright (C) 1992, 1993 Stuart Wilson.
*
* movemail.c is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 1, or (at your option)
* any later version.
*
* movemail.c is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with GNU Emacs; see the file COPYING. If not, write to
* the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
*
*
*
* Fixes & Adulterations:
* ~~~~~~~~~~~~~~~~~~~~~~
*
* Make it change dir to the mail spool directory on the correct disk.
*
* Paul Andrew
* paula@pec.co.nz
* October 1992.
*
*
* Tidied up the way it decides what directory to change to. Now it
* looks at argv[1] to decide, rather than use a constant.
*
* Problems parsing the index file. Sometimes there is a from person
* and from machine.
*
* Write the resulting mail file better, so that Emacs rmail code can
* actually find the mail messages. The result file is written in the
* babyl format that Emacs uses as it's internal format.
*
* Stuart Wilson
* stuartw@pec.co.nz
* April 1993.
*/
#include <stdio.h>
#include <ctype.h>
#define INCL_NOPMAPI
#include <os2.h> /* pja92oct13 */
/* A few states for the Index file parsing state machine */
#define SKIP_SPACE_1 0
#define SKIP_FROM_USER 1
#define SKIP_SPACE_2 2
#define SKIP_FROM_MACHINE 3
#define SKIP_SPACE_3 4
#define GET_NOTE_NAME 5
#define SKIP_SPACE_4 6
#define GET_NOTE_EXTN 7
#define DONE_NOTE 8
#define NO_FILE 9
FILE *resultf;
main (argc, argv)
int argc;
char *argv[];
{
char notename[64], indexline[1024];
FILE *indexf, *notef;
int index_state;
char *p, *q;
ULONG disk ;
/* Check the number of command line arguments */
if(argc != 3) {
fprintf(stderr, "movemail:This program should only be called by the emacs rmail command\n");
exit(0);
}
/* change to the appropriate drive before doing a change dir */
disk = ((char)((char *)argv[1])[0]) - 'a' ;
DosSetDefaultDisk (disk+1) ;
/* Go grovelling backwards through the name of the index file, to get
* the name of the incomming mail spool directory. We need to change
* to it.
*/
for(p = &argv[1][strlen(argv[1])-1] ;
p != argv[1] && *p != '/' && *p != '\\' ;
p--);
if(p == argv[1]) {
fprintf(stderr, "Can't find directory in \"%s\"\n", argv[1]);
exit(0);
}
/* Terminate argv[1] at the end of the directory, change
* to that directory and put the final directory delimiter back so
* we can open the index file
*/
*p='\000';
if (chdir(argv[1]) == -1) {
fprintf(stderr, "Can't change to mail directory \"%s\"\n", argv[1]);
exit(0);
}
*p = '\\';
/* Open the result file for writing */
resultf=fopen(argv[2], "w");
if (resultf == NULL) {
fprintf(stderr, "Can't open EMACS infile file \"%s\"\n", argv[2]);
exit(0);
}
/* Open the index file for reading */
indexf=fopen(argv[1], "r");
if (indexf == NULL) {
exit(0);
}
/* Read in the index file a line at a time, find the name of the note,
* and process it
*/
while (fgets(indexline, sizeof(indexline), indexf) != NULL) {
/* First attempt at finding the note file name, assume that there is
* a user and machine name in the index entry. we'll have to skip past
* them.
*/
p=indexline;
index_state = SKIP_SPACE_1;
while((index_state != DONE_NOTE) &&
(index_state != NO_FILE)) {
switch(index_state) {
case SKIP_SPACE_1:
if (! isspace(*p++))
index_state = SKIP_FROM_USER;
break;
case SKIP_FROM_USER:
if (isspace(*p++))
index_state = SKIP_SPACE_2;
break;
case SKIP_SPACE_2:
if (! isspace(*p++))
index_state = SKIP_FROM_MACHINE;
break;
case SKIP_FROM_MACHINE:
if (isspace(*p++))
index_state = SKIP_SPACE_3;
break;
case SKIP_SPACE_3:
if (! isspace(*p)) {
index_state = GET_NOTE_NAME;
q = notename;
*q++ = *p++;
}
else p++;
break;
case GET_NOTE_NAME:
if (! isspace(*p)) {
*q++ = *p++;
}
else {
*q++ = '.';
index_state = SKIP_SPACE_4;
p++;
}
break;
case SKIP_SPACE_4:
if (! isspace(*p)) {
index_state = GET_NOTE_EXTN;
*q++ = *p++;
}
break;
case GET_NOTE_EXTN:
if(! isspace(*p)) {
*q++ = *p++;
}
else {
/* We've got all the name of the next, note...
* terminate the string, and process the note.
*/
*q = '\0';
notef=fopen(notename, "r");
if(notef != NULL) {
process_note(notef);
fclose(notef);
unlink(notename);
index_state = DONE_NOTE;
}
else index_state = NO_FILE;
}
break;
}
}
if(index_state == DONE_NOTE)
continue;
/* Second attempt at finding the file name. Assume there is no user
* or machine name before the note name in the index entry.
*/
p=indexline;
index_state = SKIP_SPACE_3;
while((index_state != DONE_NOTE) &&
(index_state != NO_FILE)) {
switch(index_state) {
case SKIP_SPACE_3:
if (! isspace(*p)) {
index_state = GET_NOTE_NAME;
q = notename;
*q++ = *p++;
}
else p++;
break;
case GET_NOTE_NAME:
if (! isspace(*p)) {
*q++ = *p++;
}
else {
*q++ = '.';
index_state = SKIP_SPACE_4;
p++;
}
break;
case SKIP_SPACE_4:
if (! isspace(*p)) {
index_state = GET_NOTE_EXTN;
*q++ = *p++;
}
break;
case GET_NOTE_EXTN:
if(! isspace(*p)) {
*q++ = *p++;
}
else {
/* We've got all the name of the next, note...
* terminate the string, and process the note.
*/
*q = '\0';
notef=fopen(notename, "r");
if(notef != NULL) {
process_note(notef);
fclose(notef);
unlink(notename);
index_state = DONE_NOTE;
}
else index_state = NO_FILE;
}
break;
}
}
if(index_state == DONE_NOTE)
continue;
/* Any other attempts ?? */
}
/* Now remove the index file */
fclose(indexf);
unlink(argv[1]);
/* everything is Okay */
exit(255);
}
/* Return true if the line in the buffer starts with "From "
*/
int fromline(buff)
char *buff;
{
return(((buff[0]=='F') &&
(buff[1]=='r') &&
(buff[2]=='o') &&
(buff[3]=='m') &&
(buff[4]==' ')) ? 1 : 0) ;
}
/* Return true if the line in the buffer has the following regexp
* ^[A-Z][a-z-]*:
*/
int header_line(buff)
char *buff;
{
char *p;
p=buff;
if(! isupper(*p))
return(0);
p++;
/* skip to the next character non lower-case and non '-' */
while((islower(*p) || (*p == '-')))
p++;
/* It's a header line of some sort */
if(*p == ':')
return(1);
/* failed */
return(0);
}
/* Copy the contents of the note with name NOTE into the result file...
* a few little items to think about....
*
* We'll unconfuse the Emacs rmail code by chucking out the "From " line
* from the headers as well as any MMDF delimiters.
*
* Things will be alot easier if we write the result file in babyl format,
* which is the format Emacs uses.
*/
process_note(notef)
FILE *notef;
{
char buff[1024], *p;
int doing_headers;
doing_headers = 1;
fputs("\014\n0, unseen,,\n*** EOOH ***\n", resultf);
while(fgets(buff, sizeof(buff), notef) != NULL) {
/* chuck out any "From blh@blhablah" lines */
if(doing_headers && fromline(buff)) {
continue;
}
if(strlen(buff) == 1)
doing_headers=0;
/* Flatten any \001 characters remaining from mmdf */
for(p=buff; *p; p++)
*p = (*p == '\001') ? ' ' : *p ;
fputs(buff, resultf);
}
fputs("\037", resultf);
}