1 /* Dir/file menus
2 
3  * Copyright (C) 1998 J.A. Bezemer
4  *
5  * Licensed under the terms of the GNU General Public License.
6  * ABSOLUTELY NO WARRANTY.
7  * See the file `COPYING' in this directory.
8  */
9 
10 #include "dirfilemenu.h"
11 #include "scrollmenu.h"
12 #include <stdlib.h>
13 #include <dirent.h>
14 #include <string.h>
15 #include <sys/stat.h>
16 
17 
18 void
dirfilemenu(char * basedir,scrollmenu_t * menu)19 dirfilemenu (char *basedir, scrollmenu_t * menu)
20 /* NOTE: basedir must contain last '/', like "/home/" */
21 {
22   struct dirent **namelist;
23   int n;
24   char mybasedir[250];
25   char helpstring[250];
26   char *firstslash;
27   int i, j, k;
28   int indent = 0;
29   int isadir;			/* 0 if no dir, 1 if dir. */
30   struct stat filestats;
31 
32   n = scandir (basedir, &namelist, NULL, alphasort);
33 
34   if (n < 0)
35     menu->number = 0;
36   else
37     {
38       menu->items = (char **) malloc ((n + 100) * sizeof (char *));
39 
40       for (i = 0; i < n + 100; i++)
41 	menu->items[i] = NULL;
42 
43       strcpy (mybasedir, basedir);
44       i = 0;
45 
46       do
47 	{
48 	  firstslash = strchr (mybasedir, '/');
49 	  if (firstslash != NULL)
50 	    {
51 	      menu->items[i] =
52 		(char *) malloc ((firstslash - mybasedir + 2 + indent) *
53 				 sizeof (char));
54 	      for (k = 0; k < indent; k++)
55 		menu->items[i][k] = ' ';
56 
57 	      strncpy (menu->items[i] + indent, mybasedir,
58 		       firstslash - mybasedir + 1);
59 	      menu->items[i][firstslash - mybasedir + 1 + indent] = '\0';
60 
61 	      strcpy (helpstring, firstslash + 1);
62 	      strcpy (mybasedir, helpstring);
63 
64 	      i++;
65 	      indent++;
66 	    }
67 	}
68       while (strlen (mybasedir) > 0);
69 
70       menu->last_of_1st_part = i - 1;
71 
72       for (j = 0; j < n; j++)
73 	{
74 	  if (strcmp (namelist[j]->d_name, ".") &&
75 	      strcmp (namelist[j]->d_name, ".."))
76 	    {
77 	      strcpy (helpstring, basedir);
78 	      strcat (helpstring, namelist[j]->d_name);
79 	      stat (helpstring, &filestats);
80 
81 	      if (S_ISDIR (filestats.st_mode))
82 		isadir = 1;
83 	      else
84 		isadir = 0;
85 
86 	      menu->items[i] =
87 		(char *) malloc (
88 			(strlen (namelist[j]->d_name) + 1 + indent + isadir)
89 				  * sizeof (char));
90 
91 	      for (k = 0; k < indent; k++)
92 		menu->items[i][k] = ' ';
93 
94 	      strcpy (menu->items[i] + indent, namelist[j]->d_name);
95 
96 	      if (isadir)
97 		strcat (menu->items[i], "/");
98 
99 	      i++;
100 	    }
101 	}
102       menu->number = i;
103     }
104 }
105 
106 int
dirfilemenu_process_select(scrollmenu_t * menu,char * dirfile)107 dirfilemenu_process_select (scrollmenu_t * menu, char *dirfile)
108 /* Returns: 0 if file, then complete filename in dirfile
109    1 if dir, then new complete dirname in dirfile */
110 {
111   int i;
112 
113   if (menu->selected <= menu->last_of_1st_part)
114     /* parent dir */
115     {
116       dirfile[0] = '\0';
117 
118       for (i = 0; i <= menu->selected; i++)
119 	strcat (dirfile, menu->items[i] + i);
120 
121       menu->selected++;
122       return 1;
123     }
124   else
125     /* this dir */
126     {
127 
128       dirfile[0] = '\0';
129 
130       for (i = 0; i <= menu->last_of_1st_part; i++)
131 	strcat (dirfile, menu->items[i] + i);
132 
133       strcat (dirfile, menu->items[menu->selected]
134 	      + menu->last_of_1st_part + 1);
135 
136       if (menu->items[menu->selected]
137 	  [strlen (menu->items[menu->selected]) - 1] == '/')
138 	{			/* subdir */
139 	  menu->selected = menu->last_of_1st_part + 2;
140 	  return 1;
141 	}
142       else			/* file */
143 	return 0;
144     }
145 }
146