diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/Makefile.am | 8 | ||||
-rw-r--r-- | src/include/cache.h | 10 | ||||
-rw-r--r-- | src/include/draw.h | 18 | ||||
-rw-r--r-- | src/include/entry.h | 28 | ||||
-rw-r--r-- | src/include/group.h | 40 | ||||
-rw-r--r-- | src/include/read_cfg.h | 23 | ||||
-rw-r--r-- | src/unix/cache.c | 35 | ||||
-rw-r--r-- | src/unix/draw.c | 14 | ||||
-rw-r--r-- | src/unix/read_cfg.c | 234 | ||||
-rw-r--r-- | src/windows/cache.c | 30 | ||||
-rw-r--r-- | src/windows/draw.c | 44 | ||||
-rw-r--r-- | src/windows/read_cfg.c | 232 |
12 files changed, 716 insertions, 0 deletions
diff --git a/src/Makefile.am b/src/Makefile.am new file mode 100644 index 0000000..561c767 --- /dev/null +++ b/src/Makefile.am @@ -0,0 +1,8 @@ +AUTOMAKE_OPTIONS = subdir-objects + +LIBS = -lncurses + +bin_PROGRAMS = terminal_media_launcher + +terminal_media_launcher_SOURCES = cache.c draw.c read_cfg.c group.c entry.c unix/cache.c unix/draw.c unix/read_cfg.c +terminal_media_launcher_LDADD = $(LIBS) diff --git a/src/include/cache.h b/src/include/cache.h new file mode 100644 index 0000000..0f5a6c4 --- /dev/null +++ b/src/include/cache.h @@ -0,0 +1,10 @@ +#ifndef CACHE_H +#define CACHE_H + +void save_to_cache(int g_hover, int e_hover, int true_hover, char *cfg_name); + +void load_cache(int *g_hover, int *e_hover, int *true_hover, char *new_cfg_name); + +char *get_cache_path(bool create); + +#endif diff --git a/src/include/draw.h b/src/include/draw.h new file mode 100644 index 0000000..0a6baba --- /dev/null +++ b/src/include/draw.h @@ -0,0 +1,18 @@ +#ifndef DRAW_H +#define DRAW_H + +//These functions are needed by either unix/draw.c or windows/draw.c and must be supplied via a header file + +#define BUF_LEN 1024 + +extern int g_hover; +extern int e_hover; +extern struct group **g; +extern struct entry **e; + +char *get_launch(); + +//functions that differ between os +void launch(); + +#endif diff --git a/src/include/entry.h b/src/include/entry.h new file mode 100644 index 0000000..51e43ca --- /dev/null +++ b/src/include/entry.h @@ -0,0 +1,28 @@ +#ifndef ENTRY_H +#define ENTRY_H + +typedef struct entry ENTRY; + +ENTRY *create_entry(char *new_name, char *new_path, bool force); + +void entry_rm(ENTRY *e, ENTRY *prev); + +void clear_entries(ENTRY *head); + +int entry_add(ENTRY *head, ENTRY *tail, ENTRY *add); + +ENTRY **get_entries(ENTRY *head, int count); + +char *get_ename(ENTRY *e); + +char *get_epath(ENTRY *e); + +bool get_eforce(ENTRY *e); + +void set_hide(ENTRY *e, bool status); + +bool get_hide(ENTRY *e); + +void entry_debug(ENTRY *trav); + +#endif diff --git a/src/include/group.h b/src/include/group.h new file mode 100644 index 0000000..ab6f409 --- /dev/null +++ b/src/include/group.h @@ -0,0 +1,40 @@ +#ifndef GROUP_H +#define GROUP_H + +typedef struct group GROUP; + +GROUP *create_group(char *new_name); + +void group_add(char *gname, ENTRY *addme); + +void group_rm(GROUP *g); + +void clean_groups(); //remove empty groups from linked list + +GROUP **get_groups(); + +char *get_gname(GROUP *g); + +char *get_gprog(GROUP *g); + +void set_gprog(GROUP *g, char *p); + +char *get_gflags(GROUP *g); + +void set_gflags(GROUP *g, char *p); + +ENTRY *get_ghead(GROUP *g); + +int get_ecount(GROUP *g); + +void set_ecount(GROUP *g, int new_count); //for use in hiding entries + +void set_gquotes(GROUP *g, bool b); + +bool get_gquotes(GROUP *g); + +int get_gcount(); + +void group_debug(); //debug function to output all groups + +#endif diff --git a/src/include/read_cfg.h b/src/include/read_cfg.h new file mode 100644 index 0000000..b6b996f --- /dev/null +++ b/src/include/read_cfg.h @@ -0,0 +1,23 @@ +#ifndef READ_CFG_H +#define READ_CFG_H + +#define BUF_LEN 1024 + +bool cfg_interp(char *path); +bool get_sort(); +bool get_case_sensitivity(); +void refer_to_doc(); +void addme(char *path, char *group, bool force, char *name); +int search_ch(char *str, char c); +int search_last_ch(char *str, char c); +int wild_cmp(char *wild, char *literal); +char *strip_quotes(char *str); +void error_mes(int ln, char *message); + +//functions that differ by os +extern char sep; +char *find_config(); +void mkconfig_wizard(); +void handle_fname(char *path, char *group, bool recurs, bool force, char *name, int ln); + +#endif diff --git a/src/unix/cache.c b/src/unix/cache.c new file mode 100644 index 0000000..e618602 --- /dev/null +++ b/src/unix/cache.c @@ -0,0 +1,35 @@ +#include <assert.h> +#include <stdbool.h> +#include <stdio.h> +#include <stdlib.h> +#include <sys/stat.h> +#include <sys/types.h> + +#include "../include/cache.h" +#include "../include/read_cfg.h" + +char *get_cache_path(bool create){ + char *path = malloc(sizeof(char) * BUF_LEN); + char *home = getenv("HOME"); + + assert(path != NULL); + + if(home == NULL){ + printf("Failed to save cache data: HOME is not set\n"); + free(path); + return NULL; + } + + //if create is asserted, build the path to the file + if(create){ + sprintf(path, "%s%c.cache%c", home, sep, sep); + mkdir(path, 0755); + + sprintf(path, "%s%c.cache%cterminal-media-launcher%c", home, sep, sep, sep); + mkdir(path, 0755); + } + + sprintf(path, "%s%c.cache%cterminal-media-launcher%cdata.bin", home, sep, sep, sep); + + return path; +} diff --git a/src/unix/draw.c b/src/unix/draw.c new file mode 100644 index 0000000..ae7f758 --- /dev/null +++ b/src/unix/draw.c @@ -0,0 +1,14 @@ +#include <stdlib.h> +#include <string.h> + +#include "../include/draw.h" + +void launch(){ + char full_command[BUF_LEN]; + + strcpy(full_command, get_launch()); + strcat(full_command, " > /dev/null 2>&1 &"); + system(full_command); + + return; +} diff --git a/src/unix/read_cfg.c b/src/unix/read_cfg.c new file mode 100644 index 0000000..4d98c82 --- /dev/null +++ b/src/unix/read_cfg.c @@ -0,0 +1,234 @@ +#include <assert.h> +#include <dirent.h> +#include <stdbool.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <sys/stat.h> +#include <sys/types.h> +#include <unistd.h> + +#include "../include/read_cfg.h" +#include "../include/entry.h" + +char sep = '/'; + +char *find_config(){ + char *home = getenv("HOME"); + char *path = malloc(sizeof(char) * BUF_LEN); + char choices[2][BUF_LEN]; + int check_count = 2; + int i; + + sprintf(choices[0], "%s%c.config%cterminal-media-launcher%cconfig", home, sep, sep, sep); + sprintf(choices[1], "%s%c.terminal-media-launcher%cconfig", home, sep, sep); + + for(i = 0; i < check_count; i++){ + path = choices[i]; + printf("Checking for config at %s: ", choices[i]); + if(access(path, R_OK) == 0){ + printf("Using config \"%s\"\n\n", path); + return path; + } + else printf("File does not exist\n"); + } + + //TODO no config exists, ask user if they want to autogenerate one + mkconfig_wizard(choices[0]); + path = choices[0]; + return path; +} + +void mkconfig_wizard(char *path){ + char input; + FILE *fp; + + char *home = getenv("HOME"); + + printf("\nNo configuration file found. Auto-generate one now at \"%s\"? [Y/n] ", path); + fflush(stdout); + scanf(" %c", &input); + + if(input == 'n'){ + printf("Configuration will not be auto-generated\n"); + refer_to_doc(); + exit(0); + + } + + printf("Generating configuration file at \"%s\"...\n", path); + + //ensure directories have been created + if(home == NULL){ + printf("Failed: HOME is NULL\n"); + exit(1); + } + + sprintf(path, "%s%c.config%c", home, sep, sep); + mkdir(path, 0755); + + sprintf(path, "%s%c.config%cterminal-media-launcher%c", home, sep, sep, sep); + mkdir(path, 0755); + + sprintf(path, "%s%c.config%cterminal-media-launcher%cconfig", home, sep, sep, sep); + + //open file for writing, make sure non-NULL + fp = fopen(path, "w"); + if(fp == NULL){ + printf("Failed: \"%s\" could not be open for writing\n", path); + exit(1); + } + + //write to file + fprintf(fp, "# This file was auto-generated by terminal-media-launcher. See docs/terminal-media-launcher-config.md or terminal-media-launcher-config(5) for documentation\n" + "# The default launcher is set to \"xdg-open\" which will open files based on the relevant default application set through xdg\n\n" + "# Recursively add files from %s%cMusic%c to Music group\n" + "addGroup Music\n" + "setLauncher Music xdg-open\n", home, sep, sep); + fprintf(fp, "addR %s%cMusic%c*.aac Music\n", home, sep, sep); + fprintf(fp, "addR %s%cMusic%c*.aiff Music\n", home, sep, sep); + fprintf(fp, "addR %s%cMusic%c*.alac Music\n", home, sep, sep); + fprintf(fp, "addR %s%cMusic%c*.au Music\n", home, sep, sep); + fprintf(fp, "addR %s%cMusic%c*.flac Music\n", home, sep, sep); + fprintf(fp, "addR %s%cMusic%c*.m4a Music\n", home, sep, sep); + fprintf(fp, "addR %s%cMusic%c*.mp3 Music\n", home, sep, sep); + fprintf(fp, "addR %s%cMusic%c*.ogg Music\n", home, sep, sep); + fprintf(fp, "addR %s%cMusic%c*.pcm Music\n", home, sep, sep); + fprintf(fp, "addR %s%cMusic%c*.wav Music\n", home, sep, sep); + fprintf(fp, "addR %s%cMusic%c*.wma Music\n\n", home, sep, sep); + fprintf(fp, "# Recursively add files from %s%cPictures%c to Pictures group\n" + "addGroup Pictures\n" + "setLauncher Pictures xdg-open\n", home, sep, sep); + fprintf(fp, "addR %s%cPictures%c*.epi Pictures\n", home, sep, sep); + fprintf(fp, "addR %s%cPictures%c*.eps Pictures\n", home, sep, sep); + fprintf(fp, "addR %s%cPictures%c*.eps2 Pictures\n", home, sep, sep); + fprintf(fp, "addR %s%cPictures%c*.eps3 Pictures\n", home, sep, sep); + fprintf(fp, "addR %s%cPictures%c*.epsf Pictures\n", home, sep, sep); + fprintf(fp, "addR %s%cPictures%c*.epsi Pictures\n", home, sep, sep); + fprintf(fp, "addR %s%cPictures%c*.ept Pictures\n", home, sep, sep); + fprintf(fp, "addR %s%cPictures%c*.gif Pictures\n", home, sep, sep); + fprintf(fp, "addR %s%cPictures%c*.gfa Pictures\n", home, sep, sep); + fprintf(fp, "addR %s%cPictures%c*.giff Pictures\n", home, sep, sep); + fprintf(fp, "addR %s%cPictures%c*.jpeg Pictures\n", home, sep, sep); + fprintf(fp, "addR %s%cPictures%c*.jpg Pictures\n", home, sep, sep); + fprintf(fp, "addR %s%cPictures%c*.png Pictures\n", home, sep, sep); + fprintf(fp, "addR %s%cPictures%c*.svg Pictures\n", home, sep, sep); + fprintf(fp, "addR %s%cPictures%c*.svgz Pictures\n", home, sep, sep); + fprintf(fp, "addR %s%cPictures%c*.tif Pictures\n", home, sep, sep); + fprintf(fp, "addR %s%cPictures%c*.tiff Pictures\n\n", home, sep, sep); + fprintf(fp, "# Recursively add files from %s%cVideos%c to Videos group\n" + "addGroup Videos\n" + "setLauncher Videos xdg-open\n", home, sep, sep); + fprintf(fp, "addR %s%cVideos%c*.asf Videos\n", home, sep, sep); + fprintf(fp, "addR %s%cVideos%c*.avi Videos\n", home, sep, sep); + fprintf(fp, "addR %s%cVideos%c*.flv Videos\n", home, sep, sep); + fprintf(fp, "addR %s%cVideos%c*.mk3d Videos\n", home, sep, sep); + fprintf(fp, "addR %s%cVideos%c*.mkv Videos\n", home, sep, sep); + fprintf(fp, "addR %s%cVideos%c*.mov Videos\n", home, sep, sep); + fprintf(fp, "addR %s%cVideos%c*.mp4 Videos\n", home, sep, sep); + fprintf(fp, "addR %s%cVideos%c*.qt Videos\n", home, sep, sep); + fprintf(fp, "addR %s%cVideos%c*.webm Videos\n", home, sep, sep); + fprintf(fp, "addR %s%cVideos%c*.wmv Videos\n", home, sep, sep); + + fclose(fp); + printf("done\nIt is highly recommended to further tweak the configuration file! [press any key to continue]"); + fflush(stdout); + getchar(); + getchar(); + + return; +} + +//TODO augment to involve recurs +//TODO could use some cleanup... +void handle_fname(char *path, char *group, bool recurs, bool force, char *name, int ln){ + ENTRY *new; + char *search; //pointer for traversing path + char full_path_cpy[BUF_LEN]; + char relative_path_cpy[BUF_LEN]; + char arg_cpy[BUF_LEN]; + char auto_name[BUF_LEN]; + int plen = strlen(path); + char *dirname; + char *local_arg; //for use in addR + DIR *dp; + struct dirent *fname; + int i; + char *error_p; //helper for complex error messages + + assert(path != NULL && group != NULL); + + if(path[0] == '\0' || group[0] == '\0'){ + error_mes(ln, "Too few arguments for \"add\""); + return; + } + + //address potential quotes + strcpy(full_path_cpy, strip_quotes(path)); + + //don't check that the path arg is valid when forced + if(force) addme(full_path_cpy, group, force, name); + + //file is not recognized, perhaps it has a wildcard? + //TODO finish rewriting a more robust wildcard thingy + else if(access(full_path_cpy, F_OK) == -1){ + i = search_ch(full_path_cpy, '*'); + if(i > -1){ + //look for a directory + while(full_path_cpy[i] != sep && (i >= 0)){ + i--; + } + dirname = full_path_cpy; + strcpy(arg_cpy, full_path_cpy); + dirname[i+1] = '\0'; + dp = opendir(dirname); + + //the directory is real + if(dp != NULL){ + while(fname = readdir(dp)){ + relative_path_cpy[0] = '\0'; + strcat(relative_path_cpy, dirname); + strcat(relative_path_cpy, fname->d_name); + + //check if path is a file (and not a directory/symlink/etc.) and regex matches + if(fname->d_type == DT_REG && !(wild_cmp(&arg_cpy[i+1], fname->d_name))) addme(relative_path_cpy, group, force, name); + + //if the recursive option was specified and the path is a directory, run handle_fname on this directory, but for security reasons, do not consider directories that start with a '.' + else if(recurs && fname->d_type == DT_DIR && fname->d_name[0] != '.'){ + i = search_last_ch(arg_cpy, sep); + local_arg = &arg_cpy[i+1]; + strcat(relative_path_cpy, &sep); + strcat(relative_path_cpy, local_arg); + handle_fname(relative_path_cpy, group, 1, 0, NULL, ln); + } + + } + + closedir(dp); + } + + //directory is not real, report error to the user + else{ + error_p = malloc(sizeof(char) * 1024); + sprintf(error_p, "\"%s\" bad path", dirname); + error_mes(ln, error_p); + free(error_p); + //printf("Error: \"%s\" bad path\n", dirname); + } + } + + //path is not real, report error to the user + else{ + error_p = malloc(sizeof(char) * 1024); + sprintf(error_p, "\"%s\" bad path", full_path_cpy); + error_mes(ln, error_p); + free(error_p); + } + } + + //file name is okay + //FIXME does not take into account whether the argument is a file (could be a directory, symlink, etc.) + else addme(full_path_cpy, group, force, name); + + return; +} diff --git a/src/windows/cache.c b/src/windows/cache.c new file mode 100644 index 0000000..01db0ef --- /dev/null +++ b/src/windows/cache.c @@ -0,0 +1,30 @@ +#include <assert.h> +#include <stdbool.h> +#include <stdio.h> +#include <stdlib.h> +#include <sys/stat.h> +#include <sys/types.h> + +#include "../include/cache.h" +#include "../include/read_cfg.h" + +char *get_cache_path(bool create){ + char *path = malloc(sizeof(char) * BUF_LEN); + char *appdata = getenv("APPDATA"); + + if(appdata == NULL){ + printf("Failed to save cache data: APPDATA is not set\n"); + free(path); + return NULL; + } + + //if create is asserted, build the path to the file + if(create){ + sprintf(path, "%s%cterminal-media-launcher%c", appdata, sep, sep); + mkdir(path); + } + + sprintf(path, "%s%cterminal-media-launcher%ccache.bin", appdata, sep, sep); + + return path; +} diff --git a/src/windows/draw.c b/src/windows/draw.c new file mode 100644 index 0000000..28bef68 --- /dev/null +++ b/src/windows/draw.c @@ -0,0 +1,44 @@ +#include <stdbool.h> +#include <windows.h> + +#include "../include/draw.h" +#include "../include/entry.h" +#include "../include/group.h" + +void launch(){ + char *program = get_gprog(g[g_hover]); + char *flags = get_gflags(g[g_hover]); + char *path = get_epath(e[e_hover]); + bool quotes = get_gquotes(g[g_hover]); + char file[BUF_LEN]; + char params[BUF_LEN]; + + file[0] = '\0'; + + if(!(strcmp(program, "./"))){ + strcat(file, "/C "); + strcat(file, "\""); + strcat(file, path); + strcat(file, "\""); + ShellExecute(NULL, NULL, "cmd.exe", file, NULL, SW_HIDE); + } + + else{ + if(quotes) strcat(file, "\""); + strcat(file, program); + if(quotes) strcat(file, "\""); + + params[0] = '\0'; + if(flags[0] != '\0'){ + strcat(params, flags); + strcat(params, " "); + } + strcat(params, "\""); + strcat(params, path); + strcat(params, "\""); + + ShellExecute(NULL, NULL, file, params, NULL, SW_SHOW); + } + + return; +} diff --git a/src/windows/read_cfg.c b/src/windows/read_cfg.c new file mode 100644 index 0000000..2a56ef8 --- /dev/null +++ b/src/windows/read_cfg.c @@ -0,0 +1,232 @@ +#include <assert.h> +#include <dirent.h> +#include <stdbool.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <sys/stat.h> +#include <sys/types.h> +#include <unistd.h> + +#include "../include/entry.h" +#include "../include/read_cfg.h" + +char sep = '\\'; + +char *find_config(){ + char *appdata = getenv("APPDATA"); + char *path = malloc(sizeof(char) * BUF_LEN); + int check_count = 1; + char choices[check_count][BUF_LEN]; + int i; + + sprintf(choices[0], "%s%cterminal-media-launcher%cconfig", appdata, sep, sep); + + for(i = 0; i < check_count; i++){ + path = choices[i]; + printf("Checking for config at %s: ", choices[i]); + if(access(path, R_OK) == 0){ + printf("Using config \"%s\"\n\n", path); + return path; + } + else printf("File does not exist\n"); + } + + //TODO no config exists, ask user if they want to autogenerate one + mkconfig_wizard(choices[0]); + path = choices[0]; + return path; +} + +void mkconfig_wizard(char *path){ + char input; + FILE *fp; + + char *home = getenv("USERPROFILE"); + char *appdata = getenv("APPDATA"); + + printf("\nNo configuration file found. Auto-generate one now at \"%s\"? [Y/n] ", path); + fflush(stdout); + scanf(" %c", &input); + + if(input == 'n'){ + printf("Configuration will not be auto-generated\n"); + refer_to_doc(); + exit(0); + + } + + printf("Generating configuration file at \"%s\"...\n", path); + + //ensure directories have been created + if(appdata == NULL){ + printf("Failed: \%APPDATA\% is NULL\n"); + exit(1); + } + + if(home == NULL){ + printf("Failed: \%USERPROFILE\% is NULL\n"); + exit(1); + } + + sprintf(path, "%s%cterminal-media-launcher%c", appdata, sep, sep); + mkdir(path); + + sprintf(path, "%s%cterminal-media-launcher%cconfig", appdata, sep, sep); + + //open file for writing, make sure non-NULL + fp = fopen(path, "w"); + if(fp == NULL){ + printf("Failed: \"%s\" could not be open for writing\n", path); + exit(1); + } + + fprintf(fp, "# This file was auto-generated by terminal-media-launcher. See docs\\terminal-media-launcher-config.md or terminal-media-launcher-config(5) for documentation\n" + "# By default, no launcher is specified for any group. When no launcher is specified on the Windows build of terminal-media-launcher, media files will be opened with their default application.\n" + "# It is generally recommended to specify a launcher for groups containing media files using the \"setLauncher\" command\n\n" + "# Recursively add files from %s%cMusic%c to Music group\n" + "addGroup Music\n", home, sep, sep); + fprintf(fp, "addR %s%cMusic%c*.aac Music\n", home, sep, sep); + fprintf(fp, "addR %s%cMusic%c*.aiff Music\n", home, sep, sep); + fprintf(fp, "addR %s%cMusic%c*.alac Music\n", home, sep, sep); + fprintf(fp, "addR %s%cMusic%c*.au Music\n", home, sep, sep); + fprintf(fp, "addR %s%cMusic%c*.flac Music\n", home, sep, sep); + fprintf(fp, "addR %s%cMusic%c*.m4a Music\n", home, sep, sep); + fprintf(fp, "addR %s%cMusic%c*.mp3 Music\n", home, sep, sep); + fprintf(fp, "addR %s%cMusic%c*.ogg Music\n", home, sep, sep); + fprintf(fp, "addR %s%cMusic%c*.pcm Music\n", home, sep, sep); + fprintf(fp, "addR %s%cMusic%c*.wav Music\n", home, sep, sep); + fprintf(fp, "addR %s%cMusic%c*.wma Music\n\n", home, sep, sep); + fprintf(fp, "# Recursively add files from %s%cPictures%c to Pictures group\n" + "addGroup Pictures\n", home, sep, sep); + fprintf(fp, "addR %s%cPictures%c*.epi Pictures\n", home, sep, sep); + fprintf(fp, "addR %s%cPictures%c*.eps Pictures\n", home, sep, sep); + fprintf(fp, "addR %s%cPictures%c*.eps2 Pictures\n", home, sep, sep); + fprintf(fp, "addR %s%cPictures%c*.eps3 Pictures\n", home, sep, sep); + fprintf(fp, "addR %s%cPictures%c*.epsf Pictures\n", home, sep, sep); + fprintf(fp, "addR %s%cPictures%c*.epsi Pictures\n", home, sep, sep); + fprintf(fp, "addR %s%cPictures%c*.ept Pictures\n", home, sep, sep); + fprintf(fp, "addR %s%cPictures%c*.gif Pictures\n", home, sep, sep); + fprintf(fp, "addR %s%cPictures%c*.gfa Pictures\n", home, sep, sep); + fprintf(fp, "addR %s%cPictures%c*.giff Pictures\n", home, sep, sep); + fprintf(fp, "addR %s%cPictures%c*.jpeg Pictures\n", home, sep, sep); + fprintf(fp, "addR %s%cPictures%c*.jpg Pictures\n", home, sep, sep); + fprintf(fp, "addR %s%cPictures%c*.png Pictures\n", home, sep, sep); + fprintf(fp, "addR %s%cPictures%c*.svg Pictures\n", home, sep, sep); + fprintf(fp, "addR %s%cPictures%c*.svgz Pictures\n", home, sep, sep); + fprintf(fp, "addR %s%cPictures%c*.tif Pictures\n", home, sep, sep); + fprintf(fp, "addR %s%cPictures%c*.tiff Pictures\n\n", home, sep, sep); + fprintf(fp, "# Recursively add files from %s%cVideos%c to Videos group\n" + "addGroup Videos\n", home, sep, sep); + fprintf(fp, "addR %s%cVideos%c*.asf Videos\n", home, sep, sep); + fprintf(fp, "addR %s%cVideos%c*.avi Videos\n", home, sep, sep); + fprintf(fp, "addR %s%cVideos%c*.flv Videos\n", home, sep, sep); + fprintf(fp, "addR %s%cVideos%c*.mk3d Videos\n", home, sep, sep); + fprintf(fp, "addR %s%cVideos%c*.mkv Videos\n", home, sep, sep); + fprintf(fp, "addR %s%cVideos%c*.mov Videos\n", home, sep, sep); + fprintf(fp, "addR %s%cVideos%c*.mp4 Videos\n", home, sep, sep); + fprintf(fp, "addR %s%cVideos%c*.qt Videos\n", home, sep, sep); + fprintf(fp, "addR %s%cVideos%c*.webm Videos\n", home, sep, sep); + fprintf(fp, "addR %s%cVideos%c*.wmv Videos\n", home, sep, sep); + + fclose(fp); + printf("done\nIt is highly recommended to further tweak the configuration file! [press any key to continue]"); + fflush(stdout); + getchar(); + getchar(); + + return; +} + +//TODO augment to involve recurs +//TODO could use some cleanup... +void handle_fname(char *path, char *group, bool recurs, bool force, char *name, int ln){ + ENTRY *new; + char *search; //pointer for traversing path + char full_path_cpy[BUF_LEN]; + char relative_path_cpy[BUF_LEN]; + char arg_cpy[BUF_LEN]; + char auto_name[BUF_LEN]; + int plen = strlen(path); + char *dirname; + char *local_arg; //for use in addR + DIR *dp; + struct dirent *fname; + int i; + char *error_p; //helper for complex error messages + + assert(path != NULL && group != NULL); + + if(path[0] == '\0' || group[0] == '\0'){ + error_mes(ln, "Too few arguments for \"add\""); + return; + } + + //address potential quotes + strcpy(full_path_cpy, strip_quotes(path)); + + //don't check that the path arg is valid when forced + if(force) addme(full_path_cpy, group, force, name); + + //file is not recognized, perhaps it has a wildcard? + //TODO finish rewriting a more robust wildcard thingy + else if(access(full_path_cpy, F_OK) == -1){ + i = search_ch(full_path_cpy, '*'); + if(i > -1){ + //look for a directory + while(full_path_cpy[i] != sep && (i >= 0)){ + i--; + } + dirname = full_path_cpy; + strcpy(arg_cpy, full_path_cpy); + dirname[i+1] = '\0'; + dp = opendir(dirname); + + //the directory is real + if(dp != NULL){ + while(fname = readdir(dp)){ + relative_path_cpy[0] = '\0'; + strcat(relative_path_cpy, dirname); + strcat(relative_path_cpy, fname->d_name); + + //Windows cannot tell file types (TODO), so just add relatively indiscriminantly + if(!(wild_cmp(&arg_cpy[i+1], fname->d_name))) addme(relative_path_cpy, group, force, name); + + //if the recursive option was specified, run handle_fname on this directory, but for security reasons, do not consider directories that start with a '.' + else if(recurs && fname->d_name[0] != '.'){ + i = search_last_ch(arg_cpy, sep); + local_arg = &arg_cpy[i+1]; + strcat(relative_path_cpy, &sep); + strcat(relative_path_cpy, local_arg); + handle_fname(relative_path_cpy, group, 1, 0, NULL, ln); + } + } + + closedir(dp); + } + + //directory is not real, report error to the user + else if(!recurs){ + error_p = malloc(sizeof(char) * 1024); + sprintf(error_p, "\"%s\" bad path", dirname); + error_mes(ln, error_p); + free(error_p); + //printf("Error: \"%s\" bad path\n", dirname); + } + } + + //path is not real, report error to the user + else{ + error_p = malloc(sizeof(char) * 1024); + sprintf(error_p, "\"%s\" bad path", full_path_cpy); + error_mes(ln, error_p); + free(error_p); + } + } + + //file name is okay + //FIXME does not take into account whether the argument is a file (could be a directory, symlink, etc.) + else addme(full_path_cpy, group, force, name); + + return; +} |