Viewing file: sample.c (4.21 KB) -rw-r--r-- Select action/file-type: (+) | (+) | (+) | Code (+) | Session (+) | (+) | SDB (+) | (+) | (+) | (+) | (+) | (+) |
/* A trivial filter that logs all email to a file. */
#include <sys/types.h> #include <stdio.h> #include <stdlib.h> #include <string.h> #include <sysexits.h> #include <unistd.h>
#include "libmilter/mfapi.h" #include "strl.h" /*RAN*/
typedef int bool;
#ifndef FALSE # define FALSE 0 #endif /* ! FALSE*/ #ifndef TRUE # define TRUE 1 #endif /* ! TRUE*/
struct mlfiPriv { char *mlfi_fname; FILE *mlfi_fp; };
#define MLFIPRIV ((struct mlfiPriv *) smfi_getpriv(ctx))
extern sfsistat mlfi_cleanup(SMFICTX *, bool);
sfsistat mlfi_envfrom(ctx, envfrom) SMFICTX *ctx; char **envfrom; { struct mlfiPriv *priv; int fd;
/* allocate some private memory */ priv = malloc(sizeof *priv); if (priv == NULL) { /* can't accept this message right now */ return SMFIS_TEMPFAIL; } memset(priv, '\0', sizeof *priv);
/* open a file to store this message */ priv->mlfi_fname = strdup("/tmp/msg.XXXXXXXX"); if (priv->mlfi_fname == NULL) { free(priv); return SMFIS_TEMPFAIL; } if ((fd = mkstemp(priv->mlfi_fname)) < 0 || (priv->mlfi_fp = fdopen(fd, "w+")) == NULL) { free(priv->mlfi_fname); free(priv); return SMFIS_TEMPFAIL; }
/* save the private data */ smfi_setpriv(ctx, priv);
/* continue processing */ return SMFIS_CONTINUE; }
sfsistat mlfi_header(ctx, headerf, headerv) SMFICTX *ctx; char *headerf; char *headerv; { /* write the header to the log file */ fprintf(MLFIPRIV->mlfi_fp, "%s: %s\r\n", headerf, headerv);
/* continue processing */ return SMFIS_CONTINUE; }
sfsistat mlfi_eoh(ctx) SMFICTX *ctx; { /* 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; { /* 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; { return mlfi_cleanup(ctx, TRUE); }
sfsistat mlfi_close(ctx) SMFICTX *ctx; { return SMFIS_ACCEPT; }
sfsistat mlfi_abort(ctx) SMFICTX *ctx; { return mlfi_cleanup(ctx, FALSE); }
sfsistat mlfi_cleanup(ctx, ok) SMFICTX *ctx; bool ok; { sfsistat rstat = SMFIS_CONTINUE; struct mlfiPriv *priv = MLFIPRIV; char *p; char host[512]; char hbuf[1024];
if (priv == NULL) return rstat;
/* close the archive file */ if (priv->mlfi_fp != NULL && fclose(priv->mlfi_fp) == EOF) { /* failed; we have to wait until later */ rstat = SMFIS_TEMPFAIL; (void) unlink(priv->mlfi_fname); } else if (ok) { /* add a header to the message announcing our presence */ if (gethostname(host, sizeof host) < 0) strlcpy(host, "localhost", sizeof host); p = strrchr(priv->mlfi_fname, '/'); if (p == NULL) p = priv->mlfi_fname; else p++; snprintf(hbuf, sizeof hbuf, "%s@%s", p, host); smfi_addheader(ctx, "X-Archived", hbuf); } else { /* message was aborted -- delete the archive file */ (void) unlink(priv->mlfi_fname); }
/* release private memory */ free(priv->mlfi_fname); free(priv); smfi_setpriv(ctx, NULL);
/* return status */ return rstat; }
struct smfiDesc smfilter = { "SampleFilter", /* filter name */ SMFI_VERSION, /* version code -- do not change */ SMFIF_ADDHDRS, /* flags */ NULL, /* connection info filter */ NULL, /* SMTP HELO command filter */ mlfi_envfrom, /* envelope sender filter */ NULL, /* envelope recipient filter */ mlfi_header, /* header filter */ mlfi_eoh, /* end of header */ mlfi_body, /* body block filter */ mlfi_eom, /* end of message */ mlfi_abort, /* message aborted */ mlfi_close /* connection cleanup */ };
int main(argc, argv) int argc; char *argv[]; { int c; const char *args = "p:";
/* 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); exit(EX_USAGE); } (void) smfi_setconn(optarg); break;
} } if (smfi_register(smfilter) == MI_FAILURE) { fprintf(stderr, "smfi_register failed\n"); exit(EX_UNAVAILABLE); } return smfi_main(); }
/* eof */
|