/* * 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. * * $Id: t-rcb-sr.c,v 1.14 2005/04/14 17:14:02 ca Exp $ */ /* ** STDIN2RCB -- read rcb data from stdin ** ** Parameters: ** rcb -- RCB ** ** Returns: ** usual sm_error code ** ** This is a hack: it reads an "RCB" from stdin in the following format: ** I int ** S string */ sm_ret_T stdin2rcb(sm_rcb_P rcb) { int c; sm_ret_T ret; ret = sm_rcb_open_enc(rcb, -1); SM_TEST(sm_is_success(ret)); /* just a place holder for the size */ ret = sm_rcb_putuint32(rcb, 0); SM_TEST(sm_is_success(ret)); while ((c = getchar()) != EOF) { if (c == 'I') { ret = addint(rcb); SM_TEST(ret == SM_SUCCESS); } else if (c == 'S') { ret = addstr(rcb); SM_TEST(ret == SM_SUCCESS); } else { ret = sm_rcb_close_enc(rcb); SM_TEST(ret == SM_SUCCESS); if (sm_is_err(ret)) break; } if (sm_is_err(ret)) { (void) sm_rcb_close_enc(rcb); break; } } if (c == EOF && sm_is_success(ret)) { (void) sm_rcb_close_enc(rcb); ret = EOF; } return ret; } /* ** WRITERCB -- send rcb ** ** Parameters: ** rcb -- RCB ** fd -- fd ** ** Returns: ** usual sm_error code */ sm_ret_T writercb(sm_rcb_P rcb, rcb_fd_T fd) { int res; sm_ret_T ret; if (Verbose > 1) fprintf(stderr, "write: %d\n", (int) sm_rcb_getlen(rcb)); ret = sm_rcb_open_snd(rcb); SM_TEST(sm_is_success(ret)); do { res = sm_rcb_snd(fd, rcb TMO); SM_TEST(res >= 0); } while (res > 0); ret = sm_rcb_close_snd(rcb); if (res != 0) { fprintf(stderr, "clt: write_fd failed=%d, len=%d, errno=%d\n", res, (int) sm_rcb_getlen(rcb), errno); ret = sm_err_perm(EIO); } return ret; } /* ** SENDRCB -- send rcb ** ** Parameters: ** rcb -- RCB ** fd -- fd ** ** Returns: ** usual sm_error code ** ** This is a hack: it reads an "RCB" from stdin in the following format: ** I int ** S string */ sm_ret_T sendrcb(sm_rcb_P rcb, rcb_fd_T fd) { int res, c; sm_ret_T ret; ret = sm_rcb_open_enc(rcb, -1); SM_TEST(sm_is_success(ret)); /* just a place holder for the size */ ret = sm_rcb_putuint32(rcb, 0); SM_TEST(sm_is_success(ret)); while ((c = getchar()) != EOF) { if (c == 'I') { ret = addint(rcb); SM_TEST(ret == SM_SUCCESS); } else if (c == 'S') { ret = addstr(rcb); SM_TEST(ret == SM_SUCCESS); } else { ret = sm_rcb_close_enc(rcb); SM_TEST(ret == SM_SUCCESS); if (sm_is_err(ret)) { if (Verbose > 1) fprintf(stderr, "sm_rcb_close_enc=%#X\n" , ret); break; } if (Verbose > 1) fprintf(stderr, "write: %d\n", (int) sm_rcb_getlen(rcb)); ret = sm_rcb_open_snd(rcb); SM_TEST(sm_is_success(ret)); do { res = sm_rcb_snd(fd, rcb TMO); SM_TEST(res >= 0); } while (res > 0); ret = sm_rcb_close_snd(rcb); if (res != 0) { fprintf(stderr, "clt: write_fd failed=%d, len=%d, errno=%d\n", res, (int) sm_rcb_getlen(rcb), errno); ret = sm_err_perm(EIO); } else break; } if (sm_is_err(ret)) { (void) sm_rcb_close_enc(rcb); break; } } if (c == EOF && sm_is_success(ret)) { (void) sm_rcb_close_enc(rcb); ret = EOF; } return ret; } /* ** RCVRCB -- rcv rcb ** ** Parameters: ** rcb -- RCB ** fd -- fd ** full -- read the entire RCB at once (block if necessary) ** ** Returns: ** usual sm_error code */ sm_ret_T rcvrcb(sm_rcb_P rcb, rcb_fd_T fd, bool full) { sm_ret_T ret; uint32_t val, len; char buf[SM_BIGRCBSIZE]; if (full) { ret = sm_rcb_open_rcv(rcb); SM_TEST(sm_is_success(ret)); } ret = SM_SUCCESS; val = 0; len = 0; do { ret = sm_rcb_rcv(fd, rcb, 16 TMO); if (Verbose > 2) fprintf(stderr, "rcb_rcv: ret=%x\n", ret); } while (full && ret > 0); if (ret < 0) return ret; if (ret > 0 && !full) return ret; ret = sm_rcb_close_rcv(rcb); SM_TEST(ret == SM_SUCCESS); ret = sm_rcb_open_dec(rcb); SM_TEST(sm_is_success(ret)); if (!sm_is_success(ret)) return ret; ret = sm_rcb_getuint32(rcb, &val); SM_TEST(sm_is_success(ret)); if (!sm_is_success(ret)) return ret; if (Verbose > 1) fprintf(stderr, "srv: total length=%d\n", val); /* have to agree on record types with sender ... */ do { if (Verbose > 2) fprintf(stderr, "srv: rd=%d\n", rcb->sm_rcb_rw); ret = sm_rcb_getuint32(rcb, &len); SM_TEST(sm_is_success(ret)); if (!sm_is_success(ret)) break; if (Verbose > 1) fprintf(stderr, "srv: got length=%d\n", len); ret = sm_rcb_getuint32(rcb, &val); SM_TEST(sm_is_success(ret)); if (!sm_is_success(ret)) break; if (Verbose > 1) fprintf(stderr, "srv: got rectype=%x\n", val); /* bit 1: set: int */ if (val & 0x01) { ret = sm_rcb_getuint32(rcb, &val); SM_TEST(sm_is_success(ret)); if (!sm_is_success(ret)) break; if (Verbose > 1) fprintf(stderr, "srv: got val=%d\n", val); fprintf(stderr, "I=%d\n", val); } else if (len < sizeof(buf) - 1) { sm_memzero(buf, sizeof(buf)); ret = sm_rcb_getn(rcb, (uchar *) buf, len); SM_TEST(sm_is_success(ret)); if (!sm_is_success(ret)) break; if (Verbose > 1) fprintf(stderr, "srv: got buf=%d\n", buf[0]); fprintf(stderr, "S="); prtbuf(stderr, buf, len); fputc('\n', stderr); } else break; if (Verbose > 2) fprintf(stderr, "srv: next: rd=%d, len=%d\n", rcb->sm_rcb_rw, (int) rcb->sm_rcb_len); } while (rcb->sm_rcb_rw < (int) rcb->sm_rcb_len); ret = sm_rcb_close_dec(rcb); SM_TEST(ret == SM_SUCCESS); return ret; }