void FollowStreamDialog::addText(QString text, gboolean is_from_server, guint32 packet_num) { if (save_as_ == true) { size_t nwritten; int FileDescriptor = file_.handle(); int fd_new = ws_dup(FileDescriptor); if (fd_new == -1) return; FILE* fh = ws_fdopen(fd_new, "wb"); if (show_type_ == SHOW_RAW) { QByteArray binstream = QByteArray::fromHex(text.toUtf8()); nwritten = fwrite(binstream.constData(), binstream.length(), 1, fh); } else { nwritten = fwrite(text.toUtf8().constData(), text.length(), 1, fh); } fclose(fh); if ((int)nwritten != text.length()) { #if 0 report_an_error_maybe(); #endif } return; } if (truncated_) { return; } int char_count = ui->teStreamContent->document()->characterCount(); if (char_count + text.length() > max_document_length_) { text.truncate(max_document_length_ - char_count); truncated_ = true; } setUpdatesEnabled(false); int cur_pos = ui->teStreamContent->verticalScrollBar()->value(); ui->teStreamContent->moveCursor(QTextCursor::End); QTextCharFormat tcf = ui->teStreamContent->currentCharFormat(); if (is_from_server) { tcf.setForeground(ColorUtils::fromColorT(prefs.st_server_fg)); tcf.setBackground(ColorUtils::fromColorT(prefs.st_server_bg)); } else { tcf.setForeground(ColorUtils::fromColorT(prefs.st_client_fg)); tcf.setBackground(ColorUtils::fromColorT(prefs.st_client_bg)); } ui->teStreamContent->setCurrentCharFormat(tcf); ui->teStreamContent->insertPlainText(text); text_pos_to_packet_[ui->teStreamContent->textCursor().anchor()] = packet_num; if (truncated_) { tcf = ui->teStreamContent->currentCharFormat(); tcf.setBackground(palette().window().color()); tcf.setForeground(palette().windowText().color()); ui->teStreamContent->insertPlainText("\n" + tr("[Stream output truncated]")); ui->teStreamContent->moveCursor(QTextCursor::End); } else { ui->teStreamContent->verticalScrollBar()->setValue(cur_pos); } setUpdatesEnabled(true); }
/* Opens a file and prepares a wtap struct. If "do_random" is TRUE, it opens the file twice; the second open allows the application to do random-access I/O without moving the seek offset for sequential I/O, which is used by Wireshark so that it can do sequential I/O to a capture file that's being written to as new packets arrive independently of random I/O done to display protocol trees for packets when they're selected. */ wtap* wtap_open_offline(const char *filename, int *err, char **err_info, gboolean do_random) { struct stat statb; wtap *wth; unsigned int i; gboolean use_stdin = FALSE; /* open standard input if filename is '-' */ if (strcmp(filename, "-") == 0) use_stdin = TRUE; /* First, make sure the file is valid */ if (use_stdin) { if (fstat(0, &statb) < 0) { *err = errno; return NULL; } } else { if (ws_stat(filename, &statb) < 0) { *err = errno; return NULL; } } if (S_ISFIFO(statb.st_mode)) { /* * Opens of FIFOs are allowed only when not opening * for random access. * * XXX - currently, we do seeking when trying to find * out the file type, so we don't actually support * opening FIFOs. However, we may eventually * do buffering that allows us to do at least some * file type determination even on pipes, so we * allow FIFO opens and let things fail later when * we try to seek. */ if (do_random) { *err = WTAP_ERR_RANDOM_OPEN_PIPE; return NULL; } } else if (S_ISDIR(statb.st_mode)) { /* * Return different errors for "this is a directory" * and "this is some random special file type", so * the user can get a potentially more helpful error. */ *err = EISDIR; return NULL; } else if (! S_ISREG(statb.st_mode)) { *err = WTAP_ERR_NOT_REGULAR_FILE; return NULL; } /* * We need two independent descriptors for random access, so * they have different file positions. If we're opening the * standard input, we can only dup it to get additional * descriptors, so we can't have two independent descriptors, * and thus can't do random access. */ if (use_stdin && do_random) { *err = WTAP_ERR_RANDOM_OPEN_STDIN; return NULL; } errno = ENOMEM; wth = (wtap *)g_malloc(sizeof(wtap)); if (wth == NULL) { *err = errno; return NULL; } /* Open the file */ errno = WTAP_ERR_CANT_OPEN; if (use_stdin) { /* * We dup FD 0, so that we don't have to worry about * an fclose or gzclose of wth->fh closing the standard * input of the process. */ wth->fd = ws_dup(0); #ifdef _WIN32 _setmode(wth->fd, O_BINARY); #endif } else wth->fd = ws_open(filename, O_RDONLY|O_BINARY, 0000 /* no creation so don't matter */); if (wth->fd < 0) { *err = errno; g_free(wth); return NULL; } if (!(wth->fh = filed_open(wth->fd, "rb"))) { *err = errno; ws_close(wth->fd); g_free(wth); return NULL; } if (do_random) { if (!(wth->random_fh = file_open(filename, "rb"))) { *err = errno; file_close(wth->fh); g_free(wth); return NULL; } } else wth->random_fh = NULL; /* initialization */ wth->file_encap = WTAP_ENCAP_UNKNOWN; wth->data_offset = 0; wth->subtype_sequential_close = NULL; wth->subtype_close = NULL; wth->tsprecision = WTAP_FILE_TSPREC_USEC; wth->priv = NULL; init_open_routines(); /* Try all file types */ for (i = 0; i < open_routines_arr->len; i++) { /* Seek back to the beginning of the file; the open routine for the previous file type may have left the file position somewhere other than the beginning, and the open routine for this file type will probably want to start reading at the beginning. Initialize the data offset while we're at it. */ if (file_seek(wth->fh, 0, SEEK_SET, err) == -1) { /* I/O error - give up */ if (wth->random_fh != NULL) file_close(wth->random_fh); file_close(wth->fh); g_free(wth); return NULL; } wth->data_offset = 0; switch ((*open_routines[i])(wth, err, err_info)) { case -1: /* I/O error - give up */ if (wth->random_fh != NULL) file_close(wth->random_fh); file_close(wth->fh); g_free(wth); return NULL; case 0: /* No I/O error, but not that type of file */ break; case 1: /* We found the file type */ goto success; } } /* Well, it's not one of the types of file we know about. */ if (wth->random_fh != NULL) file_close(wth->random_fh); file_close(wth->fh); g_free(wth); *err = WTAP_ERR_FILE_UNKNOWN_FORMAT; return NULL; success: wth->frame_buffer = (struct Buffer *)g_malloc(sizeof(struct Buffer)); buffer_init(wth->frame_buffer, 1500); return wth; }
/* Opens a file and prepares a ftap struct. If "do_random" is TRUE, it opens the file twice; the second open allows the application to do random-access I/O without moving the seek offset for sequential I/O, which is used by Wireshark so that it can do sequential I/O to a capture file that's being written to as new packets arrive independently of random I/O done to display protocol trees for packets when they're selected. */ ftap* ftap_open_offline(const char *filename, int *err, char **err_info, gboolean do_random) { int fd; ws_statb64 statb; ftap *fth; unsigned int i; gboolean use_stdin = FALSE; gchar *extension; /* open standard input if filename is '-' */ if (strcmp(filename, "-") == 0) use_stdin = TRUE; /* First, make sure the file is valid */ if (use_stdin) { if (ws_fstat64(0, &statb) < 0) { *err = errno; return NULL; } } else { if (ws_stat64(filename, &statb) < 0) { *err = errno; return NULL; } } if (S_ISFIFO(statb.st_mode)) { /* * Opens of FIFOs are allowed only when not opening * for random access. * * XXX - currently, we do seeking when trying to find * out the file type, so we don't actually support * opening FIFOs. However, we may eventually * do buffering that allows us to do at least some * file type determination even on pipes, so we * allow FIFO opens and let things fail later when * we try to seek. */ if (do_random) { *err = FTAP_ERR_RANDOM_OPEN_PIPE; return NULL; } } else if (S_ISDIR(statb.st_mode)) { /* * Return different errors for "this is a directory" * and "this is some random special file type", so * the user can get a potentially more helpful error. */ *err = EISDIR; return NULL; } else if (! S_ISREG(statb.st_mode)) { *err = FTAP_ERR_NOT_REGULAR_FILE; return NULL; } /* * We need two independent descriptors for random access, so * they have different file positions. If we're opening the * standard input, we can only dup it to get additional * descriptors, so we can't have two independent descriptors, * and thus can't do random access. */ if (use_stdin && do_random) { *err = FTAP_ERR_RANDOM_OPEN_STDIN; return NULL; } errno = ENOMEM; fth = (ftap *)g_malloc0(sizeof(ftap)); /* Open the file */ errno = FTAP_ERR_CANT_OPEN; if (use_stdin) { /* * We dup FD 0, so that we don't have to worry about * a file_close of wth->fh closing the standard * input of the process. */ fd = ws_dup(0); if (fd < 0) { *err = errno; g_free(fth); return NULL; } #ifdef _WIN32 if (_setmode(fd, O_BINARY) == -1) { /* "Shouldn't happen" */ *err = errno; g_free(fth); return NULL; } #endif if (!(fth->fh = file_fdopen(fd))) { *err = errno; ws_close(fd); g_free(fth); return NULL; } } else { if (!(fth->fh = file_open(filename))) { *err = errno; g_free(fth); return NULL; } } if (do_random) { if (!(fth->random_fh = file_open(filename))) { *err = errno; file_close(fth->fh); g_free(fth); return NULL; } } else fth->random_fh = NULL; /* initialization */ fth->file_encap = FTAP_ENCAP_UNKNOWN; fth->subtype_sequential_close = NULL; fth->subtype_close = NULL; fth->priv = NULL; init_magic_number_open_routines(); init_heuristic_open_info(); if (fth->random_fh) { fth->fast_seek = g_ptr_array_new(); file_set_random_access(fth->fh, FALSE, fth->fast_seek); file_set_random_access(fth->random_fh, TRUE, fth->fast_seek); } /* Try all file types that support magic numbers */ for (i = 0; i < magic_number_open_routines_arr->len; i++) { /* Seek back to the beginning of the file; the open routine for the previous file type may have left the file position somewhere other than the beginning, and the open routine for this file type will probably want to start reading at the beginning. Initialize the data offset while we're at it. */ if (file_seek(fth->fh, 0, SEEK_SET, err) == -1) { /* I/O error - give up */ ftap_close(fth); return NULL; } switch ((*magic_number_open_routines[i])(fth, err, err_info)) { case -1: /* I/O error - give up */ ftap_close(fth); return NULL; case 0: /* No I/O error, but not that type of file */ break; case 1: /* We found the file type */ goto success; } } /* Does this file's name have an extension? */ extension = get_file_extension(filename); if (extension != NULL) { /* Yes - try the heuristic types that use that extension first. */ for (i = 0; i < heuristic_open_info_arr->len; i++) { /* Does this type use that extension? */ if (heuristic_uses_extension(i, extension)) { /* Yes. */ if (file_seek(fth->fh, 0, SEEK_SET, err) == -1) { /* I/O error - give up */ g_free(extension); ftap_close(fth); return NULL; } switch ((*heuristic_open_info[i].open_routine)(fth, err, err_info)) { case -1: /* I/O error - give up */ g_free(extension); ftap_close(fth); return NULL; case 0: /* No I/O error, but not that type of file */ break; case 1: /* We found the file type */ g_free(extension); goto success; } } } /* Now try the ones that don't use it. */ for (i = 0; i < heuristic_open_info_arr->len; i++) { /* Does this type use that extension? */ if (!heuristic_uses_extension(i, extension)) { /* No. */ if (file_seek(fth->fh, 0, SEEK_SET, err) == -1) { /* I/O error - give up */ g_free(extension); ftap_close(fth); return NULL; } switch ((*heuristic_open_info[i].open_routine)(fth, err, err_info)) { case -1: /* I/O error - give up */ g_free(extension); ftap_close(fth); return NULL; case 0: /* No I/O error, but not that type of file */ break; case 1: /* We found the file type */ g_free(extension); goto success; } } } g_free(extension); } else { /* No - try all the heuristics types in order. */ for (i = 0; i < heuristic_open_info_arr->len; i++) { if (file_seek(fth->fh, 0, SEEK_SET, err) == -1) { /* I/O error - give up */ ftap_close(fth); return NULL; } switch ((*heuristic_open_info[i].open_routine)(fth, err, err_info)) { case -1: /* I/O error - give up */ ftap_close(fth); return NULL; case 0: /* No I/O error, but not that type of file */ break; case 1: /* We found the file type */ goto success; } } } /* Well, it's not one of the types of file we know about. */ ftap_close(fth); *err = FTAP_ERR_FILE_UNKNOWN_FORMAT; return NULL; success: fth->frame_buffer = (struct Buffer *)g_malloc(sizeof(struct Buffer)); buffer_init(fth->frame_buffer, 1500); return fth; }