/* * Copyright (c) 2003-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-passfd.c,v 1.6 2006/10/05 04:27:35 ca Exp $") #include "sm/assert.h" #include "sm/error.h" #include "sm/test.h" #include "sm/io.h" #include "sm/ctype.h" #include "sm/fcntl.h" #include "prterr.h" #include "sm/unixsock.h" #include "sm/cmsg.h" #include /* ** Open a listening fd and pass it to another program. ** write_fd() */ extern char *optarg; extern int optind; extern int optopt; extern int opterr; static int Verbose; static short port = 1234; static char *sockspec; static char *exsock; #define SM_BUFSIZE 8192 #define NSOCKET "./rdwrfd" /* socket to use to exchange fd */ #if MTA_USE_STATETHREADS # define sm_sock_close(fd) un_st_socket_close(fd) # define SM_INVALID_SOCKET NULL # define SM_IS_INVALID_SOCKET(fd) ((fd) == NULL) #else /* MTA_USE_STATETHREADS */ # define sm_sock_close(fd) close(fd) # define SM_INVALID_SOCKET (-1) # define SM_IS_INVALID_SOCKET(fd) ((fd) < 0) #endif /* MTA_USE_STATETHREADS */ void usage(const char *prg) { fprintf(stderr, "usage: %s options\n", prg); fprintf(stderr, "-L socket-spec: open socket-spec for listening\n"); fprintf(stderr, "-V: increase verbosity\n"); exit(0); } /* ** CLIENT -- send fd ** ** Parameters: ** none ** ** Returns: ** none */ void client() { int rdfd; fd_T fd; int res; char buf[SM_BUFSIZE]; if (Verbose > 1) fprintf(stderr, "clt: connect\n"); /* connect to server */ (void) unix_client_connect(exsock, &fd); if (Verbose > 1) fprintf(stderr, "clt: connected=%d\n", fd); SM_TEST(fd >= 0); if (fd < 0) return; /* open file descriptor that will be sent to server */ rdfd = net_server_listen(sockspec, port, 10); SM_TEST(rdfd >= 0); if (rdfd < 0) return; sm_snprintf(buf, sizeof(buf), "Send %d\n", rdfd); /* send rdfd to server */ res = sm_write_fd(fd, (void *) buf, 1, rdfd); SM_TEST(res >= 0); if (sm_is_err(res)) fprintf(stderr, "clt: write_fd failed=%x, errno=%d\n", res, errno); sm_sock_close(fd); sleep(1); close(rdfd); } int main(int argc, char *argv[]) { int c; opterr = 0; Verbose = 0; sockspec = "127.0.0.1"; exsock = NSOCKET; while ((c = getopt(argc, argv, "L:p:S:V")) != -1) { switch (c) { case 'L': sockspec = strdup(optarg); break; case 'p': port = atoi(optarg); break; case 'S': exsock = strdup(optarg); break; case 'V': ++Verbose; break; default: usage(argv[0]); return(1); } } sm_test_begin(argc, argv, "pass fd"); #if MTA_USE_STATETHREADS c = st_init(); SM_TEST(c >= 0); if (c < 0) exit(c); #endif /* MTA_USE_STATETHREADS */ client(); return sm_test_end(); }