summaryrefslogtreecommitdiffstats
path: root/loader2/dirbrowser.c
diff options
context:
space:
mode:
authorJeremy Katz <katzj@redhat.com>2004-06-04 18:23:33 +0000
committerJeremy Katz <katzj@redhat.com>2004-06-04 18:23:33 +0000
commitd448d25975a31d5215f92dd69779b38d316da5e4 (patch)
tree8b13bed92996100c29a6243dd0481371ff3746d8 /loader2/dirbrowser.c
parent863c7e14f41c564a2fc81c69f6a3af837965020f (diff)
downloadanaconda-d448d25975a31d5215f92dd69779b38d316da5e4.tar.gz
anaconda-d448d25975a31d5215f92dd69779b38d316da5e4.tar.xz
anaconda-d448d25975a31d5215f92dd69779b38d316da5e4.zip
add a newt-based file selector that's probably slightly over-engineered for
my purposes
Diffstat (limited to 'loader2/dirbrowser.c')
-rw-r--r--loader2/dirbrowser.c184
1 files changed, 184 insertions, 0 deletions
diff --git a/loader2/dirbrowser.c b/loader2/dirbrowser.c
new file mode 100644
index 000000000..153607240
--- /dev/null
+++ b/loader2/dirbrowser.c
@@ -0,0 +1,184 @@
+/*
+ * dirbrowser.c - newt-based directory browser to get a file name
+ *
+ * Jeremy Katz <katzj@redhat.com>
+ *
+ * Copyright 2004 Red Hat, Inc.
+ *
+ * This software may be freely redistributed under the terms of the GNU
+ * General Public License.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#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>
+
+#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
+
+#if 0
+/* sample filter function */
+/* return 1 if a dir, 0 if not */
+int getOnlyDirs(char * dir, struct dirent *entry) {
+ struct stat sb;
+ char * fn = alloca(strlen(dir) + strlen(entry->d_name) + 2);
+
+ sprintf(fn, "%s/%s", dir, entry->d_name);
+ stat(fn, &sb);
+
+ if (!S_ISDIR(sb.st_mode)) {
+ return 1;
+ }
+ return 0;
+}
+#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: %s", dirname, strerror(errno));
+ 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;
+
+ 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 * dirname,
+ int (*filterfunc)(char *, struct dirent *)) {
+ char ** files;
+ char * fn = NULL;
+ int i, done = 0;
+ char * topdir = dirname;
+ char * dir = malloc(PATH_MAX);
+ newtGrid grid, buttons;
+ newtComponent f, listbox, ok, cancel;
+ struct newtExitStruct es;
+
+ dir = realpath(dirname, dir);
+
+ do {
+ files = get_file_list(dir, filterfunc);
+
+ f = newtForm(NULL, NULL, 0);
+ grid = newtCreateGrid(1, 3);
+ listbox = newtListbox(15, 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, listbox,
+ 0, 0, 0, 1, 0, 0);
+ newtGridSetField(grid, 0, 1, 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;
+ 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 {
+ char * path;
+ struct stat sb;
+
+ 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", "/etc", NULL);
+ newtFinished();
+ printf("got %s\n", foo);
+ return 0;
+}
+#endif