milter main returns mi_stop=2

milter main returns mi_stop=2

am 31.10.2007 16:09:06 von DFS

My milter processes a number of emails just
fine, then exits.

Don't understand why my smfi_main returns. I see

mi_stop=2

in messages log. Nothing special in my milter, just
adding a couple headers for certain emails.

What can cause smfi_main to return?

Thanks,
Mike

Re: milter main returns mi_stop=2

am 31.10.2007 18:01:48 von hume.spamfilter

Mike M wrote:
> What can cause smfi_main to return?

A variety of problems; I've had this occur when a select () on the
milter socket failed. In that case, Redhat AS3 w/ 2.4 kernel was leaking
kernel result codes into user space. (What was supposed to be a normal
EINTR was sending up as something else...)

If you have strace or truss handy, you might be able to get some useable
information with them.

--
Brandon Hume - hume -> BOFH.Ca, http://WWW.BOFH.Ca/

Re: milter main returns mi_stop=2

am 31.10.2007 18:48:07 von DFS

hume.spamfilter@bofh.ca wrote:
> Mike M wrote:
>> What can cause smfi_main to return?
>
> A variety of problems; I've had this occur when a select () on the
> milter socket failed. In that case, Redhat AS3 w/ 2.4 kernel was leaking
> kernel result codes into user space. (What was supposed to be a normal
> EINTR was sending up as something else...)
>
> If you have strace or truss handy, you might be able to get some useable
> information with them.
>

I'm attaching to it with gdb and all it says is "Program exited normally".

# gdb milter
GNU gdb Red Hat Linux (6.0post-0.20040223.19rh)
Copyright 2004 Free Software Foundation, Inc.
GDB is free software, covered by the GNU General Public License, and you are
welcome to change it and/or distribute copies of it under certain
conditions.
Type "show copying" to see the conditions.
There is absolutely no warranty for GDB. Type "show warranty" for details.
This GDB was configured as "i386-redhat-linux-gnu"...Using host
libthread_db library "/lib/tls/libthread_db.so.1".

(gdb) attach 444
Attaching to program: /home/mkm/src/milter/milter, process 444
Reading symbols from /lib/tls/libpthread.so.0...done.
[Thread debugging using libthread_db enabled]
[New Thread -1208297184 (LWP 444)]
[New Thread -1208300624 (LWP 445)]
Loaded symbols for /lib/tls/libpthread.so.0
Reading symbols from /lib/tls/libc.so.6...done.
Loaded symbols for /lib/tls/libc.so.6
Reading symbols from /lib/ld-linux.so.2...done.
Loaded symbols for /lib/ld-linux.so.2
0x0033c7a2 in _dl_sysinfo_int80 () from /lib/ld-linux.so.2
(gdb) c
Continuing.
[New Thread -1218790480 (LWP 453)]
[Thread -1218790480 (LWP 453) exited]
[New Thread -1218790480 (LWP 457)]
[Thread -1218790480 (LWP 457) exited]

Program exited normally.
(gdb) quit

Re: milter main returns mi_stop=2

am 31.10.2007 19:52:00 von DFS

This is a multi-part message in MIME format.
--------------040606090709090501080406
Content-Type: text/plain; charset=ISO-8859-1; format=flowed
Content-Transfer-Encoding: 7bit




