Subversion Repositories mdb

Rev

Rev 24 | Rev 29 | 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
	}
24 andreas 122
	else if (strcmp(p_type, "USERS") == 0)
123
	{
124
		sqlite3_close(db);
125
		return listUsers(s1, start, length);
126
	}
5 andreas 127
	else		/* No or unknown type */
128
	{
129
		strcpy (query, "ERROR:LIST:Missing type;");
130
		write(s1, query, strlen(query));
131
		sqlite3_close(db);
132
		return FALSE;
133
	}
134
 
11 andreas 135
	/* Tell client which page to show */
136
	sprintf(hv0, "PAGE:%s;", p_type);
137
	write (s1, hv0, strlen (hv0));
138
 
139
	/* Retrieve data from database */
25 andreas 140
	line = pos = 0;
5 andreas 141
 
12 andreas 142
	if (sqlite3_prepare(db, query, -1, &res, NULL) != SQLITE_OK)
5 andreas 143
	{
12 andreas 144
		syslog(LOG_DAEMON, "Error preparing SQL statement [%s]: %s", query, sqlite3_errmsg(db));
145
		strcpy(query, "ERROR:USER:Error preparing a SQL statement;");
146
		write(s1, query, strlen(query));
5 andreas 147
		return FALSE;
148
	}
149
 
12 andreas 150
	while ((rc = sqlite3_step(res)) == SQLITE_ROW)
5 andreas 151
	{
25 andreas 152
		pos++;
12 andreas 153
 
25 andreas 154
		if (pos >= start && pos < (start + length))
155
		{
156
			line++;
12 andreas 157
			listCallback(s1, p_type, line, res);
25 andreas 158
		}
12 andreas 159
 
25 andreas 160
		if (pos >= (start + length))
12 andreas 161
			break;
5 andreas 162
	}
163
 
12 andreas 164
	sqlite3_finalize(res);
5 andreas 165
	sqlite3_close(db);
166
	return TRUE;
167
}
168
 
8 andreas 169
int listQueue(int s1, int start, int length)
170
{
11 andreas 171
	int fd, line;
172
	char fname[256], hv0[256], buffer[8192];
173
	char *title, *artist, *album, *cover;
174
	int pos;
175
	QUEUE *act;
8 andreas 176
 
11 andreas 177
	if (pqueue == NULL)
8 andreas 178
	{
11 andreas 179
		strcpy (fname, configs.home);
180
		strcat (fname, NOWPLAY);
8 andreas 181
 
11 andreas 182
		if (access(fname, R_OK))
183
		{
184
			strcpy (hv0, "ERROR:LIST:No or empty queue;");
185
			write (s1, hv0, strlen(hv0));
186
			return FALSE;
187
		}
8 andreas 188
 
11 andreas 189
		if ((fd = open(fname, O_RDONLY)) <= 0)
190
		{
191
			syslog(LOG_WARNING, "Error opening file %s: %s", fname, strerror(errno));
192
			strcpy(hv0, "ERROR:LIST:Error opening queue;");
193
			write(s1, hv0, strlen(hv0));
194
			return FALSE;
195
		}
8 andreas 196
 
11 andreas 197
		scanQueue(fd);
198
		close(fd);
199
	}
8 andreas 200
 
11 andreas 201
	sprintf(hv0, "PAGE:QUEUE;TOTAL:%d;", queueTotal);
202
	write (s1, hv0, strlen(hv0));
203
	act = pqueue;
204
	pos = line = 1;
8 andreas 205
 
11 andreas 206
	while (act)
8 andreas 207
	{
208
		if (pos < start)
25 andreas 209
		{
210
			act = act->next;
211
			pos++;
8 andreas 212
			continue;
25 andreas 213
		}
214
		else if (pos >= (start + length))
8 andreas 215
			break;
216
 
11 andreas 217
		title = urlencode(act->title);
218
		artist = urlencode(act->artist);
219
		album = urlencode(act->album);
220
		cover = urlencode(act->cover);
221
		sprintf(buffer, "LINE:QUEUE:%d:%d:", act->id, line);
8 andreas 222
 
223
		if (title != NULL)
224
		{
225
			strcat(buffer, title);
226
			free(title);
227
		}
228
		else
11 andreas 229
			strcat(buffer, act->title);
230
 
8 andreas 231
		strcat(buffer, ":");
11 andreas 232
 
8 andreas 233
		if (artist != NULL)
234
		{
235
			strcat(buffer, artist);
236
			free(artist);
237
		}
238
		else
11 andreas 239
			strcat(buffer, act->artist);
240
 
8 andreas 241
		strcat(buffer, ":");
11 andreas 242
 
8 andreas 243
		if (album != NULL)
244
		{
245
			strcat(buffer, album);
246
			free(album);
247
		}
248
		else
11 andreas 249
			strcat(buffer, act->album);
250
 
8 andreas 251
		strcat(buffer, ":");
11 andreas 252
		strcat(buffer, act->genre);
253
		strcat(buffer, ":");
254
 
255
		if (cover != NULL)
256
		{
257
			strcat(buffer, cover);
258
			free(cover);
259
		}
260
		else
261
			strcat(buffer, act->cover);
262
 
8 andreas 263
		strcat(buffer, ";");
264
		write(s1, buffer, strlen(buffer));
11 andreas 265
		act = act->next;
25 andreas 266
		pos++;
11 andreas 267
		line++;
8 andreas 268
	}
269
 
270
	return TRUE;
271
}
272
 
