summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAnton Luka Šijanec <anton@sijanec.eu>2022-05-16 18:50:12 +0200
committerAnton Luka Šijanec <anton@sijanec.eu>2022-05-16 18:50:12 +0200
commit6b6a28d47f0238a8700a35d8648cb587ec49a79b (patch)
treee87561de27c8dbf72e831262348c35df3197e59a
parentse ne prevere, grem se učit kemijo (diff)
downloadprijave-6b6a28d47f0238a8700a35d8648cb587ec49a79b.tar
prijave-6b6a28d47f0238a8700a35d8648cb587ec49a79b.tar.gz
prijave-6b6a28d47f0238a8700a35d8648cb587ec49a79b.tar.bz2
prijave-6b6a28d47f0238a8700a35d8648cb587ec49a79b.tar.lz
prijave-6b6a28d47f0238a8700a35d8648cb587ec49a79b.tar.xz
prijave-6b6a28d47f0238a8700a35d8648cb587ec49a79b.tar.zst
prijave-6b6a28d47f0238a8700a35d8648cb587ec49a79b.zip
-rw-r--r--lib.c5
-rw-r--r--prijave.c91
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), "<li><form method=post><button type=submit name=do value=%lld>izbriši možnost</button><input type=reset /><input type=submit name=mq value='shrani možnost' /><br><label for=t>besedilo možnosti</label><br><textarea name=t id=t placeholder=besedilo>%s</textarea><br><label for=o>omejitev prijav na možnost (-1 za neomejeno)</label> <input type=number min=-1 step=1 placeholder=številka value=%d /><br>število odgovorov: %d</form></li>", 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 = "<li><form method=post><button type=submit name=dq value=%lld>izbriši vprašanje</button><input type=reset /><input type=submit name=mq value='shrani vprašanje' /><br><textarea name=te>%s</textarea><br><label for=r>radio</label><input type=radio id=r name=ty value=r /><label for=c>kljukica</label><input type=radio id=c name=ty value=c /><label for=v>prosto besedilo</labe><input type=radio id=v name=ty value=v /><ul>%s%s</ul></form></li>";
- if (!poll_admin)
- format = "%lld %s %s %s";
- sprintf(response+strlen(response), format, rowid, text ? text : "", opts ? "<h3>možnosti</h3>" : "", opts ? opts : "");
+ if (poll_admin)
+ sprintf(response+strlen(response), "<li><form method=post><button type=submit name=dq value=%lld>izbriši vprašanje</button><input type=reset /><input type=submit name=mq value='shrani vprašanje' /><br><textarea name=te placeholder=opis>%s</textarea><br><label for=r>radio</label><input type=radio id=r name=ty value=r /><label for=c>kljukica</label><input type=radio id=c name=ty value=c /><label for=v>prosto besedilo</labe><input type=radio id=v name=ty value=v /><label for=h>skrij vprašanje in začasno onemogoči vnos</label><input type=radio id=h name=ty value=h /></form>število odgovorov: %d<ul>%s%s</ul></li>", rowid, text ? text : "", responses, opts ? "<h3>možnosti</h3>" : "", 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") "<h1>%s</h1><p>za dostop do nastavitev obrazca je potreben samo naslov, na katerem ste sedaj, zato si ga shranite.</p><form method=post><input type=submit name=mp value=shrani /><input type=reset /><br><label for=pp>novo geslo - nastavitev novega gesla invalidira naslov za dostop do obrazca (naslovov za reševanje pa ne)</label> <input type=password name=pp id=pp placeholder=geslo value='%s' /><br><label for=pn>ime obrazca</label> <input id=pn name=pn value='%s' placeholder=ime /><br><label for=pd>opis obrazca</label><br><textarea name=pd id=pd placecholder=opis >%s</textarea><h2>vprašanja</h2><ul>%s</ul>", name, name, poll_pass, name, desc, quests);
+ sprintf(response, HTML_START("%s") "<h1>%s</h1><p>za dostop do nastavitev in podatkov obrazca je potreben samo naslov, na katerem ste sedaj, zato si ga shranite.</p><form method=post><input type=submit name=mp value=shrani /><input type=reset /><input type=submit name=dd value='prenesi podatke'><input type=submit name=aq value='dodaj vprašanje' /><input type=submit name=dp value='izbriši obrazec' /><br><label for=pp>novo geslo - nastavitev novega gesla invalidira naslov za dostop do obrazca (naslovov za reševanje pa ne)</label> <input type=password name=pp id=pp placeholder=geslo value='%s' /><br><label for=pn>ime obrazca</label> <input id=pn name=pn value='%s' placeholder=ime /><br><label for=pd>opis obrazca</label><br><textarea name=pd id=pd placecholder=opis >%s</textarea><br><label for=gl>dejanja z elektronskimi naslovi</label><br><textarea name=e id=e placeholder='elektronski naslovi, po en na vrstico'></textarea><br><input type=submit name=gl value='generiraj povezave za reševanje obrazca' /><h2>vprašanja</h2></form><ul>%s</ul>", name, name, poll_pass, name, desc, quests);
strcat(response, "</form>" HTML_END);
status_code = MHD_HTTP_OK;
content_type = "text/html; charset=UTF-8";