Mike M wrote:
> hume.spamfilter@bofh.ca wrote:
>> Mike M wrote:
>>> What can cause smfi_main to return?
>>
>> A variety of problems; I've had this occur when a select () on the
>> milter socket failed. In that case, Redhat AS3 w/ 2.4 kernel was leaking
>> kernel result codes into user space. (What was supposed to be a normal
>> EINTR was sending up as something else...)
>>
>> If you have strace or truss handy, you might be able to get some useable
>> information with them.
>>
>
> I'm attaching to it with gdb and all it says is "Program exited normally".
>
> # gdb milter
> GNU gdb Red Hat Linux (6.0post-0.20040223.19rh)
> Copyright 2004 Free Software Foundation, Inc.
> GDB is free software, covered by the GNU General Public License, and you
> are
> welcome to change it and/or distribute copies of it under certain
> conditions.
> Type "show copying" to see the conditions.
> There is absolutely no warranty for GDB. Type "show warranty" for details.
> This GDB was configured as "i386-redhat-linux-gnu"...Using host
> libthread_db library "/lib/tls/libthread_db.so.1".
>
> (gdb) attach 444
> Attaching to program: /home/mkm/src/milter/milter, process 444
> Reading symbols from /lib/tls/libpthread.so.0...done.
> [Thread debugging using libthread_db enabled]
> [New Thread -1208297184 (LWP 444)]
> [New Thread -1208300624 (LWP 445)]
> Loaded symbols for /lib/tls/libpthread.so.0
> Reading symbols from /lib/tls/libc.so.6...done.
> Loaded symbols for /lib/tls/libc.so.6
> Reading symbols from /lib/ld-linux.so.2...done.
> Loaded symbols for /lib/ld-linux.so.2
> 0x0033c7a2 in _dl_sysinfo_int80 () from /lib/ld-linux.so.2
> (gdb) c
> Continuing.
> [New Thread -1218790480 (LWP 453)]
> [Thread -1218790480 (LWP 453) exited]
> [New Thread -1218790480 (LWP 457)]
> [Thread -1218790480 (LWP 457) exited]
>
> Program exited normally.
> (gdb) quit

I've attached my milter.c in case anyone cares to loan me their eyeballs
for a second. (Ignore the comment at the top of the file, that's not
what it does).

Is there anything wrong with my use of the pthread mutex for syncing log
writes?

Thx,
Mike


--------------040606090709090501080406
Content-Type: text/plain;
name="milter.c"
Content-Transfer-Encoding: 7bit
Content-Disposition: inline;
filename="milter.c"

/* A trivial filter that logs all email to a file. */

#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
_syscall0(pid_t, gettid) ;

#include "libmilter/mfapi.h"

#ifndef true
typedef int bool;
# define false 0
# define true 1
#endif /* ! true */

struct mlfiPriv
{
char *mlfi_fname;
FILE *mlfi_fp;
int doit;
char * from;
char * to;
};

#define MLFIPRIV ((struct mlfiPriv *) smfi_getpriv(ctx))

extern sfsistat mlfi_cleanup(SMFICTX *, bool);
// sfsistat mlfi_cleanup(SMFICTX *, bool);

char myemails[5000][100];
int IsAMyEmail(const char * addr) {
int idx = 0;
while(myemails[idx][0] != 0) {
if (strcmp(addr,myemails[idx]) == 0) {
return true;
}
idx++;
}
return false;
}

pthread_mutex_t mutex1 = PTHREAD_MUTEX_INITIALIZER;
void mylock() {
pthread_mutex_lock(&mutex1);
}
void myunlock() {
pthread_mutex_unlock(&mutex1);
}
void mylockinit() {
pthread_mutex_init(&mutex1,NULL);
}
void mylockdestroy() {
pthread_mutex_destroy(&mutex1);
}

void logstamp (int fd) {
time_t timep;
struct tm * tstruct;
timep = time(NULL);
tstruct = localtime(&timep);
char buf[10000];
sprintf(buf, "%04d/%02d/%02d %02d:%02d:%02d % 10d ",
tstruct->tm_year+1900, tstruct->tm_mon+1, tstruct->tm_mday,
tstruct->tm_hour, tstruct->tm_min, tstruct->tm_sec, gettid());

write (fd, buf, strlen(buf));
}
void logmsg(int fd, char * msg) {
if (msg && strlen(msg)) write (fd, msg, strlen(msg));
write (fd, "\n", 1);
}
void dlog1 (char *msg) {
int fd;
char buf[10000];

// if (!(msg && strlen(msg))) return;


fd = open("/var/log/milter", O_WRONLY | O_CREAT | O_APPEND);
if (fd == -1) {
printf("open error\n");
return;
}

if (msg && strlen(msg)) logstamp(fd);
logmsg(fd, msg);
close(fd);
}
void dlog2 (char * msg1, char * msg2) {
char buf[10000];
sprintf(buf, "%s %s", msg1, msg2);
dlog1(buf);
}
void ldlog1(char * msg) {
mylock();
dlog1(msg);
myunlock();
}
void ldlog2(char * msg1, char * msg2) {
mylock();
dlog2(msg1,msg2);
myunlock();
}

