Rev 18 | Blame | Compare with Previous | Last modification | View Log | RSS feed
/*
* Copyright (C) 2015 by Andreas Theofilu <andreas@theosys.at>
*
* All rights reserved. No warranty, explicit or implicit, provided.
*
* NOTICE: All information contained herein is, and remains
* the property of Andreas Theofilu and his suppliers, if any.
* The intellectual and technical concepts contained
* herein are proprietary to Andreas Theofilu and its suppliers and
* may be covered by European and Foreign Patents, patents in process,
* and are protected by trade secret or copyright law.
* Dissemination of this information or reproduction of this material
* is strictly forbidden unless prior written permission is obtained
* from Andreas Theofilu.
*/
#include <stdio.h>
#include <string.h>
#include <strings.h>
#include <unistd.h>
#include <stdlib.h>
#include <ctype.h>
#include <math.h>
#include <syslog.h>
#include <errno.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <fcntl.h>
#include <sqlite3.h>
#include "config.h"
#include "helplib.h"
#include "user.h"
/* Global variables */
USERS *userchain = NULL;
/* Prototypes */
USERS *addUser();
int createUser(int s1, char *user, char *playlist)
{
char query[1024];
char fname[256];
sqlite3 *db;
int rc;
sqlite3_stmt *res;
USERS *neu;
strcpy(fname, configs.home);
strcat(fname, MUSICDB);
rc = sqlite3_open(fname, &db);
if (rc)
{
syslog(LOG_WARNING, "Error opening database %s: %s", fname, sqlite3_errmsg(db));
strcpy(query, "ERROR:USER:Error opening database;");
write (s1, query, strlen(query));
return FALSE;
}
sprintf(query, "select id, uname from \"main\".\"users\" where uname = \"%s\" and playlist = \"%s\"", user, playlist);
if (sqlite3_prepare(db, query, -1, &res, NULL) != SQLITE_OK)
{
syslog(LOG_DAEMON, "Error preparing SQL statement [%s]: %s", query, sqlite3_errmsg(db));
strcpy(query, "ERROR:USER:Error preparing a SQL statement;");
write(s1, query, strlen(query));
return FALSE;
}
rc = sqlite3_step(res);
if (rc == SQLITE_ROW) /* If we've a row, the user exists and we'll not add it again */
{
sqlite3_finalize(res);
sqlite3_close(db);
return TRUE;
}
sprintf(query, "insert into \"users\" (uname, playlist) values (\"%s\", \"%s\")", user, playlist);
if (sqlite3_prepare(db, query, -1, &res, NULL) != SQLITE_OK)
{
syslog(LOG_DAEMON, "Error preparing SQL statement [%s]: %s", query, sqlite3_errmsg(db));
strcpy(query, "ERROR:USER:Error preparing a SQL statement;");
write(s1, query, strlen(query));
return FALSE;
}
rc = sqlite3_step(res);
sqlite3_finalize(res);
sqlite3_close(db);
scanUser(s1, user);
return TRUE;
}
USERS *addUser()
{
if (userchain == NULL)
{
if ((userchain = (USERS *)malloc(sizeof(USERS))) == NULL)
{
syslog(LOG_DAEMON, "Error allocating %ld bytes for a user: %s", sizeof(USERS), strerror(errno));
return NULL;
}
memset(userchain, 0, sizeof(USERS));
return userchain;
}
else
{
USERS *neu, *act;
if ((neu = (USERS *)malloc(sizeof(USERS))) == NULL)
{
syslog(LOG_DAEMON, "Error allocating %ld bytes for a user: %s", sizeof(USERS), strerror(errno));
return NULL;
}
memset(neu, 0, sizeof(USERS));
/* Find last structure in chain */
act = userchain;
while (act->next)
act = act->next;
act->next = neu;
return neu;
}
}
void deleteUser()
{
USERS *act;
act = userchain;
while (act)
{
userchain = act->next;
free(act);
act = userchain;
}
userchain = NULL;
}
int selectUser (int s1, const char *user)
{
char query[1024], hv0[128];
char fname[256];
sqlite3 *db;
int rc, total;
sqlite3_stmt *res;
strcpy(fname, configs.home);
strcat(fname, MUSICDB);
rc = sqlite3_open(fname, &db);
if (rc)
{
syslog(LOG_WARNING, "Error opening database %s: %s", fname, sqlite3_errmsg(db));
strcpy(query, "ERROR:USER:Error opening database;");
write (s1, query, strlen(query));
return FALSE;
}
deleteUser();
/* First count the future result set */
sprintf (query, "select count(*) as cnt from users where uname = \"%s\"", user);
if (sqlite3_prepare(db, query, -1, &res, NULL) != SQLITE_OK)
{
syslog(LOG_DAEMON, "Error preparing SQL statement [%s]: %s", query, sqlite3_errmsg(db));
strcpy(query, "ERROR:USER:Error preparing a SQL statement;");
write(s1, query, strlen(query));
total = 0;
}
else if (sqlite3_step(res) == SQLITE_ROW)
total = sqlite3_column_int(res, 0);
else
total = 0;
sprintf(hv0, "USER:%s;TOTAL:%d;", user, total);
write(s1, hv0, strlen(hv0));
sqlite3_finalize(res);
sprintf(query, "select id, uname, playlist from \"main\".\"users\" where uname = \"%s\"", user);
if (sqlite3_prepare(db, query, -1, &res, NULL) != SQLITE_OK)
{
syslog(LOG_DAEMON, "Error preparing SQL statement [%s]: %s", query, sqlite3_errmsg(db));
strcpy(query, "ERROR:USER:Error preparing a SQL statement;");
write(s1, query, strlen(query));
return FALSE;
}
while ((rc = sqlite3_step(res)) == SQLITE_ROW)
{
USERS *act;
if ((act = addUser()) == NULL)
{
sqlite3_finalize(res);
sqlite3_close(db);
return FALSE;
}
act->id = sqlite3_column_int(res, 0);
strncpy(act->uname, (const char *)sqlite3_column_text(res, 1), sizeof(act->uname));
strncpy(act->playlist, (const char *)sqlite3_column_text(res, 2), sizeof(act->playlist));
}
sqlite3_finalize(res);
sqlite3_close(db);
return TRUE;
}
void scanUser(int s1, char *user)
{
char query[1024], hv0[128];
char fname[256];
sqlite3 *db;
int rc;
sqlite3_stmt *res;
USERS *act;
if (user == NULL)
return;
deleteUser();
strcpy(fname, configs.home);
strcat(fname, MUSICDB);
if ((rc = sqlite3_open(fname, &db)) != SQLITE_OK)
{
syslog(LOG_WARNING, "Error opening database %s: %s", fname, sqlite3_errmsg(db));
strcpy(hv0, "ERROR:USER:Error opening database;");
write (s1, hv0, strlen(hv0));
return;
}
sprintf(query, "select id, uname, playlist from \"main\".\"users\" where uname = \"%s\"", user);
if (sqlite3_prepare(db, query, -1, &res, NULL) != SQLITE_OK)
{
syslog(LOG_DAEMON, "Error preparing SQL statement [%s]: %s", query, sqlite3_errmsg(db));
strcpy(hv0, "ERROR:USER:Error preparing a SQL statement;");
write(s1, hv0, strlen(hv0));
}
while ((rc = sqlite3_step(res)) == SQLITE_ROW)
{
if ((act = addUser()) == NULL)
{
sqlite3_finalize(res);
sqlite3_close(db);
return;
}
act->id = sqlite3_column_int(res, 0);
strncpy(act->uname, (const char *)sqlite3_column_text(res, 1), sizeof(act->uname));
strncpy(act->playlist, (const char *)sqlite3_column_text(res, 2), sizeof(act->playlist));
}
sqlite3_finalize(res);
sqlite3_close(db);
}
USERS *findPlaylist(char *user, char *playlist)
{
USERS *act;
act = userchain;
while (act)
{
if (!strcmp(act->uname, user) && !strcmp(act->playlist, playlist))
return act;
act = act->next;
}
return NULL;
}