home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
OS/2 Spezial
/
SPEZIAL2_97.zip
/
SPEZIAL2_97.iso
/
ANWEND
/
ONLINE
/
MR2IUUCP
/
UNMBOX.C
< prev
next >
Wrap
C/C++ Source or Header
|
1997-01-05
|
13KB
|
442 lines
/* unmbox.c
* Program to take a uupc inbox and translate it into separate mail messages
* ready for processing by MR/2 ICE.
*
* Michael Taylor miket@pcug.org.au
*
* History:
* 1.0.00 Initial version. 12/10/1996
* 1.0.01 Fixes. 19/10/1996
* Fix parsing of UUPC variables
* Add fromsep logic - NO fromsep should be defined!
* Inprove get_next_fname so it does not
* return a filename that already exists.
* Rename UUPC mbox so it cannot be written
* to by uuxqt/rmail.
* 1.0.02 Fixes. 26/12/1996
* Use tmpnam rather than tempnam and remove
* dependence on envvar TMP being unset.
* Do not delete renamed mailbox if no mail.
* 1.0.03 Fixes. 01/01/1997
* Fix UNMB_MAIL - was broken :-(
* Fix bug with writing out to getmail.err - added
* new command line parameter for MR/2 username.
* 1.0.04 Cleanup. 04/01/1997
* Remove all global variables.
* Fix bug in parsing UUPC definition files - noone found this :-)
* Works with nofromsep or fromsep format mailboxes.
*
*
* This program is freely redistributable.
*
* Please maintain the current coding style if you want me to
* incorporate any changes.
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
static char version[] =
"unmbox by Michael Taylor (miket@pcug.org.au) - Version 1.0.04";
static char * get_next_fname (char *basename, char *username);
static int get_uupc_vars (char *username, char * mailbox_name, char * old_mailbox);
static void err (char * str, char * username);
static int parse_nofromsep (FILE *infile, char *xbuf, char *basename,
char *username);
static int parse_fromsep (FILE *infile, char *xbuf, char *basename,
char *username);
static char *
get_next_fname (char *basename, char *username) {
char * name1;
char tname[L_tmpnam];
static char nxtfname[256];
FILE * tmp;
int x = 0, y = 1;
#define MAXTRIES 25000
while (y && x < MAXTRIES) {
if ((name1 = tmpnam (tname)) == NULL) {
err ("Cannot create unique filename\n", username);
return NULL;
}
strcpy (nxtfname, basename);
strcat (nxtfname, "\\");
strcat (nxtfname, tname+2);
/*printf ("try: %s\n", nxtfname);*/
if ((tmp = fopen (nxtfname, "r")) != NULL) {
fclose (tmp);
++x;
continue;
}
y = 0;
}
if (!y) {
/*printf ("use: %s\n", nxtfname);*/
return (char *)nxtfname;
} else
return NULL;
}
/*
get_uupc_vars
Checks for the UUPC control files to locate the mail box.
The environment var UNMB_MAIL can be used to specify the mailbox.
*/
static int
get_uupc_vars (char * username, char * mailbox_name, char * old_mailbox) {
char buf[256];
int i, cf;
char *p, *q, *fn;
char mailext[256];
static char mailbox[256];
FILE *tmp;
p = getenv ("UNMB_MAIL");
if (p != NULL) {
strcpy (old_mailbox, p);
strcpy (mailbox_name, p);
for (q = (p = mailbox_name) + strlen (mailbox_name); p < q; ++p) {
if (*p == '.')
break;
}
if (*p == '.')
p[1] = '\0';
else {
p[0] = '.';
p[1] = '\0';
}
strcat (mailbox_name, "tmp");
return (1);
}
/*--------------------- load UUPC rc files ---------------------------*/
/* read the system file first */
for (cf = 0, i = 0; i < 2; i++) {
/* choose the file to open */
if (i == 0) {
fn = getenv ("UUPCSYSRC");
if (fn == NULL) {
err ("Enviroment variable UUPCSYSRC not defined\n", username);
exit (EXIT_FAILURE);
}
} else {
fn = getenv ("UUPCUSRRC");
if (fn == NULL) {
err ("Enviroment variable UUPCUSRRC not defined\n", username);
exit (EXIT_FAILURE);
}
}
if ((tmp = fopen (fn, "r")) != NULL) {
while (fgets (buf, 255, tmp)) {
p = buf + strlen (buf) - 1;
if (*p == '\n')
*p = '\0';
if (p > buf)
if (*(p-1) == '\n')
*(p-1) = '\0';
if (!cf && strnicmp (buf, "confdir=", 8) == 0) {
/* default root dir if mailbox var not found */
cf = 1;
strcpy (mailbox_name, buf+8);
strcat (mailbox_name, "\\mail"); /* 1.0.01 */
} else
if (strnicmp (buf, "mailbox=", 8) == 0) {
/* mailbox base name */
strcpy (mailbox, buf+8);
} else
if (strnicmp (buf, "maildir=", 8) == 0) {
/* file name for mailbox */
cf = 1;
strcpy (mailbox_name, buf+8);
} else
if (strnicmp (buf, "mailext=", 8) == 0) {
/* extension of file name for mailbox */
strcpy (mailext, buf+8);
}
}
fclose (tmp);
} else {
fprintf (stderr, "Cannot open %s\n", fn);
}
}
if (!cf) {
return (0);
}
strcat (mailbox_name, "\\");
strcat (mailbox_name, mailbox);
strcat (mailbox_name, ".");
strcpy (old_mailbox, mailbox_name);
strcat (old_mailbox, mailext);
strcat (mailbox_name, "tmp");
return (1);
}
static void
err (char * str, char * username) {
FILE * errfile;
char errfname[256];
strcpy (errfname, username);
strcat (errfname, "\\getmail.err");
if ((errfile = fopen (errfname, "w")) == NULL) {
fprintf (stderr, "unmbox: error - cannot open file for error message\n");
exit (EXIT_FAILURE);
}
fprintf (errfile, "%s", str);
fclose (errfile);
}
#define XBUFSIZE 20480
static char x01x20[20] =
"\01\01\01\01\01\01\01\01\01\01\01\01\01\01\01\01\01\01\01\01";
/*
parse_nofromsep
parse the mailbox using the 20 x01s as the delimeter between mail items
*/
static int
parse_nofromsep (FILE *infile, char *xbuf, char *basename, char *username) {
FILE * mfile=0;
int nlines, reterr = 0;
fgets (xbuf, XBUFSIZE, infile);
while (!feof (infile)) {
/* if (0 == memcmp (xbuf, x01x20, 20))
goto nextline;*/
if ((mfile = fopen (get_next_fname (basename, username), "w")) == NULL) {
/* this error most likely occurs if the SMTP directory doesn't exist */
reterr = 1;
break;
}
fputs (xbuf, mfile); nlines = 1;
while (fgets (xbuf, XBUFSIZE, infile)) {
if (0 == memcmp (xbuf, x01x20, 20))
break;
fputs (xbuf, mfile); nlines++;
}
if (mfile) { fclose (mfile); mfile = 0;}
/*nextline:*/
fgets (xbuf, XBUFSIZE, infile);
}
if (mfile) { fclose (mfile); mfile = 0;}
return reterr;
}
/* new_mail
*
* The logic here is that the From line will have the same format.
* From userid ...
* To make sure it is a valid From line we identify the format of the
* first From line and make sure all preceding From lines are the same
* format - it would be unlikely for a line starting with From to have
* Numerics and Non-numerics in the same places!
*/
static int
new_mail (char * xbuf, int setup) {
char * p;
static int nparts = 0;
static char stype[20];
char ptype[20];
int n;
/*
Example From lines
Current UUPC From format
From teamos2.org!owner-teamos2-l Sat Jan 4 18:33:31 1997 remote from miket
This is from UUPC rmail:
From fkk Sat, 14 Mar 1992 14:53:27 MET remote from stasys
while this is another:
From fkk Sat Mar 14 14:53:27 1992 [MET]
*/
if (memcmp (xbuf, "From ", 5))
return 0;
for (n = 0; n < 20; ++n)
ptype[n] = 0;
for (p = xbuf, n = 0; *p != '\0'; ++p) {
if (*p == ' ')
++n;
else /* set the type of the part */
if (n < 20 && !ptype[n] && *p > '0' && *p < '9')
ptype[n] = 1; /* Numeric */
else
ptype[n] = 2; /* Non-Numeric */
}
/* the first two parts are always a From and a userid
* are numeric userids possible?
*/
ptype[0] = 3; /* From identifier */
ptype[1] = 4; /* userid */
if (setup) {
nparts = n;
memcpy (stype, ptype, 20);
/*printf ("nparts=%d\n", nparts);*/
return 1;
}
/* if the format matches the remembered format then we have a match */
if (nparts == n && 0 == memcmp (stype, ptype, 20))
return 1;
return 0;
}
/*
parse_fromsep
parse the mailbox using the FROM+header as the delimeter between mail items
*/
static int
parse_fromsep (FILE *infile, char *xbuf, char *basename, char *username) {
FILE * mfile=0;
int nlines, reterr=0;
/* initialise new_mail test with From line format */
if (!new_mail (xbuf, 1)) {
reterr = 2;
return reterr;
}
while (!feof (infile)) {
if ((mfile = fopen (get_next_fname (basename, username), "w")) == NULL) {
/* this error most likely occurs if the SMTP directory doesn't exist */
reterr = 1;
break;
}
fputs (xbuf, mfile); nlines = 1;
while (fgets (xbuf, XBUFSIZE, infile)) {
if (new_mail (xbuf, 0))
break;
fputs (xbuf, mfile); nlines++;
}
if (mfile) { fclose (mfile); mfile = 0;}
}
if (mfile) { fclose (mfile); mfile = 0;}
return reterr;
}
int
main (int argc, char * argv[]) {
FILE * infile=0;
int isfromsep=1, errs=0;
char username[256], basename[256], omailbox[256], maildir[256];
char * mailbox_name = maildir, * old_mailbox = omailbox;
char * xbuf = NULL;
strcpy (username, "mail"); /* default value for username */
if (argc < 2) {
printf ("%s\n", version);
printf ("usage: unmbox <SMTP directory> [username]\n");
err ("usage: unmbox <SMTP directory> [username]\n", username);
exit (EXIT_FAILURE);
}
strcpy (basename, argv[1]);
if (argc > 2)
strcpy (username, argv[2]);
if (!get_uupc_vars (username, mailbox_name, old_mailbox)) {
err ("error - cannot find UUPC mail box\n", username);
exit (EXIT_FAILURE);
}
/* test if any mail - so <mailbox>.tmp is not deleted! */
if ((infile = fopen (old_mailbox, "r")) == NULL) {
/* err ("error - cannot open UUPC mailbox\n", username);*/
exit (EXIT_FAILURE);
}
fclose (infile);
remove (mailbox_name);
if (rename (old_mailbox, mailbox_name)) {
/* err ("error - cannot access UUPC mailbox - try again later\n", username);*/
exit (EXIT_FAILURE);
}
if ((infile = fopen (mailbox_name, "r")) == NULL) {
/* err ("error - cannot open UUPC mailbox\n", username);*/
exit (EXIT_FAILURE);
}
xbuf = (char *)malloc (XBUFSIZE+1);
if (xbuf == NULL) {
err("error - Cannot allocate temporary buffer\n", username);
exit (EXIT_FAILURE);
}
/* first check if file is nofromsep or fromsep format */
fgets (xbuf, XBUFSIZE, infile);
if (feof (infile)) {
fclose (infile);
/* just to be nice - rename mailbox so that the user can try again later */
rename (mailbox_name, old_mailbox);
if (xbuf) {free (xbuf); xbuf = NULL;}
exit (EXIT_FAILURE);
}
/* if the first line is 20 0x01s then this is a UUPC-style (nofromsep)
* delimeted mailbox.
*/
while (1) {
if (0 == memcmp (xbuf, x01x20, 20)) {
isfromsep = 0;
break;
}
if (0 == memcmp (xbuf, "From ", 5))
break;
fgets (xbuf, XBUFSIZE, infile);
if (feof (infile)) {
fclose (infile);
/* just to be nice - rename mailbox so that the user can try again later */
rename (mailbox_name, old_mailbox);
if (xbuf) {free (xbuf); xbuf = NULL;}
err ("error - no From or nofromsep line in mailbox\n", username);
exit (EXIT_FAILURE);
}
}
if (isfromsep)
errs = parse_fromsep (infile, xbuf, basename, username);
else
errs = parse_nofromsep (infile, xbuf, basename, username);
if (errs) {
if (1 == errs)
err ("error - cannot open new file for mail\n", username);
else if (2 == errs)
err ("error - no From line at start of mailbox\n", username);
else
err ("error - parse error reading mailbox\n", username);
/* just to be nice - rename mailbox so that the user can try again later */
rename (mailbox_name, old_mailbox);
}
fclose (infile);
if (xbuf) {free (xbuf); xbuf = NULL;}
exit (EXIT_SUCCESS);
return (EXIT_SUCCESS); /* gets rid of dumb compiler warning */
}