Gentoo Websites Logo
Go to: Gentoo Home Documentation Forums Lists Bugs Planet Store Wiki Get Gentoo!
View | Details | Raw Unified | Return to bug 114488
Collapse All | Expand All

(-)rhythmbox-0.9.2.orig/Makefile.am (-1 / +1 lines)
Lines 5-11 Link Here
5
DISTCHECK_CONFIGURE_FLAGS = --disable-schemas-install --enable-gtk-doc
5
DISTCHECK_CONFIGURE_FLAGS = --disable-schemas-install --enable-gtk-doc
6
distuninstallcheck_listfiles = find . -type f -print | grep -v '^\./var/scrollkeeper'
6
distuninstallcheck_listfiles = find . -type f -print | grep -v '^\./var/scrollkeeper'
7
7
8
SUBDIRS = macros lib metadata player rhythmdb widgets sources iradio podcast remote daapsharing shell data po help tests doc
8
SUBDIRS = macros lib metadata player rhythmdb widgets plparse sources iradio podcast remote daapsharing shell data po help tests doc
9
9
10
EXTRA_DIST = 			\
10
EXTRA_DIST = 			\
11
	autogen.sh		\
11
	autogen.sh		\
(-)rhythmbox-0.9.2.orig/configure.ac (-4 / +5 lines)
Lines 54-63 Link Here
54
		  gnome-vfs-2.0 >= $GNOME_VFS_REQS	\
54
		  gnome-vfs-2.0 >= $GNOME_VFS_REQS	\
55
		  gnome-vfs-module-2.0)
55
		  gnome-vfs-module-2.0)
56
56
57
PKG_CHECK_MODULES(TOTEM_PLPARSER, totem-plparser >= $TOTEM_PLPARSER_REQS, have_totem_plparser=yes, have_totem_plparser=no)
57
# PKG_CHECK_MODULES(TOTEM_PLPARSER, totem-plparser >= $TOTEM_PLPARSER_REQS, have_totem_plparser=yes, have_totem_plparser=no)
58
if test x$have_totem_plparser != xyes; then
58
# if test x$have_totem_plparser != xyes; then
59
   AC_MSG_ERROR([totem playlist parsing library not found or too old])
59
#    AC_MSG_ERROR([totem playlist parsing library not found or too old])
60
fi   
60
# fi   
61
61
62
dnl iPod support
62
dnl iPod support
63
63
Lines 578-583 Link Here
578
player/Makefile
578
player/Makefile
579
rhythmdb/Makefile
579
rhythmdb/Makefile
580
widgets/Makefile
580
widgets/Makefile
581
plparse/Makefile
581
iradio/Makefile
582
iradio/Makefile
582
podcast/Makefile
583
podcast/Makefile
583
remote/Makefile
584
remote/Makefile
(-)rhythmbox-0.9.2.orig/plparse/Makefile.am (+60 lines)
Line 0 Link Here
1
noinst_LIBRARIES = libtotem-plparser.a
2
3
libtotem_plparser_a_SOURCES =			\
4
	totem-pl-parser-builtins.c		\
5
	totemplparser-marshal.c			\
6
	totemplparser-marshal.h			\
7
	totem-disc.c				\
8
	totem-pl-parser.c
9
10
# libtotem_plparser_a_LDFLAGS =			\
11
# 	$(TOTEM_PLPARSER_LIBS)
12
13
INCLUDES = $(RHYTHMBOX_CFLAGS)
14
15
MARSHALFILES = totemplparser-marshal.c totemplparser-marshal.h
16
GLIB_GENMARSHAL=`pkg-config --variable=glib_genmarshal glib-2.0`
17
BUILT_SOURCES = $(MARSHALFILES)
18
19
totemplparser-marshal.c: totemplparser-marshal.h
20
	 ( $(GLIB_GENMARSHAL) --prefix=totemplparser_marshal $(srcdir)/totemplparser-marshal.list --header --body > totemplparser-marshal.c )
21
totemplparser-marshal.h: totemplparser-marshal.list
22
	( $(GLIB_GENMARSHAL) --prefix=totemplparser_marshal $(srcdir)/totemplparser-marshal.list --header > totemplparser-marshal.h )
23
24
GLIB_MKENUMS=`pkg-config --variable=glib_mkenums glib-2.0`
25
totem-pl-parser-builtins.h: stamp-totem-pl-parser-builtins.h
26
	@true
27
28
stamp-totem-pl-parser-builtins.h: totem-pl-parser.h Makefile
29
	(cd $(srcdir) && $(GLIB_MKENUMS) \
30
			--fhead "#ifndef __TOTEM_PL_PARSER_BUILTINS_H__\n#define __TOTEM_PL_PARSER_BUILTINS_H__\n\n#include <glib-object.h>\n\nG_BEGIN_DECLS\n" \
31
			--fprod "/* enumerations from \"@filename@\" */\n" \
32
			--vhead "GType @enum_name@_get_type (void) G_GNUC_CONST;\n#define TOTEM_TYPE_@ENUMSHORT@ (@enum_name@_get_type())\n" \
33
			--ftail "G_END_DECLS\n\n#endif /* __TOTEM_PL_PARSER_BUILTINS_H__ */" totem-pl-parser.h) >> xgen-gtbh \
34
	&& (cmp -s xgen-gtbh totem-pl-parser-builtins.h || cp xgen-gtbh totem-pl-parser-builtins.h ) \
35
	&& rm -f xgen-gtbh \
36
	&& echo timestamp > $(@F)
37
38
totem-pl-parser-builtins.c: totem-pl-parser.h Makefile totem-pl-parser-builtins.h
39
	(cd $(srcdir) && $(GLIB_MKENUMS) \
40
			--fhead "#include \"totem-pl-parser.h\"\n#include \"totem-pl-parser-builtins.h\"" \
41
			--fprod "\n/* enumerations from \"@filename@\" */" \
42
			--vhead "GType\n@enum_name@_get_type (void)\n{\n  static GType etype = 0;\n  if (etype == 0) {\n    static const G@Type@Value values[] = {" \
43
			--vprod "      { @VALUENAME@, \"@VALUENAME@\", \"@valuenick@\" }," \
44
			--vtail "      { 0, NULL, NULL }\n    };\n    etype = g_@type@_register_static (\"@EnumName@\", values);\n  }\n  return etype;\n}\n" \
45
		totem-pl-parser.h ) > xgen-gtbc \
46
	&& cp xgen-gtbc totem-pl-parser-builtins.c  \
47
	&& rm -f xgen-gtbc
48
49
CLEANFILES = \
50
	totem-pl-parser-builtins.h \
51
	totem-pl-parser-builtins.c \
52
	stamp-totem-pl-parser-builtins.h \
53
	$(BUILT_SOURCES)
54
55
EXTRA_DIST = \
56
	totemplparser-marshal.list \
57
	totem-disc.h \
58
	totem-pl-parser-builtins.h \
59
	totem-pl-parser.h
60
(-)rhythmbox-0.9.2.orig/plparse/Makefile.in (+574 lines)
Line 0 Link Here
1
# Makefile.in generated by automake 1.7.9 from Makefile.am.
2
# @configure_input@
3
4
# Copyright 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003
5
# Free Software Foundation, Inc.
6
# This Makefile.in is free software; the Free Software Foundation
7
# gives unlimited permission to copy and/or distribute it,
8
# with or without modifications, as long as this notice is preserved.
9
10
# This program is distributed in the hope that it will be useful,
11
# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
12
# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
13
# PARTICULAR PURPOSE.
14
15
@SET_MAKE@
16
17
srcdir = @srcdir@
18
top_srcdir = @top_srcdir@
19
VPATH = @srcdir@
20
pkgdatadir = $(datadir)/@PACKAGE@
21
pkglibdir = $(libdir)/@PACKAGE@
22
pkgincludedir = $(includedir)/@PACKAGE@
23
top_builddir = ..
24
25
am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
26
INSTALL = @INSTALL@
27
install_sh_DATA = $(install_sh) -c -m 644
28
install_sh_PROGRAM = $(install_sh) -c
29
install_sh_SCRIPT = $(install_sh) -c
30
INSTALL_HEADER = $(INSTALL_DATA)
31
transform = $(program_transform_name)
32
NORMAL_INSTALL = :
33
PRE_INSTALL = :
34
POST_INSTALL = :
35
NORMAL_UNINSTALL = :
36
PRE_UNINSTALL = :
37
POST_UNINSTALL = :
38
host_triplet = @host@
39
ACLOCAL = @ACLOCAL@
40
AMDEP_FALSE = @AMDEP_FALSE@
41
AMDEP_TRUE = @AMDEP_TRUE@
42
AMTAR = @AMTAR@
43
AR = @AR@
44
AUDIOCD_INCLUDES = @AUDIOCD_INCLUDES@
45
AUTOCONF = @AUTOCONF@
46
AUTOHEADER = @AUTOHEADER@
47
AUTOMAKE = @AUTOMAKE@
48
AWK = @AWK@
49
BONOBO_ACTIVATION_IDL = @BONOBO_ACTIVATION_IDL@
50
BONOBO_CFLAGS = @BONOBO_CFLAGS@
51
BONOBO_LIBS = @BONOBO_LIBS@
52
CATALOGS = @CATALOGS@
53
CATOBJEXT = @CATOBJEXT@
54
CC = @CC@
55
CCDEPMODE = @CCDEPMODE@
56
CFLAGS = @CFLAGS@
57
CPP = @CPP@
58
CPPFLAGS = @CPPFLAGS@
59
CXX = @CXX@
60
CXXCPP = @CXXCPP@
61
CXXDEPMODE = @CXXDEPMODE@
62
CXXFLAGS = @CXXFLAGS@
63
CYGPATH_W = @CYGPATH_W@
64
DATADIRNAME = @DATADIRNAME@
65
DBUS_CFLAGS = @DBUS_CFLAGS@
66
DBUS_LIBS = @DBUS_LIBS@
67
DEFS = @DEFS@
68
DEPDIR = @DEPDIR@
69
ECHO = @ECHO@
70
ECHO_C = @ECHO_C@
71
ECHO_N = @ECHO_N@
72
ECHO_T = @ECHO_T@
73
EGREP = @EGREP@
74
EXEEXT = @EXEEXT@
75
F77 = @F77@
76
FFLAGS = @FFLAGS@
77
GCONFTOOL = @GCONFTOOL@
78
GCONF_SCHEMAS_INSTALL_FALSE = @GCONF_SCHEMAS_INSTALL_FALSE@
79
GCONF_SCHEMAS_INSTALL_TRUE = @GCONF_SCHEMAS_INSTALL_TRUE@
80
GCONF_SCHEMA_CONFIG_SOURCE = @GCONF_SCHEMA_CONFIG_SOURCE@
81
GCONF_SCHEMA_FILE_DIR = @GCONF_SCHEMA_FILE_DIR@
82
GDA_CFLAGS = @GDA_CFLAGS@
83
GDA_LIBS = @GDA_LIBS@
84
GETTEXT_PACKAGE = @GETTEXT_PACKAGE@
85
GLIB_GENMARSHAL = `pkg-config --variable=glib_genmarshal glib-2.0`
86
GMOFILES = @GMOFILES@
87
GMSGFMT = @GMSGFMT@
88
GST_INSPECT = @GST_INSPECT@
89
HAL_CFLAGS = @HAL_CFLAGS@
90
HAL_LIBS = @HAL_LIBS@
91
HAVE_AUDIOCD_FALSE = @HAVE_AUDIOCD_FALSE@
92
HAVE_AUDIOCD_TRUE = @HAVE_AUDIOCD_TRUE@
93
HAVE_LINUX_CDROM_FALSE = @HAVE_LINUX_CDROM_FALSE@
94
HAVE_LINUX_CDROM_TRUE = @HAVE_LINUX_CDROM_TRUE@
95
HAVE_MUSICBRAINZ_FALSE = @HAVE_MUSICBRAINZ_FALSE@
96
HAVE_MUSICBRAINZ_TRUE = @HAVE_MUSICBRAINZ_TRUE@
97
INSTALL_DATA = @INSTALL_DATA@
98
INSTALL_PROGRAM = @INSTALL_PROGRAM@
99
INSTALL_SCRIPT = @INSTALL_SCRIPT@
100
INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
101
INSTOBJEXT = @INSTOBJEXT@
102
INTLLIBS = @INTLLIBS@
103
INTLTOOL_CAVES_RULE = @INTLTOOL_CAVES_RULE@
104
INTLTOOL_DESKTOP_RULE = @INTLTOOL_DESKTOP_RULE@
105
INTLTOOL_DIRECTORY_RULE = @INTLTOOL_DIRECTORY_RULE@
106
INTLTOOL_EXTRACT = @INTLTOOL_EXTRACT@
107
INTLTOOL_ICONV = @INTLTOOL_ICONV@
108
INTLTOOL_KBD_RULE = @INTLTOOL_KBD_RULE@
109
INTLTOOL_KEYS_RULE = @INTLTOOL_KEYS_RULE@
110
INTLTOOL_MERGE = @INTLTOOL_MERGE@
111
INTLTOOL_MSGFMT = @INTLTOOL_MSGFMT@
112
INTLTOOL_MSGMERGE = @INTLTOOL_MSGMERGE@
113
INTLTOOL_OAF_RULE = @INTLTOOL_OAF_RULE@
114
INTLTOOL_PERL = @INTLTOOL_PERL@
115
INTLTOOL_PONG_RULE = @INTLTOOL_PONG_RULE@
116
INTLTOOL_PROP_RULE = @INTLTOOL_PROP_RULE@
117
INTLTOOL_SCHEMAS_RULE = @INTLTOOL_SCHEMAS_RULE@
118
INTLTOOL_SERVER_RULE = @INTLTOOL_SERVER_RULE@
119
INTLTOOL_SHEET_RULE = @INTLTOOL_SHEET_RULE@
120
INTLTOOL_SOUNDLIST_RULE = @INTLTOOL_SOUNDLIST_RULE@
121
INTLTOOL_THEME_RULE = @INTLTOOL_THEME_RULE@
122
INTLTOOL_UI_RULE = @INTLTOOL_UI_RULE@
123
INTLTOOL_UPDATE = @INTLTOOL_UPDATE@
124
INTLTOOL_XAM_RULE = @INTLTOOL_XAM_RULE@
125
INTLTOOL_XGETTEXT = @INTLTOOL_XGETTEXT@
126
INTLTOOL_XML_NOMERGE_RULE = @INTLTOOL_XML_NOMERGE_RULE@
127
INTLTOOL_XML_RULE = @INTLTOOL_XML_RULE@
128
LDFLAGS = @LDFLAGS@
129
LIBBONOBO_IDL = @LIBBONOBO_IDL@
130
LIBNAUTILUS_BURN_CFLAGS = @LIBNAUTILUS_BURN_CFLAGS@
131
LIBNAUTILUS_BURN_LIBS = @LIBNAUTILUS_BURN_LIBS@
132
LIBOBJS = @LIBOBJS@
133
LIBS = @LIBS@
134
LIBTOOL = @LIBTOOL@
135
LN_S = @LN_S@
136
LTLIBOBJS = @LTLIBOBJS@
137
MAINT = @MAINT@
138
MAINTAINER_MODE_FALSE = @MAINTAINER_MODE_FALSE@
139
MAINTAINER_MODE_TRUE = @MAINTAINER_MODE_TRUE@
140
MAKEINFO = @MAKEINFO@
141
MKDTEMP_MISSING_FALSE = @MKDTEMP_MISSING_FALSE@
142
MKDTEMP_MISSING_TRUE = @MKDTEMP_MISSING_TRUE@
143
MKINSTALLDIRS = @MKINSTALLDIRS@
144
MSGFMT = @MSGFMT@
145
MUSICBRAINZ_CFLAGS = @MUSICBRAINZ_CFLAGS@
146
MUSICBRAINZ_LIBS = @MUSICBRAINZ_LIBS@
147
OBJEXT = @OBJEXT@
148
ORBIT_IDL = @ORBIT_IDL@
149
PACKAGE = @PACKAGE@
150
PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
151
PACKAGE_NAME = @PACKAGE_NAME@
152
PACKAGE_STRING = @PACKAGE_STRING@
153
PACKAGE_TARNAME = @PACKAGE_TARNAME@
154
PACKAGE_VERSION = @PACKAGE_VERSION@
155
PATH_SEPARATOR = @PATH_SEPARATOR@
156
PKG_CONFIG = @PKG_CONFIG@
157
POFILES = @POFILES@
158
POSUB = @POSUB@
159
PO_IN_DATADIR_FALSE = @PO_IN_DATADIR_FALSE@
160
PO_IN_DATADIR_TRUE = @PO_IN_DATADIR_TRUE@
161
RANLIB = @RANLIB@
162
RHYTHMBOX_CFLAGS = @RHYTHMBOX_CFLAGS@
163
RHYTHMBOX_LIBS = @RHYTHMBOX_LIBS@
164
SET_MAKE = @SET_MAKE@
165
SHELL = @SHELL@
166
SOUNDSYSTEM_CFLAGS = @SOUNDSYSTEM_CFLAGS@
167
SOUNDSYSTEM_DEPS = @SOUNDSYSTEM_DEPS@
168
SOUNDSYSTEM_LIBS = @SOUNDSYSTEM_LIBS@
169
STRIP = @STRIP@
170
USE_CD_BURNER_FALSE = @USE_CD_BURNER_FALSE@
171
USE_CD_BURNER_TRUE = @USE_CD_BURNER_TRUE@
172
USE_GDADB_FALSE = @USE_GDADB_FALSE@
173
USE_GDADB_TRUE = @USE_GDADB_TRUE@
174
USE_IPOD_FALSE = @USE_IPOD_FALSE@
175
USE_IPOD_TRUE = @USE_IPOD_TRUE@
176
USE_NLS = @USE_NLS@
177
USE_TREEDB_FALSE = @USE_TREEDB_FALSE@
178
USE_TREEDB_TRUE = @USE_TREEDB_TRUE@
179
VERSION = @VERSION@
180
WITH_BONOBO_FALSE = @WITH_BONOBO_FALSE@
181
WITH_BONOBO_TRUE = @WITH_BONOBO_TRUE@
182
WITH_DASHBOARD_FALSE = @WITH_DASHBOARD_FALSE@
183
WITH_DASHBOARD_TRUE = @WITH_DASHBOARD_TRUE@
184
WITH_DBUS_FALSE = @WITH_DBUS_FALSE@
185
WITH_DBUS_TRUE = @WITH_DBUS_TRUE@
186
XGETTEXT = @XGETTEXT@
187
ac_ct_AR = @ac_ct_AR@
188
ac_ct_CC = @ac_ct_CC@
189
ac_ct_CXX = @ac_ct_CXX@
190
ac_ct_F77 = @ac_ct_F77@
191
ac_ct_RANLIB = @ac_ct_RANLIB@
192
ac_ct_STRIP = @ac_ct_STRIP@
193
ac_pt_PKG_CONFIG = @ac_pt_PKG_CONFIG@
194
am__fastdepCC_FALSE = @am__fastdepCC_FALSE@
195
am__fastdepCC_TRUE = @am__fastdepCC_TRUE@
196
am__fastdepCXX_FALSE = @am__fastdepCXX_FALSE@
197
am__fastdepCXX_TRUE = @am__fastdepCXX_TRUE@
198
am__include = @am__include@
199
am__leading_dot = @am__leading_dot@
200
am__quote = @am__quote@
201
bindir = @bindir@
202
build = @build@
203
build_alias = @build_alias@
204
build_cpu = @build_cpu@
205
build_os = @build_os@
206
build_vendor = @build_vendor@
207
datadir = @datadir@
208
exec_prefix = @exec_prefix@
209
host = @host@
210
host_alias = @host_alias@
211
host_cpu = @host_cpu@
212
host_os = @host_os@
213
host_vendor = @host_vendor@
214
includedir = @includedir@
215
infodir = @infodir@
216
install_sh = @install_sh@
217
libdir = @libdir@
218
libexecdir = @libexecdir@
219
localstatedir = @localstatedir@
220
mandir = @mandir@
221
mkdir_p = @mkdir_p@
222
oldincludedir = @oldincludedir@
223
prefix = @prefix@
224
program_transform_name = @program_transform_name@
225
sbindir = @sbindir@
226
sharedstatedir = @sharedstatedir@
227
sysconfdir = @sysconfdir@
228
target_alias = @target_alias@
229
noinst_LIBRARIES = libtotem-plparser.a
230
231
libtotem_plparser_a_SOURCES = \
232
	totem-pl-parser-builtins.c		\
