Subversion Repositories mdb

Rev

Rev 13 | Rev 18 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
5 andreas 1
/*
2
 * Copyright (C) 2015 by Andreas Theofilu <andreas@theosys.at>
3
 *
4
 * All rights reserved. No warranty, explicit or implicit, provided.
5
 *
6
 * NOTICE:  All information contained herein is, and remains
7
 * the property of Andreas Theofilu and his suppliers, if any.
8
 * The intellectual and technical concepts contained
9
 * herein are proprietary to Andreas Theofilu and its suppliers and
10
 * may be covered by European and Foreign Patents, patents in process,
11
 * and are protected by trade secret or copyright law.
12
 * Dissemination of this information or reproduction of this material
13
 * is strictly forbidden unless prior written permission is obtained
14
 * from Andreas Theofilu.
15
 */
16
#include <stdio.h>
17
#include <string.h>
18
#include <strings.h>
19
#include <unistd.h>
20
#include <stdlib.h>
21
#include <libgen.h>
22
#include <ctype.h>
23
#include <math.h>
24
#include <syslog.h>
25
#include <errno.h>
26
#include <sys/stat.h>
27
#include <sys/types.h>
28
#include <fcntl.h>
29
#include <sqlite3.h>
30
#include <id3.h>
31
#include "config.h"
32
#include "helplib.h"
33
#include "list.h"
8 andreas 34
#include "user.h"
35
#include "play.h"
5 andreas 36
 
37
struct callPars
38
{
39
	int s1;
40
	int start;
41
	int length;
42
	char *type;
43
};
44
 
12 andreas 45
int globalLine;
46
int globalPos;
5 andreas 47
 
12 andreas 48
static int listCallback(int s1, char *type, int line, sqlite3_stmt *res);
5 andreas 49
static int folderCallback(void *hint, int argc, char **argv, char **azColName);
14 andreas 50
int countPlaylists();
5 andreas 51
 
