/*
* Copyright (c) 2002-2005 Sendmail, Inc. and its suppliers.
* All rights reserved.
*
* By using this file, you agree to the terms and conditions set
* forth in the LICENSE file which can be found at the top level of
* the sendmail distribution.
*/
#include "sm/generic.h"
SM_IDSTR(id, "@(#)$Id: t-t2821-0.c,v 1.26 2005/06/27 17:19:58 ca Exp $")
#include "sm/debug.h"
#include "sm/heap.h"
#include "sm/rpool.h"
#include "sm/test.h"
#include "sm/rfc2821.h"
#include "sm/rfc2822.h"
#include "sm/sysexits.h"
#include <stdio.h>
#if SM_HEAP_CHECK
# include "sm/io.h"
extern SM_DEBUG_T SmHeapCheck;
# define HEAP_CHECK (SmHeapCheck > 0)
#else
# define HEAP_CHECK 0
#endif
#define BUFLEN 2048
#define MAXLEN 4096
static int
stripcr(char *buf)
{
int n;
n = strlen(buf);
while (n > 0 && buf[n - 1] == '\n')
{
buf[n - 1] = '\0';
--n;
}
return n;
}
static void
usage(const char *prg)
{
fprintf(stderr, "usage: %s [options]\n", prg);
fprintf(stderr, "Test whether addresses (read from stdin) conforms to RFC 2821\n");
fprintf(stderr, "options:\n");
fprintf(stderr, "-f n set address parsing flags\n");
fprintf(stderr, "-r use rpool\n");
}
int
main(int argc, char **argv)
{
int n;
int c, flags;
sm_ret_T r;
sm_a2821_T addr;
sm_str_P vp;
sm_str_P out;
sm_rpool_P rpool;
char *buf;
#if SM_HEAP_CHECK
SmHeapCheck = 0;
#endif
rpool = 0;
flags = R2821_STRICT;
while ((c = getopt(argc, argv, "f:H:r")) != -1)
{
switch (c)
{
#if SM_HEAP_CHECK
case 'H':
SmHeapCheck = atoi(optarg);
break;
#endif
case 'f':
flags = strtol(optarg, NULL, 0);
break;
case 'r':
rpool = sm_rpool_new(NULL);
break;
default:
usage(argv[0]);
return(EX_USAGE);
}
}
buf = sm_malloc(BUFLEN);
SM_TEST(buf != NULL);
if (buf == NULL)
goto end;
while (fgets(buf, BUFLEN, stdin))
{
n = getc(stdin);
ungetc(n, stdin);
if (n == ' ' || n == '\t')
{
n = strlen(buf);
fgets(buf + n, BUFLEN - n, stdin);
}
n = stripcr(buf);
if (n <= 0)
goto end; /* bogus input, don't try to recover */
vp = sm_str_scpy(NULL, buf, MAXLEN);
SM_TEST(vp != NULL);
if (!isatty(STDIN_FILENO))
{
printf(">>>%s<<<\n", buf);
fflush(stdout);
}
A2821_INIT_RP(&addr, rpool);
r = t2821_scan((sm_rdstr_P) vp, &addr, 0);
SM_TEST(sm_is_success(r));
if (sm_is_success(r))
{
r = t2821_parse(&addr, flags);
SM_TEST(sm_is_success(r));
if (!sm_is_success(r))
printf("ERROR: %x\t>>>%s<<<\n", r, buf);
else
printf("OK\t>>>%s<<<\n", buf);
out = sm_str_new(NULL, BUFLEN, MAXLEN);
SM_TEST(out != NULL);
r = t2821_str(&addr, out, 0);
SM_TEST(sm_is_success(r));
printf("%s\n", (char *)sm_str_getdata(out));
SM_STR_FREE(out);
}
else
{
printf("FAILED=%x\t>>>%s<<<\n", r, buf);
}
a2821_free(&addr);
SM_STR_FREE(vp);
fflush(stdout);
}
end:
if (buf != NULL)
sm_free(buf);
#if SM_HEAP_CHECK
if (HEAP_CHECK)
{
sm_io_fprintf(smioout, "heap should be empty except for makebuf:\n");
sm_heap_report(smioout, 3);
}
#endif
return 0;
}
syntax highlighted by Code2HTML, v. 0.9.1