cddb_daemon: renamed to cddb_lookup, moved to /src/bin.

* It's now a standard command line tool that is launched automatically
  via the launch_daemon whenver a volume is mounted.
This commit is contained in:
Axel Dörfler
2015-10-19 21:21:21 +02:00
parent 9939ccadff
commit cfe6baf62f
11 changed files with 118 additions and 150 deletions
+1 -1
View File
@@ -4,6 +4,7 @@
include [ FDirName $(HAIKU_BUILD_RULES_DIR) images definitions minimum ] ; include [ FDirName $(HAIKU_BUILD_RULES_DIR) images definitions minimum ] ;
SYSTEM_BIN += [ FFilterByBuildFeatures SYSTEM_BIN += [ FFilterByBuildFeatures
cddb_lookup
clipboard CortexAddOnHost clipboard CortexAddOnHost
FirstBootPrompt fwcontrol@x86 FirstBootPrompt fwcontrol@x86
installsound installsound
@@ -91,7 +92,6 @@ rule HaikuImageGetPrivateSystemLibs
SYSTEM_SERVERS += [ FFilterByBuildFeatures SYSTEM_SERVERS += [ FFilterByBuildFeatures
cddb_daemon
mail_daemon media_addon_server media_server midi_server mail_daemon media_addon_server media_server midi_server
nfs4_idmapper_server nfs4_idmapper_server
print_server print_addon_server print_server print_addon_server
+6 -6
View File
@@ -55,12 +55,6 @@ service x-vnd.Haiku-net_server {
legacy legacy
} }
service x-vnd.Haiku-cddb_daemon {
launch /system/servers/cddb_daemon
no_safemode
legacy
}
service x-vnd.Haiku-print_server { service x-vnd.Haiku-print_server {
launch /system/servers/print_server launch /system/servers/print_server
no_safemode no_safemode
@@ -79,6 +73,12 @@ service x-vnd.Haiku-power_daemon {
legacy legacy
} }
job x-vnd.Haiku-cddb_lookup {
launch /system/bin/cddb_lookup
no_safemode
on volume_mounted
}
job post-install { job post-install {
launch /bin/sh /system/boot/PostInstallScript launch /bin/sh /system/boot/PostInstallScript
if file_exists /boot/system/settings/fresh_install if file_exists /boot/system/settings/fresh_install
+1
View File
@@ -265,6 +265,7 @@ DoCatalogs filepanel
SubInclude HAIKU_TOP src bin addattr ; SubInclude HAIKU_TOP src bin addattr ;
SubInclude HAIKU_TOP src bin bc ; SubInclude HAIKU_TOP src bin bc ;
SubInclude HAIKU_TOP src bin bfs_tools ; SubInclude HAIKU_TOP src bin bfs_tools ;
SubInclude HAIKU_TOP src bin cddb_lookup ;
SubInclude HAIKU_TOP src bin compress ; SubInclude HAIKU_TOP src bin compress ;
SubInclude HAIKU_TOP src bin consoled ; SubInclude HAIKU_TOP src bin consoled ;
SubInclude HAIKU_TOP src bin coreutils ; SubInclude HAIKU_TOP src bin coreutils ;
+11
View File
@@ -0,0 +1,11 @@
SubDir HAIKU_TOP src bin cddb_lookup ;
UsePrivateHeaders drivers ;
AddResources cddb_lookup : cddb_lookup.rdef ;
BinCommand cddb_lookup :
cddb_lookup.cpp
cddb_server.cpp
: be bnetapi [ TargetLibsupc++ ]
;
@@ -1,80 +1,80 @@
/* /*
* Copyright 2008-2009, Haiku, Inc. All Rights Reserved. * Copyright 2008-2015, Haiku, Inc. All Rights Reserved.
* Distributed under the terms of the MIT License. * Distributed under the terms of the MIT License.
* *
* Authors: * Authors:
* Bruno Albuquerque, bga@bug-br.org.br * Axel Dörfler, axeld@pinc-software.de
* Bruno Albuquerque, bga@bug-br.org.br
*/ */
#include "cddb_daemon.h"
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
#include <Application.h>
#include <Directory.h> #include <Directory.h>
#include <Entry.h> #include <Entry.h>
#include <fs_info.h> #include <fs_info.h>
#include <Message.h> #include <Message.h>
#include <NodeMonitor.h>
#include <Volume.h> #include <Volume.h>
#include <VolumeRoster.h> #include <VolumeRoster.h>
#include <scsi_cmds.h>
#include "cddb_server.h" #include "cddb_server.h"
class CDDBLookup : public BApplication {
public:
CDDBLookup();
virtual ~CDDBLookup();
void LookupAll();
status_t Lookup(const dev_t device);
private:
bool _CanLookup(const dev_t device, uint32* cddbId,
scsi_toc_toc* toc) const;
QueryResponseData* _SelectResult(BList* response) const;
status_t _WriteCDData(dev_t device,
QueryResponseData* diskData,
ReadResponseData* readResponse);
};
extern const char *__progname;
static const char *kProgramName = __progname;
static const char* kCddaFsName = "cdda"; static const char* kCddaFsName = "cdda";
static const int kMaxTocSize = 1024; static const int kMaxTocSize = 1024;
CDDBDaemon::CDDBDaemon() CDDBLookup::CDDBLookup()
: BApplication("application/x-vnd.Haiku-cddb_daemon"), :
fVolumeRoster(new BVolumeRoster) BApplication("application/x-vnd.Haiku-cddb_lookup")
{ {
fVolumeRoster->StartWatching();
BVolume volume;
printf("Checking currently mounted volumes ...\n");
while (fVolumeRoster->GetNextVolume(&volume) == B_OK) {
if (_Lookup(volume.Device()) != B_OK) {
continue;
}
}
printf("Checking complete. Listening for device mounts.\n");
} }
CDDBDaemon::~CDDBDaemon() CDDBLookup::~CDDBLookup()
{ {
fVolumeRoster->StopWatching();
delete fVolumeRoster;
} }
void void
CDDBDaemon::MessageReceived(BMessage* message) CDDBLookup::LookupAll()
{ {
switch(message->what) { BVolumeRoster roster;
case B_NODE_MONITOR: BVolume volume;
int32 opcode; while (roster.GetNextVolume(&volume) == B_OK) {
if (message->FindInt32("opcode", &opcode) == B_OK) { Lookup(volume.Device());
if (opcode == B_DEVICE_MOUNTED) {
dev_t device;
if (message->FindInt32("new device", &device) == B_OK) {
if (_Lookup(device) != B_OK)
break;
}
}
}
break;
default:
BApplication::MessageReceived(message);
} }
} }
status_t status_t
CDDBDaemon::_Lookup(const dev_t device) CDDBLookup::Lookup(const dev_t device)
{ {
scsi_toc_toc* toc = (scsi_toc_toc*)malloc(kMaxTocSize); scsi_toc_toc* toc = (scsi_toc_toc*)malloc(kMaxTocSize);
if (toc == NULL) if (toc == NULL)
@@ -86,7 +86,7 @@ CDDBDaemon::_Lookup(const dev_t device)
printf("Skipping device with id %" B_PRId32 ".\n", device); printf("Skipping device with id %" B_PRId32 ".\n", device);
return B_BAD_TYPE; return B_BAD_TYPE;
} }
printf("Looking up CD with CDDB Id %08" B_PRIx32 ".\n", cddbId); printf("Looking up CD with CDDB Id %08" B_PRIx32 ".\n", cddbId);
CDDBServer cddb_server("freedb.freedb.org:80"); CDDBServer cddb_server("freedb.freedb.org:80");
@@ -99,7 +99,7 @@ CDDBDaemon::_Lookup(const dev_t device)
free(toc); free(toc);
return result; return result;
} }
free(toc); free(toc);
QueryResponseData* diskData = _SelectResult(&queryResponse); QueryResponseData* diskData = _SelectResult(&queryResponse);
@@ -112,7 +112,7 @@ CDDBDaemon::_Lookup(const dev_t device)
if ((result = cddb_server.Read(diskData, &readResponse)) != B_OK) { if ((result = cddb_server.Read(diskData, &readResponse)) != B_OK) {
return result; return result;
} }
if (_WriteCDData(device, diskData, &readResponse) == B_OK) { if (_WriteCDData(device, diskData, &readResponse) == B_OK) {
printf("CD data saved.\n"); printf("CD data saved.\n");
} else { } else {
@@ -124,7 +124,7 @@ CDDBDaemon::_Lookup(const dev_t device)
for (int32 i = 0; i < count; ++i) { for (int32 i = 0; i < count; ++i) {
delete (QueryResponseData*)queryResponse.RemoveItem((int32)0); delete (QueryResponseData*)queryResponse.RemoveItem((int32)0);
} }
queryResponse.MakeEmpty(); queryResponse.MakeEmpty();
// Delete itens in the track data BList in the read response data; // Delete itens in the track data BList in the read response data;
@@ -132,15 +132,15 @@ CDDBDaemon::_Lookup(const dev_t device)
for (int32 i = 0; i < count; ++i) { for (int32 i = 0; i < count; ++i) {
delete (TrackData*)readResponse.tracks.RemoveItem((int32)0); delete (TrackData*)readResponse.tracks.RemoveItem((int32)0);
} }
readResponse.tracks.MakeEmpty(); readResponse.tracks.MakeEmpty();
return B_OK; return B_OK;
} }
bool bool
CDDBDaemon::_CanLookup(const dev_t device, uint32* cddbId, CDDBLookup::_CanLookup(const dev_t device, uint32* cddbId,
scsi_toc_toc* toc) const scsi_toc_toc* toc) const
{ {
if (cddbId == NULL || toc == NULL) if (cddbId == NULL || toc == NULL)
@@ -151,7 +151,7 @@ CDDBDaemon::_CanLookup(const dev_t device, uint32* cddbId,
fs_stat_dev(device, &info); fs_stat_dev(device, &info);
if (strncmp(info.fsh_name, kCddaFsName, strlen(kCddaFsName)) != 0) if (strncmp(info.fsh_name, kCddaFsName, strlen(kCddaFsName)) != 0)
return false; return false;
// Does it have the CD:do_lookup attribute and is it true? // Does it have the CD:do_lookup attribute and is it true?
BVolume volume(device); BVolume volume(device);
BDirectory directory; BDirectory directory;
@@ -165,19 +165,19 @@ CDDBDaemon::_CanLookup(const dev_t device, uint32* cddbId,
// Does it have the CD:cddbid attribute? // Does it have the CD:cddbid attribute?
if (directory.ReadAttr("CD:cddbid", B_UINT32_TYPE, 0, (void *)cddbId, if (directory.ReadAttr("CD:cddbid", B_UINT32_TYPE, 0, (void *)cddbId,
sizeof(uint32)) < B_OK) sizeof(uint32)) < B_OK)
return false; return false;
// Does it have the CD:toc attribute? // Does it have the CD:toc attribute?
if (directory.ReadAttr("CD:toc", B_RAW_TYPE, 0, (void *)toc, if (directory.ReadAttr("CD:toc", B_RAW_TYPE, 0, (void *)toc,
kMaxTocSize) < B_OK) kMaxTocSize) < B_OK)
return false; return false;
return true; return true;
} }
QueryResponseData* QueryResponseData*
CDDBDaemon::_SelectResult(BList* response) const CDDBLookup::_SelectResult(BList* response) const
{ {
// Select a single CD match from the response and return it. // Select a single CD match from the response and return it.
// //
@@ -197,7 +197,7 @@ CDDBDaemon::_SelectResult(BList* response) const
if (numItems > 1) { if (numItems > 1) {
printf("Returning first entry.\n"); printf("Returning first entry.\n");
} }
return (QueryResponseData*)response->ItemAt(0L); return (QueryResponseData*)response->ItemAt(0L);
} }
@@ -206,81 +206,88 @@ CDDBDaemon::_SelectResult(BList* response) const
status_t status_t
CDDBDaemon::_WriteCDData(dev_t device, QueryResponseData* diskData, CDDBLookup::_WriteCDData(dev_t device, QueryResponseData* diskData,
ReadResponseData* readResponse) ReadResponseData* readResponse)
{ {
// Rename volume. // Rename volume.
BVolume volume(device); BVolume volume(device);
status_t result;
status_t error = B_OK; status_t error = B_OK;
BString name = diskData->artist << " - " << diskData->title; BString name = diskData->artist << " - " << diskData->title;
name.ReplaceSet("/", " "); name.ReplaceSet("/", " ");
if ((result = volume.SetName(name.String())) != B_OK) { status_t result = volume.SetName(name.String());
if (result != B_OK) {
printf("Can't set volume name.\n"); printf("Can't set volume name.\n");
return result; return result;
} }
// Rename tracks and add relevant Audio attributes. // Rename tracks and add relevant Audio attributes.
BDirectory cddaRoot; BDirectory cddaRoot;
volume.GetRootDirectory(&cddaRoot); volume.GetRootDirectory(&cddaRoot);
BEntry entry; BEntry entry;
int index = 0; int index = 0;
while (cddaRoot.GetNextEntry(&entry) == B_OK) { while (cddaRoot.GetNextEntry(&entry) == B_OK) {
TrackData* data = (TrackData*)((readResponse->tracks).ItemAt(index)); TrackData* data = (TrackData*)((readResponse->tracks).ItemAt(index));
// Update name. // Update name.
int trackNum = index + 1; // index=0 is actually Track 1 int trackNum = index + 1; // index=0 is actually Track 1
name.SetToFormat("%02d %s.wav", trackNum, data->title.String()); name.SetToFormat("%02d %s.wav", trackNum, data->title.String());
name.ReplaceSet("/", " "); name.ReplaceSet("/", " ");
if ((result = entry.Rename(name.String())) != B_OK) { result = entry.Rename(name.String());
printf("Failed renaming entry at index %d to \"%s\".\n", index, if (result != B_OK) {
name.String()); fprintf(stderr, "%s: Failed renaming entry at index %d to "
"\"%s\".\n", kProgramName, index, name.String());
error = result; error = result;
// User can benefit from continuing through all tracks. // User can benefit from continuing through all tracks.
// Report error later. // Report error later.
} }
// Add relevant attributes. We consider an error here as non-fatal. // Add relevant attributes. We consider an error here as non-fatal.
BNode node(&entry); BNode node(&entry);
node.WriteAttr("Media:Title", B_STRING_TYPE, 0, (data->title).String(), node.WriteAttr("Media:Title", B_STRING_TYPE, 0, data->title.String(),
(data->title).Length()); data->title.Length());
node.WriteAttr("Audio:Album", B_STRING_TYPE, 0, node.WriteAttr("Audio:Album", B_STRING_TYPE, 0,
(readResponse->title).String(), readResponse->title.String(),
(readResponse->title).Length()); readResponse->title.Length());
if (readResponse->genre.Length() != 0) { if (readResponse->genre.Length() != 0) {
node.WriteAttr("Media:Genre", B_STRING_TYPE, 0, node.WriteAttr("Media:Genre", B_STRING_TYPE, 0,
(readResponse->genre).String(), readResponse->genre.String(),
(readResponse->genre).Length()); readResponse->genre.Length());
} }
if (readResponse->year != 0) { if (readResponse->year != 0) {
node.WriteAttr("Media:Year", B_INT32_TYPE, 0, node.WriteAttr("Media:Year", B_INT32_TYPE, 0,
&(readResponse->year), sizeof(int32)); &readResponse->year, sizeof(int32));
} }
if (data->artist == "") { if (data->artist == "") {
node.WriteAttr("Audio:Artist", B_STRING_TYPE, 0, node.WriteAttr("Audio:Artist", B_STRING_TYPE, 0,
(readResponse->artist).String(), readResponse->artist.String(),
(readResponse->artist).Length()); readResponse->artist.Length());
} else { } else {
node.WriteAttr("Audio:Artist", B_STRING_TYPE, 0, node.WriteAttr("Audio:Artist", B_STRING_TYPE, 0,
(data->artist).String(), (data->artist).Length()); data->artist.String(), data->artist.Length());
} }
index++; index++;
} }
return error; return error;
} }
int main(void) { // #pragma mark -
printf("CDDB Daemon for Haiku v1.0.0 started.\n");
CDDBDaemon* cddbDaemon = new CDDBDaemon();
cddbDaemon->Run(); int
delete cddbDaemon; main(void)
{
// TODO: support arguments to specify a device
CDDBLookup cddb;
cddb.LookupAll();
return 0;
} }
@@ -1,4 +1,4 @@
resource app_signature "application/x-vnd.Haiku-cddb_daemon"; resource app_signature "application/x-vnd.Haiku-cddb_lookup";
resource app_flags B_EXCLUSIVE_LAUNCH | B_BACKGROUND_APP; resource app_flags B_EXCLUSIVE_LAUNCH | B_BACKGROUND_APP;
@@ -10,8 +10,8 @@ resource app_version {
variety = B_APPV_FINAL, variety = B_APPV_FINAL,
internal = 3, internal = 3,
short_info = "Haiku CDDB Daemon", short_info = "Haiku CDDB Lookup",
long_info = "Haiku CDDB Daemon ©2009 Haiku" long_info = "Haiku CDDB Lookup ©2009-2015 Haiku"
}; };
#ifdef HAIKU_TARGET_PLATFORM_HAIKU #ifdef HAIKU_TARGET_PLATFORM_HAIKU
@@ -1,11 +1,12 @@
/* /*
* Copyright 2008-2009, Haiku, Inc. All Rights Reserved. * Copyright 2008-2015, Haiku, Inc. All Rights Reserved.
* Distributed under the terms of the MIT License. * Distributed under the terms of the MIT License.
* *
* Authors: * Authors:
* Bruno Albuquerque, bga@bug-br.org.br * Bruno Albuquerque, bga@bug-br.org.br
*/ */
#include "cddb_server.h" #include "cddb_server.h"
#include <errno.h> #include <errno.h>
@@ -21,7 +22,8 @@ static const uint32 kFramesPerSecond = 75;
static const uint32 kFramesPerMinute = kFramesPerSecond * 60; static const uint32 kFramesPerMinute = kFramesPerSecond * 60;
CDDBServer::CDDBServer(const BString& cddbServer): CDDBServer::CDDBServer(const BString& cddbServer)
:
fInitialized(false), fInitialized(false),
fConnected(false) fConnected(false)
{ {
@@ -92,7 +94,7 @@ CDDBServer::Query(uint32 cddbId, const scsi_toc_toc* toc, BList* queryResponse)
output.MoveInto(statusCode, 0, 3); output.MoveInto(statusCode, 0, 3);
if (statusCode == "210" || statusCode == "211") { if (statusCode == "210" || statusCode == "211") {
// TODO(bga): We can get around with returning the first result // TODO(bga): We can get around with returning the first result
// in case of multiple matches, but we most definitely needs a // in case of multiple matches, but we most definitely need a
// better handling of inexact matches. // better handling of inexact matches.
if (statusCode == "211") if (statusCode == "211")
printf("Warning : Inexact match found.\n"); printf("Warning : Inexact match found.\n");
@@ -367,7 +369,7 @@ CDDBServer::_SendCddbCommand(const BString& command, BString* output)
// Assemble full command string. // Assemble full command string.
BString fullCommand; BString fullCommand;
fullCommand << command << "&hello=" << fLocalUserName << " " << fullCommand << command << "&hello=" << fLocalUserName << " " <<
fLocalHostName << " cddb_daemon 1.0&proto=6"; fLocalHostName << " cddb_lookup 1.0&proto=6";
// Replace spaces by + signs. // Replace spaces by + signs.
fullCommand.ReplaceAll(" ", "+"); fullCommand.ReplaceAll(" ", "+");
-1
View File
@@ -2,7 +2,6 @@ SubDir HAIKU_TOP src servers ;
SubInclude HAIKU_TOP src servers app ; SubInclude HAIKU_TOP src servers app ;
SubInclude HAIKU_TOP src servers bluetooth ; SubInclude HAIKU_TOP src servers bluetooth ;
SubInclude HAIKU_TOP src servers cddb_daemon ;
SubInclude HAIKU_TOP src servers debug ; SubInclude HAIKU_TOP src servers debug ;
SubInclude HAIKU_TOP src servers index ; SubInclude HAIKU_TOP src servers index ;
SubInclude HAIKU_TOP src servers input ; SubInclude HAIKU_TOP src servers input ;
-11
View File
@@ -1,11 +0,0 @@
SubDir HAIKU_TOP src servers cddb_daemon ;
UsePrivateHeaders drivers ;
AddResources cddb_daemon : cddb_daemon.rdef ;
Server cddb_daemon :
cddb_daemon.cpp
cddb_server.cpp
: be bnetapi [ TargetLibsupc++ ]
;
-41
View File
@@ -1,41 +0,0 @@
/*
* Copyright 2008-2009, Haiku, Inc. All Rights Reserved.
* Distributed under the terms of the MIT License.
*
* Authors:
* Bruno Albuquerque, [email protected]
*/
#ifndef _CDDB_DAEMON_H
#define _CDDB_DAEMON_H
#include <Application.h>
#include <scsi_cmds.h>
struct ReadResponseData;
struct QueryResponseData;
class BList;
class BMessage;
class BVolumeRoster;
class CDDBDaemon : public BApplication {
public:
CDDBDaemon();
virtual ~CDDBDaemon();
virtual void MessageReceived(BMessage* message);
private:
status_t _Lookup(const dev_t device);
bool _CanLookup(const dev_t device, uint32* cddbId,
scsi_toc_toc* toc) const;
QueryResponseData* _SelectResult(BList* response) const;
status_t _WriteCDData(dev_t device, QueryResponseData* diskData,
ReadResponseData* readResponse);
BVolumeRoster* fVolumeRoster;
};
#endif // _CDDB_DAEMON_H