233
	totemplparser-marshal.c			\
234
	totemplparser-marshal.h			\
235
	totem-disc.c				\
236
	totem-pl-parser.c
237
238
239
240
# libtotem_plparser_a_LDFLAGS =			\
241
# 	$(TOTEM_PLPARSER_LIBS)
242
INCLUDES = $(RHYTHMBOX_CFLAGS)
243
244
MARSHALFILES = totemplparser-marshal.c totemplparser-marshal.h
245
BUILT_SOURCES = $(MARSHALFILES)
246
247
GLIB_MKENUMS = `pkg-config --variable=glib_mkenums glib-2.0`
248
249
CLEANFILES = \
250
	totem-pl-parser-builtins.h \
251
	totem-pl-parser-builtins.c \
252
	stamp-totem-pl-parser-builtins.h \
253
	$(BUILT_SOURCES)
254
255
256
EXTRA_DIST = \
257
	totemplparser-marshal.list \
258
	totem-disc.h \
259
	totem-pl-parser-builtins.h \
260
	totem-pl-parser.h
261
262
subdir = plparse
263
ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
264
mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs
265
CONFIG_HEADER = $(top_builddir)/config.h
266
CONFIG_CLEAN_FILES =
267
LIBRARIES = $(noinst_LIBRARIES)
268
269
libtotem_plparser_a_AR = $(AR) cru
270
libtotem_plparser_a_LIBADD =
271
am_libtotem_plparser_a_OBJECTS = totem-pl-parser-builtins.$(OBJEXT) \
272
	totemplparser-marshal.$(OBJEXT) totem-disc.$(OBJEXT) \
273
	totem-pl-parser.$(OBJEXT)
274
libtotem_plparser_a_OBJECTS = $(am_libtotem_plparser_a_OBJECTS)
275
276
DEFAULT_INCLUDES =  -I. -I$(srcdir) -I$(top_builddir)
277
depcomp = $(SHELL) $(top_srcdir)/depcomp
278
am__depfiles_maybe = depfiles
279
@AMDEP_TRUE@DEP_FILES = ./$(DEPDIR)/totem-disc.Po \
280
@AMDEP_TRUE@	./$(DEPDIR)/totem-pl-parser-builtins.Po \
281
@AMDEP_TRUE@	./$(DEPDIR)/totem-pl-parser.Po \
282
@AMDEP_TRUE@	./$(DEPDIR)/totemplparser-marshal.Po
283
COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \
284
	$(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
285
LTCOMPILE = $(LIBTOOL) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) \
286
	$(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
287
CCLD = $(CC)
288
LINK = $(LIBTOOL) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \
289
	$(AM_LDFLAGS) $(LDFLAGS) -o $@
290
DIST_SOURCES = $(libtotem_plparser_a_SOURCES)
291
DIST_COMMON = $(srcdir)/Makefile.in Makefile.am
292
SOURCES = $(libtotem_plparser_a_SOURCES)
293
294
all: $(BUILT_SOURCES)
295
	$(MAKE) $(AM_MAKEFLAGS) all-am
296
297
.SUFFIXES:
298
.SUFFIXES: .c .lo .o .obj
299
$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ Makefile.am  $(top_srcdir)/configure.ac $(ACLOCAL_M4)
300
	cd $(top_srcdir) && \
301
	  $(AUTOMAKE) --gnu  plparse/Makefile
302
Makefile: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.in  $(top_builddir)/config.status
303
	cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)
304
305
clean-noinstLIBRARIES:
306
	-test -z "$(noinst_LIBRARIES)" || rm -f $(noinst_LIBRARIES)
307
libtotem-plparser.a: $(libtotem_plparser_a_OBJECTS) $(libtotem_plparser_a_DEPENDENCIES) 
308
	-rm -f libtotem-plparser.a
309
	$(libtotem_plparser_a_AR) libtotem-plparser.a $(libtotem_plparser_a_OBJECTS) $(libtotem_plparser_a_LIBADD)
310
	$(RANLIB) libtotem-plparser.a
311
312
mostlyclean-compile:
313
	-rm -f *.$(OBJEXT) core *.core
314
315
distclean-compile:
316
	-rm -f *.tab.c
