static void multi_server_execute(int unused_event, char *context) { VSTREAM *stream = (VSTREAM *) context; HTABLE *attr = (vstream_flags(stream) == multi_server_saved_flags ? (HTABLE *) vstream_context(stream) : 0); if (multi_server_lock != 0 && myflock(vstream_fileno(multi_server_lock), INTERNAL_LOCK, MYFLOCK_OP_NONE) < 0) msg_fatal("select unlock: %m"); /* * Do not bother the application when the client disconnected. Don't drop * the already accepted client request after "postfix reload"; that would * be rude. */ if (peekfd(vstream_fileno(stream)) > 0) { if (master_notify(var_pid, multi_server_generation, MASTER_STAT_TAKEN) < 0) /* void */ ; multi_server_service(stream, multi_server_name, multi_server_argv); if (master_notify(var_pid, multi_server_generation, MASTER_STAT_AVAIL) < 0) multi_server_abort(EVENT_NULL_TYPE, EVENT_NULL_CONTEXT); } else { multi_server_disconnect(stream); } if (attr) htable_free(attr, myfree); }
DELIVER_REQUEST *deliver_request_read(VSTREAM *stream) { DELIVER_REQUEST *request; /* * Tell the queue manager that we are ready for this request. */ if (deliver_request_initial(stream) != 0) return (0); /* * Be prepared for the queue manager to change its mind after contacting * us. This can happen when a transport or host goes bad. */ (void) read_wait(vstream_fileno(stream), -1); if (peekfd(vstream_fileno(stream)) <= 0) return (0); /* * Allocate and read the queue manager's delivery request. */ #define XXX_DEFER_STATUS -1 request = deliver_request_alloc(); if (deliver_request_get(stream, request) < 0) { deliver_request_done(stream, request, XXX_DEFER_STATUS); request = 0; } return (request); }
int fifo_listen(const char *path, int permissions, int block_mode) { char buf[BUF_LEN]; static int open_mode = 0; char *myname = "fifo_listen"; struct stat st; int fd; int count; /* * Create a named pipe (fifo). Do whatever we can so we don't run into * trouble when this process is restarted after crash. Make sure that we * open a fifo and not something else, then change permissions to what we * wanted them to be, because mkfifo() is subject to umask settings. * Instead we could zero the umask temporarily before creating the FIFO, * but that would cost even more system calls. Figure out if the fifo * needs to be opened O_RDWR or O_RDONLY. Some systems need one, some * need the other. If we choose the wrong mode, the fifo will stay * readable, causing the program to go into a loop. */ if (unlink(path) && errno != ENOENT) msg_fatal("%s: remove %s: %m", myname, path); if (mkfifo(path, permissions) < 0) msg_fatal("%s: create fifo %s: %m", myname, path); switch (open_mode) { case 0: if ((fd = open(path, O_RDWR | O_NONBLOCK, 0)) < 0) msg_fatal("%s: open %s: %m", myname, path); if (readable(fd) == 0) { open_mode = O_RDWR | O_NONBLOCK; break; } else { open_mode = O_RDONLY | O_NONBLOCK; if (msg_verbose) msg_info("open O_RDWR makes fifo readable - trying O_RDONLY"); (void) close(fd); /* FALLTRHOUGH */ } default: if ((fd = open(path, open_mode, 0)) < 0) msg_fatal("%s: open %s: %m", myname, path); break; } /* * Make sure we opened a FIFO and skip any cruft that might have * accumulated before we opened it. */ if (fstat(fd, &st) < 0) msg_fatal("%s: fstat %s: %m", myname, path); if (S_ISFIFO(st.st_mode) == 0) msg_fatal("%s: not a fifo: %s", myname, path); if (fchmod(fd, permissions) < 0) msg_fatal("%s: fchmod %s: %m", myname, path); non_blocking(fd, block_mode); while ((count = peekfd(fd)) > 0 && read(fd, buf, BUF_LEN < count ? BUF_LEN : count) > 0) /* void */ ; return (fd); }
int mail_flow_count(void) { char *myname = "mail_flow_count"; int count; if ((count = peekfd(MASTER_FLOW_READ)) < 0) msg_warn("%s: %m", myname); return (count); }
static int qmgr_deliver_initial_reply(VSTREAM *stream) { int stat; if (peekfd(vstream_fileno(stream)) < 0) { msg_warn("%s: premature disconnect", VSTREAM_PATH(stream)); return (DELIVER_STAT_CRASH); } else if (attr_scan(stream, ATTR_FLAG_STRICT, ATTR_TYPE_INT, MAIL_ATTR_STATUS, &stat, ATTR_TYPE_END) != 1) { msg_warn("%s: malformed response", VSTREAM_PATH(stream)); return (DELIVER_STAT_CRASH); } else { return (stat ? DELIVER_STAT_DEFER : 0); } }
static int flush_request_receive(VSTREAM *client_stream, VSTRING *request) { int count; /* * Kluge: choose the protocol depending on the request size. */ if (read_wait(vstream_fileno(client_stream), var_ipc_timeout) < 0) { msg_warn("timeout while waiting for data from %s", VSTREAM_PATH(client_stream)); return (-1); } if ((count = peekfd(vstream_fileno(client_stream))) < 0) { msg_warn("cannot examine read buffer of %s: %m", VSTREAM_PATH(client_stream)); return (-1); } /* * Short request: master trigger. Use the string+null protocol. */ if (count <= 2) { if (vstring_get_null(request, client_stream) == VSTREAM_EOF) { msg_warn("end-of-input while reading request from %s: %m", VSTREAM_PATH(client_stream)); return (-1); } } /* * Long request: real flush client. Use the attribute list protocol. */ else { if (attr_scan(client_stream, ATTR_FLAG_MORE | ATTR_FLAG_STRICT, RECV_ATTR_STR(MAIL_ATTR_REQ, request), ATTR_TYPE_END) != 1) { return (-1); } } return (0); }
int arpCheck() { arpMessage ArpMsgSend,ArpMsgRecv; #ifdef OLD_LINUX_VERSION struct sockaddr addr; int j; #endif int i=0; memset(&ArpMsgSend,0,sizeof(arpMessage)); memcpy(ArpMsgSend.ethhdr.ether_dhost,MAC_BCAST_ADDR,ETH_ALEN); memcpy(ArpMsgSend.ethhdr.ether_shost,ClientHwAddr,ETH_ALEN); ArpMsgSend.ethhdr.ether_type = htons(ETHERTYPE_ARP); ArpMsgSend.htype = htons(ARPHRD_ETHER); ArpMsgSend.ptype = htons(ETHERTYPE_IP); ArpMsgSend.hlen = ETH_ALEN; ArpMsgSend.plen = 4; ArpMsgSend.operation = htons(ARPOP_REQUEST); memcpy(ArpMsgSend.sHaddr,ClientHwAddr,ETH_ALEN); memcpy(&ArpMsgSend.tInaddr,&DhcpIface.ciaddr,4); DebugSyslog(LOG_DEBUG, "broadcasting ARPOP_REQUEST for %u.%u.%u.%u\n", ArpMsgSend.tInaddr[0],ArpMsgSend.tInaddr[1], ArpMsgSend.tInaddr[2],ArpMsgSend.tInaddr[3]); do { do { if ( i++ > 4 ) return 0; /* 5 probes */ #ifdef OLD_LINUX_VERSION memset(&addr,0,sizeof(struct sockaddr)); memcpy(addr.sa_data,IfName,IfName_len); if ( sendto(dhcpSocket,&ArpMsgSend,sizeof(arpMessage),0, &addr,sizeof(struct sockaddr)) == -1 ) #else if ( send(dhcpSocket,&ArpMsgSend,sizeof(arpMessage),0) == -1 ) #endif { syslog(LOG_ERR,"arpCheck: sendto: %m\n"); return -1; } } while ( peekfd(dhcpSocket,50000) ); /* 50 msec timeout */ do { if ( recv(dhcpSocket,&ArpMsgRecv,sizeof(arpMessage),0) == -1 ) { syslog(LOG_ERR,"arpCheck: recv: %m\n"); return -1; } if ( ArpMsgRecv.ethhdr.ether_type != htons(ETHERTYPE_ARP) ) continue; if ( ArpMsgRecv.operation == htons(ARPOP_REPLY) ) { DebugSyslog(LOG_DEBUG, "ARPOP_REPLY received from %u.%u.%u.%u for %u.%u.%u.%u\n", ArpMsgRecv.sInaddr[0],ArpMsgRecv.sInaddr[1], ArpMsgRecv.sInaddr[2],ArpMsgRecv.sInaddr[3], ArpMsgRecv.tInaddr[0],ArpMsgRecv.tInaddr[1], ArpMsgRecv.tInaddr[2],ArpMsgRecv.tInaddr[3]); } else continue; if ( memcmp(ArpMsgRecv.tHaddr,ClientHwAddr,ETH_ALEN) ) { DebugSyslog(LOG_DEBUG, "target hardware address mismatch: %02X.%02X.%02X.%02X.%02X.%02X received, %02X.%02X.%02X.%02X.%02X.%02X expected\n", ArpMsgRecv.tHaddr[0],ArpMsgRecv.tHaddr[1],ArpMsgRecv.tHaddr[2], ArpMsgRecv.tHaddr[3],ArpMsgRecv.tHaddr[4],ArpMsgRecv.tHaddr[5], ClientHwAddr[0],ClientHwAddr[1], ClientHwAddr[2],ClientHwAddr[3], ClientHwAddr[4],ClientHwAddr[5]); continue; } if ( memcmp(&ArpMsgRecv.sInaddr,&DhcpIface.ciaddr,4) ) { DebugSyslog(LOG_DEBUG, "sender IP address mismatch: %u.%u.%u.%u received, %u.%u.%u.%u expected\n", ArpMsgRecv.sInaddr[0],ArpMsgRecv.sInaddr[1],ArpMsgRecv.sInaddr[2],ArpMsgRecv.sInaddr[3], ((unsigned char *)&DhcpIface.ciaddr)[0], ((unsigned char *)&DhcpIface.ciaddr)[1], ((unsigned char *)&DhcpIface.ciaddr)[2], ((unsigned char *)&DhcpIface.ciaddr)[3]); continue; } return 1; } while ( peekfd(dhcpSocket,50000) == 0 ); } while ( 1 ); return 0; }
int arpCheck() { arpMessage ArpMsgSend,ArpMsgRecv; struct sockaddr addr; int j,i=0,len=0; memset(&ArpMsgSend,0,sizeof(arpMessage)); memcpy(ArpMsgSend.ethhdr.ether_dhost,MAC_BCAST_ADDR,ETH_ALEN); memcpy(ArpMsgSend.ethhdr.ether_shost,ClientHwAddr,ETH_ALEN); ArpMsgSend.ethhdr.ether_type = htons(ETHERTYPE_ARP); ArpMsgSend.htype = (TokenRingIf) ? htons(ARPHRD_IEEE802_TR) : htons(ARPHRD_ETHER); ArpMsgSend.ptype = htons(ETHERTYPE_IP); ArpMsgSend.hlen = ETH_ALEN; ArpMsgSend.plen = 4; ArpMsgSend.operation = htons(ARPOP_REQUEST); memcpy(ArpMsgSend.sHaddr,ClientHwAddr,ETH_ALEN); memcpy(&ArpMsgSend.tInaddr,&DhcpIface.ciaddr,4); if ( DebugFlag ) syslog(LOG_DEBUG, "broadcasting ARPOP_REQUEST for %u.%u.%u.%u\n", ArpMsgSend.tInaddr[0],ArpMsgSend.tInaddr[1], ArpMsgSend.tInaddr[2],ArpMsgSend.tInaddr[3]); do { do { if ( i++ > 4 ) return 0; /* 5 probes */ memset(&addr,0,sizeof(struct sockaddr)); memcpy(addr.sa_data,IfName,IfName_len); if ( TokenRingIf ) len = eth2tr(&ArpMsgSend.ethhdr,BasicArpLen(ArpMsgSend)); else len = sizeof(arpMessage); if ( sendto(dhcpSocket,&ArpMsgSend,len,0, &addr,sizeof(struct sockaddr)) == -1 ) { syslog(LOG_ERR,"arpCheck: sendto: %m\n"); return -1; } } while ( peekfd(dhcpSocket,50000) ); /* 50 msec timeout */ do { memset(&ArpMsgRecv,0,sizeof(arpMessage)); j=sizeof(struct sockaddr); if ( recvfrom(dhcpSocket,&ArpMsgRecv,sizeof(arpMessage),0, (struct sockaddr *)&addr,&j) == -1 ) { syslog(LOG_ERR,"arpCheck: recvfrom: %m\n"); return -1; } if ( TokenRingIf ) { if ( tr2eth(&ArpMsgRecv.ethhdr) ) continue; } if ( ArpMsgRecv.ethhdr.ether_type != htons(ETHERTYPE_ARP) ) continue; if ( ArpMsgRecv.operation == htons(ARPOP_REPLY) ) { if ( DebugFlag ) syslog(LOG_DEBUG, "ARPOP_REPLY received from %u.%u.%u.%u for %u.%u.%u.%u\n", ArpMsgRecv.sInaddr[0],ArpMsgRecv.sInaddr[1], ArpMsgRecv.sInaddr[2],ArpMsgRecv.sInaddr[3], ArpMsgRecv.tInaddr[0],ArpMsgRecv.tInaddr[1], ArpMsgRecv.tInaddr[2],ArpMsgRecv.tInaddr[3]); } else continue; if ( memcmp(ArpMsgRecv.tHaddr,ClientHwAddr,ETH_ALEN) ) { if ( DebugFlag ) syslog(LOG_DEBUG, "target hardware address mismatch: %02X.%02X.%02X.%02X.%02X.%02X received, %02X.%02X.%02X.%02X.%02X.%02X expected\n", ArpMsgRecv.tHaddr[0],ArpMsgRecv.tHaddr[1],ArpMsgRecv.tHaddr[2], ArpMsgRecv.tHaddr[3],ArpMsgRecv.tHaddr[4],ArpMsgRecv.tHaddr[5], ClientHwAddr[0],ClientHwAddr[1], ClientHwAddr[2],ClientHwAddr[3], ClientHwAddr[4],ClientHwAddr[5]); continue; } if ( memcmp(&ArpMsgRecv.sInaddr,&DhcpIface.ciaddr,4) ) { if ( DebugFlag ) syslog(LOG_DEBUG, "sender IP address mismatch: %u.%u.%u.%u received, %u.%u.%u.%u expected\n", ArpMsgRecv.sInaddr[0],ArpMsgRecv.sInaddr[1],ArpMsgRecv.sInaddr[2],ArpMsgRecv.sInaddr[3], ((unsigned char *)&DhcpIface.ciaddr)[0], ((unsigned char *)&DhcpIface.ciaddr)[1], ((unsigned char *)&DhcpIface.ciaddr)[2], ((unsigned char *)&DhcpIface.ciaddr)[3]); continue; } return 1; } while ( peekfd(dhcpSocket,50000) == 0 ); } while ( 1 ); return 0; }