52
int listSongs(int s1, char *p_type, int start, int length)
53
{
11 andreas 54
	char query[1024], hv0[128];
5 andreas 55
	char fname[256];
56
	sqlite3 *db;
12 andreas 57
	sqlite3_stmt *res;
58
	int rc, pos, line;
5 andreas 59
 
60
	strcpy(fname, configs.home);
9 andreas 61
	strcat(fname, MUSICDB);
5 andreas 62
 
63
	rc = sqlite3_open(fname, &db);
64
 
65
	if (rc)
66
	{
67
		syslog(LOG_WARNING, "Error opening database %s: %s", fname, sqlite3_errmsg(db));
68
		strcpy(query, "ERROR:LIST:Error opening database;");
69
		write (s1, query, strlen(query));
70
		return FALSE;
71
	}
72
 
12 andreas 73
	/* First count the future result set */
14 andreas 74
	if (strcmp(p_type, "QUEUE") && strcmp(p_type, "PLAYLIST"))
75
	{
76
		strcpy (query, "select count(*) as cnt from musicdb");
12 andreas 77
 
14 andreas 78
		if (sqlite3_prepare(db, query, -1, &res, NULL) != SQLITE_OK)
79
		{
80
			syslog(LOG_DAEMON, "Error preparing SQL statement [%s]: %s", query, sqlite3_errmsg(db));
81
			strcpy(query, "ERROR:USER:Error preparing a SQL statement;");
82
			write(s1, query, strlen(query));
83
			return FALSE;
84
		}
85
 
86
		if (sqlite3_step(res) == SQLITE_ROW)
87
			pos = sqlite3_column_int(res, 0);
88
		else
89
			pos = 0;
90
 
91
		sqlite3_finalize(res);
12 andreas 92
	}
14 andreas 93
	else if (!strcmp(p_type, "QUEUE"))
94
		pos = queueTotal;
12 andreas 95
	else
14 andreas 96
		pos = countPlaylists();
12 andreas 97
 
98
	sprintf(hv0, "TOTAL:%d;", pos);
99
	write(s1, hv0, strlen(hv0));
100
 
11 andreas 101
	strcpy (query, "select id, title, interpret, album, genre, cover from \"main\".\"musicdb\" ");
5 andreas 102
	strcat (query, "order by ");
103
 
104
	if (strcmp(p_type, "TITLE") == 0)
105
		strcat (query, "title");
106
	else if (strcmp(p_type, "ARTIST") == 0)
107
		strcat (query, "interpret");
108
	else if (strcmp(p_type, "ALBUM") == 0)
109
		strcat (query, "album");
110
	else if (strcmp(p_type, "GENRE") == 0)
111
		strcat (query, "genre");
8 andreas 112
	else if (strcmp(p_type, "QUEUE") == 0)
113
	{
114
		sqlite3_close(db);
115
		return listQueue(s1, start, length);
116
	}
117
	else if (strcmp(p_type, "PLAYLIST") == 0)
118
	{
119
		sqlite3_close(db);
120
		return listPlaylists(s1, start, length);
121
	}
5 andreas 122
	else		/* No or unknown type */
123
	{
124
		strcpy (query, "ERROR:LIST:Missing type;");
125
		write(s1, query, strlen(query));
126
		sqlite3_close(db);
127
		return FALSE;
128
	}
129
 
11 andreas 130
	/* Tell client which page to show */
131
	sprintf(hv0, "PAGE:%s;", p_type);
132
	write (s1, hv0, strlen (hv0));
133
 
134
	/* Retrieve data from database */
5 andreas 135
	line = 0;
136
 
12 andreas 137
	if (sqlite3_prepare(db, query, -1, &res, NULL) != SQLITE_OK)
5 andreas 138
	{
12 andreas 139
		syslog(LOG_DAEMON, "Error preparing SQL statement [%s]: %s", query, sqlite3_errmsg(db));
140
		strcpy(query, "ERROR:USER:Error preparing a SQL statement;");
141
		write(s1, query, strlen(query));
5 andreas 142
		return FALSE;
143
	}
144
 
12 andreas 145
	while ((rc = sqlite3_step(res)) == SQLITE_ROW)
5 andreas 146
	{
12 andreas 147
		line++;
148
 
149
		if (line >= start && line < (start + length))
150
			listCallback(s1, p_type, line, res);
151
 
152
		if (line >= (start + length))
153
			break;
5 andreas 154
	}
155
 
12 andreas 156
	sqlite3_finalize(res);
5 andreas 157
	sqlite3_close(db);
158
	return TRUE;
159
}
160
 
8 andreas 161
int listQueue(int s1, int start, int length)
162
{
11 andreas 163
	int fd, line;
164
	char fname[256], hv0[256], buffer[8192];
165
	char *title, *artist, *album, *cover;
166
	int pos;
167
	QUEUE *act;
8 andreas 168
 
11 andreas 169
	if (pqueue == NULL)
8 andreas 170
	{
11 andreas 171
		strcpy (fname, configs.home);
172
		strcat (fname, NOWPLAY);
8 andreas 173
 
11 andreas 174
		if (access(fname, R_OK))
175
		{
176
			strcpy (hv0, "ERROR:LIST:No or empty queue;");
177
			write (s1, hv0, strlen(hv0));
178
			return FALSE;
179
		}
8 andreas 180
 
11 andreas 181
		if ((fd = open(fname, O_RDONLY)) <= 0)
182
		{
183
			syslog(LOG_WARNING, "Error opening file %s: %s", fname, strerror(errno));
184
			strcpy(hv0, "ERROR:LIST:Error opening queue;");
185
			write(s1, hv0, strlen(hv0));
186
			return FALSE;
187
		}
8 andreas 188
 
11 andreas 189
		scanQueue(fd);
190
		close(fd);
191
	}
8 andreas 192
 
11 andreas 193
	sprintf(hv0, "PAGE:QUEUE;TOTAL:%d;", queueTotal);
194
	write (s1, hv0, strlen(hv0));
195
	act = pqueue;
196
	pos = line = 1;
8 andreas 197
 
11 andreas 198
	while (act)
8 andreas 199
	{
200
		if (pos < start)
201
			continue;
11 andreas 202
		else if (pos > (start + length))
8 andreas 203
			break;
204
 
11 andreas 205
		title = urlencode(act->title);
206
		artist = urlencode(act->artist);
207
		album = urlencode(act->album);
208
		cover = urlencode(act->cover);
209
		sprintf(buffer, "LINE:QUEUE:%d:%d:", act->id, line);
8 andreas 210
 
211
		if (title != NULL)
212
		{
213
			strcat(buffer, title);
214
			free(title);
215
		}
216
		else
11 andreas 217
			strcat(buffer, act->title);
218
 
8 andreas 219
		strcat(buffer, ":");
11 andreas 220
 
8 andreas 221
		if (artist != NULL)
222
		{
223
			strcat(buffer, artist);
224
			free(artist);
225
		}
226
		else
11 andreas 227
			strcat(buffer, act->artist);
228
 
8 andreas 229
		strcat(buffer, ":");
11 andreas 230
 
8 andreas 231
		if (album != NULL)
232
		{
233
			strcat(buffer, album);
234
			free(album);
235
		}
236
		else
11 andreas 237
			strcat(buffer, act->album);
238
 
8 andreas 239
		strcat(buffer, ":");
11 andreas 240
		strcat(buffer, act->genre);
241
		strcat(buffer, ":");
242
 
243
		if (cover != NULL)
244
		{
245
			strcat(buffer, cover);
246
			free(cover);
247
		}
248
		else
249
			strcat(buffer, act->cover);
250
 
8 andreas 251
		strcat(buffer, ";");
252
		write(s1, buffer, strlen(buffer));
11 andreas 253
		act = act->next;
254
		line++;
8 andreas 255
	}
256
 
257
	return TRUE;
258
}
259
 
