/* * Copyright (c) 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_RCSID("@(#)$Id: t-extracthdr.c,v 1.10 2006/07/16 02:07:40 ca Exp $") #include "sm/error.h" #include "sm/assert.h" #include "sm/sm_extracthdr.h" #include "sm/io.h" #include "sm/sysexits.h" #include "sm/test.h" static int Verbose = 0; static int testextracthdr(sm_file_T *fp, size_t chunksize) { sm_ret_T ret; bool newchunk; sm_xhdr_ctx_P sm_xhdr_ctx; size_t len, off, thislen; uchar *chunk; char mail1[] = "From: someone@some.com\r\nTo: luser@victim.com\r\nSUBJECT: M$\r\nsucks\r\nMIME-Version: 1.0\r\nContent-Type: multipart/alternative; boundary=\"abcdef\"\r\n\r\noh really?\r\n"; off = 0; ret = sm_xhdr_init(SM_XHDR_FL_SKIP_FIRST_BLANK, &sm_xhdr_ctx); SM_TEST(sm_is_success(ret)); chunk = (uchar *) mail1; len = thislen = strlen((char *)chunk); newchunk = true; if (fp != NULL) { ret = sm_refill(fp); if (sm_is_err(ret)) return ret; chunk = f_p(*fp); len = thislen = f_r(*fp); } if (chunksize > 0 && thislen > chunksize) thislen = chunksize; do { ret = sm_xhdr(chunk + off, thislen, newchunk, sm_xhdr_ctx); newchunk = false; if (ret == SM_XHDR_GOT1 || ret == SM_XHDR_GOTA || ret == SM_XHDR_GOTL) { sm_io_fprintf(smioout, "name: %#S\n", sm_xhdr_ctx->sm_xhdr_name); sm_io_fprintf(smioout, "value: %#S\n", sm_xhdr_ctx->sm_xhdr_value); } if (ret == SM_XHDR_CONT && thislen + off < len) { newchunk = true; off += thislen; if (off + thislen > len) thislen = len - off; } else if (ret == SM_XHDR_CONT && fp != NULL) { newchunk = true; ret = sm_refill(fp); if (sm_is_err(ret)) return ret; chunk = f_p(*fp); len = thislen = f_r(*fp); if (chunksize > 0 && thislen > chunksize) thislen = chunksize; } } while (!sm_is_err(ret) && ret != SM_XHDR_EOHDR && ret != SM_XHDR_GOTL); if (Verbose > 0 && sm_is_err(ret)) sm_io_fprintf(smioout, "ret=%r, error=%m\n", ret, ret); sm_io_flush(smioout); ret = sm_xhdr_end(sm_xhdr_ctx); SM_TEST(sm_is_success(ret)); return 0; } static void usage(const char *prg) { sm_io_fprintf(smioerr, "%s: usage: %s [options] [mail]\n" "options:\n" "-s n set chunksize to n\n" "-V increase verbosity\n" , prg, prg ); exit(EX_USAGE); } int main(int argc, char **argv) { int c; size_t chunksize; char *prg; sm_file_T *fp; chunksize = 0; prg = argv[0]; while ((c = getopt(argc, argv, "s:V")) != -1) { switch (c) { case 's': chunksize = strtoul(optarg, NULL, 0); break; case 'V': ++Verbose; break; default: usage(prg); break; } } sm_test_begin(argc, argv, "test extracthdr"); argc -= optind; argv += optind; if (argc > 0) { for (c = 0; c < argc; c++) { sm_ret_T ret; ret = sm_io_open(SmStStdio, argv[c], SM_IO_RDONLY, &fp, SM_IO_WHAT_END); SM_TEST(ret == SM_SUCCESS); SM_TEST(fp != NULL); if (fp != NULL) (void) testextracthdr(fp, chunksize); ret = sm_io_close(fp, SM_IO_CF_NONE); } } else (void) testextracthdr((sm_file_T *)0, chunksize); return sm_test_end(); }