Last active
December 18, 2015 05:19
-
-
Save m0r13/5731922 to your computer and use it in GitHub Desktop.
Quiz CGI-Script
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#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