Logo Search packages:      
Sourcecode: lcrt version File versions  Download package

cterminal.c

/*
 * Copyright (c) 2009-~ Niu Tao
 *
 * This source code is released for free distribution under the terms of the
 * GNU General Public License
 *
 * Author:       Niu Tao<niutao0602@gmail.com>
 * Created Time: Sat 15 Jan 2011 05:06:01 PM CST
 * File Name:    cterminal.c
 *
 * Description:  
 */
//#define __LCRT_DEBUG__
#include <stdio.h>
#include <gtk/gtk.h>
#include <string.h>
#include <vte/vte.h>
#include "user.h"
#include "iterminal.h"
#include "debug.h"
#include "ilogin.h"
#include "message.h"
#include "iwindow.h"
#include "inotebook.h"
#include "imenubar.h"
#include "ifile.h"
#include "iedit.h"
#include "cedit.h"
#include "ipopup.h"
#include "istatus.h"
#include "itoolbar.h"

#define RESET
void lcrt_terminal_on_commit(VteTerminal *widget, gchar *text, guint length, gpointer user_data)
{
    //struct lcrt_terminal *lterminal = (struct lcrt_terminal *)user_data;
}
    
gboolean lcrt_terminal_on_key_press_event(GtkWidget*widget,
            GdkEventKey *event, gpointer user_data)
{
    struct lcrt_terminal *lterminal = (struct lcrt_terminal *)user_data;
    debug_where();
    if (event->type == GDK_KEY_PRESS && event->keyval == GDK_Return) {
        debug_print("reconnect...\n");
        lcrt_terminal_fork(lterminal);
    }
    return FALSE;
}
void lcrt_terminal_on_child_exited(VteTerminal *vteterminal, gpointer user_data)
{
    debug_where();
    struct lcrt_terminal *lterminal = (struct lcrt_terminal *)user_data;
    debug_where();

    if (lterminal->connected != LCRT_TERMINAL_CONNECTED)
        return;
    lterminal->connected = FALSE;
    lterminal->child_pid = 0;
    debug_where();
#ifdef RESET
    vte_terminal_reset(VTE_TERMINAL(lterminal->terminal), TRUE, TRUE);
#endif
    debug_where();
    lcrt_terminal_set_status(lterminal, NULL, LCRT_TERMINAL_CHILD_EXIT);
    g_signal_connect ((gpointer) lterminal->terminal, "key-press-event",
                       G_CALLBACK (lcrt_terminal_on_key_press_event),
                       lterminal);
    debug_where();
    gtk_window_set_focus(GTK_WINDOW(lterminal->parent->parent->window), 
                     GTK_WIDGET(lterminal->terminal));
    debug_where();
    lterminal->signal_connected = TRUE;
    debug_print("child exit\n");
}
int lcrt_check_space_string(const char *text)
{
    if (text == NULL)
        return TRUE;
    const char *p = text;
    while ((*p == ' ' || *p == '\n') && *p != '\0')
        p++;

    if (*p != '\0')
        return FALSE;
    else
        return TRUE;
}

