| 
																	
																	
																	
																 | 
																@ -0,0 +1,101 @@ | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																/* See LICENSE file for copyright and license details. */ | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																#include <dirent.h> | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																#include <stdio.h> | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																#include <stdlib.h> | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																#include <string.h> | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																#include <unistd.h> | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																#include <sys/stat.h> | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																
 | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																#define CACHE ".dmenu_cache" | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																
 | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																static int qstrcmp(const void *a, const void *b); | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																static void die(const char *s); | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																static void scan(void); | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																static int uptodate(void); | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																
 | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																static char **items = NULL; | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																static const char *Home, *Path; | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																static size_t count = 0; | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																
 | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																int | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																main(void) { | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																	if(!(Home = getenv("HOME"))) | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																		die("no $HOME"); | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																	if(!(Path = getenv("PATH"))) | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																		die("no $PATH"); | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																	if(chdir(Home) < 0) | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																		die("chdir failed"); | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																	if(uptodate()) { | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																		execlp("cat", "cat", CACHE, NULL); | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																		die("exec failed"); | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																	} | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																	scan(); | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																	return EXIT_SUCCESS; | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																} | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																
 | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																void | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																die(const char *s) { | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																	fprintf(stderr, "dmenu_path: %s\n", s); | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																	exit(EXIT_FAILURE); | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																} | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																
 | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																int | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																qstrcmp(const void *a, const void *b) { | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																	return strcmp(*(const char **)a, *(const char **)b); | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																} | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																
 | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																void | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																scan(void) { | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																	char buf[PATH_MAX]; | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																	char *dir, *path; | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																	size_t i; | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																	struct dirent *ent; | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																	DIR *dp; | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																	FILE *cache; | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																
 | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																	if(!(path = strdup(Path))) | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																		die("strdup failed"); | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																	for(dir = strtok(path, ":"); dir; dir = strtok(NULL, ":")) { | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																		if(!(dp = opendir(dir))) | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																			continue; | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																		while((ent = readdir(dp))) { | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																			snprintf(buf, sizeof buf, "%s/%s", dir, ent->d_name); | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																			if(ent->d_name[0] == '.' || access(buf, X_OK) < 0) | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																				continue; | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																			if(!(items = realloc(items, ++count * sizeof *items))) | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																				die("malloc failed"); | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																			if(!(items[count-1] = strdup(ent->d_name))) | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																				die("strdup failed"); | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																		} | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																		closedir(dp); | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																	} | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																	qsort(items, count, sizeof *items, qstrcmp); | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																	if(!(cache = fopen(CACHE, "w"))) | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																		die("open failed"); | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																	for(i = 0; i < count; i++) { | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																		if(i > 0 && !strcmp(items[i], items[i-1])) | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																			continue; | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																		fprintf(cache,  "%s\n", items[i]); | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																		fprintf(stdout, "%s\n", items[i]); | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																	} | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																	fclose(cache); | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																	free(path); | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																} | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																
 | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																int | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																uptodate(void) { | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																	char *dir, *path; | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																	time_t mtime; | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																	struct stat st; | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																
 | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																	if(stat(CACHE, &st) < 0) | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																		return 0; | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																	mtime = st.st_mtime; | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																	if(!(path = strdup(Path))) | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																		die("strdup failed"); | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																	for(dir = strtok(path, ":"); dir; dir = strtok(NULL, ":")) | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																		if(!stat(dir, &st) && st.st_mtime > mtime) | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																			return 0; | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																	free(path); | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																	return 1; | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																} |