5 andreas 273
int listFolders(int s1, char *p_type, int start, int length)
274
{
275
	char query[1024], field[16];
276
	char fname[256];
277
	sqlite3 *db;
278
	char *zErrMsg = 0;
279
	int rc;
280
	struct callPars cp;
281
 
282
	strcpy(fname, configs.home);
9 andreas 283
	strcat(fname, MUSICDB);
5 andreas 284
 
285
	rc = sqlite3_open(fname, &db);
286
 
287
	if (rc)
288
	{
289
		syslog(LOG_WARNING, "Error opening database %s: %s", fname, sqlite3_errmsg(db));
290
		strcpy(query, "ERROR:FOLDER:Error opening database;");
291
		write (s1, query, strlen(query));
292
		return FALSE;
293
	}
294
 
295
	strcpy (query, "select distinct ");
296
 
297
	if (strcmp(p_type, "TITLE") == 0)
298
		strcpy (field, "title");
299
	else if (strcmp(p_type, "ARTIST") == 0)
300
		strcpy (field, "interpret");
301
	else if (strcmp(p_type, "ALBUM") == 0)
302
		strcpy (field, "album");
303
	else if (strcmp(p_type, "GENRE") == 0)
304
		strcpy (field, "genre");
305
	else		/* No or unknown type */
306
	{
307
		strcpy (query, "ERROR:FOLDER:Missing type;");
308
		write(s1, query, strlen(query));
309
		sqlite3_close(db);
310
		return FALSE;
311
	}
312
 
313
	strcat (query, field);
25 andreas 314
	strcat (query, " from \"main\".\"musicdb\" order by ");
5 andreas 315
	strcat (query, field);
316
 
317
	cp.s1 = s1;
318
	cp.type = p_type;
319
	cp.start = start;
320
	cp.length = length;
12 andreas 321
	globalLine = 0;
25 andreas 322
	globalPos = 0;
5 andreas 323
 
324
	if ((rc = sqlite3_exec(db, query, folderCallback, (void *)&cp, &zErrMsg)) != SQLITE_OK)
325
	{
326
		syslog(LOG_WARNING, "SQL error [%s]: %s", query, zErrMsg);
327
		sqlite3_free(zErrMsg);
328
		sqlite3_close(db);
329
		strcpy(query, "ERROR:FOLDER:SQL error;");
330
		write (s1, query, strlen(query));
331
		return FALSE;
332
	}
333
 
12 andreas 334
	if (globalPos >= 0)
5 andreas 335
	{
12 andreas 336
		sprintf(query, "TOTAL:%d;", globalPos + 1);
5 andreas 337
		write (s1, query, strlen(query));
338
	}
339
 
340
	sqlite3_close(db);
341
	return TRUE;
342
}
343
 
