This repository has been archived on 2024-03-02. You can view files and clone it, but cannot push or open issues or pull requests.
probotic/src/api.c

237 lines
5.1 KiB
C
Raw Normal View History

2023-08-07 10:04:15 -04:00
/* api.c - Database API */
2023-08-04 11:13:47 -04:00
2023-08-07 10:04:15 -04:00
#define stmt_prepare(stmt) \
2023-08-04 11:13:47 -04:00
sqlite3_prepare_v2(connection, stmt ## _template, -1, &stmt, NULL)
VARDECL char const * db = DBFILE;
VARDECL sqlite3 * connection = NULL;
2023-08-07 07:13:13 -04:00
DECL void DBERR(const int l)
{
2023-08-07 10:04:15 -04:00
if(l != SQLITE_OK && l != SQLITE_ROW && l != SQLITE_DONE)
{
fprintf(stderr,
"sqlite (%d): %s\n",
sqlite3_errcode(connection), sqlite3_errmsg(connection));
exit(DB_ERROR);
}
2023-08-04 11:13:47 -04:00
}
DECL int
api_init(void)
{
DBERR(sqlite3_open_v2(db, &connection, SQLITE_OPEN_READWRITE, NULL));
2023-08-07 10:04:15 -04:00
/* dont you fucking dare to remove this spacing */
2023-08-04 11:13:47 -04:00
DBERR(stmt_prepare(remind_stmt));
DBERR(stmt_prepare(set_repo_stmt));
DBERR(stmt_prepare(get_nth_id_stmt));
2023-08-07 10:04:15 -04:00
DBERR(stmt_prepare(new_assignment_stmt));
DBERR(stmt_prepare(purge_assignments_stmt));
2023-08-04 11:13:47 -04:00
DBERR(stmt_prepare(is_no_assignment_stmt));
return 0;
}
DECL void
api_rope(void)
{
2023-08-07 07:13:13 -04:00
DBERR(sqlite3_finalize(remind_stmt));
DBERR(sqlite3_finalize(set_repo_stmt));
DBERR(sqlite3_finalize(get_nth_id_stmt));
DBERR(sqlite3_finalize(new_assignment_stmt));
DBERR(sqlite3_finalize(purge_assignments_stmt));
DBERR(sqlite3_finalize(is_no_assignment_stmt));
sqlite3_close(connection);
2023-08-04 11:13:47 -04:00
}
2023-08-15 09:02:32 -04:00
#define DBERR_NOMEM(v) if (v) { r = (IRC_RED "No memory!" IRC_STOP); goto fail; }
2023-08-04 11:13:47 -04:00
DECL char *
remind(char * who)
{
char * r;
char * title;
2023-08-15 09:02:32 -04:00
char * desc = NULL;
2023-08-07 10:04:15 -04:00
/* char * repo; */
2023-08-04 11:13:47 -04:00
DBERR(sqlite3_reset(remind_stmt));
DBERR(sqlite3_bind_text(remind_stmt, 1, who, -1, SQLITE_STATIC));
const int i = sqlite3_step(remind_stmt);
DBERR(i);
if (i == SQLITE_ROW)
{
title = (char *) sqlite3_column_text(remind_stmt, 0);
title = strdup(title);
2023-08-15 09:02:32 -04:00
if (!title) { goto fail; }
desc = (char *) sqlite3_column_text(remind_stmt, 1);
if (desc && (desc = strdup(desc)) == NULL)
{ goto fail; }
2023-08-07 10:04:15 -04:00
if (-1 == asprintf(&r,
2023-08-15 09:02:32 -04:00
IRC_RED "%s " IRC_YELLOW "%s" IRC_STOP,
title, desc ? desc : ""))
{ r = IRC_RED "No memory!" IRC_STOP; }
fail:
free(title);
free(desc);
2023-08-07 10:10:22 -04:00
}
else
2023-08-15 09:02:32 -04:00
{ r = IRC_RED "No current assignment." IRC_STOP; }
2023-08-07 10:04:15 -04:00
return r;
2023-08-04 11:13:47 -04:00
}
DECL void
set_repo(char const * const who,
char const * const link)
{
DBERR(sqlite3_reset(set_repo_stmt));
DBERR(sqlite3_bind_text(set_repo_stmt, 1, link, -1, SQLITE_STATIC));
DBERR(sqlite3_bind_text(set_repo_stmt, 2, who, -1, SQLITE_STATIC));
DBERR(sqlite3_step(set_repo_stmt));
}
2023-08-06 22:51:57 -04:00
#ifndef NO_VULN_COMMANDS
/* Note that this function is may not be vuln,
but is included as it's only used by vulns */
2023-08-04 11:13:47 -04:00
DECL int
rtos(void * data,
2023-08-06 22:51:57 -04:00
int argc,
char** argv,
char** colname)
{
2023-08-04 11:13:47 -04:00
(void) colname;
char ** r = (char**)data;
size_t data_len = 0;
for(int i = 0; i < argc; i++)
{
if(argv[i])
{
data_len += strlen(argv[i]);
}
else
{
/* strlen("NULL") == 4 */
data_len += 4;
}
/* strlen("|") * 2 == 2 */
data_len += 2;
}
++data_len;
*r = (char *)calloc(data_len, sizeof(char));
for(int i = 0; i < argc; i++){
2023-08-07 10:04:15 -04:00
strcat(*r, "|");
if(argv[i]){
strcat(*r, argv[i]);
}
else
{
strcat(*r, "NULL");
}
2023-08-04 11:13:47 -04:00
}
strcat(*r, "|\n");
return 0;
}
DECL char *
dump()
{
char* errmsg;
char* r = NULL;
DBERR(sqlite3_exec(connection, dump_stmt, rtos, &r, &errmsg));
return r;
}
DECL char *
raw(char const * const sql)
{
char* errmsg;
char *r = NULL;
sqlite3_exec(connection, sql, rtos, &r, &errmsg);
2023-08-06 22:51:57 -04:00
2023-08-04 11:13:47 -04:00
if (errmsg){
free(r);
2023-08-07 10:04:15 -04:00
r = errmsg;
2023-08-04 11:13:47 -04:00
} else { strcat(r, "\00"); }
return r;
}
2023-08-06 22:51:57 -04:00
#endif /* !NO_VULN_COMMANDS */
2023-08-04 11:13:47 -04:00
DECL int
get_project_count_callback(void* data, int argc, char** argv, char** colname)
{
(void)argc;
(void)colname;
2023-08-07 10:04:15 -04:00
int* count = (int*)data;
*count = atoi(argv[0]);
return 0;
2023-08-04 11:13:47 -04:00
}
DECL int
2023-08-07 10:04:15 -04:00
get_project_count(void)
2023-08-04 11:13:47 -04:00
{
2023-08-07 10:04:15 -04:00
int r = 0;
char const * sql = "SELECT COUNT(*) FROM project;";
DBERR(sqlite3_exec(connection, sql, get_project_count_callback, &r, NULL));
return r;
2023-08-04 11:13:47 -04:00
}
DECL int
get_nth_id(const int i)
{
2023-08-07 10:04:15 -04:00
int r;
DBERR(sqlite3_reset(get_nth_id_stmt));
DBERR(sqlite3_bind_int(get_nth_id_stmt, 1, i));
DBERR(sqlite3_step(get_nth_id_stmt));
r = sqlite3_column_int(get_nth_id_stmt, 0);
return r;
2023-08-04 11:13:47 -04:00
}
DECL void
2023-08-07 10:04:15 -04:00
new_assignment(char const * const who,
int const project)
2023-08-04 11:13:47 -04:00
{
2023-08-07 10:04:15 -04:00
DBERR(sqlite3_reset(new_assignment_stmt));
DBERR(sqlite3_bind_text(new_assignment_stmt, 1, who, -1, SQLITE_STATIC));
DBERR(sqlite3_bind_int(new_assignment_stmt, 2, project));
DBERR(sqlite3_step(new_assignment_stmt));
2023-08-04 11:13:47 -04:00
}
DECL void
random_assign(char const * const who)
{
int i = rand() % get_project_count();
i = get_nth_id(i);
new_assignment(who, i);
}
DECL void
purge_assignments(char const * const who)
{
DBERR(sqlite3_reset(purge_assignments_stmt));
DBERR(sqlite3_bind_text(purge_assignments_stmt, 1, who, -1, SQLITE_STATIC));
DBERR(sqlite3_step(purge_assignments_stmt));
}
2023-08-06 22:51:57 -04:00
#ifdef INITIAL_ASSIGNMENT_MESSAGE
2023-08-04 11:13:47 -04:00
DECL int
2023-08-06 22:51:57 -04:00
is_no_assignment(char const * const who)
{
2023-08-07 10:04:15 -04:00
const int e;
2023-08-04 11:13:47 -04:00
DBERR(sqlite3_reset(is_no_assignment_stmt));
DBERR(sqlite3_bind_text(is_no_assignment_stmt, 1, who, -1, SQLITE_STATIC));
2023-08-07 10:04:15 -04:00
e = sqlite3_step(is_no_assignment_stmt);
2023-08-04 11:13:47 -04:00
DBERR(e);
return (e == SQLITE_DONE);
}
2023-08-06 22:51:57 -04:00
#endif /* INITIAL_ASSIGNMENT_MESSAGE */