diff options
Diffstat (limited to 'trunk/src/ls.c')
-rw-r--r-- | trunk/src/ls.c | 281 |
1 files changed, 281 insertions, 0 deletions
diff --git a/trunk/src/ls.c b/trunk/src/ls.c new file mode 100644 index 000000000..0b3f7f354 --- /dev/null +++ b/trunk/src/ls.c @@ -0,0 +1,281 @@ +/* the Music Player Daemon (MPD) + * Copyright (C) 2003-2007 by Warren Dukes (warren.dukes@gmail.com) + * This project's homepage is: http://www.musicpd.org + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include "ls.h" +#include "playlist.h" +#include "path.h" +#include "myfprintf.h" +#include "log.h" +#include "utf8.h" +#include "utils.h" + +#include <dirent.h> +#include <stdio.h> +#include <errno.h> + +static char *remoteUrlPrefixes[] = { + "http://", + NULL +}; + +int printRemoteUrlHandlers(int fd) +{ + char **prefixes = remoteUrlPrefixes; + + while (*prefixes) { + fdprintf(fd, "handler: %s\n", *prefixes); + prefixes++; + } + + return 0; +} + +int isValidRemoteUtf8Url(char *utf8url) +{ + int ret = 0; + char *temp; + + switch (isRemoteUrl(utf8url)) { + case 1: + ret = 1; + temp = utf8url; + while (*temp) { + if ((*temp >= 'a' && *temp <= 'z') || + (*temp >= 'A' && *temp <= 'Z') || + (*temp >= '0' && *temp <= '9') || + *temp == '$' || + *temp == '-' || + *temp == '.' || + *temp == '+' || + *temp == '!' || + *temp == '*' || + *temp == '\'' || + *temp == '(' || + *temp == ')' || + *temp == ',' || + *temp == '%' || + *temp == '/' || + *temp == ':' || + *temp == '?' || + *temp == ';' || *temp == '&' || *temp == '=') { + } else { + ret = 1; + break; + } + temp++; + } + break; + } + + return ret; +} + +int isRemoteUrl(char *url) +{ + int count = 0; + char **urlPrefixes = remoteUrlPrefixes; + + while (*urlPrefixes) { + count++; + if (strncmp(*urlPrefixes, url, strlen(*urlPrefixes)) == 0) { + return count; + } + urlPrefixes++; + } + + return 0; +} + +int lsPlaylists(int fd, char *utf8path) +{ + DIR *dir; + struct stat st; + struct dirent *ent; + char *dup; + char *utf8; + char s[MAXPATHLEN + 1]; + List *list = NULL; + ListNode *node = NULL; + char *path = utf8ToFsCharset(utf8path); + char *actualPath = rpp2app(path); + int actlen = strlen(actualPath) + 1; + int maxlen = MAXPATHLEN - actlen; + int suflen = strlen(PLAYLIST_FILE_SUFFIX) + 1; + int suff; + + if (actlen > MAXPATHLEN - 1 || (dir = opendir(actualPath)) == NULL) { + return 0; + } + + s[MAXPATHLEN] = '\0'; + /* this is safe, notice actlen > MAXPATHLEN-1 above */ + strcpy(s, actualPath); + strcat(s, "/"); + + while ((ent = readdir(dir))) { + size_t len = strlen(ent->d_name) + 1; + dup = ent->d_name; + if (mpd_likely(len <= maxlen) && + dup[0] != '.' && + (suff = strlen(dup) - suflen) > 0 && + dup[suff] == '.' && + strcmp(dup + suff + 1, PLAYLIST_FILE_SUFFIX) == 0) { + memcpy(s + actlen, ent->d_name, len); + if (stat(s, &st) == 0) { + if (S_ISREG(st.st_mode)) { + if (list == NULL) + list = makeList(NULL, 1); + dup[suff] = '\0'; + if ((utf8 = fsCharsetToUtf8(dup))) { + insertInList(list, utf8, NULL); + } + } + } + } + } + + closedir(dir); + + if (list) { + int i; + sortList(list); + + dup = xmalloc(strlen(utf8path) + 2); + strcpy(dup, utf8path); + for (i = strlen(dup) - 1; i >= 0 && dup[i] == '/'; i--) { + dup[i] = '\0'; + } + if (strlen(dup)) + strcat(dup, "/"); + + node = list->firstNode; + while (node != NULL) { + if (!strchr(node->key, '\n')) { + fdprintf(fd, "playlist: %s%s\n", dup, + node->key); + } + node = node->nextNode; + } + + freeList(list); + free(dup); + } + + return 0; +} + +int myStat(char *utf8file, struct stat *st) +{ + char *file = utf8ToFsCharset(utf8file); + char *actualFile = file; + + if (actualFile[0] != '/') + actualFile = rmp2amp(file); + + return stat(actualFile, st); +} + +static int isFile(char *utf8file, time_t * mtime) +{ + struct stat st; + + if (myStat(utf8file, &st) == 0) { + if (S_ISREG(st.st_mode)) { + if (mtime) + *mtime = st.st_mtime; + return 1; + } else { + DEBUG("isFile: %s is not a regular file\n", utf8file); + return 0; + } + } else { + DEBUG("isFile: failed to stat: %s: %s\n", utf8file, + strerror(errno)); + } + + return 0; +} + +/* suffixes should be ascii only characters */ +char *getSuffix(char *utf8file) +{ + char *ret = NULL; + + while (*utf8file) { + if (*utf8file == '.') + ret = utf8file + 1; + utf8file++; + } + + return ret; +} + +static int hasSuffix(char *utf8file, char *suffix) +{ + char *s = getSuffix(utf8file); + if (s && 0 == strcmp(s, suffix)) + return 1; + return 0; +} + +int isPlaylist(char *utf8file) +{ + if (isFile(utf8file, NULL)) { + return hasSuffix(utf8file, PLAYLIST_FILE_SUFFIX); + } + return 0; +} + +int isDir(char *utf8name) +{ + struct stat st; + + if (myStat(utf8name, &st) == 0) { + if (S_ISDIR(st.st_mode)) { + return 1; + } + } + + return 0; +} + +InputPlugin *hasMusicSuffix(char *utf8file, unsigned int next) +{ + InputPlugin *ret = NULL; + + char *s = getSuffix(utf8file); + if (s) { + ret = getInputPluginFromSuffix(s, next); + } else { + DEBUG("hasMusicSuffix: The file: %s has no valid suffix\n", + utf8file); + } + + return ret; +} + +InputPlugin *isMusic(char *utf8file, time_t * mtime, unsigned int next) +{ + if (isFile(utf8file, mtime)) { + InputPlugin *plugin = hasMusicSuffix(utf8file, next); + if (plugin != NULL) + return plugin; + } + DEBUG("isMusic: %s is not a valid file\n", utf8file); + return NULL; +} |