5 andreas 260
int listFolders(int s1, char *p_type, int start, int length)
261
{
262
	char query[1024], field[16];
263
	char fname[256];
264
	sqlite3 *db;
265
	char *zErrMsg = 0;
266
	int rc;
267
	struct callPars cp;
268
 
269
	strcpy(fname, configs.home);
9 andreas 270
	strcat(fname, MUSICDB);
5 andreas 271
 
272
	rc = sqlite3_open(fname, &db);
273
 
274
	if (rc)
275
	{
276
		syslog(LOG_WARNING, "Error opening database %s: %s", fname, sqlite3_errmsg(db));
277
		strcpy(query, "ERROR:FOLDER:Error opening database;");
278
		write (s1, query, strlen(query));
279
		return FALSE;
280
	}
281
 
282
	strcpy (query, "select distinct ");
283
 
284
	if (strcmp(p_type, "TITLE") == 0)
285
		strcpy (field, "title");
286
	else if (strcmp(p_type, "ARTIST") == 0)
287
		strcpy (field, "interpret");
288
	else if (strcmp(p_type, "ALBUM") == 0)
289
		strcpy (field, "album");
290
	else if (strcmp(p_type, "GENRE") == 0)
291
		strcpy (field, "genre");
292
	else		/* No or unknown type */
293
	{
294
		strcpy (query, "ERROR:FOLDER:Missing type;");
295
		write(s1, query, strlen(query));
296
		sqlite3_close(db);
297
		return FALSE;
298
	}
299
 
300
	strcat (query, field);
11 andreas 301
	strcat (query, ",cover from \"main\".\"musicdb\" order by ");
5 andreas 302
	strcat (query, field);
303
 
304
	cp.s1 = s1;
305
	cp.type = p_type;
306
	cp.start = start;
307
	cp.length = length;
12 andreas 308
	globalLine = 0;
309
	globalPos = -1;
5 andreas 310
 
311
	if ((rc = sqlite3_exec(db, query, folderCallback, (void *)&cp, &zErrMsg)) != SQLITE_OK)
312
	{
313
		syslog(LOG_WARNING, "SQL error [%s]: %s", query, zErrMsg);
314
		sqlite3_free(zErrMsg);
315
		sqlite3_close(db);
316
		strcpy(query, "ERROR:FOLDER:SQL error;");
317
		write (s1, query, strlen(query));
318
		return FALSE;
319
	}
320
 
12 andreas 321
	if (globalPos >= 0)
5 andreas 322
	{
12 andreas 323
		sprintf(query, "TOTAL:%d;", globalPos + 1);
5 andreas 324
		write (s1, query, strlen(query));
325
	}
326
 
327
	sqlite3_close(db);
328
	return TRUE;
329
}
330
 