sfsistat
alloc_priv(ctx)
SMFICTX *ctx;
{
struct mlfiPriv *priv;
priv = malloc(sizeof *priv);
if (priv == NULL)
{
/* can't accept this message right now */
ldlog1("connect fail");
return SMFIS_TEMPFAIL;
}
memset(priv, '\0', sizeof *priv);
priv->from = malloc(500);
priv->to = malloc(500);

/* save the private data */
smfi_setpriv(ctx, priv);
}
sfsistat
mlfi_cleanup(ctx, ok)
SMFICTX *ctx;
bool ok;
{
sfsistat rstat = SMFIS_CONTINUE;
struct mlfiPriv *priv = MLFIPRIV;
if (priv == NULL) {
ldlog1("mlfi_cleanup: priv == NULL");
return rstat;
}
ldlog1("mlfi_cleanup: priv freed");

/* release private memory */
free(priv->from);
free(priv->to);
free(priv);
smfi_setpriv(ctx, NULL);

return rstat;

}

sfsistat
mlfi_connect(ctx, hostname, hostaddr)
SMFICTX *ctx;
char *hostname;
_SOCK_ADDR *hostaddr;
{
char *ident;
struct mlfiPriv *priv;

ldlog1("");
ldlog1("mlfi_connect ########################################################");

priv = MLFIPRIV;

if (priv == NULL) {
ldlog1("priv alloc'd");
alloc_priv(ctx);
priv = MLFIPRIV;
if (priv == NULL) {
/* can't accept this message right now */
ldlog1("connect fail");
return SMFIS_TEMPFAIL;
}
} else {
ldlog1("priv there, no alloc");
}

ident = smfi_getsymval(ctx, "_");
if (ident == NULL)
ident = "???";
// if ((priv->mlfi_connectfrom = strdup(ident)) == NULL)
// {
// (void) mlfi_cleanup(ctx, FALSE);
// ldlog1("connect fail");
// return SMFIS_TEMPFAIL;
// }
ldlog2("ident ",ident);
// ldlog1("connect succeed");

/* continue processing */
return SMFIS_CONTINUE;
}

sfsistat
mlfi_envto(ctx, envto)
SMFICTX *ctx;
char **envto;
{
// ldlog1("mlfi_envto");
ldlog2("recipient:",envto[0]);
struct mlfiPriv * priv = MLFIPRIV;
if (priv->doit) {
if (IsAMyEmail(envto[0])) {
strcpy(priv->to, envto[0]);
} else {
priv->doit = 0;
}
}


return SMFIS_CONTINUE;
}
sfsistat
mlfi_envfrom(ctx, envfrom)
SMFICTX *ctx;
char **envfrom;
{
// ldlog1("mlfi_envfrom");
ldlog2("sender:",envfrom[0]);
struct mlfiPriv * priv = MLFIPRIV;
priv->doit = 0;
if (!IsAMyEmail(envfrom[0])) {
priv->doit = 1;
strcpy(priv->from, envfrom[0]);
}
return SMFIS_CONTINUE;
}

sfsistat
mlfi_header(ctx, headerf, headerv)
SMFICTX *ctx;
char *headerf;
char *headerv;
{
// ldlog1("mlfi_header");
ldlog2(headerf, headerv);

struct mlfiPriv * priv = MLFIPRIV;

if (priv != NULL && priv->doit && strlen(priv->from) < 1
&& strncasecmp("from", headerf, 4) == 0) {
strcpy(priv->from, headerv);
ldlog1("mlfi_header: from was null so got from header");
}

/* continue processing */
return SMFIS_CONTINUE;
}

sfsistat
mlfi_eoh(ctx)
SMFICTX *ctx;
{
ldlog1("mlfi_eoh");
/* output the blank line between the header and the body */
// fprintf(MLFIPRIV->mlfi_fp, "\r\n");

/* continue processing */
return SMFIS_CONTINUE;
}

sfsistat
mlfi_body(ctx, bodyp, bodylen)
SMFICTX *ctx;
u_char *bodyp;
size_t bodylen;
{
ldlog1("mlfi_body");
return SMFIS_CONTINUE;

/* output body block to log file */
if (fwrite(bodyp, bodylen, 1, MLFIPRIV->mlfi_fp) <= 0)
{
/* write failed */
(void) mlfi_cleanup(ctx, false);
return SMFIS_TEMPFAIL;
}

/* continue processing */
return SMFIS_CONTINUE;
}

