static void owner_disconnect(DBusConnection *conn, void *user_data) { struct connman_session *session = user_data; DBG("session %p, %s died", session, session->owner); session_disconnect(session); }
/** @brief Disconnect from Jabber, destroy a transport_session, and close its socket. @param session Pointer to the transport_session to be destroyed. @return 1 if successful, or 0 if not. The only error condition is a NULL pointer argument. */ int session_free( transport_session* session ) { if( ! session ) return 0; else { session_disconnect( session ); return session_discard( session ); } }
static void test_session_connect_disconnect_notify(struct test_session *session) { enum test_session_state state = get_session_state(session); enum test_session_state next_state = state; DBusMessage *msg; LOG("state %d session %p %s state %d", state, session, session->notify_path, session->info->state); switch (state) { case TEST_SESSION_STATE_0: if (session->info->state == CONNMAN_SESSION_STATE_DISCONNECTED) next_state = TEST_SESSION_STATE_1; if (session->info->state == CONNMAN_SESSION_STATE_CONNECTED) { LOG("state was already connected, continuing"); next_state = TEST_SESSION_STATE_2; } break; case TEST_SESSION_STATE_1: if (session->info->state >= CONNMAN_SESSION_STATE_CONNECTED) next_state = TEST_SESSION_STATE_2; break; case TEST_SESSION_STATE_2: if (session->info->state == CONNMAN_SESSION_STATE_DISCONNECTED) next_state = TEST_SESSION_STATE_3; default: break; } if (state == next_state) return; set_session_state(session, next_state); LOG("next_state %d", next_state); switch (next_state) { case TEST_SESSION_STATE_1: msg = session_connect(session->connection, session); g_assert(msg); dbus_message_unref(msg); return; case TEST_SESSION_STATE_2: msg = session_disconnect(session->connection, session); g_assert(msg); dbus_message_unref(msg); return; case TEST_SESSION_STATE_3: util_session_cleanup(session); util_idle_call(session->fix, util_quit_loop, util_session_destroy); return; default: return; } }
static void disconnect_pppoe_ses(void) { int ret; warn("Doing disconnect"); session_disconnect(ses); ses->sp.sa_addr.pppoe.sid = 0; ret = connect(ses->fd, (struct sockaddr*)&ses->sp, sizeof(struct sockaddr_pppox)); }
static void sieve_session_reset(SieveSession *session) { PrefsAccount *account = session->account; SieveAccountConfig *config = sieve_prefs_account_get_config(account); gboolean reuse_auth = (config->auth == SIEVEAUTH_REUSE); g_slist_free_full(session->send_queue, (GDestroyNotify)command_abort); session_disconnect(SESSION(session)); SESSION(session)->ssl_cert_auto_accept = account->ssl_certs_auto_accept; SESSION(session)->nonblocking = account->use_nonblocking_ssl; session->authenticated = FALSE; session->current_cmd = NULL; session->send_queue = NULL; session->state = SIEVE_CAPABILITIES; #ifdef USE_GNUTLS session->tls_init_done = FALSE; #endif session->avail_auth_type = 0; session->auth_type = 0; session->config = config; session->host = config->use_host ? config->host : account->recv_server; session->port = config->use_port ? config->port : SIEVE_PORT; session->user = reuse_auth ? account->userid : session->config->userid; session->forced_auth_type = config->auth_type; session_register_ping(SESSION(session), sieve_ping); if (session->pass) g_free(session->pass); if (config->auth == SIEVEAUTH_NONE) { session->pass = NULL; } else if (reuse_auth && account->passwd) { session->pass = g_strdup(account->passwd); } else if (config->passwd && config->passwd[0]) { session->pass = g_strdup(config->passwd); } else if (password_get(session->user, session->host, "sieve", session->port, &session->pass)) { } else { session->pass = input_dialog_query_password_keep(session->host, session->user, &(session->pass)); } if (!session->pass) { session->pass = g_strdup(""); session->use_auth = FALSE; } else { session->use_auth = TRUE; } #ifdef USE_GNUTLS SESSION(session)->ssl_type = (config->tls_type == SIEVE_TLS_NO) ? SSL_NONE : SSL_STARTTLS; #endif }
void session_free (SESSION * session) { session_disconnect (session); if (session->dh) DH_free (session->dh); if (session->rsa) RSA_free (session->rsa); free (session); }
static void test_session_connect_disconnect_notify(struct test_session *session) { enum test_session_state state = get_session_state(session); enum test_session_state next_state = state; DBusMessage *msg; LOG("state %d session %p %s online %d", state, session, session->notify_path, session->info->online); switch (state) { case TEST_SESSION_STATE_0: if (session->info->online == FALSE) next_state = TEST_SESSION_STATE_1; break; case TEST_SESSION_STATE_1: if (session->info->online == TRUE) next_state = TEST_SESSION_STATE_2; break; case TEST_SESSION_STATE_2: if (session->info->online == FALSE) next_state = TEST_SESSION_STATE_3; default: break; } if (state == next_state) return; set_session_state(session, next_state); LOG("next_state %d", next_state); switch (next_state) { case TEST_SESSION_STATE_1: msg = session_connect(session->connection, session); g_assert(msg != NULL); dbus_message_unref(msg); return; case TEST_SESSION_STATE_2: msg = session_disconnect(session->connection, session); g_assert(msg != NULL); dbus_message_unref(msg); return; case TEST_SESSION_STATE_3: util_session_cleanup(session); util_idle_call(session->fix, util_quit_loop, util_session_destroy); return; default: return; } }
static DBusMessage *destroy_session(DBusConnection *conn, DBusMessage *msg, void *user_data) { struct connman_session *session = user_data; DBG("session %p", session); if (ecall_session && ecall_session != session) return __connman_error_failed(msg, EBUSY); session_disconnect(session); return g_dbus_create_reply(msg, DBUS_TYPE_INVALID); }
void session_free (SESSION * session) { session_disconnect (session); if (session->dh) DH_free (session->dh); if (session->rsa) RSA_free (session->rsa); pthread_cond_destroy(&session->login_cond); pthread_mutex_destroy(&session->login_mutex); free (session); }
static void test_session_disconnect(struct test_fix *fix) { struct test_session *session; DBusMessage *msg; util_session_create(fix, 1); session = fix->session; session->notify_path = g_strdup("/foo"); session->notify = test_session_disconnect_notify; util_session_init(session); msg = session_disconnect(session->connection, session); g_assert(msg); dbus_message_unref(msg); }
void cl_ev_disconnect(void) { const char *jid = connection_get_fulljid(); cons_show("%s logged out successfully.", jid); ui_disconnected(); ui_close_all_wins(); session_disconnect(); roster_destroy(); muc_invites_clear(); chat_sessions_clear(); tlscerts_clear_current(); #ifdef HAVE_LIBGPGME p_gpg_on_disconnect(); #endif }
static gboolean test_session_disconnect(gpointer data) { struct test_fix *fix = data; struct test_session *session; DBusMessage *msg; util_session_create(fix, 1); session = fix->session; session->notify_path = g_strdup("/foo"); session->notify = test_session_disconnect_notify; util_session_init(session); msg = session_disconnect(session->connection, session); g_assert(msg != NULL); dbus_message_unref(msg); return FALSE; }
static IncState inc_pop3_session_do(IncSession *session) { Pop3Session *pop3_session = POP3_SESSION(session->session); IncProgressDialog *inc_dialog = (IncProgressDialog *)session->data; gchar *server; gchar *account_name; gushort port; gchar *buf; debug_print("getting new messages of account %s...\n", pop3_session->ac_prefs->account_name); pop3_session->ac_prefs->last_pop_login_time = time(NULL); buf = g_strdup_printf(_("%s: Retrieving new messages"), pop3_session->ac_prefs->recv_server); gtk_window_set_title(GTK_WINDOW(inc_dialog->dialog->window), buf); g_free(buf); server = pop3_session->ac_prefs->recv_server; account_name = pop3_session->ac_prefs->account_name; #ifdef USE_GNUTLS port = pop3_session->ac_prefs->set_popport ? pop3_session->ac_prefs->popport : pop3_session->ac_prefs->ssl_pop == SSL_TUNNEL ? 995 : 110; SESSION(pop3_session)->ssl_type = pop3_session->ac_prefs->ssl_pop; if (pop3_session->ac_prefs->ssl_pop != SSL_NONE) SESSION(pop3_session)->nonblocking = pop3_session->ac_prefs->use_nonblocking_ssl; #else if (pop3_session->ac_prefs->ssl_pop != SSL_NONE) { if (alertpanel_full(_("Insecure connection"), _("This connection is configured to be secured " "using SSL, but SSL is not available in this " "build of Claws Mail. \n\n" "Do you want to continue connecting to this " "server? The communication would not be " "secure."), GTK_STOCK_CANCEL, _("Con_tinue connecting"), NULL, FALSE, NULL, ALERT_WARNING, G_ALERTDEFAULT) != G_ALERTALTERNATE) return INC_CANCEL; } port = pop3_session->ac_prefs->set_popport ? pop3_session->ac_prefs->popport : 110; #endif buf = g_strdup_printf(_("Account '%s': Connecting to POP3 server: %s:%d..."), account_name, server, port); statuswindow_print_all("%s", buf); log_message(LOG_PROTOCOL, "%s\n", buf); progress_dialog_set_label(inc_dialog->dialog, buf); GTK_EVENTS_FLUSH(); g_free(buf); session_set_timeout(SESSION(pop3_session), prefs_common.io_timeout_secs * 1000); if (session_connect(SESSION(pop3_session), server, port) < 0) { if(!prefs_common.no_recv_err_panel) { if((prefs_common.recv_dialog_mode == RECV_DIALOG_ALWAYS) || ((prefs_common.recv_dialog_mode == RECV_DIALOG_MANUAL) && focus_window)) { manage_window_focus_in(inc_dialog->dialog->window, NULL, NULL); } alertpanel_error(_("Can't connect to POP3 server: %s:%d"), server, port); manage_window_focus_out(inc_dialog->dialog->window, NULL, NULL); } else { log_error(LOG_PROTOCOL, _("Can't connect to POP3 server: %s:%d\n"), server, port); } session->inc_state = INC_CONNECT_ERROR; statuswindow_pop_all(); return INC_CONNECT_ERROR; } while (session_is_running(SESSION(pop3_session)) && session->inc_state != INC_CANCEL) gtk_main_iteration(); if (session->inc_state == INC_SUCCESS) { switch (pop3_session->error_val) { case PS_SUCCESS: switch (SESSION(pop3_session)->state) { case SESSION_ERROR: if (pop3_session->state == POP3_READY) session->inc_state = INC_CONNECT_ERROR; else session->inc_state = INC_ERROR; break; case SESSION_EOF: session->inc_state = INC_EOF; break; case SESSION_TIMEOUT: session->inc_state = INC_TIMEOUT; break; default: session->inc_state = INC_SUCCESS; break; } break; case PS_AUTHFAIL: session->inc_state = INC_AUTH_FAILED; break; case PS_IOERR: session->inc_state = INC_IO_ERROR; break; case PS_SOCKET: session->inc_state = INC_SOCKET_ERROR; break; case PS_LOCKBUSY: session->inc_state = INC_LOCKED; break; default: session->inc_state = INC_ERROR; break; } } session_disconnect(SESSION(pop3_session)); statusbar_pop_all(); return session->inc_state; }
/** @brief Disconnect from the Jabber session. @param client Pointer to the transport_client. @return 0 in all cases. If there are any messages still in the queue, they stay there; i.e. we don't free them here. */ int client_disconnect( transport_client* client ) { if( client == NULL ) { return 0; } return session_disconnect( client->session ); }
static gint smtp_session_recv_msg(Session *session, const gchar *msg) { SMTPSession *smtp_session = SMTP_SESSION(session); gboolean cont = FALSE; if (strlen(msg) < 4) { log_warning(_("bad SMTP response\n")); return -1; } switch (smtp_session->state) { case SMTP_EHLO: case SMTP_STARTTLS: case SMTP_AUTH: case SMTP_AUTH_PLAIN: case SMTP_AUTH_LOGIN_USER: case SMTP_AUTH_LOGIN_PASS: case SMTP_AUTH_CRAM_MD5: log_print("ESMTP< %s\n", msg); break; default: log_print("SMTP< %s\n", msg); break; } if (msg[0] == '5' && msg[1] == '0' && (msg[2] == '4' || msg[2] == '3' || msg[2] == '1')) { log_warning(_("error occurred on SMTP session\n")); smtp_session->state = SMTP_ERROR; smtp_session->error_val = SM_ERROR; g_free(smtp_session->error_msg); smtp_session->error_msg = g_strdup(msg); return -1; } if (!strncmp(msg, "535", 3)) { log_warning(_("error occurred on authentication\n")); smtp_session->state = SMTP_ERROR; smtp_session->error_val = SM_AUTHFAIL; g_free(smtp_session->error_msg); smtp_session->error_msg = g_strdup(msg); return -1; } if (msg[0] != '1' && msg[0] != '2' && msg[0] != '3') { log_warning(_("error occurred on SMTP session\n")); smtp_session->state = SMTP_ERROR; smtp_session->error_val = SM_ERROR; g_free(smtp_session->error_msg); smtp_session->error_msg = g_strdup(msg); return -1; } if (msg[3] == '-') cont = TRUE; else if (msg[3] != ' ' && msg[3] != '\0') { log_warning(_("bad SMTP response\n")); smtp_session->state = SMTP_ERROR; smtp_session->error_val = SM_UNRECOVERABLE; return -1; } /* ignore all multiline responses except for EHLO */ if (cont && smtp_session->state != SMTP_EHLO) return session_recv_msg(session); switch (smtp_session->state) { case SMTP_READY: if (strstr(msg, "ESMTP")) smtp_session->is_esmtp = TRUE; case SMTP_CONNECTED: #if USE_OPENSSL if (smtp_session->user || session->ssl_type != SSL_NONE || smtp_session->is_esmtp) #else if (smtp_session->user || smtp_session->is_esmtp) #endif smtp_ehlo(smtp_session); else smtp_helo(smtp_session); break; case SMTP_HELO: smtp_from(smtp_session); break; case SMTP_EHLO: smtp_ehlo_recv(smtp_session, msg); if (cont == TRUE) break; if (smtp_session->max_message_size > 0 && smtp_session->max_message_size < smtp_session->send_data_len) { log_warning(_("Message is too big " "(Maximum size is %s)\n"), to_human_readable( (off_t)(smtp_session->max_message_size))); smtp_session->state = SMTP_ERROR; smtp_session->error_val = SM_ERROR; return -1; } #if USE_OPENSSL if (session->ssl_type == SSL_STARTTLS && smtp_session->tls_init_done == FALSE) { smtp_starttls(smtp_session); break; } #endif if (smtp_session->user) { if (smtp_auth(smtp_session) != SM_OK) smtp_from(smtp_session); } else smtp_from(smtp_session); break; case SMTP_STARTTLS: #if USE_OPENSSL if (session_start_tls(session) < 0) { log_warning(_("can't start TLS session\n")); smtp_session->state = SMTP_ERROR; smtp_session->error_val = SM_ERROR; return -1; } smtp_session->tls_init_done = TRUE; smtp_ehlo(smtp_session); #endif break; case SMTP_AUTH: smtp_auth_recv(smtp_session, msg); break; case SMTP_AUTH_LOGIN_USER: smtp_auth_login_user_recv(smtp_session, msg); break; case SMTP_AUTH_PLAIN: case SMTP_AUTH_LOGIN_PASS: case SMTP_AUTH_CRAM_MD5: smtp_from(smtp_session); break; case SMTP_FROM: if (smtp_session->cur_to) smtp_rcpt(smtp_session); break; case SMTP_RCPT: if (smtp_session->cur_to) smtp_rcpt(smtp_session); else smtp_data(smtp_session); break; case SMTP_DATA: smtp_send_data(smtp_session); break; case SMTP_EOM: smtp_quit(smtp_session); break; case SMTP_QUIT: session_disconnect(session); break; case SMTP_ERROR: default: log_warning(_("error occurred on SMTP session\n")); smtp_session->error_val = SM_ERROR; return -1; } if (cont) return session_recv_msg(session); return 0; }
/************************************************************************* * * Make a connection -- behaviour depends on callbacks specified in "ses" * *************************************************************************/ int session_connect(struct session *ses) { struct pppoe_packet *p_out=NULL; struct pppoe_packet rcv_packet; int ret; if(ses->init_disc){ ret = (*ses->init_disc)(ses, NULL, &p_out); if( ret != 0 ) return ret; } /* main discovery loop */ while(ses->retransmits <= ses->retries || ses->retries==-1 ){ fd_set in; struct timeval tv; FD_ZERO(&in); FD_SET(disc_sock,&in); if(ses->retransmits>=0){ ++ses->retransmits; tv.tv_sec = 1 << ses->retransmits; tv.tv_usec = 0; ret = select(disc_sock+1, &in, NULL, NULL, &tv); }else{ ret = select(disc_sock+1, &in, NULL, NULL, NULL); } if( ret == 0 ){ if((DEB_DISC) && (ses->retransmits <= ses->retries) ){ poe_dbglog(ses, "Re-sending ..."); } if( ses->timeout ){ ret = (*ses->timeout)(ses, NULL, &p_out); if ( ret != 0 ) { poe_info(ses, "returning - %d", ret); return ret; } } else if (p_out) { send_disc(ses,p_out); } continue; } ret = recv_disc(ses, &rcv_packet); /* Should differentiate between system errors and bad packets and the like... */ if( ret < 0 && errno != EINTR){ poe_info(ses, "couldn't rcv packet"); return -1; } if (DEB_DISC2) syslog(LOG_ERR, "Recieved packet=%x\n", rcv_packet.hdr->code); switch (rcv_packet.hdr->code) { case PADI_CODE: { if(ses->rcv_padi){ ret = (*ses->rcv_padi)(ses,&rcv_packet,&p_out); if( ret != 0){ return ret; } } break; } case PADO_CODE: /* wait for PADO */ { if(ses->rcv_pado){ ret = (*ses->rcv_pado)(ses,&rcv_packet,&p_out); if( ret != 0){ return ret; } } break; } case PADR_CODE: { if(ses->rcv_padr){ ret = (*ses->rcv_padr)(ses,&rcv_packet,&p_out); if( ret != 0){ return ret; } } break; } case PADS_CODE: { if(ses->rcv_pads){ ret = (*ses->rcv_pads)(ses,&rcv_packet,&p_out); if( ret != 0){ return ret; } } break; } case PADT_CODE: { if( rcv_packet.hdr->sid != ses->sp.sa_addr.pppoe.sid ){ --ses->retransmits; continue; } if(ses->rcv_padt){ ret = (*ses->rcv_padt)(ses,&rcv_packet,&p_out); if( ret != 0){ return ret; } }else{ poe_error (ses,"connection terminated"); return (-1); } break; } case 0: /*receiving normal seesion frames*/ { poe_error(ses, "Already in data stream, sending PADT %P\n", &rcv_packet); if (ses->pppoe_kill) { memcpy(&ses->remote,&rcv_packet.addr, sizeof(struct sockaddr_ll)); ses->sp.sa_addr.pppoe.sid = rcv_packet.hdr->sid; session_disconnect(ses); continue; } return (-1); } default: poe_error(ses,"invalid packet %P",&rcv_packet); return (-1); } } if (ses->retransmits > ses->retries) { errno = 62; return -1; } return (0); }
void connman_session_destroy(struct connman_session *session) { DBG("session %p", session); session_disconnect(session); }
static void test_session_connect_free_ride_notify(struct test_session *session) { struct test_session *session0 = get_session(session, 0); struct test_session *session1 = get_session(session, 1); enum test_session_state state = get_session_state(session); enum test_session_state next_state = state; DBusMessage *msg; LOG("state %d session %p %s state %d", state, session, session->notify_path, session->info->state); switch (state) { case TEST_SESSION_STATE_0: if (session0->info->state == CONNMAN_SESSION_STATE_DISCONNECTED && session1->info->state == CONNMAN_SESSION_STATE_DISCONNECTED) { next_state = TEST_SESSION_STATE_1; } break; case TEST_SESSION_STATE_1: if (session0->info->state >= CONNMAN_SESSION_STATE_CONNECTED && session1->info->state >= CONNMAN_SESSION_STATE_CONNECTED) { next_state = TEST_SESSION_STATE_2; } break; case TEST_SESSION_STATE_2: if (session0->info->state == CONNMAN_SESSION_STATE_DISCONNECTED && session1->info->state == CONNMAN_SESSION_STATE_DISCONNECTED) { next_state = TEST_SESSION_STATE_3; } break; case TEST_SESSION_STATE_3: return; } if (state == next_state) return; set_session_state(session, next_state); LOG("next_state %d", next_state); switch (next_state) { case TEST_SESSION_STATE_0: return; case TEST_SESSION_STATE_1: msg = session_connect(session0->connection, session0); g_assert(msg != NULL); dbus_message_unref(msg); return; case TEST_SESSION_STATE_2: msg = session_disconnect(session0->connection, session0); g_assert(msg != NULL); dbus_message_unref(msg); return; case TEST_SESSION_STATE_3: util_session_cleanup(session0); util_session_cleanup(session1); util_idle_call(session0->fix, util_quit_loop, util_session_destroy); return; } }
static gint pop3_session_recv_msg(Session *session, const gchar *msg) { Pop3Session *pop3_session = POP3_SESSION(session); Pop3ErrorValue val = PS_SUCCESS; const gchar *body; body = msg; if (pop3_session->state != POP3_GETRANGE_UIDL_RECV && pop3_session->state != POP3_GETSIZE_LIST_RECV) { val = pop3_ok(pop3_session, msg); if (val != PS_SUCCESS) { if (val != PS_NOTSUPPORTED) { pop3_session->state = POP3_ERROR; return -1; } } if (*body == '+' || *body == '-') body++; while (g_ascii_isalpha(*body)) body++; while (g_ascii_isspace(*body)) body++; } switch (pop3_session->state) { case POP3_READY: case POP3_GREETING: pop3_greeting_recv(pop3_session, body); #ifdef USE_GNUTLS if (pop3_session->ac_prefs->ssl_pop == SSL_STARTTLS) val = pop3_stls_send(pop3_session); else #endif if (pop3_session->ac_prefs->use_apop_auth) val = pop3_getauth_apop_send(pop3_session); else val = pop3_getauth_user_send(pop3_session); break; #ifdef USE_GNUTLS case POP3_STLS: if (pop3_stls_recv(pop3_session) != PS_SUCCESS) return -1; if (pop3_session->ac_prefs->use_apop_auth) val = pop3_getauth_apop_send(pop3_session); else val = pop3_getauth_user_send(pop3_session); break; #endif case POP3_GETAUTH_USER: val = pop3_getauth_pass_send(pop3_session); break; case POP3_GETAUTH_PASS: case POP3_GETAUTH_APOP: if (!pop3_session->pop_before_smtp) val = pop3_getrange_stat_send(pop3_session); else val = pop3_logout_send(pop3_session); break; case POP3_GETRANGE_STAT: if (pop3_getrange_stat_recv(pop3_session, body) < 0) return -1; if (pop3_session->count > 0) val = pop3_getrange_uidl_send(pop3_session); else val = pop3_logout_send(pop3_session); break; case POP3_GETRANGE_LAST: if (val == PS_NOTSUPPORTED) pop3_session->error_val = PS_SUCCESS; else if (pop3_getrange_last_recv(pop3_session, body) < 0) return -1; if (pop3_session->cur_msg > 0) val = pop3_getsize_list_send(pop3_session); else val = pop3_logout_send(pop3_session); break; case POP3_GETRANGE_UIDL: if (val == PS_NOTSUPPORTED) { pop3_session->error_val = PS_SUCCESS; val = pop3_getrange_last_send(pop3_session); } else { pop3_session->state = POP3_GETRANGE_UIDL_RECV; session_recv_data(session, 0, ".\r\n"); } break; case POP3_GETSIZE_LIST: pop3_session->state = POP3_GETSIZE_LIST_RECV; session_recv_data(session, 0, ".\r\n"); break; case POP3_RETR: pop3_session->state = POP3_RETR_RECV; session_recv_data(session, 0, ".\r\n"); break; case POP3_TOP: if (val == PS_NOTSUPPORTED) { pop3_session->error_val = PS_SUCCESS; } else { pop3_session->state = POP3_TOP_RECV; session_recv_data(session, 0, ".\r\n"); } break; case POP3_DELETE: pop3_delete_recv(pop3_session); if (pop3_session->cur_msg == pop3_session->count) val = pop3_logout_send(pop3_session); else { pop3_session->cur_msg++; if (pop3_lookup_next(pop3_session) == POP3_ERROR) return -1; } break; case POP3_LOGOUT: pop3_session->state = POP3_DONE; session_disconnect(session); break; case POP3_ERROR: default: return -1; } return val == PS_SUCCESS?0:-1; }
dk_session_t * smtp_connect (char * host1, caddr_t * err_ret, caddr_t sender, caddr_t recipient, caddr_t msg_body) { volatile int rc, inx, len, addr, at; dk_session_t * volatile ses = dk_session_allocate (SESCLASS_TCPIP); caddr_t cmd = NULL; char resp [1024]; char tmp [1024], *ptmp; char c; caddr_t volatile hf = NULL, host; if (!strchr (host1, ':')) { host = dk_alloc_box (strlen (host1) + 4, DV_SHORT_STRING); strcpy_box_ck (host, host1); strcat_box_ck (host, ":25"); } else { host = box_dv_short_string (host1); } rc = session_set_address (ses->dks_session, host); dk_free_box (host); host = NULL; if (SER_SUCC != rc) { PrpcSessionFree (ses); *err_ret = srv_make_new_error ("2E000", "SM002", "Cannot resolve host in smtp_send"); return NULL; } rc = session_connect (ses->dks_session); if (SER_SUCC != rc) { if (rc != SER_NOREC) session_disconnect (ses->dks_session); PrpcSessionFree (ses); *err_ret = srv_make_new_error ("08001", "SM003", "Cannot connect in smtp_send"); return NULL; } cmd = dk_alloc_box (MAX (MAX (box_length(sender), box_length(recipient)), 1000) + 24, DV_LONG_STRING); /* get initial line */ IS_OK_GO (ses, resp, rc, RESP_OK) /* send HELO */ if (gethostname (tmp, sizeof (tmp))) strcpy_ck (tmp, "localhost"); snprintf (cmd, box_length (cmd), "HELO %s\r\n", tmp); /*WRITE_CMD (ses, rc, "HELO virtuoso.mail\r\n");*/ WRITE_CMD (ses, rc, cmd); IS_OK_GO (ses, resp, rc, RESP_OK) /* send SENDER */ len = box_length (sender); ptmp = tmp; addr = -1; at = 0; for (inx = 0; inx < len; inx++) { c = sender [inx]; if (c == '<') addr = 1; else if (c == '>' && addr == 1) addr = 2; else if (c == '>' && addr == -1) { strcpy_ck (resp, "Unbalanced <...> in sender e-mail address."); goto error_end; } else if (c == '@') at = 1; if (((ptmp - tmp) < sizeof(tmp)) && (addr == 1 || addr == 2)) *ptmp++ = c; else if ((ptmp - tmp) >= sizeof(tmp)) { strcpy_ck (resp, "Sender\'s e-mail address is too long."); goto error_end; } if (addr == 2) { *ptmp = 0; snprintf (cmd, box_length (cmd), "MAIL FROM: %s\r\n", tmp); WRITE_CMD (ses, rc, cmd); IS_OK_GO (ses, resp, rc, RESP_OK) break; } }