void lcrt_terminal_on_emulation_changed(VteTerminal *vteterminal, gpointer user_data)
{
    debug_print("emulation_changed\n");
    debug_where();
}
void lcrt_terminal_set_connected_status(struct lcrt_terminal *lterminal)
{
    struct lcrt_window *lwindow = lterminal->parent->parent;
    debug_print("Login success\n");
    lterminal->connected =TRUE;
    debug_where();
    lcrt_terminal_set_status(lterminal, NULL, LCRT_TERMINAL_CONNECTED);
    if (lterminal->signal_connected) {
        gtk_signal_disconnect_by_func(GTK_OBJECT(lterminal->terminal),
                                      G_CALLBACK(lcrt_terminal_on_key_press_event),
                                      lterminal);
        lterminal->signal_connected = FALSE;
    }
    gtk_window_set_focus(GTK_WINDOW(lwindow->window),
             GTK_WIDGET(lterminal->terminal));
    if (lterminal->save_passwd) {
        lcrt_user_save_one(&lwindow->u_config, lwindow->current_user);
    }

}
void lcrt_terminal_ssh_contens_changed(VteTerminal *vteterminal, gpointer user_data)
{
    struct lcrt_terminal *lterminal = (struct lcrt_terminal *)user_data;
    struct lcrt_window *lwindow = lterminal->parent->parent;
    struct lcrtc_user *user = lterminal->user;
    char *text;

    text = vte_terminal_get_text(vteterminal, NULL, NULL, NULL);
    if (lcrt_check_space_string(text)) {
        debug_print("text null\n");
        return;
    }
    if (strstr(text, "Connection timed out") != NULL) {
        vte_terminal_reset(VTE_TERMINAL(lterminal->terminal), TRUE, TRUE); 
        lcrt_message_error(lwindow->window,
                           lcrt_terminal_get_config(lterminal, LCRT_TM_CONNECTION_TIMEOUT)); 
        return;
    }
    if (strstr(text, "Connection refused") != NULL) {
        vte_terminal_reset(VTE_TERMINAL(lterminal->terminal), TRUE, TRUE); 
        lcrt_message_error(lwindow->window, 
                           lcrt_terminal_get_config(lterminal, LCRT_TM_CONNECTION_REFUSED));
        return;
    }
    if (strstr(text, "Permission denied") != NULL) {
        lterminal->again++;
        debug_print("Password or username error, try again %d\n", lterminal->again);

        vte_terminal_reset(VTE_TERMINAL(lterminal->terminal), TRUE, TRUE); 

        if (lterminal->again == 3) {
            //vte_terminal_feed(lterminal->terminal, "connect field\n", strlen("connect field\n"));
            lcrt_terminal_set_status(lterminal, NULL, LCRT_TERMINAL_DISCONNECT);
            lcrt_message_error(lterminal->parent->parent->window, 
                               lcrt_terminal_get_config(lterminal, LCRT_TM_CONNECTION_FAILED));
            lterminal->again = 0;
            return;
        }
        struct lcrt_login *login = lcrt_create_login(lterminal, TRUE);
        lterminal->login = login;
        if (lterminal->username_changed == TRUE) {
            kill(lterminal->child_pid, SIGKILL);
            lterminal->child_pid = 0;
            lterminal->username_changed = FALSE;
            lcrt_terminal_fork(lterminal);
            return;
        }
        //lcrt_terminal_fork(lterminal);
        debug_where();
        //return;
    }
    char password_alert[256];
    sprintf(password_alert, "%s@%s's password:", user->username, user->hostname);
    if (strstr(text, password_alert) != NULL) {

        vte_terminal_reset(VTE_TERMINAL(lterminal->terminal), TRUE, TRUE);

        /* 
         * there is no password or username, we should create 
         * a dialog to get username and password 
         */
        if (strlen(user->password) == 0 ||
            strlen(user->username) == 0) { /* ||
            (lterminal->connected == LCRT_TERMINAL_CONNECTING)) {*/
            debug_print("Enter username or password\n");
            struct lcrt_login *login = lcrt_create_login(lterminal, FALSE);
            lterminal->login = login;
            debug_where();
        }
        debug_print("Auto send username and password\n");
        if (lterminal->username_changed == TRUE) {
            kill(lterminal->child_pid, SIGKILL);
            lterminal->child_pid = 0;
            lterminal->username_changed = FALSE;
            lcrt_terminal_fork(lterminal);
            return;
        }
        vte_terminal_feed_child(vteterminal, user->password, strlen(user->password));
        vte_terminal_feed_child(vteterminal, LCRT_TERMINAL_SEND_CMD, 
                strlen(LCRT_TERMINAL_SEND_CMD));
        lcrt_terminal_set_status(lterminal, NULL, LCRT_TERMINAL_CONNECTING);
        debug_where();
        return;
    }

    if (strstr(text, "Are you sure you want to continue connecting") != NULL) {
        vte_terminal_feed_child(vteterminal, LCRT_TERMINAL_YES_CMD, strlen(LCRT_TERMINAL_YES_CMD));

        vte_terminal_reset(VTE_TERMINAL(lterminal->terminal), TRUE, TRUE); 
        lterminal->connected = LCRT_TERMINAL_WAIT_RETURN;

        debug_where();
        return;
    }
    if (lterminal->connected == LCRT_TERMINAL_WAIT_RETURN) {
        vte_terminal_reset(VTE_TERMINAL(lterminal->terminal), TRUE, TRUE);
        lterminal->connected = LCRT_TERMINAL_DISCONNECT;
        return;
    }
    //if (strstr(text, "Last login:") != NULL) 
    //if (lterminal->connected == LCRT_TERMINAL_CONNECTING || lterminal->connected != LCRT_TERMINAL_WAIT_RETURN)
        lcrt_terminal_set_connected_status(lterminal);
}
void lcrt_terminal_shell_contens_changed(VteTerminal *vteterminal, gpointer user_data)
{
    struct lcrt_terminal *lterminal = (struct lcrt_terminal *)user_data;
    lcrt_terminal_set_connected_status(lterminal);
    debug_print("reset = %f\n",
        gtk_adjustment_get_upper(
           gtk_scrolled_window_get_vadjustment(GTK_SCROLLED_WINDOW(lterminal->scrolledwindow))));
}
void lcrt_terminal_telnet_contens_changed(VteTerminal *vteterminal, gpointer user_data)
{
    struct lcrt_terminal *lterminal = (struct lcrt_terminal *)user_data;
    struct lcrt_window *lwindow = lterminal->parent->parent;
    struct lcrtc_user *user = lterminal->user;
    char *text;

    text = vte_terminal_get_text(vteterminal, NULL, NULL, NULL);
    if (lcrt_check_space_string(text)) {
        debug_print("text null\n");
        return;
    }

    if (strstr(text, "Connection refused") != NULL ||
        strstr(text, "Connection closed") != NULL) {
        lcrt_message_error(lwindow->window, 
                           lcrt_terminal_get_config(lterminal, LCRT_TM_CONNECTION_REFUSED));
        return;
    }
    if (strstr(text, "Login incorrect") != NULL) {
        vte_terminal_reset(VTE_TERMINAL(lterminal->terminal), TRUE, TRUE);
        struct lcrt_login *login = lcrt_create_login(lterminal, TRUE);
        lterminal->login = login;
    }
    if (strstr(text, "login:") != NULL && 
        (lterminal->connected & LCRT_TERMINAL_SEND_USERNAME) == 0) {
        vte_terminal_reset(VTE_TERMINAL(lterminal->terminal), TRUE, TRUE);
        if (strlen(user->username) == 0) {
            struct lcrt_login *login = lcrt_create_login(lterminal, FALSE);
            lterminal->login = login;
            debug_where();
        }
        debug_where();
        lterminal->connected |= LCRT_TERMINAL_SEND_USERNAME;
        vte_terminal_feed_child(vteterminal, user->username, strlen(user->username));
        vte_terminal_feed_child(vteterminal, LCRT_TERMINAL_SEND_CMD, 
                                strlen(LCRT_TERMINAL_SEND_CMD));
        vte_terminal_reset(VTE_TERMINAL(lterminal->terminal), TRUE, TRUE);
        return;
    }
    if (strstr(text, "Password:") != NULL) {
        vte_terminal_reset(VTE_TERMINAL(lterminal->terminal), TRUE, TRUE);
        if (strlen(user->password) == 0) {
            struct lcrt_login *login = lcrt_create_login(lterminal, FALSE);
            lterminal->login = login;
            debug_where();
        }
        debug_where();
        lterminal->connected |= LCRT_TERMINAL_SEND_PASSWORD;
        vte_terminal_feed_child(vteterminal, user->password, strlen(user->password));
        vte_terminal_feed_child(vteterminal, LCRT_TERMINAL_SEND_CMD, 
                                strlen(LCRT_TERMINAL_SEND_CMD));
        vte_terminal_reset(VTE_TERMINAL(lterminal->terminal), TRUE, TRUE);
        return;
    }
    if (lterminal->connected == (LCRT_TERMINAL_SEND_USERNAME | LCRT_TERMINAL_SEND_PASSWORD))
        lcrt_terminal_set_connected_status(lterminal);
}
void test(VteTerminal *vteterminal, gpointer user_data)
{
    //printf("%s\n", vteterminal->pvt->incoming->data);
}
void lcrt_terminal_on_contents_changed(VteTerminal *vteterminal, gpointer user_data)
{
    debug_where();
    struct lcrt_terminal *lterminal = (struct lcrt_terminal *)user_data;
    struct lcrtc_user *user = lterminal->user;
    lcrt_protocol_t protocol = user->protocol;
    if (lterminal->connected == TRUE)
        return;
    //lcrtc_user_dump(user, __func__);
    switch(protocol) {
    case LCRT_PROTOCOL_SSH2:
    case LCRT_PROTOCOL_SSH1:
        lcrt_terminal_ssh_contens_changed(vteterminal, lterminal);
        break;
    case LCRT_PROTOCOL_TELNET:
        lcrt_terminal_telnet_contens_changed(vteterminal, lterminal);
        break;
    case LCRT_PROTOCOL_SHELL:
        lcrt_terminal_shell_contens_changed(vteterminal, lterminal);
        break;
    default:
        break;
    }
}
gboolean lcrt_terminal_on_label_title_button_press_event(GtkWidget *widget,
            GdkEventButton  *event, gpointer user_data)
{
    struct lcrt_terminal *lterminal = (struct lcrt_terminal *)user_data;
    debug_where();
    if (event->type == GDK_BUTTON_PRESS && event->button == BUTTON_RIGHT) {
        struct lcrt_popup *lpopup = lcrt_create_popup_menu(lterminal);
            gtk_menu_popup (GTK_MENU(lpopup->popup_menu),
                       NULL, NULL, NULL, NULL,
                       event->button, event->time);
        debug_print("Create popup menu\n");
    }
    return FALSE;
}
gboolean lcrt_terminal_on_button_press_event(GtkWidget *widget,
            GdkEventButton  *event, gpointer user_data)
{
    struct lcrt_terminal *lterminal = (struct lcrt_terminal *)user_data;
    debug_where();
    if (event->type == GDK_BUTTON_PRESS && event->button == BUTTON_RIGHT && 
        lterminal->connected == LCRT_TERMINAL_CONNECTED) {
        struct lcrt_edit *ledit = lcrt_edit_create_menuitem(lterminal->parent->parent->w_menubar, TRUE);
        g_signal_connect ((gpointer) ledit->e_menuitem, "deactivate",
                    G_CALLBACK(lcrt_edit_on_popup_menu_deactivate),
                    ledit);
            gtk_menu_popup (GTK_MENU(ledit->e_menuitem),
                       NULL, NULL, NULL, NULL,
                       event->button, event->time);

        debug_print("Create popup menu for terminal = %p\n", ledit);

    }
    return FALSE;
}

