sip_stats_t sip_calls_stats() { sip_stats_t stats; vector_iter_t it = vector_iterator(calls.list); // Total number of calls without filtering stats.total = vector_iterator_count(&it); // Total number of calls after filtering vector_iterator_set_filter(&it, filter_check_call); stats.displayed = vector_iterator_count(&it); return stats; }
int call_group_msg_count(sip_call_group_t *group) { sip_call_t *call; vector_iter_t msgs; int msgcnt = 0, i; for (i = 0; i < vector_count(group->calls); i++) { call = vector_item(group->calls, i); msgs = vector_iterator(call->msgs); if (group->sdp_only) { vector_iterator_set_filter(&msgs, msg_has_sdp); } msgcnt += vector_iterator_count(&msgs); } return msgcnt; }
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); }
int save_to_file(ui_t *ui) { char savepath[256]; char savefile[256]; char fullfile[512]; sip_call_t *call = NULL; sip_msg_t *msg = NULL; pcap_dumper_t *pd = NULL; FILE *f = NULL; int cur = 0, total = 0; WINDOW *progress; vector_iter_t calls, msgs, rtps, packets; packet_t *packet; vector_t *sorted; // Get panel information save_info_t *info = save_info(ui); // Get current path field value. memset(savepath, 0, sizeof(savepath)); strcpy(savepath, field_buffer(info->fields[FLD_SAVE_PATH], 0)); strtrim(savepath); if (strlen(savepath)) strcat(savepath, "/"); // Get current file field value. memset(savefile, 0, sizeof(savefile)); strcpy(savefile, field_buffer(info->fields[FLD_SAVE_FILE], 0)); strtrim(savefile); if (!strlen(savefile)) { dialog_run("Please enter a valid filename"); return 1; } if (info->saveformat == SAVE_PCAP || info->saveformat == SAVE_PCAP_RTP) { if (!strstr(savefile, ".pcap")) strcat(savefile, ".pcap"); } else { if (!strstr(savefile, ".txt")) strcat(savefile, ".txt"); } // Absolute filename sprintf(fullfile, "%s%s", savepath, savefile); if (access(fullfile, R_OK) == 0) { if (dialog_confirm("Overwrite confirmation", "Selected file already exits.\n Do you want to overwrite it?", "Yes,No") != 0) return 1; } // Don't allow to save no packets! if (info->savemode == SAVE_SELECTED && call_group_msg_count(info->group) == 0) { dialog_run("Unable to save: No selected dialogs."); return 1; } if (info->saveformat == SAVE_PCAP || info->saveformat == SAVE_PCAP_RTP) { // Open dump file pd = dump_open(fullfile); if (access(fullfile, W_OK) != 0) { dialog_run(capture_last_error()); return 1; } } else { // Open a text file if (!(f = fopen(fullfile, "w"))) { dialog_run("Error: %s", strerror(errno)); return 0; } } // Get calls iterator switch (info->savemode) { case SAVE_ALL: // Get calls iterator calls = sip_calls_iterator(); break; case SAVE_SELECTED: // Save selected packets to file calls = vector_iterator(info->group->calls); break; case SAVE_DISPLAYED: // Set filtering for this iterator calls = sip_calls_iterator(); vector_iterator_set_filter(&calls, filter_check_call); break; default: break; } if (info->savemode == SAVE_MESSAGE) { if (info->saveformat == SAVE_TXT) { // Save selected message to file save_msg_txt(f, info->msg); } else { // Save selected message packet to pcap dump_packet(pd, info->msg->packet); } } else if (info->saveformat == SAVE_TXT) { // Save selected packets to file while ((call = vector_iterator_next(&calls))) { msgs = vector_iterator(call->msgs); // Save SIP message content while ((msg = vector_iterator_next(&msgs))) { save_msg_txt(f, msg); } } } else { // Store all messages in a time sorted vector sorted = vector_create(100, 50); vector_set_sorter(sorted, capture_packet_time_sorter); // Count packages for progress bar while ((call = vector_iterator_next(&calls))) { total += vector_count(call->msgs); if (info->saveformat == SAVE_PCAP_RTP) total += vector_count(call->rtp_packets); } vector_iterator_reset(&calls); progress = dialog_progress_run("Saving packets..."); dialog_progress_set_value(progress, 0); // Save selected packets to file while ((call = vector_iterator_next(&calls))) { msgs = vector_iterator(call->msgs); // Save SIP message content while ((msg = vector_iterator_next(&msgs))) { // Update progress bar dialog dialog_progress_set_value(progress, (++cur * 100) / total); vector_append(sorted, msg->packet); } // Save RTP packets if (info->saveformat == SAVE_PCAP_RTP) { rtps = vector_iterator(call->rtp_packets); while ((packet = vector_iterator_next(&rtps))) { // Update progress bar dialog dialog_progress_set_value(progress, (++cur * 100) / total); vector_append(sorted, packet); } } } // Save sorted packets packets = vector_iterator(sorted); while ((packet = vector_iterator_next(&packets))) { dump_packet(pd, packet); } dialog_progress_destroy(progress); } // Close saved file if (info->saveformat == SAVE_PCAP || info->saveformat == SAVE_PCAP_RTP) { dump_close(pd); } else { fclose(f); } // Show success popup if (info->savemode == SAVE_MESSAGE) { dialog_run("Successfully saved selected SIP message to %s", savefile); } else { dialog_run("Successfully saved %d dialogs to %s", vector_iterator_count(&calls), savefile); } return 0; }