12 andreas 344
static int listCallback(int s1, char *type, int line, sqlite3_stmt *res)
5 andreas 345
{
14 andreas 346
	int id;
12 andreas 347
	char id3_title[256], id3_artist[256], id3_album[256], id3_genre[256], id3_cover[256];
5 andreas 348
	char buffer[8192];
12 andreas 349
	char *title, *artist, *album;
5 andreas 350
 
351
	memset(id3_title, 0, sizeof(id3_title));
352
	memset(id3_artist, 0, sizeof(id3_artist));
353
	memset(id3_album, 0, sizeof(id3_album));
354
	memset(id3_genre, 0, sizeof(id3_genre));
11 andreas 355
	memset(id3_cover, 0, sizeof(id3_cover));
5 andreas 356
	id = -1;
12 andreas 357
	id = sqlite3_column_int(res, 0);
358
	strncpy(id3_title, (const char *)sqlite3_column_text(res, 1), sizeof(id3_title));
359
	strncpy(id3_artist, (const char *)sqlite3_column_text(res, 2), sizeof(id3_artist));
360
	strncpy(id3_album, (const char *)sqlite3_column_text(res, 3), sizeof(id3_album));
361
	strncpy(id3_genre, (const char *)sqlite3_column_text(res, 4), sizeof(id3_genre));
362
	strncpy(id3_cover, (const char *)sqlite3_column_text(res, 5), sizeof(id3_cover));
5 andreas 363
 
364
	title = urlencode(id3_title);
365
	artist = urlencode(id3_artist);
11 andreas 366
	album = urlencode(id3_album);
5 andreas 367
 
12 andreas 368
	sprintf(buffer, "LINE:%s:%d:%d:", type, id, line);
5 andreas 369
 
370
	if (title != NULL)
371
	{
372
		strcat(buffer, title);
373
		free(title);
374
	}
375
	else
376
		strcat(buffer, id3_title);
12 andreas 377
 
5 andreas 378
	strcat(buffer, ":");
12 andreas 379
 
5 andreas 380
	if (artist != NULL)
381
	{
382
		strcat(buffer, artist);
383
		free(artist);
384
	}
385
	else
386
		strcat(buffer, id3_artist);
12 andreas 387
 
5 andreas 388
	strcat(buffer, ":");
12 andreas 389
 
5 andreas 390
	if (album != NULL)
391
	{
392
		strcat(buffer, album);
393
		free(album);
394
	}
395
	else
396
		strcat(buffer, id3_album);
12 andreas 397
 
5 andreas 398
	strcat(buffer, ":");
399
	strcat(buffer, id3_genre);
11 andreas 400
	strcat(buffer, ":");
12 andreas 401
	strcat(buffer, id3_cover);
5 andreas 402
	strcat(buffer, ";");
12 andreas 403
	write(s1, buffer, strlen(buffer));
5 andreas 404
	return 0;
405
}
406
 