sfsistat
mlfi_eom(ctx)
SMFICTX *ctx;
{
ldlog1("mlfi_eom");
struct mlfiPriv * priv = MLFIPRIV;
if (priv->doit) {
smfi_addheader(ctx, "X-MkmEnvTo", priv->to);
smfi_addheader(ctx, "X-MkmEnvFrom", priv->from);
ldlog1("X-Mkm header added");
} else {
ldlog1("X-Mkm header not added");
}
return mlfi_cleanup(ctx, true);
return SMFIS_CONTINUE;
}

sfsistat
mlfi_close(ctx)
SMFICTX *ctx;
{
ldlog1("mlfi_close");
mlfi_cleanup(ctx, true);
return SMFIS_ACCEPT;
}

sfsistat
mlfi_abort(ctx)
SMFICTX *ctx;
{
ldlog1("mlfi_abort");
return mlfi_cleanup(ctx, false);
return SMFIS_CONTINUE;
}


struct smfiDesc smfilter =
{
"MKMs milter", /* filter name */
SMFI_VERSION, /* version code -- do not change */
SMFIF_ADDHDRS, /* flags */
mlfi_connect, /* connection info filter */
NULL, /* SMTP HELO command filter */
mlfi_envfrom, /* envelope sender filter */
mlfi_envto, /* envelope recipient filter */
mlfi_header, /* header filter */
mlfi_eoh, /* end of header */
NULL, /* body block filter */
mlfi_eom, /* end of message */
mlfi_abort, /* message aborted */
mlfi_close /* connection cleanup */
};


int
main(argc, argv)
int argc;
char *argv[];
{
bool setconn = false;
int c;
const char *args = "p:";

if (fork()) exit(0);

mylockinit();

/* Process command line options */
while ((c = getopt(argc, argv, args)) != -1)
{
switch (c)
{
case 'p':
if (optarg == NULL || *optarg == '\0')
{
(void) fprintf(stderr, "Illegal conn: %s\n",
optarg);
mylockdestroy();
exit(EX_USAGE);
}
(void) smfi_setconn(optarg);
setconn = true;
break;

}
}
if (!setconn)
{
fprintf(stderr, "%s: Missing required -p argument\n", argv[0]);
mylockdestroy();
exit(EX_USAGE);
}
if (smfi_register(smfilter) == MI_FAILURE)
{
fprintf(stderr, "smfi_register failed\n");
mylockdestroy();
exit(EX_UNAVAILABLE);
}
ldlog1("milter started");

struct stat statbuf;
char * buf, * ch;
int i,index,pos,fd;
fd = open("/u/mkm/procmail/MyEmails", O_RDONLY);
if (fd == -1) {
fprintf(stderr, "open /u/mkm/procmail/MyEmails failed\n");
ldlog1("MyEmails failed");
exit(EX_UNAVAILABLE);
}
// ldlog1("x");
fstat(fd, &statbuf);
buf = (char*)malloc(statbuf.st_size);
read(fd, buf, statbuf.st_size);
close(fd);
pos=0;
index = 0;
// ldlog1("x");
strncat(myemails[0], "<", 1);
// ldlog1("x");
while(pos < statbuf.st_size) {
ch = buf + pos;
if (*ch == '\n') {
strncat(myemails[index], ">", 1);
index++;
if (pos < statbuf.st_size-1)
strncat(myemails[index], "<", 1);
} else {
strncat(myemails[index], ch, 1);
}
pos++;
}
// ldlog1("y");
myemails[index][0] = 0;
ldlog1("myemails");
for(i = 0 ; i <= index; ++i) {
ldlog1(myemails[i]);
}
ldlog1("myemails done");

int r = smfi_main();
if (r == MI_FAILURE) {
ldlog1("smfi_main returned MI_FAILURE");
} else if (r == MI_SUCCESS) {
ldlog1("smfi_main returned MI_SUCCESS");
} else {
char buf[32];
sprintf(buf,"%d",r);
ldlog2("smfi_main returned ", buf);
}
return r;
mylockdestroy();
}

/* eof */



--------------040606090709090501080406--