diff options
80 files changed, 17 insertions, 21295 deletions
diff --git a/.gitignore b/.gitignore index da5117b773..84aabf63db 100644 --- a/.gitignore +++ b/.gitignore @@ -155,9 +155,6 @@ config.log /lib/addons/library.xbmc.pvr/project/VS2010Express/Release /lib/addons/library.xbmc.pvr/project/VS2010Express/Debug -# /lib/cmyth/ -lib/cmyth/Makefile - # /lib/cpluff/ /lib/cpluff/ABOUT-NLS /lib/cpluff/aclocal.m4 @@ -395,7 +392,6 @@ lib/cpluff/stamp-h1 # /system /system/cpluff.dll /system/ImageLib.dll -/system/libcmyth.dll /system/libcurl.dll /system/libeay32.dll /system/librtmp.dll @@ -928,14 +924,6 @@ lib/cpluff/stamp-h1 #/lib/win32/ffmpeg /lib/win32/ffmpeg/ -# /lib/cmyth/ -/lib/cmyth/Makefile.depend -/lib/cmyth/Win32/libcmyth.lib - -# /lib/cmyth/Win32 -/lib/cmyth/Win32/Debug -/lib/cmyth/Win32/Release - # lib/cximage-6.0/ /lib/cximage-6.0/Makefile /lib/cximage-6.0/Debug diff --git a/CONTRIBUTORS b/CONTRIBUTORS deleted file mode 100644 index 93457e3fc5..0000000000 --- a/CONTRIBUTORS +++ /dev/null @@ -1,10 +0,0 @@ -Joakim Plate: - filehtsp, filecurl, filevtp, filemyth, - overlayrenderer, filehdhomerun - dvdplayer, upnp, sapfile, ... - -Andreas Ă–man: - libhts - -Mattias Wadman - libhts diff --git a/Kodi.xcodeproj/project.pbxproj b/Kodi.xcodeproj/project.pbxproj index 80c885578c..8e46329f55 100644 --- a/Kodi.xcodeproj/project.pbxproj +++ b/Kodi.xcodeproj/project.pbxproj @@ -726,8 +726,6 @@ 7CF80DC919710DC2003B2B34 /* KeyboardLayout.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 7CF80DC719710DC2003B2B34 /* KeyboardLayout.cpp */; }; 7CF80DCA19710DC2003B2B34 /* KeyboardLayout.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 7CF80DC719710DC2003B2B34 /* KeyboardLayout.cpp */; }; 7CF80DCB19710DC2003B2B34 /* KeyboardLayout.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 7CF80DC719710DC2003B2B34 /* KeyboardLayout.cpp */; }; - 810C9FA90D67D1FB0095F5DD /* MythDirectory.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 810C9FA50D67D1FB0095F5DD /* MythDirectory.cpp */; }; - 810C9FAA0D67D1FB0095F5DD /* MythFile.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 810C9FA70D67D1FB0095F5DD /* MythFile.cpp */; }; 815EE6350E17F1DC009FBE3C /* DVDInputStreamRTMP.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 815EE6330E17F1DC009FBE3C /* DVDInputStreamRTMP.cpp */; }; 820023DB171A28A300667D1C /* OSXTextInputResponder.mm in Sources */ = {isa = PBXBuildFile; fileRef = 820023DA171A28A300667D1C /* OSXTextInputResponder.mm */; }; 83A72B970FBC8E3B00171871 /* LockFree.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 83A72B950FBC8E3B00171871 /* LockFree.cpp */; settings = {COMPILER_FLAGS = "-O0"; }; }; @@ -1328,9 +1326,6 @@ DFF0F22917528350002DA3A4 /* MusicDatabaseFile.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF93D67B1444A8B0007C6459 /* MusicDatabaseFile.cpp */; }; DFF0F22A17528350002DA3A4 /* MusicFileDirectory.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 880DBE530DC224A100E26B71 /* MusicFileDirectory.cpp */; }; DFF0F22B17528350002DA3A4 /* MusicSearchDirectory.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E38E17390D25F9FA00618676 /* MusicSearchDirectory.cpp */; }; - DFF0F22C17528350002DA3A4 /* MythDirectory.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 810C9FA50D67D1FB0095F5DD /* MythDirectory.cpp */; }; - DFF0F22D17528350002DA3A4 /* MythFile.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 810C9FA70D67D1FB0095F5DD /* MythFile.cpp */; }; - DFF0F22E17528350002DA3A4 /* MythSession.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E3BBB7980D7EA78A00CAAFD3 /* MythSession.cpp */; }; DFF0F22F17528350002DA3A4 /* NFSDirectory.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF0DF15913A3ADA7008ED511 /* NFSDirectory.cpp */; }; DFF0F23017528350002DA3A4 /* NFSFile.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF93D67D1444A8B0007C6459 /* NFSFile.cpp */; }; DFF0F23117528350002DA3A4 /* NptXbmcFile.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E4E91BB70E7F7338001F0546 /* NptXbmcFile.cpp */; settings = {COMPILER_FLAGS = "-I$SRCROOT/lib/libUPnP -I$SRCROOT/lib/libUPnP/Neptune/Source/Core -I$SRCROOT/lib/libUPnP/Platinum/Source/Core -I$SRCROOT/lib/libUPnP/Platinum/Source/Platinum -I$SRCROOT/lib/libUPnP/Platinum/Source/Extras -I$SRCROOT/lib/libUPnP/Platinum/Source/Devices/MediaServer -I$SRCROOT/lib/libUPnP/Platinum/Source/Devices/MediaConnect -I$SRCROOT/lib/libUPnP/Platinum/Source/Devices/MediaRenderer"; }; }; @@ -2248,7 +2243,6 @@ E3A4780A0D29029A00F3C3A6 /* GUIDialogCache.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E3A478090D29029A00F3C3A6 /* GUIDialogCache.cpp */; }; E3A4781A0D29032C00F3C3A6 /* GUIDialogAccessPoints.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E3A478190D29032C00F3C3A6 /* GUIDialogAccessPoints.cpp */; }; E3B53E7C0D97B08100021A96 /* DVDSubtitleParserMicroDVD.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E3B53E7A0D97B08100021A96 /* DVDSubtitleParserMicroDVD.cpp */; }; - E3BBB7990D7EA78A00CAAFD3 /* MythSession.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E3BBB7980D7EA78A00CAAFD3 /* MythSession.cpp */; }; E3DAAF8D0D6E1B0500F17647 /* SMBDirectory.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E3DAAF8B0D6E1B0500F17647 /* SMBDirectory.cpp */; }; E3E91FFD0D8C61DF002BF43D /* EventPacket.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E3E91FFA0D8C61DF002BF43D /* EventPacket.cpp */; }; E3E91FFE0D8C61DF002BF43D /* EventServer.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E3E91FFB0D8C61DF002BF43D /* EventServer.cpp */; }; @@ -2568,9 +2562,6 @@ E4991292174E5D9900741B6D /* MusicDatabaseFile.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF93D67B1444A8B0007C6459 /* MusicDatabaseFile.cpp */; }; E4991293174E5D9900741B6D /* MusicFileDirectory.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 880DBE530DC224A100E26B71 /* MusicFileDirectory.cpp */; }; E4991294174E5D9900741B6D /* MusicSearchDirectory.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E38E17390D25F9FA00618676 /* MusicSearchDirectory.cpp */; }; - E4991295174E5D9900741B6D /* MythDirectory.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 810C9FA50D67D1FB0095F5DD /* MythDirectory.cpp */; }; - E4991296174E5D9900741B6D /* MythFile.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 810C9FA70D67D1FB0095F5DD /* MythFile.cpp */; }; - E4991297174E5D9900741B6D /* MythSession.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E3BBB7980D7EA78A00CAAFD3 /* MythSession.cpp */; }; E4991298174E5D9900741B6D /* NFSDirectory.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF0DF15913A3ADA7008ED511 /* NFSDirectory.cpp */; }; E4991299174E5D9900741B6D /* NFSFile.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF93D67D1444A8B0007C6459 /* NFSFile.cpp */; }; E499129A174E5D9900741B6D /* NptXbmcFile.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E4E91BB70E7F7338001F0546 /* NptXbmcFile.cpp */; settings = {COMPILER_FLAGS = "-I$SRCROOT/lib/libUPnP -I$SRCROOT/lib/libUPnP/Neptune/Source/Core -I$SRCROOT/lib/libUPnP/Platinum/Source/Core -I$SRCROOT/lib/libUPnP/Platinum/Source/Platinum -I$SRCROOT/lib/libUPnP/Platinum/Source/Extras -I$SRCROOT/lib/libUPnP/Platinum/Source/Devices/MediaServer -I$SRCROOT/lib/libUPnP/Platinum/Source/Devices/MediaConnect -I$SRCROOT/lib/libUPnP/Platinum/Source/Devices/MediaRenderer"; }; }; @@ -4286,10 +4277,6 @@ 7CF34D9E1930264A00D543C5 /* AudioEncoder.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AudioEncoder.h; sourceTree = "<group>"; }; 7CF80DC719710DC2003B2B34 /* KeyboardLayout.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = KeyboardLayout.cpp; sourceTree = "<group>"; }; 7CF80DC819710DC2003B2B34 /* KeyboardLayout.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = KeyboardLayout.h; sourceTree = "<group>"; }; - 810C9FA50D67D1FB0095F5DD /* MythDirectory.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = MythDirectory.cpp; sourceTree = "<group>"; }; - 810C9FA60D67D1FB0095F5DD /* MythDirectory.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MythDirectory.h; sourceTree = "<group>"; }; - 810C9FA70D67D1FB0095F5DD /* MythFile.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = MythFile.cpp; sourceTree = "<group>"; }; - 810C9FA80D67D1FB0095F5DD /* MythFile.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MythFile.h; sourceTree = "<group>"; }; 815EE6330E17F1DC009FBE3C /* DVDInputStreamRTMP.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = DVDInputStreamRTMP.cpp; sourceTree = "<group>"; }; 815EE6340E17F1DC009FBE3C /* DVDInputStreamRTMP.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DVDInputStreamRTMP.h; sourceTree = "<group>"; }; 820023D9171A28A300667D1C /* OSXTextInputResponder.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = OSXTextInputResponder.h; sourceTree = "<group>"; }; @@ -5589,7 +5576,6 @@ E3A478190D29032C00F3C3A6 /* GUIDialogAccessPoints.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = GUIDialogAccessPoints.cpp; sourceTree = "<group>"; }; E3B53E7A0D97B08100021A96 /* DVDSubtitleParserMicroDVD.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = DVDSubtitleParserMicroDVD.cpp; sourceTree = "<group>"; }; E3B53E7B0D97B08100021A96 /* DVDSubtitleParserMicroDVD.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DVDSubtitleParserMicroDVD.h; sourceTree = "<group>"; }; - E3BBB7980D7EA78A00CAAFD3 /* MythSession.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = MythSession.cpp; sourceTree = "<group>"; }; E3DAAF8B0D6E1B0500F17647 /* SMBDirectory.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = SMBDirectory.cpp; sourceTree = "<group>"; }; E3E91FFA0D8C61DF002BF43D /* EventPacket.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = EventPacket.cpp; sourceTree = "<group>"; }; E3E91FFB0D8C61DF002BF43D /* EventServer.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = EventServer.cpp; sourceTree = "<group>"; }; @@ -8964,11 +8950,6 @@ 880DBE540DC224A100E26B71 /* MusicFileDirectory.h */, E38E17390D25F9FA00618676 /* MusicSearchDirectory.cpp */, E38E173A0D25F9FA00618676 /* MusicSearchDirectory.h */, - 810C9FA50D67D1FB0095F5DD /* MythDirectory.cpp */, - 810C9FA60D67D1FB0095F5DD /* MythDirectory.h */, - 810C9FA70D67D1FB0095F5DD /* MythFile.cpp */, - 810C9FA80D67D1FB0095F5DD /* MythFile.h */, - E3BBB7980D7EA78A00CAAFD3 /* MythSession.cpp */, DF0DF15913A3ADA7008ED511 /* NFSDirectory.cpp */, DF0DF15A13A3ADA7008ED511 /* NFSDirectory.h */, DF93D67D1444A8B0007C6459 /* NFSFile.cpp */, @@ -10746,10 +10727,7 @@ E36578880D3AA7B40033CC1C /* DVDPlayerCodec.cpp in Sources */, E33206380D5070AA00435CE3 /* DVDDemuxVobsub.cpp in Sources */, E33979960D62FD48004ECDDA /* DVDInputStreamTV.cpp in Sources */, - 810C9FA90D67D1FB0095F5DD /* MythDirectory.cpp in Sources */, - 810C9FAA0D67D1FB0095F5DD /* MythFile.cpp in Sources */, E3DAAF8D0D6E1B0500F17647 /* SMBDirectory.cpp in Sources */, - E3BBB7990D7EA78A00CAAFD3 /* MythSession.cpp in Sources */, E3E91FFD0D8C61DF002BF43D /* EventPacket.cpp in Sources */, E3E91FFE0D8C61DF002BF43D /* EventServer.cpp in Sources */, E3E91FFF0D8C61DF002BF43D /* Socket.cpp in Sources */, @@ -11787,9 +11765,6 @@ DFF0F22917528350002DA3A4 /* MusicDatabaseFile.cpp in Sources */, DFF0F22A17528350002DA3A4 /* MusicFileDirectory.cpp in Sources */, DFF0F22B17528350002DA3A4 /* MusicSearchDirectory.cpp in Sources */, - DFF0F22C17528350002DA3A4 /* MythDirectory.cpp in Sources */, - DFF0F22D17528350002DA3A4 /* MythFile.cpp in Sources */, - DFF0F22E17528350002DA3A4 /* MythSession.cpp in Sources */, DFF0F22F17528350002DA3A4 /* NFSDirectory.cpp in Sources */, DFF0F23017528350002DA3A4 /* NFSFile.cpp in Sources */, DFF0F23117528350002DA3A4 /* NptXbmcFile.cpp in Sources */, @@ -12866,9 +12841,6 @@ E4991292174E5D9900741B6D /* MusicDatabaseFile.cpp in Sources */, E4991293174E5D9900741B6D /* MusicFileDirectory.cpp in Sources */, E4991294174E5D9900741B6D /* MusicSearchDirectory.cpp in Sources */, - E4991295174E5D9900741B6D /* MythDirectory.cpp in Sources */, - E4991296174E5D9900741B6D /* MythFile.cpp in Sources */, - E4991297174E5D9900741B6D /* MythSession.cpp in Sources */, E4991298174E5D9900741B6D /* NFSDirectory.cpp in Sources */, E4991299174E5D9900741B6D /* NFSFile.cpp in Sources */, E499129A174E5D9900741B6D /* NptXbmcFile.cpp in Sources */, @@ -13698,8 +13670,6 @@ "$(SRCROOT)", "$(SRCROOT)/lib/libRTV", "$(SRCROOT)/lib/libXDAAP", - "$(SRCROOT)/lib/cmyth/libcmyth", - "$(SRCROOT)/lib/cmyth/librefmem", "$(SRCROOT)/lib/SlingboxLib", "$(SRCROOT)/xbmc/interfaces/json-rpc", "\"$(SRCROOT)/xbmc/interfaces/python\"", @@ -13763,8 +13733,6 @@ "$(SRCROOT)", "$(SRCROOT)/lib/libRTV", "$(SRCROOT)/lib/libXDAAP", - "$(SRCROOT)/lib/cmyth/libcmyth", - "$(SRCROOT)/lib/cmyth/librefmem", "$(SRCROOT)/lib/SlingboxLib", "$(SRCROOT)/xbmc/interfaces/json-rpc", "\"$(SRCROOT)/xbmc/interfaces/python\"", @@ -13874,8 +13842,6 @@ "\"$(SRCROOT)\"", "\"$(SRCROOT)/lib/libRTV\"", "\"$(SRCROOT)/lib/libXDAAP\"", - "\"$(SRCROOT)/lib/cmyth/libcmyth\"", - "\"$(SRCROOT)/lib/cmyth/librefmem\"", "\"$(SRCROOT)/lib/SlingboxLib\"", "\"$(SRCROOT)/xbmc/interfaces/json-rpc\"", "\"$(SRCROOT)/xbmc/interfaces/legacy\"", @@ -13933,8 +13899,6 @@ "\"$(SRCROOT)\"", "\"$(SRCROOT)/lib/libRTV\"", "\"$(SRCROOT)/lib/libXDAAP\"", - "\"$(SRCROOT)/lib/cmyth/libcmyth\"", - "\"$(SRCROOT)/lib/cmyth/librefmem\"", "\"$(SRCROOT)/lib/SlingboxLib\"", "\"$(SRCROOT)/xbmc/interfaces/json-rpc\"", "\"$(SRCROOT)/xbmc/interfaces/legacy\"", diff --git a/Makefile.in b/Makefile.in index 1624ff7491..244c206e15 100644 --- a/Makefile.in +++ b/Makefile.in @@ -207,11 +207,6 @@ LIB_DIRS=\ lib/cpluff \ lib/xbmc-dll-symbols -ifeq (@USE_MYSQL@,1) -LIB_DIRS += lib/cmyth -CMYTH=cmyth -endif - SS_DIRS= ifneq (@DISABLE_RSXS@,1) SS_DIRS+= xbmc/screensavers/rsxs-0.9/xbmc @@ -424,8 +419,6 @@ else endif libexif: dllloader $(MAKE) -C lib/libexif -cmyth: dllloader - $(MAKE) -C lib/cmyth libhdhomerun: dllloader $(MAKE) -C lib/libhdhomerun papcodecs: dllloader dvdpcodecs @@ -450,7 +443,7 @@ imagelib: dllloader codecs: papcodecs dvdpcodecs dvdpextcodecs -libs: $(LIBSSE4) libhdhomerun imagelib libexif system/libcpluff-@ARCH@.so $(CMYTH) +libs: $(LIBSSE4) libhdhomerun imagelib libexif system/libcpluff-@ARCH@.so externals: codecs libs visualizations screensavers libaddon diff --git a/addons/resource.language.en_gb/resources/strings.po b/addons/resource.language.en_gb/resources/strings.po index 48b2bd87db..0e142c5028 100644 --- a/addons/resource.language.en_gb/resources/strings.po +++ b/addons/resource.language.en_gb/resources/strings.po @@ -2859,10 +2859,7 @@ msgctxt "#670" msgid "Verbose logging for CURL library (http, dav)" msgstr "" -#: xbmc/settings/AdvancedSettings.cpp -msgctxt "#671" -msgid "Verbose logging for CMYTH library" -msgstr "" +#empty string with id 671 #: xbmc/settings/AdvancedSettings.cpp msgctxt "#672" @@ -10341,10 +10338,7 @@ msgctxt "#20257" msgid "VDR Streamdev client" msgstr "" -#: xbmc/network/GUIDialogNetworkSetup.cpp -msgctxt "#20258" -msgid "MythTV client" -msgstr "" +#empty string with id 20285 #: xbmc/network/GUIDialogNetworkSetup.cpp msgctxt "#20259" @@ -12110,9 +12104,8 @@ msgctxt "#22019" msgid "Recordings by title" msgstr "" -#. Electronic program guide, used as label in the menu of the PVR section and the MythDirectory +#. Electronic program guide, used as label in the menu of the PVR section #: addons/skin/confluence -#: xbmc/filesystem/MythDirectory.cpp msgctxt "#22020" msgid "Guide" msgstr "" diff --git a/configure.in b/configure.in index 696655490e..a438521059 100644 --- a/configure.in +++ b/configure.in @@ -2493,7 +2493,6 @@ OUTPUT_FILES="Makefile \ lib/libRTV/Makefile \ lib/libexif/Makefile \ lib/libXDAAP/Makefile \ - lib/cmyth/Makefile \ lib/libhdhomerun/Makefile \ lib/cximage-6.0/Makefile \ lib/libUPnP/Makefile \ diff --git a/lib/cmyth/COPYING b/lib/cmyth/COPYING deleted file mode 100644 index b1e3f5a263..0000000000 --- a/lib/cmyth/COPYING +++ /dev/null @@ -1,504 +0,0 @@ - GNU LESSER GENERAL PUBLIC LICENSE - Version 2.1, February 1999 - - Copyright (C) 1991, 1999 Free Software Foundation, Inc. - 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - Everyone is permitted to copy and distribute verbatim copies - of this license document, but changing it is not allowed. - -[This is the first released version of the Lesser GPL. It also counts - as the successor of the GNU Library Public License, version 2, hence - the version number 2.1.] - - Preamble - - The licenses for most software are designed to take away your -freedom to share and change it. By contrast, the GNU General Public -Licenses are intended to guarantee your freedom to share and change -free software--to make sure the software is free for all its users. - - This license, the Lesser General Public License, applies to some -specially designated software packages--typically libraries--of the -Free Software Foundation and other authors who decide to use it. You -can use it too, but we suggest you first think carefully about whether -this license or the ordinary General Public License is the better -strategy to use in any particular case, based on the explanations below. - - When we speak of free software, we are referring to freedom of use, -not price. Our General Public Licenses are designed to make sure that -you have the freedom to distribute copies of free software (and charge -for this service if you wish); that you receive source code or can get -it if you want it; that you can change the software and use pieces of -it in new free programs; and that you are informed that you can do -these things. - - To protect your rights, we need to make restrictions that forbid -distributors to deny you these rights or to ask you to surrender these -rights. These restrictions translate to certain responsibilities for -you if you distribute copies of the library or if you modify it. - - For example, if you distribute copies of the library, whether gratis -or for a fee, you must give the recipients all the rights that we gave -you. You must make sure that they, too, receive or can get the source -code. If you link other code with the library, you must provide -complete object files to the recipients, so that they can relink them -with the library after making changes to the library and recompiling -it. And you must show them these terms so they know their rights. - - We protect your rights with a two-step method: (1) we copyright the -library, and (2) we offer you this license, which gives you legal -permission to copy, distribute and/or modify the library. - - To protect each distributor, we want to make it very clear that -there is no warranty for the free library. Also, if the library is -modified by someone else and passed on, the recipients should know -that what they have is not the original version, so that the original -author's reputation will not be affected by problems that might be -introduced by others. - - Finally, software patents pose a constant threat to the existence of -any free program. We wish to make sure that a company cannot -effectively restrict the users of a free program by obtaining a -restrictive license from a patent holder. Therefore, we insist that -any patent license obtained for a version of the library must be -consistent with the full freedom of use specified in this license. - - Most GNU software, including some libraries, is covered by the -ordinary GNU General Public License. This license, the GNU Lesser -General Public License, applies to certain designated libraries, and -is quite different from the ordinary General Public License. We use -this license for certain libraries in order to permit linking those -libraries into non-free programs. - - When a program is linked with a library, whether statically or using -a shared library, the combination of the two is legally speaking a -combined work, a derivative of the original library. The ordinary -General Public License therefore permits such linking only if the -entire combination fits its criteria of freedom. The Lesser General -Public License permits more lax criteria for linking other code with -the library. - - We call this license the "Lesser" General Public License because it -does Less to protect the user's freedom than the ordinary General -Public License. It also provides other free software developers Less -of an advantage over competing non-free programs. These disadvantages -are the reason we use the ordinary General Public License for many -libraries. However, the Lesser license provides advantages in certain -special circumstances. - - For example, on rare occasions, there may be a special need to -encourage the widest possible use of a certain library, so that it becomes -a de-facto standard. To achieve this, non-free programs must be -allowed to use the library. A more frequent case is that a free -library does the same job as widely used non-free libraries. In this -case, there is little to gain by limiting the free library to free -software only, so we use the Lesser General Public License. - - In other cases, permission to use a particular library in non-free -programs enables a greater number of people to use a large body of -free software. For example, permission to use the GNU C Library in -non-free programs enables many more people to use the whole GNU -operating system, as well as its variant, the GNU/Linux operating -system. - - Although the Lesser General Public License is Less protective of the -users' freedom, it does ensure that the user of a program that is -linked with the Library has the freedom and the wherewithal to run -that program using a modified version of the Library. - - The precise terms and conditions for copying, distribution and -modification follow. Pay close attention to the difference between a -"work based on the library" and a "work that uses the library". The -former contains code derived from the library, whereas the latter must -be combined with the library in order to run. - - GNU LESSER GENERAL PUBLIC LICENSE - TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION - - 0. This License Agreement applies to any software library or other -program which contains a notice placed by the copyright holder or -other authorized party saying it may be distributed under the terms of -this Lesser General Public License (also called "this License"). -Each licensee is addressed as "you". - - A "library" means a collection of software functions and/or data -prepared so as to be conveniently linked with application programs -(which use some of those functions and data) to form executables. - - The "Library", below, refers to any such software library or work -which has been distributed under these terms. A "work based on the -Library" means either the Library or any derivative work under -copyright law: that is to say, a work containing the Library or a -portion of it, either verbatim or with modifications and/or translated -straightforwardly into another language. (Hereinafter, translation is -included without limitation in the term "modification".) - - "Source code" for a work means the preferred form of the work for -making modifications to it. For a library, complete source code means -all the source code for all modules it contains, plus any associated -interface definition files, plus the scripts used to control compilation -and installation of the library. - - Activities other than copying, distribution and modification are not -covered by this License; they are outside its scope. The act of -running a program using the Library is not restricted, and output from -such a program is covered only if its contents constitute a work based -on the Library (independent of the use of the Library in a tool for -writing it). Whether that is true depends on what the Library does -and what the program that uses the Library does. - - 1. You may copy and distribute verbatim copies of the Library's -complete source code as you receive it, in any medium, provided that -you conspicuously and appropriately publish on each copy an -appropriate copyright notice and disclaimer of warranty; keep intact -all the notices that refer to this License and to the absence of any -warranty; and distribute a copy of this License along with the -Library. - - You may charge a fee for the physical act of transferring a copy, -and you may at your option offer warranty protection in exchange for a -fee. - - 2. You may modify your copy or copies of the Library or any portion -of it, thus forming a work based on the Library, and copy and -distribute such modifications or work under the terms of Section 1 -above, provided that you also meet all of these conditions: - - a) The modified work must itself be a software library. - - b) You must cause the files modified to carry prominent notices - stating that you changed the files and the date of any change. - - c) You must cause the whole of the work to be licensed at no - charge to all third parties under the terms of this License. - - d) If a facility in the modified Library refers to a function or a - table of data to be supplied by an application program that uses - the facility, other than as an argument passed when the facility - is invoked, then you must make a good faith effort to ensure that, - in the event an application does not supply such function or - table, the facility still operates, and performs whatever part of - its purpose remains meaningful. - - (For example, a function in a library to compute square roots has - a purpose that is entirely well-defined independent of the - application. Therefore, Subsection 2d requires that any - application-supplied function or table used by this function must - be optional: if the application does not supply it, the square - root function must still compute square roots.) - -These requirements apply to the modified work as a whole. If -identifiable sections of that work are not derived from the Library, -and can be reasonably considered independent and separate works in -themselves, then this License, and its terms, do not apply to those -sections when you distribute them as separate works. But when you -distribute the same sections as part of a whole which is a work based -on the Library, the distribution of the whole must be on the terms of -this License, whose permissions for other licensees extend to the -entire whole, and thus to each and every part regardless of who wrote -it. - -Thus, it is not the intent of this section to claim rights or contest -your rights to work written entirely by you; rather, the intent is to -exercise the right to control the distribution of derivative or -collective works based on the Library. - -In addition, mere aggregation of another work not based on the Library -with the Library (or with a work based on the Library) on a volume of -a storage or distribution medium does not bring the other work under -the scope of this License. - - 3. You may opt to apply the terms of the ordinary GNU General Public -License instead of this License to a given copy of the Library. To do -this, you must alter all the notices that refer to this License, so -that they refer to the ordinary GNU General Public License, version 2, -instead of to this License. (If a newer version than version 2 of the -ordinary GNU General Public License has appeared, then you can specify -that version instead if you wish.) Do not make any other change in -these notices. - - Once this change is made in a given copy, it is irreversible for -that copy, so the ordinary GNU General Public License applies to all -subsequent copies and derivative works made from that copy. - - This option is useful when you wish to copy part of the code of -the Library into a program that is not a library. - - 4. You may copy and distribute the Library (or a portion or -derivative of it, under Section 2) in object code or executable form -under the terms of Sections 1 and 2 above provided that you accompany -it with the complete corresponding machine-readable source code, which -must be distributed under the terms of Sections 1 and 2 above on a -medium customarily used for software interchange. - - If distribution of object code is made by offering access to copy -from a designated place, then offering equivalent access to copy the -source code from the same place satisfies the requirement to -distribute the source code, even though third parties are not -compelled to copy the source along with the object code. - - 5. A program that contains no derivative of any portion of the -Library, but is designed to work with the Library by being compiled or -linked with it, is called a "work that uses the Library". Such a -work, in isolation, is not a derivative work of the Library, and -therefore falls outside the scope of this License. - - However, linking a "work that uses the Library" with the Library -creates an executable that is a derivative of the Library (because it -contains portions of the Library), rather than a "work that uses the -library". The executable is therefore covered by this License. -Section 6 states terms for distribution of such executables. - - When a "work that uses the Library" uses material from a header file -that is part of the Library, the object code for the work may be a -derivative work of the Library even though the source code is not. -Whether this is true is especially significant if the work can be -linked without the Library, or if the work is itself a library. The -threshold for this to be true is not precisely defined by law. - - If such an object file uses only numerical parameters, data -structure layouts and accessors, and small macros and small inline -functions (ten lines or less in length), then the use of the object -file is unrestricted, regardless of whether it is legally a derivative -work. (Executables containing this object code plus portions of the -Library will still fall under Section 6.) - - Otherwise, if the work is a derivative of the Library, you may -distribute the object code for the work under the terms of Section 6. -Any executables containing that work also fall under Section 6, -whether or not they are linked directly with the Library itself. - - 6. As an exception to the Sections above, you may also combine or -link a "work that uses the Library" with the Library to produce a -work containing portions of the Library, and distribute that work -under terms of your choice, provided that the terms permit -modification of the work for the customer's own use and reverse -engineering for debugging such modifications. - - You must give prominent notice with each copy of the work that the -Library is used in it and that the Library and its use are covered by -this License. You must supply a copy of this License. If the work -during execution displays copyright notices, you must include the -copyright notice for the Library among them, as well as a reference -directing the user to the copy of this License. Also, you must do one -of these things: - - a) Accompany the work with the complete corresponding - machine-readable source code for the Library including whatever - changes were used in the work (which must be distributed under - Sections 1 and 2 above); and, if the work is an executable linked - with the Library, with the complete machine-readable "work that - uses the Library", as object code and/or source code, so that the - user can modify the Library and then relink to produce a modified - executable containing the modified Library. (It is understood - that the user who changes the contents of definitions files in the - Library will not necessarily be able to recompile the application - to use the modified definitions.) - - b) Use a suitable shared library mechanism for linking with the - Library. A suitable mechanism is one that (1) uses at run time a - copy of the library already present on the user's computer system, - rather than copying library functions into the executable, and (2) - will operate properly with a modified version of the library, if - the user installs one, as long as the modified version is - interface-compatible with the version that the work was made with. - - c) Accompany the work with a written offer, valid for at - least three years, to give the same user the materials - specified in Subsection 6a, above, for a charge no more - than the cost of performing this distribution. - - d) If distribution of the work is made by offering access to copy - from a designated place, offer equivalent access to copy the above - specified materials from the same place. - - e) Verify that the user has already received a copy of these - materials or that you have already sent this user a copy. - - For an executable, the required form of the "work that uses the -Library" must include any data and utility programs needed for -reproducing the executable from it. However, as a special exception, -the materials to be distributed need not include anything that is -normally distributed (in either source or binary form) with the major -components (compiler, kernel, and so on) of the operating system on -which the executable runs, unless that component itself accompanies -the executable. - - It may happen that this requirement contradicts the license -restrictions of other proprietary libraries that do not normally -accompany the operating system. Such a contradiction means you cannot -use both them and the Library together in an executable that you -distribute. - - 7. You may place library facilities that are a work based on the -Library side-by-side in a single library together with other library -facilities not covered by this License, and distribute such a combined -library, provided that the separate distribution of the work based on -the Library and of the other library facilities is otherwise -permitted, and provided that you do these two things: - - a) Accompany the combined library with a copy of the same work - based on the Library, uncombined with any other library - facilities. This must be distributed under the terms of the - Sections above. - - b) Give prominent notice with the combined library of the fact - that part of it is a work based on the Library, and explaining - where to find the accompanying uncombined form of the same work. - - 8. You may not copy, modify, sublicense, link with, or distribute -the Library except as expressly provided under this License. Any -attempt otherwise to copy, modify, sublicense, link with, or -distribute the Library is void, and will automatically terminate your -rights under this License. However, parties who have received copies, -or rights, from you under this License will not have their licenses -terminated so long as such parties remain in full compliance. - - 9. You are not required to accept this License, since you have not -signed it. However, nothing else grants you permission to modify or -distribute the Library or its derivative works. These actions are -prohibited by law if you do not accept this License. Therefore, by -modifying or distributing the Library (or any work based on the -Library), you indicate your acceptance of this License to do so, and -all its terms and conditions for copying, distributing or modifying -the Library or works based on it. - - 10. Each time you redistribute the Library (or any work based on the -Library), the recipient automatically receives a license from the -original licensor to copy, distribute, link with or modify the Library -subject to these terms and conditions. You may not impose any further -restrictions on the recipients' exercise of the rights granted herein. -You are not responsible for enforcing compliance by third parties with -this License. - - 11. If, as a consequence of a court judgment or allegation of patent -infringement or for any other reason (not limited to patent issues), -conditions are imposed on you (whether by court order, agreement or -otherwise) that contradict the conditions of this License, they do not -excuse you from the conditions of this License. If you cannot -distribute so as to satisfy simultaneously your obligations under this -License and any other pertinent obligations, then as a consequence you -may not distribute the Library at all. For example, if a patent -license would not permit royalty-free redistribution of the Library by -all those who receive copies directly or indirectly through you, then -the only way you could satisfy both it and this License would be to -refrain entirely from distribution of the Library. - -If any portion of this section is held invalid or unenforceable under any -particular circumstance, the balance of the section is intended to apply, -and the section as a whole is intended to apply in other circumstances. - -It is not the purpose of this section to induce you to infringe any -patents or other property right claims or to contest validity of any -such claims; this section has the sole purpose of protecting the -integrity of the free software distribution system which is -implemented by public license practices. Many people have made -generous contributions to the wide range of software distributed -through that system in reliance on consistent application of that -system; it is up to the author/donor to decide if he or she is willing -to distribute software through any other system and a licensee cannot -impose that choice. - -This section is intended to make thoroughly clear what is believed to -be a consequence of the rest of this License. - - 12. If the distribution and/or use of the Library is restricted in -certain countries either by patents or by copyrighted interfaces, the -original copyright holder who places the Library under this License may add -an explicit geographical distribution limitation excluding those countries, -so that distribution is permitted only in or among countries not thus -excluded. In such case, this License incorporates the limitation as if -written in the body of this License. - - 13. The Free Software Foundation may publish revised and/or new -versions of the Lesser General Public License from time to time. -Such new versions will be similar in spirit to the present version, -but may differ in detail to address new problems or concerns. - -Each version is given a distinguishing version number. If the Library -specifies a version number of this License which applies to it and -"any later version", you have the option of following the terms and -conditions either of that version or of any later version published by -the Free Software Foundation. If the Library does not specify a -license version number, you may choose any version ever published by -the Free Software Foundation. - - 14. If you wish to incorporate parts of the Library into other free -programs whose distribution conditions are incompatible with these, -write to the author to ask for permission. For software which is -copyrighted by the Free Software Foundation, write to the Free -Software Foundation; we sometimes make exceptions for this. Our -decision will be guided by the two goals of preserving the free status -of all derivatives of our free software and of promoting the sharing -and reuse of software generally. - - NO WARRANTY - - 15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO -WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW. -EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR -OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY -KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE -IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR -PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE -LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME -THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. - - 16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN -WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY -AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU -FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR -CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE -LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING -RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A -FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF -SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH -DAMAGES. - - END OF TERMS AND CONDITIONS - - How to Apply These Terms to Your New Libraries - - If you develop a new library, and you want it to be of the greatest -possible use to the public, we recommend making it free software that -everyone can redistribute and change. You can do so by permitting -redistribution under these terms (or, alternatively, under the terms of the -ordinary General Public License). - - To apply these terms, attach the following notices to the library. It is -safest to attach them to the start of each source file to most effectively -convey the exclusion of warranty; and each file should have at least the -"copyright" line and a pointer to where the full notice is found. - - <one line to give the library's name and a brief idea of what it does.> - Copyright (C) <year> <name of author> - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2.1 of the License, or (at your option) any later version. - - This library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with this library; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - -Also add information on how to contact you by electronic and paper mail. - -You should also get your employer (if you work as a programmer) or your -school, if any, to sign a "copyright disclaimer" for the library, if -necessary. Here is a sample; alter the names: - - Yoyodyne, Inc., hereby disclaims all copyright interest in the - library `Frob' (a library for tweaking knobs) written by James Random Hacker. - - <signature of Ty Coon>, 1 April 1990 - Ty Coon, President of Vice - -That's all there is to it! - - diff --git a/lib/cmyth/Makefile.in b/lib/cmyth/Makefile.in deleted file mode 100644 index e91a3d32db..0000000000 --- a/lib/cmyth/Makefile.in +++ /dev/null @@ -1,32 +0,0 @@ -ARCH=@ARCH@ - -.PHONY: compile - -DIRS=libcmyth librefmem - -CMYTH_SYSDIR=@abs_top_srcdir@/system -CMYTH_SO=libcmyth-$(ARCH).so -CMYTH_LIB=$(CMYTH_SYSDIR)/$(CMYTH_SO) - -all: $(CMYTH_LIB) - -ifeq ($(findstring osx,$(ARCH)), osx) -$(CMYTH_LIB): libcmyth/libcmyth.a librefmem/librefmem.a - $(CC) $(LDFLAGS) -bundle -o $@ @MYSQL_LIBS@ \ - -Wl,-all_load libcmyth/libcmyth.a librefmem/librefmem.a -else -$(CMYTH_LIB): libcmyth/libcmyth.a librefmem/librefmem.a - $(CC) $(LDFLAGS) -shared -fpic -o $@ -Wl,--whole-archive \ - libcmyth/libcmyth.a librefmem/librefmem.a -Wl,--no-whole-archive @MYSQL_LIBS@ -endif - -libcmyth/libcmyth.a: compile - $(MAKE) -C libcmyth - -librefmem/librefmem.a: compile - $(MAKE) -C librefmem - - -CLEAN_FILES=$(CMYTH_LIB) - -include @abs_top_srcdir@/Makefile.include diff --git a/lib/cmyth/Win32/gensymbols.bat b/lib/cmyth/Win32/gensymbols.bat deleted file mode 100644 index 275bb49eb9..0000000000 --- a/lib/cmyth/Win32/gensymbols.bat +++ /dev/null @@ -1 +0,0 @@ -dumpbin /symbols Release\*.obj | grep -E "SECT.. notype \(\) +External +\| \_[^\_]"
\ No newline at end of file diff --git a/lib/cmyth/Win32/libcmyth.def b/lib/cmyth/Win32/libcmyth.def deleted file mode 100644 index 599bc4b610..0000000000 --- a/lib/cmyth/Win32/libcmyth.def +++ /dev/null @@ -1,223 +0,0 @@ -EXPORTS - ref_alloc_show - ref_set_destroy - ref_strdup - ref_hold - ref_release - ref_realloc - cmyth_get_bookmark - cmyth_set_bookmark - cmyth_commbreaklist_create - cmyth_commbreak_destroy - cmyth_commbreak_create - cmyth_rcv_commbreaklist - cmyth_get_commbreaklist - cmyth_conn_connect_ctrl - cmyth_conn_connect_event - cmyth_conn_connect_file - cmyth_conn_connect_ring - cmyth_conn_connect_recorder - cmyth_conn_check_block - cmyth_conn_get_recorder_from_num - cmyth_conn_get_free_recorder - cmyth_conn_get_freespace - cmyth_conn_hung - cmyth_conn_get_protocol_version - cmyth_conn_get_free_recorder_count - cmyth_dbg_level - cmyth_dbg_all - cmyth_dbg_none - cmyth_dbg - cmyth_set_dbg_msgcallback - refmem_dbg_level - refmem_dbg_all - refmem_dbg_none - refmem_dbg - cmyth_event_get - cmyth_event_select - cmyth_file_set_closed_callback - cmyth_file_data - cmyth_file_control - cmyth_file_start - cmyth_file_length - cmyth_file_get_block - cmyth_file_select - cmyth_file_request_block - cmyth_file_seek - cmyth_freespace_create - cmyth_keyframe_create - cmyth_keyframe_fill - cmyth_keyframe_string - cmyth_livetv_chain_create - cmyth_livetv_chain_get_block - cmyth_livetv_chain_switch - cmyth_livetv_chain_switch_last - cmyth_livetv_seek - cmyth_livetv_request_block - cmyth_livetv_select - cmyth_livetv_get_block - cmyth_livetv_chain_update - cmyth_livetv_chain_setup - cmyth_spawn_live_tv - cmyth_mysql_query_create - cmyth_mysql_query_reset - cmyth_mysql_query_param_long - cmyth_mysql_query_param_ulong - cmyth_mysql_query_param_int - cmyth_mysql_query_param_uint - cmyth_mysql_query_param_unixtime - cmyth_mysql_query_param_str - cmyth_mysql_query_string - cmyth_mysql_query_result - cmyth_database_close - cmyth_database_init - cmyth_database_set_host - cmyth_database_set_user - cmyth_database_set_pass - cmyth_database_set_name - cmyth_db_get_connection - cmyth_schedule_recording - cmyth_mysql_escape_chars - cmyth_get_offset_mysql - cmyth_get_recordid_mysql - cmyth_mysql_delete_scheduled_recording - cmyth_mysql_insert_into_record - cmyth_mysql_get_prev_recorded - cmyth_mysql_get_guide - cmyth_mysql_get_recgroups - cmyth_mysql_get_prog_finder_char_title - cmyth_mysql_get_prog_finder_time - fill_program_recording_status - cmyth_get_bookmark_mark - cmyth_get_bookmark_offset - cmyth_mysql_get_commbreak_list - cmyth_mythtv_remove_previous_recorded - cmyth_mysql_testdb_connection - cmyth_chanlist_create - cmyth_chanlist_get_item - cmyth_chanlist_get_count - cmyth_channel_chanid - cmyth_channel_channum - cmyth_channel_name - cmyth_channel_icon - cmyth_channel_visible - cmyth_channel_create - cmyth_mysql_get_chanlist - cmyth_posmap_create - cmyth_proginfo_create - cmyth_proginfo_stop_recording - cmyth_proginfo_check_recording - cmyth_proginfo_delete_recording - cmyth_proginfo_forget_recording - cmyth_proginfo_get_recorder_num - cmyth_proginfo_chan_id - cmyth_proginfo_title - cmyth_proginfo_subtitle - cmyth_proginfo_description - cmyth_proginfo_category - cmyth_proginfo_seriesid - cmyth_proginfo_programid - cmyth_proginfo_stars - cmyth_proginfo_playgroup - cmyth_proginfo_originalairdate - cmyth_proginfo_chanstr - cmyth_proginfo_chansign - cmyth_proginfo_channame - cmyth_proginfo_pathname - cmyth_proginfo_length - cmyth_proginfo_length_sec - cmyth_proginfo_start - cmyth_proginfo_end - cmyth_proginfo_rec_start - cmyth_proginfo_rec_end - cmyth_proginfo_rec_status - cmyth_proginfo_flags - cmyth_proginfo_get_detail - cmyth_proginfo_compare - cmyth_proginfo_host - cmyth_proginfo_card_id - cmyth_proginfo_recgroup - cmyth_proginfo_year - cmyth_get_delete_list - cmyth_proglist_create - cmyth_proglist_get_item - cmyth_proglist_delete_item - cmyth_proglist_get_count - cmyth_proglist_get_all_recorded - cmyth_proglist_get_all_pending - cmyth_proglist_get_all_scheduled - cmyth_proglist_get_conflicting - cmyth_proglist_sort - cmyth_recorder_create - cmyth_recorder_dup - cmyth_recorder_is_recording - cmyth_recorder_get_framerate - cmyth_recorder_get_frames_written - cmyth_recorder_get_free_space - cmyth_recorder_get_keyframe_pos - cmyth_recorder_get_position_map - cmyth_recorder_get_recording - cmyth_recorder_stop_playing - cmyth_recorder_frontend_ready - cmyth_recorder_cancel_next_recording - cmyth_recorder_pause - cmyth_recorder_finish_recording - cmyth_recorder_toggle_channel_favorite - cmyth_recorder_change_channel - cmyth_recorder_set_channel - cmyth_recorder_change_color - cmyth_recorder_change_brightness - cmyth_recorder_change_contrast - cmyth_recorder_change_hue - cmyth_recorder_check_channel - cmyth_recorder_check_channel_prefix - cmyth_recorder_get_cur_proginfo - cmyth_recorder_get_next_program_info - cmyth_recorder_get_next_proginfo - cmyth_recorder_get_input_name - cmyth_recorder_seek - cmyth_recorder_spawn_livetv - cmyth_recorder_spawn_chain_livetv - cmyth_recorder_stop_livetv - cmyth_recorder_done_ringbuf - cmyth_recorder_start_stream - cmyth_recorder_end_stream - cmyth_recorder_get_filename - cmyth_recorder_get_recorder_id - cmyth_rec_num_create - cmyth_rec_num_hold - cmyth_rec_num_release - cmyth_rec_num_get - cmyth_rec_num_string - cmyth_ringbuf_create - cmyth_ringbuf_setup - cmyth_ringbuf_pathname - cmyth_ringbuf_get_block - cmyth_ringbuf_select - cmyth_ringbuf_request_block - cmyth_ringbuf_seek - cmyth_timestamp_create - cmyth_timestamp_from_string - cmyth_timestamp_from_tm - cmyth_timestamp_from_unixtime - cmyth_timestamp_to_unixtime - cmyth_timestamp_to_string - cmyth_timestamp_to_isostring - cmyth_timestamp_to_display_string - cmyth_datetime_to_string - cmyth_timestamp_compare - cmyth_livetv_chain_switch_last - cmyth_proginfo_get_from_basename - cmyth_proginfo_delete_recording - cmyth_livetv_keep_recording - cmyth_conn_connect_path - cmyth_proginfo_chanicon - cmyth_ringbuf_read - cmyth_file_read - cmyth_livetv_read - cmyth_get_cutlist - cmyth_tuner_type_check - cmyth_update_bookmark_setting - cmyth_proginfo_port - cmyth_proginfo_season - cmyth_proginfo_episode
\ No newline at end of file diff --git a/lib/cmyth/Win32/libcmyth.sln b/lib/cmyth/Win32/libcmyth.sln deleted file mode 100644 index 877ed33e32..0000000000 --- a/lib/cmyth/Win32/libcmyth.sln +++ /dev/null @@ -1,21 +0,0 @@ -Microsoft Visual Studio Solution File, Format Version 8.00 -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libcmyth", "libcmyth.vcproj", "{F9E6874D-60A8-49BA-9393-A2105E63ABCF}" - ProjectSection(ProjectDependencies) = postProject - EndProjectSection -EndProject -Global - GlobalSection(SolutionConfiguration) = preSolution - Debug = Debug - Release = Release - EndGlobalSection - GlobalSection(ProjectConfiguration) = postSolution - {F9E6874D-60A8-49BA-9393-A2105E63ABCF}.Debug.ActiveCfg = Debug|Win32 - {F9E6874D-60A8-49BA-9393-A2105E63ABCF}.Debug.Build.0 = Debug|Win32 - {F9E6874D-60A8-49BA-9393-A2105E63ABCF}.Release.ActiveCfg = Release|Win32 - {F9E6874D-60A8-49BA-9393-A2105E63ABCF}.Release.Build.0 = Release|Win32 - EndGlobalSection - GlobalSection(ExtensibilityGlobals) = postSolution - EndGlobalSection - GlobalSection(ExtensibilityAddIns) = postSolution - EndGlobalSection -EndGlobal diff --git a/lib/cmyth/Win32/libcmyth.vcxproj b/lib/cmyth/Win32/libcmyth.vcxproj deleted file mode 100644 index d075528131..0000000000 --- a/lib/cmyth/Win32/libcmyth.vcxproj +++ /dev/null @@ -1,154 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> - <ItemGroup Label="ProjectConfigurations"> - <ProjectConfiguration Include="Debug|Win32"> - <Configuration>Debug</Configuration> - <Platform>Win32</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="Release|Win32"> - <Configuration>Release</Configuration> - <Platform>Win32</Platform> - </ProjectConfiguration> - </ItemGroup> - <PropertyGroup Label="Globals"> - <ProjectName>libcmyth_dll</ProjectName> - <ProjectGuid>{F9E6874D-60A8-49BA-9393-A2105E63ABCF}</ProjectGuid> - <RootNamespace>libcmyth</RootNamespace> - <Keyword>Win32Proj</Keyword> - </PropertyGroup> - <Import Project="$(SolutionDir)\XBMC.core-defaults.props" /> - <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" /> - <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration"> - <ConfigurationType>DynamicLibrary</ConfigurationType> - <UseDebugLibraries>false</UseDebugLibraries> - <CharacterSet>MultiByte</CharacterSet> - </PropertyGroup> - <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration"> - <ConfigurationType>DynamicLibrary</ConfigurationType> - <UseDebugLibraries>true</UseDebugLibraries> - <CharacterSet>MultiByte</CharacterSet> - </PropertyGroup> - <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" /> - <ImportGroup Label="ExtensionSettings"> - </ImportGroup> - <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="PropertySheets"> - <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> - <Import Project="$(SolutionDir)\XBMC.defaults.props" /> - </ImportGroup> - <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="PropertySheets"> - <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> - <Import Project="$(SolutionDir)\XBMC.defaults.props" /> - </ImportGroup> - <PropertyGroup Label="UserMacros" /> - <PropertyGroup> - <_ProjectFileVersion>10.0.30319.1</_ProjectFileVersion> - <OutDir Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">$(SolutionDir)libs\$(TargetName)\$(Configuration)\</OutDir> - <IntDir Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">$(SolutionDir)objs\$(TargetName)\$(Configuration)\</IntDir> - <OutDir Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">$(SolutionDir)libs\$(TargetName)\$(Configuration)\</OutDir> - <IntDir Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">$(SolutionDir)objs\$(TargetName)\$(Configuration)\</IntDir> - <TargetName Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">libcmyth</TargetName> - <TargetName Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">libcmyth</TargetName> - <CustomBuildAfterTargets Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Build</CustomBuildAfterTargets> - <CustomBuildAfterTargets Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">Build</CustomBuildAfterTargets> - </PropertyGroup> - <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> - <ClCompile> - <AdditionalIncludeDirectories>../include;../librefmem;../libcmyth;%(AdditionalIncludeDirectories);$(SolutionDir)../../xbmc/win32</AdditionalIncludeDirectories> - <PreprocessorDefinitions>WIN32_LEAN_AND_MEAN;_LIB;inline=__inline;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions)</PreprocessorDefinitions> - <PrecompiledHeader> - </PrecompiledHeader> - </ClCompile> - <Link> - <AdditionalDependencies>ws2_32.lib;mysqlclient.lib;%(AdditionalDependencies)</AdditionalDependencies> - <OutputFile>$(OutDir)$(TargetName)$(TargetExt)</OutputFile> - <IgnoreSpecificDefaultLibraries>LIBCMTD;%(IgnoreSpecificDefaultLibraries)</IgnoreSpecificDefaultLibraries> - <ModuleDefinitionFile>libcmyth.def</ModuleDefinitionFile> - <RandomizedBaseAddress>false</RandomizedBaseAddress> - <DataExecutionPrevention> - </DataExecutionPrevention> - <ImportLibrary>$(Configuration)\vs2010\$(TargetName).lib</ImportLibrary> - </Link> - <PostBuildEvent> - <Command> - </Command> - </PostBuildEvent> - <CustomBuildStep> - <Command>copy /B /Y "$(TargetPath)" "$(SolutionDir)..\..\system\$(TargetFileName)"</Command> - </CustomBuildStep> - <CustomBuildStep> - <Message>Copy output</Message> - </CustomBuildStep> - <CustomBuildStep> - <Outputs>$(SolutionDir)..\..\system\$(TargetFileName)</Outputs> - <Inputs>$(TargetPath)</Inputs> - </CustomBuildStep> - </ItemDefinitionGroup> - <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> - <ClCompile> - <AdditionalIncludeDirectories>../include;../librefmem;../libcmyth;%(AdditionalIncludeDirectories);$(SolutionDir)../../xbmc/win32</AdditionalIncludeDirectories> - <PreprocessorDefinitions>WIN32_LEAN_AND_MEAN;_LIB;inline=__inline;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions)</PreprocessorDefinitions> - <PrecompiledHeader> - </PrecompiledHeader> - </ClCompile> - <Link> - <AdditionalDependencies>ws2_32.lib;mysqlclient.lib;%(AdditionalDependencies)</AdditionalDependencies> - <OutputFile>$(OutDir)$(TargetName)$(TargetExt)</OutputFile> - <IgnoreSpecificDefaultLibraries>LIBCMT;%(IgnoreSpecificDefaultLibraries)</IgnoreSpecificDefaultLibraries> - <ModuleDefinitionFile>libcmyth.def</ModuleDefinitionFile> - <RandomizedBaseAddress>false</RandomizedBaseAddress> - <DataExecutionPrevention> - </DataExecutionPrevention> - <ImportLibrary>$(Configuration)\vs2010\$(TargetName).lib</ImportLibrary> - </Link> - <PostBuildEvent> - <Command> - </Command> - </PostBuildEvent> - <CustomBuildStep> - <Command>copy /B /Y "$(TargetPath)" "$(SolutionDir)..\..\system\$(TargetFileName)"</Command> - </CustomBuildStep> - <CustomBuildStep> - <Message>Copy output</Message> - </CustomBuildStep> - <CustomBuildStep> - <Outputs>$(SolutionDir)..\..\system\$(TargetFileName)</Outputs> - <Inputs>$(TargetPath)</Inputs> - </CustomBuildStep> - </ItemDefinitionGroup> - <ItemGroup> - <ClCompile Include="..\libcmyth\bookmark.c" /> - <ClCompile Include="..\libcmyth\commbreak.c" /> - <ClCompile Include="..\libcmyth\connection.c" /> - <ClCompile Include="..\libcmyth\debug.c" /> - <ClCompile Include="..\libcmyth\event.c" /> - <ClCompile Include="..\libcmyth\file.c" /> - <ClCompile Include="..\libcmyth\freespace.c" /> - <ClCompile Include="..\libcmyth\keyframe.c" /> - <ClCompile Include="..\libcmyth\livetv.c" /> - <ClCompile Include="..\libcmyth\mysql_query.c" /> - <ClCompile Include="..\libcmyth\mythtv_mysql.c" /> - <ClCompile Include="..\libcmyth\posmap.c" /> - <ClCompile Include="..\libcmyth\proginfo.c" /> - <ClCompile Include="..\libcmyth\proglist.c" /> - <ClCompile Include="..\libcmyth\rec_num.c" /> - <ClCompile Include="..\libcmyth\recorder.c" /> - <ClCompile Include="..\libcmyth\ringbuf.c" /> - <ClCompile Include="..\libcmyth\socket.c" /> - <ClCompile Include="..\libcmyth\timestamp.c" /> - <ClCompile Include="..\libcmyth\utf8tolatin1.c" /> - <ClCompile Include="..\librefmem\alloc.c" /> - <ClCompile Include="..\librefmem\debug_refmem.c" /> - </ItemGroup> - <ItemGroup> - <ClInclude Include="..\include\cmyth\cmyth.h" /> - <ClInclude Include="..\libcmyth\cmyth_local.h" /> - <ClInclude Include="..\libcmyth\safe_string.h" /> - <ClInclude Include="..\librefmem\refmem_local.h" /> - </ItemGroup> - <ItemGroup> - <None Include="libcmyth.def" /> - </ItemGroup> - <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" /> - <ImportGroup Label="ExtensionTargets"> - </ImportGroup> -</Project>
\ No newline at end of file diff --git a/lib/cmyth/Win32/libcmyth.vcxproj.filters b/lib/cmyth/Win32/libcmyth.vcxproj.filters deleted file mode 100644 index 0032e92938..0000000000 --- a/lib/cmyth/Win32/libcmyth.vcxproj.filters +++ /dev/null @@ -1,97 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> - <ItemGroup> - <Filter Include="Source Files"> - <UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier> - <Extensions>h;cpp;c;cxx;def;odl;idl;hpj;bat;asm;asmx</Extensions> - </Filter> - <Filter Include="refmem"> - <UniqueIdentifier>{11629684-a59f-469a-ade2-cca15af8c776}</UniqueIdentifier> - </Filter> - </ItemGroup> - <ItemGroup> - <ClCompile Include="..\libcmyth\bookmark.c"> - <Filter>Source Files</Filter> - </ClCompile> - <ClCompile Include="..\libcmyth\commbreak.c"> - <Filter>Source Files</Filter> - </ClCompile> - <ClCompile Include="..\libcmyth\connection.c"> - <Filter>Source Files</Filter> - </ClCompile> - <ClCompile Include="..\libcmyth\debug.c"> - <Filter>Source Files</Filter> - </ClCompile> - <ClCompile Include="..\libcmyth\event.c"> - <Filter>Source Files</Filter> - </ClCompile> - <ClCompile Include="..\libcmyth\file.c"> - <Filter>Source Files</Filter> - </ClCompile> - <ClCompile Include="..\libcmyth\freespace.c"> - <Filter>Source Files</Filter> - </ClCompile> - <ClCompile Include="..\libcmyth\keyframe.c"> - <Filter>Source Files</Filter> - </ClCompile> - <ClCompile Include="..\libcmyth\livetv.c"> - <Filter>Source Files</Filter> - </ClCompile> - <ClCompile Include="..\libcmyth\mysql_query.c"> - <Filter>Source Files</Filter> - </ClCompile> - <ClCompile Include="..\libcmyth\mythtv_mysql.c"> - <Filter>Source Files</Filter> - </ClCompile> - <ClCompile Include="..\libcmyth\posmap.c"> - <Filter>Source Files</Filter> - </ClCompile> - <ClCompile Include="..\libcmyth\proginfo.c"> - <Filter>Source Files</Filter> - </ClCompile> - <ClCompile Include="..\libcmyth\proglist.c"> - <Filter>Source Files</Filter> - </ClCompile> - <ClCompile Include="..\libcmyth\rec_num.c"> - <Filter>Source Files</Filter> - </ClCompile> - <ClCompile Include="..\libcmyth\recorder.c"> - <Filter>Source Files</Filter> - </ClCompile> - <ClCompile Include="..\libcmyth\ringbuf.c"> - <Filter>Source Files</Filter> - </ClCompile> - <ClCompile Include="..\libcmyth\socket.c"> - <Filter>Source Files</Filter> - </ClCompile> - <ClCompile Include="..\libcmyth\timestamp.c"> - <Filter>Source Files</Filter> - </ClCompile> - <ClCompile Include="..\libcmyth\utf8tolatin1.c"> - <Filter>Source Files</Filter> - </ClCompile> - <ClCompile Include="..\librefmem\alloc.c"> - <Filter>refmem</Filter> - </ClCompile> - <ClCompile Include="..\librefmem\debug_refmem.c"> - <Filter>refmem</Filter> - </ClCompile> - </ItemGroup> - <ItemGroup> - <ClInclude Include="..\include\cmyth\cmyth.h"> - <Filter>Source Files</Filter> - </ClInclude> - <ClInclude Include="..\libcmyth\cmyth_local.h"> - <Filter>Source Files</Filter> - </ClInclude> - <ClInclude Include="..\libcmyth\safe_string.h"> - <Filter>Source Files</Filter> - </ClInclude> - <ClInclude Include="..\librefmem\refmem_local.h"> - <Filter>refmem</Filter> - </ClInclude> - </ItemGroup> - <ItemGroup> - <None Include="libcmyth.def" /> - </ItemGroup> -</Project>
\ No newline at end of file diff --git a/lib/cmyth/include/cmyth/cmyth.h b/lib/cmyth/include/cmyth/cmyth.h deleted file mode 100644 index fae6889069..0000000000 --- a/lib/cmyth/include/cmyth/cmyth.h +++ /dev/null @@ -1,1125 +0,0 @@ -/* - * Copyright (C) 2004-2012, Eric Lund, Jon Gettler - * http://www.mvpmc.org/ - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -/*! \mainpage cmyth - * - * cmyth is a library that provides a C language API to access and control - * a MythTV backend. - * - * \section projectweb Project website - * http://www.mvpmc.org/ - * - * \section repos Source repositories - * http://git.mvpmc.org/ - * - * \section libraries Libraries - * \li \link cmyth.h libcmyth \endlink - * \li \link refmem.h librefmem \endlink - */ - -/** \file cmyth.h - * A C library for communicating with a MythTV server. - */ - -#ifndef __CMYTH_H -#define __CMYTH_H - -#ifdef __APPLE__ -#include <sys/time.h> -#else -#include <time.h> -#endif - -/* - * ----------------------------------------------------------------- - * Types - * ----------------------------------------------------------------- - */ -struct cmyth_conn; -typedef struct cmyth_conn *cmyth_conn_t; - -/* Sergio: Added to support the new livetv protocol */ -struct cmyth_livetv_chain; -typedef struct cmyth_livetv_chain *cmyth_livetv_chain_t; - -struct cmyth_recorder; -typedef struct cmyth_recorder *cmyth_recorder_t; - -struct cmyth_ringbuf; -typedef struct cmyth_ringbuf *cmyth_ringbuf_t; - -struct cmyth_rec_num; -typedef struct cmyth_rec_num *cmyth_rec_num_t; - -struct cmyth_posmap; -typedef struct cmyth_posmap *cmyth_posmap_t; - -struct cmyth_proginfo; -typedef struct cmyth_proginfo *cmyth_proginfo_t; - -struct cmyth_database; -typedef struct cmyth_database *cmyth_database_t; - - -typedef enum { - CHANNEL_DIRECTION_UP = 0, - CHANNEL_DIRECTION_DOWN = 1, - CHANNEL_DIRECTION_FAVORITE = 2, - CHANNEL_DIRECTION_SAME = 4, -} cmyth_channeldir_t; - -typedef enum { - ADJ_DIRECTION_UP = 1, - ADJ_DIRECTION_DOWN = 0, -} cmyth_adjdir_t; - -typedef enum { - BROWSE_DIRECTION_SAME = 0, - BROWSE_DIRECTION_UP = 1, - BROWSE_DIRECTION_DOWN = 2, - BROWSE_DIRECTION_LEFT = 3, - BROWSE_DIRECTION_RIGHT = 4, - BROWSE_DIRECTION_FAVORITE = 5, -} cmyth_browsedir_t; - -typedef enum { - WHENCE_SET = 0, - WHENCE_CUR = 1, - WHENCE_END = 2, -} cmyth_whence_t; - -typedef enum { - CMYTH_EVENT_UNKNOWN = 0, - CMYTH_EVENT_CLOSE = 1, - CMYTH_EVENT_RECORDING_LIST_CHANGE, - CMYTH_EVENT_RECORDING_LIST_CHANGE_ADD, - CMYTH_EVENT_RECORDING_LIST_CHANGE_UPDATE, - CMYTH_EVENT_RECORDING_LIST_CHANGE_DELETE, - CMYTH_EVENT_SCHEDULE_CHANGE, - CMYTH_EVENT_DONE_RECORDING, - CMYTH_EVENT_QUIT_LIVETV, - CMYTH_EVENT_WATCH_LIVETV, - CMYTH_EVENT_LIVETV_CHAIN_UPDATE, - CMYTH_EVENT_SIGNAL, - CMYTH_EVENT_ASK_RECORDING, - CMYTH_EVENT_SYSTEM_EVENT, - CMYTH_EVENT_UPDATE_FILE_SIZE, - CMYTH_EVENT_GENERATED_PIXMAP, - CMYTH_EVENT_CLEAR_SETTINGS_CACHE, -} cmyth_event_t; - -#define CMYTH_NUM_SORTS 2 -typedef enum { - MYTHTV_SORT_DATE_RECORDED = 0, - MYTHTV_SORT_ORIGINAL_AIRDATE, -} cmyth_proglist_sort_t; - -struct cmyth_timestamp; -typedef struct cmyth_timestamp *cmyth_timestamp_t; - -struct cmyth_keyframe; -typedef struct cmyth_keyframe *cmyth_keyframe_t; - -struct cmyth_freespace; -typedef struct cmyth_freespace *cmyth_freespace_t; - -struct cmyth_proglist; -typedef struct cmyth_proglist *cmyth_proglist_t; - -struct cmyth_file; -typedef struct cmyth_file *cmyth_file_t; - -struct cmyth_commbreak { - long long start_mark; - long long start_offset; - long long end_mark; - long long end_offset; -}; -typedef struct cmyth_commbreak *cmyth_commbreak_t; - -struct cmyth_commbreaklist { - cmyth_commbreak_t *commbreak_list; - long commbreak_count; -}; -typedef struct cmyth_commbreaklist *cmyth_commbreaklist_t; - -/* Sergio: Added to support the tvguide functionality */ - -struct cmyth_channel; -typedef struct cmyth_channel *cmyth_channel_t; - -struct cmyth_chanlist; -typedef struct cmyth_chanlist *cmyth_chanlist_t; - -struct cmyth_tvguide_progs; -typedef struct cmyth_tvguide_progs *cmyth_tvguide_progs_t; - -/* - * ----------------------------------------------------------------- - * Debug Output Control - * ----------------------------------------------------------------- - */ - -/* - * Debug level constants used to determine the level of debug tracing - * to be done and the debug level of any given message. - */ - -#define CMYTH_DBG_NONE -1 -#define CMYTH_DBG_ERROR 0 -#define CMYTH_DBG_WARN 1 -#define CMYTH_DBG_INFO 2 -#define CMYTH_DBG_DETAIL 3 -#define CMYTH_DBG_DEBUG 4 -#define CMYTH_DBG_PROTO 5 -#define CMYTH_DBG_ALL 6 - -/** - * Set the libcmyth debug level. - * \param l level - */ -extern void cmyth_dbg_level(int l); - -/** - * Turn on all libcmyth debugging. - */ -extern void cmyth_dbg_all(void); - -/** - * Turn off all libcmyth debugging. - */ -extern void cmyth_dbg_none(void); - -/** - * Print a libcmyth debug message. - * \param level debug level - * \param fmt printf style format - */ -extern void cmyth_dbg(int level, char *fmt, ...); - -/** - * Define a callback to use to send messages rather than using stdout - * \param msgcb function pointer to pass a string to - */ -extern void cmyth_set_dbg_msgcallback(void (*msgcb)(int level,char *)); - -/* - * ----------------------------------------------------------------- - * Connection Operations - * ----------------------------------------------------------------- - */ - -/** - * Create a control connection to a backend. - * \param server server hostname or ip address - * \param port port number to connect on - * \param buflen buffer size for the connection to use - * \param tcp_rcvbuf if non-zero, the TCP receive buffer size for the socket - * \return control handle - */ -extern cmyth_conn_t cmyth_conn_connect_ctrl(char *server, - unsigned short port, - unsigned buflen, int tcp_rcvbuf); - -/** - * Create an event connection to a backend. - * \param server server hostname or ip address - * \param port port number to connect on - * \param buflen buffer size for the connection to use - * \param tcp_rcvbuf if non-zero, the TCP receive buffer size for the socket - * \return event handle - */ -extern cmyth_conn_t cmyth_conn_connect_event(char *server, - unsigned short port, - unsigned buflen, int tcp_rcvbuf); - -/** - * Create a file connection to a backend for reading a recording. - * \param prog program handle - * \param control control handle - * \param buflen buffer size for the connection to use - * \param tcp_rcvbuf if non-zero, the TCP receive buffer size for the socket - * \return file handle - */ -extern cmyth_file_t cmyth_conn_connect_file(cmyth_proginfo_t prog, - cmyth_conn_t control, - unsigned buflen, int tcp_rcvbuf); - - -/** - * Create a file connection to a backend. - * \param path path to file - * \param control control handle - * \param buflen buffer size for the connection to use - * \param tcp_rcvbuf if non-zero, the TCP receive buffer size for the socket - * \return file handle - */ -extern cmyth_file_t cmyth_conn_connect_path(char* path, cmyth_conn_t control, - unsigned buflen, int tcp_rcvbuf); - -/** - * Create a ring buffer connection to a recorder. - * \param rec recorder handle - * \param buflen buffer size for the connection to use - * \param tcp_rcvbuf if non-zero, the TCP receive buffer size for the socket - * \retval 0 success - * \retval -1 error - */ -extern int cmyth_conn_connect_ring(cmyth_recorder_t rec, unsigned buflen, - int tcp_rcvbuf); - -/** - * Create a connection to a recorder. - * \param rec recorder to connect to - * \param buflen buffer size for the connection to use - * \param tcp_rcvbuf if non-zero, the TCP receive buffer size for the socket - * \retval 0 success - * \retval -1 error - */ -extern int cmyth_conn_connect_recorder(cmyth_recorder_t rec, - unsigned buflen, int tcp_rcvbuf); - -/** - * Check whether a block has finished transfering from a backend. - * \param conn control handle - * \param size size of block - * \retval 0 not complete - * \retval 1 complete - * \retval <0 error - */ -extern int cmyth_conn_check_block(cmyth_conn_t conn, unsigned long size); - -/** - * Obtain a recorder from a connection by its recorder number. - * \param conn connection handle - * \param num recorder number - * \return recorder handle - */ -extern cmyth_recorder_t cmyth_conn_get_recorder_from_num(cmyth_conn_t conn, - int num); - -/** - * Obtain the next available free recorder on a backend. - * \param conn connection handle - * \return recorder handle - */ -extern cmyth_recorder_t cmyth_conn_get_free_recorder(cmyth_conn_t conn); - -/** - * Get the amount of free disk space on a backend. - * \param control control handle - * \param[out] total total disk space - * \param[out] used used disk space - * \retval 0 success - * \retval <0 error - */ -extern int cmyth_conn_get_freespace(cmyth_conn_t control, - long long *total, long long *used); - -/** - * Determine if a control connection is not responding. - * \param control control handle - * \retval 0 not hung - * \retval 1 hung - * \retval <0 error - */ -extern int cmyth_conn_hung(cmyth_conn_t control); - -/** - * Determine the number of free recorders. - * \param conn connection handle - * \return number of free recorders - */ -extern int cmyth_conn_get_free_recorder_count(cmyth_conn_t conn); - -/** - * Determine the MythTV protocol version being used. - * \param conn connection handle - * \return protocol version - */ -extern int cmyth_conn_get_protocol_version(cmyth_conn_t conn); - -/** - * Return a MythTV setting for a hostname - * \param conn connection handle - * \param hostname hostname to retreive the setting from - * \param setting the setting name to get - * \return ref counted string with the setting - */ -extern char * cmyth_conn_get_setting(cmyth_conn_t conn, - const char* hostname, const char* setting); - -/* - * ----------------------------------------------------------------- - * Event Operations - * ----------------------------------------------------------------- - */ - -/** - * Retrieve an event from a backend. - * \param conn connection handle - * \param[out] data data, if the event returns any - * \param len size of data buffer - * \return event type - */ -extern cmyth_event_t cmyth_event_get(cmyth_conn_t conn, char * data, int len); - -/** - * Selects on the event socket, waiting for an event to show up. - * allows nonblocking access to events. - * \return <= 0 on failure - */ -extern int cmyth_event_select(cmyth_conn_t conn, struct timeval *timeout); - -/* - * ----------------------------------------------------------------- - * Recorder Operations - * ----------------------------------------------------------------- - */ - -/** - * Create a new recorder. - * \return recorder handle - */ -extern cmyth_recorder_t cmyth_recorder_create(void); - -/** - * Duplicaate a recorder. - * \param p recorder handle - * \return duplicated recorder handle - */ -extern cmyth_recorder_t cmyth_recorder_dup(cmyth_recorder_t p); - -/** - * Determine if a recorder is in use. - * \param rec recorder handle - * \retval 0 not recording - * \retval 1 recording - * \retval <0 error - */ -extern int cmyth_recorder_is_recording(cmyth_recorder_t rec); - -/** - * Determine the framerate for a recorder. - * \param rec recorder handle - * \param[out] rate framerate - * \retval 0 success - * \retval <0 error - */ -extern int cmyth_recorder_get_framerate(cmyth_recorder_t rec, - double *rate); - -extern long long cmyth_recorder_get_frames_written(cmyth_recorder_t rec); - -extern long long cmyth_recorder_get_free_space(cmyth_recorder_t rec); - -extern long long cmyth_recorder_get_keyframe_pos(cmyth_recorder_t rec, - unsigned long keynum); - -extern cmyth_posmap_t cmyth_recorder_get_position_map(cmyth_recorder_t rec, - unsigned long start, - unsigned long end); - -extern cmyth_proginfo_t cmyth_recorder_get_recording(cmyth_recorder_t rec); - -extern int cmyth_recorder_stop_playing(cmyth_recorder_t rec); - -extern int cmyth_recorder_frontend_ready(cmyth_recorder_t rec); - -extern int cmyth_recorder_cancel_next_recording(cmyth_recorder_t rec); - -/** - * Request that the recorder stop transmitting data. - * \param rec recorder handle - * \retval 0 success - * \retval <0 error - */ -extern int cmyth_recorder_pause(cmyth_recorder_t rec); - -extern int cmyth_recorder_finish_recording(cmyth_recorder_t rec); - -extern int cmyth_recorder_toggle_channel_favorite(cmyth_recorder_t rec); - -/** - * Request that the recorder change the channel being recorded. - * \param rec recorder handle - * \param direction direction in which to change channel - * \retval 0 success - * \retval <0 error - */ -extern int cmyth_recorder_change_channel(cmyth_recorder_t rec, - cmyth_channeldir_t direction); - -/** - * Set the channel for a recorder. - * \param rec recorder handle - * \param channame channel name to change to - * \retval 0 success - * \retval <0 error - */ -extern int cmyth_recorder_set_channel(cmyth_recorder_t rec, - char *channame); - -extern int cmyth_recorder_change_color(cmyth_recorder_t rec, - cmyth_adjdir_t direction); - -extern int cmyth_recorder_change_brightness(cmyth_recorder_t rec, - cmyth_adjdir_t direction); - -extern int cmyth_recorder_change_contrast(cmyth_recorder_t rec, - cmyth_adjdir_t direction); - -extern int cmyth_recorder_change_hue(cmyth_recorder_t rec, - cmyth_adjdir_t direction); - -extern int cmyth_recorder_check_channel(cmyth_recorder_t rec, - char *channame); - -extern int cmyth_recorder_check_channel_prefix(cmyth_recorder_t rec, - char *channame); - -/** - * Request the current program info for a recorder. - * \param rec recorder handle - * \return program info handle - */ -extern cmyth_proginfo_t cmyth_recorder_get_cur_proginfo(cmyth_recorder_t rec); - -/** - * Request the next program info for a recorder. - * \param rec recorder handle - * \param current current program - * \param direction direction of next program - * \retval 0 success - * \retval <0 error - */ -extern cmyth_proginfo_t cmyth_recorder_get_next_proginfo( - cmyth_recorder_t rec, - cmyth_proginfo_t current, - cmyth_browsedir_t direction); - -extern int cmyth_recorder_get_input_name(cmyth_recorder_t rec, - char *name, - unsigned len); - -extern long long cmyth_recorder_seek(cmyth_recorder_t rec, - long long pos, - cmyth_whence_t whence, - long long curpos); - -extern int cmyth_recorder_spawn_chain_livetv(cmyth_recorder_t rec, char* channame); - -extern int cmyth_recorder_spawn_livetv(cmyth_recorder_t rec); - -extern int cmyth_recorder_start_stream(cmyth_recorder_t rec); - -extern int cmyth_recorder_end_stream(cmyth_recorder_t rec); -extern char*cmyth_recorder_get_filename(cmyth_recorder_t rec); -extern int cmyth_recorder_stop_livetv(cmyth_recorder_t rec); -extern int cmyth_recorder_done_ringbuf(cmyth_recorder_t rec); -extern int cmyth_recorder_get_recorder_id(cmyth_recorder_t rec); - -/* - * ----------------------------------------------------------------- - * Live TV Operations - * ----------------------------------------------------------------- - */ - -extern cmyth_livetv_chain_t cmyth_livetv_chain_create(char * chainid); - -extern cmyth_file_t cmyth_livetv_get_cur_file(cmyth_recorder_t rec); - -extern int cmyth_livetv_chain_switch(cmyth_recorder_t rec, int dir); - -extern int cmyth_livetv_chain_switch_last(cmyth_recorder_t rec); - -extern int cmyth_livetv_chain_update(cmyth_recorder_t rec, char * chainid, - int tcp_rcvbuf); - -extern cmyth_recorder_t cmyth_spawn_live_tv(cmyth_recorder_t rec, - unsigned buflen, - int tcp_rcvbuf, - void (*prog_update_callback)(cmyth_proginfo_t), - char ** err, char * channame); - -extern cmyth_recorder_t cmyth_livetv_chain_setup(cmyth_recorder_t old_rec, - int tcp_rcvbuf, - void (*prog_update_callback)(cmyth_proginfo_t)); - -extern int cmyth_livetv_get_block(cmyth_recorder_t rec, char *buf, - unsigned long len); - -extern int cmyth_livetv_select(cmyth_recorder_t rec, struct timeval *timeout); - -extern int cmyth_livetv_request_block(cmyth_recorder_t rec, unsigned long len); - -extern long long cmyth_livetv_seek(cmyth_recorder_t rec, - long long offset, int whence); - -extern int cmyth_livetv_read(cmyth_recorder_t rec, - char *buf, - unsigned long len); - -extern int cmyth_livetv_keep_recording(cmyth_recorder_t rec, cmyth_database_t db, int keep); - -extern int mythtv_new_livetv(void); -extern int cmyth_tuner_type_check(cmyth_database_t db, cmyth_recorder_t rec, int check_tuner_enabled); - -/* - * ----------------------------------------------------------------- - * Database Operations - * ----------------------------------------------------------------- - */ - -extern cmyth_database_t cmyth_database_init(char *host, char *db_name, char *user, char *pass); -extern cmyth_chanlist_t myth_tvguide_load_channels(cmyth_database_t db, - int sort_desc); -extern int cmyth_database_set_host(cmyth_database_t db, char *host); -extern int cmyth_database_set_user(cmyth_database_t db, char *user); -extern int cmyth_database_set_pass(cmyth_database_t db, char *pass); -extern int cmyth_database_set_name(cmyth_database_t db, char *name); - -/* - * ----------------------------------------------------------------- - * Ring Buffer Operations - * ----------------------------------------------------------------- - */ -extern char * cmyth_ringbuf_pathname(cmyth_recorder_t rec); - -extern cmyth_ringbuf_t cmyth_ringbuf_create(void); - -extern cmyth_recorder_t cmyth_ringbuf_setup(cmyth_recorder_t old_rec); - -extern int cmyth_ringbuf_request_block(cmyth_recorder_t rec, - unsigned long len); - -extern int cmyth_ringbuf_select(cmyth_recorder_t rec, struct timeval *timeout); - -extern int cmyth_ringbuf_get_block(cmyth_recorder_t rec, - char *buf, - unsigned long len); - -extern long long cmyth_ringbuf_seek(cmyth_recorder_t rec, - long long offset, - int whence); - -extern int cmyth_ringbuf_read(cmyth_recorder_t rec, - char *buf, - unsigned long len); -/* - * ----------------------------------------------------------------- - * Recorder Number Operations - * ----------------------------------------------------------------- - */ -extern cmyth_rec_num_t cmyth_rec_num_create(void); - -extern cmyth_rec_num_t cmyth_rec_num_get(char *host, - unsigned short port, - unsigned id); - -extern char *cmyth_rec_num_string(cmyth_rec_num_t rn); - -/* - * ----------------------------------------------------------------- - * Timestamp Operations - * ----------------------------------------------------------------- - */ -extern cmyth_timestamp_t cmyth_timestamp_create(void); - -extern cmyth_timestamp_t cmyth_timestamp_from_string(char *str); - -extern cmyth_timestamp_t cmyth_timestamp_from_unixtime(time_t l); - -extern time_t cmyth_timestamp_to_unixtime(cmyth_timestamp_t ts); - -extern int cmyth_timestamp_to_string(char *str, cmyth_timestamp_t ts); - -extern int cmyth_timestamp_to_isostring(char *str, cmyth_timestamp_t ts); - -extern int cmyth_timestamp_to_display_string(char *str, cmyth_timestamp_t ts, - int time_format_12); - -extern int cmyth_datetime_to_string(char *str, cmyth_timestamp_t ts); - -extern cmyth_timestamp_t cmyth_datetime_from_string(char *str); - -extern int cmyth_timestamp_compare(cmyth_timestamp_t ts1, - cmyth_timestamp_t ts2); - -/* - * ----------------------------------------------------------------- - * Key Frame Operations - * ----------------------------------------------------------------- - */ -extern cmyth_keyframe_t cmyth_keyframe_create(void); - -extern cmyth_keyframe_t cmyth_keyframe_tcmyth_keyframe_get( - unsigned long keynum, - unsigned long long pos); - -extern char *cmyth_keyframe_string(cmyth_keyframe_t kf); - -/* - * ----------------------------------------------------------------- - * Position Map Operations - * ----------------------------------------------------------------- - */ -extern cmyth_posmap_t cmyth_posmap_create(void); - -/* - * ----------------------------------------------------------------- - * Program Info Operations - * ----------------------------------------------------------------- - */ - -/** - * Program recording status. - */ -typedef enum { - RS_DELETED = -5, - RS_STOPPED = -4, - RS_RECORDED = -3, - RS_RECORDING = -2, - RS_WILL_RECORD = -1, - RS_DONT_RECORD = 1, - RS_PREVIOUS_RECORDING = 2, - RS_CURRENT_RECORDING = 3, - RS_EARLIER_RECORDING = 4, - RS_TOO_MANY_RECORDINGS = 5, - RS_CANCELLED = 6, - RS_CONFLICT = 7, - RS_LATER_SHOWING = 8, - RS_REPEAT = 9, - RS_LOW_DISKSPACE = 11, - RS_TUNER_BUSY = 12, -} cmyth_proginfo_rec_status_t; - -/** - * Create a new program info data structure. - * \return proginfo handle - */ -extern cmyth_proginfo_t cmyth_proginfo_create(void); - -extern int cmyth_proginfo_stop_recording(cmyth_conn_t control, - cmyth_proginfo_t prog); - -extern int cmyth_proginfo_check_recording(cmyth_conn_t control, - cmyth_proginfo_t prog); - -/** - * Delete a program. - * \param control backend control handle - * \param prog proginfo handle - * \retval 0 success - * \retval <0 error - */ -extern int cmyth_proginfo_delete_recording(cmyth_conn_t control, - cmyth_proginfo_t prog); - -/** - * Delete a program such that it may be recorded again. - * \param control backend control handle - * \param prog proginfo handle - * \retval 0 success - * \retval <0 error - */ -extern int cmyth_proginfo_forget_recording(cmyth_conn_t control, - cmyth_proginfo_t prog); - -extern int cmyth_proginfo_get_recorder_num(cmyth_conn_t control, - cmyth_rec_num_t rnum, - cmyth_proginfo_t prog); - -extern cmyth_proginfo_t cmyth_proginfo_get_from_basename(cmyth_conn_t control, - const char* basename); - -/** - * Retrieve the title of a program. - * \param prog proginfo handle - * \return null-terminated string - */ -extern char *cmyth_proginfo_title(cmyth_proginfo_t prog); - -/** - * Retrieve the subtitle of a program. - * \param prog proginfo handle - * \return null-terminated string - */ -extern char *cmyth_proginfo_subtitle(cmyth_proginfo_t prog); - -/** - * Retrieve the description of a program. - * \param prog proginfo handle - * \return null-terminated string - */ -extern char *cmyth_proginfo_description(cmyth_proginfo_t prog); - -/** - * Retrieve the season of a program. - * \param prog proginfo handle - * \return season - */ -extern unsigned short cmyth_proginfo_season(cmyth_proginfo_t prog); - -/** - * Retrieve the episode of a program. - * \param prog proginfo handle - * \return episode - */ -extern unsigned short cmyth_proginfo_episode(cmyth_proginfo_t prog); - -/** - * Retrieve the category of a program. - * \param prog proginfo handle - * \return null-terminated string - */ -extern char *cmyth_proginfo_category(cmyth_proginfo_t prog); - -/** - * Retrieve the channel number of a program. - * \param prog proginfo handle - * \return null-terminated string - */ -extern char *cmyth_proginfo_chanstr(cmyth_proginfo_t prog); - -/** - * Retrieve the channel name of a program. - * \param prog proginfo handle - * \return null-terminated string - */ -extern char *cmyth_proginfo_chansign(cmyth_proginfo_t prog); - -/** - * Retrieve the channel name of a program. - * \param prog proginfo handle - * \return null-terminated string - */ -extern char *cmyth_proginfo_channame(cmyth_proginfo_t prog); - -/** - * Retrieve the channel number of a program. - * \param prog proginfo handle - * \return channel number - */ -extern long cmyth_proginfo_chan_id(cmyth_proginfo_t prog); - -/** - * Retrieve the pathname of a program file. - * \param prog proginfo handle - * \return null-terminated string - */ -extern char *cmyth_proginfo_pathname(cmyth_proginfo_t prog); - -/** - * Retrieve the series ID of a program. - * \param prog proginfo handle - * \return null-terminated string - */ -extern char *cmyth_proginfo_seriesid(cmyth_proginfo_t prog); - -/** - * Retrieve the program ID of a program. - * \param prog proginfo handle - * \return null-terminated string - */ -extern char *cmyth_proginfo_programid(cmyth_proginfo_t prog); - -/** - * Retrieve the inetref of a program. - * \param prog proginfo handle - * \return null-terminated string - */ -extern char *cmyth_proginfo_inetref(cmyth_proginfo_t prog); - -/** - * Retrieve the critics rating (number of stars) of a program. - * \param prog proginfo handle - * \return null-terminated string - */ -extern char *cmyth_proginfo_stars(cmyth_proginfo_t prog); - -/** - * Retrieve the start time of a program. - * \param prog proginfo handle - * \return timestamp handle - */ -extern cmyth_timestamp_t cmyth_proginfo_rec_start(cmyth_proginfo_t prog); - -/** - * Retrieve the end time of a program. - * \param prog proginfo handle - * \return timestamp handle - */ -extern cmyth_timestamp_t cmyth_proginfo_rec_end(cmyth_proginfo_t prog); - -/** - * Retrieve the original air date of a program. - * \param prog proginfo handle - * \return timestamp handle - */ -extern cmyth_timestamp_t cmyth_proginfo_originalairdate(cmyth_proginfo_t prog); - -/** - * Retrieve the recording status of a program. - * \param prog proginfo handle - * \return recording status - */ -extern cmyth_proginfo_rec_status_t cmyth_proginfo_rec_status( - cmyth_proginfo_t prog); - -/** - * Retrieve the flags associated with a program. - * \param prog proginfo handle - * \return flags - */ -extern unsigned long cmyth_proginfo_flags( - cmyth_proginfo_t prog); - -/** - * Retrieve the size, in bytes, of a program. - * \param prog proginfo handle - * \return program length - */ -extern long long cmyth_proginfo_length(cmyth_proginfo_t prog); - -/** - * Retrieve the hostname of the MythTV backend that recorded a program. - * \param prog proginfo handle - * \return MythTV backend hostname - */ -extern char *cmyth_proginfo_host(cmyth_proginfo_t prog); - -extern int cmyth_proginfo_port(cmyth_proginfo_t prog); - -/** - * Determine if two proginfo handles refer to the same program. - * \param a proginfo handle a - * \param b proginfo handle b - * \retval 0 programs are the same - * \retval -1 programs are different - */ -extern int cmyth_proginfo_compare(cmyth_proginfo_t a, cmyth_proginfo_t b); - -/** - * Retrieve the program length in seconds. - * \param prog proginfo handle - * \return program length in seconds - */ -extern int cmyth_proginfo_length_sec(cmyth_proginfo_t prog); - -extern cmyth_proginfo_t cmyth_proginfo_get_detail(cmyth_conn_t control, - cmyth_proginfo_t p); - -/** - * Retrieve the start time of a program. - * \param prog proginfo handle - * \return timestamp handle - */ -extern cmyth_timestamp_t cmyth_proginfo_start(cmyth_proginfo_t prog); - -/** - * Retrieve the end time of a program. - * \param prog proginfo handle - * \return timestamp handle - */ -extern cmyth_timestamp_t cmyth_proginfo_end(cmyth_proginfo_t prog); - -/** - * Retrieve the card ID where the program was recorded. - * \param prog proginfo handle - * \return card ID - */ -extern long cmyth_proginfo_card_id(cmyth_proginfo_t prog); - -/** - * Retrieve the recording group of a program. - * \param prog proginfo handle - * \return null-terminated string - */ -extern char *cmyth_proginfo_recgroup(cmyth_proginfo_t prog); - -/** - * Retrieve the channel icon path this program info - * \param prog proginfo handle - * \return null-terminated string - */ -extern char *cmyth_proginfo_chanicon(cmyth_proginfo_t prog); - - -/** - * Retrieve the production year for this program info - * \param prog proginfo handle - * \return production year - */ -extern unsigned short cmyth_proginfo_year(cmyth_proginfo_t prog); - -/* - * ----------------------------------------------------------------- - * Program List Operations - * ----------------------------------------------------------------- - */ - -extern cmyth_proglist_t cmyth_proglist_create(void); - -extern cmyth_proglist_t cmyth_proglist_get_all_recorded(cmyth_conn_t control); - -extern cmyth_proglist_t cmyth_proglist_get_all_pending(cmyth_conn_t control); - -extern cmyth_proglist_t cmyth_proglist_get_all_scheduled(cmyth_conn_t control); - -extern cmyth_proglist_t cmyth_proglist_get_conflicting(cmyth_conn_t control); - -extern cmyth_proginfo_t cmyth_proglist_get_item(cmyth_proglist_t pl, - int index); - -extern int cmyth_proglist_delete_item(cmyth_proglist_t pl, - cmyth_proginfo_t prog); - -extern int cmyth_proglist_get_count(cmyth_proglist_t pl); - -extern int cmyth_proglist_sort(cmyth_proglist_t pl, int count, - cmyth_proglist_sort_t sort); - -/* - * ----------------------------------------------------------------- - * File Transfer Operations - * ----------------------------------------------------------------- - */ -extern cmyth_conn_t cmyth_file_data(cmyth_file_t file); - -extern unsigned long long cmyth_file_start(cmyth_file_t file); - -extern unsigned long long cmyth_file_length(cmyth_file_t file); - -extern int cmyth_file_get_block(cmyth_file_t file, char *buf, - unsigned long len); - -extern int cmyth_file_request_block(cmyth_file_t file, unsigned long len); - -extern long long cmyth_file_seek(cmyth_file_t file, - long long offset, int whence); - -extern int cmyth_file_select(cmyth_file_t file, struct timeval *timeout); - -extern void cmyth_file_set_closed_callback(cmyth_file_t file, - void (*callback)(cmyth_file_t)); - -extern int cmyth_file_read(cmyth_file_t file, - char *buf, - unsigned long len); -/* - * ----------------------------------------------------------------- - * Channel Operations - * ----------------------------------------------------------------- - */ - -extern long cmyth_channel_chanid(cmyth_channel_t channel); - -extern long cmyth_channel_channum(cmyth_channel_t channel); - -extern char * cmyth_channel_name(cmyth_channel_t channel); - -extern char * cmyth_channel_icon(cmyth_channel_t channel); - -extern int cmyth_channel_visible(cmyth_channel_t channel); - -extern cmyth_channel_t cmyth_chanlist_get_item(cmyth_chanlist_t pl, int index); - -extern int cmyth_chanlist_get_count(cmyth_chanlist_t pl); - -/* - * ----------------------------------------------------------------- - * Free Space Operations - * ----------------------------------------------------------------- - */ -extern cmyth_freespace_t cmyth_freespace_create(void); - -/* - * ------- - * Bookmark,Commercial Skip Operations - * ------- - */ -extern long long cmyth_get_bookmark(cmyth_conn_t conn, cmyth_proginfo_t prog); -extern int cmyth_get_bookmark_offset(cmyth_database_t db, long chanid, long long mark, char *starttime, int mode); -extern int cmyth_update_bookmark_setting(cmyth_database_t, cmyth_proginfo_t); -extern long long cmyth_get_bookmark_mark(cmyth_database_t, cmyth_proginfo_t, long long, int); -extern int cmyth_set_bookmark(cmyth_conn_t conn, cmyth_proginfo_t prog, - long long bookmark); -extern cmyth_commbreaklist_t cmyth_commbreaklist_create(void); -extern cmyth_commbreak_t cmyth_commbreak_create(void); -extern cmyth_commbreaklist_t cmyth_mysql_get_commbreaklist(cmyth_database_t db, cmyth_conn_t conn, cmyth_proginfo_t prog); -extern cmyth_commbreaklist_t cmyth_get_commbreaklist(cmyth_conn_t conn, cmyth_proginfo_t prog); -extern cmyth_commbreaklist_t cmyth_get_cutlist(cmyth_conn_t conn, cmyth_proginfo_t prog); -extern int cmyth_rcv_commbreaklist(cmyth_conn_t conn, int *err, cmyth_commbreaklist_t breaklist, int count); - -/* - * mysql info - */ - - -typedef struct cmyth_program { - int chanid; - char callsign[30]; - char name[84]; - int sourceid; - char title[150]; - char subtitle[150]; - char description[280]; - time_t starttime; - time_t endtime; - char programid[30]; - char seriesid[24]; - char category[84]; - int recording; - int rec_status; - int channum; - int event_flags; - int startoffset; - int endoffset; -}cmyth_program_t; - -typedef struct cmyth_recgrougs { - char recgroups[33]; -}cmyth_recgroups_t; - -extern int cmyth_mysql_get_recgroups(cmyth_database_t, cmyth_recgroups_t **); -extern int cmyth_mysql_delete_scheduled_recording(cmyth_database_t db, char * query); -extern int cmyth_mysql_insert_into_record(cmyth_database_t db, char * query, char * query1, char * query2, char *title, char * subtitle, char * description, char * callsign); - -extern char* cmyth_get_recordid_mysql(cmyth_database_t, int, char *, char *, char *, char *, char *); -extern int cmyth_get_offset_mysql(cmyth_database_t, int, char *, int, char *, char *, char *, char *, char *); - -extern int cmyth_mysql_get_prog_finder_char_title(cmyth_database_t db, cmyth_program_t **prog, time_t starttime, char *program_name); -extern int cmyth_mysql_get_prog_finder_time(cmyth_database_t db, cmyth_program_t **prog, time_t starttime, char *program_name); -extern int cmyth_mysql_get_guide(cmyth_database_t db, cmyth_program_t **prog, time_t starttime, time_t endtime); -extern int cmyth_mysql_testdb_connection(cmyth_database_t db,char **message); -extern int cmyth_schedule_recording(cmyth_conn_t conn, char * msg); -extern char * cmyth_mysql_escape_chars(cmyth_database_t db, char * string); -extern int cmyth_mysql_get_commbreak_list(cmyth_database_t db, int chanid, char * start_ts_dt, cmyth_commbreaklist_t breaklist, int conn_version); - -extern int cmyth_mysql_get_prev_recorded(cmyth_database_t db, cmyth_program_t **prog); - -extern int cmyth_get_delete_list(cmyth_conn_t, char *, cmyth_proglist_t); - -#define PROGRAM_ADJUST 3600 - -extern int cmyth_mythtv_remove_previous_recorded(cmyth_database_t db,char *query); - -extern cmyth_chanlist_t cmyth_mysql_get_chanlist(cmyth_database_t db); -#endif /* __CMYTH_H */ diff --git a/lib/cmyth/include/debug.h b/lib/cmyth/include/debug.h deleted file mode 100644 index 6a868bf5f7..0000000000 --- a/lib/cmyth/include/debug.h +++ /dev/null @@ -1,69 +0,0 @@ -/** \file debug.h - * A C library for generating and controlling debug output - */ - -#ifndef __CMYTH_DEBUG_H -#define __CMYTH_DEBUG_H - -#include <stdio.h> -#include <stdarg.h> -#include <string.h> - -typedef struct { - char *name; - int cur_level; - int (*selector)(int plevel, int slevel); - void (*msg_callback)(int level, char *msg); -} cmyth_debug_ctx_t; - -/** - * Make a static initializer for an cmyth_debug_ctx_t which provides a debug - * context for a subsystem. This is a macro. - * \param n subsystem name (a static string is fine) - * \param l initial debug level for the subsystem - * \param s custom selector function pointer (NULL is okay) - */ -#define CMYTH_DEBUG_CTX_INIT(n,l,s) { n, l, s, NULL } - -/** - * Set the debug level to be used for the subsystem - * \param ctx the subsystem debug context to use - * \param level the debug level for the subsystem - * \return an integer subsystem id used for future interaction - */ -static inline void -__cmyth_dbg_setlevel(cmyth_debug_ctx_t *ctx, int level) -{ - if (ctx != NULL) { - ctx->cur_level = level; - } -} - -/** - * Generate a debug message at a given debug level - * \param ctx the subsystem debug context to use - * \param level the debug level of the debug message - * \param fmt a printf style format string for the message - * \param ... arguments to the format - */ -static inline void -__cmyth_dbg(cmyth_debug_ctx_t *ctx, int level, char *fmt, va_list ap) -{ - char msg[4096]; - int len; - if (!ctx) { - return; - } - if ((ctx->selector && ctx->selector(level, ctx->cur_level)) || - (!ctx->selector && (level < ctx->cur_level))) { - len = snprintf(msg, sizeof(msg), "(%s)", ctx->name); - vsnprintf(msg + len, sizeof(msg)-len, fmt, ap); - if (ctx->msg_callback) { - ctx->msg_callback(level, msg); - } else { - fwrite(msg, strlen(msg), 1, stdout); - } - } -} - -#endif /* __CMYTH_DEBUG_H */ diff --git a/lib/cmyth/include/refmem/atomic.h b/lib/cmyth/include/refmem/atomic.h deleted file mode 100644 index 5c107f5845..0000000000 --- a/lib/cmyth/include/refmem/atomic.h +++ /dev/null @@ -1,164 +0,0 @@ -/* - * Copyright (C) 2004-2008, Eric Lund, Jon Gettler - * http://www.mvpmc.org/ - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -#ifndef __MVP_ATOMIC_H -#define __MVP_ATOMIC_H - -#ifdef __APPLE__ -#pragma GCC optimization_level 0 -#endif - -#ifdef _MSC_VER -#include <windows.h> -#endif -/** - * Atomically incremente a reference count variable. - * \param valp address of atomic variable - * \return incremented reference count - */ -typedef unsigned mvp_atomic_t; -static inline unsigned -__mvp_atomic_increment(mvp_atomic_t *valp) -{ - mvp_atomic_t __val; -#if defined __i486__ || defined __i586__ || defined __i686__ - __asm__ __volatile__( - "lock xaddl %0, (%1);" - " inc %0;" - : "=r" (__val) - : "r" (valp), "0" (0x1) - : "cc", "memory" - ); -#elif defined __i386__ - asm volatile (".byte 0xf0, 0x0f, 0xc1, 0x02" /*lock; xaddl %eax, (%edx) */ - : "=a" (__val) - : "0" (1), "m" (*valp), "d" (valp) - : "memory"); - /* on the x86 __val is the pre-increment value, so normalize it. */ - ++__val; -#elif defined __powerpc__ || defined __ppc__ - asm volatile ("1: lwarx %0,0,%1\n" - " addic. %0,%0,1\n" - " dcbt %0,%1\n" - " stwcx. %0,0,%1\n" - " bne- 1b\n" - " isync\n" - : "=&r" (__val) - : "r" (valp) - : "cc", "memory"); -#elif defined _MSC_VER - __val = InterlockedIncrement(valp); -#else - /* - * Don't know how to atomic increment for a generic architecture - * so punt and just increment the value. - */ -#ifdef _WIN32 - #pragma message("unknown architecture, atomic increment is not..."); -#else - #warning unknown architecture, atomic increment is not... -#endif - __val = ++(*valp); -#endif - return __val; -} - -/** - * Atomically decrement a reference count variable. - * \param valp address of atomic variable - * \return decremented reference count - */ -static inline unsigned -__mvp_atomic_decrement(mvp_atomic_t *valp) -{ - mvp_atomic_t __val; -#if defined __i486__ || defined __i586__ || defined __i686__ - __asm__ __volatile__( - "lock xaddl %0, (%1);" - " dec %0;" - : "=r" (__val) - : "r" (valp), "0" (0x1) - : "cc", "memory" - ); -#elif defined __i386__ - asm volatile (".byte 0xf0, 0x0f, 0xc1, 0x02" /*lock; xaddl %eax, (%edx) */ - : "=a" (__val) - : "0" (-1), "m" (*valp), "d" (valp) - : "memory"); - /* __val is the pre-decrement value, so normalize it */ - --__val; -#elif defined __powerpc__ || defined __ppc__ - asm volatile ("1: lwarx %0,0,%1\n" - " addic. %0,%0,-1\n" - " dcbt %0,%1\n" - " stwcx. %0,0,%1\n" - " bne- 1b\n" - " isync\n" - : "=&r" (__val) - : "r" (valp) - : "cc", "memory"); -#elif defined __sparcv9__ - mvp_atomic_t __newval, __oldval = (*valp); - do - { - __newval = __oldval - 1; - __asm__ ("cas [%4], %2, %0" - : "=r" (__oldval), "=m" (*valp) - : "r" (__oldval), "m" (*valp), "r"((valp)), "0" (__newval)); - } - while (__newval != __oldval); - /* The value for __val is in '__oldval' */ - __val = __oldval; -#elif defined _MSC_VER - __val = InterlockedDecrement(valp); -#else - /* - * Don't know how to atomic decrement for a generic architecture - * so punt and just decrement the value. - */ -//#warning unknown architecture, atomic decrement is not... - __val = --(*valp); -#endif - return __val; -} -#define mvp_atomic_inc __mvp_atomic_inc -static inline int mvp_atomic_inc(mvp_atomic_t *a) { - return __mvp_atomic_increment(a); -}; - -#define mvp_atomic_dec __mvp_atomic_dec -static inline int mvp_atomic_dec(mvp_atomic_t *a) { - return __mvp_atomic_decrement(a); -}; - -#define mvp_atomic_dec_and_test __mvp_atomic_dec_and_test -static inline int mvp_atomic_dec_and_test(mvp_atomic_t *a) { - return (__mvp_atomic_decrement(a) == 0); -}; - -#define mvp_atomic_set __mvp_atomic_set -static inline void mvp_atomic_set(mvp_atomic_t *a, unsigned val) { - *a = val; -}; - -#ifdef __APPLE__ -#pragma GCC optimization_level reset -#endif - -#endif /* __MVP_ATOMIC_H */ diff --git a/lib/cmyth/include/refmem/refmem.h b/lib/cmyth/include/refmem/refmem.h deleted file mode 100644 index cc8155cba4..0000000000 --- a/lib/cmyth/include/refmem/refmem.h +++ /dev/null @@ -1,98 +0,0 @@ -/* - * Copyright (C) 2004-2012, Eric Lund, Jon Gettler - * http://www.mvpmc.org/ - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -/** \file refmem.h - * A C library for managing reference counted memory allocations - */ - -#ifndef __REFMEM_H -#define __REFMEM_H - -/* - * ----------------------------------------------------------------- - * Types - * ----------------------------------------------------------------- - */ - -/** - * Release a reference to allocated memory. - * \param p allocated memory - */ -extern void ref_release(void *p); - -/** - * Add a reference to allocated memory. - * \param p allocated memory - * \return new reference - */ -extern void *ref_hold(void *p); - -/** - * Duplicate a string using reference counted memory. - * \param str string to duplicate - * \return reference to the duplicated string - */ -extern char *ref_strdup(char *str); - -/** - * Allocate reference counted memory. (PRIVATE) - * \param len allocation size - * \param file filename - * \param func function name - * \param line line number - * \return reference counted memory - */ -extern void *__ref_alloc(size_t len, - const char *file, - const char *func, - int line); - -/** - * Allocate a block of reference counted memory. - * \param len allocation size - * \return pointer to reference counted memory block - */ -#if defined(DEBUG) -#define ref_alloc(l) (__ref_alloc((l), __FILE__, __FUNCTION__, __LINE__)) -#else -#define ref_alloc(l) (__ref_alloc((l), (char *)0, (char *)0, 0)) -#endif -/** - * Reallocate reference counted memory. - * \param p allocated memory - * \param len new allocation size - * \return reference counted memory - */ -extern void *ref_realloc(void *p, size_t len); - -typedef void (*ref_destroy_t)(void *p); - -/** - * Add a destroy callback for reference counted memory. - * \param block allocated memory - * \param func destroy function - */ -extern void ref_set_destroy(void *block, ref_destroy_t func); - -/** - * Print allocation information to stdout. - */ -extern void ref_alloc_show(void); - -#endif /* __REFMEM_H */ diff --git a/lib/cmyth/libcmyth/Makefile b/lib/cmyth/libcmyth/Makefile deleted file mode 100644 index 9b37fbf143..0000000000 --- a/lib/cmyth/libcmyth/Makefile +++ /dev/null @@ -1,9 +0,0 @@ -INCLUDES=-I. -I../include - -SRCS=bookmark.c commbreak.c connection.c event.c file.c freespace.c keyframe.c livetv.c mysql_query.c mythtv_mysql.c posmap.c proginfo.c proglist.c rec_num.c recorder.c ringbuf.c socket.c timestamp.c debug.c utf8tolatin1.c - -LIB=libcmyth.a - -include ../../../Makefile.include --include $(patsubst %.cpp,%.P,$(patsubst %.c,%.P,$(SRCS))) - diff --git a/lib/cmyth/libcmyth/bookmark.c b/lib/cmyth/libcmyth/bookmark.c deleted file mode 100644 index 43529697e0..0000000000 --- a/lib/cmyth/libcmyth/bookmark.c +++ /dev/null @@ -1,121 +0,0 @@ -/* - * Copyright (C) 2005-2009, Jon Gettler - * http://www.mvpmc.org/ - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <inttypes.h> -#include <errno.h> -#include <cmyth_local.h> - - -long long cmyth_get_bookmark(cmyth_conn_t conn, cmyth_proginfo_t prog) -{ - char *buf; - unsigned int len = CMYTH_TIMESTAMP_LEN + CMYTH_LONGLONG_LEN + 18; - int err; - long long ret; - int count; - int64_t ll; - int r; - char start_ts_dt[CMYTH_TIMESTAMP_LEN + 1]; - cmyth_datetime_to_string(start_ts_dt, prog->proginfo_rec_start_ts); - buf = alloca(len); - if (!buf) { - return -ENOMEM; - } - sprintf(buf,"%s %ld %s","QUERY_BOOKMARK",prog->proginfo_chanId, - start_ts_dt); - pthread_mutex_lock(&mutex); - if ((err = cmyth_send_message(conn,buf)) < 0) { - cmyth_dbg(CMYTH_DBG_ERROR, - "%s: cmyth_send_message() failed (%d)\n", - __FUNCTION__, err); - ret = err; - goto out; - } - count = cmyth_rcv_length(conn); - if (count < 0) { - cmyth_dbg(CMYTH_DBG_ERROR, - "%s: cmyth_rcv_length() failed (%d)\n", - __FUNCTION__, count); - ret = count; - goto out; - } - if ((r=cmyth_rcv_int64(conn, &err, &ll, count)) < 0) { - cmyth_dbg(CMYTH_DBG_ERROR, - "%s: cmyth_rcv_int64() failed (%d)\n", - __FUNCTION__, r); - ret = err; - goto out; - } - - ret = ll; - out: - pthread_mutex_unlock(&mutex); - return ret; -} - -int cmyth_set_bookmark(cmyth_conn_t conn, cmyth_proginfo_t prog, long long bookmark) -{ - char *buf; - unsigned int len = CMYTH_TIMESTAMP_LEN + CMYTH_LONGLONG_LEN * 2 + 18; - char resultstr[3]; - int r,err; - int ret; - int count; - char start_ts_dt[CMYTH_TIMESTAMP_LEN + 1]; - cmyth_datetime_to_string(start_ts_dt, prog->proginfo_rec_start_ts); - buf = alloca(len); - if (!buf) { - return -ENOMEM; - } - if (conn->conn_version >= 66) { - /* - * Since protocol 66 mythbackend expects a single 64 bit integer rather than two 32 bit - * hi and lo integers. - */ - sprintf(buf, "SET_BOOKMARK %ld %s %"PRIu64, prog->proginfo_chanId, - start_ts_dt, (int64_t)bookmark); - } - else { - sprintf(buf, "SET_BOOKMARK %ld %s %d %d", prog->proginfo_chanId, - start_ts_dt, (int32_t)(bookmark >> 32), (int32_t)(bookmark & 0xffffffff)); - } - pthread_mutex_lock(&mutex); - if ((err = cmyth_send_message(conn,buf)) < 0) { - cmyth_dbg(CMYTH_DBG_ERROR, - "%s: cmyth_send_message() failed (%d)\n", - __FUNCTION__, err); - ret = err; - goto out; - } - count = cmyth_rcv_length(conn); - if ((r=cmyth_rcv_string(conn,&err,resultstr,sizeof(resultstr),count)) < 0) { - cmyth_dbg(CMYTH_DBG_ERROR, - "%s: cmyth_rcv_string() failed (%d)\n", - __FUNCTION__, count); - ret = count; - goto out; - } - ret = (strncmp(resultstr,"OK",2) == 0); - out: - pthread_mutex_unlock(&mutex); - return ret; -} diff --git a/lib/cmyth/libcmyth/cmyth_local.h b/lib/cmyth/libcmyth/cmyth_local.h deleted file mode 100644 index a7e535901d..0000000000 --- a/lib/cmyth/libcmyth/cmyth_local.h +++ /dev/null @@ -1,445 +0,0 @@ -/* - * Copyright (C) 2004-2012, Eric Lund, Jon Gettler - * http://www.mvpmc.org/ - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -/** - * \file cmyth_local.h - * Local definitions which are internal to libcmyth. - */ - -#ifndef __CMYTH_LOCAL_H -#define __CMYTH_LOCAL_H - -#include <stdio.h> -#include <stdlib.h> -#if !defined(_MSC_VER) -#include <sys/time.h> -#endif -#include <refmem/refmem.h> -#include <cmyth/cmyth.h> -#include <time.h> -#include <stdint.h> -#include <mysql/mysql.h> - -#if defined(_MSC_VER) -#include "cmyth_msc.h" -#else -#include <unistd.h> -#include <sys/types.h> -#include <sys/socket.h> -#include <sys/select.h> -#include <netinet/in.h> -#include <netdb.h> -#include <arpa/inet.h> -#include <pthread.h> - -typedef int cmyth_socket_t; -#define closesocket(fd) close(fd) -#endif /* _MSC_VER */ - -#define mutex __cmyth_mutex -extern pthread_mutex_t mutex; - -/* - * Some useful constants - */ -#define CMYTH_LONGLONG_LEN (sizeof("-18446744073709551616") - 1) -#define CMYTH_LONG_LEN (sizeof("-4294967296") - 1) -#define CMYTH_SHORT_LEN (sizeof("-65536") - 1) -#define CMYTH_BYTE_LEN (sizeof("-256") - 1) -#define CMYTH_TIMESTAMP_LEN (sizeof("YYYY-MM-DDTHH:MM:SS") - 1) -#define CMYTH_DATESTAMP_LEN (sizeof("YYYY-MM-DD") - 1) -#define CMYTH_UTC_LEN (sizeof("1240120680") - 1) -#define CMYTH_COMMBREAK_START 4 -#define CMYTH_COMMBREAK_END 5 -#define CMYTH_CUTLIST_START 1 -#define CMYTH_CUTLIST_END 0 - -/** - * MythTV backend connection - */ -struct cmyth_conn { - cmyth_socket_t conn_fd; /**< socket file descriptor */ - unsigned char *conn_buf; /**< connection buffer */ - int conn_buflen; /**< buffer size */ - int conn_len; /**< amount of data in buffer */ - int conn_pos; /**< current position in buffer */ - unsigned long conn_version; /**< protocol version */ - volatile int conn_hang; /**< is connection stuck? */ - int conn_tcp_rcvbuf;/**< TCP receive buffer size */ -}; - -/* Sergio: Added to support new livetv protocol */ -struct cmyth_livetv_chain { - char *chainid; - int chain_ct; - int chain_switch_on_create; - int chain_current; - void (*prog_update_callback)(cmyth_proginfo_t prog); - cmyth_proginfo_t *progs; - char **chain_urls; - cmyth_file_t *chain_files; /* File pointers for the urls */ -}; - -/* Sergio: Added to clean up database interaction */ -struct cmyth_database { - char * db_host; - char * db_user; - char * db_pass; - char * db_name; - MYSQL * mysql; -}; - -/* Sergio: Added to clean up channel list handling */ -struct cmyth_channel { - long chanid; - int channum; - char chanstr[10]; - long cardids;/* A bit array of recorders/tuners supporting the channel */ - char *callsign; - char *name; - char *icon; - int visible; -}; - -struct cmyth_chanlist { - cmyth_channel_t *chanlist_list; - int chanlist_count; -}; - -/* Sergio: Added to support the tvguide functionality */ -struct cmyth_tvguide_progs { - cmyth_program_t * progs; - int count; - int alloc; -}; - -struct cmyth_recorder { - unsigned rec_have_stream; - unsigned rec_id; - char *rec_server; - int rec_port; - cmyth_ringbuf_t rec_ring; - cmyth_conn_t rec_conn; - /* Sergio: Added to support new livetv protocol */ - cmyth_livetv_chain_t rec_livetv_chain; - cmyth_file_t rec_livetv_file; - double rec_framerate; -}; - -/** - * MythTV file connection - */ -struct cmyth_file { - cmyth_conn_t file_data; /**< backend connection */ - long file_id; /**< file identifier */ - /** callback when close is completed */ - void (*closed_callback)(cmyth_file_t file); - uint64_t file_start; /**< file start offest */ - uint64_t file_length; /**< file length */ - uint64_t file_pos; /**< current file position */ - uint64_t file_req; /**< current file position requested */ - cmyth_conn_t file_control; /**< master backend connection */ -}; - -struct cmyth_ringbuf { - cmyth_conn_t conn_data; - long file_id; - char *ringbuf_url; - uint64_t ringbuf_size; - uint64_t file_length; - uint64_t file_pos; - uint64_t ringbuf_fill; - char *ringbuf_hostname; - int ringbuf_port; -}; - -struct cmyth_rec_num { - char *recnum_host; - unsigned short recnum_port; - unsigned recnum_id; -}; - -struct cmyth_keyframe { - unsigned long keyframe_number; - uint64_t keyframe_pos; -}; - -struct cmyth_posmap { - unsigned posmap_count; - struct cmyth_keyframe **posmap_list; -}; - -struct cmyth_freespace { - uint64_t freespace_total; - uint64_t freespace_used; -}; - -struct cmyth_timestamp { - unsigned long timestamp_year; - unsigned long timestamp_month; - unsigned long timestamp_day; - unsigned long timestamp_hour; - unsigned long timestamp_minute; - unsigned long timestamp_second; - int timestamp_isdst; -}; - -struct cmyth_proginfo { - char *proginfo_title; - char *proginfo_subtitle; - char *proginfo_description; - unsigned short proginfo_season; /* new in V67 */ - unsigned short proginfo_episode; /* new in V67 */ - char *proginfo_category; - long proginfo_chanId; - char *proginfo_chanstr; - char *proginfo_chansign; - char *proginfo_channame; /* Deprecated in V8, simulated for compat. */ - char *proginfo_chanicon; /* New in V8 */ - char *proginfo_url; - int64_t proginfo_Length; - cmyth_timestamp_t proginfo_start_ts; - cmyth_timestamp_t proginfo_end_ts; - unsigned long proginfo_conflicting; /* Deprecated in V8, always 0 */ - char *proginfo_unknown_0; /* May be new 'conflicting' in V8 */ - unsigned long proginfo_recording; - unsigned long proginfo_override; - char *proginfo_hostname; - long proginfo_source_id; /* ??? in V8 */ - long proginfo_card_id; /* ??? in V8 */ - long proginfo_input_id; /* ??? in V8 */ - char *proginfo_rec_priority; /* ??? in V8 */ - long proginfo_rec_status; /* ??? in V8 */ - unsigned long proginfo_record_id; /* ??? in V8 */ - unsigned long proginfo_rec_type; /* ??? in V8 */ - unsigned long proginfo_rec_dups; /* ??? in V8 */ - unsigned long proginfo_unknown_1; /* new in V8 */ - cmyth_timestamp_t proginfo_rec_start_ts; - cmyth_timestamp_t proginfo_rec_end_ts; - unsigned long proginfo_repeat; /* ??? in V8 */ - unsigned long proginfo_program_flags; - char *proginfo_rec_profile; /* new in V8 */ - char *proginfo_recgroup; /* new in V8 */ - char *proginfo_chancommfree; /* new in V8 */ - char *proginfo_chan_output_filters; /* new in V8 */ - char *proginfo_seriesid; /* new in V8 */ - char *proginfo_programid; /* new in V12 */ - char *proginfo_inetref; /* new in V67 */ - cmyth_timestamp_t proginfo_lastmodified; /* new in V12 */ - char *proginfo_stars; /* new in V12 */ - cmyth_timestamp_t proginfo_originalairdate; /* new in V12 */ - char *proginfo_pathname; - int proginfo_port; - unsigned long proginfo_hasairdate; - char *proginfo_host; - unsigned long proginfo_version; - char *proginfo_playgroup; /* new in v18 */ - char *proginfo_recpriority_2; /* new in V25 */ - long proginfo_parentid; /* new in V31 */ - char *proginfo_storagegroup; /* new in v32 */ - unsigned long proginfo_audioproperties; /* new in v35 */ - unsigned long proginfo_videoproperties; /* new in v35 */ - unsigned long proginfo_subtitletype; /* new in v35 */ - unsigned short proginfo_year; /* new in v43 */ -}; - -struct cmyth_proglist { - cmyth_proginfo_t *proglist_list; - long proglist_count; -}; - -/* - * Private funtions in socket.c - */ -#define cmyth_send_message __cmyth_send_message -extern int cmyth_send_message(cmyth_conn_t conn, char *request); - -#define cmyth_rcv_length __cmyth_rcv_length -extern int cmyth_rcv_length(cmyth_conn_t conn); - -#define cmyth_rcv_string __cmyth_rcv_string -extern int cmyth_rcv_string(cmyth_conn_t conn, - int *err, - char *buf, int buflen, - int count); - -#define cmyth_rcv_okay __cmyth_rcv_okay -extern int cmyth_rcv_okay(cmyth_conn_t conn, char *ok); - -#define cmyth_rcv_version __cmyth_rcv_version -extern int cmyth_rcv_version(cmyth_conn_t conn, unsigned long *vers); - -#define cmyth_rcv_byte __cmyth_rcv_byte -extern int cmyth_rcv_byte(cmyth_conn_t conn, int *err, char *buf, int count); - -#define cmyth_rcv_short __cmyth_rcv_short -extern int cmyth_rcv_short(cmyth_conn_t conn, int *err, short *buf, int count); - -#define cmyth_rcv_long __cmyth_rcv_long -extern int cmyth_rcv_long(cmyth_conn_t conn, int *err, long *buf, int count); -#define cmyth_rcv_u_long(c, e, b, n) cmyth_rcv_long(c, e, (long*)b, n) - -#define cmyth_rcv_old_int64 __cmyth_rcv_old_int64 -extern int cmyth_rcv_old_int64(cmyth_conn_t conn, int *err, int64_t *buf, - int count); - -#define cmyth_rcv_new_int64 __cmyth_rcv_new_int64 -extern int cmyth_rcv_new_int64(cmyth_conn_t conn, int *err, int64_t *buf, - int count, int forced); - -#define cmyth_rcv_old_uint64 __cmyth_rcv_old_uint64 -extern int cmyth_rcv_old_uint64(cmyth_conn_t conn, int *err, uint64_t *buf, - int count); - -#define cmyth_rcv_new_uint64 __cmyth_rcv_new_uint64 -extern int cmyth_rcv_new_uint64(cmyth_conn_t conn, int *err, uint64_t *buf, - int count, int forced); - -#define cmyth_rcv_int64(conn, err, buf, count) \ - cmyth_rcv_new_int64(conn, err, buf, count, 0) - -#define cmyth_rcv_uint64(conn, err, buf, count) \ - cmyth_rcv_new_uint64(conn, err, buf, count, 0) - -#define cmyth_rcv_ubyte __cmyth_rcv_ubyte -extern int cmyth_rcv_ubyte(cmyth_conn_t conn, int *err, unsigned char *buf, - int count); - -#define cmyth_rcv_ushort __cmyth_rcv_ushort -extern int cmyth_rcv_ushort(cmyth_conn_t conn, int *err, unsigned short *buf, - int count); - -#define cmyth_rcv_ulong __cmyth_rcv_ulong -extern int cmyth_rcv_ulong(cmyth_conn_t conn, int *err, unsigned long *buf, - int count); - -#define cmyth_rcv_ulong_long __cmyth_rcv_ulong_long -extern int cmyth_rcv_ulong_long(cmyth_conn_t conn, - int *err, - unsigned long long *buf, - int count); - -#define cmyth_rcv_data __cmyth_rcv_data -extern int cmyth_rcv_data(cmyth_conn_t conn, int *err, unsigned char *buf, - int count); - -#define cmyth_rcv_timestamp __cmyth_rcv_timestamp -extern int cmyth_rcv_timestamp(cmyth_conn_t conn, int *err, - cmyth_timestamp_t *ts_p, - int count); -#define cmyth_rcv_datetime __cmyth_rcv_datetime -extern int cmyth_rcv_datetime(cmyth_conn_t conn, int *err, - cmyth_timestamp_t *ts_p, - int count); - -#define cmyth_rcv_proginfo __cmyth_rcv_proginfo -extern int cmyth_rcv_proginfo(cmyth_conn_t conn, int *err, - cmyth_proginfo_t buf, - int count); - -#define cmyth_rcv_chaninfo __cmyth_rcv_chaninfo -extern int cmyth_rcv_chaninfo(cmyth_conn_t conn, int *err, - cmyth_proginfo_t buf, - int count); - -#define cmyth_rcv_proglist __cmyth_rcv_proglist -extern int cmyth_rcv_proglist(cmyth_conn_t conn, int *err, - cmyth_proglist_t buf, - int count); - -#define cmyth_rcv_keyframe __cmyth_rcv_keyframe -extern int cmyth_rcv_keyframe(cmyth_conn_t conn, int *err, - cmyth_keyframe_t buf, - int count); - -#define cmyth_rcv_freespace __cmyth_rcv_freespace -extern int cmyth_rcv_freespace(cmyth_conn_t conn, int *err, - cmyth_freespace_t buf, - int count); - -#define cmyth_rcv_recorder __cmyth_rcv_recorder -extern int cmyth_rcv_recorder(cmyth_conn_t conn, int *err, - cmyth_recorder_t buf, - int count); - -#define cmyth_rcv_ringbuf __cmyth_rcv_ringbuf -extern int cmyth_rcv_ringbuf(cmyth_conn_t conn, int *err, cmyth_ringbuf_t buf, - int count); -#define cmyth_datetime_to_dbstring __cmyth_datetime_to_dbstring -extern int cmyth_datetime_to_dbstring(char *str, cmyth_timestamp_t ts); - -/* - * From proginfo.c - */ -#define cmyth_proginfo_string __cmyth_proginfo_string -extern char *cmyth_proginfo_string(cmyth_proginfo_t prog); - -#define cmyth_chaninfo_string __cmyth_chaninfo_string -extern char *cmyth_chaninfo_string(cmyth_proginfo_t prog); - -/* - * From file.c - */ -#define cmyth_file_create __cmyth_file_create -extern cmyth_file_t cmyth_file_create(cmyth_conn_t control); - -/* - * From timestamp.c - */ -#define cmyth_timestamp_diff __cmyth_timestamp_diff -extern int cmyth_timestamp_diff(cmyth_timestamp_t, cmyth_timestamp_t); - -/* - * From mythtv_mysql.c - */ - -extern MYSQL * cmyth_db_get_connection(cmyth_database_t db); - - -/* - * From mysql_query.c - */ - -typedef struct cmyth_mysql_query_s cmyth_mysql_query_t; - -extern cmyth_mysql_query_t * cmyth_mysql_query_create(cmyth_database_t db, const char * query_string); - -extern void cmyth_mysql_query_reset(cmyth_mysql_query_t *query); - -extern int cmyth_mysql_query_param_long(cmyth_mysql_query_t * query,long param); - -extern int cmyth_mysql_query_param_ulong(cmyth_mysql_query_t * query,unsigned long param); - -extern int cmyth_mysql_query_param_int(cmyth_mysql_query_t * query,int param); - -extern int cmyth_mysql_query_param_uint(cmyth_mysql_query_t * query,int param); - -extern int cmyth_mysql_query_param_unixtime(cmyth_mysql_query_t * query, time_t param); - -extern int cmyth_mysql_query_param_str(cmyth_mysql_query_t * query, const char *param); - -extern char * cmyth_mysql_query_string(cmyth_mysql_query_t * query); - -extern MYSQL_RES * cmyth_mysql_query_result(cmyth_mysql_query_t * query); - -extern int cmyth_mysql_query(cmyth_mysql_query_t * query); - -extern char* cmyth_utf8tolatin1(char* s); - -#endif /* __CMYTH_LOCAL_H */ diff --git a/lib/cmyth/libcmyth/cmyth_msc.h b/lib/cmyth/libcmyth/cmyth_msc.h deleted file mode 100644 index 78e0c92f98..0000000000 --- a/lib/cmyth/libcmyth/cmyth_msc.h +++ /dev/null @@ -1,79 +0,0 @@ -/* - * Copyright (C) 2012, Jon Gettler - * http://www.mvpmc.org/ - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -/** - * \file cmyth_msc.h - * Contain most of the Microsoft related differences in a single file. - */ - -#ifndef __CMYTH_MSC_H -#define __CMYTH_MSC_H - -#if !defined(_MSC_VER) -#error This file may only be included on windows builds! -#endif /* !_MSC_VER */ - -#include <malloc.h> -#include <winsock2.h> -#include <Ws2tcpip.h> - -#pragma warning(disable:4267) -#pragma warning(disable:4996) - -#define pthread_mutex_lock(a) -#define pthread_mutex_unlock(a) -#define PTHREAD_MUTEX_INITIALIZER NULL; -typedef void *pthread_mutex_t; - -#undef ECANCELED -#undef ETIMEDOUT - -#define ECANCELED -1 -#define ETIMEDOUT -1 -#define SHUT_RDWR SD_BOTH - -typedef SOCKET cmyth_socket_t; -typedef int socklen_t; - -#define snprintf _snprintf -#define sleep(a) Sleep(a*1000) -#define usleep(a) Sleep(a/1000) - -static inline struct tm *localtime_r(const time_t * clock, struct tm *result) -{ - struct tm *data; - if (!clock || !result) - return NULL; - data = localtime(clock); - if (!data) - return NULL; - memcpy(result, data, sizeof(*result)); - return result; -} - -static inline __int64 atoll(const char *s) -{ - __int64 value; - if (sscanf(s, "%I64d", &value)) - return value; - else - return 0; -} - -#endif /* __CMYTH_MSC_H */ diff --git a/lib/cmyth/libcmyth/commbreak.c b/lib/cmyth/libcmyth/commbreak.c deleted file mode 100644 index ad5391f1d0..0000000000 --- a/lib/cmyth/libcmyth/commbreak.c +++ /dev/null @@ -1,305 +0,0 @@ -/* - * Copyright (C) 2005-2012, Jon Gettler - * http://www.mvpmc.org/ - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <errno.h> -#include <cmyth_local.h> - -static void -cmyth_commbreaklist_destroy(cmyth_commbreaklist_t cbl) -{ - int i; - - cmyth_dbg(CMYTH_DBG_DEBUG, "%s\n", __FUNCTION__); - if (!cbl) { - return; - } - for (i = 0; i < cbl->commbreak_count; ++i) { - if (cbl->commbreak_list[i]) { - ref_release(cbl->commbreak_list[i]); - } - cbl->commbreak_list[i] = NULL; - } - if (cbl->commbreak_list) { - free(cbl->commbreak_list); - } -} - -cmyth_commbreaklist_t -cmyth_commbreaklist_create(void) -{ - cmyth_commbreaklist_t ret; - - cmyth_dbg(CMYTH_DBG_DEBUG, "%s\n", __FUNCTION__); - ret = ref_alloc(sizeof(*ret)); - if (!ret) { - return(NULL); - } - ref_set_destroy(ret, (ref_destroy_t)cmyth_commbreaklist_destroy); - - ret->commbreak_list = NULL; - ret->commbreak_count = 0; - return ret; -} - -void -cmyth_commbreak_destroy(cmyth_commbreak_t b) -{ - cmyth_dbg(CMYTH_DBG_DEBUG, "%s {\n", __FUNCTION__); - if (!b) { - cmyth_dbg(CMYTH_DBG_DEBUG, "%s }!a\n", __FUNCTION__); - return; - } - cmyth_dbg(CMYTH_DBG_DEBUG, "%s }\n", __FUNCTION__); -} - -cmyth_commbreak_t -cmyth_commbreak_create(void) -{ - cmyth_commbreak_t ret = ref_alloc(sizeof(*ret)); - - cmyth_dbg(CMYTH_DBG_DEBUG, "%s {\n", __FUNCTION__); - if (!ret) { - cmyth_dbg(CMYTH_DBG_DEBUG, "%s }!\n", __FUNCTION__); - return NULL; - } - ref_set_destroy(ret, (ref_destroy_t)cmyth_commbreak_destroy); - - ret->start_mark = 0; - ret->start_offset = 0; - ret->end_mark = 0; - ret->end_offset = 0; - - cmyth_dbg(CMYTH_DBG_DEBUG, "%s }\n", __FUNCTION__); - return ret; -} - -cmyth_commbreaklist_t -cmyth_get_commbreaklist(cmyth_conn_t conn, cmyth_proginfo_t prog) -{ - unsigned int len = CMYTH_UTC_LEN + CMYTH_LONGLONG_LEN + 19; - int err; - int count; - char *buf; - int r; - - cmyth_commbreaklist_t breaklist = cmyth_commbreaklist_create(); - - buf = alloca(len); - if (!buf) { - return breaklist; - } - - sprintf(buf,"%s %ld %i", "QUERY_COMMBREAK", prog->proginfo_chanId, - (int)cmyth_timestamp_to_unixtime(prog->proginfo_rec_start_ts)); - pthread_mutex_lock(&mutex); - if ((err = cmyth_send_message(conn, buf)) < 0) { - cmyth_dbg(CMYTH_DBG_ERROR, - "%s: cmyth_send_message() failed (%d)\n", - __FUNCTION__, err); - goto out; - } - - count = cmyth_rcv_length(conn); - if (count < 0) { - cmyth_dbg(CMYTH_DBG_ERROR, - "%s: cmyth_rcv_length() failed (%d)\n", - __FUNCTION__, count); - goto out; - } - - if ((r = cmyth_rcv_commbreaklist(conn, &err, breaklist, count)) < 0) { - cmyth_dbg(CMYTH_DBG_ERROR, - "%s: cmyth_rcv_string() failed (%d)\n", - __FUNCTION__, r); - goto out; - } - - out: - pthread_mutex_unlock(&mutex); - return breaklist; -} - -cmyth_commbreaklist_t -cmyth_get_cutlist(cmyth_conn_t conn, cmyth_proginfo_t prog) -{ - unsigned int len = CMYTH_UTC_LEN + CMYTH_LONGLONG_LEN + 17; - int err; - int count; - char *buf; - int r; - - cmyth_commbreaklist_t breaklist = cmyth_commbreaklist_create(); - - buf = alloca(len); - if (!buf) { - return breaklist; - } - - sprintf(buf,"%s %ld %i", "QUERY_CUTLIST", prog->proginfo_chanId, - (int)cmyth_timestamp_to_unixtime(prog->proginfo_rec_start_ts)); - - if ((err = cmyth_send_message(conn, buf)) < 0) { - cmyth_dbg(CMYTH_DBG_ERROR, - "%s: cmyth_send_message() failed (%d)\n", - __FUNCTION__, err); - goto out; - } - - count = cmyth_rcv_length(conn); - if (count < 0) { - cmyth_dbg(CMYTH_DBG_ERROR, - "%s: cmyth_rcv_length() failed (%d)\n", - __FUNCTION__, count); - goto out; - } - - if ((r = cmyth_rcv_commbreaklist(conn, &err, breaklist, count)) < 0) { - cmyth_dbg(CMYTH_DBG_ERROR, - "%s: cmyth_rcv_string() failed (%d)\n", - __FUNCTION__, r); - goto out; - } - - out: - pthread_mutex_unlock(&mutex); - return breaklist; -} - -int cmyth_rcv_commbreaklist(cmyth_conn_t conn, int *err, - cmyth_commbreaklist_t breaklist, int count) -{ - int consumed; - int total = 0; - long rows; - int64_t mark; - long long start = -1; - char *failed = NULL; - cmyth_commbreak_t commbreak; - unsigned short type; - unsigned short start_type; - int i; - - if (count <= 0) { - *err = EINVAL; - return 0; - } - - /* - * Get number of rows - */ - consumed = cmyth_rcv_long(conn, err, &rows, count); - count -= consumed; - total += consumed; - if (*err) { - failed = "cmyth_rcv_long"; - goto fail; - } - - if (rows < 0) { - cmyth_dbg(CMYTH_DBG_DEBUG, "%s: no commercial breaks found.\n", - __FUNCTION__); - return 0; - } - - for (i = 0; i < rows; i++) { - consumed = cmyth_rcv_ushort(conn, err, &type, count); - count -= consumed; - total += consumed; - if (*err) { - failed = "cmyth_rcv_ushort"; - goto fail; - } - - consumed = cmyth_rcv_int64(conn, err, &mark, count); - count -= consumed; - total += consumed; - if (*err) { - failed = "cmyth_rcv_long long"; - goto fail; - } - if (type == CMYTH_COMMBREAK_START || type == CMYTH_CUTLIST_START) { - start = mark; - start_type = type; - } else if (type == CMYTH_COMMBREAK_END || type == CMYTH_CUTLIST_END) { - if (start >= 0 && - ((type == CMYTH_COMMBREAK_END && start_type == CMYTH_COMMBREAK_START) - || (type == CMYTH_CUTLIST_END && start_type == CMYTH_CUTLIST_START))) - { - commbreak = cmyth_commbreak_create(); - commbreak->start_mark = start; - commbreak->end_mark = mark; - start = -1; - breaklist->commbreak_list = realloc(breaklist->commbreak_list, - (++breaklist->commbreak_count) * sizeof(cmyth_commbreak_t)); - breaklist->commbreak_list[breaklist->commbreak_count - 1] = commbreak; - } else { - cmyth_dbg(CMYTH_DBG_WARN, - "%s: ignoring 'end' marker without a 'start' marker at %lld\n", - __FUNCTION__, type, mark); - } - } else { - cmyth_dbg(CMYTH_DBG_WARN, - "%s: type (%d) is not a COMMBREAK or CUTLIST\n", - __FUNCTION__, type); - } - } - - /* - * If the last entry is a start marker then it doesn't have an associated end marker. In this - * case we choose to simply ignore it. Another option is to put in a really large fake end marker - * but that may cause strange seek behaviour in a client application. - */ - - return total; - - fail: - cmyth_dbg(CMYTH_DBG_ERROR, "%s: %s() failed (%d)\n", - __FUNCTION__, failed, *err); - return total; -} - -cmyth_commbreaklist_t -cmyth_mysql_get_commbreaklist(cmyth_database_t db, cmyth_conn_t conn, cmyth_proginfo_t prog) -{ - cmyth_commbreaklist_t breaklist = cmyth_commbreaklist_create(); - char start_ts_dt[CMYTH_TIMESTAMP_LEN + 1]; - int r; - - cmyth_timestamp_to_display_string(start_ts_dt, prog->proginfo_rec_start_ts, 0); - pthread_mutex_lock(&mutex); - if ((r=cmyth_mysql_get_commbreak_list(db, prog->proginfo_chanId, start_ts_dt, breaklist, conn->conn_version)) < 0) { - cmyth_dbg(CMYTH_DBG_ERROR, - "%s: cmyth_mysql_get_commbreak_list() failed (%d)\n", - __FUNCTION__, r); - goto out; - } - - fprintf(stderr, "Found %li commercial breaks for current program.\n", breaklist->commbreak_count); - if (r != breaklist->commbreak_count) { - fprintf(stderr, "commbreak error. Setting number of commercial breaks to zero\n"); - cmyth_dbg(CMYTH_DBG_ERROR, "%s - returned rows=%d commbreak_count=%li\n",__FUNCTION__, r,breaklist->commbreak_count); - breaklist->commbreak_count = 0; - } - out: - pthread_mutex_unlock(&mutex); - return breaklist; -} diff --git a/lib/cmyth/libcmyth/connection.c b/lib/cmyth/libcmyth/connection.c deleted file mode 100644 index 16fe074bd1..0000000000 --- a/lib/cmyth/libcmyth/connection.c +++ /dev/null @@ -1,1422 +0,0 @@ -/* - * Copyright (C) 2004-2012, Eric Lund, Jon Gettler - * http://www.mvpmc.org/ - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -/** - * \file connection.c - * Functions to handle creating connections to a MythTV backend and - * interacting with those connections. - */ - -#include <stdlib.h> -#include <stdio.h> -#include <errno.h> -#include <string.h> -#include <signal.h> -#include <cmyth_local.h> - -static char * cmyth_conn_get_setting_unlocked(cmyth_conn_t conn, const char* hostname, const char* setting); - -pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER; - -typedef struct { - unsigned int version; - char token[9]; // 8 characters + the terminating NULL character -} myth_protomap_t; - -static myth_protomap_t protomap[] = { - {62, "78B5631E"}, - {63, "3875641D"}, - {64, "8675309J"}, - {65, "D2BB94C2"}, - {66, "0C0FFEE0"}, - {67, "0G0G0G0"}, - {68, "90094EAD"}, - {69, "63835135"}, - {70, "53153836"}, - {71, "05e82186"}, - {72, "D78EFD6F"}, - {73, "D7FE8D6F"}, - {0, ""} -}; - -/* - * cmyth_conn_destroy(cmyth_conn_t conn) - * - * Scope: PRIVATE (static) - * - * Description - * - * Tear down and release storage associated with a connection. This - * should only be called by cmyth_conn_release(). All others should - * call ref_release() to release a connection. - * - * Return Value: - * - * None. - */ -static void -cmyth_conn_destroy(cmyth_conn_t conn) -{ - cmyth_dbg(CMYTH_DBG_DEBUG, "%s {\n", __FUNCTION__); - if (!conn) { - cmyth_dbg(CMYTH_DBG_DEBUG, "%s } !\n", __FUNCTION__); - return; - } - if (conn->conn_buf) { - free(conn->conn_buf); - } - if (conn->conn_fd >= 0) { - cmyth_dbg(CMYTH_DBG_PROTO, - "%s: shutdown and close connection fd = %d\n", - __FUNCTION__, conn->conn_fd); - shutdown(conn->conn_fd, SHUT_RDWR); - closesocket(conn->conn_fd); - } - cmyth_dbg(CMYTH_DBG_DEBUG, "%s }\n", __FUNCTION__); -} - -/* - * cmyth_conn_create(void) - * - * Scope: PRIVATE (static) - * - * Description - * - * Allocate and initialize a cmyth_conn_t structure. This should only - * be called by cmyth_connect(), which establishes a connection. - * - * Return Value: - * - * Success: A non-NULL cmyth_conn_t (this type is a pointer) - * - * Failure: A NULL cmyth_conn_t - */ -static cmyth_conn_t -cmyth_conn_create(void) -{ - cmyth_conn_t ret = ref_alloc(sizeof(*ret)); - - cmyth_dbg(CMYTH_DBG_DEBUG, "%s {\n", __FUNCTION__); - if (!ret) { - cmyth_dbg(CMYTH_DBG_DEBUG, "%s }!\n", __FUNCTION__); - return NULL; - } - ref_set_destroy(ret, (ref_destroy_t)cmyth_conn_destroy); - - ret->conn_fd = -1; - ret->conn_buf = NULL; - ret->conn_len = 0; - ret->conn_buflen = 0; - ret->conn_pos = 0; - ret->conn_hang = 0; - cmyth_dbg(CMYTH_DBG_DEBUG, "%s }\n", __FUNCTION__); - return ret; -} - -/* - * cmyth_connect(char *server, unsigned short port, unsigned buflen) - * - * Scope: PUBLIC - * - * Description - * - * Create a connection to the port specified by 'port' on the - * server named 'server'. This creates a data structure called a - * cmyth_conn_t which contains the file descriptor for a socket, a - * buffer for reading from the socket, and information used to manage - * offsets in that buffer. The buffer length is specified in 'buflen'. - * - * The returned connection has a single reference. The connection - * will be shut down and closed when the last reference is released - * using ref_release(). - * - * Return Value: - * - * Success: A non-NULL cmyth_conn_t (this type is a pointer) - * - * Failure: A NULL cmyth_conn_t - */ -static char my_hostname[128]; -static volatile cmyth_socket_t my_fd; - -static void -sighandler(int sig) -{ - /* - * XXX: This is not thread safe... - */ - closesocket(my_fd); - my_fd = -1; -} - -static cmyth_conn_t -cmyth_connect_addr(struct addrinfo* addr, unsigned buflen, - int tcp_rcvbuf) -{ - cmyth_conn_t ret = NULL; - unsigned char *buf = NULL; - cmyth_socket_t fd; -#ifndef _MSC_VER - void (*old_sighandler)(int); - int old_alarm; -#endif - int temp; - socklen_t size; - char namebuf[NI_MAXHOST], portbuf[NI_MAXSERV]; - - fd = socket(addr->ai_family, addr->ai_socktype, addr->ai_protocol); - if (fd < 0) { - cmyth_dbg(CMYTH_DBG_ERROR, "%s: cannot create socket (%d)\n", - __FUNCTION__, errno); - return NULL; - } - - /* - * Set a 4kb tcp receive buffer on all myth protocol sockets, - * otherwise we risk the connection hanging. Oddly, setting this - * on the data sockets causes stuttering during playback. - */ - if (tcp_rcvbuf == 0) - tcp_rcvbuf = 4096; - - temp = tcp_rcvbuf; - size = sizeof(temp); - setsockopt(fd, SOL_SOCKET, SO_RCVBUF, (void*)&temp, size); - if(getsockopt(fd, SOL_SOCKET, SO_RCVBUF, (void*)&temp, &size)) { - cmyth_dbg(CMYTH_DBG_ERROR, "%s: could not get rcvbuf from socket(%d)\n", - __FUNCTION__, errno); - temp = tcp_rcvbuf; - } - tcp_rcvbuf = temp; - - if (getnameinfo(addr->ai_addr, addr->ai_addrlen, namebuf, sizeof(namebuf), portbuf, sizeof(portbuf), NI_NUMERICHOST)) { - strcpy(namebuf, "[unknown]"); - strcpy(portbuf, "[unknown]"); - } - - cmyth_dbg(CMYTH_DBG_PROTO, "%s: connecting to %s:%s fd = %d\n", - __FUNCTION__, namebuf, portbuf, fd); -#ifndef _MSC_VER - old_sighandler = signal(SIGALRM, sighandler); - old_alarm = alarm(5); -#endif - my_fd = fd; - if (connect(fd, addr->ai_addr, addr->ai_addrlen) < 0) { - cmyth_dbg(CMYTH_DBG_ERROR, - "%s: connect failed on port %s to '%s' (%d)\n", - __FUNCTION__, portbuf, namebuf, errno); - closesocket(fd); -#ifndef _MSC_VER - signal(SIGALRM, old_sighandler); - alarm(old_alarm); -#endif - return NULL; - } - my_fd = -1; -#ifndef _MSC_VER - signal(SIGALRM, old_sighandler); - alarm(old_alarm); -#endif - - if ((my_hostname[0] == '\0') && - (gethostname(my_hostname, sizeof(my_hostname)) < 0)) { - cmyth_dbg(CMYTH_DBG_ERROR, "%s: gethostname failed (%d)\n", - __FUNCTION__, errno); - goto shut; - } - - /* - * Okay, we are connected. Now is a good time to allocate some - * resources. - */ - ret = cmyth_conn_create(); - if (!ret) { - cmyth_dbg(CMYTH_DBG_ERROR, "%s: cmyth_conn_create() failed\n", - __FUNCTION__); - goto shut; - } - buf = malloc(buflen * sizeof(unsigned char)); - if (!buf) { - cmyth_dbg(CMYTH_DBG_ERROR, - "%s:- malloc(%d) failed allocating buf\n", - __FUNCTION__, buflen * sizeof(unsigned char *)); - goto shut; - } - ret->conn_fd = fd; - ret->conn_buflen = buflen; - ret->conn_buf = buf; - ret->conn_len = 0; - ret->conn_pos = 0; - ret->conn_version = 8; - ret->conn_tcp_rcvbuf = tcp_rcvbuf; - return ret; - - shut: - if (ret) { - ref_release(ret); - } - - cmyth_dbg(CMYTH_DBG_PROTO, "%s: error connecting to " - "%s, shutdown and close fd = %d\n", - __FUNCTION__, namebuf, fd); - shutdown(fd, 2); - closesocket(fd); - return NULL; -} - -static cmyth_conn_t -cmyth_connect(char *server, unsigned short port, unsigned buflen, - int tcp_rcvbuf) -{ - struct addrinfo hints; - struct addrinfo *result, *addr; - char service[33]; - int res; - cmyth_conn_t conn = NULL; - - memset(&hints, 0, sizeof(hints)); - hints.ai_family = AF_UNSPEC; - hints.ai_socktype = SOCK_STREAM; - hints.ai_protocol = IPPROTO_TCP; - sprintf(service, "%d", port); - - res = getaddrinfo(server, service, &hints, &result); - if(res) { - switch(res) { - case EAI_NONAME: - cmyth_dbg(CMYTH_DBG_ERROR,"%s:- The specified host is unknown\n", - __FUNCTION__); - break; - - case EAI_FAIL: - cmyth_dbg(CMYTH_DBG_ERROR,"%s:- A non-recoverable failure in name resolution occurred\n", - __FUNCTION__); - break; - - case EAI_MEMORY: - cmyth_dbg(CMYTH_DBG_ERROR,"%s:- A memory allocation failure occurred\n", - __FUNCTION__); - break; - - case EAI_AGAIN: - cmyth_dbg(CMYTH_DBG_ERROR,"%s:- A temporary error occurred on an authoritative name server\n", - __FUNCTION__); - break; - - default: - cmyth_dbg(CMYTH_DBG_ERROR,"%s:- Unknown error %d\n", - __FUNCTION__, res); - break; - } - return NULL; - } - - for (addr = result; addr; addr = addr->ai_next) { - conn = cmyth_connect_addr(addr, buflen, tcp_rcvbuf); - if (conn) - break; - } - - freeaddrinfo(result); - return conn; -} - -static cmyth_conn_t -cmyth_conn_connect(char *server, unsigned short port, unsigned buflen, - int tcp_rcvbuf, int event) -{ - cmyth_conn_t conn; - char announcement[256]; - unsigned long tmp_ver; - int attempt = 0; - - top: - conn = cmyth_connect(server, port, buflen, tcp_rcvbuf); - if (!conn) { - cmyth_dbg(CMYTH_DBG_ERROR, - "%s: cmyth_connect(%s, %d, %d) failed\n", - __FUNCTION__, server, port, buflen); - return NULL; - } - - /* - * Find out what the Myth Protocol Version is for this connection. - * Loop around until we get agreement from the server. - */ - if (attempt == 0) - tmp_ver = conn->conn_version; - conn->conn_version = tmp_ver; - - /* - * Myth 0.23.1 (Myth 0.23 + fixes) introduced an out of sequence protocol version number (23056) - * due to the next protocol version number having already been bumped in trunk. - * - * http://www.mythtv.org/wiki/Myth_Protocol - */ - if (tmp_ver >= 62 && tmp_ver != 23056) { // Treat protocol version number 23056 the same as protocol 56 - myth_protomap_t *map = protomap; - while (map->version != 0 && map->version != tmp_ver) - map++; - if (map->version == 0) { - cmyth_dbg(CMYTH_DBG_ERROR, - "%s: failed to connect with any version\n", - __FUNCTION__); - goto shut; - } - sprintf(announcement, "MYTH_PROTO_VERSION %ld %s", conn->conn_version, map->token); - } else { - sprintf(announcement, "MYTH_PROTO_VERSION %ld", conn->conn_version); - } - if (cmyth_send_message(conn, announcement) < 0) { - cmyth_dbg(CMYTH_DBG_ERROR, - "%s: cmyth_send_message('%s') failed\n", - __FUNCTION__, announcement); - goto shut; - } - if (cmyth_rcv_version(conn, &tmp_ver) < 0) { - cmyth_dbg(CMYTH_DBG_ERROR, - "%s: cmyth_rcv_version() failed\n", - __FUNCTION__); - goto shut; - } - cmyth_dbg(CMYTH_DBG_ERROR, - "%s: asked for version %ld, got version %ld\n", - __FUNCTION__, conn->conn_version, tmp_ver); - if (conn->conn_version != tmp_ver) { - if (attempt == 1) { - cmyth_dbg(CMYTH_DBG_ERROR, - "%s: failed to connect with any version\n", - __FUNCTION__); - goto shut; - } - attempt = 1; - ref_release(conn); - goto top; - } - cmyth_dbg(CMYTH_DBG_PROTO, "%s: agreed on Version %ld protocol\n", - __FUNCTION__, conn->conn_version); - - sprintf(announcement, "ANN Playback %s %d", my_hostname, event); - if (cmyth_send_message(conn, announcement) < 0) { - cmyth_dbg(CMYTH_DBG_ERROR, - "%s: cmyth_send_message('%s') failed\n", - __FUNCTION__, announcement); - goto shut; - } - if (cmyth_rcv_okay(conn, "OK") < 0) { - cmyth_dbg(CMYTH_DBG_ERROR, "%s: cmyth_rcv_okay() failed\n", - __FUNCTION__); - goto shut; - } - - /* - * All of the downstream code in libcmyth assumes a monotonically increasing version number. - * This was not the case for Myth 0.23.1 (0.23 + fixes) where protocol version number 23056 - * was used since 57 had already been used in trunk. - * - * Convert from protocol version number 23056 to version number 56 so subsequent code within - * libcmyth uses the same logic for the 23056 protocol as would be used for protocol version 56. - */ - if (conn->conn_version == 23056) { - conn->conn_version = 56; - } - - return conn; - - shut: - ref_release(conn); - return NULL; -} - -/* - * cmyth_conn_connect_ctrl(char *server, unsigned short port, unsigned buflen) - * - * Scope: PUBLIC - * - * Description: - * - * Create a connection for use as a control connection within the - * MythTV protocol. Return a pointer to the newly created connection. - * The connection is returned held, and may be released using - * ref_release(). - * - * Return Value: - * - * Success: Non-NULL cmyth_conn_t (this is a pointer type) - * - * Failure: NULL cmyth_conn_t - */ -cmyth_conn_t -cmyth_conn_connect_ctrl(char *server, unsigned short port, unsigned buflen, - int tcp_rcvbuf) -{ - cmyth_conn_t ret; - - cmyth_dbg(CMYTH_DBG_PROTO, "%s: connecting control connection\n", - __FUNCTION__); - ret = cmyth_conn_connect(server, port, buflen, tcp_rcvbuf, 0); - cmyth_dbg(CMYTH_DBG_PROTO, - "%s: done connecting control connection ret = %p\n", - __FUNCTION__, ret); - return ret; -} - -cmyth_conn_t -cmyth_conn_connect_event(char *server, unsigned short port, unsigned buflen, - int tcp_rcvbuf) -{ - cmyth_conn_t ret; - cmyth_dbg(CMYTH_DBG_PROTO, "%s: connecting event channel connection\n", - __FUNCTION__); - ret = cmyth_conn_connect(server, port, buflen, tcp_rcvbuf, 1); - cmyth_dbg(CMYTH_DBG_PROTO, - "%s: done connecting event channel connection ret = %p\n", - __FUNCTION__, ret); - return ret; -} - -/* - * cmyth_conn_connect_file(char *server, unsigned short port, unsigned buflen - * cmyth_proginfo_t prog) - * - * Scope: PUBLIC - * - * Description: - * - * Create a file structure containing a data connection for use - * transfering a file within the MythTV protocol. Return a pointer to - * the newly created file structure. The connection in the file - * structure is returned held as is the file structure itself. The - * connection will be released when the file structure is released. - * The file structure can be released using ref_release(). - * - * Return Value: - * - * Success: Non-NULL cmyth_file_t (this is a pointer type) - * - * Failure: NULL cmyth_file_t - */ -cmyth_file_t -cmyth_conn_connect_file(cmyth_proginfo_t prog, cmyth_conn_t control, - unsigned buflen, int tcp_rcvbuf) -{ - cmyth_conn_t conn = NULL; - char *announcement = NULL; - char *myth_host = NULL; - char reply[16]; - int err = 0; - int count = 0; - int r; - int ann_size = sizeof("ANN FileTransfer 0[]:[][]:[]"); - cmyth_file_t ret = NULL; - - if (!prog) { - cmyth_dbg(CMYTH_DBG_ERROR, "%s: prog is NULL\n", __FUNCTION__); - goto shut; - } - if (!prog->proginfo_host) { - cmyth_dbg(CMYTH_DBG_ERROR, "%s: prog host is NULL\n", - __FUNCTION__); - goto shut; - } - if (!prog->proginfo_pathname) { - cmyth_dbg(CMYTH_DBG_ERROR, "%s: prog has no pathname in it\n", - __FUNCTION__); - goto shut; - } - ret = cmyth_file_create(control); - if (!ret) { - cmyth_dbg(CMYTH_DBG_ERROR, "%s: cmyth_file_create() failed\n", - __FUNCTION__); - goto shut; - } - cmyth_dbg(CMYTH_DBG_PROTO, "%s: connecting data connection\n", - __FUNCTION__); - if (control->conn_version >= 17) { - myth_host = cmyth_conn_get_setting_unlocked(control, prog->proginfo_host, - "BackendServerIP"); - if (myth_host && (strcmp(myth_host, "-1") == 0)) { - ref_release(myth_host); - myth_host = NULL; - } - } - if (!myth_host) { - cmyth_dbg(CMYTH_DBG_PROTO, - "%s: BackendServerIP setting not found. Using proginfo_host: %s\n", - __FUNCTION__, prog->proginfo_host); - myth_host = ref_alloc(strlen(prog->proginfo_host) + 1); - strcpy(myth_host, prog->proginfo_host); - } - conn = cmyth_connect(myth_host, prog->proginfo_port, - buflen, tcp_rcvbuf); - cmyth_dbg(CMYTH_DBG_PROTO, - "%s: done connecting data connection, conn = %d\n", - __FUNCTION__, conn); - if (!conn) { - cmyth_dbg(CMYTH_DBG_ERROR, - "%s: cmyth_connect(%s, %d, %d) failed\n", - __FUNCTION__, - myth_host, prog->proginfo_port, buflen); - goto shut; - } - /* - * Explicitly set the conn version to the control version as cmyth_connect() doesn't and some of - * the cmyth_rcv_* functions expect it to be the same as the protocol version used by mythbackend. - */ - conn->conn_version = control->conn_version; - - ann_size += strlen(prog->proginfo_pathname) + strlen(my_hostname); - announcement = malloc(ann_size); - if (!announcement) { - cmyth_dbg(CMYTH_DBG_ERROR, - "%s: malloc(%d) failed for announcement\n", - __FUNCTION__, ann_size); - goto shut; - } - if (control->conn_version >= 44) { - sprintf(announcement, "ANN FileTransfer %s 0[]:[]%s[]:[]", // write = false - my_hostname, prog->proginfo_pathname); - } - else { - sprintf(announcement, "ANN FileTransfer %s[]:[]%s", - my_hostname, prog->proginfo_pathname); - } - - if (cmyth_send_message(conn, announcement) < 0) { - cmyth_dbg(CMYTH_DBG_ERROR, - "%s: cmyth_send_message('%s') failed\n", - __FUNCTION__, announcement); - goto shut; - } - ret->file_data = ref_hold(conn); - count = cmyth_rcv_length(conn); - if (count < 0) { - cmyth_dbg(CMYTH_DBG_ERROR, - "%s: cmyth_rcv_length() failed (%d)\n", - __FUNCTION__, count); - goto shut; - } - reply[sizeof(reply) - 1] = '\0'; - r = cmyth_rcv_string(conn, &err, reply, sizeof(reply) - 1, count); - if (err != 0) { - cmyth_dbg(CMYTH_DBG_ERROR, - "%s: cmyth_rcv_string() failed (%d)\n", - __FUNCTION__, err); - goto shut; - } - if (strcmp(reply, "OK") != 0) { - cmyth_dbg(CMYTH_DBG_ERROR, "%s: reply ('%s') is not 'OK'\n", - __FUNCTION__, reply); - goto shut; - } - count -= r; - r = cmyth_rcv_long(conn, &err, &ret->file_id, count); - if (err) { - cmyth_dbg(CMYTH_DBG_ERROR, - "%s: (id) cmyth_rcv_long() failed (%d)\n", - __FUNCTION__, err); - goto shut; - } - count -= r; - r = cmyth_rcv_uint64(conn, &err, &ret->file_length, count); - if (err) { - cmyth_dbg(CMYTH_DBG_ERROR, - "%s: (length) cmyth_rcv_uint64() failed (%d)\n", - __FUNCTION__, err); - goto shut; - } - count -= r; - if (count != 0) { - cmyth_dbg(CMYTH_DBG_ERROR, "%s: %d leftover bytes\n", - __FUNCTION__, count); - } - free(announcement); - ref_release(conn); - ref_release(myth_host); - return ret; - - shut: - if (announcement) { - free(announcement); - } - ref_release(ret); - ref_release(conn); - ref_release(myth_host); - return NULL; -} - -/* - * cmyth_conn_connect_path(char* path, cmyth_conn_t control, - * unsigned buflen, int tcp_rcvbuf) - * - * Scope: PUBLIC - * - * Description: - * - * Create a file structure containing a data connection for use - * transfering a file within the MythTV protocol. Return a pointer to - * the newly created file structure. The connection in the file - * structure is returned held as is the file structure itself. The - * connection will be released when the file structure is released. - * The file structure can be released using ref_release(). - * - * Return Value: - * - * Success: Non-NULL cmyth_file_t (this is a pointer type) - * - * Failure: NULL cmyth_file_t - */ -cmyth_file_t -cmyth_conn_connect_path(char* path, cmyth_conn_t control, - unsigned buflen, int tcp_rcvbuf) -{ - cmyth_conn_t conn = NULL; - char *announcement = NULL; - char reply[16]; - char host[256]; - int err = 0; - int count = 0; - int r, port; - int ann_size = sizeof("ANN FileTransfer 0[]:[][]:[]"); - struct sockaddr_in addr; - socklen_t addr_size = sizeof(addr); - cmyth_file_t ret = NULL; - - if (getpeername(control->conn_fd, (struct sockaddr*)&addr, &addr_size)<0) { - cmyth_dbg(CMYTH_DBG_ERROR, "%s: getpeername() failed\n", - __FUNCTION__); - goto shut; - } - - inet_ntop(addr.sin_family, &addr.sin_addr, host, sizeof(host)); - port = ntohs(addr.sin_port); - - ret = cmyth_file_create(control); - if (!ret) { - cmyth_dbg(CMYTH_DBG_ERROR, "%s: cmyth_file_create() failed\n", - __FUNCTION__); - goto shut; - } - - cmyth_dbg(CMYTH_DBG_PROTO, "%s: connecting data connection\n", - __FUNCTION__); - conn = cmyth_connect(host, port, buflen, tcp_rcvbuf); - cmyth_dbg(CMYTH_DBG_PROTO, - "%s: done connecting data connection, conn = %p\n", - __FUNCTION__, conn); - if (!conn) { - cmyth_dbg(CMYTH_DBG_ERROR, - "%s: cmyth_connect(%s, %d, %d) failed\n", - __FUNCTION__, host, port, buflen); - goto shut; - } - /* - * Explicitly set the conn version to the control version as cmyth_connect() doesn't and some of - * the cmyth_rcv_* functions expect it to be the same as the protocol version used by mythbackend. - */ - conn->conn_version = control->conn_version; - - ann_size += strlen(path) + strlen(my_hostname); - announcement = malloc(ann_size); - if (!announcement) { - cmyth_dbg(CMYTH_DBG_ERROR, - "%s: malloc(%d) failed for announcement\n", - __FUNCTION__, ann_size); - goto shut; - } - if (control->conn_version >= 44) { - sprintf(announcement, "ANN FileTransfer %s 0[]:[]%s[]:[]", // write = false - my_hostname, path); - } - else { - sprintf(announcement, "ANN FileTransfer %s[]:[]%s", - my_hostname, path); - } - if (cmyth_send_message(conn, announcement) < 0) { - cmyth_dbg(CMYTH_DBG_ERROR, - "%s: cmyth_send_message('%s') failed\n", - __FUNCTION__, announcement); - goto shut; - } - ret->file_data = ref_hold(conn); - count = cmyth_rcv_length(conn); - if (count < 0) { - cmyth_dbg(CMYTH_DBG_ERROR, - "%s: cmyth_rcv_length() failed (%d)\n", - __FUNCTION__, count); - goto shut; - } - reply[sizeof(reply) - 1] = '\0'; - r = cmyth_rcv_string(conn, &err, reply, sizeof(reply) - 1, count); - if (err != 0) { - cmyth_dbg(CMYTH_DBG_ERROR, - "%s: cmyth_rcv_string() failed (%d)\n", - __FUNCTION__, err); - goto shut; - } - if (strcmp(reply, "OK") != 0) { - cmyth_dbg(CMYTH_DBG_ERROR, "%s: reply ('%s') is not 'OK'\n", - __FUNCTION__, reply); - goto shut; - } - count -= r; - r = cmyth_rcv_long(conn, &err, &ret->file_id, count); - if (err) { - cmyth_dbg(CMYTH_DBG_ERROR, - "%s: (id) cmyth_rcv_long() failed (%d)\n", - __FUNCTION__, err); - goto shut; - } - count -= r; - r = cmyth_rcv_uint64(conn, &err, &ret->file_length, count); - if (err) { - cmyth_dbg(CMYTH_DBG_ERROR, - "%s: (length) cmyth_rcv_uint64() failed (%d)\n", - __FUNCTION__, err); - goto shut; - } - count -= r; - free(announcement); - ref_release(conn); - return ret; - - shut: - if (announcement) { - free(announcement); - } - ref_release(ret); - ref_release(conn); - return NULL; -} - -/* - * cmyth_conn_connect_ring(char *server, unsigned short port, unsigned buflen - * cmyth_recorder_t rec) - * - * Scope: PUBLIC - * - * Description: - * - * Create a new ring buffer connection for use transferring live-tv - * using the MythTV protocol. Return a pointer to the newly created - * ring buffer connection. The ring buffer connection is returned - * held, and may be released using ref_release(). - * - * Return Value: - * - * Success: Non-NULL cmyth_conn_t (this is a pointer type) - * - * Failure: NULL cmyth_conn_t - */ -int -cmyth_conn_connect_ring(cmyth_recorder_t rec, unsigned buflen, int tcp_rcvbuf) -{ - cmyth_conn_t conn; - char *announcement; - int ann_size = sizeof("ANN RingBuffer "); - char *server; - unsigned short port; - - if (!rec) { - cmyth_dbg(CMYTH_DBG_ERROR, "%s: rec is NULL\n", __FUNCTION__); - return -1; - } - - server = rec->rec_server; - port = rec->rec_port; - - cmyth_dbg(CMYTH_DBG_PROTO, "%s: connecting ringbuffer\n", - __FUNCTION__); - conn = cmyth_connect(server, port, buflen, tcp_rcvbuf); - cmyth_dbg(CMYTH_DBG_PROTO, - "%s: connecting ringbuffer, conn = %p\n", - __FUNCTION__, conn); - if (!conn) { - cmyth_dbg(CMYTH_DBG_ERROR, - "%s: cmyth_connect(%s, %d, %d) failed\n", - __FUNCTION__, server, port, buflen); - return -1; - } - - ann_size += CMYTH_LONG_LEN + strlen(my_hostname); - announcement = malloc(ann_size); - if (!announcement) { - cmyth_dbg(CMYTH_DBG_ERROR, - "%s: malloc(%d) failed for announcement\n", - __FUNCTION__, ann_size); - goto shut; - } - sprintf(announcement, - "ANN RingBuffer %s %d", my_hostname, rec->rec_id); - if (cmyth_send_message(conn, announcement) < 0) { - cmyth_dbg(CMYTH_DBG_ERROR, - "%s: cmyth_send_message('%s') failed\n", - __FUNCTION__, announcement); - free(announcement); - goto shut; - } - free(announcement); - if (cmyth_rcv_okay(conn, "OK") < 0) { - cmyth_dbg(CMYTH_DBG_ERROR, "%s: cmyth_rcv_okay() failed\n", - __FUNCTION__); - goto shut; - } - - rec->rec_ring->conn_data = conn; - return 0; - - shut: - ref_release(conn); - return -1; -} - -int -cmyth_conn_connect_recorder(cmyth_recorder_t rec, unsigned buflen, - int tcp_rcvbuf) -{ - cmyth_conn_t conn; - char *server; - unsigned short port; - - if (!rec) { - cmyth_dbg(CMYTH_DBG_ERROR, "%s: rec is NULL\n", __FUNCTION__); - return -1; - } - - server = rec->rec_server; - port = rec->rec_port; - - cmyth_dbg(CMYTH_DBG_PROTO, "%s: connecting recorder control\n", - __FUNCTION__); - conn = cmyth_conn_connect_ctrl(server, port, buflen, tcp_rcvbuf); - cmyth_dbg(CMYTH_DBG_PROTO, - "%s: done connecting recorder control, conn = %p\n", - __FUNCTION__, conn); - if (!conn) { - cmyth_dbg(CMYTH_DBG_ERROR, - "%s: cmyth_connect(%s, %d, %d) failed\n", - __FUNCTION__, server, port, buflen); - return -1; - } - - if (rec->rec_conn) - ref_release(rec->rec_conn); - rec->rec_conn = conn; - - return 0; -} - -/* - * cmyth_conn_check_block(cmyth_conn_t conn, unsigned long size) - * - * Scope: PUBLIC - * - * Description - * - * Check whether a block has finished transfering from a backend - * server. This non-blocking check looks for a response from the - * server indicating that a block has been entirely sent to on a data - * socket. - * - * Return Value: - * - * Success: 0 for not complete, 1 for complete - * - * Failure: -(errno) - */ -int -cmyth_conn_check_block(cmyth_conn_t conn, unsigned long size) -{ - fd_set check; - struct timeval timeout; - int length; - int err = 0; - unsigned long sent; - - if (!conn) { - return -EINVAL; - } - timeout.tv_sec = timeout.tv_usec = 0; - FD_ZERO(&check); - FD_SET(conn->conn_fd, &check); - if (select((int)conn->conn_fd + 1, &check, NULL, NULL, &timeout) < 0) { - cmyth_dbg(CMYTH_DBG_DEBUG, "%s: select failed (%d)\n", - __FUNCTION__, errno); - return -(errno); - } - if (FD_ISSET(conn->conn_fd, &check)) { - /* - * We have a bite, reel it in. - */ - length = cmyth_rcv_length(conn); - if (length < 0) { - return length; - } - cmyth_rcv_ulong(conn, &err, &sent, length); - if (err) { - return -err; - } - if (sent == size) { - /* - * This block has been sent, return TRUE. - */ - cmyth_dbg(CMYTH_DBG_DEBUG, - "%s: block finished (%d bytes)\n", - __FUNCTION__, sent); - return 1; - } else { - cmyth_dbg(CMYTH_DBG_ERROR, - "%s: block finished short (%d bytes)\n", - __FUNCTION__, sent); - return -ECANCELED; - } - } - return 0; -} - -/* - * cmyth_conn_get_recorder_from_num(cmyth_conn_t control, - * cmyth_recorder_num_t num, - * cmyth_recorder_t rec) - * - * Scope: PUBLIC - * - * Description - * - * Obtain a recorder from a connection by its recorder number. The - * recorder structure created by this describes how to set up a data - * connection and play media streamed from a particular back-end recorder. - * - * This fills out the recorder structure specified by 'rec'. - * - * Return Value: - * - * Success: 0 for not complete, 1 for complete - * - * Failure: -(errno) - */ -cmyth_recorder_t -cmyth_conn_get_recorder_from_num(cmyth_conn_t conn, int id) -{ - int err, count; - int r; - long port; - char msg[256]; - char reply[256]; - cmyth_recorder_t rec = NULL; - - if (!conn) { - cmyth_dbg(CMYTH_DBG_ERROR, "%s: no connection\n", - __FUNCTION__); - return NULL; - } - - pthread_mutex_lock(&mutex); - - if ((rec=cmyth_recorder_create()) == NULL) - goto fail; - - snprintf(msg, sizeof(msg), "GET_RECORDER_FROM_NUM[]:[]%d", id); - - if ((err = cmyth_send_message(conn, msg)) < 0) { - cmyth_dbg(CMYTH_DBG_ERROR, - "%s: cmyth_send_message() failed (%d)\n", - __FUNCTION__, err); - goto fail; - } - - count = cmyth_rcv_length(conn); - if (count < 0) { - cmyth_dbg(CMYTH_DBG_ERROR, - "%s: cmyth_rcv_length() failed (%d)\n", - __FUNCTION__, count); - goto fail; - } - - if ((r=cmyth_rcv_string(conn, &err, - reply, sizeof(reply)-1, count)) < 0) { - cmyth_dbg(CMYTH_DBG_ERROR, - "%s: cmyth_rcv_string() failed (%d)\n", - __FUNCTION__, r); - goto fail; - } - count -= r; - - if ((r=cmyth_rcv_long(conn, &err, &port, count)) < 0) { - cmyth_dbg(CMYTH_DBG_ERROR, - "%s: cmyth_rcv_long() failed (%d)\n", - __FUNCTION__, r); - goto fail; - } - - if (port == -1) - goto fail; - - rec->rec_id = id; - rec->rec_server = ref_strdup(reply); - rec->rec_port = port; - - if (cmyth_conn_connect_recorder(rec, conn->conn_buflen, - conn->conn_tcp_rcvbuf) < 0) - goto fail; - - pthread_mutex_unlock(&mutex); - - return rec; - - fail: - if (rec) - ref_release(rec); - - pthread_mutex_unlock(&mutex); - - return NULL; -} - -/* - * cmyth_conn_get_free_recorder(cmyth_conn_t control, cmyth_recorder_t rec) - * - * - * Scope: PUBLIC - * - * Description - * - * Obtain the next available free recorder the connection specified by - * 'control'. This fills out the recorder structure specified by 'rec'. - * - * Return Value: - * - * Success: 0 for not complete, 1 for complete - * - * Failure: -(errno) - */ -cmyth_recorder_t -cmyth_conn_get_free_recorder(cmyth_conn_t conn) -{ - int err, count; - int r; - long port, id; - char msg[256]; - char reply[256]; - cmyth_recorder_t rec = NULL; - - if (!conn) { - cmyth_dbg(CMYTH_DBG_ERROR, "%s: no connection\n", - __FUNCTION__); - return NULL; - } - - pthread_mutex_lock(&mutex); - - if ((rec=cmyth_recorder_create()) == NULL) - goto fail; - - snprintf(msg, sizeof(msg), "GET_FREE_RECORDER"); - - if ((err = cmyth_send_message(conn, msg)) < 0) { - cmyth_dbg(CMYTH_DBG_ERROR, - "%s: cmyth_send_message() failed (%d)\n", - __FUNCTION__, err); - goto fail; - } - - count = cmyth_rcv_length(conn); - if (count < 0) { - cmyth_dbg(CMYTH_DBG_ERROR, - "%s: cmyth_rcv_length() failed (%d)\n", - __FUNCTION__, count); - goto fail; - } - if ((r=cmyth_rcv_long(conn, &err, &id, count)) < 0) { - cmyth_dbg(CMYTH_DBG_ERROR, - "%s: cmyth_rcv_long() failed (%d)\n", - __FUNCTION__, r); - goto fail; - } - count -= r; - if ((r=cmyth_rcv_string(conn, &err, - reply, sizeof(reply)-1, count)) < 0) { - cmyth_dbg(CMYTH_DBG_ERROR, - "%s: cmyth_rcv_string() failed (%d)\n", - __FUNCTION__, r); - goto fail; - } - count -= r; - if ((r=cmyth_rcv_long(conn, &err, &port, count)) < 0) { - cmyth_dbg(CMYTH_DBG_ERROR, - "%s: cmyth_rcv_long() failed (%d)\n", - __FUNCTION__, r); - goto fail; - } - - if (port == -1) - goto fail; - - rec->rec_id = id; - rec->rec_server = ref_strdup(reply); - rec->rec_port = port; - - if (cmyth_conn_connect_recorder(rec, conn->conn_buflen, - conn->conn_tcp_rcvbuf) < 0) - goto fail; - - pthread_mutex_unlock(&mutex); - - return rec; - - fail: - if (rec) - ref_release(rec); - - pthread_mutex_unlock(&mutex); - - return NULL; -} - -int -cmyth_conn_get_freespace(cmyth_conn_t control, - long long *total, long long *used) -{ - int err, count, ret = 0; - int r; - char msg[256]; - char reply[256]; - int64_t lreply; - - if (control == NULL) - return -EINVAL; - - if ((total == NULL) || (used == NULL)) - return -EINVAL; - - pthread_mutex_lock(&mutex); - - if (control->conn_version >= 32) - { snprintf(msg, sizeof(msg), "QUERY_FREE_SPACE_SUMMARY"); } - else if (control->conn_version >= 17) - { snprintf(msg, sizeof(msg), "QUERY_FREE_SPACE"); } - else - { snprintf(msg, sizeof(msg), "QUERY_FREESPACE"); } - - if ((err = cmyth_send_message(control, msg)) < 0) { - cmyth_dbg(CMYTH_DBG_ERROR, - "%s: cmyth_send_message() failed (%d)\n", - __FUNCTION__, err); - ret = err; - goto out; - } - - if ((count=cmyth_rcv_length(control)) < 0) { - cmyth_dbg(CMYTH_DBG_ERROR, - "%s: cmyth_rcv_length() failed (%d)\n", - __FUNCTION__, count); - ret = count; - goto out; - } - - if (control->conn_version >= 17) { - if ((r=cmyth_rcv_int64(control, &err, &lreply, count)) < 0) { - cmyth_dbg(CMYTH_DBG_ERROR, - "%s: cmyth_rcv_int64() failed (%d)\n", - __FUNCTION__, err); - ret = err; - goto out; - } - *total = lreply; - if ((r=cmyth_rcv_int64(control, &err, &lreply, count - r)) < 0) { - cmyth_dbg(CMYTH_DBG_ERROR, - "%s: cmyth_rcv_int64() failed (%d)\n", - __FUNCTION__, err); - ret = err; - goto out; - } - *used = lreply; - } - else - { - if ((r=cmyth_rcv_string(control, &err, reply, - sizeof(reply)-1, count)) < 0) { - cmyth_dbg(CMYTH_DBG_ERROR, - "%s: cmyth_rcv_string() failed (%d)\n", - __FUNCTION__, err); - ret = err; - goto out; - } - *total = atoi(reply); - if ((r=cmyth_rcv_string(control, &err, reply, - sizeof(reply)-1, - count-r)) < 0) { - cmyth_dbg(CMYTH_DBG_ERROR, - "%s: cmyth_rcv_string() failed (%d)\n", - __FUNCTION__, err); - ret = err; - goto out; - } - *used = atoi(reply); - - *used *= 1024; - *total *= 1024; - } - - out: - pthread_mutex_unlock(&mutex); - - return ret; -} - -int -cmyth_conn_hung(cmyth_conn_t control) -{ - if (control == NULL) - return -EINVAL; - - return control->conn_hang; -} - -int -cmyth_conn_get_protocol_version(cmyth_conn_t conn) -{ - if (!conn) { - cmyth_dbg(CMYTH_DBG_ERROR, "%s: no connection\n", - __FUNCTION__); - return -1; - } - - return conn->conn_version; -} - - -int -cmyth_conn_get_free_recorder_count(cmyth_conn_t conn) -{ - char msg[256]; - int count, err; - long c, r; - int ret; - - if (!conn) { - cmyth_dbg(CMYTH_DBG_ERROR, "%s: no connection\n", - __FUNCTION__); - return -1; - } - - pthread_mutex_lock(&mutex); - - snprintf(msg, sizeof(msg), "GET_FREE_RECORDER_COUNT"); - if ((err = cmyth_send_message(conn, msg)) < 0) { - cmyth_dbg(CMYTH_DBG_ERROR, - "%s: cmyth_send_message() failed (%d)\n", - __FUNCTION__, err); - ret = err; - goto err; - } - - if ((count=cmyth_rcv_length(conn)) < 0) { - cmyth_dbg(CMYTH_DBG_ERROR, - "%s: cmyth_rcv_length() failed (%d)\n", - __FUNCTION__, count); - ret = count; - goto err; - } - if ((r=cmyth_rcv_long(conn, &err, &c, count)) < 0) { - cmyth_dbg(CMYTH_DBG_ERROR, - "%s: cmyth_rcv_long() failed (%d)\n", - __FUNCTION__, r); - ret = err; - goto err; - } - - ret = c; - - err: - pthread_mutex_unlock(&mutex); - - return ret; -} - -static char * -cmyth_conn_get_setting_unlocked(cmyth_conn_t conn, const char* hostname, const char* setting) -{ - char msg[256]; - int count, err; - char* result = NULL; - - if(conn->conn_version < 17) { - cmyth_dbg(CMYTH_DBG_ERROR, "%s: protocol version doesn't support QUERY_SETTING\n", - __FUNCTION__); - return NULL; - } - - if (!conn) { - cmyth_dbg(CMYTH_DBG_ERROR, "%s: no connection\n", - __FUNCTION__); - return NULL; - } - - snprintf(msg, sizeof(msg), "QUERY_SETTING %s %s", hostname, setting); - if ((err = cmyth_send_message(conn, msg)) < 0) { - cmyth_dbg(CMYTH_DBG_ERROR, - "%s: cmyth_send_message() failed (%d)\n", - __FUNCTION__, err); - goto err; - } - - if ((count=cmyth_rcv_length(conn)) < 0) { - cmyth_dbg(CMYTH_DBG_ERROR, - "%s: cmyth_rcv_length() failed (%d)\n", - __FUNCTION__, count); - goto err; - } - - result = ref_alloc(count+1); - count -= cmyth_rcv_string(conn, &err, - result, count, count); - if (err < 0) { - cmyth_dbg(CMYTH_DBG_ERROR, - "%s: cmyth_rcv_string() failed (%d)\n", - __FUNCTION__, err); - goto err; - } - - while(count > 0 && !err) { - char buffer[100]; - count -= cmyth_rcv_string(conn, &err, buffer, sizeof(buffer)-1, count); - buffer[sizeof(buffer)-1] = 0; - cmyth_dbg(CMYTH_DBG_ERROR, "%s: odd left over data %s\n", __FUNCTION__, buffer); - } - - return result; -err: - if(result) - ref_release(result); - - return NULL; -} - -char * -cmyth_conn_get_setting(cmyth_conn_t conn, const char* hostname, const char* setting) -{ - char* result = NULL; - - pthread_mutex_lock(&mutex); - result = cmyth_conn_get_setting_unlocked(conn, hostname, setting); - pthread_mutex_unlock(&mutex); - - return result; -} diff --git a/lib/cmyth/libcmyth/debug.c b/lib/cmyth/libcmyth/debug.c deleted file mode 100644 index 77b852cf3a..0000000000 --- a/lib/cmyth/libcmyth/debug.c +++ /dev/null @@ -1,122 +0,0 @@ -/* - * Copyright (C) 2004-2009, Eric Lund - * http://www.mvpmc.org/ - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -/* - * debug.c - functions to produce and control debug output from - * libcmyth routines. - */ - -#include <stdlib.h> -#include <cmyth_local.h> - -#include "debug.h" - -static cmyth_debug_ctx_t cmyth_debug_ctx = CMYTH_DEBUG_CTX_INIT("cmyth", - CMYTH_DBG_NONE, - NULL); - -/* - * cmyth_dbg_level(int l) - * - * Scope: PUBLIC - * - * Description - * - * Set the current debug level to the absolute setting 'l' - * permitting all debug messages with a debug level less - * than or equal to 'l' to be displayed. - * - * Return Value: - * - * None. - */ -void -cmyth_dbg_level(int l) -{ - __cmyth_dbg_setlevel(&cmyth_debug_ctx, l); -} - -/* - * cmyth_dbg_all() - * - * Scope: PUBLIC - * - * Description - * - * Set the current debug level so that all debug messages are displayed. - * - * Return Value: - * - * None. - */ -void -cmyth_dbg_all() -{ - __cmyth_dbg_setlevel(&cmyth_debug_ctx, CMYTH_DBG_ALL); -} - -/* - * cmyth_dbg_none() - * - * Scope: PUBLIC - * - * Description - * - * Set the current debug level so that no debug messages are displayed. - * - * Return Value: - * - * None. - */ -void -cmyth_dbg_none() -{ - __cmyth_dbg_setlevel(&cmyth_debug_ctx, CMYTH_DBG_NONE); -} - -/* - * cmyth_dbg() - * - * Scope: PRIVATE (mapped to __cmyth_dbg) - * - * Description - * - * Print a debug message of level 'level' on 'stderr' provided that - * the current debug level allows messages of level 'level' to be - * printed. - * - * Return Value: - * - * None. - */ -void -cmyth_dbg(int level, char *fmt, ...) -{ - va_list ap; - - va_start(ap, fmt); - __cmyth_dbg(&cmyth_debug_ctx, level, fmt, ap); - va_end(ap); -} - -void -cmyth_set_dbg_msgcallback(void (*msgcb)(int level,char *)) -{ - cmyth_debug_ctx.msg_callback = msgcb; -} diff --git a/lib/cmyth/libcmyth/event.c b/lib/cmyth/libcmyth/event.c deleted file mode 100644 index 2208c3e793..0000000000 --- a/lib/cmyth/libcmyth/event.c +++ /dev/null @@ -1,185 +0,0 @@ -/* - * Copyright (C) 2005-2012, Jon Gettler - * http://www.mvpmc.org/ - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <errno.h> -#include <cmyth_local.h> - -cmyth_event_t -cmyth_event_get(cmyth_conn_t conn, char * data, int len) -{ - int count, err, consumed, i; - char tmp[1024]; - cmyth_event_t event; - cmyth_proginfo_t proginfo = NULL; - - if (conn == NULL) - goto fail; - - if ((count=cmyth_rcv_length(conn)) <= 0) { - cmyth_dbg(CMYTH_DBG_ERROR, - "%s: cmyth_rcv_length() failed (%d)\n", - __FUNCTION__, count); - return CMYTH_EVENT_CLOSE; - } - - consumed = cmyth_rcv_string(conn, &err, tmp, sizeof(tmp) - 1, count); - count -= consumed; - if (strcmp(tmp, "BACKEND_MESSAGE") != 0) { - cmyth_dbg(CMYTH_DBG_ERROR, - "%s: cmyth_rcv_string() failed (%d)\n", - __FUNCTION__, count); - goto fail; - } - - consumed = cmyth_rcv_string(conn, &err, tmp, sizeof(tmp) - 1, count); - count -= consumed; - if (strcmp(tmp, "RECORDING_LIST_CHANGE") == 0) { - event = CMYTH_EVENT_RECORDING_LIST_CHANGE; - } else if (strncmp(tmp, "RECORDING_LIST_CHANGE ADD", 25) == 0) { - event = CMYTH_EVENT_RECORDING_LIST_CHANGE_ADD; - strncpy(data, tmp + 26, len); - } else if (strcmp(tmp, "RECORDING_LIST_CHANGE UPDATE") == 0) { - event = CMYTH_EVENT_RECORDING_LIST_CHANGE_UPDATE; - /* receive a proginfo structure - do nothing with it (yet?)*/ - proginfo = cmyth_proginfo_create(); - if (!proginfo) { - cmyth_dbg(CMYTH_DBG_ERROR, - "%s: cmyth_proginfo_create() failed\n", - __FUNCTION__); - goto fail; - } - consumed = cmyth_rcv_proginfo(conn, &err, proginfo, count); - ref_release(proginfo); - proginfo = NULL; - count -= consumed; - } else if (strncmp(tmp, "RECORDING_LIST_CHANGE DELETE", 28) == 0) { - event = CMYTH_EVENT_RECORDING_LIST_CHANGE_DELETE; - strncpy(data, tmp + 29, len); - } else if (strcmp(tmp, "SCHEDULE_CHANGE") == 0) { - event = CMYTH_EVENT_SCHEDULE_CHANGE; - } else if (strncmp(tmp, "DONE_RECORDING", 14) == 0) { - event = CMYTH_EVENT_DONE_RECORDING; - } else if (strncmp(tmp, "QUIT_LIVETV", 11) == 0) { - event = CMYTH_EVENT_QUIT_LIVETV; - } else if (strncmp(tmp, "LIVETV_WATCH", 12) == 0) { - event = CMYTH_EVENT_WATCH_LIVETV; - strncpy(data, tmp + 13, len); - /* Sergio: Added to support the new live tv protocol */ - } else if (strncmp(tmp, "LIVETV_CHAIN UPDATE", 19) == 0) { - event = CMYTH_EVENT_LIVETV_CHAIN_UPDATE; - strncpy(data, tmp + 20, len); - } else if (strncmp(tmp, "SIGNAL", 6) == 0) { - event = CMYTH_EVENT_SIGNAL; - /* get slock, signal, seen_pat, matching_pat */ - while (count > 0) { - /* get signalmonitorvalue name */ - consumed = cmyth_rcv_string(conn, &err, tmp, sizeof(tmp) - 1, count); - count -= consumed; - - /* get signalmonitorvalue status */ - consumed = cmyth_rcv_string(conn, &err, tmp, sizeof(tmp) - 1, count); - count -= consumed; - } - } else if (strncmp(tmp, "ASK_RECORDING", 13) == 0) { - event = CMYTH_EVENT_ASK_RECORDING; - if (cmyth_conn_get_protocol_version(conn) < 37) { - /* receive 4 string - do nothing with them */ - for (i = 0; i < 4; i++) { - consumed = cmyth_rcv_string(conn, &err, tmp, sizeof(tmp) -1, count); - count -= consumed; - } - } else { - /* receive a proginfo structure - do nothing with it (yet?)*/ - proginfo = cmyth_proginfo_create(); - if (!proginfo) { - cmyth_dbg(CMYTH_DBG_ERROR, - "%s: cmyth_proginfo_create() failed\n", - __FUNCTION__); - goto fail; - } - consumed = cmyth_rcv_proginfo(conn, &err, proginfo, count); - ref_release(proginfo); - proginfo = NULL; - count -= consumed; - } - } else if (strncmp(tmp, "CLEAR_SETTINGS_CACHE", 20) == 0) { - event = CMYTH_EVENT_CLEAR_SETTINGS_CACHE; - } else if (strncmp(tmp, "GENERATED_PIXMAP", 16) == 0) { - /* capture the file which a pixmap has been generated for */ - event = CMYTH_EVENT_GENERATED_PIXMAP; - consumed = cmyth_rcv_string(conn, &err, tmp, sizeof(tmp) - 1, count); - if (strncmp(tmp, "OK", 2) == 0) { - consumed = cmyth_rcv_string(conn, &err, tmp, sizeof(tmp) - 1, count); - strncpy(data, tmp, len); - } else { - data[0] = 0; - } - } else if (strncmp(tmp, "SYSTEM_EVENT", 12) == 0) { - event = CMYTH_EVENT_SYSTEM_EVENT; - strncpy(data, tmp + 13, len); - } else if (strncmp(tmp, "UPDATE_FILE_SIZE", 16) == 0) { - event = CMYTH_EVENT_UPDATE_FILE_SIZE; - strncpy(data, tmp + 17, len); - } else { - cmyth_dbg(CMYTH_DBG_ERROR, - "%s: unknown mythtv BACKEND_MESSAGE '%s'\n", __FUNCTION__, tmp); - event = CMYTH_EVENT_UNKNOWN; - } - - while(count > 0) { - consumed = cmyth_rcv_string(conn, &err, tmp, sizeof(tmp) - 1, count); - count -= consumed; - cmyth_dbg(CMYTH_DBG_DEBUG, "%s: leftover data %s\n", __FUNCTION__, tmp); - } - - return event; - - fail: - return CMYTH_EVENT_UNKNOWN; -} - -int -cmyth_event_select(cmyth_conn_t conn, struct timeval *timeout) -{ - fd_set fds; - int ret; - cmyth_socket_t fd; - - cmyth_dbg(CMYTH_DBG_DEBUG, "%s [%s:%d]: (trace) {\n", __FUNCTION__, - __FILE__, __LINE__); - - if (conn == NULL) - return -EINVAL; - - fd = conn->conn_fd; - - FD_ZERO(&fds); - FD_SET(fd, &fds); - - ret = select((int)fd+1, &fds, NULL, NULL, timeout); - - cmyth_dbg(CMYTH_DBG_DEBUG, "%s [%s:%d]: (trace) }\n", - __FUNCTION__, __FILE__, __LINE__); - - return ret; -} - diff --git a/lib/cmyth/libcmyth/file.c b/lib/cmyth/libcmyth/file.c deleted file mode 100644 index 1939aa9e1c..0000000000 --- a/lib/cmyth/libcmyth/file.c +++ /dev/null @@ -1,820 +0,0 @@ -/* - * Copyright (C) 2004-2012, Eric Lund - * http://www.mvpmc.org/ - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -#include <stdio.h> -#include <stdlib.h> -#include <errno.h> -#include <inttypes.h> -#include <sys/types.h> -#include <cmyth_local.h> - -/* - * cmyth_file_destroy(cmyth_file_t file) - * - * Scope: PRIVATE (static) - * - * Description - * - * Tear down and release storage associated with a file connection. - * This should only be called by ref_release(). All others - * should call ref_release() to release a file connection. - * - * Return Value: - * - * None. - */ -static void -cmyth_file_destroy(cmyth_file_t file) -{ - int err; - char msg[256]; - - cmyth_dbg(CMYTH_DBG_DEBUG, "%s {\n", __FUNCTION__); - if (!file) { - cmyth_dbg(CMYTH_DBG_DEBUG, "%s }!\n", __FUNCTION__); - return; - } - if (file->file_control) { - pthread_mutex_lock(&mutex); - - /* - * Try to shut down the file transfer. Can't do much - * if it fails other than log it. - */ - snprintf(msg, sizeof(msg), - "QUERY_FILETRANSFER %ld[]:[]DONE", file->file_id); - - if ((err = cmyth_send_message(file->file_control, msg)) < 0) { - cmyth_dbg(CMYTH_DBG_ERROR, - "%s: cmyth_send_message() failed (%d)\n", - __FUNCTION__, err); - goto fail; - } - - if ((err=cmyth_rcv_okay(file->file_control, "ok")) < 0) { - cmyth_dbg(CMYTH_DBG_ERROR, - "%s: cmyth_rcv_okay() failed (%d)\n", - __FUNCTION__, err); - goto fail; - } - fail: - ref_release(file->file_control); - pthread_mutex_unlock(&mutex); - } - if (file->closed_callback) { - (file->closed_callback)(file); - } - if (file->file_data) { - ref_release(file->file_data); - } - - cmyth_dbg(CMYTH_DBG_DEBUG, "%s }\n", __FUNCTION__); -} - -/* - * cmyth_file_set_closed_callback(cmyth_file_t file, void (*callback)(cmyth_file_t)) - * - * Scope: PUBLIC - * - * Description - * - * Sets a callback which will be called when a file connection has been - * signalled as done. Passing in NULL means no callback. - */ - -void cmyth_file_set_closed_callback(cmyth_file_t file, void (*callback)(cmyth_file_t)) -{ - if(!file) - return; - file->closed_callback = callback; -} - -/* - * cmyth_file_create(cmyth_conn_t control) - * - * Scope: PRIVATE (mapped to __cmyth_file_create) - * - * Description - * - * Allocate and initialize a cmyth_file_t structure. This should only - * be called by cmyth_connect_file(), which establishes a file - * transfer connection. - * - * Return Value: - * - * Success: A non-NULL cmyth_file_t (this type is a pointer) - * - * Failure: A NULL cmyth_file_t - */ -cmyth_file_t -cmyth_file_create(cmyth_conn_t control) -{ - cmyth_file_t ret = ref_alloc(sizeof(*ret)); - - cmyth_dbg(CMYTH_DBG_DEBUG, "%s {\n", __FUNCTION__); - if (!ret) { - cmyth_dbg(CMYTH_DBG_DEBUG, "%s }\n", __FUNCTION__); - return NULL; - } - ref_set_destroy(ret, (ref_destroy_t)cmyth_file_destroy); - - ret->file_control = ref_hold(control); - ret->file_data = NULL; - ret->file_id = -1; - ret->file_start = 0; - ret->file_length = 0; - ret->file_pos = 0; - ret->file_req = 0; - ret->closed_callback = NULL; - cmyth_dbg(CMYTH_DBG_DEBUG, "%s }\n", __FUNCTION__); - return ret; -} - -/* - * cmyth_file_data(cmyth_file_t p) - * - * Scope: PUBLIC - * - * Description - * - * Obtain a held reference to the data connection inside of a file - * connection. This cmyth_conn_t can be used to read data from the - * MythTV backend server during a file transfer. - * - * Return Value: - * - * Sucess: A non-null cmyth_conn_t (this is a pointer type) - * - * Failure: NULL - */ -cmyth_conn_t -cmyth_file_data(cmyth_file_t file) -{ - if (!file) { - return NULL; - } - if (!file->file_data) { - return NULL; - } - return ref_hold(file->file_data); -} - -/* - * cmyth_file_control(cmyth_file_t p) - * - * Scope: PUBLIC - * - * Description - * - * Obtain a held reference to the control connection inside of a file - * connection. This cmyth_conn_t can be used to control the - * MythTV backend server during a file transfer. - * - * Return Value: - * - * Sucess: A non-null cmyth_conn_t (this is a pointer type) - * - * Failure: NULL - */ -cmyth_conn_t -cmyth_file_control(cmyth_file_t file) -{ - if (!file) { - return NULL; - } - if (!file->file_control) { - return NULL; - } - return ref_hold(file->file_control); -} - -/* - * cmyth_file_start(cmyth_file_t p) - * - * Scope: PUBLIC - * - * Description - * - * Obtain the start offset in a file for the beginning of the data. - * - * Return Value: - * - * Sucess: a long long value >= 0 - * - * Failure: a long long containing -errno - */ -unsigned long long -cmyth_file_start(cmyth_file_t file) -{ - if (!file) { - return -EINVAL; - } - return file->file_start; -} - -/* - * cmyth_file_length(cmyth_file_t p) - * - * Scope: PUBLIC - * - * Description - * - * Obtain the length of the data in a file. - * - * Return Value: - * - * Sucess: a long long value >= 0 - * - * Failure: a long long containing -errno - */ -unsigned long long -cmyth_file_length(cmyth_file_t file) -{ - if (!file) { - return -EINVAL; - } - return file->file_length; -} - -/* - * cmyth_file_get_block(cmyth_file_t file, char *buf, unsigned long len) - * - * Scope: PUBLIC - * - * Description - * - * Read incoming file data off the network into a buffer of length len. - * - * Return Value: - * - * Sucess: number of bytes read into buf - * - * Failure: -1 - */ -int -cmyth_file_get_block(cmyth_file_t file, char *buf, unsigned long len) -{ - struct timeval tv; - fd_set fds; - int ret; - - if (file == NULL || file->file_data == NULL) - return -EINVAL; - - tv.tv_sec = 10; - tv.tv_usec = 0; - FD_ZERO(&fds); - FD_SET(file->file_data->conn_fd, &fds); - if (select((int)(file->file_data->conn_fd)+1, NULL, &fds, NULL, &tv) == 0) { - file->file_data->conn_hang = 1; - return 0; - } else { - file->file_data->conn_hang = 0; - } - - ret = recv(file->file_data->conn_fd, buf, len, 0); - - if(ret < 0) - return ret; - - file->file_pos += ret; - - if(file->file_pos > file->file_length) - file->file_length = file->file_pos; - - return ret; -} - -int -cmyth_file_select(cmyth_file_t file, struct timeval *timeout) -{ - fd_set fds; - int ret; - cmyth_socket_t fd; - - if (file == NULL || file->file_data == NULL) - return -EINVAL; - - fd = file->file_data->conn_fd; - - FD_ZERO(&fds); - FD_SET(fd, &fds); - - ret = select((int)fd+1, &fds, NULL, NULL, timeout); - - if (ret == 0) - file->file_data->conn_hang = 1; - else - file->file_data->conn_hang = 0; - - return ret; -} - -/* - * cmyth_file_request_block(cmyth_file_t file, unsigned long len) - * - * Scope: PUBLIC - * - * Description - * - * Request a file data block of a certain size, and return when the - * block has been transfered. - * - * Return Value: - * - * Sucess: number of bytes transfered - * - * Failure: an int containing -errno - */ -int -cmyth_file_request_block(cmyth_file_t file, unsigned long len) -{ - int err, count; - int r; - long c, ret; - char msg[256]; - - if (!file) { - cmyth_dbg(CMYTH_DBG_ERROR, "%s: no connection\n", - __FUNCTION__); - return -EINVAL; - } - - pthread_mutex_lock(&mutex); - - if(len > (unsigned int)file->file_control->conn_tcp_rcvbuf) - len = (unsigned int)file->file_control->conn_tcp_rcvbuf; - - snprintf(msg, sizeof(msg), - "QUERY_FILETRANSFER %ld[]:[]REQUEST_BLOCK[]:[]%ld", - file->file_id, len); - - if ((err = cmyth_send_message(file->file_control, msg)) < 0) { - cmyth_dbg(CMYTH_DBG_ERROR, - "%s: cmyth_send_message() failed (%d)\n", - __FUNCTION__, err); - ret = err; - goto out; - } - - if ((count=cmyth_rcv_length(file->file_control)) < 0) { - cmyth_dbg(CMYTH_DBG_ERROR, - "%s: cmyth_rcv_length() failed (%d)\n", - __FUNCTION__, count); - ret = count; - goto out; - } - if ((r=cmyth_rcv_long(file->file_control, &err, &c, count)) < 0) { - cmyth_dbg(CMYTH_DBG_ERROR, - "%s: cmyth_rcv_long() failed (%d)\n", - __FUNCTION__, r); - ret = err; - goto out; - } - - file->file_req += c; - ret = c; - - out: - pthread_mutex_unlock(&mutex); - - return ret; -} - -/* - * cmyth_file_seek(cmyth_file_t file, long long offset, int whence) - * - * Scope: PUBLIC - * - * Description - * - * Seek to a new position in the file based on the value of whence: - * SEEK_SET - * The offset is set to offset bytes. - * SEEK_CUR - * The offset is set to the current position plus offset bytes. - * SEEK_END - * The offset is set to the size of the file minus offset bytes. - * - * Return Value: - * - * Sucess: 0 - * - * Failure: an int containing -errno - */ -long long -cmyth_file_seek(cmyth_file_t file, long long offset, int whence) -{ - char msg[128]; - int err; - int count; - int64_t c; - long r; - long long ret; - - if (file == NULL) - return -EINVAL; - - if ((offset == 0) && (whence == SEEK_CUR)) - return file->file_pos; - - if ((offset == file->file_pos) && (whence == SEEK_SET)) - return file->file_pos; - - while(file->file_pos < file->file_req) { - c = file->file_req - file->file_pos; - if(c > sizeof(msg)) - c = sizeof(msg); - - if (cmyth_file_get_block(file, msg, (unsigned long)c) < 0) - return -1; - } - - pthread_mutex_lock(&mutex); - - if (file->file_control->conn_version >= 66) { - /* - * Since protocol 66 mythbackend expects to receive a single 64 bit integer rather than - * two 32 bit hi and lo integers. - */ - snprintf(msg, sizeof(msg), - "QUERY_FILETRANSFER %ld[]:[]SEEK[]:[]%"PRIu64"[]:[]%d[]:[]%"PRIu64, - file->file_id, - (int64_t)offset, - whence, - (int64_t)file->file_pos); - } - else { - snprintf(msg, sizeof(msg), - "QUERY_FILETRANSFER %ld[]:[]SEEK[]:[]%d[]:[]%d[]:[]%d[]:[]%d[]:[]%d", - file->file_id, - (int32_t)(offset >> 32), - (int32_t)(offset & 0xffffffff), - whence, - (int32_t)(file->file_pos >> 32), - (int32_t)(file->file_pos & 0xffffffff)); - } - - if ((err = cmyth_send_message(file->file_control, msg)) < 0) { - cmyth_dbg(CMYTH_DBG_ERROR, - "%s: cmyth_send_message() failed (%d)\n", - __FUNCTION__, err); - ret = err; - goto out; - } - - if ((count=cmyth_rcv_length(file->file_control)) < 0) { - cmyth_dbg(CMYTH_DBG_ERROR, - "%s: cmyth_rcv_length() failed (%d)\n", - __FUNCTION__, count); - ret = count; - goto out; - } - if ((r=cmyth_rcv_int64(file->file_control, &err, &c, count)) < 0) { - cmyth_dbg(CMYTH_DBG_ERROR, - "%s: cmyth_rcv_int64() failed (%d)\n", - __FUNCTION__, r); - ret = err; - goto out; - } - - switch (whence) { - case SEEK_SET: - file->file_pos = offset; - break; - case SEEK_CUR: - file->file_pos += offset; - break; - case SEEK_END: - file->file_pos = file->file_length - offset; - break; - } - - file->file_req = file->file_pos; - if(file->file_pos > file->file_length) - file->file_length = file->file_pos; - - ret = file->file_pos; - - out: - pthread_mutex_unlock(&mutex); - - return ret; -} - -/* - * cmyth_file_read(cmyth_recorder_t rec, char *buf, unsigned long len) - * - * Scope: PUBLIC - * - * Description - * - * Request and read a block of data from backend - * - * Return Value: - * - * Sucess: number of bytes transfered - * - * Failure: an int containing -errno - */ -int cmyth_file_read(cmyth_file_t file, char *buf, unsigned long len) -{ - int err, count; - int ret, req, nfds, rec; - char *end, *cur; - char msg[256]; - int64_t len64; - struct timeval tv; - fd_set fds; - - if (!file || !file->file_data) { - cmyth_dbg (CMYTH_DBG_ERROR, "%s: no connection\n", - __FUNCTION__); - return -EINVAL; - } - if (len == 0) - return 0; - - pthread_mutex_lock (&mutex); - - /* make sure we have outstanding requests that fill the buffer that was called with */ - /* this way we should be able to saturate the network connection better */ - if (file->file_req < file->file_pos + len) { - - snprintf (msg, sizeof (msg), - "QUERY_FILETRANSFER %ld[]:[]REQUEST_BLOCK[]:[]%ld", - file->file_id, (unsigned long)(file->file_pos + len - file->file_req)); - - if ( (err = cmyth_send_message (file->file_control, msg) ) < 0) { - cmyth_dbg (CMYTH_DBG_ERROR, - "%s: cmyth_send_message() failed (%d)\n", - __FUNCTION__, err); - ret = err; - goto out; - } - req = 1; - } else { - req = 0; - } - - rec = 0; - cur = buf; - end = buf+len; - - while (cur == buf || req || rec) { - if(rec) { - tv.tv_sec = 0; - tv.tv_usec = 0; - } else { - tv.tv_sec = 20; - tv.tv_usec = 0; - } - nfds = 0; - - FD_ZERO (&fds); - if (req) { - if ((int)file->file_control->conn_fd > nfds) - nfds = (int)file->file_control->conn_fd; - FD_SET (file->file_control->conn_fd, &fds); - } - if ((int)file->file_data->conn_fd > nfds) - nfds = (int)file->file_data->conn_fd; - FD_SET (file->file_data->conn_fd, &fds); - - if ((ret = select (nfds+1, &fds, NULL, NULL,&tv)) < 0) { - cmyth_dbg (CMYTH_DBG_ERROR, - "%s: select(() failed (%d)\n", - __FUNCTION__, ret); - goto out; - } - - if (ret == 0 && !rec) { - file->file_control->conn_hang = 1; - file->file_data->conn_hang = 1; - ret = -ETIMEDOUT; - goto out; - } - - /* check control connection */ - if (FD_ISSET(file->file_control->conn_fd, &fds)) { - - if ((count=cmyth_rcv_length (file->file_control)) < 0) { - cmyth_dbg (CMYTH_DBG_ERROR, - "%s: cmyth_rcv_length() failed (%d)\n", - __FUNCTION__, count); - ret = count; - goto out; - } - - /* - * MythTV originally sent back a signed 32bit value but was changed to a - * signed 64bit value in http://svn.mythtv.org/trac/changeset/18011 (1-Aug-2008). - * - * libcmyth now retrieves the 64-bit signed value, does error-checking, - * and then converts to a 32bit unsigned. - * - * This rcv_ method needs to be forced to use new_int64 to pull back a - * single 64bit number otherwise the handling in rcv_int64 will revert to - * the old two 32bit hi and lo long values. - */ - if ((ret=cmyth_rcv_new_int64 (file->file_control, &err, &len64, count, 1))< 0) { - cmyth_dbg (CMYTH_DBG_ERROR, - "%s: cmyth_rcv_new_int64() failed (%d)\n", - __FUNCTION__, ret); - ret = err; - goto out; - } - if (len64 >= 0x100000000LL || len64 < 0) { - /* -1 seems to be a common result, but isn't valid so use 0 instead. */ - cmyth_dbg (CMYTH_DBG_WARN, - "%s: cmyth_rcv_new_int64() returned out of bound value (%"PRId64"). Using 0 instead.\n", - __FUNCTION__, len64); - len64 = 0; - } - len = (unsigned long)len64; - req = 0; - file->file_req += len; - - if (file->file_req < file->file_pos) { - cmyth_dbg (CMYTH_DBG_ERROR, - "%s: received invalid invalid length, read position is ahead of request (req: %"PRIu64", pos: %"PRIu64", len: %"PRId64")\n", - __FUNCTION__, file->file_req, file->file_pos, len64); - ret = -1; - goto out; - } - - - /* check if we are already done */ - if (file->file_pos == file->file_req) - break; - } - - /* restore direct request fleg */ - rec = 0; - - /* check data connection */ - if (FD_ISSET(file->file_data->conn_fd, &fds)) { - if (end < cur) { - cmyth_dbg (CMYTH_DBG_ERROR, - "%s: positions invalid on read, bailing out (cur: %x, end: %x)\n", - __FUNCTION__, cur, end); - ret = -1; - goto out; - } - if ((ret = recv (file->file_data->conn_fd, cur, (int)(end-cur), 0)) < 0) { - cmyth_dbg (CMYTH_DBG_ERROR, - "%s: recv() failed (%d)\n", - __FUNCTION__, ret); - goto out; - } - cur += ret; - file->file_pos += ret; - if(ret) - rec = 1; /* attempt to read directly again to get all queued packets */ - } - } - - /* make sure file grows, as we move past length */ - if (file->file_pos > file->file_length) - file->file_length = file->file_pos; - - ret = (int)(cur - buf); -out: - pthread_mutex_unlock (&mutex); - return ret; -} - -#ifdef _MSC_VER - -struct errentry { - unsigned long oscode; /* OS return value */ - int errnocode; /* System V error code */ -}; - -static struct errentry errtable[] = { - { ERROR_INVALID_FUNCTION, EINVAL }, /* 1 */ - { ERROR_FILE_NOT_FOUND, ENOENT }, /* 2 */ - { ERROR_PATH_NOT_FOUND, ENOENT }, /* 3 */ - { ERROR_TOO_MANY_OPEN_FILES, EMFILE }, /* 4 */ - { ERROR_ACCESS_DENIED, EACCES }, /* 5 */ - { ERROR_INVALID_HANDLE, EBADF }, /* 6 */ - { ERROR_ARENA_TRASHED, ENOMEM }, /* 7 */ - { ERROR_NOT_ENOUGH_MEMORY, ENOMEM }, /* 8 */ - { ERROR_INVALID_BLOCK, ENOMEM }, /* 9 */ - { ERROR_BAD_ENVIRONMENT, E2BIG }, /* 10 */ - { ERROR_BAD_FORMAT, ENOEXEC }, /* 11 */ - { ERROR_INVALID_ACCESS, EINVAL }, /* 12 */ - { ERROR_INVALID_DATA, EINVAL }, /* 13 */ - { ERROR_INVALID_DRIVE, ENOENT }, /* 15 */ - { ERROR_CURRENT_DIRECTORY, EACCES }, /* 16 */ - { ERROR_NOT_SAME_DEVICE, EXDEV }, /* 17 */ - { ERROR_NO_MORE_FILES, ENOENT }, /* 18 */ - { ERROR_LOCK_VIOLATION, EACCES }, /* 33 */ - { ERROR_BAD_NETPATH, ENOENT }, /* 53 */ - { ERROR_NETWORK_ACCESS_DENIED, EACCES }, /* 65 */ - { ERROR_BAD_NET_NAME, ENOENT }, /* 67 */ - { ERROR_FILE_EXISTS, EEXIST }, /* 80 */ - { ERROR_CANNOT_MAKE, EACCES }, /* 82 */ - { ERROR_FAIL_I24, EACCES }, /* 83 */ - { ERROR_INVALID_PARAMETER, EINVAL }, /* 87 */ - { ERROR_NO_PROC_SLOTS, EAGAIN }, /* 89 */ - { ERROR_DRIVE_LOCKED, EACCES }, /* 108 */ - { ERROR_BROKEN_PIPE, EPIPE }, /* 109 */ - { ERROR_DISK_FULL, ENOSPC }, /* 112 */ - { ERROR_INVALID_TARGET_HANDLE, EBADF }, /* 114 */ - { ERROR_INVALID_HANDLE, EINVAL }, /* 124 */ - { ERROR_WAIT_NO_CHILDREN, ECHILD }, /* 128 */ - { ERROR_CHILD_NOT_COMPLETE, ECHILD }, /* 129 */ - { ERROR_DIRECT_ACCESS_HANDLE, EBADF }, /* 130 */ - { ERROR_NEGATIVE_SEEK, EINVAL }, /* 131 */ - { ERROR_SEEK_ON_DEVICE, EACCES }, /* 132 */ - { ERROR_DIR_NOT_EMPTY, ENOTEMPTY }, /* 145 */ - { ERROR_NOT_LOCKED, EACCES }, /* 158 */ - { ERROR_BAD_PATHNAME, ENOENT }, /* 161 */ - { ERROR_MAX_THRDS_REACHED, EAGAIN }, /* 164 */ - { ERROR_LOCK_FAILED, EACCES }, /* 167 */ - { ERROR_ALREADY_EXISTS, EEXIST }, /* 183 */ - { ERROR_FILENAME_EXCED_RANGE, ENOENT }, /* 206 */ - { ERROR_NESTING_NOT_ALLOWED, EAGAIN }, /* 215 */ - { ERROR_NOT_ENOUGH_QUOTA, ENOMEM } /* 1816 */ -}; - -/* size of the table */ -#define ERRTABLESIZE (sizeof(errtable)/sizeof(errtable[0])) - -/* The following two constants must be the minimum and maximum - values in the (contiguous) range of Exec Failure errors. */ -#define MIN_EXEC_ERROR ERROR_INVALID_STARTING_CODESEG -#define MAX_EXEC_ERROR ERROR_INFLOOP_IN_RELOC_CHAIN - -/* These are the low and high value in the range of errors that are - access violations */ -#define MIN_EACCES_RANGE ERROR_WRITE_PROTECT -#define MAX_EACCES_RANGE ERROR_SHARING_BUFFER_EXCEEDED - - -/*** - *void _dosmaperr(oserrno) - Map function number - * - *Purpose: - * This function takes an OS error number, and maps it to the - * corresponding errno value (based on UNIX System V values). The - * OS error number is stored in _doserrno (and the mapped value is - * stored in errno) - * - *Entry: - * ULONG oserrno = OS error value - * - *Exit: - * sets _doserrno and errno. - * - *Exceptions: - * - *******************************************************************************/ - -void __cdecl _dosmaperr ( - unsigned long oserrno - ) -{ - int i; - - _doserrno = oserrno; /* set _doserrno */ - - /* check the table for the OS error code */ - for (i = 0; i < ERRTABLESIZE; ++i) { - if (oserrno == errtable[i].oscode) { - errno = errtable[i].errnocode; - return; - } - } - - /* The error code wasn't in the table. We check for a range of */ - /* EACCES errors or exec failure errors (ENOEXEC). Otherwise */ - /* EINVAL is returned. */ - - if (oserrno >= MIN_EACCES_RANGE && oserrno <= MAX_EACCES_RANGE) - errno = EACCES; - else if (oserrno >= MIN_EXEC_ERROR && oserrno <= MAX_EXEC_ERROR) - errno = ENOEXEC; - else - errno = EINVAL; -} - -#endif - diff --git a/lib/cmyth/libcmyth/freespace.c b/lib/cmyth/libcmyth/freespace.c deleted file mode 100644 index 6b291aca71..0000000000 --- a/lib/cmyth/libcmyth/freespace.c +++ /dev/null @@ -1,53 +0,0 @@ -/* - * Copyright (C) 2004-2010, Eric Lund - * http://www.mvpmc.org/ - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -/* - * freespace.c - functions to manage freespace structures. - */ -#include <stdlib.h> -#include <cmyth_local.h> - -/* - * cmyth_freespace_create(void) - * - * Scope: PUBLIC - * - * Description - * - * Create a key frame structure. - * - * Return Value: - * - * Success: A non-NULL cmyth_freespace_t (this type is a pointer) - * - * Failure: A NULL cmyth_freespace_t - */ -cmyth_freespace_t -cmyth_freespace_create(void) -{ - cmyth_freespace_t ret = ref_alloc(sizeof(*ret)); - cmyth_dbg(CMYTH_DBG_DEBUG, "%s\n", __FUNCTION__); - if (!ret) { - return NULL; - } - - ret->freespace_total = 0; - ret->freespace_used = 0; - return ret; -} diff --git a/lib/cmyth/libcmyth/keyframe.c b/lib/cmyth/libcmyth/keyframe.c deleted file mode 100644 index 4f6f912313..0000000000 --- a/lib/cmyth/libcmyth/keyframe.c +++ /dev/null @@ -1,132 +0,0 @@ -/* - * Copyright (C) 2004-2010, Eric Lund - * http://www.mvpmc.org/ - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -/* - * keyframe.c - functions to manage key frame structures. Mostly - * just allocating, freeing, and filling them out. - */ -#include <sys/types.h> -#include <stdlib.h> -#include <string.h> -#include <stdio.h> -#include <cmyth_local.h> - -/* - * cmyth_keyframe_create(void) - * - * Scope: PUBLIC - * - * Description - * - * Create a key frame structure. - * - * Return Value: - * - * Success: A non-NULL cmyth_keyframe_t (this type is a pointer) - * - * Failure: A NULL cmyth_keyframe_t - */ -cmyth_keyframe_t -cmyth_keyframe_create(void) -{ - cmyth_keyframe_t ret = ref_alloc(sizeof(*ret)); - - cmyth_dbg(CMYTH_DBG_DEBUG, "%s {\n", __FUNCTION__); - if (!ret) { - cmyth_dbg(CMYTH_DBG_DEBUG, "%s } !\n", __FUNCTION__); - return NULL; - } - ret->keyframe_number = 0; - ret->keyframe_pos = 0; - cmyth_dbg(CMYTH_DBG_DEBUG, "%s }\n", __FUNCTION__); - return ret; -} - -/* - * cmyth_keyframe_fill(cmyth_keyframe_t kf, - * unsigned long keynum, - * unsigned long long pos) - * - * Scope: PUBLIC - * - * Description - * - * Fill out the contents of the recorder number structure 'rn' using - * the values 'keynum' and 'pos'. - * - * Return Value: - * - * Success: 0 - * - * Failure: -(ERRNO) - */ -cmyth_keyframe_t -cmyth_keyframe_fill(unsigned long keynum, unsigned long long pos) -{ - cmyth_keyframe_t ret = cmyth_keyframe_create(); - - if (!ret) { - return NULL; - } - - ret->keyframe_number = keynum; - ret->keyframe_pos = pos; - return ret; -} - -/* - * cmyth_keyframe_string(cmyth_keyframe_t kf) - * - * Scope: PUBLIC - * - * Description - * - * Compose a MythTV protocol string from a keyframe structure and - * return a pointer to a malloc'ed buffer containing the string. - * - * Return Value: - * - * Success: A non-NULL malloc'ed character buffer pointer. - * - * Failure: NULL - */ -char * -cmyth_keyframe_string(cmyth_keyframe_t kf) -{ - unsigned len = sizeof("[]:[]"); - char key[32]; - char pos[32]; - char *ret; - - if (!kf) { - return NULL; - } - sprintf(pos, "%lld", kf->keyframe_pos); - len += strlen(pos); - sprintf(key, "%ld", kf->keyframe_number); - len += strlen(key); - ret = malloc(len * sizeof(char)); - if (!ret) { - return NULL; - } - strcpy(ret, key); - strcat(ret, "[]:[]"); - strcat(ret, pos); - return ret; -} diff --git a/lib/cmyth/libcmyth/livetv.c b/lib/cmyth/libcmyth/livetv.c deleted file mode 100644 index 9f5ccd77de..0000000000 --- a/lib/cmyth/libcmyth/livetv.c +++ /dev/null @@ -1,1065 +0,0 @@ -/* - * Copyright (C) 2006-2012, Sergio Slobodrian - * http://www.mvpmc.org/ - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -/* - * livetv.c - functions to handle operations on MythTV livetv chains. A - * MythTV livetv chain is the part of the backend that handles - * recording of live-tv for streaming to a MythTV frontend. - * This allows the watcher to do things like pause, rewind - * and so forth on live-tv. - */ -#include <stdlib.h> -#include <stdio.h> -#include <errno.h> -#include <string.h> -#include <sys/types.h> -#include <cmyth_local.h> - -#define LAST 0x7FFFFFFF - -static int cmyth_livetv_chain_has_url(cmyth_recorder_t rec, char * url); -static int cmyth_livetv_chain_add_file(cmyth_recorder_t rec, - char * url, cmyth_file_t fp); -static int cmyth_livetv_chain_add_url(cmyth_recorder_t rec, char * url); -static int cmyth_livetv_chain_add(cmyth_recorder_t rec, char * url, - cmyth_file_t fp, cmyth_proginfo_t prog); - - -/* - * cmyth_livetv_chain_destroy(cmyth_livetv_chain_t ltc) - * - * Scope: PRIVATE (static) - * - * Description - * - * Clean up and free a livetv chain structure. This should only be done - * by the ref_release() code. Everyone else should call - * ref_release() because ring buffer structures are reference - * counted. - * - * Return Value: - * - * None. - */ -static void -cmyth_livetv_chain_destroy(cmyth_livetv_chain_t ltc) -{ - int i; - - cmyth_dbg(CMYTH_DBG_DEBUG, "%s\n", __FUNCTION__); - if (!ltc) { - return; - } - - if (ltc->chainid) { - ref_release(ltc->chainid); - } - if (ltc->chain_urls) { - for(i=0;i<ltc->chain_ct; i++) - if (ltc->chain_urls[i]) - ref_release(ltc->chain_urls[i]); - ref_release(ltc->chain_urls); - } - if (ltc->chain_files) { - for(i=0;i<ltc->chain_ct; i++) - if (ltc->chain_files[i]) - ref_release(ltc->chain_files[i]); - ref_release(ltc->chain_files); - } - if (ltc->progs) { - for(i=0;i<ltc->chain_ct; i++) - if (ltc->progs[i]) - ref_release(ltc->progs[i]); - ref_release(ltc->progs); - } -} - -/* - * cmyth_livetv_chain_create(void) - * - * Scope: PUBLIC - * - * Description - * - * Allocate and initialize a ring buffer structure. - * - * Return Value: - * - * Success: A non-NULL cmyth_livetv_chain_t (this type is a pointer) - * - * Failure: A NULL cmyth_livetv_chain_t - */ -cmyth_livetv_chain_t -cmyth_livetv_chain_create(char * chainid) -{ - cmyth_livetv_chain_t ret = ref_alloc(sizeof(*ret)); - - cmyth_dbg(CMYTH_DBG_DEBUG, "%s\n", __FUNCTION__); - if (!ret) { - return NULL; - } - - ret->chainid = ref_strdup(chainid); - ret->chain_ct = 0; - ret->chain_switch_on_create = 0; - ret->chain_current = -1; - ret->chain_urls = NULL; - ret->chain_files = NULL; - ret->progs = NULL; - ref_set_destroy(ret, (ref_destroy_t)cmyth_livetv_chain_destroy); - return ret; -} - -/* - Returns the index of the chain entry with the URL or 0 if the - URL isn't there. -*/ -/* - * cmyth_livetv_chain_has_url(void) - * - * Scope: PRIVATE - * - * Description - * - * Returns the index of the chain entry with the URL or -1 if the - * URL isn't there. - * - * Return Value: - * - * Success: The index of the entry in the chain that has the - * specified URL. - * - * Failure: -1 if the URL doesn't appear in the chain. - */ -int cmyth_livetv_chain_has_url(cmyth_recorder_t rec, char * url) -{ - int found, i; - found = 0; - if(rec->rec_livetv_chain) { - if(rec->rec_livetv_chain->chain_current != -1) { - for(i=0;i<rec->rec_livetv_chain->chain_ct; i++) { - if(strcmp(rec->rec_livetv_chain->chain_urls[i],url) == 0) { - found = 1; - break; - } - } - } - } - return found?i:-1; -} - -#if 0 -static int cmyth_livetv_chain_current(cmyth_recorder_t rec); -int -cmyth_livetv_chain_current(cmyth_recorder_t rec) -{ - return rec->rec_livetv_chain->chain_current; -} - -static cmyth_file_t cmyth_livetv_get_cur_file(cmyth_recorder_t rec); -cmyth_file_t -cmyth_livetv_get_cur_file(cmyth_recorder_t rec) -{ - return rec->rec_livetv_file; -} -#endif - -/* - * cmyth_livetv_chain_add_file(cmyth_recorder_t rec, char * url, - * cmyth_file_t fp) - * - * Scope: PRIVATE - * - * Description - * - * Called to add a file handle to a livetv chain structure. The handle is added - * only if the url is already there. - * - * Return Value: - * - * Success: 0 - * - * Faiure: -1 - */ -static int -cmyth_livetv_chain_add_file(cmyth_recorder_t rec, char * url, cmyth_file_t ft) -{ - - int cur; - int ret = 0; - cmyth_file_t tmp; - - if(rec->rec_livetv_chain) { - if(rec->rec_livetv_chain->chain_current != -1) { - /* Is this file already in the chain? */ - if((cur = cmyth_livetv_chain_has_url(rec, url)) != -1) { - /* Release the existing handle after holding the new */ - /* this allows them to be the same. */ - tmp = rec->rec_livetv_chain->chain_files[cur]; - rec->rec_livetv_chain->chain_files[cur] = ref_hold(ft); - ref_release(tmp); - } - } - else { - cmyth_dbg(CMYTH_DBG_ERROR, - "%s: attempted to add file for %s to an empty chain\n", - __FUNCTION__, url); - ret = -1; - } - } - else { - cmyth_dbg(CMYTH_DBG_ERROR, - "%s: attempted to add file for %s to an non existant chain\n", - __FUNCTION__, url); - ret = -1; - } - return ret; -} - -/* - * cmyth_livetv_chain_add_prog(cmyth_recorder_t rec, char * url, - * cmyth_proginfo_t prog) - * - * Scope: PRIVATE - * - * Description - * - * Called to add program info to a livetv chain structure. The info is added - * only if the url is already there. - * - * Return Value: - * - * Success: 0 - * - * Faiure: -1 - */ -static int -cmyth_livetv_chain_add_prog(cmyth_recorder_t rec, char * url, - cmyth_proginfo_t prog) -{ - - int cur; - int ret = 0; - cmyth_proginfo_t tmp; - - if(rec->rec_livetv_chain) { - if(rec->rec_livetv_chain->chain_current != -1) { - /* Is this file already in the chain? */ - if((cur = cmyth_livetv_chain_has_url(rec, url)) != -1) { - /* Release the existing handle after holding the new */ - /* this allows them to be the same. */ - tmp = rec->rec_livetv_chain->progs[cur]; - rec->rec_livetv_chain->progs[cur] = ref_hold(prog); - ref_release(tmp); - } - } - else { - cmyth_dbg(CMYTH_DBG_ERROR, - "%s: attempted to add prog for %s to an empty chain\n", - __FUNCTION__, url); - ret = -1; - } - } - else { - cmyth_dbg(CMYTH_DBG_ERROR, - "%s: attempted to add prog for %s to an non existant chain\n", - __FUNCTION__, url); - ret = -1; - } - return ret; -} - -/* - * cmyth_livetv_chain_add_url(cmyth_recorder_t rec, char * url) - * - * Scope: PRIVATE - * - * Description - * - * Called to add a url to a livetv chain structure. The url is added - * only if it is not already there. - * - * Return Value: - * - * Success: 0 - * - * Faiure: -1 - */ -static int -cmyth_livetv_chain_add_url(cmyth_recorder_t rec, char * url) -{ - char ** tmp; - cmyth_file_t * fp; - cmyth_proginfo_t * pi; - int ret = 0; - - if(cmyth_livetv_chain_has_url(rec,url) == -1) { - if(rec->rec_livetv_chain->chain_current == -1) { - rec->rec_livetv_chain->chain_ct = 1; - rec->rec_livetv_chain->chain_current = 0; - /* Nothing in the chain yet, allocate the space */ - tmp = (char**)ref_alloc(sizeof(char *)); - fp = (cmyth_file_t *)ref_alloc(sizeof(cmyth_file_t)); - pi = (cmyth_proginfo_t *)ref_alloc(sizeof(cmyth_proginfo_t)); - } - else { - rec->rec_livetv_chain->chain_ct++; - tmp = (char**)ref_realloc(rec->rec_livetv_chain->chain_urls, - sizeof(char *)*rec->rec_livetv_chain->chain_ct); - fp = (cmyth_file_t *) - ref_realloc(rec->rec_livetv_chain->chain_files, - sizeof(cmyth_file_t)*rec->rec_livetv_chain->chain_ct); - pi = (cmyth_proginfo_t *) - ref_realloc(rec->rec_livetv_chain->progs, - sizeof(cmyth_proginfo_t)*rec->rec_livetv_chain->chain_ct); - } - if(tmp != NULL && fp != NULL) { - rec->rec_livetv_chain->chain_urls = ref_hold(tmp); - rec->rec_livetv_chain->chain_files = ref_hold(fp); - rec->rec_livetv_chain->progs = ref_hold(pi); - ref_release(tmp); - ref_release(fp); - ref_release(pi); - rec->rec_livetv_chain->chain_urls[rec->rec_livetv_chain->chain_ct-1] - = ref_strdup(url); - rec->rec_livetv_chain->chain_files[rec->rec_livetv_chain->chain_ct-1] - = ref_hold(NULL); - rec->rec_livetv_chain->progs[rec->rec_livetv_chain->chain_ct-1] - = ref_hold(NULL); - } - else { - ret = -1; - cmyth_dbg(CMYTH_DBG_ERROR, - "%s: memory allocation request failed\n", - __FUNCTION__); - } - - } - return ret; -} - -/* - * cmyth_livetv_chain_add(cmyth_recorder_t rec, char * url, cmyth_file_t ft) - * - * Scope: PRIVATE - * - * Description - * - * Called to add a url and file pointer to a livetv chain structure. - * The url is added only if it is not already there. The file pointer - * will be held (ref count increased) by this call if successful. - * - * Return Value: - * - * Success: 0 - * - * Faiure: -1 - */ -int -cmyth_livetv_chain_add(cmyth_recorder_t rec, char * url, cmyth_file_t ft, - cmyth_proginfo_t pi) -{ - int ret = 0; - - if(cmyth_livetv_chain_has_url(rec, url) == -1) - ret = cmyth_livetv_chain_add_url(rec, url); - if(ret != -1) - ret = cmyth_livetv_chain_add_file(rec, url, ft); - if(ret != -1) - ret = cmyth_livetv_chain_add_prog(rec, url, pi); - - return ret; -} - -/* - * cmyth_livetv_chain_update(cmyth_recorder_t rec, char * chainid, int buff) - * - * Scope: PUBLIC - * - * Description - * - * Called in response to the backend's notification of a chain update. - * The recorder is supplied and will be queried for the current recording - * to determine if a new file needs to be added to the chain of files - * in the live tv instance. - * - * Return Value: - * - * Success: 0 - * - * Failure: -1 - */ -int -cmyth_livetv_chain_update(cmyth_recorder_t rec, char * chainid, - int tcp_rcvbuf) -{ - int ret=0; - char url[1024]; - cmyth_proginfo_t loc_prog; - cmyth_file_t ft; - - if (!rec) { - cmyth_dbg(CMYTH_DBG_ERROR, "%s: rec is NULL\n", __FUNCTION__); - goto out; - } - - loc_prog = cmyth_recorder_get_cur_proginfo(rec); - pthread_mutex_lock(&mutex); - - if(rec->rec_livetv_chain) { - if(strncmp(rec->rec_livetv_chain->chainid, chainid, strlen(chainid)) == 0) { - sprintf(url, "myth://%s:%d%s",loc_prog->proginfo_hostname, rec->rec_port, - loc_prog->proginfo_pathname); - - /* - Now check if this file is in the recorder chain and if not - then open a new file transfer and add it to the chain. - */ - - if(cmyth_livetv_chain_has_url(rec, url) == -1) { - ft = cmyth_conn_connect_file(loc_prog, rec->rec_conn, 16*1024, tcp_rcvbuf); - if (!ft) { - cmyth_dbg(CMYTH_DBG_ERROR, - "%s: cmyth_conn_connect_file(%s) failed\n", - __FUNCTION__, url); - ret = -1; - goto out; - } - if(cmyth_livetv_chain_add(rec, url, ft, loc_prog) == -1) { - cmyth_dbg(CMYTH_DBG_ERROR, - "%s: cmyth_livetv_chain_add(%s) failed\n", - __FUNCTION__, url); - ret = -1; - goto out; - } - ref_release(ft); - if(rec->rec_livetv_chain->chain_switch_on_create) { - cmyth_livetv_chain_switch(rec, LAST); - rec->rec_livetv_chain->chain_switch_on_create = 0; - } - } - } - else { - cmyth_dbg(CMYTH_DBG_ERROR, - "%s: chainid doesn't match recorder's chainid!!\n", - __FUNCTION__, url); - ret = -1; - } - } - else { - cmyth_dbg(CMYTH_DBG_ERROR, - "%s: rec_livetv_chain is NULL!!\n", - __FUNCTION__, url); - ret = -1; - } - - ref_release(loc_prog); - out: - pthread_mutex_unlock(&mutex); - - return ret; -} - -/* - * cmyth_livetv_chain_setup(cmyth_recorder_t old_rec) - * - * Scope: PUBLIC - * - * Description - * - * Set up the file information the recorder needs to watch live - * tv. The recorder is supplied. This will be duplicated and - * released, so the caller can re-use the same variable to hold the - * return. The new copy of the recorder will have a livetv chain - * within it. - * - * Return Value: - * - * Success: A pointer to a new recorder structure with a livetvchain - * - * Failure: NULL but the recorder passed in is not released the - * caller needs to do this on a failure. - */ -cmyth_recorder_t -cmyth_livetv_chain_setup(cmyth_recorder_t rec, int tcp_rcvbuf, - void (*prog_update_callback)(cmyth_proginfo_t)) -{ - - cmyth_recorder_t new_rec = NULL; - char url[1024]; - cmyth_conn_t control; - cmyth_proginfo_t loc_prog, loc_prog2; - cmyth_file_t ft; - int i=0; - - - if (!rec) { - cmyth_dbg(CMYTH_DBG_ERROR, "%s: no recorder connection\n", - __FUNCTION__); - return NULL; - } - - control = rec->rec_conn; - /* Get the current recording information */ - loc_prog = cmyth_recorder_get_cur_proginfo(rec); - - /* Since backend will pretty much lockup when trying to open an * - * empty file, like the dummy file first generated by dvd */ - loc_prog2 = (cmyth_proginfo_t)ref_hold(loc_prog); - while(i++<5 && (loc_prog2 == NULL || (loc_prog2 && loc_prog2->proginfo_Length == 0))) { - usleep(200000); - if(loc_prog2) - ref_release(loc_prog2); - loc_prog2 = cmyth_recorder_get_cur_proginfo(rec); - loc_prog2 = cmyth_proginfo_get_detail(control, loc_prog2); - } - - if (loc_prog == NULL) { - cmyth_dbg(CMYTH_DBG_DEBUG, "%s: could not get current filename\n", - __FUNCTION__); - goto out; - } - - pthread_mutex_lock(&mutex); - - sprintf(url, "myth://%s:%d%s",loc_prog->proginfo_hostname, rec->rec_port, - loc_prog->proginfo_pathname); - - new_rec = cmyth_recorder_dup(rec); - if (new_rec == NULL) { - cmyth_dbg(CMYTH_DBG_DEBUG, "%s: cannot create recorder\n", - __FUNCTION__); - goto out; - } - ref_release(rec); - - if(new_rec->rec_livetv_chain == NULL) { - cmyth_dbg(CMYTH_DBG_DEBUG, "%s: error no livetv_chain\n", - __FUNCTION__); - new_rec = NULL; - goto out; - } - - if(cmyth_livetv_chain_has_url(new_rec, url) == -1) { - ft = cmyth_conn_connect_file(loc_prog, new_rec->rec_conn, 16*1024, tcp_rcvbuf); - if (!ft) { - cmyth_dbg(CMYTH_DBG_ERROR, - "%s: cmyth_conn_connect_file(%s) failed\n", - __FUNCTION__, url); - new_rec = NULL; - goto out; - } - if(cmyth_livetv_chain_add(new_rec, url, ft, loc_prog) == -1) { - cmyth_dbg(CMYTH_DBG_ERROR, - "%s: cmyth_livetv_chain_add(%s) failed\n", - __FUNCTION__, url); - new_rec = NULL; - goto out; - } - new_rec->rec_livetv_chain->prog_update_callback = prog_update_callback; - ref_release(ft); - cmyth_livetv_chain_switch(new_rec, 0); - } - - - ref_release(loc_prog); - out: - pthread_mutex_unlock(&mutex); - - return new_rec; -} - -/* - * cmyth_livetv_chain_get_block(cmyth_recorder_t rec, char *buf, - * unsigned long len) - * Scope: PUBLIC - * Description - * Read incoming file data off the network into a buffer of length len. - * - * Return Value: - * Sucess: number of bytes read into buf - * Failure: -1 - */ -int -cmyth_livetv_chain_get_block(cmyth_recorder_t rec, char *buf, - unsigned long len) -{ - if (!rec) { - cmyth_dbg(CMYTH_DBG_ERROR, "%s: no connection\n", - __FUNCTION__); - return -EINVAL; - } - - return cmyth_file_get_block(rec->rec_livetv_file, buf, len); -} - -static int -cmyth_livetv_chain_select(cmyth_recorder_t rec, struct timeval *timeout) -{ - if (!rec) { - cmyth_dbg(CMYTH_DBG_ERROR, "%s: no connection\n", - __FUNCTION__); - return -EINVAL; - } - - return cmyth_file_select(rec->rec_livetv_file, timeout); -} - - -/* - * cmyth_livetv_chain_switch(cmyth_recorder_t rec, int dir) - * - * Scope: PUBLIC - * - * Description - * - * Switches to the next or previous chain depending on the - * value of dir. Dir is usually 1 or -1. - * - * Return Value: - * - * Sucess: 1 - * - * Failure: 0 - */ -int -cmyth_livetv_chain_switch(cmyth_recorder_t rec, int dir) -{ - int ret; - - ret = 0; - - if(dir == LAST) { - dir = rec->rec_livetv_chain->chain_ct - - rec->rec_livetv_chain->chain_current - 1; - ret = 1; - } - - if((dir < 0 && rec->rec_livetv_chain->chain_current + dir >= 0) - || (rec->rec_livetv_chain->chain_current < - rec->rec_livetv_chain->chain_ct - dir )) { - ref_release(rec->rec_livetv_file); - ret = rec->rec_livetv_chain->chain_current += dir; - rec->rec_livetv_file = ref_hold(rec->rec_livetv_chain->chain_files[ret]); - rec->rec_livetv_chain - ->prog_update_callback(rec->rec_livetv_chain->progs[ret]); - ret = 1; - } - - return ret; -} - -/* for calls from other modules where the mutex isn't set */ -int -cmyth_livetv_chain_switch_last(cmyth_recorder_t rec) -{ - int dir; - - if (!rec) { - cmyth_dbg(CMYTH_DBG_ERROR, "%s: invalid args rec = %p\n", - __FUNCTION__, rec); - return 0; - } - - if (!rec->rec_conn) { - cmyth_dbg(CMYTH_DBG_ERROR, "%s: invalid args rec->rec_conn = %p\n", - __FUNCTION__, rec->rec_conn); - return 0; - } - - if(rec->rec_conn->conn_version < 26) - return 1; - - pthread_mutex_lock(&mutex); - dir = rec->rec_livetv_chain->chain_ct - - rec->rec_livetv_chain->chain_current - 1; - if(dir != 0) { - cmyth_livetv_chain_switch(rec, dir); - } - else { - rec->rec_livetv_chain->chain_switch_on_create=1; - } - pthread_mutex_unlock(&mutex); - return 1; -} - -/* - * cmyth_livetv_chain_request_block(cmyth_recorder_t file, unsigned long len) - * - * Scope: PUBLIC - * - * Description - * - * Request a file data block of a certain size, and return when the - * block has been transfered. - * - * Return Value: - * - * Sucess: number of bytes transfered - * - * Failure: an int containing -errno - */ -static int -cmyth_livetv_chain_request_block(cmyth_recorder_t rec, unsigned long len) -{ - int ret, retry; - - cmyth_dbg(CMYTH_DBG_DEBUG, "%s [%s:%d]: (trace) {\n", __FUNCTION__, - __FILE__, __LINE__); - - if (!rec) { - cmyth_dbg(CMYTH_DBG_ERROR, "%s: no connection\n", - __FUNCTION__); - return -EINVAL; - } - - pthread_mutex_lock(&mutex); - - do { - retry = 0; - ret = cmyth_file_request_block(rec->rec_livetv_file, len); - if (ret == 0) { /* We've gotten to the end, need to progress in the chain */ - /* Switch if there are files left in the chain */ - retry = cmyth_livetv_chain_switch(rec, 1); - } - } - while (retry); - - pthread_mutex_unlock(&mutex); - - cmyth_dbg(CMYTH_DBG_DEBUG, "%s [%s:%d]: (trace) }\n", - __FUNCTION__, __FILE__, __LINE__); - - return ret; -} - -int cmyth_livetv_chain_read(cmyth_recorder_t rec, char *buf, unsigned long len) -{ - int ret, retry; - - cmyth_dbg(CMYTH_DBG_DEBUG, "%s [%s:%d]: (trace) {\n", - __FUNCTION__, __FILE__, __LINE__); - - if (rec == NULL) { - cmyth_dbg(CMYTH_DBG_ERROR, "%s: no connection\n", - __FUNCTION__); - return -EINVAL; - } - - do { - retry = 0; - ret = cmyth_file_read(rec->rec_livetv_file, buf, len); - if (ret == 0) { - /* eof, switch to next file */ - retry = cmyth_livetv_chain_switch(rec, 1); - } - } while(retry); - - cmyth_dbg(CMYTH_DBG_DEBUG, "%s [%s:%d]: (trace) }\n", - __FUNCTION__, __FILE__, __LINE__); - - return ret; -} - -/* - * cmyth_livetv_chain_seek(cmyth_recorder_t file, long long offset, int whence) - * - * Scope: PUBLIC - * - * Description - * - * Seek to a new position in the file based on the value of whence: - * SEEK_SET - * The offset is set to offset bytes. - * SEEK_CUR - * The offset is set to the current position plus offset bytes. - * SEEK_END - * The offset is set to the size of the file minus offset bytes. - * - * Return Value: - * - * Sucess: 0 - * - * Failure: an int containing -errno - */ -static long long -cmyth_livetv_chain_seek(cmyth_recorder_t rec, long long offset, int whence) -{ - long long ret; - cmyth_file_t fp; - int cur, ct; - - if (rec == NULL) - return -EINVAL; - - ct = rec->rec_livetv_chain->chain_ct; - - if (whence == SEEK_END) { - - offset -= rec->rec_livetv_file->file_req; - for (cur = rec->rec_livetv_chain->chain_current; cur < ct; cur++) { - offset += rec->rec_livetv_chain->chain_files[cur]->file_length; - } - - cur = rec->rec_livetv_chain->chain_current; - fp = rec->rec_livetv_chain->chain_files[cur]; - whence = SEEK_CUR; - } - - if (whence == SEEK_SET) { - - for (cur = 0; cur < ct; cur++) { - fp = rec->rec_livetv_chain->chain_files[cur]; - if (offset < (long long)fp->file_length) - break; - offset -= fp->file_length; - } - } - - if (whence == SEEK_CUR) { - - if (offset == 0) { - cur = rec->rec_livetv_chain->chain_current; - offset += rec->rec_livetv_chain->chain_files[cur]->file_req; - for (; cur > 0; cur--) { - offset += rec->rec_livetv_chain->chain_files[cur-1]->file_length; - } - return offset; - } - - offset += fp->file_req; - - while (offset > (long long)fp->file_length) { - cur++; - offset -= fp->file_length; - if(cur == ct) - return -1; - fp = rec->rec_livetv_chain->chain_files[cur]; - } - - while (offset < 0) { - cur--; - if(cur < 0) - return -1; - fp = rec->rec_livetv_chain->chain_files[cur]; - offset += fp->file_length; - } - - offset -= fp->file_req; - } - - pthread_mutex_lock(&mutex); - - ret = cmyth_file_seek(fp, offset, whence); - - cur -= rec->rec_livetv_chain->chain_current; - if (ret >= 0 && cur) { - cmyth_livetv_chain_switch(rec, cur); - } - - pthread_mutex_unlock(&mutex); - - return ret; -} - -/* - * cmyth_livetv_read(cmyth_recorder_t rec, char *buf, unsigned long len) - * - * Scope: PUBLIC - * - * Description - * - * Request and read a block of data from backend - * - * Return Value: - * - * Sucess: number of bytes transfered - * - * Failure: an int containing -errno - */ -int cmyth_livetv_read(cmyth_recorder_t rec, char *buf, unsigned long len) -{ - if(rec->rec_conn->conn_version >= 26) - return cmyth_livetv_chain_read(rec, buf, len); - else - return cmyth_ringbuf_read(rec, buf, len); - -} - -/* - * cmyth_livetv_seek(cmyth_recorder_t file, long long offset, int whence) - * - * Scope: PUBLIC - * - * Description - * - * Seek to a new position in the file based on the value of whence: - * SEEK_SET - * The offset is set to offset bytes. - * SEEK_CUR - * The offset is set to the current position plus offset bytes. - * SEEK_END - * The offset is set to the size of the file minus offset bytes. - * This function will select the appropriate call based on the protocol. - * - * Return Value: - * - * Sucess: 0 - * - * Failure: an int containing -errno - */ -long long -cmyth_livetv_seek(cmyth_recorder_t rec, long long offset, int whence) -{ - long long rtrn; - - if(rec->rec_conn->conn_version >= 26) - rtrn = cmyth_livetv_chain_seek(rec, offset, whence); - else - rtrn = cmyth_ringbuf_seek(rec, offset, whence); - - return rtrn; -} - -/* - * cmyth_livetv_request_block(cmyth_recorder_t file, unsigned long len) - * - * Scope: PUBLIC - * - * Description - * - * Request a file data block of a certain size, and return when the - * block has been transfered. This function will select the appropriate - * call to use based on the protocol. - * - * Return Value: - * - * Sucess: number of bytes transfered - * - * Failure: an int containing -errno - */ -int -cmyth_livetv_request_block(cmyth_recorder_t rec, unsigned long size) -{ - unsigned long rtrn; - - if(rec->rec_conn->conn_version >= 26) - rtrn = cmyth_livetv_chain_request_block(rec, size); - else - rtrn = cmyth_ringbuf_request_block(rec, size); - - return rtrn; -} - -int -cmyth_livetv_select(cmyth_recorder_t rec, struct timeval *timeout) -{ - int rtrn; - - if(rec->rec_conn->conn_version >= 26) - rtrn = cmyth_livetv_chain_select(rec, timeout); - else - rtrn = cmyth_ringbuf_select(rec, timeout); - - return rtrn; -} - -/* - * cmyth_livetv_get_block(cmyth_recorder_t rec, char *buf, unsigned long len) - * Scope: PUBLIC - * Description - * Read incoming file data off the network into a buffer of length len. - * - * Return Value: - * Sucess: number of bytes read into buf - * Failure: -1 - */ -int -cmyth_livetv_get_block(cmyth_recorder_t rec, char *buf, unsigned long len) -{ - int rtrn; - - if(rec->rec_conn->conn_version >= 26) - rtrn = cmyth_livetv_chain_get_block(rec, buf, len); - else - rtrn = cmyth_ringbuf_get_block(rec, buf, len); - - return rtrn; -} - -cmyth_recorder_t -cmyth_spawn_live_tv(cmyth_recorder_t rec, unsigned buflen, int tcp_rcvbuf, - void (*prog_update_callback)(cmyth_proginfo_t), - char ** err, char* channame) -{ - cmyth_recorder_t rtrn = NULL; - int i; - - if(rec->rec_conn->conn_version >= 26) { - if (cmyth_recorder_spawn_chain_livetv(rec, channame) != 0) { - *err = "Spawn livetv failed."; - goto err; - } - - if ((rtrn = cmyth_livetv_chain_setup(rec, tcp_rcvbuf, - prog_update_callback)) == NULL) { - *err = "Failed to setup livetv."; - goto err; - } - - for(i=0; i<20; i++) { - if(cmyth_recorder_is_recording(rtrn) != 1) - sleep(1); - else - break; - } - } - else { - if ((rtrn = cmyth_ringbuf_setup(rec)) == NULL) { - *err = "Failed to setup ringbuffer."; - goto err; - } - - if (cmyth_conn_connect_ring(rtrn, buflen, tcp_rcvbuf) != 0) { - *err = "Cannot connect to mythtv ringbuffer."; - goto err; - } - - if (cmyth_recorder_spawn_livetv(rtrn) != 0) { - *err = "Spawn livetv failed."; - goto err; - } - } - - if(rtrn->rec_conn->conn_version < 34 && channame) { - if (cmyth_recorder_pause(rtrn) != 0) { - *err = "Failed to pause recorder to change channel"; - goto err; - } - - if (cmyth_recorder_set_channel(rtrn, channame) != 0) { - *err = "Failed to change channel on recorder"; - goto err; - } - } - - err: - - return rtrn; -} diff --git a/lib/cmyth/libcmyth/mysql_query.c b/lib/cmyth/libcmyth/mysql_query.c deleted file mode 100644 index ade4c5c638..0000000000 --- a/lib/cmyth/libcmyth/mysql_query.c +++ /dev/null @@ -1,370 +0,0 @@ -/* - * Copyright (C) 2006-2009, Simon Hyde - * http://www.mvpmc.org/ - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -#include <sys/types.h> -#include <string.h> -#include <stdio.h> -#include <cmyth_local.h> - -#define CMYTH_ULONG_STRLEN ((sizeof(long)*3)+1) -#define CMYTH_LONG_STRLEN (CMYTH_ULONG_STRLEN+1) - -/** - * Hold in-progress query - */ -struct cmyth_mysql_query_s -{ - char * buf; - const char * source; - const char * source_pos; - int buf_size, buf_used, source_len; - cmyth_database_t db; -}; - - -/** - * Internal only! Registered as callback to de-allocate actual buffer if - * the query is de-allocated - * \param p pointer to the query data structure - */ -static void -query_destroy(void *p) -{ - cmyth_mysql_query_t * query = (cmyth_mysql_query_t *)p; - if(query->buf != NULL) - { - ref_release(query->buf); - query->buf = NULL; - query->buf_size = 0; - } - if(query->db != NULL) - { - ref_release(query->db); - query->db = NULL; - } -} - -/** - * Allocate a dynamic query string to have parameters added to it - * \param db database connection object - * \param query_string Query string with ? placemarks for all dynamic - * parameters, this is NOT copied and must therefore - * remain valid for the life of the query. - */ -cmyth_mysql_query_t * -cmyth_mysql_query_create(cmyth_database_t db, const char * query_string) -{ - cmyth_mysql_query_t * out; - out = ref_alloc(sizeof(*out)); - if(out != NULL) - { - ref_set_destroy(out,query_destroy); - out->source = out->source_pos = query_string; - out->source_len = strlen(out->source); - out->buf_size = out->source_len *2; - out->buf_used = 0; - out->db = ref_hold(db); - out->buf = ref_alloc(out->buf_size); - if(out->buf == NULL) - { - ref_release(out); - out = NULL; - } - else - { - out->buf[0] = '\0'; - } - - } - return out; -} - -void -cmyth_mysql_query_reset(cmyth_mysql_query_t *query) -{ - query->buf_used = 0; - query->source_pos = query->source; -} - -static int -query_buffer_check_len(cmyth_mysql_query_t *query, int len) -{ - if(len + query->buf_used >= query->buf_size) - { - /* Increase buffer size by len or out->source_len, whichever - * is bigger - */ - if(query->source_len > len) - query->buf_size += query->source_len; - else - query->buf_size += len; - query->buf = ref_realloc(query->buf,query->buf_size); - if(query->buf == NULL) - { - cmyth_mysql_query_reset(query); - return -1; - } - } - return 0; -} - -static int -query_buffer_add(cmyth_mysql_query_t *query, const char *buf,int len) -{ - int ret = query_buffer_check_len(query,len); - if(ret < 0) - return ret; - memcpy(query->buf + query->buf_used,buf,len); - query->buf_used +=len; - query->buf[query->buf_used] = '\0'; - return len; -} - -static inline int -query_buffer_add_str(cmyth_mysql_query_t *query, const char *str) -{ - return query_buffer_add(query,str,strlen(str)); -} - -static int -query_buffer_add_escape_str(cmyth_mysql_query_t *query, const char *str) -{ - int ret; - int srclen = strlen(str); - MYSQL * mysql; - unsigned long destlen; - /*According to the mysql C API refrence, there must be sourcelen*2 +1 - * characters of space in the destination buffer - */ - ret = query_buffer_check_len(query,srclen*2 +1); - if(ret < 0) - return ret; - mysql = cmyth_db_get_connection(query->db); - if(mysql == NULL) - return -1; - destlen = mysql_real_escape_string(mysql, query->buf + query->buf_used, - str, srclen); - query->buf_used += destlen; - /* MySQL claims it null terminates, but do so anyway just in case we've - * done something stupid - */ - query->buf[query->buf_used] = '\0'; - return destlen; -} - -static int -query_begin_next_param(cmyth_mysql_query_t *query) -{ - int len,ret; - const char * endpos = strchr(query->source_pos,(int)'?'); - /*No more parameter insertion points left!*/ - if(endpos == NULL) - return -1; - len = endpos - query->source_pos; - ret = query_buffer_add(query,query->source_pos,len); - query->source_pos = endpos + 1; - return ret; -} - -static inline int -query_buffer_add_long(cmyth_mysql_query_t * query, long param) -{ - char buf[CMYTH_LONG_STRLEN]; - sprintf(buf,"%ld",param); - return query_buffer_add_str(query,buf); -} - -static inline int -query_buffer_add_ulong(cmyth_mysql_query_t * query, long param) -{ - char buf[CMYTH_ULONG_STRLEN]; - sprintf(buf,"%lu",param); - return query_buffer_add_str(query,buf); -} - -/** - * Add a long integer parameter - * \param query the query object - * \param param the integer to add - */ -int -cmyth_mysql_query_param_long(cmyth_mysql_query_t * query,long param) -{ - int ret; - ret = query_begin_next_param(query); - if(ret < 0) - return ret; - return query_buffer_add_long(query,param); -} - -/** - * Add an unsigned long integer parameter - * \param query the query object - * \param param the integer to add - */ -int -cmyth_mysql_query_param_ulong(cmyth_mysql_query_t * query,unsigned long param) -{ - int ret; - ret = query_begin_next_param(query); - if(ret < 0) - return ret; - return query_buffer_add_ulong(query,param); -} - -/** - * Add an integer parameter - * \param query the query object - * \param param the integer to add - */ -int -cmyth_mysql_query_param_int(cmyth_mysql_query_t * query,int param) -{ - return cmyth_mysql_query_param_long(query,(long)param); -} - -/** - * Add an unsigned integer parameter - * \param query the query object - * \param param the integer to add - */ -int -cmyth_mysql_query_param_uint(cmyth_mysql_query_t * query,int param) -{ - return cmyth_mysql_query_param_ulong(query,(unsigned long)param); -} - -/** - * Add, and convert a unixtime to mysql date/timestamp - * \param query the query object - * \param param the time to add - */ -int -cmyth_mysql_query_param_unixtime(cmyth_mysql_query_t * query, time_t param) -{ - int ret; - ret = query_begin_next_param(query); - if(ret < 0) - return ret; - ret = query_buffer_add_str(query,"FROM_UNIXTIME("); - if(ret < 0) - return ret; - ret = query_buffer_add_long(query,(long)param); - if(ret < 0) - return ret; - return query_buffer_add_str(query,")"); -} - - -/** - * Add (including adding quotes), and escape a string parameter. - * \param query the query object - * \param param the string to add - */ -int -cmyth_mysql_query_param_str(cmyth_mysql_query_t * query, const char *param) -{ - int ret; - ret = query_begin_next_param(query); - if(ret < 0) - return ret; - if(param == NULL) - return query_buffer_add_str(query,"NULL"); - ret = query_buffer_add_str(query,"'"); - if(ret < 0) - return ret; - ret = query_buffer_add_escape_str(query,param); - if(ret < 0) - return ret; - return query_buffer_add_str(query,"'"); -} - -/** - * Get the completed query string - * \return If all fields haven't been filled, or there is some other failure - * this will return NULL, otherwise a string is returned. The returned - * string must be released by the caller using ref_release(). - */ -char * -cmyth_mysql_query_string(cmyth_mysql_query_t * query) -{ - if(strchr(query->source_pos, (int)'?') != NULL) - { - return NULL;/*Still more parameters to be added*/ - } - if(query_buffer_add_str(query,query->source_pos) < 0) - return NULL; - /*Point source_pos to the '\0' at the end of the string so this can - * be called multiple times - */ - query->source_pos = query->source + query->source_len; - return ref_hold(query->buf); -} - - -MYSQL_RES * -cmyth_mysql_query_result(cmyth_mysql_query_t * query) -{ - MYSQL_RES * retval = NULL; - int ret; - char * query_str; - MYSQL *mysql = cmyth_db_get_connection(query->db); - if(mysql == NULL) - return NULL; - query_str = cmyth_mysql_query_string(query); - if(query_str == NULL) - return NULL; - ret = mysql_query(mysql,query_str); - ref_release(query_str); - if(ret != 0) - { - cmyth_dbg(CMYTH_DBG_ERROR, "%s: mysql_query(%s) Failed: %s\n", - __FUNCTION__, query_str, mysql_error(mysql)); - return NULL; - } - retval = mysql_store_result(mysql); - if(retval == NULL) - { - cmyth_dbg(CMYTH_DBG_ERROR, "%s: mysql_use_result Failed: %s\n", - __FUNCTION__, query_str, mysql_error(mysql)); - } - return retval; -} - -int -cmyth_mysql_query(cmyth_mysql_query_t * query) -{ - int ret; - char * query_str; - MYSQL *mysql = cmyth_db_get_connection(query->db); - if(mysql == NULL) - return -1; - query_str = cmyth_mysql_query_string(query); - if(query_str == NULL) - return -1; - ret = mysql_query(mysql,query_str); - ref_release(query_str); - if(ret != 0) - { - cmyth_dbg(CMYTH_DBG_ERROR, "%s: mysql_query(%s) Failed: %s\n", - __FUNCTION__, query_str, mysql_error(mysql)); - return -1; - } - return 0; -} diff --git a/lib/cmyth/libcmyth/mythtv_mysql.c b/lib/cmyth/libcmyth/mythtv_mysql.c deleted file mode 100644 index de5695cc1d..0000000000 --- a/lib/cmyth/libcmyth/mythtv_mysql.c +++ /dev/null @@ -1,1347 +0,0 @@ -/* - * Copyright (C) 2004-2012, Eric Lund - * http://www.mvpmc.org/ - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -#include <stdlib.h> -#include <stdio.h> -#include <errno.h> -#include <string.h> -#include <mysql/mysql.h> -#include <cmyth_local.h> -#include <safe_string.h> - -void -cmyth_database_close(cmyth_database_t db) -{ - if(db->mysql != NULL) - { - mysql_close(db->mysql); - db->mysql = NULL; - } -} - -cmyth_database_t -cmyth_database_init(char *host, char *db_name, char *user, char *pass) -{ - cmyth_database_t rtrn = ref_alloc(sizeof(*rtrn)); - cmyth_dbg(CMYTH_DBG_DEBUG, "%s\n", __FUNCTION__); - - if (rtrn != NULL) { - rtrn->db_host = ref_strdup(host); - rtrn->db_user = ref_strdup(user); - rtrn->db_pass = ref_strdup(pass); - rtrn->db_name = ref_strdup(db_name); - } - - return rtrn; -} - -int -cmyth_database_set_host(cmyth_database_t db, char *host) -{ - cmyth_database_close(db); - ref_release(db->db_host); - db->db_host = ref_strdup(host); - if(! db->db_host) - return 0; - else - return 1; -} - -int -cmyth_database_set_user(cmyth_database_t db, char *user) -{ - cmyth_database_close(db); - ref_release(db->db_user); - db->db_user = ref_strdup(user); - if(! db->db_user) - return 0; - else - return 1; -} - -int -cmyth_database_set_pass(cmyth_database_t db, char *pass) -{ - cmyth_database_close(db); - ref_release(db->db_user); - db->db_pass = ref_strdup(pass); - if(! db->db_pass) - return 0; - else - return 1; -} - -int -cmyth_database_set_name(cmyth_database_t db, char *name) -{ - cmyth_database_close(db); - ref_release(db->db_name); - db->db_name = ref_strdup(name); - if(! db->db_name) - return 0; - else - return 1; -} - - -static int -cmyth_db_check_connection(cmyth_database_t db) -{ - if(db->mysql != NULL) - { - /* Fetch the mysql stats (uptime and stuff) to check the connection is - * still good - */ - if(mysql_stat(db->mysql) == NULL) - { - cmyth_database_close(db); - } - } - if(db->mysql == NULL) - { - db->mysql = mysql_init(NULL); - if(db->mysql == NULL) - { - fprintf(stderr,"%s: mysql_init() failed, insufficient memory?", - __FUNCTION__); - return -1; - } - if(NULL == mysql_real_connect(db->mysql, - db->db_host,db->db_user,db->db_pass,db->db_name,0,NULL,0)) - { - fprintf(stderr,"%s: mysql_connect() failed: %s", __FUNCTION__, - mysql_error(db->mysql)); - cmyth_database_close(db); - return -1; - } - } - return 0; -} - -MYSQL * -cmyth_db_get_connection(cmyth_database_t db) -{ - if(cmyth_db_check_connection(db) != 0) - { - cmyth_dbg(CMYTH_DBG_ERROR, "%s: cmyth_db_check_connection failed\n", - __FUNCTION__); - return NULL; - } - - /* - * mythbackend stores any multi-byte characters using utf8 encoding within latin1 database - * columns. The MySQL connection needs to be told to use a utf8 character set when reading the - * database columns or any multi-byte characters will be treated as 2 or 3 subsequent latin1 - * characters with nonsense values. - * - * http://www.mythtv.org/wiki/Fixing_Corrupt_Database_Encoding#Note_on_MythTV_0.21-fixes_and_below_character_encoding - * http://dev.mysql.com/doc/refman/5.0/en/charset-connection.html - */ - if(mysql_query(db->mysql,"SET NAMES utf8;")) { - cmyth_dbg(CMYTH_DBG_ERROR, "%s: mysql_query() failed: %s\n", __FUNCTION__, mysql_error(db->mysql)); - return NULL; - } - - return db->mysql; -} - -int -cmyth_schedule_recording(cmyth_conn_t conn, char * msg) -{ - int err=0; - int count; - char buf[256]; - - fprintf (stderr, "In function : %s\n",__FUNCTION__); - if (!conn) { - cmyth_dbg(CMYTH_DBG_ERROR, "%s: no connection\n", __FUNCTION__); - return -1; - } - - pthread_mutex_lock(&mutex); - - if ((err = cmyth_send_message(conn, msg)) < 0) { - cmyth_dbg(CMYTH_DBG_ERROR, - "%s: cmyth_send_message() failed (%d)\n",__FUNCTION__,err); - return err; - } - - count = cmyth_rcv_length(conn); - cmyth_rcv_string(conn, &err, buf, sizeof(buf)-1,count); - pthread_mutex_unlock(&mutex); - return err; -} - -char * -cmyth_mysql_escape_chars(cmyth_database_t db, char * string) -{ - char *N_string; - size_t len; - - if(cmyth_db_check_connection(db) != 0) - { - cmyth_dbg(CMYTH_DBG_ERROR, "%s: cmyth_db_check_connection failed\n", - __FUNCTION__); - fprintf(stderr,"%s: cmyth_db_check_connection failed\n", __FUNCTION__); - return NULL; - } - - len = strlen(string); - N_string=ref_alloc(len*2+1); - mysql_real_escape_string(db->mysql,N_string,string,len); - - return (N_string); -} - -int -cmyth_get_offset_mysql(cmyth_database_t db, int type, char *recordid, int chanid, char *title, char *subtitle, char *description, char *seriesid, char *programid) -{ - MYSQL_RES *res=NULL; - MYSQL_ROW row; - char query[1000]; - int count; - - if(cmyth_db_check_connection(db) != 0) - { - cmyth_dbg(CMYTH_DBG_ERROR, "%s: cmyth_db_check_connection failed\n", __FUNCTION__); - fprintf(stderr,"%s: cmyth_db_check_connection failed\n", __FUNCTION__); - return -1; - } - if (type == 1) { // startoffset - sprintf (query,"SELECT startoffset FROM record WHERE (recordid='%s' AND chanid=%d AND title='%s' AND subtitle='%s' AND description='%s' AND seriesid='%s' AND programid='%s')",recordid,chanid,title,subtitle,description,seriesid,programid); - } - else if (type == 0) { //endoffset - sprintf (query,"SELECT endoffset FROM record WHERE (recordid='%s' AND chanid=%d AND title='%s' AND subtitle='%s' AND description='%s' AND seriesid='%s' AND programid='%s')",recordid,chanid,title,subtitle,description,seriesid,programid); - } - - cmyth_dbg(CMYTH_DBG_ERROR, "%s : query=%s\n",__FUNCTION__, query); - - if(mysql_query(db->mysql,query)) { - cmyth_dbg(CMYTH_DBG_ERROR, "%s: mysql_query() Failed: %s\n", __FUNCTION__, mysql_error(db->mysql)); - return -1; - } - res = mysql_store_result(db->mysql); - if ( (count = (int)mysql_num_rows(res)) >0) { - row = mysql_fetch_row(res); - fprintf(stderr, "row grabbed done count=%d\n",count); - mysql_free_result(res); - return atoi(row[0]); - } - else { - mysql_free_result(res); - return 0; - } -} - -char * -cmyth_get_recordid_mysql(cmyth_database_t db, int chanid, char *title, char *subtitle, char *description, char *seriesid, char *programid) -{ - MYSQL_RES *res=NULL; - MYSQL_ROW row; - char query[1000]; - int count; - - if(cmyth_db_check_connection(db) != 0) - { - cmyth_dbg(CMYTH_DBG_ERROR, "%s: cmyth_db_check_connection failed\n", __FUNCTION__); - fprintf(stderr,"%s: cmyth_db_check_connection failed\n", __FUNCTION__); - return NULL; - } - sprintf (query,"SELECT recordid FROM record WHERE (chanid=%d AND title='%s' AND subtitle='%s' AND description='%s' AND seriesid='%s' AND programid='%s')",chanid,title,subtitle,description,seriesid,programid); - - cmyth_dbg(CMYTH_DBG_ERROR, "%s : query=%s\n",__FUNCTION__, query); - - if(mysql_query(db->mysql,query)) { - cmyth_dbg(CMYTH_DBG_ERROR, "%s: mysql_query() Failed: %s\n", __FUNCTION__, mysql_error(db->mysql)); - return NULL; - } - res = mysql_store_result(db->mysql); - if ( (count = (int)mysql_num_rows(res)) >0) { - row = mysql_fetch_row(res); - fprintf(stderr, "row grabbed done count=%d\n",count); - mysql_free_result(res); - return row[0]; - } - else { - mysql_free_result(res); - return "NULL"; - } -} - -int -cmyth_mysql_delete_scheduled_recording(cmyth_database_t db, char * query) -{ - int rows=0; - if(cmyth_db_check_connection(db) != 0) - { - cmyth_dbg(CMYTH_DBG_ERROR, "%s: cmyth_db_check_connection failed\n", - __FUNCTION__); - fprintf(stderr,"%s: cmyth_db_check_connection failed\n", __FUNCTION__); - return -1; - } - cmyth_dbg(CMYTH_DBG_ERROR, "mysql query :%s\n",query); - - if(mysql_real_query(db->mysql,query,(unsigned int) strlen(query))) { - cmyth_dbg(CMYTH_DBG_ERROR, "%s: mysql_query() Failed: %s\n", - __FUNCTION__, mysql_error(db->mysql)); - return -1; - } - rows=(int)mysql_affected_rows(db->mysql); - - if (rows <=0) { - cmyth_dbg(CMYTH_DBG_ERROR, "%s: mysql_query() Failed: %s\n", - __FUNCTION__, mysql_error(db->mysql)); - } - - return rows; -} - -int -cmyth_mysql_insert_into_record(cmyth_database_t db, char * query, char * query1, char * query2, char *title, char * subtitle, char * description, char * callsign) -{ - int rows=0; - char *N_title; - char *N_subtitle; - char *N_description; - char *N_callsign; - char N_query[2570]; - - if(cmyth_db_check_connection(db) != 0) - { - cmyth_dbg(CMYTH_DBG_ERROR, "%s: cmyth_db_check_connection failed\n", - __FUNCTION__); - fprintf(stderr,"%s: cmyth_db_check_connection failed\n", __FUNCTION__); - return -1; - } - - N_title = ref_alloc(strlen(title)*2+1); - mysql_real_escape_string(db->mysql,N_title,title,strlen(title)); - N_subtitle = ref_alloc(strlen(subtitle)*2+1); - mysql_real_escape_string(db->mysql,N_subtitle,subtitle,strlen(subtitle)); - N_description = ref_alloc(strlen(description)*2+1); - mysql_real_escape_string(db->mysql,N_description,description,strlen(description)); - N_callsign = ref_alloc(strlen(callsign)*2+1); - mysql_real_escape_string(db->mysql,N_callsign,callsign,strlen(callsign)); - - snprintf(N_query,2500,"%s '%s','%s','%s' %s '%s' %s",query,N_title,N_subtitle,N_description,query1,N_callsign,query2); - ref_release(N_title); - ref_release(N_subtitle); - ref_release(N_callsign); - cmyth_dbg(CMYTH_DBG_ERROR, "mysql query :%s\n",N_query); - - if(mysql_real_query(db->mysql,N_query,(unsigned int) strlen(N_query))) { - cmyth_dbg(CMYTH_DBG_ERROR, "%s: mysql_query() Failed: %s\n", - __FUNCTION__, mysql_error(db->mysql)); - return -1; - } - rows=(int)mysql_insert_id(db->mysql); - - if (rows <=0) { - cmyth_dbg(CMYTH_DBG_ERROR, "%s: mysql_query() Failed: %s\n", - __FUNCTION__, mysql_error(db->mysql)); - } - - - return rows; -} - -int -cmyth_mysql_get_prev_recorded(cmyth_database_t db, cmyth_program_t **prog) -{ - MYSQL_RES *res= NULL; - MYSQL_ROW row; - int n=0; - int rows=0; - const char *query = "SELECT oldrecorded.chanid, UNIX_TIMESTAMP(starttime), UNIX_TIMESTAMP(endtime), title, subtitle, description, category, seriesid, programid, channel.channum, channel.callsign, channel.name, findid, rectype, recstatus, recordid, duplicate FROM oldrecorded LEFT JOIN channel ON oldrecorded.chanid = channel.chanid ORDER BY `starttime` ASC"; - if(cmyth_db_check_connection(db) != 0) - { - cmyth_dbg(CMYTH_DBG_ERROR, "%s: cmyth_db_check_connection failed\n", __FUNCTION__); - fprintf(stderr,"%s: cmyth_db_check_connection failed\n", __FUNCTION__); - return -1; - } - if(mysql_query(db->mysql,query)) { - cmyth_dbg(CMYTH_DBG_ERROR, "%s: mysql_query() Failed: %s\n", - __FUNCTION__, mysql_error(db->mysql)); - return -1; - } - res = mysql_store_result(db->mysql); - while((row = mysql_fetch_row(res))) { - if (rows >= n) { - n+=10; - *prog=realloc(*prog,sizeof(**prog)*(n)); - } - (*prog)[rows].chanid = safe_atoi(row[0]); - (*prog)[rows].recording=0; - (*prog)[rows].starttime=(time_t)safe_atol(row[1]); - (*prog)[rows].endtime= (time_t)safe_atol(row[2]); - sizeof_strncpy((*prog)[rows].title, row[3]); - sizeof_strncpy((*prog)[rows].subtitle, row[4]); - sizeof_strncpy((*prog)[rows].description, row[5]); - sizeof_strncpy((*prog)[rows].category, row[6]); - sizeof_strncpy((*prog)[rows].seriesid, row[7]); - sizeof_strncpy((*prog)[rows].programid, row[8]); - (*prog)[rows].channum = safe_atoi(row[9]); - sizeof_strncpy((*prog)[rows].callsign, row[10]); - sizeof_strncpy((*prog)[rows].name, row[11]); - //sizeof_strncpy((*prog)[rows].rec_status, row[14]); - (*prog)[rows].rec_status=safe_atoi(row[14]); - //fprintf(stderr, "row=%s val=%d\n",row[14],(*prog)[rows].rec_status); - rows++; - } - mysql_free_result(res); - cmyth_dbg(CMYTH_DBG_ERROR, "%s: rows= %d\n", __FUNCTION__, rows); - return rows; -} - -int -cmyth_mysql_get_guide(cmyth_database_t db, cmyth_program_t **prog, time_t starttime, time_t endtime) -{ - MYSQL_RES *res= NULL; - MYSQL_ROW row; - const char *query_str = "SELECT program.chanid,UNIX_TIMESTAMP(program.starttime),UNIX_TIMESTAMP(program.endtime),program.title,program.description,program.subtitle,program.programid,program.seriesid,program.category,channel.channum,channel.callsign,channel.name,channel.sourceid FROM program INNER JOIN channel ON program.chanid=channel.chanid WHERE ( ( starttime>=? and starttime<? ) OR ( starttime <? and endtime > ?) ) ORDER BY (channel.channum + 0), program.starttime ASC "; - int rows=0; - int n=0; - cmyth_mysql_query_t * query; - query = cmyth_mysql_query_create(db,query_str); - - if(cmyth_mysql_query_param_unixtime(query,starttime) < 0 - || cmyth_mysql_query_param_unixtime(query,endtime) < 0 - || cmyth_mysql_query_param_unixtime(query,starttime) < 0 - || cmyth_mysql_query_param_unixtime(query,starttime) < 0) - { - cmyth_dbg(CMYTH_DBG_ERROR,"%s, binding of query parameters failed! Maybe we're out of memory?\n", __FUNCTION__); - ref_release(query); - return -1; - } - res = cmyth_mysql_query_result(query); - ref_release(query); - if(res == NULL) - { - cmyth_dbg(CMYTH_DBG_ERROR,"%s, finalisation/execution of query failed!\n", __FUNCTION__); - return -1; - } - - - while((row = mysql_fetch_row(res))) { - if (rows >= n) { - n+=10; - *prog=ref_realloc(*prog,sizeof(**prog)*(n)); - } - (*prog)[rows].chanid = safe_atoi(row[0]); - (*prog)[rows].recording=0; - (*prog)[rows].starttime= (time_t)safe_atol(row[1]); - (*prog)[rows].endtime= (time_t)safe_atol(row[2]); - sizeof_strncpy((*prog)[rows].title, row[3]); - sizeof_strncpy((*prog)[rows].description, row[4]); - sizeof_strncpy((*prog)[rows].subtitle, row[5]); - sizeof_strncpy((*prog)[rows].programid, row[6]); - sizeof_strncpy((*prog)[rows].seriesid, row[7]); - sizeof_strncpy((*prog)[rows].category, row[8]); - (*prog)[rows].channum = safe_atoi(row[9]); - sizeof_strncpy((*prog)[rows].callsign, row[10]); - sizeof_strncpy((*prog)[rows].name, row[11]); - (*prog)[rows].sourceid = safe_atoi(row[12]); - (*prog)[rows].startoffset=0; - (*prog)[rows].endoffset=0; - rows++; - } - mysql_free_result(res); - cmyth_dbg(CMYTH_DBG_ERROR, "%s: rows= %d\n", __FUNCTION__, rows); - return rows; -} - -int -cmyth_mysql_get_recgroups(cmyth_database_t db, cmyth_recgroups_t **sqlrecgroups) -{ - MYSQL_RES *res=NULL; - MYSQL_ROW row; - const char *query="SELECT DISTINCT recgroup FROM record"; - int rows=0; - int n=0; - - if(cmyth_db_check_connection(db) != 0) - { - cmyth_dbg(CMYTH_DBG_ERROR, "%s: cmyth_db_check_connection failed\n", - __FUNCTION__); - fprintf(stderr,"%s: cmyth_db_check_connection failed\n", __FUNCTION__); - return -1; - } - - cmyth_dbg(CMYTH_DBG_ERROR, "%s: query= %s\n", __FUNCTION__, query); - if(mysql_query(db->mysql,query)) { - cmyth_dbg(CMYTH_DBG_ERROR, "%s: mysql_query() Failed: %s\n", - __FUNCTION__, mysql_error(db->mysql)); - return -1; - } - res = mysql_store_result(db->mysql); - while((row = mysql_fetch_row(res))) { - if (rows == n ) { - n++; - *sqlrecgroups=realloc(*sqlrecgroups,sizeof(**sqlrecgroups)*(n)); - } - sizeof_strncpy ( (*sqlrecgroups)[rows].recgroups, row[0]); - cmyth_dbg(CMYTH_DBG_ERROR, "(*sqlrecgroups)[%d].recgroups = %s\n",rows, (*sqlrecgroups)[rows].recgroups); - rows++; - } - mysql_free_result(res); - cmyth_dbg(CMYTH_DBG_ERROR, "%s: rows= %d\n", __FUNCTION__, rows); - return rows; -} - - -int -cmyth_mysql_get_prog_finder_char_title(cmyth_database_t db, cmyth_program_t **prog, time_t starttime, char *program_name) -{ - MYSQL_RES *res=NULL; - MYSQL_ROW row; - char query[350]; - int rows=0; - int n = 50; - - if(cmyth_db_check_connection(db) != 0) - { - cmyth_dbg(CMYTH_DBG_ERROR, "%s: cmyth_db_check_connection failed\n", - __FUNCTION__); - fprintf(stderr,"%s: cmyth_db_check_connection failed\n", __FUNCTION__); - return -1; - } - - if (strncmp(program_name, "@", 1)==0) - snprintf(query, 350, "SELECT DISTINCT title FROM program " \ - "WHERE ( title NOT REGEXP '^[A-Z0-9]' AND " \ - "title NOT REGEXP '^The [A-Z0-9]' AND " \ - "title NOT REGEXP '^A [A-Z0-9]' AND " \ - "starttime >= FROM_UNIXTIME(%d)) ORDER BY title", \ - (int)starttime); - else - snprintf(query, 350, "SELECT DISTINCT title FROM program " \ - "where starttime >= FROM_UNIXTIME(%d) and " \ - "title like '%s%%' ORDER BY `title` ASC", - (int)starttime, program_name); - - fprintf(stderr, "%s\n", query); - cmyth_dbg(CMYTH_DBG_ERROR, "%s: query= %s\n", __FUNCTION__, query); - if(mysql_query(db->mysql,query)) { - cmyth_dbg(CMYTH_DBG_ERROR, "%s: mysql_query() Failed: %s\n", - __FUNCTION__, mysql_error(db->mysql)); - return -1; - } - res = mysql_store_result(db->mysql); - while((row = mysql_fetch_row(res))) { - if (rows == n) { - n++; - *prog=realloc(*prog,sizeof(**prog)*(n)); - } - sizeof_strncpy ( (*prog)[rows].title, row[0]); - cmyth_dbg(CMYTH_DBG_ERROR, "prog[%d].title = %s\n",rows, (*prog)[rows].title); - rows++; - } - mysql_free_result(res); - cmyth_dbg(CMYTH_DBG_ERROR, "%s: rows= %d\n", __FUNCTION__, rows); - return rows; -} - -int -cmyth_mysql_get_prog_finder_time(cmyth_database_t db, cmyth_program_t **prog, time_t starttime, char *program_name) -{ - MYSQL_RES *res=NULL; - MYSQL_ROW row; - char query[630]; - char *N_title; - int rows=0; - int n = 50; - int ch; - - - if(cmyth_db_check_connection(db) != 0) - { - cmyth_dbg(CMYTH_DBG_ERROR, "%s: cmyth_db_check_connection failed\n", - __FUNCTION__); - fprintf(stderr,"%s: cmyth_db_check_connection failed\n", __FUNCTION__); - return -1; - } - - N_title = ref_alloc(strlen(program_name)*2+1); - mysql_real_escape_string(db->mysql,N_title,program_name,strlen(program_name)); - - //sprintf(query, "SELECT chanid,starttime,endtime,title,description,subtitle,programid,seriesid,category FROM program WHERE starttime >= '%s' and title ='%s' ORDER BY `starttime` ASC ", starttime, N_title); - snprintf(query, 630, "SELECT program.chanid,UNIX_TIMESTAMP(program.starttime),UNIX_TIMESTAMP(program.endtime),program.title,program.description,program.subtitle,program.programid,program.seriesid,program.category, channel.channum, channel.callsign, channel.name, channel.sourceid FROM program LEFT JOIN channel on program.chanid=channel.chanid WHERE starttime >= FROM_UNIXTIME(%d) and title ='%s' ORDER BY `starttime` ASC ", (int)starttime, N_title); - ref_release(N_title); - fprintf(stderr, "%s\n", query); - cmyth_dbg(CMYTH_DBG_ERROR, "%s: query= %s\n", __FUNCTION__, query); - if(mysql_query(db->mysql,query)) { - cmyth_dbg(CMYTH_DBG_ERROR, "%s: mysql_query() Failed: %s\n", - __FUNCTION__, mysql_error(db->mysql)); - return -1; - } - cmyth_dbg(CMYTH_DBG_ERROR, "n = %d\n",n); - res = mysql_store_result(db->mysql); - cmyth_dbg(CMYTH_DBG_ERROR, "n = %d\n",n); - while((row = mysql_fetch_row(res))) { - cmyth_dbg(CMYTH_DBG_ERROR, "n = %d\n",n); - if (rows == n) { - n++; - cmyth_dbg(CMYTH_DBG_ERROR, "realloc n = %d\n",n); - *prog=realloc(*prog,sizeof(**prog)*(n)); - } - cmyth_dbg(CMYTH_DBG_ERROR, "rows = %d\nrow[0]=%d\n",rows, row[0]); - cmyth_dbg(CMYTH_DBG_ERROR, "row[1]=%d\n",row[1]); - ch = atoi(row[0]); - (*prog)[rows].chanid=ch; - cmyth_dbg(CMYTH_DBG_ERROR, "prog[%d].chanid = %d\n",rows, (*prog)[rows].chanid); - (*prog)[rows].recording=0; - (*prog)[rows].starttime = atoi(row[1]); - (*prog)[rows].endtime = atoi(row[2]); - sizeof_strncpy ((*prog)[rows].title, row[3]); - sizeof_strncpy ((*prog)[rows].description, row[4]); - sizeof_strncpy ((*prog)[rows].subtitle, row[5]); - sizeof_strncpy ((*prog)[rows].programid, row[6]); - sizeof_strncpy ((*prog)[rows].seriesid, row[7]); - sizeof_strncpy ((*prog)[rows].category, row[8]); - (*prog)[rows].channum = atoi (row[9]); - sizeof_strncpy ((*prog)[rows].callsign,row[10]); - sizeof_strncpy ((*prog)[rows].name,row[11]); - (*prog)[rows].sourceid = atoi (row[12]); - cmyth_dbg(CMYTH_DBG_ERROR, "prog[%d].chanid = %d\n",rows, (*prog)[rows].chanid); - cmyth_dbg(CMYTH_DBG_ERROR, "prog[%d].title = %s\n",rows, (*prog)[rows].title); - rows++; - } - mysql_free_result(res); - cmyth_dbg(CMYTH_DBG_ERROR, "%s: rows= %d\n", __FUNCTION__, rows); - return rows; -} - -int -fill_program_recording_status(cmyth_conn_t conn, char * msg) -{ - int err=0; - fprintf (stderr, "In function : %s\n",__FUNCTION__); - if (!conn) { - cmyth_dbg(CMYTH_DBG_ERROR, "%s: no connection\n", __FUNCTION__); - return -1; - } - if ((err = cmyth_send_message(conn, msg)) < 0) { - cmyth_dbg(CMYTH_DBG_ERROR, - "%s: cmyth_send_message() failed (%d)\n",__FUNCTION__,err); - return err; - } - return err; -} -int -cmyth_update_bookmark_setting(cmyth_database_t db, cmyth_proginfo_t prog) -{ - MYSQL_RES *res = NULL; - const char *query_str = "UPDATE recorded SET bookmark = 1 WHERE chanid = ? AND starttime = ?"; - cmyth_mysql_query_t * query; - char starttime[CMYTH_TIMESTAMP_LEN + 1]; - - cmyth_timestamp_to_string(starttime, prog->proginfo_rec_start_ts); - query = cmyth_mysql_query_create(db,query_str); - if (cmyth_mysql_query_param_long(query, prog->proginfo_chanId) < 0 - || cmyth_mysql_query_param_str(query, starttime) < 0 ) { - cmyth_dbg(CMYTH_DBG_ERROR,"%s, binding of query parameters failed! Maybe we're out of memory?\n", __FUNCTION__); - ref_release(query); - return -1; - } - res = cmyth_mysql_query_result(query); - ref_release(query); - if (res == NULL) { - cmyth_dbg(CMYTH_DBG_ERROR, "%s, finalisation/execution of query failed!\n", __FUNCTION__); - return -1; - } - mysql_free_result(res); - return (1); -} - -long long -cmyth_get_bookmark_mark(cmyth_database_t db, cmyth_proginfo_t prog, long long bk, int mode) -{ - MYSQL_RES *res = NULL; - MYSQL_ROW row; - const char *query_str = "SELECT mark, type FROM recordedseek WHERE chanid = ? AND offset < ? AND (type = 6 or type = 9 ) AND starttime = ? ORDER by MARK DESC LIMIT 0, 1;"; - int rows = 0; - long long mark=0; - int rectype = 0; - char start_ts_dt[CMYTH_TIMESTAMP_LEN + 1]; - cmyth_mysql_query_t * query; - cmyth_timestamp_to_string(start_ts_dt, prog->proginfo_rec_start_ts); - query = cmyth_mysql_query_create(db,query_str); - - if (cmyth_mysql_query_param_long(query, prog->proginfo_chanId) < 0 - || cmyth_mysql_query_param_long(query, bk) < 0 - || cmyth_mysql_query_param_str(query, start_ts_dt) < 0 - ) { - cmyth_dbg(CMYTH_DBG_ERROR,"%s, binding of query parameters failed! Maybe we're out of memory?\n", __FUNCTION__); - ref_release(query); - return -1; - } - res = cmyth_mysql_query_result(query); - ref_release(query); - if (res == NULL) { - cmyth_dbg(CMYTH_DBG_ERROR, "%s, finalisation/execution of query failed!\n", __FUNCTION__); - return -1; - } - while ((row = mysql_fetch_row(res))) { - mark = safe_atoi(row[0]); - rectype = safe_atoi(row[1]); - rows++; - } - mysql_free_result(res); - - if (rectype == 6) { - if (mode == 0) { - mark=(mark-1)*15; - } - else if (mode == 1) { - mark=(mark-1)*12; - } - } - - return mark; -} - -int -cmyth_get_bookmark_offset(cmyth_database_t db, long chanid, long long mark, char *starttime, int mode) -{ - MYSQL_RES *res = NULL; - MYSQL_ROW row; - int offset=0; - int rows = 0; - int rectype = 0; - cmyth_mysql_query_t * query; - - const char *query_str = "SELECT * FROM recordedseek WHERE chanid = ? AND mark<= ? AND starttime = ? ORDER BY MARK DESC LIMIT 1;"; - - query = cmyth_mysql_query_create(db,query_str); - if (cmyth_mysql_query_param_long(query, chanid) < 0 - || cmyth_mysql_query_param_long(query, mark) < 0 - || cmyth_mysql_query_param_str(query, starttime) < 0 - ) { - cmyth_dbg(CMYTH_DBG_ERROR,"%s, binding of query parameters failed! Maybe we're out of memory?\n", __FUNCTION__); - ref_release(query); - return -1; - } - res = cmyth_mysql_query_result(query); - ref_release(query); - if (res == NULL) { - cmyth_dbg(CMYTH_DBG_ERROR, "%s, finalisation/execution of query failed!\n", __FUNCTION__); - return -1; - } - while ((row = mysql_fetch_row(res))) { - offset = safe_atoi(row[3]); - rectype = safe_atoi(row[4]); - rows++; - } - if (rectype != 9) { - if (mode == 0) { - mark=(mark/15)+1; - } - else if (mode == 1) { - mark=(mark/12)+1; - } - query = cmyth_mysql_query_create(db, query_str); - if (cmyth_mysql_query_param_long(query, chanid) < 0 - || cmyth_mysql_query_param_long(query, mark) < 0 - || cmyth_mysql_query_param_str(query, starttime) < 0 - ) { - cmyth_dbg(CMYTH_DBG_ERROR,"%s, binding of query parameters failed! Maybe we're out of memory?\n", __FUNCTION__); - ref_release(query); - return -1; - } - res = cmyth_mysql_query_result(query); - ref_release(query); - if (res == NULL) { - cmyth_dbg(CMYTH_DBG_ERROR, "%s, finalisation/execution of query failed!\n", __FUNCTION__); - return -1; - } - while ((row = mysql_fetch_row(res))) { - offset = safe_atoi(row[3]); - rows++; - } - } - mysql_free_result(res); - return offset; -} - -int -cmyth_mysql_query_commbreak_count(cmyth_database_t db, int chanid, char * start_ts_dt) { - MYSQL_RES *res = NULL; - int count = 0; - char * query_str; - cmyth_mysql_query_t * query; - query_str = "SELECT * FROM recordedmarkup WHERE chanid = ? AND starttime = ? AND TYPE IN ( 4 )"; - - query = cmyth_mysql_query_create(db,query_str); - if ((cmyth_mysql_query_param_int(query, chanid) < 0 - || cmyth_mysql_query_param_str(query, start_ts_dt) < 0 - )) { - cmyth_dbg(CMYTH_DBG_ERROR,"%s, binding of query parameters failed! Maybe we're out of memory?\n", __FUNCTION__); - ref_release(query); - return -1; - } - res = cmyth_mysql_query_result(query); - ref_release(query); - if (res == NULL) { - cmyth_dbg(CMYTH_DBG_ERROR,"%s, finalisation/execution of query failed!\n", __FUNCTION__); - return -1; - } - count = (int)mysql_num_rows(res); - mysql_free_result(res); - return (count); -} - -int -cmyth_mysql_get_commbreak_list(cmyth_database_t db, int chanid, char * start_ts_dt, cmyth_commbreaklist_t breaklist, int conn_version) -{ - MYSQL_RES *res = NULL; - MYSQL_ROW row; - int resolution = 30; - char * query_str; - int rows = 0; - int i; - cmyth_mysql_query_t * query; - cmyth_commbreak_t commbreak = NULL; - long long start_previous = 0; - long long end_previous = 0; - - if (conn_version >= 43) { - query_str = "SELECT m.type,m.mark,s.mark,s.offset FROM recordedmarkup m INNER JOIN recordedseek AS s ON m.chanid = s.chanid AND m.starttime = s.starttime WHERE m.chanid = ? AND m.starttime = ? AND m.type in (?,?) and FLOOR(m.mark/?)=FLOOR(s.mark/?) ORDER BY `m`.`mark` LIMIT 300 "; - } - else { - query_str = "SELECT m.type AS type, m.mark AS mark, s.offset AS offset FROM recordedmarkup m INNER JOIN recordedseek AS s ON (m.chanid = s.chanid AND m.starttime = s.starttime AND (FLOOR(m.mark / 15) + 1) = s.mark) WHERE m.chanid = ? AND m.starttime = ? AND m.type IN (?, ?) ORDER BY mark;"; - } - - cmyth_dbg(CMYTH_DBG_ERROR,"%s, query=%s\n", __FUNCTION__,query_str); - - query = cmyth_mysql_query_create(db,query_str); - - if ((conn_version >= 43) && ( - cmyth_mysql_query_param_int(query, chanid) < 0 - || cmyth_mysql_query_param_str(query, start_ts_dt) < 0 - || cmyth_mysql_query_param_int(query, CMYTH_COMMBREAK_START) < 0 - || cmyth_mysql_query_param_int(query, CMYTH_COMMBREAK_END) < 0 - || cmyth_mysql_query_param_int(query, resolution) < 0 - || cmyth_mysql_query_param_int(query, resolution) < 0 - )) { - cmyth_dbg(CMYTH_DBG_ERROR,"%s, binding of query parameters failed! Maybe we're out of memory?\n", __FUNCTION__); - ref_release(query); - return -1; - } - - if ((conn_version < 43) && ( - cmyth_mysql_query_param_int(query, chanid) < 0 - || cmyth_mysql_query_param_str(query, start_ts_dt) < 0 - || cmyth_mysql_query_param_int(query, CMYTH_COMMBREAK_START) < 0 - || cmyth_mysql_query_param_int(query, CMYTH_COMMBREAK_END) < 0 - )) { - cmyth_dbg(CMYTH_DBG_ERROR,"%s, binding of query parameters failed! Maybe we're out of memory?\n", __FUNCTION__); - ref_release(query); - return -1; - } - res = cmyth_mysql_query_result(query); - ref_release(query); - if (res == NULL) { - cmyth_dbg(CMYTH_DBG_ERROR, "%s, finalisation/execution of query failed!\n", __FUNCTION__); - return -1; - } - - if (conn_version >= 43) { - breaklist->commbreak_count = cmyth_mysql_query_commbreak_count(db,chanid,start_ts_dt); - } - else { - breaklist->commbreak_count = (long)mysql_num_rows(res) / 2; - } - breaklist->commbreak_list = malloc(breaklist->commbreak_count * sizeof(cmyth_commbreak_t)); - - if (!breaklist->commbreak_list) { - cmyth_dbg(CMYTH_DBG_ERROR, "%s: malloc() failed for list\n", - __FUNCTION__); - return -1; - } - memset(breaklist->commbreak_list, 0, breaklist->commbreak_count * sizeof(cmyth_commbreak_t)); - - i = 0; - if (conn_version >= 43) { - while ((row = mysql_fetch_row(res))) { - if (safe_atoi(row[0]) == CMYTH_COMMBREAK_START) { - if (safe_atoll(row[1]) != start_previous) { - commbreak = cmyth_commbreak_create(); - commbreak->start_mark = safe_atoll(row[1]); - commbreak->start_offset = safe_atoll(row[3]); - start_previous = commbreak->start_mark; - } - else if (safe_atoll(row[1]) == safe_atoll(row[2])) { - commbreak = cmyth_commbreak_create(); - commbreak->start_mark = safe_atoll(row[1]); - commbreak->start_offset = safe_atoll(row[3]); - } - } else if (safe_atoi(row[0]) == CMYTH_COMMBREAK_END) { - if (safe_atoll(row[1]) != end_previous) { - commbreak->end_mark = safe_atoll(row[1]); - commbreak->end_offset = safe_atoll(row[3]); - breaklist->commbreak_list[rows] = commbreak; - end_previous = commbreak->end_mark; - rows++; - } - else if (safe_atoll(row[1]) == safe_atoll(row[2])) { - commbreak->end_mark = safe_atoll(row[1]); - commbreak->end_offset = safe_atoll(row[3]); - breaklist->commbreak_list[rows] = commbreak; - if (end_previous != safe_atoll(row[1])) { - rows++; - } - } - } - else { - cmyth_dbg(CMYTH_DBG_ERROR, "%s: Unknown COMMBREAK returned\n", - __FUNCTION__); - return -1; - } - i++; - } - } - - // mythtv protolcol version < 43 - else { - while ((row = mysql_fetch_row(res))) { - if ((i % 2) == 0) { - if (safe_atoi(row[0]) != CMYTH_COMMBREAK_START) { - return -1; - } - commbreak = cmyth_commbreak_create(); - commbreak->start_mark = safe_atoll(row[1]); - commbreak->start_offset = safe_atoll(row[2]); - i++; - } else { - if (safe_atoi(row[0]) != CMYTH_COMMBREAK_END) { - return -1; - } - commbreak->end_mark = safe_atoll(row[1]); - commbreak->end_offset = safe_atoll(row[2]); - breaklist->commbreak_list[rows] = commbreak; - i = 0; - rows++; - } - } - } - mysql_free_result(res); - cmyth_dbg(CMYTH_DBG_ERROR, "%s: COMMBREAK rows= %d\n", __FUNCTION__, rows); - return rows; -} - -int -cmyth_tuner_type_check(cmyth_database_t db, cmyth_recorder_t rec, int check_tuner_type) { - MYSQL_RES *res=NULL; - MYSQL_ROW row; - const char * query_str = "SELECT cardtype from capturecard WHERE cardid=?"; - cmyth_mysql_query_t * query; - - if ( check_tuner_type == 0 ) { - cmyth_dbg(CMYTH_DBG_ERROR,"MythTV Tuner check not enabled in Mythtv Options\n"); - return (1); - } - - - query = cmyth_mysql_query_create(db,query_str); - if (cmyth_mysql_query_param_uint(query,rec->rec_id) < 0) { - cmyth_dbg(CMYTH_DBG_ERROR,"%s, binding of query failed\n",__FUNCTION__); - ref_release(query); - return -1; - } - res = cmyth_mysql_query_result(query); - - if(res == NULL) { - cmyth_dbg(CMYTH_DBG_ERROR,"%s, finalisation/execution\n",__FUNCTION__); - return -1; - } - row = mysql_fetch_row(res); - ref_release(query); - mysql_free_result(res); - if (strcmp(row[0],"MPEG") == 0) { - return (1); //return the first available MPEG tuner - } - else if (strcmp(row[0],"HDHOMERUN") == 0) { - return (1); //return the first available MPEG2TS tuner - } - else if (strcmp(row[0],"DVB") == 0) { - return (1); //return the first available DVB tuner - } - else { - return (0); - } -} - -int -cmyth_mythtv_remove_previous_recorded(cmyth_database_t db,char *query) -{ - MYSQL_RES *res=NULL; - char N_query[128]; - int rows; - - if(cmyth_db_check_connection(db) != 0) - { - cmyth_dbg(CMYTH_DBG_ERROR, "%s: cmyth_db_check_connection failed\n", - __FUNCTION__); - fprintf(stderr,"%s: cmyth_db_check_connection failed\n", __FUNCTION__); - return -1; - } - - mysql_real_escape_string(db->mysql,N_query,query,strlen(query)); - - if(mysql_query(db->mysql,query)) { - cmyth_dbg(CMYTH_DBG_ERROR, "%s: mysql_query() Failed: %s\n", - __FUNCTION__, mysql_error(db->mysql)); - return -1; - } - res = mysql_store_result(db->mysql); - rows=(int)mysql_insert_id(db->mysql); - if (rows <=0) { - cmyth_dbg(CMYTH_DBG_ERROR, "%s: mysql_query() Failed: %s\n", - __FUNCTION__, mysql_error(db->mysql)); - } - mysql_free_result(res); - - return rows; -} - -int -cmyth_mysql_testdb_connection(cmyth_database_t db,char **message) { - char *buf=malloc(sizeof(char)*1001); - int new_conn = 0; - if (db->mysql != NULL) { - if (mysql_stat(db->mysql) == NULL) { - cmyth_database_close(db); - return -1; - } - } - if (db->mysql == NULL) { - db->mysql = mysql_init(NULL); - new_conn = 1; - if(db->mysql == NULL) { - fprintf(stderr,"%s: mysql_init() failed, insufficient memory?", __FUNCTION__); - snprintf(buf, 1000, "mysql_init() failed, insufficient memory?"); - *message=buf; - return -1; - } - if (NULL == mysql_real_connect(db->mysql, db->db_host,db->db_user,db->db_pass,db->db_name,0,NULL,0)) { - fprintf(stderr,"%s: mysql_connect() failed: %s\n", __FUNCTION__, - mysql_error(db->mysql)); - snprintf(buf, 1000, "%s",mysql_error(db->mysql)); - fprintf (stderr,"buf = %s\n",buf); - *message=buf; - cmyth_database_close(db); - return -1; - } - } - snprintf(buf, 1000, "All Test Successful\n"); - *message=buf; - return 1; -} - -static void -cmyth_chanlist_destroy(cmyth_chanlist_t pl) -{ - int i; - - cmyth_dbg(CMYTH_DBG_DEBUG, "%s\n", __FUNCTION__); - if (!pl) { - return; - } - for (i = 0; i < pl->chanlist_count; ++i) { - if (pl->chanlist_list[i]) { - ref_release(pl->chanlist_list[i]); - } - pl->chanlist_list[i] = NULL; - } - if (pl->chanlist_list) { - free(pl->chanlist_list); - } -} - -cmyth_chanlist_t -cmyth_chanlist_create(void) -{ - cmyth_chanlist_t ret; - - cmyth_dbg(CMYTH_DBG_DEBUG, "%s\n", __FUNCTION__); - ret = ref_alloc(sizeof(*ret)); - if (!ret) { - return(NULL); - } - ref_set_destroy(ret, (ref_destroy_t)cmyth_chanlist_destroy); - - ret->chanlist_list = NULL; - ret->chanlist_count = 0; - return ret; -} - -cmyth_channel_t -cmyth_chanlist_get_item(cmyth_chanlist_t pl, int index) -{ - if (!pl) { - cmyth_dbg(CMYTH_DBG_ERROR, "%s: NULL program list\n", - __FUNCTION__); - return NULL; - } - if (!pl->chanlist_list) { - cmyth_dbg(CMYTH_DBG_ERROR, "%s: NULL list\n", - __FUNCTION__); - return NULL; - } - if ((index < 0) || (index >= pl->chanlist_count)) { - cmyth_dbg(CMYTH_DBG_ERROR, "%s: index %d out of range\n", - __FUNCTION__, index); - return NULL; - } - ref_hold(pl->chanlist_list[index]); - return pl->chanlist_list[index]; -} - -int -cmyth_chanlist_get_count(cmyth_chanlist_t pl) -{ - if (!pl) { - cmyth_dbg(CMYTH_DBG_ERROR, "%s: NULL program list\n", - __FUNCTION__); - return -EINVAL; - } - return pl->chanlist_count; -} - -static void -cmyth_channel_destroy(cmyth_channel_t pl) -{ - - cmyth_dbg(CMYTH_DBG_DEBUG, "%s\n", __FUNCTION__); - if (!pl) { - return; - } - - if(pl->name) - ref_release(pl->name); - if(pl->callsign) - ref_release(pl->callsign); - if(pl->icon) - ref_release(pl->callsign); -} - -long -cmyth_channel_chanid(cmyth_channel_t channel) -{ - if (!channel) { - return -EINVAL; - } - return channel->chanid; -} - -long -cmyth_channel_channum(cmyth_channel_t channel) -{ - if (!channel) { - return -EINVAL; - } - return channel->channum; -} - -char * -cmyth_channel_name(cmyth_channel_t channel) -{ - if (!channel) { - return NULL; - } - return ref_hold(channel->name); -} - -char * -cmyth_channel_icon(cmyth_channel_t channel) -{ - if (!channel) { - return NULL; - } - return ref_hold(channel->icon); -} - -int -cmyth_channel_visible(cmyth_channel_t channel) -{ - if (!channel) { - return -EINVAL; - } - return channel->visible; -} - -cmyth_channel_t -cmyth_channel_create(void) -{ - cmyth_channel_t ret = ref_alloc(sizeof(*ret)); - memset(ret, 0, sizeof(*ret)); - - cmyth_dbg(CMYTH_DBG_DEBUG, "%s {\n", __FUNCTION__); - if (!ret) { - cmyth_dbg(CMYTH_DBG_DEBUG, "%s }!\n", __FUNCTION__); - return NULL; - } - ref_set_destroy(ret, (ref_destroy_t)cmyth_channel_destroy); - - return ret; -} - - -cmyth_chanlist_t cmyth_mysql_get_chanlist(cmyth_database_t db) -{ - MYSQL_RES *res = NULL; - MYSQL_ROW row; - const char *query_str = "SELECT chanid, channum, name, icon, visible FROM channel;"; - int rows = 0; - int i; - cmyth_mysql_query_t * query; - cmyth_channel_t channel; - cmyth_chanlist_t chanlist; - query = cmyth_mysql_query_create(db,query_str); - - res = cmyth_mysql_query_result(query); - ref_release(query); - if (res == NULL) { - cmyth_dbg(CMYTH_DBG_ERROR, "%s, finalisation/execution of query failed!\n", __FUNCTION__); - return NULL; - } - - chanlist = cmyth_chanlist_create(); - - chanlist->chanlist_count = (int)mysql_num_rows(res); - chanlist->chanlist_list = malloc(chanlist->chanlist_count * sizeof(cmyth_chanlist_t)); - if (!chanlist->chanlist_list) { - cmyth_dbg(CMYTH_DBG_ERROR, "%s: malloc() failed for list\n", - __FUNCTION__); - ref_release(chanlist); - return NULL; - } - memset(chanlist->chanlist_list, 0, chanlist->chanlist_count * sizeof(cmyth_chanlist_t)); - - i = 0; - while ((row = mysql_fetch_row(res))) { - channel = cmyth_channel_create(); - channel->chanid = safe_atol(row[0]); - channel->channum = safe_atoi(row[1]); - channel->name = ref_strdup(row[2]); - channel->icon = ref_strdup(row[3]); - channel->visible = safe_atoi(row[4]); - chanlist->chanlist_list[rows] = channel; - i = 0; - rows++; - } - - mysql_free_result(res); - cmyth_dbg(CMYTH_DBG_ERROR, "%s: rows= %d\n", __FUNCTION__, rows); - return chanlist; -} - - -int cmyth_livetv_keep_recording(cmyth_recorder_t rec, cmyth_database_t db, int keep) -{ - cmyth_proginfo_t prog; - int autoexpire; - const char* recgroup; - cmyth_mysql_query_t * query; - char timestamp[CMYTH_TIMESTAMP_LEN+1]; - - if(cmyth_db_check_connection(db) != 0) - { - cmyth_dbg(CMYTH_DBG_ERROR, "%s: cmyth_db_check_connection failed\n", __FUNCTION__); - return -1; - } - - prog = cmyth_recorder_get_cur_proginfo(rec); - if(!prog) { - cmyth_dbg(CMYTH_DBG_ERROR, "%s: cmyth_recorder_get_cur_proginfo failed\n", __FUNCTION__); - return -1; - } - - if(keep) { - char* str; - str = cmyth_conn_get_setting(rec->rec_conn, prog->proginfo_hostname, "AutoExpireDefault"); - if(!str) { - cmyth_dbg(CMYTH_DBG_ERROR, "%s: failed to get AutoExpireDefault\n", __FUNCTION__); - ref_release(prog); - return -1; - } - autoexpire = atol(str); - recgroup = "Default"; - ref_release(str); - } else { - autoexpire = 10000; - recgroup = "LiveTV"; - } - - - sprintf(timestamp, - "%4.4ld-%2.2ld-%2.2ld %2.2ld:%2.2ld:%2.2ld", - prog->proginfo_rec_start_ts->timestamp_year, - prog->proginfo_rec_start_ts->timestamp_month, - prog->proginfo_rec_start_ts->timestamp_day, - prog->proginfo_rec_start_ts->timestamp_hour, - prog->proginfo_rec_start_ts->timestamp_minute, - prog->proginfo_rec_start_ts->timestamp_second); - - query = cmyth_mysql_query_create(db,"UPDATE recorded SET autoexpire = ?, recgroup = ? WHERE chanid = ? AND starttime = ?"); - - if(cmyth_mysql_query_param_long(query,autoexpire) < 0 - || cmyth_mysql_query_param_str(query,recgroup) < 0 - || cmyth_mysql_query_param_long(query,prog->proginfo_chanId) < 0 - || cmyth_mysql_query_param_str(query,timestamp) < 0) - { - cmyth_dbg(CMYTH_DBG_ERROR,"%s, binding of query parameters failed! Maybe we're out of memory?\n", __FUNCTION__); - ref_release(query); - ref_release(prog); - return -1; - } - - if(cmyth_mysql_query(query) < 0) - { - cmyth_dbg(CMYTH_DBG_ERROR,"%s, finalisation/execution of query failed!\n", __FUNCTION__); - ref_release(query); - ref_release(prog); - return -1; - } - ref_release(query); - - if(rec->rec_conn->conn_version >= 26) - { - char msg[256]; - int err; - snprintf(msg, sizeof(msg), "QUERY_RECORDER %d[]:[]SET_LIVE_RECORDING[]:[]%d", - rec->rec_id, keep); - - if ((err=cmyth_send_message(rec->rec_conn, msg)) < 0) { - cmyth_dbg(CMYTH_DBG_ERROR, - "%s: cmyth_send_message() failed (%d)\n", - __FUNCTION__, err); - return -1; - } - - if ((err=cmyth_rcv_okay(rec->rec_conn, "ok")) < 0) { - cmyth_dbg(CMYTH_DBG_ERROR, - "%s: cmyth_rcv_okay() failed (%d)\n", - __FUNCTION__, err); - return -1; - } - } - return 1; -} - diff --git a/lib/cmyth/libcmyth/posmap.c b/lib/cmyth/libcmyth/posmap.c deleted file mode 100644 index c5043ec0e2..0000000000 --- a/lib/cmyth/libcmyth/posmap.c +++ /dev/null @@ -1,94 +0,0 @@ -/* - * Copyright (C) 2004-2010, Eric Lund - * http://www.mvpmc.org/ - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -/* - * posmap.c - functions to handle operations on MythTV position maps. - * A position map contains a list of key-frames each of - * which represents a indexed position in a recording - * stream. These may be markers set by hand, or they may - * be markers inserted by commercial detection. A position - * map collects these in one place. - */ -#include <stdlib.h> -#include <stdio.h> -#include <cmyth_local.h> - -/* - * cmyth_posmap_destroy(cmyth_posmap_t pm) - * - * Scope: PRIVATE (static) - * - * Description - * - * Clean up and free a position map structure. This should only be done - * by the ref_release() code. Everyone else should call - * ref_release() because position map structures are reference - * counted. - * - * Return Value: - * - * None. - */ -static void -cmyth_posmap_destroy(cmyth_posmap_t pm) -{ - unsigned int i; - - cmyth_dbg(CMYTH_DBG_DEBUG, "%s\n", __FUNCTION__); - if (!pm) { - return; - } - if (pm->posmap_list) { - for (i = 0; i < pm->posmap_count; ++i) { - ref_release(pm->posmap_list[i]); - } - free(pm->posmap_list); - } -} - -/* - * cmyth_posmap_create(void) - * - * Scope: PUBLIC - * - * Description - * - * Allocate and initialize a position map structure. - * - * Return Value: - * - * Success: A non-NULL cmyth_posmap_t (this type is a pointer) - * - * Failure: A NULL cmyth_posmap_t - */ -cmyth_posmap_t -cmyth_posmap_create(void) -{ - cmyth_posmap_t ret = ref_alloc(sizeof(*ret)); - - cmyth_dbg(CMYTH_DBG_DEBUG, "%s\n", __FUNCTION__); - if (!ret) { - return NULL; - } - ref_set_destroy(ret, (ref_destroy_t)cmyth_posmap_destroy); - - ret->posmap_count = 0; - ret->posmap_list = NULL; - return ret; -} diff --git a/lib/cmyth/libcmyth/proginfo.c b/lib/cmyth/libcmyth/proginfo.c deleted file mode 100644 index fa9db29fa1..0000000000 --- a/lib/cmyth/libcmyth/proginfo.c +++ /dev/null @@ -1,1844 +0,0 @@ -/* - * Copyright (C) 2004-2010, Eric Lund - * http://www.mvpmc.org/ - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -/* - * proginfo.c - functions to manage MythTV program info. This is - * information kept by MythTV to describe recordings and - * also to describe programs in the program guide. The - * functions here allocate and fill out program - * information and lists of program information. They - * also retrieve and manipulate recordings and program - * material based on program information. - */ -#include <stdlib.h> -#include <stdio.h> -#include <errno.h> -#include <string.h> -#include <inttypes.h> -#include <cmyth_local.h> - -/* - * cmyth_proginfo_destroy(cmyth_proginfo_t p) - * - * Scope: PRIVATE (static) - * - * Description - * - * Destroy the program info structure pointed to by 'p' and release - * its storage. This should only be called by - * ref_release(). All others should use - * ref_release() to release references to a program info - * structure. - * - * Return Value: - * - * None. - */ -static void -cmyth_proginfo_destroy(cmyth_proginfo_t p) -{ - cmyth_dbg(CMYTH_DBG_DEBUG, "%s {\n", __FUNCTION__); - if (!p) { - cmyth_dbg(CMYTH_DBG_DEBUG, "%s }!a\n", __FUNCTION__); - return; - } - if (p->proginfo_title) { - ref_release(p->proginfo_title); - } - if (p->proginfo_subtitle) { - ref_release(p->proginfo_subtitle); - } - if (p->proginfo_description) { - ref_release(p->proginfo_description); - } - if (p->proginfo_category) { - ref_release(p->proginfo_category); - } - if (p->proginfo_chanstr) { - ref_release(p->proginfo_chanstr); - } - if (p->proginfo_chansign) { - ref_release(p->proginfo_chansign); - } - if (p->proginfo_channame) { - ref_release(p->proginfo_channame); - } - if (p->proginfo_chanicon) { - ref_release(p->proginfo_chanicon); - } - if (p->proginfo_url) { - ref_release(p->proginfo_url); - } - if (p->proginfo_unknown_0) { - ref_release(p->proginfo_unknown_0); - } - if (p->proginfo_hostname) { - ref_release(p->proginfo_hostname); - } - if (p->proginfo_rec_priority) { - ref_release(p->proginfo_rec_priority); - } - if (p->proginfo_rec_profile) { - ref_release(p->proginfo_rec_profile); - } - if (p->proginfo_recgroup) { - ref_release(p->proginfo_recgroup); - } - if (p->proginfo_chancommfree) { - ref_release(p->proginfo_chancommfree); - } - if (p->proginfo_chan_output_filters) { - ref_release(p->proginfo_chan_output_filters); - } - if (p->proginfo_seriesid) { - ref_release(p->proginfo_seriesid); - } - if (p->proginfo_programid) { - ref_release(p->proginfo_programid); - } - if (p->proginfo_inetref) { - ref_release(p->proginfo_inetref); - } - if (p->proginfo_stars) { - ref_release(p->proginfo_stars); - } - if (p->proginfo_pathname) { - ref_release(p->proginfo_pathname); - } - if (p->proginfo_host) { - ref_release(p->proginfo_host); - } - if (p->proginfo_playgroup) { - ref_release(p->proginfo_playgroup); - } - if (p->proginfo_lastmodified) { - ref_release(p->proginfo_lastmodified); - } - if (p->proginfo_start_ts) { - ref_release(p->proginfo_start_ts); - } - if (p->proginfo_end_ts) { - ref_release(p->proginfo_end_ts); - } - if (p->proginfo_rec_start_ts) { - ref_release(p->proginfo_rec_start_ts); - } - if (p->proginfo_rec_end_ts) { - ref_release(p->proginfo_rec_end_ts); - } - if (p->proginfo_originalairdate) { - ref_release(p->proginfo_originalairdate); - } - if (p->proginfo_storagegroup) { - ref_release(p->proginfo_storagegroup); - } - if (p->proginfo_recpriority_2) { - ref_release(p->proginfo_recpriority_2); - } - cmyth_dbg(CMYTH_DBG_DEBUG, "%s }\n", __FUNCTION__); -} - -/* - * cmyth_proginfo_create(void) - * - * Scope: PUBLIC - * - * Description - * - * Create a programinfo structure to be used to hold program - * information and return a pointer to the structure. The structure - * is initialized to default values. - * - * Return Value: - * - * Success: A non-NULL cmyth_proginfo_t (this type is a pointer) - * - * Failure: A NULL cmyth_proginfo_t - */ -cmyth_proginfo_t -cmyth_proginfo_create(void) -{ - cmyth_proginfo_t ret = ref_alloc(sizeof(*ret)); - - cmyth_dbg(CMYTH_DBG_DEBUG, "%s {\n", __FUNCTION__); - if (!ret) { - cmyth_dbg(CMYTH_DBG_DEBUG, "%s }!\n", __FUNCTION__); - return NULL; - } - ref_set_destroy(ret, (ref_destroy_t)cmyth_proginfo_destroy); - - ret->proginfo_start_ts = cmyth_timestamp_create(); - if (!ret->proginfo_start_ts) { - cmyth_dbg(CMYTH_DBG_DEBUG, "%s }!!\n", __FUNCTION__); - goto err; - } - ret->proginfo_end_ts = cmyth_timestamp_create(); - if (!ret->proginfo_end_ts) { - cmyth_dbg(CMYTH_DBG_DEBUG, "%s }!!!\n", __FUNCTION__); - goto err; - } - ret->proginfo_rec_start_ts = cmyth_timestamp_create(); - if (!ret->proginfo_rec_start_ts) { - cmyth_dbg(CMYTH_DBG_DEBUG, "%s }!!!!\n", __FUNCTION__); - goto err; - } - ret->proginfo_rec_end_ts = cmyth_timestamp_create(); - if (!ret->proginfo_rec_end_ts) { - cmyth_dbg(CMYTH_DBG_DEBUG, "%s } !!!!!\n", __FUNCTION__); - goto err; - } - ret->proginfo_lastmodified = cmyth_timestamp_create(); - if (!ret->proginfo_lastmodified) { - cmyth_dbg(CMYTH_DBG_DEBUG, "%s } !!!!!!\n", __FUNCTION__); - goto err; - } - ret->proginfo_originalairdate = cmyth_timestamp_create(); - if (!ret->proginfo_originalairdate) { - cmyth_dbg(CMYTH_DBG_DEBUG, "%s } !!!!!!!\n", __FUNCTION__); - goto err; - } - ret->proginfo_title = NULL; - ret->proginfo_subtitle = NULL; - ret->proginfo_description = NULL; - ret->proginfo_season = 0; - ret->proginfo_episode = 0; - ret->proginfo_category = NULL; - ret->proginfo_chanId = 0; - ret->proginfo_chanstr = NULL; - ret->proginfo_chansign = NULL; - ret->proginfo_channame = NULL; - ret->proginfo_chanicon = NULL; - ret->proginfo_url = NULL; - ret->proginfo_pathname = NULL; - ret->proginfo_host = NULL; - ret->proginfo_port = -1; - ret->proginfo_Length = 0; - ret->proginfo_conflicting = 0; - ret->proginfo_unknown_0 = NULL; - ret->proginfo_recording = 0; - ret->proginfo_override = 0; - ret->proginfo_hostname = NULL; - ret->proginfo_source_id = 0; - ret->proginfo_card_id = 0; - ret->proginfo_input_id = 0; - ret->proginfo_rec_priority = 0; - ret->proginfo_rec_status = 0; - ret->proginfo_record_id = 0; - ret->proginfo_rec_type = 0; - ret->proginfo_rec_dups = 0; - ret->proginfo_unknown_1 = 0; - ret->proginfo_repeat = 0; - ret->proginfo_program_flags = 0; - ret->proginfo_rec_profile = NULL; - ret->proginfo_recgroup = NULL; - ret->proginfo_chancommfree = NULL; - ret->proginfo_chan_output_filters = NULL; - ret->proginfo_seriesid = NULL; - ret->proginfo_programid = NULL; - ret->proginfo_inetref = NULL; - ret->proginfo_stars = NULL; - ret->proginfo_version = 12; - ret->proginfo_hasairdate = 0; - ret->proginfo_playgroup = NULL; - ret->proginfo_storagegroup = NULL; - ret->proginfo_recpriority_2 = NULL; - ret->proginfo_parentid = 0; - ret->proginfo_audioproperties = 0; - ret->proginfo_videoproperties = 0; - ret->proginfo_subtitletype = 0; - ret->proginfo_year = 0; - cmyth_dbg(CMYTH_DBG_DEBUG, "%s }\n", __FUNCTION__); - return ret; - - err: - ref_release(ret); - cmyth_dbg(CMYTH_DBG_DEBUG, "%s } !++\n", __FUNCTION__); - return NULL; -} - -/* - * cmyth_proginfo_create(void) - * - * Scope: PRIVATE (static) - * - * Description - * - * Duplicate a program information structure into a new one. The sub-fields - * get held, not actually copied. - * - * Return Value: - * - * Success: A non-NULL cmyth_proginfo_t (this type is a pointer) - * - * Failure: A NULL cmyth_proginfo_t - */ -static cmyth_proginfo_t -cmyth_proginfo_dup(cmyth_proginfo_t p) -{ - cmyth_proginfo_t ret = cmyth_proginfo_create(); - - cmyth_dbg(CMYTH_DBG_DEBUG, "%s {\n", __FUNCTION__); - if (!ret) { - cmyth_dbg(CMYTH_DBG_DEBUG, "%s }!\n", __FUNCTION__); - return NULL; - } - ref_set_destroy(ret, (ref_destroy_t)cmyth_proginfo_destroy); - - ret->proginfo_start_ts = ref_hold(p->proginfo_start_ts); - ret->proginfo_end_ts = ref_hold(p->proginfo_end_ts); - ret->proginfo_rec_start_ts = ref_hold(p->proginfo_rec_start_ts); - ret->proginfo_rec_end_ts = ref_hold(p->proginfo_rec_end_ts); - ret->proginfo_lastmodified = ref_hold(p->proginfo_lastmodified); - ret->proginfo_originalairdate = ref_hold(p->proginfo_originalairdate); - ret->proginfo_title = ref_hold(p->proginfo_title); - ret->proginfo_subtitle = ref_hold(p->proginfo_subtitle); - ret->proginfo_description = ref_hold(p->proginfo_description); - ret->proginfo_season = p->proginfo_season; - ret->proginfo_episode = p->proginfo_episode; - ret->proginfo_category = ref_hold(p->proginfo_category); - ret->proginfo_chanId = p->proginfo_chanId; - ret->proginfo_chanstr = ref_hold(p->proginfo_chanstr); - ret->proginfo_chansign = ref_hold(p->proginfo_chansign); - ret->proginfo_channame = ref_hold(p->proginfo_channame); - ret->proginfo_chanicon = ref_hold(p->proginfo_chanicon); - ret->proginfo_url = ref_hold(p->proginfo_url); - ret->proginfo_pathname = ref_hold(p->proginfo_pathname); - ret->proginfo_host = ref_hold(p->proginfo_host); - ret->proginfo_port = p->proginfo_port; - ret->proginfo_Length = p->proginfo_Length; - ret->proginfo_conflicting = p->proginfo_conflicting; - ret->proginfo_unknown_0 = ref_hold(p->proginfo_unknown_0); - ret->proginfo_recording = p->proginfo_recording; - ret->proginfo_override = p->proginfo_override; - ret->proginfo_hostname = ref_hold(p->proginfo_hostname); - ret->proginfo_source_id = p->proginfo_source_id; - ret->proginfo_card_id = p->proginfo_card_id; - ret->proginfo_input_id = p->proginfo_input_id; - ret->proginfo_rec_priority = ref_hold(p->proginfo_rec_priority); - ret->proginfo_rec_status = p->proginfo_rec_status; - ret->proginfo_record_id = p->proginfo_record_id; - ret->proginfo_rec_type = p->proginfo_rec_type; - ret->proginfo_rec_dups = p->proginfo_rec_dups; - ret->proginfo_unknown_1 = p->proginfo_unknown_1; - ret->proginfo_repeat = p->proginfo_repeat; - ret->proginfo_program_flags = p->proginfo_program_flags; - ret->proginfo_rec_profile = ref_hold(p->proginfo_rec_profile); - ret->proginfo_recgroup = ref_hold(p->proginfo_recgroup); - ret->proginfo_chancommfree = ref_hold(p->proginfo_chancommfree); - ret->proginfo_chan_output_filters = ref_hold(p->proginfo_chan_output_filters); - ret->proginfo_seriesid = ref_hold(p->proginfo_seriesid); - ret->proginfo_programid = ref_hold(p->proginfo_programid); - ret->proginfo_inetref = ref_hold(p->proginfo_inetref); - ret->proginfo_stars = ref_hold(p->proginfo_stars); - ret->proginfo_version = p->proginfo_version; - ret->proginfo_hasairdate = p->proginfo_hasairdate; - ret->proginfo_playgroup = ref_hold(p->proginfo_playgroup); - ret->proginfo_storagegroup = ref_hold(p->proginfo_storagegroup); - ret->proginfo_recpriority_2 = ref_hold(p->proginfo_recpriority_2); - ret->proginfo_parentid = p->proginfo_parentid; - ret->proginfo_audioproperties = p->proginfo_audioproperties; - ret->proginfo_videoproperties = p->proginfo_videoproperties; - ret->proginfo_subtitletype = p->proginfo_subtitletype; - ret->proginfo_year = p->proginfo_year; - cmyth_dbg(CMYTH_DBG_DEBUG, "%s }\n", __FUNCTION__); - return ret; -} - -/* - * cmyth_proginfo_check_recording(cmyth_conn_t control, - * cmyth_proginfo_t prog) - * - * Scope: PUBLIC - * - * Description - * - * Make a request on the control connection 'control' to check the - * existence of the program 'prog' on the MythTV back end. - * - * Return Value: - * - * Success: 1 - if the recording exists, 0 - if it does not - * - * Failure: -(ERRNO) - */ -int -cmyth_proginfo_check_recording(cmyth_conn_t control, cmyth_proginfo_t prog) -{ - cmyth_dbg(CMYTH_DBG_DEBUG, "%s\n", __FUNCTION__); - return -ENOSYS; -} - -static int -delete_command(cmyth_conn_t control, cmyth_proginfo_t prog, char *cmd) -{ - long c = 0; - char *buf; - unsigned int len = ((2 * CMYTH_LONGLONG_LEN) + - (6 * CMYTH_TIMESTAMP_LEN) + - (16 * CMYTH_LONG_LEN)); - char start_ts[CMYTH_TIMESTAMP_LEN + 1]; - char end_ts[CMYTH_TIMESTAMP_LEN + 1]; - char rec_start_ts[CMYTH_TIMESTAMP_LEN + 1]; - char rec_end_ts[CMYTH_TIMESTAMP_LEN + 1]; - char originalairdate[CMYTH_TIMESTAMP_LEN + 1]; - char lastmodified[CMYTH_TIMESTAMP_LEN + 1]; - int err = 0; - int count = 0; - long r = 0; - int ret = 0; - - if (!prog) { - cmyth_dbg(CMYTH_DBG_ERROR, "%s: no program info\n", - __FUNCTION__); - return -EINVAL; - } -#define S(a) ((a) == NULL ? "" : (a)) - - len += strlen(S(prog->proginfo_title)); - len += strlen(S(prog->proginfo_subtitle)); - len += strlen(S(prog->proginfo_description)); - len += strlen(S(prog->proginfo_category)); - len += strlen(S(prog->proginfo_chanstr)); - len += strlen(S(prog->proginfo_chansign)); - len += strlen(S(prog->proginfo_channame)); - len += strlen(S(prog->proginfo_url)); - len += strlen(S(prog->proginfo_hostname)); - len += strlen(S(prog->proginfo_playgroup)); - len += strlen(S(prog->proginfo_seriesid)); - len += strlen(S(prog->proginfo_programid)); - len += strlen(S(prog->proginfo_inetref)); - len += strlen(S(prog->proginfo_recpriority_2)); - len += strlen(S(prog->proginfo_storagegroup)); - - buf = alloca(len + 1+2048); - if (!buf) { - return -ENOMEM; - } - - if(control->conn_version < 14) - { - cmyth_timestamp_to_string(start_ts, prog->proginfo_start_ts); - cmyth_timestamp_to_string(end_ts, prog->proginfo_end_ts); - cmyth_timestamp_to_string(rec_start_ts, - prog->proginfo_rec_start_ts); - cmyth_timestamp_to_string(rec_end_ts, prog->proginfo_rec_end_ts); - cmyth_timestamp_to_string(originalairdate, - prog->proginfo_originalairdate); - cmyth_timestamp_to_string(lastmodified, - prog->proginfo_lastmodified); - } - else - { - cmyth_datetime_to_string(start_ts, prog->proginfo_start_ts); - cmyth_datetime_to_string(end_ts, prog->proginfo_end_ts); - cmyth_datetime_to_string(rec_start_ts, prog->proginfo_rec_start_ts); - cmyth_datetime_to_string(rec_end_ts, prog->proginfo_rec_end_ts); - cmyth_datetime_to_string(originalairdate, - prog->proginfo_originalairdate); - cmyth_datetime_to_string(lastmodified, prog->proginfo_lastmodified); - } - - if(control->conn_version > 32) { - cmyth_timestamp_to_isostring(originalairdate, - prog->proginfo_originalairdate); - } - - if(control->conn_version < 12) - { - cmyth_dbg(CMYTH_DBG_ERROR, - "%s: delete not supported with protocol ver %d\n", - __FUNCTION__, control->conn_version); - return -EINVAL; - } - sprintf(buf, "%s 0[]:[]", cmd); - sprintf(buf + strlen(buf), "%s[]:[]", S(prog->proginfo_title)); - sprintf(buf + strlen(buf), "%s[]:[]", S(prog->proginfo_subtitle)); - sprintf(buf + strlen(buf), "%s[]:[]", S(prog->proginfo_description)); - if (control->conn_version >= 67) { - sprintf(buf + strlen(buf), "%u[]:[]", prog->proginfo_season); - sprintf(buf + strlen(buf), "%u[]:[]", prog->proginfo_episode); - } - sprintf(buf + strlen(buf), "%s[]:[]", S(prog->proginfo_category)); - sprintf(buf + strlen(buf), "%ld[]:[]", prog->proginfo_chanId); - sprintf(buf + strlen(buf), "%s[]:[]", S(prog->proginfo_chanstr)); - sprintf(buf + strlen(buf), "%s[]:[]", S(prog->proginfo_chansign)); - sprintf(buf + strlen(buf), "%s[]:[]", S(prog->proginfo_channame)); - sprintf(buf + strlen(buf), "%s[]:[]", S(prog->proginfo_url)); - if (control->conn_version >= 57) { - sprintf(buf + strlen(buf), "%"PRId64"[]:[]", prog->proginfo_Length); - } else { - sprintf(buf + strlen(buf), "%d[]:[]", (int32_t)(prog->proginfo_Length >> 32)); - sprintf(buf + strlen(buf), "%d[]:[]", (int32_t)(prog->proginfo_Length & 0xffffffff)); - } - sprintf(buf + strlen(buf), "%s[]:[]", start_ts); - sprintf(buf + strlen(buf), "%s[]:[]", end_ts); - if (control->conn_version < 57) { - sprintf(buf + strlen(buf), "%s[]:[]", S(prog->proginfo_unknown_0)); // "duplicate" - sprintf(buf + strlen(buf), "%ld[]:[]", 0L); // "shareable" - } - sprintf(buf + strlen(buf), "%ld[]:[]", 0L); // "findid" - sprintf(buf + strlen(buf), "%s[]:[]", S(prog->proginfo_hostname)); - sprintf(buf + strlen(buf), "%ld[]:[]", prog->proginfo_source_id); - sprintf(buf + strlen(buf), "%ld[]:[]", prog->proginfo_card_id); - sprintf(buf + strlen(buf), "%ld[]:[]", prog->proginfo_input_id); - sprintf(buf + strlen(buf), "%s[]:[]", S(prog->proginfo_rec_priority)); - sprintf(buf + strlen(buf), "%ld[]:[]", prog->proginfo_rec_status); - sprintf(buf + strlen(buf), "%ld[]:[]", prog->proginfo_record_id); - sprintf(buf + strlen(buf), "%ld[]:[]", prog->proginfo_rec_type); - sprintf(buf + strlen(buf), "%ld[]:[]", prog->proginfo_rec_dups); - sprintf(buf + strlen(buf), "%ld[]:[]", prog->proginfo_unknown_1); // "dupmethod" - sprintf(buf + strlen(buf), "%s[]:[]", rec_start_ts); - sprintf(buf + strlen(buf), "%s[]:[]", rec_end_ts); - if (control->conn_version < 57) { - sprintf(buf + strlen(buf), "%ld[]:[]", prog->proginfo_repeat); - } - sprintf(buf + strlen(buf), "%ld[]:[]", prog->proginfo_program_flags); - sprintf(buf + strlen(buf), "%s[]:[]", S(prog->proginfo_recgroup)); - if (control->conn_version < 57) { - sprintf(buf + strlen(buf), "%s[]:[]", S(prog->proginfo_chancommfree)); - } - sprintf(buf + strlen(buf), "%s[]:[]", S(prog->proginfo_chan_output_filters)); - sprintf(buf + strlen(buf), "%s[]:[]", S(prog->proginfo_seriesid)); - sprintf(buf + strlen(buf), "%s[]:[]", S(prog->proginfo_programid)); - if (control->conn_version >= 67) { - sprintf(buf + strlen(buf), "%s[]:[]", S(prog->proginfo_inetref)); - } - sprintf(buf + strlen(buf), "%s[]:[]", lastmodified); - sprintf(buf + strlen(buf), "%s[]:[]", S(prog->proginfo_stars)); - sprintf(buf + strlen(buf), "%s[]:[]", originalairdate); - if (control->conn_version >= 15 && control->conn_version < 57) { - sprintf(buf + strlen(buf), "%ld[]:[]", prog->proginfo_hasairdate); - } - if (control->conn_version >= 18) { - sprintf(buf + strlen(buf), "%s[]:[]", S(prog->proginfo_playgroup)); - } - if (control->conn_version >= 25) { - sprintf(buf + strlen(buf), "%s[]:[]", S(prog->proginfo_recpriority_2)); - } - if (control->conn_version >= 31) { - sprintf(buf + strlen(buf), "%ld[]:[]", prog->proginfo_parentid); - } - if (control->conn_version >= 32) { - sprintf(buf + strlen(buf), "%s[]:[]", S(prog->proginfo_storagegroup)); - } - if (control->conn_version >= 35) { - sprintf(buf + strlen(buf), "%ld[]:[]", prog->proginfo_audioproperties); - sprintf(buf + strlen(buf), "%ld[]:[]", prog->proginfo_videoproperties); - sprintf(buf + strlen(buf), "%ld[]:[]", prog->proginfo_subtitletype); - } - if (control->conn_version >= 43) { - sprintf(buf + strlen(buf), "%d[]:[]", prog->proginfo_year); - } -#undef S - - pthread_mutex_lock(&mutex); - - if ((err = cmyth_send_message(control, buf)) < 0) { - cmyth_dbg(CMYTH_DBG_ERROR, - "%s: cmyth_send_message() failed (%d)\n", - __FUNCTION__, err); - ret = err; - goto out; - } - - count = cmyth_rcv_length(control); - if ((r=cmyth_rcv_long(control, &err, &c, count)) < 0) { - cmyth_dbg(CMYTH_DBG_ERROR, - "%s: cmyth_rcv_length() failed (%d)\n", - __FUNCTION__, r); - ret = err; - goto out; - } - - out: - pthread_mutex_unlock(&mutex); - - return ret; -} - - -/* - * cmyth_proginfo_delete_recording(cmyth_conn_t control, - * cmyth_proginfo_t prog) - * - * Scope: PUBLIC - * - * Description - * - * Make a request on the control connection 'control' to delete the - * program 'prog' from the MythTV back end. - * - * Return Value: - * - * Success: 0 - * - * Failure: -(ERRNO) - */ -int -cmyth_proginfo_delete_recording(cmyth_conn_t control, cmyth_proginfo_t prog) -{ - return delete_command(control, prog, "DELETE_RECORDING"); -} - -/* - * cmyth_proginfo_forget_recording(cmyth_conn_t control, - * cmyth_proginfo_t prog) - * - * Scope: PUBLIC - * - * Description - * - * Make a request on the control connection 'control' to tell the - * MythTV back end to forget the program 'prog'. - * - * Return Value: - * - * Success: 0 - * - * Failure: -(ERRNO) - */ -int -cmyth_proginfo_forget_recording(cmyth_conn_t control, cmyth_proginfo_t prog) -{ - return delete_command(control, prog, "FORGET_RECORDING"); -} - -/* - * cmyth_proginfo_stop_recording(cmyth_conn_t control, - * cmyth_proginfo_t prog) - * - * Scope: PUBLIC - * - * Description - * - * Make a request on the control connection 'control' to ask the - * MythTV back end to stop recording the program described in 'prog'. - * - * Return Value: - * - * Success: 0 - * - * Failure: -(ERRNO) - */ -int -cmyth_proginfo_stop_recording(cmyth_conn_t control, cmyth_proginfo_t prog) -{ - return delete_command(control, prog, "STOP_RECORDING"); -} - -/* - * cmyth_proginfo_get_recorder_num(cmyth_conn_t control, - * cmyth_rec_num_t rnum, - * cmyth_proginfo_t prog) - * - * Scope: PUBLIC - * - * Description - * - * Make a request on the control connection 'control' to obtain the - * recorder number for the program 'prog' and fill out 'rnum' with the - * information. - * - * Return Value: - * - * Success: 0 - * - * Failure: -(ERRNO) - */ -int -cmyth_proginfo_get_recorder_num(cmyth_conn_t control, - cmyth_rec_num_t rnum, - cmyth_proginfo_t prog) -{ - return -ENOSYS; -} - -/* - * cmyth_proginfo_chan_id(cmyth_proginfo_t prog) - * - * Scope: PUBLIC - * - * Description - * - * Obtain the channel identifier from a program information structure. - * - * Return Value: - * - * Success: A positive integer channel identifier (these are formed from - * the recorder number and the channel number). - * - * Failure: -(ERRNO) - */ -long -cmyth_proginfo_chan_id(cmyth_proginfo_t prog) -{ - if (!prog) { - return -EINVAL; - } - return prog->proginfo_chanId; -} - -/* - * cmyth_proginfo_title(cmyth_proginfo_t prog) - * - * - * Scope: PUBLIC - * - * Description - * - * Retrieves the 'proginfo_title' field of a program info structure. - * - * The returned string is a pointer to the string within the program - * info structure, so it should not be modified by the caller. The - * return value is a 'char *' for this reason. - * - * Return Value: - * - * Success: A pointer to a 'char *' pointing to the field. - * - * Failure: NULL - */ -char * -cmyth_proginfo_title(cmyth_proginfo_t prog) -{ - if (!prog) { - cmyth_dbg(CMYTH_DBG_ERROR, "%s: NULL program information\n", - __FUNCTION__); - return NULL; - } - return ref_hold(prog->proginfo_title); -} - -/* - * cmyth_proginfo_subtitle(cmyth_proginfo_t prog) - * - * - * Scope: PUBLIC - * - * Description - * - * Retrieves the 'proginfo_subtitle' field of a program info structure. - * - * The returned string is a pointer to the string within the program - * info structure, so it should not be modified by the caller. The - * return value is a 'char *' for this reason. - * - * Return Value: - * - * Success: A pointer to a 'char *' pointing to the field. - * - * Failure: NULL - */ -char * -cmyth_proginfo_subtitle(cmyth_proginfo_t prog) -{ - if (!prog) { - cmyth_dbg(CMYTH_DBG_ERROR, "%s: NULL program information\n", - __FUNCTION__); - return NULL; - } - return ref_hold(prog->proginfo_subtitle); -} - -/* - * cmyth_proginfo_description(cmyth_proginfo_t prog) - * - * - * Scope: PUBLIC - * - * Description - * - * Retrieves the 'proginfo_description' field of a program info structure. - * - * The returned string is a pointer to the string within the program - * info structure, so it should not be modified by the caller. The - * return value is a 'char *' for this reason. - * - * Return Value: - * - * Success: A pointer to a 'char *' pointing to the field. - * - * Failure: NULL - */ -char * -cmyth_proginfo_description(cmyth_proginfo_t prog) -{ - if (!prog) { - cmyth_dbg(CMYTH_DBG_ERROR, "%s: NULL program information\n", - __FUNCTION__); - return NULL; - } - return ref_hold(prog->proginfo_description); -} - -unsigned short -cmyth_proginfo_season(cmyth_proginfo_t prog) -{ - if (!prog) { - return 0; - } - return prog->proginfo_season; -} - -unsigned short -cmyth_proginfo_episode(cmyth_proginfo_t prog) -{ - if (!prog) { - return 0; - } - return prog->proginfo_episode; -} - -/* - * cmyth_proginfo_category(cmyth_proginfo_t prog) - * - * - * Scope: PUBLIC - * - * Description - * - * Retrieves the 'proginfo_category' field of a program info structure. - * - * The returned string is a pointer to the string within the program - * info structure, so it should not be modified by the caller. The - * return value is a 'char *' for this reason. - * - * Return Value: - * - * Success: A pointer to a 'char *' pointing to the field. - * - * Failure: NULL - */ -char * -cmyth_proginfo_category(cmyth_proginfo_t prog) -{ - if (!prog) { - cmyth_dbg(CMYTH_DBG_ERROR, "%s: NULL program information\n", - __FUNCTION__); - return NULL; - } - return ref_hold(prog->proginfo_category); -} - -char * -cmyth_proginfo_seriesid(cmyth_proginfo_t prog) -{ - if (!prog) { - cmyth_dbg(CMYTH_DBG_ERROR, "%s: NULL series ID\n", - __FUNCTION__); - return NULL; - } - return ref_hold(prog->proginfo_seriesid); -} - -char * -cmyth_proginfo_programid(cmyth_proginfo_t prog) -{ - if (!prog) { - cmyth_dbg(CMYTH_DBG_ERROR, "%s: NULL program ID\n", - __FUNCTION__); - return NULL; - } - return ref_hold(prog->proginfo_programid); -} - -char * -cmyth_proginfo_inetref(cmyth_proginfo_t prog) -{ - if (!prog) { - cmyth_dbg(CMYTH_DBG_ERROR, "%s: NULL inetref\n", - __FUNCTION__); - return NULL; - } - return ref_hold(prog->proginfo_inetref); -} - -char * -cmyth_proginfo_stars(cmyth_proginfo_t prog) -{ - if (!prog) { - cmyth_dbg(CMYTH_DBG_ERROR, "%s: NULL stars\n", - __FUNCTION__); - return NULL; - } - return ref_hold(prog->proginfo_stars); -} - -char * -cmyth_proginfo_playgroup(cmyth_proginfo_t prog) -{ - if (!prog) { - cmyth_dbg(CMYTH_DBG_ERROR, "%s: NULL playgroup\n", - __FUNCTION__); - return NULL; - } - return ref_hold(prog->proginfo_playgroup); -} - -cmyth_timestamp_t -cmyth_proginfo_originalairdate(cmyth_proginfo_t prog) -{ - if (!prog) { - cmyth_dbg(CMYTH_DBG_ERROR, "%s: NULL original air date\n", - __FUNCTION__); - return NULL; - } - return ref_hold(prog->proginfo_originalairdate); -} - -/* - * cmyth_proginfo_chanstr(cmyth_proginfo_t prog) - * - * - * Scope: PUBLIC - * - * Description - * - * Retrieves the 'proginfo_chanstr' field of a program info structure. - * - * The returned string is a pointer to the string within the program - * info structure, so it should not be modified by the caller. The - * return value is a 'char *' for this reason. - * - * Return Value: - * - * Success: A pointer to a 'char *' pointing to the field. - * - * Failure: NULL - */ -char * -cmyth_proginfo_chanstr(cmyth_proginfo_t prog) -{ - if (!prog) { - cmyth_dbg(CMYTH_DBG_ERROR, "%s: NULL program information\n", - __FUNCTION__); - return NULL; - } - return ref_hold(prog->proginfo_chanstr); -} - -/* - * cmyth_proginfo_chansign(cmyth_proginfo_t prog) - * - * - * Scope: PUBLIC - * - * Description - * - * Retrieves the 'proginfo_chansign' field of a program info - * structure. - * - * The returned string is a pointer to the string within the program - * info structure, so it should not be modified by the caller. The - * return value is a 'char *' for this reason. - * - * Return Value: - * - * Success: A pointer to a 'char *' pointing to the field. - * - * Failure: NULL - */ -char * -cmyth_proginfo_chansign(cmyth_proginfo_t prog) -{ - if (!prog) { - cmyth_dbg(CMYTH_DBG_ERROR, "%s: NULL program information\n", - __FUNCTION__); - return NULL; - } - return ref_hold(prog->proginfo_chansign); -} - -/* - * cmyth_proginfo_channame(cmyth_proginfo_t prog) - * - * - * Scope: PUBLIC - * - * Description - * - * Retrieves the 'proginfo_channame' field of a program info - * structure. - * - * The returned string is a pointer to the string within the program - * info structure, so it should not be modified by the caller. The - * return value is a 'char *' for this reason. - * - * Return Value: - * - * Success: A pointer to a 'char *' pointing to the field. - * - * Failure: NULL - */ -char * -cmyth_proginfo_channame(cmyth_proginfo_t prog) -{ - if (!prog) { - cmyth_dbg(CMYTH_DBG_ERROR, "%s: NULL program information\n", - __FUNCTION__); - return NULL; - } - return ref_hold(prog->proginfo_channame); -} - -/* - * cmyth_proginfo_channame(cmyth_proginfo_t prog) - * - * - * Scope: PUBLIC - * - * Description - * - * Retrieves the 'proginfo_pathname' field of a program info - * structure. - * - * The returned string is a pointer to the string within the program - * info structure, so it should not be modified by the caller. The - * return value is a 'char *' for this reason. - * - * Return Value: - * - * Success: A pointer to a 'char *' pointing to the field. - * - * Failure: NULL - */ -char * -cmyth_proginfo_pathname(cmyth_proginfo_t prog) -{ - if (!prog) { - return NULL; - } - return ref_hold(prog->proginfo_pathname); -} - -/* - * cmyth_proginfo_length(cmyth_proginfo_t prog) - * - * - * Scope: PUBLIC - * - * Description - * - * Retrieves the 'proginfo_Length' field of a program info - * structure. - * - * Return Value: - * - * Success: long long file length - * - * Failure: NULL - */ -long long -cmyth_proginfo_length(cmyth_proginfo_t prog) -{ - if (!prog) { - return -1; - } - return prog->proginfo_Length; -} - -/* - * cmyth_proginfo_length_sec(cmyth_proginfo_t prog) - * - * - * Scope: PUBLIC - * - * Description - * - * Retrieves the program length in seconds. - * - * Return Value: - * - * Success: int file length - * - * Failure: NULL - */ -int -cmyth_proginfo_length_sec(cmyth_proginfo_t prog) -{ - int seconds; - - if (!prog) { - return -1; - } - - seconds = cmyth_timestamp_diff(prog->proginfo_start_ts, - prog->proginfo_end_ts); - - return seconds; -} -/* - * cmyth_proginfo_start(cmyth_proginfo_t prog) - * - * - * Scope: PUBLIC - * - * Description - * - * Retrieves the 'start' timestamp from a program info structure. - * This indicates a programmes start time. - * - * The returned timestamp is returned held. It should be released - * when no longer needed using ref_release(). - * - * Return Value: - * - * Success: A non-NULL cmyth_timestamp_t - * - * Failure: NULL - */ -cmyth_timestamp_t -cmyth_proginfo_start(cmyth_proginfo_t prog) -{ - if (!prog) { - return NULL; - } - return ref_hold(prog->proginfo_start_ts); -} - - -/* - * cmyth_proginfo_rec_end(cmyth_proginfo_t prog) - * - * - * Scope: PUBLIC - * - * Description - * - * Retrieves the 'end' timestamp from a program info structure. - * This tells when a recording started. - * - * The returned timestamp is returned held. It should be released - * when no longer needed using ref_release(). - * - * Return Value: - * - * Success: A non-NULL cmyth_timestamp_t - * - * Failure: NULL - */ -cmyth_timestamp_t -cmyth_proginfo_end(cmyth_proginfo_t prog) -{ - if (!prog) { - return NULL; - } - return ref_hold(prog->proginfo_end_ts); -} - -/* - * cmyth_proginfo_rec_start(cmyth_proginfo_t prog) - * - * - * Scope: PUBLIC - * - * Description - * - * Retrieves the 'rec_start' timestamp from a program info structure. - * This tells when a recording started. - * - * The returned timestamp is returned held. It should be released - * when no longer needed using ref_release(). - * - * Return Value: - * - * Success: A non-NULL cmyth_timestamp_t - * - * Failure: NULL - */ -cmyth_timestamp_t -cmyth_proginfo_rec_start(cmyth_proginfo_t prog) -{ - if (!prog) { - return NULL; - } - return ref_hold(prog->proginfo_rec_start_ts); -} - - -/* - * cmyth_proginfo_rec_end(cmyth_proginfo_t prog) - * - * - * Scope: PUBLIC - * - * Description - * - * Retrieves the 'rec_end' timestamp from a program info structure. - * This tells when a recording started. - * - * The returned timestamp is returned held. It should be released - * when no longer needed using ref_release(). - * - * Return Value: - * - * Success: A non-NULL cmyth_timestamp_t - * - * Failure: NULL - */ -cmyth_timestamp_t -cmyth_proginfo_rec_end(cmyth_proginfo_t prog) -{ - if (!prog) { - return NULL; - } - return ref_hold(prog->proginfo_rec_end_ts); -} - -/* - * cmyth_proginfo_rec_status(cmyth_proginfo_t prog) - * - * Scope: PUBLIC - * - * Description - * - * Retrieves the recording status from a program info structure. - * Recording status has the following possible values: - * - * RS_DELETED - * RS_STOPPED - * RS_RECORDED - * RS_RECORDING - * RS_WILL_RECORD - * RS_DONT_RECORD - * RS_PREVIOUS_RECORDING - * RS_CURRENT_RECORDING - * RS_EARLIER_RECORDING - * RS_TOO_MANY_RECORDINGS - * RS_CANCELLED - * RS_CONFLICT - * RS_LATER_SHOWING - * RS_REPEAT - * RS_LOW_DISKSPACE - * RS_TUNER_BUSY - * - * Return Value: - * - * Success: A recording status - * - * Failure: 0 (an invalid status) - */ -cmyth_proginfo_rec_status_t -cmyth_proginfo_rec_status(cmyth_proginfo_t prog) -{ - if (!prog) { - return 0; - } - return prog->proginfo_rec_status; -} - -/* - * cmyth_proginfo_flags(cmyth_proginfo_t prog) - * - * Scope: PUBLIC - * - * Description - * - * Retrieves the flags mask from a program info structure. - * - * Return Value: - * - * Success: The program flag mask. - * - * Failure: 0 (an invalid status) - */ -unsigned long -cmyth_proginfo_flags(cmyth_proginfo_t prog) -{ - if (!prog) { - return 0; - } - return prog->proginfo_program_flags; -} - -/* - * cmyth_proginfo_year(cmyth_proginfo_t prog) - * - * - * Scope: PUBLIC - * - * Description - * - * Retrieves the 'proginfo_year' field of a program info - * structure. - * - * Return Value: - * - * Success: the production year for the program - * - * Failure: 0 - */ -unsigned short -cmyth_proginfo_year(cmyth_proginfo_t prog) -{ - if (!prog) { - return 0; - } - return prog->proginfo_year; -} - -static int -fill_command(cmyth_conn_t control, cmyth_proginfo_t prog, char *cmd) -{ - char *buf; - unsigned int len = ((2 * CMYTH_LONGLONG_LEN) + - (6 * CMYTH_TIMESTAMP_LEN) + - (16 * CMYTH_LONG_LEN)); - char start_ts[CMYTH_TIMESTAMP_LEN + 1]; - char end_ts[CMYTH_TIMESTAMP_LEN + 1]; - char rec_start_ts[CMYTH_TIMESTAMP_LEN + 1]; - char rec_end_ts[CMYTH_TIMESTAMP_LEN + 1]; - char originalairdate[CMYTH_TIMESTAMP_LEN + 1]; - char lastmodified[CMYTH_TIMESTAMP_LEN + 1]; - int err = 0; - int ret = 0; - char *host = "libcmyth"; - - if (!prog) { - cmyth_dbg(CMYTH_DBG_ERROR, "%s: no program info\n", - __FUNCTION__); - return -EINVAL; - } -#define S(a) ((a) == NULL ? "" : (a)) - - len += strlen(S(prog->proginfo_title)); - len += strlen(S(prog->proginfo_subtitle)); - len += strlen(S(prog->proginfo_description)); - len += strlen(S(prog->proginfo_category)); - len += strlen(S(prog->proginfo_chanstr)); - len += strlen(S(prog->proginfo_chansign)); - len += strlen(S(prog->proginfo_channame)); - len += strlen(S(prog->proginfo_url)); - len += strlen(S(prog->proginfo_hostname)); - len += strlen(S(prog->proginfo_playgroup)); - len += strlen(S(prog->proginfo_seriesid)); - len += strlen(S(prog->proginfo_programid)); - len += strlen(S(prog->proginfo_inetref)); - len += strlen(S(prog->proginfo_recpriority_2)); - len += strlen(S(prog->proginfo_storagegroup)); - - buf = alloca(len + 1+2048); - if (!buf) { - return -ENOMEM; - } - - if(control->conn_version < 14) - { - cmyth_timestamp_to_string(start_ts, prog->proginfo_start_ts); - cmyth_timestamp_to_string(end_ts, prog->proginfo_end_ts); - cmyth_timestamp_to_string(rec_start_ts, - prog->proginfo_rec_start_ts); - cmyth_timestamp_to_string(rec_end_ts, prog->proginfo_rec_end_ts); - cmyth_timestamp_to_string(originalairdate, - prog->proginfo_originalairdate); - cmyth_timestamp_to_string(lastmodified, - prog->proginfo_lastmodified); - } - else - { - cmyth_datetime_to_string(start_ts, prog->proginfo_start_ts); - cmyth_datetime_to_string(end_ts, prog->proginfo_end_ts); - cmyth_datetime_to_string(rec_start_ts, prog->proginfo_rec_start_ts); - cmyth_datetime_to_string(rec_end_ts, prog->proginfo_rec_end_ts); - cmyth_datetime_to_string(originalairdate, - prog->proginfo_originalairdate); - cmyth_datetime_to_string(lastmodified, prog->proginfo_lastmodified); - } - - if(control->conn_version > 32) { - cmyth_timestamp_to_isostring(originalairdate, - prog->proginfo_originalairdate); - } - - if (control->conn_version < 12) - { - cmyth_dbg(CMYTH_DBG_ERROR, - "%s: fill not supported with protocol ver %d\n", - __FUNCTION__, control->conn_version); - return -EINVAL; - } - sprintf(buf, "%s %s[]:[]0[]:[]", cmd, host); - sprintf(buf + strlen(buf), "%s[]:[]", S(prog->proginfo_title)); - sprintf(buf + strlen(buf), "%s[]:[]", S(prog->proginfo_subtitle)); - sprintf(buf + strlen(buf), "%s[]:[]", S(prog->proginfo_description)); - if (control->conn_version >= 67) { - sprintf(buf + strlen(buf), "%u[]:[]", prog->proginfo_season); - sprintf(buf + strlen(buf), "%u[]:[]", prog->proginfo_episode); - } - sprintf(buf + strlen(buf), "%s[]:[]", S(prog->proginfo_category)); - sprintf(buf + strlen(buf), "%ld[]:[]", prog->proginfo_chanId); - sprintf(buf + strlen(buf), "%s[]:[]", S(prog->proginfo_chanstr)); - sprintf(buf + strlen(buf), "%s[]:[]", S(prog->proginfo_chansign)); - sprintf(buf + strlen(buf), "%s[]:[]", S(prog->proginfo_channame)); - sprintf(buf + strlen(buf), "%s[]:[]", S(prog->proginfo_url)); - if (control->conn_version >= 57) { - sprintf(buf + strlen(buf), "%"PRId64"[]:[]", prog->proginfo_Length); - } else { - sprintf(buf + strlen(buf), "%d[]:[]", (int32_t)(prog->proginfo_Length >> 32)); - sprintf(buf + strlen(buf), "%d[]:[]", (int32_t)(prog->proginfo_Length & 0xffffffff)); - } - sprintf(buf + strlen(buf), "%s[]:[]", start_ts); - sprintf(buf + strlen(buf), "%s[]:[]", end_ts); - if (control->conn_version < 57) { - sprintf(buf + strlen(buf), "%s[]:[]", S(prog->proginfo_unknown_0)); // "duplicate" - sprintf(buf + strlen(buf), "%ld[]:[]", 0L); // "shareable" - } - sprintf(buf + strlen(buf), "%ld[]:[]", 0L); // "findid" - sprintf(buf + strlen(buf), "%s[]:[]", S(prog->proginfo_hostname)); - sprintf(buf + strlen(buf), "%ld[]:[]", prog->proginfo_source_id); - sprintf(buf + strlen(buf), "%ld[]:[]", prog->proginfo_card_id); - sprintf(buf + strlen(buf), "%ld[]:[]", prog->proginfo_input_id); - sprintf(buf + strlen(buf), "%s[]:[]", S(prog->proginfo_rec_priority)); - sprintf(buf + strlen(buf), "%ld[]:[]", prog->proginfo_rec_status); - sprintf(buf + strlen(buf), "%ld[]:[]", prog->proginfo_record_id); - sprintf(buf + strlen(buf), "%ld[]:[]", prog->proginfo_rec_type); - sprintf(buf + strlen(buf), "%ld[]:[]", prog->proginfo_rec_dups); - sprintf(buf + strlen(buf), "%ld[]:[]", prog->proginfo_unknown_1); // "dupmethod" - sprintf(buf + strlen(buf), "%s[]:[]", rec_start_ts); - sprintf(buf + strlen(buf), "%s[]:[]", rec_end_ts); - if (control->conn_version < 57) { - sprintf(buf + strlen(buf), "%ld[]:[]", prog->proginfo_repeat); - } - sprintf(buf + strlen(buf), "%ld[]:[]", prog->proginfo_program_flags); - sprintf(buf + strlen(buf), "%s[]:[]", S(prog->proginfo_recgroup)); - if (control->conn_version < 57) { - sprintf(buf + strlen(buf), "%s[]:[]", S(prog->proginfo_chancommfree)); - } - sprintf(buf + strlen(buf), "%s[]:[]", S(prog->proginfo_chan_output_filters)); - sprintf(buf + strlen(buf), "%s[]:[]", S(prog->proginfo_seriesid)); - sprintf(buf + strlen(buf), "%s[]:[]", S(prog->proginfo_programid)); - if (control->conn_version >= 67) { - sprintf(buf + strlen(buf), "%s[]:[]", S(prog->proginfo_inetref)); - } - sprintf(buf + strlen(buf), "%s[]:[]", lastmodified); - sprintf(buf + strlen(buf), "%s[]:[]", S(prog->proginfo_stars)); - sprintf(buf + strlen(buf), "%s[]:[]", originalairdate); - if (control->conn_version >= 15 && control->conn_version < 57) { - sprintf(buf + strlen(buf), "%ld[]:[]", prog->proginfo_hasairdate); - } - if (control->conn_version >= 18) { - sprintf(buf + strlen(buf), "%s[]:[]", S(prog->proginfo_playgroup)); - } - if (control->conn_version >= 25) { - sprintf(buf + strlen(buf), "%s[]:[]", S(prog->proginfo_recpriority_2)); - } - if (control->conn_version >= 31) { - sprintf(buf + strlen(buf), "%ld[]:[]", prog->proginfo_parentid); - } - if (control->conn_version >= 32) { - sprintf(buf + strlen(buf), "%s[]:[]", S(prog->proginfo_storagegroup)); - } - if (control->conn_version >= 35) { - sprintf(buf + strlen(buf), "%ld[]:[]", prog->proginfo_audioproperties); - sprintf(buf + strlen(buf), "%ld[]:[]", prog->proginfo_videoproperties); - sprintf(buf + strlen(buf), "%ld[]:[]", prog->proginfo_subtitletype); - } - if (control->conn_version >= 43) { - sprintf(buf + strlen(buf), "%d[]:[]", prog->proginfo_year); - } -#undef S - - if ((err = cmyth_send_message(control, buf)) < 0) { - cmyth_dbg(CMYTH_DBG_ERROR, - "%s: cmyth_send_message() failed (%d)\n", - __FUNCTION__, err); - ret = err; - goto out; - } - - out: - return ret; -} - -/* - * cmyth_proginfo_fill(cmyth_conn_t control, cmyth_proginfo_t prog) - * - * Scope: PRIVATE (static) - * - * Description - * - * Fill out a (possibly incomplete) program info. Incomplete program - * info comes from program listings. Since this modifies the contents of - * the supplied program info, it must never be called with a program info - * that has more than one reference). - * - * Return Value: - * - * Success: 0 - * - * Failure: a negative error code. - */ -static int -cmyth_proginfo_fill(cmyth_conn_t control, cmyth_proginfo_t prog) -{ - int err = 0; - int count; - int ret; - long long length = 0; - - if (!control) { - cmyth_dbg(CMYTH_DBG_ERROR, "%s: no connection\n", - __FUNCTION__); - return -EINVAL; - } - if (!prog) { - cmyth_dbg(CMYTH_DBG_ERROR, "%s: no program info\n", - __FUNCTION__); - return -EINVAL; - } - - pthread_mutex_lock(&mutex); - - length = prog->proginfo_Length; - if ((ret=fill_command(control, prog, "FILL_PROGRAM_INFO") != 0)) - goto out; - - count = cmyth_rcv_length(control); - if (count < 0) { - cmyth_dbg(CMYTH_DBG_ERROR, - "%s: cmyth_rcv_length() failed (%d)\n", - __FUNCTION__, count); - ret = count; - goto out; - } - if (cmyth_rcv_proginfo(control, &err, prog, count) != count) { - cmyth_dbg(CMYTH_DBG_ERROR, - "%s: cmyth_rcv_proginfo() < count\n", __FUNCTION__); - ret = err; - goto out; - } - - /* - * Myth seems to cache the program length, rather than call stat() - * every time it needs to know. Using FILL_PROGRAM_INFO has worked - * to force mythbackend to call stat() and return the correct length. - * - * However, some users are reporting that FILL_PROGRAM_INFO is - * returning 0 for the program length. In that case, the original - * number is still probably wrong, but it's better than 0. - */ - if (prog->proginfo_Length == 0) { - prog->proginfo_Length = length; - ret = -1; - goto out; - } - - ret = 0; - - out: - pthread_mutex_unlock(&mutex); - - return ret; -} - -/* - * cmyth_proginfo_get_detail(cmyth_conn_t control, cmyth_proginfo_t prog) - * - * Scope: PUBLIC - * - * Description - * - * Completely fill out a program info based on a supplied (possibly - * incomplete) program info. The supplied program info will be duplicated and - * a pointer to the duplicate will be returned. - * - * NOTE: The original program info is released before the return. If the - * caller wishes to retain access to the original it must already be - * held before the call. This permits the called to replace a - * program info directly with the return from this function. - * - * Return Value: - * - * Success: A held, Non-NULL program_info - * - * Failure: NULL - */ -cmyth_proginfo_t -cmyth_proginfo_get_detail(cmyth_conn_t control, cmyth_proginfo_t p) -{ - cmyth_proginfo_t ret = cmyth_proginfo_dup(p); - - if (ret == NULL) { - cmyth_dbg(CMYTH_DBG_ERROR, - "%s: cmyth_proginfo_dup() failed\n", - __FUNCTION__); - return NULL; - } - if (cmyth_proginfo_fill(control, ret) < 0) { - ref_release(ret); - cmyth_dbg(CMYTH_DBG_ERROR, - "%s: cmyth_proginfo_fill() failed\n", - __FUNCTION__); - return NULL; - } - return ret; -} - -/* - * cmyth_proginfo_compare(cmyth_proginfo_t a, cmyth_proginfo_t b) - * - * Scope: PUBLIC - * - * Description - * - * Compare two program info's and indicate whether they are the same program. - * - * Return Value: - * - * Same: 0 - * - * Different: -1 - */ -int -cmyth_proginfo_compare(cmyth_proginfo_t a, cmyth_proginfo_t b) -{ - if (a == b) - return 0; - - if ((a == NULL) || (b == NULL)) - return -1; - -#define STRCMP(a, b) ( (a && b && (strcmp(a,b) == 0)) ? 0 : \ - ((a == NULL) && (b == NULL) ? 0 : -1) ) - - if (STRCMP(a->proginfo_title, b->proginfo_title) != 0) - return -1; - if (STRCMP(a->proginfo_subtitle, b->proginfo_subtitle) != 0) - return -1; - if (STRCMP(a->proginfo_description, b->proginfo_description) != 0) - return -1; - if (STRCMP(a->proginfo_chanstr, b->proginfo_chanstr) != 0) - return -1; - - if (a->proginfo_url && b->proginfo_url) { - char* aa = strrchr(a->proginfo_url, '/'); - char* bb = strrchr(b->proginfo_url, '/'); - if (strcmp(aa ? aa+1 : a->proginfo_url, bb ? bb+1 : b->proginfo_url) != 0) - return -1; - } else if(!a->proginfo_url != !b->proginfo_url) - return -1; - - if (cmyth_timestamp_compare(a->proginfo_start_ts, - b->proginfo_start_ts) != 0) - return -1; - if (cmyth_timestamp_compare(a->proginfo_end_ts, - b->proginfo_end_ts) != 0) - return -1; - - return 0; -} - -/* - * cmyth_proginfo_host(cmyth_proginfo_t prog) - * - * Scope: PUBLIC - * - * Description - * - * Get the host name of the recorder serving the program 'prog'. - * - * Return Value: - * - * Success: A held, non-NULL string pointer - * - * Failure: NULL - */ -char* -cmyth_proginfo_host(cmyth_proginfo_t prog) -{ - if (!prog) { - cmyth_dbg(CMYTH_DBG_ERROR, - "%s: no program info\n", __FUNCTION__); - return NULL; - } - - return ref_hold(prog->proginfo_host); -} - -int -cmyth_proginfo_port(cmyth_proginfo_t prog) -{ - if (!prog) { - cmyth_dbg(CMYTH_DBG_ERROR, - "%s: no program info\n", __FUNCTION__); - return -1; - } - - return prog->proginfo_port; -} - -long -cmyth_proginfo_card_id(cmyth_proginfo_t prog) -{ - if (!prog) { - cmyth_dbg(CMYTH_DBG_ERROR, - "%s: no program info\n", __FUNCTION__); - return -1; - } - - return prog->proginfo_card_id; -} - -char * -cmyth_proginfo_recgroup(cmyth_proginfo_t prog) -{ - if (!prog) { - cmyth_dbg(CMYTH_DBG_ERROR, "%s: NULL program information\n", - __FUNCTION__); - return NULL; - } - return ref_hold(prog->proginfo_recgroup); -} - -char * -cmyth_proginfo_chanicon(cmyth_proginfo_t prog) -{ - if (!prog) { - cmyth_dbg(CMYTH_DBG_ERROR, "%s: NULL program information\n", - __FUNCTION__); - return NULL; - } - return ref_hold(prog->proginfo_chanicon); -} - -int -cmyth_get_delete_list(cmyth_conn_t conn, char * msg, cmyth_proglist_t prog) -{ - int err=0; - int count; - int prog_count=0; - - if (!conn) { - cmyth_dbg(CMYTH_DBG_ERROR, "%s: no connection\n", __FUNCTION__); - return -1; - } - pthread_mutex_lock(&mutex); - if ((err = cmyth_send_message(conn, msg)) < 0) { - fprintf (stderr, "ERROR %d \n",err); - cmyth_dbg(CMYTH_DBG_ERROR, - "%s: cmyth_send_message() failed (%d)\n",__FUNCTION__,err); - return err; - } - count = cmyth_rcv_length(conn); - cmyth_rcv_proglist(conn, &err, prog, count); - prog_count=cmyth_proglist_get_count(prog); - pthread_mutex_unlock(&mutex); - return prog_count; -} - -cmyth_proginfo_t -cmyth_proginfo_get_from_basename(cmyth_conn_t control, const char* basename) -{ - int err = 0; - int count, i; - char msg[4096]; - char *base; - cmyth_proginfo_t prog = NULL; - cmyth_proglist_t list = NULL; - - if (!control) { - cmyth_dbg(CMYTH_DBG_ERROR, "%s: no connection\n", - __FUNCTION__); - return NULL; - } - - /* - * mythbackend doesn't support spaces in basenames - * when doing QUERY_RECORDING. If there are spaces, fallback - * to enumerating all recordings - */ - if(control->conn_version >= 32 && strchr(basename, ' ') == NULL) { - pthread_mutex_lock(&mutex); - - snprintf(msg, sizeof(msg), "QUERY_RECORDING BASENAME %s", - basename); - - if ((err=cmyth_send_message(control, msg)) < 0) { - cmyth_dbg(CMYTH_DBG_ERROR, - "%s: cmyth_send_message() failed (%d)\n", - __FUNCTION__, err); - goto out; - } - - count = cmyth_rcv_length(control); - if (count < 0) { - cmyth_dbg(CMYTH_DBG_ERROR, - "%s: cmyth_rcv_length() failed (%d)\n", - __FUNCTION__, count); - goto out; - } - - i = cmyth_rcv_string(control, &err, msg, sizeof(msg), count); - if (err) { - cmyth_dbg(CMYTH_DBG_ERROR, "%s: cmyth_rcv_string() failed\n", - __FUNCTION__); - goto out; - } - count -= i; - - if (strcmp(msg, "OK") != 0) { - cmyth_dbg(CMYTH_DBG_ERROR, "%s: didn't recieve OK as response\n", - __FUNCTION__); - goto out; - } - - prog = cmyth_proginfo_create(); - if (cmyth_rcv_proginfo(control, &err, prog, count) != count) { - cmyth_dbg(CMYTH_DBG_ERROR, - "%s: cmyth_rcv_proginfo() < count\n", __FUNCTION__); - goto out; - } - - pthread_mutex_unlock(&mutex); - return prog; -out: - pthread_mutex_unlock(&mutex); - if(prog) - ref_release(prog); - return NULL; - - } else { - - list = cmyth_proglist_get_all_recorded(control); - if (!list) { - cmyth_dbg(CMYTH_DBG_ERROR, "%s: no program list\n", - __FUNCTION__); - } - - count = cmyth_proglist_get_count(list); - for (i = 0;i < count; i++) { - prog = cmyth_proglist_get_item(list, i); - if (!prog) { - cmyth_dbg(CMYTH_DBG_DEBUG, "%s: no program info\n", - __FUNCTION__); - continue; - } - base = strrchr(prog->proginfo_pathname, '/'); - if (!base || strcmp(base+1, basename) !=0) { - ref_release(prog); - prog = NULL; - continue; - } - break; - } - ref_release(list); - return prog; - } - -} diff --git a/lib/cmyth/libcmyth/proglist.c b/lib/cmyth/libcmyth/proglist.c deleted file mode 100644 index b0a4820702..0000000000 --- a/lib/cmyth/libcmyth/proglist.c +++ /dev/null @@ -1,637 +0,0 @@ -/* - * Copyright (C) 2004-2010, Eric Lund - * http://www.mvpmc.org/ - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -/* - * proglist.c - functions to manage MythTV timestamps. Primarily, - * these allocate timestamps and convert between string - * and cmyth_proglist_t and between long long and - * cmyth_proglist_t. - */ -#include <stdlib.h> -#include <stdio.h> -#include <errno.h> -#include <string.h> -#include <cmyth_local.h> - -/* - * cmyth_proglist_destroy(void) - * - * Scope: PRIVATE (static) - * - * Description - * - * Destroy and free a timestamp structure. This should only be called - * by ref_release(). All others should use - * ref_release() to release references to time stamps. - * - * Return Value: - * - * None. - */ -static void -cmyth_proglist_destroy(cmyth_proglist_t pl) -{ - int i; - - cmyth_dbg(CMYTH_DBG_DEBUG, "%s\n", __FUNCTION__); - if (!pl) { - return; - } - for (i = 0; i < pl->proglist_count; ++i) { - if (pl->proglist_list[i]) { - ref_release(pl->proglist_list[i]); - } - pl->proglist_list[i] = NULL; - } - if (pl->proglist_list) { - free(pl->proglist_list); - } -} - -/* - * cmyth_proglist_create(void) - * - * Scope: PUBLIC - * - * Description - * - * Create a timestamp structure and return a pointer to the structure. - * - * Return Value: - * - * Success: A non-NULL cmyth_proglist_t (this type is a pointer) - * - * Failure: A NULL cmyth_proglist_t - */ -cmyth_proglist_t -cmyth_proglist_create(void) -{ - cmyth_proglist_t ret; - - cmyth_dbg(CMYTH_DBG_DEBUG, "%s\n", __FUNCTION__); - ret = ref_alloc(sizeof(*ret)); - if (!ret) { - return(NULL); - } - ref_set_destroy(ret, (ref_destroy_t)cmyth_proglist_destroy); - - ret->proglist_list = NULL; - ret->proglist_count = 0; - return ret; -} - -/* - * cmyth_proglist_get_item(cmyth_proglist_t pl, int index) - * - * Scope: PUBLIC - * - * Description: - * - * Retrieve the program information structure found at index 'index' - * in the list in 'pl'. Return the program information structure - * held. Before forgetting the reference to this program info structure - * the caller must call ref_release(). - * - * Return Value: - * - * Success: A non-null cmyth_proginfo_t (this is a pointer type) - * - * Failure: A NULL cmyth_proginfo_t - */ -cmyth_proginfo_t -cmyth_proglist_get_item(cmyth_proglist_t pl, int index) -{ - if (!pl) { - cmyth_dbg(CMYTH_DBG_ERROR, "%s: NULL program list\n", - __FUNCTION__); - return NULL; - } - if (!pl->proglist_list) { - cmyth_dbg(CMYTH_DBG_ERROR, "%s: NULL list\n", - __FUNCTION__); - return NULL; - } - if ((index < 0) || (index >= pl->proglist_count)) { - cmyth_dbg(CMYTH_DBG_ERROR, "%s: index %d out of range\n", - __FUNCTION__, index); - return NULL; - } - ref_hold(pl->proglist_list[index]); - return pl->proglist_list[index]; -} - -int -cmyth_proglist_delete_item(cmyth_proglist_t pl, cmyth_proginfo_t prog) -{ - int i; - cmyth_proginfo_t old; - int ret = -EINVAL; - - if (!pl) { - cmyth_dbg(CMYTH_DBG_ERROR, "%s: NULL program list\n", - __FUNCTION__); - return -EINVAL; - } - if (!prog) { - cmyth_dbg(CMYTH_DBG_ERROR, "%s: NULL program item\n", - __FUNCTION__); - return -EINVAL; - } - - pthread_mutex_lock(&mutex); - - for (i=0; i<pl->proglist_count; i++) { - if (cmyth_proginfo_compare(prog, pl->proglist_list[i]) == 0) { - old = pl->proglist_list[i]; - memmove(pl->proglist_list+i, - pl->proglist_list+i+1, - (pl->proglist_count-i-1)*sizeof(cmyth_proginfo_t)); - pl->proglist_count--; - ref_release(old); - ret = 0; - goto out; - } - } - - out: - pthread_mutex_unlock(&mutex); - - return ret; -} - -/* - * cmyth_proglist_get_count(cmyth_proglist_t pl) - * - * Scope: PUBLIC - * - * Description: - * - * Retrieve the number of elements in the program information - * structure in 'pl'. - * - * Return Value: - * - * Success: A number >= 0 indicating the number of items in 'pl' - * - * Failure: -errno - */ -int -cmyth_proglist_get_count(cmyth_proglist_t pl) -{ - if (!pl) { - cmyth_dbg(CMYTH_DBG_ERROR, "%s: NULL program list\n", - __FUNCTION__); - return -EINVAL; - } - return pl->proglist_count; -} - -/* - * cmyth_proglist_get_list(cmyth_conn_t conn, - * cmyth_proglist_t proglist, - * char *msg, char *func) - * - * Scope: PRIVATE (static) - * - * Description - * - * Obtain a program list from the query specified in 'msg' from the - * function 'func'. Make the query on 'conn' and put the results in - * 'proglist'. - * - * Return Value: - * - * Success: 0 - * - * Failure: -(ERRNO) - */ -static int -cmyth_proglist_get_list(cmyth_conn_t conn, - cmyth_proglist_t proglist, - char *msg, const char *func) -{ - int err = 0; - int count; - int ret; - - if (!conn) { - cmyth_dbg(CMYTH_DBG_ERROR, "%s: no connection\n", func); - return -EINVAL; - } - if (!proglist) { - cmyth_dbg(CMYTH_DBG_ERROR, "%s: no program list\n", func); - return -EINVAL; - } - - pthread_mutex_lock(&mutex); - - if ((err = cmyth_send_message(conn, msg)) < 0) { - cmyth_dbg(CMYTH_DBG_ERROR, - "%s: cmyth_send_message() failed (%d)\n", - func, err); - ret = err; - goto out; - } - count = cmyth_rcv_length(conn); - if (count < 0) { - cmyth_dbg(CMYTH_DBG_ERROR, - "%s: cmyth_rcv_length() failed (%d)\n", - func, count); - ret = count; - goto out; - } - if (strcmp(msg, "QUERY_GETALLPENDING") == 0) { - long c; - int r; - if ((r=cmyth_rcv_long(conn, &err, &c, count)) < 0) { - cmyth_dbg(CMYTH_DBG_ERROR, - "%s: cmyth_rcv_length() failed (%d)\n", - __FUNCTION__, r); - ret = err; - goto out; - } - count -= r; - } - if (cmyth_rcv_proglist(conn, &err, proglist, count) != count) { - cmyth_dbg(CMYTH_DBG_ERROR, - "%s: cmyth_rcv_proglist() < count\n", - func); - } - if (err) { - cmyth_dbg(CMYTH_DBG_ERROR, - "%s: cmyth_rcv_proglist() failed (%d)\n", - func, err); - ret = -1 * err; - goto out; - } - - ret = 0; - - out: - pthread_mutex_unlock(&mutex); - - return ret; -} - -/* - * cmyth_proglist_get_all_recorded(cmyth_conn_t control, - * cmyth_proglist_t *proglist) - * - * Scope: PUBLIC - * - * Description - * - * Make a request on the control connection 'control' to obtain a list - * of completed or in-progress recordings. Build a list of program - * information structures and put a malloc'ed pointer to the list (an - * array of pointers) in proglist. - * - * Return Value: - * - * Success: A held, noon-NULL cmyth_proglist_t - * - * Failure: NULL - */ -cmyth_proglist_t -cmyth_proglist_get_all_recorded(cmyth_conn_t control) -{ - char query[32]; - cmyth_proglist_t proglist = cmyth_proglist_create(); - - if (proglist == NULL) { - cmyth_dbg(CMYTH_DBG_ERROR, - "%s: cmyth_proglist_create() failed\n", - __FUNCTION__); - return NULL; - } - - if (control->conn_version < 65) { - strcpy(query, "QUERY_RECORDINGS Play"); - } - else { - strcpy(query, "QUERY_RECORDINGS Ascending"); - } - if (cmyth_proglist_get_list(control, proglist, - query, - __FUNCTION__) < 0) { - cmyth_dbg(CMYTH_DBG_ERROR, - "%s: cmyth_proglist_get_list() failed\n", - __FUNCTION__); - ref_release(proglist); - return NULL; - } - return proglist; -} - -/* - * cmyth_proglist_get_all_pending(cmyth_conn_t control, - * cmyth_proglist_t *proglist) - * - * Scope: PUBLIC - * - * Description - * - * Make a request on the control connection 'control' to obtain a list - * of pending recordings. Build a list of program information - * structures and put a malloc'ed pointer to the list (an array of - * pointers) in proglist. - * - * Return Value: - * - * Success: A held, noon-NULL cmyth_proglist_t - * - * Failure: NULL - */ -cmyth_proglist_t -cmyth_proglist_get_all_pending(cmyth_conn_t control) -{ - cmyth_proglist_t proglist = cmyth_proglist_create(); - - if (proglist == NULL) { - cmyth_dbg(CMYTH_DBG_ERROR, - "%s: cmyth_proglist_create() failed\n", - __FUNCTION__); - return NULL; - } - - if (cmyth_proglist_get_list(control, proglist, - "QUERY_GETALLPENDING", - __FUNCTION__) < 0) { - cmyth_dbg(CMYTH_DBG_ERROR, - "%s: cmyth_proglist_get_list() failed\n", - __FUNCTION__); - ref_release(proglist); - return NULL; - } - return proglist; -} - -/* - * cmyth_proglist_get_all_scheduled(cmyth_conn_t control, - * cmyth_proglist_t *proglist) - * - * Scope: PUBLIC - * - * Description - * - * Make a request on the control connection 'control' to obtain a list - * of scheduled recordings. Build a list of program information - * structures and put a malloc'ed pointer to the list (an array of - * pointers) in proglist. - * - * Return Value: - * - * Success: A held, noon-NULL cmyth_proglist_t - * - * Failure: NULL - */ -cmyth_proglist_t -cmyth_proglist_get_all_scheduled(cmyth_conn_t control) -{ - cmyth_proglist_t proglist = cmyth_proglist_create(); - - if (proglist == NULL) { - cmyth_dbg(CMYTH_DBG_ERROR, - "%s: cmyth_proglist_create() failed\n", - __FUNCTION__); - return NULL; - } - - if (cmyth_proglist_get_list(control, proglist, - "QUERY_GETALLSCHEDULED", - __FUNCTION__) < 0) { - cmyth_dbg(CMYTH_DBG_ERROR, - "%s: cmyth_proglist_get_list() failed\n", - __FUNCTION__); - ref_release(proglist); - return NULL; - } - return proglist; -} - -/* - * cmyth_proglist_get_conflicting(cmyth_conn_t control, - * cmyth_proglist_t *proglist) - * - * Scope: PUBLIC - * - * Description - * - * Make a request on the control connection 'control' to obtain a list - * of conflicting recordings. Build a list of program information - * structures and put a malloc'ed pointer to the list (an array of - * pointers) in proglist. - * - * Return Value: - * - * Success: A held, noon-NULL cmyth_proglist_t - * - * Failure: NULL - */ -cmyth_proglist_t -cmyth_proglist_get_conflicting(cmyth_conn_t control) -{ - cmyth_proglist_t proglist = cmyth_proglist_create(); - - if (proglist == NULL) { - cmyth_dbg(CMYTH_DBG_ERROR, - "%s: cmyth_proglist_create() failed\n", - __FUNCTION__); - return NULL; - } - - if (cmyth_proglist_get_list(control, proglist, - "QUERY_GETCONFLICTING", - __FUNCTION__) < 0) { - cmyth_dbg(CMYTH_DBG_ERROR, - "%s: cmyth_proglist_get_list() failed\n", - __FUNCTION__); - ref_release(proglist); - return NULL; - } - return proglist; -} - -/* - * sort_timestamp(const void *a, const void *b) - * - * Scope: PRIVATE - * - * Description - * - * Return an integer value to specify the relative position of the timestamp - * This is a helper function for the sort function called by qsort. It will - * sort any of the timetstamps for the qsort functions - * - * Return Value: - * - * Same Date/Time: 0 - * Date a > b: 1 - * Date a < b: -1 - * - */ -static int sort_timestamp(cmyth_timestamp_t X, cmyth_timestamp_t Y) -{ - - if (X->timestamp_year > Y->timestamp_year) - return 1; - else if (X->timestamp_year < Y->timestamp_year) - return -1; - else /* X->timestamp_year == Y->timestamp_year */ - { - if (X->timestamp_month > Y->timestamp_month) - return 1; - else if (X->timestamp_month < Y->timestamp_month) - return -1; - else /* X->timestamp_month == Y->timestamp_month */ - { - if (X->timestamp_day > Y->timestamp_day) - return 1; - else if (X->timestamp_day < Y->timestamp_day) - return -1; - else /* X->timestamp_day == Y->timestamp_day */ - { - if (X->timestamp_hour > Y->timestamp_hour) - return 1; - else if (X->timestamp_hour < Y->timestamp_hour) - return -1; - else /* X->timestamp_hour == Y->timestamp_hour */ - { - if (X->timestamp_minute > Y->timestamp_minute) - return 1; - else if (X->timestamp_minute < Y->timestamp_minute) - return -1; - else /* X->timestamp_minute == Y->timestamp_minute */ - { - if (X->timestamp_second > Y->timestamp_second) - return 1; - else if (X->timestamp_second < Y->timestamp_second) - return -1; - else /* X->timestamp_second == Y->timestamp_second */ - return 0; - } - } - } - } - } -} - -/* - * recorded_compare(const void *a, const void *b) - * - * Scope: PRIVATE - * - * Description - * - * Return an integer value to a qsort function to specify the relative - * position of the recorded date - * - * Return Value: - * - * Same Day: 0 - * Date a > b: 1 - * Date a < b: -1 - * - */ -static int -recorded_compare(const void *a, const void *b) -{ - const cmyth_proginfo_t x = *(cmyth_proginfo_t *)a; - const cmyth_proginfo_t y = *(cmyth_proginfo_t *)b; - cmyth_timestamp_t X = x->proginfo_rec_start_ts; - cmyth_timestamp_t Y = y->proginfo_rec_start_ts; - - return sort_timestamp(X, Y); -} - -/* - * airdate_compare(const void *a, const void *b) - * - * Scope: PRIVATE - * - * Description - * - * Return an integer value to a qsort function to specify the relative - * position of the original airdate - * - * Return Value: - * - * Same Day: 0 - * Date a > b: 1 - * Date a < b: -1 - * - */ -static int -airdate_compare(const void *a, const void *b) -{ - const cmyth_proginfo_t x = *(cmyth_proginfo_t *)a; - const cmyth_proginfo_t y = *(cmyth_proginfo_t *)b; - const cmyth_timestamp_t X = x->proginfo_originalairdate; - const cmyth_timestamp_t Y = y->proginfo_originalairdate; - - return sort_timestamp(X, Y); -} - -/* - * cmyth_proglist_sort(cmyth_proglist_t pl, int count, int sort) - * - * Scope: PUBLIC - * - * Description - * - * Sort the epispde list by mythtv_sort setting. Check to ensure that the - * program list is not null and pass the proglist_list to the qsort function - * - * Return Value: - * - * Success = 0 - * Failure = -1 - */ -int -cmyth_proglist_sort(cmyth_proglist_t pl, int count, cmyth_proglist_sort_t sort) -{ - if (!pl) { - cmyth_dbg(CMYTH_DBG_ERROR, "%s: NULL program list\n", - __FUNCTION__); - return -1; - } - if (!pl->proglist_list) { - cmyth_dbg(CMYTH_DBG_ERROR, "%s: NULL list\n", - __FUNCTION__); - return -1; - } - - cmyth_dbg(CMYTH_DBG_ERROR, - "cmyth_proglist_sort\n"); - - switch (sort) { - case MYTHTV_SORT_DATE_RECORDED: /* Default Date Recorded */ - qsort((cmyth_proginfo_t)pl->proglist_list, count, sizeof(pl->proglist_list) , recorded_compare); - break; - case MYTHTV_SORT_ORIGINAL_AIRDATE: /*Default Date Recorded */ - qsort((cmyth_proginfo_t)pl->proglist_list, count, sizeof(pl->proglist_list) , airdate_compare); - break; - default: - printf("Unsupported MythTV sort type\n"); - } - - cmyth_dbg(CMYTH_DBG_ERROR, - "end cmyth_proglist_sort\n"); - return 0; -} diff --git a/lib/cmyth/libcmyth/rec_num.c b/lib/cmyth/libcmyth/rec_num.c deleted file mode 100644 index a5ae2b3e40..0000000000 --- a/lib/cmyth/libcmyth/rec_num.c +++ /dev/null @@ -1,227 +0,0 @@ -/* - * Copyright (C) 2004-2010, Eric Lund - * http://www.mvpmc.org/ - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -/* - * rec_num.c - functions to manage recorder number structures. Mostly - * just allocating, freeing, and filling them out. - */ -#include <stdlib.h> -#include <stdio.h> -#include <string.h> -#include <cmyth_local.h> - -/* - * cmyth_rec_num_destroy(cmyth_rec_num_t rn) - * - * Scope: PRIVATE (static) - * - * Description - * - * Destroy and release all storage associated with the recorder number - * structure 'rn'. This function should only ever be called by - * cmyth_rec_num_release(). All others should call - * cmyth_rec_num_release() to free rec_num structures. - * - * Return Value: - * - * None. - */ -static void -cmyth_rec_num_destroy(cmyth_rec_num_t rn) -{ - cmyth_dbg(CMYTH_DBG_DEBUG, "%s\n", __FUNCTION__); - if (!rn) { - return; - } - if (rn->recnum_host) { - ref_release(rn->recnum_host); - } -} - -/* - * cmyth_rec_num_create(void) - * - * Scope: PUBLIC - * - * Description - * - * Create a recorder number structure. - * - * Return Value: - * - * Success: A non-NULL cmyth_rec_num_t (this type is a pointer) - * - * Failure: A NULL cmyth_rec_num_t - */ -cmyth_rec_num_t -cmyth_rec_num_create(void) -{ - cmyth_rec_num_t ret = ref_alloc(sizeof(*ret)); - - cmyth_dbg(CMYTH_DBG_DEBUG, "%s\n", __FUNCTION__); - if (!ret) { - return NULL; - } - ref_set_destroy(ret, (ref_destroy_t)cmyth_rec_num_destroy); - - ret->recnum_host = NULL; - ret->recnum_port = 0; - ret->recnum_id = 0; - return ret; -} - -/* - * cmyth_rec_num_hold(cmyth_rec_num_t p) - * - * Scope: PUBLIC - * - * Description - * - * Take a new reference to a rec_num structure. Rec_Num structures - * are reference counted to facilitate caching of pointers to them. - * This allows a holder of a pointer to release their hold and trust - * that once the last reference is released the rec_num will be - * destroyed. This function is how one creates a new holder of a - * rec_num. This function always returns the pointer passed to it. - * While it cannot fail, if it is passed a NULL pointer, it will do - * nothing. - * - * Return Value: - * - * Success: The value of 'p' - * - * Failure: There is no real failure case, but a NULL 'p' will result in a - * NULL return. - */ -cmyth_rec_num_t -cmyth_rec_num_hold(cmyth_rec_num_t p) -{ - cmyth_dbg(CMYTH_DBG_DEBUG, "%s\n", __FUNCTION__); - return ref_hold(p); -} - -/* - * cmyth_rec_num_release(cmyth_rec_num_t p) - * - * Scope: PUBLIC - * - * Description - * - * Release a reference to a rec_num structure. Rec_Num structures - * are reference counted to facilitate caching of pointers to them. - * This allows a holder of a pointer to release their hold and trust - * that once the last reference is released the rec_num will be - * destroyed. This function is how one drops a reference to a - * rec_num. - * - * Return Value: - * - * None. - */ -void -cmyth_rec_num_release(cmyth_rec_num_t p) -{ - cmyth_dbg(CMYTH_DBG_DEBUG, "%s\n", __FUNCTION__); - ref_release(p); -} - -/* - * cmyth_rec_num_get(char *host, - * unsigned short port, - * unsigned id) - * - * Scope: PUBLIC - * - * Description - * - * Create a recorder number structure 'rn' using the values 'host', - * 'port', and 'id'. - * - * Return Value: - * - * Success: A new cmyth_rec_num (this is a ppointer type) - * - * Failure: NULL - */ -cmyth_rec_num_t -cmyth_rec_num_get(char *host, - unsigned short port, - unsigned id) -{ - cmyth_rec_num_t ret; - - if ((ret = cmyth_rec_num_create()) == NULL) { - return NULL; - } - ret->recnum_host = ref_strdup(host); - if (!ret->recnum_host) { - ref_release(ret); - return NULL; - } - ret->recnum_port = port; - ret->recnum_id = id; - return ret; -} - -/* - * cmyth_rec_num_string(cmyth_rec_num_t rn) - * - * Scope: PUBLIC - * - * Description - * - * Compose a MythTV protocol string from a rec_num structure and - * return a pointer to a malloc'ed buffer containing the string. - * - * Return Value: - * - * Success: A non-NULL malloc'ed character buffer pointer. - * - * Failure: NULL - */ -char * -cmyth_rec_num_string(cmyth_rec_num_t rn) -{ - unsigned len = sizeof("[]:[][]:[]"); - char id[16]; - char port[8]; - char *ret; - - if (!rn) { - return NULL; - } - if (!rn->recnum_host) { - return NULL; - } - sprintf(id, "%d", rn->recnum_id); - len += strlen(id); - sprintf(port, "%d", rn->recnum_port); - len += strlen(port); - len += strlen(rn->recnum_host); - ret = malloc((len + 1) * sizeof(char)); - if (!ret) { - return NULL; - } - strcpy(ret, id); - strcat(ret, "[]:[]"); - strcat(ret, rn->recnum_host); - strcat(ret, "[]:[]"); - strcat(ret, port); - return ret; -} diff --git a/lib/cmyth/libcmyth/recorder.c b/lib/cmyth/libcmyth/recorder.c deleted file mode 100644 index 207a241ba0..0000000000 --- a/lib/cmyth/libcmyth/recorder.c +++ /dev/null @@ -1,1583 +0,0 @@ -/* - * Copyright (C) 2004-2009, Eric Lund, Jon Gettler - * http://www.mvpmc.org/ - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -/* - * recorder.c - functions to handle operations on MythTV recorders. A - * MythTV Recorder is the part of the MythTV backend that - * handles capturing video from a video capture card and - * storing it in files for transfer to a backend. A - * recorder is the key to live-tv streams as well, and - * owns the tuner and channel information (i.e. program - * guide data). - */ -#include <stdlib.h> -#include <stdio.h> -#include <errno.h> -#include <string.h> -#include <time.h> -#include <cmyth_local.h> - -/* - * cmyth_recorder_destroy(cmyth_recorder_t rec) - * - * Scope: PRIVATE (static) - * - * Description - * - * Clean up and free a recorder structure. This should only be done - * by the ref_release() code. Everyone else should call - * ref_release() because recorder structures are reference - * counted. - * - * Return Value: - * - * None. - */ -static void -cmyth_recorder_destroy(cmyth_recorder_t rec) -{ - cmyth_dbg(CMYTH_DBG_DEBUG, "%s\n", __FUNCTION__); - if (!rec) { - return; - } - - if (rec->rec_server) { - ref_release(rec->rec_server); - } - if (rec->rec_ring) { - ref_release(rec->rec_ring); - } - if (rec->rec_conn) { - ref_release(rec->rec_conn); - } - if (rec->rec_livetv_chain) { - ref_release(rec->rec_livetv_chain); - } - if (rec->rec_livetv_file) { - ref_release(rec->rec_livetv_file); - } - -} - -/* - * cmyth_recorder_create(void) - * - * Scope: PUBLIC - * - * Description - * - * Allocate and initialize a cmyth recorder structure. - * - * Return Value: - * - * Success: A non-NULL cmyth_recorder_t (this type is a pointer) - * - * Failure: A NULL cmyth_recorder_t - */ -cmyth_recorder_t -cmyth_recorder_create(void) -{ - cmyth_recorder_t ret = ref_alloc(sizeof(*ret)); - - cmyth_dbg(CMYTH_DBG_DEBUG, "%s\n", __FUNCTION__); - if (!ret) { - return NULL; - } - ref_set_destroy(ret, (ref_destroy_t)cmyth_recorder_destroy); - - ret->rec_server = NULL; - ret->rec_port = 0; - ret->rec_have_stream = 0; - ret->rec_id = 0; - ret->rec_ring = NULL; - ret->rec_conn = NULL; - ret->rec_framerate = 0.0; - ret->rec_livetv_chain = NULL; - ret->rec_livetv_file = NULL; - return ret; -} - -/* - * cmyth_recorder_dup(cmyth_recorder_t old) - * - * Scope: PUBLIC - * - * Description - * - * Copy a recorder structure and return the copy - * - * Return Value: - * - * Success: A non-NULL cmyth_recorder_t (this type is a pointer) - * - * Failure: A NULL cmyth_recorder_t - */ -cmyth_recorder_t -cmyth_recorder_dup(cmyth_recorder_t old) -{ - cmyth_recorder_t ret = cmyth_recorder_create(); - if (ret == NULL) { - return NULL; - } - - ret->rec_have_stream = old->rec_have_stream; - ret->rec_id = old->rec_id; - ret->rec_server = ref_hold(old->rec_server); - ret->rec_port = old->rec_port; - ret->rec_ring = ref_hold(old->rec_ring); - ret->rec_conn = ref_hold(old->rec_conn); - ret->rec_framerate = old->rec_framerate; - ret->rec_livetv_chain = ref_hold(old->rec_livetv_chain); - ret->rec_livetv_file = ref_hold(old->rec_livetv_file); - - return ret; -} - -/* - * cmyth_recorder_is_recording(cmyth_recorder_t rec) - * - * Scope: PUBLIC - * - * Description - * - * Determine whether recorder 'rec' is currently recording. Return - * the true / false answer. - * - * Return Value: - * - * Success: 0 if the recorder is idle, 1 if the recorder is recording. - * - * Failure: -(ERRNO) - */ -int -cmyth_recorder_is_recording(cmyth_recorder_t rec) -{ - int err, count; - int r; - long c, ret; - char msg[256]; - - if (!rec) { - cmyth_dbg(CMYTH_DBG_ERROR, "%s: no recorder connection\n", - __FUNCTION__); - return -EINVAL; - } - - pthread_mutex_lock(&mutex); - - snprintf(msg, sizeof(msg), "QUERY_RECORDER %u[]:[]IS_RECORDING", - rec->rec_id); - - if ((err=cmyth_send_message(rec->rec_conn, msg)) < 0) { - cmyth_dbg(CMYTH_DBG_ERROR, - "%s: cmyth_send_message() failed (%d)\n", - __FUNCTION__, err); - ret = err; - goto out; - } - - count = cmyth_rcv_length(rec->rec_conn); - if ((r=cmyth_rcv_long(rec->rec_conn, &err, &c, count)) < 0) { - cmyth_dbg(CMYTH_DBG_ERROR, - "%s: cmyth_rcv_length() failed (%d)\n", - __FUNCTION__, r); - ret = err; - goto out; - } - - ret = c; - - out: - pthread_mutex_unlock(&mutex); - - return ret; -} - -/* - * cmyth_recorder_get_framerate( - * cmyth_recorder_t rec, - * double *rate) - * - * Scope: PUBLIC - * - * Description - * - * Obtain the current frame rate for recorder 'rec'. Put the result - * in 'rate'. - * - * Return Value: - * - * Success: 0 - * - * Failure: -(ERRNO) - */ -int -cmyth_recorder_get_framerate(cmyth_recorder_t rec, - double *rate) -{ - int err, count; - int r; - long ret; - char msg[256]; - char reply[256]; - - if (!rec || !rate) { - cmyth_dbg(CMYTH_DBG_ERROR, "%s: no recorder connection\n", - __FUNCTION__); - return -EINVAL; - } - - pthread_mutex_lock(&mutex); - - snprintf(msg, sizeof(msg), "QUERY_RECORDER %u[]:[]GET_FRAMERATE", - rec->rec_id); - - if ((err=cmyth_send_message(rec->rec_conn, msg)) < 0) { - cmyth_dbg(CMYTH_DBG_ERROR, - "%s: cmyth_send_message() failed (%d)\n", - __FUNCTION__, err); - ret = err; - goto out; - } - - count = cmyth_rcv_length(rec->rec_conn); - if ((r=cmyth_rcv_string(rec->rec_conn, &err, - reply, sizeof(reply), count)) < 0) { - cmyth_dbg(CMYTH_DBG_ERROR, - "%s: cmyth_rcv_string() failed (%d)\n", - __FUNCTION__, r); - ret = err; - goto out; - } - - *rate = atof(reply); - ret = 0; - - out: - pthread_mutex_unlock(&mutex); - - return ret; -} - -/* - * cmyth_recorder_get_frames_written(cmyth_recorder_t rec, - * double *rate) - * - * Scope: PUBLIC - * - * Description - * - * Obtain the current number of frames written by recorder 'rec'. - * - * Return Value: - * - * Success: long long number of frames (>= 0) - * - * Failure: long long -(ERRNO) - */ -long long -cmyth_recorder_get_frames_written(cmyth_recorder_t rec) -{ - return (long long) -ENOSYS; -} - -/* - * cmyth_recorder_get_free_space(cmyth_recorder_t rec) - * - * Scope: PUBLIC - * - * Description - * - * Obtain the current number of bytes of free space on the recorder - * 'rec'. - * - * Return Value: - * - * Success: long long freespace (>= 0) - * - * Failure: long long -(ERRNO) - */ -long long -cmyth_recorder_get_free_space(cmyth_recorder_t rec) -{ - return (long long) -ENOSYS; -} - -/* - * cmyth_recorder_get_key_frame(cmyth_recorder_t rec, long keynum) - * - * Scope: PUBLIC - * - * Description - * - * Obtain the position in a recording of the key frame number 'keynum' - * on the recorder 'rec'. - * - * Return Value: - * - * Success: long long seek offset >= 0 - * - * Failure: long long -(ERRNO) - */ -long long -cmyth_recorder_get_keyframe_pos(cmyth_recorder_t rec, unsigned long keynum) -{ - return (long long)-ENOSYS; -} - -/* - * cmyth_recorder_get_position_map(cmyth_recorder_t rec, - * cmyth_posmap_t map, - * long start, - * long end) - * - * Scope: PUBLIC - * - * Description - * - * Request a list of {keynum, position} pairs starting at keynum - * 'start' and ending with keynum 'end' from the current recording on - * recorder 'rec'. - * - * Return Value: - * - * Success: 0 - * - * Failure: -(ERRNO) - */ -cmyth_posmap_t -cmyth_recorder_get_position_map(cmyth_recorder_t rec, - unsigned long start, - unsigned long end) -{ - return NULL; -} - -/* - * cmyth_recorder_get_recording(cmyth_recorder_t rec) - * - * Scope: PUBLIC - * - * Description - * - * Obtain from the recorder specified by 'rec' program information for - * the current recording (i.e. the recording being made right now). - * - * Return Value: - * - * Success: 0 - * - * Failure: -(ERRNO) - */ -cmyth_proginfo_t -cmyth_recorder_get_recording(cmyth_recorder_t rec) -{ - return NULL; -} - -/* - * cmyth_recorder_stop_playing(cmyth_recorder_t rec) - * - * Scope: PUBLIC - * - * Description - * - * Request that the recorder 'rec' stop playing the current recording - * or live-tv stream. - * - * Return Value: - * - * Success: 0 - * - * Failure: -(ERRNO) - */ -int -cmyth_recorder_stop_playing(cmyth_recorder_t rec) -{ - return -ENOSYS; -} - -/* - * cmyth_recorder_frontend_ready(cmyth_recorder_t rec) - * - * Scope: PUBLIC - * - * Description - * - * Let the recorder 'rec' know that the frontend is ready for data. - * - * Return Value: - * - * Success: 0 - * - * Failure: -(ERRNO) - */ -int -cmyth_recorder_frontend_ready(cmyth_recorder_t rec) -{ - return -ENOSYS; -} - -/* - * cmyth_recorder_cancel_next_recording(cmyth_recorder_t rec) - * - * Scope: PUBLIC - * - * Description - * - * Request that the recorder 'rec' cancel its next scheduled - * recording. - * - * Return Value: - * - * Success: 0 - * - * Failure: -(ERRNO) - */ -int -cmyth_recorder_cancel_next_recording(cmyth_recorder_t rec) -{ - return -ENOSYS; -} - -/* - * cmyth_recorder_pause(cmyth_recorder_t rec) - * - * Scope: PUBLIC - * - * Description - * - * Request that the recorder 'rec' pause in the middle of the current - * recording. This will prevent the recorder from transmitting any - * data until the recorder is unpaused. At this moment, it is not - * clear to me what will cause an unpause. - * - * Return Value: - * - * Success: 0 - * - * Failure: -(ERRNO) - */ -int -cmyth_recorder_pause(cmyth_recorder_t rec) -{ - int ret = -EINVAL; - char Buffer[255]; - - if (rec == NULL) { - cmyth_dbg(CMYTH_DBG_ERROR, - "%s: Invalid args rec = %p\n", - __FUNCTION__, rec); - return -EINVAL; - } - - pthread_mutex_lock(&mutex); - - sprintf(Buffer, "QUERY_RECORDER %ld[]:[]PAUSE", (long) rec->rec_id); - if ((ret=cmyth_send_message(rec->rec_conn, Buffer)) < 0) { - cmyth_dbg(CMYTH_DBG_ERROR, - "%s: cmyth_send_message('%s') failed\n", - __FUNCTION__, Buffer); - goto err; - } - - if ((ret=cmyth_rcv_okay(rec->rec_conn, "ok")) < 0) { - cmyth_dbg(CMYTH_DBG_ERROR, "%s: cmyth_rcv_okay() failed\n", - __FUNCTION__); - goto err; - } - - ret = 0; - - err: - pthread_mutex_unlock(&mutex); - - return ret; -} - -/* - * cmyth_recorder_finish_recording(cmyth_recorder_t rec) - * - * Scope: PUBLIC - * - * Description - * - * Request that the recorder 'rec' stop recording the current - * recording / live-tv. - * - * Return Value: - * - * Success: 0 - * - * Failure: -(ERRNO) - */ -int -cmyth_recorder_finish_recording(cmyth_recorder_t rec) -{ - return -ENOSYS; -} - -/* - * cmyth_recorder_toggle_channel_favorite(cmyth_recorder_t rec) - * - * Scope: PUBLIC - * - * Description - * - * Request that the recorder 'rec' switch among the favorite channels. - * Note that the recorder must not be actively recording when this - * request is made or bad things may happen to the server (i.e. it may - * segfault). - * - * Return Value: - * - * Success: 0 - * - * Failure: -(ERRNO) - */ -int -cmyth_recorder_toggle_channel_favorite(cmyth_recorder_t rec) -{ - return -ENOSYS; -} - -/* - * cmyth_recorder_change_channel(cmyth_recorder_t rec, - * cmyth_channeldir_t direction) - * - * Scope: PUBLIC - * - * Description - * - * Request that the recorder 'rec' change channels in one of the - * followin - * - * CHANNEL_DIRECTION_UP - Go up one channel in the listing - * - * CHANNEL_DIRECTION_DOWN - Go down one channel in the listing - * - * CHANNEL_DIRECTION_FAVORITE - Go to the next favorite channel - * - * CHANNEL_DIRECTION_SAME - Stay on the same (current) channel - * - * Note that the recorder must not be actively recording when this - * request is made or bad things may happen to the server (i.e. it may - * segfault). - * - * Return Value: - * - * Success: 0 - * - * Failure: -(ERRNO) - */ -int -cmyth_recorder_change_channel(cmyth_recorder_t rec, - cmyth_channeldir_t direction) -{ - int err; - int ret = -1; - char msg[256]; - - if (!rec) { - cmyth_dbg(CMYTH_DBG_ERROR, "%s: no recorder connection\n", - __FUNCTION__); - return -ENOSYS; - } - - pthread_mutex_lock(&mutex); - - snprintf(msg, sizeof(msg), - "QUERY_RECORDER %d[]:[]CHANGE_CHANNEL[]:[]%d", - rec->rec_id, direction); - - if ((err=cmyth_send_message(rec->rec_conn, msg)) < 0) { - cmyth_dbg(CMYTH_DBG_ERROR, - "%s: cmyth_send_message() failed (%d)\n", - __FUNCTION__, err); - goto fail; - } - - if ((err=cmyth_rcv_okay(rec->rec_conn, "ok")) < 0) { - cmyth_dbg(CMYTH_DBG_ERROR, - "%s: cmyth_rcv_okay() failed (%d)\n", - __FUNCTION__, err); - goto fail; - } - - if(rec->rec_ring) - rec->rec_ring->file_pos = 0; - else - rec->rec_livetv_file->file_pos = 0; - - ret = 0; - - fail: - pthread_mutex_unlock(&mutex); - - return ret; -} - -/* - * cmyth_recorder_set_channel(cmyth_recorder_t rec, - * char *channame) - * - * Scope: PUBLIC - * - * Description - * - * Request that the recorder 'rec' change channels to the channel - * named 'channame'. - * - * Note that the recorder must not be actively recording when this - * request is made or bad things may happen to the server (i.e. it may - * segfault). - * - * Return Value: - * - * Success: 0 - * - * Failure: -(ERRNO) - */ -int -cmyth_recorder_set_channel(cmyth_recorder_t rec, char *channame) -{ - int err; - int ret = -1; - char msg[256]; - - if (!rec) { - cmyth_dbg(CMYTH_DBG_ERROR, "%s: no recorder connection\n", - __FUNCTION__); - return -ENOSYS; - } - - pthread_mutex_lock(&mutex); - - snprintf(msg, sizeof(msg), - "QUERY_RECORDER %d[]:[]SET_CHANNEL[]:[]%s", - rec->rec_id, channame); - - if ((err=cmyth_send_message(rec->rec_conn, msg)) < 0) { - cmyth_dbg(CMYTH_DBG_ERROR, - "%s: cmyth_send_message() failed (%d)\n", - __FUNCTION__, err); - goto fail; - } - - if ((err=cmyth_rcv_okay(rec->rec_conn, "ok")) < 0) { - cmyth_dbg(CMYTH_DBG_ERROR, - "%s: cmyth_rcv_okay() failed (%d)\n", - __FUNCTION__, err); - goto fail; - } - - if(rec->rec_ring) - rec->rec_ring->file_pos = 0; - else - rec->rec_livetv_file->file_pos = 0; - - ret = 0; - - fail: - pthread_mutex_unlock(&mutex); - - return ret; -} - -/* - * cmyth_recorder_change_color(cmyth_recorder_t rec, - * cmyth_adjdir_t direction) - * - * Scope: PUBLIC - * - * Description - * - * Request that the recorder 'rec' change the color saturation of the - * currently recording channel (this setting is preserved in the - * recorder settings for that channel). The change is controlled by - * the value of 'direction' which may be: - * - * ADJ_DIRECTION_UP - Change the value upward one step - * - * ADJ_DIRECTION_DOWN - Change the value downward one step - * - * This may be done while the recorder is recording. - * - * Return Value: - * - * Success: 0 - * - * Failure: -(ERRNO) - */ -int -cmyth_recorder_change_color(cmyth_recorder_t rec, cmyth_adjdir_t direction) -{ - return -ENOSYS; -} - -/* - * cmyth_recorder_change_brightness(cmyth_recorder_t rec, - * cmyth_adjdir_t direction) - * - * Scope: PUBLIC - * - * Description - * - * Request that the recorder 'rec' change the brightness (black level) - * of the currently recording channel (this setting is preserved in - * the recorder settings for that channel). The change is controlled - * by the value of 'direction' which may be: - * - * ADJ_DIRECTION_UP - Change the value upward one step - * - * ADJ_DIRECTION_DOWN - Change the value downward one step - * - * This may be done while the recorder is recording. - * - * Return Value: - * - * Success: 0 - * - * Failure: -(ERRNO) - */ -int -cmyth_recorder_change_brightness(cmyth_recorder_t rec, - cmyth_adjdir_t direction) -{ - return -ENOSYS; -} - -/* - * cmyth_recorder_change_contrast(cmyth_recorder_t rec, - * cmyth_adjdir_t direction) - * - * Scope: PUBLIC - * - * Description - * - * Request that the recorder 'rec' change the contrast of the - * currently recording channel (this setting is preserved in the - * recorder settings for that channel). The change is controlled by - * the value of 'direction' which may be: - * - * ADJ_DIRECTION_UP - Change the value upward one step - * - * ADJ_DIRECTION_DOWN - Change the value downward one step - * - * This may be done while the recorder is recording. - * - * Return Value: - * - * Success: 0 - * - * Failure: -(ERRNO) - */ -int -cmyth_recorder_change_contrast(cmyth_recorder_t rec, cmyth_adjdir_t direction) -{ - return -ENOSYS; -} - -/* - * cmyth_recorder_change_hue(cmyth_recorder_t rec, - * cmyth_adjdir_t direction) - * - * Scope: PUBLIC - * - * Description - * - * Request that the recorder 'rec' change the hue (color balance) of - * the currently recording channel (this setting is preserved in the - * recorder settings for that channel). The change is controlled by - * the value of 'direction' which may be: - * - * ADJ_DIRECTION_UP - Change the value upward one step - * - * ADJ_DIRECTION_DOWN - Change the value downward one step - * - * This may be done while the recorder is recording. - * - * Return Value: - * - * Success: 0 - * - * Failure: -(ERRNO) - */ -int -cmyth_recorder_change_hue(cmyth_recorder_t rec, cmyth_adjdir_t direction) -{ - return -ENOSYS; -} - -/* - * cmyth_recorder_check_channel(cmyth_recorder_t rec, char *channame) - * - * Scope: PUBLIC - * - * Description - * - * Request that the recorder 'rec' check the validity of the channel - * specified by 'channame'. - * - * Return Value: - * - * Check the validity of a channel name. - * Success: 1 - valid channel, 0 - invalid channel - * - * Failure: -(ERRNO) - */ -int -cmyth_recorder_check_channel(cmyth_recorder_t rec, - char *channame) -{ - int err; - int ret = -1; - char msg[256]; - - if (!rec || !channame) { - cmyth_dbg(CMYTH_DBG_ERROR, "%s: invalid args " - "rec = %p, channame = %p\n", - __FUNCTION__, rec, channame); - return -EINVAL; - } - - pthread_mutex_lock(&mutex); - - snprintf(msg, sizeof(msg), - "QUERY_RECORDER %d[]:[]CHECK_CHANNEL[]:[]%s", - rec->rec_id, channame); - - if ((err=cmyth_send_message(rec->rec_conn, msg)) < 0) { - cmyth_dbg(CMYTH_DBG_ERROR, - "%s: cmyth_send_message() failed (%d)\n", - __FUNCTION__, err); - goto fail; - } - - if ((err=cmyth_rcv_okay(rec->rec_conn, "1")) < 0) { - cmyth_dbg(CMYTH_DBG_ERROR, - "%s: cmyth_rcv_okay() failed (%d)\n", - __FUNCTION__, err); - goto fail; - } - - ret = 0; - - fail: - pthread_mutex_unlock(&mutex); - - return ret; -} - -/* - * cmyth_recorder_check_channel_prefix(cmyth_recorder_t rec, - * char *channame) - * - * Scope: PUBLIC - * - * Description - * - * Request that the recorder 'rec' check the validity of the channel - * prefix specified by 'channame'. - * - * Return Value: - * - * Success: 1 - valid channel, 0 - invalid channel - * - * Failure: -(ERRNO) - */ -int -cmyth_recorder_check_channel_prefix(cmyth_recorder_t rec, char *channame) -{ - return -ENOSYS; -} - -/* - * cmyth_recorder_get_program_info(cmyth_recorder_t rec) - * - * Scope: PRIVATE (static) - * - * Description: - * - * Request program information from the recorder 'rec' for the current - * program in the program guide (i.e. current channel and time slot). - * - * The program information will be used to fill out 'proginfo'. - * - * This does not affect the current recording. - * - * Return Value: - * - * Success: 1 - valid channel, 0 - invalid channel - * - * Failure: -(ERRNO) - */ -static cmyth_proginfo_t -cmyth_recorder_get_program_info(cmyth_recorder_t rec) -{ - int err, count, ct; - char msg[256]; - cmyth_proginfo_t proginfo = NULL; - - if (!rec) { - cmyth_dbg(CMYTH_DBG_ERROR, "%s: no recorder connection\n", - __FUNCTION__); - return NULL; - } - - proginfo = cmyth_proginfo_create(); - if (proginfo == NULL) { - cmyth_dbg(CMYTH_DBG_ERROR, "%s: proginfo_create failed\n", - __FUNCTION__); - goto out; - } - pthread_mutex_lock(&mutex); - - if(rec->rec_conn->conn_version >= 26) - snprintf(msg, sizeof(msg), "QUERY_RECORDER %d[]:[]GET_CURRENT_RECORDING", - rec->rec_id); - else - snprintf(msg, sizeof(msg), "QUERY_RECORDER %d[]:[]GET_PROGRAM_INFO", - rec->rec_id); - - if ((err=cmyth_send_message(rec->rec_conn, msg)) < 0) { - cmyth_dbg(CMYTH_DBG_ERROR, - "%s: cmyth_send_message() failed (%d)\n", - __FUNCTION__, err); - ref_release(proginfo); - proginfo = NULL; - goto out; - } - - count = cmyth_rcv_length(rec->rec_conn); - - if(rec->rec_conn->conn_version >= 26) - ct = cmyth_rcv_proginfo(rec->rec_conn, &err, proginfo, count); - else - ct = cmyth_rcv_chaninfo(rec->rec_conn, &err, proginfo, count); - - if (ct != count) { - cmyth_dbg(CMYTH_DBG_ERROR, - "%s: cmyth_rcv_proginfo() < count\n", __FUNCTION__); - ref_release(proginfo); - proginfo = NULL; - goto out; - } - - out: - pthread_mutex_unlock(&mutex); - - return proginfo; -} - -/* - * cmyth_recorder_get_cur_proginfo(cmyth_recorder_t rec) - * - * Scope: PUBLIC - * - * Description: - * - * Request program information from the recorder 'rec' for the first - * program in the program guide (i.e. current channel and time slot). - * - * This does not affect the current recording. - * - * Return Value: - * - * Success: A non-NULL, held cmyth_proginfo_t - * Failure: A NULL pointer - * - */ -cmyth_proginfo_t -cmyth_recorder_get_cur_proginfo(cmyth_recorder_t rec) -{ - cmyth_proginfo_t ret; - - if (!rec) { - cmyth_dbg(CMYTH_DBG_ERROR, "%s: invalid args rec = %p\n", - __FUNCTION__, rec); - return NULL; - } - if ((ret = cmyth_recorder_get_program_info(rec)) == NULL) { - cmyth_dbg(CMYTH_DBG_ERROR, - "%s: cmyth_recorder_get_program_info() failed\n", - __FUNCTION__); - return NULL; - } - return ret; -} - -/* - * cmyth_recorder_get_next_program_info(cmyth_recorder_t rec, - * cmyth_proginfo_t proginfo, - * cmyth_browsedir_t direction) - * - * Scope: PRIVATE (static) - * - * Description: - * - * Request program information from the recorder 'rec' for the next - * program in the program guide from the current program (i.e. current - * channel and time slot) in the direction specified by 'direction' - * which may have any of the following values: - * - * BROWSE_DIRECTION_SAME - Stay in the same place - * BROWSE_DIRECTION_UP - Move up one slot (down one channel) - * BROWSE_DIRECTION_DOWN - Move down one slot (up one channel) - * BROWSE_DIRECTION_LEFT - Move left one slot (down one time slot) - * BROWSE_DIRECTION_RIGHT - Move right one slot (up one time slot) - * BROWSE_DIRECTION_FAVORITE - Move to the next favorite slot - * - * The program information will be used to fill out 'proginfo'. - * - * This does not affect the current recording. - * - * Return Value: - * - * Success: 1 - valid channel, 0 - invalid channel - * - * Failure: -(ERRNO) - */ -int -cmyth_recorder_get_next_program_info(cmyth_recorder_t rec, - cmyth_proginfo_t cur_prog, - cmyth_proginfo_t next_prog, - cmyth_browsedir_t direction) -{ - int err, count; - int ret = -ENOSYS; - char msg[256]; - char title[256], subtitle[256], desc[256], category[256]; - char callsign[256], iconpath[256]; - char channelname[256], chanid[256], seriesid[256], programid[256]; - char date[256]; - struct tm *tm; - time_t t; - cmyth_conn_t control; - - if (!rec) { - cmyth_dbg(CMYTH_DBG_ERROR, "%s: no recorder connection\n", - __FUNCTION__); - return -ENOSYS; - } - - control = rec->rec_conn; - - pthread_mutex_lock(&mutex); - - t = time(NULL); - tm = localtime(&t); - snprintf(date, sizeof(date), "%.4d%.2d%.2d%.2d%.2d%.2d", - tm->tm_year + 1900, tm->tm_mon + 1, - tm->tm_mday, tm->tm_hour, tm->tm_min, tm->tm_sec); - - snprintf(msg, sizeof(msg), "QUERY_RECORDER %d[]:[]GET_NEXT_PROGRAM_INFO[]:[]%s[]:[]%ld[]:[]%i[]:[]%s", - rec->rec_id, cur_prog->proginfo_channame, - cur_prog->proginfo_chanId, direction, date); - - if ((err=cmyth_send_message(control, msg)) < 0) { - cmyth_dbg(CMYTH_DBG_ERROR, - "%s: cmyth_send_message() failed (%d)\n", - __FUNCTION__, err); - ret = err; - goto out; - } - - count = cmyth_rcv_length(control); - - count -= cmyth_rcv_string(control, &err, - title, sizeof(title), count); - count -= cmyth_rcv_string(control, &err, - subtitle, sizeof(subtitle), count); - count -= cmyth_rcv_string(control, &err, - desc, sizeof(desc), count); - count -= cmyth_rcv_string(control, &err, - category, sizeof(category), count); - count -= cmyth_rcv_timestamp(control, &err, - &next_prog->proginfo_start_ts, count); - count -= cmyth_rcv_timestamp(control, &err, - &next_prog->proginfo_end_ts, count); - count -= cmyth_rcv_string(control, &err, - callsign, sizeof(callsign), count); - count -= cmyth_rcv_string(control, &err, - iconpath, sizeof(iconpath), count); - count -= cmyth_rcv_string(control, &err, - channelname, sizeof(channelname), count); - count -= cmyth_rcv_string(control, &err, - chanid, sizeof(chanid), count); - if (control->conn_version >= 12) { - count -= cmyth_rcv_string(control, &err, - seriesid, sizeof(seriesid), count); - count -= cmyth_rcv_string(control, &err, - programid, sizeof(programid), count); - } - - if (count != 0) { - ret = -1; - goto out; - } - - /* - * if the program info is blank, return an error - */ - if ((strlen(title) == 0) && (strlen(subtitle) == 0) && - (strlen(desc) == 0) && (strlen(channelname) == 0) && - (strlen(chanid) == 0)) { - cmyth_dbg(CMYTH_DBG_ERROR, - "%s: blank channel found\n", __FUNCTION__); - ret = -1; - goto out; - } - - next_prog->proginfo_title = ref_strdup(title); - next_prog->proginfo_subtitle = ref_strdup(subtitle); - next_prog->proginfo_description = ref_strdup(desc); - next_prog->proginfo_channame = ref_strdup(channelname); - next_prog->proginfo_chanstr = ref_strdup(channelname); - if (control->conn_version > 40) { /* we are hoping this is fixed by next version bump */ - next_prog->proginfo_chansign = ref_strdup(callsign); - } else { - next_prog->proginfo_chansign = cmyth_utf8tolatin1(callsign); - } - next_prog->proginfo_chanicon = ref_strdup(iconpath); - - next_prog->proginfo_chanId = atoi(chanid); - - ref_hold(next_prog->proginfo_start_ts); - ref_hold(next_prog->proginfo_end_ts); - - ret = 0; - - out: - pthread_mutex_unlock(&mutex); - - return ret; -} - -/* - * cmyth_recorder_get_next_proginfo(cmyth_recorder_t rec, - * cmyth_proginfo_t current, - * cmyth_browsedir_t direction) - * - * Scope: PUBLIC - * - * Description: - * - * Request program information from the recorder 'rec' for the next - * program in the program guide from the current program (i.e. current - * channel and time slot) in the direction specified by 'direction' - * which may have any of the following values: - * - * BROWSE_DIRECTION_SAME - Stay in the same place - * BROWSE_DIRECTION_UP - Move up one slot (down one channel) - * BROWSE_DIRECTION_DOWN - Move down one slot (up one channel) - * BROWSE_DIRECTION_LEFT - Move left one slot (down one time slot) - * BROWSE_DIRECTION_RIGHT - Move right one slot (up one time slot) - * BROWSE_DIRECTION_FAVORITE - Move to the next favorite slot - * - * This does not affect the current recording. - * - * Return Value: - * - * Success: A held non-NULL cmyth_proginfo_t - * Failure: A NULL pointer - */ -cmyth_proginfo_t -cmyth_recorder_get_next_proginfo(cmyth_recorder_t rec, - cmyth_proginfo_t current, - cmyth_browsedir_t direction) -{ - cmyth_proginfo_t ret; - - if (!rec || !current) { - cmyth_dbg(CMYTH_DBG_ERROR, "%s: invalid args " - "rec =%p, current = %p\n", - __FUNCTION__, rec, current); - return NULL; - } - ret = cmyth_proginfo_create(); - if (ret == NULL) { - cmyth_dbg(CMYTH_DBG_ERROR, - "%s: cmyth_proginfo_create() failed\n", - __FUNCTION__); - return NULL; - } - if (cmyth_recorder_get_next_program_info(rec, current, - ret, direction) < 0) { - cmyth_dbg(CMYTH_DBG_ERROR, - "%s: cmyth_recorder_get_next_program_info()\n", - __FUNCTION__); - ref_release(ret); - return NULL; - } - return ret; -} - -/* - * cmyth_recorder_get_input_name(cmyth_recorder_t rec) - * - * Scope: PUBLIC - * - * Description: - * - * Request the current input name from the recorder 'rec'. - * - * The input name up to 'len' bytes will be placed in the user - * supplied string buffer 'name' which must be large enough to hold - * 'len' bytes. If the name is greater than or equal to 'len' bytes - * long, the first 'len' - 1 bytes will be placed in 'name' followed - * by a '\0' terminator. - * - * This does not affect the current recording. - * - * Return Value: - * - * Success: 1 - valid channel, 0 - invalid channel - * - * Failure: -(ERRNO) - */ -int -cmyth_recorder_get_input_name(cmyth_recorder_t rec, - char *name, - unsigned len) -{ - return -ENOSYS; -} - -/* - * cmyth_recorder_seek(cmyth_recorder_t rec, - * long long pos, - * cmyth_whence_t whence, - * long long curpos) - * - * Scope: PUBLIC - * - * Description: - * - * Request the recorder 'rec' to seek to the offset specified by 'pos' - * using the specifier 'whence' to indicate how to perform the seek. - * The value of 'whence' may be: - * - * WHENCE_SET - set the seek offset absolutely from the beginning - * of the stream. - * - * WHENCE_CUR - set the seek offset relatively from the current - * offset (as specified in 'curpos'). - * - * WHENCE_END - set the seek offset absolutely from the end - * of the stream. - * - * - * Return Value: - * - * Success: long long current offset >= 0 - * - * Failure: (long long) -(ERRNO) - */ -long long -cmyth_recorder_seek(cmyth_recorder_t rec, - long long pos, - cmyth_whence_t whence, - long long curpos) - -{ - return (long long) -ENOSYS; -} - -/* - * cmyth_recorder_spawn_livetv(cmyth_recorder_t rec) - * - * Scope: PUBLIC - * - * Description: - * - * Request the recorder 'rec' to start recording live-tv on its - * current channel. - * - * Return Value: - * - * Success: 0 - * - * Failure: -(ERRNO) - */ -int -cmyth_recorder_spawn_livetv(cmyth_recorder_t rec) -{ - int err; - int ret = -1; - char msg[256]; - - if (!rec) { - cmyth_dbg(CMYTH_DBG_ERROR, "%s: no recorder connection\n", - __FUNCTION__); - return -ENOSYS; - } - - pthread_mutex_lock(&mutex); - - snprintf(msg, sizeof(msg), "QUERY_RECORDER %d[]:[]SPAWN_LIVETV", - rec->rec_id); - - if ((err=cmyth_send_message(rec->rec_conn, msg)) < 0) { - cmyth_dbg(CMYTH_DBG_ERROR, - "%s: cmyth_send_message() failed (%d)\n", - __FUNCTION__, err); - goto fail; - } - - if ((err=cmyth_rcv_okay(rec->rec_conn, "ok")) < 0) { - cmyth_dbg(CMYTH_DBG_ERROR, - "%s: cmyth_rcv_okay() failed (%d)\n", - __FUNCTION__, err); - goto fail; - } - - ret = 0; - - fail: - pthread_mutex_unlock(&mutex); - - return ret; -} - -/* Sergio: Added to support the new livetv protocol */ -int -cmyth_recorder_spawn_chain_livetv(cmyth_recorder_t rec, char* channame) -{ - int err; - int ret = -1; - char msg[256]; - char myhostname[32]; - char datestr[32]; - time_t t; - - if (!rec) { - cmyth_dbg(CMYTH_DBG_ERROR, "%s: no recorder connection\n", - __FUNCTION__); - return -ENOSYS; - } - - pthread_mutex_lock(&mutex); - - - /* Get our own IP address */ - gethostname(myhostname, 32); - - /* Get the current date and time to create a unique id */ - t = time(NULL); - strftime(datestr, 32, "%Y-%m-%dT%H:%M:%S", localtime(&t)); - - /* Now build the SPAWN_LIVETV message */ - if(rec->rec_conn->conn_version >= 34 && channame) - snprintf(msg, sizeof(msg), - "QUERY_RECORDER %d[]:[]SPAWN_LIVETV[]:[]live-%s-%s[]:[]%d[]:[]%s", - rec->rec_id, myhostname, datestr, 0, channame); - else - snprintf(msg, sizeof(msg), - "QUERY_RECORDER %d[]:[]SPAWN_LIVETV[]:[]live-%s-%s[]:[]%d", - rec->rec_id, myhostname, datestr, 0); - - if ((err=cmyth_send_message(rec->rec_conn, msg)) < 0) { - cmyth_dbg(CMYTH_DBG_ERROR, - "%s: cmyth_send_message() failed (%d)\n", - __FUNCTION__, err); - goto fail; - } - - if ((err=cmyth_rcv_okay(rec->rec_conn, "ok")) < 0) { - cmyth_dbg(CMYTH_DBG_ERROR, - "%s: cmyth_rcv_okay() failed (%d)\n", - __FUNCTION__, err); - goto fail; - } - - /* Create an empty livetv chain with the ID used in the spawn command */ - snprintf(msg, sizeof(msg), - "live-%s-%s[]:[]", - myhostname, datestr); - rec->rec_livetv_chain = cmyth_livetv_chain_create(msg); - - ret = 0; - - fail: - pthread_mutex_unlock(&mutex); - - return ret; -} - -int -cmyth_recorder_stop_livetv(cmyth_recorder_t rec) -{ - int err; - int ret = -1; - char msg[256]; - - if (!rec) { - cmyth_dbg(CMYTH_DBG_ERROR, "%s: no recorder connection\n", - __FUNCTION__); - return -ENOSYS; - } - - pthread_mutex_lock(&mutex); - - snprintf(msg, sizeof(msg), "QUERY_RECORDER %d[]:[]STOP_LIVETV", - rec->rec_id); - - if ((err=cmyth_send_message(rec->rec_conn, msg)) < 0) { - cmyth_dbg(CMYTH_DBG_ERROR, - "%s: cmyth_send_message() failed (%d)\n", - __FUNCTION__, err); - goto fail; - } - - if ((err=cmyth_rcv_okay(rec->rec_conn, "ok")) < 0) { - cmyth_dbg(CMYTH_DBG_ERROR, - "%s: cmyth_rcv_okay() failed (%d)\n", - __FUNCTION__, err); - goto fail; - } - - ret = 0; - - fail: - pthread_mutex_unlock(&mutex); - - return ret; -} - -int -cmyth_recorder_done_ringbuf(cmyth_recorder_t rec) -{ - int err; - int ret = -1; - char msg[256]; - - if (!rec) { - cmyth_dbg(CMYTH_DBG_ERROR, "%s: no recorder connection\n", - __FUNCTION__); - return -ENOSYS; - } - - if(rec->rec_conn->conn_version >= 26) - return 0; - - pthread_mutex_lock(&mutex); - - snprintf(msg, sizeof(msg), "QUERY_RECORDER %d[]:[]DONE_RINGBUF", - rec->rec_id); - - if ((err=cmyth_send_message(rec->rec_conn, msg)) < 0) { - cmyth_dbg(CMYTH_DBG_ERROR, - "%s: cmyth_send_message() failed (%d)\n", - __FUNCTION__, err); - goto fail; - } - - if ((err=cmyth_rcv_okay(rec->rec_conn, "OK")) < 0) { - cmyth_dbg(CMYTH_DBG_ERROR, - "%s: cmyth_rcv_okay() failed (%d)\n", - __FUNCTION__, err); - goto fail; - } - - ret = 0; - - fail: - pthread_mutex_unlock(&mutex); - - return ret; -} - -/* - * cmyth_recorder_start_stream(cmyth_recorder_t rec) - * - * Scope: PUBLIC - * - * Description: - * - * Request the recorder 'rec' to start a stream of the current - * recording (or live-tv). - * - * Return Value: - * - * Success: 0 - * - * Failure: -(ERRNO) - */ -int -cmyth_recorder_start_stream(cmyth_recorder_t rec) -{ - return -ENOSYS; -} - -/* - * cmyth_recorder_end_stream(cmyth_recorder_t rec) - * - * Scope: PUBLIC - * - * Description: - * - * Request the recorder 'rec' to end a stream of the current recording - * (or live-tv). - * - * Return Value: - * - * Success: 0 - * - * Failure: -(ERRNO) - */ -int -cmyth_recorder_end_stream(cmyth_recorder_t rec) -{ - return -ENOSYS; -} - -char* -cmyth_recorder_get_filename(cmyth_recorder_t rec) -{ - char buf[256], *ret; - - if (!rec) { - cmyth_dbg(CMYTH_DBG_ERROR, "%s: no recorder connection\n", - __FUNCTION__); - return NULL; - } - - if(rec->rec_conn->conn_version >= 26) - snprintf(buf, sizeof(buf), "%s", - rec->rec_livetv_chain->chain_urls[rec->rec_livetv_chain->chain_current]); - else - snprintf(buf, sizeof(buf), "ringbuf%d.nuv", rec->rec_id); - - ret = ref_strdup(buf); - - return ret; -} - -int -cmyth_recorder_get_recorder_id(cmyth_recorder_t rec) -{ - if (!rec) { - cmyth_dbg(CMYTH_DBG_ERROR, "%s: no recorder connection\n", - __FUNCTION__); - return -EINVAL; - } - - return rec->rec_id; -} diff --git a/lib/cmyth/libcmyth/ringbuf.c b/lib/cmyth/libcmyth/ringbuf.c deleted file mode 100644 index 77ea52d54b..0000000000 --- a/lib/cmyth/libcmyth/ringbuf.c +++ /dev/null @@ -1,590 +0,0 @@ -/* - * Copyright (C) 2004-2012, Eric Lund - * http://www.mvpmc.org/ - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -/* - * ringbuf.c - functions to handle operations on MythTV ringbuffers. A - * MythTV Ringbuffer is the part of the backend that handles - * recording of live-tv for streaming to a MythTV frontend. - * This allows the watcher to do things like pause, rewind - * and so forth on live-tv. - */ -#include <stdlib.h> -#include <stdio.h> -#include <errno.h> -#include <string.h> -#include <sys/types.h> -#include <cmyth_local.h> - -/* - * cmyth_ringbuf_destroy(cmyth_ringbuf_t rb) - * - * Scope: PRIVATE (static) - * - * Description - * - * Clean up and free a ring buffer structure. This should only be done - * by the ref_release() code. Everyone else should call - * ref_release() because ring buffer structures are reference - * counted. - * - * Return Value: - * - * None. - */ -static void -cmyth_ringbuf_destroy(cmyth_ringbuf_t rb) -{ - cmyth_dbg(CMYTH_DBG_DEBUG, "%s\n", __FUNCTION__); - if (!rb) { - return; - } - - if (rb->ringbuf_url) { - ref_release(rb->ringbuf_url); - } - if (rb->ringbuf_hostname) { - ref_release(rb->ringbuf_hostname); - } -} - -/* - * cmyth_ringbuf_create(void) - * - * Scope: PUBLIC - * - * Description - * - * Allocate and initialize a ring buffer structure. - * - * Return Value: - * - * Success: A non-NULL cmyth_ringbuf_t (this type is a pointer) - * - * Failure: A NULL cmyth_ringbuf_t - */ -cmyth_ringbuf_t -cmyth_ringbuf_create(void) -{ - cmyth_ringbuf_t ret = ref_alloc(sizeof(*ret)); - - cmyth_dbg(CMYTH_DBG_DEBUG, "%s\n", __FUNCTION__); - if (!ret) { - return NULL; - } - - ret->conn_data = NULL; - ret->ringbuf_url = NULL; - ret->ringbuf_size = 0; - ret->ringbuf_fill = 0; - ret->file_pos = 0; - ret->file_id = 0; - ret->ringbuf_hostname = NULL; - ret->ringbuf_port = 0; - ref_set_destroy(ret, (ref_destroy_t)cmyth_ringbuf_destroy); - return ret; -} - -/* - * cmyth_ringbuf_setup(cmyth_recorder_t old_rec) - * - * Scope: PUBLIC - * - * Description - * - * Set up the ring buffer inside a recorder for use in playing live - * tv. The recorder is supplied. This will be duplicated and - * released, so the caller can re-use the same variable to hold the - * return. The new copy of the recorder will have a ringbuffer set up - * within it. - * - * Return Value: - * - * Success: A pointer to a new recorder structure with a ringbuffer - * - * Faiure: NULL - */ -cmyth_recorder_t -cmyth_ringbuf_setup(cmyth_recorder_t rec) -{ - static const char service[]="rbuf://"; - cmyth_recorder_t new_rec = NULL; - char *host = NULL; - char *port = NULL; - char *path = NULL; - char tmp; - - int err, count; - int r; - int64_t size, fill; - char msg[256]; - char url[1024]; - char buf[32]; - cmyth_conn_t control; - - if (!rec) { - cmyth_dbg(CMYTH_DBG_ERROR, "%s: no recorder connection\n", - __FUNCTION__); - return NULL; - } - - control = rec->rec_conn; - - pthread_mutex_lock(&mutex); - - snprintf(msg, sizeof(msg), - "QUERY_RECORDER %u[]:[]SETUP_RING_BUFFER[]:[]0", - rec->rec_id); - - if ((err=cmyth_send_message(control, msg)) < 0) { - cmyth_dbg(CMYTH_DBG_ERROR, - "%s: cmyth_send_message() failed (%d)\n", - __FUNCTION__, err); - goto out; - } - - count = cmyth_rcv_length(control); - - if (control->conn_version >= 16) { - r = cmyth_rcv_string(control, &err, buf, sizeof(buf)-1, count); - count -= r; - } - r = cmyth_rcv_string(control, &err, url, sizeof(url)-1, count); - count -= r; - - if ((r=cmyth_rcv_int64(control, &err, &size, count)) < 0) { - cmyth_dbg(CMYTH_DBG_ERROR, - "%s: cmyth_rcv_length() failed (%d)\n", - __FUNCTION__, r); - goto out; - } - count -= r; - - if ((r=cmyth_rcv_int64(control, &err, &fill, count)) < 0) { - cmyth_dbg(CMYTH_DBG_ERROR, - "%s: cmyth_rcv_length() failed (%d)\n", - __FUNCTION__, r); - goto out; - } - - cmyth_dbg(CMYTH_DBG_DEBUG, "%s: url is: '%s'\n", - __FUNCTION__, url); - path = url; - if (strncmp(url, service, sizeof(service) - 1) == 0) { - /* - * The URL starts with rbuf://. The rest looks like - * <host>:<port>/<filename>. - */ - host = url + strlen(service); - port = strchr(host, ':'); - if (!port) { - /* - * This does not seem to be a proper URL, so just - * assume it is a filename, and get out. - */ - cmyth_dbg(CMYTH_DBG_DEBUG, - "%s: 1 port %s, host = %s\n", - __FUNCTION__, port, host); - goto out; - } - port = port + 1; - path = strchr(port, '/'); - if (!path) { - /* - * This does not seem to be a proper URL, so just - * assume it is a filename, and get out. - */ - cmyth_dbg(CMYTH_DBG_DEBUG, "%s: no path\n", - __FUNCTION__); - goto out; - } - } - - new_rec = cmyth_recorder_dup(rec); - if (new_rec == NULL) { - cmyth_dbg(CMYTH_DBG_DEBUG, "%s: cannot create recorder\n", - __FUNCTION__); - goto out; - } - ref_release(rec); - new_rec->rec_ring = cmyth_ringbuf_create(); - - tmp = *(port - 1); - *(port - 1) = '\0'; - new_rec->rec_ring->ringbuf_hostname = ref_strdup(host); - *(port - 1) = tmp; - tmp = *(path); - *(path) = '\0'; - new_rec->rec_ring->ringbuf_port = atoi(port); - *(path) = tmp; - new_rec->rec_ring->ringbuf_url = ref_strdup(url); - new_rec->rec_ring->ringbuf_size = size; - new_rec->rec_ring->ringbuf_fill = fill; - - out: - pthread_mutex_unlock(&mutex); - - return new_rec; -} - -char * -cmyth_ringbuf_pathname(cmyth_recorder_t rec) -{ - return ref_hold(rec->rec_ring->ringbuf_url); -} - -/* - * cmyth_ringbuf_get_block(cmyth_recorder_t rec, char *buf, unsigned long len) - * Scope: PUBLIC - * Description - * Read incoming file data off the network into a buffer of length len. - * - * Return Value: - * Sucess: number of bytes read into buf - * Failure: -1 - */ -int -cmyth_ringbuf_get_block(cmyth_recorder_t rec, char *buf, unsigned long len) -{ - struct timeval tv; - fd_set fds; - - if (rec == NULL) - return -EINVAL; - - tv.tv_sec = 10; - tv.tv_usec = 0; - FD_ZERO(&fds); - FD_SET(rec->rec_ring->conn_data->conn_fd, &fds); - if (select((int)rec->rec_ring->conn_data->conn_fd+1, - NULL, &fds, NULL, &tv) == 0) { - rec->rec_ring->conn_data->conn_hang = 1; - return 0; - } else { - rec->rec_ring->conn_data->conn_hang = 0; - } - return recv(rec->rec_ring->conn_data->conn_fd, buf, len, 0); -} - -int -cmyth_ringbuf_select(cmyth_recorder_t rec, struct timeval *timeout) -{ - fd_set fds; - int ret; - cmyth_socket_t fd; - if (rec == NULL) - return -EINVAL; - - fd = rec->rec_ring->conn_data->conn_fd; - - FD_ZERO(&fds); - FD_SET(fd, &fds); - - ret = select((int)fd+1, &fds, NULL, NULL, timeout); - - if (ret == 0) - rec->rec_ring->conn_data->conn_hang = 1; - else - rec->rec_ring->conn_data->conn_hang = 0; - - return ret; -} - -/* - * cmyth_ringbuf_request_block(cmyth_ringbuf_t file, unsigned long len) - * - * Scope: PUBLIC - * - * Description - * - * Request a file data block of a certain size, and return when the - * block has been transfered. - * - * Return Value: - * - * Sucess: number of bytes transfered - * - * Failure: an int containing -errno - */ -int -cmyth_ringbuf_request_block(cmyth_recorder_t rec, unsigned long len) -{ - int err, count; - int r; - long c, ret; - char msg[256]; - - if (!rec) { - cmyth_dbg(CMYTH_DBG_ERROR, "%s: no connection\n", - __FUNCTION__); - return -EINVAL; - } - - pthread_mutex_lock(&mutex); - - if(len > (unsigned int)rec->rec_conn->conn_tcp_rcvbuf) - len = (unsigned int)rec->rec_conn->conn_tcp_rcvbuf; - - snprintf(msg, sizeof(msg), - "QUERY_RECORDER %u[]:[]REQUEST_BLOCK_RINGBUF[]:[]%ld", - rec->rec_id, len); - - if ((err = cmyth_send_message(rec->rec_conn, msg)) < 0) { - cmyth_dbg(CMYTH_DBG_ERROR, - "%s: cmyth_send_message() failed (%d)\n", - __FUNCTION__, err); - ret = err; - goto out; - } - - count = cmyth_rcv_length(rec->rec_conn); - if ((r=cmyth_rcv_long(rec->rec_conn, &err, &c, count)) < 0) { - cmyth_dbg(CMYTH_DBG_ERROR, - "%s: cmyth_rcv_length() failed (%d)\n", - __FUNCTION__, r); - ret = err; - goto out; - } - - rec->rec_ring->file_pos += c; - ret = c; - - out: - pthread_mutex_unlock(&mutex); - - return ret; -} - -/* - * cmyth_ringbuf_read (cmyth_recorder_t rec, char *buf, unsigned long len) - * - * Scope: PUBLIC - * - * Description - * - * Request and read a block of data from backend - * - * Return Value: - * - * Sucess: number of bytes transfered - * - * Failure: an int containing -errno - */ -int cmyth_ringbuf_read(cmyth_recorder_t rec, char *buf, unsigned long len) -{ - int err, count; - int ret, req, nfds; - char *end, *cur; - char msg[256]; - struct timeval tv; - fd_set fds; - - if (!rec) - { - cmyth_dbg (CMYTH_DBG_ERROR, "%s: no connection\n", - __FUNCTION__); - return -EINVAL; - } - - pthread_mutex_lock (&mutex); - - snprintf(msg, sizeof(msg), - "QUERY_RECORDER %u[]:[]REQUEST_BLOCK_RINGBUF[]:[]%ld", - rec->rec_id, len); - - if ( (err = cmyth_send_message (rec->rec_conn, msg) ) < 0) - { - cmyth_dbg (CMYTH_DBG_ERROR, - "%s: cmyth_send_message() failed (%d)\n", - __FUNCTION__, err); - ret = err; - goto out; - } - - nfds = 0; - req = 1; - cur = buf; - end = buf+len; - - while (cur < end || req) - { - tv.tv_sec = 20; - tv.tv_usec = 0; - FD_ZERO (&fds); - if(req) { - if((int)rec->rec_conn->conn_fd > nfds) - nfds = (int)rec->rec_conn->conn_fd; - FD_SET (rec->rec_conn->conn_fd, &fds); - } - if((int)rec->rec_ring->conn_data->conn_fd > nfds) - nfds = (int)rec->rec_ring->conn_data->conn_fd; - FD_SET (rec->rec_ring->conn_data->conn_fd, &fds); - - if ((ret = select (nfds+1, &fds, NULL, NULL,&tv)) < 0) - { - cmyth_dbg (CMYTH_DBG_ERROR, - "%s: select(() failed (%d)\n", - __FUNCTION__, ret); - goto out; - } - - if (ret == 0) - { - rec->rec_ring->conn_data->conn_hang = 1; - rec->rec_conn->conn_hang = 1; - ret = -ETIMEDOUT; - goto out; - } - - /* check control connection */ - if (FD_ISSET(rec->rec_conn->conn_fd, &fds) ) - { - - if ((count = cmyth_rcv_length (rec->rec_conn)) < 0) - { - cmyth_dbg (CMYTH_DBG_ERROR, - "%s: cmyth_rcv_length() failed (%d)\n", - __FUNCTION__, count); - ret = count; - goto out; - } - - if ((ret = cmyth_rcv_ulong (rec->rec_conn, &err, &len, count))< 0) - { - cmyth_dbg (CMYTH_DBG_ERROR, - "%s: cmyth_rcv_long() failed (%d)\n", - __FUNCTION__, ret); - ret = err; - goto out; - } - - rec->rec_ring->file_pos += len; - req = 0; - end = buf+len; - } - - /* check data connection */ - if (FD_ISSET(rec->rec_ring->conn_data->conn_fd, &fds)) - { - - if ((ret = recv (rec->rec_ring->conn_data->conn_fd, cur, end-cur, 0)) < 0) - { - cmyth_dbg (CMYTH_DBG_ERROR, - "%s: recv() failed (%d)\n", - __FUNCTION__, ret); - goto out; - } - cur += ret; - } - } - - ret = end - buf; -out: - pthread_mutex_unlock (&mutex); - return ret; -} - -/* - * cmyth_ringbuf_seek( - * cmyth_ringbuf_t file, long long offset, int whence) - * - * Scope: PUBLIC - * - * Description - * - * Seek to a new position in the file based on the value of whence: - * SEEK_SET - * The offset is set to offset bytes. - * SEEK_CUR - * The offset is set to the current position plus offset bytes. - * SEEK_END - * The offset is set to the size of the file minus offset bytes. - * - * Return Value: - * - * Sucess: 0 - * - * Failure: an int containing -errno - */ -long long -cmyth_ringbuf_seek(cmyth_recorder_t rec, - long long offset, int whence) -{ - char msg[128]; - int err; - int count; - int64_t c; - long r; - long long ret; - cmyth_ringbuf_t ring; - - if (rec == NULL) - return -EINVAL; - - ring = rec->rec_ring; - - if ((offset == 0) && (whence == SEEK_CUR)) - return ring->file_pos; - - pthread_mutex_lock(&mutex); - - snprintf(msg, sizeof(msg), - "QUERY_RECORDER %u[]:[]SEEK_RINGBUF[]:[]%d[]:[]%d[]:[]%d[]:[]%d[]:[]%d", - rec->rec_id, - (int32_t)(offset >> 32), - (int32_t)(offset & 0xffffffff), - whence, - (int32_t)(ring->file_pos >> 32), - (int32_t)(ring->file_pos & 0xffffffff)); - - if ((err = cmyth_send_message(rec->rec_conn, msg)) < 0) { - cmyth_dbg(CMYTH_DBG_ERROR, - "%s: cmyth_send_message() failed (%d)\n", - __FUNCTION__, err); - ret = err; - goto out; - } - - count = cmyth_rcv_length(rec->rec_conn); - if ((r=cmyth_rcv_int64(rec->rec_conn, &err, &c, count)) < 0) { - cmyth_dbg(CMYTH_DBG_ERROR, - "%s: cmyth_rcv_length() failed (%d)\n", - __FUNCTION__, r); - ret = err; - goto out; - } - - switch (whence) { - case SEEK_SET: - ring->file_pos = offset; - break; - case SEEK_CUR: - ring->file_pos += offset; - break; - case SEEK_END: - ring->file_pos = ring->file_length - offset; - break; - } - - ret = ring->file_pos; - - out: - pthread_mutex_unlock(&mutex); - - return ret; -} diff --git a/lib/cmyth/libcmyth/safe_string.h b/lib/cmyth/libcmyth/safe_string.h deleted file mode 100644 index 3efa9a1576..0000000000 --- a/lib/cmyth/libcmyth/safe_string.h +++ /dev/null @@ -1,49 +0,0 @@ -/* - * Copyright (C) 2006-2009, Simon Hyde - * http://www.mvpmc.org/ - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -/** \file safe_string.h - * Some basic string handling routines to help avoid segfaults/buffer overflows - */ - -#ifndef __CMYTH_STRING_H -#define __CMYTH_STRING_H - -#include <stdio.h> - -static inline char * safe_strncpy(char *dest,const char *src,size_t n) -{ - if(src == NULL) - { - dest[0] = '\0'; - } - else - { - dest[n-1] = '\0'; - strncpy(dest,src,n-1); - } - return dest; -} - -#define sizeof_strncpy(dest,src) (safe_strncpy(dest,src,sizeof(dest))) - -#define safe_atol(str) (((str) == NULL)? (long)0: atol(str)) -#define safe_atoll(str) (((str) == NULL)? (long long)0: atoll(str)) -#define safe_atoi(str) (((str) == NULL)? (int)0: atoi(str)) - -#endif /* __CMYTH_STRING_H */ diff --git a/lib/cmyth/libcmyth/socket.c b/lib/cmyth/libcmyth/socket.c deleted file mode 100644 index 4340f2ea78..0000000000 --- a/lib/cmyth/libcmyth/socket.c +++ /dev/null @@ -1,3007 +0,0 @@ -/* - * Copyright (C) 2004-2012, Eric Lund - * http://www.mvpmc.org/ - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -/* - * socket.c - functions to handle low level socket interactions with a - * MythTV frontend. - */ -#include <stdlib.h> -#include <stdio.h> -#include <ctype.h> -#include <string.h> -#include <errno.h> -#include <sys/types.h> -#include <cmyth_local.h> - -#define __UNSIGNED "0123456789" -#define __SIGNED "+-0123456789" -#define __check_num(num) (strspn((num), __SIGNED) == strlen((num))) -#define __check_unum(num) (strspn((num), __UNSIGNED) == strlen((num))) - -/* - * cmyth_send_message(cmyth_conn_t conn, char *request) - * - * Scope: PRIVATE (mapped to __cmyth_send_message) - * - * Description - * - * Send a myth protocol on the socket indicated by 'conn'. The - * message sent has the form: - * - * <length><request> - * - * Where <length> is the 8 character, space padded, left justified - * ASCII representation of the number of bytes in the message - * (including <length>) and <request> is the string specified in the - * 'request' argument. - * - * Return Value: - * - * Success: 0 - * - * Failure: -(errno) - */ -int -cmyth_send_message(cmyth_conn_t conn, char *request) -{ - /* - * For now this is unimplemented. - */ - char *msg; - int reqlen; - int written = 0; - int w; - struct timeval tv; - fd_set fds; - - cmyth_dbg(CMYTH_DBG_DEBUG, "%s\n", __FUNCTION__); - if (!conn) { - cmyth_dbg(CMYTH_DBG_ERROR, "%s: no connection\n", - __FUNCTION__); - return -EBADF; - } - if (conn->conn_fd < 0) { - cmyth_dbg(CMYTH_DBG_ERROR, "%s: not connected\n", - __FUNCTION__); - return -EBADF; - } - if (!request) { - cmyth_dbg(CMYTH_DBG_ERROR, "%s: no request\n", __FUNCTION__); - return -EINVAL; - } - reqlen = strlen(request); - msg = malloc(9 + reqlen); - if (!msg) { - cmyth_dbg(CMYTH_DBG_ERROR, - "%s: cannot allocate message buffer\n", - __FUNCTION__); - return -ENOMEM; - } - sprintf(msg, "%-8d%s", reqlen, request); - cmyth_dbg(CMYTH_DBG_PROTO, "%s: sending message '%s'\n", - __FUNCTION__, msg); - reqlen += 8; - do { - tv.tv_sec = 10; - tv.tv_usec = 0; - FD_ZERO(&fds); - FD_SET(conn->conn_fd, &fds); - if (select((int)conn->conn_fd+1, NULL, &fds, NULL, &tv) == 0) { - conn->conn_hang = 1; - continue; - } else { - conn->conn_hang = 0; - } - w = send(conn->conn_fd, msg + written, reqlen - written, 0); - if (w < 0) { - cmyth_dbg(CMYTH_DBG_ERROR, "%s: write() failed (%d)\n", - __FUNCTION__, errno); - free(msg); - return -errno; - } - written += w; - } while (written < reqlen); - - free(msg); - return 0; -} - -/* - * cmyth_rcv_length(cmyth_conn_t conn) - * - * Scope: PRIVATE (mapped to __cmyth_rcv_length) - * - * Description - * - * Receive the <length> portion of a MythTV Protocol message - * on the socket specified by 'conn' - * - * Return Value: - * - * Success: A length value > 0 and < 100000000 - * - * Failure: -(errno) - */ -int -cmyth_rcv_length(cmyth_conn_t conn) -{ - char buf[16]; - int rtot = 0; - int r; - int ret; - struct timeval tv; - fd_set fds; - - cmyth_dbg(CMYTH_DBG_DEBUG, "%s\n", __FUNCTION__); - if (!conn) { - cmyth_dbg(CMYTH_DBG_ERROR, "%s: no connection\n", - __FUNCTION__); - return -EBADF; - } - if (conn->conn_fd < 0) { - cmyth_dbg(CMYTH_DBG_ERROR, "%s: not connected\n", - __FUNCTION__); - return -EBADF; - } - buf[8] ='\0'; - do { - tv.tv_sec = 10; - tv.tv_usec = 0; - FD_ZERO(&fds); - FD_SET(conn->conn_fd, &fds); - if ((r=select((int)conn->conn_fd+1, &fds, NULL, NULL, &tv)) == 0) { - conn->conn_hang = 1; - continue; - } else if (r > 0) { - conn->conn_hang = 0; - r = recv(conn->conn_fd, &buf[rtot], 8 - rtot, 0); - } - if (r <= 0) { - cmyth_dbg(CMYTH_DBG_ERROR, "%s: read() failed (%d)\n", - __FUNCTION__, errno); - return -errno; - } - if (r == 0) { - cmyth_dbg(CMYTH_DBG_ERROR, "%s: read() failed (%d)\n", - __FUNCTION__, errno); - return -EBADF; - } - rtot += r; - } while (rtot < 8); - ret = atoi(buf); - cmyth_dbg(CMYTH_DBG_PROTO, "%s: buffer is '%s' ret = %d\n", - __FUNCTION__, buf, ret); - return ret; -} - -/* - * cmyth_conn_refill(cmyth_conn_t conn, int len) - * - * Scope: PRIVATE (static) - * - * Description - * - * FIll up the buffer in the connection 'conn' with up to 'len' bytes - * of data. - * - * Return Value: - * - * Success: 0 - * - * Failure: -errno - */ -static int -cmyth_conn_refill(cmyth_conn_t conn, int len) -{ - int r; - int total = 0; - unsigned char *p; - struct timeval tv; - fd_set fds; - - if (!conn) { - cmyth_dbg(CMYTH_DBG_ERROR, "%s: no connection\n", - __FUNCTION__); - return -EINVAL; - } - if (!conn->conn_buf) { - cmyth_dbg(CMYTH_DBG_ERROR, "%s: connection has no buffer\n", - __FUNCTION__); - return -EINVAL; - } - if (len > conn->conn_buflen) { - len = conn->conn_buflen; - } - p = conn->conn_buf; - while (len > 0) { - tv.tv_sec = 10; - tv.tv_usec = 0; - FD_ZERO(&fds); - FD_SET(conn->conn_fd, &fds); - if ((r=select((int)conn->conn_fd+1, &fds, NULL, NULL, &tv)) == 0) { - conn->conn_hang = 1; - continue; - } else if (r > 0) { - conn->conn_hang = 0; - r = recv(conn->conn_fd, p, len, 0); - } - if (r <= 0) { - if (total == 0) { - cmyth_dbg(CMYTH_DBG_ERROR, - "%s: read failed (%d)\n", - __FUNCTION__, errno); - return -1 * errno; - } - /* - * There were bytes read before the error, use them and - * then report the error next time. - */ - break; - } - total += r; - len -= r; - p += r; - } - conn->conn_pos = 0; - conn->conn_len = total; - return 0; -} - -/* - * cmyth_rcv_string(cmyth_conn_t conn, char *buf, int buflen, int count) - * - * Scope: PRIVATE (mapped to __cmyth_rcv_length) - * - * Description - * - * Receive a string token from a list of tokens in a MythTV Protocol - * message. Tokens in MythTV Protocol messages are separated by the - * string: []:[] or terminated by running out of message. Up to - * 'count' Bytes will be consumed from the socket specified by 'conn' - * (stopping when a separator is seen or 'count' is exhausted). Of - * these, the first 'buflen' bytes will be copied into 'buf'. If - * a full 'buflen' bytes is read, 'buf' will not be terminated with a - * '\0', otherwise it will be. If an error is encountered and - * 'err' is not NULL, an indication of the nature of the error will be - * recorded by placing an error code in the location pointed to by - * 'err'. If all goes well, 'err' wil be set to 0. - * - * Return Value: - * - * A value >=0 indicating the number of bytes consumed. - */ -int -cmyth_rcv_string(cmyth_conn_t conn, int *err, char *buf, int buflen, int count) -{ - static char separator[] = "[]:[]"; - int consumed = 0; - int placed = 0; - char *state = separator; - char *sep_start = NULL; - int tmp; - - if (!err) { - err = &tmp; - } - - if (count < 0) { - /* - * Strings are terminated by either the next separator or the end of the payload. If - * the last string requested in the payload is empty the count will be zero. In this case - * we should return an empty string rather than an error. - * - * http://www.mythtv.org/wiki/Myth_Protocol#Packet_Data_Format - */ - *err = EINVAL; - return 0; - } - - if (!conn) { - cmyth_dbg(CMYTH_DBG_ERROR, "%s: no connection\n", - __FUNCTION__); - *err = EBADF; - return 0; - } - if (conn->conn_fd < 0) { - cmyth_dbg(CMYTH_DBG_ERROR, "%s: not connected\n", - __FUNCTION__); - *err = EBADF; - return 0; - } - if (!conn->conn_buf) { - cmyth_dbg(CMYTH_DBG_ERROR, "%s: no connection buffer\n", - __FUNCTION__); - *err = EBADF; - return 0; - } - if (!buf) { - cmyth_dbg(CMYTH_DBG_ERROR, "%s: no output buffer\n", - __FUNCTION__); - *err = EBADF; - return 0; - } - - while (1) { - if (consumed >= count) { - /* - * We have consumed all the characters we were - * asked to from the stream. Force a refill - * on the next call, and return 'consumed'. - */ - conn->conn_pos = conn->conn_len = 0; - if (buflen > placed) { - buf[placed] = '\0'; - } - break; - } - - if (conn->conn_pos >= conn->conn_len) { - /* - * We have run out of (or never had any) bytes - * from the connection. Refill the buffer. - */ - *err = cmyth_conn_refill(conn, count - consumed); - if (*err < 0) { - *err = -1 * (*err); - break; - } - } - - if (conn->conn_buf[conn->conn_pos] == (unsigned char)*state) { - /* - * We matched the next (possibly first) step - * of a separator, advance to the next. - */ - if ((state == separator) && (placed < buflen)) { - sep_start = &buf[placed]; - } - ++state; - } else { - /* - * No match with separator, reset the state to the - * beginning. - */ - sep_start = NULL; - state = separator; - } - - if (placed < buflen) { - /* - * This character goes in the output buffer, - * put it there. - */ - buf[placed++] = conn->conn_buf[conn->conn_pos]; - } - ++conn->conn_pos; - ++consumed; - - if (*state == '\0') { - /* - * Reached the end of a separator, terminate - * the returned buffer at the beginning of the - * separator (if it fell within the buffer) - * and return. - */ - if (sep_start) { - *sep_start = '\0'; - } else if (buflen > placed) { - buf[placed] = '\0'; - } - break; - } - } - cmyth_dbg(CMYTH_DBG_PROTO, "%s: string received '%s'\n", - __FUNCTION__, buf); - return consumed; -} - -/* - * cmyth_rcv_ulong(cmyth_conn_t conn, int *err, unsigned long *buf, - * int count) - * - * Scope: PRIVATE (mapped to __cmyth_rcv_ulong_long) - * - * Description - * - * Receive an unsigned long long (64 bit) integer token from a list of - * tokens in a MythTV Protocol message. Tokens in MythTV Protocol - * messages are separated by the string: []:[] or terminated by - * running out of message. Up to 'count' Bytes will be consumed from - * the socket specified by 'conn' (stopping when a separator is seen - * or 'count' is exhausted). The unsigned long long integer value of - * the token is placed in the location pointed to by 'buf'. If an - * error is encountered and 'err' is not NULL, an indication of the - * nature of the error will be recorded by placing an error code in - * the location pointed to by 'err'. If all goes well, 'err' wil be - * set to 0. - * - * Return Value: - * - * A value >=0 indicating the number of bytes consumed. - * - * Error Codes: - * - * In addition to system call error codes, the following errors may be - * placed in 'err': - * - * ERANGE The token received is too large to fit in an unsinged - * long long integer - * - * EINVAL The token received is not numeric or is signed - */ -int -cmyth_rcv_ulong(cmyth_conn_t conn, int *err, unsigned long *buf, - int count) -{ - char num[32]; - char *num_p = num; - unsigned long long val = 0; - unsigned long limit = 0xffffffff; - int consumed; - int tmp; - - *buf = 0; - - if (!err) { - err = &tmp; - } - - if (count <= 0) { - *err = EINVAL; - return 0; - } - - *err = 0; - consumed = cmyth_rcv_string(conn, err, num, sizeof(num), count); - if (*err) { - cmyth_dbg(CMYTH_DBG_ERROR, - "%s: cmyth_rcv_string() failed (%d)\n", - __FUNCTION__, consumed); - return consumed; - } - while (*num_p) { - if (!isdigit(*num_p)) { - cmyth_dbg(CMYTH_DBG_ERROR, - "%s: received illegal integer: '%s'\n", - __FUNCTION__, num); - *err = EINVAL; - return consumed; - } - /* - * If we are about to make 'val' bigger than 32bit, - * it is ERANGE. - */ - if (val > limit && *num_p > '5') { - *err = ERANGE; - return consumed; - } - val *= 10; - val += ((*num_p) - '0'); - num_p++; - } - - /* - * Got a result, return it. - */ - *buf = (unsigned long)val; - return consumed; -} - -/* - * cmyth_rcv_long(cmyth_conn_t conn, int *err, long *buf, int count) - * - * Scope: PRIVATE (mapped to __cmyth_rcv_long_long) - * - * Description - * - * Receive a long (signed 32 bit) integer token from a list of - * tokens in a MythTV Protocol message. Tokens in MythTV Protocol - * messages are separated by the string: []:[] or terminated by - * running out of message. Up to 'count' Bytes will be consumed from - * the socket specified by 'conn' (stopping when a separator is seen - * or 'count' is exhausted). The long long integer value of the token - * is placed in the location pointed to by 'buf'. If an error is - * encountered and 'err' is not NULL, an indication of the nature of - * the error will be recorded by placing an error code in the location - * pointed to by 'err'. If all goes well, 'err' wil be set to 0. - * - * Return Value: - * - * A value >=0 indicating the number of bytes consumed. - * - * Error Codes: - * - * In addition to system call error codes, the following errors may be - * placed in 'err': - * - * ERANGE The token received is too large to fit in a - * long long integer - * - * EINVAL The token received is not numeric - */ -int -cmyth_rcv_long(cmyth_conn_t conn, int *err, long *buf, int count) -{ - char num[32]; - char *num_p = num; - unsigned long long val = 0; - int sign = 1; - long limit = 0x7fffffff; - int consumed; - int tmp; - - if (!err) { - err = &tmp; - } - if (count <= 0) { - *err = EINVAL; - return 0; - } - *err = 0; - consumed = cmyth_rcv_string(conn, err, num, sizeof(num), count); - if (*err) { - cmyth_dbg(CMYTH_DBG_ERROR, - "%s: cmyth_rcv_string() failed (%d)\n", - __FUNCTION__, consumed); - return consumed; - } - if (*num_p && (*num_p == '-')) { - ++num_p; - sign = -1; - } - while (*num_p) { - if (!isdigit(*num_p)) { - cmyth_dbg(CMYTH_DBG_ERROR, - "%s: received illegal integer: '%s'\n", - __FUNCTION__, num); - *err = EINVAL; - return consumed; - } - val *= 10; - val += ((*num_p) - '0'); - /* - * Check and make sure we are still under the limit (this is - * an absolute value limit, sign will be applied later). - */ - if (val > (unsigned long)limit) { - cmyth_dbg(CMYTH_DBG_ERROR, - "%s: long out of range: '%s'\n", - __FUNCTION__, num); - *err = ERANGE; - return consumed; - } - num_p++; - } - - /* - * Got a result, return it. - */ - *buf = (long)(sign * val); - - return consumed; -} - -/* - * cmyth_rcv_okay(cmyth_conn_t conn, char *ok) - * - * Scope: PRIVATE (mapped to __cmyth_rcv_okay) - * - * Description - * - * Receive an 'OK' (or another user specified) response on a - * connection. If 'ok' is non-NULL it points to a string which should - * be matched in place of 'OK'. If it is NULL, this routine will look - * for "OK". This is here to easily handle simple acknowledgement from - * the server. - * - * Return Value: - * - * Success: 0 - * - * Failure: -(errno) - */ -int -cmyth_rcv_okay(cmyth_conn_t conn, char *ok) -{ - int len; - int consumed; - char buf[8]; - int err; - - len = cmyth_rcv_length(conn); - if (len < 0) { - cmyth_dbg(CMYTH_DBG_ERROR, "%s: cmyth_rcv_length() failed\n", - __FUNCTION__); - return len; - } - if (!ok) { - ok = "OK"; - } - consumed = cmyth_rcv_string(conn, &err, buf, sizeof(buf), len); - if (err) { - cmyth_dbg(CMYTH_DBG_ERROR, "%s: cmyth_rcv_string() failed\n", - __FUNCTION__); - return -err; - } - if (consumed < len) { - cmyth_dbg(CMYTH_DBG_ERROR, - "%s: did not consume everything %d < %d\n", - __FUNCTION__, consumed, len); - } - return (strcmp(buf, ok) == 0) ? 0 : -1; -} - -/* - * cmyth_rcv_version(cmyth_conn_t conn, unsigned long *vers) - * - * Scope: PRIVATE (mapped to __cmyth_rcv_version) - * - * Description - * - * Receive an ACCEPT <version> or REJECT <version> response on a - * connection. If 'vers' is non-NULL it points to the location where - * the received version number should be placed. If it is NULL, this - * routine will still read the version but it will throw it away. - * - * Return Value: - * - * Success: 0 - * - * Failure: -(errno) - */ -int -cmyth_rcv_version(cmyth_conn_t conn, unsigned long *vers) -{ - int len; - int consumed; - char buf[8]; - unsigned long tmp_vers; - int err; - - if (!vers) { - vers = &tmp_vers; - } - len = cmyth_rcv_length(conn); - if (len < 0) { - cmyth_dbg(CMYTH_DBG_ERROR, "%s: cmyth_rcv_length() failed\n", - __FUNCTION__); - return len; - } - consumed = cmyth_rcv_string(conn, &err, buf, sizeof(buf), len); - if (err) { - cmyth_dbg(CMYTH_DBG_ERROR, "%s: cmyth_rcv_string() failed\n", - __FUNCTION__); - return -err; - } - len -= consumed; - /* - * The string we just consumed was either "ACCEPT" or "REJECT". In - * either case, the number following it is the correct version, and - * we use it as an unsigned long. - */ - consumed = cmyth_rcv_ulong(conn, &err, vers, len); - if (consumed < len) { - cmyth_dbg(CMYTH_DBG_ERROR, - "%s: did not consume everything %d < %d\n", - __FUNCTION__, consumed, len); - } - return -err; -} - -/* - * cmyth_rcv_byte(cmyth_conn_t conn, int *err, char *buf, int count) - * - * Scope: PRIVATE (mapped to __cmyth_rcv_byte) - * - * Description - * - * Receive a byte (signed 8 bit) integer token from a list of tokens - * in a MythTV Protocol message. Tokens in MythTV Protocol messages - * are separated by the string: []:[] or terminated by running out of - * message. Up to 'count' Bytes will be consumed from the socket - * specified by 'conn' (stopping when a separator is seen or 'count' - * is exhausted). The byte integer value of the token is placed in - * the location pointed to by 'buf'. If an error is encountered and - * 'err' is not NULL, an indication of the nature of the error will be - * recorded by placing an error code in the location pointed to by - * 'err'. If all goes well, 'err' wil be set to 0. - * - * Return Value: - * - * Success / Failure: A value >=0 indicating the number of bytes - * consumed. - * - * Error Codes: - * - * In addition to system call error codes, the following errors may be - * placed in 'err' by this function: - * - * ERANGE The token received is too large to fit in a byte integer - * - * EINVAL The token received is not numeric - */ -int -cmyth_rcv_byte(cmyth_conn_t conn, int *err, char *buf, int count) -{ - long val; - int consumed; - int tmp; - - if (!err) { - err = &tmp; - } - if (count <= 0) { - *err = EINVAL; - return 0; - } - consumed = cmyth_rcv_long(conn, err, &val, count); - if (*err) { - cmyth_dbg(CMYTH_DBG_ERROR, - "%s: cmyth_rcv_long() failed (%d)\n", - __FUNCTION__, consumed); - return consumed; - } - if ((val > 127) || (val < -128)) { - cmyth_dbg(CMYTH_DBG_ERROR, "%s: value doesn't fit: '%lld'\n", - __FUNCTION__, val); - *err = ERANGE; - return consumed; - } - *err = 0; - *buf = (char)val; - return consumed; -} - -/* - * cmyth_rcv_short(cmyth_conn_t conn, int *err, short *buf, int count) - * - * Scope: PRIVATE (mapped to __cmyth_rcv_short) - * - * Description - * - * Receive a short (signed 16 bit) integer token from a list of tokens - * in a MythTV Protocol message. Tokens in MythTV Protocol messages - * are separated by the string: []:[] or terminated by running out of - * message. Up to 'count' Bytes will be consumed from the socket - * specified by 'conn' (stopping when a separator is seen or 'count' - * is exhausted). The short integer value of the token is placed in - * the location pointed to by 'buf'. If an error is encountered and - * 'err' is not NULL, an indication of the nature of the error will be - * recorded by placing an error code in the location pointed to by - * 'err'. If all goes well, 'err' wil be set to 0. - * - * Return Value: - * - * A value >=0 indicating the number of bytes consumed. - * - * Error Codes: - * - * In addition to system call error codes, the following errors may be - * placed in 'err': - * - * ERANGE The token received is too large to fit in a short integer - * - * EINVAL The token received is not numeric - */ -int -cmyth_rcv_short(cmyth_conn_t conn, int *err, short *buf, int count) -{ - long val; - int consumed; - int tmp; - - if (!err) { - err = &tmp; - } - if (count <= 0) { - *err = EINVAL; - return 0; - } - consumed = cmyth_rcv_long(conn, err, &val, count); - if (*err) { - cmyth_dbg(CMYTH_DBG_ERROR, - "%s: cmyth_rcv_long() failed (%d)\n", - __FUNCTION__, consumed); - return consumed; - } - if ((val > 32767) || (val < -32768)) { - cmyth_dbg(CMYTH_DBG_ERROR, "%s: value doesn't fit: '%lld'\n", - __FUNCTION__, val); - *err = ERANGE; - return consumed; - } - *err = 0; - *buf = (short)val; - return consumed; -} - -/* - * cmyth_rcv_old_int64(cmyth_conn_t conn, int *err, long long *buf, int count) - * - * Scope: PRIVATE (mapped to __cmyth_rcv_long) - * - * Description - * - * Receive a long long (signed 64 bit) integer token from a list of tokens - * in a MythTV Protocol message. Tokens in MythTV Protocol messages - * are separated by the string: []:[] or terminated by running out of - * message. Up to 'count' Bytes will be consumed from the socket - * specified by 'conn' (stopping when a separator is seen or 'count' - * is exhausted). The long integer value of the token is placed in - * the location pointed to by 'buf'. If an error is encountered and - * 'err' is not NULL, an indication of the nature of the error will be - * recorded by placing an error code in the location pointed to by - * 'err'. If all goes well, 'err' wil be set to 0. - * - * Return Value: - * - * A value >=0 indicating the number of bytes consumed. - * - * Error Codes: - * - * In addition to system call error codes, the following errors may be - * placed in 'err': - * - * ERANGE The token received is too large to fit in a long integer - * - * EINVAL The token received is not numeric - */ -int -cmyth_rcv_old_int64(cmyth_conn_t conn, int *err, int64_t *buf, int count) -{ - int64_t val; - int consumed; - int tmp; - unsigned long hi, lo; - - if (!err) { - err = &tmp; - } - - if (count <= 0) { - *err = EINVAL; - return 0; - } - - consumed = cmyth_rcv_u_long(conn, err, &hi, count); - if (*err) { - cmyth_dbg(CMYTH_DBG_ERROR, - "%s: cmyth_rcv_u_long() failed (%d)\n", - __FUNCTION__, consumed); - return consumed; - } - consumed += cmyth_rcv_u_long(conn, err, &lo, count-consumed); - if (*err) { - cmyth_dbg(CMYTH_DBG_ERROR, - "%s: cmyth_rcv_u_long() failed (%d)\n", - __FUNCTION__, consumed); - return consumed; - } - val = (((long long)hi) << 32) | ((long long)(lo & 0xFFFFFFFF)); - - *err = 0; - *buf = val; - - return consumed; -} - -/* - * cmyth_rcv_new_int64(cmyth_conn_t conn, int *err, long long *buf, int count) - * - * Scope: PRIVATE (mapped to __cmyth_rcv_long) - * - * Description - * - * Receive a long long (signed 64 bit) integer token from a list of tokens - * in a MythTV Protocol message. Tokens in MythTV Protocol messages - * are separated by the string: []:[] or terminated by running out of - * message. Up to 'count' Bytes will be consumed from the socket - * specified by 'conn' (stopping when a separator is seen or 'count' - * is exhausted). The long integer value of the token is placed in - * the location pointed to by 'buf'. If an error is encountered and - * 'err' is not NULL, an indication of the nature of the error will be - * recorded by placing an error code in the location pointed to by - * 'err'. If all goes well, 'err' wil be set to 0. - * - * As of protocol version 57, Myth now sends a single 64bit string instead - * of 2 32bit strings when sending proginfo data. This does not seem to - * apply uniformly though. For instance 'ANN FILETRANSFER' still uses - * the old method - * - * Return Value: - * - * A value >=0 indicating the number of bytes consumed. - * - * Error Codes: - * - * In addition to system call error codes, the following errors may be - * placed in 'err': - * - * ERANGE The token received is too large to fit in a long integer - * - * EINVAL The token received is not numeric - */ -int -cmyth_rcv_new_int64(cmyth_conn_t conn, int *err, int64_t *buf, int count, - int forced) -{ - char num[32]; - char *num_p = num; - unsigned long long val = 0; - int sign = 1; - long long limit = 0x7fffffffffffffffLL; - int consumed; - int tmp; - - /* - * Between protocols 57 and 66, not all messages used the new - * format for 64-bit values. - */ - if ((conn->conn_version < 57) || - ((conn->conn_version < 66) && !forced)) { - return cmyth_rcv_old_int64(conn, err, buf, count); - } - - if (!err) { - err = &tmp; - } - if (count <= 0) { - *err = EINVAL; - return 0; - } - *err = 0; - consumed = cmyth_rcv_string(conn, err, num, sizeof(num), count); - if (*err) { - cmyth_dbg(CMYTH_DBG_ERROR, - "%s: cmyth_rcv_string() failed (%d)\n", - __FUNCTION__, consumed); - return consumed; - } - if (*num_p && (*num_p == '-')) { - ++num_p; - sign = -1; - } - while (*num_p) { - if (!isdigit(*num_p)) { - cmyth_dbg(CMYTH_DBG_ERROR, - "%s: received illegal integer: '%s'\n", - __FUNCTION__, num); - *err = EINVAL; - return consumed; - } - val *= 10; - val += ((*num_p) - '0'); - /* - * Check and make sure we are still under the limit (this is - * an absolute value limit, sign will be applied later). - */ - if (val > (unsigned long long)limit) { - cmyth_dbg(CMYTH_DBG_ERROR, - "%s: long long out of range: '%s'\n", - __FUNCTION__, num, limit); - *err = ERANGE; - return consumed; - } - num_p++; - } - - /* - * Got a result, return it. - */ - *buf = (long long)(sign * val); - - return consumed; -} - -/* - * cmyth_rcv_new_uint64(cmyth_conn_t conn, int *err, uint64_t *buf, int count) - * - * Scope: PRIVATE (mapped to __cmyth_rcv_long) - * - * Description - * - * Receive a long long (signed 64 bit) integer token from a list of tokens - * in a MythTV Protocol message. Tokens in MythTV Protocol messages - * are separated by the string: []:[] or terminated by running out of - * message. Up to 'count' Bytes will be consumed from the socket - * specified by 'conn' (stopping when a separator is seen or 'count' - * is exhausted). The long integer value of the token is placed in - * the location pointed to by 'buf'. If an error is encountered and - * 'err' is not NULL, an indication of the nature of the error will be - * recorded by placing an error code in the location pointed to by - * 'err'. If all goes well, 'err' wil be set to 0. - * - * As of protocol version 57, Myth now sends a single 64bit string instead - * of 2 32bit strings when sending proginfo data. This does not seem to - * apply uniformly though. For instance 'ANN FILETRANSFER' still uses - * the old method - * - * Return Value: - * - * A value >=0 indicating the number of bytes consumed. - * - * Error Codes: - * - * In addition to system call error codes, the following errors may be - * placed in 'err': - * - * ERANGE The token received is too large to fit in a long integer - * - * EINVAL The token received is not numeric - */ -int -cmyth_rcv_new_uint64(cmyth_conn_t conn, int *err, uint64_t *buf, int count, - int forced) -{ - char num[32]; - char *num_p = num; - uint64_t val = 0; - int sign = 1; - long long limit = 0x7fffffffffffffffLL; - int consumed; - int tmp; - - /* - * Between protocols 57 and 66, not all messages used the new - * format for 64-bit values. - */ - if ((conn->conn_version < 57) || - ((conn->conn_version < 66) && !forced)) { - return cmyth_rcv_old_uint64(conn, err, buf, count); - } - - if (!err) { - err = &tmp; - } - if (count <= 0) { - *err = EINVAL; - return 0; - } - *err = 0; - consumed = cmyth_rcv_string(conn, err, num, sizeof(num), count); - if (*err) { - cmyth_dbg(CMYTH_DBG_ERROR, - "%s: cmyth_rcv_string() failed (%d)\n", - __FUNCTION__, consumed); - return consumed; - } - if (*num_p && (*num_p == '-')) { - ++num_p; - sign = -1; - } - while (*num_p) { - if (!isdigit(*num_p)) { - cmyth_dbg(CMYTH_DBG_ERROR, - "%s: received illegal integer: '%s'\n", - __FUNCTION__, num); - *err = EINVAL; - return consumed; - } - val *= 10; - val += ((*num_p) - '0'); - /* - * Check and make sure we are still under the limit (this is - * an absolute value limit, sign will be applied later). - */ - if (val > (unsigned long long)limit) { - cmyth_dbg(CMYTH_DBG_ERROR, - "%s: long long out of range: '%s'\n", - __FUNCTION__, num, limit); - *err = ERANGE; - return consumed; - } - num_p++; - } - - /* - * Got a result, return it. - */ - *buf = (long long)(sign * val); - - return consumed; -} - -/* - * cmyth_rcv_ubyte(cmyth_conn_t conn, int *err, unsigned char *buf, int count) - * - * Scope: PRIVATE (mapped to __cmyth_rcv_ubyte) - * - * Description - * - * Receive an unsigned byte (8 bit) integer token from a list of - * tokens in a MythTV Protocol message. Tokens in MythTV Protocol - * messages are separated by the string: []:[] or terminated by - * running out of message. Up to 'count' Bytes will be consumed from - * the socket specified by 'conn' (stopping when a separator is seen - * or 'count' is exhausted). The unsigned byte integer value of the - * token is placed in the location pointed to by 'buf'. If an error - * is encountered and 'err' is not NULL, an indication of the nature - * of the error will be recorded by placing an error code in the - * location pointed to by 'err'. If all goes well, 'err' wil be set - * to 0. - * - * Return Value: - * - * A value >=0 indicating the number of bytes consumed. - * - * Error Codes: - * - * In addition to system call error codes, the following errors may be - * placed in 'err': - * - * ERANGE The token received is too large to fit in an - # unsigned byte integer - * - * EINVAL The token received is not numeric or is signed - */ -int -cmyth_rcv_ubyte(cmyth_conn_t conn, int *err, unsigned char *buf, int count) -{ - unsigned long val; - int consumed; - int tmp; - - if (!err) { - err = &tmp; - } - if (count <= 0) { - *err = EINVAL; - return 0; - } - consumed = cmyth_rcv_ulong(conn, err, &val, count); - if (*err) { - cmyth_dbg(CMYTH_DBG_ERROR, - "%s: cmyth_rcv_ulong() failed (%d)\n", - __FUNCTION__, consumed); - return consumed; - } - if (val > 255) { - cmyth_dbg(CMYTH_DBG_ERROR, "%s: value doesn't fit: '%llu'\n", - __FUNCTION__, val); - *err = ERANGE; - return consumed; - } - *err = 0; - *buf = (unsigned char)val; - return consumed; -} - -/* - * cmyth_rcv_ushort(cmyth_conn_t conn, int *err, unsigned short *buf, - * int count) - * - * Scope: PRIVATE (mapped to __cmyth_rcv_ushort) - * - * Description - * - * Receive an unsigned short (16 bit) integer token from a list of - * tokens in a MythTV Protocol message. Tokens in MythTV Protocol - * messages are separated by the string: []:[] or terminated by - * running out of message. Up to 'count' Bytes will be consumed from - * the socket specified by 'conn' (stopping when a separator is seen - * or 'count' is exhausted). The unsigned short integer value of the - * token is placed in the location pointed to by 'buf'. If an error - * is encountered and 'err' is not NULL, an indication of the nature - * of the error will be recorded by placing an error code in the - * location pointed to by 'err'. If all goes well, 'err' wil be set - * to 0. - * - * Return Value: - * - * A value >=0 indicating the number of bytes consumed. - * - * Error Codes: - * - * In addition to system call error codes, the following errors may be - * placed in 'err': - * - * ERANGE The token received is too large to fit in an - * unsinged short integer - * - * EINVAL The token received is not numeric or is signed - */ -int -cmyth_rcv_ushort(cmyth_conn_t conn, int *err, unsigned short *buf, int count) -{ - unsigned long val; - int consumed; - int tmp; - - if (!err) { - err = &tmp; - } - if (count <= 0) { - *err = EINVAL; - return 0; - } - consumed = cmyth_rcv_ulong(conn, err, &val, count); - if (*err) { - cmyth_dbg(CMYTH_DBG_ERROR, - "%s: cmyth_rcv_ulong() failed (%d)\n", - __FUNCTION__, consumed); - return consumed; - } - if (val > 65535) { - cmyth_dbg(CMYTH_DBG_ERROR, "%s: value doesn't fit: '%llu'\n", - __FUNCTION__, val); - *err = ERANGE; - return consumed; - } - *err = 0; - *buf = (unsigned short)val; - return consumed; -} - -/* - * cmyth_rcv_ulong(cmyth_conn_t conn, int *err, unsigned long *buf, int count) - * - * Scope: PRIVATE (mapped to __cmyth_rcv_ulong) - * - * Description - * - * Receive an unsigned long (32 bit) integer token from a list of - * tokens in a MythTV Protocol message. Tokens in MythTV Protocol - * messages are separated by the string: []:[] or terminated by - * running out of message. Up to 'count' Bytes will be consumed from - * the socket specified by 'conn' (stopping when a separator is seen - * or 'count' is exhausted). The unsigned long integer value of the - * token is placed in the location pointed to by 'buf'. If an error - * is encountered and 'err' is not NULL, an indication of the nature - * of the error will be recorded by placing an error code in the - * location pointed to by 'err'. If all goes well, 'err' wil be set - * to 0. - * - * Return Value: - * - * A value >=0 indicating the number of bytes consumed. - * - * Error Codes: - * - * In addition to system call error codes, the following errors may be - * placed in 'err': - * - * ERANGE The token received is too large to fit in an unsigned - * long integer - * - * EINVAL The token received is not numeric or is signed - */ -int -cmyth_rcv_old_uint64(cmyth_conn_t conn, int *err, uint64_t *buf, int count) -{ - unsigned long long val; - unsigned long hi, lo; - int consumed; - int tmp; - - *buf = 0; - - if (!err) { - err = &tmp; - } - - if (count <= 0) { - *err = EINVAL; - return 0; - } - - consumed = cmyth_rcv_u_long(conn, err, &hi, count); - if (*err) { - cmyth_dbg(CMYTH_DBG_ERROR, - "%s: cmyth_rcv_u_long() failed (%d)\n", - __FUNCTION__, consumed); - return consumed; - } - consumed += cmyth_rcv_u_long(conn, err, &lo, count - consumed); - if (*err) { - cmyth_dbg(CMYTH_DBG_ERROR, - "%s: cmyth_rcv_u_long() failed (%d)\n", - __FUNCTION__, consumed); - return consumed; - } - val = (((unsigned long long)hi) << 32) | ((unsigned long long)(lo & 0xFFFFFFFF)); - - *err = 0; - *buf = val; - - return consumed; -} - -/* - * cmyth_rcv_timestamp(cmyth_conn_t conn, int *err, cmyth_timestamp_t buf, - * int count) - * - * Scope: PRIVATE (mapped to __cmyth_rcv_timestamp) - * - * Description - * - * Receive a timestamp in international format from a list of - * tokens in a MythTV Protocol message. A time stamp is formatted - * as follows: - * - * <YYYY>-<MM>-<DD>T<HH>:<MM>:<SS> - * - * Tokens in MythTV Protocol messages are separated by the string: - * []:[] or terminated by running out of message. Up to 'count' Bytes - * will be consumed from the socket specified by 'conn' (stopping when - * a separator is seen or 'count' is exhausted). The timestamp - * structure specified in 'buf' will be filled out. If an error is - * encountered and 'err' is not NULL, an indication of the nature of - * the error will be recorded by placing an error code in the location - * pointed to by 'err'. If all goes well, 'err' wil be set to 0. - * - * Return Value: - * - * A value >=0 indicating the number of bytes consumed. - * - * Error Codes: - * - * In addition to system call error codes, the following errors may be - * placed in 'err': - * - * ERANGE The token received did not parse into a timestamp - * - * EINVAL The token received is not numeric or is signed - */ -int -cmyth_rcv_timestamp(cmyth_conn_t conn, int *err, cmyth_timestamp_t *ts, - int count) -{ - int consumed; - char tbuf[CMYTH_TIMESTAMP_LEN + 1]; - int tmp; - - if (!err) { - err = &tmp; - } - if (count <= 0) { - *err = EINVAL; - return 0; - } - *err = 0; - tbuf[CMYTH_TIMESTAMP_LEN] = '\0'; - consumed = cmyth_rcv_string(conn, err, tbuf, - CMYTH_TIMESTAMP_LEN, count); - if (*err) { - cmyth_dbg(CMYTH_DBG_ERROR, - "%s: cmyth_rcv_string() failed (%d)\n", - __FUNCTION__, *err); - return consumed; - } - - /* - * Allow for the timestamp to be empty in the case of livetv - */ - if ((strlen(tbuf) == 1) && (tbuf[0] = ' ')) - return consumed; - - if (strlen(tbuf) == 0) - return consumed; - - if (*ts) - ref_release(*ts); - - *ts = cmyth_timestamp_from_string(tbuf); - if (*ts == NULL) { - cmyth_dbg(CMYTH_DBG_ERROR, - "%s: cmyth_timestamp_from_string() failed\n", - __FUNCTION__); - *err = -EINVAL; - } - return consumed; -} - - -/* - * cmyth_rcv_datetime(cmyth_conn_t conn, int *err, cmyth_timestamp_t buf, - * int count) - * - * Scope: PRIVATE (mapped to __cmyth_rcv_datetime) - * - * Description - * - * Receive a datetime as an unsigned integer -- number of seconds - * since Jan 1, 1970. - * - * Tokens in MythTV Protocol messages are separated by the string: - * []:[] or terminated by running out of message. Up to 'count' Bytes - * will be consumed from the socket specified by 'conn' (stopping when - * a separator is seen or 'count' is exhausted). The timestamp - * structure specified in 'buf' will be filled out. If an error is - * encountered and 'err' is not NULL, an indication of the nature of - * the error will be recorded by placing an error code in the location - * pointed to by 'err'. If all goes well, 'err' wil be set to 0. - * - * Return Value: - * - * A value >=0 indicating the number of bytes consumed. - * - * Error Codes: - * - * In addition to system call error codes, the following errors may be - * placed in 'err': - * - * ERANGE The token received did not parse into a datetime - * - * EINVAL The token received is not numeric or is signed - */ -int -cmyth_rcv_datetime(cmyth_conn_t conn, int *err, cmyth_timestamp_t *ts, - int count) -{ - int consumed; - char tbuf[CMYTH_LONG_LEN + 1]; - int tmp; - - if (!err) { - err = &tmp; - } - if (count <= 0) { - *err = EINVAL; - return 0; - } - *err = 0; - tbuf[CMYTH_LONG_LEN] = '\0'; - consumed = cmyth_rcv_string(conn, err, tbuf, CMYTH_LONG_LEN, count); - if (*err) { - cmyth_dbg(CMYTH_DBG_ERROR, - "%s: cmyth_rcv_string() failed (%d)\n", - __FUNCTION__, *err); - return consumed; - } - if (*ts) - ref_release(*ts); - *ts = cmyth_timestamp_from_unixtime((time_t)atoi(tbuf)); - if (*ts == NULL) { - cmyth_dbg(CMYTH_DBG_ERROR, - "%s: cmyth_datetime_from_string() failed\n", - __FUNCTION__); - *err = -EINVAL; - } - return consumed; -} - -static void -cmyth_proginfo_parse_url(cmyth_proginfo_t p) -{ - static const char service[]="myth://"; - char *host = NULL; - char *port = NULL; - char *path = NULL; - - if (!p || ! p->proginfo_url || - (!strcmp(p->proginfo_url, "none")) || - (!strcmp(p->proginfo_url, " "))) { - cmyth_dbg(CMYTH_DBG_ERROR, - "%s: proginfo or url was NULL, p = %p, url = %p\n", - __FUNCTION__, p, p ? p->proginfo_url : NULL); - return; - } - cmyth_dbg(CMYTH_DBG_DEBUG, "%s: url is: '%s'\n", - __FUNCTION__, p->proginfo_url); - path = p->proginfo_url; - if (strncmp(p->proginfo_url, service, sizeof(service) - 1) == 0) { - /* - * The URL starts with myth://. The rest looks like - * <host>:<port>/<filename>. - */ - host = p->proginfo_url + strlen(service); - port = strchr(host, ':'); - if (!port) { - /* - * This does not seem to be a proper URL, so - * just assume it is a filename, and get out. - */ - goto out; - } - port = port + 1; - path = strchr(port, '/'); - if (!path) { - /* - * This does not seem to be a proper URL, so - * just assume it is a filename, and get out. - */ - goto out; - } - } - - out: - if (host && port && path) { - char tmp = *(port - 1); - *(port - 1) = '\0'; - if (p->proginfo_host) - ref_release(p->proginfo_host); - p->proginfo_host = ref_strdup(host); - *(port - 1) = tmp; - tmp = *(path); - *(path) = '\0'; - p->proginfo_port = atoi(port); - *(path) = tmp; - } else { - if (p->proginfo_host) - ref_release(p->proginfo_host); - p->proginfo_host = ref_strdup(p->proginfo_hostname); - p->proginfo_port = 6543; - } - if (p->proginfo_pathname) - ref_release(p->proginfo_pathname); - p->proginfo_pathname = ref_strdup(path); -} - -/* - * cmyth_rcv_proginfo(cmyth_conn_t conn, cmyth_proginfo_t buf, int count) - * - * Scope: PRIVATE (mapped to __cmyth_rcv_proginfo) - * - * Description - * - * Receive a program information structure from a list of tokens in a - * MythTV Protocol message. Tokens in MythTV Protocol messages are - * separated by the string: []:[] or terminated by running out of - * message. Up to 'count' Bytes will be consumed from the socket - * specified by 'conn' (stopping when a separator is seen or 'count' - * is exhausted). The proginfo structure specified in 'buf' will be - * filled out. If an error is encountered and 'err' is not NULL, an - * indication of the nature of the error will be recorded by placing - * an error code in the location pointed to by 'err'. If all goes - * well, 'err' wil be set to 0. - * - * Return Value: - * - * A value >=0 indicating the number of bytes consumed. - * - * Error Codes: - * - * In addition to system call error codes, the following errors may be - * placed in 'err': - * - * ERANGE The token received did not parse into a program - * information structure - * - * EINVAL The token received is not numeric or is signed - */ -int -cmyth_rcv_proginfo(cmyth_conn_t conn, int *err, cmyth_proginfo_t buf, - int count) -{ - int consumed; - int total = 0; - char *failed = NULL; - char tmp_str[32768]; - - if (count <= 0) { - *err = EINVAL; - return 0; - } - - tmp_str[sizeof(tmp_str) - 1] = '\0'; - - buf->proginfo_version = conn->conn_version; - cmyth_dbg(CMYTH_DBG_DEBUG, "%s: VERSION IS %ld\n", - __FUNCTION__, buf->proginfo_version); - - /* - * Get proginfo_title (string) - */ - consumed = cmyth_rcv_string(conn, err, - tmp_str, sizeof(tmp_str) - 1, count); - count -= consumed; - total += consumed; - if (*err) { - failed = "cmyth_rcv_string"; - goto fail; - } - if (buf->proginfo_title) - ref_release(buf->proginfo_title); - buf->proginfo_title = ref_strdup(tmp_str); - - /* - * Get proginfo_subtitle (string) - */ - consumed = cmyth_rcv_string(conn, err, - tmp_str, sizeof(tmp_str) - 1, count); - count -= consumed; - total += consumed; - if (*err) { - failed = "cmyth_rcv_string"; - goto fail; - } - if (buf->proginfo_subtitle) - ref_release(buf->proginfo_subtitle); - buf->proginfo_subtitle = ref_strdup(tmp_str); - - /* - * Get proginfo_description (string) - */ - consumed = cmyth_rcv_string(conn, err, - tmp_str, sizeof(tmp_str) - 1, count); - count -= consumed; - total += consumed; - if (*err) { - failed = "cmyth_rcv_string"; - goto fail; - } - if (buf->proginfo_description) - ref_release(buf->proginfo_description); - buf->proginfo_description = ref_strdup(tmp_str); - - if (buf->proginfo_version >= 67) { - /* - * Get season and episode (unsigned int) - */ - consumed = cmyth_rcv_ushort(conn, err, - &buf->proginfo_season, count); - count -= consumed; - total += consumed; - if (*err) { - failed = "cmyth_rcv_ushort"; - goto fail; - } - - consumed = cmyth_rcv_ushort(conn, err, - &buf->proginfo_episode, count); - count -= consumed; - total += consumed; - if (*err) { - failed = "cmyth_rcv_ushort"; - goto fail; - } - } - - /* - * Get proginfo_category (string) - */ - consumed = cmyth_rcv_string(conn, err, - tmp_str, sizeof(tmp_str) - 1, count); - count -= consumed; - total += consumed; - if (*err) { - failed = "cmyth_rcv_string"; - goto fail; - } - if (buf->proginfo_category) - ref_release(buf->proginfo_category); - buf->proginfo_category = ref_strdup(tmp_str); - - /* - * Get proginfo_chanId (long) - */ - consumed = cmyth_rcv_string(conn, err, - tmp_str, sizeof(tmp_str) - 1, count); - count -= consumed; - total += consumed; - if (*err) { - failed = "cmyth_rcv_long"; - goto fail; - } - buf->proginfo_chanId = atoi(tmp_str); - - /* - * Get proginfo_chanstr (string) - */ - consumed = cmyth_rcv_string(conn, err, - tmp_str, sizeof(tmp_str) - 1, count); - count -= consumed; - total += consumed; - if (*err) { - failed = "cmyth_rcv_string"; - goto fail; - } - if (buf->proginfo_chanstr) - ref_release(buf->proginfo_chanstr); - buf->proginfo_chanstr = ref_strdup(tmp_str); - - /* - * Get proginfo_chansign (string) - */ - consumed = cmyth_rcv_string(conn, err, - tmp_str, sizeof(tmp_str) - 1, count); - count -= consumed; - total += consumed; - if (*err) { - failed = "cmyth_rcv_string"; - goto fail; - } - if (buf->proginfo_chansign) - ref_release(buf->proginfo_chansign); - buf->proginfo_chansign = ref_strdup(tmp_str); - - /* - * Get proginfo_channame (string) Version 1 or proginfo_chanicon - * (string) Version 8. - */ - consumed = cmyth_rcv_string(conn, err, - tmp_str, sizeof(tmp_str) - 1, count); - count -= consumed; - total += consumed; - if (*err) { - failed = "cmyth_rcv_string"; - goto fail; - } - /* FIXME: doesn't seem to match the dump? */ - cmyth_dbg(CMYTH_DBG_DEBUG, "%s: GOT TO ICON/NAME\n", __FUNCTION__); - if (buf->proginfo_chanicon) - ref_release(buf->proginfo_chanicon); - if (buf->proginfo_channame) - ref_release(buf->proginfo_channame); - if (buf->proginfo_version >= 8) { - buf->proginfo_chanicon = ref_strdup(tmp_str); - /* - * Simulate a channel name (Number and Callsign) for - * compatibility. - */ - sprintf(tmp_str, - "%s %s", buf->proginfo_chanstr, - buf->proginfo_chansign); - buf->proginfo_channame = ref_strdup(tmp_str); - } else { /* Assume version 1 */ - buf->proginfo_channame = ref_strdup(tmp_str); - buf->proginfo_chanicon = ref_strdup(""); - } - - /* - * Get proginfo_url (string) - */ - consumed = cmyth_rcv_string(conn, err, - tmp_str, sizeof(tmp_str) - 1, count); - count -= consumed; - total += consumed; - if (*err) { - failed = "cmyth_rcv_string"; - goto fail; - } - if (buf->proginfo_url) - ref_release(buf->proginfo_url); - buf->proginfo_url = ref_strdup(tmp_str); - - /* - * Get proginfo_Length (long_long) - */ - if (buf->proginfo_version < 57) { - consumed = cmyth_rcv_old_int64(conn, err, &buf->proginfo_Length, - count); - } else { - /* - * Since protocol 57 mythbackend now sends a single 64 bit - * integer rather than two 32 bit hi and lo integers for the - * proginfo length. - */ - consumed = cmyth_rcv_new_int64(conn, err, &buf->proginfo_Length, - count, 1); - } - count -= consumed; - total += consumed; - if (*err) { - failed = "rcv_64"; - goto fail; - } - - /* - * Get proginfo_start_ts (timestamp) - */ - cmyth_dbg(CMYTH_DBG_DEBUG, "%s: GOT TO START_TS\n", __FUNCTION__); - if (buf->proginfo_version >= 14) { - consumed = cmyth_rcv_datetime(conn, err, - &(buf->proginfo_start_ts), - count); - } - else { - consumed = cmyth_rcv_timestamp(conn, err, - &(buf->proginfo_start_ts), - count); - } - count -= consumed; - total += consumed; - if (*err) { - failed = "proginfo_start_ts cmyth_rcv"; - goto fail; - } - - /* - * Get proginfo_end_ts (timestamp) - */ - cmyth_dbg(CMYTH_DBG_DEBUG, "%s: GOT TO END_TS\n", __FUNCTION__); - if (buf->proginfo_version >= 14) { - consumed = cmyth_rcv_datetime(conn, err, - &(buf->proginfo_end_ts), count); - } - else { - consumed = cmyth_rcv_timestamp(conn, err, - &(buf->proginfo_end_ts), count); - } - count -= consumed; - total += consumed; - if (*err) { - failed = "cmyth_rcv_timestamp"; - goto fail; - } - - if (buf->proginfo_version < 57) { - /* - * Get proginfo_conflicting (ulong in Version 1, string in Version 8) - */ - if (buf->proginfo_version >= 8) { - consumed = cmyth_rcv_string(conn, err, - tmp_str, sizeof(tmp_str) - 1, - count); - count -= consumed; - total += consumed; - if (*err) { - failed = "cmyth_rcv_string"; - goto fail; - } - if (buf->proginfo_unknown_0) - ref_release(buf->proginfo_unknown_0); - buf->proginfo_unknown_0 = ref_strdup(tmp_str); - } else { /* Assume version 1 */ - consumed = cmyth_rcv_ulong(conn, err, - &buf->proginfo_conflicting, count); - count -= consumed; - total += consumed; - if (*err) { - failed = "cmyth_rcv_ulong"; - goto fail; - } - } - - /* - * Get proginfo_recording (ulong) - */ - consumed = cmyth_rcv_ulong(conn, err, &buf->proginfo_recording, count); - count -= consumed; - total += consumed; - if (*err) { - failed = "cmyth_rcv_ulong"; - goto fail; - } - } - - /* - * Get proginfo_override (ulong) - */ - consumed = cmyth_rcv_ulong(conn, err, &buf->proginfo_override, count); - count -= consumed; - total += consumed; - if (*err) { - failed = "cmyth_rcv_ulong"; - goto fail; - } - - /* - * Get proginfo_hostname (string) - */ - consumed = cmyth_rcv_string(conn, err, - tmp_str, sizeof(tmp_str) - 1, count); - count -= consumed; - total += consumed; - if (*err) { - failed = "cmyth_rcv_string"; - goto fail; - } - if (buf->proginfo_hostname) - ref_release(buf->proginfo_hostname); - buf->proginfo_hostname = ref_strdup(tmp_str); - - /* - * Get proginfo_source_id (long) - */ - consumed = cmyth_rcv_long(conn, err, &buf->proginfo_source_id, count); - count -= consumed; - total += consumed; - if (*err) { - failed = "cmyth_rcv_ulong"; - goto fail; - } - - /* - * Get proginfo_card_id (long) - */ - consumed = cmyth_rcv_long(conn, err, &buf->proginfo_card_id, count); - count -= consumed; - total += consumed; - if (*err) { - failed = "cmyth_rcv_ulong"; - goto fail; - } - - /* - * Get proginfo_input_id (long) - */ - consumed = cmyth_rcv_long(conn, err, &buf->proginfo_input_id, count); - count -= consumed; - total += consumed; - if (*err) { - failed = "cmyth_rcv_ulong"; - goto fail; - } - - /* - * Get proginfo_rec_priority (long) - */ - consumed = cmyth_rcv_string(conn, err, - tmp_str, sizeof(tmp_str) - 1, count); - count -= consumed; - total += consumed; - if (*err) { - failed = "cmyth_rcv_string"; - goto fail; - } - if (buf->proginfo_rec_priority) - ref_release(buf->proginfo_rec_priority); - buf->proginfo_rec_priority = ref_strdup(tmp_str); - - /* - * Get proginfo_rec_status (ulong) - */ - consumed = cmyth_rcv_long(conn, err, &buf->proginfo_rec_status, count); - count -= consumed; - total += consumed; - if (*err) { - failed = "cmyth_rcv_ulong"; - goto fail; - } - - /* - * Get proginfo_record_id (ulong) - */ - consumed = cmyth_rcv_ulong(conn, err, &buf->proginfo_record_id, count); - count -= consumed; - total += consumed; - if (*err) { - failed = "cmyth_rcv_ulong"; - goto fail; - } - - /* - * Get proginfo_rec_type (ulong) - */ - consumed = cmyth_rcv_ulong(conn, err, &buf->proginfo_rec_type, count); - count -= consumed; - total += consumed; - if (*err) { - failed = "cmyth_rcv_ulong"; - goto fail; - } - - /* - * Get proginfo_rec_dups (ulong) - */ - consumed = cmyth_rcv_ulong(conn, err, &buf->proginfo_rec_dups, count); - count -= consumed; - total += consumed; - if (*err) { - failed = "cmyth_rcv_ulong"; - goto fail; - } - - if (buf->proginfo_version >= 8) { - /* - * Get proginfo_unknown_1 (long) - */ - consumed = cmyth_rcv_ulong(conn, err, - &buf->proginfo_unknown_1, count); - count -= consumed; - total += consumed; - if (*err) { - failed = "cmyth_rcv_ulong"; - goto fail; - } - } - - /* - * Get proginfo_rec_start_ts (timestamp) - */ - if (buf->proginfo_version >= 14) { - consumed = cmyth_rcv_datetime(conn, err, - &(buf->proginfo_rec_start_ts), - count); - } - else { - consumed = cmyth_rcv_timestamp(conn, err, - &(buf->proginfo_rec_start_ts), - count); - } - - count -= consumed; - total += consumed; - if (*err) { - failed = "cmyth_rcv_timestamp"; - goto fail; - } - - /* - * Get proginfo_rec_end_ts (timestamp) - */ - if (buf->proginfo_version >= 14) { - consumed = cmyth_rcv_datetime(conn, err, - &(buf->proginfo_rec_end_ts), - count); - } - else { - consumed = cmyth_rcv_timestamp(conn, err, - &(buf->proginfo_rec_end_ts), - count); - } - - count -= consumed; - total += consumed; - if (*err) { - failed = "cmyth_rcv_timestamp"; - goto fail; - } - - if (buf->proginfo_version < 57) { - /* - * Get proginfo_repeat (ulong) - */ - consumed = cmyth_rcv_ulong(conn, err, &buf->proginfo_repeat, count); - count -= consumed; - total += consumed; - if (*err) { - failed = "cmyth_rcv_ulong"; - goto fail; - } - } - - /* - * Get proginfo_program_flags (long) - */ - consumed = cmyth_rcv_ulong(conn, err, &buf->proginfo_program_flags, - count); - count -= consumed; - total += consumed; - if (*err) { - failed = "cmyth_rcv_ulong"; - goto fail; - } - - if (buf->proginfo_version >= 8) { - /* - * Get proginfo_recgroup (string) - */ - consumed = cmyth_rcv_string(conn, err, - tmp_str, sizeof(tmp_str) - 1, - count); - count -= consumed; - total += consumed; - if (*err) { - failed = "cmyth_rcv_string"; - goto fail; - } - if (buf->proginfo_recgroup) - ref_release(buf->proginfo_recgroup); - buf->proginfo_recgroup = ref_strdup(tmp_str); - } - - if (buf->proginfo_version >= 8 && buf->proginfo_version < 57) { - /* - * Get proginfo_chancommfree (string) - */ - consumed = cmyth_rcv_string(conn, err, - tmp_str, sizeof(tmp_str) - 1, - count); - count -= consumed; - total += consumed; - if (*err) { - failed = "cmyth_rcv_string"; - goto fail; - } - if (buf->proginfo_chancommfree) - ref_release(buf->proginfo_chancommfree); - buf->proginfo_chancommfree = ref_strdup(tmp_str); - } - - if (buf->proginfo_version >= 8) { - /* - * Get proginfo_chan_output_filters (string) - */ - consumed = cmyth_rcv_string(conn, err, - tmp_str, sizeof(tmp_str) - 1, - count); - count -= consumed; - total += consumed; - if (*err) { - failed = "cmyth_rcv_string"; - goto fail; - } - if (buf->proginfo_chan_output_filters) - ref_release(buf->proginfo_chan_output_filters); - buf->proginfo_chan_output_filters = ref_strdup(tmp_str); - } - - if (buf->proginfo_version >= 8) { - /* - * Get proginfo_seriesid (string) - */ - consumed = cmyth_rcv_string(conn, err, - tmp_str, sizeof(tmp_str) - 1, - count); - count -= consumed; - total += consumed; - if (*err) { - failed = "cmyth_rcv_string"; - goto fail; - } - if (buf->proginfo_seriesid) - ref_release(buf->proginfo_seriesid); - buf->proginfo_seriesid = ref_strdup(tmp_str); - } - - if (buf->proginfo_version >= 8) { - /* - * Get programid (string) - */ - consumed = cmyth_rcv_string(conn, err, tmp_str, - sizeof(tmp_str) - 1, count); - count -= consumed; - total += consumed; - if (*err) { - failed = "cmyth_rcv_string"; - goto fail; - } - if (buf->proginfo_programid) - ref_release(buf->proginfo_programid); - buf->proginfo_programid = ref_strdup(tmp_str); - } - - if (buf->proginfo_version >= 67) { - /* - * Get inetref (string) - */ - consumed = cmyth_rcv_string(conn, err, tmp_str, - sizeof(tmp_str) - 1, count); - count -= consumed; - total += consumed; - if (*err) { - failed = "cmyth_rcv_string"; - goto fail; - } - if (buf->proginfo_inetref) - ref_release(buf->proginfo_inetref); - buf->proginfo_inetref = ref_strdup(tmp_str); - } - - if (buf->proginfo_version >= 12) { - /* - * Get lastmodified (string) - */ - if (buf->proginfo_version >= 14) { - consumed = - cmyth_rcv_datetime(conn, err, - &(buf->proginfo_lastmodified), - count); - } - else { - consumed = - cmyth_rcv_timestamp(conn, err, - &(buf->proginfo_lastmodified), - count); - } - count -= consumed; - total += consumed; - if (*err) { - failed = "cmyth_rcv_timestamp"; - goto fail; - } - } - - if (buf->proginfo_version >= 12) { - char stars[16]; - - /* - * Get stars (string) - */ - consumed = cmyth_rcv_string(conn, err, tmp_str, - sizeof(tmp_str) - 1, count); - count -= consumed; - total += consumed; - if (*err) { - failed = "cmyth_rcv_string"; - goto fail; - } - if (buf->proginfo_stars) - ref_release(buf->proginfo_stars); - snprintf(stars, sizeof(stars), "%3.1f", atof(tmp_str) * 4.0); - buf->proginfo_stars = ref_strdup(stars); - } - - if (buf->proginfo_version >= 12) { - /* - * Get original_air_date (string) - */ - if ((buf->proginfo_version >= 14) & (buf->proginfo_version <=32)) { - consumed = - cmyth_rcv_datetime(conn, err, - &(buf->proginfo_originalairdate), - count); - } - else { - consumed = - cmyth_rcv_timestamp(conn, err, - &(buf->proginfo_originalairdate), - count); - } - count -= consumed; - total += consumed; - if (*err) { - failed = "cmyth_rcv_string"; - goto fail; - } - } - - if (buf->proginfo_version >= 15 && buf->proginfo_version < 57) { - consumed = cmyth_rcv_ulong(conn, err, - &buf->proginfo_hasairdate, count); - count -= consumed; - total += consumed; - if (*err) { - failed = "cmyth_rcv_ulong"; - goto fail; - } - } - - if (buf->proginfo_version >= 18) { - /* - * Get playgroup (string) - */ - consumed = cmyth_rcv_string(conn, err, tmp_str, - sizeof(tmp_str) - 1, count); - count -= consumed; - total += consumed; - if (*err) { - failed = "cmyth_rcv_string"; - goto fail; - } - if (buf->proginfo_playgroup) - ref_release(buf->proginfo_playgroup); - buf->proginfo_playgroup = ref_strdup(tmp_str); - } - if (buf->proginfo_version >= 25) { - /* - * Get proginfo_recpriority_2 (string) - */ - consumed = cmyth_rcv_string(conn, err, - tmp_str, sizeof(tmp_str) - 1, - count); - count -= consumed; - total += consumed; - if (*err) { - failed = "cmyth_rcv_string"; - goto fail; - } - if (buf->proginfo_recpriority_2) - ref_release(buf->proginfo_recpriority_2); - buf->proginfo_recpriority_2 = ref_strdup(tmp_str); - } - if (buf->proginfo_version >= 31) { - /* - * Get proginfo_parentid (long) - */ - consumed = cmyth_rcv_long(conn, err, - &buf->proginfo_parentid, count); - count -= consumed; - total += consumed; - if (*err) { - failed = "cmyth_rcv_long"; - goto fail; - } - } - if (buf->proginfo_version >= 32) { - /* - * Get storagegroup (string) - */ - consumed = cmyth_rcv_string(conn, err, tmp_str, - sizeof(tmp_str) - 1, count); - count -= consumed; - total += consumed; - if (*err) { - failed = "cmyth_rcv_string"; - goto fail; - } - if (buf->proginfo_storagegroup) - ref_release(buf->proginfo_storagegroup); - buf->proginfo_storagegroup = ref_strdup(tmp_str); - } - if (buf->proginfo_version >= 35) { - /* - * Get audioproperties,videoproperties,subtitletype (int) - */ - consumed = cmyth_rcv_ulong(conn, err, - &buf->proginfo_audioproperties, count); - count -= consumed; - total += consumed; - if (*err) { - failed = "cmyth_rcv_ulong audio"; - goto fail; - } - consumed = cmyth_rcv_ulong(conn, err, - &buf->proginfo_videoproperties, count); - count -= consumed; - total += consumed; - if (*err) { - failed = "cmyth_rcv_ulong video"; - goto fail; - } - consumed = cmyth_rcv_ulong(conn, err, - &buf->proginfo_subtitletype, count); - count -= consumed; - total += consumed; - if (*err) { - failed = "cmyth_rcv_ulong subtitletype"; - goto fail; - } - } - - /* - * Get Year - */ - if (buf->proginfo_version >= 43) { - consumed = cmyth_rcv_ushort(conn, err, &buf->proginfo_year, - count); - count -= consumed; - total += consumed; - if (*err) { - failed = "cmyth_rcv_ushort proginfo_year"; - goto fail; - } - } - - cmyth_dbg(CMYTH_DBG_INFO, "%s: got recording info\n", __FUNCTION__); - - cmyth_proginfo_parse_url(buf); - return total; - - fail: - cmyth_dbg(CMYTH_DBG_ERROR, "%s: %s() failed (%d) (count = %d)\n", - __FUNCTION__, failed, *err, count); - return total; -} - -/* - * cmyth_rcv_chaninfo(cmyth_conn_t conn, cmyth_proginfo_t buf, int count) - * - * Scope: PRIVATE (mapped to __cmyth_rcv_chaninfo) - * - * Description - * - * Receive a program information structure containing channel - * information from a list of tokens in a MythTV Protocol message. - * Channel information is a subset of program information containing - * only the title, episode name (subtitle), description, category, - * start and end timestamps, callsign, icon path (a pathname to the - * channel icon found in filename), channel name, and channel id. - * This is the information returned for each program in a program - * guide when browsing on a recorder. - * - * Tokens in MythTV Protocol messages are separated by the string: - * []:[] or terminated by running out of message. Up to 'count' Bytes - * will be consumed from the socket specified by 'conn' (stopping when - * a separator is seen or 'count' is exhausted). The proginfo - * structure specified in 'buf' will be filled out. If an error is - * encountered and 'err' is not NULL, an indication of the nature of - * the error will be recorded by placing an error code in the location - * pointed to by 'err'. If all goes well, 'err' wil be set to 0. - * - * Return Value: - * - * A value >=0 indicating the number of bytes consumed. - * - * Error Codes: - * - * In addition to system call error codes, the following errors may be - * placed in 'err': - * - * ERANGE The token received did not parse into a channel - * information structure - * - * EINVAL The token received is not numeric or is signed - */ -int -cmyth_rcv_chaninfo(cmyth_conn_t conn, int *err, cmyth_proginfo_t buf, - int count) -{ - int consumed; - int total = 0; - char *failed = NULL; - char tmp_str[32768]; - - if (count <= 0) { - *err = EINVAL; - return 0; - } - - tmp_str[sizeof(tmp_str) - 1] = '\0'; - - /* - * Get proginfo_title (string) - */ - consumed = cmyth_rcv_string(conn, err, - tmp_str, sizeof(tmp_str) - 1, count); - count -= consumed; - total += consumed; - if (*err) { - failed = "cmyth_rcv_string"; - goto fail; - } - if (buf->proginfo_title) - ref_release(buf->proginfo_title); - buf->proginfo_title = ref_strdup(tmp_str); - - /* - * Get proginfo_subtitle (string) - */ - consumed = cmyth_rcv_string(conn, err, - tmp_str, sizeof(tmp_str) - 1, count); - count -= consumed; - total += consumed; - if (*err) { - failed = "cmyth_rcv_string"; - goto fail; - } - if (buf->proginfo_subtitle) - ref_release(buf->proginfo_subtitle); - buf->proginfo_subtitle = ref_strdup(tmp_str); - - /* - * Get proginfo_description (string) - */ - consumed = cmyth_rcv_string(conn, err, - tmp_str, sizeof(tmp_str) - 1, count); - count -= consumed; - total += consumed; - if (*err) { - failed = "cmyth_rcv_string"; - goto fail; - } - if (buf->proginfo_description) - ref_release(buf->proginfo_description); - buf->proginfo_description = ref_strdup(tmp_str); - - /* - * Get proginfo_category (string) - */ - consumed = cmyth_rcv_string(conn, err, - tmp_str, sizeof(tmp_str) - 1, count); - count -= consumed; - total += consumed; - if (*err) { - failed = "cmyth_rcv_string"; - goto fail; - } - if (buf->proginfo_category) - ref_release(buf->proginfo_category); - buf->proginfo_category = ref_strdup(tmp_str); - - /* - * Get proginfo_start_ts (timestamp) - */ - consumed = cmyth_rcv_timestamp(conn, err, - &(buf->proginfo_start_ts), count); - count -= consumed; - total += consumed; - if (*err) { - failed = "cmyth_rcv_timestamp"; - goto fail; - } - - /* - * Get proginfo_end_ts (timestamp) - */ - consumed = cmyth_rcv_timestamp(conn, err, &(buf->proginfo_end_ts), - count); - count -= consumed; - total += consumed; - if (*err) { - failed = "cmyth_rcv_timestamp"; - goto fail; - } - - /* - * Get proginfo_chansign (string) - */ - consumed = cmyth_rcv_string(conn, err, - tmp_str, sizeof(tmp_str) - 1, count); - count -= consumed; - total += consumed; - if (*err) { - failed = "cmyth_rcv_string"; - goto fail; - } - if (buf->proginfo_chansign) - ref_release(buf->proginfo_chansign); - buf->proginfo_chansign = ref_strdup(tmp_str); - - /* - * Get proginfo_url (string) (this is the channel icon path) - * - * XXX: This isn't a url, but what is it? - */ - consumed = cmyth_rcv_string(conn, err, - tmp_str, sizeof(tmp_str) - 1, count); - count -= consumed; - total += consumed; - if (*err) { - failed = "cmyth_rcv_string"; - goto fail; - } - buf->proginfo_url = NULL; - - /* - * Get proginfo_channame (string) - */ - consumed = cmyth_rcv_string(conn, err, - tmp_str, sizeof(tmp_str) - 1, count); - count -= consumed; - total += consumed; - if (*err) { - failed = "cmyth_rcv_string"; - goto fail; - } - if (buf->proginfo_channame) - ref_release(buf->proginfo_channame); - buf->proginfo_channame = ref_strdup(tmp_str); - - /* - * Get proginfo_chanId (long) - */ - consumed = cmyth_rcv_string(conn, err, - tmp_str, sizeof(tmp_str) - 1, count); - count -= consumed; - total += consumed; - if (*err) { - failed = "cmyth_rcv_long"; - goto fail; - } - buf->proginfo_chanId = atoi(tmp_str); - - // get seriesid - consumed = cmyth_rcv_string(conn, err, - tmp_str, sizeof(tmp_str) - 1, count); - count -= consumed; - total += consumed; - if (*err) { - failed = "cmyth_rcv_string"; - goto fail; - } - if (buf->proginfo_seriesid) - ref_release(buf->proginfo_seriesid); - buf->proginfo_seriesid = ref_strdup(tmp_str); - - // get programid - consumed = cmyth_rcv_string(conn, err, - tmp_str, sizeof(tmp_str) - 1, count); - count -= consumed; - total += consumed; - if (*err) { - failed = "cmyth_rcv_string"; - goto fail; - } - if (buf->proginfo_programid) - ref_release(buf->proginfo_programid); - buf->proginfo_programid = ref_strdup(tmp_str); - - // get chanOutputFilters - consumed = cmyth_rcv_string(conn, err, - tmp_str, sizeof(tmp_str) - 1, count); - count -= consumed; - total += consumed; - if (*err) { - failed = "cmyth_rcv_string"; - goto fail; - } - // get repeat - consumed = cmyth_rcv_string(conn, err, - tmp_str, sizeof(tmp_str) - 1, count); - count -= consumed; - total += consumed; - if (*err) { - failed = "cmyth_rcv_string"; - goto fail; - } - // get airdate - consumed = cmyth_rcv_string(conn, err, - tmp_str, sizeof(tmp_str) - 1, count); - count -= consumed; - total += consumed; - if (*err) { - failed = "cmyth_rcv_string"; - goto fail; - } - // get stars - consumed = cmyth_rcv_string(conn, err, - tmp_str, sizeof(tmp_str) - 1, count); - count -= consumed; - total += consumed; - if (*err) { - failed = "cmyth_rcv_string"; - goto fail; - } - - return total; - - fail: - cmyth_dbg(CMYTH_DBG_ERROR, "%s: %s() failed (%d) (count = %d)\n", - __FUNCTION__, failed, *err, count); - return total; -} - -/* - * cmyth_rcv_proglist(cmyth_conn_t conn, int *err, cmyth_proglist_t buf, - * int count) - * - * Scope: PRIVATE (mapped to __cmyth_rcv_proglist) - * - * Description - * - * Receive a program list from a list of tokens in a MythTV Protocol - * message. Tokens in MythTV Protocol messages are separated by the - * string: []:[] or terminated by running out of message. Up to - * 'count' Bytes will be consumed from the socket specified by 'conn' - * (stopping when a separator is seen or 'count' is exhausted). The - * program list structure specified in 'buf' will be filled out. If - * an error is encountered and 'err' is not NULL, an indication of the - * nature of the error will be recorded by placing an error code in - * the location pointed to by 'err'. If all goes well, 'err' wil be - * set to 0. - * - * Return Value: - * - * A value >=0 indicating the number of bytes consumed. - * - * Error Codes: - * - * In addition to system call error codes, the following errors may be - * placed in 'err': - * - * ERANGE The token received did not parse into a program list - */ -int -cmyth_rcv_proglist(cmyth_conn_t conn, int *err, cmyth_proglist_t buf, - int count) -{ - int tmp_err; - int consumed = 0; - int r; - int c; - cmyth_proginfo_t pi; - int i; - - cmyth_dbg(CMYTH_DBG_DEBUG, "%s\n", __FUNCTION__); - if (!err) { - err = &tmp_err; - } - if (count <= 0) { - *err = EINVAL; - return 0; - } - *err = 0; - if(!buf) { - *err = EINVAL; - cmyth_dbg(CMYTH_DBG_ERROR, "%s: NULL buffer\n", __FUNCTION__); - return 0; - } - r = cmyth_rcv_long(conn, err, &buf->proglist_count, count); - consumed += r; - if (*err) { - cmyth_dbg(CMYTH_DBG_ERROR, - "%s: cmyth_rcv_long() failed (%d)\n", - __FUNCTION__, *err); - return consumed; - } - count -= r; - c = buf->proglist_count; - buf->proglist_list = malloc(c * sizeof(cmyth_proginfo_t)); - if (!buf->proglist_list) { - cmyth_dbg(CMYTH_DBG_ERROR, "%s: malloc() failed for list\n", - __FUNCTION__); - *err = ENOMEM; - return consumed; - } - memset(buf->proglist_list, 0, c * sizeof(cmyth_proginfo_t)); - for (i = 0; i < c; ++i) { - pi = cmyth_proginfo_create(); - if (!pi) { - cmyth_dbg(CMYTH_DBG_ERROR, - "%s: cmyth_proginfo_create() failed\n", - __FUNCTION__); - *err = ENOMEM; - break; - } - r = cmyth_rcv_proginfo(conn, err, pi, count); - consumed += r; - count -= r; - if (*err) { - ref_release(pi); - cmyth_dbg(CMYTH_DBG_ERROR, - "%s: cmyth_rcv_proginfo() failed (%d)\n", - __FUNCTION__, *err); - break; - } - buf->proglist_list[i] = pi; - } - return consumed; -} - -/* - * cmyth_rcv_keyframe(cmyth_conn_t conn, int *err, cmyth_keyframe_t buf, - * int count) - * - * Scope: PRIVATE (mapped to __cmyth_rcv_keyframe) - * - * Description - * - * Receive a keyframe description from a list of tokens in a MythTV - * Protocol message. Tokens in MythTV Protocol messages are separated - * by the string: []:[] or terminated by running out of message. Up - * to 'count' Bytes will be consumed from the socket specified by - * 'conn' (stopping when a separator is seen or 'count' is exhausted). - * The keyframe structure specified in 'buf' will be filled out. If - * an error is encountered and 'err' is not NULL, an indication of the - * nature of the error will be recorded by placing an error code in - * the location pointed to by 'err'. If all goes well, 'err' wil be - * set to 0. - * - * Return Value: - * - * A value >=0 indicating the number of bytes consumed. - * - * Error Codes: - * - * In addition to system call error codes, the following errors may be - * placed in 'err': - * - * ERANGE The token received did not parse into a keyframe - * - * EINVAL The token received is not numeric or is signed - */ -int -cmyth_rcv_keyframe(cmyth_conn_t conn, int *err, cmyth_keyframe_t buf, - int count) -{ - int tmp_err; - - if (!err) { - err = &tmp_err; - } - /* - * For now this is unimplemented. - */ - *err = ENOSYS; - return 0; -} - -/* - * cmyth_rcv_freespace(cmyth_conn_t conn, cmyth_freespace_t buf, int count) - * - * Scope: PRIVATE (mapped to __cmyth_rcv_freespace) - * - * Description - * - * Receive a free space description from a list of tokens in a MythTV - * Protocol message. Tokens in MythTV Protocol messages are separated - * by the string: []:[] or terminated by running out of message. Up - * to 'count' Bytes will be consumed from the socket specified by - * 'conn' (stopping when a separator is seen or 'count' is exhausted). - * The free space structure specified in 'buf' will be filled out. If - * an error is encountered and 'err' is not NULL, an indication of the - * nature of the error will be recorded by placing an error code in - * the location pointed to by 'err'. If all goes well, 'err' wil be - * set to 0. - * - * Return Value: - * - * A value >=0 indicating the number of bytes consumed. - * - * Error Codes: - * - * In addition to system call error codes, the following errors may be - * placed in 'err': - * - * ERANGE The token received did not parse into a free space - * description - * - * EINVAL The token received is not numeric or is signed - */ -int -cmyth_rcv_freespace(cmyth_conn_t conn, int *err, cmyth_freespace_t buf, - int count) -{ - int tmp_err; - - if (!err) { - err = &tmp_err; - } - /* - * For now this is unimplemented. - */ - *err = ENOSYS; - return 0; -} - -/* - * cmyth_rcv_recorder(cmyth_conn_t conn, cmyth_recorder_t buf, - * int count) - * - * Scope: PRIVATE (mapped to __cmyth_rcv_recorder) - * - * Description - * - * Receive a recorder description from a list of tokens in a MythTV - * Protocol message. Tokens in MythTV Protocol messages are separated - * by the string: []:[] or terminated by running out of message. Up - * to 'count' Bytes will be consumed from the socket specified by - * 'conn' (stopping when a separator is seen or 'count' is exhausted). - * The recorder structure specified in 'buf' will be filled out. If - * an error is encountered and 'err' is not NULL, an indication of the - * nature of the error will be recorded by placing an error code in - * the location pointed to by 'err'. If all goes well, 'err' wil be - * set to 0. - * - * Return Value: - * - * A value >=0 indicating the number of bytes consumed. - * - * Error Codes: - * - * In addition to system call error codes, the following errors may be - * placed in 'err': - * - * ERANGE The token received did not parse into a recorder - * description - * - * EINVAL The token received is not numeric or is signed - */ -int -cmyth_rcv_recorder(cmyth_conn_t conn, int *err, cmyth_recorder_t buf, - int count) -{ - int tmp_err; - - if (!err) { - err = &tmp_err; - } - /* - * For now this is unimplemented. - */ - *err = ENOSYS; - return 0; -} - -/* - * cmyth_rcv_ringbuf(cmyth_conn_t conn, int *err, cmyth_ringbuf_t buf, - * int count) - * - * Scope: PRIVATE (mapped to __cmyth_rcv_ringbuf) - * - * Description - * - * Receive a ring buffer description from a list of tokens in a MythTV - * Protocol message. Tokens in MythTV Protocol messages are separated - * by the string: []:[] or terminated by running out of message. Up - * to 'count' Bytes will be consumed from the socket specified by - * 'conn' (stopping when a separator is seen or 'count' is exhausted). - * The ring buffer structure specified in 'buf' will be filled out. - * If an error is encountered and 'err' is not NULL, an indication of - * the nature of the error will be recorded by placing an error code - * in the location pointed to by 'err'. If all goes well, 'err' wil - * be set to 0. - * - * Return Value: - * - * A value >=0 indicating the number of bytes consumed. - * - * Error Codes: - * - * In addition to system call error codes, the following errors may be - * placed in 'err': - * - * ERANGE The token received did not parse into a recorder - * description - * - * EINVAL The token received is not numeric or is signed - */ -int -cmyth_rcv_ringbuf(cmyth_conn_t conn, int *err, cmyth_ringbuf_t buf, int count) -{ - int tmp_err; - - if (!err) { - err = &tmp_err; - } - /* - * For now this is unimplemented. - */ - *err = ENOSYS; - return 0; -} - -/* - * cmyth_rcv_data(cmyth_conn_t conn, int *err, unsigned char *buf, int count) - * - * Scope: PRIVATE (mapped to __cmyth_rcv_data) - * - * Description - * - * Receive raw data from the socket specified by 'conn' and place it - * in 'buf'. This function consumes 'count' bytes and places them in - * 'buf'. If an error is encountered and 'err' is not NULL, an - * indication of the nature of the error will be recorded by placing - * an error code in the location pointed to by 'err'. If all goes - * well, 'err' wil be set to 0. - * - * Return Value: - * - * A value >=0 indicating the number of bytes consumed. - */ -int -cmyth_rcv_data(cmyth_conn_t conn, int *err, unsigned char *buf, int count) -{ - int r; - int total = 0; - unsigned char *p; - int tmp_err; - struct timeval tv; - fd_set fds; - - if (!err) { - err = &tmp_err; - } - if (count <= 0) { - *err = EINVAL; - return 0; - } - *err = 0; - if (!conn) { - cmyth_dbg(CMYTH_DBG_ERROR, "%s: no connection\n", - __FUNCTION__); - *err = EINVAL; - return 0; - } - p = buf; - while (count > 0) { - tv.tv_sec = 10; - tv.tv_usec = 0; - FD_ZERO(&fds); - FD_SET(conn->conn_fd, &fds); - if (select((int)conn->conn_fd+1, &fds, NULL, NULL, &tv) == 0) { - conn->conn_hang = 1; - continue; - } else { - conn->conn_hang = 0; - } - r = recv(conn->conn_fd, p, count, 0); - if (r < 0) { - if (total == 0) { - cmyth_dbg(CMYTH_DBG_ERROR, - "%s: read failed (%d)\n", - __FUNCTION__, errno); - *err = -1 * errno; - return 0; - } - /* - * There were bytes read before the error, use them and - * then report the error next time. - */ - break; - } - total += r; - count -= r; - p += r; - } - return total; -} diff --git a/lib/cmyth/libcmyth/timestamp.c b/lib/cmyth/libcmyth/timestamp.c deleted file mode 100644 index e19e37a27f..0000000000 --- a/lib/cmyth/libcmyth/timestamp.c +++ /dev/null @@ -1,546 +0,0 @@ -/* - * Copyright (C) 2004-2010, Eric Lund - * http://www.mvpmc.org/ - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -/* - * timestamp.c - functions to manage MythTV timestamps. Primarily, - * these allocate timestamps and convert between string - * and cmyth_timestamp_t and between time_t and - * cmyth_timestamp_t. - */ -#include <stdlib.h> -#include <stdio.h> -#include <ctype.h> -#include <errno.h> -#include <string.h> -#include <cmyth_local.h> - -/* - * cmyth_timestamp_create(void) - * - * Scope: PUBLIC - * - * Description - * - * Create a timestamp structure and return a pointer to the structure. - * - * Return Value: - * - * Success: A non-NULL cmyth_timestamp_t (this type is a pointer) - * - * Failure: A NULL cmyth_timestamp_t - */ -cmyth_timestamp_t -cmyth_timestamp_create(void) -{ - cmyth_timestamp_t ret = ref_alloc(sizeof(*ret)); - - cmyth_dbg(CMYTH_DBG_DEBUG, "%s\n", __FUNCTION__); - if (!ret) { - return(NULL); - } - ret->timestamp_year = 0; - ret->timestamp_month = 0; - ret->timestamp_day = 0; - ret->timestamp_hour = 0; - ret->timestamp_minute = 0; - ret->timestamp_second = 0; - ret->timestamp_isdst = 0; - return ret; -} - -/* - * cmyth_timestamp_from_string(char *str) - * - * Scope: PUBLIC - * - * Description - * - * Create and fill out a timestamp structure using the string 'str'. - * The string must be a timestamp of the forn: - * - * yyyy-mm-ddThh:mm:ss - * - * Return Value: - * - * Success: A timestamp structure (this is a pointer type) - * - * Failure: NULL - */ -cmyth_timestamp_t -cmyth_timestamp_from_string(char *str) -{ - cmyth_timestamp_t ret; - unsigned int i; - int datetime = 1; - char *yyyy = &str[0]; - char *MM = &str[5]; - char *dd = &str[8]; - char *hh = &str[11]; - char *mm = &str[14]; - char *ss = &str[17]; - - if (!str) { - cmyth_dbg(CMYTH_DBG_ERROR, "%s: NULL string\n", __FUNCTION__); - return NULL; - } - - ret = cmyth_timestamp_create(); - if (!ret) { - cmyth_dbg(CMYTH_DBG_ERROR, "%s: NULL timestamp\n", - __FUNCTION__); - return NULL; - } - if (strlen(str) != CMYTH_TIMESTAMP_LEN) { - datetime = 0; - if (strlen(str) != CMYTH_DATESTAMP_LEN) { - cmyth_dbg(CMYTH_DBG_ERROR, - "%s: string is not a timestamp '%s'\n", - __FUNCTION__, str); - goto err; - } - } - - if ((datetime == 1) && - ((str[4] != '-') || (str[7] != '-') || (str[10] != 'T') || - (str[13] != ':') || (str[16] != ':'))) { - cmyth_dbg(CMYTH_DBG_ERROR, "%s: string is badly formed '%s'\n", - __FUNCTION__, str); - goto err; - } - if ((datetime == 0) && - ((str[4] != '-') || (str[7] != '-'))) { - cmyth_dbg(CMYTH_DBG_ERROR, "%s: string is badly formed '%s'\n", - __FUNCTION__, str); - goto err; - } - - str[4] = '\0'; - str[7] = '\0'; - if (datetime) { - str[10] = '\0'; - str[13] = '\0'; - str[16] = '\0'; - } - for (i = 0; - i < (datetime ? CMYTH_TIMESTAMP_LEN : CMYTH_DATESTAMP_LEN); - ++i) { - if (str[i] && !isdigit(str[i])) { - cmyth_dbg(CMYTH_DBG_ERROR, - "%s: expected numeral at '%s'[%d]\n", - __FUNCTION__, str, i); - goto err; - } - } - ret->timestamp_year = atoi(yyyy); - ret->timestamp_month = atoi(MM); - if (ret->timestamp_month > 12) { - cmyth_dbg(CMYTH_DBG_ERROR, "%s: month value too big'%s'\n", - __FUNCTION__, str); - goto err; - } - ret->timestamp_day = atoi(dd); - if (ret->timestamp_day > 31) { - cmyth_dbg(CMYTH_DBG_ERROR, "%s: day value too big'%s'\n", - __FUNCTION__, str); - goto err; - } - - if (datetime == 0) - return ret; - - ret->timestamp_hour = atoi(hh); - if (ret->timestamp_hour > 23) { - cmyth_dbg(CMYTH_DBG_ERROR, "%s: hour value too big'%s'\n", - __FUNCTION__, str); - goto err; - } - ret->timestamp_minute = atoi(mm); - if (ret->timestamp_minute > 59) { - cmyth_dbg(CMYTH_DBG_ERROR, "%s: minute value too big'%s'\n", - __FUNCTION__, str); - goto err; - } - ret->timestamp_second = atoi(ss); - if (ret->timestamp_second > 59) { - cmyth_dbg(CMYTH_DBG_ERROR, "%s: second value too big'%s'\n", - __FUNCTION__, str); - goto err; - } - return ret; - - err: - ref_release(ret); - return NULL; -} - -cmyth_timestamp_t -cmyth_timestamp_from_tm(struct tm * tm_datetime) -{ - cmyth_timestamp_t ret; - ret = cmyth_timestamp_create(); - if (!ret) { - cmyth_dbg(CMYTH_DBG_ERROR, "%s: NULL timestamp\n", - __FUNCTION__); - return NULL; - } - - ret->timestamp_year = tm_datetime->tm_year + 1900; - ret->timestamp_month = tm_datetime->tm_mon + 1; - ret->timestamp_day = tm_datetime->tm_mday; - ret->timestamp_hour = tm_datetime->tm_hour; - ret->timestamp_minute = tm_datetime->tm_min; - ret->timestamp_second = tm_datetime->tm_sec; - ret->timestamp_isdst = tm_datetime->tm_isdst; - return ret; -} - -/* - * cmyth_timestamp_from_unixtime(time_t l) - * - * Scope: PUBLIC - * - * Description - * - * Create and fill out a timestamp structure using the time_t 'l'. - * - * Return Value: - * - * Success: cmyth_timestamp_t object - * - * Failure: -(ERRNO) - */ -cmyth_timestamp_t -cmyth_timestamp_from_unixtime(time_t l) -{ - struct tm tm_datetime; - localtime_r(&l,&tm_datetime); - return cmyth_timestamp_from_tm(&tm_datetime); -} - - -/* - * cmyth_timestamp_to_longlong( cmyth_timestamp_t ts) - * - * Scope: PUBLIC - * - * Description - * - * Create a time_t value from the timestamp structure 'ts' and - * return the result. - * - * - * Return Value: - * - * Success: time_t value > 0 (seconds from January 1, 1970) - * - * Failure: (time_t) -1 - */ -time_t -cmyth_timestamp_to_unixtime(cmyth_timestamp_t ts) -{ - struct tm tm; - tm.tm_sec = ts->timestamp_second; - tm.tm_min = ts->timestamp_minute; - tm.tm_hour = ts->timestamp_hour; - tm.tm_mday = ts->timestamp_day; - tm.tm_mon = ts->timestamp_month-1; - tm.tm_year = ts->timestamp_year-1900; - tm.tm_isdst = ts->timestamp_isdst; - return mktime(&tm); -} - -/* - * cmyth_timestamp_to_string(char *str, cmyth_timestamp_t ts) - * - * Scope: PUBLIC - * - * Description - * - * Create a string from the timestamp structure 'ts' and put it in the - * user supplied buffer 'str'. The size of 'str' must be - * CMYTH_TIMESTAMP_LEN + 1 or this will overwrite beyond 'str'. - * - * - * Return Value: - * - * Success: 0 - * - * Failure: -(ERRNO) - */ -int -cmyth_timestamp_to_string(char *str, cmyth_timestamp_t ts) -{ - if (!str) { - cmyth_dbg(CMYTH_DBG_ERROR, "%s: NULL output string provided\n", - __FUNCTION__); - return -EINVAL; - } - if (!ts) { - cmyth_dbg(CMYTH_DBG_ERROR, "%s: NULL timestamp provided\n", - __FUNCTION__); - return -EINVAL; - } - sprintf(str, - "%4.4ld-%2.2ld-%2.2ldT%2.2ld:%2.2ld:%2.2ld", - ts->timestamp_year, - ts->timestamp_month, - ts->timestamp_day, - ts->timestamp_hour, - ts->timestamp_minute, - ts->timestamp_second); - return 0; -} - -/* - * cmyth_timestamp_to_isostring(char *str, cmyth_timestamp_t ts) - * - * Scope: PUBLIC - * - * Description - * - * Create a string from the timestamp structure 'ts' and put it in the - * user supplied buffer 'str'. The size of 'str' must be - * CMYTH_TIMESTAMP_LEN + 1 or this will overwrite beyond 'str'. - * - * - * Return Value: - * - * Success: 0 - * - * Failure: -(ERRNO) - */ -int -cmyth_timestamp_to_isostring(char *str, cmyth_timestamp_t ts) -{ - if (!str) { - cmyth_dbg(CMYTH_DBG_ERROR, "%s: NULL output string provided\n", - __FUNCTION__); - return -EINVAL; - } - if (!ts) { - cmyth_dbg(CMYTH_DBG_ERROR, "%s: NULL timestamp provided\n", - __FUNCTION__); - return -EINVAL; - } - sprintf(str, - "%4.4ld-%2.2ld-%2.2ld", - ts->timestamp_year, - ts->timestamp_month, - ts->timestamp_day); - return 0; -} - -int -cmyth_timestamp_to_display_string(char *str, cmyth_timestamp_t ts, - int time_format_12) -{ - if (!str) { - cmyth_dbg(CMYTH_DBG_ERROR, "%s: NULL output string provided\n", - __FUNCTION__); - return -EINVAL; - } - if (!ts) { - cmyth_dbg(CMYTH_DBG_ERROR, "%s: NULL timestamp provided\n", - __FUNCTION__); - return -EINVAL; - } - if (time_format_12) - { - unsigned long hour = ts->timestamp_hour; - int pm = 0; - if (hour > 11) - { - pm = 1; - hour -= 12; - } - if (hour == 0) - hour = 12; - - sprintf(str, - "%4.4ld-%2.2ld-%2.2ldT%2.2ld:%2.2ld:%2.2ld %s", - ts->timestamp_year, - ts->timestamp_month, - ts->timestamp_day, - hour, - ts->timestamp_minute, - ts->timestamp_second, - pm ? "PM" : "AM"); - } - else - { - sprintf(str, - "%4.4ld-%2.2ld-%2.2ldT%2.2ld:%2.2ld:%2.2ld", - ts->timestamp_year, - ts->timestamp_month, - ts->timestamp_day, - ts->timestamp_hour, - ts->timestamp_minute, - ts->timestamp_second); - } - return 0; -} - -/* - * cmyth_datetime_to_string(char *str, cmyth_timestamp_t ts) - * - * Scope: PUBLIC - * - * Description - * - * Create a string from the timestamp structure 'ts' and put it in the - * user supplied buffer 'str'. The size of 'str' must be - * CMYTH_DATETIME_LEN + 1 or this will overwrite beyond 'str'. - * - * - * Return Value: - * - * Success: 0 - * - * Failure: -(ERRNO) - */ -int -cmyth_datetime_to_string(char *str, cmyth_timestamp_t ts) -{ - struct tm tm_datetime; - time_t t_datetime; - - if (!str) { - cmyth_dbg(CMYTH_DBG_ERROR, "%s: NULL output string provided\n", - __FUNCTION__); - return -EINVAL; - } - if (!ts) { - cmyth_dbg(CMYTH_DBG_ERROR, "%s: NULL timestamp provided\n", - __FUNCTION__); - return -EINVAL; - } - - memset(&tm_datetime, 0, sizeof(tm_datetime)); - tm_datetime.tm_year = ts->timestamp_year - 1900; - tm_datetime.tm_mon = ts->timestamp_month - 1; - tm_datetime.tm_mday = ts->timestamp_day; - tm_datetime.tm_hour = ts->timestamp_hour; - tm_datetime.tm_min = ts->timestamp_minute; - tm_datetime.tm_sec = ts->timestamp_second; - tm_datetime.tm_isdst = ts->timestamp_isdst; - t_datetime = mktime(&tm_datetime); - sprintf(str, - "%4.4ld-%2.2ld-%2.2ldT%2.2ld:%2.2ld:%2.2ld", - ts->timestamp_year, - ts->timestamp_month, - ts->timestamp_day, - ts->timestamp_hour, - ts->timestamp_minute, - ts->timestamp_second); - cmyth_dbg(CMYTH_DBG_ERROR, "original timestamp string: %s \n",str); - sprintf(str,"%lu",(unsigned long) t_datetime); - cmyth_dbg(CMYTH_DBG_ERROR, "time in seconds: %s \n",str); - - return 0; -} - - - -/* - * cmyth_timestamp_compare(cmyth_timestamp_t ts1, cmyth_timestamp_t ts2) - * - * Scope: PUBLIC - * - * Description - * - * Compare ts1 to ts2 and indicate whether ts1 is less than, equal to - * or greater than ts1. - * - * - * Return Value: - * - * -1: ts1 is less than (erlier than) ts2 - * 0: ts1 is the same as ts2 - * 1: ts1 is greater than (later than) ts2 - */ -int -cmyth_timestamp_compare(cmyth_timestamp_t ts1, cmyth_timestamp_t ts2) -{ - /* - * If either timestamp is NULL it is 'less than' the non-NULL one - * (this is a stretch, but it shouldn't happen). If they are both - * NULL, they are equal. - */ - if (!ts1) { - if (!ts2) { - return 0; - } - return -1; - } - if (!ts2) { - return 1; - } - if (ts1->timestamp_year != ts2->timestamp_year) { - return (ts1->timestamp_year > ts2->timestamp_year) ? 1 : -1; - } - if (ts1->timestamp_month != ts2->timestamp_month) { - return (ts1->timestamp_month > ts2->timestamp_month) ? 1 : -1; - } - if (ts1->timestamp_day != ts2->timestamp_day) { - return (ts1->timestamp_day > ts2->timestamp_day) ? 1 : -1; - } - if (ts1->timestamp_hour != ts2->timestamp_hour) { - return (ts1->timestamp_hour > ts2->timestamp_hour) ? 1 : -1; - } - if (ts1->timestamp_minute != ts2->timestamp_minute) { - return (ts1->timestamp_minute > ts2->timestamp_minute) - ? 1 - : -1; - } - if (ts1->timestamp_second != ts2->timestamp_second) { - return (ts1->timestamp_second > ts2->timestamp_second) - ? 1 - : -1; - } - return 0; -} - -int -cmyth_timestamp_diff(cmyth_timestamp_t ts1, cmyth_timestamp_t ts2) -{ - struct tm tm_datetime; - time_t start, end; - - memset(&tm_datetime, 0, sizeof(tm_datetime)); - tm_datetime.tm_year = ts1->timestamp_year - 1900; - tm_datetime.tm_mon = ts1->timestamp_month - 1; - tm_datetime.tm_mday = ts1->timestamp_day; - tm_datetime.tm_hour = ts1->timestamp_hour; - tm_datetime.tm_min = ts1->timestamp_minute; - tm_datetime.tm_sec = ts1->timestamp_second; - tm_datetime.tm_isdst = ts1->timestamp_isdst; - start = mktime(&tm_datetime); - - memset(&tm_datetime, 0, sizeof(tm_datetime)); - tm_datetime.tm_year = ts2->timestamp_year - 1900; - tm_datetime.tm_mon = ts2->timestamp_month - 1; - tm_datetime.tm_mday = ts2->timestamp_day; - tm_datetime.tm_hour = ts2->timestamp_hour; - tm_datetime.tm_min = ts2->timestamp_minute; - tm_datetime.tm_sec = ts2->timestamp_second; - tm_datetime.tm_isdst = ts2->timestamp_isdst; - end = mktime(&tm_datetime); - - return (int)(end - start); -} diff --git a/lib/cmyth/libcmyth/utf8tolatin1.c b/lib/cmyth/libcmyth/utf8tolatin1.c deleted file mode 100644 index c791aef258..0000000000 --- a/lib/cmyth/libcmyth/utf8tolatin1.c +++ /dev/null @@ -1,162 +0,0 @@ -/* - Copyright (C) 2002 Ulric Eriksson <ulric@siag.nu> - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2, or (at your option) - any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place - Suite 330, Boston, - MA 02111-1307, USA. - - Modified by Joakim Plate <elupus@ecce.se> - */ - -#include <sys/types.h> -#include <string.h> -#include "refmem/refmem.h" - -char* cmyth_utf8tolatin1(char* s) -{ - unsigned long ucs4; - int c, state, octets; - char *out, *t; - - ucs4 = 0; - state = 0; - octets = 0; - out = (char*)ref_alloc(strlen(s)+1); - t = out; - *t = 0; - - while ((c = *(s++)) != 0) { - switch (state) { - case 0: /* start of utf8 char */ - ucs4 = 0; /* reset ucs4 char */ - if ((c & 0xfe) == 0xfc) { /* 6 octets */ - ucs4 = (c & 0x01) << 30; - octets = 6; - state = 5; /* look for 5 more */ - } else if ((c & 0xfc) == 0xf8) { /* 5 octets */ - ucs4 = (c & 0x03) << 24; - octets = 5; - state = 4; - } else if ((c & 0xf8) == 0xf0) { /* 4 octets */ - ucs4 = (c & 0x07) << 18; - octets = 4; - state = 3; - } else if ((c & 0xf0) == 0xe0) { /* 3 octets */ - ucs4 = (c & 0x0f) << 12; - octets = 3; - state = 2; - } else if ((c & 0xe0) == 0xc0) { /* 2 octets */ - ucs4 = (c & 0x1f) << 6; - octets = 2; - state = 1; /* look for 1 more */ - } else if ((c & 0x80) == 0x00) { /* 1 octet */ - ucs4 = (c & 0x7f); - octets = 1; - state = 0; /* we have a result */ - } else { /* error */ - ; - } - break; - case 1: - if ((c & 0xc0) == 0x80) { - ucs4 = ucs4 | (c & 0x3f); - if (ucs4 < 0x80 || ucs4 > 0x7ff) { - ucs4 = 0xffffffff; - } - } else { - ucs4 = 0xffffffff; - } - state = 0; /* we're done and have a result */ - break; - case 2: - if ((c & 0xc0) == 0x80) { - ucs4 = ucs4 | ((c & 0x3f) << 6); - state = 1; - } else { - ucs4 = 0xffffffff; - state = 0; - } - break; - case 3: - if ((c & 0xc0) == 0x80) { - ucs4 = ucs4 | ((c & 0x3f) << 12); - state = 2; - } else { - ucs4 = 0xffffffff; - state = 0; - } - break; - case 4: - if ((c & 0xc0) == 0x80) { - ucs4 = ucs4 | ((c & 0x3f) << 18); - state = 3; - } else { - ucs4 = 0xffffffff; - state = 0; - } - break; - case 5: - if ((c & 0xc0) == 0x80) { - ucs4 = ucs4 | ((c & 0x3f) << 24); - state = 4; - } else { - ucs4 = 0xffffffff; - state = 0; - } - break; - default: /* error, can't happen */ - ucs4 = 0xffffffff; - state = 0; - break; - } - if (state == 0) { - switch (octets) { - case 1: - if (ucs4 > 0x7f) - ucs4 = 0xffffffff; - break; - case 2: - if (ucs4 < 0x80 || ucs4 > 0x7ff) - ucs4 = 0xffffffff; - break; - case 3: - if (ucs4 < 0x800 || ucs4 > 0xffff) - ucs4 = 0xffffffff; - break; - case 4: - if (ucs4 < 0x10000 || ucs4 > 0x1fffff) - ucs4 = 0xffffffff; - break; - case 5: - if (ucs4 < 0x200000 || ucs4 > 0x3ffffff) - ucs4 = 0xffffffff; - break; - case 6: - if (ucs4 < 0x4000000 || ucs4 > 0x7fffffff) - ucs4 = 0xffffffff; - break; - default: - ucs4 = 0xffffffff; - break; - } - if (ucs4 != 0xffffffff) { - *(t++) = (char)ucs4; - } - } - } - *t = 0; - return out; -} - - diff --git a/lib/cmyth/librefmem/Makefile b/lib/cmyth/librefmem/Makefile deleted file mode 100644 index 42c6ee4a64..0000000000 --- a/lib/cmyth/librefmem/Makefile +++ /dev/null @@ -1,9 +0,0 @@ -INCLUDES=-I. -I../include -I../libcmyth - -SRCS=alloc.c debug_refmem.c - -LIB=librefmem.a - -include ../../../Makefile.include --include $(patsubst %.cpp,%.P,$(patsubst %.c,%.P,$(SRCS))) - diff --git a/lib/cmyth/librefmem/alloc.c b/lib/cmyth/librefmem/alloc.c deleted file mode 100644 index af19ac6d39..0000000000 --- a/lib/cmyth/librefmem/alloc.c +++ /dev/null @@ -1,485 +0,0 @@ -/* - * Copyright (C) 2005-2006, Eric Lund, Jon Gettler - * http://www.mvpmc.org/ - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -/* - * alloc.c - Memory management functions. The structures returned from - * librefmem APIs are actually pointers to reference counted - * blocks of memory. The functions provided here handle allocating - * these blocks (strictly internally to the library), placing - * holds on these blocks (publicly) and releasing holds (publicly). - * - * All pointer type return values, including strings are reference - * counted. - * - * NOTE: Since reference counted pointers are used to move - * these structures around, it is strictly forbidden to - * modify the contents of a structure once its pointer has - * been returned to a callerthrough an API function. This - * means that all API functions that modify the contents - * of a structure must copy the structure, modify the - * copy, and return a pointer to the copy. It is safe to - * copy pointers (as long as you hold them) everyone - * follows this simple rule. There is no need for deep - * copying of any structure. - */ -#include <sys/types.h> -#include <stdlib.h> -#ifndef _MSC_VER -#include <unistd.h> -#endif -#include <errno.h> -#include <refmem/refmem.h> -#include <refmem/atomic.h> -#include <refmem_local.h> - -#include <string.h> -#include <stdio.h> - -#ifdef DEBUG -#include <assert.h> -#define ALLOC_MAGIC 0xef37a45d -#define GUARD_MAGIC 0xe3 -#endif /* DEBUG */ - -/* Disable optimization on OSX ppc - Compilation fails in release mode both with Apple gcc build 5490 and 5493 */ -#if defined(__APPLE__) && defined(__ppc__) -#pragma GCC optimization_level 0 -#endif - -/* - * struct refcounter - * - * Scope: PRIVATE (local to this module) - * - * Description: - * - * The structure used to manage references. One of these is prepended to every - * allocation. It contains two key pieces of information: - * - * - The reference count on the structure or string attached to it - * - * - A pointer to a 'destroy' function (a destructor) to be called when - * the last reference is released. This function facilitates tearing down - * of any complex structures contained in the reference counted block. If - * it is NULL, no function is called. - * - * NOTE: Make sure this has a word aligned length, as it will be placed - * before each allocation and will affect the alignment of pointers. - */ -typedef struct refcounter { -#ifdef DEBUG - unsigned int magic; - struct refcounter *next; - const char *file; - const char *func; - int line; -#endif /* DEBUG */ - mvp_atomic_t refcount; - size_t length; - ref_destroy_t destroy; -} refcounter_t; - -#ifdef DEBUG -typedef struct { - unsigned char magic; -} guard_t; -#endif /* DEBUG */ - -#define REF_REFCNT(p) ((refcounter_t *)(((unsigned char *)(p)) - sizeof(refcounter_t))) -#define REF_DATA(r) (((unsigned char *)(r)) + sizeof(refcounter_t)) - -#if defined(DEBUG) -#define REF_ALLOC_BINS 101 -static refcounter_t *ref_list[REF_ALLOC_BINS]; -#endif /* DEBUG */ - -#if defined(DEBUG) -static inline void -ref_remove(refcounter_t *ref) -{ - int bin; - refcounter_t *r, *p; - - bin = ((uintptr_t)ref >> 2) % REF_ALLOC_BINS; - - r = ref_list[bin]; - p = NULL; - - while (r && (r != ref)) { - p = r; - r = r->next; - } - - assert(r == ref); - - if (p) { - p->next = r->next; - } else { - ref_list[bin] = r->next; - } -} - -static inline void -ref_add(refcounter_t *ref) -{ - int bin; - - bin = ((uintptr_t)ref >> 2) % REF_ALLOC_BINS; - - ref->next = ref_list[bin]; - ref_list[bin] = ref; -} - -static struct alloc_type { - const char *file; - const char *func; - int line; - int count; -} alloc_list[128]; - -void -ref_alloc_show(void) -{ - int i, j; - int types = 0, bytes = 0, count = 0; - refcounter_t *r; - - for (i=0; i<REF_ALLOC_BINS; i++) { - r = ref_list[i]; - - while (r) { - for (j=0; (j<types) && (j<128); j++) { - if ((alloc_list[j].file == r->file) && - (alloc_list[j].func == r->func) && - (alloc_list[j].line == r->line)) { - alloc_list[j].count++; - break; - } - } - if (j == types) { - alloc_list[j].file = r->file; - alloc_list[j].func = r->func; - alloc_list[j].line = r->line; - alloc_list[j].count = 1; - types++; - } - bytes += r->length + sizeof(*r); - count++; - r = r->next; - } - } - - printf("refmem allocation count: %d\n", count); - printf("refmem allocation bytes: %d\n", bytes); - printf("refmem unique allocation types: %d\n", types); - for (i=0; i<types; i++) { - printf("ALLOC: %s %s():%d count %d\n", - alloc_list[i].file, alloc_list[i].func, - alloc_list[i].line, alloc_list[i].count); - } -} -#else -void -ref_alloc_show(void) -{ -} -#endif /* DEBUG */ - -/* - * ref_alloc(size_t len) - * - * Scope: PRIVATE (mapped to __ref_alloc) - * - * Description - * - * Allocate a reference counted block of data. - * - * Return Value: - * - * Success: A non-NULL pointer to a block of memory at least 'len' bytes long - * and safely aligned. The block is reference counted and can be - * released using ref_release(). - * - * Failure: A NULL pointer. - */ -void * -__ref_alloc(size_t len, const char *file, const char *func, int line) -{ -#ifdef DEBUG - void *block = malloc(sizeof(refcounter_t) + len + sizeof(guard_t)); - guard_t *guard; -#else - void *block = malloc(sizeof(refcounter_t) + len); -#endif /* DEBUG */ - void *ret = REF_DATA(block); - refcounter_t *ref = (refcounter_t *)block; - - refmem_dbg(REF_DBG_DEBUG, "%s(%d, ret = %p, ref = %p) {\n", - __FUNCTION__, len, ret, ref); - if (block) { - memset(block, 0, sizeof(refcounter_t) + len); - mvp_atomic_set(&ref->refcount, 1); -#ifdef DEBUG - ref->magic = ALLOC_MAGIC; - ref->file = file; - ref->func = func; - ref->line = line; - guard = (guard_t*)((uintptr_t)block + - sizeof(refcounter_t) + len); - guard->magic = GUARD_MAGIC; - ref_add(ref); -#endif /* DEBUG */ - ref->destroy = NULL; - ref->length = len; - refmem_dbg(REF_DBG_DEBUG, "%s(%d, ret = %p, ref = %p) }\n", - __FUNCTION__, len, ret, ref); - return ret; - } - refmem_dbg(REF_DBG_DEBUG, "%s(%d, ret = %p, ref = %p) !}\n", - __FUNCTION__, len, ret, ref); - return NULL; -} - -/* - * ref_realloc(void *p, size_t len) - * - * Scope: PRIVATE (mapped to __ref_realloc) - * - * Description - * - * Change the allocation size of a reference counted allocation. - * - * Return Value: - * - * Success: A non-NULL pointer to a block of memory at least 'len' bytes long - * and safely aligned. The block is reference counted and can be - * released using ref_release(). - * - * Failure: A NULL pointer. - */ -void * -ref_realloc(void *p, size_t len) -{ - refcounter_t *ref = REF_REFCNT(p); - void *ret = ref_alloc(len); - - refmem_dbg(REF_DBG_DEBUG, "%s(%d, ret = %p, ref = %p) {\n", - __FUNCTION__, len, ret, ref); -#ifdef DEBUG - if(p) - assert(ref->magic == ALLOC_MAGIC); -#endif /* DEBUG */ - if (p && ret) { - memcpy(ret, p, ref->length); - ref_set_destroy(ret, ref->destroy); - } - if (p) { - ref_release(p); - } - refmem_dbg(REF_DBG_DEBUG, "%s(%d, ret = %p, ref = %p) }\n", - __FUNCTION__, len, ret, ref); - return ret; -} - -/* - * ref_set_destroy(void *block, ref_destroy_t func) - * - * Scope: PRIVATE (mapped to __ref_set_destroy) - * - * Description - * - * Set the destroy function for a block of data. The first argument - * is a pointer to the data block (as returned by ref_alloc()). The - * second argument is a pointer to the destroy function which, when - * called, will be passed one argument, the pointer to the block (as - * returned by ref_alloc()). The destroy function is - * respsonsible for any cleanup needed prior to finally releasing the - * memory holding the memory block. - * - * Return Value: NONE - */ -void -ref_set_destroy(void *data, ref_destroy_t func) -{ - void *block = REF_REFCNT(data); - refcounter_t *ref = block; - - refmem_dbg(REF_DBG_DEBUG, "%s(%p, func = %p, ref = %p) {\n", - __FUNCTION__, data, func, ref); -#ifdef DEBUG - assert(ref->magic == ALLOC_MAGIC); -#endif /* DEBUG */ - if (data) { - ref->destroy = func; - } - refmem_dbg(REF_DBG_DEBUG, "%s(%p, func = %p, ref = %p) }\n", - __FUNCTION__, data, func, ref); -} - -/* - * ref_strdup(char *str) - * - * Scope: PUBLIC - * - * Description - * - * Similar to the libc version of strdup() except that it returns a pointer - * to a reference counted string. - * - * Return Value: - * - * Success: A non-NULL pointer to a reference counted string which can be - * released using ref_release(). - * - * Failure: A NULL pointer. - */ -char * -ref_strdup(char *str) -{ - size_t len; - char *ret = NULL; - - refmem_dbg(REF_DBG_DEBUG, "%s(%p) {\n", - __FUNCTION__, str); - if (str) { - len = strlen(str) + 1; - ret = ref_alloc(len); - if (ret) { - strncpy(ret, str, len); - ret[len - 1] = '\0'; - } - refmem_dbg(REF_DBG_DEBUG, - "%s str = %p[%s], len = %d, ret =%p\n", - __FUNCTION__, str, str, len, ret); - } - refmem_dbg(REF_DBG_DEBUG, "%s() }\n", __FUNCTION__); - return ret; -} - -/* - * ref_hold(void *p) - * - * Scope: PUBLIC - * - * Description - * - * This is how holders of references to reference counted blocks take - * additional references. The argument is a pointer to a structure or - * string returned from ref_alloc. The structure's reference count - * will be incremented and a pointer to that space returned. - * - * There is really no error condition possible, but if a NULL pointer - * is passed in, a NULL is returned. - * - * NOTE: since this function operates outside of the space that is directly - * accessed by the pointer, if a pointer that was NOT allocated by - * ref_alloc() is provided, negative consequences are likely. - * - * Return Value: A pointer to the held space - */ -void * -ref_hold(void *p) -{ - void *block = REF_REFCNT(p); - refcounter_t *ref = block; -#ifdef DEBUG - guard_t *guard; -#endif /* DEBUG */ - - refmem_dbg(REF_DBG_DEBUG, "%s(%p) {\n", __FUNCTION__, p); - if (p) { -#ifdef DEBUG - assert(ref->magic == ALLOC_MAGIC); - guard = (guard_t*)((uintptr_t)block + - sizeof(refcounter_t) + ref->length); - assert(guard->magic == GUARD_MAGIC); -#endif /* DEBUG */ - mvp_atomic_inc(&ref->refcount); - } - refmem_dbg(REF_DBG_DEBUG, "%s(%p) }\n", __FUNCTION__, p); - return p; -} - -/* - * ref_release(void *p) - * - * Scope: PUBLIC - * - * Description - * - * This is how holders of references to reference counted blocks release - * those references. The argument is a pointer to a structure or string - * returned from a librefmem API function (or from ref_alloc). The - * structure's reference count will be decremented and, when it reaches zero - * the structure's destroy function (if any) will be called and then the - * memory block will be released. - * - * Return Value: NONE - */ -void -ref_release(void *p) -{ - void *block = REF_REFCNT(p); - refcounter_t *ref = block; -#ifdef DEBUG - guard_t *guard; -#endif /* DEBUG */ - - refmem_dbg(REF_DBG_DEBUG, "%s(%p) {\n", __FUNCTION__, p); - if (p) { - refmem_dbg(REF_DBG_DEBUG, - "%s:%d %s(%p,ref = %p,refcount = %p,length = %d)\n", - __FILE__, __LINE__, __FUNCTION__, - p, ref, ref->refcount, ref->length); -#ifdef DEBUG - assert(ref->magic == ALLOC_MAGIC); - guard = (guard_t*)((uintptr_t)block + - sizeof(refcounter_t) + ref->length); - assert(guard->magic == GUARD_MAGIC); -#endif /* DEBUG */ - if (mvp_atomic_dec_and_test(&ref->refcount)) { - /* - * Last reference, destroy the structure (if - * there is a destroy function) and free the - * block. - */ - if (ref->destroy) { - ref->destroy(p); - } - refmem_dbg(REF_DBG_DEBUG, - "%s:%d %s() -- free it\n", - __FILE__, __LINE__, __FUNCTION__); -#ifdef DEBUG - ref->magic = 0; - guard->magic = 0; -#ifndef _WIN32 - refmem_ref_remove(ref); -#endif - ref->next = NULL; -#endif /* DEBUG */ - free(block); - } - } - refmem_dbg(REF_DBG_DEBUG, "%s(%p) }\n", __FUNCTION__, p); -} - -#if defined(__APPLE__) && defined(__ppc__) -#pragma GCC optimization_level reset -#endif diff --git a/lib/cmyth/librefmem/debug_refmem.c b/lib/cmyth/librefmem/debug_refmem.c deleted file mode 100644 index 50b09a7cb7..0000000000 --- a/lib/cmyth/librefmem/debug_refmem.c +++ /dev/null @@ -1,118 +0,0 @@ -/* - * Copyright (C) 2004-2006, Eric Lund - * http://www.mvpmc.org/ - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -/* - * debug.c - functions to produce and control debug output from - * libcmyth routines. - */ - -#include <stdio.h> -#include <stdlib.h> -#include <stdarg.h> -#include <refmem_local.h> -#include <cmyth_local.h> - -#include "debug.h" - -static cmyth_debug_ctx_t refmem_debug_ctx = CMYTH_DEBUG_CTX_INIT("refmem", - REF_DBG_NONE, - NULL); -/* - * refmem_dbg_level(int l) - * - * Scope: PUBLIC - * - * Description - * - * Set the current debug level to the absolute setting 'l' - * permitting all debug messages with a debug level less - * than or equal to 'l' to be displayed. - * - * Return Value: - * - * None. - */ -void -refmem_dbg_level(int l) -{ - __cmyth_dbg_setlevel(&refmem_debug_ctx, l); -} - -/* - * refmem_dbg_all() - * - * Scope: PUBLIC - * - * Description - * - * Set the current debug level so that all debug messages are displayed. - * - * Return Value: - * - * None. - */ -void -refmem_dbg_all() -{ - __cmyth_dbg_setlevel(&refmem_debug_ctx, REF_DBG_ALL); -} - -/* - * refmem_dbg_none() - * - * Scope: PUBLIC - * - * Description - * - * Set the current debug level so that no debug messages are displayed. - * - * Return Value: - * - * None. - */ -void -refmem_dbg_none() -{ - __cmyth_dbg_setlevel(&refmem_debug_ctx, REF_DBG_NONE); -} - -/* - * refmem_dbg() - * - * Scope: PRIVATE (mapped to __refmem_dbg) - * - * Description - * - * Print a debug message of level 'level' on 'stderr' provided that - * the current debug level allows messages of level 'level' to be - * printed. - * - * Return Value: - * - * None. - */ -void -refmem_dbg(int level, char *fmt, ...) -{ - va_list ap; - - va_start(ap, fmt); - __cmyth_dbg(&refmem_debug_ctx, level, fmt, ap); - va_end(ap); -} diff --git a/lib/cmyth/librefmem/refmem_local.h b/lib/cmyth/librefmem/refmem_local.h deleted file mode 100644 index 061248e13c..0000000000 --- a/lib/cmyth/librefmem/refmem_local.h +++ /dev/null @@ -1,20 +0,0 @@ -#ifndef __REFMEM_LOCAL_H -#define __REFMEM_LOCAL_H - -/* - * Debug level constants used to determine the level of debug tracing - * to be done and the debug level of any given message. - */ - -#define REF_DBG_NONE -1 -#define REF_DBG_DEBUG 0 -#define REF_DBG_ALL 0 - -void refmem_dbg_level(int l); - -void refmem_dbg_all(); - -void refmem_dbg_none(); - -void refmem_dbg(int level, char *fmt, ...); -#endif /* __REFMEM_LOCAL_H */ diff --git a/project/VS2010Express/XBMC for Windows.sln b/project/VS2010Express/XBMC for Windows.sln index 2c1d2bbf17..e1d8afee9a 100644 --- a/project/VS2010Express/XBMC for Windows.sln +++ b/project/VS2010Express/XBMC for Windows.sln @@ -15,8 +15,6 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libhts", "..\..\lib\libhts\ EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "visMilkdrop", "..\..\xbmc\visualizations\Milkdrop\Plugin.vcxproj", "{5E479372-4F34-426D-AA1E-9879E94C105D}" EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libcmyth_dll", "..\..\lib\cmyth\Win32\libcmyth.vcxproj", "{F9E6874D-60A8-49BA-9393-A2105E63ABCF}" -EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libXDAAP", "..\..\lib\libXDAAP\libXDAAP_win32\libXDAAP_win32.vcxproj", "{19B16CD0-3B47-47B7-AB0E-81EF2BF1B187}" EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libenca", "..\..\lib\enca\libenca_win32\libenca_win32.vcxproj", "{22B25AEC-7223-46FC-8356-4418327EFDE1}" diff --git a/project/VS2010Express/XBMC.vcxproj b/project/VS2010Express/XBMC.vcxproj index 9d35b9ee62..d91950528a 100644 --- a/project/VS2010Express/XBMC.vcxproj +++ b/project/VS2010Express/XBMC.vcxproj @@ -333,9 +333,6 @@ <ClCompile Include="..\..\xbmc\filesystem\MusicDatabaseFile.cpp" /> <ClCompile Include="..\..\xbmc\filesystem\MusicFileDirectory.cpp" /> <ClCompile Include="..\..\xbmc\filesystem\MusicSearchDirectory.cpp" /> - <ClCompile Include="..\..\xbmc\filesystem\MythDirectory.cpp" /> - <ClCompile Include="..\..\xbmc\filesystem\MythFile.cpp" /> - <ClCompile Include="..\..\xbmc\filesystem\MythSession.cpp" /> <ClCompile Include="..\..\xbmc\filesystem\NFSDirectory.cpp" /> <ClCompile Include="..\..\xbmc\filesystem\NFSFile.cpp" /> <ClCompile Include="..\..\xbmc\filesystem\NptXbmcFile.cpp" /> @@ -1089,7 +1086,6 @@ <ClInclude Include="..\..\xbmc\filesystem\Directory.h" /> <ClInclude Include="..\..\xbmc\filesystem\DirectoryFactory.h" /> <ClInclude Include="..\..\xbmc\filesystem\DirectoryHistory.h" /> - <ClInclude Include="..\..\xbmc\filesystem\DllLibCMyth.h" /> <ClInclude Include="..\..\xbmc\filesystem\DllLibCurl.h" /> <ClInclude Include="..\..\xbmc\filesystem\DllLibNfs.h" /> <ClInclude Include="..\..\xbmc\filesystem\File.h" /> @@ -1117,9 +1113,6 @@ <ClInclude Include="..\..\xbmc\filesystem\MusicDatabaseFile.h" /> <ClInclude Include="..\..\xbmc\filesystem\MusicFileDirectory.h" /> <ClInclude Include="..\..\xbmc\filesystem\MusicSearchDirectory.h" /> - <ClInclude Include="..\..\xbmc\filesystem\MythDirectory.h" /> - <ClInclude Include="..\..\xbmc\filesystem\MythFile.h" /> - <ClInclude Include="..\..\xbmc\filesystem\MythSession.h" /> <ClInclude Include="..\..\xbmc\filesystem\NFSDirectory.h" /> <ClInclude Include="..\..\xbmc\filesystem\NFSFile.h" /> <ClInclude Include="..\..\xbmc\filesystem\NSFFileDirectory.h" /> diff --git a/project/VS2010Express/XBMC.vcxproj.filters b/project/VS2010Express/XBMC.vcxproj.filters index 6173801e46..ea7d5ce7bf 100644 --- a/project/VS2010Express/XBMC.vcxproj.filters +++ b/project/VS2010Express/XBMC.vcxproj.filters @@ -2071,15 +2071,6 @@ <ClCompile Include="..\..\xbmc\filesystem\MusicSearchDirectory.cpp"> <Filter>filesystem</Filter> </ClCompile> - <ClCompile Include="..\..\xbmc\filesystem\MythDirectory.cpp"> - <Filter>filesystem</Filter> - </ClCompile> - <ClCompile Include="..\..\xbmc\filesystem\MythFile.cpp"> - <Filter>filesystem</Filter> - </ClCompile> - <ClCompile Include="..\..\xbmc\filesystem\MythSession.cpp"> - <Filter>filesystem</Filter> - </ClCompile> <ClCompile Include="..\..\xbmc\filesystem\NFSDirectory.cpp"> <Filter>filesystem</Filter> </ClCompile> @@ -5019,9 +5010,6 @@ <ClInclude Include="..\..\xbmc\filesystem\DirectoryHistory.h"> <Filter>filesystem</Filter> </ClInclude> - <ClInclude Include="..\..\xbmc\filesystem\DllLibCMyth.h"> - <Filter>filesystem</Filter> - </ClInclude> <ClInclude Include="..\..\xbmc\filesystem\DllLibCurl.h"> <Filter>filesystem</Filter> </ClInclude> @@ -5103,15 +5091,6 @@ <ClInclude Include="..\..\xbmc\filesystem\MusicSearchDirectory.h"> <Filter>filesystem</Filter> </ClInclude> - <ClInclude Include="..\..\xbmc\filesystem\MythDirectory.h"> - <Filter>filesystem</Filter> - </ClInclude> - <ClInclude Include="..\..\xbmc\filesystem\MythFile.h"> - <Filter>filesystem</Filter> - </ClInclude> - <ClInclude Include="..\..\xbmc\filesystem\MythSession.h"> - <Filter>filesystem</Filter> - </ClInclude> <ClInclude Include="..\..\xbmc\filesystem\NFSDirectory.h"> <Filter>filesystem</Filter> </ClInclude> diff --git a/system/playercorefactory.xml b/system/playercorefactory.xml index 57dfcddb91..2d10bd85ce 100644 --- a/system/playercorefactory.xml +++ b/system/playercorefactory.xml @@ -12,7 +12,7 @@ <rules name="system rules"> <rule name="rtv" protocols="rtv" player="DVDPlayer" /> - <rule name="hdhomerun/myth/mms/udp" protocols="hdhomerun|myth|cmyth|mms|mmsh|udp" player="DVDPlayer" /> + <rule name="hdhomerun/mms/udp" protocols="hdhomerun|mms|mmsh|udp" player="DVDPlayer" /> <rule name="lastfm/shout" protocols="lastfm|shout" player="PAPlayer" /> <rule name="rtmp" protocols="rtmp" player="videodefaultplayer" /> diff --git a/tools/darwin/Configurations/App.xcconfig.in b/tools/darwin/Configurations/App.xcconfig.in index bdf04a6ab8..703f252d6b 100644 --- a/tools/darwin/Configurations/App.xcconfig.in +++ b/tools/darwin/Configurations/App.xcconfig.in @@ -22,7 +22,7 @@ XBMC_DEPENDS_ROOT = @DEPENDS_ROOT_FOR_XCODE@ HEADER_SEARCH_PATHS = $(inherited) $SRCROOT xbmc xbmc/linux xbmc/osx xbmc/cores/dvdplayer lib $XBMC_DEPENDS/include $XBMC_DEPENDS/include/libcec $XBMC_DEPENDS/include/mysql $XBMC_DEPENDS/include/freetype2 $XBMC_DEPENDS/include/python2.6 -LIBRARY_SEARCH_PATHS = $(inherited) $(SRCROOT) $(SRCROOT)/lib/libRTV $(SRCROOT)/lib/libXDAAP $(SRCROOT)/lib/cmyth/libcmyth $(SRCROOT)/lib/cmyth/librefmem $(SRCROOT)/lib/SlingboxLib $(SRCROOT)/xbmc/interfaces/json-rpc "$(SRCROOT)/xbmc/interfaces/python" "$(SRCROOT)/xbmc/interfaces/legacy" +LIBRARY_SEARCH_PATHS = $(inherited) $(SRCROOT) $(SRCROOT)/lib/libRTV $(SRCROOT)/lib/libXDAAP $(SRCROOT)/lib/SlingboxLib $(SRCROOT)/xbmc/interfaces/json-rpc "$(SRCROOT)/xbmc/interfaces/python" "$(SRCROOT)/xbmc/interfaces/legacy" FRAMEWORK_SEARCH_PATHS = $(inherited) "$(SDKROOT)/System/Library/PrivateFrameworks/" "$(SDKROOT)/System/Library/Frameworks/" XBMC_OTHER_LDFLAGS_COMMON = $(inherited) -Wl,-headerpad_max_install_names -Wl,-all_load -L$XBMC_DEPENDS/lib -lbz2 -lintl -lexpat -lssl -lgpg-error -lresolv -lffi -lssh -llzo2 -lpcre -lpcrecpp -lfribidi -lfreetype -lfontconfig -lsqlite3 -ltinyxml -lmicrohttpd -lsmbclient -lpython2.6 -lyajl -ljpeg -lcrypto -lgcrypt -lavdevice -lavfilter -lavcodec -lavformat -lpostproc -lavutil -lswresample -lswscale -ltag -L$XBMC_DEPENDS/lib/mysql -lmysqlclient -lxml2 -lxslt -lnettle -lgmp -lhogweed -lgnutls -lsquish diff --git a/xbmc/Application.cpp b/xbmc/Application.cpp index a60c4827aa..66f9b3a3f2 100644 --- a/xbmc/Application.cpp +++ b/xbmc/Application.cpp @@ -66,7 +66,6 @@ #include "filesystem/StackDirectory.h" #include "filesystem/SpecialProtocol.h" #include "filesystem/DllLibCurl.h" -#include "filesystem/MythSession.h" #include "filesystem/PluginDirectory.h" #ifdef HAS_FILESYSTEM_SAP #include "filesystem/SAPDirectory.h" @@ -4227,9 +4226,6 @@ void CApplication::ProcessSlow() // check for any idle curl connections g_curlInterface.CheckIdle(); - // check for any idle myth sessions - CMythSession::CheckIdle(); - #ifdef HAS_FILESYSTEM_HTSP // check for any idle htsp sessions HTSP::CHTSPDirectorySession::CheckIdle(); diff --git a/xbmc/DllPaths_generated.h.in b/xbmc/DllPaths_generated.h.in index aa028629f8..2d96c35dc0 100644 --- a/xbmc/DllPaths_generated.h.in +++ b/xbmc/DllPaths_generated.h.in @@ -30,7 +30,6 @@ #define DLL_PATH_LIBEXIF "special://xbmcbin/system/libexif-@ARCH@.so" #define DLL_PATH_LIBHDHOMERUN "special://xbmcbin/system/hdhomerun-@ARCH@.so" #define DLL_PATH_MEDIAINFO "special://xbmcbin/system/mediainfo-@ARCH@.so" -#define DLL_PATH_LIBCMYTH "special://xbmcbin/system/libcmyth-@ARCH@.so" #define DLL_PATH_LIBRTMP "@RTMP_SONAME@" #define DLL_PATH_LIBNFS "@NFS_SONAME@" diff --git a/xbmc/DllPaths_generated_android.h.in b/xbmc/DllPaths_generated_android.h.in index ff79a45119..6270b85da1 100644 --- a/xbmc/DllPaths_generated_android.h.in +++ b/xbmc/DllPaths_generated_android.h.in @@ -32,7 +32,6 @@ #define DLL_PATH_LIBEXIF "libexif-@ARCH@.so" #define DLL_PATH_LIBHDHOMERUN "libhdhomerun-@ARCH@.so" #define DLL_PATH_MEDIAINFO "libmediainfo-@ARCH@.so" -#define DLL_PATH_LIBCMYTH "libcmyth-@ARCH@.so" #define DLL_PATH_LIBRTMP "@RTMP_SONAME@" #define DLL_PATH_LIBNFS "@NFS_SONAME@" diff --git a/xbmc/DllPaths_win32.h b/xbmc/DllPaths_win32.h index 7f379ae5a5..4794fc8f07 100644 --- a/xbmc/DllPaths_win32.h +++ b/xbmc/DllPaths_win32.h @@ -25,7 +25,6 @@ #define DLL_PATH_CPLUFF "special://xbmcbin/system/cpluff.dll" #define DLL_PATH_IMAGELIB "special://xbmcbin/system/ImageLib.dll" #define DLL_PATH_LIBEXIF "special://xbmcbin/system/libexif.dll" -#define DLL_PATH_LIBCMYTH "special://xbmcbin/system/libcmyth.dll" #define DLL_PATH_LIBHDHOMERUN "special://xbmcbin/system/hdhomerun.dll" #define DLL_PATH_LIBCURL "special://xbmcbin/system/libcurl.dll" #define DLL_PATH_LIBMICROHTTP "special://xbmcbin/system/webserver/libmicrohttpd-5.dll" diff --git a/xbmc/FileItem.cpp b/xbmc/FileItem.cpp index e857f34fa3..0bcce6b15b 100644 --- a/xbmc/FileItem.cpp +++ b/xbmc/FileItem.cpp @@ -1065,11 +1065,6 @@ bool CFileItem::IsDAAP() const return URIUtils::IsDAAP(m_strPath); } -bool CFileItem::IsMythTV() const -{ - return URIUtils::IsMythTV(m_strPath); -} - bool CFileItem::IsHDHomeRun() const { return URIUtils::IsHDHomeRun(m_strPath); diff --git a/xbmc/FileItem.h b/xbmc/FileItem.h index 02a1e09d6c..7ea6dc90f5 100644 --- a/xbmc/FileItem.h +++ b/xbmc/FileItem.h @@ -220,7 +220,6 @@ public: bool IsParentFolder() const; bool IsFileFolder(EFileFolderType types = EFILEFOLDER_MASK_ALL) const; bool IsRemovable() const; - bool IsMythTV() const; bool IsHDHomeRun() const; bool IsSlingbox() const; bool IsVTP() const; diff --git a/xbmc/Util.cpp b/xbmc/Util.cpp index 592492c859..968409c136 100644 --- a/xbmc/Util.cpp +++ b/xbmc/Util.cpp @@ -54,7 +54,6 @@ #ifdef HAS_FILESYSTEM_RAR #include "filesystem/RarManager.h" #endif -#include "filesystem/MythDirectory.h" #ifdef HAS_UPNP #include "filesystem/UPnPDirectory.h" #endif @@ -207,10 +206,6 @@ std::string CUtil::GetTitleFromPath(const CURL& url, bool bIsFolder /* = false * else if (url.IsProtocol("vtp")) strFilename = g_localizeStrings.Get(20257); - // MythTV client - else if (url.IsProtocol("myth")) - strFilename = g_localizeStrings.Get(20258); - // SAP Streams else if (url.IsProtocol("sap") && strFilename.empty()) strFilename = "SAP Streams"; @@ -515,9 +510,6 @@ bool CUtil::IsLiveTV(const std::string& strFile) || StringUtils::StartsWithNoCase(strFile, "sap:")) return true; - if (URIUtils::IsMythTV(strFile) && CMythDirectory::IsLiveTV(strFile)) - return true; - return false; } @@ -1517,15 +1509,6 @@ bool CUtil::SupportsWriteFileOperations(const std::string& strPath) return true; if (URIUtils::IsDAV(strPath)) return true; - if (URIUtils::IsMythTV(strPath)) - { - /* - * Can't use CFile::Exists() to check whether the myth:// path supports file operations because - * it hits the directory cache on the way through, which has the Live Channels and Guide - * items cached. - */ - return CMythDirectory::SupportsWriteFileOperations(strPath); - } if (URIUtils::IsStack(strPath)) return SupportsWriteFileOperations(CStackDirectory::GetFirstStackedFile(strPath)); if (URIUtils::IsMultiPath(strPath)) diff --git a/xbmc/commons/ilog.h b/xbmc/commons/ilog.h index 4a69bb7344..de90359aa6 100644 --- a/xbmc/commons/ilog.h +++ b/xbmc/commons/ilog.h @@ -44,16 +44,15 @@ #define LOGSAMBA (1 << (LOGMASKBIT + 0)) #define LOGCURL (1 << (LOGMASKBIT + 1)) -#define LOGCMYTH (1 << (LOGMASKBIT + 2)) -#define LOGFFMPEG (1 << (LOGMASKBIT + 3)) -#define LOGRTMP (1 << (LOGMASKBIT + 4)) -#define LOGDBUS (1 << (LOGMASKBIT + 5)) -#define LOGJSONRPC (1 << (LOGMASKBIT + 6)) -#define LOGAUDIO (1 << (LOGMASKBIT + 7)) -#define LOGAIRTUNES (1 << (LOGMASKBIT + 8)) -#define LOGUPNP (1 << (LOGMASKBIT + 9)) -#define LOGCEC (1 << (LOGMASKBIT + 10)) -#define LOGVIDEO (1 << (LOGMASKBIT + 11)) +#define LOGFFMPEG (1 << (LOGMASKBIT + 2)) +#define LOGRTMP (1 << (LOGMASKBIT + 3)) +#define LOGDBUS (1 << (LOGMASKBIT + 4)) +#define LOGJSONRPC (1 << (LOGMASKBIT + 5)) +#define LOGAUDIO (1 << (LOGMASKBIT + 6)) +#define LOGAIRTUNES (1 << (LOGMASKBIT + 7)) +#define LOGUPNP (1 << (LOGMASKBIT + 8)) +#define LOGCEC (1 << (LOGMASKBIT + 9)) +#define LOGVIDEO (1 << (LOGMASKBIT + 10)) #include "utils/params_check_macros.h" diff --git a/xbmc/cores/dvdplayer/DVDInputStreams/DVDFactoryInputStream.cpp b/xbmc/cores/dvdplayer/DVDInputStreams/DVDFactoryInputStream.cpp index 314d9a3470..dbc97ef9fd 100644 --- a/xbmc/cores/dvdplayer/DVDInputStreams/DVDFactoryInputStream.cpp +++ b/xbmc/cores/dvdplayer/DVDInputStreams/DVDFactoryInputStream.cpp @@ -91,9 +91,6 @@ CDVDInputStream* CDVDFactoryInputStream::CreateInputStream(IDVDPlayer* pPlayer, || file.substr(0, 7) == "mmsh://") return new CDVDInputStreamFFmpeg(); else if(file.substr(0, 8) == "sling://" - || file.substr(0, 7) == "myth://" - || file.substr(0, 8) == "cmyth://" - || file.substr(0, 8) == "gmyth://" || file.substr(0, 6) == "vtp://") return new CDVDInputStreamTV(); #ifdef ENABLE_DVDINPUTSTREAM_STACK diff --git a/xbmc/cores/dvdplayer/DVDInputStreams/DVDInputStreamTV.cpp b/xbmc/cores/dvdplayer/DVDInputStreams/DVDInputStreamTV.cpp index 8c846bcdfe..2e9a3c7688 100644 --- a/xbmc/cores/dvdplayer/DVDInputStreams/DVDInputStreamTV.cpp +++ b/xbmc/cores/dvdplayer/DVDInputStreams/DVDInputStreamTV.cpp @@ -19,7 +19,6 @@ */ #include "DVDInputStreamTV.h" -#include "filesystem/MythFile.h" #include "filesystem/VTPFile.h" #include "pvr/channels/PVRChannel.h" #include "filesystem/VTPFile.h" @@ -62,12 +61,6 @@ bool CDVDInputStreamTV::Open(const char* strFile, const std::string& content) m_pLiveTV = ((CSlingboxFile*)m_pFile)->GetLiveTV(); m_pRecordable = NULL; } - else - { - m_pFile = new CMythFile(); - m_pLiveTV = ((CMythFile*)m_pFile)->GetLiveTV(); - m_pRecordable = ((CMythFile*)m_pFile)->GetRecordable(); - } CURL url(strFile); // open file in binary mode diff --git a/xbmc/cores/dvdplayer/Edl.cpp b/xbmc/cores/dvdplayer/Edl.cpp index 9569ab9db7..bb0b753162 100644 --- a/xbmc/cores/dvdplayer/Edl.cpp +++ b/xbmc/cores/dvdplayer/Edl.cpp @@ -22,7 +22,6 @@ #include "utils/StringUtils.h" #include "utils/URIUtils.h" #include "filesystem/File.h" -#include "filesystem/MythFile.h" #include "settings/AdvancedSettings.h" #include "utils/log.h" #include "utils/XBMCTinyXML.h" @@ -31,11 +30,6 @@ #include "pvr/recordings/PVRRecordings.h" #include "pvr/PVRManager.h" -extern "C" -{ -#include "cmyth/include/cmyth/cmyth.h" -} - using namespace std; #define COMSKIP_HEADER "FILE PROCESSING COMPLETE" @@ -134,20 +128,6 @@ bool CEdl::ReadEditDecisionLists(const std::string& strMovie, const float fFrame if (!bFound) bFound = ReadBeyondTV(strMovie); } - /* - * Or if the movie points to MythTV and isn't live TV. - */ - else if (URIUtils::IsMythTV(strMovie) - && !URIUtils::IsLiveTV(strMovie)) - { - Clear(); // Don't clear in either ReadMyth* method as they are intended to be used together. - CLog::Log(LOGDEBUG, "%s - Checking for commercial breaks within MythTV for: %s", __FUNCTION__, - strMovie.c_str()); - bFound = ReadMythCommBreakList(strMovie, fFramesPerSecond); - CLog::Log(LOGDEBUG, "%s - Checking for cut list within MythTV for: %s", __FUNCTION__, - strMovie.c_str()); - bFound |= ReadMythCutList(strMovie, fFramesPerSecond); - } /* * PVR Recordings @@ -921,109 +901,6 @@ std::string CEdl::MillisecondsToTimeString(const int iMilliseconds) return strTimeString; } -bool CEdl::ReadMythCommBreakList(const std::string& strMovie, const float fFramesPerSecond) -{ - /* - * Exists() sets up all the internal bits needed for GetCommBreakList(). - */ - CMythFile mythFile; - CURL url(strMovie); - if (!mythFile.Exists(url)) - return false; - - CLog::Log(LOGDEBUG, "%s - Reading commercial break list from MythTV for: %s", __FUNCTION__, - url.GetFileName().c_str()); - - cmyth_commbreaklist_t commbreaklist; - if (!mythFile.GetCommBreakList(commbreaklist)) - { - CLog::Log(LOGERROR, "%s - Error getting commercial break list from MythTV for: %s", __FUNCTION__, - url.GetFileName().c_str()); - return false; - } - - for (int i = 0; i < (int)commbreaklist->commbreak_count; i++) - { - cmyth_commbreak_t commbreak = commbreaklist->commbreak_list[i]; - - Cut cut; - cut.action = COMM_BREAK; - cut.start = (int64_t)(commbreak->start_mark / fFramesPerSecond * 1000); - cut.end = (int64_t)(commbreak->end_mark / fFramesPerSecond * 1000); - - if (!AddCut(cut)) // Log and continue with errors while still testing. - CLog::Log(LOGERROR, "%s - Invalid commercial break [%s - %s] found in MythTV for: %s. Continuing anyway.", - __FUNCTION__, MillisecondsToTimeString(cut.start).c_str(), - MillisecondsToTimeString(cut.end).c_str(), url.GetFileName().c_str()); - } - - if (HasCut()) - { - CLog::Log(LOGDEBUG, "%s - Added %" PRIuS" commercial breaks from MythTV for: %s. Used detected frame rate of %.3f fps to calculate times from the frame markers.", - __FUNCTION__, m_vecCuts.size(), url.GetFileName().c_str(), fFramesPerSecond); - return true; - } - else - { - CLog::Log(LOGDEBUG, "%s - No commercial breaks found in MythTV for: %s", __FUNCTION__, - url.GetFileName().c_str()); - return false; - } -} - -bool CEdl::ReadMythCutList(const std::string& strMovie, const float fFramesPerSecond) -{ - /* - * Exists() sets up all the internal bits needed for GetCutList(). - */ - CMythFile mythFile; - CURL url(strMovie); - if (!mythFile.Exists(url)) - return false; - - CLog::Log(LOGDEBUG, "%s - Reading cut list from MythTV for: %s", __FUNCTION__, - url.GetFileName().c_str()); - - cmyth_commbreaklist_t commbreaklist; - if (!mythFile.GetCutList(commbreaklist)) - { - CLog::Log(LOGERROR, "%s - Error getting cut list from MythTV for: %s", __FUNCTION__, - url.GetFileName().c_str()); - return false; - } - - bool found = false; - for (int i = 0; i < (int)commbreaklist->commbreak_count; i++) - { - cmyth_commbreak_t commbreak = commbreaklist->commbreak_list[i]; - - Cut cut; - cut.action = CUT; - cut.start = (int64_t)(commbreak->start_mark / fFramesPerSecond * 1000); - cut.end = (int64_t)(commbreak->end_mark / fFramesPerSecond * 1000); - - if (!AddCut(cut)) // Log and continue with errors while still testing. - CLog::Log(LOGERROR, "%s - Invalid cut [%s - %s] found in MythTV for: %s. Continuing anyway.", - __FUNCTION__, MillisecondsToTimeString(cut.start).c_str(), - MillisecondsToTimeString(cut.end).c_str(), url.GetFileName().c_str()); - else - found = true; - } - - if (found) - { - CLog::Log(LOGDEBUG, "%s - Added %" PRIuS" cuts from MythTV for: %s. Used detected frame rate of %.3f fps to calculate times from the frame markers.", - __FUNCTION__, m_vecCuts.size(), url.GetFileName().c_str(), fFramesPerSecond); - return true; - } - else - { - CLog::Log(LOGDEBUG, "%s - No cut list found in MythTV for: %s", __FUNCTION__, - url.GetFileName().c_str()); - return false; - } -} - void CEdl::MergeShortCommBreaks() { /* diff --git a/xbmc/cores/dvdplayer/Edl.h b/xbmc/cores/dvdplayer/Edl.h index 219f6edc4b..ff26078dc4 100644 --- a/xbmc/cores/dvdplayer/Edl.h +++ b/xbmc/cores/dvdplayer/Edl.h @@ -72,8 +72,6 @@ private: bool ReadVideoReDo(const std::string& strMovie); bool ReadBeyondTV(const std::string& strMovie); bool ReadPvr(const std::string& strMovie); - bool ReadMythCommBreakList(const std::string& strMovie, const float fFramesPerSecond); - bool ReadMythCutList(const std::string& strMovie, const float fFramesPerSecond); bool AddCut(Cut& NewCut); bool AddSceneMarker(const int sceneMarker); diff --git a/xbmc/filesystem/DirectoryFactory.cpp b/xbmc/filesystem/DirectoryFactory.cpp index 692b3ab301..92cd246358 100644 --- a/xbmc/filesystem/DirectoryFactory.cpp +++ b/xbmc/filesystem/DirectoryFactory.cpp @@ -95,7 +95,6 @@ #endif #include "HDHomeRunDirectory.h" #include "SlingboxDirectory.h" -#include "MythDirectory.h" #include "FileItem.h" #include "URL.h" #include "RSSDirectory.h" @@ -211,8 +210,6 @@ IDirectory* CDirectoryFactory::Create(const CURL& url) #endif if (url.IsProtocol("hdhomerun")) return new CHomeRunDirectory(); if (url.IsProtocol("sling")) return new CSlingboxDirectory(); - if (url.IsProtocol("myth")) return new CMythDirectory(); - if (url.IsProtocol("cmyth")) return new CMythDirectory(); if (url.IsProtocol("rss")) return new CRSSDirectory(); #ifdef HAS_FILESYSTEM_SAP if (url.IsProtocol("sap")) return new CSAPDirectory(); diff --git a/xbmc/filesystem/DllLibCMyth.h b/xbmc/filesystem/DllLibCMyth.h deleted file mode 100644 index 4dc27bbb55..0000000000 --- a/xbmc/filesystem/DllLibCMyth.h +++ /dev/null @@ -1,344 +0,0 @@ -#pragma once -/* - * Copyright (C) 2005-2013 Team XBMC - * http://xbmc.org - * - * This Program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2, or (at your option) - * any later version. - * - * This Program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with XBMC; see the file COPYING. If not, see - * <http://www.gnu.org/licenses/>. - * - */ - -#include "DynamicDll.h" - -extern "C" { -#include "cmyth/include/cmyth/cmyth.h" -#include "cmyth/include/refmem/refmem.h" -} - -class DllLibCMythInterface -{ -public: - virtual ~DllLibCMythInterface() {} - virtual cmyth_conn_t conn_connect_ctrl (char *server, unsigned short port, unsigned buflen, int tcp_rcvbuf)=0; - virtual cmyth_conn_t conn_connect_event (char *server, unsigned short port, unsigned buflen, int tcp_rcvbuf)=0; - virtual cmyth_file_t conn_connect_file (cmyth_proginfo_t prog, cmyth_conn_t control, unsigned buflen, int tcp_rcvbuf)=0; - virtual cmyth_file_t conn_connect_path (char* path, cmyth_conn_t control, unsigned buflen, int tcp_rcvbuf)=0; - virtual cmyth_recorder_t conn_get_free_recorder (cmyth_conn_t conn)=0; - virtual cmyth_recorder_t conn_get_recorder_from_num(cmyth_conn_t conn, int num)=0; - - virtual int conn_get_freespace (cmyth_conn_t control,long long *total, long long *used)=0; - virtual int conn_hung (cmyth_conn_t control)=0; - - virtual cmyth_event_t event_get (cmyth_conn_t conn, char * data, int len)=0; - virtual int event_select (cmyth_conn_t conn, struct timeval *timeout)=0; - - virtual cmyth_proglist_t proglist_get_all_recorded(cmyth_conn_t control)=0; - virtual cmyth_proglist_t proglist_get_all_scheduled(cmyth_conn_t control)=0; - virtual cmyth_proglist_t proglist_get_all_pending (cmyth_conn_t control)=0; - virtual cmyth_proglist_t proglist_get_conflicting (cmyth_conn_t control)=0; - - virtual int mysql_get_guide(cmyth_database_t db, cmyth_program_t **prog, time_t starttime, time_t endtime) = 0; - virtual cmyth_proginfo_t proglist_get_item (cmyth_proglist_t pl, int index)=0; - virtual int proglist_get_count (cmyth_proglist_t pl)=0; - virtual cmyth_channel_t chanlist_get_item (cmyth_chanlist_t pl, int index)=0; - virtual int chanlist_get_count (cmyth_chanlist_t pl)=0; - - virtual int channel_channum (cmyth_channel_t chan)=0; - virtual char* channel_name (cmyth_channel_t chan)=0; - virtual char* channel_icon (cmyth_channel_t chan)=0; - virtual int channel_visible (cmyth_channel_t chan)=0; - - virtual cmyth_recorder_t recorder_is_recording (cmyth_recorder_t conn)=0; - virtual int recorder_spawn_livetv (cmyth_recorder_t rec)=0; - virtual char* recorder_get_filename (cmyth_recorder_t rec)=0; - virtual cmyth_proginfo_t recorder_get_cur_proginfo(cmyth_recorder_t rec)=0; - virtual cmyth_proginfo_t recorder_get_next_proginfo(cmyth_recorder_t rec, cmyth_proginfo_t current, cmyth_browsedir_t direction)=0; - virtual int recorder_change_channel (cmyth_recorder_t rec, cmyth_channeldir_t direction)=0; - virtual int recorder_pause (cmyth_recorder_t rec)=0; - virtual int recorder_stop_livetv (cmyth_recorder_t rec)=0; - virtual int recorder_set_channel (cmyth_recorder_t rec, char *channame)=0; - virtual int recorder_check_channel (cmyth_recorder_t rec, char *channame)=0; - - virtual int livetv_get_block (cmyth_recorder_t rec, char *buf, unsigned long len)=0; - virtual int livetv_select (cmyth_recorder_t rec, struct timeval *timeout)=0; - virtual int livetv_request_block (cmyth_recorder_t rec, unsigned long len)=0; - virtual long long livetv_seek (cmyth_recorder_t rec, long long offset, int whence)=0; - virtual int livetv_read (cmyth_recorder_t rec, char *buf, unsigned long len)=0; - virtual int livetv_chain_update (cmyth_recorder_t rec, char * chainid, int tcp_rcvbuf)=0; - virtual int livetv_chain_switch_last (cmyth_recorder_t rec)=0; - virtual int livetv_keep_recording (cmyth_recorder_t rec, cmyth_database_t db, int keep)=0; - virtual cmyth_recorder_t spawn_live_tv (cmyth_recorder_t rec, unsigned buflen, int tcp_rcvbuf, - void (*prog_update_callback)(cmyth_proginfo_t), - char ** err, char * channame)=0; - - virtual int file_get_block (cmyth_file_t file, char *buf, unsigned long len)=0; - virtual int file_select (cmyth_file_t file, struct timeval *timeout)=0; - virtual int file_request_block (cmyth_file_t file, unsigned long len)=0; - virtual long long file_seek (cmyth_file_t file, long long offset, int whence)=0; - virtual int file_read (cmyth_file_t file, char *buf, unsigned long len)=0; - virtual unsigned long long file_length (cmyth_file_t file)=0; - virtual unsigned long long file_start (cmyth_file_t file)=0; - - virtual char* proginfo_pathname (cmyth_proginfo_t prog)=0; - virtual char* proginfo_title (cmyth_proginfo_t prog)=0; - virtual char* proginfo_description (cmyth_proginfo_t prog)=0; - virtual char* proginfo_subtitle (cmyth_proginfo_t prog)=0; - virtual char* proginfo_chanstr (cmyth_proginfo_t prog)=0; - virtual char* proginfo_channame (cmyth_proginfo_t prog)=0; - virtual char* proginfo_chansign (cmyth_proginfo_t prog)=0; - virtual char* proginfo_recgroup (cmyth_proginfo_t prog)=0; - virtual char* proginfo_chanicon (cmyth_proginfo_t prog)=0; - virtual char* proginfo_category (cmyth_proginfo_t prog)=0; - virtual long long proginfo_length (cmyth_proginfo_t prog)=0; - virtual int proginfo_length_sec (cmyth_proginfo_t prog)=0; - virtual char* proginfo_host (cmyth_proginfo_t prog)=0; - virtual char* proginfo_programid (cmyth_proginfo_t prog)=0; - virtual char* proginfo_seriesid (cmyth_proginfo_t prog)=0; - virtual cmyth_timestamp_t proginfo_originalairdate(cmyth_proginfo_t prog)=0; - virtual cmyth_timestamp_t proginfo_start (cmyth_proginfo_t prog)=0; - virtual cmyth_timestamp_t proginfo_end (cmyth_proginfo_t prog)=0; - virtual cmyth_timestamp_t proginfo_rec_start (cmyth_proginfo_t prog)=0; - virtual cmyth_timestamp_t proginfo_rec_end (cmyth_proginfo_t prog)=0; - virtual cmyth_proginfo_rec_status_t proginfo_rec_status(cmyth_proginfo_t prog)=0; - virtual unsigned short proginfo_year (cmyth_proginfo_t prog)=0; - virtual cmyth_proginfo_t proginfo_get_from_basename (cmyth_conn_t control, const char* basename)=0; - virtual int proginfo_delete_recording(cmyth_conn_t control, cmyth_proginfo_t prog)=0; - virtual int proginfo_stop_recording(cmyth_conn_t control, cmyth_proginfo_t prog)=0; - virtual int proginfo_forget_recording(cmyth_conn_t control, cmyth_proginfo_t prog)=0; - virtual int proginfo_chan_id (cmyth_proginfo_t prog)=0; - virtual cmyth_proginfo_t proginfo_get_detail (cmyth_conn_t control, cmyth_proginfo_t p)=0; - virtual int proginfo_compare (cmyth_proginfo_t a, cmyth_proginfo_t b)=0; - - virtual void ref_release (void* ptr)=0; - virtual void* ref_hold (void* ptr)=0; - virtual void dbg_level (int l)=0; - virtual void set_dbg_msgcallback (void (*msgcb)(int l, char *m))=0; - - virtual time_t timestamp_to_unixtime (cmyth_timestamp_t ts)=0; - virtual int timestamp_compare (cmyth_timestamp_t ts1, cmyth_timestamp_t ts2)=0; - virtual cmyth_database_t database_init (char *host, char *db_name, char *user, char *pass)=0; - virtual cmyth_chanlist_t mysql_get_chanlist (cmyth_database_t db)=0; - - virtual cmyth_commbreaklist_t get_commbreaklist (cmyth_conn_t control, cmyth_proginfo_t prog)=0; - virtual cmyth_commbreaklist_t get_cutlist (cmyth_conn_t control, cmyth_proginfo_t prog)=0; - -}; - -class DllLibCMyth : public DllDynamic, DllLibCMythInterface -{ - DECLARE_DLL_WRAPPER(DllLibCMyth, DLL_PATH_LIBCMYTH) - DEFINE_METHOD4(cmyth_conn_t, conn_connect_ctrl, (char *p1, unsigned short p2, unsigned p3, int p4)) - DEFINE_METHOD4(cmyth_conn_t, conn_connect_event, (char *p1, unsigned short p2, unsigned p3, int p4)) - DEFINE_METHOD4(cmyth_file_t, conn_connect_file, (cmyth_proginfo_t p1, cmyth_conn_t p2, unsigned p3, int p4)) - DEFINE_METHOD4(cmyth_file_t, conn_connect_path, (char* p1, cmyth_conn_t p2, unsigned p3, int p4)) - - DEFINE_METHOD1(cmyth_recorder_t, conn_get_free_recorder, (cmyth_conn_t p1)) - DEFINE_METHOD2(cmyth_recorder_t, conn_get_recorder_from_num,(cmyth_conn_t p1, int p2)) - DEFINE_METHOD3(int, conn_get_freespace, (cmyth_conn_t p1, long long *p2, long long *p3)) - DEFINE_METHOD1(int, conn_hung, (cmyth_conn_t p1)) - - DEFINE_METHOD3(cmyth_event_t, event_get, (cmyth_conn_t p1, char * p2, int p3)) - DEFINE_METHOD2(int, event_select, (cmyth_conn_t p1, struct timeval *p2)) - - DEFINE_METHOD1(cmyth_proglist_t, proglist_get_all_recorded, (cmyth_conn_t p1)) - DEFINE_METHOD1(cmyth_proglist_t, proglist_get_all_scheduled, (cmyth_conn_t p1)) - DEFINE_METHOD1(cmyth_proglist_t, proglist_get_all_pending, (cmyth_conn_t p1)) - DEFINE_METHOD1(cmyth_proglist_t, proglist_get_conflicting, (cmyth_conn_t p1)) - - DEFINE_METHOD4(int, mysql_get_guide, (cmyth_database_t p1, cmyth_program_t **p2, time_t p3, time_t p4)) - DEFINE_METHOD2(cmyth_proginfo_t, proglist_get_item, (cmyth_proglist_t p1, int p2)) - DEFINE_METHOD1(int, proglist_get_count, (cmyth_proglist_t p1)) - DEFINE_METHOD2(cmyth_channel_t, chanlist_get_item, (cmyth_chanlist_t p1, int p2)) - DEFINE_METHOD1(int, chanlist_get_count, (cmyth_chanlist_t p1)) - DEFINE_METHOD1(int, channel_channum, (cmyth_channel_t p1)) - DEFINE_METHOD1(char*, channel_name, (cmyth_channel_t p1)) - DEFINE_METHOD1(char*, channel_icon, (cmyth_channel_t p1)) - DEFINE_METHOD1(int, channel_visible, (cmyth_channel_t p1)) - - DEFINE_METHOD1(cmyth_recorder_t, recorder_is_recording, (cmyth_recorder_t p1)) - DEFINE_METHOD1(int, recorder_spawn_livetv, (cmyth_recorder_t p1)) - DEFINE_METHOD1(char*, recorder_get_filename, (cmyth_recorder_t p1)) - DEFINE_METHOD1(cmyth_proginfo_t, recorder_get_cur_proginfo, (cmyth_recorder_t p1)) - DEFINE_METHOD3(cmyth_proginfo_t, recorder_get_next_proginfo, (cmyth_recorder_t p1, cmyth_proginfo_t p2, cmyth_browsedir_t p3)) - DEFINE_METHOD2(int, recorder_change_channel, (cmyth_recorder_t p1, cmyth_channeldir_t p2)) - DEFINE_METHOD1(int, recorder_pause, (cmyth_recorder_t p1)) - DEFINE_METHOD1(int, recorder_stop_livetv, (cmyth_recorder_t p1)) - DEFINE_METHOD2(int, recorder_set_channel, (cmyth_recorder_t p1, char * p2)) - DEFINE_METHOD2(int, recorder_check_channel, (cmyth_recorder_t p1, char * p2)) - - DEFINE_METHOD3(int, livetv_get_block, (cmyth_recorder_t p1, char *p2, unsigned long p3)) - DEFINE_METHOD2(int, livetv_select, (cmyth_recorder_t p1, struct timeval *p2)) - DEFINE_METHOD2(int, livetv_request_block, (cmyth_recorder_t p1, unsigned long p2)) - DEFINE_METHOD3(long long, livetv_seek, (cmyth_recorder_t p1, long long p2, int p3)) - DEFINE_METHOD3(int, livetv_read, (cmyth_recorder_t p1, char *p2, unsigned long p3)) - - DEFINE_METHOD3(int, livetv_chain_update, (cmyth_recorder_t p1, char * p2, int p3)) - DEFINE_METHOD1(int, livetv_chain_switch_last, (cmyth_recorder_t p1)) - DEFINE_METHOD3(int, livetv_keep_recording, (cmyth_recorder_t p1, cmyth_database_t p2, int p3)) - DEFINE_METHOD6(cmyth_recorder_t, spawn_live_tv, (cmyth_recorder_t p1, unsigned p2, int p3, void (*p4)(cmyth_proginfo_t), char ** p5, char * p6)) - - DEFINE_METHOD3(int, file_get_block, (cmyth_file_t p1, char *p2, unsigned long p3)) - DEFINE_METHOD2(int, file_select, (cmyth_file_t p1, struct timeval *p2)) - DEFINE_METHOD2(int, file_request_block, (cmyth_file_t p1, unsigned long p2)) - DEFINE_METHOD3(long long, file_seek, (cmyth_file_t p1, long long p2, int p3)) - DEFINE_METHOD3(int, file_read, (cmyth_file_t p1, char *p2, unsigned long p3)) - DEFINE_METHOD1(unsigned long long, file_length, (cmyth_file_t p1)) - DEFINE_METHOD1(unsigned long long, file_start, (cmyth_file_t p1)) - - DEFINE_METHOD1(char*, proginfo_pathname, (cmyth_proginfo_t p1)) - DEFINE_METHOD1(char*, proginfo_title, (cmyth_proginfo_t p1)) - DEFINE_METHOD1(char*, proginfo_description, (cmyth_proginfo_t p1)) - DEFINE_METHOD1(char*, proginfo_subtitle, (cmyth_proginfo_t p1)) - DEFINE_METHOD1(char*, proginfo_chanstr, (cmyth_proginfo_t p1)) - DEFINE_METHOD1(char*, proginfo_channame, (cmyth_proginfo_t p1)) - DEFINE_METHOD1(char*, proginfo_chansign, (cmyth_proginfo_t p1)) - DEFINE_METHOD1(char*, proginfo_recgroup, (cmyth_proginfo_t p1)) - DEFINE_METHOD1(char*, proginfo_chanicon, (cmyth_proginfo_t p1)) - DEFINE_METHOD1(char*, proginfo_category, (cmyth_proginfo_t p1)) - DEFINE_METHOD1(long long, proginfo_length, (cmyth_proginfo_t p1)) - DEFINE_METHOD1(int, proginfo_length_sec, (cmyth_proginfo_t p1)) - DEFINE_METHOD1(char*, proginfo_host, (cmyth_proginfo_t p1)) - DEFINE_METHOD1(char*, proginfo_programid, (cmyth_proginfo_t p1)) - DEFINE_METHOD1(char*, proginfo_seriesid, (cmyth_proginfo_t p1)) - DEFINE_METHOD1(cmyth_timestamp_t, proginfo_originalairdate, (cmyth_proginfo_t p1)) - DEFINE_METHOD1(cmyth_timestamp_t, proginfo_start, (cmyth_proginfo_t p1)) - DEFINE_METHOD1(cmyth_timestamp_t, proginfo_end, (cmyth_proginfo_t p1)) - DEFINE_METHOD1(cmyth_timestamp_t, proginfo_rec_start, (cmyth_proginfo_t p1)) - DEFINE_METHOD1(cmyth_timestamp_t, proginfo_rec_end, (cmyth_proginfo_t p1)) - DEFINE_METHOD1(cmyth_proginfo_rec_status_t, proginfo_rec_status, (cmyth_proginfo_t p1)) - DEFINE_METHOD1(unsigned long, proginfo_flags, (cmyth_proginfo_t p1)) - DEFINE_METHOD1(unsigned short, proginfo_year, (cmyth_proginfo_t p1)) - DEFINE_METHOD2(cmyth_proginfo_t, proginfo_get_from_basename, (cmyth_conn_t p1, const char* p2)) - DEFINE_METHOD2(int, proginfo_delete_recording, (cmyth_conn_t p1, cmyth_proginfo_t p2)) - DEFINE_METHOD2(int, proginfo_stop_recording, (cmyth_conn_t p1, cmyth_proginfo_t p2)) - DEFINE_METHOD2(int, proginfo_forget_recording, (cmyth_conn_t p1, cmyth_proginfo_t p2)) - DEFINE_METHOD1(int, proginfo_chan_id, (cmyth_proginfo_t p1)) - DEFINE_METHOD2(cmyth_proginfo_t, proginfo_get_detail, (cmyth_conn_t p1, cmyth_proginfo_t p2)) - DEFINE_METHOD2(int, proginfo_compare, (cmyth_proginfo_t p1, cmyth_proginfo_t p2)) - - DEFINE_METHOD1(void, ref_release, (void* p1)) - DEFINE_METHOD1(void*, ref_hold, (void* p1)) - DEFINE_METHOD1(void, dbg_level, (int p1)) - DEFINE_METHOD1(void, set_dbg_msgcallback, (void (*p1)(int l, char *m))) - - DEFINE_METHOD1(time_t, timestamp_to_unixtime, (cmyth_timestamp_t p1)) - DEFINE_METHOD2(int, timestamp_compare, (cmyth_timestamp_t p1, cmyth_timestamp_t p2)) - DEFINE_METHOD4(cmyth_database_t, database_init, (char *p1, char *p2, char *p3, char *p4)) - DEFINE_METHOD1(cmyth_chanlist_t, mysql_get_chanlist, (cmyth_database_t p1)) - - DEFINE_METHOD2(cmyth_commbreaklist_t, get_commbreaklist, (cmyth_conn_t p1, cmyth_proginfo_t p2)) - DEFINE_METHOD2(cmyth_commbreaklist_t, get_cutlist, (cmyth_conn_t p1, cmyth_proginfo_t p2)) - - BEGIN_METHOD_RESOLVE() - RESOLVE_METHOD_RENAME(cmyth_conn_connect_ctrl, conn_connect_ctrl) - RESOLVE_METHOD_RENAME(cmyth_conn_connect_event, conn_connect_event) - RESOLVE_METHOD_RENAME(cmyth_conn_connect_file, conn_connect_file) - RESOLVE_METHOD_RENAME(cmyth_conn_connect_path, conn_connect_path) - RESOLVE_METHOD_RENAME(cmyth_conn_get_free_recorder, conn_get_free_recorder) - RESOLVE_METHOD_RENAME(cmyth_conn_get_recorder_from_num, conn_get_recorder_from_num) - RESOLVE_METHOD_RENAME(cmyth_conn_get_freespace, conn_get_freespace) - RESOLVE_METHOD_RENAME(cmyth_conn_hung, conn_hung) - - RESOLVE_METHOD_RENAME(cmyth_event_get, event_get) - RESOLVE_METHOD_RENAME(cmyth_event_select, event_select) - RESOLVE_METHOD_RENAME(cmyth_proglist_get_all_recorded, proglist_get_all_recorded) - RESOLVE_METHOD_RENAME(cmyth_proglist_get_all_scheduled, proglist_get_all_scheduled) - RESOLVE_METHOD_RENAME(cmyth_proglist_get_all_pending, proglist_get_all_pending) - RESOLVE_METHOD_RENAME(cmyth_proglist_get_conflicting, proglist_get_conflicting) - RESOLVE_METHOD_RENAME(cmyth_mysql_get_guide, mysql_get_guide) - RESOLVE_METHOD_RENAME(cmyth_proglist_get_item, proglist_get_item) - RESOLVE_METHOD_RENAME(cmyth_proglist_get_count, proglist_get_count) - RESOLVE_METHOD_RENAME(cmyth_chanlist_get_item, chanlist_get_item) - RESOLVE_METHOD_RENAME(cmyth_chanlist_get_count, chanlist_get_count) - RESOLVE_METHOD_RENAME(cmyth_channel_channum, channel_channum) - RESOLVE_METHOD_RENAME(cmyth_channel_name, channel_name) - RESOLVE_METHOD_RENAME(cmyth_channel_icon, channel_icon) - RESOLVE_METHOD_RENAME(cmyth_channel_visible, channel_visible) - - RESOLVE_METHOD_RENAME(cmyth_recorder_is_recording, recorder_is_recording) - RESOLVE_METHOD_RENAME(cmyth_recorder_spawn_livetv, recorder_spawn_livetv) - RESOLVE_METHOD_RENAME(cmyth_recorder_get_filename, recorder_get_filename) - RESOLVE_METHOD_RENAME(cmyth_recorder_get_cur_proginfo, recorder_get_cur_proginfo) - RESOLVE_METHOD_RENAME(cmyth_recorder_get_next_proginfo, recorder_get_next_proginfo) - RESOLVE_METHOD_RENAME(cmyth_recorder_change_channel, recorder_change_channel) - RESOLVE_METHOD_RENAME(cmyth_recorder_pause, recorder_pause) - RESOLVE_METHOD_RENAME(cmyth_recorder_stop_livetv, recorder_stop_livetv) - RESOLVE_METHOD_RENAME(cmyth_recorder_set_channel, recorder_set_channel) - RESOLVE_METHOD_RENAME(cmyth_recorder_check_channel, recorder_check_channel) - - - RESOLVE_METHOD_RENAME(cmyth_livetv_get_block, livetv_get_block) - RESOLVE_METHOD_RENAME(cmyth_livetv_select, livetv_select) - RESOLVE_METHOD_RENAME(cmyth_livetv_request_block, livetv_request_block) - RESOLVE_METHOD_RENAME(cmyth_livetv_seek, livetv_seek) - RESOLVE_METHOD_RENAME(cmyth_livetv_read, livetv_read) - RESOLVE_METHOD_RENAME(cmyth_livetv_chain_update, livetv_chain_update) - RESOLVE_METHOD_RENAME(cmyth_livetv_chain_switch_last, livetv_chain_switch_last) - RESOLVE_METHOD_RENAME(cmyth_livetv_keep_recording, livetv_keep_recording) - RESOLVE_METHOD_RENAME(cmyth_spawn_live_tv, spawn_live_tv) - - RESOLVE_METHOD_RENAME(cmyth_file_get_block, file_get_block) - RESOLVE_METHOD_RENAME(cmyth_file_select, file_select) - RESOLVE_METHOD_RENAME(cmyth_file_request_block, file_request_block) - RESOLVE_METHOD_RENAME(cmyth_file_seek, file_seek) - RESOLVE_METHOD_RENAME(cmyth_file_read, file_read) - RESOLVE_METHOD_RENAME(cmyth_file_length, file_length) - RESOLVE_METHOD_RENAME(cmyth_file_start, file_start) - - RESOLVE_METHOD_RENAME(cmyth_proginfo_pathname, proginfo_pathname) - RESOLVE_METHOD_RENAME(cmyth_proginfo_title, proginfo_title) - RESOLVE_METHOD_RENAME(cmyth_proginfo_description, proginfo_description) - RESOLVE_METHOD_RENAME(cmyth_proginfo_subtitle, proginfo_subtitle) - RESOLVE_METHOD_RENAME(cmyth_proginfo_chanstr, proginfo_chanstr) - RESOLVE_METHOD_RENAME(cmyth_proginfo_channame, proginfo_channame) - RESOLVE_METHOD_RENAME(cmyth_proginfo_chansign, proginfo_chansign) - RESOLVE_METHOD_RENAME(cmyth_proginfo_recgroup, proginfo_recgroup) - RESOLVE_METHOD_RENAME(cmyth_proginfo_chanicon, proginfo_chanicon) - RESOLVE_METHOD_RENAME(cmyth_proginfo_category, proginfo_category) - RESOLVE_METHOD_RENAME(cmyth_proginfo_length, proginfo_length) - RESOLVE_METHOD_RENAME(cmyth_proginfo_length_sec, proginfo_length_sec) - RESOLVE_METHOD_RENAME(cmyth_proginfo_host, proginfo_host) - RESOLVE_METHOD_RENAME(cmyth_proginfo_programid, proginfo_programid) - RESOLVE_METHOD_RENAME(cmyth_proginfo_seriesid, proginfo_seriesid) - RESOLVE_METHOD_RENAME(cmyth_proginfo_originalairdate, proginfo_originalairdate) - RESOLVE_METHOD_RENAME(cmyth_proginfo_start, proginfo_start) - RESOLVE_METHOD_RENAME(cmyth_proginfo_end, proginfo_end) - RESOLVE_METHOD_RENAME(cmyth_proginfo_rec_start, proginfo_rec_start) - RESOLVE_METHOD_RENAME(cmyth_proginfo_rec_end, proginfo_rec_end) - RESOLVE_METHOD_RENAME(cmyth_proginfo_rec_status, proginfo_rec_status) - RESOLVE_METHOD_RENAME(cmyth_proginfo_flags, proginfo_flags) - RESOLVE_METHOD_RENAME(cmyth_proginfo_year, proginfo_year) - RESOLVE_METHOD_RENAME(cmyth_proginfo_get_from_basename, proginfo_get_from_basename) - RESOLVE_METHOD_RENAME(cmyth_proginfo_delete_recording, proginfo_delete_recording) - RESOLVE_METHOD_RENAME(cmyth_proginfo_stop_recording, proginfo_stop_recording) - RESOLVE_METHOD_RENAME(cmyth_proginfo_forget_recording, proginfo_forget_recording) - RESOLVE_METHOD_RENAME(cmyth_proginfo_chan_id, proginfo_chan_id) - RESOLVE_METHOD_RENAME(cmyth_proginfo_get_detail, proginfo_get_detail) - RESOLVE_METHOD_RENAME(cmyth_proginfo_compare, proginfo_compare) - - RESOLVE_METHOD(ref_release) - RESOLVE_METHOD(ref_hold) - RESOLVE_METHOD_RENAME(cmyth_dbg_level, dbg_level) - RESOLVE_METHOD_RENAME(cmyth_set_dbg_msgcallback, set_dbg_msgcallback) - - RESOLVE_METHOD_RENAME(cmyth_timestamp_to_unixtime, timestamp_to_unixtime) - RESOLVE_METHOD_RENAME(cmyth_timestamp_compare, timestamp_compare) - RESOLVE_METHOD_RENAME(cmyth_database_init, database_init) - RESOLVE_METHOD_RENAME(cmyth_mysql_get_chanlist, mysql_get_chanlist) - - RESOLVE_METHOD_RENAME(cmyth_get_commbreaklist, get_commbreaklist) - RESOLVE_METHOD_RENAME(cmyth_get_cutlist, get_cutlist) - - END_METHOD_RESOLVE() -}; diff --git a/xbmc/filesystem/FileFactory.cpp b/xbmc/filesystem/FileFactory.cpp index c89ca8d788..16efc0f5d3 100644 --- a/xbmc/filesystem/FileFactory.cpp +++ b/xbmc/filesystem/FileFactory.cpp @@ -90,7 +90,6 @@ #include "SpecialProtocolFile.h" #include "MultiPathFile.h" #include "UDFFile.h" -#include "MythFile.h" #include "HDHomeRunFile.h" #include "SlingboxFile.h" #include "ImageFile.h" @@ -170,8 +169,6 @@ IFile* CFileFactory::CreateLoader(const CURL& url) else if (url.IsProtocol("shout")) return new CShoutcastFile(); else if (url.IsProtocol("hdhomerun")) return new CHomeRunFile(); else if (url.IsProtocol("sling")) return new CSlingboxFile(); - else if (url.IsProtocol("myth")) return new CMythFile(); - else if (url.IsProtocol("cmyth")) return new CMythFile(); #ifdef HAS_FILESYSTEM_SMB #ifdef TARGET_WINDOWS else if (url.IsProtocol("smb")) return new CWin32SMBFile(); diff --git a/xbmc/filesystem/Makefile.in b/xbmc/filesystem/Makefile.in index 01ecfc1e89..cbdb68189b 100644 --- a/xbmc/filesystem/Makefile.in +++ b/xbmc/filesystem/Makefile.in @@ -45,9 +45,6 @@ SRCS += MusicDatabaseDirectory.cpp SRCS += MusicDatabaseFile.cpp SRCS += MusicFileDirectory.cpp SRCS += MusicSearchDirectory.cpp -SRCS += MythDirectory.cpp -SRCS += MythFile.cpp -SRCS += MythSession.cpp SRCS += NSFFileDirectory.cpp SRCS += OGGFileDirectory.cpp SRCS += OverrideDirectory.cpp diff --git a/xbmc/filesystem/MythDirectory.cpp b/xbmc/filesystem/MythDirectory.cpp deleted file mode 100644 index dbda721a86..0000000000 --- a/xbmc/filesystem/MythDirectory.cpp +++ /dev/null @@ -1,645 +0,0 @@ -/* - * Copyright (C) 2005-2013 Team XBMC - * http://xbmc.org - * - * This Program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2, or (at your option) - * any later version. - * - * This Program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with XBMC; see the file COPYING. If not, see - * <http://www.gnu.org/licenses/>. - * - */ - -#include "MythDirectory.h" -#include "MythSession.h" -#include "utils/URIUtils.h" -#include "DllLibCMyth.h" -#include "video/VideoInfoTag.h" -#include "URL.h" -#include "settings/AdvancedSettings.h" -#include "settings/Settings.h" -#include "FileItem.h" -#include "utils/StringUtils.h" -#include "guilib/LocalizeStrings.h" -#include "utils/log.h" -#include "DirectoryCache.h" -#include "utils/TimeUtils.h" - -extern "C" -{ -#include "cmyth/include/cmyth/cmyth.h" -#include "cmyth/include/refmem/refmem.h" -} - -using namespace XFILE; -using namespace std; - -CMythDirectory::CMythDirectory() -{ - m_session = NULL; - m_dll = NULL; - m_database = NULL; - m_recorder = NULL; -} - -CMythDirectory::~CMythDirectory() -{ - Release(); -} - -DIR_CACHE_TYPE CMythDirectory::GetCacheType(const CURL& url) const -{ - std::string fileName = url.GetFileName(); - URIUtils::RemoveSlashAtEnd(fileName); - - /* - * Always cache "All Recordings", "Guide" (top folder only), "Movies", and "TV Shows" (including - * sub folders). - * - * Entire directory cache for myth:// is invalidated when the root directory is requested to - * ensure content is always up-to-date. - */ - if (fileName == "recordings" - || fileName == "guide" - || fileName == "movies" - || StringUtils::StartsWith(fileName, "tvshows")) - return DIR_CACHE_ALWAYS; - - return DIR_CACHE_ONCE; -} - -void CMythDirectory::Release() -{ - if (m_recorder) - { - m_dll->ref_release(m_recorder); - m_recorder = NULL; - } - if (m_session) - { - CMythSession::ReleaseSession(m_session); - m_session = NULL; - } - m_dll = NULL; -} - -bool CMythDirectory::GetGuide(const std::string& base, CFileItemList &items) -{ - cmyth_database_t db = m_session->GetDatabase(); - if (!db) - return false; - - cmyth_chanlist_t list = m_dll->mysql_get_chanlist(db); - if (!list) - { - CLog::Log(LOGERROR, "%s - Unable to get list of channels: %s", __FUNCTION__, base.c_str()); - return false; - } - CURL url(base); - - int count = m_dll->chanlist_get_count(list); - for (int i = 0; i < count; i++) - { - cmyth_channel_t channel = m_dll->chanlist_get_item(list, i); - if (channel) - { - if (!m_dll->channel_visible(channel)) - { - m_dll->ref_release(channel); - continue; - } - - int channum = m_dll->channel_channum(channel); // e.g. 3 - std::string name = GetValue(m_dll->channel_name(channel)); // e.g. TV3 - if (channum <= 0) - { - CLog::Log(LOGDEBUG, "%s - Skipping channel number %d as <= 0: %s", __FUNCTION__, channum, name.c_str()); - m_dll->ref_release(channel); - continue; - } - - CLog::Log(LOGDEBUG, "%s - Adding channel number %d: %s", __FUNCTION__, channum, name.c_str()); - - std::string number = StringUtils::Format("%d", channum); // std::string easier for string manipulation than int. - url.SetFileName("guide/" + number); - CFileItemPtr item(new CFileItem(url.Get(), true)); - item->m_strTitle = number; - if (!name.empty()) - item->m_strTitle += " - " + name; // e.g. 3 - TV3 - - std::string icon = GetValue(m_dll->channel_icon(channel)); - if (!icon.empty()) - { - url.SetFileName("files/channels/" + URIUtils::GetFileName(icon)); // e.g. files/channels/tv3.jpg - item->SetArt("thumb", url.Get()); - } - - items.Add(item); - - m_dll->ref_release(channel); - } - } - - items.AddSortMethod(SortByLabel, 551 /* Name */, LABEL_MASKS("", "", "%K", "")); - - m_dll->ref_release(list); - return true; -} - -bool CMythDirectory::GetGuideForChannel(const std::string& base, CFileItemList &items, int channelNumber) -{ - cmyth_database_t database = m_session->GetDatabase(); - if (!database) - { - CLog::Log(LOGERROR, "%s - Could not get database", __FUNCTION__); - return false; - } - - time_t now; - time(&now); - time_t end = now + (24 * 60 * 60); // How many seconds of EPG from now we should grab, 24 hours in seconds - - cmyth_program_t *program = NULL; - // TODO: See if there is a way to just get the entries for the chosen channel rather than ALL - int count = m_dll->mysql_get_guide(database, &program, now, end); - CLog::Log(LOGDEBUG, "%s - %i entries in guide data", __FUNCTION__, count); - if (count <= 0) - return false; - - for (int i = 0; i < count; i++) - { - if (program[i].channum == channelNumber) - { - CFileItemPtr item(new CFileItem("", false)); // No path for guide entries - - /* - * Set the FileItem meta data. - */ - std::string title = program[i].title; // e.g. Mythbusters - std::string subtitle = program[i].subtitle; // e.g. The Pirate Special - CDateTime localstart; - if (program[i].starttime) - localstart = CTimeUtils::GetLocalTime(program[i].starttime); - item->m_strTitle = StringUtils::Format("%s - %s", - localstart.GetAsLocalizedTime("HH:mm", false).c_str(), - title.c_str()); // e.g. 20:30 - Mythbusters - if (!subtitle.empty()) - item->m_strTitle += " - \"" + subtitle + "\""; // e.g. 20:30 - Mythbusters - "The Pirate Special" - item->m_dateTime = localstart; - - /* - * Set the VideoInfoTag meta data so it matches the FileItem meta data where possible. - */ - CVideoInfoTag* tag = item->GetVideoInfoTag(); - tag->m_strTitle = title; - if (!subtitle.empty()) - tag->m_strTitle += " - \"" + subtitle + "\""; // e.g. Mythbusters - "The Pirate Special" - tag->m_strShowTitle = title; - tag->m_strOriginalTitle = title; - tag->m_strPlotOutline = subtitle; - tag->m_strPlot = program[i].description; - // TODO: Strip out the subtitle from the description if it is present at the start? - // TODO: Do we need to add the subtitle to the start of the plot if not already as it used to? Seems strange, should be handled by skin? - tag->m_genre = StringUtils::Split(program[i].category, g_advancedSettings.m_videoItemSeparator); // e.g. Sports - tag->m_strAlbum = program[i].callsign; // e.g. TV3 - - CDateTime start(program[i].starttime); - CDateTime end(program[i].endtime); - CDateTimeSpan runtime = end - start; - tag->m_duration = runtime.GetSeconds() + runtime.GetMinutes() * 60 + runtime.GetHours() * 3600; - tag->m_iSeason = 0; // So XBMC treats the content as an episode and displays tag information. - tag->m_iEpisode = 0; - - items.Add(item); - } - } - - /* - * Items are sorted as added to the list (in ascending date order). Specifying sorting by date can - * result in the guide being shown in the wrong order for skins that sort by date in descending - * order by default with no option to change to ascending, e.g. Confluence. - */ - items.AddSortMethod(SortByNone, 552 /* Date */, LABEL_MASKS("%K", "%J")); // Still leave the date label - - m_dll->ref_release(program); - return true; -} - -bool CMythDirectory::GetRecordings(const std::string& base, CFileItemList &items, enum FilterType type, - const std::string& filter) -{ - cmyth_proglist_t list = m_session->GetAllRecordedPrograms(); - if (!list) - { - CLog::Log(LOGERROR, "%s - unable to get list of recordings", __FUNCTION__); - return false; - } - - int count = m_dll->proglist_get_count(list); - for (int i = 0; i < count; i++) - { - cmyth_proginfo_t program = m_dll->proglist_get_item(list, i); - if (program) - { - if (!IsVisible(program)) - { - m_dll->ref_release(program); - continue; - } - - CURL url(base); - /* - * The base is the URL used to connect to the master server. The hostname in this may not - * appropriate for all items as MythTV supports multiple backends (master + slaves). - * - * The appropriate host for playback is contained in the program information sent back from - * the master. The same username and password are used in the URL as for the master. - */ - url.SetHostName(GetValue(m_dll->proginfo_host(program))); - - std::string path = URIUtils::GetFileName(GetValue(m_dll->proginfo_pathname(program))); - std::string name = GetValue(m_dll->proginfo_title(program)); - - switch (type) - { - case MOVIES: - if (!IsMovie(program)) - { - m_dll->ref_release(program); - continue; - } - url.SetFileName("movies/" + path); - break; - case TV_SHOWS: - if (!StringUtils::EqualsNoCase(filter, name)) - { - m_dll->ref_release(program); - continue; - } - url.SetFileName("tvshows/" + name + "/" + path); - break; - case ALL: - url.SetFileName("recordings/" + path); - break; - } - - CFileItemPtr item(new CFileItem(url.Get(), false)); - m_session->SetFileItemMetaData(*item, program); - - /* - * If MOVIES, set the label and specify as pre-formatted so any scraper lookup will use the - * label rather than the filename. Don't set as pre-formatted for any other types as this - * prevents the display of the title changing depending on what the list is being sorted by. - */ - if (type == MOVIES) - { - /* - * Adding the production year, if available, to the label for Movies to aid in scraper - * lookups. - */ - std::string label(item->m_strTitle); - unsigned short year = m_dll->proginfo_year(program); - if (year > 0) - label += StringUtils::Format(" (%d)", year); - item->SetLabel(label); - item->SetLabelPreformated(true); - } - - items.Add(item); - m_dll->ref_release(program); - } - } - m_dll->ref_release(list); - - /* - * Don't sort by name for TV_SHOWS as they all have the same name, so only date sort is useful. - * Since the subtitle has been added to the TV Show name, the video sort title sort is used so - * the subtitle doesn't influence the sort order and they are sorted by date. - */ - if (type != TV_SHOWS) - items.AddSortMethod(SortBySortTitle, 556 /* Name */, LABEL_MASKS("%K", "%J"), CSettings::Get().GetBool("filelists.ignorethewhensorting") ? SortAttributeIgnoreArticle : SortAttributeNone); - items.AddSortMethod(SortByDate, 552 /* Date */, LABEL_MASKS("%K", "%J")); - - return true; -} - -/** - * \brief Gets a list of folders for recorded TV shows - */ -bool CMythDirectory::GetTvShowFolders(const std::string& base, CFileItemList &items) -{ - cmyth_proglist_t list = m_session->GetAllRecordedPrograms(); - if (!list) - { - CLog::Log(LOGERROR, "%s - unable to get list of recordings", __FUNCTION__); - return false; - } - - int count = m_dll->proglist_get_count(list); - for (int i = 0; i < count; i++) - { - cmyth_proginfo_t program = m_dll->proglist_get_item(list, i); - if (program) - { - if (!IsVisible(program)) - { - m_dll->ref_release(program); - continue; - } - - if (!IsTvShow(program)) - { - m_dll->ref_release(program); - continue; - } - - std::string title = GetValue(m_dll->proginfo_title(program)); - std::string path = base + "/" + title + "/"; - - /* - * Only add each TV show once. If the TV show is already in the list, update the date for the - * folder to be the date of the last recorded TV show as the programs are returned in the - * order they were recorded. - */ - if (items.Contains(path)) - { - CFileItemPtr item = items.Get(path); - item->m_dateTime = GetValue(m_dll->proginfo_rec_start(program)); - } - else - { - CFileItemPtr item(new CFileItem(path, true)); - item->m_dateTime = GetValue(m_dll->proginfo_rec_start(program)); - item->SetLabel(title); - items.Add(item); - } - m_dll->ref_release(program); - } - - } - m_dll->ref_release(list); - - items.AddSortMethod(SortByLabel, 551 /* Name */, LABEL_MASKS("", "", "%L", "%J"), CSettings::Get().GetBool("filelists.ignorethewhensorting") ? SortAttributeIgnoreArticle : SortAttributeNone); - items.AddSortMethod(SortByDate, 552 /* Date */, LABEL_MASKS("", "", "%L", "%J")); - - return true; -} - -bool CMythDirectory::GetChannels(const std::string& base, CFileItemList &items) -{ - cmyth_conn_t control = m_session->GetControl(); - if (!control) - return false; - - vector<cmyth_proginfo_t> channels; - for (unsigned i = 0; i < 16; i++) - { - cmyth_recorder_t recorder = m_dll->conn_get_recorder_from_num(control, i); - if (!recorder) - continue; - - cmyth_proginfo_t program; - program = m_dll->recorder_get_cur_proginfo(recorder); - program = m_dll->recorder_get_next_proginfo(recorder, program, BROWSE_DIRECTION_UP); - if (!program) - { - m_dll->ref_release(m_recorder); - continue; - } - - long startchan = m_dll->proginfo_chan_id(program); - long currchan = -1; - while (startchan != currchan) - { - unsigned j; - for (j = 0; j < channels.size(); j++) - { - if (m_dll->proginfo_compare(program, channels[j]) == 0) - break; - } - - if (j == channels.size()) - channels.push_back(program); - - program = m_dll->recorder_get_next_proginfo(recorder, program, BROWSE_DIRECTION_UP); - if (!program) - break; - - currchan = m_dll->proginfo_chan_id(program); - } - m_dll->ref_release(recorder); - } - - CURL url(base); - /* - * The content of the cmyth_proginfo_t struct retrieved and stored in channels[] above does not - * contain the host so the URL cannot be modified to support both master and slave servers. - */ - - for (unsigned i = 0; i < channels.size(); i++) - { - cmyth_proginfo_t program = channels[i]; - - url.SetFileName("channels/" + GetValue(m_dll->proginfo_chanstr(program)) + ".ts"); // e.g. 3.ts - CFileItemPtr item(new CFileItem(url.Get(), false)); - m_session->SetFileItemMetaData(*item, program); - - items.Add(item); - m_dll->ref_release(program); - } - - items.AddSortMethod(SortByLabel, 551 /* Name */, LABEL_MASKS("%K", "%B")); - - /* - * Video sort title is set to the channel number. - */ - items.AddSortMethod(SortBySortTitle, 556 /* Title */, LABEL_MASKS("%K", "%B"), CSettings::Get().GetBool("filelists.ignorethewhensorting") ? SortAttributeIgnoreArticle : SortAttributeNone); - - return true; -} - -bool CMythDirectory::GetDirectory(const CURL& url, CFileItemList &items) -{ - m_session = CMythSession::AquireSession(url); - if (!m_session) - return false; - - m_dll = m_session->GetLibrary(); - if (!m_dll) - return false; - - std::string base(url.Get()); - URIUtils::RemoveSlashAtEnd(base); - - std::string fileName = url.GetFileName(); - URIUtils::RemoveSlashAtEnd(fileName); - - if (fileName == "") - { - /* - * If we can't get the control then we can't connect to the backend. Don't even show any of the - * virtual folders as none of them will work. Without this check the "Browse" functionality - * when adding a myth:// source is way confusing as it shows folders so it looks like it has - * connected successfully when it in fact hasn't. - */ - cmyth_conn_t control = m_session->GetControl(); - if (!control) - return false; - - CFileItemPtr item; - - item.reset(new CFileItem(base + "/recordings/", true)); - item->SetLabel(g_localizeStrings.Get(22015)); // All recordings - items.Add(item); - - item.reset(new CFileItem(base + "/tvshows/", true)); - item->SetLabel(g_localizeStrings.Get(20343)); // TV shows - items.Add(item); - - item.reset(new CFileItem(base + "/movies/", true)); - item->SetLabel(g_localizeStrings.Get(20342)); // Movies - items.Add(item); - - item.reset(new CFileItem(base + "/channels/", true)); - item->SetLabel(g_localizeStrings.Get(22018)); // Live channels - items.Add(item); - - item.reset(new CFileItem(base + "/guide/", true)); - item->SetLabel(g_localizeStrings.Get(22020)); // Guide - items.Add(item); - - items.AddSortMethod(SortByNone, 564 /* Type */, LABEL_MASKS("", "", "%L", "")); // No sorting, as added to list. - - /* - * Clear the directory cache so the cached sub-folders are guaranteed to be accurate. - */ - g_directoryCache.ClearSubPaths(base); - - return true; - } - else if (fileName == "channels") - return GetChannels(base, items); - else if (fileName == "guide") - return GetGuide(base, items); - else if (StringUtils::StartsWith(fileName, "guide/")) - return GetGuideForChannel(base, items, atoi(fileName.substr(6).c_str())); - else if (fileName == "movies") - return GetRecordings(base, items, MOVIES); - else if (fileName == "recordings") - return GetRecordings(base, items); - else if (fileName == "tvshows") - return GetTvShowFolders(base, items); - else if (StringUtils::StartsWith(fileName, "tvshows/")) - return GetRecordings(base, items, TV_SHOWS, fileName.substr(8).c_str()); - return false; -} - -bool CMythDirectory::Exists(const CURL& url) -{ - /* - * Return true for any virtual folders that are known to exist. Don't check for explicit - * existence using GetDirectory() as most methods will return true with empty content due to the - * way they are implemented - by iterating over all programs and filtering out content. - */ - std::string fileName = url.GetFileName(); - URIUtils::RemoveSlashAtEnd(fileName); - - if (fileName == "" - || fileName == "channels" - || fileName == "guide" - || StringUtils::StartsWith(fileName, "guide/") - || fileName == "movies" - || fileName == "recordings" - || fileName == "tvshows" - || StringUtils::StartsWith(fileName, "tvshows/")) - return true; - - return false; -} - -bool CMythDirectory::IsVisible(const cmyth_proginfo_t program) -{ - std::string group = GetValue(m_dll->proginfo_recgroup(program)); - unsigned long flags = m_dll->proginfo_flags(program); - - /* - * Ignore programs that were recorded using "LiveTV" or that have been deleted via the - * "Auto Expire Instead of Delete Recording" option, which places the recording in the - * "Deleted" recording group for x days rather than deleting straight away. - * - * As of 0.24, when a recording is deleted using the Myth Protocol it is marked as "pending delete" - * using the program flags mask. It is then scheduled to be physically deleted in a detached - * thread. This means that a deleted recording can still appear in the list of all recordings. - * Recordings that are "pending delete" will have a program flag mask that matches - * FL_DELETEPENDING = 0x00000080. - */ - return !(StringUtils::EqualsNoCase(group, "LiveTV") || - StringUtils::EqualsNoCase(group, "Deleted") || flags & 0x00000080); -} - -bool CMythDirectory::IsMovie(const cmyth_proginfo_t program) -{ - /* - * The mythconverg.recordedprogram.programid field (if it exists) is a combination key where the first 2 characters map - * to the category_type and the rest is the key. From MythTV/release-0-21-fixes/mythtv/libs/libmythtv/programinfo.cpp - * "MV" = movie - * "EP" = series - * "SP" = sports - * "SH" = tvshow - * - * Based on MythTV usage it appears that the programid is only filled in for Movies though. Shame, could have used - * it for the other categories as well. - * - * mythconverg.recordedprogram.category_type contains the exact information that is needed. However, category_type - * isn't available through the libcmyth API. Since there is a direct correlation between the programid starting - * with "MV" and the category_type being "movie" that should work fine. - */ - - const int iMovieLength = g_advancedSettings.m_iMythMovieLength; // Minutes - if (iMovieLength > 0) // Use hack to identify movie based on length (used if EPG is dubious). - return StringUtils::StartsWith(GetValue(m_dll->proginfo_programid(program)), "MV") - || m_dll->proginfo_length_sec(program) > iMovieLength * 60; // Minutes to seconds - else - return StringUtils::StartsWith(GetValue(m_dll->proginfo_programid(program)), "MV"); -} - -bool CMythDirectory::IsTvShow(const cmyth_proginfo_t program) -{ - /* - * There isn't enough information exposed by libcmyth to distinguish between an episode in a series and a - * one off TV show. See comment in IsMovie for more information. - * - * Return anything that isn't a movie as per any advanced setting override. This may result in a - * recorded TV Show only being shown in the Movies directory if it's something like a double - * episode. - */ - return !IsMovie(program); -} - -bool CMythDirectory::SupportsWriteFileOperations(const std::string& strPath) -{ - CURL url(strPath); - std::string filename = url.GetFileName(); - URIUtils::RemoveSlashAtEnd(filename); - /* - * TV Shows directory has sub-folders so extra check is included so only files get the file - * operations. - */ - return StringUtils::StartsWith(filename, "recordings/") || - StringUtils::StartsWith(filename, "movies/") || - (StringUtils::StartsWith(filename, "tvshows/") && URIUtils::HasExtension(filename)); -} - -bool CMythDirectory::IsLiveTV(const std::string& strPath) -{ - CURL url(strPath); - return StringUtils::StartsWith(url.GetFileName(), "channels/"); -} diff --git a/xbmc/filesystem/MythDirectory.h b/xbmc/filesystem/MythDirectory.h deleted file mode 100644 index deeab322da..0000000000 --- a/xbmc/filesystem/MythDirectory.h +++ /dev/null @@ -1,71 +0,0 @@ -#pragma once -/* - * Copyright (C) 2005-2013 Team XBMC - * http://xbmc.org - * - * This Program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2, or (at your option) - * any later version. - * - * This Program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with XBMC; see the file COPYING. If not, see - * <http://www.gnu.org/licenses/>. - * - */ - -#include "IDirectory.h" -#include "MythSession.h" -#include "XBDateTime.h" - -namespace XFILE -{ - -enum FilterType -{ - MOVIES, - TV_SHOWS, - ALL -}; - -class CMythDirectory - : public IDirectory -{ -public: - CMythDirectory(); - virtual ~CMythDirectory(); - - virtual bool GetDirectory(const CURL& url, CFileItemList &items); - virtual bool Exists(const CURL& url); - virtual bool AllowAll() const { return true; } - virtual DIR_CACHE_TYPE GetCacheType(const CURL& url) const; - - static bool SupportsWriteFileOperations(const std::string& strPath); - static bool IsLiveTV(const std::string& strPath); - -private: - void Release(); - bool GetGuide(const std::string& base, CFileItemList &items); - bool GetGuideForChannel(const std::string& base, CFileItemList &items, const int channelNumber); - bool GetRecordings(const std::string& base, CFileItemList &items, enum FilterType type = ALL, const std::string& filter = ""); - bool GetTvShowFolders(const std::string& base, CFileItemList &items); - bool GetChannels(const std::string& base, CFileItemList &items); - - std::string GetValue(char* str) { return m_session->GetValue(str); } - CDateTime GetValue(cmyth_timestamp_t t) { return m_session->GetValue(t); } - bool IsVisible(const cmyth_proginfo_t program); - bool IsMovie(const cmyth_proginfo_t program); - bool IsTvShow(const cmyth_proginfo_t program); - - XFILE::CMythSession* m_session; - DllLibCMyth* m_dll; - cmyth_database_t m_database; - cmyth_recorder_t m_recorder; -}; - -} diff --git a/xbmc/filesystem/MythFile.cpp b/xbmc/filesystem/MythFile.cpp deleted file mode 100644 index ec2aa2a01f..0000000000 --- a/xbmc/filesystem/MythFile.cpp +++ /dev/null @@ -1,726 +0,0 @@ -/* - * Copyright (C) 2005-2013 Team XBMC - * http://xbmc.org - * - * This Program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2, or (at your option) - * any later version. - * - * This Program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with XBMC; see the file COPYING. If not, see - * <http://www.gnu.org/licenses/>. - * - */ - -#include "threads/SystemClock.h" -#include "MythFile.h" -#include "XBDateTime.h" -#include "FileItem.h" -#include "utils/URIUtils.h" -#include "DllLibCMyth.h" -#include "URL.h" -#include "DirectoryCache.h" -#include "threads/SingleLock.h" -#include "utils/log.h" -#include "utils/StringUtils.h" -#include "utils/TimeUtils.h" -#include "utils/StringUtils.h" - -extern "C" { -#include "cmyth/include/cmyth/cmyth.h" -#include "cmyth/include/refmem/refmem.h" -} - -using namespace XFILE; -using namespace std; - -static void prog_update_callback(cmyth_proginfo_t prog) -{ - CLog::Log(LOGDEBUG, "%s - prog_update_callback", __FUNCTION__); -} - -void CMythFile::OnEvent(int event, const string& data) -{ - CSingleLock lock(m_section); - m_events.push(make_pair(event, data)); -} - -bool CMythFile::HandleEvents() -{ - CSingleLock lock(m_section); - - if(m_events.empty()) - return false; - - while(!m_events.empty()) - { - int event = m_events.front().first; - string data = m_events.front().second; - m_events.pop(); - - lock.Leave(); - - switch (event) { - case CMYTH_EVENT_CLOSE: - Close(); - break; - case CMYTH_EVENT_LIVETV_CHAIN_UPDATE: - { - if(m_recorder) - m_dll->livetv_chain_update(m_recorder, (char*)data.c_str(), 4096); - } - break; - } - - lock.Enter(); - } - return true; -} - -bool CMythFile::SetupConnection(const CURL& url, bool control, bool event, bool database) -{ - if(!m_session) - m_session = CMythSession::AquireSession(url); - - if(!m_session) - return false; - - if(!m_dll) - { - m_dll = m_session->GetLibrary(); - if(!m_dll) - return false; - } - - if(control && !m_control) - { - m_control = m_session->GetControl(); - if(!m_control) - return false; - } - if(event) - { - if(!m_session->SetListener(this)) - return false; - } - if(database && !m_database) - { - m_database = m_session->GetDatabase(); - if(!m_database) - return false; - } - - return true; -} - -bool CMythFile::SetupRecording(const CURL& url) -{ - if (!StringUtils::StartsWith(url.GetFileName(), "recordings/") && - !StringUtils::StartsWith(url.GetFileName(), "movies/") && - !StringUtils::StartsWith(url.GetFileName(), "tvshows/")) - return false; - - if(!SetupConnection(url, true, false, false)) - return false; - - m_filename = url.GetFileNameWithoutPath(); - - m_program = m_dll->proginfo_get_from_basename(m_control, m_filename.c_str()); - if(!m_program) - { - CLog::Log(LOGERROR, "%s - unable to get find selected file", __FUNCTION__); - return false; - } - - m_file = m_dll->conn_connect_file(m_program, m_control, 16*1024, 4096); - if(!m_file) - { - CLog::Log(LOGERROR, "%s - unable to connect to file", __FUNCTION__); - return false; - } - - /* - * proginfo_get_from_basename doesn't return the recording status. Hopefully this will be added to - * mythbackend eventually. - * - * Since cycling through the recorders to check if the program is recording takes some time - * (depending on the MythTV backend configuration), make some assumptions based on the recording - * end time since nearly all recordings opened won't be recording. - */ - m_recording = false; - CDateTime start = GetValue(m_dll->proginfo_rec_start(m_program)); - CDateTime end = GetValue(m_dll->proginfo_rec_end(m_program)); - if (end > start // Assume could be recording if empty date comes back as the epoch - && end < CDateTime::GetCurrentDateTime()) - CLog::Log(LOGDEBUG, "%s - Assumed not recording since recording end time before current time: %s", - __FUNCTION__, end.GetAsLocalizedDateTime().c_str()); - else - { - CLog::Log(LOGDEBUG, "%s - Checking recording status using tuners since recording end time NULL or before current time: %s", - __FUNCTION__, end.GetAsLocalizedDateTime().c_str()); - for(int i=0;i<16 && !m_recording;i++) - { - cmyth_recorder_t recorder = m_dll->conn_get_recorder_from_num(m_control, i); - if(!recorder) - continue; - if(m_dll->recorder_is_recording(recorder)) - { - cmyth_proginfo_t program = m_dll->recorder_get_cur_proginfo(recorder); - - if(m_dll->proginfo_compare(program, m_program) == 0) - m_recording = true; - m_dll->ref_release(program); - } - m_dll->ref_release(recorder); - } - } - - if (m_recording) - CLog::Log(LOGDEBUG, "%s - Currently recording: %s", __FUNCTION__, m_filename.c_str()); - - return true; -} - -bool CMythFile::SetupLiveTV(const CURL& url) -{ - if (!StringUtils::StartsWith(url.GetFileName(), "channels/")) - return false; - - if(!SetupConnection(url, true, true, true)) - return false; - - std::string channel = url.GetFileNameWithoutPath(); - if(!URIUtils::HasExtension(channel, ".ts")) - { - CLog::Log(LOGERROR, "%s - invalid channel url %s", __FUNCTION__, channel.c_str()); - return false; - } - URIUtils::RemoveExtension(channel); - - for(int i=0;i<16;i++) - { - m_recorder = m_dll->conn_get_recorder_from_num(m_control, i); - if(!m_recorder) - continue; - - if(m_dll->recorder_is_recording(m_recorder)) - { - /* for now don't allow reuse of tuners, we would have to change tuner on channel * - * and make sure we don't stop the tuner when stopping playback as that affects * - * other clients */ -#if 0 - /* if already recording, check if it is this channel */ - cmyth_proginfo_t program; - program = m_dll->recorder_get_cur_proginfo(m_recorder); - if(program) - { - if(channel == GetValue(m_dll->proginfo_chanstr(program))) - { - m_dll->ref_release(program); - break; - } - m_dll->ref_release(program); - } -#endif - } - else - { - /* not recording, check if it supports this channel */ - if(m_dll->recorder_check_channel(m_recorder, (char*)channel.c_str()) == 0) - break; - } - m_dll->ref_release(m_recorder); - m_recorder = NULL; - } - - if(!m_recorder) - { - CLog::Log(LOGERROR, "%s - unable to get recorder", __FUNCTION__); - return false; - } - - m_recording = !!m_dll->recorder_is_recording(m_recorder); - if(!m_recording) - CLog::Log(LOGDEBUG, "%s - recorder isn't running, let's start it", __FUNCTION__); - - char* msg = NULL; - if(!(m_recorder = m_dll->spawn_live_tv(m_recorder, 16*1024, 4096, prog_update_callback, &msg, (char*)channel.c_str()))) - { - CLog::Log(LOGERROR, "%s - unable to spawn live tv: %s", __FUNCTION__, msg ? msg : ""); - return false; - } - - m_program = m_dll->recorder_get_cur_proginfo(m_recorder); - m_timestamp = XbmcThreads::SystemClockMillis(); - - if(m_recording) - { - /* recorder was running when we started, seek to last position */ - if(!m_dll->livetv_seek(m_recorder, 0, SEEK_END)) - CLog::Log(LOGDEBUG, "%s - failed to seek to last position", __FUNCTION__); - } - - m_filename = GetValue(m_dll->recorder_get_filename(m_recorder)); - return true; -} - -bool CMythFile::SetupFile(const CURL& url) -{ - if (!StringUtils::StartsWith(url.GetFileName(), "files/")) - return false; - - if(!SetupConnection(url, true, false, false)) - return false; - - m_filename = url.GetFileName().substr(6); - - m_file = m_dll->conn_connect_path((char*)m_filename.c_str(), m_control, 16*1024, 4096); - if(!m_file) - { - CLog::Log(LOGERROR, "%s - unable to connect to file", __FUNCTION__); - return false; - } - - if(m_dll->file_length(m_file) == 0) - { - CLog::Log(LOGERROR, "%s - file is empty, probably doesn't even exist", __FUNCTION__); - return false; - } - - return true; -} - -bool CMythFile::Open(const CURL& url) -{ - Close(); - - std::string path(url.GetFileName()); - - if (StringUtils::StartsWith(path, "recordings/") || - StringUtils::StartsWith(path, "movies/") || - StringUtils::StartsWith(path, "tvshows/")) - { - if(!SetupRecording(url)) - return false; - - CLog::Log(LOGDEBUG, "%s - file: size %" PRIu64", start %" PRIu64", ", __FUNCTION__, (int64_t)m_dll->file_length(m_file), (int64_t)m_dll->file_start(m_file)); - } - else if (StringUtils::StartsWith(path, "channels/")) - { - - if(!SetupLiveTV(url)) - return false; - - CLog::Log(LOGDEBUG, "%s - recorder has started on filename %s", __FUNCTION__, m_filename.c_str()); - } - else if (StringUtils::StartsWith(path, "files/")) - { - if(!SetupFile(url)) - return false; - - CLog::Log(LOGDEBUG, "%s - file: size %" PRId64", start %" PRId64", ", __FUNCTION__, (int64_t)m_dll->file_length(m_file), (int64_t)m_dll->file_start(m_file)); - } - else - { - CLog::Log(LOGERROR, "%s - invalid path specified %s", __FUNCTION__, path.c_str()); - return false; - } - - /* check for any events */ - HandleEvents(); - - return true; -} - - -void CMythFile::Close() -{ - if(!m_dll) - return; - - if(m_program) - { - m_dll->ref_release(m_program); - m_program = NULL; - } - if(m_recorder) - { - m_dll->recorder_stop_livetv(m_recorder); - m_dll->ref_release(m_recorder); - m_recorder = NULL; - } - if(m_file) - { - m_dll->ref_release(m_file); - m_file = NULL; - } - if(m_session) - { - m_session->SetListener(NULL); - CMythSession::ReleaseSession(m_session); - m_session = NULL; - } -} - -CMythFile::CMythFile() -{ - m_dll = NULL; - m_program = NULL; - m_recorder = NULL; - m_control = NULL; - m_database = NULL; - m_file = NULL; - m_session = NULL; - m_timestamp = 0; - m_recording = false; -} - -CMythFile::~CMythFile() -{ - Close(); -} - -bool CMythFile::Exists(const CURL& url) -{ - std::string path(url.GetFileName()); - - /* - * mythbackend provides access to the .mpg or .nuv recordings. The associated thumbnails - * (*.mpg.png or *.nuv.png) and channel icons, which are an arbitrary image format, are requested - * through the files/ path. - */ - if ((StringUtils::StartsWith(path, "recordings/") - || StringUtils::StartsWith(path, "movies/") - || StringUtils::StartsWith(path, "tvshows/")) - && (URIUtils::HasExtension(path, ".mpg|.nuv"))) - { - if(!SetupConnection(url, true, false, false)) - return false; - - m_filename = url.GetFileNameWithoutPath(); - m_program = m_dll->proginfo_get_from_basename(m_control, m_filename.c_str()); - if(!m_program) - { - CLog::Log(LOGERROR, "%s - unable to get find %s", __FUNCTION__, m_filename.c_str()); - return false; - } - return true; - } - else if(StringUtils::StartsWith(path, "files/")) - return true; - - return false; -} - -bool CMythFile::Delete(const CURL& url) -{ - std::string path(url.GetFileName()); - - if (StringUtils::StartsWith(path, "recordings/") || - StringUtils::StartsWith(path, "movies/") || - StringUtils::StartsWith(path, "tvshows/")) - { - /* this will setup all interal variables */ - if(!Exists(url)) - return false; - if(!m_program) - return false; - - if(m_dll->proginfo_delete_recording(m_control, m_program)) - { - CLog::Log(LOGDEBUG, "%s - Error deleting recording: %s", __FUNCTION__, url.GetFileName().c_str()); - return false; - } - - if (StringUtils::StartsWith(path, "tvshows/")) - { - /* - * Clear the directory cache for the TV Shows folder so the listing is accurate if this was - * the last TV Show in the current directory that was deleted. - */ - CURL tvshows(url); - tvshows.SetFileName("tvshows/"); - g_directoryCache.ClearDirectory(tvshows.Get()); - } - - /* - * Reset the recorded programs cache so the updated list is retrieved from mythbackend. - */ - m_session->ResetAllRecordedPrograms(); - - return true; - } - return false; -} - -int64_t CMythFile::Seek(int64_t pos, int whence) -{ - CLog::Log(LOGDEBUG, "%s - seek to pos %" PRId64", whence %d", __FUNCTION__, pos, whence); - - if(m_recorder) // Live TV - return -1; // Seeking not possible. Eventually will use m_dll->livetv_seek(m_recorder, pos, whence); - - if(m_file) // Recording - { - if (whence == 16) // SEEK_POSSIBLE = 0x10 = 16 - return 1; - else - return m_dll->file_seek(m_file, pos, whence); - } - return -1; -} - -int64_t CMythFile::GetPosition() -{ - if(m_recorder) - return m_dll->livetv_seek(m_recorder, 0, SEEK_CUR); - else - return m_dll->file_seek(m_file, 0, SEEK_CUR); - return -1; -} - -int64_t CMythFile::GetLength() -{ - if(m_file) - return m_dll->file_length(m_file); - return -1; -} - -ssize_t CMythFile::Read(void* buffer, size_t size) -{ - /* check for any events */ - HandleEvents(); - - /* file might have gotten closed */ - if(!m_recorder && !m_file) - return -1; - - if (size > SSIZE_MAX) - size = SSIZE_MAX; - - int ret; - if(m_recorder) - ret = m_dll->livetv_read(m_recorder, (char*)buffer, (unsigned long)size); - else - ret = m_dll->file_read(m_file, (char*)buffer, (unsigned long)size); - - if(ret < 0) - CLog::Log(LOGERROR, "%s - cmyth read returned error %d", __FUNCTION__, ret); - - return ret; -} - -bool CMythFile::SkipNext() -{ - HandleEvents(); - if(m_recorder) - return m_dll->recorder_is_recording(m_recorder) > 0; - - return false; -} - -bool CMythFile::UpdateItem(CFileItem& item) -{ - /* - * UpdateItem should only return true if a LiveTV item has changed via a channel change, or the - * program being aired on the current channel has changed requiring the UI to update the currently - * playing information. - * - * Check by comparing the current title with the new title. - */ - if (!m_recorder) - return false; - - if (!m_program || !m_session) - return false; - - std::string title = item.m_strTitle; - m_session->SetFileItemMetaData(item, m_program); - return title != item.m_strTitle; -} - -int CMythFile::GetTotalTime() -{ - if(m_recorder && (XbmcThreads::SystemClockMillis() - m_timestamp) > 5000 ) - { - m_timestamp = XbmcThreads::SystemClockMillis(); - if(m_program) - m_dll->ref_release(m_program); - m_program = m_dll->recorder_get_cur_proginfo(m_recorder); - } - - if(m_program && m_recorder) - return m_dll->proginfo_length_sec(m_program) * 1000; - - return -1; -} - -int CMythFile::GetStartTime() -{ - if(m_program && m_recorder) - { - cmyth_timestamp_t start = m_dll->proginfo_start(m_program); - - CDateTimeSpan time; - time = CDateTime::GetCurrentDateTime() - - CDateTime(m_dll->timestamp_to_unixtime(start)); - - m_dll->ref_release(start); - return time.GetDays() * 1000 * 60 * 60 * 24 - + time.GetHours() * 1000 * 60 * 60 - + time.GetMinutes() * 1000 * 60 - + time.GetSeconds() * 1000; - } - return 0; -} - -bool CMythFile::ChangeChannel(int direction, const std::string &channel) -{ - CLog::Log(LOGDEBUG, "%s - channel change started", __FUNCTION__); - - if(direction == CHANNEL_DIRECTION_SAME) - { - if(!m_program || channel != GetValue(m_dll->proginfo_chanstr(m_program))) - { - if(m_dll->recorder_pause(m_recorder) < 0) - { - CLog::Log(LOGDEBUG, "%s - failed to pause recorder", __FUNCTION__); - return false; - } - - CLog::Log(LOGDEBUG, "%s - chainging channel to %s", __FUNCTION__, channel.c_str()); - if(m_dll->recorder_set_channel(m_recorder, (char*)channel.c_str()) < 0) - { - CLog::Log(LOGDEBUG, "%s - failed to change channel", __FUNCTION__); - return false; - } - } - } - else - { - if(m_dll->recorder_pause(m_recorder) < 0) - { - CLog::Log(LOGDEBUG, "%s - failed to pause recorder", __FUNCTION__); - return false; - } - - CLog::Log(LOGDEBUG, "%s - chainging channel direction %d", __FUNCTION__, direction); - if(m_dll->recorder_change_channel(m_recorder, (cmyth_channeldir_t)direction) < 0) - { - CLog::Log(LOGDEBUG, "%s - failed to change channel", __FUNCTION__); - return false; - } - } - - if(!m_dll->livetv_chain_switch_last(m_recorder)) - CLog::Log(LOGDEBUG, "%s - failed to change to last item in chain", __FUNCTION__); - - if(m_program) - m_dll->ref_release(m_program); - m_program = m_dll->recorder_get_cur_proginfo(m_recorder); - - CLog::Log(LOGDEBUG, "%s - channel change done", __FUNCTION__); - return true; -} - -bool CMythFile::NextChannel(bool preview) -{ - return ChangeChannel(CHANNEL_DIRECTION_UP, ""); -} - -bool CMythFile::PrevChannel(bool preview) -{ - return ChangeChannel(CHANNEL_DIRECTION_DOWN, ""); -} - -bool CMythFile::SelectChannel(unsigned int channel) -{ - return ChangeChannel(CHANNEL_DIRECTION_SAME, StringUtils::Format("%d", channel)); -} - -bool CMythFile::CanRecord() -{ - if(m_recorder || m_recording) - return true; - - return false; -} - -bool CMythFile::IsRecording() -{ - return m_recording; -} - -bool CMythFile::Record(bool bOnOff) -{ - if(m_recorder) - { - if(!m_database) - return false; - - int ret; - if(bOnOff) - ret = m_dll->livetv_keep_recording(m_recorder, m_database, 1); - else - ret = m_dll->livetv_keep_recording(m_recorder, m_database, 0); - - if(ret < 0) - { - CLog::Log(LOGERROR, "%s - failed to turn on recording", __FUNCTION__); - return false; - } - - m_recording = bOnOff; - return true; - } - else - { - if(m_recording) - { - if(m_dll->proginfo_stop_recording(m_control, m_program) < 0) - return false; - - m_recording = false; - return true; - } - } - return false; -} - -bool CMythFile::GetCommBreakList(cmyth_commbreaklist_t& commbreaklist) -{ - if (m_program) - { - commbreaklist = m_dll->get_commbreaklist(m_control, m_program); - return true; - } - return false; -} - -bool CMythFile::GetCutList(cmyth_commbreaklist_t& commbreaklist) -{ - if (m_program) - { - commbreaklist = m_dll->get_cutlist(m_control, m_program); - return true; - } - return false; -} - -int CMythFile::IoControl(EIoControl request, void* param) -{ - if(request == IOCTRL_SEEK_POSSIBLE) - { - if(m_recorder) - return 0; - else - return 1; - } - return -1; -} diff --git a/xbmc/filesystem/MythFile.h b/xbmc/filesystem/MythFile.h deleted file mode 100644 index 70a7ac513c..0000000000 --- a/xbmc/filesystem/MythFile.h +++ /dev/null @@ -1,117 +0,0 @@ -#pragma once -/* - * Copyright (C) 2005-2013 Team XBMC - * http://xbmc.org - * - * This Program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2, or (at your option) - * any later version. - * - * This Program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with XBMC; see the file COPYING. If not, see - * <http://www.gnu.org/licenses/>. - * - */ - -#include "IFile.h" -#include "ILiveTV.h" -#include "MythSession.h" -#include "XBDateTime.h" -#include "video/VideoInfoTag.h" -#include <queue> - -extern "C" { -#include "cmyth/include/cmyth/cmyth.h" -} - -class DllLibCMyth; - -namespace XFILE -{ - - -class CMythFile - : public IFile - , ILiveTVInterface - , IRecordable - , private CMythSession::IEventListener -{ -public: - CMythFile(); - virtual ~CMythFile(); - virtual bool Open(const CURL& url); - virtual int64_t Seek(int64_t pos, int whence=SEEK_SET); - virtual int64_t GetPosition(); - virtual int64_t GetLength(); - virtual int Stat(const CURL& url, struct __stat64* buffer) { return -1; } - virtual void Close(); - virtual ssize_t Read(void* buffer, size_t size); - virtual std::string GetContent() { return ""; } - virtual bool SkipNext(); - - virtual bool Delete(const CURL& url); - virtual bool Exists(const CURL& url); - virtual int GetChunkSize() {return 1;}; - - virtual ILiveTVInterface* GetLiveTV() {return (ILiveTVInterface*)this;} - - virtual bool NextChannel(bool preview = false); - virtual bool PrevChannel(bool preview = false); - virtual bool SelectChannel(unsigned int channel); - - virtual int GetTotalTime(); - virtual int GetStartTime(); - - virtual bool UpdateItem(CFileItem& item); - - virtual IRecordable* GetRecordable() {return (IRecordable*)this;} - - virtual bool CanRecord(); - virtual bool IsRecording(); - virtual bool Record(bool bOnOff); - - virtual bool GetCommBreakList(cmyth_commbreaklist_t& commbreaklist); - virtual bool GetCutList(cmyth_commbreaklist_t& commbreaklist); - - virtual int IoControl(EIoControl request, void* param); -protected: - virtual void OnEvent(int event, const std::string& data); - - bool HandleEvents(); - bool ChangeChannel(int direction, const std::string &channel); - - bool SetupConnection(const CURL& url, bool control, bool event, bool database); - bool SetupRecording(const CURL& url); - bool SetupLiveTV(const CURL& url); - bool SetupFile(const CURL& url); - - std::string GetValue(char* str) { return m_session->GetValue(str); } - CDateTime GetValue(const cmyth_timestamp_t t) { return m_session->GetValue(t); } - - CMythSession* m_session; - DllLibCMyth* m_dll; - cmyth_conn_t m_control; - cmyth_database_t m_database; - cmyth_recorder_t m_recorder; - cmyth_proginfo_t m_program; - cmyth_file_t m_file; - std::string m_filename; - CVideoInfoTag m_infotag; - - CCriticalSection m_section; - std::queue<std::pair<int, std::string> > m_events; - - bool m_recording; - - unsigned int m_timestamp; -}; - -} - - diff --git a/xbmc/filesystem/MythSession.cpp b/xbmc/filesystem/MythSession.cpp deleted file mode 100644 index 5c73aa57d5..0000000000 --- a/xbmc/filesystem/MythSession.cpp +++ /dev/null @@ -1,622 +0,0 @@ -/* - * Copyright (C) 2005-2013 Team XBMC - * http://xbmc.org - * - * This Program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2, or (at your option) - * any later version. - * - * This Program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with XBMC; see the file COPYING. If not, see - * <http://www.gnu.org/licenses/>. - * - */ - -#include "threads/SystemClock.h" -#include "DllLibCMyth.h" -#include "MythSession.h" -#include "video/VideoInfoTag.h" -#include "settings/AdvancedSettings.h" -#include "XBDateTime.h" -#include "FileItem.h" -#include "URL.h" -#include "utils/URIUtils.h" -#include "utils/StringUtils.h" -#include "threads/SingleLock.h" -#include "utils/log.h" -#include "utils/TimeUtils.h" - -extern "C" -{ -#include "cmyth/include/cmyth/cmyth.h" -#include "cmyth/include/refmem/refmem.h" -} - -using namespace XFILE; -using namespace std; - -#define MYTH_DEFAULT_PORT 6543 -#define MYTH_DEFAULT_USERNAME "mythtv" -#define MYTH_DEFAULT_PASSWORD "mythtv" -#define MYTH_DEFAULT_DATABASE "mythconverg" - -#define MYTH_IDLE_TIMEOUT 5 * 60 // 5 minutes in seconds - -CCriticalSection CMythSession::m_section_session; -vector<CMythSession*> CMythSession::m_sessions; - -void CMythSession::CheckIdle() -{ - CSingleLock lock(m_section_session); - - vector<CMythSession*>::iterator it; - for (it = m_sessions.begin(); it != m_sessions.end(); ) - { - CMythSession* session = *it; - if ((XbmcThreads::SystemClockMillis() - session->m_timestamp) > (MYTH_IDLE_TIMEOUT * 1000) ) - { - CLog::Log(LOGINFO, "%s - closing idle connection to MythTV backend: %s", __FUNCTION__, session->m_hostname.c_str()); - delete session; - it = m_sessions.erase(it); - } - else - { - ++it; - } - } -} - -CMythSession* CMythSession::AquireSession(const CURL& url) -{ - CSingleLock lock(m_section_session); - - vector<CMythSession*>::iterator it; - for (it = m_sessions.begin(); it != m_sessions.end(); ++it) - { - CMythSession* session = *it; - if (session->CanSupport(url)) - { - m_sessions.erase(it); - CLog::Log(LOGDEBUG, "%s - Aquired existing MythTV session: %p", __FUNCTION__, session); - return session; - } - } - CMythSession* session = new CMythSession(url); - CLog::Log(LOGINFO, "%s - Aquired new MythTV session for %s: %p", __FUNCTION__, - url.GetWithoutUserDetails().c_str(), session); - return session; -} - -void CMythSession::ReleaseSession(CMythSession* session) -{ - CLog::Log(LOGDEBUG, "%s - Releasing MythTV session: %p", __FUNCTION__, session); - session->SetListener(NULL); - session->m_timestamp = XbmcThreads::SystemClockMillis(); - CSingleLock lock(m_section_session); - m_sessions.push_back(session); -} - -CDateTime CMythSession::GetValue(cmyth_timestamp_t t) -{ - CDateTime result; - if (t) - { - time_t time = m_dll->timestamp_to_unixtime(t); // Returns NULL if error - if (time) - result = CTimeUtils::GetLocalTime(time); - else - result = CTimeUtils::GetLocalTime(0); - m_dll->ref_release(t); - } - else // Return epoch so 0 and NULL behave the same. - result = CTimeUtils::GetLocalTime(0); - - return result; -} - -std::string CMythSession::GetValue(char *str) -{ - std::string result; - if (str) - { - result = str; - m_dll->ref_release(str); - StringUtils::Trim(result); - } - return result; -} - -void CMythSession::SetFileItemMetaData(CFileItem &item, cmyth_proginfo_t program) -{ - if (!program) - return; - - /* - * Set the FileItem meta-data. - */ - std::string title = GetValue(m_dll->proginfo_title(program)); // e.g. Mythbusters - std::string subtitle = GetValue(m_dll->proginfo_subtitle(program)); // e.g. The Pirate Special - item.m_strTitle = title; - if (!subtitle.empty()) - item.m_strTitle += " - \"" + subtitle + "\""; // e.g. Mythbusters - "The Pirate Special" - item.m_dateTime = GetValue(m_dll->proginfo_rec_start(program)); - item.m_dwSize = m_dll->proginfo_length(program); // size in bytes - - /* - * Set the VideoInfoTag meta-data so it matches the FileItem meta-data where possible. - */ - CVideoInfoTag* tag = item.GetVideoInfoTag(); - tag->m_strTitle = subtitle; // The title is just supposed to be the episode title. - tag->m_strShowTitle = title; - tag->m_strOriginalTitle = title; - tag->m_strPlotOutline = subtitle; - tag->m_strPlot = GetValue(m_dll->proginfo_description(program)); - /* - * TODO: Strip out the subtitle from the description if it is present at the start? OR add the - * subtitle to the start of the plot if not already as it used to? Seems strange, should be - * handled by skin? - * - if (tag->m_strPlot.Left(tag->m_strPlotOutline.length()) != tag->m_strPlotOutline && !tag->m_strPlotOutline.empty()) - tag->m_strPlot = tag->m_strPlotOutline + '\n' + tag->m_strPlot; - */ - tag->m_genre = StringUtils::Split(GetValue(m_dll->proginfo_category(program)), g_advancedSettings.m_videoItemSeparator); // e.g. Sports - tag->m_strAlbum = GetValue(m_dll->proginfo_chansign(program)); // e.g. TV3 - tag->m_duration = m_dll->proginfo_length_sec(program); - - SetSeasonAndEpisode(program, &tag->m_iSeason, &tag->m_iEpisode); - - /* - * Original air date is used by the VideoInfoScanner to scrape the TV Show information into the - * Video Library. If the original air date is empty the date returned will be the epoch. - */ - std::string originalairdate = GetValue(m_dll->proginfo_originalairdate(program)).GetAsDBDate(); - if (originalairdate != "1970-01-01" - && originalairdate != "1969-12-31") - tag->m_firstAired.SetFromDateString(originalairdate); - - /* - * Video sort title is the raw title with the date appended on the end in a sortable format so - * when the "All Recordings" listing is sorted by "Name" rather than "Date", all of the episodes - * for a given show are still presented in date order (even though some may have a subtitle that - * would cause it to be shown in a different position if it was indeed strictly sorting by - * what is displayed in the list). - */ - tag->m_strSortTitle = title + " " + item.m_dateTime.GetAsDBDateTime(); // e.g. Mythbusters 2009-12-13 12:23:14 - - /* - * Set further FileItem and VideoInfoTag meta-data based on whether it is LiveTV or not. - */ - CURL url(item.GetPath()); - if (StringUtils::StartsWith(url.GetFileName(), "channels/")) - { - /* - * Prepend the channel number onto the FileItem title for the listing so it's clear what is - * playing on each channel without using up as much room as the channel name. - */ - std::string number = GetValue(m_dll->proginfo_chanstr(program)); - item.m_strTitle = number + " - " + item.m_strTitle; - - /* - * Append the channel name onto the end of the tag title for the OSD so it's clear what LiveTV - * channel is currently being watched to give some context for Next or Previous channel. Added - * to the end so sorting by title will work, and it's not really as important as the title - * within the OSD. - */ - std::string name = GetValue(m_dll->proginfo_chansign(program)); - if (!name.empty()) - tag->m_strTitle += " - " + name; - - /* - * Set the sort title to be the channel number. - */ - tag->m_strSortTitle = number; - - /* - * Set the status so XBMC treats the content as LiveTV. - */ - tag->m_strStatus = "livetv"; - - /* - * Update the path and channel icon for LiveTV in case the channel has changed through - * NextChannel(), PreviousChannel() or SetChannel(). - */ - if (!number.empty()) - { - url.SetFileName("channels/" + number + ".ts"); // e.g. channels/3.ts - item.SetPath(url.Get()); - } - std::string chanicon = GetValue(m_dll->proginfo_chanicon(program)); - if (!chanicon.empty()) - { - url.SetFileName("files/channels/" + URIUtils::GetFileName(chanicon)); // e.g. files/channels/tv3.jpg - item.SetArt("thumb", url.Get()); - } - } - else - { - /* - * MythTV thumbnails aren't generated until a program has finished recording. - */ - if (m_dll->proginfo_rec_status(program) == RS_RECORDED) - { - url.SetFileName("files/" + URIUtils::GetFileName(GetValue(m_dll->proginfo_pathname(program))) + ".png"); - item.SetArt("thumb", url.Get()); - } - } -} - -void CMythSession::SetSeasonAndEpisode(const cmyth_proginfo_t &program, int *season, int *episode) { - /* - * A valid programid generated from an XMLTV source should look like: - * [EP|MV|SH|SP][seriesid][episode][season]([partnumber][parttotal]) - * mythtv/trunk/programs/mytfilldatabaseline/xmltvparser.cpp - Line 522 onwards. - * - * Season changed to a base36 character for XMLTV in Myth 0.24. http://svn.mythtv.org/trac/changeset/24724 - * - * A valid SchedulesDirect programid appears to have a similar format to the XMLTV programid but - * doesn't have any obvious way to parse out the season and episode information. The number at the - * end of the programid could possibly be the completely sequential number for the episode, but - * even that doesn't seem to match up with TVDB. SchedulesDirect data does seem to have a valid - * original air date though, so if we identify a SchedulesDirect programid, leave the season and - * episode as 0. - */ - std::string programid = GetValue(m_dll->proginfo_programid(program)); - std::string seriesid = GetValue(m_dll->proginfo_seriesid(program)); - - /* - * Default the season and episode to 0 so XBMC treats the content as an episode and displays tag - * information. If the season and episode can be parsed from the programid these will be - * overwritten. - */ - *season = 0; - *episode = 0; - - if (programid.empty() // Can't do anything if the program ID is empty - || seriesid.empty()) // Can't figure out the end parsing if the series ID is empty { - return; - - std::string category = programid.substr(0, 2); // Valid for both XMLTV and SchedulesDirect sources - if (category != "MV" // Movie - && category != "EP" // Series - && category != "SH" // TV Show - && category != "SP") // Sports - return; - - if (programid.substr(category.length(), seriesid.length()) != seriesid) // Series ID does not follow the category - return; - - std::string remainder = programid.substr(category.length() + seriesid.length()); // Whatever is after series ID - - /* - * All SchedulesDirect remainders appear to be 4 characters and start with a 0. If the assumption - * is correct that the number somehow relates to the sequential episode number across all seasons - * then we can ignore remainders that start with 0. It will be very unlikely for a sequential - * episode number for a series to be > 999. - */ - if (remainder.length() == 4 // All SchedulesDirect codes seem to be 4 characters - && remainder[0] == '0') // Padded with 0's for low number. No valid XMLTV remainder will start with 0. - return; - - /* - * If the remainder is more than 5 characters, it must include the optional part number and total - * number of parts. Strip off the last 2 characters assuming that there are ridiculously few - * cases where the number of parts for a single episode is > 9. - */ - if (remainder.length() >= 5) // Must include optional part number and total number of parts - remainder = remainder.substr(0, remainder.length() - 2); // Assumes part number and total are both < 10 - - /* - * Now for some heuristic black magic. - */ - if (remainder.length() == 2) // Single character season and episode. - { - *season = atoi(remainder.substr(1, 1).c_str()); // TODO: Fix for base 36 in Myth 0.24. Assume season < 10 - *episode = atoi(remainder.substr(0, 1).c_str()); - } - else if (remainder.length() == 3) // Ambiguous in Myth 0.23. Single character season in Myth 0.24 - { - /* - * Following heuristics are intended to work with largest possible number of cases. It won't be - * perfect, but way better than just assuming the season is < 10. - */ - if (remainder[2] == '0') // e.g. 610. Unlikely to have a season of 0 (specials) with more than 9 special episodes. - { - *season = atoi(remainder.substr(1, 2).c_str()); - *episode = atoi(remainder.substr(0, 1).c_str()); - } - else if (remainder[1] == '0') // e.g. 203. Can't have a season start with 0. Must be end of episode. - { - *season = atoi(remainder.substr(2, 1).c_str()); // TODO: Fix for base 36 in Myth 0.24. Assume season < 10 - *episode = atoi(remainder.substr(0, 2).c_str()); - } - else if (atoi(remainder.substr(0, 1).c_str()) > 3) // e.g. 412. Very unlikely to have more than 39 episodes per season if season > 9. - { - /* - * TODO: See if a check for > 2 is better, e.g. is it still unlike to have more than 29 episodes - * per season if season > 9? - */ - *season = atoi(remainder.substr(1, 2).c_str()); - *episode = atoi(remainder.substr(0, 1).c_str()); - } - else // e.g. 129. Assume season is < 10 or Myth 0.24 Base 36 season. - { - *season = atoi(remainder.substr(2, 1).c_str()); // TODO: Fix for base 36 in Myth 0.24. Assume season < 10 - *episode = atoi(remainder.substr(0, 2).c_str()); - } - } - else if (remainder.length() == 4) // Double digit season and episode in Myth 0.23 OR TODO: has part number and total number of parts - { - *season = atoi(remainder.substr(2, 2).c_str()); - *episode = atoi(remainder.substr(0, 2).c_str()); - } - return; -} - -CMythSession::CMythSession(const CURL& url) : CThread("MythSession"), - m_hostname(url.GetHostName()), - m_username(url.GetUserName() == "" ? MYTH_DEFAULT_USERNAME : url.GetUserName()), - m_password(url.GetPassWord() == "" ? MYTH_DEFAULT_PASSWORD : url.GetPassWord()) -{ - m_control = NULL; - m_event = NULL; - m_database = NULL; - m_listener = NULL; - m_port = url.HasPort() ? url.GetPort() : MYTH_DEFAULT_PORT; - m_timestamp = XbmcThreads::SystemClockMillis(); - m_dll = new DllLibCMyth; - m_dll->Load(); - if (m_dll->IsLoaded()) - { - m_dll->set_dbg_msgcallback(&CMythSession::LogCMyth); - if (g_advancedSettings.CanLogComponent(LOGCMYTH)) - m_dll->dbg_level(CMYTH_DBG_ALL); - else if (g_advancedSettings.m_logLevel >= LOG_LEVEL_DEBUG) - m_dll->dbg_level(CMYTH_DBG_DETAIL); - else - m_dll->dbg_level(CMYTH_DBG_ERROR); - } - m_all_recorded = NULL; -} - -CMythSession::~CMythSession() -{ - Disconnect(); - delete m_dll; -} - -bool CMythSession::CanSupport(const CURL& url) -{ - if (m_hostname != url.GetHostName()) - return false; - - if (m_port != (url.HasPort() ? url.GetPort() : MYTH_DEFAULT_PORT)) - return false; - - if (m_username != (url.GetUserName() == "" ? MYTH_DEFAULT_USERNAME : url.GetUserName())) - return false; - - if (m_password != (url.GetPassWord() == "" ? MYTH_DEFAULT_PASSWORD : url.GetPassWord())) - return false; - - return true; -} - -void CMythSession::Process() -{ - char buf[128]; - int next; - - struct timeval to; - - while (!m_bStop) - { - /* check if there are any new events */ - to.tv_sec = 0; - to.tv_usec = 100000; - if (m_dll->event_select(m_event, &to) <= 0) - continue; - - next = m_dll->event_get(m_event, buf, sizeof(buf)); - buf[sizeof(buf) - 1] = 0; - - switch (next) - { - case CMYTH_EVENT_UNKNOWN: - CLog::Log(LOGDEBUG, "%s - MythTV event UNKNOWN (error?)", __FUNCTION__); - break; - case CMYTH_EVENT_CLOSE: - CLog::Log(LOGDEBUG, "%s - MythTV event EVENT_CLOSE", __FUNCTION__); - break; - case CMYTH_EVENT_RECORDING_LIST_CHANGE: - CLog::Log(LOGDEBUG, "%s - MythTV event RECORDING_LIST_CHANGE", __FUNCTION__); - ResetAllRecordedPrograms(); - break; - case CMYTH_EVENT_RECORDING_LIST_CHANGE_ADD: - CLog::Log(LOGDEBUG, "%s - MythTV event RECORDING_LIST_CHANGE_ADD: %s", __FUNCTION__, buf); - ResetAllRecordedPrograms(); - break; - case CMYTH_EVENT_RECORDING_LIST_CHANGE_UPDATE: - CLog::Log(LOGDEBUG, "%s - MythTV event RECORDING_LIST_CHANGE_UPDATE", __FUNCTION__); - ResetAllRecordedPrograms(); - break; - case CMYTH_EVENT_RECORDING_LIST_CHANGE_DELETE: - CLog::Log(LOGDEBUG, "%s - MythTV event RECORDING_LIST_CHANGE_DELETE: %s", __FUNCTION__, buf); - ResetAllRecordedPrograms(); - break; - case CMYTH_EVENT_SCHEDULE_CHANGE: - CLog::Log(LOGDEBUG, "%s - MythTV event SCHEDULE_CHANGE", __FUNCTION__); - break; - case CMYTH_EVENT_DONE_RECORDING: - CLog::Log(LOGDEBUG, "%s - MythTV event DONE_RECORDING", __FUNCTION__); - break; - case CMYTH_EVENT_QUIT_LIVETV: - CLog::Log(LOGDEBUG, "%s - MythTV event QUIT_LIVETV", __FUNCTION__); - break; - case CMYTH_EVENT_WATCH_LIVETV: - CLog::Log(LOGDEBUG, "%s - MythTV event LIVETV_WATCH", __FUNCTION__); - break; - case CMYTH_EVENT_LIVETV_CHAIN_UPDATE: - CLog::Log(LOGDEBUG, "%s - MythTV event LIVETV_CHAIN_UPDATE: %s", __FUNCTION__, buf); - break; - case CMYTH_EVENT_SIGNAL: - CLog::Log(LOGDEBUG, "%s - MythTV event SIGNAL", __FUNCTION__); - break; - case CMYTH_EVENT_ASK_RECORDING: - CLog::Log(LOGDEBUG, "%s - MythTV event ASK_RECORDING", __FUNCTION__); - break; - case CMYTH_EVENT_SYSTEM_EVENT: - CLog::Log(LOGDEBUG, "%s - MythTV event SYSTEM_EVENT: %s", __FUNCTION__, buf); - break; - case CMYTH_EVENT_UPDATE_FILE_SIZE: - CLog::Log(LOGDEBUG, "%s - MythTV event UPDATE_FILE_SIZE: %s", __FUNCTION__, buf); - break; - case CMYTH_EVENT_GENERATED_PIXMAP: - CLog::Log(LOGDEBUG, "%s - MythTV event GENERATED_PIXMAP: %s", __FUNCTION__, buf); - break; - case CMYTH_EVENT_CLEAR_SETTINGS_CACHE: - CLog::Log(LOGDEBUG, "%s - MythTV event CLEAR_SETTINGS_CACHE", __FUNCTION__); - break; - } - - { - CSingleLock lock(m_section); - if (m_listener) - m_listener->OnEvent(next, buf); - } - } -} - -void CMythSession::Disconnect() -{ - if (!m_dll || !m_dll->IsLoaded()) - return; - - StopThread(); - - if (m_control) - m_dll->ref_release(m_control); - if (m_event) - m_dll->ref_release(m_event); - if (m_database) - m_dll->ref_release(m_database); - if (m_all_recorded) - m_dll->ref_release(m_all_recorded); -} - -cmyth_conn_t CMythSession::GetControl() -{ - if (!m_control) - { - if (!m_dll->IsLoaded()) - return NULL; - - m_control = m_dll->conn_connect_ctrl((char*)m_hostname.c_str(), m_port, 16*1024, 4096); - if (!m_control) - CLog::Log(LOGERROR, "%s - unable to connect to server on %s:%d", __FUNCTION__, m_hostname.c_str(), m_port); - } - return m_control; -} - -cmyth_database_t CMythSession::GetDatabase() -{ - if (!m_database) - { - if (!m_dll->IsLoaded()) - return NULL; - - m_database = m_dll->database_init((char*)m_hostname.c_str(), (char*)MYTH_DEFAULT_DATABASE, - (char*)m_username.c_str(), (char*)m_password.c_str()); - if (!m_database) - CLog::Log(LOGERROR, "%s - unable to connect to database on %s:%d", __FUNCTION__, m_hostname.c_str(), m_port); - } - return m_database; -} - -bool CMythSession::SetListener(IEventListener *listener) -{ - if (!m_event && listener) - { - if (!m_dll->IsLoaded()) - return false; - - m_event = m_dll->conn_connect_event((char*)m_hostname.c_str(), m_port, 16*1024 , 4096); - if (!m_event) - { - CLog::Log(LOGERROR, "%s - unable to connect to server on %s:%d", __FUNCTION__, m_hostname.c_str(), m_port); - return false; - } - /* start event handler thread */ - CThread::Create(false, THREAD_MINSTACKSIZE); - } - CSingleLock lock(m_section); - m_listener = listener; - return true; -} - -DllLibCMyth* CMythSession::GetLibrary() -{ - if (m_dll->IsLoaded()) - return m_dll; - return NULL; -} - -/* - * The caller must call m_dll->ref_release() when finished. - */ -cmyth_proglist_t CMythSession::GetAllRecordedPrograms() -{ - CSingleLock lock(m_section); - if (!m_all_recorded) - { - if (m_all_recorded) - { - m_dll->ref_release(m_all_recorded); - m_all_recorded = NULL; - } - cmyth_conn_t control = GetControl(); - if (!control) - return NULL; - - m_all_recorded = m_dll->proglist_get_all_recorded(control); - } - /* - * An extra reference is needed to prevent a race condition while resetting the proglist from - * the Process() thread while it is being read. - */ - m_dll->ref_hold(m_all_recorded); - - return m_all_recorded; -} - -void CMythSession::ResetAllRecordedPrograms() -{ - CSingleLock lock(m_section); - if (m_all_recorded) - { - m_dll->ref_release(m_all_recorded); - m_all_recorded = NULL; - } - return; -} - -void CMythSession::LogCMyth(int level, char *msg) -{ - int xbmc_lvl = -1; - switch (level) - { - case CMYTH_DBG_NONE: break; - case CMYTH_DBG_ERROR: xbmc_lvl = LOGERROR; break; - case CMYTH_DBG_WARN: xbmc_lvl = LOGWARNING; break; - case CMYTH_DBG_INFO: xbmc_lvl = LOGINFO; break; - default: xbmc_lvl = LOGDEBUG; break; - } - if (xbmc_lvl >= 0) { - CLog::Log(xbmc_lvl, "%s", msg); - } -} diff --git a/xbmc/filesystem/MythSession.h b/xbmc/filesystem/MythSession.h deleted file mode 100644 index 6cc96eda36..0000000000 --- a/xbmc/filesystem/MythSession.h +++ /dev/null @@ -1,99 +0,0 @@ -#pragma once -/* - * Copyright (C) 2005-2013 Team XBMC - * http://xbmc.org - * - * This Program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2, or (at your option) - * any later version. - * - * This Program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with XBMC; see the file COPYING. If not, see - * <http://www.gnu.org/licenses/>. - * - */ - -#include <string> -#include "threads/CriticalSection.h" -#include "threads/Thread.h" - -typedef struct cmyth_ringbuf *cmyth_ringbuf_t; -typedef struct cmyth_conn *cmyth_conn_t; -typedef struct cmyth_recorder *cmyth_recorder_t; -typedef struct cmyth_proginfo *cmyth_proginfo_t; -typedef struct cmyth_proglist *cmyth_proglist_t; -typedef struct cmyth_file *cmyth_file_t; -typedef struct cmyth_database *cmyth_database_t; -typedef struct cmyth_timestamp *cmyth_timestamp_t; - -class DllLibCMyth; -class CDateTime; -class CFileItem; -class CURL; - -namespace XFILE -{ - -class CMythSession - : private CThread -{ -public: - static CMythSession* AquireSession(const CURL& url); - static void ReleaseSession(CMythSession*); - static void CheckIdle(); - static void LogCMyth(int level, char *msg); - - class IEventListener - { - public: - virtual ~IEventListener() {}; - virtual void OnEvent(int event, const std::string& data)=0; - }; - - bool SetListener(IEventListener *listener); - cmyth_conn_t GetControl(); - cmyth_database_t GetDatabase(); - DllLibCMyth* GetLibrary(); - cmyth_proglist_t GetAllRecordedPrograms(); - void ResetAllRecordedPrograms(); - - void SetFileItemMetaData(CFileItem &item, cmyth_proginfo_t program); - - CDateTime GetValue(cmyth_timestamp_t t); - std::string GetValue(char* str); - -private: - CMythSession(const CURL& url); - ~CMythSession(); - - virtual void Process(); - - bool CanSupport(const CURL& url); - void Disconnect(); - - void SetSeasonAndEpisode(const cmyth_proginfo_t &program, int *season, int *epsiode); - - IEventListener* m_listener; - cmyth_conn_t m_control; - cmyth_conn_t m_event; - cmyth_database_t m_database; - std::string m_hostname; - std::string m_username; - std::string m_password; - int m_port; - DllLibCMyth* m_dll; - CCriticalSection m_section; - unsigned int m_timestamp; - cmyth_proglist_t m_all_recorded; // Cache of all_recorded programs. - - static CCriticalSection m_section_session; - static std::vector<CMythSession*> m_sessions; -}; - -} diff --git a/xbmc/network/GUIDialogNetworkSetup.cpp b/xbmc/network/GUIDialogNetworkSetup.cpp index 723f7ba0aa..755d4e7803 100644 --- a/xbmc/network/GUIDialogNetworkSetup.cpp +++ b/xbmc/network/GUIDialogNetworkSetup.cpp @@ -120,9 +120,6 @@ void CGUIDialogNetworkSetup::OnInitWindow() #endif labels.push_back(make_pair(g_localizeStrings.Get(20256), NET_PROTOCOL_HTSP)); labels.push_back(make_pair(g_localizeStrings.Get(20257), NET_PROTOCOL_VTP)); -#ifdef HAS_MYSQL - labels.push_back(make_pair(g_localizeStrings.Get(20258), NET_PROTOCOL_MYTH)); -#endif labels.push_back(make_pair(g_localizeStrings.Get(20301), NET_PROTOCOL_HTTPS)); labels.push_back(make_pair(g_localizeStrings.Get(20300), NET_PROTOCOL_HTTP)); labels.push_back(make_pair(g_localizeStrings.Get(20254), NET_PROTOCOL_DAVS)); @@ -207,8 +204,6 @@ void CGUIDialogNetworkSetup::OnProtocolChange() m_port = "9982"; else if (m_protocol == NET_PROTOCOL_VTP) m_port = "2004"; - else if (m_protocol == NET_PROTOCOL_MYTH) - m_port = "6543"; else if (m_protocol == NET_PROTOCOL_SFTP) m_port = "22"; else @@ -238,8 +233,7 @@ void CGUIDialogNetworkSetup::UpdateButtons() CONTROL_ENABLE_ON_CONDITION(CONTROL_REMOTE_PATH, m_protocol != NET_PROTOCOL_DAAP && m_protocol != NET_PROTOCOL_UPNP && m_protocol != NET_PROTOCOL_HTSP && - m_protocol != NET_PROTOCOL_VTP && - m_protocol != NET_PROTOCOL_MYTH); + m_protocol != NET_PROTOCOL_VTP); if (m_protocol == NET_PROTOCOL_FTP || m_protocol == NET_PROTOCOL_HTTP || m_protocol == NET_PROTOCOL_HTTPS || @@ -275,7 +269,6 @@ void CGUIDialogNetworkSetup::UpdateButtons() m_protocol == NET_PROTOCOL_DAVS || m_protocol == NET_PROTOCOL_HTSP || m_protocol == NET_PROTOCOL_VTP || - m_protocol == NET_PROTOCOL_MYTH || m_protocol == NET_PROTOCOL_RSS || m_protocol == NET_PROTOCOL_DAAP || m_protocol == NET_PROTOCOL_SFTP); @@ -302,7 +295,6 @@ void CGUIDialogNetworkSetup::UpdateButtons() m_protocol == NET_PROTOCOL_RSS || m_protocol == NET_PROTOCOL_HTSP || m_protocol == NET_PROTOCOL_VTP || - m_protocol == NET_PROTOCOL_MYTH || m_protocol == NET_PROTOCOL_SFTP)); } @@ -331,8 +323,6 @@ std::string CGUIDialogNetworkSetup::ConstructPath() const url.SetProtocol("htsp"); else if (m_protocol == NET_PROTOCOL_VTP) url.SetProtocol("vtp"); - else if (m_protocol == NET_PROTOCOL_MYTH) - url.SetProtocol("myth"); else if (m_protocol == NET_PROTOCOL_NFS) url.SetProtocol("nfs"); else if (m_protocol == NET_PROTOCOL_SFTP) @@ -355,7 +345,6 @@ std::string CGUIDialogNetworkSetup::ConstructPath() const (m_protocol == NET_PROTOCOL_DAAP && !m_server.empty()) || (m_protocol == NET_PROTOCOL_HTSP) || (m_protocol == NET_PROTOCOL_VTP) || - (m_protocol == NET_PROTOCOL_MYTH) || (m_protocol == NET_PROTOCOL_SFTP) || (m_protocol == NET_PROTOCOL_NFS)) && !m_port.empty() && atoi(m_port.c_str()) > 0) @@ -390,8 +379,6 @@ void CGUIDialogNetworkSetup::SetPath(const std::string &path) m_protocol = NET_PROTOCOL_HTSP; else if (url.IsProtocol("vtp")) m_protocol = NET_PROTOCOL_VTP; - else if (url.IsProtocol("myth")) - m_protocol = NET_PROTOCOL_MYTH; else if (url.IsProtocol("rss")) m_protocol = NET_PROTOCOL_RSS; else if (url.IsProtocol("nfs")) diff --git a/xbmc/network/GUIDialogNetworkSetup.h b/xbmc/network/GUIDialogNetworkSetup.h index f46881a112..88c6adf021 100644 --- a/xbmc/network/GUIDialogNetworkSetup.h +++ b/xbmc/network/GUIDialogNetworkSetup.h @@ -38,7 +38,6 @@ public: NET_PROTOCOL_RSS, NET_PROTOCOL_HTSP, NET_PROTOCOL_VTP, - NET_PROTOCOL_MYTH, NET_PROTOCOL_SFTP, NET_PROTOCOL_NFS}; CGUIDialogNetworkSetup(void); diff --git a/xbmc/pvr/PVRActionListener.cpp b/xbmc/pvr/PVRActionListener.cpp index d1e9f10627..f1c99db71b 100644 --- a/xbmc/pvr/PVRActionListener.cpp +++ b/xbmc/pvr/PVRActionListener.cpp @@ -131,7 +131,7 @@ bool CPVRActionListener::OnAction(const CAction &action) } else { - // filesystem provider like slingbox, cmyth, etc + // filesystem provider like slingbox etc int iChannelNumber = -1; std::string strChannel = StringUtils::Format("%i", action.GetID() - REMOTE_0); if (CGUIDialogNumeric::ShowAndGetNumber(strChannel, g_localizeStrings.Get(19000))) diff --git a/xbmc/settings/AdvancedSettings.cpp b/xbmc/settings/AdvancedSettings.cpp index 277908c9c7..f66e32230b 100644 --- a/xbmc/settings/AdvancedSettings.cpp +++ b/xbmc/settings/AdvancedSettings.cpp @@ -288,8 +288,6 @@ void CAdvancedSettings::Initialize() m_bVideoScannerIgnoreErrors = false; m_iVideoLibraryDateAdded = 1; // prefer mtime over ctime and current time - m_iMythMovieLength = 0; // 0 == Off - m_iEpgLingerTime = 60 * 24; /* keep 24 hours by default */ m_iEpgUpdateCheckInterval = 300; /* check if tables need to be updated every 5 minutes */ m_iEpgCleanupInterval = 900; /* remove old entries from the EPG every 15 minutes */ @@ -860,13 +858,6 @@ void CAdvancedSettings::ParseSettingsFile(const std::string &file) XMLUtils::GetBoolean(pRootElement,"virtualshares", m_bVirtualShares); XMLUtils::GetUInt(pRootElement, "packagefoldersize", m_addonPackageFolderSize); - // Myth TV - pElement = pRootElement->FirstChildElement("myth"); - if (pElement) - { - XMLUtils::GetInt(pElement, "movielength", m_iMythMovieLength); - } - // EPG pElement = pRootElement->FirstChildElement("epg"); if (pElement) @@ -1345,7 +1336,6 @@ void CAdvancedSettings::SettingOptionsLoggingComponentsFiller(const CSetting *se { list.push_back(std::make_pair(g_localizeStrings.Get(669), LOGSAMBA)); list.push_back(std::make_pair(g_localizeStrings.Get(670), LOGCURL)); - list.push_back(std::make_pair(g_localizeStrings.Get(671), LOGCMYTH)); list.push_back(std::make_pair(g_localizeStrings.Get(672), LOGFFMPEG)); list.push_back(std::make_pair(g_localizeStrings.Get(676), LOGAUDIO)); list.push_back(std::make_pair(g_localizeStrings.Get(680), LOGVIDEO)); diff --git a/xbmc/settings/AdvancedSettings.h b/xbmc/settings/AdvancedSettings.h index 4b0e926e1b..f434ee30eb 100644 --- a/xbmc/settings/AdvancedSettings.h +++ b/xbmc/settings/AdvancedSettings.h @@ -289,8 +289,6 @@ class CAdvancedSettings : public ISettingCallback, public ISettingsHandler std::set<std::string> m_vecTokens; - int m_iMythMovieLength; // minutes - int m_iEpgLingerTime; // minutes int m_iEpgUpdateCheckInterval; // seconds int m_iEpgCleanupInterval; // seconds diff --git a/xbmc/utils/URIUtils.cpp b/xbmc/utils/URIUtils.cpp index 1bee06f7dd..2df435d094 100644 --- a/xbmc/utils/URIUtils.cpp +++ b/xbmc/utils/URIUtils.cpp @@ -23,7 +23,6 @@ #include "Application.h" #include "FileItem.h" #include "filesystem/MultiPathDirectory.h" -#include "filesystem/MythDirectory.h" #include "filesystem/SpecialProtocol.h" #include "filesystem/StackDirectory.h" #include "network/DNSNameCache.h" @@ -926,11 +925,6 @@ bool URIUtils::IsUPnP(const std::string& strFile) return IsProtocol(strFile, "upnp"); } -bool URIUtils::IsMythTV(const std::string& strFile) -{ - return IsProtocol(strFile, "myth"); -} - bool URIUtils::IsHDHomeRun(const std::string& strFile) { return IsProtocol(strFile, "hdhomerun"); @@ -964,9 +958,6 @@ bool URIUtils::IsLiveTV(const std::string& strFile) ||(StringUtils::EndsWithNoCase(strFileWithoutSlash, ".pvr") && !PathStarts(strFileWithoutSlash, "pvr://recordings"))) return true; - if (IsMythTV(strFile) && CMythDirectory::IsLiveTV(strFile)) - return true; - return false; } diff --git a/xbmc/utils/URIUtils.h b/xbmc/utils/URIUtils.h index 596ee98b91..500a85cc41 100644 --- a/xbmc/utils/URIUtils.h +++ b/xbmc/utils/URIUtils.h @@ -138,7 +138,6 @@ public: static bool IsPVRRecording(const std::string& strFile); static bool IsMultiPath(const std::string& strPath); static bool IsMusicDb(const std::string& strFile); - static bool IsMythTV(const std::string& strFile); static bool IsNfs(const std::string& strFile); static bool IsOnDVD(const std::string& strFile); static bool IsOnLAN(const std::string& strFile); diff --git a/xbmc/utils/test/TestURIUtils.cpp b/xbmc/utils/test/TestURIUtils.cpp index dd944f833e..ad2093b171 100644 --- a/xbmc/utils/test/TestURIUtils.cpp +++ b/xbmc/utils/test/TestURIUtils.cpp @@ -337,7 +337,6 @@ TEST_F(TestURIUtils, IsLiveTV) EXPECT_TRUE(URIUtils::IsLiveTV("sling://path/to/file")); EXPECT_TRUE(URIUtils::IsLiveTV("htsp://path/to/file")); EXPECT_TRUE(URIUtils::IsLiveTV("sap://path/to/file")); - EXPECT_TRUE(URIUtils::IsLiveTV("myth://path/channels/")); } TEST_F(TestURIUtils, IsMultiPath) @@ -350,11 +349,6 @@ TEST_F(TestURIUtils, IsMusicDb) EXPECT_TRUE(URIUtils::IsMusicDb("musicdb://path/to/file")); } -TEST_F(TestURIUtils, IsMythTV) -{ - EXPECT_TRUE(URIUtils::IsMythTV("myth://path/to/file")); -} - TEST_F(TestURIUtils, IsNfs) { EXPECT_TRUE(URIUtils::IsNfs("nfs://path/to/file")); |