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@871: #ifndef PUBLIC_ACCESS jbe@1108: #ifdef PUBLIC_AVATAR_ACCESS jbe@1108: int authorization_required = 0; jbe@1108: #endif 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@871: #endif 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@873: if (!args_string) { bsw@873: fputs("Status: 403 Access Denied\n\n", stdout); bsw@873: return 0; bsw@873: } jbe@1108: jbe@1108: member_id = strtok(args_string, "+"); jbe@1108: image_type = strtok(NULL, "+"); jbe@1108: if (!member_id || !image_type) { bsw/jbe@4: fputs("Status: 403 Access Denied\n\n", stdout); bsw/jbe@4: return 0; bsw/jbe@4: } bsw/jbe@4: sql_member_image_params[0] = member_id; bsw/jbe@4: sql_member_image_params[1] = image_type; bsw/jbe@4: bsw@871: #ifndef PUBLIC_ACCESS jbe@1108: #ifdef PUBLIC_AVATAR_ACCESS jbe@1108: if (strcmp(image_type, "avatar")) { jbe@1108: authorization_required = 1; jbe@1108: #endif jbe@1108: cookies = getenv("HTTP_COOKIE"); jbe@1108: if (!args_string || !cookies) { jbe@1108: fputs("Status: 403 Access Denied\n\n", stdout); jbe@1108: return 0; jbe@1108: } jbe@1108: if (regcomp(&session_ident_regex, "(^|[; \t])liquid_feedback_session=([0-9A-Za-z]+)", REG_EXTENDED) != 0) { jbe@1108: // shouldn't happen jbe@1108: abort(); jbe@1108: } jbe@1108: if (regexec(&session_ident_regex, cookies, 3, session_ident_regmatch, 0) != 0) { jbe@1108: fputs("Status: 403 Access Denied\n\n", stdout); jbe@1108: return 0; jbe@1108: } jbe@1108: start = session_ident_regmatch[2].rm_so; jbe@1108: length = session_ident_regmatch[2].rm_eo - session_ident_regmatch[2].rm_so; jbe@1108: session_ident = malloc(length + 1); jbe@1108: if (!session_ident) abort(); // shouldn't happen jbe@1108: strncpy(session_ident, cookies + start, length); jbe@1108: session_ident[length] = 0; jbe@1108: sql_session_params[0] = session_ident; jbe@1108: #ifdef PUBLIC_AVATAR_ACCESS bsw/jbe@4: } jbe@1108: #endif bsw@874: #endif 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@874: #ifndef PUBLIC_ACCESS jbe@1108: #ifdef PUBLIC_AVATAR_ACCESS jbe@1108: if (authorization_required) { jbe@1108: #endif jbe@1108: dbr = PQexecParams(conn, jbe@1108: "SELECT NULL FROM session JOIN member ON member.id = session.member_id WHERE session.ident = $1 AND member.active", jbe@1108: 1, NULL, sql_session_params, NULL, NULL, 0 jbe@1108: ); jbe@1108: if (PQresultStatus(dbr) != PGRES_TUPLES_OK) { jbe@1108: fputs(PQresultErrorMessage(dbr), stderr); jbe@1108: PQfinish(conn); jbe@1108: return 1; jbe@1108: } jbe@1108: if (PQntuples(dbr) != 1) { jbe@1108: fputs("Status: 403 Access Denied\n\n", stdout); jbe@1108: PQfinish(conn); jbe@1108: return 0; jbe@1108: } jbe@1108: #ifdef PUBLIC_AVATAR_ACCESS bsw/jbe@4: } jbe@1108: #endif bsw@871: #endif 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: }