12 andreas 331
static int listCallback(int s1, char *type, int line, sqlite3_stmt *res)
5 andreas 332
{
14 andreas 333
	int id;
12 andreas 334
	char id3_title[256], id3_artist[256], id3_album[256], id3_genre[256], id3_cover[256];
5 andreas 335
	char buffer[8192];
12 andreas 336
	char *title, *artist, *album;
5 andreas 337
 
338
	memset(id3_title, 0, sizeof(id3_title));
339
	memset(id3_artist, 0, sizeof(id3_artist));
340
	memset(id3_album, 0, sizeof(id3_album));
341
	memset(id3_genre, 0, sizeof(id3_genre));
11 andreas 342
	memset(id3_cover, 0, sizeof(id3_cover));
5 andreas 343
	id = -1;
12 andreas 344
	id = sqlite3_column_int(res, 0);
345
	strncpy(id3_title, (const char *)sqlite3_column_text(res, 1), sizeof(id3_title));
346
	strncpy(id3_artist, (const char *)sqlite3_column_text(res, 2), sizeof(id3_artist));
347
	strncpy(id3_album, (const char *)sqlite3_column_text(res, 3), sizeof(id3_album));
348
	strncpy(id3_genre, (const char *)sqlite3_column_text(res, 4), sizeof(id3_genre));
349
	strncpy(id3_cover, (const char *)sqlite3_column_text(res, 5), sizeof(id3_cover));
5 andreas 350
 
351
	title = urlencode(id3_title);
352
	artist = urlencode(id3_artist);
11 andreas 353
	album = urlencode(id3_album);
5 andreas 354
 
12 andreas 355
	sprintf(buffer, "LINE:%s:%d:%d:", type, id, line);
5 andreas 356
 
357
	if (title != NULL)
358
	{
359
		strcat(buffer, title);
360
		free(title);
361
	}
362
	else
363
		strcat(buffer, id3_title);
12 andreas 364
 
5 andreas 365
	strcat(buffer, ":");
12 andreas 366
 
5 andreas 367
	if (artist != NULL)
368
	{
369
		strcat(buffer, artist);
370
		free(artist);
371
	}
372
	else
373
		strcat(buffer, id3_artist);
12 andreas 374
 
5 andreas 375
	strcat(buffer, ":");
12 andreas 376
 
5 andreas 377
	if (album != NULL)
378
	{
379
		strcat(buffer, album);
380
		free(album);
381
	}
382
	else
383
		strcat(buffer, id3_album);
12 andreas 384
 
5 andreas 385
	strcat(buffer, ":");
386
	strcat(buffer, id3_genre);
11 andreas 387
	strcat(buffer, ":");
12 andreas 388
	strcat(buffer, id3_cover);
5 andreas 389
	strcat(buffer, ";");
12 andreas 390
	write(s1, buffer, strlen(buffer));
5 andreas 391
	return 0;
392
}
393
 
394
static int folderCallback(void *hint, int argc, char **argv, char **azColName)
395
{
396
	int i;
11 andreas 397
	char id3_buffer[256], id3_cover[512];
5 andreas 398
	char buffer[8192];
399
	char *buf;
400
	struct callPars *cp;
401
 
12 andreas 402
	globalPos++;
5 andreas 403
	cp = (struct callPars *)hint;
404
	memset(id3_buffer, 0, sizeof(id3_buffer));
11 andreas 405
	memset(id3_cover, 0, sizeof(id3_cover));
5 andreas 406
 
12 andreas 407
	if (globalPos < cp->start || globalPos >= (cp->start + cp->length))
5 andreas 408
		return 0;
409
 
410
	for(i = 0; i < argc; i++)
411
	{
412
		if (strcasecmp(azColName[i], "title") == 0 || strcasecmp(azColName[i], "interpret") == 0 ||
413
			strcasecmp(azColName[i], "album") == 0 || strcasecmp(azColName[i], "genre") == 0)
414
			if (argv[i])
415
				strncpy(id3_buffer, argv[i], sizeof(id3_buffer));
11 andreas 416
 
417
		if (strcasecmp(azColName[i], "cover") == 0)
418
			if (argv[i])
419
				strncpy(id3_cover, argv[i], sizeof(id3_cover));
5 andreas 420
	}
421
 
422
	buf = urlencode(id3_buffer);
12 andreas 423
	globalLine++;
5 andreas 424
 
12 andreas 425
	sprintf(buffer, "FOLDER:%s:%d:", cp->type, globalLine);
5 andreas 426
 
427
	if (buf != NULL)
428
	{
429
		strcat(buffer, buf);
430
		free(buf);
431
	}
432
	else
433
		strcat(buffer, id3_buffer);
434
 
11 andreas 435
	strcat(buffer, ":");
12 andreas 436
	strcat(buffer, id3_cover);
5 andreas 437
	strcat(buffer, ";");
438
	write(cp->s1, buffer, strlen(buffer));
439
	return 0;
440
}
8 andreas 441
 