void lcrt_terminal_on_selection_changed(VteTerminal *vteterminal, gpointer user_data)
{
    struct lcrt_terminal *lterminal = (struct lcrt_terminal *)user_data;
    struct lcrt_toolbar *ltoolbar = lterminal->parent->parent->w_toolbar;
    gboolean selected = vte_terminal_get_has_selection(lterminal->terminal);
    
    gtk_widget_set_sensitive(ltoolbar->toolitem[LCRT_B_COPY], selected);
    gtk_widget_set_sensitive(ltoolbar->toolitem[LCRT_B_PASTE], lterminal->connected == LCRT_TERMINAL_CONNECTED);
}
void lcrt_terminal_on_button_close_clicked(GtkButton *button, gpointer user_data)
{
    debug_where();
    struct lcrt_terminal *lterminal = (struct lcrt_terminal *)user_data;
    int rv = TRUE;

    if (lterminal->user->protocol != LCRT_PROTOCOL_SHELL && lterminal->connected == LCRT_TERMINAL_CONNECTED) {
        rv = lcrt_message_choose(lterminal->parent->parent->window,
                             GTK_MESSAGE_WARNING,
                             lterminal->parent->parent->w_status->config.value[LCRT_S_SESSION_DISCONNECT],
                             lterminal->user->hostname);
    }
    if (rv == TRUE)
        lcrt_destroy_terminal(lterminal);
}

gboolean lcrt_terminal_has_selection(struct lcrt_window *lwindow)
{
    if (lwindow == NULL || lwindow->w_notebook == NULL ||
        lwindow->w_notebook->current_terminal == NULL)
        return FALSE;
    return vte_terminal_get_has_selection(lwindow->w_notebook->current_terminal->terminal);
}

Generated by  Doxygen 1.6.0   Back to index