Subversion Repositories mdb

Rev

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;
}