13 andreas 442
int listFolderContent(int s1, char *p_type, char *name, int start, int length)
443
{
444
	char query[1024], hv0[128], field[32];
445
	char fname[256];
446
	sqlite3 *db;
447
	sqlite3_stmt *res;
448
	int rc, pos, line;
449
 
450
	strcpy(fname, configs.home);
451
	strcat(fname, MUSICDB);
452
 
453
	if (!strcasecmp(p_type, "TITLE"))
454
		strcpy (field, "title");
455
	else if (!strcasecmp(p_type, "ARTIST"))
456
		strcpy (field, "interpret");
457
	else if (!strcasecmp(p_type, "ALBUM"))
458
		strcpy (field, "album");
459
	else if (!strcasecmp(p_type, "GENRE"))
460
		strcpy (field, "genre");
461
	else
462
	{
463
		strcpy (hv0, "ERROR:LIST:Missing valid type;");
464
		write(s1, hv0, strlen(hv0));
465
		return FALSE;
466
	}
467
 
468
	rc = sqlite3_open(fname, &db);
469
 
470
	if (rc)
471
	{
472
		syslog(LOG_WARNING, "Error opening database %s: %s", fname, sqlite3_errmsg(db));
473
		strcpy(query, "ERROR:LIST:Error opening database;");
474
		write (s1, query, strlen(query));
475
		return FALSE;
476
	}
477
 
478
	/* First count the future result set */
479
	sprintf (query, "select count(*) as cnt from musicdb where %s = \"%s\"", field, name);
480
 
481
	if (sqlite3_prepare(db, query, -1, &res, NULL) != SQLITE_OK)
482
	{
483
		syslog(LOG_DAEMON, "Error preparing SQL statement [%s]: %s", query, sqlite3_errmsg(db));
484
		strcpy(query, "ERROR:USER:Error preparing a SQL statement;");
485
		write(s1, query, strlen(query));
486
		return FALSE;
487
	}
488
 
489
	if (sqlite3_step(res) == SQLITE_ROW)
490
		pos = sqlite3_column_int(res, 0);
491
	else
492
		pos = 0;
493
 
494
	sprintf(hv0, "TOTAL:%d;", pos);
495
	write(s1, hv0, strlen(hv0));
496
	sqlite3_finalize(res);
497
 
498
	sprintf (query, "select id, title, interpret, album, genre, cover from \"main\".\"musicdb\" where %s = \"%s\" order by title", field, name);
499
 
500
	/* Tell client which page to show */
501
	sprintf(hv0, "PAGE:%s;FOLDER:%s;", p_type, name);
502
	write (s1, hv0, strlen (hv0));
503
 
504
	/* Retrieve data from database */
505
	line = 0;
506
 
507
	if (sqlite3_prepare(db, query, -1, &res, NULL) != SQLITE_OK)
508
	{
509
		syslog(LOG_DAEMON, "Error preparing SQL statement [%s]: %s", query, sqlite3_errmsg(db));
510
		strcpy(query, "ERROR:LIST:Error preparing a SQL statement;");
511
		write(s1, query, strlen(query));
512
		return FALSE;
513
	}
514
 
515
	while ((rc = sqlite3_step(res)) == SQLITE_ROW)
516
	{
517
		line++;
518
 
519
		if (line >= start && line < (start + length))
520
			listCallback(s1, p_type, line, res);
521
 
522
		if (line >= (start + length))
523
			break;
524
	}
525
 
526
	sqlite3_finalize(res);
527
	sqlite3_close(db);
528
	return TRUE;
529
}
530
 
