static void script_execute_finish(void) { const char *keys_str, *username, *const *keys, *value; string_t *reply = t_str_new(512); ssize_t ret; keys_str = getenv(ENV_USERDB_KEYS); if (keys_str == NULL) i_fatal(ENV_USERDB_KEYS" environment missing"); username = getenv("USER"); if (username == NULL) i_fatal("USER environment missing"); str_append(reply, username); for (keys = t_strsplit_spaces(keys_str, " "); *keys != NULL; keys++) { value = getenv(t_str_ucase(*keys)); if (value != NULL) { str_append_c(reply, '\t'); str_tabescape_write(reply, t_strconcat(t_str_lcase(*keys), "=", value, NULL)); } } str_append_c(reply, '\n'); ret = fd_send(SCRIPT_COMM_FD, STDOUT_FILENO, str_data(reply), str_len(reply)); if (ret < 0) i_fatal("fd_send() failed: %m"); else if (ret != (ssize_t)str_len(reply)) i_fatal("fd_send() sent partial output"); }
void service_anvil_send_log_fd(void) { ssize_t ret; char b; if (service_anvil_global->process_count == 0) return; ret = fd_send(service_anvil_global->log_fdpass_fd[1], services->anvil->log_fd[1], &b, 1); if (ret < 0) i_error("fd_send(anvil log fd) failed: %m"); else if (ret == 0) i_error("fd_send(anvil log fd) failed: disconnected"); }
static void test_istream_unix_client(int fd) { /* 1) */ write_one(fd); read_one(fd); /* 2) */ if (fd_send(fd, send_fd, "1", 1) < 0) i_fatal("fd_send() failed: %m"); read_one(fd); /* 3) */ write_one(fd); read_one(fd); /* 4) */ if (fd_send(fd, send_fd2, "1", 1) < 0) i_fatal("fd_send() failed: %m"); read_one(fd); /* 5) */ write_one(fd); read_one(fd); /* 6) */ if (fd_send(fd, send_fd, "1", 1) < 0) i_fatal("fd_send() failed: %m"); read_one(fd); /* 7-8) */ if (fd_send(fd, send_fd, "1", 1) < 0) i_fatal("fd_send() failed: %m"); if (fd_send(fd, send_fd2, "1", 1) < 0) i_fatal("fd_send() failed: %m"); read_one(fd); /* 9-10) */ if (fd_send(fd, send_fd, "1", 1) < 0) i_fatal("fd_send() failed: %m"); if (fd_send(fd, send_fd2, "1", 1) < 0) i_fatal("fd_send() failed: %m"); read_one(fd); i_close_fd(&fd); }
int nvlist_send(int sock, const nvlist_t *nvl) { size_t datasize, nfds; int *fds; void *data; int64_t fdidx; int ret; if (nvlist_error(nvl) != 0) { ERRNO_SET(nvlist_error(nvl)); return (-1); } fds = nvlist_descriptors(nvl, &nfds); if (fds == NULL) return (-1); ret = -1; data = NULL; fdidx = 0; data = nvlist_xpack(nvl, &fdidx, &datasize); if (data == NULL) goto out; if (buf_send(sock, data, datasize) == -1) goto out; if (nfds > 0) { if (fd_send(sock, fds, nfds) == -1) goto out; } ret = 0; out: ERRNO_SAVE(); nv_free(fds); nv_free(data); ERRNO_RESTORE(); return (ret); }
int nvlist_send(int sock, const nvlist_t *nvl) { size_t datasize, nfds; int *fds; void *data; int64_t fdidx; int serrno, ret; if (nvlist_error(nvl) != 0) { errno = nvlist_error(nvl); return (-1); } fds = nvlist_descriptors(nvl, &nfds); if (fds == NULL) return (-1); ret = -1; data = NULL; fdidx = 0; data = nvlist_xpack(nvl, &fdidx, &datasize); if (data == NULL) goto out; if (buf_send(sock, data, datasize) == -1) goto out; if (nfds > 0) { if (fd_send(sock, fds, nfds) == -1) goto out; } ret = 0; out: serrno = errno; free(fds); free(data); errno = serrno; return (ret); }
static int imap_hibernate_process_send_cmd(int fd_socket, const char *path, const string_t *cmd, int fd_client) { ssize_t ret; i_assert(fd_socket != -1); i_assert(str_len(cmd) > 1); if (imap_hibernate_handshake(fd_socket, path) < 0) return -1; if ((ret = fd_send(fd_socket, fd_client, str_data(cmd), 1)) < 0) { i_error("fd_send(%s) failed: %m", path); return -1; } if ((ret = write_full(fd_socket, str_data(cmd)+1, str_len(cmd)-1)) < 0) { i_error("write(%s) failed: %m", path); return -1; } return 0; }
static void script_execute_finish(void) { const char *keys_str, *username, *const *keys, *value; string_t *reply = t_str_new(512); ssize_t ret; keys_str = getenv(ENV_USERDB_KEYS); if (keys_str == NULL) i_fatal(ENV_USERDB_KEYS" environment missing"); username = getenv("USER"); if (username == NULL) i_fatal("USER environment missing"); str_append(reply, username); for (keys = t_strsplit_spaces(keys_str, " "); *keys != NULL; keys++) { value = getenv(t_str_ucase(*keys)); if (value != NULL) { str_append_c(reply, '\t'); str_append_tabescaped(reply, t_strconcat(t_str_lcase(*keys), "=", value, NULL)); } } str_append_c(reply, '\n'); /* finish by sending the fd to the mail process */ ret = fd_send(SCRIPT_COMM_FD, STDOUT_FILENO, str_data(reply), str_len(reply)); if (ret == (ssize_t)str_len(reply)) { /* success */ } else { if (ret < 0) i_error("fd_send() failed: %m"); else i_error("fd_send() sent partial output"); /* exit with 0 even though we failed. non-0 exit just makes master log an unnecessary error. */ } }
static ssize_t o_stream_unix_writev(struct file_ostream *fstream, const struct const_iovec *iov, unsigned int iov_count) { struct unix_ostream *ustream = (struct unix_ostream *)fstream; size_t sent; ssize_t ret; if (ustream->write_fd == -1) { /* no fd */ return o_stream_file_writev(fstream, iov, iov_count); } /* send first iovec along with fd */ if (iov_count == 0) return 0; i_assert(iov[0].iov_len > 0); ret = fd_send(fstream->fd, ustream->write_fd, iov[0].iov_base, iov[0].iov_len); if (ret < 0) return ret; /* update stream */ sent = ret; fstream->real_offset += sent; ustream->write_fd = -1; if (sent < iov[0].iov_len || iov_count == 1) { /* caller will call us again to write the rest */ return sent; } /* send remaining iovecs */ ret = o_stream_file_writev(fstream, &iov[1], iov_count-1); if (ret < 0) return (errno == EAGAIN || errno == EINTR ? (ssize_t)sent : ret); sent += ret; return sent; }
struct access_lookup * access_lookup(const char *path, int client_fd, const char *daemon_name, access_lookup_callback_t *callback, void *context) { struct access_lookup *lookup; const char *cmd; ssize_t ret; int fd; fd = net_connect_unix(path); if (fd == -1) { i_error("connect(%s) failed: %m", path); return NULL; } cmd = t_strconcat(daemon_name, "\n", NULL); ret = fd_send(fd, client_fd, cmd, strlen(cmd)); if (ret != (ssize_t)strlen(cmd)) { if (ret < 0) i_error("fd_send(%s) failed: %m", path); else i_error("fd_send(%s) didn't write enough bytes", path); i_close_fd(&fd); return NULL; } lookup = i_new(struct access_lookup, 1); lookup->refcount = 1; lookup->fd = fd; lookup->path = i_strdup(path); lookup->io = io_add(fd, IO_READ, access_lookup_input, lookup); lookup->to = timeout_add(ACCESS_LOOKUP_TIMEOUT_MSECS, access_lookup_timeout, lookup); lookup->callback = callback; lookup->context = context; return lookup; }
static int imap_hibernate_process_send(struct client *client, const buffer_t *state, int fd_notify) { string_t *cmd = t_str_new(512); const char *path; ssize_t ret = 0; int fd; i_assert(state->used > 0); path = t_strconcat(client->user->set->base_dir, "/"IMAP_HIBERNATE_SOCKET_NAME, NULL); fd = net_connect_unix_with_retries(path, 1000); if (fd == -1) { i_error("net_connect_unix(%s) failed: %m", path); return -1; } net_set_nonblock(fd, FALSE); imap_hibernate_write_cmd(client, cmd, state, fd_notify); alarm(IMAP_HIBERNATE_SEND_TIMEOUT_SECS); if (imap_hibernate_process_send_cmd(fd, path, cmd, client->fd_in) < 0 || imap_hibernate_process_read(fd, path) < 0) ret = -1; else if (fd_notify != -1) { if ((ret = fd_send(fd, fd_notify, "\n", 1)) < 0) i_error("fd_send(%s) failed: %m", path); else ret = imap_hibernate_process_read(fd, path); } alarm(0); net_disconnect(fd); return ret < 0 ? -1 : 0; }