Skip to content

Instantly share code, notes, and snippets.

@m0r13
Last active December 18, 2015 05:19
Show Gist options
  • Save m0r13/5731922 to your computer and use it in GitHub Desktop.
Save m0r13/5731922 to your computer and use it in GitHub Desktop.
Quiz CGI-Script
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sqlite3.h>
void read_teachers(sqlite3* handler) {
sqlite3_stmt* stmt;
int ret = sqlite3_prepare(handler, "SELECT * FROM teachers", -1, &stmt, NULL);
if(ret != SQLITE_OK) {
printf("ERROR,SQLITE SELECT %d\n", ret);
return;
}
printf("OK\n");
while(sqlite3_step(stmt) != SQLITE_DONE) {
int id = sqlite3_column_int(stmt, 0);
const char* name = sqlite3_column_text(stmt, 1);
printf("%d,%s\n", id, name);
}
sqlite3_finalize(stmt);
}
typedef struct {
int image;
int teacher;
} Assign;
int is_assign_correct(Assign assign, Assign correct[100], int len) {
int i;
for(i = 0; i < len; i++)
if(assign.image == correct[i].image && assign.teacher == correct[i].teacher)
return 1;
return 0;
}
int contains(int search, int list[100], int len) {
int i;
for(i = 0; i < len; i++)
if(list[i] == search)
return 1;
return 0;
}
int are_assigns_valid(Assign assigns[100], int len) {
int i;
int images[100], teachers[100];
for(i = 0; i < len; i++) {
images[i] = assigns[i].image;
teachers[i] = assigns[i].teacher;
if(contains(images[i], images, i) || contains(teachers[i], teachers, i))
return 0;
}
return 1;
}
int parse_assigns(char* str, Assign assigns[100]) {
int i = 0;
char* part = strtok(str, ",");
if(part == NULL)
return -1;
while(part != NULL) {
int len = strlen(part);
if(len == 0)
continue;
char* mid = strchr(part, (int) ':');
if(mid == NULL)
return -1;
int pos = mid - part;
if(pos == 0 || pos == len-1)
return -1;
int n2 = atoi(mid+1);
*(mid) = '\0';
int n1 = atoi(part);
if(i >= 100)
return i;
assigns[i].image = n1;
assigns[i++].teacher = n2;
part = strtok(NULL, ",");
}
return i;
}
int get_correct_assigns(sqlite3* handler, Assign assigns[100]) {
sqlite3_stmt* stmt;
int ret = sqlite3_prepare(handler, "SELECT * FROM teachers", -1, &stmt, NULL);
if(ret != SQLITE_OK)
return -1;
int i = 0;
while(sqlite3_step(stmt) != SQLITE_DONE) {
int id = sqlite3_column_int(stmt, 0);
//const char* name = sqlite3_column_text(stmt, 1);
if(sqlite3_column_text(stmt, 2) == NULL)
continue;
int image = sqlite3_column_int(stmt, 2);
assigns[i].image = image;
assigns[i++].teacher = id;
}
sqlite3_finalize(stmt);
return i;
}
void insert_result(sqlite3* handler) {
char first_name[256] = "";
char last_name[256] = "";
char email[256] = "";
char assignstr[256] = "";
int points = 0;
char line[256];
char* l = line;
size_t bytes = 255;
while(getline(&l, &bytes, stdin) != -1) {
// empty lines have only a \n
if(strlen(line) == 1)
continue;
// remove newline char
line[strlen(line)-1] = '\0';
if(strstr(line, "FIRST_NAME=") == line) {
strncpy(first_name, line+11, sizeof(first_name));
} else if(strstr(line, "LAST_NAME=") == line) {
strncpy(last_name, line+10, sizeof(last_name));
} else if(strstr(line, "EMAIL=") == line) {
strncpy(email, line+6, sizeof(email));
} else if(strstr(line, "ASSIGNS=") == line) {
strncpy(assignstr, line+8, sizeof(assignstr));
}
bytes = 255;
}
/*
printf("firstname: %s\n", first_name);
printf("lastname: %s\n", last_name);
printf("email: %s\n", email);
printf("results: %s\n", results);
*/
if(strlen(first_name) == 0) {
printf("ERROR,NO FIRST NAME\n");
return;
} else if(strlen(last_name) == 0) {
printf("ERROR,NO LAST NAME\n");
return;
} else if(strlen(email) == 0) {
printf("ERROR,NO EMAIL\n");
return;
} else if(strlen(assignstr) == 0) {
printf("ERROR,NO ASSIGNS\n");
return;
}
Assign assigns[100];
int assignlen = parse_assigns(assignstr, assigns);
if(assignlen == -1) {
printf("ERROR,INVALID ASSIGNS\n");
return;
}
Assign correct[100];
int correctlen = get_correct_assigns(handler, correct);
if(correctlen == -1) {
printf("ERROR,CAN'T GET CORRECT ASSIGNS\n");
return;
}
int i;
/*
printf("Your assigns:\n");
for(i = 0; i < assignlen; i++)
printf("%d -> %d\n", assigns[i].image, assigns[i].teacher);
printf("Correct assigns:\n");
for(i = 0; i < correctlen; i++)
printf("%d -> %d\n", correct[i].image, correct[i].teacher);
*/
if(!are_assigns_valid(assigns, assignlen)) {
printf("ERROR,REDUNDANT ASSIGNS\n");
return;
}
for(i = 0; i < correctlen; i++)
if(is_assign_correct(assigns[i], correct, correctlen))
points++;
//printf("%d points\n", points);
sqlite3_stmt* stmt;
const char* query = "INSERT INTO results (first_name, last_name, email, results, points) VALUES(?, ?, ?, ? ,?)";
int ret = sqlite3_prepare_v2(handler, query, strlen(query), &stmt, NULL);
if(ret != SQLITE_OK) {
printf("ERROR,SQLITE INSERT %d\n", ret);
return;
}
sqlite3_bind_text(stmt, 1, first_name, strlen(first_name), SQLITE_STATIC);
sqlite3_bind_text(stmt, 2, last_name, strlen(last_name), SQLITE_STATIC);
sqlite3_bind_text(stmt, 3, email, strlen(email), SQLITE_STATIC);
sqlite3_bind_text(stmt, 4, assignstr, strlen(assignstr), SQLITE_STATIC);
sqlite3_bind_int(stmt, 5, points);
ret = sqlite3_step(stmt);
if(ret != SQLITE_DONE) {
printf("ERROR,SQLITE INSERT %d\n", ret);
return;
}
printf("OK\n");
sqlite3_finalize(stmt);
}
void read_results(sqlite3* handler) {
sqlite3_stmt* stmt;
int ret = sqlite3_prepare(handler, "SELECT * FROM results ORDER BY points DESC", -1, &stmt, NULL);
if(ret != SQLITE_OK) {
printf("ERROR,SQLITE SELECT %d\n", ret);
return;
}
printf("OK\n");
while(sqlite3_step(stmt) != SQLITE_DONE) {
int id = sqlite3_column_int(stmt, 0);
const char* first_name = sqlite3_column_text(stmt, 1);
const char* last_name = sqlite3_column_text(stmt, 2);
const char* email = sqlite3_column_text(stmt, 3);
const char* results = sqlite3_column_text(stmt, 4);
int points = sqlite3_column_int(stmt, 5);
printf("%dp: %s %s (%s)\n", points, first_name, last_name, email);
}
sqlite3_finalize(stmt);
}
int main() {
printf("Content-Type: text/plain; charset=utf-8\n\n");
sqlite3* handler;
int ret = sqlite3_open_v2("quiz.sqlite", &handler, SQLITE_OPEN_READWRITE | SQLITE_OPEN_FULLMUTEX, NULL);
if(ret != SQLITE_OK) {
printf("ERROR,SQLITE OPEN %d\n", ret);
return 0;
}
char* query = getenv("QUERY_STRING");
if(query == NULL)
query = "";
if(strcmp(query, "TEACHERS") == 0) {
read_teachers(handler);
} else if(strcmp(query, "SEND") == 0) {
insert_result(handler);
} else if(strcmp(query, "RESULTS") == 0) {
read_results(handler);
} else {
printf("ERROR,INVALID PAGE\n");
}
sqlite3_close(handler);
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment