Skip to content

Commit 14cd49c

Browse files
committed
fixed another long standing bug in extractor. It now works perfectly fine.
semplified search_inside_archive() func.
1 parent f5dc640 commit 14cd49c

File tree

5 files changed

+53
-50
lines changed

5 files changed

+53
-50
lines changed

Changelog

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
* fixed a small memleak when leaving ncursesfm while a search was active
77
* some print_info() related fixes
88
* fixed a bug in shasum call from within main()
9+
* fixed another long standing bug in extractor. It now works perfectly fine
910

1011
12 / 18 / 2015
1112
* fixed a small bug in ask_user

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
# ncursesFM
22
Ncurses File Manager for linux.
3-
It aims to be as user friendly and lightweight as possible, while being good looking (my own tastes), simple and easy to use.
3+
It aims to be as user friendly and lightweight as possible, while being good looking (my own tastes) and simple.
44
Being simple doesn't imply being useless; indeed it is a full featured fm.
55
It can be built with a very small set of dependencies, as i tried to make as many deps as possible optional (compile time or runtime).
66

src/archiver.c

Lines changed: 20 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33
static void archiver_func(void);
44
static int recursive_archive(const char *path, const struct stat *sb, int typeflag, struct FTW *ftwbuf);
5-
static void extractor_thread(struct archive *a);
5+
static void extractor_thread(struct archive *a, const char *current_dir);
66

77
static struct archive *archive;
88

