bsw/jbe@4: #include bsw/jbe@4: #include bsw/jbe@4: #include bsw/jbe@4: #include bsw/jbe@4: #include bsw/jbe@4: #include bsw/jbe@4: #include bsw/jbe@4: #include bsw/jbe@4: bsw/jbe@4: #ifndef GETPIC_CONNINFO bsw/jbe@4: #define GETPIC_CONNINFO "dbname=liquid_feedback" bsw/jbe@4: #endif bsw/jbe@4: bsw/jbe@4: #ifndef GETPIC_DEFAULT_AVATAR bsw/jbe@4: #define GETPIC_DEFAULT_AVATAR "/opt/liquid_feedback_testing/app/static/avatar.jpg" bsw/jbe@4: #endif bsw/jbe@4: bsw/jbe@4: int main(int argc, const char * const *argv) { bsw/jbe@4: bsw/jbe@4: char *args_string; bsw/jbe@4: char *member_id; bsw/jbe@4: char *image_type; bsw/jbe@52: const char *sql_member_image_params[2]; bsw/jbe@4: bsw/jbe@5: char *cookies; bsw/jbe@5: regex_t session_ident_regex; bsw/jbe@4: ssize_t start, length; bsw/jbe@5: regmatch_t session_ident_regmatch[3]; bsw/jbe@4: char *session_ident; bsw/jbe@52: const char *sql_session_params[1]; bsw/jbe@4: bsw/jbe@5: PGconn *conn; bsw/jbe@5: PGresult *dbr; bsw/jbe@4: bsw/jbe@4: args_string = getenv("QUERY_STRING"); bsw/jbe@5: cookies = getenv("HTTP_COOKIE"); bsw/jbe@5: if (!args_string || !cookies) { bsw/jbe@4: fputs("Status: 403 Access Denied\n\n", stdout); bsw/jbe@4: return 0; bsw/jbe@4: } bsw/jbe@4: bsw/jbe@4: member_id = strtok(args_string, "+"); bsw/jbe@4: image_type = strtok(NULL, "+"); bsw/jbe@4: sql_member_image_params[0] = member_id; bsw/jbe@4: sql_member_image_params[1] = image_type; bsw/jbe@4: bsw/jbe@5: if (regcomp(&session_ident_regex, "(^|[; \t])liquid_feedback_session=([0-9A-Za-z]+)", REG_EXTENDED) != 0) { bsw/jbe@4: // shouldn't happen bsw/jbe@4: abort(); bsw/jbe@4: } bsw/jbe@52: if (regexec(&session_ident_regex, cookies, 3, session_ident_regmatch, 0) != 0) { bsw/jbe@4: fputs("Status: 403 Access Denied\n\n", stdout); bsw/jbe@4: return 0; bsw/jbe@4: } bsw/jbe@5: start = session_ident_regmatch[2].rm_so; bsw/jbe@5: length = session_ident_regmatch[2].rm_eo - session_ident_regmatch[2].rm_so; bsw/jbe@4: session_ident = malloc(length + 1); bsw/jbe@5: if (!session_ident) abort(); // shouldn't happen bsw/jbe@4: strncpy(session_ident, cookies + start, length); bsw/jbe@4: session_ident[length] = 0; bsw/jbe@4: sql_session_params[0] = session_ident; bsw/jbe@4: bsw/jbe@4: conn = PQconnectdb(GETPIC_CONNINFO); bsw/jbe@4: if (!conn) { bsw/jbe@4: fputs("Could not create PGconn structure.\n", stderr); bsw/jbe@4: return 1; bsw/jbe@4: } bsw/jbe@4: if (PQstatus(conn) != CONNECTION_OK) { bsw/jbe@4: fputs(PQerrorMessage(conn), stderr); bsw/jbe@5: PQfinish(conn); bsw/jbe@4: return 1; bsw/jbe@4: } bsw/jbe@4: bsw/jbe@4: dbr = PQexecParams(conn, bsw/jbe@4: "SELECT NULL FROM session JOIN member ON member.id = session.member_id WHERE session.ident = $1 AND member.active", bsw/jbe@4: 1, NULL, sql_session_params, NULL, NULL, 0 bsw/jbe@4: ); bsw/jbe@4: if (PQresultStatus(dbr) != PGRES_TUPLES_OK) { bsw/jbe@4: fputs(PQresultErrorMessage(dbr), stderr); bsw/jbe@5: PQfinish(conn); bsw/jbe@4: return 1; bsw/jbe@4: } bsw/jbe@4: if (PQntuples(dbr) != 1) { bsw/jbe@4: fputs("Status: 403 Access Denied\n\n", stdout); bsw/jbe@5: PQfinish(conn); bsw/jbe@4: return 0; bsw/jbe@4: } bsw/jbe@4: bsw/jbe@4: dbr = PQexecParams(conn, bsw/jbe@4: "SELECT content_type, data " bsw/jbe@4: "FROM member_image " bsw/jbe@4: "WHERE member_id = $1 " bsw/jbe@4: "AND image_type = $2 " bsw/jbe@4: "AND scaled " bsw/jbe@4: "LIMIT 1;", bsw/jbe@4: 2, NULL, sql_member_image_params, NULL, NULL, 1 bsw/jbe@4: ); bsw/jbe@4: if (PQresultStatus(dbr) != PGRES_TUPLES_OK) { bsw/jbe@4: fputs(PQresultErrorMessage(dbr), stderr); bsw/jbe@5: PQfinish(conn); bsw/jbe@4: return 1; bsw/jbe@4: } bsw/jbe@4: if (PQntuples(dbr) == 0) { bsw/jbe@4: struct stat sb; bsw/jbe@4: PQclear(dbr); bsw/jbe@4: PQfinish(conn); bsw/jbe@4: fputs("Content-Type: image/jpeg\n\n", stdout); bsw/jbe@4: if (stat(GETPIC_DEFAULT_AVATAR, &sb)) return 1; bsw/jbe@5: fprintf(stdout, "Content-Length: %i\n", (int)sb.st_size); bsw/jbe@4: execl("/bin/cat", "cat", GETPIC_DEFAULT_AVATAR, NULL); bsw/jbe@4: return 1; bsw/jbe@4: } else { bsw/jbe@4: if (PQnfields(dbr) < 0) { bsw/jbe@4: fputs("Too few columns returned by database.\n", stderr); bsw/jbe@5: PQfinish(conn); bsw/jbe@4: return 1; bsw/jbe@4: } bsw/jbe@4: if (PQfformat(dbr, 0) != 1 || PQfformat(dbr, 1) != 1) { bsw/jbe@4: fputs("Database did not return data in binary format.\n", stderr); bsw/jbe@5: PQfinish(conn); bsw/jbe@4: return 1; bsw/jbe@4: } bsw/jbe@4: if (PQgetisnull(dbr, 0, 0) || PQgetisnull(dbr, 0, 1)) { bsw/jbe@4: fputs("Unexpected NULL in database result.\n", stderr); bsw/jbe@5: PQfinish(conn); bsw/jbe@4: return 1; bsw/jbe@4: } bsw/jbe@52: fprintf(stdout, "Content-Type: %s\n\n", PQgetvalue(dbr, 0, 0)); bsw/jbe@4: fwrite(PQgetvalue(dbr, 0, 1), PQgetlength(dbr, 0, 1), 1, stdout); bsw/jbe@4: } bsw/jbe@4: PQfinish(conn); bsw/jbe@4: return 0; bsw/jbe@5: bsw/jbe@4: }