407
static int folderCallback(void *hint, int argc, char **argv, char **azColName)
408
{
409
	int i;
25 andreas 410
	char id3_buffer[256];
5 andreas 411
	char buffer[8192];
412
	char *buf;
413
	struct callPars *cp;
414
 
12 andreas 415
	globalPos++;
5 andreas 416
	cp = (struct callPars *)hint;
417
	memset(id3_buffer, 0, sizeof(id3_buffer));
418
 
12 andreas 419
	if (globalPos < cp->start || globalPos >= (cp->start + cp->length))
5 andreas 420
		return 0;
421
 
422
	for(i = 0; i < argc; i++)
423
	{
424
		if (strcasecmp(azColName[i], "title") == 0 || strcasecmp(azColName[i], "interpret") == 0 ||
425
			strcasecmp(azColName[i], "album") == 0 || strcasecmp(azColName[i], "genre") == 0)
426
			if (argv[i])
427
				strncpy(id3_buffer, argv[i], sizeof(id3_buffer));
428
	}
429
 
430
	buf = urlencode(id3_buffer);
12 andreas 431
	globalLine++;
5 andreas 432
 
12 andreas 433
	sprintf(buffer, "FOLDER:%s:%d:", cp->type, globalLine);
5 andreas 434
 
435
	if (buf != NULL)
436
	{
437
		strcat(buffer, buf);
438
		free(buf);
439
	}
440
	else
441
		strcat(buffer, id3_buffer);
442
 
443
	strcat(buffer, ";");
444
	write(cp->s1, buffer, strlen(buffer));
445
	return 0;
446
}
8 andreas 447
 
13 andreas 448
int listFolderContent(int s1, char *p_type, char *name, int start, int length)
449
{
450
	char query[1024], hv0[128], field[32];
451
	char fname[256];
452
	sqlite3 *db;
453
	sqlite3_stmt *res;
454
	int rc, pos, line;
455
 
456
	strcpy(fname, configs.home);
457
	strcat(fname, MUSICDB);
458
 
459
	if (!strcasecmp(p_type, "TITLE"))
460
		strcpy (field, "title");
461
	else if (!strcasecmp(p_type, "ARTIST"))
462
		strcpy (field, "interpret");
463
	else if (!strcasecmp(p_type, "ALBUM"))
464
		strcpy (field, "album");
465
	else if (!strcasecmp(p_type, "GENRE"))
466
		strcpy (field, "genre");
467
	else
468
	{
469
		strcpy (hv0, "ERROR:LIST:Missing valid type;");
470
		write(s1, hv0, strlen(hv0));
471
		return FALSE;
472
	}
473
 
474
	rc = sqlite3_open(fname, &db);
475
 
476
	if (rc)
477
	{
478
		syslog(LOG_WARNING, "Error opening database %s: %s", fname, sqlite3_errmsg(db));
479
		strcpy(query, "ERROR:LIST:Error opening database;");
480
		write (s1, query, strlen(query));
481
		return FALSE;
482
	}
483
 
484
	/* First count the future result set */
485
	sprintf (query, "select count(*) as cnt from musicdb where %s = \"%s\"", field, name);
486
 
487
	if (sqlite3_prepare(db, query, -1, &res, NULL) != SQLITE_OK)
488
	{
489
		syslog(LOG_DAEMON, "Error preparing SQL statement [%s]: %s", query, sqlite3_errmsg(db));
490
		strcpy(query, "ERROR:USER:Error preparing a SQL statement;");
491
		write(s1, query, strlen(query));
492
		return FALSE;
493
	}
494
 
495
	if (sqlite3_step(res) == SQLITE_ROW)
496
		pos = sqlite3_column_int(res, 0);
497
	else
498
		pos = 0;
499
 
500
	sprintf(hv0, "TOTAL:%d;", pos);
501
	write(s1, hv0, strlen(hv0));
502
	sqlite3_finalize(res);
503
 
504
	sprintf (query, "select id, title, interpret, album, genre, cover from \"main\".\"musicdb\" where %s = \"%s\" order by title", field, name);
505
 
506
	/* Tell client which page to show */
25 andreas 507
	sprintf(hv0, "PAGE:%s;FOLDERNAME:%s;", p_type, name);
13 andreas 508
	write (s1, hv0, strlen (hv0));
509
 
510
	/* Retrieve data from database */
511
	line = 0;
512
 
513
	if (sqlite3_prepare(db, query, -1, &res, NULL) != SQLITE_OK)
514
	{
515
		syslog(LOG_DAEMON, "Error preparing SQL statement [%s]: %s", query, sqlite3_errmsg(db));
516
		strcpy(query, "ERROR:LIST:Error preparing a SQL statement;");
517
		write(s1, query, strlen(query));
518
		return FALSE;
519
	}
520
 
521
	while ((rc = sqlite3_step(res)) == SQLITE_ROW)
522
	{
523
		line++;
524
 
525
		if (line >= start && line < (start + length))
526
			listCallback(s1, p_type, line, res);
527
 
528
		if (line >= (start + length))
529
			break;
530
	}
531
 
532
	sqlite3_finalize(res);
533
	sqlite3_close(db);
534
	return TRUE;
535
}
536
 
