/* * 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 #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; }