Exemplo n.º 1
0
Arquivo: request.c Projeto: dmt4/ne
char *complete_filename(const char *start_prefix) {

	/* This might be NULL if the current directory has been unlinked, or it is not readable.
		in that case, we end up moving to the completion directory. */
	char * const cur_dir_name = ne_getcwd(CUR_DIR_MAX_SIZE);

	char * const dir_name = str_dup(start_prefix);
	if (dir_name) {
		char * const p = (char *)file_part(dir_name);
		*p = 0;
		if (p != dir_name && chdir(tilde_expand(dir_name)) == -1) {
			free(dir_name);
			return NULL;
		}
	}

	start_prefix = file_part(start_prefix);
	bool is_dir, unique = true;
	char *cur_prefix = NULL;
	DIR * const d = opendir(CURDIR);

	if (d) {
		for(struct dirent * de; !stop && (de = readdir(d)); ) {
			if (is_prefix(start_prefix, de->d_name))
				if (cur_prefix) {
					cur_prefix[max_prefix(cur_prefix, de->d_name)] = 0;
					unique = false;
				}
				else {
					cur_prefix = str_dup(de->d_name);
					is_dir = is_directory(de->d_name);
				}
		}

		closedir(d);
	}

	char * result = NULL;

	if (cur_prefix) {
		result = malloc(strlen(dir_name) + strlen(cur_prefix) + 2);
		strcat(strcat(strcpy(result, dir_name), cur_prefix), unique && is_dir ? "/" : "");
	}

	if (cur_dir_name != NULL) {
		chdir(cur_dir_name);
		free(cur_dir_name);
	}
	free(dir_name);
	free(cur_prefix);

	return result;
}
Exemplo n.º 2
0
Arquivo: request.c Projeto: dmt4/ne
char *request_files(const char * const filename, bool use_prefix) {

	char * const cur_dir_name = ne_getcwd(CUR_DIR_MAX_SIZE);
	if (!cur_dir_name) return NULL;

	char * const dir_name = str_dup(filename);
	if (dir_name) {
		int result = 0;
		char * const p = (char *)file_part(dir_name);
		if (p != dir_name) {
			*p = 0;
			result = chdir(tilde_expand(dir_name));
		}
		free(dir_name);
		if (result == -1) return NULL;
	}

	req_list rl;
	bool next_dir;
	char *result = NULL;
	do {
		next_dir = false;
		if (req_list_init(&rl, filenamecmp, true, false, '/') != OK) break;

		DIR * const d = opendir(CURDIR);
		if (d) {

			stop = false;
			for(struct dirent * de; !stop && (de = readdir(d)); ) {
				const bool is_dir = is_directory(de->d_name);
				if (use_prefix && !is_prefix(file_part(filename), de->d_name)) continue;
				if (!req_list_add(&rl, de->d_name, is_dir)) break;
			}

			req_list_finalize(&rl);

			if (rl.cur_entries) {
				/* qsort(rl.entries, rl.cur_entries, sizeof(char *), filenamecmpp); */

				const int t = request_strings(&rl, 0);
				if (t != ERROR) {
					char * const p = rl.entries[t >= 0 ? t : -t - 2];
					if (p[strlen(p) - 1] == '/' && t >= 0) {
						p[strlen(p) - 1] = 0;
						if (chdir(p)) alert();
						else use_prefix = false;
						next_dir = true;
					}
					else {
						result = ne_getcwd(CUR_DIR_MAX_SIZE + strlen(p) + 2);
						if (strcmp(result, "/")) strcat(result, "/");
						strcat(result, p);
						if (t < 0) {
							memmove(result + 1, result, strlen(result) + 1);
							result[0] = 0;
						}
					}
				}
			}

			closedir(d);
		}
		else alert();
		req_list_free(&rl);
	} while(next_dir);

	chdir(cur_dir_name);
	free(cur_dir_name);

	return result;
}
Exemplo n.º 3
0
char *request_files(const char * const filename, int use_prefix) {

	int i, num_entries, name_len, max_name_len, total_len, next_dir, is_dir,
		entries_alloc_size = DEF_ENTRIES_ALLOC_SIZE,
		names_alloc_size = DEF_NAMES_ALLOC_SIZE;

	char *dir_name, **entries = NULL, *names = NULL, *cur_dir_name, *result = NULL, *p;

	DIR *d;
	struct dirent *de;

	if (!(cur_dir_name = ne_getcwd(CUR_DIR_MAX_SIZE))) return NULL;

	if (dir_name = str_dup(filename)) {
		i = 0;
		if ((p = (char *)file_part(dir_name)) != dir_name) {
			*p = 0;
			i = chdir(tilde_expand(dir_name));
		}
		free(dir_name);
		if (i == -1) return NULL;
	}

	if (entries = malloc(sizeof(char *) * entries_alloc_size)) {
		if (names = malloc(sizeof(char) * names_alloc_size)) {
			do {
				next_dir = FALSE;

				if (d = opendir(CURDIR)) {

					num_entries = max_name_len = total_len = 0;

					stop = FALSE;

					while(!stop && (de = readdir(d))) {
						is_dir = is_directory(de->d_name);
						if (use_prefix && !is_prefix(file_part(filename), de->d_name)) continue;
						name_len = strlen(de->d_name) + is_dir + 1;

						if (name_len > max_name_len) max_name_len = name_len;

						if (total_len + name_len > names_alloc_size) {
							char *t;
							t = realloc(names, sizeof(char) * (names_alloc_size = names_alloc_size * 2 + name_len));
							if (!t) break;
							names = t;
							/* Now adjust the entries to point to the newly reallocated strings */
							entries[0] = names;
							for (i = 1; i < num_entries; i++)
							  entries[i] = entries[i - 1] + strlen(entries[i - 1]) + 1;
						}

						if (num_entries >= entries_alloc_size) {
							char **t;
							t = realloc(entries, sizeof(char *) * (entries_alloc_size *= 2));
							if (!t) break;
							entries = t;
						}

						strcpy(entries[num_entries] = names + total_len, de->d_name);
						if (is_dir) strcpy(names + total_len + name_len - 2, "/");
						total_len += name_len;
						num_entries++;
					}

					if (num_entries) {
						qsort(entries, num_entries, sizeof(char *), filenamecmpp);

						if ((i = request_strings((const char * const *)entries, num_entries, 0, max_name_len, '/')) != ERROR) {
							p = entries[i >= 0 ? i : -i - 2];
							if (p[strlen(p) - 1] == '/' && i >= 0) {
								p[strlen(p) - 1] = 0;
								if (chdir(p)) alert();
								else use_prefix = FALSE;
								next_dir = TRUE;
							}
							else {
								result = ne_getcwd(CUR_DIR_MAX_SIZE + strlen(p) + 2);
								if (strcmp(result, "/")) strcat(result, "/");
								strcat(result, p);
								if (i < 0) {
									memmove(result + 1, result, strlen(result) + 1);
									result[0] = 0;
								}
							}
						}
					}

					closedir(d);
				}
				else alert();

			} while(next_dir);

			free(names);
		}
		free(entries);
	}

	chdir(cur_dir_name);
	free(cur_dir_name);

	return result;
}