00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026 #include <dirent.h>
00027 #include <unistd.h>
00028
00029 #ifdef _WIN32
00030 #include <windows.h>
00031 #endif
00032
00033 #ifdef HAVE_CONFIG_H
00034 # include "config.h"
00035 #endif
00036
00037 #include <glib.h>
00038 #include <stdlib.h>
00039 #include <string.h>
00040 #include <ctype.h>
00041
00042 #include <errno.h>
00043
00044 #include <libaudcore/audstrings.h>
00045 #include <libaudcore/stringpool.h>
00046
00047 #include "debug.h"
00048 #include "i18n.h"
00049 #include "misc.h"
00050 #include "plugins.h"
00051 #include "util.h"
00052
00053 gboolean dir_foreach (const gchar * path, DirForeachFunc func, void * user)
00054 {
00055 DIR * dir = opendir (path);
00056 if (! dir)
00057 return FALSE;
00058
00059 struct dirent * entry;
00060 while ((entry = readdir (dir)))
00061 {
00062 if (entry->d_name[0] == '.')
00063 continue;
00064
00065 gchar * full = g_strdup_printf ("%s" G_DIR_SEPARATOR_S "%s", path, entry->d_name);
00066 gboolean stop = func (full, entry->d_name, user);
00067 g_free (full);
00068
00069 if (stop)
00070 break;
00071 }
00072
00073 closedir (dir);
00074 return TRUE;
00075 }
00076
00077 gchar * construct_uri (const gchar * string, const gchar * playlist_name)
00078 {
00079 gchar *filename = g_strdup(string);
00080 gchar *uri = NULL;
00081
00082
00083 convert_dos_path(filename);
00084
00085
00086
00087 if (filename[0] == '/' || strstr(filename, "://")) {
00088 uri = g_filename_to_uri(filename, NULL, NULL);
00089 if(!uri)
00090 uri = g_strdup(filename);
00091 }
00092
00093
00094 else
00095 {
00096 const gchar * slash = strrchr (playlist_name, '/');
00097 if (slash)
00098 uri = g_strdup_printf ("%.*s/%s", (gint) (slash - playlist_name),
00099 playlist_name, filename);
00100 }
00101
00102 g_free (filename);
00103 return uri;
00104 }
00105
00106
00107 gint file_get_mtime (const gchar * filename)
00108 {
00109 struct stat info;
00110
00111 if (stat (filename, & info))
00112 return -1;
00113
00114 return info.st_mtime;
00115 }
00116
00117 void
00118 make_directory(const gchar * path, mode_t mode)
00119 {
00120 if (g_mkdir_with_parents(path, mode) == 0)
00121 return;
00122
00123 g_printerr(_("Could not create directory (%s): %s\n"), path,
00124 g_strerror(errno));
00125 }
00126
00127 gchar * get_path_to_self (void)
00128 {
00129 #if defined _WIN32 || defined HAVE_PROC_SELF_EXE
00130 gint size = 256;
00131 gchar * buf = g_malloc (size);
00132
00133 while (1)
00134 {
00135 gint len;
00136
00137 #ifdef _WIN32
00138 if (! (len = GetModuleFileName (NULL, buf, size)))
00139 {
00140 fprintf (stderr, "GetModuleFileName failed.\n");
00141 g_free (buf);
00142 return NULL;
00143 }
00144 #else
00145 if ((len = readlink ("/proc/self/exe", buf, size)) < 0)
00146 {
00147 fprintf (stderr, "Cannot access /proc/self/exe: %s.\n", strerror (errno));
00148 g_free (buf);
00149 return NULL;
00150 }
00151 #endif
00152
00153 if (len < size)
00154 {
00155 buf[len] = 0;
00156 return buf;
00157 }
00158
00159 size += size;
00160 buf = g_realloc (buf, size);
00161 }
00162 #else
00163 return NULL;
00164 #endif
00165 }
00166
00167
00168
00169
00170
00171
00172
00173
00174
00175 static gchar * skip_top_folders (gchar * name)
00176 {
00177 const gchar * home = getenv ("HOME");
00178 if (! home)
00179 goto NO_HOME;
00180
00181 gint len = strlen (home);
00182 if (len > 0 && home[len - 1] == G_DIR_SEPARATOR)
00183 len --;
00184
00185 #ifdef _WIN32
00186 if (! strncasecmp (name, home, len) && name[len] == '\\')
00187 #else
00188 if (! strncmp (name, home, len) && name[len] == '/')
00189 #endif
00190 return name + len + 1;
00191
00192 NO_HOME:
00193 #ifdef _WIN32
00194 return (name[0] && name[1] == ':' && name[2] == '\\') ? name + 3 : name;
00195 #else
00196 return (name[0] == '/') ? name + 1 : name;
00197 #endif
00198 }
00199
00200
00201
00202
00203
00204
00205
00206
00207
00208 static void split_filename (gchar * name, gchar * * base, gchar * * first,
00209 gchar * * second)
00210 {
00211 * first = * second = NULL;
00212
00213 gchar * c;
00214
00215 if ((c = strrchr (name, G_DIR_SEPARATOR)))
00216 {
00217 * base = c + 1;
00218 * c = 0;
00219 }
00220 else
00221 {
00222 * base = name;
00223 goto DONE;
00224 }
00225
00226 if ((c = strrchr (name, G_DIR_SEPARATOR)))
00227 {
00228 * first = c + 1;
00229 * c = 0;
00230 }
00231 else
00232 {
00233 * first = name;
00234 goto DONE;
00235 }
00236
00237 if ((c = strrchr (name, G_DIR_SEPARATOR)))
00238 * second = c + 1;
00239 else
00240 * second = name;
00241
00242 DONE:
00243 if ((c = strrchr (* base, '.')))
00244 * c = 0;
00245 }
00246
00247
00248
00249
00250
00251
00252
00253 static gchar * stream_name (gchar * name)
00254 {
00255 if (! strncmp (name, "http://", 7))
00256 name += 7;
00257 else if (! strncmp (name, "https://", 8))
00258 name += 8;
00259 else if (! strncmp (name, "mms://", 6))
00260 name += 6;
00261 else
00262 return NULL;
00263
00264 gchar * c;
00265
00266 if ((c = strchr (name, '/')))
00267 * c = 0;
00268 if ((c = strchr (name, ':')))
00269 * c = 0;
00270 if ((c = strchr (name, '?')))
00271 * c = 0;
00272
00273 return name;
00274 }
00275
00276
00277
00278
00279 void describe_song (const gchar * name, const Tuple * tuple, gchar * * _title,
00280 gchar * * _artist, gchar * * _album)
00281 {
00282
00283 static const gchar * const skip[] = {"music"};
00284
00285 const gchar * title = tuple ? tuple_get_string (tuple, FIELD_TITLE, NULL) : NULL;
00286 const gchar * artist = tuple ? tuple_get_string (tuple, FIELD_ARTIST, NULL) : NULL;
00287 const gchar * album = tuple ? tuple_get_string (tuple, FIELD_ALBUM, NULL) : NULL;
00288
00289 if (title && ! title[0])
00290 title = NULL;
00291 if (artist && ! artist[0])
00292 artist = NULL;
00293 if (album && ! album[0])
00294 album = NULL;
00295
00296 gchar * copy = NULL;
00297
00298 if (title && artist && album)
00299 goto DONE;
00300
00301 copy = uri_to_display (name);
00302
00303 if (! strncmp (name, "file://", 7))
00304 {
00305 gchar * base, * first, * second;
00306 split_filename (skip_top_folders (copy), & base, & first,
00307 & second);
00308
00309 if (! title)
00310 title = base;
00311
00312 for (gint i = 0; i < G_N_ELEMENTS (skip); i ++)
00313 {
00314 if (first && ! strcasecmp (first, skip[i]))
00315 first = NULL;
00316 if (second && ! strcasecmp (second, skip[i]))
00317 second = NULL;
00318 }
00319
00320 if (first)
00321 {
00322 if (second && ! artist && ! album)
00323 {
00324 artist = second;
00325 album = first;
00326 }
00327 else if (! artist)
00328 artist = first;
00329 else if (! album)
00330 album = first;
00331 }
00332 }
00333 else
00334 {
00335 if (! title)
00336 title = stream_name (copy);
00337 else if (! artist)
00338 artist = stream_name (copy);
00339 else if (! album)
00340 album = stream_name (copy);
00341 }
00342
00343 DONE:
00344 * _title = title ? stringpool_get ((gchar *) title, FALSE) : NULL;
00345 * _artist = artist ? stringpool_get ((gchar *) artist, FALSE) : NULL;
00346 * _album = album ? stringpool_get ((gchar *) album, FALSE) : NULL;
00347
00348 g_free (copy);
00349 }