317
318
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/totem-disc.Po@am__quote@
319
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/totem-pl-parser-builtins.Po@am__quote@
320
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/totem-pl-parser.Po@am__quote@
321
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/totemplparser-marshal.Po@am__quote@
322
323
.c.o:
324
@am__fastdepCC_TRUE@	if $(COMPILE) -MT $@ -MD -MP -MF "$(DEPDIR)/$*.Tpo" \
325
@am__fastdepCC_TRUE@	  -c -o $@ `test -f '$<' || echo '$(srcdir)/'`$<; \
326
@am__fastdepCC_TRUE@	then mv -f "$(DEPDIR)/$*.Tpo" "$(DEPDIR)/$*.Po"; \
327
@am__fastdepCC_TRUE@	else rm -f "$(DEPDIR)/$*.Tpo"; exit 1; \
328
@am__fastdepCC_TRUE@	fi
329
@AMDEP_TRUE@@am__fastdepCC_FALSE@	source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
330
@AMDEP_TRUE@@am__fastdepCC_FALSE@	depfile='$(DEPDIR)/$*.Po' tmpdepfile='$(DEPDIR)/$*.TPo' @AMDEPBACKSLASH@
331
@AMDEP_TRUE@@am__fastdepCC_FALSE@	$(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
332
@am__fastdepCC_FALSE@	$(COMPILE) -c `test -f '$<' || echo '$(srcdir)/'`$<
333
334
.c.obj:
335
@am__fastdepCC_TRUE@	if $(COMPILE) -MT $@ -MD -MP -MF "$(DEPDIR)/$*.Tpo" \
336
@am__fastdepCC_TRUE@	  -c -o $@ `if test -f '$<'; then $(CYGPATH_W) '$<'; else $(CYGPATH_W) '$(srcdir)/$<'; fi`; \
337
@am__fastdepCC_TRUE@	then mv -f "$(DEPDIR)/$*.Tpo" "$(DEPDIR)/$*.Po"; \
338
@am__fastdepCC_TRUE@	else rm -f "$(DEPDIR)/$*.Tpo"; exit 1; \
339
@am__fastdepCC_TRUE@	fi
340
@AMDEP_TRUE@@am__fastdepCC_FALSE@	source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
341
@AMDEP_TRUE@@am__fastdepCC_FALSE@	depfile='$(DEPDIR)/$*.Po' tmpdepfile='$(DEPDIR)/$*.TPo' @AMDEPBACKSLASH@
342
@AMDEP_TRUE@@am__fastdepCC_FALSE@	$(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
343
@am__fastdepCC_FALSE@	$(COMPILE) -c `if test -f '$<'; then $(CYGPATH_W) '$<'; else $(CYGPATH_W) '$(srcdir)/$<'; fi`
344
345
.c.lo:
346
@am__fastdepCC_TRUE@	if $(LTCOMPILE) -MT $@ -MD -MP -MF "$(DEPDIR)/$*.Tpo" \
347
@am__fastdepCC_TRUE@	  -c -o $@ `test -f '$<' || echo '$(srcdir)/'`$<; \
348
@am__fastdepCC_TRUE@	then mv -f "$(DEPDIR)/$*.Tpo" "$(DEPDIR)/$*.Plo"; \
349
@am__fastdepCC_TRUE@	else rm -f "$(DEPDIR)/$*.Tpo"; exit 1; \
350
@am__fastdepCC_TRUE@	fi
351
@AMDEP_TRUE@@am__fastdepCC_FALSE@	source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@
352
@AMDEP_TRUE@@am__fastdepCC_FALSE@	depfile='$(DEPDIR)/$*.Plo' tmpdepfile='$(DEPDIR)/$*.TPlo' @AMDEPBACKSLASH@
353
@AMDEP_TRUE@@am__fastdepCC_FALSE@	$(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
354
@am__fastdepCC_FALSE@	$(LTCOMPILE) -c -o $@ `test -f '$<' || echo '$(srcdir)/'`$<
355
356
mostlyclean-libtool:
357
	-rm -f *.lo
358
359
clean-libtool:
360
	-rm -rf .libs _libs
361
362
distclean-libtool:
363
	-rm -f libtool
364
uninstall-info-am:
365
366
ETAGS = etags
367
ETAGSFLAGS =
368
369
CTAGS = ctags
370
CTAGSFLAGS =
371
372
tags: TAGS
373
374
ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES)
375
	list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
376
	unique=`for i in $$list; do \
377
	    if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
378
	  done | \
379
	  $(AWK) '    { files[$$0] = 1; } \
380
	       END { for (i in files) print i; }'`; \
381
	mkid -fID $$unique
382
383
TAGS:  $(HEADERS) $(SOURCES)  $(TAGS_DEPENDENCIES) \
384
		$(TAGS_FILES) $(LISP)
385
	tags=; \
386
	here=`pwd`; \
387
	list='$(SOURCES) $(HEADERS)  $(LISP) $(TAGS_FILES)'; \
388
	unique=`for i in $$list; do \
389
	    if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
390
	  done | \
391
	  $(AWK) '    { files[$$0] = 1; } \
392
	       END { for (i in files) print i; }'`; \
393
	test -z "$(ETAGS_ARGS)$$tags$$unique" \
394
	  || $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
395
	     $$tags $$unique
396
397
ctags: CTAGS
398
CTAGS:  $(HEADERS) $(SOURCES)  $(TAGS_DEPENDENCIES) \
399
		$(TAGS_FILES) $(LISP)
400
	tags=; \
401
	here=`pwd`; \
402
	list='$(SOURCES) $(HEADERS)  $(LISP) $(TAGS_FILES)'; \
403
	unique=`for i in $$list; do \
404
	    if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
405
	  done | \
406
	  $(AWK) '    { files[$$0] = 1; } \
407
	       END { for (i in files) print i; }'`; \
408
	test -z "$(CTAGS_ARGS)$$tags$$unique" \
409
	  || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \
410
	     $$tags $$unique
411
412
GTAGS:
413
	here=`$(am__cd) $(top_builddir) && pwd` \
414
	  && cd $(top_srcdir) \
415
	  && gtags -i $(GTAGS_ARGS) $$here
416
417
distclean-tags:
418
	-rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
419
DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
420
421
top_distdir = ..
422
distdir = $(top_distdir)/$(PACKAGE)-$(VERSION)
423
424
distdir: $(DISTFILES)
425
	@srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; \
426
	topsrcdirstrip=`echo "$(top_srcdir)" | sed 's|.|.|g'`; \
427
	list='$(DISTFILES)'; for file in $$list; do \
428
	  case $$file in \
429
	    $(srcdir)/*) file=`echo "$$file" | sed "s|^$$srcdirstrip/||"`;; \
430
	    $(top_srcdir)/*) file=`echo "$$file" | sed "s|^$$topsrcdirstrip/|$(top_builddir)/|"`;; \
431
	  esac; \
432
	  if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
433
	  dir=`echo "$$file" | sed -e 's,/[^/]*$$,,'`; \
434
	  if test "$$dir" != "$$file" && test "$$dir" != "."; then \
435
	    dir="/$$dir"; \
436
	    $(mkinstalldirs) "$(distdir)$$dir"; \
437
	  else \
438
	    dir=''; \
439
	  fi; \
440
	  if test -d $$d/$$file; then \
441
	    if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
442
	      cp -pR $(srcdir)/$$file $(distdir)$$dir || exit 1; \
443
	    fi; \
444
	    cp -pR $$d/$$file $(distdir)$$dir || exit 1; \
445
	  else \
446
	    test -f $(distdir)/$$file \
447
	    || cp -p $$d/$$file $(distdir)/$$file \
448
	    || exit 1; \
449
	  fi; \
450
	done
451
check-am: all-am
452
check: $(BUILT_SOURCES)
453
	$(MAKE) $(AM_MAKEFLAGS) check-am
454
all-am: Makefile $(LIBRARIES)
455
456
installdirs:
457
install: $(BUILT_SOURCES)
458
	$(MAKE) $(AM_MAKEFLAGS) install-am
459
install-exec: install-exec-am
460
install-data: install-data-am
461
uninstall: uninstall-am
462
463
install-am: all-am
464
	@$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
465
466
installcheck: installcheck-am
467
install-strip:
468
	$(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
469
	  install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
470
	  `test -z '$(STRIP)' || \
471
	    echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install
472
mostlyclean-generic:
473
474
clean-generic:
475
	-test -z "$(CLEANFILES)" || rm -f $(CLEANFILES)
476
477
distclean-generic:
478
	-rm -f $(CONFIG_CLEAN_FILES)
479
480
maintainer-clean-generic:
481
	@echo "This command is intended for maintainers to use"
482
	@echo "it deletes files that may require special tools to rebuild."
483
	-test -z "$(BUILT_SOURCES)" || rm -f $(BUILT_SOURCES)
484
clean: clean-am
485
486
clean-am: clean-generic clean-libtool clean-noinstLIBRARIES \
487
	mostlyclean-am
488
489
distclean: distclean-am
490
	-rm -rf ./$(DEPDIR)
491
	-rm -f Makefile
492
distclean-am: clean-am distclean-compile distclean-generic \
493
	distclean-libtool distclean-tags
494
495
dvi: dvi-am
496
497
dvi-am:
498
499
info: info-am
500
501
info-am:
502
503
install-data-am:
504
505
install-exec-am:
506
507
install-info: install-info-am
508
509
install-man:
510
511
installcheck-am:
512
513
maintainer-clean: maintainer-clean-am
514
	-rm -rf ./$(DEPDIR)
515
	-rm -f Makefile
516
maintainer-clean-am: distclean-am maintainer-clean-generic
517
518
mostlyclean: mostlyclean-am
519
520
mostlyclean-am: mostlyclean-compile mostlyclean-generic \
521
	mostlyclean-libtool
522
523
pdf: pdf-am
524
525
pdf-am:
526
527
ps: ps-am
528
529
ps-am:
530
531
uninstall-am: uninstall-info-am
532
533
.PHONY: CTAGS GTAGS all all-am check check-am clean clean-generic \
534
	clean-libtool clean-noinstLIBRARIES ctags distclean \
535
	distclean-compile distclean-generic distclean-libtool \
536
	distclean-tags distdir dvi dvi-am info info-am install \
537
	install-am install-data install-data-am install-exec \
538
	install-exec-am install-info install-info-am install-man \
539
	install-strip installcheck installcheck-am installdirs \
540
	maintainer-clean maintainer-clean-generic mostlyclean \
541
	mostlyclean-compile mostlyclean-generic mostlyclean-libtool pdf \
542
	pdf-am ps ps-am tags uninstall uninstall-am uninstall-info-am
543
544
545
totemplparser-marshal.c: totemplparser-marshal.h
546
	 ( $(GLIB_GENMARSHAL) --prefix=totemplparser_marshal $(srcdir)/totemplparser-marshal.list --header --body > totemplparser-marshal.c )
547
totemplparser-marshal.h: totemplparser-marshal.list
548
	( $(GLIB_GENMARSHAL) --prefix=totemplparser_marshal $(srcdir)/totemplparser-marshal.list --header > totemplparser-marshal.h )
549
totem-pl-parser-builtins.h: stamp-totem-pl-parser-builtins.h
550
	@true
551
552
stamp-totem-pl-parser-builtins.h: totem-pl-parser.h Makefile
553
	(cd $(srcdir) && $(GLIB_MKENUMS) \
554
			--fhead "#ifndef __TOTEM_PL_PARSER_BUILTINS_H__\n#define __TOTEM_PL_PARSER_BUILTINS_H__\n\n#include <glib-object.h>\n\nG_BEGIN_DECLS\n" \
555
			--fprod "/* enumerations from \"@filename@\" */\n" \
556
			--vhead "GType @enum_name@_get_type (void) G_GNUC_CONST;\n#define TOTEM_TYPE_@ENUMSHORT@ (@enum_name@_get_type())\n" \
557
			--ftail "G_END_DECLS\n\n#endif /* __TOTEM_PL_PARSER_BUILTINS_H__ */" totem-pl-parser.h) >> xgen-gtbh \
558
	&& (cmp -s xgen-gtbh totem-pl-parser-builtins.h || cp xgen-gtbh totem-pl-parser-builtins.h ) \
559
	&& rm -f xgen-gtbh \
560
	&& echo timestamp > $(@F)
561
562
totem-pl-parser-builtins.c: totem-pl-parser.h Makefile totem-pl-parser-builtins.h
563
	(cd $(srcdir) && $(GLIB_MKENUMS) \
564
			--fhead "#include \"totem-pl-parser.h\"\n#include \"totem-pl-parser-builtins.h\"" \
565
			--fprod "\n/* enumerations from \"@filename@\" */" \
566
			--vhead "GType\n@enum_name@_get_type (void)\n{\n  static GType etype = 0;\n  if (etype == 0) {\n    static const G@Type@Value values[] = {" \
567
			--vprod "      { @VALUENAME@, \"@VALUENAME@\", \"@valuenick@\" }," \
568
			--vtail "      { 0, NULL, NULL }\n    };\n    etype = g_@type@_register_static (\"@EnumName@\", values);\n  }\n  return etype;\n}\n" \
569
		totem-pl-parser.h ) > xgen-gtbc \
570
	&& cp xgen-gtbc totem-pl-parser-builtins.c  \
571
	&& rm -f xgen-gtbc
572
# Tell versions [3.59,3.63) of GNU make to not export all variables.
573
# Otherwise a system limit (for SysV at least) may be exceeded.
574
.NOEXPORT:
(-)rhythmbox-0.9.2.orig/plparse/totem-disc.c (+710 lines)
Line 0 Link Here
1
/* Totem Disc Content Detection
2
 * (c) 2004 Ronald Bultje <rbultje@ronald.bitfreak.net>
3
 *
4
 * This library is free software; you can redistribute it and/or
5
 * modify it under the terms of the GNU Library General Public
6
 * License as published by the Free Software Foundation; either
7
 * version 2 of the License, or (at your option) any later version.
8
 *
9
 * This library is distributed in the hope that it will be useful,
10
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12
 * Library General Public License for more details.
13
 *
14
 * You should have received a copy of the GNU Library General Public
15
 * License along with this library; if not, write to the
16
 * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
17
 * Boston, MA 02111-1307, USA.
18
 *
19
 * The Totem project hereby grant permission for non-gpl compatible GStreamer
20
 * plugins to be used and distributed together with GStreamer and Totem. This
21
 * permission are above and beyond the permissions granted by the GPL license
22
 * Totem is covered by.
23
 *
24
 * Monday 7th February 2005: Christian Schaller: Add excemption clause.
25
 * See license_change file for details.
26
 *
27
 */
28
29
#ifdef HAVE_CONFIG_H
30
#include "config.h"
31
#endif
32
33
#include <fcntl.h>
34
#include <stdio.h>
35
#include <stdlib.h>
36
#include <errno.h>
37
#include <mntent.h>
38
#include <string.h>
39
40
#include <sys/ioctl.h>
41
#include <sys/stat.h>
42
43
#include <glib.h>
44
#include <glib/gi18n.h>
45
#include <libgnomevfs/gnome-vfs.h>
46
47
#include <linux/cdrom.h>
48
49
#include "totem-disc.h"
50
51
typedef struct _CdCache {
52
  /* device node and mountpoint */
53
  char *device, *mountpoint;
54
  GnomeVFSDrive *drive;
55
56
  /* file descriptor to the device */
57
  int fd;
58
59
  /* capabilities of the device */
60
  int cap;
61
62
  /* if we're checking a media, or a dir */
63
  gboolean is_media;
64
65
  /* indicates if we mounted this mountpoint ourselves or if it
66
   * was already mounted. */
67
  gboolean self_mounted;
68
  gboolean mounted;
69
} CdCache;
70
71
/* 
72
 * Resolve relative paths
73
 */
74
75
static char *
76
totem_disc_resolve_link (const char *dev, const char *buf)
77
{
78
  char *parent, *new, *result;
79
80
  /* is it an absolute path? */
81
  if (g_path_is_absolute (buf) != FALSE) {
82
    result = realpath (buf, NULL);
83
    if (result == NULL)
84
      result = g_strdup (buf);
85
  } else {
86
    parent = g_path_get_dirname (dev);
87
    new = g_build_filename (parent, buf, NULL);
88
    result = realpath (new, NULL);
89
    if (result == NULL)
90
      result = g_strdup (new);
91
    g_free (new);
92
    g_free (parent);
93
  }
94
95
  return result;
96
}
97
98
/*
99
 * So, devices can be symlinks and that screws up.
100
 */
101
102
static char *
103
get_device (const char *device,
104
	    GError     **error)
105
{
106
  char *buf;
107
  char *dev = g_strdup (device);
108
  struct stat st;
109
110
  while (1) {
111
    char *new;
112
113
    if (lstat (dev, &st) != 0) {
114
      g_set_error (error, 0, 0,
115
          _("Failed to find real device node for %s: %s"),
116
          dev, g_strerror (errno));
117
      g_free (dev);
118
      return NULL;
119
    }
120
121
    if (!S_ISLNK (st.st_mode))
122
      break;
123
124
    if (!(buf = g_file_read_link (dev, NULL))) {
125
      g_set_error (error, 0, 0,
126
          _("Failed to read symbolic link %s: %s"),
127
          dev, g_strerror (errno));
128
      g_free (dev);
129
      return NULL;
130
    }
131
    new = totem_disc_resolve_link (dev, buf);
132
    g_free (dev);
133
    g_free (buf);
134
    dev = new;
135
  }
136
137
  return dev;
138
}
139
140
static gboolean
141
cd_cache_get_dev_from_volumes (GnomeVFSVolumeMonitor *mon, const char *device,
142
			      char **mountpoint)
143
{
144
  gboolean found;
145
  GnomeVFSVolume *volume = NULL;
146
  GList *list, *or;
147
148
  found = FALSE;
149
150
  for (or = list = gnome_vfs_volume_monitor_get_mounted_volumes (mon);
151
       list != NULL; list = list->next) {
152
    char *pdev, *pdev2;
153
154
    volume = list->data;
155
    if (!(pdev = gnome_vfs_volume_get_device_path (volume)))
156
      continue;
157
    if (!(pdev2 = get_device (pdev, NULL))) {
158
      g_free (pdev);
159
      continue;
160
    }
161
    g_free (pdev);
162
163
    if (strcmp (pdev2, device) == 0) {
164
      char *mnt;
165
166
      mnt = gnome_vfs_volume_get_activation_uri (volume);
167
      if (mnt && strncmp (mnt, "file://", 7) == 0) {
168
	g_free (pdev2);
169
        *mountpoint = g_strdup (mnt + 7);
170
        g_free (mnt);
171
	found = TRUE;
172
        break;
173
      } else if (mnt && strncmp (mnt, "cdda://", 7) == 0) {
174
	g_free (pdev2);
175
	*mountpoint = NULL;
176
	g_free (mnt);
177
	found = TRUE;
178
	break;
179
      }
180
      g_free (mnt);
181
    }
182
    g_free (pdev2);
183
  }
184
  g_list_foreach (or, (GFunc) gnome_vfs_volume_unref, NULL);
185
  g_list_free (or);
186
187
  return found;
188
}
189
static gboolean
190
cd_cache_get_dev_from_drives (GnomeVFSVolumeMonitor *mon, const char *device,
191
			      char **mountpoint, GnomeVFSDrive **d)
192
{
193
  gboolean found;
194
  GnomeVFSDrive *drive = NULL;
195
  GList *list, *or;
196
197
  found = FALSE;
198
199
  for (or = list = gnome_vfs_volume_monitor_get_connected_drives (mon);
200
       list != NULL; list = list->next) {
201
    char *pdev, *pdev2;
202
203
    drive = list->data;
204
    if (!(pdev = gnome_vfs_drive_get_device_path (drive)))
205
      continue;
206
    if (!(pdev2 = get_device (pdev, NULL))) {
207
      g_free (pdev);
208
      continue;
209
    }
210
    g_free (pdev);
211
212
    if (strcmp (pdev2, device) == 0) {
213
      char *mnt;
214
215
      mnt = gnome_vfs_drive_get_activation_uri (drive);
216
      if (mnt && strncmp (mnt, "file://", 7) == 0) {
217
	g_free (pdev2);
218
        *mountpoint = g_strdup (mnt + 7);
219
        g_free (mnt);
220
        gnome_vfs_drive_ref (drive);
221
	found = TRUE;
222
        break;
223
      } else if (mnt && strncmp (mnt, "cdda://", 7) == 0) {
224
	g_free (pdev2);
225
	*mountpoint = NULL;
226
	g_free (mnt);
227
	gnome_vfs_drive_ref (drive);
228
	found = TRUE;
229
	break;
230
      }
231
      g_free (mnt);
232
    }
233
    g_free (pdev2);
234
  }
235
  g_list_foreach (or, (GFunc) gnome_vfs_drive_unref, NULL);
236
  g_list_free (or);
237
238
  *d = drive;
239
240
  return found;
241
}
242
243
static CdCache *
244
cd_cache_new (const char *dev,
245
	      GError     **error)
246
{
247
  CdCache *cache;
248
  char *mountpoint = NULL, *device, *local;
249
  GnomeVFSVolumeMonitor *mon;
250
  GnomeVFSDrive *drive = NULL;
251
  gboolean is_dir, found;
252
253
  if (g_str_has_prefix (dev, "file://") != FALSE)
254
    local = g_filename_from_uri (dev, NULL, NULL);
255
  else
256
    local = g_strdup (dev);
257
258
  g_assert (local != NULL);
259
260
  is_dir = g_file_test (local, G_FILE_TEST_IS_DIR);
261
262
  if (is_dir) {
263
    cache = g_new0 (CdCache, 1);
264
    cache->mountpoint = local;
265
    cache->fd = -1;
266
    cache->is_media = FALSE;
267
268
    return cache;
269
  }
270
271
  /* retrieve mountpoint (/etc/fstab) */
272
  device = get_device (local, error);
273
  g_free (local);
274
  if (!device)
275
    return NULL;
276
  mon = gnome_vfs_get_volume_monitor ();
277
  found = cd_cache_get_dev_from_drives (mon, device, &mountpoint, &drive);
278
  if (!found) {
279
    drive = NULL;
280
    found = cd_cache_get_dev_from_volumes (mon, device, &mountpoint);
281
  }
282
283
  if (!found) {
284
    g_set_error (error, 0, 0,
285
	_("Failed to find mountpoint for device %s in /etc/fstab"),
286
	device);
287
    return NULL;
288
  }
289
290
  /* create struture */
291
  cache = g_new0 (CdCache, 1);
292
  cache->device = device;
293
  cache->mountpoint = mountpoint;
294
  cache->fd = -1;
295
  cache->self_mounted = FALSE;
296
  cache->drive = drive;
297
  cache->is_media = TRUE;
298
299
  return cache;
300
}
301
302
static gboolean
303
cd_cache_open_device (CdCache *cache,
304
		      GError **error)
305
{
306
  int drive, err;
307
308
  /* not a medium? */
309
  if (cache->is_media == FALSE) {
310
    cache->cap = CDC_DVD;
311
    return TRUE;
312
  }
313
314
  /* already open? */
315
  if (cache->fd > 0)
316
    return TRUE;
317
318
  /* try to open the CD before creating anything */
319
  if ((cache->fd = open (cache->device, O_RDONLY)) < 0) {
320
    err = errno;
321
    if (err == ENOMEDIUM) {
322
      g_set_error (error, 0, 0,
323
          _("Please check that a disc is present in the drive."));
324
    } else {
325
      g_set_error (error, 0, 0,
326
          _("Failed to open device %s for reading: %s"),
327
        cache->device, g_strerror (err));
328
    }
329
    return FALSE;
330
  }
331
332
  /* get capabilities */
333
  if ((cache->cap = ioctl (cache->fd, CDROM_GET_CAPABILITY, NULL)) < 0) {
334
    close (cache->fd);
335
    cache->fd = -1;
336
    g_set_error (error, 0, 0,
337
        _("Failed to retrieve capabilities of device %s: %s"),
338
        cache->device, g_strerror (errno));
339
    return FALSE;
340
  }
341
342
  /* is there a disc in the tray? */
343
  if ((drive = ioctl (cache->fd, CDROM_DRIVE_STATUS, NULL)) != CDS_DISC_OK) {
344
    const char *drive_s;
345
346
    close (cache->fd);
347
    cache->fd = -1;
348
349
    switch (drive) {
350
      case CDS_NO_INFO:
351
        drive_s = "Not implemented";
352
        break;
353
      case CDS_NO_DISC:
354
        drive_s = "No disc in tray";
355
        break;
356
      case CDS_TRAY_OPEN:
357
        drive_s = "Tray open";
358
        break;
359
      case CDS_DRIVE_NOT_READY:
360
        drive_s = "Drive not ready";
361
        break;
362
      case CDS_DISC_OK:
363
        drive_s = "OK";
364
        break;
365
      default:
366
        drive_s = "Unknown";
367
        break;
368
    }
369
    g_set_error (error, 0, 0,
370
        _("Drive status 0x%x (%s) - check disc"),
371
        drive, drive_s);
372
    return FALSE;
373
  }
374
375
  return TRUE;
376
}
377
378
static gboolean
379
cd_cache_open_mountpoint (CdCache *cache,
380
			  GError **error)
381
{
382
  /* already opened? */
383
  if (cache->mounted || cache->is_media == FALSE)
384
    return TRUE;
385
386
  /* check for mounting - assume we'll mount ourselves */
387
  if (cache->drive == NULL)
388
    return TRUE;
389
  cache->self_mounted = !gnome_vfs_drive_is_mounted (cache->drive);
390
391
  /* mount if we have to */
392
  if (cache->self_mounted) {
393
    char *command;
394
    int status;
395
396
    command = g_strdup_printf ("mount %s", cache->mountpoint);
397
    if (!g_spawn_command_line_sync (command,
398
             NULL, NULL, &status, error)) {
399
      g_free (command);
400
      return FALSE;
401
    }
402
    g_free (command);
403
    if (status != 0) {
404
      g_set_error (error, 0, 0,
405
          _("Unexpected error status %d while mounting %s"),
406
          status, cache->mountpoint);
407
      return FALSE;
408
    }
409
  }
410
411
  cache->mounted = TRUE;
412
  return TRUE;
413
}
414
415
static void
416
cd_cache_free (CdCache *cache)
417
{
418
  /* umount if we mounted */
419
  if (cache->self_mounted && cache->mounted) {
420
    char *command;
421
422
    command = g_strdup_printf ("umount %s", cache->mountpoint);
423
    g_spawn_command_line_sync (command, NULL, NULL, NULL, NULL);
424
    g_free (command);
425
  }
426
427
  /* close file descriptor to device */
428
  if (cache->fd > 0) {
429
    close (cache->fd);
430
  }
431
432
  /* free mem */
433
  if (cache->drive)
434
    gnome_vfs_drive_unref (cache->drive);
435
  g_free (cache->mountpoint);
436
  g_free (cache->device);
437
  g_free (cache);
438
}
439
440
static MediaType
441
cd_cache_disc_is_cdda (CdCache *cache,
442
		       GError **error)
443
{
444
  MediaType type = MEDIA_TYPE_DATA;
445
  int disc;
446
  const char *disc_s;
447
448
  /* We can't have audio CDs on disc, yet */
449
  if (cache->is_media == FALSE)
450
    return type;
451
452
  /* open disc and open mount */
453
  if (!cd_cache_open_device (cache, error))
454
    return MEDIA_TYPE_ERROR;
455
456
  if ((disc = ioctl (cache->fd, CDROM_DISC_STATUS, NULL)) < 0) {
457
    g_set_error (error, 0, 0,
458
        _("Error getting %s disc status: %s"),
459
        cache->device, g_strerror (errno));
460
    return MEDIA_TYPE_ERROR;
461
  }
462
463
  switch (disc) {
464
    case CDS_NO_INFO:
465
      /* The drive doesn't implement CDROM_DISC_STATUS */
466
      break;
467
    case CDS_NO_DISC:
468
      disc_s = "No disc in tray";
469
      type = MEDIA_TYPE_ERROR;
470
      break;
471
    case CDS_AUDIO:
472
    case CDS_MIXED:
473
      type = MEDIA_TYPE_CDDA;
474
      break;
475
    case CDS_DATA_1:
476
    case CDS_DATA_2:
477
    case CDS_XA_2_1:
478
    case CDS_XA_2_2:
479
      break;
480
    default:
481
      disc_s = "Unknown";
482
      type = MEDIA_TYPE_ERROR;
483
      break;
484
  }
485
  if (type == MEDIA_TYPE_ERROR) {
486
    g_set_error (error, 0, 0,
487
        _("Unexpected/unknown cd type 0x%x (%s)"),
488
        disc, disc_s);
489
    return MEDIA_TYPE_ERROR;
490
  }
491
492
  return type;
493
}
494
495
static gboolean
496
cd_cache_file_exists (CdCache *cache, const char *subdir, const char *filename)
497
{
498
  char *path, *dir;
499
  gboolean ret;
500
501
  dir = NULL;
502
503
  /* Check whether the directory exists, for a start */
504
  path = g_build_filename (cache->mountpoint, subdir, NULL);
505
  ret = g_file_test (path, G_FILE_TEST_IS_DIR);
506
  if (ret == FALSE) {
507
    char *subdir_low;
508
509
    g_free (path);
510
    subdir_low = g_ascii_strdown (subdir, -1);
511
    path = g_build_filename (cache->mountpoint, subdir_low, NULL);
512
    ret = g_file_test (path, G_FILE_TEST_IS_DIR);
513
    g_free (path);
514
    if (ret) {
515
      dir = subdir_low;
516
    } else {
517
      g_free (subdir_low);
518
      return FALSE;
519
    }
520
  } else {
521
    g_free (path);
522
    dir = g_strdup (subdir);
523
  }
524
525
  /* And now the file */
526
  path = g_build_filename (cache->mountpoint, dir, filename, NULL);
527
  ret = g_file_test (path, G_FILE_TEST_IS_REGULAR);
528
  if (ret == FALSE) {
529
    char *fname_low;
530
531
    g_free (path);
532
    fname_low = g_ascii_strdown (filename, -1);
533
    path = g_build_filename (cache->mountpoint, dir, fname_low, NULL);
534
    ret = g_file_test (path, G_FILE_TEST_IS_REGULAR);
535
    g_free (fname_low);
536
  }
537
538
  g_free (dir);
539
  g_free (path);
540
541
  return ret;
542
}
543
544
static MediaType
545
cd_cache_disc_is_vcd (CdCache *cache,
546
                      GError **error)
547
{
548
  if (!cache->mountpoint)
549
    return MEDIA_TYPE_ERROR;
550
  /* open disc and open mount */
551
  if (!cd_cache_open_device (cache, error))
552
    return MEDIA_TYPE_ERROR;
553
  if (!cd_cache_open_mountpoint (cache, error))
554
    return MEDIA_TYPE_ERROR;
555
  /* first is VCD, second is SVCD */
556
  if (cd_cache_file_exists (cache, "MPEGAV", "AVSEQ01.DAT") ||
557
      cd_cache_file_exists (cache, "MPEG2", "AVSEQ01.MPG"))
558
    return MEDIA_TYPE_VCD;
559
560
  return MEDIA_TYPE_DATA;
561
}
562
563
static MediaType
564
cd_cache_disc_is_dvd (CdCache *cache,
565
		      GError **error)
566
{
567
  if (!cache->mountpoint)
568
    return MEDIA_TYPE_ERROR;
569
  /* open disc, check capabilities and open mount */
570
  if (!cd_cache_open_device (cache, error))
571
    return MEDIA_TYPE_ERROR;
572
  if (!(cache->cap & CDC_DVD))
573
    return MEDIA_TYPE_DATA;
574
  if (!cd_cache_open_mountpoint (cache, error))
575
    return MEDIA_TYPE_ERROR;
576
  if (cd_cache_file_exists (cache, "VIDEO_TS", "VIDEO_TS.IFO"))
577
    return MEDIA_TYPE_DVD;
578
579
  return MEDIA_TYPE_DATA;
580
}
581
582
static char *
583
totem_cd_mrl_from_type (const char *scheme, const char *dir)
584
{
585
  char *retval;
586
587
  if (g_str_has_prefix (dir, "file://") != FALSE) {
588
    char *local;
589
    local = g_filename_from_uri (dir, NULL, NULL);
590
    retval = g_strdup_printf ("%s://%s", scheme, local);
591
    g_free (local);
592
  } else {
593
    retval = g_strdup_printf ("%s://%s", scheme, dir);
594
  }
595
  return retval;
596
}
597
598
MediaType
599
totem_cd_detect_type_from_dir (const char *dir, char **url, GError **error)
600
{
601
  CdCache *cache;
602
  MediaType type;
603
604
  g_return_val_if_fail (dir != NULL, MEDIA_TYPE_ERROR);
605
606
  if (dir[0] != '/' && g_str_has_prefix (dir, "file://") == FALSE)
607
    return MEDIA_TYPE_ERROR;
608
609
  if (!(cache = cd_cache_new (dir, error)))
610
    return MEDIA_TYPE_ERROR;
611
  if ((type = cd_cache_disc_is_vcd (cache, error)) == MEDIA_TYPE_DATA &&
612
      (type = cd_cache_disc_is_dvd (cache, error)) == MEDIA_TYPE_DATA) {
613
    /* crap, nothing found */
614
    cd_cache_free (cache);
615
    return type;
616
  }
617
  cd_cache_free (cache);
618
619
  if (url == NULL) {
620
    return type;
621
  }
622
623
  if (type == MEDIA_TYPE_DVD) {
624
    *url = totem_cd_mrl_from_type ("dvd", dir);
625
  } else if (type == MEDIA_TYPE_VCD) {
626
    *url = totem_cd_mrl_from_type ("vcd", dir);
627
  }
628
629
  return type;
630
}
631
632
MediaType
633
totem_cd_detect_type_with_url (const char *device,
634
    			       char      **url,
635
			       GError     **error)
636
{
637
  CdCache *cache;
638
  MediaType type;
639
640
  if (url != NULL)
641
    *url = NULL;
642
643
  if (!(cache = cd_cache_new (device, error)))
644
    return MEDIA_TYPE_ERROR;
645
646
  type = cd_cache_disc_is_cdda (cache, error);
647
  if (type == MEDIA_TYPE_ERROR && *error != NULL)
648
    return type;
649
650
  if ((type == MEDIA_TYPE_DATA || type == MEDIA_TYPE_ERROR) &&
651
      (type = cd_cache_disc_is_vcd (cache, error)) == MEDIA_TYPE_DATA &&
652
      (type = cd_cache_disc_is_dvd (cache, error)) == MEDIA_TYPE_DATA) {
653
    /* crap, nothing found */
654
  }
655
656
  if (url == NULL) {
657
    cd_cache_free (cache);
658
    return type;
659
  }
660
661
  switch (type) {
662
  case MEDIA_TYPE_DVD:
663
    *url = totem_cd_mrl_from_type ("dvd", device);
664
    break;
665
  case MEDIA_TYPE_VCD:
666
    *url = totem_cd_mrl_from_type ("vcd", device);
667
    break;
668
  case MEDIA_TYPE_CDDA:
669
    *url = totem_cd_mrl_from_type ("cdda", device);
670
    break;
671
  case MEDIA_TYPE_DATA:
672
    *url = g_strdup (cache->mountpoint);
673
    break;
674
  default:
675
    break;
676
  }
677
678
  cd_cache_free (cache);
679
680
  return type;
681
}
682
683
MediaType
684
totem_cd_detect_type (const char  *device,
685
		      GError     **error)
686
{
687
  return totem_cd_detect_type_with_url (device, NULL, error);
688
}
689
690
const char *
691
totem_cd_get_human_readable_name (MediaType type)
692
{
693
  switch (type)
694
  {
695
  case MEDIA_TYPE_CDDA:
696
    return N_("Audio CD");
697
  case MEDIA_TYPE_VCD:
698
    return N_("Video CD");
699
  case MEDIA_TYPE_DVD:
700
    return N_("DVD");
701
  default:
702
    g_assert_not_reached ();
703
  }
704
705
  return NULL;
706
}
707
708
/*
709
 * vim: sw=2 ts=8 cindent noai bs=2
710
 */
(-)rhythmbox-0.9.2.orig/plparse/totem-disc.h (+49 lines)
Line 0 Link Here
1
/* Totem Disc Content Detection
2
 * (c) 2004 Ronald Bultje <rbultje@ronald.bitfreak.net>
3
 *
4
 * totem-disc.h: media content detection
5
 *
6
 * This library is free software; you can redistribute it and/or
7
 * modify it under the terms of the GNU Library General Public
8
 * License as published by the Free Software Foundation; either
9
 * version 2 of the License, or (at your option) any later version.
10
 *
11
 * This library is distributed in the hope that it will be useful,
12
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14
 * Library General Public License for more details.
15
 *
16
 * You should have received a copy of the GNU Library General Public
17
 * License along with this library; if not, write to the
18
 * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
19
 * Boston, MA 02111-1307, USA.
20
 */
21
22
#ifndef TOTEM_DISC_H
23
#define TOTEM_DISC_H
24
25
#include <glib.h>
26
27
G_BEGIN_DECLS
28
29
typedef enum {
30
  MEDIA_TYPE_ERROR = -1, /* error */
31
  MEDIA_TYPE_DATA = 1,
32
  MEDIA_TYPE_CDDA,
33
  MEDIA_TYPE_VCD,
34
  MEDIA_TYPE_DVD
35
} MediaType;
36
37
MediaType	totem_cd_detect_type	(const char *device,
38
					 GError     **error);
39
MediaType	totem_cd_detect_type_with_url (const char  *device,
40
					       char       **url,
41
					       GError     **error);
42
MediaType	totem_cd_detect_type_from_dir (const char *dir,
43
					 char      **url, 
44
					 GError    **error);
45
const char *	totem_cd_get_human_readable_name (MediaType type);
46
47
G_END_DECLS
48
49
#endif /* TOTEM_DISC_H */
(-)rhythmbox-0.9.2.orig/plparse/totem-pl-parser.c (+1632 lines)
Line 0 Link Here
1
/* 
2
   arch-tag: Implementation of Rhythmbox playlist parser
3
4
   Copyright (C) 2002, 2003, 2004 Bastien Nocera
5
   Copyright (C) 2003,2004 Colin Walters <walters@rhythmbox.org>
6
7
   The Gnome Library is free software; you can redistribute it and/or
8
   modify it under the terms of the GNU Library General Public License as
9
   published by the Free Software Foundation; either version 2 of the
10
   License, or (at your option) any later version.
11
12
   The Gnome Library is distributed in the hope that it will be useful,
13
   but WITHOUT ANY WARRANTY; without even the implied warranty of
14
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15
   Library General Public License for more details.
16
17
   You should have received a copy of the GNU Library General Public
18
   License along with the Gnome Library; see the file COPYING.LIB.  If not,
19
   write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
20
   Boston, MA 02111-1307, USA.
21
22
   Author: Bastien Nocera <hadess@hadess.net>
23
 */
24
25
#ifdef HAVE_CONFIG_H
26
#include "config.h"
27
#endif /* HAVE_CONFIG_H */
28
29
#include "totem-pl-parser.h"
30
31
#include "totemplparser-marshal.h"
32
#include "totem-disc.h"
33
34
#include <glib.h>
35
#include <glib/gi18n.h>
36
#include <gtk/gtk.h>
37
#include <libxml/tree.h>
38
#include <libxml/parser.h>
39
#include <libgnomevfs/gnome-vfs.h>
40
#include <libgnomevfs/gnome-vfs-mime.h>
41
#include <libgnomevfs/gnome-vfs-mime-utils.h>
42
#include <libgnomevfs/gnome-vfs-utils.h>
43
#include <string.h>
44
45
#define READ_CHUNK_SIZE 8192
46
#define MIME_READ_CHUNK_SIZE 1024
47
#define RECURSE_LEVEL_MAX 4
48
49
typedef TotemPlParserResult (*PlaylistCallback) (TotemPlParser *parser, const char *url, gpointer data);
50
static gboolean totem_pl_parser_scheme_is_ignored (TotemPlParser *parser, const char *url);
51
static gboolean totem_pl_parser_ignore (TotemPlParser *parser, const char *url);
52
static TotemPlParserResult totem_pl_parser_parse_internal (TotemPlParser *parser, const char *url);
53
static TotemPlParserResult totem_pl_parser_add_asx (TotemPlParser *parser, const char *url, gpointer data);
54
55
typedef struct {
56
	char *mimetype;
57
	PlaylistCallback func;
58
} PlaylistTypes;
59
60
struct TotemPlParserPrivate
61
{
62
	GList *ignore_schemes;
63
	GList *ignore_mimetypes;
64
	guint recurse_level;
65
	gboolean fallback;
66
};
67
68
/* Signals */
69
enum {
70
	ENTRY,
71
	PLAYLIST_START,
72
	PLAYLIST_END,
73
	LAST_SIGNAL
74
};
75
76
static int totem_pl_parser_table_signals[LAST_SIGNAL] = { 0 };
77
78
static GObjectClass *parent_class = NULL;
79
80
static void totem_pl_parser_class_init (TotemPlParserClass *class);
81
static void totem_pl_parser_init       (TotemPlParser      *parser);
82
static void totem_pl_parser_finalize   (GObject *object);
83
84
G_DEFINE_TYPE(TotemPlParser, totem_pl_parser, G_TYPE_OBJECT)
85
86
static void
87
totem_pl_parser_class_init (TotemPlParserClass *klass)
88
{
89
	GObjectClass *object_class = G_OBJECT_CLASS (klass);
90
91
	parent_class = g_type_class_peek_parent (klass);
92
93
	object_class->finalize = totem_pl_parser_finalize;
94
95
	/* Signals */
96
	totem_pl_parser_table_signals[ENTRY] =
97
		g_signal_new ("entry",
98
			      G_TYPE_FROM_CLASS (klass),
99
			      G_SIGNAL_RUN_LAST,
100
			      G_STRUCT_OFFSET (TotemPlParserClass, entry),
101
			      NULL, NULL,
102
			      totemplparser_marshal_VOID__STRING_STRING_STRING,
103
			      G_TYPE_NONE, 3, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING);
104
	totem_pl_parser_table_signals[PLAYLIST_START] =
105
		g_signal_new ("playlist-start",
106
			      G_TYPE_FROM_CLASS (klass),
107
			      G_SIGNAL_RUN_LAST,
108
			      G_STRUCT_OFFSET (TotemPlParserClass, playlist_start),
109
			      NULL, NULL,
110
			      g_cclosure_marshal_VOID__STRING,
111
			      G_TYPE_NONE, 1, G_TYPE_STRING);
112
	totem_pl_parser_table_signals[PLAYLIST_END] =
113
		g_signal_new ("playlist-end",
114
			      G_TYPE_FROM_CLASS (klass),
115
			      G_SIGNAL_RUN_LAST,
116
			      G_STRUCT_OFFSET (TotemPlParserClass, playlist_end),
117
			      NULL, NULL,
118
			      g_cclosure_marshal_VOID__STRING,
119
			      G_TYPE_NONE, 1, G_TYPE_STRING);
120
}
121
122
GQuark
123
totem_pl_parser_error_quark (void)
124
{
125
	static GQuark quark;
126
	if (!quark)
127
		quark = g_quark_from_static_string ("totem_pl_parser_error");
128
129
	return quark;
130
}
131
132
TotemPlParser *
133
totem_pl_parser_new (void)
134
{
135
	return TOTEM_PL_PARSER (g_object_new (TOTEM_TYPE_PL_PARSER, NULL));
136
}
137
138
static const char *
139
my_gnome_vfs_get_mime_type_with_data (const char *uri, gpointer *data)
140
{
141
	GnomeVFSResult result;
142
	GnomeVFSHandle *handle;
143
	char *buffer;
144
	const char *mimetype;
145
	GnomeVFSFileSize total_bytes_read;
146
	GnomeVFSFileSize bytes_read;
147
148
	*data = NULL;
149
150
	/* Open the file. */
151
	result = gnome_vfs_open (&handle, uri, GNOME_VFS_OPEN_READ);
152
	if (result != GNOME_VFS_OK)
153
		return NULL;
154
155
	/* Read the whole thing, up to MIME_READ_CHUNK_SIZE */
156
	buffer = NULL;
157
	total_bytes_read = 0;
158
	do {
159
		buffer = g_realloc (buffer, total_bytes_read
160
				+ MIME_READ_CHUNK_SIZE);
161
		result = gnome_vfs_read (handle,
162
				buffer + total_bytes_read,
163
				MIME_READ_CHUNK_SIZE,
164
				&bytes_read);
165
		if (result != GNOME_VFS_OK && result != GNOME_VFS_ERROR_EOF) {
166
			g_free (buffer);
167
			gnome_vfs_close (handle);
168
			return NULL;
169
		}
170
171
		/* Check for overflow. */
172
		if (total_bytes_read + bytes_read < total_bytes_read) {
173
			g_free (buffer);
174
			gnome_vfs_close (handle);
175
			return NULL;
176
		}
177
178
		total_bytes_read += bytes_read;
179
	} while (result == GNOME_VFS_OK
180
			&& total_bytes_read < MIME_READ_CHUNK_SIZE);
181
182
	/* Close the file. */
183
	result = gnome_vfs_close (handle);
184
	if (result != GNOME_VFS_OK) {
185
		g_free (buffer);
186
		return NULL;
187
	}
188
189
	/* Return the file null-terminated. */
190
	buffer = g_realloc (buffer, total_bytes_read + 1);
191
	buffer[total_bytes_read] = '\0';
192
	*data = buffer;
193
194
	mimetype = gnome_vfs_get_mime_type_for_data (*data, total_bytes_read);
195
196
	return mimetype;
197
}
198
199
static char*
200
totem_pl_parser_base_url (const char *url)
201
{
202
	/* Yay, let's reconstruct the base by hand */
203
	GnomeVFSURI *uri, *parent;
204
	char *base;
205
206
	uri = gnome_vfs_uri_new (url);
207
	if (uri == NULL)
208
		return NULL;
209
210
	parent = gnome_vfs_uri_get_parent (uri);
211
	if (!parent) {
212
		parent = uri;
213
	}
214
	base = gnome_vfs_uri_to_string (parent, 0);
215
216
	gnome_vfs_uri_unref (uri);
217
	if (parent != uri) {
218
		gnome_vfs_uri_unref (parent);
219
	}
220
221
	return base;
222
}
223
224
static gboolean
225
write_string (GnomeVFSHandle *handle, const char *buf, GError **error)
226
{
227
	GnomeVFSResult res;
228
	GnomeVFSFileSize written;
229
	guint len;
230
231
	len = strlen (buf);
232
	res = gnome_vfs_write (handle, buf, len, &written);
233
	if (res != GNOME_VFS_OK || written < len) {
234
		g_set_error (error,
235
			     TOTEM_PL_PARSER_ERROR,
236
			     TOTEM_PL_PARSER_ERROR_VFS_WRITE,
237
			     _("Couldn't write parser: %s"),
238
			     gnome_vfs_result_to_string (res));
239
		gnome_vfs_close (handle);
240
		return FALSE;
241
	}
242
243
	return TRUE;
244
}
245
246
static int
247
totem_pl_parser_num_entries (TotemPlParser *parser, GtkTreeModel *model,
248
			     TotemPlParserIterFunc func, gpointer user_data)
249
{
250
	int num_entries, i, ignored;
251
252
	num_entries = gtk_tree_model_iter_n_children (model, NULL);
253
	ignored = 0;
254
255
	for (i = 1; i <= num_entries; i++)
256
	{
257
		GtkTreeIter iter;
258
		char *path, *url, *title;
259
260
		path = g_strdup_printf ("%d", i - 1);
261
		gtk_tree_model_get_iter_from_string (model, &iter, path);
262
		g_free (path);
263
264
		func (model, &iter, &url, &title, user_data);
265
		if (totem_pl_parser_scheme_is_ignored (parser, url) != FALSE)
266
			ignored++;
267
268
		g_free (url);
269
		g_free (title);
270
	}
271
272
	return num_entries - ignored;
273
}
274
275
static char *
276
totem_pl_parser_relative (const char *url, const char *output)
277
{
278
	char *url_base, *output_base;
279
	char *base, *needle;
280
281
	base = NULL;
282
	url_base = totem_pl_parser_base_url (url);
283
	if (url_base == NULL)
284
		return NULL;
285
286
	output_base = totem_pl_parser_base_url (output);
287
288
	needle = strstr (url_base, output_base);
289
	if (needle != NULL)
290
	{
291
		GnomeVFSURI *uri;
292
		char *newurl;
293
294
		uri = gnome_vfs_uri_new (url);
295
		newurl = gnome_vfs_uri_to_string (uri, 0);
296
		if (newurl[strlen (output_base)] == '/') {
297
			base = g_strdup (newurl + strlen (output_base) + 1);
298
		} else {
299
			base = g_strdup (newurl + strlen (output_base));
300
		}
301
		gnome_vfs_uri_unref (uri);
302
		g_free (newurl);
303
304
		/* And finally unescape the string */
305
		newurl = gnome_vfs_unescape_string (base, NULL);
306
		g_free (base);
307
		base = newurl;
308
	}
309
310
	g_free (url_base);
311
	g_free (output_base);
312
313
	return base;
314
}
315
316
static gboolean
317
totem_pl_parser_write_pls (TotemPlParser *parser, GtkTreeModel *model,
318
			   TotemPlParserIterFunc func, 
319
			   const char *output, const char *title,
320
			   gpointer user_data, GError **error)
321
{
322
	GnomeVFSHandle *handle;
323
	GnomeVFSResult res;
324
	int num_entries_total, num_entries, i;
325
	char *buf;
326
	gboolean success;
327
328
	num_entries = totem_pl_parser_num_entries (parser, model, func, user_data);
329
	num_entries_total = gtk_tree_model_iter_n_children (model, NULL);
330
331
	res = gnome_vfs_open (&handle, output, GNOME_VFS_OPEN_WRITE);
332
	if (res == GNOME_VFS_ERROR_NOT_FOUND) {
333
		res = gnome_vfs_create (&handle, output,
334
				GNOME_VFS_OPEN_WRITE, FALSE,
335
				GNOME_VFS_PERM_USER_WRITE
336
				| GNOME_VFS_PERM_USER_READ
337
				| GNOME_VFS_PERM_GROUP_READ);
338
	}
339
340
	if (res != GNOME_VFS_OK) {
341
		g_set_error(error,
342
			    TOTEM_PL_PARSER_ERROR,
343
			    TOTEM_PL_PARSER_ERROR_VFS_OPEN,
344
			    _("Couldn't open file '%s': %s"),
345
			    output, gnome_vfs_result_to_string (res));
346
		return FALSE;
347
	}
348
349
	buf = g_strdup ("[playlist]\n");
350
	success = write_string (handle, buf, error);
351
	g_free (buf);
352
	if (success == FALSE)
353
		return FALSE;
354
355
	if (title != NULL) {
356
		buf = g_strdup_printf ("X-GNOME-Title=%s\n", title);
357
		success = write_string (handle, buf, error);
358
		g_free (buf);
359
		if (success == FALSE)
360
		{
361
			gnome_vfs_close (handle);
362
			return FALSE;
363
		}
364
	}
365
366
	buf = g_strdup_printf ("NumberOfEntries=%d\n", num_entries);
367
	success = write_string (handle, buf, error);
368
	g_free (buf);
369
	if (success == FALSE)
370
	{
371
		gnome_vfs_close (handle);
372
		return FALSE;
373
	}
374
375
	for (i = 1; i <= num_entries_total; i++) {
376
		GtkTreeIter iter;
377
		char *path, *url, *title, *relative;
378
379
		path = g_strdup_printf ("%d", i - 1);
380
		gtk_tree_model_get_iter_from_string (model, &iter, path);
381
		g_free (path);
382
383
		func (model, &iter, &url, &title, user_data);
384
385
		if (totem_pl_parser_scheme_is_ignored (parser, url) != FALSE)
386
		{
387
			g_free (url);
388
			g_free (title);
389
			continue;
390
		}
391
392
		relative = totem_pl_parser_relative (url, output);
393
		buf = g_strdup_printf ("File%d=%s\n", i,
394
				relative ? relative : url);
395
		g_free (relative);
396
		g_free (url);
397
		success = write_string (handle, buf, error);
398
		g_free (buf);
399
		if (success == FALSE)
400
		{
401
			gnome_vfs_close (handle);
402
			g_free (title);
403
			return FALSE;
404
		}
405
406
		buf = g_strdup_printf ("Title%d=%s\n", i, title);
407
		success = write_string (handle, buf, error);
408
		g_free (buf);
409
		g_free (title);
410
		if (success == FALSE)
411
		{
412
			gnome_vfs_close (handle);
413
			return FALSE;
414
		}
415
	}
416
417
	gnome_vfs_close (handle);
418
	return TRUE;
419
}
420
421
static char *
422
totem_pl_parser_url_to_dos (const char *url, const char *output)
423
{
424
	char *retval, *i;
425
426
	retval = totem_pl_parser_relative (url, output);
427
428
	if (retval == NULL)
429
		retval = g_strdup (url);
430
431
	/* Don't change URIs, but change smb:// */
432
	if (g_str_has_prefix (retval, "smb://") != FALSE)
433
	{
434
		char *tmp;
435
		tmp = g_strdup (retval + strlen ("smb:"));
436
		g_free (retval);
437
		retval = tmp;
438
	}
439
440
	if (strstr (retval, "://") != NULL)
441
		return retval;
442
443
	i = retval;
444
	while (*i != '\0')
445
	{
446
		if (*i == '/')
447
			*i = '\\';
448
		i++;
449
	}
450
451
	return retval;
452
}
453
454
static gboolean
455
totem_pl_parser_write_m3u (TotemPlParser *parser, GtkTreeModel *model,
456
		TotemPlParserIterFunc func, const char *output,
457
		gboolean dos_compatible, gpointer user_data, GError **error)
458
{
459
	GnomeVFSHandle *handle;
460
	GnomeVFSResult res;
461
	int num_entries_total, i;
462
	gboolean success;
463
	char *buf;
464
465
	res = gnome_vfs_open (&handle, output, GNOME_VFS_OPEN_WRITE);
466
	if (res == GNOME_VFS_ERROR_NOT_FOUND) {
467
		res = gnome_vfs_create (&handle, output,
468
				GNOME_VFS_OPEN_WRITE, FALSE,
469
				GNOME_VFS_PERM_USER_WRITE
470
				| GNOME_VFS_PERM_USER_READ
471
				| GNOME_VFS_PERM_GROUP_READ);
472
	}
473
474
	if (res != GNOME_VFS_OK) {
475
		g_set_error(error,
476
			    TOTEM_PL_PARSER_ERROR,
477
			    TOTEM_PL_PARSER_ERROR_VFS_OPEN,
478
			    _("Couldn't open file '%s': %s"),
479
			    output, gnome_vfs_result_to_string (res));
480
		return FALSE;
481
	}
482
483
	num_entries_total = gtk_tree_model_iter_n_children (model, NULL);
484
485
	for (i = 1; i <= num_entries_total; i++) {
486
		GtkTreeIter iter;
487
		char *path, *url, *title;
488
489
		path = g_strdup_printf ("%d", i - 1);
490
		gtk_tree_model_get_iter_from_string (model, &iter, path);
491
		g_free (path);
492
493
		func (model, &iter, &url, &title, user_data);
494
495
		if (totem_pl_parser_scheme_is_ignored (parser, url) != FALSE)
496
		{
497
			g_free (url);
498
			g_free (title);
499
			continue;
500
		}
501
502
		if (dos_compatible != FALSE)
503
		{
504
			char *dos;
505
506
			dos = totem_pl_parser_url_to_dos (url, output);
507
			buf = g_strdup_printf ("%s\r\n", dos);
508
			g_free (dos);
509
		} else {
510
			char *relative;
511
512
			relative = totem_pl_parser_relative (url, output);
513
			buf = g_strdup_printf ("%s\n", relative);
514
			g_free (relative);
515
		}
516
517
		success = write_string (handle, url, error);
518
519
		if (success == FALSE)
520
		{
521
			gnome_vfs_close (handle);
522
			return FALSE;
523
		}
524
	}
525
526
	return TRUE;
527
}
528
529
gboolean
530
totem_pl_parser_write_with_title (TotemPlParser *parser, GtkTreeModel *model,
531
				  TotemPlParserIterFunc func,
532
				  const char *output, const char *title,
533
				  TotemPlParserType type,
534
				  gpointer user_data, GError **error)
535
{
536
	switch (type)
537
	{
538
	case TOTEM_PL_PARSER_PLS:
539
		return totem_pl_parser_write_pls (parser, model, func,
540
				output, title, user_data, error);
541
	case TOTEM_PL_PARSER_M3U:
542
	case TOTEM_PL_PARSER_M3U_DOS:
543
		return totem_pl_parser_write_m3u (parser, model, func,
544
				output, (type == TOTEM_PL_PARSER_M3U_DOS),
545
                                user_data, error);
546
	default:
547
		g_assert_not_reached ();
548
	}
549
550
	return FALSE;
551
}
552
553
gboolean
554
totem_pl_parser_write (TotemPlParser *parser, GtkTreeModel *model,
555
		       TotemPlParserIterFunc func,
556
		       const char *output, TotemPlParserType type,
557
		       gpointer user_data,
558
		       GError **error)
559
{
560
	return totem_pl_parser_write_with_title (parser, model, func, output,
561
			NULL, type, user_data, error);
562
}
563
564
static int
565
read_ini_line_int (char **lines, const char *key)
566
{
567
	int retval = -1;
568
	int i;
569
570
	if (lines == NULL || key == NULL)
571
		return -1;
572
573
	for (i = 0; (lines[i] != NULL && retval == -1); i++) {
574
		if (g_ascii_strncasecmp (lines[i], key, strlen (key)) == 0) {
575
			char **bits;
576
577
			bits = g_strsplit (lines[i], "=", 2);
578
			if (bits[0] == NULL || bits [1] == NULL) {
579
				g_strfreev (bits);
580
				return -1;
581
			}
582
583
			retval = (gint) g_strtod (bits[1], NULL);
584
			g_strfreev (bits);
585
		}
586
	}
587
588
	return retval;
589
}
590
591
static char*
592
read_ini_line_string (char **lines, const char *key, gboolean dos_mode)
593
{
594
	char *retval = NULL;
595
	int i;
596
597
	if (lines == NULL || key == NULL)
598
		return NULL;
599
600
	for (i = 0; (lines[i] != NULL && retval == NULL); i++) {
601
		if (g_ascii_strncasecmp (lines[i], key, strlen (key)) == 0) {
602
			char **bits;
603
			ssize_t len;
604
605
			bits = g_strsplit (lines[i], "=", 2);
606
			if (bits[0] == NULL || bits [1] == NULL) {
607
				g_strfreev (bits);
608
				return NULL;
609
			}
610
611
			retval = g_strdup (bits[1]);
612
			len = strlen (retval);
613
			if (dos_mode && len >= 2 && retval[len-2] == '\r') {
614
				retval[len-2] = '\n';
615
				retval[len-1] = '\0';
616
			}
617
618
			g_strfreev (bits);
619
		}
620
	}
621
622
	return retval;
623
}
624
625
static void
626
totem_pl_parser_init (TotemPlParser *parser)
627
{
628
	parser->priv = g_new0 (TotemPlParserPrivate, 1);
629
}
630
631
static void
632
totem_pl_parser_finalize (GObject *object)
633
{
634
	TotemPlParser *parser = TOTEM_PL_PARSER (object);
635
636
	g_return_if_fail (object != NULL);
637
	g_return_if_fail (parser->priv != NULL);
638
639
	g_list_foreach (parser->priv->ignore_schemes, (GFunc) g_free, NULL);
640
	g_list_free (parser->priv->ignore_schemes);
641
642
	g_list_foreach (parser->priv->ignore_mimetypes, (GFunc) g_free, NULL);
643
	g_list_free (parser->priv->ignore_mimetypes);
644
645
	g_free (parser->priv);
646
	parser->priv = NULL;
647
648
	if (G_OBJECT_CLASS (parent_class)->finalize != NULL) {
649
		(* G_OBJECT_CLASS (parent_class)->finalize) (object);
650
	}
651
}
652
653
static gboolean
654
totem_pl_parser_check_utf8 (const char *title)
655
{
656
	return title ? g_utf8_validate (title, -1, NULL) : FALSE;
657
}
658
659
static void
660
totem_pl_parser_add_one_url (TotemPlParser *parser, const char *url, const char *title)
661
{
662
	g_signal_emit (G_OBJECT (parser), totem_pl_parser_table_signals[ENTRY],
663
		       0, url,
664
		       totem_pl_parser_check_utf8 (title) ? title : NULL,
665
		       NULL);
666
}
667
668
static void
669
totem_pl_parser_add_one_url_ext (TotemPlParser *parser, const char *url,
670
		const char *title, const char *genre)
671
{
672
	g_signal_emit (G_OBJECT (parser), totem_pl_parser_table_signals[ENTRY],
673
		       0, url,
674
		       totem_pl_parser_check_utf8 (title) ? title : NULL,
675
		       genre);
676
}
677
678
static TotemPlParserResult
679
totem_pl_parser_add_ram (TotemPlParser *parser, const char *url, gpointer data)
680
{
681
	gboolean retval = TOTEM_PL_PARSER_RESULT_UNHANDLED;
682
	char *contents, **lines;
683
	int size, i;
684
	const char *split_char;
685
686
	if (gnome_vfs_read_entire_file (url, &size, &contents) != GNOME_VFS_OK)
687
		return TOTEM_PL_PARSER_RESULT_ERROR;
688
689
	/* figure out whether we're a unix or dos RAM file */
690
	if (strstr(contents,"\x0d") == NULL)
691
		split_char = "\n";
692
	else
693
		split_char = "\x0d\n";
694
695
	lines = g_strsplit (contents, split_char, 0);
696
	g_free (contents);
697
698
	for (i = 0; lines[i] != NULL; i++) {
699
		if (strcmp (lines[i], "") == 0)
700
			continue;
701
702
		retval = TOTEM_PL_PARSER_RESULT_SUCCESS;
703
704
		/* Either it's a URI, or it has a proper path ... */
705
		if (strstr(lines[i], "://") != NULL
706
				|| lines[i][0] == G_DIR_SEPARATOR) {
707
			/* .ram files can contain .smil entries */
708
			if (totem_pl_parser_parse_internal (parser, lines[i]) != TOTEM_PL_PARSER_RESULT_SUCCESS)
709
			{
710
				totem_pl_parser_add_one_url (parser,
711
						lines[i], NULL);
712
			}
713
		} else if (strcmp (lines[i], "--stop--") == 0) {
714
			/* For Real Media playlists, handle the stop command */
715
			break;
716
		} else {
717
			char *fullpath, *base;
718
719
			/* Try with a base */
720
			base = totem_pl_parser_base_url (url);
721
722
			fullpath = g_strdup_printf ("%s/%s", base, lines[i]);
723
			if (totem_pl_parser_parse_internal (parser, fullpath) != TOTEM_PL_PARSER_RESULT_SUCCESS)
724
			{
725
				totem_pl_parser_add_one_url (parser, fullpath, NULL);
726
			}
727
			g_free (fullpath);
728
			g_free (base);
729
		}
730
	}
731
732
	g_strfreev (lines);
733
734
	return retval;
735
}
736
737
static const char *
738
totem_pl_parser_get_extinfo_title (gboolean extinfo, char **lines, int i)
739
{
740
	const char *retval;
741
742
	if (extinfo == FALSE || lines == NULL)
743
		return NULL;
744
745
	if (i == 0)
746
		return NULL;
747
748
	retval = strstr (lines[i-1], "#EXTINF:");
749
	retval = strstr (retval, ",");
750
	if (retval == NULL || retval[0] == '\0')
751
		return NULL;
752
753
	retval++;
754
755
	return retval;
756
}
757
758
static TotemPlParserResult
759
totem_pl_parser_add_m3u (TotemPlParser *parser, const char *url, gpointer data)
760
{
761
	gboolean retval = TOTEM_PL_PARSER_RESULT_UNHANDLED;
762
	char *contents, **lines;
763
	int size, i;
764
	const char *split_char;
765
	gboolean extinfo;
766
767
	if (gnome_vfs_read_entire_file (url, &size, &contents) != GNOME_VFS_OK)
768
		return FALSE;
769
770
	/* is TRUE if there's an EXTINF on the previous line */
771
	extinfo = FALSE;
772
773
	/* figure out whether we're a unix m3u or dos m3u */
774
	if (strstr(contents,"\x0d") == NULL)
775
		split_char = "\n";
776
	else
777
		split_char = "\x0d\n";
778
779
	lines = g_strsplit (contents, split_char, 0);
780
	g_free (contents);
781
782
	for (i = 0; lines[i] != NULL; i++) {
783
		if (lines[i][0] == '\0')
784
			continue;
785
786
		retval = TOTEM_PL_PARSER_RESULT_SUCCESS;
787
788
		/* Ignore comments, but mark it if we have extra info */
789
		if (lines[i][0] == '#') {
790
			if (strstr (lines[i], "#EXTINF") != NULL)
791
				extinfo = TRUE;
792
			continue;
793
		}
794
795
		/* Either it's a URI, or it has a proper path ... */
796
		if (strstr(lines[i], "://") != NULL
797
				|| lines[i][0] == G_DIR_SEPARATOR) {
798
			totem_pl_parser_add_one_url (parser, lines[i],
799
					totem_pl_parser_get_extinfo_title (extinfo, lines, i));
800
			extinfo = FALSE;
801
		} else if (lines[i][0] == '\\' && lines[i][1] == '\\') {
802
			/* ... Or it's in the windows smb form
803
			 * (\\machine\share\filename), Note drive names
804
			 * (C:\ D:\ etc) are unhandled (unknown base for
805
			 * drive letters) */
806
		        char *tmpurl;
807
808
			lines[i] = g_strdelimit (lines[i], "\\", '/');
809
			tmpurl = g_strjoin (NULL, "smb:", lines[i], NULL);
810
811
			totem_pl_parser_add_one_url (parser, lines[i],
812
					totem_pl_parser_get_extinfo_title (extinfo, lines, i));
813
			extinfo = FALSE;
814
815
			g_free (tmpurl);
816
		} else {
817
			/* Try with a base */
818
			char *fullpath, *base, sep;
819
820
			base = totem_pl_parser_base_url (url);
821
			sep = (split_char[0] == '\n' ? '/' : '\\');
822
			if (sep == '\\')
823
				lines[i] = g_strdelimit (lines[i], "\\", '/');
824
			fullpath = g_strdup_printf ("%s/%s", base, lines[i]);
825
			totem_pl_parser_add_one_url (parser, fullpath,
826
					totem_pl_parser_get_extinfo_title (extinfo, lines, i));
827
			g_free (fullpath);
828
			g_free (base);
829
			extinfo = FALSE;
830
		}
831
	}
832
833
	g_strfreev (lines);
834
835
	return retval;
836
}
837
838
static TotemPlParserResult
839
totem_pl_parser_add_asf_reference_parser (TotemPlParser *parser,
840
		const char *url, gpointer data)
841
{
842
	gboolean retval = TOTEM_PL_PARSER_RESULT_UNHANDLED;
843
	char *contents, **lines, *ref, *split_char;
844
	int size;
845
846
	if (gnome_vfs_read_entire_file (url, &size, &contents) != GNOME_VFS_OK)
847
		return TOTEM_PL_PARSER_RESULT_ERROR;
848
849
	if (strstr(contents,"\x0d") == NULL) {
850
		split_char = "\n";
851
	} else {
852
		split_char = "\x0d\n";
853
	}
854
855
	lines = g_strsplit (contents, split_char, 0);
856
	g_free (contents);
857
858
	ref = read_ini_line_string (lines, "Ref1", FALSE);
859
860
	if (ref == NULL) {
861
		g_strfreev (lines);
862
		return totem_pl_parser_add_asx (parser, url, data);
863
	}
864
865
	/* change http to mmsh, thanks Microsoft */
866
	if (g_str_has_prefix (ref, "http") != FALSE)
867
		memcpy(ref, "mmsh", 4);
868
869
	totem_pl_parser_add_one_url (parser, ref, NULL);
870
	retval = TOTEM_PL_PARSER_RESULT_SUCCESS;
871
	g_free (ref);
872
873
	g_strfreev (lines);
874
875
	return retval;
876
}
877
878
static TotemPlParserResult
879
totem_pl_parser_add_asf_parser (TotemPlParser *parser,
880
		const char *url, gpointer data)
881
{
882
	gboolean retval = TOTEM_PL_PARSER_RESULT_UNHANDLED;
883
	char *contents, *ref;
884
	int size;
885
886
	if (g_str_has_prefix (data, "ASF ") == FALSE) {
887
		return totem_pl_parser_add_asf_reference_parser (parser, url, data);
888
	}
889
890
	if (gnome_vfs_read_entire_file (url, &size, &contents) != GNOME_VFS_OK)
891
		return TOTEM_PL_PARSER_RESULT_ERROR;
892
893
	if (size <= 4) {
894
		g_free (contents);
895
		return TOTEM_PL_PARSER_RESULT_ERROR;
896
	}
897
898
	/* Skip 'ASF ' */
899
	ref = contents + 4;
900
	if (g_str_has_prefix (ref, "http") != FALSE) {
901
		memcpy(ref, "mmsh", 4);
902
		totem_pl_parser_add_one_url (parser, ref, NULL);
903
		retval = TOTEM_PL_PARSER_RESULT_SUCCESS;
904
	}
905
906
	g_free (contents);
907
	return retval;
908
}
909
910
static TotemPlParserResult
911
totem_pl_parser_add_pls (TotemPlParser *parser, const char *url, gpointer data)
912
{
913
	gboolean retval = TOTEM_PL_PARSER_RESULT_UNHANDLED;
914
	char *contents, **lines;
915
	int size, i, num_entries;
916
	char *split_char, *playlist_title;
917
	gboolean dos_mode = FALSE;
918
919
	if (gnome_vfs_read_entire_file (url, &size, &contents) != GNOME_VFS_OK)
920
		return TOTEM_PL_PARSER_RESULT_ERROR;
921
922
	if (size == 0)
923
	{
924
		g_free (contents);
925
		return TOTEM_PL_PARSER_RESULT_SUCCESS;
926
	}
927
928
	/* figure out whether we're a unix pls or dos pls */
929
	if (strstr(contents,"\x0d") == NULL) {
930
		split_char = "\n";
931
	} else {
932
		split_char = "\x0d\n";
933
		dos_mode = TRUE;
934
	}
935
	lines = g_strsplit (contents, split_char, 0);
936
	g_free (contents);
937
938
	/* [playlist] */
939
	i = 0;
940
	playlist_title = NULL;
941
942
	/* Ignore empty lines */
943
	while (lines[i] != NULL && strcmp (lines[i], "") == 0)
944
		i++;
945
946
	if (lines[i] == NULL
947
			|| g_ascii_strncasecmp (lines[i], "[playlist]",
948
				(gsize)strlen ("[playlist]")) != 0)
949
		goto bail;
950
951
	playlist_title = read_ini_line_string (lines,
952
			"X-GNOME-Title", dos_mode);
953
954
	if (playlist_title != NULL) {
955
		g_signal_emit (G_OBJECT (parser),
956
				totem_pl_parser_table_signals[PLAYLIST_START],
957
				0, playlist_title);
958
	}
959
960
	/* numberofentries=? */
961
	num_entries = read_ini_line_int (lines, "numberofentries");
962
	if (num_entries == -1)
963
		goto bail;
964
965
	retval = TOTEM_PL_PARSER_RESULT_SUCCESS;
966
967
	for (i = 1; i <= num_entries; i++) {
968
		char *file, *title, *genre;
969
		char *file_key, *title_key, *genre_key;
970
971
		file_key = g_strdup_printf ("file%d", i);
972
		title_key = g_strdup_printf ("title%d", i);
973
		/* Genre is our own little extension */
974
		genre_key = g_strdup_printf ("genre%d", i);
975
976
		file = read_ini_line_string (lines, (const char*)file_key, dos_mode);
977
		title = read_ini_line_string (lines, (const char*)title_key, dos_mode);
978
		genre = read_ini_line_string (lines, (const char*)genre_key, dos_mode);
979
980
		g_free (file_key);
981
		g_free (title_key);
982
		g_free (genre_key);
983
984
		if (file == NULL)
985
		{
986
			g_free (file);
987
			g_free (title);
988
			g_free (genre);
989
			continue;
990
		}
991
992
		if (strstr (file, "://") != NULL
993
				|| file[0] == G_DIR_SEPARATOR) {
994
			totem_pl_parser_add_one_url_ext (parser,
995
					file, title, genre);
996
		} else {
997
			char *uri, *base, *escaped;
998
999
			/* Try with a base */
1000
			base = totem_pl_parser_base_url (url);
1001
			escaped = gnome_vfs_escape_path_string (file);
1002
1003
			uri = g_strdup_printf ("%s/%s", base, escaped);
1004
1005
			totem_pl_parser_add_one_url_ext (parser,
1006
					uri, title, genre);
1007
1008
			g_free (escaped);
1009
			g_free (uri);
1010
			g_free (base);
1011
		}
1012
1013
		g_free (file);
1014
		g_free (title);
1015
		g_free (genre);
1016
	}
1017
1018
	if (playlist_title != NULL) {
1019
		g_signal_emit (G_OBJECT (parser),
1020
				totem_pl_parser_table_signals[PLAYLIST_END],
1021
				0, playlist_title);
1022
	}
1023
1024
bail:
1025
	g_free (playlist_title);
1026
	g_strfreev (lines);
1027
1028
	return retval;
1029
}
1030
1031
static gboolean
1032
parse_asx_entry (TotemPlParser *parser, char *base, xmlDocPtr doc,
1033
		xmlNodePtr parent, const char *pl_title)
1034
{
1035
	xmlNodePtr node;
1036
	guchar *title, *url;
1037
	gboolean retval = FALSE;
1038
	char *fullpath = NULL;
1039
1040
	title = NULL;
1041
	url = NULL;
1042
1043
	for (node = parent->children; node != NULL; node = node->next) {
1044
		if (node->name == NULL)
1045
			continue;
1046
1047
		/* ENTRY should only have one ref and one title nodes */
1048
		if (g_ascii_strcasecmp ((char *)node->name, "ref") == 0
1049
				|| g_ascii_strcasecmp ((char *)node->name, "entryref") == 0) {
1050
			url = xmlGetProp (node, (guchar *)"href");
1051
			if (url == NULL)
1052
				url = xmlGetProp (node, (guchar *)"HREF");
1053
			continue;
1054
		}
1055
1056
		if (g_ascii_strcasecmp ((char *)node->name, "title") == 0)
1057
			title = xmlNodeListGetString(doc, node->children, 1);
1058
	}
1059
1060
	if (url == NULL) {
1061
		g_free (title);
1062
		return FALSE;
1063
	}
1064
1065
	if (strstr ((char *)url, "://") == NULL && url[0] != '/') {
1066
		fullpath = g_strdup_printf ("%s/%s", base, url);
1067
	} else {
1068
		fullpath = g_strdup ((char *)url);
1069
	}
1070
1071
	/* .asx files can contain references to other .asx files */
1072
	if (totem_pl_parser_parse_internal (parser, fullpath) != TOTEM_PL_PARSER_RESULT_SUCCESS) {
1073
		totem_pl_parser_add_one_url (parser, fullpath,
1074
				(char *)title ? (char *)title : pl_title);
1075
	}
1076
1077
	g_free (fullpath);
1078
	g_free (title);
1079
	g_free (url);
1080
1081
	return retval;
1082
}
1083
1084
static gboolean
1085
parse_asx_entries (TotemPlParser *parser, char *base, xmlDocPtr doc,
1086
		xmlNodePtr parent)
1087
{
1088
	guchar *title = NULL;
1089
	xmlNodePtr node;
1090
	gboolean retval = FALSE;
1091
1092
	for (node = parent->children; node != NULL; node = node->next) {
1093
		if (node->name == NULL)
1094
			continue;
1095
1096
		if (g_ascii_strcasecmp ((char *)node->name, "title") == 0) {
1097
			title = xmlNodeListGetString(doc, node->children, 1);
1098
		}
1099
1100
		if (g_ascii_strcasecmp ((char *)node->name, "entry") == 0) {
1101
			/* Whee found an entry here, find the REF and TITLE */
1102
			if (parse_asx_entry (parser, base, doc, node, (char *)title) != FALSE)
1103
				retval = TRUE;
1104
		}
1105
		if (g_ascii_strcasecmp ((char *)node->name, "entryref") == 0) {
1106
			/* Found an entryref, give the parent instead of the
1107
			 * children to the parser */
1108
			if (parse_asx_entry (parser, base, doc, parent, (char *)title) != FALSE)
1109
				retval = TRUE;
1110
		}
1111
		if (g_ascii_strcasecmp ((char *)node->name, "repeat") == 0) {
1112
			/* Repeat at the top-level */
1113
			if (parse_asx_entries (parser, base, doc, node) != FALSE)
1114
				retval = TRUE;
1115
		}
1116
	}
1117
1118
	g_free (title);
1119
1120
	return retval;
1121
}
1122
1123
static TotemPlParserResult
1124
totem_pl_parser_add_asx (TotemPlParser *parser, const char *url, gpointer data)
1125
{
1126
	xmlDocPtr doc;
1127
	xmlNodePtr node;
1128
	char *contents = NULL, *base;
1129
	int size;
1130
	gboolean retval = TOTEM_PL_PARSER_RESULT_UNHANDLED;
1131
1132
	if (gnome_vfs_read_entire_file (url, &size, &contents) != GNOME_VFS_OK)
1133
		return FALSE;
1134
1135
	doc = xmlParseMemory (contents, size);
1136
	if (doc == NULL)
1137
		doc = xmlRecoverMemory (contents, size);
1138
	g_free (contents);
1139
1140
	/* If the document has no root, or no name */
1141
	if(!doc || !doc->children || !doc->children->name) {
1142
		if (doc != NULL)
1143
			xmlFreeDoc(doc);
1144
		return TOTEM_PL_PARSER_RESULT_ERROR;
1145
	}
1146
1147
	base = totem_pl_parser_base_url (url);
1148
1149
	for (node = doc->children; node != NULL; node = node->next)
1150
		if (parse_asx_entries (parser, base, doc, node) != FALSE)
1151
			retval = TOTEM_PL_PARSER_RESULT_SUCCESS;
1152
1153
	g_free (base);
1154
	xmlFreeDoc(doc);
1155
	return retval;
1156
}
1157
1158
static TotemPlParserResult
1159
totem_pl_parser_add_ra (TotemPlParser *parser, const char *url, gpointer data)
1160
{
1161
	if (data == NULL
1162
			|| (g_str_has_prefix (data, "http://") == FALSE
1163
			&& g_str_has_prefix (data, "rtsp://") == FALSE
1164
			&& g_str_has_prefix (data, "pnm://") == FALSE)) {
1165
		totem_pl_parser_add_one_url (parser, url, NULL);
1166
		return TOTEM_PL_PARSER_RESULT_SUCCESS;
1167
	}
1168
1169
	return totem_pl_parser_add_ram (parser, url, NULL);
1170
}
1171
1172
static gboolean
1173
parse_smil_video_entry (TotemPlParser *parser, char *base,
1174
		char *url, char *title)
1175
{
1176
	if (strstr (url, "://") != NULL || url[0] == '/') {
1177
		totem_pl_parser_add_one_url (parser, url, title);
1178
	} else {
1179
		char *fullpath;
1180
1181
		fullpath = g_strdup_printf ("%s/%s", base, url);
1182
		totem_pl_parser_add_one_url (parser, fullpath, title);
1183
1184
		g_free (fullpath);
1185
	}
1186
1187
	return TRUE;
1188
}
1189
1190
static gboolean
1191
parse_smil_entry (TotemPlParser *parser, char *base, xmlDocPtr doc,
1192
		xmlNodePtr parent)
1193
{
1194
	xmlNodePtr node;
1195
	guchar *title, *url;
1196
	gboolean retval = FALSE;
1197
1198
	title = NULL;
1199
	url = NULL;
1200
1201
	for (node = parent->children; node != NULL; node = node->next)
1202
	{
1203
		if (node->name == NULL)
1204
			continue;
1205
1206
		/* ENTRY should only have one ref and one title nodes */
1207
		if (g_ascii_strcasecmp ((char *)node->name, "video") == 0) {
1208
			url = xmlGetProp (node, (guchar *)"src");
1209
			title = xmlGetProp (node, (guchar *)"title");
1210
1211
			if (url != NULL) {
1212
				if (parse_smil_video_entry (parser,
1213
						base, (char *)url, (char *)title) != FALSE)
1214
					retval = TRUE;
1215
			}
1216
1217
			g_free (title);
1218
			g_free (url);
1219
		} else {
1220
			if (parse_smil_entry (parser,
1221
						base, doc, node) != FALSE)
1222
				retval = TRUE;
1223
		}
1224
	}
1225
1226
	return retval;
1227
}
1228
1229
static gboolean
1230
parse_smil_entries (TotemPlParser *parser, char *base, xmlDocPtr doc,
1231
		xmlNodePtr parent)
1232
{
1233
	xmlNodePtr node;
1234
	gboolean retval = FALSE;
1235
1236
	for (node = parent->children; node != NULL; node = node->next) {
1237
		if (node->name == NULL)
1238
			continue;
1239
1240
		if (g_ascii_strcasecmp ((char *)node->name, "body") == 0) {
1241
			if (parse_smil_entry (parser, base,
1242
						doc, node) != FALSE)
1243
				retval = TRUE;
1244
		}
1245
1246
	}
1247
1248
	return retval;
1249
}
1250
1251
static TotemPlParserResult
1252
totem_pl_parser_add_smil (TotemPlParser *parser, const char *url, gpointer data)
1253
{
1254
	xmlDocPtr doc;
1255
	xmlNodePtr node;
1256
	char *contents = NULL, *base;
1257
	int size;
1258
	gboolean retval = TOTEM_PL_PARSER_RESULT_UNHANDLED;
1259
1260
	if (gnome_vfs_read_entire_file (url, &size, &contents) != GNOME_VFS_OK)
1261
		return TOTEM_PL_PARSER_RESULT_ERROR;
1262
1263
	doc = xmlParseMemory (contents, size);
1264
	if (doc == NULL)
1265
		doc = xmlRecoverMemory (contents, size);
1266
	g_free (contents);
1267
1268
	/* If the document has no root, or no name */
1269
	if(!doc || !doc->children
1270
			|| !doc->children->name
1271
			|| g_ascii_strcasecmp ((char *)doc->children->name,
1272
				"smil") != 0) {
1273
		if (doc != NULL)
1274
			xmlFreeDoc (doc);
1275
		return TOTEM_PL_PARSER_RESULT_ERROR;
1276
	}
1277
1278
	base = totem_pl_parser_base_url (url);
1279
1280
	for (node = doc->children; node != NULL; node = node->next)
1281
		if (parse_smil_entries (parser, base, doc, node) != FALSE)
1282
			retval = TOTEM_PL_PARSER_RESULT_SUCCESS;
1283
1284
	g_free (base);
1285
	xmlFreeDoc (doc);
1286
1287
	return retval;
1288
}
1289
1290
static TotemPlParserResult
1291
totem_pl_parser_add_asf (TotemPlParser *parser, const char *url, gpointer data)
1292
{
1293
	if (data != NULL &&
1294
		(g_str_has_prefix (data, "[Reference]") == FALSE
1295
		 && g_ascii_strncasecmp (data, "<ASX", strlen ("<ASX")) != 0
1296
		 && strstr (data, "<ASX") == NULL)
1297
		 && g_str_has_prefix (data, "ASF ") == FALSE) {
1298
		totem_pl_parser_add_one_url (parser, url, NULL);
1299
		return TOTEM_PL_PARSER_RESULT_SUCCESS;
1300
	}
1301
1302
	return totem_pl_parser_add_asf_parser (parser, url, data);
1303
}
1304
1305
static TotemPlParserResult
1306
totem_pl_parser_add_desktop (TotemPlParser *parser, const char *url, gpointer data)
1307
{
1308
	char *contents, **lines;
1309
	const char *path, *display_name, *type;
1310
	int size;
1311
1312
	if (gnome_vfs_read_entire_file (url, &size, &contents) != GNOME_VFS_OK)
1313
		return TOTEM_PL_PARSER_RESULT_ERROR;
1314
1315
	lines = g_strsplit (contents, "\n", 0);
1316
	g_free (contents);
1317
1318
	type = read_ini_line_string (lines, "Type", FALSE);
1319
	if (type == NULL || g_ascii_strcasecmp (type, "Link") != 0) {
1320
		g_strfreev (lines);
1321
		return TOTEM_PL_PARSER_RESULT_ERROR;
1322
	}
1323
1324
	path = read_ini_line_string (lines, "URL", FALSE);
1325
	if (path == NULL) {
1326
		g_strfreev (lines);
1327
		return TOTEM_PL_PARSER_RESULT_ERROR;
1328
	}
1329
1330
	display_name = read_ini_line_string (lines, "Name", FALSE);
1331
1332
	if (totem_pl_parser_ignore (parser, path) == FALSE) {
1333
		totem_pl_parser_add_one_url (parser, path, display_name);
1334
	} else {
1335
		if (totem_pl_parser_parse_internal (parser, path) != TOTEM_PL_PARSER_RESULT_SUCCESS)
1336
			totem_pl_parser_add_one_url (parser, path, display_name);
1337
	}
1338
1339
	g_strfreev (lines);
1340
1341
	return TOTEM_PL_PARSER_RESULT_SUCCESS;
1342
}
1343
1344
static int
1345
totem_pl_parser_dir_compare (GnomeVFSFileInfo *a, GnomeVFSFileInfo *b)
1346
{
1347
	if (a->name == NULL) {
1348
		if (b->name == NULL)
1349
			return 0;
1350
		else
1351
			return -1;
1352
	} else {
1353
		if (b->name == NULL)
1354
			return 1;
1355
		else
1356
			return strcmp (a->name, b->name);
1357
	}
1358
}
1359
1360
static TotemPlParserResult
1361
totem_pl_parser_add_directory (TotemPlParser *parser, const char *url,
1362
			   gpointer data)
1363
{
1364
	MediaType type;
1365
	GList *list, *l;
1366
	GnomeVFSResult res;
1367
1368
	if (parser->priv->recurse_level == 1) {
1369
		char *media_url;
1370
1371
		type = totem_cd_detect_type_from_dir (url, &media_url, NULL);
1372
		if (type != MEDIA_TYPE_DATA && type != MEDIA_TYPE_ERROR) {
1373
			if (media_url != NULL) {
1374
				totem_pl_parser_add_one_url (parser, media_url, NULL);
1375
				g_free (media_url);
1376
				return TOTEM_PL_PARSER_RESULT_SUCCESS;
1377
			}
1378
		}
1379
	}
1380
1381
	res = gnome_vfs_directory_list_load (&list, url,
1382
			GNOME_VFS_FILE_INFO_DEFAULT);
1383
	if (res != GNOME_VFS_OK)
1384
		return TOTEM_PL_PARSER_RESULT_ERROR;
1385
1386
	list = g_list_sort (list, (GCompareFunc) totem_pl_parser_dir_compare);
1387
	l = list;
1388
1389
	while (l != NULL) {
1390
		char *name, *fullpath;
1391
		GnomeVFSFileInfo *info = l->data;
1392
		TotemPlParserResult ret;
1393
1394
		if (info->name != NULL && (strcmp (info->name, ".") == 0
1395
					|| strcmp (info->name, "..") == 0)) {
1396
			l = l->next;
1397
			continue;
1398
		}
1399
1400
		name = gnome_vfs_escape_string (info->name);
1401
		fullpath = g_strconcat (url, "/", name, NULL);
1402
		g_free (name);
1403
1404
		ret = totem_pl_parser_parse_internal (parser, fullpath);
1405
		if (ret != TOTEM_PL_PARSER_RESULT_SUCCESS && ret != TOTEM_PL_PARSER_RESULT_IGNORED)
1406
			totem_pl_parser_add_one_url (parser, fullpath, NULL);
1407
1408
		l = l->next;
1409
	}
1410
1411
	g_list_foreach (list, (GFunc) gnome_vfs_file_info_unref, NULL);
1412
	g_list_free (list);
1413
1414
	return TOTEM_PL_PARSER_RESULT_SUCCESS;
1415
}
1416
1417
/* These ones need a special treatment, mostly parser formats */
1418
static PlaylistTypes special_types[] = {
1419
	{ "audio/x-mpegurl", totem_pl_parser_add_m3u },
1420
	{ "audio/playlist", totem_pl_parser_add_m3u },
1421
	{ "audio/x-ms-asx", totem_pl_parser_add_asx },
1422
	{ "audio/x-scpls", totem_pl_parser_add_pls },
1423
	{ "application/x-smil", totem_pl_parser_add_smil },
1424
	{ "application/x-gnome-app-info", totem_pl_parser_add_desktop },
1425
	{ "application/x-desktop", totem_pl_parser_add_desktop },
1426
	{ "x-directory/normal", totem_pl_parser_add_directory },
1427
	{ "video/x-ms-wvx", totem_pl_parser_add_asx },
1428
	{ "audio/x-ms-wax", totem_pl_parser_add_asx },
1429
};
1430
1431
static PlaylistTypes ignore_types[] = {
1432
	{ "image/*", NULL },
1433
	{ "text/plain", NULL },
1434
	{ "application/x-rar", NULL },
1435
	{ "application/zip", NULL },
1436
};
1437
1438
/* These ones are "dual" types, might be a video, might be a parser */
1439
static PlaylistTypes dual_types[] = {
1440
	{ "audio/x-real-audio", totem_pl_parser_add_ra },
1441
	{ "audio/x-pn-realaudio", totem_pl_parser_add_ra },
1442
	{ "application/vnd.rn-realmedia", totem_pl_parser_add_ra },
1443
	{ "audio/x-pn-realaudio-plugin", totem_pl_parser_add_ra },
1444
	{ "text/plain", totem_pl_parser_add_ra },
1445
	{ "video/x-ms-asf", totem_pl_parser_add_asf },
1446
	{ "video/x-ms-wmv", totem_pl_parser_add_asf },
1447
};
1448
1449
static gboolean
1450
totem_pl_parser_scheme_is_ignored (TotemPlParser *parser, const char *url)
1451
{
1452
	GList *l;
1453
1454
	if (parser->priv->ignore_schemes == NULL)
1455
		return FALSE;
1456
1457
	for (l = parser->priv->ignore_schemes; l != NULL; l = l->next)
1458
	{
1459
		const char *scheme = l->data;
1460
		if (g_str_has_prefix (url, scheme) != FALSE)
1461
			return TRUE;
1462
	}
1463
1464
	return FALSE;
1465
}
1466
1467
static gboolean
1468
totem_pl_parser_mimetype_is_ignored (TotemPlParser *parser,
1469
				     const char *mimetype)
1470
{
1471
	GList *l;
1472
1473
	if (parser->priv->ignore_mimetypes == NULL)
1474
		return FALSE;
1475
1476
	for (l = parser->priv->ignore_mimetypes; l != NULL; l = l->next)
1477
	{
1478
		const char *item = l->data;
1479
		if (strcmp (mimetype, item) == 0)
1480
			return TRUE;
1481
	}
1482
1483
	return FALSE;
1484
1485
}
1486
1487
static gboolean
1488
totem_pl_parser_ignore (TotemPlParser *parser, const char *url)
1489
{
1490
	const char *mimetype;
1491
	guint i;
1492
1493
	if (totem_pl_parser_scheme_is_ignored (parser, url) != FALSE)
1494
		return TRUE;
1495
1496
	mimetype = gnome_vfs_get_file_mime_type (url, NULL, TRUE);
1497
	if (mimetype == NULL || strcmp (mimetype, "application/octet-stream") == 0)
1498
		return FALSE;
1499
1500
	for (i = 0; i < G_N_ELEMENTS (special_types); i++)
1501
		if (strcmp (special_types[i].mimetype, mimetype) == 0)
1502
			return FALSE;
1503
1504
	for (i = 0; i < G_N_ELEMENTS (dual_types); i++)
1505
		if (strcmp (dual_types[i].mimetype, mimetype) == 0)
1506
			return FALSE;
1507
1508
	/* It's a remote file that could be an m3u file */
1509
	if (strcmp (mimetype, "audio/x-mp3") == 0)
1510
	{
1511
		if (strstr (url, "m3u") != NULL)
1512
			return FALSE;
1513
	}
1514
1515
	return TRUE;
1516
}
1517
1518
static TotemPlParserResult
1519
totem_pl_parser_parse_internal (TotemPlParser *parser, const char *url)
1520
{
1521
	const char *mimetype;
1522
	guint i;
1523
	gpointer data = NULL;
1524
	gboolean ret = FALSE;
1525
	char *super;
1526
1527
	if (parser->priv->recurse_level > RECURSE_LEVEL_MAX)
1528
		return TOTEM_PL_PARSER_RESULT_ERROR;
1529
1530
	mimetype = gnome_vfs_get_mime_type (url);
1531
	if (!mimetype)
1532
		mimetype = my_gnome_vfs_get_mime_type_with_data (url, &data);
1533
1534
	if (mimetype == NULL)
1535
		return TOTEM_PL_PARSER_RESULT_UNHANDLED;
1536
1537
	if (totem_pl_parser_mimetype_is_ignored (parser, mimetype) != FALSE) {
1538
		g_free (data);
1539
		return TOTEM_PL_PARSER_RESULT_IGNORED;
1540
	}
1541
1542
	super = gnome_vfs_get_supertype_from_mime_type (mimetype);
1543
	for (i = 0; i < G_N_ELEMENTS (ignore_types); i++) {
1544
		if (gnome_vfs_mime_type_is_supertype (ignore_types[i].mimetype) != FALSE) {
1545
			if (strcmp (super, ignore_types[i].mimetype) == 0) {
1546
				g_free (data);
1547
				g_free (super);
1548
				return TOTEM_PL_PARSER_RESULT_IGNORED;
1549
			}
1550
		} else {
1551
			GnomeVFSMimeEquivalence eq;
1552
1553
			eq = gnome_vfs_mime_type_get_equivalence (mimetype, ignore_types[i].mimetype);
1554
			if (eq == GNOME_VFS_MIME_PARENT || eq == GNOME_VFS_MIME_IDENTICAL) {
1555
				g_free (data);
1556
				return TOTEM_PL_PARSER_RESULT_IGNORED;
1557
			}
1558
		}
1559
	}
1560
1561
	parser->priv->recurse_level++;
1562
1563
	for (i = 0; i < G_N_ELEMENTS(special_types); i++) {
1564
		if (strcmp (special_types[i].mimetype, mimetype) == 0) {
1565
			ret = (* special_types[i].func) (parser, url, data);
1566
			g_free (data);
1567
			break;
1568
		}
1569
	}
1570
1571
	for (i = 0; i < G_N_ELEMENTS(dual_types); i++) {
1572
		if (strcmp (dual_types[i].mimetype, mimetype) == 0) {
1573
			if (data == NULL) {
1574
				mimetype = my_gnome_vfs_get_mime_type_with_data (url, &data);
1575
			}
1576
			ret = (* dual_types[i].func) (parser, url, data);
1577
			g_free (data);
1578
			break;
1579
		}
1580
	}
1581
1582
	parser->priv->recurse_level--;
1583
1584
	if (ret == FALSE && parser->priv->fallback) {
1585
		totem_pl_parser_add_one_url (parser, url, NULL);
1586
		return TOTEM_PL_PARSER_RESULT_SUCCESS;
1587
	}
1588
1589
	if (ret)
1590
		return TOTEM_PL_PARSER_RESULT_SUCCESS;
1591
	else
1592
		return TOTEM_PL_PARSER_RESULT_UNHANDLED;
1593
}
1594
1595
TotemPlParserResult
1596
totem_pl_parser_parse (TotemPlParser *parser, const char *url,
1597
		       gboolean fallback)
1598
{
1599
	g_return_val_if_fail (TOTEM_IS_PL_PARSER (parser), TOTEM_PL_PARSER_RESULT_UNHANDLED);
1600
	g_return_val_if_fail (url != NULL, TOTEM_PL_PARSER_RESULT_UNHANDLED);
1601
1602
	if (totem_pl_parser_scheme_is_ignored (parser, url) != FALSE)
1603
		return TOTEM_PL_PARSER_RESULT_UNHANDLED;
1604
1605
	g_return_val_if_fail (strstr (url, "://") != NULL,
1606
			TOTEM_PL_PARSER_RESULT_IGNORED);
1607
1608
	parser->priv->recurse_level = 0;
1609
	parser->priv->fallback = fallback;
1610
	return totem_pl_parser_parse_internal (parser, url);
1611
}
1612
1613
void
1614
totem_pl_parser_add_ignored_scheme (TotemPlParser *parser,
1615
		const char *scheme)
1616
{
1617
	g_return_if_fail (TOTEM_IS_PL_PARSER (parser));
1618
1619
	parser->priv->ignore_schemes = g_list_prepend
1620
		(parser->priv->ignore_schemes, g_strdup (scheme));
1621
}
1622
1623
void
1624
totem_pl_parser_add_ignored_mimetype (TotemPlParser *parser,
1625
		const char *mimetype)
1626
{
1627
	g_return_if_fail (TOTEM_IS_PL_PARSER (parser));
1628
1629
	parser->priv->ignore_mimetypes = g_list_prepend
1630
		(parser->priv->ignore_mimetypes, g_strdup (mimetype));
1631
}
1632
(-)rhythmbox-0.9.2.orig/plparse/totem-pl-parser.h (+115 lines)
Line 0 Link Here
1
/* 
2
   arch-tag: Header for Rhythmbox playlist parser
3
4
   Copyright (C) 2002, 2003 Bastien Nocera <hadess@hadess.net>
5
   Copyright (C) 2003 Colin Walters <walters@verbum.org>
6
7
   The Gnome Library is free software; you can redistribute it and/or
8
   modify it under the terms of the GNU Library General Public License as
9
   published by the Free Software Foundation; either version 2 of the
10
   License, or (at your option) any later version.
11
12
   The Gnome Library is distributed in the hope that it will be useful,
13
   but WITHOUT ANY WARRANTY; without even the implied warranty of
14
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15
   Library General Public License for more details.
16
17
   You should have received a copy of the GNU Library General Public
18
   License along with the Gnome Library; see the file COPYING.LIB.  If not,
19
   write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
20
   Boston, MA 02111-1307, USA.
21
22
   Author: Bastien Nocera <hadess@hadess.net>
23
 */
24
25
#ifndef TOTEM_PL_PARSER_H
26
#define TOTEM_PL_PARSER_H
27
28
#include <glib.h>
29
#include <gtk/gtktreemodel.h>
30
31
#include "totem-pl-parser-builtins.h"
32
33
G_BEGIN_DECLS
34
35
#define TOTEM_TYPE_PL_PARSER            (totem_pl_parser_get_type ())
36
#define TOTEM_PL_PARSER(obj)            (G_TYPE_CHECK_INSTANCE_CAST ((obj), TOTEM_TYPE_PL_PARSER, TotemPlParser))
37
#define TOTEM_PL_PARSER_CLASS(klass)    (G_TYPE_CHECK_CLASS_CAST ((klass), TOTEM_TYPE_PL_PARSER, TotemPlParserClass))
38
#define TOTEM_IS_PL_PARSER(obj)         (G_TYPE_CHECK_INSTANCE_TYPE ((obj), TOTEM_TYPE_PL_PARSER))
39
#define TOTEM_IS_PL_PARSER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), TOTEM_TYPE_PL_PARSER))
40
41
typedef enum
42
{
43
	TOTEM_PL_PARSER_RESULT_UNHANDLED,
44
	TOTEM_PL_PARSER_RESULT_ERROR,
45
	TOTEM_PL_PARSER_RESULT_SUCCESS,
46
	TOTEM_PL_PARSER_RESULT_IGNORED
47
} TotemPlParserResult;
48
49
typedef struct TotemPlParser	       TotemPlParser;
50
typedef struct TotemPlParserClass      TotemPlParserClass;
51
typedef struct TotemPlParserPrivate    TotemPlParserPrivate;
52
53
struct TotemPlParser {
54
	GObject parent;
55
	TotemPlParserPrivate *priv;
56
};
57
58
struct TotemPlParserClass {
59
	GObjectClass parent_class;
60
61
	/* signals */
62
	void (*entry) (TotemPlParser *parser, const char *uri,
63
		       const char *title, const char *genre);
64
	void (*playlist_start) (TotemPlParser *parser, const char *title);
65
	void (*playlist_end) (TotemPlParser *parser, const char *title);
66
};
67
68
typedef enum
69
{
70
	TOTEM_PL_PARSER_PLS,
71
	TOTEM_PL_PARSER_M3U,
72
	TOTEM_PL_PARSER_M3U_DOS,
73
} TotemPlParserType;
74
75
typedef enum
76
{
77
	TOTEM_PL_PARSER_ERROR_VFS_OPEN,
78
	TOTEM_PL_PARSER_ERROR_VFS_WRITE,
79
} TotemPlParserError;
80
81
#define TOTEM_PL_PARSER_ERROR (totem_pl_parser_error_quark ())
82
83
GQuark totem_pl_parser_error_quark (void);
84
85
typedef void (*TotemPlParserIterFunc) (GtkTreeModel *model, GtkTreeIter *iter,
86
                                       char **uri, char **title, gpointer user_data);
87
88
GType    totem_pl_parser_get_type (void);
89
90
gboolean   totem_pl_parser_write (TotemPlParser *parser, GtkTreeModel *model,
91
				  TotemPlParserIterFunc func,
92
				  const char *output, TotemPlParserType type,
93
                                  gpointer user_data,
94
				  GError **error);
95
96
gboolean   totem_pl_parser_write_with_title (TotemPlParser *parser,
97
					     GtkTreeModel *model,
98
					     TotemPlParserIterFunc func,
99
					     const char *output,
100
					     const char *title,
101
					     TotemPlParserType type,
102
					     gpointer user_data,
103
					     GError **error);
104
105
void	   totem_pl_parser_add_ignored_scheme (TotemPlParser *parser,
106
					       const char *scheme);
107
void       totem_pl_parser_add_ignored_mimetype (TotemPlParser *parser,
108
						 const char *mimetype);
109
TotemPlParserResult totem_pl_parser_parse (TotemPlParser *parser, const char *url, gboolean fallback);
110
111
TotemPlParser *totem_pl_parser_new (void);
112
113
G_END_DECLS
114
115
#endif /* TOTEM_PL_PARSER_H */
(-)rhythmbox-0.9.2.orig/plparse/totemplparser-marshal.list (+1 lines)
Line 0 Link Here
1
VOID:STRING,STRING,STRING
(-)rhythmbox-0.9.2.orig/shell/Makefile.am (+1 lines)
Lines 76-81 Link Here
76
76
77
rhythmbox_LDADD =					\
77
rhythmbox_LDADD =					\
78
	librbshell.la					\
78
	librbshell.la					\
79
	$(top_builddir)/plparse/libtotem-plparser.a	        \
79
	$(top_builddir)/sources/libsources.la	        \
80
	$(top_builddir)/sources/libsources.la	        \
80
	$(top_builddir)/sources/libsourcesimpl.la	\
81
	$(top_builddir)/sources/libsourcesimpl.la	\
81
	$(top_builddir)/rhythmdb/librhythmdb.la         \
82
	$(top_builddir)/rhythmdb/librhythmdb.la         \
(-)rhythmbox-0.9.2.orig/shell/rb-playlist-manager.c (-1 / +1 lines)
Lines 36-42 Link Here
36
#include "rb-sourcelist.h"
36
#include "rb-sourcelist.h"
37
#include "rb-sourcelist-model.h"
37
#include "rb-sourcelist-model.h"
38
#include "rb-query-creator.h"
38
#include "rb-query-creator.h"
39
#include "totem-pl-parser.h"
39
#include "plparse/totem-pl-parser.h"
40
40
41
#include "rb-file-helpers.h"
41
#include "rb-file-helpers.h"
42
#include "rb-debug.h"
42
#include "rb-debug.h"
(-)rhythmbox-0.9.2.orig/shell/rb-shell-player.c (-1 / +1 lines)
Lines 49-55 Link Here
49
#include "rb-debug.h"
49
#include "rb-debug.h"
50
#include "rb-player.h"
50
#include "rb-player.h"
51
#include "rb-header.h"
51
#include "rb-header.h"
52
#include "totem-pl-parser.h"
52
#include "plparse/totem-pl-parser.h"
53
#include "rb-metadata.h"
53
#include "rb-metadata.h"
54
#include "bacon-volume.h"
54
#include "bacon-volume.h"
55
#include "rb-remote.h"
55
#include "rb-remote.h"
(-)rhythmbox-0.9.2.orig/shell/rb-shell.c (-1 / +1 lines)
Lines 67-73 Link Here
67
#include "rb-shell-preferences.h"
67
#include "rb-shell-preferences.h"
68
#include "rb-library-source.h"
68
#include "rb-library-source.h"
69
#include "rb-podcast-source.h"
69
#include "rb-podcast-source.h"
70
#include "totem-pl-parser.h"
70
#include "plparse/totem-pl-parser.h"
71
#ifdef WITH_DAAP_SUPPORT
71
#ifdef WITH_DAAP_SUPPORT
72
#include "rb-daap-source.h"
72
#include "rb-daap-source.h"
73
#include "rb-daap-sharing.h"
73
#include "rb-daap-sharing.h"
(-)rhythmbox-0.9.2.orig/sources/Makefile.am (+1 lines)
Lines 36-41 Link Here
36
	-I$(top_srcdir)/widgets 			\
36
	-I$(top_srcdir)/widgets 			\
37
	-I$(top_srcdir)/library 			\
37
	-I$(top_srcdir)/library 			\
38
	-I$(top_srcdir)/player	 			\
38
	-I$(top_srcdir)/player	 			\
39
	-I$(top_srcdir)/plparse	 			\
39
	-I$(top_srcdir)/iradio				\
40
	-I$(top_srcdir)/iradio				\
40
	-I$(top_srcdir)/podcast				\
41
	-I$(top_srcdir)/podcast				\
41
	-I$(top_srcdir)/shell				\
42
	-I$(top_srcdir)/shell				\
(-)rhythmbox-0.9.2.orig/sources/rb-iradio-source.c (-1 / +1 lines)
Lines 36-42 Link Here
36
#include "rb-property-view.h"
36
#include "rb-property-view.h"
37
#include "rb-util.h"
37
#include "rb-util.h"
38
#include "rb-file-helpers.h"
38
#include "rb-file-helpers.h"
39
#include "totem-pl-parser.h"
39
#include "plparse/totem-pl-parser.h"
40
#include "rb-preferences.h"
40
#include "rb-preferences.h"
41
#include "rb-dialog.h"
41
#include "rb-dialog.h"
42
#include "rb-station-properties-dialog.h"
42
#include "rb-station-properties-dialog.h"
(-)rhythmbox-0.9.2.orig/sources/rb-playlist-source.c (-1 / +1 lines)
Lines 25-35 Link Here
25
#include <gtk/gtk.h>
25
#include <gtk/gtk.h>
26
#include <libgnome/gnome-i18n.h>
26
#include <libgnome/gnome-i18n.h>
27
#include <libgnomevfs/gnome-vfs-uri.h>
27
#include <libgnomevfs/gnome-vfs-uri.h>
28
#include <totem-pl-parser.h>
29
#include <libxml/tree.h>
28
#include <libxml/tree.h>
30
#include <unistd.h>
29
#include <unistd.h>
31
#include <string.h>
30
#include <string.h>
32
31
32
#include "plparse/totem-pl-parser.h"
33
#include "rb-stock-icons.h"
33
#include "rb-stock-icons.h"
34
#include "rb-entry-view.h"
34
#include "rb-entry-view.h"
35
#include "rb-search-entry.h"
35
#include "rb-search-entry.h"

Return to bug 114488