8 andreas 537
/*
14 andreas 538
 * Count the playlists of the users and return the result.
539
 */
540
int countPlaylists()
541
{
542
	USERS *act;
543
	int count;
544
 
545
	count = 0;
546
	act = userchain;
547
 
548
	while (act)
549
	{
550
		count++;
551
		act = act->next;
552
	}
553
 
554
	return count;
555
}
556
 
557
/*
8 andreas 558
 * List the playlists of the current user.
559
 */
560
int listPlaylists(int s1, int start, int length)
561
{
562
	USERS *act;
563
	char hv0[512], *user, *playlist;
9 andreas 564
	int pos;
8 andreas 565
 
566
	if (userchain == NULL)
567
	{
568
		strcpy(hv0, "ERROR:PLAYLIST:No user selected;");
569
		write(s1, hv0, strlen(hv0));
570
		return FALSE;
571
	}
572
 
573
	act = userchain;
9 andreas 574
	pos = 1;
8 andreas 575
 
576
	while (act)
577
	{
578
		if (pos < start)
579
		{
580
			act = act->next;
581
			continue;
582
		}
583
 
9 andreas 584
		if (pos >= (start + length))
8 andreas 585
			break;
586
 
587
		user = urlencode(act->uname);
588
		playlist = urlencode(act->playlist);
9 andreas 589
		sprintf(hv0, "PLAYLIST:%d:%s:%s;", act->id, user, playlist);
590
		write (s1, hv0, strlen(hv0));
8 andreas 591
 
592
		if (user)
593
			free (user);
594
 
595
		if (playlist)
596
			free (playlist);
597
 
598
		act = act->next;
599
	}
600
 
601
	return TRUE;
602
}
9 andreas 603
 
