
Example 11-5. The menu_dir.c program (continued)
* recursive, a new menu is created for each subdirectory under the
* original path.
*/
Menu_item
add_path_to_menu(path)
char *path;
{
DIR *dirp;
struct direct *dp;
struct stat s_buf;
Menu_item mi;
Menu next_menu;
char buf[MAXPATHLEN];
/* don’t add a folder to the list if user can’t read it */
if (stat(path, &s_buf) == -1 || !(s_buf.st_mode & S_IREAD))
return NULL;
if (s_buf.st_mode & S_IFDIR) {
int cnt = 0;
if (!(dirp = opendir(path)))
/* don’t bother adding to list if we can’t scan it */
return NULL;
next_menu = (Menu)xv_create(XV_NULL, MENU, NULL);
while (dp = readdir(dirp))
if (strcmp(dp->d_name, ".") && strcmp(dp->d_name, "..")) {
(void) sprintf(buf, "%s/%s", path, dp–>d_name);
if (!(mi = add_path_to_menu(buf)))
/* unreadable file or dir - deactivate item */
mi = xv_create(XV_NULL, MENUITEM,
MENU_STRING, getfilename(dp->d_name),
MENU_RELEASE,
MENU_RELEASE_IMAGE,
MENU_INACTIVE, TRUE,
NULL);
xv_set(next_menu, MENU_APPEND_ITEM, mi, NULL);
cnt++;
}
closedir(dirp);
mi = xv_create(XV_NULL, MENUITEM,
MENU_STRING, getfilename(path),
MENU_RELEASE,
MENU_RELEASE_IMAGE,
MENU_NOTIFY_PROC, my_action_proc,
NULL);
if (!cnt) {
xv_destroy(next_menu);
/* An empty or unsearchable directory - deactivate item */
xv_set(mi, MENU_INACTIVE, TRUE, NULL);
} else {
xv_set(next_menu, MENU_TITLE_ITEM, getfilename(path), NULL);
xv_set(mi, MENU_PULLRIGHT, next_menu, NULL);
}
return mi;
}
return (Menu_item)x