@@ -69,12 +69,17 @@ static int recursive_archive(const char *path, const struct stat *sb, int typefl
6969

7070
int try_extractor(void) {
7171
struct archive *a;
72+
char current_dir[PATH_MAX + 1];
7273

7374
a = archive_read_new();
7475
archive_read_support_filter_all(a);
7576
archive_read_support_format_all(a);
7677
if ((a) && (archive_read_open_filename(a, thread_h->filename, BUFF_SIZE) == ARCHIVE_OK)) {
77-
extractor_thread(a);
78+
strcpy(current_dir, thread_h->filename);
79+
char *tmp = strrchr(current_dir, '/');
80+
int len = strlen(current_dir) - strlen(tmp);
81+
current_dir[len] = '\0';
82+
extractor_thread(a, current_dir);
7883
return 0;
7984
}
8085
archive_read_free(a);
@@ -87,37 +92,30 @@ int try_extractor(void) {
8792
* While there are headers inside the archive being read, it goes on copying data from
8893
* the read archive to the disk.
8994
*/
90-
static void extractor_thread(struct archive *a) {
95+
static void extractor_thread(struct archive *a, const char *current_dir) {
9196
struct archive *ext;
9297
struct archive_entry *entry;
93-
int len, num = 0;
98+
int len, num;
9499
int flags = ARCHIVE_EXTRACT_TIME | ARCHIVE_EXTRACT_PERM | ARCHIVE_EXTRACT_ACL | ARCHIVE_EXTRACT_FFLAGS;
95-
char buff[BUFF_SIZE], current_dir[PATH_MAX + 1], fullpathname[PATH_MAX + 1];
96-
char *tmp;
100+
char buff[BUFF_SIZE], fullpathname[PATH_MAX + 1];
97101
char name[PATH_MAX + 1], tmp_name[PATH_MAX + 1];
98102

99-
strcpy(current_dir, thread_h->filename);
100-
tmp = strrchr(current_dir, '/');
101-
len = strlen(current_dir) - strlen(tmp);
102-
current_dir[len] = '\0';
103103
ext = archive_write_disk_new();
104104
archive_write_disk_set_options(ext, flags);
105105
archive_write_disk_set_standard_lookup(ext);
106106
while (archive_read_next_header(a, &entry) != ARCHIVE_EOF) {
107107
strcpy(name, archive_entry_pathname(entry));
108-
/* only perform overwrite check if on the first entry, or if num != 1 */
109-
if ((len == strlen(current_dir)) || (num != 1)) {
110-
/* avoid overwriting a file/dir in path if it has the same name of a file being extracted there */
108+
num = 0;
109+
/* avoid overwriting a file/dir in path if it has the same name of a file being extracted there */
110+
if (strchr(name, '/')) {
111111
strcpy(tmp_name, strchr(name, '/'));
112-
len = strlen(name) - strlen(tmp_name);
113-
if (num == 0) {
114-
while (access(name, F_OK) != -1) {
115-
num++;
116-
sprintf(name + len, "%d%s", num, tmp_name);
117-
}
118-
} else {
119-
sprintf(name + len, "%d%s", num, tmp_name);
120-
}
112+
} else {
113+
tmp_name[0] = '\0';
114+
}
115+
len = strlen(name) - strlen(tmp_name);
116+
while (access(name, F_OK) != -1) {
117+
num++;
118+
sprintf(name + len, "%d%s", num, tmp_name);
121119
}
122120
sprintf(fullpathname, "%s/%s", current_dir, name);
123121
archive_entry_set_pathname(entry, fullpathname);

src/inhibit.c

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,11 @@
22

33
#include "../inc/inhibit.h"
44

5+
6+
/*
7+
* Thanks elogind project for some hints to improve my old implementation.
8+
* https://github.com/andywingo/elogind/blob/master/src/login/inhibit.c
9+
*/
510
int inhibit_suspend(const char *str) {
611
sd_bus *bus;
712
sd_bus_message *reply = NULL;

src/search.c

Lines changed: 26 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -10,17 +10,17 @@ void search(void) {
1010
ask_user(search_insert_name, sv.searched_string, 20, 0);
1111
if (strlen(sv.searched_string) < 5) {
1212
print_info(searched_string_minimum, ERR_LINE);
13-
return;
14-
}
15-
sv.found_cont = 0;
16-
sv.search_archive = 0;
17-
ask_user(search_archives, &c, 1, 'n');
18-
if (c == 'y') {
19-
sv.search_archive = 1;
13+
} else {
14+
sv.found_cont = 0;
15+
sv.search_archive = 0;
16+
ask_user(search_archives, &c, 1, 'n');
17+
if (c == 'y') {
18+
sv.search_archive = 1;
19+
}
20+
sv.searching = 1;
21+
print_info("", SEARCH_LINE);
22+
pthread_create(&search_th, NULL, search_thread, NULL);
2023
}
21-
sv.searching = 1;
22-
print_info("", SEARCH_LINE);
23-
pthread_create(&search_th, NULL, search_thread, NULL);
2424
}
2525

2626
static int recursive_search(const char *path, const struct stat *sb, int typeflag, struct FTW *ftwbuf) {
@@ -48,34 +48,33 @@ static int recursive_search(const char *path, const struct stat *sb, int typefla
4848
return quit ? 1 : ret;
4949
}
5050

51+
/*
52+
* For each entry in the archive, it checks "entry + len" pointer against searched string.
53+
* Len is always the offset of the current dir inside archive, eg: foo.tgz/bar/x,
54+
* while checking x, len will be strlen("bar/")
55+
*/
5156
static int search_inside_archive(const char *path) {
52-
char str[PATH_MAX + 1], *ptr;
53-
struct archive *a = archive_read_new();
57+
char *ptr;
58+
int len = 0, ret = 0, string_length;
5459
struct archive_entry *entry;
55-
int len, ret = 0;
56-
60+
struct archive *a = archive_read_new();
61+
5762
archive_read_support_filter_all(a);
5863
archive_read_support_format_all(a);
64+
string_length = strlen(sv.searched_string);
5965
if ((a) && (archive_read_open_filename(a, path, BUFF_SIZE) == ARCHIVE_OK)) {
60-
while ((!quit) && (archive_read_next_header(a, &entry) == ARCHIVE_OK)) {
61-
strcpy(str, archive_entry_pathname(entry));
62-
len = strlen(str);
63-
if (str[len - 1] == '/') { // check if we're on a dir
64-
str[len - 1] = '\0';
65-
}
66-
ptr = str;
67-
if (strrchr(str, '/')) {
68-
ptr = strrchr(str, '/') + 1;
69-
}
70-
len = strlen(sv.searched_string);
71-
if (strncmp(ptr, sv.searched_string, len) == 0) {
66+
while ((!quit) && (!ret) && (archive_read_next_header(a, &entry) == ARCHIVE_OK)) {
67+
if (strncmp(archive_entry_pathname(entry) + len, sv.searched_string, string_length) == 0) {
7268
sprintf(sv.found_searched[sv.found_cont], "%s/%s", path, archive_entry_pathname(entry));
7369
sv.found_cont++;
7470
if (sv.found_cont == MAX_NUMBER_OF_FOUND) {
7571
ret = 1;
76-
break;
7772
}
7873
}
74+
ptr = strrchr(archive_entry_pathname(entry), '/');
75+
if ((ptr) && (strlen(ptr) == 1)) {
76+
len = strlen(archive_entry_pathname(entry));
77+
}
7978
}
8079
}
8180
archive_read_free(a);

0 commit comments

Comments
 (0)