From 6b6a28d47f0238a8700a35d8648cb587ec49a79b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Anton=20Luka=20=C5=A0ijanec?= Date: Mon, 16 May 2022 18:50:12 +0200 Subject: =?UTF-8?q?compila=20se,=20po=C5=BEene,=20=C5=A1e=20veliko=20stvar?= =?UTF-8?q?i=20za=20narediti,=20zdaj=20se=20grem=20pa=20res=20u=C4=8Dit=20?= =?UTF-8?q?kemijo?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- lib.c | 5 ++++ prijave.c | 91 +++++++++++++++++++++++++++++++++++++++++++++------------------ 2 files changed, 71 insertions(+), 25 deletions(-) diff --git a/lib.c b/lib.c index 2dea5a9..0df787d 100644 --- a/lib.c +++ b/lib.c @@ -71,3 +71,8 @@ static char * htmlspecialchars (const char * i) { /* remember to free the output o[w++] = '\0'; return o; } +static char * hscf (char * i) { // htmlspecialchars and free + char * hsc = htmlspecialchars(i); + free(i); + return hsc; +} diff --git a/prijave.c b/prijave.c index 4279920..c9edb56 100644 --- a/prijave.c +++ b/prijave.c @@ -33,6 +33,7 @@ enum question { RADIO = (0 << 0), CHECKBOX = (1 << 0), TEXT = (1 << 1), + HIDDEN = (1 << 2), // options: NOT_NULL = (1 << 5) }; @@ -77,40 +78,80 @@ static enum MHD_Result iterator (void * userdata, enum MHD_ValueKind kind __attr OBTAIN_PARAMETER(pd); return MHD_YES; } -char * db_error (sqlite3 * db, const char * section, int ret, sqlite3_stmt * stmt) { +char * db_error (sqlite3 * db, const char * section, int ret, sqlite3_stmt * stmt, const char * statem) { char spaces[2048]; memset(spaces, ' ', 2048); spaces[2047] = '\0'; - int len = strlen(sqlite3_errstr(ret))+strlen(sqlite3_errmsg(db))+strlen(section)+strlen(sqlite3_expanded_sql(stmt) ? sqlite3_expanded_sql(stmt) : 0)+512+2*strlen(statem); + int len = strlen(sqlite3_errstr(ret))+strlen(sqlite3_errmsg(db))+strlen(section)+512+2*strlen(statem); + if (stmt) + len += strlen(sqlite3_expanded_sql(stmt) ? sqlite3_expanded_sql(stmt) : ""); char * response = malloc(len); if (!response) return NULL; - snprintf(response, len, "db_error %s\n%s\n%s\n%.*s^\n%s\n%s\n", section, sqlite3_expanded_sql(stmt) ? sqlite3_expanded_sql(stmt) : 0, statem, sqlite3_error_offset(db) == -1 ? 0 : sqlite3_error_offset(db), spaces, sqlite3_errstr(ret), sqlite3_errmsg(db)); + if (stmt) + snprintf(response, len, "db_error %s\n%s\n%s\n%.*s^\n%s\n%s\n", section, sqlite3_expanded_sql(stmt) ? sqlite3_expanded_sql(stmt) : 0, statem, sqlite3_error_offset(db) == -1 ? 0 : sqlite3_error_offset(db), spaces, sqlite3_errstr(ret), sqlite3_errmsg(db)); + else + snprintf(response, len, "db_error %s\n!stmt\n%s\n%.*s^\n%s\n%s\n", section, statem, sqlite3_error_offset(db) == -1 ? 0 : sqlite3_error_offset(db), spaces, sqlite3_errstr(ret), sqlite3_errmsg(db)); fprintf(stderr, "%s", response); - stmt_finalize(stmt); + sqlite3_finalize(stmt); + return response; } -static char * options (sqlite3 db, sqlite3_int64 id, int poll_admin) { +static char * options (sqlite3 * db, sqlite3_int64 id, int poll_admin, enum question type __attribute__((unused))) { + int ret; + char statem[2048]; sqlite3_stmt * stmt; // cheat sheet stavek vrne tabelo s stolpci: // id obrazca, ime obrazca, število vprašanj v stolpcu // SELECT polls.rowid, polls.name, COUNT(*) FROM polls INNER JOIN questions ON questions.poll = polls.rowid GROUP BY questions.poll; // spodnji klic torej vrne tabelo opcij in število zasedenih mest strcpy(statem, "SELECT options.rowid, options.text, options.max, COUNT(*) FROM options INNER JOIN responses ON responses.answer=options.rowid GROUP BY responses.answer WHERE options.question=:i"); - ... + if ((ret = sqlite3_prepare_v3(db, statem, -1, 0, &stmt, NULL)) != SQLITE_OK) + return hscf(db_error(db, "options prepare", ret, stmt, statem)); + if ((ret = sqlite3_bind_int64(stmt, sqlite3_bind_parameter_index(stmt, ":i"), id)) != SQLITE_OK) + return hscf(db_error(db, "options bind_int64", ret, stmt, statem)); + char * response = NULL; + while ((ret = sqlite3_step(stmt)) == SQLITE_ROW) { + long long int rowid = sqlite3_column_int64(stmt, 0); + char * text = htmlspecialchars((const char *) sqlite3_column_text(stmt, 1)); + int max = sqlite3_column_int(stmt, 2); + int responses = sqlite3_column_int(stmt, 3); + char * old = response; + response = realloc(response, (strlen(text ? text : "")+2048)*2); + if (!response) { + free(text); + free(old); + sqlite3_finalize(stmt); + return strdup("[err @ options] oom"); + } + if (poll_admin) + sprintf(response+strlen(response), "




  • število odgovorov: %d
  • ", rowid, text ? text : "", max, responses); + else + sprintf(response+strlen(response), "not implemented"); + free(text); + } + sqlite3_finalize(stmt); + if (ret != SQLITE_DONE) { + free(response); + return strdup("[err @ options] sqlite_step(stmt) != SQLITE_DONE"); + } + return response; } -static char * questions (sqlite3 db, sqlite3_int64 id, int poll_admin) { +static char * questions (sqlite3 * db, sqlite3_int64 id, int poll_admin) { + int ret; + char statem[2048]; sqlite3_stmt * stmt; - strcpy(statem, "SELECT id, text, type FROM questions WHERE poll=:i"); - if ((ret = sqlite3_prepare_v3(prijave->db, statem, -1, 0, &stmt, NULL)) != SQLITE_OK) - return db_error(db, "questions", ret, stmt); // finalizes stmt for us + strcpy(statem, "SELECT questions.rowid, questions.text, questions.type, COUNT(*) FROM questions INNER JOIN responses ON responses.question=questions.rowid WHERE questions.poll=:i GROUP BY responses.question"); + if ((ret = sqlite3_prepare_v3(db, statem, -1, 0, &stmt, NULL)) != SQLITE_OK) + return hscf(db_error(db, "questions prepare", ret, stmt, statem)); if ((ret = sqlite3_bind_int64(stmt, sqlite3_bind_parameter_index(stmt, ":i"), id)) != SQLITE_OK) - return db_error(db, "questions bind_int64", ret, stmt); - char * response = NULL; + return hscf(db_error(db, "questions bind_int64", ret, stmt, statem)); + char * response = strdup(""); while ((ret = sqlite3_step(stmt)) == SQLITE_ROW) { long long int rowid = sqlite3_column_int64(stmt, 0); char * text = htmlspecialchars((const char *) sqlite3_column_text(stmt, 1)); - int type = sqlite3_column_int(stmt, 2); - char * opts = options(db, id, poll_admin); + enum question type = sqlite3_column_int(stmt, 2); + int responses = sqlite3_column_int(stmt, 3); + char * opts = options(db, id, poll_admin, type); char * old = response; response = realloc(response, (strlen(response ? response : "")+strlen(text ? text : "")+strlen(opts ? opts : "")+2048)*2); if (!response) { @@ -118,19 +159,19 @@ static char * questions (sqlite3 db, sqlite3_int64 id, int poll_admin) { free(text); free(opts); sqlite3_finalize(stmt); - return strdup("[err] oom"); + return strdup("[err @ questions] oom"); } - const char * format = "


  • "; - if (!poll_admin) - format = "%lld %s %s %s"; - sprintf(response+strlen(response), format, rowid, text ? text : "", opts ? "

    možnosti

    " : "", opts ? opts : ""); + if (poll_admin) + sprintf(response+strlen(response), "


  • ", rowid, text ? text : "", responses, opts ? "

    možnosti

    " : "", opts ? opts : ""); + else + sprintf(response+strlen(response), "not implemented"); free(opts); free(text); } sqlite3_finalize(stmt); if (ret != SQLITE_DONE) { free(response); - return strdup("[err] sqlite_step(stmt) != SQLITE_DONE"); + return strdup("[err @ questions] sqlite_step(stmt) != SQLITE_DONE"); } return response; } @@ -173,7 +214,7 @@ static enum MHD_Result httpd (void * userdata, struct MHD_Connection * connectio { \ content_type = "text/plain; charset=UTF-8"; \ status_code = MHD_HTTP_BAD_GATEWAY; \ - response = db_error(prijave->db, section, ret, stmt); /* finaliz */ \ + response = db_error(prijave->db, section, ret, stmt, statem); \ if (!response) { \ rmm = MHD_RESPMEM_PERSISTENT; \ response = "HTTP 502: " section " oom\n"; \ @@ -400,16 +441,16 @@ static enum MHD_Result httpd (void * userdata, struct MHD_Connection * connectio char * poll_pass = htmlspecialchars((const char *) sqlite3_column_text(stmt, 2)); sqlite3_finalize(stmt); char * quests = questions(prijave->db, id, 1); - response = malloc((strlen(HTML_START(""))+strlen(name)*3+strlen(desc)+strlen(poll_pass)+strlen(quests)+2048)*2); + response = malloc((strlen(HTML_START(""))+strlen(name ? name : "")*3+strlen(desc ? desc : "")+strlen(poll_pass ? poll_pass : "")+strlen(quests ? quests : "")+2048)*2); if (!response || !quests) { - free(quests); + free(response); rmm = MHD_RESPMEM_PERSISTENT; status_code = MHD_HTTP_BAD_GATEWAY; response = "HTTP 502: id oom\n"; content_type = "text/plain; charset=UTF-8"; - goto r; + goto m; } - sprintf(response, HTML_START("%s") "

    %s

    za dostop do nastavitev obrazca je potreben samo naslov, na katerem ste sedaj, zato si ga shranite.





    vprašanja

    ", name, name, poll_pass, name, desc, quests); + sprintf(response, HTML_START("%s") "

    %s

    za dostop do nastavitev in podatkov obrazca je potreben samo naslov, na katerem ste sedaj, zato si ga shranite.








    vprašanja

    ", name, name, poll_pass, name, desc, quests); strcat(response, "" HTML_END); status_code = MHD_HTTP_OK; content_type = "text/html; charset=UTF-8"; -- cgit v1.2.3