8 andreas 531
/*
14 andreas 532
 * Count the playlists of the users and return the result.
533
 */
534
int countPlaylists()
535
{
536
	USERS *act;
537
	int count;
538
 
539
	count = 0;
540
	act = userchain;
541
 
542
	while (act)
543
	{
544
		count++;
545
		act = act->next;
546
	}
547
 
548
	return count;
549
}
550
 
551
/*
8 andreas 552
 * List the playlists of the current user.
553
 */
554
int listPlaylists(int s1, int start, int length)
555
{
556
	USERS *act;
557
	char hv0[512], *user, *playlist;
9 andreas 558
	int pos;
8 andreas 559
 
560
	if (userchain == NULL)
561
	{
562
		strcpy(hv0, "ERROR:PLAYLIST:No user selected;");
563
		write(s1, hv0, strlen(hv0));
564
		return FALSE;
565
	}
566
 
567
	act = userchain;
9 andreas 568
	pos = 1;
8 andreas 569
 
570
	while (act)
571
	{
572
		if (pos < start)
573
		{
574
			act = act->next;
575
			continue;
576
		}
577
 
9 andreas 578
		if (pos >= (start + length))
8 andreas 579
			break;
580
 
581
		user = urlencode(act->uname);
582
		playlist = urlencode(act->playlist);
9 andreas 583
		sprintf(hv0, "PLAYLIST:%d:%s:%s;", act->id, user, playlist);
584
		write (s1, hv0, strlen(hv0));
8 andreas 585
 
586
		if (user)
587
			free (user);
588
 
589
		if (playlist)
590
			free (playlist);
591
 
592
		act = act->next;
593
	}
594
 
595
	return TRUE;
596
}
9 andreas 597
 
