Hi.
This patch implements the lk_rio_update_props_from_tags() which can
be used by lkarmafs to update tag details for both USB and Lan attached
devices. This version no longer passes a filename argument as the
library does everything itself.
The patch should apply cleanly to hg112 (ie. after all my previous
patches are applied).
There is also a patch for lkarmafs which is against the vanilla 0.1.8.
If a USB device is in use, then the file on the karma is used directly
to obtain the tag information. If a Lan device is used, then a temporary
file is created under /dev/shm (or /tmp if that fails) containing just
the header+64k, mid 64k and tail+64k. These are obtained from the
karma using the lk_karma_read_file_chunk() as per Franky's suggestion.
Note to Franky: you should probably hold off on applying this patch
until EV gives the go-ahead. If libkarma has changed by then, I will
post a new version.
Keith.
# HG changeset patch
# User [EMAIL PROTECTED]
# Date 1156948156 -3600
# Node ID 114430a212e8f1568e3a9d5f09c7a9fe9e49fd2f
# Parent d53799c131b5afaae7866cd52d7d2ad39ff4e776
Added support for calculating rids correctly in lkarmafs.
diff -r d53799c131b5 -r 114430a212e8 src/errors.c
--- a/src/errors.c Wed Aug 30 15:26:36 2006 +0100
+++ b/src/errors.c Wed Aug 30 15:29:16 2006 +0100
@@ -54,7 +54,9 @@ const char *lkerrorList[MAXLKERRORS + 1]
/* E_UNSUPTAG 35 */ "* Libkarma warning: unsupported tag type",
/* E_NOTAGFILE 36 */ "* Libkarma warning: can't access tags file",
/* E_BADFDB 37 */ "* Libkarma warning: unrecognised fdb file",
- /* E_UNSUPFDB 38 */ "* Libkarma warning: unsupported fdb file"
+ /* E_UNSUPFDB 38 */ "* Libkarma warning: unsupported fdb file",
+ /* E_NOTMPDIR 39 */ "* Libkarma warning: no temporary directory found",
+ /* E_TMPCREAT 40 */ "** Libkarma error: can't create temporary tag file"
};
#define libkarmaErrorString lkerrorList[libkarmaError]
diff -r d53799c131b5 -r 114430a212e8 src/karma.c
--- a/src/karma.c Wed Aug 30 15:26:36 2006 +0100
+++ b/src/karma.c Wed Aug 30 15:29:16 2006 +0100
@@ -9,12 +9,22 @@
*
*/
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <stdlib.h>
+#include <string.h>
+
#include "lkarma.h"
#include "karma.h"
#include "karmaLan.h"
#include "karmaUsb.h"
#include "properties.h"
#include "fdb.h"
+
+int using_usb = 0;
+char *karma_tmpdir = NULL;
#ifdef __USE_ISOC99
#define set_usb_ptr(x) .lk_karma_ ##x = lk_karmaUsb_ ##x
@@ -111,14 +121,43 @@ char *lk_karma_fidToPath(int rio, uint32
/* --------------------------------------------------------------------------
*/
/* Basic Protocol Functions */
+static int lk_karma_find_tmpdir(void)
+{
+ int fd;
+ char path[32];
+
+ memcpy(path, "/dev/shm/lkarmaXXXXXX", 22);
+ fd = mkstemp(path);
+ if (fd != -1) {
+ close(fd);
+ unlink(path);
+ karma_tmpdir = strdup("/dev/shm/");
+ return 0;
+ }
+ memcpy(path, "/tmp/lkarmaXXXXXX", 19);
+ fd = mkstemp(path);
+ if (fd != -1) {
+ close(fd);
+ unlink(path);
+ karma_tmpdir = strdup("/tmp/");
+ return 0;
+ }
+ lk_errors_set(E_NOTMPDIR);
+ return 1;
+}
+
int lk_karma_connect(char *ipHostOrPath)
{
- int using_usb = (ipHostOrPath[0] == '/');
int rio;
+ using_usb = (ipHostOrPath[0] == '/');
lk_ops = using_usb ? &usb_ops : &lan_ops;
rio = lk_ops->lk_karma_connect(ipHostOrPath);
lk_fdb_set_device(rio);
+
+ if (rio >= 0 && using_usb == 0 && karma_tmpdir == NULL)
+ lk_karma_find_tmpdir();
+
return rio;
}
diff -r d53799c131b5 -r 114430a212e8 src/karma.h
--- a/src/karma.h Wed Aug 30 15:26:36 2006 +0100
+++ b/src/karma.h Wed Aug 30 15:29:16 2006 +0100
@@ -12,6 +12,9 @@
#define _KARMA_H
#include <inttypes.h>
+
+extern int using_usb;
+extern char *karma_tmpdir;
char * lk_karma_fidToPath (int rio, uint32_t file_id);
diff -r d53799c131b5 -r 114430a212e8 src/lkarma.h
--- a/src/lkarma.h Wed Aug 30 15:26:36 2006 +0100
+++ b/src/lkarma.h Wed Aug 30 15:29:16 2006 +0100
@@ -152,8 +152,10 @@ char * lk_errors_numberstr(int lkerrnum)
#define E_NOTAGFILE 36 /* warning: can't access tags file */ /* RIO_RW */
#define E_BADFDB 37 /* warning: unrecognised fdb file */ /* FDB */
#define E_UNSUPFDB 38 /* warning: unsupported fdb file */ /* FDB */
-
-#define MAXLKERRORS 38
+#define E_NOTMPDIR 39 /* warning: no temporary directory found */
+#define E_TMPCREAT 40 /* error: can't create temporary tag file */
+
+#define MAXLKERRORS 40
/*
diff -r d53799c131b5 -r 114430a212e8 src/rio_rw.c
--- a/src/rio_rw.c Wed Aug 30 15:26:36 2006 +0100
+++ b/src/rio_rw.c Wed Aug 30 15:29:16 2006 +0100
@@ -125,60 +125,31 @@ int lk_rio_read(int rio, uint32_t fid, c
return 0;
}
-int lk_rio_update_props_from_tags(int rio, uint32_t fid, const char *fname)
-{
- int got=-1, usb=0;
+static int lk_rio_do_update_props_from_tags(int rio, uint32_t fid,
+ const char *filename)
+{
+ int got=-1;
struct stat len;
HASH * props;
mp3info mp3;
- char *rid, *filename;
+ char *rid;
int type, rid_fd;
/** uint32_t *fids; **/
- if (fname == NULL) {
- filename = lk_karma_fidToPath(rio, fid);
- usb = 1;
- } else
- filename = (char *)fname;
-
- if(lstat(filename, &len)==-1) {
- if (usb) {
- unlink(filename);
- free(filename);
- }
- return -1;
- }
+ if(lstat(filename, &len)==-1)
+ return -1;
memset(&mp3, 0, sizeof(mp3info));
- mp3.filename = filename;
+ mp3.filename = (char *)filename;
type = get_file_type(&mp3);
rid_fd = open(filename, O_RDONLY);
rid = (char*)lk_generate_rid(rid_fd, mp3.offset, mp3.datasize);
close(rid_fd);
-/* This doesn't belong to update_props_from_tags: moved to lk_rio_do_write() */
-/** if (write_dupes == 0 && fdb == 0) {
- fids = lk_properties_andOrSearch(EXACT|ORS, NULL, "rid", rid);
-
- if (fids != NULL) {
- if (usb) {
- unlink(filename);
- free(filename);
- }
- free(fids);
- lk_errors_set(E_DUPE);
- return -1;
- }
- } **/
-
/* uses lk_properties_getnextfid()...*/
props=lk_properties_idsearch(fid);
if(props==NULL){
- if (usb) {
- unlink(filename);
- free(filename);
- }
lk_errors_set(E_NOHASH);
/* printf("huh, no hash found?\n"); */
return -1;
@@ -202,17 +173,130 @@ int lk_rio_update_props_from_tags(int ri
else
got=get_taxi_props(props);
- if (usb)
- free(filename);
-
return got;
}
-/** No longer needed !! **/
-/** int lk_rio_update_props_from_tags(int rio, uint32_t fid, const char *fname)
-{
- return lk_rio_do_update_props_from_tags(0, rio, fid, fname);
-} **/
+/*
+ * Create a temporary file containing the head, tail and middle 64k
+ * of data needed for finding the tags and rid.
+ */
+static char *lk_rio_create_temp_file(int rio, uint32_t fid)
+{
+#define RID_BLOCKS 65536
+ int fd, ret;
+ int64_t len;
+ uint64_t blk, got, off, length;
+ char *filename = NULL, *tmp;
+ mp3info mp3;
+
+ tmp = lk_properties_get_property(fid, "length");
+ if (tmp == NULL)
+ goto err;
+
+ length = strtoull(tmp, NULL, 10);
+
+ /* 4k should be enough for the header in most cases */
+ blk = RID_BLOCKS + 4096;
+ off = 0;
+ ret = lk_karma_read_file_chunk(rio, off, blk, fid, &tmp, &got);
+ if (ret != 0 || got != blk)
+ goto err;
+
+ len = strlen(karma_tmpdir) + strlen(simple_itoa(fid)) + 8;
+ filename = malloc(len);
+ snprintf(filename, len, "%s/lkarma%d", karma_tmpdir, fid);
+
+ fd = open(filename, O_WRONLY|O_CREAT|O_EXCL, 0600);
+ if (fd == -1)
+ goto err;
+
+ ret = write(fd, tmp, got);
+ free(tmp);
+ close(fd);
+
+ memset(&mp3, 0, sizeof(mp3));
+ mp3.filename = filename;
+ get_file_type(&mp3);
+
+ fd = open(filename, O_WRONLY);
+
+ /* read the rest of the header if 4k wasnt enough */
+ len = mp3.offset + RID_BLOCKS - blk;
+ if (len > 0) {
+ off = blk;
+ blk = len;
+ ret = lk_karma_read_file_chunk(rio, off, blk, fid, &tmp, &got);
+ if (ret != 0 || got != blk)
+ goto err;
+ ret = lseek(fd, off, SEEK_SET);
+ ret = write(fd, tmp, got);
+ free(tmp);
+ }
+
+ /* tail */
+ blk = RID_BLOCKS + 128;
+ off = length - blk;
+ ret = lk_karma_read_file_chunk(rio, off, blk, fid, &tmp, &got);
+ if (ret != 0 || got != blk)
+ goto err;
+
+ ret = lseek(fd, (mp3.offset + 2*RID_BLOCKS), SEEK_SET);
+ if (memcmp(tmp+got-128, "TAG", 3) == 0) {
+ ret = write(fd, tmp, got);
+ length -= 128;
+ } else
+ ret = write(fd, tmp+128, got-128);
+ free(tmp);
+
+ /* middle 64k */
+ blk = RID_BLOCKS;
+ off = (mp3.offset + length - RID_BLOCKS)/2;
+ ret = lk_karma_read_file_chunk(rio, off, blk, fid, &tmp, &got);
+ if (ret != 0 || got != blk)
+ goto err;
+ ret = lseek(fd, (mp3.offset + RID_BLOCKS), SEEK_SET);
+ ret = write(fd, tmp, got);
+ free(tmp);
+
+ close(fd);
+
+ mp3.datasize = mp3.offset + 3*RID_BLOCKS;
+
+ return filename;
+
+ err:
+ if (filename) {
+ close(fd);
+ unlink(filename);
+ }
+ if (tmp)
+ free(tmp);
+ lk_errors_set(E_TMPCREAT);
+ return NULL;
+}
+
+int lk_rio_update_props_from_tags(int rio, uint32_t fid)
+{
+ int ret;
+ char *filename;
+
+ if (using_usb)
+ filename = lk_karma_fidToPath(rio, fid);
+ else
+ filename = lk_rio_create_temp_file(rio, fid);
+
+ if (!filename)
+ return -1;
+
+ ret = lk_rio_do_update_props_from_tags(rio, fid, filename);
+
+ if (using_usb == 0 || ret)
+ unlink(filename);
+
+ free(filename);
+
+ return ret;
+}
/*
To use that function properly:
@@ -248,7 +332,7 @@ static uint32_t lk_rio_do_write(int fdb,
if (!fid)
fid = lk_properties_new_property();
- got = lk_rio_update_props_from_tags(rio, fid, filename);
+ got = lk_rio_do_update_props_from_tags(rio, fid, filename);
if (got != 0) {
lk_properties_del_property(fid);
close(fd);
--- lkarmafs-0.1.8.orig/lkarmafs.c 2006-08-01 20:10:00.000000000 +0100
+++ lkarmafs-0.1.8/lkarmafs.c 2006-08-27 22:41:25.000000000 +0100
@@ -915,7 +915,8 @@
static int kfs_flush(const char *path, struct fuse_file_info *fi) {
uint32_t fid;
int res=0, timeout=0;
- char *aux=NULL;
+ char *aux=NULL, *length=NULL;
+ pathElementsType P;
FPRINTF(stderr, "==> FLUSH: %s %d %x\n",
path, (int)fi->fh & 0x7FFFFFFF, fi->flags);
(void) path;
@@ -930,12 +931,25 @@
}
if(fid > 255) { /* close WRITE open
*/
res = setProp(fid, "ctime", simple_itoa(time(NULL)));
+ if(res) return -EPROTO;
if((timeout = waitForIOlock())) return timeout;
- aux = lk_properties_export(fid);
- res += lk_karma_update_file_details(karma, fid, aux);
+ length = strdup(getProp(fid, "length"));
+ res = lk_rio_update_props_from_tags(karma, fid);
+ if(res) {
+ releaseIOlock();
+ return -EPROTO;
+ }
+ P = parsePath(path);
+ setPropCS (fid, "genre", P.genre);
+ setPropTRCS(fid, "artist", P.artist);
+ setPropTRCS(fid, "source", P.source);
+ setPropTRCS(fid, "title", P.title);
+ setPropTRCS(fid, "length", length);
+ aux = lk_properties_export(fid);
+ res = lk_karma_update_file_details(karma, fid, aux);
+ free(aux);
releaseIOlock();
/* fprintf(stderr, "--> %d %d ***%s***\n", fid, res, aux); */
- free(aux);
if(res) return -EPROTO;
}
else return -ENOENT;
-------------------------------------------------------------------------
Using Tomcat but need to do more? Need to support web services, security?
Get stuff done quickly with pre-integrated technology to make your job easier
Download IBM WebSphere Application Server v.1.0.1 based on Apache Geronimo
http://sel.as-us.falkag.net/sel?cmd=lnk&kid=120709&bid=263057&dat=121642
_______________________________________________
linux-karma-devel mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/linux-karma-devel