aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorwiktor w brodlo <wiktor@brodlo.net>2011-06-15 16:59:54 +0000
committerwiktor w brodlo <wiktor@brodlo.net>2011-06-15 16:59:54 +0000
commit2590d96369d0217e31dc2812690dde61dac417b5 (patch)
tree82276f787b08a28548e342c7921486f1acefab9f /loader/dirbrowser.c
parentfirst commit (diff)
downloadanaconda-2590d96369d0217e31dc2812690dde61dac417b5.tar.gz
anaconda-2590d96369d0217e31dc2812690dde61dac417b5.tar.bz2
anaconda-2590d96369d0217e31dc2812690dde61dac417b5.zip
Initial import from Sabayon (ver 0.9.9.56)
Diffstat (limited to 'loader/dirbrowser.c')
-rw-r--r--loader/dirbrowser.c199
1 files changed, 199 insertions, 0 deletions
diff --git a/loader/dirbrowser.c b/loader/dirbrowser.c
new file mode 100644
index 0000000..9199850
--- /dev/null
+++ b/loader/dirbrowser.c
@@ -0,0 +1,199 @@
+/*
+ * dirbrowser.c - newt-based directory browser to get a file name
+ *
+ * Copyright (C) 2004 Red Hat, Inc. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * Author(s): Jeremy Katz <katzj@redhat.com>
+ */
+
+#include <newt.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <sys/types.h>
+#include <dirent.h>
+#include <errno.h>
+#include <string.h>
+#include <sys/stat.h>
+
+#ifndef STANDALONE
+#include "../isys/log.h"
+
+#include "loader.h"
+#include "loadermisc.h"
+#include "lang.h"
+#endif
+
+#ifdef STANDALONE
+#define _(x) x
+
+static int simpleStringCmp(const void * a, const void * b) {
+ const char * first = *((const char **) a);
+ const char * second = *((const char **) b);
+
+ return strcmp(first, second);
+}
+#endif
+
+#define FSTEP 10
+
+static char ** get_file_list(char * dirname,
+ int (*filterfunc)(char *, struct dirent *)) {
+ DIR * dir;
+ struct dirent *entry;
+ char ** files;
+ int numfiles = FSTEP, i = 0;
+
+ dir = opendir(dirname);
+ if (dir == NULL) {
+ fprintf(stderr, "error opening %s: %m", dirname);
+ return NULL;
+ }
+
+ files = malloc(numfiles * sizeof(char *));
+
+ while ((entry = readdir(dir))) {
+ if ((strlen(entry->d_name) == 1) && !strncmp(entry->d_name, ".", 1))
+ continue;
+ if ((strlen(entry->d_name) == 2) && !strncmp(entry->d_name, "..", 2))
+ continue;
+ if (filterfunc && filterfunc(dirname, entry))
+ continue;
+
+ files[i] = strdup(entry->d_name);
+ if (i++ >= (numfiles - 1)) {
+ numfiles += FSTEP;
+ files = realloc(files, numfiles * sizeof(char *));
+ }
+ }
+ files[i] = NULL;
+ closedir(dir);
+
+ qsort(files, i, sizeof(*files), simpleStringCmp);
+ return files;
+}
+
+/* Browse through a directory structure looking for a file.
+ * Returns the full path to the file.
+ *
+ * Parameters:
+ * title: Title for newt dialog window
+ * dirname: Directory to use for root of browsing. NOTE: you cannot go
+ * up above this root.
+ * filterfunc: An (optional) function to filter out files based on whatever
+ * criteria you want. Returns 1 if it passes, 0 if not.
+ * Function should take arguments of the directory name and
+ * the dirent for the file.
+ */
+char * newt_select_file(char * title, char * text, char * dirname,
+ int (*filterfunc)(char *, struct dirent *)) {
+ char ** files;
+ char * fn = NULL;
+ int i, done = 0;
+ char * topdir = dirname;
+ char * dir = malloc(PATH_MAX);
+ char * path = NULL;
+ newtGrid grid, buttons;
+ newtComponent f, tb, listbox, ok, cancel;
+ struct stat sb;
+ struct newtExitStruct es;
+
+ dir = realpath(dirname, dir);
+
+ do {
+ files = get_file_list(dir, filterfunc);
+
+ f = newtForm(NULL, NULL, 0);
+ grid = newtCreateGrid(1, 4);
+
+ tb = newtTextboxReflowed(-1, -1, text, 60, 0, 10, 0);
+
+ listbox = newtListbox(12, 65, 10,
+ NEWT_FLAG_SCROLL | NEWT_FLAG_RETURNEXIT);
+
+ newtListboxSetWidth(listbox, 55);
+ buttons = newtButtonBar(_("OK"), &ok, _("Cancel"), &cancel, NULL);
+ newtGridSetField(grid, 0, 0, NEWT_GRID_COMPONENT, tb,
+ 0, 0, 0, 1, 0, 0);
+ newtGridSetField(grid, 0, 1, NEWT_GRID_COMPONENT, listbox,
+ 0, 0, 0, 1, 0, 0);
+ newtGridSetField(grid, 0, 3, NEWT_GRID_SUBGRID, buttons,
+ 0, 0, 0, 0, 0, NEWT_GRID_FLAG_GROWX);
+
+ /* if this isn't our topdir, we want to let them go up a dir */
+ if (strcmp(topdir, dir))
+ newtListboxAppendEntry(listbox, "../", "..");
+
+ for (i = 0; (files[i] != NULL); i++) {
+ if ((files[i] == NULL) || (strlen(files[i]) == 0)) continue;
+ path = malloc(strlen(files[i]) + strlen(dir) + 2);
+ sprintf(path, "%s/%s", dir, files[i]);
+ stat(path, &sb);
+ free(path);
+ if (S_ISDIR(sb.st_mode)) {
+ char *dir = malloc(strlen(files[i]) + 2);
+ sprintf(dir, "%s/", files[i]);
+ newtListboxAppendEntry(listbox, dir, files[i]);
+ } else {
+ newtListboxAppendEntry(listbox, files[i], files[i]);
+ }
+ }
+
+ newtGridWrappedWindow(grid, title);
+ newtGridAddComponentsToForm(grid, f, 1);
+ newtFormRun(f, &es);
+
+ if (es.reason == NEWT_EXIT_COMPONENT && es.u.co == cancel) {
+ fn = NULL;
+ done = -1;
+ } else {
+ fn = (char *) newtListboxGetCurrent(listbox);
+ path = malloc(strlen(fn) + strlen(dir) + 2);
+ sprintf(path, "%s/%s", dir, fn);
+
+ stat(path, &sb);
+ if (!S_ISDIR(sb.st_mode)) {
+ fn = path;
+ done = 1;
+ } else {
+ dir = realpath(path, dir);
+ free(path);
+ }
+ }
+
+ newtGridFree(grid, 1);
+ newtFormDestroy(f);
+ newtPopWindow();
+ } while (done == 0);
+
+ return fn;
+}
+
+#ifdef STANDALONE
+int main(int argc, char ** argv) {
+ char * foo;
+
+ newtInit();
+ newtCls();
+
+ foo = newt_select_file("Get File Name", "foo, blah blah blah",
+ "/etc", NULL);
+ newtFinished();
+ printf("got %s\n", foo);
+ return 0;
+}
+#endif