gint sock_write_all(SockInfo *sock, const gchar *buf, gint len) { g_return_val_if_fail(sock != NULL, -1); #if USE_SSL if (sock->ssl) return ssl_write_all(sock->ssl, buf, len); #endif return fd_write_all(sock->sock, buf, len); }
static gboolean sock_send(int fd, const char *msg) { int bytes_to_write, bytes_written; bytes_to_write = strlen(msg); bytes_written = fd_write_all(fd, msg, bytes_to_write); if (bytes_written != bytes_to_write) { g_print("could not write all bytes to socket\n"); return FALSE; } return TRUE; }
gint sock_write_all(SockInfo *sock, const gchar *buf, gint len) { gint ret; cm_return_val_if_fail(sock != NULL, -1); #ifdef USE_GNUTLS if (sock->ssl) ret = ssl_write_all(sock->ssl, buf, len); else #endif ret = fd_write_all(sock->sock, buf, len); if (ret < 0) sock->state = CONN_DISCONNECTED; return ret; }
gint send_message_local(const gchar *command, FILE *fp) { gchar **argv; GPid pid; gint child_stdin; gchar buf[BUFFSIZE]; gboolean err = FALSE; cm_return_val_if_fail(command != NULL, -1); cm_return_val_if_fail(fp != NULL, -1); log_message(LOG_PROTOCOL, _("Sending message using command: %s\n"), command); argv = strsplit_with_quote(command, " ", 0); if (g_spawn_async_with_pipes(NULL, argv, NULL, #ifdef G_OS_WIN32 0, #else G_SPAWN_DO_NOT_REAP_CHILD, #endif NULL, NULL, &pid, &child_stdin, NULL, NULL, NULL) == FALSE) { g_snprintf(buf, sizeof(buf), _("Couldn't execute command: %s"), command); log_warning(LOG_PROTOCOL, "%s\n", buf); alertpanel_error("%s", buf); g_strfreev(argv); return -1; } g_strfreev(argv); while (claws_fgets(buf, sizeof(buf), fp) != NULL) { strretchomp(buf); if (buf[0] == '.' && buf[1] == '\0') { if (fd_write_all(child_stdin, ".", 1) < 0) { err = TRUE; break; } } if (fd_write_all(child_stdin, buf, strlen(buf)) < 0 || fd_write_all(child_stdin, "\n", 1) < 0) { err = TRUE; break; } } fd_close(child_stdin); #ifndef G_OS_WIN32 gint status; waitpid(pid, &status, 0); if (!WIFEXITED(status) || WEXITSTATUS(status) != 0) err = TRUE; #endif g_spawn_close_pid(pid); if (err) { g_snprintf(buf, sizeof(buf), _("Error occurred while executing command: %s"), command); log_warning(LOG_PROTOCOL, "%s\n", buf); alertpanel_error("%s", buf); return -1; } return 0; }
static SockLookupData *sock_get_address_info_async(const gchar *hostname, gushort port, SockAddrFunc func, gpointer data) { SockLookupData *lookup_data = NULL; gint pipe_fds[2]; pid_t pid; resolver_init(); if (pipe(pipe_fds) < 0) { perror("pipe"); func(NULL, data); return NULL; } if ((pid = fork()) < 0) { perror("fork"); func(NULL, data); return NULL; } /* child process */ if (pid == 0) { #ifdef INET6 gint gai_err; struct addrinfo hints, *res, *ai; gchar port_str[6]; #else /* !INET6 */ struct hostent *hp; gchar **addr_list_p; struct sockaddr_in ad; #endif /* INET6 */ gint ai_member[4] = {AF_UNSPEC, 0, 0, 0}; close(pipe_fds[0]); #ifdef INET6 memset(&hints, 0, sizeof(hints)); /* hints.ai_flags = AI_CANONNAME; */ hints.ai_family = AF_UNSPEC; hints.ai_socktype = SOCK_STREAM; hints.ai_protocol = IPPROTO_TCP; g_snprintf(port_str, sizeof(port_str), "%d", port); gai_err = getaddrinfo(hostname, port_str, &hints, &res); if (gai_err != 0) { g_warning("getaddrinfo for %s:%s failed: %s\n", hostname, port_str, gai_strerror(gai_err)); fd_write_all(pipe_fds[1], (gchar *)ai_member, sizeof(ai_member)); close(pipe_fds[1]); _exit(1); } for (ai = res; ai != NULL; ai = ai->ai_next) { ai_member[0] = ai->ai_family; ai_member[1] = ai->ai_socktype; ai_member[2] = ai->ai_protocol; ai_member[3] = ai->ai_addrlen; fd_write_all(pipe_fds[1], (gchar *)ai_member, sizeof(ai_member)); fd_write_all(pipe_fds[1], (gchar *)ai->ai_addr, ai->ai_addrlen); } if (res != NULL) freeaddrinfo(res); #else /* !INET6 */ hp = my_gethostbyname(hostname); if (hp == NULL || hp->h_addrtype != AF_INET) { fd_write_all(pipe_fds[1], (gchar *)ai_member, sizeof(ai_member)); close(pipe_fds[1]); _exit(1); } ai_member[0] = AF_INET; ai_member[1] = SOCK_STREAM; ai_member[2] = IPPROTO_TCP; ai_member[3] = sizeof(ad); memset(&ad, 0, sizeof(ad)); ad.sin_family = AF_INET; ad.sin_port = htons(port); for (addr_list_p = hp->h_addr_list; *addr_list_p != NULL; addr_list_p++) { memcpy(&ad.sin_addr, *addr_list_p, hp->h_length); fd_write_all(pipe_fds[1], (gchar *)ai_member, sizeof(ai_member)); fd_write_all(pipe_fds[1], (gchar *)&ad, sizeof(ad)); } #endif /* INET6 */ close(pipe_fds[1]); _exit(0); } else { close(pipe_fds[1]); lookup_data = g_new0(SockLookupData, 1); lookup_data->hostname = g_strdup(hostname); lookup_data->child_pid = pid; lookup_data->func = func; lookup_data->data = data; lookup_data->channel = g_io_channel_unix_new(pipe_fds[0]); lookup_data->io_tag = g_io_add_watch (lookup_data->channel, G_IO_IN, sock_get_address_info_async_cb, lookup_data); } return lookup_data; }
/* For better readability we use a separate function to implement the child code of sock_get_address_info_async. Note, that under W32 this is actually not a child but a thread and this is the reason why we pass only a void pointer. */ static void address_info_async_child(void *opaque) { SockLookupData *parm = opaque; #ifdef INET6 gint gai_err; struct addrinfo hints, *res, *ai; gchar port_str[6]; #else /* !INET6 */ struct hostent *hp; gchar **addr_list_p; struct sockaddr_in ad; #endif /* INET6 */ gint ai_member[4] = {AF_UNSPEC, 0, 0, 0}; #ifndef G_OS_WIN32 close(parm->pipe_fds[0]); parm->pipe_fds[0] = -1; #endif #ifdef INET6 memset(&hints, 0, sizeof(hints)); hints.ai_flags = AI_CANONNAME; hints.ai_family = AF_UNSPEC; hints.ai_socktype = SOCK_STREAM; hints.ai_protocol = IPPROTO_TCP; g_snprintf(port_str, sizeof(port_str), "%d", parm->port); gai_err = getaddrinfo(parm->hostname, port_str, &hints, &res); if (gai_err != 0) { gchar len = 0; g_warning("getaddrinfo for %s:%s failed: %s\n", parm->hostname, port_str, gai_strerror(gai_err)); log_error(LOG_PROTOCOL, _("%s:%s: host lookup failed (%s).\n"), parm->hostname, port_str, gai_strerror(gai_err)); fd_write_all(parm->pipe_fds[1], &len, sizeof(len)); fd_write_all(parm->pipe_fds[1], (gchar *)ai_member, sizeof(ai_member)); close(parm->pipe_fds[1]); parm->pipe_fds[1] = -1; #ifdef G_OS_WIN32 _endthread(); #else _exit(1); #endif } if (res != NULL) { if (res->ai_canonname && strlen(res->ai_canonname) < 255) { gchar len = strlen(res->ai_canonname); fd_write_all(parm->pipe_fds[1], &len, sizeof(len)); fd_write_all(parm->pipe_fds[1], res->ai_canonname, len); } else { gchar len = 0; fd_write_all(parm->pipe_fds[1], &len, sizeof(len)); } } else { gchar len = 0; fd_write_all(parm->pipe_fds[1], &len, sizeof(len)); } for (ai = res; ai != NULL; ai = ai->ai_next) { ai_member[0] = ai->ai_family; ai_member[1] = ai->ai_socktype; ai_member[2] = ai->ai_protocol; ai_member[3] = ai->ai_addrlen; fd_write_all(parm->pipe_fds[1], (gchar *)ai_member, sizeof(ai_member)); fd_write_all(parm->pipe_fds[1], (gchar *)ai->ai_addr, ai->ai_addrlen); } if (res != NULL) freeaddrinfo(res); #else /* !INET6 */ hp = my_gethostbyname(parm->hostname); if (hp == NULL || hp->h_addrtype != AF_INET) { gchar len = 0; fd_write_all(parm->pipe_fds[1], &len, sizeof(len)); fd_write_all(parm->pipe_fds[1], (gchar *)ai_member, sizeof(ai_member)); close(parm->pipe_fds[1]); parm->pipe_fds[1] = -1; #ifdef G_OS_WIN32 _endthread(); #else _exit(1); #endif } ai_member[0] = AF_INET; ai_member[1] = SOCK_STREAM; ai_member[2] = IPPROTO_TCP; ai_member[3] = sizeof(ad); memset(&ad, 0, sizeof(ad)); ad.sin_family = AF_INET; ad.sin_port = htons(parm->port); if (hp->h_name && strlen(hp->h_name) < 255) { gchar len = strlen(hp->h_name); fd_write_all(parm->pipe_fds[1], &len, sizeof(len)); fd_write_all(parm->pipe_fds[1], hp->h_name, len); } else { gchar len = 0; fd_write_all(parm->pipe_fds[1], &len, sizeof(len)); } for (addr_list_p = hp->h_addr_list; *addr_list_p != NULL; addr_list_p++) { memcpy(&ad.sin_addr, *addr_list_p, hp->h_length); fd_write_all(parm->pipe_fds[1], (gchar *)ai_member, sizeof(ai_member)); fd_write_all(parm->pipe_fds[1], (gchar *)&ad, sizeof(ad)); } #endif /* INET6 */ close(parm->pipe_fds[1]); parm->pipe_fds[1] = -1; #ifdef G_OS_WIN32 _endthread(); #else _exit(0); #endif }