598
int listUserPlaylist(int s1, const char *user, const char *playlist, int start, int length)
599
{
600
	char query[1024], hv0[128], buffer[8192];
601
	char fname[256];
602
	sqlite3 *db;
603
	int rc, id, total, pos, line;
604
	sqlite3_stmt *res;
11 andreas 605
	char id3_title[256], id3_artist[256], id3_album[256], id3_genre[256], id3_cover[512];
14 andreas 606
	char *title, *artist, *album, *cover;
9 andreas 607
	USERS *act;
608
 
609
	if (playlist == NULL)
610
	{
611
		strcpy(hv0, "ERROR:LIST:Missing name of playlist;");
612
		write (s1, hv0, strlen(hv0));
613
		return FALSE;
614
	}
615
 
616
	/* Check current user */
617
	if (user != NULL)
618
	{
619
		if (userchain == NULL || strcmp(userchain->uname, user))
620
		{
621
			if (!selectUser(s1, user))
622
				return FALSE;
623
		}
624
	}
625
 
626
	/* Find the playlist */
627
	act = userchain;
628
 
629
	while (act)
630
	{
631
		if (!strcmp(act->playlist, playlist))
632
			break;
633
 
634
		act = act->next;
635
	}
636
 
637
	if (act == NULL)
638
	{
639
		strcpy(hv0, "ERROR:LIST:Playlist not found;");
640
		write (s1, hv0, strlen(hv0));
641
		return FALSE;
642
	}
643
 
644
	strcpy(fname, configs.home);
645
	strcat(fname, MUSICDB);
646
 
647
	rc = sqlite3_open(fname, &db);
648
 
649
	if (rc)
650
	{
651
		syslog(LOG_WARNING, "Error opening database %s: %s", fname, sqlite3_errmsg(db));
652
		strcpy(query, "ERROR:USER:Error opening database;");
653
		write (s1, query, strlen(query));
654
		return FALSE;
655
	}
14 andreas 656
 
657
	sprintf(query, "select count(*) from musicdb as a where (select musicid from playlist as b where a.id = b.musicid and b.userid = %d)", act->id);
9 andreas 658
 
14 andreas 659
	if (sqlite3_prepare(db, query, -1, &res, NULL) != SQLITE_OK)
660
	{
661
		syslog(LOG_DAEMON, "Error preparing SQL statement [%s]: %s", query, sqlite3_errmsg(db));
662
		strcpy(hv0, "ERROR:USER:Error preparing a SQL statement;");
663
		write(s1, hv0, strlen(hv0));
664
		return FALSE;
665
	}
666
 
667
	if ((rc = sqlite3_step(res)) == SQLITE_ROW)
668
	{
669
		total = sqlite3_column_int(res, 0);
670
		sprintf(hv0, "TOTAL:%d;", total);
671
		write (s1, hv0, strlen(hv0));
672
	}
673
 
674
	sqlite3_finalize(res);
11 andreas 675
	strcpy (query, "select id, title, interpret, album, genre, cover from musicdb as a where ");
9 andreas 676
	strcat (query, "(select musicid from playlists as b where a.id = b.musicid and b.userid = ");
677
	sprintf(hv0, "%d", act->id);
678
	strcat (query, hv0);
679
	strcat (query, ")");
680
 
681
	if (sqlite3_prepare(db, query, -1, &res, NULL) != SQLITE_OK)
682
	{
683
		syslog(LOG_DAEMON, "Error preparing SQL statement [%s]: %s", query, sqlite3_errmsg(db));
684
		strcpy(hv0, "ERROR:USER:Error preparing a SQL statement;");
685
		write(s1, hv0, strlen(hv0));
686
		return FALSE;
687
	}
688
 
689
	pos = 1;
690
	line = 0;
691
 
692
	while ((rc = sqlite3_step(res)) == SQLITE_ROW)
693
	{
694
		if (pos < start)
695
		{
696
			pos++;
697
			continue;
698
		}
699
 
700
		if (pos >= (start + length))
701
			break;
702
 
703
		line++;
704
		memset(id3_title, 0, sizeof(id3_title));
705
		memset(id3_artist, 0, sizeof(id3_artist));
706
		memset(id3_album, 0, sizeof(id3_album));
707
		memset(id3_genre, 0, sizeof(id3_genre));
11 andreas 708
		memset(id3_cover, 0, sizeof(id3_cover));
9 andreas 709
		id = sqlite3_column_int(res, 0);
710
		strncpy(id3_title, (const char *)sqlite3_column_text(res, 1), sizeof(id3_title));
711
		strncpy(id3_artist, (const char *)sqlite3_column_text(res, 2), sizeof(id3_artist));
712
		strncpy(id3_album, (const char *)sqlite3_column_text(res, 3), sizeof(id3_album));
713
		strncpy(id3_genre, (const char *)sqlite3_column_text(res, 4), sizeof(id3_genre));
11 andreas 714
		strncpy(id3_cover, (const char *)sqlite3_column_text(res, 5), sizeof(id3_cover));
9 andreas 715
		title = urlencode(id3_title);
716
		artist = urlencode(id3_artist);
717
		album = urlencode(id3_album);
11 andreas 718
		cover = urlencode(id3_cover);
719
 
9 andreas 720
		if (title != NULL)
721
		{
722
			strncpy(id3_title, title, sizeof(id3_title));
723
			free(title);
724
		}
11 andreas 725
 
9 andreas 726
		if (artist != NULL)
727
		{
728
			strncpy(id3_artist, artist, sizeof(id3_artist));
729
			free(artist);
730
		}
11 andreas 731
 
9 andreas 732
		if (album != NULL)
733
		{
734
			strncpy(id3_album, album, sizeof(id3_album));
735
			free(album);
736
		}
11 andreas 737
 
738
		if (cover != NULL)
739
		{
740
			strncpy(id3_cover, cover, sizeof(id3_cover));
741
			free(cover);
742
		}
743
 
744
		sprintf (buffer, "LINE:PLAYLIST:%d:%d:%s:%s:%s:%s:%s;", id, line, id3_title, id3_artist, id3_album, id3_genre, id3_cover);
9 andreas 745
		write (s1, buffer, strlen(buffer));
746
		pos++;
747
	}
748
 
749
	sqlite3_finalize(res);
750
	sqlite3_close(db);
751
	return TRUE;
752
}