コード例 #1
0
ファイル: ui_call_list.c プロジェクト: dynax60/sngrep
void
call_list_destroy(PANEL *panel)
{
    call_list_info_t *info;

    // Free its status data
    if ((info = call_list_info(panel))) {
        // Deallocate forms data
        if (info->form) {
            unpost_form(info->form);
            free_form(info->form);
            free_field(info->fields[FLD_LIST_FILTER]);
        }

        // Deallocate group data
        call_group_destroy(info->group);

        // Deallocate panel windows
        delwin(info->list_win);
        sng_free(info);
    }

    // Deallocate panel window
    delwin(panel_window(panel));
    // Deallocate panel pointer
    del_panel(panel);
}
コード例 #2
0
ファイル: ui_column_select.c プロジェクト: cruzccl/sngrep
void
column_select_update_columns(ui_t *ui)
{
    int column, attr_id;

    // Get panel information
    column_select_info_t *info = column_select_info(ui);

    // Set enabled fields
    ui_t *ui_list = ui_find_by_type(PANEL_CALL_LIST);
    call_list_info_t *list_info = call_list_info(ui_list);

    // Reset column count
    list_info->columncnt = 0;

    // Add all selected columns
    for (column = 0; column < item_count(info->menu); column++) {
        // If column is active
        if (!strncmp(item_name(info->items[column]), "[ ]", 3))
            continue;

        // Get column attribute
        attr_id = sip_attr_from_name(item_userptr(info->items[column]));
        // Add a new column to the list
        call_list_add_column(ui_list, attr_id, sip_attr_get_name(attr_id),
                             sip_attr_get_title(attr_id), sip_attr_get_width(attr_id));
    }
}
コード例 #3
0
ファイル: ui_call_list.c プロジェクト: dynax60/sngrep
void
call_list_draw_header(PANEL *panel)
{
    const char *infile, *coldesc;
    int height, width, colpos, collen, i;

    // Get panel info
    call_list_info_t *info = call_list_info(panel);

    // Let's draw the fixed elements of the screen
    WINDOW *win = panel_window(panel);
    getmaxyx(win, height, width);

    // Draw panel title
    draw_title(panel, "sngrep - SIP messages flow viewer");

    // Draw a Panel header lines
    clear_line(win, 1);
    if ((infile = capture_get_infile()))
        mvwprintw(win, 1, width - strlen(infile) - 11, "Filename: %s", infile);
    mvwprintw(win, 2, 2, "Display Filter: ");
    mvwprintw(win, 1, 2, "Current Mode: %s", capture_get_status_desc());

    // Reverse colors on monochrome terminals
    if (!has_colors())
        wattron(win, A_REVERSE);

    // Draw columns titles
    wattron(win, A_BOLD | COLOR_PAIR(CP_DEF_ON_CYAN));
    mvwprintw(win, 3, 0, "%*s", width, "");
    for (colpos = 6, i = 0; i < info->columncnt; i++) {
        // Get current column width
        collen = info->columns[i].width;
        // Get current column title
        coldesc = sip_attr_get_title(info->columns[i].id);

        // Check if the column will fit in the remaining space of the screen
        if (colpos + strlen(coldesc) >= width)
            break;
        mvwprintw(win, 3, colpos, "%.*s", collen, coldesc);
        colpos += collen + 1;
    }
    // Print Autoscroll indicator
    if (info->autoscroll)
        mvwprintw(win, 3, 0, "A");
    wattroff(win, A_BOLD | A_REVERSE | COLOR_PAIR(CP_DEF_ON_CYAN));

    // Get filter call counters
    sip_calls_stats(&info->callcnt, &info->dispcallcnt);

    // Print calls count (also filtered)
    mvwprintw(win, 1, 35, "%*s", 35, "");
    if (info->callcnt != info->dispcallcnt) {
        mvwprintw(win, 1, 35, "Dialogs: %d (%d displayed)", info->callcnt, info->dispcallcnt);
    } else {
        mvwprintw(win, 1, 35, "Dialogs: %d", info->callcnt);
    }

}
コード例 #4
0
ファイル: ui_call_list.c プロジェクト: dynax60/sngrep
const char *
call_list_line_text(PANEL *panel, sip_call_t *call, char *text)
{
    int i, collen;
    char call_attr[256];
    char coltext[256];
    int colid;
    int width;

    WINDOW *win = panel_window(panel);

    // Get window width
    width = getmaxx(win);

    // Get panel info
    call_list_info_t *info = call_list_info(panel);

    // Print requested columns
    for (i = 0; i < info->columncnt; i++) {

        // Get current column id
        colid = info->columns[i].id;

        // Get current column width
        collen = info->columns[i].width;

        // Check if next column fits on window width
        if (strlen(text) + collen >= width)
            collen = width - strlen(text);

        // If no space left on the screen stop processing columns
        if (collen <= 0)
            break;

        // Initialize column text
        memset(coltext, 0, sizeof(coltext));
        memset(call_attr, 0, sizeof(call_attr));

        // Get call attribute for current column
        if (call_get_attribute(call, colid, call_attr)) {
            sprintf(coltext, "%.*s", collen, call_attr);
        }
        // Add the column text to the existing columns
        sprintf(text + strlen(text), "%-*s ", collen, coltext);
    }

    return text;
}
コード例 #5
0
ファイル: ui_call_list.c プロジェクト: dynax60/sngrep
int
call_list_add_column(PANEL *panel, enum sip_attr_id id, const char* attr, const char *title,
                     int width)
{
    call_list_info_t *info;

    if (!(info = call_list_info(panel)))
        return 1;

    info->columns[info->columncnt].id = id;
    info->columns[info->columncnt].attr = attr;
    info->columns[info->columncnt].title = title;
    info->columns[info->columncnt].width = width;
    info->columncnt++;
    return 0;
}
コード例 #6
0
ファイル: ui_call_list.c プロジェクト: dynax60/sngrep
void
call_list_clear(PANEL *panel)
{
    call_list_info_t *info;

    // Get panel info
    if (!(info = call_list_info(panel)))
        return;

    // Initialize structures
    info->first_call = info->cur_call = -1;
    info->first_line = info->cur_line = 0;
    vector_clear(info->group->calls);

    // Clear Displayed lines
    werase(info->list_win);
}
コード例 #7
0
ファイル: ui_call_list.c プロジェクト: dynax60/sngrep
int
call_list_resize(PANEL *panel)
{
    int maxx, maxy;

    // Get panel info
    call_list_info_t *info = call_list_info(panel);
    // Get current screen dimensions
    getmaxyx(stdscr, maxy, maxx);

    // Change the main window size
    wresize(panel_window(panel), maxy, maxx);
    // Calculate available printable area
    wresize(info->list_win, maxy - 5, maxx - 4);
    // Force list redraw
    call_list_clear(panel);

    return 0;
}
コード例 #8
0
ファイル: ui_call_list.c プロジェクト: dynax60/sngrep
void
call_list_form_activate(PANEL *panel, int active)
{
    call_list_info_t *info = call_list_info(panel);

    // Store form state
    info->form_active = active;

    if (active) {
        set_current_field(info->form, info->fields[FLD_LIST_FILTER]);
        // Show cursor
        curs_set(1);
        // Change current field background
        set_field_back(info->fields[FLD_LIST_FILTER], A_REVERSE);
    } else {
        set_current_field(info->form, NULL);
        // Hide cursor
        curs_set(0);
        // Change current field background
        set_field_back(info->fields[FLD_LIST_FILTER], A_NORMAL);
    }
    post_form(info->form);
    form_driver(info->form, REQ_END_LINE);
}
コード例 #9
0
ファイル: ui_column_select.c プロジェクト: cruzccl/sngrep
void
column_select_create(ui_t *ui)
{
    int attr_id, column;
    MENU *menu;
    column_select_info_t *info;

    // Cerate a new indow for the panel and form
    ui_panel_create(ui, 20, 60);

    // Initialize Filter panel specific data
    info = sng_malloc(sizeof(column_select_info_t));

    // Store it into panel userptr
    set_panel_userptr(ui->panel, (void*) info);

    // Initialize the fields
    info->fields[FLD_COLUMNS_ACCEPT] = new_field(1, 10, ui->height - 2, 13, 0, 0);
    info->fields[FLD_COLUMNS_SAVE]   = new_field(1, 10, ui->height - 2, 25, 0, 0);
    info->fields[FLD_COLUMNS_CANCEL] = new_field(1, 10, ui->height - 2, 37, 0, 0);
    info->fields[FLD_COLUMNS_COUNT] = NULL;

    // Field Labels
    set_field_buffer(info->fields[FLD_COLUMNS_ACCEPT], 0, "[ Accept ]");
    set_field_buffer(info->fields[FLD_COLUMNS_SAVE],   0, "[  Save  ]");
    set_field_buffer(info->fields[FLD_COLUMNS_CANCEL], 0, "[ Cancel ]");

    // Create the form and post it
    info->form = new_form(info->fields);
    set_form_sub(info->form, ui->win);
    post_form(info->form);

    // Create a subwin for the menu area
    info->menu_win = derwin(ui->win, 10, ui->width - 2, 7, 0);

    // Initialize one field for each attribute
    for (attr_id = 0; attr_id < SIP_ATTR_COUNT; attr_id++) {
        // Create a new field for this column
        info->items[attr_id] = new_item("[ ]", sip_attr_get_description(attr_id));
        set_item_userptr(info->items[attr_id], (void*) sip_attr_get_name(attr_id));
    }
    info->items[SIP_ATTR_COUNT] = NULL;

    // Create the columns menu and post it
    info->menu = menu = new_menu(info->items);

    // Set current enabled fields
    // FIXME Stealing Call list columns :/
    call_list_info_t *list_info = call_list_info(ui_find_by_type(PANEL_CALL_LIST));

    // Enable current enabled fields and move them to the top
    for (column = 0; column < list_info->columncnt; column++) {
        const char *attr = list_info->columns[column].attr;
        for (attr_id = 0; attr_id < item_count(menu); attr_id++) {
            if (!strcmp(item_userptr(info->items[attr_id]), attr)) {
                column_select_toggle_item(ui, info->items[attr_id]);
                column_select_move_item(ui, info->items[attr_id], column);
                break;
            }
        }
    }

    // Set main window and sub window
    set_menu_win(menu, ui->win);
    set_menu_sub(menu, derwin(ui->win, 10, ui->width - 5, 7, 2));
    set_menu_format(menu, 10, 1);
    set_menu_mark(menu, "");
    set_menu_fore(menu, COLOR_PAIR(CP_DEF_ON_BLUE));
    menu_opts_off(menu, O_ONEVALUE);
    post_menu(menu);

    // Draw a scrollbar to the right
    info->scroll = ui_set_scrollbar(info->menu_win, SB_VERTICAL, SB_RIGHT);
    info->scroll.max = item_count(menu) - 1;
    ui_scrollbar_draw(info->scroll);

    // Set the window title and boxes
    mvwprintw(ui->win, 1, ui->width / 2 - 14, "Call List columns selection");
    wattron(ui->win, COLOR_PAIR(CP_BLUE_ON_DEF));
    title_foot_box(ui->panel);
    mvwhline(ui->win, 6, 1, ACS_HLINE, ui->width - 1);
    mvwaddch(ui->win, 6, 0, ACS_LTEE);
    mvwaddch(ui->win, 6, ui->width - 1, ACS_RTEE);
    wattroff(ui->win, COLOR_PAIR(CP_BLUE_ON_DEF));

    // Some brief explanation abotu what window shows
    wattron(ui->win, COLOR_PAIR(CP_CYAN_ON_DEF));
    mvwprintw(ui->win, 3, 2, "This windows show the list of columns displayed on Call");
    mvwprintw(ui->win, 4, 2, "List. You can enable/disable using Space Bar and reorder");
    mvwprintw(ui->win, 5, 2, "them using + and - keys.");
    wattroff(ui->win, COLOR_PAIR(CP_CYAN_ON_DEF));

    info->form_active = 0;
}
コード例 #10
0
ファイル: ui_call_list.c プロジェクト: dynax60/sngrep
int
call_list_handle_form_key(PANEL *panel, int key)
{
    int field_idx;
    char dfilter[256];
    int action = -1;

    // Get panel information
    call_list_info_t *info = call_list_info(panel);

    // Get current field id
    field_idx = field_index(current_field(info->form));

    // Check actions for this key
    while ((action = key_find_action(key, action)) != ERR) {
        // Check if we handle this action
        switch (action) {
            case ACTION_PRINTABLE:
                // If this is a normal character on input field, print it
                form_driver(info->form, key);
                break;
            case ACTION_PREV_SCREEN:
            case ACTION_NEXT_FIELD:
            case ACTION_CONFIRM:
            case ACTION_SELECT:
            case ACTION_UP:
            case ACTION_DOWN:
                // Activate list
                call_list_form_activate(panel, 0);
                break;
            case ACTION_RIGHT:
                form_driver(info->form, REQ_RIGHT_CHAR);
                break;
            case ACTION_LEFT:
                form_driver(info->form, REQ_LEFT_CHAR);
                break;
            case ACTION_BEGIN:
                form_driver(info->form, REQ_BEG_LINE);
                break;
            case ACTION_END:
                form_driver(info->form, REQ_END_LINE);
                break;
            case ACTION_CLEAR:
                form_driver(info->form, REQ_BEG_LINE);
                form_driver(info->form, REQ_CLR_EOL);
                break;
            case ACTION_DELETE:
                form_driver(info->form, REQ_DEL_CHAR);
                break;
            case ACTION_BACKSPACE:
                form_driver(info->form, REQ_DEL_PREV);
                break;
            default:
                // Parse next action
                continue;
        }

        // We've handled this key, stop checking actions
        break;
    }

    // Filter has changed, re-apply filter to displayed calls
    if (action == ACTION_PRINTABLE || action == ACTION_BACKSPACE ||
            action == ACTION_DELETE || action == ACTION_CLEAR) {
        // Updated displayed results
         call_list_clear(panel);
         // Reset filters on each key stroke
         filter_reset_calls();
    }

    // Validate all input data
    form_driver(info->form, REQ_VALIDATION);

    // Store dfilter input
    // We trim spaces with sscanf because and empty field is stored as space characters
    memset(dfilter, 0, sizeof(dfilter));
    strcpy(dfilter, field_buffer(info->fields[FLD_LIST_FILTER], 0));
    strtrim(dfilter);

    // Set display filter
    filter_set(FILTER_CALL_LIST, strlen(dfilter) ? dfilter : NULL);

    // Return if this panel has handled or not the key
    return (action == ERR) ? key : 0;
}
コード例 #11
0
ファイル: ui_call_list.c プロジェクト: dynax60/sngrep
int
call_list_handle_key(PANEL *panel, int key)
{
    int i, height, width, rnpag_steps = setting_get_intvalue(SETTING_CL_SCROLLSTEP);
    call_list_info_t *info;
    ui_t *next_panel;
    sip_call_group_t *group;
    int action = -1;
    sip_call_t *call;

    // Sanity check, this should not happen
    if (!(info  = call_list_info(panel)))
        return -1;

    // Handle form key
    if (info->form_active)
        return call_list_handle_form_key(panel, key);

    // Get window of call list panel
    WINDOW *win = info->list_win;
    getmaxyx(win, height, width);

    // Reset iterator position to current call
    vector_iterator_set_current(&info->calls, info->cur_call);

    // Check actions for this key
    while ((action = key_find_action(key, action)) != ERR) {
        // Check if we handle this action
        switch (action) {
            case ACTION_DOWN:
                // Check if there is a call below us
                if (!vector_iterator_next(&info->calls))
                    break;
                info->cur_call = vector_iterator_current(&info->calls);
                info->cur_line++;
                // If we are out of the bottom of the displayed list
                // refresh it starting in the next call
                if (info->cur_line > height) {
                    vector_iterator_set_current(&info->calls, info->first_call);
                    vector_iterator_next(&info->calls);
                    info->first_call = vector_iterator_current(&info->calls);
                    info->first_line++;
                    info->cur_line = height;
                }
                // Disable Autoscroll
                info->autoscroll = 0;
                break;
            case ACTION_UP:
                // Check if there is a call above us
                if (!vector_iterator_prev(&info->calls))
                    break;
                info->cur_call = vector_iterator_current(&info->calls);
                info->cur_line--;
                // If we are out of the top of the displayed list
                // refresh it starting in the previous (in fact current) call
                if (info->cur_line <= 0) {
                    info->first_call = info->cur_call;
                    info->first_line--;
                    info->cur_line = 1;
                }
                // Disable Autoscroll
                info->autoscroll = 0;
                break;
            case ACTION_HNPAGE:
                rnpag_steps = rnpag_steps / 2;
                /* no break */
            case ACTION_NPAGE:
                // Next page => N key down strokes
                for (i = 0; i < rnpag_steps; i++)
                    call_list_handle_key(panel, KEY_DOWN);
                // Disable Autoscroll
                info->autoscroll = 0;
                break;
            case ACTION_HPPAGE:
                rnpag_steps = rnpag_steps / 2;
                /* no break */
            case ACTION_PPAGE:
                // Prev page => N key up strokes
                for (i = 0; i < rnpag_steps; i++)
                    call_list_handle_key(panel, KEY_UP);
                // Disable Autoscroll
                info->autoscroll = 0;
                break;
            case ACTION_BEGIN:
                // Initialize structures
                info->first_call = info->cur_call = -1;
                info->first_line = info->cur_line = 0;
                // Disable Autoscroll
                info->autoscroll = 0;
                break;
            case ACTION_END:
                // Check if there is a call below us
                while (vector_iterator_next(&info->calls)) {
                    info->cur_call = vector_iterator_current(&info->calls);
                    info->cur_line++;
                    // If we are out of the bottom of the displayed list
                    // refresh it starting in the next call
                    if (info->cur_line > height) {
                        vector_iterator_set_current(&info->calls, info->first_call);
                        vector_iterator_next(&info->calls);
                        info->first_call = vector_iterator_current(&info->calls);
                        info->first_line++;
                        info->cur_line = height;
                        vector_iterator_set_current(&info->calls, info->cur_call);
                    }
                }
                break;
            case ACTION_DISP_FILTER:
                // Activate Form
                call_list_form_activate(panel, 1);
                // Disable Autoscroll
                info->autoscroll = 0;
                break;
            case ACTION_SHOW_FLOW:
            case ACTION_SHOW_FLOW_EX:
            case ACTION_SHOW_RAW:
                // Check we have calls in the list
                if (info->cur_call == -1)
                    break;
                // Create a new group of calls
                group = call_group_clone(info->group);
                // If not selected call, show current call flow
                if (call_group_count(info->group) == 0)
                    call_group_add(group, sip_find_by_index(info->cur_call));

                // Add xcall to the group
                if (action == ACTION_SHOW_FLOW_EX)
                    call_group_add(group, call_get_xcall(sip_find_by_index(info->cur_call)));

                if (action == ACTION_SHOW_RAW) {
                    // Create a Call Flow panel
                    ui_create_panel(PANEL_CALL_RAW);
                    call_raw_set_group(group);
                } else {
                    // Display current call flow (normal or extended)
                    ui_create_panel(PANEL_CALL_FLOW);
                    call_flow_set_group(group);
                }
                break;
            case ACTION_SHOW_FILTERS:
                ui_create_panel(PANEL_FILTER);
                break;
            case ACTION_SHOW_COLUMNS:
                ui_create_panel(PANEL_COLUMN_SELECT);
                break;
            case ACTION_SHOW_STATS:
                ui_create_panel(PANEL_STATS);
                break;
            case ACTION_SAVE:
                next_panel = ui_create_panel(PANEL_SAVE);
                save_set_group(ui_get_panel(next_panel), info->group);
                break;
            case ACTION_CLEAR:
                // Clear group calls
                vector_clear(info->group->calls);
                break;
            case ACTION_CLEAR_CALLS:
                // Remove all stored calls
                sip_calls_clear();
                // Clear List
                call_list_clear(panel);
                break;
            case ACTION_AUTOSCROLL:
                info->autoscroll = (info->autoscroll) ? 0 : 1;
                break;
            case ACTION_SHOW_SETTINGS:
                ui_create_panel(PANEL_SETTINGS);
                break;
            case ACTION_SELECT:
                call = vector_item(vector_iterator_vector(&info->calls), info->cur_call);
                if (call_group_exists(info->group, call)) {
                    call_group_del(info->group, call);
                } else {
                    call_group_add(info->group, call);
                }
                break;
            case ACTION_PREV_SCREEN:
                // Handle quit from this screen unless requested
                if (setting_enabled(SETTING_EXITPROMPT)) {
                    if (dialog_confirm("Confirm exit", "Are you sure you want to quit?", "Yes,No") == 0) {
                        return KEY_ESC;
                    } else {
                        return 0;
                    }
                } else {
                    return KEY_ESC;
                }
                break;
            default:
                // Parse next action
                continue;
        }

        // This panel has handled the key successfully
        break;
    }

    // Return if this panel has handled or not the key
    return (action == ERR) ? key : 0;
}
コード例 #12
0
ファイル: ui_call_list.c プロジェクト: dynax60/sngrep
void
call_list_draw_list(PANEL *panel)
{
    WINDOW *win;
    int height, width, cline = 0;
    struct sip_call *call;
    int i, collen;
    char coltext[256];
    int colid;
    int colpos;
    int color;

    // Get panel info
    call_list_info_t *info = call_list_info(panel);

    // Get window of call list panel
    win = info->list_win;
    getmaxyx(win, height, width);

    // If autoscroll is enabled, select the last dialog
    if (info->autoscroll) {
        call_list_handle_key(panel, key_action_key(ACTION_END));
    }

    // If no active call, use the fist one (if exists)
    if (info->first_call == -1 && vector_iterator_count(&info->calls)) {
        vector_iterator_reset(&info->calls);
        call = vector_iterator_next(&info->calls);
        info->cur_call = info->first_call = vector_index(vector_iterator_vector(&info->calls), call);
        info->cur_line = info->first_line = 1;
    }

    // Clear call list before redrawing
    werase(win);

    // Set the iterator position to the first call
    vector_iterator_set_current(&info->calls, info->first_call - 1 );

    // Fill the call list
    while ((call = vector_iterator_next(&info->calls))) {
        // Stop if we have reached the bottom of the list
        if (cline == height)
            break;

        // We only print calls with messages (In fact, all call should have msgs)
        if (!call_msg_count(call))
            continue;

        // Show bold selected rows
        if (call_group_exists(info->group, call))
            wattron(win, A_BOLD | COLOR_PAIR(CP_DEFAULT));

        // Highlight active call
        if (call->index == info->cur_call + 1) {
            wattron(win, COLOR_PAIR(CP_WHITE_ON_BLUE));
            // Reverse colors on monochrome terminals
            if (!has_colors())
                wattron(win, A_REVERSE);
        }
        // Set current line background
        clear_line(win, cline);
        // Set current line selection box
        mvwprintw(win, cline, 2, call_group_exists(info->group, call) ? "[*]" : "[ ]");

        // Print requested columns
        colpos = 6;
        for (i = 0; i < info->columncnt; i++) {
            // Get current column id
            colid = info->columns[i].id;
            // Get current column width
            collen = info->columns[i].width;
            // Check if next column fits on window width
            if (colpos + collen >= width)
                break;

            // Initialize column text
            memset(coltext, 0, sizeof(coltext));

            // Get call attribute for current column
            if (!call_get_attribute(call, colid, coltext)) {
                colpos += collen + 1;
                continue;
            }

            // Enable attribute color (if not current one)
            color = 0;
            if (call->index != info->cur_call + 1 && (color = sip_attr_get_color(colid, coltext)) > 0)
                wattron(win, color);

            // Add the column text to the existing columns
            mvwprintw(win, cline, colpos, "%.*s", collen, coltext);
            colpos += collen + 1;

            // Disable attribute color
            if (color > 0)
                wattroff(win, color);
        }
        cline++;

        wattroff(win, COLOR_PAIR(CP_DEFAULT));
        wattroff(win, COLOR_PAIR(CP_DEF_ON_BLUE));
        wattroff(win, A_BOLD | A_REVERSE);
    }

    // Draw scrollbar to the right
    draw_vscrollbar(win, info->first_line, info->dispcallcnt, 1);
    wnoutrefresh(info->list_win);

}