604
int listUserPlaylist(int s1, const char *user, const char *playlist, int start, int length)
605
{
606
	char query[1024], hv0[128], buffer[8192];
607
	char fname[256];
608
	sqlite3 *db;
609
	int rc, id, total, pos, line;
610
	sqlite3_stmt *res;
11 andreas 611
	char id3_title[256], id3_artist[256], id3_album[256], id3_genre[256], id3_cover[512];
14 andreas 612
	char *title, *artist, *album, *cover;
9 andreas 613
	USERS *act;
614
 
615
	if (playlist == NULL)
616
	{
617
		strcpy(hv0, "ERROR:LIST:Missing name of playlist;");
618
		write (s1, hv0, strlen(hv0));
619
		return FALSE;
620
	}
621
 
622
	/* Check current user */
623
	if (user != NULL)
624
	{
625
		if (userchain == NULL || strcmp(userchain->uname, user))
626
		{
627
			if (!selectUser(s1, user))
628
				return FALSE;
629
		}
630
	}
631
 
632
	/* Find the playlist */
633
	act = userchain;
634
 
635
	while (act)
636
	{
637
		if (!strcmp(act->playlist, playlist))
638
			break;
639
 
640
		act = act->next;
641
	}
642
 
643
	if (act == NULL)
644
	{
645
		strcpy(hv0, "ERROR:LIST:Playlist not found;");
646
		write (s1, hv0, strlen(hv0));
647
		return FALSE;
648
	}
649
 
650
	strcpy(fname, configs.home);
651
	strcat(fname, MUSICDB);
652
 
653
	rc = sqlite3_open(fname, &db);
654
 
655
	if (rc)
656
	{
657
		syslog(LOG_WARNING, "Error opening database %s: %s", fname, sqlite3_errmsg(db));
658
		strcpy(query, "ERROR:USER:Error opening database;");
659
		write (s1, query, strlen(query));
660
		return FALSE;
661
	}
14 andreas 662
 
18 andreas 663
	sprintf(query, "select count(*) from musicdb as a where (select musicid from playlists as b where a.id = b.musicid and b.userid = %d)", act->id);
9 andreas 664
 
14 andreas 665
	if (sqlite3_prepare(db, query, -1, &res, NULL) != SQLITE_OK)
666
	{
667
		syslog(LOG_DAEMON, "Error preparing SQL statement [%s]: %s", query, sqlite3_errmsg(db));
668
		strcpy(hv0, "ERROR:USER:Error preparing a SQL statement;");
669
		write(s1, hv0, strlen(hv0));
670
		return FALSE;
671
	}
672
 
673
	if ((rc = sqlite3_step(res)) == SQLITE_ROW)
674
	{
675
		total = sqlite3_column_int(res, 0);
676
		sprintf(hv0, "TOTAL:%d;", total);
677
		write (s1, hv0, strlen(hv0));
678
	}
679
 
680
	sqlite3_finalize(res);
11 andreas 681
	strcpy (query, "select id, title, interpret, album, genre, cover from musicdb as a where ");
9 andreas 682
	strcat (query, "(select musicid from playlists as b where a.id = b.musicid and b.userid = ");
683
	sprintf(hv0, "%d", act->id);
684
	strcat (query, hv0);
685
	strcat (query, ")");
686
 
687
	if (sqlite3_prepare(db, query, -1, &res, NULL) != SQLITE_OK)
688
	{
689
		syslog(LOG_DAEMON, "Error preparing SQL statement [%s]: %s", query, sqlite3_errmsg(db));
690
		strcpy(hv0, "ERROR:USER:Error preparing a SQL statement;");
691
		write(s1, hv0, strlen(hv0));
692
		return FALSE;
693
	}
694
 
695
	pos = 1;
696
	line = 0;
697
 
698
	while ((rc = sqlite3_step(res)) == SQLITE_ROW)
699
	{
700
		if (pos < start)
701
		{
702
			pos++;
703
			continue;
704
		}
705
 
706
		if (pos >= (start + length))
707
			break;
708
 
709
		line++;
710
		memset(id3_title, 0, sizeof(id3_title));
711
		memset(id3_artist, 0, sizeof(id3_artist));
712
		memset(id3_album, 0, sizeof(id3_album));
713
		memset(id3_genre, 0, sizeof(id3_genre));
11 andreas 714
		memset(id3_cover, 0, sizeof(id3_cover));
9 andreas 715
		id = sqlite3_column_int(res, 0);
716
		strncpy(id3_title, (const char *)sqlite3_column_text(res, 1), sizeof(id3_title));
717
		strncpy(id3_artist, (const char *)sqlite3_column_text(res, 2), sizeof(id3_artist));
718
		strncpy(id3_album, (const char *)sqlite3_column_text(res, 3), sizeof(id3_album));
719
		strncpy(id3_genre, (const char *)sqlite3_column_text(res, 4), sizeof(id3_genre));
11 andreas 720
		strncpy(id3_cover, (const char *)sqlite3_column_text(res, 5), sizeof(id3_cover));
9 andreas 721
		title = urlencode(id3_title);
722
		artist = urlencode(id3_artist);
723
		album = urlencode(id3_album);
11 andreas 724
		cover = urlencode(id3_cover);
725
 
9 andreas 726
		if (title != NULL)
727
		{
728
			strncpy(id3_title, title, sizeof(id3_title));
729
			free(title);
730
		}
11 andreas 731
 
9 andreas 732
		if (artist != NULL)
733
		{
734
			strncpy(id3_artist, artist, sizeof(id3_artist));
735
			free(artist);
736
		}
11 andreas 737
 
9 andreas 738
		if (album != NULL)
739
		{
740
			strncpy(id3_album, album, sizeof(id3_album));
741
			free(album);
742
		}
11 andreas 743
 
744
		if (cover != NULL)
745
		{
746
			strncpy(id3_cover, cover, sizeof(id3_cover));
747
			free(cover);
748
		}
749
 
750
		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 751
		write (s1, buffer, strlen(buffer));
752
		pos++;
753
	}
754
 
755
	sqlite3_finalize(res);
756
	sqlite3_close(db);
757
	return TRUE;
758
}
24 andreas 759
 
