/* update the time and size of this file in the list */ void fileset_update_file(const char *path) { int fh, result; ws_statb64 buf; fileset_entry *entry = NULL; GList *entry_list; fh = ws_open( path, O_RDONLY, 0000 /* no creation so don't matter */); if(fh != -1) { /* Get statistics */ result = ws_fstat64( fh, &buf ); /* Show statistics if they are valid */ if( result == 0 ) { entry_list = g_list_find_custom(set.entries, path, fileset_find_by_path); if (entry_list) { entry = (fileset_entry *) entry_list->data; entry->ctime = buf.st_ctime; entry->mtime = buf.st_mtime; entry->size = buf.st_size; } } ws_close(fh); } }
/* we know this file is part of the set, so add it */ static fileset_entry * fileset_add_file(const char *dirname, const char *fname, gboolean current) { int fh, result; ws_statb64 buf; char *path; fileset_entry *entry = NULL; path = g_strdup_printf("%s%s", dirname, fname); fh = ws_open( path, O_RDONLY, 0000 /* no creation so don't matter */); if(fh != -1) { /* Get statistics */ result = ws_fstat64( fh, &buf ); /* Show statistics if they are valid */ if( result == 0 ) { entry = (fileset_entry *)g_malloc(sizeof(fileset_entry)); entry->fullname = g_strdup(path); entry->name = g_strdup(fname); entry->ctime = buf.st_ctime; entry->mtime = buf.st_mtime; entry->size = buf.st_size; entry->current = current; set.entries = g_list_append(set.entries, entry); } ws_close(fh); } g_free(path); return entry; }
/* 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; }