/* * Create the server end of a stream. For bsd, this means setup a tcp * socket for receiving a connection. */ static void * bsd_stream_server( void * h) { struct sec_stream *bs = NULL; struct sec_handle *bh = h; assert(bh != NULL); bs = g_new0(struct sec_stream, 1); security_streaminit(&bs->secstr, &bsd_security_driver); bs->socket = stream_server(SU_GET_FAMILY(&bh->udp->peer), &bs->port, (size_t)STREAM_BUFSIZE, (size_t)STREAM_BUFSIZE, 0); if (bs->socket < 0) { security_seterror(&bh->sech, _("can't create server stream: %s"), strerror(errno)); amfree(bs->secstr.error); amfree(bs); return (NULL); } bs->fd = -1; bs->ev_read = NULL; return (bs); }
static NATIVECALL(streamserver_create){ Link * args = array_getArray(Arg); int port = object_asNumber(args[0]); StreamServer ss = stream_server(port); if (! ss) return exception("StreamListenError", NULL, NULL); Link link = object_create(streamserver_type); link->value.vptr = ss; return link; }
static void stream_test(void) { struct sockaddr_un sun; pid_t childpid; int listenfd; listenfd = socket(PF_UNIX, SOCK_STREAM, 0); if (listenfd < 0) err(-1, "stream_test: socket"); bzero(&sun, sizeof(sun)); sun.sun_len = sizeof(sun); sun.sun_family = AF_UNIX; strcpy(sun.sun_path, socket_path); if (bind(listenfd, (struct sockaddr *)&sun, sizeof(sun)) < 0) err(-1, "stream_test: bind"); if (listen(listenfd, -1) < 0) err(-1, "stream_test: listen"); childpid = fork(); if (childpid < 0) err(-1, "stream_test: fork"); if (childpid != 0) { sleep(1); stream_client(); kill(childpid, SIGTERM); sleep(1); } else stream_server(listenfd); (void)unlink(socket_path); }
void dcc_send_connection::incoming_message(irc::connection& aConnection, const message& aMessage) { if (&aConnection != iConnection) return; if (aMessage.command() != message::PRIVMSG) return; typedef std::vector<std::pair<std::string::const_iterator, std::string::const_iterator> > bits_t; bits_t bits; neolib::tokens(aMessage.content(), std::string("\001 "), bits); if (neolib::to_upper(neolib::to_string(bits[0])) != "DCC") return; if (iSendType == Download && neolib::to_upper(neolib::to_string(bits[1])) == "ACCEPT" && bits.size() >= 5) { if (*bits[2].first == '\"') { for (bits_t::size_type i = 3; i < bits.size(); ++i) if (*(bits[i].second - 1) == '\"') { bits[2].second = bits[i].second; bits.erase(bits.begin() + 3, bits.begin() + i + 1); break; } } std::string fileName = neolib::to_string(bits[2]); if (fileName == iResumeData->iFileName && neolib::string_to_unsigned_integer(neolib::to_string(bits[3])) == iResumeData->iPort && neolib::string_to_unsigned_integer(neolib::to_string(bits[4])) == iResumeData->iResumeFileSize) { u_long address = iResumeData->iAddress; u_short port = iResumeData->iPort; iBytesTransferred = iResumeData->iResumeFileSize; iLastBytesTransferred = iBytesTransferred; if (!connect(address, port)) { close(); return; } neolib::observable<dcc_send_connection_observer>::notify_observers(dcc_send_connection_observer::NotifyTransferStarted); if (!open_file()) return; } } else if (iSendType == Listen && neolib::to_upper(neolib::to_string(bits[1])) == "RESUME" && bits.size() >= 5) { if (*bits[2].first == '\"') { for (bits_t::size_type i = 3; i < bits.size(); ++i) if (*(bits[i].second - 1) == '\"') { bits[2].second = bits[i].second; bits.erase(bits.begin() + 3, bits.begin() + i + 1); break; } } std::string fileName = neolib::to_string(bits[2]); if (fileName == iName && neolib::string_to_unsigned_integer(neolib::to_string(bits[3])) == stream_server().local_port()) { iResumeData = resume_data_t(0, stream_server().local_port(), name(), neolib::string_to_unsigned_integer(neolib::to_string(bits[4]))); message newMessage(*iConnection, message::OUTGOING); newMessage.set_command(message::PRIVMSG); newMessage.parameters().push_back(iRemoteUser.nick_name()); newMessage.parameters().push_back("\001DCC ACCEPT "); newMessage.parameters().back() += iResumeData->iFileName + " "; newMessage.parameters().back() += neolib::unsigned_integer_to_string<char>(iResumeData->iPort) + " "; newMessage.parameters().back() += neolib::unsigned_integer_to_string<char>(iResumeData->iResumeFileSize) + "\001"; iConnection->send_message(newMessage); } } }
/* Open a socket to the dumper. Returns TRUE if everything is happy, FALSE otherwise. */ static gboolean open_read_socket(dump_info_t * info, char * split_diskbuffer, guint64 splitsize, guint64 fallback_splitsize) { in_port_t port = 0; int socket; int fd; int result; struct addrinfo *res; if ((result = resolve_hostname("localhost", 0, &res, NULL) != 0)) { char *m; char *q; int save_errno = errno; char *qdiskname = quote_string(info->diskname); m = vstralloc("[localhost resolve failure: ", strerror(save_errno), "]", NULL); q = quote_string(m); putresult(TAPE_ERROR, "%s %s\n", info->handle, q); log_add(L_FAIL, "%s %s %s %d %s", info->hostname, qdiskname, info->timestamp, info->level, q); amfree(qdiskname); amfree(m); amfree(q); return FALSE; } socket = stream_server(res->ai_family, &port, 0, STREAM_BUFSIZE, 0); freeaddrinfo(res); if (socket < 0) { char *m; char *q; int save_errno = errno; char *qdiskname = quote_string(info->diskname); m = vstralloc("[port create failure: ", strerror(save_errno), "]", NULL); q = quote_string(m); putresult(TAPE_ERROR, "%s %s\n", info->handle, q); log_add(L_FAIL, "%s %s %s %d %s", info->hostname, qdiskname, info->timestamp, info->level, q); amfree(qdiskname); amfree(m); amfree(q); return FALSE; } putresult(PORT, "%d\n", port); fd = stream_accept(socket, CONNECT_TIMEOUT, 0, STREAM_BUFSIZE); if (fd < 0) { char *m, *q; int save_errno = errno; char *qdiskname = quote_string(info->diskname); m = vstralloc("[port connect failure: ", strerror(save_errno), "]", NULL); q = quote_string(m); putresult(TAPE_ERROR, "%s %s\n", info->handle, q); log_add(L_FAIL, "%s %s %s %d %s", info->hostname, qdiskname, info->timestamp, info->level, q); amfree(qdiskname); aclose(socket); amfree(m); amfree(q); return FALSE; } else { aclose(socket); } info->source = taper_source_new(info->handle, PORT_WRITE, NULL, fd, split_diskbuffer, splitsize, fallback_splitsize); /* FIXME: This should be handled properly. */ g_assert(info->source != NULL); return TRUE; }
/* * Returns a file descriptor to the incoming port * on success, or -1 on error. */ static int startup_chunker( char * filename, off_t use, off_t chunksize, struct databuf * db) { int infd, outfd; char *tmp_filename, *pc; in_port_t data_port; int data_socket; int result; struct addrinfo *res; data_port = 0; if ((result = resolve_hostname("localhost", 0, &res, NULL) != 0)) { errstr = newvstrallocf(errstr, _("could not resolve localhost: %s"), gai_strerror(result)); return -1; } data_socket = stream_server(res->ai_family, &data_port, 0, STREAM_BUFSIZE, 0); if (res) freeaddrinfo(res); if(data_socket < 0) { errstr = vstrallocf(_("error creating stream server: %s"), strerror(errno)); return -1; } putresult(PORT, "%d\n", data_port); infd = stream_accept(data_socket, CONNECT_TIMEOUT, 0, STREAM_BUFSIZE); aclose(data_socket); if(infd == -1) { errstr = vstrallocf(_("error accepting stream: %s"), strerror(errno)); return -1; } tmp_filename = vstralloc(filename, ".tmp", NULL); pc = strrchr(tmp_filename, '/'); g_assert(pc != NULL); *pc = '\0'; mkholdingdir(tmp_filename); *pc = '/'; if ((outfd = open(tmp_filename, O_RDWR|O_CREAT|O_TRUNC, 0600)) < 0) { int save_errno = errno; char *m = vstrallocf(_("holding file \"%s\": %s"), tmp_filename, strerror(errno)); errstr = quote_string(m); amfree(m); amfree(tmp_filename); aclose(infd); if(save_errno == ENOSPC) { putresult(NO_ROOM, "%s %lld\n", handle, (long long)use); return -2; } else { return -1; } } amfree(tmp_filename); databuf_init(db, outfd, filename, use, chunksize); db->filename_seq++; return infd; }