760
int listUsers(int s1, int start, int length)
761
{
762
	char query[1024], hv0[256];
763
	char fname[256], uname[128], *un;
764
	sqlite3 *db;
765
	int rc, id, total, pos;
766
	sqlite3_stmt *res;
767
 
768
	rc = sqlite3_open(fname, &db);
769
 
770
	if (rc)
771
	{
772
		syslog(LOG_WARNING, "Error opening database %s: %s", fname, sqlite3_errmsg(db));
773
		strcpy(query, "ERROR:LIST:Error opening database;");
774
		write (s1, query, strlen(query));
775
		return FALSE;
776
	}
777
 
778
	sprintf(query, "select distinct count(*) from users order by uname");
779
 
780
	if (sqlite3_prepare(db, query, -1, &res, NULL) != SQLITE_OK)
781
	{
782
		syslog(LOG_DAEMON, "Error preparing SQL statement [%s]: %s", query, sqlite3_errmsg(db));
783
		strcpy(hv0, "ERROR:USER:Error preparing a SQL statement;");
784
		write(s1, hv0, strlen(hv0));
785
		return FALSE;
786
	}
787
 
788
	if ((rc = sqlite3_step(res)) == SQLITE_ROW)
789
	{
790
		total = sqlite3_column_int(res, 0);
791
		sprintf(hv0, "TOTAL:%d;", total);
792
		write (s1, hv0, strlen(hv0));
793
	}
794
 
795
	sqlite3_finalize(res);
796
 
797
	strcpy (query, "select distinct uname, id from users order by users");
798
 
799
	if (sqlite3_prepare(db, query, -1, &res, NULL) != SQLITE_OK)
800
	{
801
		syslog(LOG_DAEMON, "Error preparing SQL statement [%s]: %s", query, sqlite3_errmsg(db));
802
		strcpy(hv0, "ERROR:USER:Error preparing a SQL statement;");
803
		write(s1, hv0, strlen(hv0));
804
		return FALSE;
805
	}
806
 
807
	pos = 0;
808
 
809
	while ((rc = sqlite3_step(res)) == SQLITE_ROW)
810
	{
811
		pos++;
812
 
813
		if (pos < start)
814
			continue;
815
 
816
		if (pos >= (start + length))
817
			break;
818
 
819
		strncpy(uname, (const char *)sqlite3_column_text(res, 0), sizeof(uname));
820
		id = sqlite3_column_int(res, 1);
821
		un = urlencode(uname);
822
 
823
		if (un)
824
		{
825
			strncpy(uname, un, sizeof(uname));
826
			free(un);
827
		}
828
 
829
		sprintf(hv0, "USERS:%d:%d:%s;", id, pos+1, uname);
830
		write(s1, hv0, strlen(hv0));
831
	}
832
 
833
	sqlite3_finalize(res);
834
	sqlite3_close(db);
835
	return TRUE;
836
}