mirror of
				https://github.com/alsa-project/alsa-lib.git
				synced 2025-11-03 09:01:52 -05:00 
			
		
		
		
	conf: Search included files under user specified configuration directories
Users can include file by giving a relative path or just a file name via alsaconf syntax <xxx>. ALSA conf will search the file in top configuration directory and additional configuration directories defined by users via alsaconf syntax <searchdir:xxx>. ALSA conf will search and open an included file in the following order of priority: 1. directly open the file by its name; 2. search for the file name in top config direcotry "/usr/share/alsa/"; 3. search for the file name in additional configuration directories specified by users, via alsaconf syntax <searchdir:relative-path/to/user/share/alsa>; These directories will be searched in the same order as their definition. The configuration directories defined by a file will only be used to search the files included by this file. Signed-off-by: Mengdong Lin <mengdong.lin@linux.intel.com> Signed-off-by: Takashi Iwai <tiwai@suse.de>
This commit is contained in:
		
							parent
							
								
									adb9866b70
								
							
						
					
					
						commit
						c169438682
					
				
					 1 changed files with 158 additions and 1 deletions
				
			
		
							
								
								
									
										159
									
								
								src/conf.c
									
										
									
									
									
								
							
							
						
						
									
										159
									
								
								src/conf.c
									
										
									
									
									
								
							| 
						 | 
					@ -456,6 +456,18 @@ struct filedesc {
 | 
				
			||||||
	snd_input_t *in;
 | 
						snd_input_t *in;
 | 
				
			||||||
	unsigned int line, column;
 | 
						unsigned int line, column;
 | 
				
			||||||
	struct filedesc *next;
 | 
						struct filedesc *next;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/* list of the include paths (configuration directories),
 | 
				
			||||||
 | 
						 * defined by <searchdir:relative-path/to/top-alsa-conf-dir>,
 | 
				
			||||||
 | 
						 * for searching its included files.
 | 
				
			||||||
 | 
						 */
 | 
				
			||||||
 | 
						struct list_head include_paths;
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* path to search included files */
 | 
				
			||||||
 | 
					struct include_path {
 | 
				
			||||||
 | 
						char *dir;
 | 
				
			||||||
 | 
						struct list_head list;
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#define LOCAL_ERROR			(-0x68000000)
 | 
					#define LOCAL_ERROR			(-0x68000000)
 | 
				
			||||||
| 
						 | 
					@ -501,6 +513,108 @@ static inline void snd_config_unlock(void) { }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/*
 | 
				
			||||||
 | 
					 * Add a diretory to the paths to search included files.
 | 
				
			||||||
 | 
					 * param fd -  File object that owns these paths to search files included by it.
 | 
				
			||||||
 | 
					 * param dir - Path of the directory to add. Allocated externally and need to
 | 
				
			||||||
 | 
					*              be freed manually later.
 | 
				
			||||||
 | 
					 * return - Zero if successful, otherwise a negative error code.
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * The direcotry should be a subdiretory of top configuration directory
 | 
				
			||||||
 | 
					 * "/usr/share/alsa/".
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					static int add_include_path(struct filedesc *fd, char *dir)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						struct include_path *path;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						path = calloc(1, sizeof(*path));
 | 
				
			||||||
 | 
						if (!path)
 | 
				
			||||||
 | 
							return -ENOMEM;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						path->dir = dir;
 | 
				
			||||||
 | 
						list_add_tail(&path->list, &fd->include_paths);
 | 
				
			||||||
 | 
						return 0;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/*
 | 
				
			||||||
 | 
					 * Free all include paths of a file descriptor.
 | 
				
			||||||
 | 
					 * param fd - File object that owns these paths to search files included by it.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					static void free_include_paths(struct filedesc *fd)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						struct list_head *pos, *npos, *base;
 | 
				
			||||||
 | 
						struct include_path *path;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						base = &fd->include_paths;
 | 
				
			||||||
 | 
						list_for_each_safe(pos, npos, base) {
 | 
				
			||||||
 | 
							path = list_entry(pos, struct include_path, list);
 | 
				
			||||||
 | 
							list_del(&path->list);
 | 
				
			||||||
 | 
							if (path->dir)
 | 
				
			||||||
 | 
								free(path->dir);
 | 
				
			||||||
 | 
							free(path);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/*
 | 
				
			||||||
 | 
					 * Search and open a file, and creates a new input object reading from the file.
 | 
				
			||||||
 | 
					 * param inputp - The functions puts the pointer to the new input object
 | 
				
			||||||
 | 
					 *               at the address specified by \p inputp.
 | 
				
			||||||
 | 
					 * param file - Name of the configuration file.
 | 
				
			||||||
 | 
					 * param include_paths - Optional, addtional directories to search the file.
 | 
				
			||||||
 | 
					 * return - Zero if successful, otherwise a negative error code.
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * This function will search and open the file in the following order
 | 
				
			||||||
 | 
					 * of priority:
 | 
				
			||||||
 | 
					 * 1. directly open the file by its name;
 | 
				
			||||||
 | 
					 * 2. search for the file name in top configuration directory
 | 
				
			||||||
 | 
					 *     "/usr/share/alsa/";
 | 
				
			||||||
 | 
					 * 3. search for the file name in in additional configuration directories
 | 
				
			||||||
 | 
					 *     specified by users, via alsaconf syntax
 | 
				
			||||||
 | 
					 *     <searchdir:relative-path/to/user/share/alsa>;
 | 
				
			||||||
 | 
					 *     These directories should be subdirectories of /usr/share/alsa.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					static int input_stdio_open(snd_input_t **inputp, const char *file,
 | 
				
			||||||
 | 
								    struct list_head *include_paths)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						struct list_head *pos, *base;
 | 
				
			||||||
 | 
						struct include_path *path;
 | 
				
			||||||
 | 
						char full_path[PATH_MAX + 1];
 | 
				
			||||||
 | 
						int err = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						err = snd_input_stdio_open(inputp, file, "r");
 | 
				
			||||||
 | 
						if (err == 0)
 | 
				
			||||||
 | 
							goto out;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (file[0] == '/') /* not search file with absolute path */
 | 
				
			||||||
 | 
							return err;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/* search file in top configuration directory /usr/share/alsa */
 | 
				
			||||||
 | 
						snprintf(full_path, PATH_MAX, "%s/%s", ALSA_CONFIG_DIR, file);
 | 
				
			||||||
 | 
						err = snd_input_stdio_open(inputp, full_path, "r");
 | 
				
			||||||
 | 
						if (err == 0)
 | 
				
			||||||
 | 
							goto out;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/* search file in user specified include paths. These directories
 | 
				
			||||||
 | 
						 * are subdirectories of /usr/share/alsa.
 | 
				
			||||||
 | 
						 */
 | 
				
			||||||
 | 
						if (include_paths) {
 | 
				
			||||||
 | 
							base = include_paths;
 | 
				
			||||||
 | 
							list_for_each(pos, base) {
 | 
				
			||||||
 | 
								path = list_entry(pos, struct include_path, list);
 | 
				
			||||||
 | 
								if (!path->dir)
 | 
				
			||||||
 | 
									continue;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								snprintf(full_path, PATH_MAX, "%s/%s", path->dir, file);
 | 
				
			||||||
 | 
								err = snd_input_stdio_open(inputp, full_path, "r");
 | 
				
			||||||
 | 
								if (err == 0)
 | 
				
			||||||
 | 
									goto out;
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					out:
 | 
				
			||||||
 | 
						return err;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static int safe_strtoll(const char *str, long long *val)
 | 
					static int safe_strtoll(const char *str, long long *val)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	long long v;
 | 
						long long v;
 | 
				
			||||||
| 
						 | 
					@ -629,10 +743,44 @@ static int get_char_skip_comments(input_t *input)
 | 
				
			||||||
			char *str;
 | 
								char *str;
 | 
				
			||||||
			snd_input_t *in;
 | 
								snd_input_t *in;
 | 
				
			||||||
			struct filedesc *fd;
 | 
								struct filedesc *fd;
 | 
				
			||||||
 | 
								DIR *dirp;
 | 
				
			||||||
			int err = get_delimstring(&str, '>', input);
 | 
								int err = get_delimstring(&str, '>', input);
 | 
				
			||||||
			if (err < 0)
 | 
								if (err < 0)
 | 
				
			||||||
				return err;
 | 
									return err;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								if (!strncmp(str, "searchdir:", 10)) {
 | 
				
			||||||
 | 
									/* directory to search included files */
 | 
				
			||||||
 | 
									char *tmp;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
									tmp = malloc(strlen(ALSA_CONFIG_DIR) + 1
 | 
				
			||||||
 | 
										     + strlen(str + 10) + 1);
 | 
				
			||||||
 | 
									if (tmp == NULL) {
 | 
				
			||||||
 | 
										free(str);
 | 
				
			||||||
 | 
										return -ENOMEM;
 | 
				
			||||||
 | 
									}
 | 
				
			||||||
 | 
									sprintf(tmp, ALSA_CONFIG_DIR "/%s", str + 10);
 | 
				
			||||||
 | 
									free(str);
 | 
				
			||||||
 | 
									str = tmp;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
									dirp = opendir(str);
 | 
				
			||||||
 | 
									if (!dirp) {
 | 
				
			||||||
 | 
										SNDERR("Invalid search dir %s", str);
 | 
				
			||||||
 | 
										free(str);
 | 
				
			||||||
 | 
										return -EINVAL;
 | 
				
			||||||
 | 
									}
 | 
				
			||||||
 | 
									closedir(dirp);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
									err = add_include_path(input->current, str);
 | 
				
			||||||
 | 
									if (err < 0) {
 | 
				
			||||||
 | 
										SNDERR("Cannot add search dir %s", str);
 | 
				
			||||||
 | 
										free(str);
 | 
				
			||||||
 | 
										return err;
 | 
				
			||||||
 | 
									}
 | 
				
			||||||
 | 
									continue;
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			if (!strncmp(str, "confdir:", 8)) {
 | 
								if (!strncmp(str, "confdir:", 8)) {
 | 
				
			||||||
 | 
									/* file in the specified directory */
 | 
				
			||||||
				char *tmp = malloc(strlen(ALSA_CONFIG_DIR) + 1 + strlen(str + 8) + 1);
 | 
									char *tmp = malloc(strlen(ALSA_CONFIG_DIR) + 1 + strlen(str + 8) + 1);
 | 
				
			||||||
				if (tmp == NULL) {
 | 
									if (tmp == NULL) {
 | 
				
			||||||
					free(str);
 | 
										free(str);
 | 
				
			||||||
| 
						 | 
					@ -641,8 +789,12 @@ static int get_char_skip_comments(input_t *input)
 | 
				
			||||||
				sprintf(tmp, ALSA_CONFIG_DIR "/%s", str + 8);
 | 
									sprintf(tmp, ALSA_CONFIG_DIR "/%s", str + 8);
 | 
				
			||||||
				free(str);
 | 
									free(str);
 | 
				
			||||||
				str = tmp;
 | 
									str = tmp;
 | 
				
			||||||
 | 
									err = snd_input_stdio_open(&in, str, "r");
 | 
				
			||||||
 | 
								} else { /* absolute or relative file path */
 | 
				
			||||||
 | 
									err = input_stdio_open(&in, str,
 | 
				
			||||||
 | 
											&input->current->include_paths);
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
			err = snd_input_stdio_open(&in, str, "r");
 | 
					
 | 
				
			||||||
			if (err < 0) {
 | 
								if (err < 0) {
 | 
				
			||||||
				SNDERR("Cannot access file %s", str);
 | 
									SNDERR("Cannot access file %s", str);
 | 
				
			||||||
				free(str);
 | 
									free(str);
 | 
				
			||||||
| 
						 | 
					@ -658,6 +810,7 @@ static int get_char_skip_comments(input_t *input)
 | 
				
			||||||
			fd->next = input->current;
 | 
								fd->next = input->current;
 | 
				
			||||||
			fd->line = 1;
 | 
								fd->line = 1;
 | 
				
			||||||
			fd->column = 0;
 | 
								fd->column = 0;
 | 
				
			||||||
 | 
								INIT_LIST_HEAD(&fd->include_paths);
 | 
				
			||||||
			input->current = fd;
 | 
								input->current = fd;
 | 
				
			||||||
			continue;
 | 
								continue;
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
| 
						 | 
					@ -1668,6 +1821,7 @@ static int snd_config_load1(snd_config_t *config, snd_input_t *in, int override)
 | 
				
			||||||
	fd->line = 1;
 | 
						fd->line = 1;
 | 
				
			||||||
	fd->column = 0;
 | 
						fd->column = 0;
 | 
				
			||||||
	fd->next = NULL;
 | 
						fd->next = NULL;
 | 
				
			||||||
 | 
						INIT_LIST_HEAD(&fd->include_paths);
 | 
				
			||||||
	input.current = fd;
 | 
						input.current = fd;
 | 
				
			||||||
	input.unget = 0;
 | 
						input.unget = 0;
 | 
				
			||||||
	err = parse_defs(config, &input, 0, override);
 | 
						err = parse_defs(config, &input, 0, override);
 | 
				
			||||||
| 
						 | 
					@ -1708,9 +1862,12 @@ static int snd_config_load1(snd_config_t *config, snd_input_t *in, int override)
 | 
				
			||||||
		fd_next = fd->next;
 | 
							fd_next = fd->next;
 | 
				
			||||||
		snd_input_close(fd->in);
 | 
							snd_input_close(fd->in);
 | 
				
			||||||
		free(fd->name);
 | 
							free(fd->name);
 | 
				
			||||||
 | 
							free_include_paths(fd);
 | 
				
			||||||
		free(fd);
 | 
							free(fd);
 | 
				
			||||||
		fd = fd_next;
 | 
							fd = fd_next;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						free_include_paths(fd);
 | 
				
			||||||
	free(fd);
 | 
						free(fd);
 | 
				
			||||||
	return err;
 | 
						return err;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue